Send a 2068 Message

Author(s): P. H. Skipper
Publication: SyncWare News
Pub Details: SyncWare News v3 n4 (Volume 3, Issue 4)
Date: Mar-Apr 1986
Pages: 22-23

As is well known, the 2068 computer will print something on the screen from a BASIC program through the use of a PRINT statement. If it is desired to print a message in the lower part of the screen one can use a statement such as:

1010 PRINT #1;AT 0,0;"Message"

It is also possible to print messages from machine code. After all, if the computer can send those nasty helpful little error messages, it must have a routine in the ROM somewhere for doing so.

This routine does exist and is located at address 073Fh (1855d). It is so important that it has been named. Ray Kingsley‘s HOT Z calls it “msgs”; the Timex ROM disassembly, “PUTMES”; and The Complete SPECTRUM ROM Disassembly, by Logan and O’Hara, “PO-MSG.” (In the SPECTRUM it is located at 0C0Ah.) But it doesn’t matter what it’s called. If it is called as a subroutine from machine code, then it will print a message in the lower part of the screen.

Before it can be called, however, two items of information must be provided so that it knows where to find the message it is to print. These items are loaded into the Z-80’s A register and the DE register-pair using machine code as follows:

1) LD A,sequence number. The “sequence number” is one less than the number of the desired message in a string of messages. Its range is from 0 through 255. For example, if a string contains ten messages and it is desired to print the fifth one, then load A with 04h. To print the first message in the string, or if there is only one message, load A with 00h.

2) LD DE,base address. The “base address” is the address at which the message or the string of messages starts. The term “start” is defined as the address of the initial non-printing character of the message (see below).

Furthermore, to enable the message-printing routine to do its job, the message string must be written in a certain way:

1) The code of the first character in the string must equal or exceed 80h (128d). This first character will not be printed, but the routine will seek it out and begin counting messages from that point. If the code of the first character is too low, it and the following characters will be ignored and the message-printing routine will run down the message string without printing until it does find a code equal to or greater than 80h. It will then start printing with the character which follows this code. It will also fail to properly count the messages in a string of messages. The address of this first character is defined as the “start” of the message, although the actual message begins one address later. If the address just before the actual message should happen to contain a code which is 80h or greater, such as C9h for RETURN, then this address can be used as the “start” address with the actual message following immediately thereafter.)

2) The code of the last character in each message must also equal or exceed 80h in order to tell the message-printing routine when it has come to the end of the message. This is achieved by adding 80h to the normal code of the desired last character of the message.

For example, suppose the last character is “?” with a code of 3Fh (63d). Adding 80h (128d) will give a code of BFh (191d) to be used as the last code of the message. The “?” will be printed, as desired. This “big” code will also be used by the message-counting procedure to select the requested message from within a string of messages.

As an illustration of the use of this routine, Figure 1 gives a BASIC program which will load the appropriate machine code to provide three messages, one of which can be selected by you. Type in the BASIC program, SAVE it and RUN it. It will ask you which message number is to be printed. 1, 2, or 3 are the only acceptable replies.

The decimal codes for the three messages are contained in Lines 330, 350, and 370, respectively. Codes for any other messages can be substituted, but Line 200 may then have to be modified to accomodate the length of the data to be loaded. Note that lines 1 and 2 evaporate when the program is first RUN.

Figure 1.

   1 REM "Send a Message"
2 GO TO 100
10 INPUT "Msg Nr? ";A
20 IF A<1 OR A>3 THEN GO TO 10
30 LET A=A-1
40 POKE 64001,A
50 RANDOMIZE USR 64000
60 GO TO 10
100 RESTORE
200 FOR i=64000 TO 64076
210 READ c
220 POKE i,c
230 NEXT i
300 REM MC Program:
310 DATA 62,0,17,11,250,205,63,7,195,47,14
320 REM Msg 1:
330 DATA 128,77,101,115,115,97,103,101,32,35,49,160
340 REM Msg 2:
350 DATA 77,101,115,115,97,103,101,32,35,50,160
360 REM Msg 3:
370 DATA 84,104,111,117,103,104,116,32,116,104,105,115,32,119,111,117,108,100,32,98,101,32,77,115,103,32,35,51,44,32,32,32,100,105,100,110,39,116,32,121,97,63,160
400 DELETE ,3
410 GO TO 10

If HOT Z is available (and it should be to anyone serious about machine code), then the code can be written directly, following the disassembly in Figure 2. A short BASIC program can then be modeled on Lines 10 through 60 of Figure 1 to demonstrate the code.

Figure 2.

ADDR HEXCODE LABEL MNEMONIC
============================
FA00 3E00 LD A,00
FA02 110BFA LD DE,FA0B
FA05 CD3F07 CALL msgs
FA08 C32F0E JP 0E2F
FA0B 80 ADD A,B
FA0C 4D LD C,L
FA0D 65 LD H,L
FA0E 73 LD (HL),E
FA0F 73 LD (HL),E
FA10 61 LD H,C
FA11 67 LD H,A
FA12 65 LD H,L
FA13 2023 JR NZ,FA38
FA15 31A04D LD SP,4DA0
FA18 65 LD H,L
FA19 73 LD (HL),E
FA1A 73 LD (HL),E
FA1B 61 LD H,C
FA1C 67 LD H,A
FA1D 65 LD H,L
FA1E 2023 JR NZ,FA43
FA20 32A054 LD (54A0),A
FA23 68 LD L,B
FA24 6F LD L,A
FA25 75 LD (HL),L
FA26 67 LD H,A
FA27 68 LD L,B
FA28 74 LD (HL),H
FA29 2074 JR NZ,FA9F
FA2B 68 LD L,B
FA2C 69 LD L,C
FA2D 73 LD (HL),E
FA2E 2077 JR NZ,FAA7
FA30 6F LD L,A
FA31 75 LD (HL),L
FA32 6C LD L,H
FA33 64 LD H,H
FA34 2062 JR NZ,FA98
FA36 65 LD H,L
FA37 204D JR NZ,FA86
FA39 73 LD (HL),E
FA3A 67 LD H,A
FA3B 2023 JR NZ,FA60
FA3D 33 INC SP
FA3E 2C INC L
FA3F 2020 JR NZ,FA61
FA41 2064 JR NZ,FAA7
FA43 69 LD L,C
FA44 64 LD H,H
FA45 6E LD L,(HL)
FA46 27 DAA
FA47 74 LD (HL),H
FA48 2079 JR NZ,FAC3
FA4A 61 LD H,C
FA4B 3F CCF
FA4C A0 AND B

In the machine-code program, the routine is ended at FA08h with a jump into the main execution loop of the ROM instead of using RET. This is because if RET is used then, upon returning, the usual “STOP” or “OK” message will immediately overwrite the message which was written by the machine-code routine.

The 2068 ROM is replete with messages to practice on. Some message-strings lie at:

3C89h Cassette messages.
0F65h Report (“Error”) messages.
0095h Token table (Use the routine at 0745h to print tokens instead of the message printing routine).

Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.