MZ-800 course Chapter 3
|3. Machine language on the SHARP MZ-800|
Some standard routines have already been predefined in the ROM-monitor, like routines for reading the keyboard, asking the directory listing, scrolling up the screen and so on.
These routines can be accessed by a CALL. This way you can, for example, ask for the directory listing of the QD with 3 bytes. In some cases certain registers must contain a certain value, before you issue the CALL. For example; if you want to start the clock, register A ( the accumulator ) must contain a value that indicates whether it is AM or PM and register DE should contain the number of seconds ( with a maximum of 43,200 ), after this, the clock can be started with CALL 0033H. In this part of chapter 3 you can find a program that makes this all very clear.
The opposite can also be the case. First you issue a CALL and afterwards a couple of registers have been altered. To stick by the clock example: First you do: CALL 003BH and this will put the number of seconds in DE and the AM / PM indicator will be in A.
In order to make things more easy to understand, we will embed most CALLS in a program, which will be accompanied by its assembler listing.
Actually, assembler listings should be in another chapter, but in this case they will be placed next to the machine code to make things a bit easier.
Program 1: On-screen time.
As mentioned before, the SHARP has an internal clock. By issuing CALL 0033H you can start the clock and with CALL 003BH you can read the time in seconds. By putting this all together in a structured program, we can make a normal running digital clock, this is exactly what the following program does.
Unfortunately, the clock always starts on 00:00:00 and keeps on counting when it reaches 12:00:00. It could be nice to integrate this in your own programs if this program is altered to accept an arbitrary start time. To keep this program short, we do not apply this here.
First we will give you the machine code, then data about saving the program, then the assembler listing and finally an explanation.
1200 3E 1212 00 1224 D0 1236 FE 1248 C9 125A 7E 126C 20 1201 00 1213 CD 1225 7E 1237 26 1249 3E 125B 3C 126C 3D 1202 11 1214 3B 1226 3C 1238 CC 124A 20 125C FE 126D 20 1203 00 1215 00 1227 FE 1239 3C 124B 77 125D 2A 126E 30 1204 00 1216 43 1228 2A 123A 12 124C 2B 125E CC 126F 30 1205 CD 1217 3A 1229 CC 123B C9 124D 7E 125F 62 1270 3A 1206 33 1218 03 122A 30 123C 3E 124E 3C 1260 12 1271 30 1207 00 1219 12 122B 12 123D 20 124F FE 1261 C9 1272 30 1208 3E 121A B8 122C 77 123E 77 1250 26 1262 3E 1273 3A 1209 C6 121B CA 122D C3 123F 2B 1251 CC 1263 20 1274 30 120A CD 121C 13 122E 13 1240 2B 1252 55 1264 77 1275 30 120B DC 121D 12 122F 12 1241 7E 1253 12 1265 2B 1276 0D 120C 0D 121E 21 1230 3E 1242 3C 1254 C9 1266 34 120D 11 121F 03 1231 20 1243 FE 1255 3E 1267 C9 120E 68 1220 12 1232 77 1244 2A 1256 20 1268 54 120F 12 1221 34 1233 2B 1245 CC 1257 77 1269 49 1210 CD 1222 21 1234 7E 1246 49 1258 2B 126A 4D 1211 15 1223 0E 1235 3C 1247 12 1259 2B 126B 45
Assembler listing of program 1:
1200 ORG 1200H 1200 LD A,00H 1202 STTIME: 1202 LD DE,0000H 1205 CALL 0033H 1208 LD A,C6H 120A CALL 0DDCH 120D LD DE,TEXT 1210 CALL 0015H 1213 TIME: 1213 CALL 003BH 1216 LD B,E 1217 LD A,(STTIME+1) 121A CP B 121B JP Z,TIME 121E LD HL,STTIME+1 1221 INC (HL) 1222 LD HL,D00DH 1225 LD A,(HL) 1226 INC A 1227 CP 2AH 1229 CALL Z,PA 122C LD (HL),A 122D JP TIME 1230 PA: 1230 LP A,20H 1232 LD (HL),A 1233 DEC HL 1234 LD A,(HL) 1235 INC A 1236 CP 26H 1238 CALL Z,PB 123B RET 123C PB: 123C LD A,20H 123E LD (HL),A 123F DEC HL 1240 DEC HL 1241 LD A,(HL) 1242 INC A 1243 CP 2AH 1245 CALL Z,PC 1248 RET 1249 PC: 1249 LD A,20H 124B LD (HL),A 124C DEC HL 124D LD A,(HL) 124E INC A 124F CP 26H 1251 CALL Z,PD 1254 RET 1255 PD: 1255 LD A,20H 1257 LD (HL),A 1258 DEC HL 1259 DEC HL 125A LD A,(HL) 125B INC A 125C CP 2AH 125E CALL Z,PE 1261 RET 1262 PE: 1262 LD A,20H 1264 LD (HL),A 1265 DEC HL 1266 INC (HL) 1267 RET 1268 TEXT: 1268 DEFB 54H 1269 DEFB 49H 126A DEFB 4DH 126B DEFB 45H 126C DEFB 3DH 126D DEFB 20H 126E DEFB 30H 126F DEFB 30H 1270 DEFB 3AH 1271 DEFB 30H 1272 DEFB 30H 1273 DEFB 3AH 1274 DEFB 30H 1275 DEFB 30H 1276 DEFB 0DH
The observant reader may have noticed that there is a small difference between machine code and assembler listing. This has almost no consequence for the program.
The explanation of program 1:
This program contains 4 different CALLS. These calls will be discussed below.
From address 1216 ( LD B,E ) up to address 122B the program checks if the clock has advanced 1 second already. If this is not the case, the check will be repeated. This will continue until the clock did advance one second and then the program will run the cycle from 122C up to 1267 to put the progress on the screen.
Since the clock on the screen always starts at 00:00:00, it does not matter which value the DE register has on startup because this first value is not printed on the screen.
You have just seen how a program is discussed. This will be the same for all programs. In the chapter about assembly we will also discuss things in this manner. In that chapter we may have added a couple of things, but that is all.
As you can see, it is obviously not our intention to teach you machine language, because there are more than enough books on that subject.
Program 2: Tone with adjustable frequency.
This is a very nice little program that uses a CALL to make a tone with an arbitrary frequency. The arrow-keys can be used to vary the frequency and this gives a really nice result.
1200 21 1208 CD 1210 CC 1218 FE 1220 C3 1228 A1 1230 A1 1201 A1 1209 44 1211 23 1219 64 1221 08 1229 11 1231 11 1202 11 120A 00 1212 12 121A CA 1222 12 122A C9 1232 C9 1203 36 120B CD 1213 FE 121B 33 1223 2A 122B 2A 1233 CD 1204 00 120C 1B 1214 11 121C 12 1224 A1 122C A1 1234 47 1205 23 120D 00 1215 CC 121D 00 1225 11 122D 11 1235 00 1206 36 120E FE 1216 2B 121E 00 1226 23 122E 2B 1236 C9 1207 05 120F 12 1217 12 121F 00 1227 22 122F 22
Assembler listing of program 2:
1200 LD HL,11A1H 1203 LD (HL),00H 1205 INC HL 1206 LD (HL),05H 1208 TONE: 1208 CALL 0044H 120B CALL 001BH 120E CP 12H 1210 CALL Z,HIGH 1213 CP 11H 1215 CALL Z,LOW 1218 CP 64H 121A JP Z,END 121D NOP 121E NOP 121F NOP 1220 JP TONE 1223 HIGH: 1223 LD HL,(11A1H) 1226 INC HL 1227 LD (11A1H),HL 122A RET 122B LOW: 122B LD HL,(11A1H) 122E DEC HL 122F LD (11A1H),HL 1232 RET 1233 END: 1233 CALL 0047H 1236 RET
The explanation of program 2:
This program contains 3 different CALLS.
This program is so simple that no further explanation is needed. However, you could pull a little trick by changing the addresses 121D up to 121F to CD, 47, 00. If you now start the program you will hear a different type of tone. The assembler listing will read:
121D CALL 0047H
Program 3: Show an arbitrary text 20 times.
This program requires an input of at most 80 characters. You will see this text appear 20 times in a row on the screen.
1200 11 1205 00 120A 0D 120F 00 1214 CD 1219 00 121E 00 1201 00 1206 3E 120B 06 1210 10 1215 15 121A 10 1202 20 1207 C6 120C 19 1211 FB 1216 00 121B F8 1203 CD 1208 CD 120D CD 1212 06 1217 CD 121C CD 1204 03 1209 DC 120E 06 1213 14 1218 06 121D AD
Assembler listing of program 3:
1200 LD DE,2000H 1203 CALL 0003H 1206 LD A,C6H 1208 CALL 0DDCH 120B LD B,19H 120D REPEAT: 120D CALL 0006H 1210 DJNZ REPEAT 1214 ?TEXT: 1214 CALL 0015H 1217 CALL 0006H 121A DJNZ ?TEXT 121C CALL 00ADH
The explanation of program 3:
This program contains three new calls. The calls CALL 0DDCH and CALL 0015H have been explained already.
One last note about the last call:
This annoyance can be solved in two ways. The first solution is to load the program with QC instead of QL, this is only possible with programs that start at address 1200. After loading the program with QC, press N and you can start the program and the RET-instruction will be executed.
Programs that do not start at 1200 usually can not be loaded and executed in this manner. The QC instruction always loads a program to address 1200.
The second solution is to replace the RET-instruction with a CALL 00ADH. The computer will always jump back to the ROM-monitor, even if the program is started from QD. The only disadvantage is that in the real ROM-monitor several instructions are not available, as mentioned before.
Program 4: Border lining.
A normal program to make a border line is shorter and faster than a program with calls. Therefore this program is just to give an example for the used calls and not to make an efficient program.
1200 3E 1208 C8 1210 3E 1218 10 1220 00 1228 12 1230 C4 1201 C6 1209 CD 1211 C8 1219 F6 1221 10 1229 00 1231 CD 1202 CD 120A 12 1212 CD 121A 06 1222 F9 122A 3E 1232 DC 1203 DC 120B 00 1213 12 121B 27 1223 06 122B C2 1233 0D 1204 0D 120C 10 1214 00 121C 3E 1224 17 122C CD 1234 10 1205 06 120D F9 1215 CD 121D C8 1225 3E 122D DC 1235 EF 1206 28 120E 06 1216 06 121E CD 1226 C8 122E 0D 1236 C9 1207 3E 120F 16 1217 00 121F 12 1227 CD 122F 3E
Assembler listing of program 4:
1200 LD A,C6H 1202 CALL 0DDCH 1205 LD B,28H 1207 LONE: 1207 LD A,C8H 1209 CALL 0012H 120C DJNZ LONE 120E LD B,16H 1210 LTWO: 1210 LD A,C8H 1212 CALL 0012H 1215 CALL 0006H 1218 DJNZ LTWO 121A LD B,27H 121C LTHREE: 121C LD A,C8H 121E CALL 0012H 1221 DJNZ LTHREE 1223 LD B,17H 1225 LFOUR: 1225 LD A,C8H 1227 CALL 0012H 122A LD A,C2H 122C CALL 0DDCH 122F LD A,C4H 1231 CALL 0DDCH 1234 DJNZ LFOUR 1236 RET
The explanation of program 4:
In this program only one new call and two familiar calls occur. CALL 0DDCH has changed slightly though, register A contains C2H and C4H instead of value C6H. This results in the following:
Value C2H makes the cursor move up 1 line.
First of all, the screen is cleared and the cursor is placed on the upper left coordinate ( 1200 - 1204 ). After that, forty squares are printed on one line and the cursor will be on the first line of the inside of the screen ( 1205 - 120D ). Then a square is placed on the beginning of each line and the cursor will be on the left side of the last-but-one line ( 120E - 1219 ). Subsequently, the last-but-one line is filled with 39 squares and the cursor will be at the right side of the last-but-one line ( 121A - 1221 ). Finally, the last character of each line is replaced with a square and the borderline is finished.
Why is the bottom border not on the last line?
If you put something on the last line with these calls, the screen is scrolled one line up and this will make the top line disappear. Of course there are a lot more calls, the most important ones will be explained below. You can try these calls directly with the G monitor instruction. For example: you can test CALL 000FH by typing G000FH.
These were all calls from the lower part of the ROM-monitor. Now some calls from the upper part of the ROM-monitor will be discussed.
There are a lot more calls for the QD and tape recorder. Moreover there are calls for the floppy disk from address E000H up to FFFFH. It does not make a lot of sense to discuss the calls for these devices, because most functionality is already present in simple instructions like QX.
Now we will present a summary of the most important addresses from 1000H up to 1200H. Lots of these addresses contain, amongst other things, important data about loaded programs. The most important of these addresses will be discussed below.
This was a sample of the calls and useful addresses of the ROM-monitor of the SHARP. Because we did not want to bother you with calls which are not very useful, we only discussed the relevant calls. However, if you want to make a QD-index program or something similar, you need more. You can always write us if you need information on other calls.