Beyond Basic - Part 2
Written By: Tony Cruise
First Published: MSX and Spectravideo Computer Forum Vol. 2 No. 11
In this section I will explain how you attach extra commands to ROM routines.
In MSX computers there are many Hook Jumps provided so that machine code programmers can attach their own routines to most of the basic ROM routines. Each Hook consists of five memory locations in RAM. When the computer is first switched on or reset, each of the locations contains the value 201. This is the decimal value for a RETURN statement in machine code. Each of the Hooks are jumped to at the start of each of the corresponding ROM routines, so you can insert or eliminate entirely each routine.
To use a Hook, all you have to do is insert your own commands into the five memory locations. This is usually a JUMP instruction to your machine code routine.
Here is an example program that uses the Hook HTIMI. This Hook is jumped to every 1/50th of a second.
Machine Code Program
D000 | 1 ORIGIN | ORG 0D000H | ||
2 ; | ||||
3 ; PROGRAM TO UPDATE AND DISPLAY A CLOCK | ||||
4 ; ON SCREEN 0 | ||||
5 ; | ||||
6 ; LABEL SETTINGS | ||||
7 HTIMI | EQU 0FD9FH | ; Hook Jump – Timer | ||
8 SCRMOD | EQU 0FCAFH | ; RAM Storage – Screen Mode | ||
9 SETWRT | EQU 0053H | ; ROM Routine – Set Video Write | ||
10 ; | ||||
D000 | 3EC3 | 11 START: | LD A,0C3H | ; Value for JUMP instruction |
D002 | 329FFD | 12 | LD (HTIMI),A | ; Load into Hook |
D005 | 210CD0 | 13 | LD HL,CUE | ; Address to jump to |
D008 | 22A0FD | 14 | LD (HTIMI+1),A | ; Load into Hook |
D00B | C9 | 15 | RET | |
16 ; | ||||
D00C | CD14D0 | 17 CUE: | CALL CLOCK | ; Call CLOCK routine |
D00F | F7 | 18 | RST 030H | ; Disk delay routine |
D010 | 879C77 | 19 | DEFB 087H,09CH,077H | ;-remove if you do not |
D013 | C9 | 20 | ; have a disk drive | |
21 ; | ||||
D014 | 161D0 | 22 CLOCK: | LD HL,STORE | ; Decrease counter |
D017 | 7E | 23 | LD A,(HL) | ; |
D018 | 3D | 24 | DEC A | ; |
D019 | 77 | 25 | LD (HL),A | ; |
D01A | C0 | 26 | RET NZ | ; Return if not ZERO |
D01B | 3E33 | 27 | LD A,51 | ; Set new counter |
D01D | 77 | 28 | LD (HL),A | ; |
D01E | 2162D0 | 29 | LD HL,CLKSTR | ; Update – seconds |
D021 | 0603 | 30 | LD B,3 | ; - minutes |
D023 | 7E | 31 CL1: | LD A,(HL) | ; - hours |
D024 | 3C | 32 | INC A | ; |
D025 | 27 | 33 | DAA | ; Decimal addition |
D026 | FE69 | 34 | CP 060H | ; |
D028 | 3003 | 35 | JR NC,CL2 | ; |
D02A | 77 | 36 | LD (HL),A | ; |
D02B | 1805 | 37 | JR PRTCLK | ; |
D02D | 3600 | 38 CL2: | LD (HL),0 | ; |
D02F | 23 | 39 | INC HL | ; |
D030 | 10F1 | 40 | DJNZ CL1 | ; |
D032 | 3AAFFC | 41 PRTCLK: | LD A,(SCRMOD) | ; Get screen mode |
D035 | 3D | 42 | DEC A | ; |
D036 | D0 | 43 | RET NC | ; Check for screen 0 |
D037 | 211F00 | 44 | LD HL,31 | ; |
D03A | CD5300 | 45 | CALL SETWRT | ; Set screen address |
D03D | 2164D0 | 46 | LD HL,CLKSTR+2 | ; Set pointer to clock |
D040 | 0603 | 47 | LD B,3 | ; Set counter |
D042 | 7E | 48 P1: | LD A,(HL) | ; |
D043 | 27 | 49 | DAA | ; |
D044 | F5 | 50 | PUSH AF | ; Save value |
D045 | CB3F | 51 | SRL A | ; Get right digit |
D047 | CB3F | 52 | SRL A | ; |
D049 | CB3F | 53 | SRL A | ; |
D04B | CB3F | 54 | SRL A | ; |
D04D | C630 | 55 | ADD A,48 | ; Change to ASCII |
D04F | D398 | 56 | OUT (098H),A | ; Send to screen |
D051 | F1 | 57 | POP AF | ; Return value |
D052 | E60F | 58 | AND 1111B | ; Get left digit |
D054 | C630 | 59 | ADD A,48 | ; Change to ASCII |
D056 | D398 | 60 | OUT (098H),A | ; Send to screen |
D058 | 3E3A | 61 | LD A,58 | ; Value for ‘:’ |
D05A | 2B | 62 | DEC HL | ; Update pointer |
D05B | 05 | 63 | DEC B | ; Update counter |
D05C | C8 | 64 | RET Z | ; Return if finished |
D05D | D398 | 65 | OUT (098H),A | ; Send ‘:’ to screen |
D05F | 18E1 | 66 | JR P1 | ; Go again |
67 ; | ||||
68 ; DATA STORAGE | ||||
D061 | 33 | 69 STORE:DEFB 51 | ||
D062 | 000000 | 70 CLKSTR:DEFB 0,0,0 | ||
D065 | 71 END: |
Basic Loader
10 CLS:CLEAR 200,&HCFFF:DEFINTA-Z:A=&HD000
20 READ A$:IF A$ <> “@” THEN POKE A, VAL(“&H”+A$):A=A+1:GOTO 20
30 PRINT” INSERT TAPE/DISK TO SAVE PROGRAM”
40 PRINT” AND PRESS ANY KEY”
50 A$=INPUT$(1):PRINT:PRINT “ SAVING ....”
60 BSAVE”CLOCK”,&HD000,A-1
100 DATA 3E,C3,32,9F,FD,21,0C,D0,21,0C,D0,22,A0,FD,C9,CD
110 DATA 14,D0,F7,87,9C,77,C9,21,61,D0,7E,3D,77,C0,3E,33
120 DATA 77,21,62,D0,06,03,7E,3C,27,FE,60,30,03,77,18,05
130 DATA 36,00,23,10,F1,3A,AF,FC,3D,D0,21,1F,00,CD,53,00
140 DATA 21,64,D0,06,03,7E,27,F5,CB,3F,CB,3F,CB,3F,CB,3F
150 DATA C6,30,D3,98,F1,E6,0F,C6,30,D3,98,3E,3A,2B,05,C8
160 DATA D3,98,18,E1,33,00,00,00,@
If you do not have a disk drive, change line 110 to -;
110 DATA 14,D0,00,00,00,00,C9,21,61,D0,7E,3D,77,C0,3E,33
This program displays a clock in the top right hand corner of the screen, but only when the computer is in screen mode zero. The first part of the program fills the Hook HTIMI with a jump command pointing to a routine called CUE. This routine calls all the things that are using this Hook. In this case, just the two things are being called, the clock routine, and the routine to turn the disk drive motor off after a certain period of time. If you are not using a disk drive, set the four memory locations to zero. In later articles, I will detail more routines that use this Hook.
The clock routine starts by decreasing the first counter, which was initially set to 51. This counter is to measure the passing of one second (The Hook is called every 1/50th of a second). Once a second has passed, the clock counters for the hour, minutes and seconds are updated. Then, if the screen mode is set to zero, the clock will be printed out.
In the next section, I will cover another of the Hook jumps called HGONE, and show how new statements can be added to your Basic programs.