Beyond Basic - Part 3
Written By: Tony Cruise
First Published: Micro’s Gazette – Issue 000 (November/December 1988)
This issue I will explain about the Hook HGONE which can be used to add extra commands to your Basic programs. This eliminates the need to use USR statements which can be confusing to use for people who are not familiar with machine code. It also limits the number of parameters to one.
The Hook HGONE is called by the Basic ROM before each statement is processed. This allows you to add a routine that checks if the next Basic statement is one that you have added. For the ease of checking I will use the ‘[‘ character to identify any commands that we add.
The following routine creates two new Basic commands called [BANG and [ZAP. Each time you use these statements they will produce a sound, [BANG an explosion sound and [ZAP a laser firing sound. These new commands can be used in your Basic programs.
e.g.
10 PRINT “THIS IS A LASER...”:[ZAP
20 FOR A=1 TO 500:NEXT A
30 PRINT “THIS IS AN EXPLOSION...”:[BANGMachine Code Program
0000 | 1 ORIGIN | ; Example of Hook HGONE | ||
2 | ; | |||
D000 | 3 | ORG 0D000H | ||
4 | ; | |||
5 HGONE | EQU 0FF43H | ; Hook Jump – Basic handler | ||
6 | ; | |||
D000 | F3 | 7 START | DI | |
D001 | 210ED0 | 8 | LD HL,CHECK | ; Address to jump to |
D004 | 2244FF | 9 | LD (HGONE+1),HL | ; Load into Hook |
D007 | 3EC3 | 10 | LD A,0C3H | ; Value for JUMP |
D009 | 3243FF | 11 | LD (HGONE),A | ; Load into Hook |
D00C | FB | 12 | EI | |
D00D | C9 | 13 | RET | |
14 | ; | |||
D00E | FE5B | 15 | CHECK CP “[“ | ; Is next statement |
D010 | C0 | 16 | RET NZ | ; one of our commands |
D011 | F3 | 17 | DI | ; |
D012 | E5 | 18 | PUSH HL | ; Save pointer |
D013 | 1149D0 | 19 | LD DE,TABLE | ; Table of new commands |
D016 | 0600 | 20 | LD B,0 | ; Loop counter |
D018 | 23 | 21 LOOP1 | INC HL | ; Increment pointer |
D019 | 1A | 22 | LD A,(DE) | ; |
D01A | FE00 | 23 | CP 0 | ; |
D01C | 2002 | 24 | JR NZ,LOOP2 | ; End of Table? |
D01E | 1842 | 25 | JR EXIT | ; Yes – Back to Basic |
D020 | FE2E | 26 LOOP2 | CP “.” | ; End of statement |
D022 | 2015 | 27 | JR NZ,LOOP3 | ; No keep going |
D024 | 33 | 28 | INC SP | ; Get rid of old |
D025 | 33 | 29 | INC SP | ; pointer |
D026 | E5 | 30 | PUSH HL | ; save new pointer |
D027 | DD2153D0 | 31 | LD IX,JMPTBL | ; |
D02B | 1600 | 32 | LD D,0 | ; |
D02D | 58 | 33 | LD E,B | ; |
D02E | CB23 | 34 | SLA E | ; |
D030 | DD19 | 35 | ADD IX,DE | ; |
D032 | DD6E00 | 36 | LD L,(IX+0) | ; Calculate jump |
D035 | DD6601 | 37 | LD H,(IX+1) | ; address |
D038 | E9 | 38 | JP (HL) | ; |
D039 | 4E | 39 LOOP3 | LD C,(HL) | ; Get next character |
D03A | 13 | 40 | INC DE | ; Set DE for next loop |
D03B | B9 | 41 | CP C | ; Match? |
D03C | 28DA | 42 | JR Z,LOOP1 | ; Yes, go again |
D03E | 04 | 43 | INC B | ; Next statement |
D03F | E1 | 44 | POP HL | ; |
D040 | E5 | 45 | PUSH HL | ; Restore pointer |
D041 | 1A | 46 LOOP4 | LD A,(DE) | ; |
D042 | 13 | 47 | INC DE | ; Move DE to next |
D043 | FE2E | 48 | CP “.” | ; statement |
D045 | 28D1 | 49 | JR Z,LOOP1 | ; Loop again |
D047 | 18F8 | 50 | JR LOOP4 | ; |
51 | ; | |||
D049 | 42414E47 | 58 TABLE | DEFM “BANG.” | ; Statement table |
D04D | 2E | |||
D04E | 5A41592E | 59 | DEFM “ZAP.” | ; |
D052 | 00 | 60 | DEFB 0 | ; |
61 | ; | |||
D053 | 74D0 | 62 JMPTBL | DEFW BANG | ; Jump Table |
D055 | 8CD0 | 63 | DEFW ZAP | ; |
64 | ; | |||
D057 | 1A | 65 SOUND | LD A,(DE) | ; Get next value |
D058 | FEFF | 66 | CP 255 | ; End of List? |
D05A | C8 | 67 | RET Z | ; Yes – Return |
D05B | D3A0 | 68 | OUT (0A0H),A | ; Send value |
D05D | 13 | 69 | INC DE | ; Increment pointer |
D05E | FE07 | 70 | CP 7 | ; Is it register 7 |
D060 | 1A | 71 | LD A,(DE) | ; |
D061 | 2006 | 72 | JR NZ,SNDLP1 | ; No - Continue |
D063 | 47 | 73 | LD B,A | ; |
D064 | DBA2 | 74 | IN A,(0A2H) | ; Get current value |
D066 | E6C0 | 75 | AND 192 | ; |
D068 | 80 | 76 | ADD A,B | ; Combine values |
D069 | D3A1 | 77 SNDLP1 | OUT (0A1H),A | ; Send value |
D06B | 13 | 78 | INC DE | ; Increment pointer |
D06C | 18E9 | 79 | JR SOUND | ; |
80 | ; | |||
D06E | E1 | 81 EXIT | POP HL | ; Restore pointer |
D06F | 7E | 82 | LD A,(HL) | ; Restore A |
D070 | 33 | 83 | INC SP | ; Get rid of |
D071 | 33 | 84 | INC SP | ; Basic return |
D072 | FB | 85 | EI | ; |
D073 | C9 | 86 | RET | ; |
87 | ; | |||
D074 | 117CD0 | 88 BANG | LD DE,BANG1 | ; Set pointer |
D077 | CD57D0 | 89 | CALL SOUND | ; Call sound routine |
D07A | 18F2 | 90 | JR EXIT | ; Exit to Basic |
91 | ; | |||
D07C | 09100208 | 92 BANG1 | DEFB 9,16,2,8,3,5,7,40 | |
D080 | 03050728 | |||
D084 | 06140C0A | 93 | DEFB 6,20,12,10,13,0,255,255 | |
D088 | 0D00FFFF | |||
94 | ; | |||
D08C | 1194D0 | 95 ZAP | LD DE,ZAP1 | ; Set pointer |
D08F | CD57D0 | 96 | CALL SOUND | ; Call sound routine |
D092 | 18DA | 97 | JR EXIT | ; Exit to Basic |
98 | ; | |||
D094 | 091002C8 | 99 ZAP1 | DEFB 9,16,2,200,3,0,12,6 | |
D098 | 03000C08 | |||
D09C | 07380D04 | 100 | DEFB 7,56,13,4,255,255 | |
D0A0 | FFFF | |||
D0A2 | 101 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”CHECK”,&HD000,A-1
100 DATA F3,21,0E,D0,22,44,FF,3E,C3,32,43,FF,FB,C9,FE,5B
110 DATA C0,F3,E5,11,49,D0,06,00,23,1A,FE,00,20,02,18,4E
120 DATA FE,2E,20,15,33,33,E5,DD,21,53,D0,16,00,58,CB,23
130 DATA DD,19,DD,6E,00,DD,66,01,E9,4E,13,B9,28,DA,04,E1
140 DATA E5,1A,13,FE,2E,28,D1,18,F8,42,41,4E,47,2E,5A,41
150 DATA 50,2E,00,74,D0,8C,D0,1A,FE,FF,C8,D3,A0,13,FE,07
160 DATA 1A,20,06,47,DB,A2,E6,C0,80,D3,A1,13,18,E9,E1,7E
170 DATA 33,33,FB,C9,11,7C,D0,CD,57,D0,18,F2,09,10,02,08
180 DATA 03,05,07,28,06,14,0C,0A,0D,00,FF,FF,11,94,D0,CD
190 DATA 57,D0,18,DA,09,10,02,C8,03,00,0C,06,07,38,0D,04
200 DATA FF,FF,@
Next issue I will cover how to read command line variables and start on the new commands.