0000- 5 0000- 6 ; ***************************************************************************** 0000- 7 ; MK14 Snake v1 8th Dec 2023 0000- 8 ; Developed by Ian Reynolds for the SBASM 8060 assembler 0000- 9 ; 0000- 10 ; Requires continuous memory from $0200 to $07FF and base RAM at $0F00 0000- 11 ; Program operates in character mode 0000- 12 ; 0000- 13 ; $200-$3FF VDU RAM 0000- 14 ; $400-$4FF Snake body segment array 0000- 15 ; $500-$7FE Program 0000- 16 ; $7FF PiView control byte 0000- 17 ; $F00-$F0F SCIOS Variables 0000- 18 ; $F10-$F27 Game Variables 0000- 19 ; $F28-$FF7 Game subroutines 0000- 20 ; $FF8-$FFF SCIOS variables (inc. fast loader) 0000- 21 ; 0000- 22 ; Keys: 1 to turn left 0000- 23 ; 3 to turn right 0000- 24 ; GO to start game 0000- 25 ; 0000- 26 ; The snake can have 126 segments max. If you achieve that then you win!! 0000- 27 ; 0000- 28 ; Visit the UK Vintage Radio Forums, Vintage Computers, for updates 0000- 29 ; 0000- 30 ; https://www.vintage-radio.net/ My username is Realtime 0000- 31 ; ***************************************************************************** 0000- 32 0000- 33 ;-------------------------------------------------------------------- 0000- 34 ;Game Constants 0200- 35 DISP_CH .EQ $0200 ; Start of VDU frame store for characters 0400- 36 SNAKE_ARRAY .EQ $0400 ; 256 bytes allows for 127 snake elements 0500- 37 PROG .EQ $0500 ; Start of program memory 0F10- 38 VAR .EQ $0F10 ; Variables storage area ($18 bytes) 07FF- 39 PIVIEW_MODE .EQ $07FF ; PiView VDU mode control address 0800- 40 INS8154 .EQ $0800 ; MK14 I/O chip base address 0D00- 41 LED_DISP .EQ $0D00 ; MK14 LED display and keypad 0000- 42 00FF- 43 CELL_EMPTY .EQ $FF ; unoccupied cell in the snake array 0020- 44 CHAR_SPACE .EQ $20 ; ' ' 000F- 45 CHAR_BODY .EQ $0F ; 'O' 003C- 46 CHAR_HEAD_R .EQ $3C ; '<' (cannot be $00) 003E- 47 CHAR_HEAD_L .EQ $3E ; '>' (cannot be $00) 0016- 48 CHAR_HEAD_U .EQ $16 ; 'V' (cannot be $00) 001E- 49 CHAR_HEAD_D .EQ $1E ; '^' (cannot be $00) 002A- 50 CHAR_APPLE .EQ $2A ; '*' (cannot be $00) 0021- 51 PORT_B .EQ $21 ; INS8154 Port B Output register write address 02E0- 52 MESSAGE .EQ $02E0 ; Address at which to display end of game message 0380- 53 MESSAGE2 .EQ $0380 ; Address at which the "PRESS GO" mesaage is displayed 007D- 54 SEGMENTS .EQ $7D ; Max number of snake segments allowed 0030- 55 GAME_DELAY .EQ $30 ; Sets the loop speed 0000- 56 0000- 57 ; Game Variables 0000- 58 COUNT1 .EQ $00 ; When not zero Game has ended 0001- 59 P3H_TMP .EQ $01 ; Temporary store for P3 0002- 60 P3L_TMP .EQ $02 ; Temporary store for P3 0003- 61 X_COORD .EQ $03 ; x position of snake segment 0004- 62 Y_COORD .EQ $04 ; y position of snake segment 0005- 63 SNAKE_LEN .EQ $05 ; Current length of the snake 0006- 64 CHAR_HEAD .EQ $06 ; Head character to be displayed 0007- 65 KEY_LATCH .EQ $07 ; 00= no key pressed (used for key debounce) 0008- 66 APPLE .EQ $08 ; Non zero indicates an apple is on screen 0009- 67 GAME_OVER .EQ $09 ; When zero Game has ended 000A- 68 DIR .EQ $0A ; Direction vector 000B- 69 HEAD .EQ $0B ; Indicates if Head character is being output 000C- 70 P3H_WIPE .EQ $0C ; Last position of tail end to be wiped out when snake moves 000D- 71 P3L_WIPE .EQ $0D ; 000E- 72 SEED .EQ $0E ; Pseudo random number gen for Apple position 000F- 73 X_BYTE .EQ $0F ; Local copy of snake segment X data 0010- 74 Y_BYTE .EQ $10 ; Local copy of snake segment Y data 0011- 75 SCORE_H .EQ $11 ; BCD counter high byte 0012- 76 SCORE_L .EQ $12 ; BCD counter low byte 0013- 77 YOU_WIN .EQ $13 ; 00 indicates you have exceeded the max number of body segments and have won the game 0000- 78 0000- 79 ;-------------------------------------------------------------------- 0000- 80 ; Splash Screen during programme load 0200- 81 .OR DISP_CH 0200-20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 82 .DB $20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20 ; 0210-20 20 20 20 20 20 2C 2D 2E 20 20 20 20 20 20 20 83 .DB $20,$20,$20,$20,$20,$20,$2C,$2D,$2E,$20,$20,$20,$20,$20,$20,$20 ; 0220-20 20 20 20 2C 2D 20 20 20 2D 2E 20 20 20 20 20 84 .DB $20,$20,$20,$20,$2C,$2D,$20,$20,$20,$2D,$2E,$20,$20,$20,$20,$20 ; ,-----. 0230-20 20 20 2C 20 20 20 20 20 20 20 2E 20 20 20 20 85 .DB $20,$20,$20,$2C,$20,$20,$20,$20,$20,$20,$20,$2E,$20,$20,$20,$20 ; , . 0240-20 20 2F 20 1E 20 20 20 20 20 1E 20 1C 20 20 20 86 .DB $20,$20,$2F,$20,$1E,$20,$20,$20,$20,$20,$1E,$20,$1C,$20,$20,$20 ; / ^ ^ \ 0250-20 2C 2D 28 30 29 2D 20 2D 28 30 29 2D 2E 20 20 87 .DB $20,$2C,$2D,$28,$30,$29,$2D,$20,$2D,$28,$30,$29,$2D,$2E,$20,$20 ; ,-(0)- -(0)-. 0260-20 21 20 20 21 20 20 20 20 20 21 20 20 21 20 20 88 .DB $20,$21,$20,$20,$21,$20,$20,$20,$20,$20,$21,$20,$20,$21,$20,$20 ; ! ! ! ! 0270-20 1C 1F 20 20 20 20 20 20 20 20 20 1F 2F 20 20 89 .DB $20,$1C,$1F,$20,$20,$20,$20,$20,$20,$20,$20,$20,$1F,$2F,$20,$20 ; \_ _/ 0280-20 20 21 20 20 20 20 20 20 20 20 20 21 20 20 20 90 .DB $20,$20,$21,$20,$20,$20,$20,$20,$20,$20,$20,$20,$21,$20,$20,$20 ; ! ! 0290-20 20 1C 20 20 20 0F 20 0F 20 20 20 2F 20 20 20 91 .DB $20,$20,$1C,$20,$20,$20,$0F,$20,$0F,$20,$20,$20,$2F,$20,$20,$20 ; \ O O / 02A0-20 20 20 1C 1F 1F 20 20 20 1F 1F 2F 20 20 20 20 92 .DB $20,$20,$20,$1C,$1F,$1F,$20,$20,$20,$1F,$1F,$2F,$20,$20,$20,$20 ; \__ __/ 02B0-20 20 20 20 21 20 20 20 20 20 21 20 20 20 20 20 93 .DB $20,$20,$20,$20,$21,$20,$20,$20,$20,$20,$21,$20,$20,$20,$20,$20 ; ! ! 02C0-20 20 20 20 1C 20 1C 20 2F 20 2F 20 20 20 20 20 94 .DB $20,$20,$20,$20,$1C,$20,$1C,$20,$2F,$20,$2F,$20,$20,$20,$20,$20 ; \ \ / / 02D0-20 20 20 20 20 1C 20 21 20 2F 20 20 20 20 20 20 95 .DB $20,$20,$20,$20,$20,$1C,$20,$21,$20,$2F,$20,$20,$20,$20,$20,$20 ; \ ! / 02E0-20 20 20 20 20 20 20 21 20 20 20 20 20 20 20 20 96 .DB $20,$20,$20,$20,$20,$20,$20,$21,$20,$20,$20,$20,$20,$20,$20,$20 ; V!V 02F0-20 20 20 20 20 20 16 20 16 20 20 20 20 20 20 20 97 .DB $20,$20,$20,$20,$20,$20,$16,$20,$16,$20,$20,$20,$20,$20,$20,$20 ; 0300-20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 98 .DB $20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20 ; 0310-20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 99 .DB $20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20 ; 0320-20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 100 .DB $20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20 ; 0330-20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 101 .DB $20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20 ; 0340-20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 102 .DB $20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20 ; 0350-20 0D 0B 31 34 20 13 0E 01 0B 05 20 16 31 20 20 103 .DB $20,$0D,$0B,$31,$34,$20,$13,$0E,$01,$0B,$05,$20,$16,$31,$20,$20 ; MK14 SNAKE V1 0360-20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 104 .DB $20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20 ; 0370-20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 105 .DB $20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20 ; 0380-20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 106 .DB $20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20 ; 0390-20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 107 .DB $20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20 ; 03A0-20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 108 .DB $20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20 ; 03B0-20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 109 .DB $20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20 ; 03C0-20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 110 .DB $20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20 ; 03D0-20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 111 .DB $20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20 ; 03E0-20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 112 .DB $20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20 ; 03F0-20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 113 .DB $20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20 ; 0400- 114 0400- 115 ; Game entry point 0500- 116 .OR PROG 0500- 117 ENTRY: 0500- 118 ; Set up INS8154 0500- 119 ; The following is for Realtime's 'Realview' MK14 VDU, using Port B for the control byte 0500- 120 ; Other VDU's may require a different set up byte 0500- 121 0500-C4 08 122 ( 10) LDI INS8154/256 ; Base address of I/O device 0502-37 123 ( 8) XPAH P3 0503-C4 00 124 ( 10) LDI INS8154\256 0505-33 125 ( 8) XPAL P3 0506- 126 ; LDI $08 0506- 127 ; ST PORT_B+2(P3) ; Port B output definition register - bit3 (VDUOFF) as output, all others as inputs 0506- 128 ; LDI $FF ; Set VDU control bits - Enable VDU only. All other controls are via RealView DIP switches 0506- 129 ; ST Port_B(P3) ; Set port B outputs (Port B is always in basic I/O mode) 0506- 130 ; 0506- 131 ; Port B bit 7 = PS3 - set to '0' \ 0506- 132 ; Port B bit 6 = PS1 - set to '1' \ Sets the video RAM address to $0200 0506- 133 ; Port B bit 5 = PS2 - set to '1' / However, note that PS1 must not be physically connected 0506- 134 ; Port B bit 4 = PS4 - set to '0' / to the VDU card as this line is controlled by the TOPPAGE signal 0506- 135 ; Port B bit 3 = VDUOFF - set to '0' for VDU on 0506- 136 ; Port B bit 2 = Graphics/nCharacters - set to '1' to allow TOPPAGE to control the mixed graphic/character display 0506- 137 ; Port B bit 1 = REVPAGES - set to '0' for $200 at top of the screen ($300 at bottom) 0506- 138 ; Port B bit 0 = INVERT - set to '0' for white video on black background 0506- 139 0506- 140 ; Set PiView mode: $00 = Character mode 0506-C4 00 141 ( 10) LDI $00 0508-CB FF 142 ( 18) ST -1(P3) ; Store at $07FF 050A-C4 0F 143 ( 10) LDI VAR/256 050C-36 144 ( 8) XPAH P2 050D-C4 10 145 ( 10) LDI VAR\256 050F-32 146 ( 8) XPAL P2 ; P2 is the games variables pointer 0510-C4 00 147 ( 10) LDI $00 0512-CA 09 148 ( 18) ST GAME_OVER(P2) ; Force game over so that keyboad scan looks only for the GO key 0514-C4 06 37 C4 27 33 3F 149 JS P3,KBD ; wait for the GO key to be pressed to start the game 051B- 150 051B- 151 GAME_START: 051B-C4 07 37 C4 22 33 3F 152 JS P3,CLS ; Clear screen and initialise the snake array 0522- 153 0522- 154 ;-------------------------------------------------------------------- 0522- 155 ; Initialise Variables 0522- 156 0522-C4 05 157 ( 10) LDI $05 0524-CA 09 158 ( 18) ST GAME_OVER(P2) ; $00 is game over 0526-CA 05 159 ( 18) ST SNAKE_LEN(P2) ; Number of segments in snake's body 0528-CA 13 160 ( 18) ST YOU_WIN(P2) ; Any non-zero value means you haven't won yet 052A- 161 052A-C4 3C 162 ( 10) LDI CHAR_HEAD_R 052C-CA 06 163 ( 18) ST CHAR_HEAD(P2) ; Initial head direction is right 052E-C4 00 164 ( 10) LDI $00 0530-CA 07 165 ( 18) ST KEY_LATCH(P2) ; Indicate no key pressed yet 0532-CA 08 166 ( 18) ST APPLE(P2) ; No apple on screen 0534-C2 0E 167 ( 18) LD SEED(P2) ; ensure random number seed is non-zero 0536-9C 02 168 (9/11) JNZ START 0538-AA 0E 169 ( 22) ILD SEED(P2) 053A- 170 053A- 171 ;============================================================================= 053A- 172 ; Main loop 053A- 173 ; Interpret array to generate display 053A- 174 ; Before head byte is output look ahead to see if there is an obstacle 053A- 175 START: 053A- 176 053A- 177 GEN_DISP: 053A-C4 00 178 ( 10) LDI $00 053C-CA 0B 179 ( 18) ST HEAD(P2) ; 0 indicates current position is the head 053E-C4 04 180 ( 10) LDI SNAKE_ARRAY/256 0540-35 181 ( 8) XPAH P1 0541-C4 00 182 ( 10) LDI SNAKE_ARRAY\256 0543-31 183 ( 8) XPAL P1 ; P1 now contains start address of snake array 0544-C2 05 184 ( 18) LD SNAKE_LEN(P2) 0546-CA 00 185 ( 18) ST COUNT1(P2) 0548- 186 GEN: 0548-C1 00 187 ( 18) LD (P1) ; Get X byte of array entry 054A-CA 0F 188 ( 18) ST X_BYTE(P2) 054C-C1 01 189 ( 18) LD 1(P1) 054E-CA 10 190 ( 18) ST Y_BYTE(P2) 0550-D4 1F 191 ( 10) ANI $1F ; Mask off Y co-ordinate 0552-CA 04 192 ( 18) ST Y_COORD(P2) 0554-C2 0F 193 ( 18) LD X_BYTE(P2) 0556-D4 0F 194 ( 10) ANI $0F ; Mask off X co-ordinate 0558-CA 03 195 ( 18) ST X_COORD(P2) 055A-02 196 ( 5) CCL 055B-C2 04 197 ( 18) LD Y_COORD(P2) 055D-1F 198 ( 5) RRL 055E-1F 199 ( 5) RRL 055F-1F 200 ( 5) RRL 0560-1F 201 ( 5) RRL 0561-1F 202 ( 5) RRL 0562-01 203 ( 7) XAE ; E=16*Y_COORD 0563-1F 204 ( 5) RRL ; rotate carry bit into bit 7 0564-94 04 205 (9/11) JP G1 ; if +ve then location is in upper display page 0566-C4 03 206 ( 10) LDI DISP_CH/256+1 ; if -ve then location is in lower display page 0568-90 02 207 ( 11) JMP G2 056A- 208 G1: 056A-C4 02 209 ( 10) LDI DISP_CH/256 056C- 210 G2: 056C-37 211 ( 8) XPAH P3 056D-02 212 ( 5) CCL 056E-40 213 ( 6) LDE ; retreive offset 056F-F2 03 214 ( 19) ADD X_COORD(P2) ; add X co-ordinate 0571-33 215 ( 8) XPAL P3 ; P3 now points to correct position in display RAM 0572- 216 ; Check if next move is into a free cell 0572-C2 0B 217 ( 18) LD HEAD(P2) ; if HEAD is 00 then check if obstacle before updating and outputing CHAR_HEAD 0574-9C 7A 218 (9/11) JNZ G3 0576- 219 ; Head clash check 0576-C3 00 220 ( 18) LD (P3) ; get character at display position 0578-E4 20 221 ( 10) XRI CHAR_SPACE ; is it an empty space 057A-98 6E 222 (9/11) JZ HEAD_OUT ; If yes then display head as normal 057C-C3 00 223 ( 18) LD (P3) ; cell is occupied so 057E-E4 2A 224 ( 10) XRI CHAR_APPLE ; is it an Apple? 0580-98 09 225 (9/11) JZ CONT ; if yes then increment snake length. If not then it's game over 0582- 226 G_END: 0582-C4 0F 37 C4 27 33 3F 227 JS P3,GAME_END 0589-90 5D 228 ( 11) JMP KBD_STEP 058B- 229 CONT: 058B-C2 05 230 ( 18) LD SNAKE_LEN(P2) 058D-E4 7D 231 ( 10) XRI SEGMENTS ; Max number of snake segments allowed 058F-9C 06 232 (9/11) JNZ INC_SNAKE_LEN 0591-CA 13 233 ( 18) ST YOU_WIN(P2) ; 00 indicates you win by reaching 126 segments long 0593-90 ED 234 ( 11) JMP G_END 0595- 235 0595- 236 GEN_STEP: 0595-90 B1 237 ( 11) JMP GEN ; This is a stepping stone 0597- 238 ;-------------------------------------------------------------------- 0597- 239 ; Increment snake length and place new entry in array 0597- 240 ; 0597- 241 INC_SNAKE_LEN: 0597-C4 00 242 ( 10) LDI $00 0599-CA 08 243 ( 18) ST APPLE(P2) ; Indicate no apple on screen 059B- 244 ; increase snake length 059B-C2 05 245 ( 18) LD SNAKE_LEN(P2) 059D-02 246 ( 5) CCL 059E-F2 05 247 ( 19) ADD SNAKE_LEN(P2) ; Point to next free array position (=2xSNAKE_LEN) 05A0-31 248 ( 8) XPAL P1 05A1-C4 04 249 ( 10) LDI SNAKE_ARRAY/256 05A3-35 250 ( 8) XPAH P1 05A4-C1 FE 251 ( 18) LD -2(P1) ; Duplicate last entry in next position 05A6-C9 00 252 ( 18) ST (P1) 05A8-C1 FF 253 ( 18) LD -1(P1) 05AA-C9 01 254 ( 18) ST 1(P1) 05AC-D4 C0 255 ( 10) ANI $C0 ; update new entry position based on direction bits 05AE-CA 0A 256 ( 18) ST DIR(P2) 05B0-9C 08 257 (9/11) JNZ DIR_LEFT_T 05B2- 258 DIR_RIGHT: ; dir bits = 00 05B2-B9 00 259 ( 22) DLD (P1) 05B4-D4 0F 260 ( 10) ANI $0F ; if X <0 the roll back to zero 05B6-C9 00 261 ( 18) ST (P1) 05B8-90 22 262 ( 11) JMP DIR_END 05BA- 263 DIR_LEFT_T: 05BA-E4 80 264 ( 10) XRI $80 05BC-9C 08 265 (9/11) JNZ DIR_UP_T 05BE- 266 DIR_LEFT: ; dir bits = 10 05BE-A9 00 267 ( 22) ILD (P1) 05C0-D4 0F 268 ( 10) ANI $0F 05C2-C9 00 269 ( 18) ST (P1) 05C4-90 16 270 ( 11) JMP DIR_END 05C6- 271 DIR_UP_T: 05C6-E4 C0 272 ( 10) XRI $C0 05C8-9C 0A 273 (9/11) JNZ DIR_DOWN 05CA- 274 DIR_UP: ; dir bits = 01 05CA-A9 01 275 ( 22) ILD 1(P1) 05CC-D4 1F 276 ( 10) ANI $1F 05CE-DA 0A 277 ( 18) OR DIR(P2) 05D0-C9 01 278 ( 18) ST 1(P1) 05D2-90 08 279 ( 11) JMP DIR_END 05D4- 280 DIR_DOWN: ; dir bits must be 11 05D4-B9 01 281 ( 22) DLD 1(P1) 05D6-D4 1F 282 ( 10) ANI $1F 05D8-DA 0A 283 ( 18) OR DIR(P2) 05DA-C9 01 284 ( 18) ST 1(P1) 05DC- 285 DIR_END: 05DC-AA 05 286 ( 22) ILD SNAKE_LEN(P2) 05DE-C4 04 287 ( 10) LDI SNAKE_ARRAY/256 05E0-35 288 ( 8) XPAH P1 05E1-C4 00 289 ( 10) LDI SNAKE_ARRAY\256 05E3-31 290 ( 8) XPAL P1 05E4-90 04 291 ( 11) JMP HEAD_OUT 05E6- 292 05E6- 293 ;************************************************** 05E6- 294 DISP_END_STEP: ; * 05E6-90 12 295 ( 11) JMP DISP_END ; this is a stepping stone * 05E8- 296 KBD_STEP: ; * 05E8-90 3E 297 ( 11) JMP KBD ; this is a stepping stone * 05EA- 298 ;************************************************** 05EA- 299 05EA- 300 HEAD_OUT: 05EA-C2 06 301 ( 18) LD CHAR_HEAD(P2) 05EC-CA 0B 302 ( 18) ST HEAD(P2) ; set head flag to non-zero 05EE-90 02 303 ( 11) JMP G4 05F0- 304 G3: 05F0-C4 0F 305 ( 10) LDI CHAR_BODY ; else output body character 05F2- 306 G4: 05F2-CB 00 307 ( 18) ST (P3) ; store snake character on screen 05F4- 308 05F4-C5 02 309 ( 18) LD @2(P1) ; move P1 onto next entry in the snake array 05F6-BA 00 310 ( 22) DLD COUNT1(P2) 05F8-9C 9B 311 (9/11) JNZ GEN_STEP ; Jump to display generation loop via stepping stone 05FA- 312 DISP_END: 05FA- 313 ; P3 holds the screen address of the last snake segment. Copy this 05FA-C2 0C 314 ( 18) LD P3H_WIPE(P2) 05FC-37 315 ( 8) XPAH P3 05FD-CA 0C 316 ( 18) ST P3H_WIPE(P2) 05FF-C2 0D 317 ( 18) LD P3L_WIPE(P2) 0601-33 318 ( 8) XPAL P3 0602-CA 0D 319 ( 18) ST P3L_WIPE(P2) ; P3_WIPE now holds the last screen write 0604- 320 ; P3 holds the previous last position 0604-C4 20 321 ( 10) LDI CHAR_SPACE 0606-CB 00 322 ( 18) ST (P3) ; Remove old snake tail from screen 0608- 323 0608- 324 ; ***************************************************************************** 0608- 325 ; Move Snake in the array 0608-C2 05 326 ( 18) LD SNAKE_LEN(P2) 060A-CA 00 327 ( 18) ST COUNT1(P2) 060C-02 328 ( 5) CCL 060D-F2 05 329 ( 19) ADD SNAKE_LEN(P2) 060F-31 330 ( 8) XPAL P1 ; Point P1 to end of snake array +1 0610-C5 FF 331 ( 18) LD @-1(P1) ; P1 now pointing to end of array 0612-BA 00 332 ( 22) DLD COUNT1(P2) ; want to process 1 less than length (ignore head) 0614- 333 0614- 334 AGAIN: 0614- 335 ; Copy direction array(n-1) to direction array(n) 0614-C1 FE 336 ( 18) LD -2(P1) ; copy next position direction to current position 0616-D4 C0 337 ( 10) ANI $C0 ; Mask off direction bits 0618-CA 0A 338 ( 18) ST DIR(P2) 061A-01 339 ( 7) XAE 061B-C1 00 340 ( 18) LD (P1) 061D-D4 1F 341 ( 10) ANI $1F ; Mask off Y co-ordinate 061F-58 342 ( 6) ORE ; combine with new direction 0620-C9 00 343 ( 18) ST (P1) 0622-C5 FE 344 ( 18) LD @-2(P1) ; Move P1 to next ENTRY 0624-BA 00 345 ( 22) DLD COUNT1(P2) 0626-9C EC 346 (9/11) JNZ AGAIN ; Note: The head direction doesn't get changed 0628- 347 0628- 348 ;================================================ 0628- 349 ; scan keyboard for 1,3, GO 0628- 350 ; Change snake head direction when 1 or 3 is pressed 0628- 351 ; On entry to this routine P1 is pointing to Array+1 0628- 352 ;================================================ 0628- 353 KBD: 0628-C5 FF 354 ( 18) LD @-$01(P1) ; P1 now points to beginning of array 062A-C4 0D 355 ( 10) LDI LED_DISP/256 062C-37 356 ( 8) XPAH P3 062D-C4 00 357 ( 10) LDI LED_DISP\256 062F-33 358 ( 8) XPAL P3 ; P3 points to MK14 display/keyboard 0630-C4 00 359 ( 10) LDI $00 0632-CB 00 360 ( 18) ST (P3) ; Set all display segments to off 0634-C2 09 361 ( 18) LD GAME_OVER(P2) ; If Game over flag is zero then only test GO key 0636-98 2C 362 (9/11) JZ TEST_GO 0638- 363 TEST_NO_KEY: 0638-C2 07 364 ( 18) LD KEY_LATCH(P2) 063A-98 0A 365 (9/11) JZ TEST_1 063C-C3 01 366 ( 18) LD 1(P3) 063E-E3 03 367 ( 18) XOR 3(P3) 0640-9C 5A 368 (9/11) JNZ NO_KEY ; if both results are the same then there is no key being pressed 0642-C4 00 369 ( 10) LDI $00 0644-CA 07 370 ( 18) ST KEY_LATCH(P2) ; Reset the key debounce flag 0646- 371 TEST_1: ; Rotate left 0646-C3 01 372 ( 18) LD 1(P3) ; read keypad $0D01 (Key 1) 0648-DC 0F 373 ( 10) ORI $0F ; Mask top 4 bits 064A-E4 7F 374 ( 10) XRI $7F ; Result will be zero if key pressed 064C-9C 07 375 (9/11) JNZ TEST_3 064E- 376 ; change snake direction left rotate 064E-C1 01 377 ( 18) LD 1(P1) ; Get Y byte of head entry 0650-02 378 ( 5) CCL 0651-F4 40 379 ( 11) ADI $40 ; changing direction in a left rotation simply needs the direction bits to be incremented 0653-90 1E 380 ( 11) JMP END_KEYSCAN 0655- 381 TEST_3: ; Rotate right 0655-C3 03 382 ( 18) LD 3(P3) ; read keypad $0D03 (Key 3) 0657-DC 0F 383 ( 10) ORI $0F ; Mask top 4 bits 0659-E4 7F 384 ( 10) XRI $7F ; Result will be zero if key pressed 065B-9C 3F 385 (9/11) JNZ NO_KEY 065D- 386 ; change snake direction right rotate 065D-C1 01 387 ( 18) LD 1(P1) ; Get Y byte of head entry 065F-02 388 ( 5) CCL 0660-F4 C0 389 ( 11) ADI $C0 ; changing direction in a left rotation simply needs the direction bits to be decremented 0662-90 0F 390 ( 11) JMP END_KEYSCAN 0664- 391 TEST_GO: ; New Game 0664-C3 02 392 ( 18) LD 2(P3) ; read keypad $0D02 (Key GO) 0666-DC 0F 393 ( 10) ORI $0F ; Mask top 4 bits 0668-E4 DF 394 ( 10) XRI $DF ; Result will be zero if key pressed 066A-9C F8 395 (9/11) JNZ TEST_GO 066C-C4 05 37 C4 1A 33 3F 396 JS P3,GAME_START ; Use JS as a long jump to restart the game 0673- 397 END_KEYSCAN: 0673-D4 C0 398 ( 10) ANI $C0 ; constrain to 2 bits (ignore any carry over) 0675-01 399 ( 7) XAE ; Temp store direction new bits 0676-C1 01 400 ( 18) LD 1(P1) ; Get Y byte of head entry 0678-D4 1F 401 ( 10) ANI $1F ; mask Y co-ordinate 067A-58 402 ( 6) ORE ; Include direction bits 067B-C9 01 403 ( 18) ST 1(P1) ; Update head Y byte 067D-C4 FF 404 ( 10) LDI $FF ; Indicate key has been pressed 067F-CA 07 405 ( 18) ST KEY_LATCH(P2) 0681- 406 0681- 407 ;******************************************************************************** 0681- 408 ; Set head character according to the change of direction 0681- 409 0681-40 410 ( 6) LDE ; E already holds the new direction bits 0682- 411 TEST_R: 0682-9C 04 412 (9/11) JNZ TEST_L 0684-C4 3C 413 ( 10) LDI CHAR_HEAD_R ; if 00 then new direction is right 0686-90 12 414 ( 11) JMP SET_HEAD 0688- 415 TEST_L: 0688-E4 80 416 ( 10) XRI $80 068A-9C 04 417 (9/11) JNZ TEST_U 068C-C4 3E 418 ( 10) LDI CHAR_HEAD_L ; if 80 then new direction is left 068E-90 0A 419 ( 11) JMP SET_HEAD 0690- 420 TEST_U: 0690-E4 C0 421 ( 10) XRI $C0 0692-9C 04 422 (9/11) JNZ TEST_D 0694-C4 16 423 ( 10) LDI CHAR_HEAD_U ; if 40 then new direction is up 0696-90 02 424 ( 11) JMP SET_HEAD 0698- 425 TEST_D: 0698-C4 1E 426 ( 10) LDI CHAR_HEAD_D ; else direction must be down 069A- 427 SET_HEAD: 069A-CA 06 428 ( 18) ST CHAR_HEAD(P2) ; store new head character ready for next display loop 069C- 429 NO_KEY: 069C- 430 069C- 431 ;******************************************************************************** 069C- 432 ; Update co-ordinates of each snake segment according to direction bits 069C- 433 ; On entry P1 is pointing to start of array 069C- 434 069C-C2 05 435 ( 18) LD SNAKE_LEN(P2) 069E-CA 00 436 ( 18) ST COUNT1(P2) 06A0- 437 TEST_DIR: 06A0-C1 01 438 ( 18) LD 1(P1) ; Get Y Byte 06A2-D4 C0 439 ( 10) ANI $C0 ; mask off direction bits 06A4-CA 0A 440 ( 18) ST DIR(P2) 06A6-9C 08 441 (9/11) JNZ TEST_LEFT 06A8- 442 MOVE_RIGHT: ; dir bits = 00 06A8-A9 00 443 ( 22) ILD (P1) 06AA-D4 0F 444 ( 10) ANI $0F ; if X >15 the roll back to zero 06AC-C9 00 445 ( 18) ST (P1) 06AE-90 22 446 ( 11) JMP MOVE_END 06B0- 447 TEST_LEFT: 06B0-E4 80 448 ( 10) XRI $80 06B2-9C 08 449 (9/11) JNZ TEST_UP 06B4- 450 MOVE_LEFT: ; dir bits = 10 06B4-B9 00 451 ( 22) DLD (P1) 06B6-D4 0F 452 ( 10) ANI $0F 06B8-C9 00 453 ( 18) ST (P1) 06BA-90 16 454 ( 11) JMP MOVE_END 06BC- 455 TEST_UP: 06BC-E4 C0 456 ( 10) XRI $C0 06BE-9C 0A 457 (9/11) JNZ MOVE_DOWN 06C0- 458 MOVE_UP: ; dir bits = 01 06C0-B9 01 459 ( 22) DLD 1(P1) 06C2-D4 1F 460 ( 10) ANI $1F 06C4-DA 0A 461 ( 18) OR DIR(P2) 06C6-C9 01 462 ( 18) ST 1(P1) 06C8-90 08 463 ( 11) JMP MOVE_END 06CA- 464 MOVE_DOWN: ; dir bits must be 11 06CA-A9 01 465 ( 22) ILD 1(P1) 06CC-D4 1F 466 ( 10) ANI $1F 06CE-DA 0A 467 ( 18) OR DIR(P2) 06D0-C9 01 468 ( 18) ST 1(P1) 06D2- 469 MOVE_END: 06D2-C5 02 470 ( 18) LD @2(P1) ; Move P1 to next ENTRY 06D4-BA 00 471 ( 22) DLD COUNT1(P2) 06D6-9C C8 472 (9/11) JNZ TEST_DIR 06D8-C2 05 473 ( 18) LD SNAKE_LEN(P2) 06DA-F4 80 474 ( 11) ADI $80 06DC-CA 00 475 ( 18) ST COUNT1(P2) 06DE- 476 BODY_DLY: ; Delay is inversely proportional to the number of body segments. 06DE-C4 40 477 ( 10) LDI $40 ; This avoids the game slowing as the body length increases 06E0-8F 00 478 ( 13+) DLY $0 06E2-AA 00 479 ( 22) ILD COUNT1(P2) 06E4-9C F8 480 (9/11) JNZ BODY_DLY 06E6- 481 ;------------------------------------------------------------------- 06E6- 482 ; Place an Apple on screen 06E6- 483 06E6-C2 08 484 ( 18) LD APPLE(P2) ; If APPLE is not zero then there's already one on screen 06E8-9C 2E 485 (9/11) JNZ PLACED 06EA- 486 06EA- 487 ;Generate random number for position of the next Apple's position 06EA-C2 0E 488 ( 18) LD SEED(P2) 06EC-D4 01 489 ( 10) ANI $01 06EE-01 490 ( 7) XAE 06EF-C2 0E 491 ( 18) LD SEED(P2) ; This small piece of code implements an 8 bit PRNG 06F1-1C 492 ( 5) SR 06F2-01 493 ( 7) XAE 06F3-98 05 494 (9/11) JZ NO_XOR 06F5-40 495 ( 6) LDE 06F6-E4 B8 496 ( 10) XRI $B8 06F8-90 01 497 ( 11) JMP STORE 06FA- 498 NO_XOR: 06FA-40 499 ( 6) LDE 06FB- 500 STORE: 06FB-CA 0E 501 ( 18) ST SEED(P2) 06FD-33 502 ( 8) XPAL P3 06FE-C2 0E 503 ( 18) LD SEED(P2) 0700-D4 01 504 ( 10) ANI $01 0702-DC 02 505 ( 10) ORI $02 0704-37 506 ( 8) XPAH P3 0705- 507 TEST_APPLE: ; Check that position for next Apple is empty. If not increment it until aspace if found 0705-C3 00 508 ( 18) LD (P3) 0707-E4 20 509 ( 10) XRI $20 0709-98 07 510 (9/11) JZ PLACE_APPLE 070B-33 511 ( 8) XPAL P3 070C-02 512 ( 5) CCL 070D-F4 01 513 ( 11) ADI $01 070F-33 514 ( 8) XPAL P3 0710-90 F3 515 ( 11) JMP TEST_APPLE 0712- 516 PLACE_APPLE: 0712-C4 2A 517 ( 10) LDI CHAR_APPLE 0714-CB 00 518 ( 18) ST (P3) ; Display Apple on screen 0716-CA 08 519 ( 18) ST APPLE(P2) ; Make apple flag non-zero to indicate aplle is on screen 0718- 520 PLACED: 0718- 521 0718-8F 30 522 ( 13+) DLY GAME_DELAY 071A-8F 30 523 ( 13+) DLY GAME_DELAY 071C- 524 071C-C4 05 37 C4 39 33 3F 525 JS P3,START ; long jump back to start of main loop 0723- 526 0723- 527 0723- 528 ;================================================ 0723- 529 ;Clear screen and initialise snake array - Subroutine 0723- 530 CLS: 0723-C4 02 531 ( 10) LDI DISP_CH/256 0725-CA 0C 532 ( 18) ST P3H_WIPE(P2) 0727-35 533 ( 8) XPAH P1 0728-C4 00 534 ( 10) LDI DISP_CH\256 072A-CA 0D 535 ( 18) ST P3L_WIPE(P2) 072C-31 536 ( 8) XPAL P1 ; P1 now contains start address of character display 072D- 537 CLS2: 072D-C4 20 538 ( 10) LDI CHAR_SPACE 072F-CD 01 539 ( 18) ST @1(P1) ; Clear character location 0731-35 540 ( 8) XPAH P1 0732-E4 04 541 ( 10) XRI DISP_CH/256+2 ; XOR to determine if page clear completed 0734-98 05 542 (9/11) JZ CLS3 ; If zero then then finished clear screen 0736-E4 04 543 ( 10) XRI DISP_CH/256+2 ; Restore P1_H 0738-35 544 ( 8) XPAH P1 0739-90 F2 545 ( 11) JMP CLS2 073B- 546 CLS3: 073B- 547 ; Place Snake in the array 073B-C4 04 548 ( 10) LDI SNAKE_ARRAY/256 073D-35 549 ( 8) XPAH P1 073E- 550 ; P1L is already $00 073E- 551 073E- 552 ;--------------------------------------------- 073E- 553 ; X_BYTE = 7 6 5 4 3 2 1 0 073E- 554 ; 0 0 0 0 X3 X2 X1 X0 073E- 555 ; 073E- 556 ; X = X co-ordinate on screen, bit 4 reserved for overflow 073E- 557 ; If X=FF then indicates end of snake reached 073E- 558 ; 073E- 559 ; Y_BYTE = 7 6 5 4 3 2 1 0 073E- 560 ; D1 D0 0 Y4 Y3 Y2 Y1 Y0 073E- 561 ; 073E- 562 ; D = direction, Y = Y co-ordinate on screen, bit 5 reserved for overflow 073E- 563 ; Direction 0= right, 1 = up, 2 = left, 3 = down 073E- 564 ; 073E- 565 ;--------------------------------------------- 073E- 566 073E-C4 06 567 ( 10) LDI $06 ; Top of array is always the head, X=6 0740-C9 00 568 ( 18) ST (P1) 0742-C4 05 569 ( 10) LDI $05 ; X=5 0744-C9 02 570 ( 18) ST 2(P1) 0746-C4 04 571 ( 10) LDI $04 ; X=4 0748-C9 04 572 ( 18) ST 4(P1) 074A-C4 03 573 ( 10) LDI $03 ; X=3 074C-C9 06 574 ( 18) ST 6(P1) 074E-C4 02 575 ( 10) LDI $02 ; X=2 0750-C9 08 576 ( 18) ST 8(P1) 0752-C4 10 577 ( 10) LDI $10 ; Direction=0=Right, Y=$10 0754-C9 01 578 ( 18) ST 1(P1) 0756-C9 03 579 ( 18) ST 3(P1) 0758-C9 05 580 ( 18) ST 5(P1) 075A-C9 07 581 ( 18) ST 7(P1) 075C-C9 09 582 ( 18) ST 9(P1) 075E- 583 075E-3F 584 ( 7) RET P3 075F- 585 075F- 586 ;====================================================== 075F- 587 ; Subroutine 075F- 588 ; Ouput message to screen 075F- 589 ; P1 needs to point to the screen location 075F- 590 ;====================================================== 075F- 591 OUT_MESSAGE 075F-C7 01 592 ( 18) LD @1(P3) 0761- 593 IS2: 0761-C7 01 594 ( 18) LD @1(P3) ; copy it to screen 0763-98 04 595 (9/11) JZ END_MESS ; EOF is $00 0765-CD 01 596 ( 18) ST @1(P1) 0767-90 F8 597 ( 11) JMP IS2 0769- 598 END_MESS: 0769-C7 FF 599 ( 18) LD @-1(P3) 076B-3F 600 ( 7) RET P3 076C- 601 076C- 602 ;------------------------------------------------------------------------------ 076C- 603 ; SCIOS Variables $0F00 to $0F0F 076C- 604 ; Game variables $0F10 to $0F27 076C- 605 ;------------------------------------------------------------------------------ 0F28- 606 .OR $F28 0F28- 607 ;====================================================== 0F28- 608 ; GAME over subroutine 0F28- 609 ;====================================================== 0F28- 610 GAME_END: 0F28-37 611 ( 8) XPAH P3 ; Temporarily store return address held in P3 0F29-CA 01 612 ( 18) ST P3H_TMP(P2) 0F2B-33 613 ( 8) XPAL P3 0F2C-CA 02 614 ( 18) ST P3L_TMP(P2) 0F2E-C4 00 615 ( 10) LDI $00 0F30-CA 09 616 ( 18) ST GAME_OVER(P2) ; 0 = game over 0F32-C4 07 37 C4 22 33 3F 617 JS P3,CLS ; Clear screen and initialise the snake array 0F39-C4 02 618 ( 10) LDI MESSAGE/256 ; Get address of message display area 0F3B-35 619 ( 8) XPAH P1 0F3C-C4 E0 620 ( 10) LDI MESSAGE\256 0F3E-31 621 ( 8) XPAL P1 0F3F-C2 13 622 ( 18) LD YOU_WIN(P2) 0F41-9C 1A 623 (9/11) JNZ nU_WIN 0F43-C4 07 37 C4 5E 33 3F 624 JS P3,OUT_MESSAGE 0F4A-01 0D 01 1A 09 0E 07 21 20 19 0F 15 20 17 0F 0E 00 625 U_WON: .DB $1,$D,$1,$1A,$9,$E,$7,$21,$20,$19,$F,$15,$20,$17,$F,$E,$00 ; AMAZING! YOU WON 0F5B-C5 10 626 ( 18) LD @$10(P1) ; increment to next line of display 0F5D- 627 nU_WIN: 0F5D-C4 07 37 C4 5E 33 3F 628 JS P3,OUT_MESSAGE 0F64-20 0D 0B 31 34 20 13 0E 01 0B 05 20 16 31 00 629 SNAKE14: .DB $20,$D,$B,$31,$34,$20,$13,$E,$1,$B,$5,$20,$16,$31,$00 ; MK14 SNAKE V1 0F73-C5 15 630 ( 18) LD @$15(P1) ; increment to Next line of display 0F75-C4 07 37 C4 5E 33 3F 631 JS P3,OUT_MESSAGE 0F7C-07 01 0D 05 20 0F 16 05 12 00 632 OVER: .DB $07,$01,$0D,$05,$20,$0F,$16,$05,$12,$00 ; GAME OVER 0F86-C5 13 633 ( 18) LD @$13(P1) ; increment to next line of display 0F88-C4 07 37 C4 5E 33 3F 634 JS P3,OUT_MESSAGE 0F8F-20 13 0E 01 0B 05 20 13 09 1A 05 3D 00 635 SCORE: .DB $20,$13,$E,$1,$B,$5,$20,$13,$9,$1A,$5,$3D,$00 ; SNAKE SIZE= 0F9C-C2 05 636 ( 18) LD SNAKE_LEN(P2) ; 0F9E-CA 00 637 ( 18) ST COUNT1(P2) 0FA0-C4 00 638 ( 10) LDI $00 0FA2-CA 11 639 ( 18) ST SCORE_H(P2) 0FA4-CA 12 640 ( 18) ST SCORE_L(P2) 0FA6- 641 UPDATE1: 0FA6-C2 12 642 ( 18) LD SCORE_L(P2) 0FA8-02 643 ( 5) CCL 0FA9-EC 01 644 ( 15) DAI $01 0FAB-CA 12 645 ( 18) ST SCORE_L(P2) 0FAD-1F 646 ( 5) RRL ; rotate carry flag into bit 7 0FAE-94 07 647 (9/11) JP UPDATE2 0FB0-C2 11 648 ( 18) LD SCORE_H(P2) 0FB2-02 649 ( 5) CCL 0FB3-EC 01 650 ( 15) DAI $01 0FB5-CA 11 651 ( 18) ST SCORE_H(P2) 0FB7- 652 UPDATE2: 0FB7-02 653 ( 5) CCL 0FB8-C2 11 654 ( 18) LD SCORE_H(P2) 0FBA-D4 0F 655 ( 10) ANI $0F ; Mask off lower nibble 0FBC-F4 30 656 ( 11) ADI $30 ; Convert to number character 0FBE-CD 01 657 ( 18) ST @1(P1) ; Display number and increment pointer 0FC0-C2 12 658 ( 18) LD SCORE_L(P2) 0FC2-D4 F0 659 ( 10) ANI $F0 ; Mask off upper nibble 0FC4-1C 660 ( 5) SR ; Shift right 4 times 0FC5-1C 661 ( 5) SR 0FC6-1C 662 ( 5) SR 0FC7-1C 663 ( 5) SR 0FC8-F4 30 664 ( 11) ADI $30 ; Convert to number character 0FCA-CD 01 665 ( 18) ST @1(P1) 0FCC-C2 12 666 ( 18) LD SCORE_L(P2) 0FCE-D4 0F 667 ( 10) ANI $0F ; Mask off lower nibble 0FD0-F4 30 668 ( 11) ADI $30 ; Convert to number character 0FD2-CD 00 669 ( 18) ST @(P1) ; Display number 0FD4-C5 FE 670 ( 18) LD @-2(P1) ; Move P1 pointer back to start of score 0FD6-8F A0 671 ( 13+) DLY $A0 ; Delay for visual effect only 0FD8-BA 00 672 ( 22) DLD COUNT1(P2) 0FDA-9C CA 673 (9/11) JNZ UPDATE1 0FDC- 674 RET_KBD: 0FDC-C5 18 675 ( 18) LD @$18(P1) ; increment to next line of display 0FDE-C4 07 37 C4 5E 33 3F 676 JS P3,OUT_MESSAGE 0FE5-10 12 05 13 13 20 07 0F 00 677 PRESSGO: .DB $10,$12,$05,$13,$13,$20,$07,$0F,$00 ; PRESS GO 0FEE-C2 01 678 ( 18) LD P3H_TMP(P2) ; Restore P3 return address 0FF0-37 679 ( 8) XPAH P3 0FF1-C2 02 680 ( 18) LD P3L_TMP(P2) 0FF3-33 681 ( 8) XPAL P3 0FF4-3F 682 ( 7) RET P3 0FF5- 683 ; 0FF5- 684 ;****************************************************************************** 0FF5- 685 ; NOTE: THE PROGRAM LOAD MUST NOT GO PAST $FF7 AS THE FAST LOADER VARIABLES WILL BE CORRUPTED 0FF5- 686 ; ***************************************************************************** 0FF5- 687 ; This line is displayed at the end of program load only 0380- 688 .OR MESSAGE2 0380-20 20 20 20 10 12 05 13 13 20 07 0F 20 20 20 20 689 .DB $20,$20,$20,$20,$10,$12,$5,$13,$13,$20,$7,$F,$20,$20,$20,$20 ; PRESS GO 0390- 690 0390- 691 ; ENTRY is the execution address that the Hex loader will use during program load 0390- 692 EXEC_ADR: FFFE- 693 .OR $FFFE FFFE-05 694 .DB ENTRY/256 FFFF-00 695 .DB ENTRY\256 010000- 696 010000- 697