Sharp logo

MZ-800 course Chapter 3 
3. Machine language on the SHARP MZ-800


3.3 Calls into the ROM-monitor

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

Filename? CLOCK
Top adrs? 1200
End adrs? 1277
Exc adrs? 1200
Start this program with G1200.
This program can only be stopped by pressing the reset button.

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.

CALL 0033H This call starts the internal clock. DE contains the number of seconds and A contains the value 0 ( AM ) or 1 ( PM ). So you have to convert the time to seconds.
CALL 003BH This call reads the clock. After the operation DE will contain the number of seconds and A will contain the value 0 or 1. To calculate the real time, you have to convert the number of seconds in DE to hours, minutes and seconds.
CALL 0DDCH This call either does something with the screen or the position of the cursor. The contents of register A determines what will happen. In this case A contains the value C6H. This means that the screen will be cleared and HL will receive the value of the first cursor position.
CALL 0015H This call prints text to the screen, it will start at the current cursor position ( in this case the upper-left coordinate, because the call above this one was issued in the program ). The text is stored at a memory location which is in register DE and the end of the text is denoted by CODE 0DH.

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

Filename? FREQ
Top adrs? 1200
End adrs? 1236
Exc adrs? 1200
Start this program with G1200.
This program can only be stopped by pressing SHIFT/BREAK. The tone will also cease.

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.

CALL 0044H This call will generate a tone with a certain frequency. The frequency is determined by the values at addresses 11A1 and 11A2.
CALL 0047H This call will make the tone cease.
CALL 001BH This call reads the keyboard and puts the value(s) of the pressed key(s) in register A. If the arrow-up key is pressed, A will contain the value 12H. If the arrow-down key is pressed, A will contain the value 11H. If the keys SHIFT and BREAK are pressed, A will contain the value 64H.

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

Filename? TEXT*20
Top adrs? 1200
End adrs? 121E
Exc adrs? 1200
Start this program with G1200. After starting this program you can only restart it with J1200. This will be explained later on.
The programs stops itself.

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.

CALL 0003H This call makes sure you can enter a text on the keyboard of at most 80 characters. This text will be stored at the address in register DE and is terminated by either code 0DH or a break-code.
CALL 0006H This call works exactly like the <cr>-key. The cursor will jump to the first column of the next line when this call is executed.
CALL 00ADH This call will make the computer jump to the real ROMmonitor. This monitor does not have the ability to use the QD instructions and uses J instead of G to execute a call directly. There is also the possibility of returning to BASIC with the # sign followed by <cr>, provided BASIC is loaded.

One last note about the last call:
If you load a machine language program from QD which jumps back to the monitor with a RET-instruction, the computer will not comply. If you start this program from the ROM-monitor, without loading it from QD first, then the RET will be adhered.

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.
Value C4H makes the cursor move 1 column to the left.

CALL 0012H This call will convert the contents of register A to the corresponding character, put it on the screen and shift the cursor one column to the right.

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.

CALL 000FH This call will place 10 spaces in a row. This call has the same function as the TAB-key.
CALL 001BH This call is discussed before, but we want to direct the reader to the page in the manual where more information on this call can be found. The page is A-15.
CALL 0030H Plays the melody stored at the address in DE. The melody is terminated with character 0DH. In the chapter on music you will read a lot more on this.
CALL 003EH This call does the same as the BASIC BEEP instruction.
CALL 0041H With this call you can change the tempo of the melody that can be played. Register A must contain the tempo value ( 1 <= A <= 7 ).
CALL 00F7H After this call, each key press will be accompanied by a short beep. Typing B followed by <cr> will yield the same result. To turn this function off, you have to issue the call a second time.
CALL 018FH The character, of which its value is in register A, will be send to the printer or plotter.
CALL 01A5H The text that is stored at the memory address in DE will be send to the printer or plotter. The text must be terminated with character 0DH.
CALL 038DH This call will set the clock to 00:00:00 and AM is changed to PM or the other way around.
CALL 069FH Start the tape recorder motor.
CALL 0700H Stop the tape recorder motor.
CALL 0DDCH See page A-16 of the manual for more on this call.
CALL 0FD8H From the address in HL on, each address will be loaded with code 00H. The number of addresses that should be loaded with 00H, is stored in register B.

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.

CALL E090H Format the QD.
CALL E29BH Start the QD motor.
CALL E2E8H Stop the QD motor.
CALL E807H Load a program from tape and load it to address 1200H.
CALL E80AH Save the program located at 1200H to the tape.
CALL EFEFH Give the directory of the QD.

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.

10F0H At this address the program type of the loaded program is stored. If the value is 01H then the loaded program is an OBJ-file. If it reads 05H then we are dealing with an BTX-file and so on.
10F1H From this address up to address 1101H the program name is stored. The name must be terminated by the 0DH character.
1102H At this address and the subsequent 5 addresses are stored the length, the begin-address and the start-address respectively. For the QD the addresses are 1104H up to 1109H.
1171H The X-coordinate of the cursor.
1172H The Y-coordinate of the cursor.
1192H The code of the sign under the cursor position.
119BH Reserved for the clock. AM=0, PM=1.
119CH If the value is F0H then the internal clock is running.
119DH Indicates whether a beep is audible on key press or not. Value 00H indicates the beep is audible with each key press.
119EH Here the value of the music tempo is stored.
119FH Here the value of the tone length is stored.
11A0H Here the value of the octave number is stored.
11A1H This address has already been discussed.

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.

Previous page
Next page
Contents


Go to the top of this page Home

last updated July 8, 2004
Arjan Habing, Mark de Rover, Jeroen F. J. Laros, sharpmz@sharpmz.org