1 ; ACORN monitor, written in TASM-compatible assembly language, 2 ; incorporating commentary from original text (corrected where 3 ; necessary) and using original names where possible. 4 ; [Mike Cowlishaw, 2002.01.06] 5 6 ; 7 ; ACORN MONITOR 8 ; 9 10 ; --------------------------------------------------------------- 11 ; Monitor variables (RAM $0000-$001F) 12 ; --------------------------------------------------------------- 13 0000 .dseg 14 0000 .org $0000 15 0000 MAP .block 2 ; M address (Low and high bytes) 16 0002 GAP .block 2 ; Go address 17 0004 PAP .block 2 ; breakPoint address 18 0006 FAP .block 2 ; tape From address 19 0008 TAP .block 2 ; tape To address 20 000A R0 .block 1 ; Register 0: contains A after Break 21 000B R1 .block 1 ; Register 1: contains X after Break 22 000C R2 .block 1 ; Register 2: contains Y after Break 23 000D R3 .equ * ; Register 3: temporarily P after Break, 24 000D KEY .block 1 ; contains last pressed key for display 25 000E REPEAT .block 1 ; MSB=1 sets repeatedly scanned display, 26 ; otherwise single scan 27 000F EXEC .block 1 ; Execution status of the key processing 28 ; routine [must precede D immediately] 29 0010 D .equ * ; Base address of the eight displayed 30 ; memory locations 31 0010 R4 .block 1 ; Register 4: temporarily PCH after Break, 32 0011 R5 .block 1 ; Register 5: temporarily PCL after Break, 33 0012 R6 .block 1 ; Register 6: temporarily 01 after Break, 34 0013 R7 .block 1 ; Register 7: temporarily S after Break, 35 0014 .block 4 ; Last 4 displayed memory locations 36 0018 P .block 1 ; Single level of storage for previous 37 ; data at break point 38 0019 COL .block 1 ; Column of key currently being processed 39 001A TX .equ * ; Temporary storage for X (in DISPLAY) or 40 001A TY .block 1 ; Y (various places) 41 001B RECAL .block 1 ; Contains PC recalculation factor for 42 ; break [Note: not set by monitor] 43 001C USERNMI .block 2 ; Address of User's NMI program 44 001E USERIRQ .block 2 ; Address of User's IRQ program 45 46 ; --------------------------------------------------------------- 47 ; Processor stack (RAM $0100-$01FF) 48 ; --------------------------------------------------------------- 49 0100 .org $0100 50 0100 STACK .block 256 ; The stack page 51 52 ; --------------------------------------------------------------- 53 ; First RAM/IO PIO 54 ; --------------------------------------------------------------- 55 0E20 .org $0E20 56 0E20 X1PIA .block 1 ; 20 A Programmable I/O 57 0E21 X1PIB .block 1 ; 21 B Programmable I/O 58 0E22 X1ADDR .block 1 ; 22 A Data direction register 59 0E23 X1BDDR .block 1 ; 23 B Data direction register 60 61 ; --------------------------------------------------------------- 62 ; First RAM/IO RAM ($0E80-$0EFF; not used by monitor) 63 ; --------------------------------------------------------------- 64 0E80 .org $0E80 65 0E80 .block 128 66 67 ; --------------------------------------------------------------- 68 ; Monitor code in PROM ($FE00-$FFFF) 69 ; --------------------------------------------------------------- 70 0F00 .cseg 71 FE00 .org $FE00 72 ; --------------------------------------------------------------- 73 ; QUAD: DISPLAY THE 4 BYTES AT X-3,X-2, X-1 & X IN THAT 74 ; ORDER ON THE DISPLAY 75 ; --------------------------------------------------------------- 76 FE00 A0 06 QUAD ldy #$06 ; - LOOP COUNTER 77 FE02 B5 00 STILL lda 0,X ; - GET THE BYTE POINTED TO BY X 78 FE04 20 6F FE jsr DHEXTD ; - USE DOUBLE HEX TO DISPLAY 79 ; ROUTINE 80 FE07 CA dex ; - NEXT X 81 FE08 88 dey ; - NEXT Y POSITION 82 FE09 88 dey ; 83 FE0A 10 F6 bpl STILL ; - FALL INTO DISPLAY WHEN 84 ; FINISHED - Y WAS POSITION & 85 ; ALSO LOOP COUNTER 86 ; --------------------------------------------------------------- 87 ; DISPLAY: STROBE KEYBOARD, MULTIPLEX DISPLAY, RETURN WITH KEY 88 ; INFORMATION 89 ; --------------------------------------------------------------- 90 FE0C 86 1A DISPLAY stx TX ; - SAVE X!!!! 91 FE0E A2 07 RESCAN ldx #$07 ; - SCAN 8 DIGITS, NO MATTER WHAT 92 FE10 8E 22 0E stx X1ADDR ; - SET UP DATA DIRECTION 93 ; REGISTER 94 FE13 A0 00 SCAN ldy #$00 ; - CLEAR Y FOR LATER USE 95 FE15 B5 10 lda D,X ; - GET DISPLAY DATA FROM THE 96 ; ZERO PAGE MEMORY 97 FE17 8D 21 0E sta X1PIB ; - & PUT IT ONTO SEGMENTS 98 FE1A 8E 20 0E stx X1PIA ; - SET DIGIT DRIVE ON AND THE KEY 99 ; COLUMNS 100 FE1D AD 20 0E lda X1PIA ; - GET KEY DIGIT BACK 101 FE20 29 3F and #$3F ; - REMOVE SURPLUS TOP BITS 102 FE22 24 0F bit EXEC ; - CHECK STATUS ='1' MEANS NOT 103 ; PROCESSING A KEY 104 FE24 10 18 bpl BUTTON ; - BUT 0 MEANS THAT WE ARE 105 ; [the next instruction is not in the ROM] 106 ; bvs DELAY ; - THUS CAN BE BLOWN TO AN 107 ; ; ESCAPE FROM THE DISPLAY 108 ; ; ROUTINE ALTOGETHER ON STATUS 109 ; ; C0 AT THE MOMENT IT IGNORES 110 ; ; KEYS IF GIVEN THIS STATUS 111 FE26 C9 38 cmp #$38 ; - CHECK FOR ALL 1'S ROW INPUT 112 ; FROM KEYBOARD = SET COPY IF SO 113 FE28 B0 06 bcs DELAY ; - IF ALL 1's THEN NO KEY HAS BEEN 114 ; PRESSED 115 FE2A 86 19 stx COL ; - STORE THE PRESSED KEY'S 116 ; COLUMN INFORMATION 117 FE2C A9 40 lda #$40 ; - SET STATUS TO "WE ARE 118 ; PROCESSING A KEY" 119 FE2E 85 0F KEYCLEAR sta EXEC ; 120 ; [change here from published monitor; the LDA Indirect 121 ; has been added to increase the delay time] 122 FE30 A1 00 DELAY lda (0,X) ; - (new) TIME PADDING ONLY 123 FE32 88 dey ; - Y WAS ZERO SO HERE IS A 256x12uS 124 ; DELAY (~ 3ms) 125 FE33 D0 FB bne DELAY ; - Y WILL BE ZERO ON EXIT 126 FE35 CA dex ; 127 FE36 10 DB bpl SCAN ; - IF X WAS STILL +VE, CONTINUE 128 ; THIS SCAN 129 FE38 A5 0E lda REPEAT ; - IF WE SHOULD CONTINUE 130 ; SCANNING THEN TOP BIT IS SET 131 FE3A 30 D2 bmi RESCAN ; - CONTINUE SCANNING 132 FE3C 10 14 bpl OUTPUT ; - IF TOP BIT IS ZERO, THEN USE THIS 133 ; DATA AS THE KEY ITSELF 134 135 FE3E E4 19 BUTTON cpx COL ; - ARE WE ON THE SAME KEY'S 136 ; COLUMN? 137 FE40 D0 EE bne DELAY ; - NO 138 FE42 C9 38 cmp #$38 ; - HAS A KEY ACTUALLY BEEN 139 ; PRESSED? 140 FE44 90 04 bcc PRESSED ; - YES 141 FE46 A9 80 lda #$80 ; - NO, THEN CLEAR THE EXECUTION 142 ; STATUS - THE KEY HAS BEEN 143 ; PRESSED & RELEASED 144 FE48 D0 E4 bne KEYCLEAR ; - ALWAYS BRANCH 145 146 FE4A C5 0F PRESSED cmp EXEC ; - A KEY HAS BEEN PRESSED 147 FE4C F0 E2 beq DELAY ; - BUT IT HAS ALREADY BEEN 148 ; EXECUTED 149 FE4E 85 0F sta EXEC ; - SET IT AS BEING EXECUTED 150 FE50 49 38 eor #$38 ; - JIGGERY POKERY TO ENCODE THE 151 ; ROW INPUTS TO BINARY 152 FE52 29 1F OUTPUT and #$1F ; - ALSO ENSURE THE KEY IN REPEAT 153 ; WAS OF REASONABLE SIZE 154 FE54 C9 10 cmp #$10 ; - A HEX KEY OR NOT? CARRY CLEAR 155 ; IF HEX 156 FE56 85 0D sta KEY ; - PUT THE KEY IN A TEMP LOCATION 157 ; FOR FURTHER USE (BY "MODIFY") 158 FE58 A6 1A ldx TX ; - RETRIEVE X 159 FE5A 8C 21 0E sty X1PIB ; - TURN THE SEGMENT DRIVES OFF 160 FE5D 60 rts ; - AND RETURN 161 162 ; --------------------------------------------------------------- 163 ; MHEXTD: MEMORY HEX TO DISPLAY: DISPLAY A MEMORY BYTE ON 164 ; RIGHT OF DISPLAY 165 ; --------------------------------------------------------------- 166 FE5E A1 00 MHEXTD lda (0,X) ; - MEMORY HEX TO DISPLAY = GET A 167 ; BYTE FROM MEMORY 168 169 ; --------------------------------------------------------------- 170 ; RDHEXTD: RIGHT DIGITS HEX TO DISPLAY: DISPLAY A ON RIGHT OF 171 ; DISPLAY 172 ; --------------------------------------------------------------- 173 FE60 A0 06 RDHEXTD ldy #$06 ; - RIGHT (OF DISPLAY) DOUBLE HEX 174 ; TO DISPLAY : SET Y TO RIGHT OF 175 ; DISPLAY 176 FE62 D0 0B bne DHEXTD ; - AND USE DHEXTD 177 178 ; --------------------------------------------------------------- 179 ; QHEXTD1: QUAD HEX TO DISPLAY; DISPLAY (X) AND (X+1) BYTES ON 180 ; DISPLAYS 1, 2, 3 & 4 181 ; --------------------------------------------------------------- 182 FE64 A0 03 QHEXTD1 ldy #$03 ; - SET Y TO USE POSNS 1,2,3 & 4 183 184 ; --------------------------------------------------------------- 185 ; QHEXTD2: DISPLAY (X) AND (X+1) BYTES ON DISPLAYS Y-2, Y-1, 186 ; Y & Y+1 187 ; --------------------------------------------------------------- 188 FE66 B5 00 QHEXTD2 lda 0,X ; - GET THE DATA 189 FE68 20 6F FE jsr DHEXTD ; - AND USE DHEXTD 190 FE6B 88 dey ; 191 FE6C 88 dey ; - HAVING DECREMENTED THE 192 ; POSITION 193 FE6D B5 01 lda 1,X ; - GET THE HIGH BYTE OF THE DATA 194 ; & USE DHEXTD 195 ; --------------------------------------------------------------- 196 ; DHEXTD: DOUBLE HEX TO DISPLAY: DISPLAY A ON DISPLAYS Y & 197 ; Y+1 198 ; --------------------------------------------------------------- 199 FE6F C8 DHEXTD iny ; - DOUBLE HEX TO DISPLAY : FIRST 200 ; HEX ON RIGHTEST POSITION 201 FE70 48 pha ; - SAVE A 202 FE71 20 7A FE jsr HEXTD ; - USE HEX TO DISPLAY 203 FE74 88 dey ; - GET Y BACK TO CORRECT 204 ; POSITION 205 FE75 68 pla ; - RETRIEVE A 206 FE76 4A lsr A ; 207 FE77 4A lsr A ; 208 FE78 4A lsr A ; 209 FE79 4A lsr A ; - ORIENTED FOR OTHER HEX DIGIT 210 211 212 ; --------------------------------------------------------------- 213 ; HEXTD: HEX TO DISPLAY: DISPLAY BOTTOM 4 BITS OF A ON 214 ; DISPLAY Y 215 ; --------------------------------------------------------------- 216 FE7A 84 1A HEXTD sty TY ; - HEX TO DISPLAY = SAVE Y 217 FE7C 29 0F and #$0F ; - REMOVE SURPLUS BITS FROM A 218 FE7E A8 tay ; - & PUT IT IN Y 219 FE7F B9 EA FF LDA FONT,Y ; - GET THE 7 SEGMENT FORM 220 FE82 A4 1A ldy TY ; - RETRIEVE Y 221 FE84 99 10 00 sta D,Y ; - AND POSITION THE 7 SEG FORM ON 222 ; THE DISPLAY 223 FE87 60 rts ; 224 225 ; --------------------------------------------------------------- 226 ; QDATFET: QUAD DATA FETCH: FETCH AN ADDRESS INTO (X) & (X+1) 227 ; --------------------------------------------------------------- 228 FE88 20 64 FE QDATFET jsr QHEXTD1 ; - QUAD DATA FETCH - DISPLAY OLD 229 ; DATA 230 FE8B 20 0C FE jsr DISPLAY ; - GET KEY 231 FE8E B0 20 bcs RETURN ; - NON HEX RETURN 232 FE90 A0 04 ldy #$04 ; - LOOP COUNTER 233 FE92 0A asl A ; 234 FE93 0A asl A ; 235 FE94 0A asl A ; 236 FE95 0A asl A ; - DIGIT IN A IN CORRECT PLACE 237 FE96 0A SHIFTIN asl A ; - MULTI SHIFT TO GET DIGIT INTO 238 ; MEMORY 239 FE97 36 00 rol 0,X ; - INDEXED 240 FE99 36 01 rol 1,X ; (high byte) 241 FE9B 88 dey ; 242 FE9C D0 F8 bne SHIFTIN ; - KEEP SHIFTING IN 243 FE9E F0 E8 beq QDATFET ; - GO AND DO IT ALL AGAIN 244 245 ; --------------------------------------------------------------- 246 ; COM16: COMPARE 16: INCREMENT (X+6) & (X+7) AND COMPARE 247 ; WITH (X+8) & (X+9) 248 ; --------------------------------------------------------------- 249 FEA0 F6 06 COM16 inc $06,X ; - INCREMENT & COMPARE 16 BIT 250 ; NOS - INCREMENT LOWER 251 FEA2 D0 02 bne NOINC ; - NO HIGH INCREMENT 252 FEA4 F6 07 inc $07,X ; 253 ; --------------------------------------------------------------- 254 ; NOINC: COMPARE 16 WITHOUT INCREMENT: COMPARE (X+6) & (X+7) 255 ; WITH (X+8) & (X+9) 256 ; --------------------------------------------------------------- 257 FEA6 B5 06 NOINC lda $06,X ; - LOW BYTE EQUALITY TEST 258 FEA8 D5 08 cmp $08,X ; 259 FEAA D0 04 bne RETURN ; - NO NEED TO DO HIGH BYTE 260 FEAC B5 07 lda $07,X ; - HIGH BYTE EQUALITY TEST 261 FEAE D5 09 cmp $09,X ; 262 FEB0 60 RETURN rts ; 263 264 ; --------------------------------------------------------------- 265 ; PUTBYTE: PUT A TO TAPE, DO 1 START BIT & 1 STOP BIT, NO 266 ; PARITY 267 ; --------------------------------------------------------------- 268 FEB1 A0 40 PUTBYTE ldy #$40 ; - PUT BYTE TO TAPE - CONFIGURE 269 ; I/O PORT 270 FEB3 8C 22 0E sty X1ADDR ; 271 FEB6 A0 07 ldy #$07 ; - LOOPCOUNTER 272 FEB8 8C 20 0E sty X1PIA ; - AND SEND THE START BIT 273 FEBB 6A ror A ; 274 FEBC 6A ror A ; - BACK A UP A COUPLE OF BITS 275 FEBD 20 CD FE AGAIN jsr WAIT ; - WAIT TO SEND OUT RESET BIT 276 FEC0 6A ror A ; - SENDING ORDER IS BIT 0 -> BIT 7 277 FEC1 8D 20 0E sta X1PIA ; - SEND BIT 278 FEC4 88 dey ; 279 FEC5 10 F6 bpl AGAIN ; - KEEP GOING 280 FEC7 20 CD FE jsr WAIT ; - WAIT FOR THAT BIT TO END 281 FECA 8C 20 0E sty X1PIA ; - SEND STOP BIT : Y IS FF 282 283 ; --------------------------------------------------------------- 284 ; WAIT: WAIT FOR CASSETTE TIMING 285 ; --------------------------------------------------------------- 286 FECD 20 D0 FE WAIT jsr HALFWAIT ; - 300 BAND WAITING TIME - IN TWO 287 ; PARTS 288 ; --------------------------------------------------------------- 289 ; HALFWAIT: HALF THE WAIT 290 ; --------------------------------------------------------------- 291 FED0 84 1A HALFWAIT sty TY ; - 1/2 THE WAITING TIME - SAVE Y 292 FED2 A0 48 ldy #$48 ; - 72 X 5uS DELAY 293 FED4 88 WAIT1 dey ; - PART ONE OF THE WAIT 294 FED5 D0 FD bne WAIT1 ; 295 FED7 88 WAIT2 dey ; - Y WAS ZERO ON ENTRY - 256 x 5uS 296 FED8 D0 FD bne WAIT2 ; DELAY 297 FEDA A4 1A ldy TY ; - RETRIEVE Y 298 FEDC 60 rts ; 299 300 ; --------------------------------------------------------------- 301 ; GETBYTE: GET BYTE FROM TAPE TO A, WAIT FOR A START BIT, 302 ; CENTRE TIMING 303 ; --------------------------------------------------------------- 304 FEDD A0 08 GETBYTE ldy #$08 ; - GET BYTE FROM TAPE - LOAD 305 ; COUNTER 306 FEDF 2C 20 0E START bit X1PIA ; - WAIT FOR 1 -> 0 TRANSISITON - 307 FEE2 30 FB bmi START ; A START BIT 308 FEE4 20 D0 FE jsr HALFWAIT ; - WAIT HALF THE TIME, SO 309 ; SAMPLING IN THE CENTRE 310 FEE7 20 CD FE INPUT jsr WAIT ; - FULL WAIT TIME BETWEEN 311 ; SAMPLES 312 FEEA 0E 20 0E asl X1PIA ; - GET SAMPLE INTO CARRY 313 FEED 6A ror A ; - AND INTO A 314 FEEE 88 dey ; 315 FEEF D0 F6 bne INPUT ; - KEEP GOING 316 FEF1 F0 DA beq WAIT ; - USE WAIT TO GET OUT ONTO 317 ; THE STOP BIT HIGH 318 319 ; --------------------------------------------------------------- 320 ; RESET: ENTRY TO MONITOR 321 ; --------------------------------------------------------------- 322 FEF3 A2 FF RESET ldx #$FF ; - MAIN PROGRAM 323 FEF5 9A txs ; - INITIALIZE STACK 324 FEF6 8E 23 0E stx X1BDDR ; - AND B DATA DIRECTION REGISTER 325 FEF9 86 0E stx REPEAT ; - MULTI-SCAN DISPLAY MODE 326 FEFB A0 80 INIT ldy #$80 ; - THE FAMILIAR DOT ON THE 327 ; DISPLAY 328 FEFD A2 09 ldx #$09 ; - ALL EIGHT DISPLAYS AND 329 ; INITIALIZE EXEC 330 FEFF 94 0E ROUND sty REPEAT,X ; - Y USED FOR AMUSEMENT 331 FF01 CA dex ; 332 FF02 D0 FB bne ROUND ; - X ZERO ON EXIT, SO UP & DOWN 333 ; IMMEDIATELY VALID ($00 -> MAP) 334 ; --------------------------------------------------------------- 335 ; RESTART: RE-ENTRY TO RUNNING MONITOR 336 ; --------------------------------------------------------------- 337 FF04 20 0C FE RESTART jsr DISPLAY ; - MARK RETURN TO MONITOR POINT 338 ; DISPLAY DISPLAY & GET KEY 339 FF07 90 F2 REENTER bcc INIT ; - HEX KEY GETS THE DOTS BACK 340 FF09 29 07 SEARCH and #$07 ; - REMOVE ANY STRAY BITS 341 ; (EFFECTIVELY SUBTRACT $10) 342 FF0B C9 04 cmp #$04 ; 343 FF0D 90 25 bcc FETADD ; - KEYS OF VALUE LESS THAN 4 344 ; NEED AN ADDRESS 345 FF0F F0 6F beq LOAD ; - KEY 4 IS THE LOAD KEY 346 FF11 C9 06 TEST6 cmp #$06 ; 347 FF13 F0 09 beq UP ; - KEY 6 IS UP 348 FF15 B0 0F bcs DOWN ; - & KEY 7 IS DOWN 349 ; "RETURN" command 350 FF17 A5 0A RETURN2 lda R0 ; - MUST BE KEY 5 - GET A BACK 351 FF19 A6 0B ldx R1 ; - GET X BACK 352 FF1B A4 0C ldy R2 ; - GET Y BACK 353 FF1D 40 rti ; - GET P & PC BACK & CONTINUE 354 ; FROM WHERE YOU WERE 355 356 ; "UP" command 357 FF1E F6 00 UP inc 0,X ; - 16 BIT INDEXED INCREMENT 358 FF20 D0 0C bne ENTERM ; 359 FF22 F6 01 inc 1,X ; 360 FF24 B0 08 bcs ENTERM ; - A BRANCH ALWAYS: THE CARRY 361 ; WAS SET BY THE COMPARE AT TEST6 362 ; "DOWN" command 363 FF26 B5 00 DOWN lda 0,X ; - 16 BIT INDEXED DECREMENT 364 FF28 D0 02 bne NODEC ; 365 FF2A D6 01 dec 1,X ; 366 FF2C D6 00 NODEC dec 0,X ; 367 FF2E 20 64 FE ENTERM jsr QHEXTD1 ; - NOW DISPLAY THE VALUE 368 FF31 4C 45 FF jmp MODIFY ; - AND GET INTO THE MODIFY 369 ; SECTION 370 371 FF34 84 16 FETADD sty D+6 ; - CLEAR DISPLAYS 6 372 FF36 84 17 sty D+7 ; - & 7 - Y WAS ZERO ON EXIT FROM 373 ; DISPLAY 374 FF38 0A asl A ; - DOUBLE A 375 FF39 AA tax ; - THE ZERO PAGE ADDRESSES MAP, 376 ; GAP, PAP & FAP 377 FF3A 49 F7 eor #$F7 ; - FIX UP DIGIT 0 COMMAND SYMBOL 378 FF3C 85 10 sta D ; 379 FF3E 20 88 FE jsr QDATFET ; - FETCH THE ADDRESS, INTO MAP, 380 ; GAP, PAP OR FAP 381 FF41 E0 02 cpx #$02 ; - CHECK X TO FIND OUT WHICH 382 ; COMMAND WE'RE DOING 383 FF43 B0 15 bcs N1 ; - MUST BE 2,4 OR 6 - AS 0 IS .. 384 ; "MODIFY" command 385 FF45 20 5E FE MODIFY jsr MHEXTD ; - DISPLAY THE MEMORY 386 FF48 20 0C FE jsr DISPLAY ; - AND GET KEY 387 FF4B B0 BC bcs SEARCH ; - IF NOT HEX DO OVER 388 FF4D A1 00 lda (0, X) ; - HEX SO GET OLD INFO 389 FF4F 0A asl A ; 390 FF50 0A asl A ; 391 FF51 0A asl A ; 392 FF52 0A asl A ; - MOVED ALONG 393 FF53 05 0D ora KEY ; - AND PUT IN NEW INFO 394 FF55 81 00 sta (0, X) ; - AND PUT IT BACK 395 FF57 4C 45 FF jmp MODIFY ; - THEN KEEP DOING IT 396 FF5A D0 03 N1 bne N2 ; - MUST BE 4 OR 6 AS 2 IS .. 397 398 ; "GO" command 399 FF5C 6C 02 00 GO jmp (GAP) ; - THE VERY SIMPLE GO 400 401 FF5F E0 04 N2 cpx #$04 ; - IS IT 4 OR 6? 402 FF61 F0 36 beq POINT ; - WELL IT'S NOT 4 403 404 ; "STORE" command 405 FF63 A2 08 STORE ldx #TAP ; - SO IT MUST BE 6 - X NOW POINTS 406 ; TO TAP 407 FF65 86 10 stx D ; - GIVE PROMPT 408 FF67 20 88 FE jsr QDATFET ; - AND GET 2ND STORE INFO 409 FF6A A2 04 ldx #$04 ; - LOOP COUNT 410 FF6C B5 05 ADDRESS lda FAP-1,X ; - SEND ADDRESSES TO TAPE 411 FF6E 20 B1 FE jsr PUTBYTE ; 412 FF71 CA dex ; 413 FF72 D0 F8 bne ADDRESS ; - X NEATLY ZEROED ON EXIT 414 FF74 A1 06 DATAS lda (FAP,X) ; - DATA SEND - GET INFO FROM 415 ; MEMORY 416 FF76 20 B1 FE jsr PUTBYTE ; - AND SEND IT TO TAPE 417 FF79 20 A0 FE jsr COM16 ; - Increment and SEE IF FINISHED 418 FF7C D0 F6 bne DATAS ; - NO 419 FF7E F0 2A beq WAYOUT ; - YES 420 421 ; "LOAD" command 422 FF80 A2 04 LOAD ldx #$04 ; - LOOP COUNTER 423 FF82 20 DD FE ADDRSL jsr GETBYTE ; - RESCUE ADDRESSES FROM TAPE 424 FF85 95 05 sta FAP-1,X ; - PUT THEM IN FAP & TAP, THOUGH 425 ; IT COULD BE ELSEWHERE 426 FF87 CA dex ; 427 FF88 D0 F8 bne ADDRSL ; - X NEATLY ZEROED AGAIN 428 FF8A 20 DD FE DATAL jsr GETBYTE ; - GET DATA FROM TAPE 429 FF8D 81 06 sta (FAP,X) ; - AND STORE IT IN MEMORY 430 FF8F 8D 21 0E sta X1PIB ; - AND ON THE DISPLAY SO IT CAN BE 431 ; SEEN 432 FF92 20 A0 FE jsr COM16 ; - Increment and SEE IF FINISHED 433 FF95 D0 F3 bne DATAL ; - NO 434 FF97 F0 11 beq WAYOUT ; - YES 435 436 ; "POINT" command 437 FF99 A1 00 POINT lda (0,X) ; - SET/CLEAR BREAK POINT - GET 438 ; DATA FROM ADDRESSED MEMORY 439 FF9B F0 06 beq SET ; - IF ZERO BREAK POINT HAS 440 ; ALREADY BEEN SET = MUST CLEAR 441 ; IT 442 FF9D 85 18 sta P ; - NOT ZERO SO SAVE THE 443 ; INFORMATION 444 FF9F A9 00 lda #$00 ; - AND PUT IN A BREAK POINT 445 FFA1 F0 02 beq OUT ; 446 FFA3 A5 18 SET lda P ; - WAS SET SO GET OLD 447 ; INFORMATION BACK 448 FFA5 81 00 OUT sta ($00,X) ; - INSERT BREAK POINT OR OLD 449 ; INFORMATION 450 FFA7 20 5E FE jsr MHEXTD ; - NOW READ IT OUT AGAIN TO 451 ; REVEAL ROM 452 FFAA 4C 04 FF WAYOUT jmp RESTART ; - GO BACK & DO IT ALL OVER AGAIN 453 454 FFAD 6C 1C 00 NMI jmp (USERNMI) ; - INDIRECTION ON NMI 455 456 FFB0 6C 1E 00 IRQ jmp (USERIRQ) ; - INDIRECTION ON IRQ 457 458 ; --------------------------------------------------------------- 459 ; BREAK: ENTRY TO MONITOR FROM BRK INSTRUCTION, DISPLAY CPU 460 ; --------------------------------------------------------------- 461 FFB3 85 0A BREAK sta R0 ; - WHEN THE IRQ/BREAK VECTOR 462 ; POINTS HERE THEN DISPLAY 463 ; EVERYTHING - SAVE A 464 FFB5 86 0B stx R1 ; - SAVE X 465 FFB7 84 0C sty R2 ; - SAVE Y 466 FFB9 68 pla ; - GET P OFF STACK 467 FFBA 48 pha ; - PUT IT BACK FOR FUTURE USE 468 FFBB 85 0D sta R3 ; - STORE P IN REGISTER 3 469 FFBD A2 0D ldx #R3 ; - SET X TO POINT AT REGISTERS 470 ; 3 -> 0 FOR QUAD 471 FFBF A9 FF lda #$FF ; - KILL POSSIBILITY OF DISPLAY 472 ; BEING ON SINGLE SCAN 473 FFC1 85 0E sta REPEAT ; 474 FFC3 20 00 FE jsr QUAD ; - USE QUAD TO WRITE OUT A X Y P 475 ; (and wait for key) 476 FFC6 BA tsx ; - GET STACK POINTER 477 FFC7 86 13 stx R7 ; 478 FFC9 C8 iny ; - Y ZERO SINCE QUAD ENDED WITH 479 ; DISPLAY SO THIS FORMS 01 480 FFCA 84 12 sty R6 ; 481 FFCC D8 cld ; - CLEAR DECIMAL MODE FOR BINARY 482 ; SUBTRACT - DOESN'T AFFECT 483 ; USER SINCE P IS STACKED 484 FFCD BD 02 01 lda STACK+2,X ; - GET PCL OFF STACK 485 FFD0 38 sec ; 486 FFD1 E5 1B sbc RECAL ; - CORRECT IT BY AMOUNT IN RECAL 487 FFD3 9D 02 01 sta STACK+2,X ; - PUT IT BACK ON STACK 488 FFD6 85 11 sta R5 ; - AND STORE IT FOR QUAD 489 FFD8 BD 03 01 lda STACK+3,X ; - PCH OFF STACK 490 FFDB E9 00 sbc #$00 ; - REST OF TWO BYTE SUBTRACTION 491 FFDD 9D 03 01 sta STACK+3,X ; - PUT IT BACK ON STACK 492 FFE0 85 10 sta R4 ; - AND STORE IT FOR QUAD 493 FFE2 A2 13 ldx #R7 ; - POINT X AT THESE REGISTERS - 494 ; QUAD WILL DESTROY THEM 495 FFE4 20 00 FE jsr QUAD ; - QUAD WRITES OUT PC SP 496 ; (and waits for key) 497 FFE7 4C 07 FF jmp REENTER ; - AND THE WHOLE SHEBARG STARTS 498 ; OVER AGAIN 499 500 ; --------------------------------------------------------------- 501 ; FONT: SEVEN SEGMENT PICTURES OF THE HEX DIGITS 502 ; --------------------------------------------------------------- 503 ; [the bits are: 0(MSB)=d.p; 1=centre; 2=left-top; 3=left-bot; 504 ; 4=bot; 5=right-bot; 6=right-top; 7=top;] 505 FFEA 3F 06 5B 4F FONT .byte $3F,$06,$5B,$4F ; '0'-'3' 506 FFEE 66 6D 7D 07 .byte $66,$6D,$7D,$07 ; '4'-'7 507 FFF2 7F 6F 77 7C .byte $7F,$6F,$77,$7C ; '8','9','A','b' 508 FFF6 58 5E 79 71 .byte $58,$5E,$79,$71 ; 'c','d','E','F' 509 510 FFFA AD FF NMIVEC .word NMI ; - POINT TO THE ADDED INDIRECTION 511 FFFC F3 FE RSTVEC .word RESET ; - POINT TO THE RESET ENTRY POINT 512 FFFE B0 FF IRQVEC .word IRQ ; - POINT TO THE ADDED INDIRECTION 513 514 1000 .end tasm: Number of errors = 0