;********************************************************************************
;** An Assembly File Listing to generate an 8K ROM for the MICRO-POKEer device **
;********************************************************************************
; -------------------------
; Last updated: 15-NOV-2010
; -------------------------
; This assembly source based on MICRO-POKEer version 1.6 ROM.
; Compiling this source will produce byte-exact ROM image.
; Tested with Sjasm 0.42 but may compile with other Z80 compilers.
ORG $0000
; -----------------------------------
; KEYBOARD HANDLING RESTART (RST 00H)
; -----------------------------------
;; INKEY-1
L0000: JP L0228 ; jump to KEY-MAIN which calls KEY-SCAN
; and produces key click tones
DEFB $00, $00, $00 ; 5 unused bytes
DEFB $00, $00
; ----------------------------
; SAVE BYTES RESTART (RST 08H)
; ----------------------------
;; SAVE-NORMAL
L0008: CALL L14D5 ; wait for 1 second
JP L1000 ; jump to SA-BYTES
DEFB $00, $00 ; 2 unused bytes
; ----------------------------------
; TURBO LOAD BYTES RESTART (RST 10H)
; ----------------------------------
;; LOAD-TURBO
L0010: JP L10C8 ; jump to LD-BYTES TURBO version
DEFB $00, $00, $00 ; 5 unused bytes
DEFB $00, $00
; ----------------------------------
; TURBO SAVE BYTES RESTART (RST 18H)
; ----------------------------------
;; SAVE-TURBO
L0018: CALL L14D5 ; wait for 1 second
JP L1190 ; jump to SA-BYTES TURBO version
DEFB $00, $00 ; 2 unused bytes
; ------------------------
; UNUSED RESTART (RST 20H)
; ------------------------
L0020: JP $1224 ; this jumps to an unused area
DEFB $00, $00, $00 ; 5 unused bytes
DEFB $00, $00
; ------------------------
; UNUSED RESTART (RST 28H)
; ------------------------
L0028: DEFB $00, $00, $00 ; 8 unused bytes
DEFB $00, $00, $00
DEFB $00, $00
; ---------------------------------------
; THE KEYBOARD SCANNING RESTART (RST 30H)
; ---------------------------------------
;; INKEY-2
L0030: JP L1770 ; jump to KEY-SCAN
DEFB $00, $00, $00 ; 5 unused bytes
DEFB $00, $00
; ------------------------
; UNUSED RESTART (RST 38H)
; ------------------------
L0038: EI
RET
DEFB $00, $00, $00 ; 6 unused bytes
DEFB $00, $00, $00
; $0040
DEFM "MICRO-POKEer 1.6/00"
DEFB $00, $00, $00 ; 19 unused bytes
DEFB $00, $00, $00
DEFB $00, $00, $00
DEFB $00, $00, $00
DEFB $00, $00, $00
DEFB $00, $00, $00
DEFB $00
; ------------------------------------
; THE 'NON-MASKABLE INTERRUPT' ROUTINE
; ------------------------------------
; This is the main entry
; saves the current ZX Spectrum state
; and waits for a menu-key press
;; NMI-ENTRY
L0066: PUSH AF ; save registers
PUSH HL
LD A,I ; the Parity flag has state of IFF2
PUSH AF ; IFF2 holds IFF1 which was the EI/DI state
DI ; disable interrupts
LD A,R
PUSH AF
PUSH DE
PUSH BC
EX AF,AF'
PUSH AF
EX AF,AF'
EXX
PUSH HL
PUSH DE
PUSH BC
EXX
PUSH IX
PUSH IY
;; MAIN-KEYS
L007D: RST 00H ; Call KEY-MAIN to get
LD A,E ; a keypress
CP D ; wait until a valid
JR Z,L007D ; key is pressed
LD A,E
CP $0D ; R
JR Z,L00A7 ; jump to SAVE-TOTAL
CP $21 ; ENTER
JP Z,L052A ; jump to EXIT-POKER routine
CP $1E ; S
JP Z,L018E ; jump to SAVE-SCREEN
CP $1D ; W
JP Z,L130C ; jump to WARM-RESTART routine
CP $19 ; L
JP Z,L012E ; jump to LOAD-SCREEN (or LOAD-SNAPSHOT)
CP $10 ; M
JP Z,L1313 ; jump to MM-MAIN routine
CP $01 ; H
CALL Z,L17A8 ; call the SCROLL-MENU subroutine
JR L007D ; or else jump back to MAIN-KEYS
;; SAVE-TOTAL
L00A7: LD A,D
CP $27 ; caps-shift pressed?
JR Z,L00ED ; jump if capital 'R' pressed
LD DE,$11 ; if small 'r' pressed
LD IX,L1E94 ; save basic loader header
LD A,$00
RST 08H ; call save
LD DE,$10A ; save basic loader data
LD IX,L026D
LD A,$FF
RST 08H ; call save
LD DE,$11 ; save screen header
LD IX,L1EA5
LD A,$00
RST 08H ; call save
LD HL,($5B00) ; preserve data at $5800
EXX
LD ($5B00),SP ; save SP after attributes
LD DE,$1B02 ; save whole screen + SP
LD IX,$4000 ; screen start
LD A,$FF
RST 08H ; call save
EXX
LD ($5B00),HL ; restore data at $5800
LD DE,$A500 ; save whole memory (48K Spectrum!)
LD IX,$5B00 ; after attributes
LD A,$0F
RST 08H ; call save
JP L007D ; jump back to MAIN-KEYS
; resume here if capital 'R' pressed
;; SAVE-TOTAL-TURBO
L00ED: LD DE,$0011
LD IX,L1E94 ; save basic loader header
LD A,$00
RST 18H ; call turbo save
LD DE,$10A ; save basic loader data
LD IX,L026D
LD A,$FF
RST 18H ; call turbo save
LD DE,$11 ; save screen header
LD IX,L1EA5
LD A,$00
RST 18H ; call turbo save
LD HL,($5B00) ; preserve data at $5800
EXX
LD ($5B00),SP ; save SP after attributes
LD DE,$1B02 ; save whole screen + SP
LD IX,$4000 ; screen start
LD A,$FF
RST 18H ; call turbo save
EXX
LD ($5B00),HL ; restore data at $5800
LD DE,$A500 ; save whole memory (48K Spectrum!)
LD IX,$5B00 ; after attributes
LD A,$0F
RST 18H ; call turbo save
JP L007D ; jump back to MAIN-KEYS
;; LOAD-SCREEN
L012E: LD A,D
CP $27 ; is it caps-shift?
JP Z,L014D ; jump if capital 'L' pressed
LD DE,$11 ; if small 'l' pressed
LD IX,L0210 ; load screen header
LD A,$00
SCF
RST 10H ; call turbo load
LD DE,$1B00 ; load screen data
LD IX,$4000
LD A,$FF
SCF
RST 10H ; call turbo load
JP L007D ; jump back to MAIN-KEYS
; resume here if capital 'L' pressed
;; LOAD-SNAPSHOT
L014D: LD DE,$11 ; skip basic loader by loading it
LD IX,L0210 ; load screen header
LD A,$00 ; which is incorrect
SCF ; because basic data follows
RST 10H ; call turbo load
LD DE,$10A ; load basic loader data
LD IX,L026D
LD A,$FF
SCF
RST 10H ; call turbo load
LD DE,$11 ; load screen header
LD IX,L1EA5
LD A,$00
SCF
RST 10H ; call turbo load
LD DE,$1B02 ; load screen data + SP
LD IX,$4000
LD A,$FF
SCF
RST 10H ; call turbo load
LD HL,($5B00)
EXX
LD SP,$4009 ; give SP a short buffer
; this will mess the top of
; the screen but there is no
; other place for SP
LD DE,$A500 ; load whole snapshot
LD IX,$5B00
LD A,$0F
SCF
RST 10H ; call turbo load
JP L0528 ; continue program execution
; by jumping to EXIT-LOAD
;; SAVE-SCREEN
L018E: LD A,D
CP $27 ; is it caps-shift?
JR Z,L01AA ; jump if capital 'S' pressed
LD DE,$0011 ; if small 's' pressed
LD IX,L0210 ; save screen header
LD A,$00
RST 08H ; call save
LD A,$FF
LD DE,$1B00 ; save screen data
LD IX,$4000
RST 08H ; call save
JP L007D ; jump back to MAIN-KEYS
; resume here if capital 'S' pressed
;; SAVE-SCREEN-TURBO
L01AA: LD DE,$0011
LD IX,L0210 ; save screen header
LD A,$00
RST 18H ; call turbo save
LD A,$FF
LD DE,$1B00 ; save screen data
LD IX,$4000
RST 18H ; call turbo save
JP L007D ; jump back to MAIN-KEYS
LD B,B ; garbage code
RST 18H ; left here
JP L007D
DEFM "POPALL #52A-TOL MOVE"
; This part (1DA-205) is almost a direct copy of 52A-555
; But this 01DA routine never gets executed
L01DA: POP IY ; restore registers
POP IX
EXX
POP BC
POP DE
POP HL
EXX
EX AF,AF'
POP AF
EX AF,AF'
POP BC
POP DE
POP AF
LD R,A
POP AF
LD I,A ; restore EI/DI state by observing
JP PO,$0544 ; the restored parity flag
EI
JR L01F5
DI
L01F5: POP HL ; This POP is late, should be before EI
CP $3F ; Spectrum ROM sets I to $3F in START-NEW routine
JR NZ,L01FE ; if I was not $3F we should restore IM 2 mode.
IM 1 ; restore interrupt mode 1 - Spectrum ROM default
JR L0200
L01FE: IM 2
L0200: LD A,$00 ; exit from MICRO-POKEer by
OUT ($7F),A ; switching back to original Spectrum ROM
POP AF ; this piece of code never gets executed
RET ; these are the same in the original ROM
POP DE ; garbage code
POP DE ;
JP $007C ;
NOP
NOP
NOP
NOP
NOP
; screen header descriptor
L0210: DEFB $03 ; type code
DEFM "SCREEN " ; filename
DEFB $00, $1B ; length 6192 bytes
DEFB $00, $40 ; start address $4000
DEFB $00, $80 ; unused $8000
DEFB $00, $00, $00 ; 7 unused bytes
DEFB $00, $00, $00
DEFB $00
; -------------------------
; KEYBOARD HANDLING ROUTINE
; -------------------------
; Calls the copy of the original Spectrum KEY-SCAN routine
; and produces a key-tone if a non-shift key pressed.
; The key(s) is returned in the DE register pair.
; It produces lower-pitched key-tone for Micro-monitor.
;; KEY-MAIN
L0228: RST 30H ; call routine KEY-SCAN: keys in D and E registers
LD A,E ; compare D to E
CP D ; if no keys pressed these are all $FF
RET Z ; return if no key pressed
CP $18 ; first key in E - is it symbol shift?
RET Z ; return if just symbol shift pressed
CP $27 ; first key in E - is it caps shift?
RET Z ; return if just caps shift pressed
; changes the key tone for different calling addresses
POP HL ; HL = the return address (caller address + 1)
PUSH HL ; called from memory $00xx?
LD A,H ; this must be MAIN-KEYS
CP $00 ; return address is $007E
JR Z,L0242 ; key-tone will be higher
LD A,L ; possible return addresses: $137B, $13CF, $13EC
CP $7D ; so there is no return address ending with $7D
JR Z,L0242
LD L,$40 ; tone is lower (called from Micro-monitor)
JR L0244
L0242: LD L,$28 ; tone is higher
;; KEY-TONE
L0244: LD B,$D0 ; cycle 208 times
LD C,$07 ; white border and speaker off
L0248: LD A,C
OUT ($FE),A
XOR $F8 ; turns on/off the speaker (why not just XOR $10?)
LD C,A ; with L as the period/frequency
LD H,L
L024F: DEC H ; wait for L-times
JR NZ,L024F ; before change speaker state
DJNZ L0248
;; KEY-RELEASE
L0254: XOR A
IN A,($FE) ; wait for key-release
AND $1F ; before exit routine
CP $1F
JR NZ,L0254
EI ; enable interrupts
RET
DEFB $FF, $FF, $FF ; 14 unused bytes
DEFB $FF, $FF, $FF
DEFB $FF, $FF, $FF
DEFB $00, $00, $00
DEFB $00, $00
; ------------
; BASIC LOADER
; ------------
; This is the Basic Loader which will be put in front of snapshot if "Total RAM SAVE" selected.
; It stores a machine code in the variables area.
; This program loads the screen and then it will call a machine code loader (which calls ZX ROM)
; to load the snapshot data and resume the program execution.
; BUG: No Turbo Loader alternative so "TURBO total RAM SAVE" will fail at load.
; This is the Basic loader listing:
; 10 PRINT AT 10,4;"V&REW software Hungary"
; 20 PRINT AT 10,4; OVER 1;"!'|!!"
; 25 LOAD "" CODE 16384
; 40 FOR a=1 TO 66: POKE a+16383, CODE c$(a): NEXT a
; 50 RANDOMIZE USR 16384
; Note: Line 20 is just a little modification on the copyright text: W&REW software Hungary
; EPROM data $26D-$31B basic program, $31C-$376 variables
;; BASIC-LOADER
L026D: DEFB $00, $0A, $2C, $00, $F5, $AC, $31, $30
DEFB $0E, $00, $00, $0A, $00, $00, $2C, $34
DEFB $0E, $00, $00, $04, $00, $00, $3B, $22
DEFB $56, $26, $52, $45, $57, $20, $73, $6F
DEFB $66, $74, $77, $61, $72, $65, $20, $48
DEFB $75, $6E, $67, $61, $72, $79, $22, $0D
; 10 PRINT AT 10,4;"V&REW software Hungary"
DEFB $00, $14, $24, $00, $F5, $AC, $31, $30
DEFB $0E, $00, $00, $0A, $00, $00, $2C, $34
DEFB $0E, $00, $00, $04, $00, $00, $3B, $DE
DEFB $31, $0E, $00, $00, $01, $00, $00, $3B
DEFB $22, $21, $27, $7C, $21, $21, $22, $0D
; 20 PRINT AT 10,4; OVER 1;"!'|!!"
DEFB $00, $19, $10, $00, $EF, $22, $22, $AF
DEFB $31, $36, $33, $38, $34, $0E, $00, $00
DEFB $00, $40, $00, $0D
; 25 LOAD "" CODE 16384
DEFB $00, $28, $2D, $00, $EB, $61, $3D, $31
DEFB $0E, $00, $00, $01, $00, $00, $CC, $36
DEFB $36, $0E, $00, $00, $42, $00, $00, $3A
DEFB $F4, $61, $2B, $31, $36, $33, $38, $33
DEFB $0E, $00, $00, $FF, $3F, $00, $2C, $AF
DEFB $63, $24, $28, $61, $29, $3A, $F3, $61
DEFB $0D
; 40 FOR a=1 TO 66: POKE a+16383, CODE c$(a): NEXT a
DEFB $00, $32, $0E, $00, $F9, $C0, $31, $36
DEFB $33, $38, $34, $0E, $00, $00, $00, $40
DEFB $00, $0D
; 50 RANDOMIZE USR 16384
; variables
DEFB $C3, $45, $00, $01, $42, $00
; c$ = 66 bytes...
; code hiding in variables which restores the cpu state
; and continues the execution of the saved snapshot
; note that this code will be relocated to $4000 (screen start)
; so this will mess up the first 66 bytes of the screen
; $0322
NOP ; starting with some NOPs
NOP ; these are here to make
NOP ; room for a temporary stack
NOP ; see below
NOP
NOP
NOP
NOP
LD HL,($5B00) ; saved SP when program was frozen
; this is saved along with screen data
EXX ; switch to alternate set
LD DE,$A500 ; length $A500
LD IX,$5B00 ; start $5B00
LD A,$0F
SCF ; load bytes flag
LD SP,$4009 ; temporary stack pointer
; because memory from $5B00
; will be overwritten
CALL $0556 ; call LD-BYTES from the
; original Spectrum ROM
; to load the snapshot file
EXX ; switch back to main set
LD SP,HL ; restore SP
POP IY ; restore all registers
POP IX ; saved on NMI
EXX
POP BC
POP DE
POP HL
EXX
EX AF,AF'
POP AF
EX AF,AF'
POP BC
POP DE
POP AF
LD R,A
POP AF
LD I,A ; restore interrupt state
JP PO,$4038 ; EI or DI
; note this "weird" absolute jump
; this code will be copied to $4000
EI
JR L035B
DI ; at $4038
L035B: POP HL ; restore interrupt mode
CP $3F ; IM2 or leave in IM1
JR Z,L0362
IM 2
L0362: POP AF
RET ; continue running the
; saved snapshot
; variable data for the FOR loop:
DEFB $E1, $00, $00, $43, $00, $00, $00, $00
DEFB $42, $00, $00, $00, $00, $01, $00, $00
DEFB $28, $00, $02
;; END OF BASIC LOADER
; $0377 - unknown data
DEFB $00, $00, $40, $00, $0D, $83, $93, $01, $01
; ----------------------------
; 385 unused bytes: $0380-$500
; ----------------------------
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF
; garbage data? $501-$527
DEFB $00, $00, $00, $00, $00, $00, $00, $00
DEFB $00, $00, $00, $00, $00, $00, $00, $00
DEFB $00, $E1, $00, $00, $2D, $00, $00, $00
DEFB $00, $3C, $00, $00, $00, $00, $01, $00
DEFB $00, $FE, $FF, $02, $00, $00, $00
;; EXIT-LOAD
L0528: EXX ; switch back to main set
LD SP,HL ; restore SP from HL
; --------------------------------
; 'EXIT FROM MICRO-POKEer' ROUTINE
; --------------------------------
; Restores the registers, the interrupt mode
; and the interrupt state then switches back
; the original ZX Spectrum ROM
;; EXIT-POKER
L052A: POP IY ; restore all the registers
POP IX ; saved on NMI
EXX
POP BC
POP DE
POP HL
EXX
EX AF,AF'
POP AF
EX AF,AF'
POP BC
POP DE
POP AF
LD R,A
POP AF ; parity flag stores IFF2 (which stores IFF1)
LD I,A
POP HL
JP PO,L0545 ; interrupts was enabled or not?
EI ; restore Enable Interrupts
JR L0546
L0545: DI ; restore Disable Interrupts
L0546: CP $3F ; Spectrum ROM sets I to $3F in START-NEW routine
JR NZ,L054E ; if I was not $3F we should restore IM 2 mode.
IM 1 ; restore interrupt mode 1 - Spectrum ROM default
JR L0550
L054E: IM 2 ; restore interrupt mode 2
L0550: LD A,$00 ; exit from MICRO-POKEer by
OUT ($7F),A ; switching back to original Spectrum ROM
POP AF ; this piece of code never gets executed
RET ; these are the same in the original ROM
DEFB $00, $5A
; 0558 - doesn't seem to be called
LD B,$04 ; push the previous 8 bytes of data
L055A: LD E,(HL) ; pointed by HL on the stack
DEC HL
LD D,(HL)
DEC HL
PUSH DE
DJNZ L055A
EXX
JP $00AF ; jump to ...
DEFB $FF, $FF, $FF ; 11 unused bytes
DEFB $FF, $FF, $FF
DEFB $FF, $FF, $FF
DEFB $FF, $FF
DEFM "MONITOR #570-#1E7E-IG"
DEFB $FF, $FF, $FF ; 3 unused bytes
; -------------------------------
; THE 'ZX SPECTRUM CHARACTER SET'
; -------------------------------
; Copy from the original ZX Spectrum ROM
; $20 - Character: ' ' CHR$(32)
L0588: DEFB %00000000
DEFB %00000000
DEFB %00000000
DEFB %00000000
DEFB %00000000
DEFB %00000000
DEFB %00000000
DEFB %00000000
; $21 - Character: '!' CHR$(33)
DEFB %00000000
DEFB %00010000
DEFB %00010000
DEFB %00010000
DEFB %00010000
DEFB %00000000
DEFB %00010000
DEFB %00000000
; $22 - Character: '"' CHR$(34)
DEFB %00000000
DEFB %00100100
DEFB %00100100
DEFB %00000000
DEFB %00000000
DEFB %00000000
DEFB %00000000
DEFB %00000000
; $23 - Character: '#' CHR$(35)
DEFB %00000000
DEFB %00100100
DEFB %01111110
DEFB %00100100
DEFB %00100100
DEFB %01111110
DEFB %00100100
DEFB %00000000
; $24 - Character: '$' CHR$(36)
DEFB %00000000
DEFB %00001000
DEFB %00111110
DEFB %00101000
DEFB %00111110
DEFB %00001010
DEFB %00111110
DEFB %00001000
; $25 - Character: '%' CHR$(37)
DEFB %00000000
DEFB %01100010
DEFB %01100100
DEFB %00001000
DEFB %00010000
DEFB %00100110
DEFB %01000110
DEFB %00000000
; $26 - Character: '&' CHR$(38)
DEFB %00000000
DEFB %00010000
DEFB %00101000
DEFB %00010000
DEFB %00101010
DEFB %01000100
DEFB %00111010
DEFB %00000000
; $27 - Character: ''' CHR$(39)
DEFB %00000000
DEFB %00001000
DEFB %00010000
DEFB %00000000
DEFB %00000000
DEFB %00000000
DEFB %00000000
DEFB %00000000
; $28 - Character: '(' CHR$(40)
DEFB %00000000
DEFB %00000100
DEFB %00001000
DEFB %00001000
DEFB %00001000
DEFB %00001000
DEFB %00000100
DEFB %00000000
; $29 - Character: ')' CHR$(41)
DEFB %00000000
DEFB %00100000
DEFB %00010000
DEFB %00010000
DEFB %00010000
DEFB %00010000
DEFB %00100000
DEFB %00000000
; $2A - Character: '*' CHR$(42)
DEFB %00000000
DEFB %00000000
DEFB %00010100
DEFB %00001000
DEFB %00111110
DEFB %00001000
DEFB %00010100
DEFB %00000000
; $2B - Character: '+' CHR$(43)
DEFB %00000000
DEFB %00000000
DEFB %00001000
DEFB %00001000
DEFB %00111110
DEFB %00001000
DEFB %00001000
DEFB %00000000
; $2C - Character: ',' CHR$(44)
DEFB %00000000
DEFB %00000000
DEFB %00000000
DEFB %00000000
DEFB %00000000
DEFB %00001000
DEFB %00001000
DEFB %00010000
; $2D - Character: '-' CHR$(45)
DEFB %00000000
DEFB %00000000
DEFB %00000000
DEFB %00000000
DEFB %00111110
DEFB %00000000
DEFB %00000000
DEFB %00000000
; $2E - Character: '.' CHR$(46)
DEFB %00000000
DEFB %00000000
DEFB %00000000
DEFB %00000000
DEFB %00000000
DEFB %00011000
DEFB %00011000
DEFB %00000000
; $2F - Character: '/' CHR$(47)
DEFB %00000000
DEFB %00000000
DEFB %00000010
DEFB %00000100
DEFB %00001000
DEFB %00010000
DEFB %00100000
DEFB %00000000
; $30 - Character: '0' CHR$(48)
DEFB %00000000
DEFB %00111100
DEFB %01000110
DEFB %01001010
DEFB %01010010
DEFB %01100010
DEFB %00111100
DEFB %00000000
; $31 - Character: '1' CHR$(49)
DEFB %00000000
DEFB %00011000
DEFB %00101000
DEFB %00001000
DEFB %00001000
DEFB %00001000
DEFB %00111110
DEFB %00000000
; $32 - Character: '2' CHR$(50)
DEFB %00000000
DEFB %00111100
DEFB %01000010
DEFB %00000010
DEFB %00111100
DEFB %01000000
DEFB %01111110
DEFB %00000000
; $33 - Character: '3' CHR$(51)
DEFB %00000000
DEFB %00111100
DEFB %01000010
DEFB %00001100
DEFB %00000010
DEFB %01000010
DEFB %00111100
DEFB %00000000
; $34 - Character: '4' CHR$(52)
DEFB %00000000
DEFB %00001000
DEFB %00011000
DEFB %00101000
DEFB %01001000
DEFB %01111110
DEFB %00001000
DEFB %00000000
; $35 - Character: '5' CHR$(53)
DEFB %00000000
DEFB %01111110
DEFB %01000000
DEFB %01111100
DEFB %00000010
DEFB %01000010
DEFB %00111100
DEFB %00000000
; $36 - Character: '6' CHR$(54)
DEFB %00000000
DEFB %00111100
DEFB %01000000
DEFB %01111100
DEFB %01000010
DEFB %01000010
DEFB %00111100
DEFB %00000000
; $37 - Character: '7' CHR$(55)
DEFB %00000000
DEFB %01111110
DEFB %00000010
DEFB %00000100
DEFB %00001000
DEFB %00010000
DEFB %00010000
DEFB %00000000
; $38 - Character: '8' CHR$(56)
DEFB %00000000
DEFB %00111100
DEFB %01000010
DEFB %00111100
DEFB %01000010
DEFB %01000010
DEFB %00111100
DEFB %00000000
; $39 - Character: '9' CHR$(57)
DEFB %00000000
DEFB %00111100
DEFB %01000010
DEFB %01000010
DEFB %00111110
DEFB %00000010
DEFB %00111100
DEFB %00000000
; $3A - Character: ':' CHR$(58)
DEFB %00000000
DEFB %00000000
DEFB %00000000
DEFB %00010000
DEFB %00000000
DEFB %00000000
DEFB %00010000
DEFB %00000000
; $3B - Character: ';' CHR$(59)
DEFB %00000000
DEFB %00000000
DEFB %00010000
DEFB %00000000
DEFB %00000000
DEFB %00010000
DEFB %00010000
DEFB %00100000
; $3C - Character: '<' CHR$(60)
DEFB %00000000
DEFB %00000000
DEFB %00000100
DEFB %00001000
DEFB %00010000
DEFB %00001000
DEFB %00000100
DEFB %00000000
; $3D - Character: '=' CHR$(61)
DEFB %00000000
DEFB %00000000
DEFB %00000000
DEFB %00111110
DEFB %00000000
DEFB %00111110
DEFB %00000000
DEFB %00000000
; $3E - Character: '>' CHR$(62)
DEFB %00000000
DEFB %00000000
DEFB %00010000
DEFB %00001000
DEFB %00000100
DEFB %00001000
DEFB %00010000
DEFB %00000000
; $3F - Character: '?' CHR$(63)
DEFB %00000000
DEFB %00111100
DEFB %01000010
DEFB %00000100
DEFB %00001000
DEFB %00000000
DEFB %00001000
DEFB %00000000
; $40 - Character: '@' CHR$(64)
DEFB %00000000
DEFB %00111100
DEFB %01001010
DEFB %01010110
DEFB %01011110
DEFB %01000000
DEFB %00111100
DEFB %00000000
; $41 - Character: 'A' CHR$(65)
DEFB %00000000
DEFB %00111100
DEFB %01000010
DEFB %01000010
DEFB %01111110
DEFB %01000010
DEFB %01000010
DEFB %00000000
; $42 - Character: 'B' CHR$(66)
DEFB %00000000
DEFB %01111100
DEFB %01000010
DEFB %01111100
DEFB %01000010
DEFB %01000010
DEFB %01111100
DEFB %00000000
; $43 - Character: 'C' CHR$(67)
DEFB %00000000
DEFB %00111100
DEFB %01000010
DEFB %01000000
DEFB %01000000
DEFB %01000010
DEFB %00111100
DEFB %00000000
; $44 - Character: 'D' CHR$(68)
DEFB %00000000
DEFB %01111000
DEFB %01000100
DEFB %01000010
DEFB %01000010
DEFB %01000100
DEFB %01111000
DEFB %00000000
; $45 - Character: 'E' CHR$(69)
DEFB %00000000
DEFB %01111110
DEFB %01000000
DEFB %01111100
DEFB %01000000
DEFB %01000000
DEFB %01111110
DEFB %00000000
; $46 - Character: 'F' CHR$(70)
DEFB %00000000
DEFB %01111110
DEFB %01000000
DEFB %01111100
DEFB %01000000
DEFB %01000000
DEFB %01000000
DEFB %00000000
; $47 - Character: 'G' CHR$(71)
DEFB %00000000
DEFB %00111100
DEFB %01000010
DEFB %01000000
DEFB %01001110
DEFB %01000010
DEFB %00111100
DEFB %00000000
; $48 - Character: 'H' CHR$(72)
DEFB %00000000
DEFB %01000010
DEFB %01000010
DEFB %01111110
DEFB %01000010
DEFB %01000010
DEFB %01000010
DEFB %00000000
; $49 - Character: 'I' CHR$(73)
DEFB %00000000
DEFB %00111110
DEFB %00001000
DEFB %00001000
DEFB %00001000
DEFB %00001000
DEFB %00111110
DEFB %00000000
; $4A - Character: 'J' CHR$(74)
DEFB %00000000
DEFB %00000010
DEFB %00000010
DEFB %00000010
DEFB %01000010
DEFB %01000010
DEFB %00111100
DEFB %00000000
; $4B - Character: 'K' CHR$(75)
DEFB %00000000
DEFB %01000100
DEFB %01001000
DEFB %01110000
DEFB %01001000
DEFB %01000100
DEFB %01000010
DEFB %00000000
; $4C - Character: 'L' CHR$(76)
DEFB %00000000
DEFB %01000000
DEFB %01000000
DEFB %01000000
DEFB %01000000
DEFB %01000000
DEFB %01111110
DEFB %00000000
; $4D - Character: 'M' CHR$(77)
DEFB %00000000
DEFB %01000010
DEFB %01100110
DEFB %01011010
DEFB %01000010
DEFB %01000010
DEFB %01000010
DEFB %00000000
; $4E - Character: 'N' CHR$(78)
DEFB %00000000
DEFB %01000010
DEFB %01100010
DEFB %01010010
DEFB %01001010
DEFB %01000110
DEFB %01000010
DEFB %00000000
; $4F - Character: 'O' CHR$(79)
DEFB %00000000
DEFB %00111100
DEFB %01000010
DEFB %01000010
DEFB %01000010
DEFB %01000010
DEFB %00111100
DEFB %00000000
; $50 - Character: 'P' CHR$(80)
DEFB %00000000
DEFB %01111100
DEFB %01000010
DEFB %01000010
DEFB %01111100
DEFB %01000000
DEFB %01000000
DEFB %00000000
; $51 - Character: 'Q' CHR$(81)
DEFB %00000000
DEFB %00111100
DEFB %01000010
DEFB %01000010
DEFB %01010010
DEFB %01001010
DEFB %00111100
DEFB %00000000
; $52 - Character: 'R' CHR$(82)
DEFB %00000000
DEFB %01111100
DEFB %01000010
DEFB %01000010
DEFB %01111100
DEFB %01000100
DEFB %01000010
DEFB %00000000
; $53 - Character: 'S' CHR$(83)
DEFB %00000000
DEFB %00111100
DEFB %01000000
DEFB %00111100
DEFB %00000010
DEFB %01000010
DEFB %00111100
DEFB %00000000
; $54 - Character: 'T' CHR$(84)
DEFB %00000000
DEFB %11111110
DEFB %00010000
DEFB %00010000
DEFB %00010000
DEFB %00010000
DEFB %00010000
DEFB %00000000
; $55 - Character: 'U' CHR$(85)
DEFB %00000000
DEFB %01000010
DEFB %01000010
DEFB %01000010
DEFB %01000010
DEFB %01000010
DEFB %00111100
DEFB %00000000
; $56 - Character: 'V' CHR$(86)
DEFB %00000000
DEFB %01000010
DEFB %01000010
DEFB %01000010
DEFB %01000010
DEFB %00100100
DEFB %00011000
DEFB %00000000
; $57 - Character: 'W' CHR$(87)
DEFB %00000000
DEFB %01000010
DEFB %01000010
DEFB %01000010
DEFB %01000010
DEFB %01011010
DEFB %00100100
DEFB %00000000
; $58 - Character: 'X' CHR$(88)
DEFB %00000000
DEFB %01000010
DEFB %00100100
DEFB %00011000
DEFB %00011000
DEFB %00100100
DEFB %01000010
DEFB %00000000
; $59 - Character: 'Y' CHR$(89)
DEFB %00000000
DEFB %10000010
DEFB %01000100
DEFB %00101000
DEFB %00010000
DEFB %00010000
DEFB %00010000
DEFB %00000000
; $5A - Character: 'Z' CHR$(90)
DEFB %00000000
DEFB %01111110
DEFB %00000100
DEFB %00001000
DEFB %00010000
DEFB %00100000
DEFB %01111110
DEFB %00000000
; $5B - Character: '[' CHR$(91)
DEFB %00000000
DEFB %00001110
DEFB %00001000
DEFB %00001000
DEFB %00001000
DEFB %00001000
DEFB %00001110
DEFB %00000000
; $5C - Character: '\' CHR$(92)
DEFB %00000000
DEFB %00000000
DEFB %01000000
DEFB %00100000
DEFB %00010000
DEFB %00001000
DEFB %00000100
DEFB %00000000
; $5D - Character: ']' CHR$(93)
DEFB %00000000
DEFB %01110000
DEFB %00010000
DEFB %00010000
DEFB %00010000
DEFB %00010000
DEFB %01110000
DEFB %00000000
; $5E - Character: '^' CHR$(94)
DEFB %00000000
DEFB %00010000
DEFB %00111000
DEFB %01010100
DEFB %00010000
DEFB %00010000
DEFB %00010000
DEFB %00000000
; $5F - Character: '_' CHR$(95)
DEFB %00000000
DEFB %00000000
DEFB %00000000
DEFB %00000000
DEFB %00000000
DEFB %00000000
DEFB %00000000
DEFB %11111111
; $60 - Character: ' £ ' CHR$(96)
DEFB %00000000
DEFB %00011100
DEFB %00100010
DEFB %01111000
DEFB %00100000
DEFB %00100000
DEFB %01111110
DEFB %00000000
; $61 - Character: 'a' CHR$(97)
DEFB %00000000
DEFB %00000000
DEFB %00111000
DEFB %00000100
DEFB %00111100
DEFB %01000100
DEFB %00111100
DEFB %00000000
; $62 - Character: 'b' CHR$(98)
DEFB %00000000
DEFB %00100000
DEFB %00100000
DEFB %00111100
DEFB %00100010
DEFB %00100010
DEFB %00111100
DEFB %00000000
; $63 - Character: 'c' CHR$(99)
DEFB %00000000
DEFB %00000000
DEFB %00011100
DEFB %00100000
DEFB %00100000
DEFB %00100000
DEFB %00011100
DEFB %00000000
; $64 - Character: 'd' CHR$(100)
DEFB %00000000
DEFB %00000100
DEFB %00000100
DEFB %00111100
DEFB %01000100
DEFB %01000100
DEFB %00111100
DEFB %00000000
; $65 - Character: 'e' CHR$(101)
DEFB %00000000
DEFB %00000000
DEFB %00111000
DEFB %01000100
DEFB %01111000
DEFB %01000000
DEFB %00111100
DEFB %00000000
; $66 - Character: 'f' CHR$(102)
DEFB %00000000
DEFB %00001100
DEFB %00010000
DEFB %00011000
DEFB %00010000
DEFB %00010000
DEFB %00010000
DEFB %00000000
; $67 - Character: 'g' CHR$(103)
DEFB %00000000
DEFB %00000000
DEFB %00111100
DEFB %01000100
DEFB %01000100
DEFB %00111100
DEFB %00000100
DEFB %00111000
; $68 - Character: 'h' CHR$(104)
DEFB %00000000
DEFB %01000000
DEFB %01000000
DEFB %01111000
DEFB %01000100
DEFB %01000100
DEFB %01000100
DEFB %00000000
; $69 - Character: 'i' CHR$(105)
DEFB %00000000
DEFB %00010000
DEFB %00000000
DEFB %00110000
DEFB %00010000
DEFB %00010000
DEFB %00111000
DEFB %00000000
; $6A - Character: 'j' CHR$(106)
DEFB %00000000
DEFB %00000100
DEFB %00000000
DEFB %00000100
DEFB %00000100
DEFB %00000100
DEFB %00100100
DEFB %00011000
; $6B - Character: 'k' CHR$(107)
DEFB %00000000
DEFB %00100000
DEFB %00101000
DEFB %00110000
DEFB %00110000
DEFB %00101000
DEFB %00100100
DEFB %00000000
; $6C - Character: 'l' CHR$(108)
DEFB %00000000
DEFB %00010000
DEFB %00010000
DEFB %00010000
DEFB %00010000
DEFB %00010000
DEFB %00001100
DEFB %00000000
; $6D - Character: 'm' CHR$(109)
DEFB %00000000
DEFB %00000000
DEFB %01101000
DEFB %01010100
DEFB %01010100
DEFB %01010100
DEFB %01010100
DEFB %00000000
; $6E - Character: 'n' CHR$(110)
DEFB %00000000
DEFB %00000000
DEFB %01111000
DEFB %01000100
DEFB %01000100
DEFB %01000100
DEFB %01000100
DEFB %00000000
; $6F - Character: 'o' CHR$(111)
DEFB %00000000
DEFB %00000000
DEFB %00111000
DEFB %01000100
DEFB %01000100
DEFB %01000100
DEFB %00111000
DEFB %00000000
; $70 - Character: 'p' CHR$(112)
DEFB %00000000
DEFB %00000000
DEFB %01111000
DEFB %01000100
DEFB %01000100
DEFB %01111000
DEFB %01000000
DEFB %01000000
; $71 - Character: 'q' CHR$(113)
DEFB %00000000
DEFB %00000000
DEFB %00111100
DEFB %01000100
DEFB %01000100
DEFB %00111100
DEFB %00000100
DEFB %00000110
; $72 - Character: 'r' CHR$(114)
DEFB %00000000
DEFB %00000000
DEFB %00011100
DEFB %00100000
DEFB %00100000
DEFB %00100000
DEFB %00100000
DEFB %00000000
; $73 - Character: 's' CHR$(115)
DEFB %00000000
DEFB %00000000
DEFB %00111000
DEFB %01000000
DEFB %00111000
DEFB %00000100
DEFB %01111000
DEFB %00000000
; $74 - Character: 't' CHR$(116)
DEFB %00000000
DEFB %00010000
DEFB %00111000
DEFB %00010000
DEFB %00010000
DEFB %00010000
DEFB %00001100
DEFB %00000000
; $75 - Character: 'u' CHR$(117)
DEFB %00000000
DEFB %00000000
DEFB %01000100
DEFB %01000100
DEFB %01000100
DEFB %01000100
DEFB %00111000
DEFB %00000000
; $76 - Character: 'v' CHR$(118)
DEFB %00000000
DEFB %00000000
DEFB %01000100
DEFB %01000100
DEFB %00101000
DEFB %00101000
DEFB %00010000
DEFB %00000000
; $77 - Character: 'w' CHR$(119)
DEFB %00000000
DEFB %00000000
DEFB %01000100
DEFB %01010100
DEFB %01010100
DEFB %01010100
DEFB %00101000
DEFB %00000000
; $78 - Character: 'x' CHR$(120)
DEFB %00000000
DEFB %00000000
DEFB %01000100
DEFB %00101000
DEFB %00010000
DEFB %00101000
DEFB %01000100
DEFB %00000000
; $79 - Character: 'y' CHR$(121)
DEFB %00000000
DEFB %00000000
DEFB %01000100
DEFB %01000100
DEFB %01000100
DEFB %00111100
DEFB %00000100
DEFB %00111000
; $7A - Character: 'z' CHR$(122)
DEFB %00000000
DEFB %00000000
DEFB %01111100
DEFB %00001000
DEFB %00010000
DEFB %00100000
DEFB %01111100
DEFB %00000000
; $7B - Character: '{' CHR$(123)
DEFB %00000000
DEFB %00001110
DEFB %00001000
DEFB %00110000
DEFB %00001000
DEFB %00001000
DEFB %00001110
DEFB %00000000
; $7C - Character: '|' CHR$(124)
DEFB %00000000
DEFB %00001000
DEFB %00001000
DEFB %00001000
DEFB %00001000
DEFB %00001000
DEFB %00001000
DEFB %00000000
; $7D - Character: '}' CHR$(125)
DEFB %00000000
DEFB %01110000
DEFB %00010000
DEFB %00001100
DEFB %00010000
DEFB %00010000
DEFB %01110000
DEFB %00000000
; $7E - Character: '~' CHR$(126)
DEFB %00000000
DEFB %00010100
DEFB %00101000
DEFB %00000000
DEFB %00000000
DEFB %00000000
DEFB %00000000
DEFB %00000000
; $7F - Character: '©' CHR$(127)
DEFB %00111100
DEFB %01000010
DEFB %10011001
DEFB %10100001
DEFB %10100001
DEFB %10011001
DEFB %01000010
DEFB %00111100
; $80 - First UDG character CHR$(128)
DEFB %11111111
DEFB %11111111
DEFB %11111111
DEFB %11111111
DEFB %11111111
DEFB %11111111
DEFB %11111111
DEFB %11111111
; ----------------------
; MICRO-POKEer MENU TEXT
; ----------------------
; scrolling menu text
;; SCROLLER
L0890: DEFM "MICRO-POKEer v1.6 "
DEFM "Space:exit from HELP "
DEFM "ENTER:Return "
DEFM "r:Total RAM SAVE "
DEFM "R:TURBO total RAM SAVE "
DEFM "s:SCREEN SAVE "
DEFM "S:TURBO SCREEN SAVE "
DEFM "l:TURBO SCREEN LOAD "
DEFM "L:TURBO total RAM LOAD "
DEFM "w:Warm RESET "
DEFM "H:HELP "
DEFM "m:Micro-monitor q/a/o/p/ENTER:move box "
DEFM "input address (dec) q:quit j:jump ENTER:new addr.p:POKE data "
DEFM "MICRO-STUDIO "
DEFM "............................ "
L09EE: DEFM " "
; ------------------------------
; 1190 unused bytes: $0A10-$0EB5
; ------------------------------
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF
; -----------------------------
; MICRO-MONITOR CURSOR ROUTINES
; -----------------------------
;; MM-CURSOR
L0EB6: LD BC,$0000 ; initialize to X=0, Y=0
LD ($7000),BC
;; MM-SELECT
L0EBD: CALL L0EE1 ; calls MM-INVERT to invert
; pixels pointed BC by (Y/X)
;; MM-DELAY
L0EC0: IM 1 ; set Interrupt Mode 1 and
EI ; Enable Interrupt to
LD B,$03 ; wait for 3/50 second (60 msec)
L0EC5: HALT
DJNZ L0EC5
; Micro-Monitor key event handler
;; MM-KEYS
L0EC8: CALL L0030 ; KEY-SCAN (RST 30H instead?)
LD A,E ; wait until a key pressed from the
LD HL,L0F76 ; MM-TABLE at L0F76
LD B,$05 ; table has 5 elements (key-address pairs)
;; MM-TEST
L0ED1: CP (HL) ; key found?
JR NZ,L0EDA ; skip to next element if not
INC HL
LD E,(HL) ; DE has the address
INC HL ; associated with the key
LD D,(HL)
EX DE,HL ; swap DE-HL, now HL has the address
JP (HL) ; jump to the table address
L0EDA: INC HL ; table has 3 bytes per row
INC HL ; skip to next
INC HL ; row
DJNZ L0ED1 ; go back to MM-TEST until no more keys
JR L0EC8 ; then start checking at MM-KEYS
; This routine inverts a 5 pixels by 40 pixels box pointed by B/C (Y/X)
;; MM-INVERT
L0EE1: LD C,$05 ; process 5 rows
L0EE3: PUSH BC
LD BC,($7000) ; get X/Y coords
CALL L0F85 ; and get pixel address (PIXEL-ADD)
LD B,$05 ; process 5x8=40 pixels
L0EED: LD A,(HL) ; get 8 pixel pointed by B,C (Y,X coords)
CPL ; invert pixels
LD (HL),A ; and put back
INC HL ; next 8 pixels
DJNZ L0EED ; and continue loop
LD BC,($7000)
INC B ; next row
LD ($7000),BC
POP BC
DEC C
JR NZ,L0EE3 ; continue loop
LD HL,$7001 ; point to Y value
LD B,$05 ; decrement Y by 5 pixels
L0F05: DEC (HL) ; to restore original value
DJNZ L0F05
RET ; return
;; MM-KEYUP
L0F09: LD BC,($7000) ; get X-Y position
LD A,B ; check Y
CP $A8 ; is it 168?
JP Z,L0EC0 ; do nothing (go back to MM-DELAY)
CALL L0EE1 ; if not, invert pixels back
LD HL,$7001 ; and
LD B,$08 ; increment Y value by 8 pixels
L0F1B: INC (HL)
DJNZ L0F1B
JP L0EBD ; go back to MM-SELECT
; and invert the new position
;; MM-KEYDOWN
L0F21: LD BC,($7000) ; get X-Y position
LD A,B ; check Y
CP $00 ; is it zero?
JP Z,L0EC0 ; do nothing (go back to MM-DELAY)
CALL L0EE1 ; if not, invert pixels back
LD HL,$7001 ; and
LD B,$08 ; decrement Y value by 8 pixels
L0F33: DEC (HL)
DJNZ L0F33
JP L0EBD ; go back to MM-SELECT
; and invert the new position
;; MM-KEYLEFT
L0F39: LD BC,($7000) ; get X-Y positon
LD A,C ; check X
CP $00 ; is it zero?
JP Z,L0EC0 ; do nothing (go back to MM-DELAY)
CALL L0EE1 ; if not, invert pixels back
LD HL,$7000 ; and
LD B,$08 ; decrement X value by 8 pixels
L0F4B: DEC (HL)
DJNZ L0F4B
JP L0EBD ; go back to MM-SELECT
; and invert the new position
;; MM-KEYRIGHT
L0F51: LD BC,($7000) ; get X-Y position
LD A,C ; check X
CP $D8 ; is it 216?
JP Z,L0EC0 ; do nothing (go back to MM-DELAY)
CALL L0EE1 ; if not, invert pixels back
LD HL,$7000 ; and
LD B,$08 ; increment X value by 8
L0F63: INC (HL)
DJNZ L0F63
JP L0EBD ; go back to MM-SELECT
; and invert the new position
;; MM-ENTER
L0F69: LD BC,($7000) ; get Y/X position in B/C pair
NOP
INC B ; increment Y by 4 pixels
INC B
INC B
INC B
CALL L0F85 ; call PIXEL-ADD to get screen
RET ; position in HL and return
; Micro-Monitor key assignments
; and associated function addresses
;; MM-KEYTAB
L0F76: DEFB $25, $09, $0F ; L0F09 - key 'Q'
DEFB $26, $21, $0F ; L0F21 - key 'A'
DEFB $1A, $39, $0F ; L0F39 - key 'O'
DEFB $22, $51, $0F ; L0F51 - key 'P'
DEFB $21, $69, $0F ; L0F69 - key 'ENTER'
; -----------------
; Get pixel address
; -----------------
; B - y position, C - x position
; HL - the desired screen memory address
; Almost exact copy of the Spectrum ROM routine.
; Copied from $22AA to $0F85
;; PIXEL-ADD
L0F85: LD A,$AF ; load with 175 decimal.
SUB B ; subtract the y value.
NOP ; a 3 byte long conditional
NOP ; JP instruction to REPORT-Bc
NOP ; is zeroed out
; the high byte is derived from Y only.
; the first 3 bits are always 010
; the next 2 bits denote in which third of the screen the byte is.
; the last 3 bits denote in which of the 8 scan lines within a third
; the byte is located. There are 24 discrete values.
LD B,A ; the line number from top of screen to B.
AND A ; clear carry (already clear)
RRA ; 0xxxxxxx
SCF ; set carry flag
RRA ; 10xxxxxx
AND A ; clear carry flag
RRA ; 010xxxxx
XOR B
AND $F8 ; keep the top 5 bits 11111000
XOR B ; 010xxbbb
LD H,A ; transfer high byte to H.
; the low byte is derived from both X and Y.
LD A,C ; the x value 0-255.
RLCA
RLCA
RLCA
XOR B ; the y value
AND $C7 ; apply mask 11000111
XOR B ; restore unmasked bits xxyyyxxx
RLCA ; rotate to xyyyxxxx
RLCA ; required position. yyyxxxxx
LD L,A ; low byte to L.
; finally form the pixel position in A.
LD A,C ; x value to A
AND $07 ; mod 8
RET ; return
; --------------------------
; 90 unused bytes: $FA6-$FFF
; --------------------------
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF
; =========================================
;
; PORT 254 ($FE)
;
; spk mic { border }
; ___ ___ ___ ___ ___ ___ ___ ___
; PORT | | | | | | | | |
; 254 | | | | | | G | R | B |
; $FE |___|___|___|___|___|___|___|___|
; 7 6 5 4 3 2 1 0
;
; ----------------------------------
; Save header and program/data bytes
; ----------------------------------
; This is a slightly modified version of the ZX-Spectrum 'Save' ROM routine,
; relocated from $04C2 to $1000.
; All comments are borrowed from the The Incomplete Spectrum ROM Assembly.
; On entry:
; HL points to start of data.
; IX points to descriptor.
; The accumulator is set to $00 for a header, $FF for data.
;; SA-BYTES
L1000: LD HL,L107D ; address: SA/LD-RET
PUSH HL ; is pushed as common exit route.
LD HL,$1F80 ; a timing constant H=$1F, L=$80
; inner and outer loop counters
; a five second lead-in is used for a header.
BIT 7,A ; test one bit of accumulator.
JR Z,L100E ; skip to SA-FLAG if a header is being saved.
; else is data bytes and a shorter lead-in is used.
LD HL,$0C98 ; another timing value H=$0C, L=$98.
; a two second lead-in is used for the data.
;; SA-FLAG
L100E: EX AF,AF' ; save flag
INC DE ; increase length by one.
DEC IX ; decrease start.
DI ; disable interrupts
LD A,$02 ; select red for border, microphone bit on.
LD B,A ; also does as an initial slight counter value.
;; SA-LEADER
L1016: DJNZ L1016 ; self loop to SA-LEADER for delay.
; after initial loop, count is $A4 (or $A3)
OUT ($FE),A ; output byte $02/$0D to tape port.
XOR $0F ; switch from RED (mic on) to CYAN (mic off).
LD B,$0A4 ; hold count. also timed instruction.
DEC L ; originally $80 or $98.
; but subsequently cycles 256 times.
JR NZ,L1016 ; back to SA-LEADER until L is zero.
; the outer loop is counted by H
DEC B ; decrement count
DEC H ; originally twelve or thirty-one.
JP P,L1016 ; back to SA-LEADER until H becomes $FF
; now send a sync pulse. At this stage mic is off and A holds value
; for mic on.
; A sync pulse is much shorter than the steady pulses of the lead-in.
LD B,$2F ; another short timed delay.
;; SA-SYNC-1
L1028: DJNZ L1028 ; self loop to SA-SYNC-1
OUT ($FE),A ; switch to mic on and red.
LD A,$0D ; prepare mic off - cyan
LD B,$37 ; another short timed delay.
;; SA-SYNC-2
L1030: DJNZ L1030 ; self loop to SA-SYNC-2
OUT ($FE),A ; output mic off, cyan border.
LD BC,$3B0E ; B=$3B time(*), C=$0E, YELLOW, MIC OFF.
EX AF,AF' ; restore saved flag
; which is 1st byte to be saved.
LD L,A ; and transfer to L.
; the initial parity is A, $FF or $00.
JP L1045 ; JUMP forward to SA-START ->
; the mid entry point of loop.
; During the save loop a parity byte is maintained in H.
; the save loop begins by testing if reduced length is zero and if so
; the final parity byte is saved reducing count to $FFFF.
;; SA-LOOP
L103C: LD A,D ; fetch high byte
OR E ; test against low byte.
JR Z,L104C ; forward to SA-PARITY if zero.
LD L,(IX+$00) ; load currently addressed byte to L.
;; SA-LOOP-P
L1043: LD A,H ; fetch parity byte.
XOR L ; exclusive or with new byte.
; -> the mid entry point of loop.
;; SA-START
L1045: LD H,A ; put parity byte in H.
LD A,$01 ; prepare blue, mic=on.
SCF ; set carry flag ready to rotate in.
JP L1063 ; JUMP forward to SA-8-BITS
;; SA-PARITY
L104C: LD L,H ; transfer the running parity byte to L and
JR L1043 ; back to SA-LOOP-P
; to output that byte before quitting normally.
; The entry point to save yellow part of bit.
; A bit consists of a period with mic on and blue border followed by
; a period of mic off with yellow border.
; Note. since the DJNZ instruction does not affect flags, the zero flag is
; used to indicate which of the two passes is in effect and the carry
; maintains the state of the bit to be saved.
;; SA-BIT-2
L104F: LD A,C ; fetch 'mic on and yellow' which is
; held permanently in C.
BIT 7,B ; set the zero flag. B holds $3E.
; The entry point to save 1 entire bit. For first bit B holds $3B(*).
; Carry is set if saved bit is 1. zero is reset NZ on entry.
;; SA-BIT-1
L1052: DJNZ L1052 ; self loop for delay to SA-BIT-1
JR NC,L105A ; forward to SA-OUT if bit is 0.
; but if bit is 1 then the mic state is held for longer.
LD B,$42 ; set timed delay. (66 decimal)
;; SA-SET
L1058: DJNZ L1058 ; self loop to SA-SET
; (roughly an extra 66*13 clock cycles)
;; SA-OUT
L105A: OUT ($FE),A ; blue and mic on OR yellow and mic off.
LD B,$3E ; set up delay
JR NZ,L104F ; back to SA-BIT-2 if zero reset NZ (first pass)
; proceed when the blue and yellow bands have been output.
DEC B ; change value $3E to $3D.
XOR A ; clear carry flag (ready to rotate in).
INC A ; reset zero flag i.e. NZ.
;; SA-8-BITS
L1063: RL L ; rotate left through carry
; C<76543210L1052 ; JUMP back to SA-BIT-1
; until all 8 bits done.
; when the initial set carry is passed out again then a byte is complete.
DEC DE ; decrease length
INC IX ; increase byte pointer
LD B,$31 ; set up timing.
LD A,$7F ; test the space key and
IN A,($FE) ; return to common exit (to restore border)
RRA ; if a space is pressed
RET NC ; return to SA/LD-RET.
; now test if byte counter has reached $FFFF.
LD A,D ; fetch high byte
INC A ; increment.
JP NZ,L103C ; JUMP to SA-LOOP if more bytes.
LD B,$3B ; a final delay.
;; SA-DELAY
L107A: DJNZ L107A ; self loop to SA-DELAY
RET ; return to SA/LD-RET
; ------------------------------
; THE 'SAVE/LOAD RETURN' ROUTINE
; ------------------------------
; This is also copied from the Spectrum ROM, modified slightly at the end.
; The Enable Interrupts and the REPORT-Da section is zeroed out by NOPs.
;; SA/LD-RET
L107D: PUSH AF ; preserve accumulator throughout.
LD A,($5C48) ; fetch border colour from BORDCR.
AND $38 ; mask off paper bits.
RRCA ; rotate
RRCA ; to the
RRCA ; range 0-7.
OUT ($FE),A ; change the border colour.
LD A,$7F ; read from port address $7FFE the
IN A,($FE) ; row with the space key at outside.
RRA ; test for space key pressed.
NOP ; EI changed to NOP
NOP ; JR changed to NOP
INC BC ; remnant of JR offset and becomes INC BC
;; REPORT-Da
NOP ; RST 08H changed to NOP
NOP ; DEFB $0C changed to NOP
NOP ; added byte - not exists in original ROM
;; SA/LD-END
POP AF ; restore the accumulator.
RET ; return.
; ----------------------------
; 51 unused bytes: $1095-$10C7
; ----------------------------
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $00, $00, $00, $00, $00
DEFB $00, $00, $00
; ------------------------------------------------------------------
; Load header or block of information - TURBO VERSION (double speed)
; ------------------------------------------------------------------
; This routine is used to load bytes and on entry A is set to $00 for a
; header or to $FF for data. IX points to the start of receiving location
; and DE holds the length of bytes to be loaded. If, on entry the carry flag
; is set then data is loaded, if reset then it is verified.
; This is a slightly modified version of the ZX-Spectrum 'Load' ROM routine,
; relocated from $0556 to $10C8. Timing constants altered for Turbo Load.
; All comments are borrowed from 'The Incomplete Spectrum ROM Assembly'.
;; LD-BYTES
L10C8: INC D ; reset the zero flag without disturbing carry.
EX AF,AF' ; preserve entry flags.
DEC D ; restore high byte of length.
DI ; disable interrupts
LD A,$0F ; make the border white and mic off.
OUT ($FE),A ; output to port.
LD HL,L107D ; address: SA/LD-RET
PUSH HL ; is saved on stack as terminating routine.
; the reading of the EAR bit (D6) will always be preceded by a test of the
; space key (D0), so store the initial post-test state.
IN A,($FE) ; read the ear state - bit 6.
RRA ; rotate to bit 5.
AND $20 ; isolate this bit.
OR $02 ; combine with red border colour.
LD C,A ; and store initial state long-term in C.
CP A ; set the zero flag.
;; LD-BREAK
L10DD: RET NZ ; return if at any time space is pressed.
;; LD-START
L10DE: CALL L1159 ; routine LD-EDGE-1
JR NC,L10DD ; back to LD-BREAK with time out and no
; edge present on tape.
; but continue when a transition is found on tape.
LD HL,$0415 ; set up 16-bit outer loop counter for
; approx 1 second delay.
;; LD-WAIT
L10E6: DJNZ L10E6 ; self loop to LD-WAIT (for 256 times)
DEC HL ; decrease outer loop counter.
LD A,H ; test for
OR L ; zero.
JR NZ,L10E6 ; back to LD-WAIT, if not zero, with zero in B.
; continue after delay with H holding zero and B also.
; sample 256 edges to check that we are in the middle of a lead-in section.
CALL L1155 ; routine LD-EDGE-2
JR NC,L10DD ; back to LD-BREAK
; if no edges at all.
;; LD-LEADER
L10F2: LD B,$9C ; set timing value.
CALL L1155 ; routine LD-EDGE-2
JR NC,L10DD ; back to LD-BREAK if time-out
LD A,$C6 ; two edges must be spaced apart.
CP B ; compare
JR NC,L10DE ; back to LD-START if too close together for a
; lead-in.
INC H ; proceed to test 256 edged sample.
JR NZ,L10F2 ; back to LD-LEADER while more to do.
; sample indicates we are in the middle of a two or five second lead-in.
; Now test every edge looking for the terminal sync signal.
;; LD-SYNC
L1101: LD B,$C9 ; initial timing value in B.
CALL L1159 ; routine LD-EDGE-1
JR NC,L10DD ; back to LD-BREAK with time-out.
LD A,B ; fetch augmented timing value from B.
CP $D4 ; compare
JR NC,L1101 ; back to LD-SYNC if gap too big, that is,
; a normal lead-in edge gap.
; but a short gap will be the sync pulse.
; in which case another edge should appear before B rises to $FF
CALL L1159 ; routine LD-EDGE-1
RET NC ; return with time-out.
; proceed when the sync at the end of the lead-in is found.
; We are about to load data so change the border colours.
LD A,C ; fetch long-term mask from C
XOR $03 ; and make blue/yellow.
LD C,A ; store the new long-term byte.
LD H,$00 ; set up parity byte as zero.
LD B,$DC ; timing (dec 220). <-- original ROM has $B0 here [1446]
JR L113A ; forward to LD-MARKER
; the loop mid entry point with the alternate
; zero flag reset to indicate first byte
; is discarded.
; the loading loop loads each byte and is entered at the mid point.
;; LD-LOOP
L111B: EX AF,AF' ; restore entry flags and type in A.
JR NZ,L1125 ; forward to LD-FLAG if awaiting initial flag
; which is to be discarded.
JR NC,L112F ; forward to LD-VERIFY if not to be loaded.
LD (IX+$00),L ; place loaded byte at memory location.
JR L1134 ; forward to LD-NEXT
;; LD-FLAG
L1125: RL C ; preserve carry (verify) flag in long-term
; state byte. Bit 7 can be lost.
XOR L ; compare type in A with first byte in L.
RET NZ ; return if no match e.g. CODE vs. DATA.
; continue when data type matches.
LD A,C ; fetch byte with stored carry
RRA ; rotate it to carry flag again
LD C,A ; restore long-term port state.
INC DE ; increment length ??
JR L1136 ; forward to LD-DEC.
; but why not to location after ?
; for verification the byte read from tape is compared with that in memory.
;; LD-VERIFY
L112F: LD A,(IX+$00) ; fetch byte from memory.
XOR L ; compare with that on tape
RET NZ ; return if not zero.
;; LD-NEXT
L1134: INC IX ; increment byte pointer.
;; LD-DEC
L1136: DEC DE ; decrement length.
EX AF,AF' ; store the flags.
LD B,$DE ; timing (dec 222). <-- original ROM has $B2 here [1479]
; when starting to read 8 bits the receiving byte is marked with bit at right.
; when this is rotated out again then 8 bits have been read.
;; LD-MARKER
L113A: LD L,$01 ; initialize as %00000001
;; LD-8-BITS
L113C: CALL L1155 ; routine LD-EDGE-2 increments B relative to
; gap between 2 edges.
RET NC ; return with time-out.
LD A,$E9 ; the comparison byte (dec 233). <-- original ROM has $CB here [1487]
CP B ; compare to incremented value of B.
; if B is higher then bit on tape was set.
; if <= then bit on tape is reset.
RL L ; rotate the carry bit into L.
LD B,$0DC ; reset the B timer byte (dec 220). <-- original ROM has $B0 here [1492]
JP NC,L113C ; JUMP back to LD-8-BITS
; when carry set then marker bit has been passed out and byte is complete.
LD A,H ; fetch the running parity byte.
XOR L ; include the new byte.
LD H,A ; and store back in parity register.
LD A,D ; check length of
OR E ; expected bytes.
JR NZ,L111B ; back to LD-LOOP
; while there are more.
; when all bytes loaded then parity byte should be zero.
LD A,H ; fetch parity byte.
CP $01 ; set carry if zero.
RET ; return
; in no carry then error as checksum disagrees.
; -------------------------
; Check signal being loaded
; -------------------------
; An edge is a transition from one mic state to another.
; More specifically a change in bit 6 of value input from port $FE.
; Graphically it is a change of border colour, say, blue to yellow.
; The first entry point looks for two adjacent edges. The second entry point
; is used to find a single edge.
; The B register holds a count, up to 256, within which the edge (or edges)
; must be found. The gap between two edges will be more for a '1' than a '0'
;; LD-EDGE-2
L1155: CALL L1159 ; call routine LD-EDGE-1 below.
RET NC ; return if space pressed or time-out.
; else continue and look for another adjacent
; edge which together represent a bit on the
; tape.
; this entry point is used to find a single edge from above but also
; when detecting a read-in signal on the tape.
L1159: LD A,$0A ; a delay value (dec 10). <-- original ROM has $16 here. [1512]
;; LD-DELAY
L115B: DEC A ; decrement counter
JR NZ,L115B ; loop back to LD-DELAY 22 times.
AND A ; clear carry.
;; LD-SAMPLE
L115F: INC B ; increment the time-out counter.
RET Z ; return with failure when $FF passed.
LD A,$7F ; prepare to read keyboard and EAR port
IN A,($FE) ; row $7FFE. bit 6 is EAR, bit 0 is SPACE key.
RRA ; test outer key the space. (bit 6 moves to 5)
RET NC ; return if space pressed.
XOR C ; compare with initial long-term state.
AND $20 ; isolate bit 5
JR Z,L115F ; back to LD-SAMPLE if no edge.
; but an edge, a transition of the EAR bit, has been found so switch the
; long-term comparison byte containing both border colour and EAR bit.
LD A,C ; fetch comparison value.
CPL ; switch the bits
LD C,A ; and put back in C for long-term.
AND $07 ; isolate new colour bits.
OR $08 ; set bit 3 - MIC off.
OUT ($FE),A ; send to port to effect the change of colour.
SCF ; set carry flag signaling edge found within
; time allowed.
RET ; return.
; ----------------------------
; 25 unused bytes: $1177-$118F
; ----------------------------
DEFB $00, $00, $00, $00, $00, $00, $00, $00
DEFB $00, $00, $00, $00, $00, $00, $00, $00
DEFB $00, $00, $00, $00, $00, $00, $00, $00
DEFB $00
; -----------------------------------------------------------------
; Save header and program/data bytes - TURBO VERSION (double speed)
; -----------------------------------------------------------------
; This is a slightly modified version of the ZX-Spectrum 'Save' ROM routine,
; relocated from $04C2 to $1190.
; All comments are borrowed from the The Incomplete Spectrum ROM Assembly.
; On entry:
; HL points to start of data.
; IX points to descriptor.
; The accumulator is set to $00 for a header, $FF for data.
;; SA-BYTES
L1190: LD HL,L120D ; address: SA/LD-RET
PUSH HL ; is pushed as common exit route.
LD HL,$1F80 ; a timing constant H=$1F, L=$80
; inner and outer loop counters
; a five second lead-in is used for a header.
BIT 7,A ; test one bit of accumulator.
JR Z,L119E ; skip to SA-FLAG if a header is being saved.
; else is data bytes and a shorter lead-in is used.
LD HL,$0C98 ; another timing value H=$0C, L=$98.
; a two second lead-in is used for the data.
;; SA-FLAG
L119E: EX AF,AF' ; save flag
INC DE ; increase length by one.
DEC IX ; decrease start.
DI ; disable interrupts
LD A,$02 ; select red for border, microphone bit on.
LD B,A ; also does as an initial slight counter value.
;; SA-LEADER
L11A6: DJNZ L11A6 ; self loop to SA-LEADER for delay.
; after initial loop, count is $A4 (or $A3)
OUT ($FE),A ; output byte $02/$0D to tape port.
XOR $0F ; switch from RED (mic on) to CYAN (mic off).
LD B,$A4 ; hold count. also timed instruction.
DEC L ; originally $80 or $98.
; but subsequently cycles 256 times.
JR NZ,L11A6 ; back to SA-LEADER until L is zero.
; the outer loop is counted by H
DEC B ; decrement count
DEC H ; originally twelve or thirty-one.
JP P,L11A6 ; back to SA-LEADER until H becomes $FF
; now send a sync pulse. At this stage mic is off and A holds value
; for mic on.
; A sync pulse is much shorter than the steady pulses of the lead-in.
LD B,$2F ; another short timed delay.
;; SA-SYNC-1
L11B8: DJNZ L11B8 ; self loop to SA-SYNC-1
OUT ($FE),A ; switch to mic on and red.
LD A,$0D ; prepare mic off - cyan
LD B,$37 ; another short timed delay.
;; SA-SYNC-2
L11C0: DJNZ L11C0 ; self loop to SA-SYNC-2
OUT ($FE),A ; output mic off, cyan border.
LD BC,$3B0E ; B=$3B time(*), C=$0E, YELLOW, MIC OFF.
EX AF,AF' ; restore saved flag
; which is 1st byte to be saved.
LD L,A ; and transfer to L.
; the initial parity is A, $FF or $00.
JP L11D5 ; JUMP forward to SA-START
; the mid entry point of loop.
; During the save loop a parity byte is maintained in H.
; the save loop begins by testing if reduced length is zero and if so
; the final parity byte is saved reducing count to $FFFF.
L11CC: LD A,D ; fetch high byte
OR E ; test against low byte.
JR Z,L11DC ; forward to SA-PARITY if zero.
LD L,(IX+$00) ; load currently addressed byte to L.
;; SA-LOOP-P
L11D3: LD A,H ; fetch parity byte.
XOR L ; exclusive or with new byte.
; -> the mid entry point of loop.
;; SA-START
L11D5: LD H,A ; put parity byte in H.
LD A,$01 ; prepare blue, mic=on.
SCF ; set carry flag ready to rotate in.
JP L11F3 ; JUMP forward to SA-8-BITS
;; SA-PARITY
L11DC: LD L,H ; transfer the running parity byte to L and
JR L11D3 ; back to SA-LOOP-P
; to output that byte before quitting normally.
; The entry point to save yellow part of bit.
; A bit consists of a period with mic on and blue border followed by
; a period of mic off with yellow border.
; Note. since the DJNZ instruction does not affect flags, the zero flag is
; used to indicate which of the two passes is in effect and the carry
; maintains the state of the bit to be saved.
;; SA-BIT-2
L11DF: LD A,C ; fetch 'mic on and yellow' which is
; held permanently in C.
BIT 7,B ; set the zero flag. B holds $3E.
; The entry point to save 1 entire bit. For first bit B holds $3B(*).
; Carry is set if saved bit is 1. zero is reset NZ on entry.
;; SA-BIT-1
L11E2: DJNZ L11E2 ; self loop for delay to SA-BIT-1
JR NC,L11EA ; forward to SA-OUT if bit is 0.
; but if bit is 1 then the mic state is held for longer.
LD B,$1F ; set timed delay (dec 31). <-- original ROM has $42 here. [1305]
;; SA-SET
L11E8: DJNZ L11E8 ; self loop to SA-SET
; (roughly an extra 31*13 clock cycles)
;; SA-OUT
L11EA: OUT ($FE),A ; blue and mic on OR yellow and mic off.
LD B,$1A ; set up delay (dec 26) <-- original ROM has $3E here [1311].
JR NZ,L11DF ; back to SA-BIT-2 if zero reset NZ (first pass)
; proceed when the blue and yellow bands have been output.
DEC B ; change value $3E to $3D.
XOR A ; clear carry flag (ready to rotate in).
INC A ; reset zero flag i.e. NZ.
;; SA-8-BITS
L11F3: RL L ; rotate left through carry
; 0>76543210>C
JP NZ,L11E2 ; JUMP back to SA-BIT-1
; until all 8 bits done.
; when the initial set carry is passed out again then a byte is complete.
DEC DE ; decrease length
INC IX ; increase byte pointer
LD B,$0D ; set up timing (dec 13). <-- original ROM has $31 here. [1326]
LD A,$7F ; test the space key and
IN A,($FE) ; return to common exit (to restore border)
RRA ; if a space is pressed
RET NC ; return to SA/LD-RET.
; now test if byte counter has reached $FFFF.
LD A,D ; fetch high byte
INC A ; increment.
JP NZ,L11CC ; JUMP to SA-LOOP if more bytes.
LD B,$3B ; a final delay.
;; SA-DELAY
L120A: DJNZ L120A ; self loop to SA-DELAY
RET ; return to SA/LD-RET
; ------------------------------
; THE 'SAVE/LOAD RETURN' ROUTINE
; ------------------------------
; The address of this routine is pushed on the stack prior to any load/save
; operation and it handles normal completion with the restoration of the
; border and also abnormal termination when the break key, or to be more
; precise the space key is pressed during a tape operation.
; Another copy of the Spectrum's SAVE/LOAD RETURN Routine.
; The REPORT-Da section is zeroed out by NOPs.
;; SA/LD-RET
L120D: PUSH AF ; preserve accumulator throughout.
LD A,($5C48) ; fetch border colour from BORDCR.
AND $38 ; mask off paper bits.
RRCA ; rotate
RRCA ; to the
RRCA ; range 0-7.
OUT ($FE),A ; change the border colour.
LD A,$7F ; read from port address $7FFE the
IN A,($FE) ; row with the space key at outside.
RRA ; test for space key pressed.
EI ; enable interrupts
JR C,L1222 ; forward to SA/LD-END if not
;; REPORT-Da
NOP ; RST 08H changed to NOP
NOP ; DEBF $0C changed to NOP
;; SA/LD-END
L1222: POP AF ; restore the accumulator.
RET ; return.
; -----------------------------
; 189 unused bytes: $1224-$12E0
; -----------------------------
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $00, $00, $00, $00, $00, $00, $00, $00
DEFB $00, $00, $00, $00, $00
; Part of the original Spectrum ROM 'LOAD' routine copied here again
; but actually never gets called - considered as garbage.
; The comments are here to recognize the origin.
; Code relocated from $05DF to $12E1.
;; End of LD-8-BITS part (address $12E1)
; when all bytes loaded then parity byte should be zero.
LD A,H ; fetch parity byte.
CP $01 ; set carry if zero.
RET ; return
; in no carry then error as checksum disagrees.
; -------------------------
; Check signal being loaded
; -------------------------
; An edge is a transition from one mic state to another.
; More specifically a change in bit 6 of value input from port $FE.
; Graphically it is a change of border colour, say, blue to yellow.
; The first entry point looks for two adjacent edges. The second entry point
; is used to find a single edge.
; The B register holds a count, up to 256, within which the edge (or edges)
; must be found. The gap between two edges will be more for a '1' than a '0'
; so the value of B denotes the state of the bit (two edges) read from tape.
;; LD-EDGE-2
CALL L12E9 ; call routine LD-EDGE-1 below.
RET NC ; return if space pressed or time-out.
; else continue and look for another adjacent
; edge which together represent a bit on the
; tape.
; this entry point is used to find a single edge from above but also
; when detecting a read-in signal on the tape.
;; LD-EDGE-1
L12E9: LD A,$0A ; a delay value of twenty two. <-- original ROM has $16 here.
;; LD-DELAY
L12EB: DEC A ; decrement counter
JR NZ,L12EB ; loop back to LD-DELAY 22 times.
AND A ; clear carry.
;; LD-SAMPLE
L12EF: INC B ; increment the time-out counter.
RET Z ; return with failure when $FF passed.
LD A,$7F ; prepare to read keyboard and EAR port
IN A,($FE) ; row $7FFE. bit 6 is EAR, bit 0 is SPACE key.
RRA ; test outer key the space. (bit 6 moves to 5)
RET NC ; return if space pressed.
XOR C ; compare with initial long-term state.
AND $20 ; isolate bit 5
JR Z,L12EF ; back to LD-SAMPLE if no edge.
; but an edge, a transition of the EAR bit, has been found so switch the
; long-term comparison byte containing both border colour and EAR bit.
LD A,C ; fetch comparison value.
CPL ; switch the bits
LD C,A ; and put back in C for long-term.
AND $07 ; isolate new colour bits.
OR $08 ; set bit 3 - MIC off.
OUT ($FE),A ; send to port to effect the change of colour.
SCF ; set carry flag signaling edge found within
; time allowed.
RET ; return.
DEFB $00, $FF, $FF ; 5 unused bytes
DEFB $FF, $FF
; --------------------
; WARM RESTART ROUTINE
; --------------------
; Switch back to Spectrum's IM1 mode and switch back the ROM.
; The code execution resumed at the MAIN-G routine (L1313).
; Maybe NMI_VECT at L121C would be more appropriate?
;; WARM-RESTART
L130C: IM 1 ; switch back to Interrupt Mode 1
EI ; and enable interrupts
LD A,$00 ; switch back to original Spectrum ROM
OUT ($7F),A ; the code from L1313 in the original ROM
; is the MAIN-G
; ---------------------
; MICRO-MONITOR ROUTINE
; ---------------------
;; MM-MAIN
L1313: LD HL,$7000
LD B,$04
L1318: LD D,(HL) ; save 4x2 bytes
INC HL ; starting from $7000
LD E,(HL) ; into stack
INC HL ; ($7000-$7007)
PUSH DE
DJNZ L1318 ; loop until 8 bytes done
L131F: LD HL,$7002
RES 0,(HL) ; reset bit 0 at $7002
CALL L0EB6 ; call MM-CURSOR cursor handler which
; returns cursor screen position in HL
LD ($7000),HL ; store this position at $7000
LD C,$05 ; process 5 digits
CALL L13BF ; call MM-INPUT5 to enter a 5 digits long
; decimal value
LD A,(HL) ; get value from the entered memory location
EXX ; switch to alternate set
LD L,A
LD H,$00
LD A,$0A ; display a ':' character
CALL L1442 ; call MM-DISPLAY
LD BC,$0064 ; display A/100
CALL L134D
LD BC,$000A ; display A/10
CALL L134D
LD BC,$0001 ; display A/1
CALL L134D
JR L136B
; calculate A = HL / BC
; display integer part of HL and return the remainder
L134D: LD A,$00
PUSH HL ; save original value
L1350: SCF
CCF ; reset carry
SBC HL,BC ; HL = HL - BC
JP M,L135A
INC A
JR L1350
L135A: POP HL ; restore original value
PUSH AF
CALL L1442 ; call MM-DISPLAY
POP AF ; to display integer part
CP $00
RET Z ; return if no remainder
L1363: SCF
CCF ; reset carry
SBC HL,BC ; HL = HL - BC
DEC A
JR NZ,L1363
RET ; HL = remainder
L136B: LD HL,($7000) ; get cursor screen address
DEC HL ; decrement X by 8 pixels
LD A,($7002) ; invert bit 0. at $7002
XOR $01
LD ($7002),A
LD ($7000),HL
L137A: RST 00H ; CALL KEY-MAIN to
LD A,E ; get a keypress
CP $09 ; is it key 'J' ?
JR NZ,L1393 ; jump if not
; This JUMP command only modifies the return address from NMI.
; Therefore this jump is enforced after exiting from MICRO-POKEer in main menu.
;; MM-JUMP
LD HL,$0000 ; get stack pointer
ADD HL,SP ; into HL' register
LD DE,$0020 ; increment HL' by 32
ADD HL,DE ; and store this value
PUSH HL ; on stack
EXX ; switch back to main set
LD D,H ; get HL (entered memory address)
LD E,L ; into DE
POP HL ; get back HL'
LD (HL),E ; which points to SP+32
INC HL ; and store HL (memaddr) into
LD (HL),D ; this address which is the
; return address from NMI
JP L13B0 ; and jump to MM-EXIT
L1393: CP $21 ; is it key 'ENTER' ?
JR Z,L131F ; release cell and handle
; cursor box again
CP $25 ; is it key 'Q' ?
JR Z,L13B0 ; jump to MM-EXIT to quit
CP $22 ; is it key 'P' ?
JR NZ,L137A ; wait again if not
;; MM-POKE
EXX
PUSH HL
LD C,$03 ; input 3 digits
LD IX,$7005
CALL L13C3 ; call MM-INPUT
LD A,L
POP HL ; store entered decimal value
LD (HL),A
JP L136B ; waiting for new command
;; MM-EXIT
L13B0: LD B,$04 ; restore the original
LD HL,$7007 ; ram content between
L13B5: POP DE ; $7000-$7007 from the
LD (HL),E ; stack
DEC HL
LD (HL),D
DEC HL
DJNZ L13B5
JP L007D ; exit from Micro-Monitor
; jump back to MAIN-KEYS
;; MM-INPUT5
L13BF: LD IX,$7003 ; index register to $7003
;; MM-INPUT
L13C3: LD B,$05 ; clear 5 bytes of memory
LD HL,$7003 ; between $7003-$7007
L13C8: LD (HL),$00 ; these 5 locations will hold
INC HL ; the 5 digits entered
DJNZ L13C8 ; loop until 5 bytes done
L13CD: PUSH BC ; save C (B is already zero)
; this routine waits for a numeric key
; and converts to a decimal value (ie. key '5' -> 5)
; then displays it and calculate the entered decimal value (5 digits)
L13CE: RST 00H ; get a keypress
LD A,E
CP D ; wait until a
JR Z,L13CE ; key is pressed
LD HL,L14C0 ; table at L14C0
LD B,$0A ; has 10 items
L13D8: CP (HL) ; compare key
JR Z,L13E1 ; a jump if found
INC HL ; skip to next
INC HL ; item
DJNZ L13D8 ; and continue
JR L13CE ; else start again
L13E1: INC HL ; get numerical value
LD A,(HL) ; of the key
LD (IX+$00),A ; and store at (IX)
INC IX
CALL L1442 ; call MM-DISPLAY to
; write digit
L13EB: RST 00H ; get a keypress
LD A,E
CP D ; wait until the
JR NZ,L13EB ; key is released
POP BC ; restore C value
DEC C ; count digits
JR NZ,L13CD ; input the next number
; HL = decimal value entered
LD BC,$0000
LD DE,$7003 ; pointer to first digit
LD HL,$2710 ; HL = 10000 highest digit
LD A,(DE) ; get first digit
CALL L142F ; HL = HL * A
ADD HL,BC
PUSH HL
POP BC
LD HL,$03E8 ; HL = 1000
INC DE
LD A,(DE) ; get second digit
CALL L142F ; HL = HL * A
ADD HL,BC
PUSH HL
POP BC
LD HL,$0064 ; HL = 100
INC DE
LD A,(DE) ; get third digit
CALL L142F ; HL = HL * A
ADD HL,BC
PUSH HL
POP BC
LD HL,$000A ; HL = 10
INC DE
LD A,(DE) ; get fourth digit
CALL L142F ; HL = HL * A
ADD HL,BC
PUSH HL
POP BC
LD HL,$0001 ; HL = 1
INC DE
LD A,(DE) ; get fifth digit
CALL L142F ; HL = HL * A
ADD HL,BC
RET
; calculate HL = HL * A
L142F: CP $00
JR NZ,L1437
LD HL,$0000 ; handle A = 0 case
RET
L1437: PUSH DE
PUSH HL
POP DE
L143A: DEC A ; increment HL
JR Z,L1440 ; until A is zero
ADD HL,DE
JR L143A
L1440: POP DE
RET
;; MM-DISPLAY
; draws number a number on screen
; inputs: A - number
; ($7000) - screen address
L1442: PUSH DE ; register A has
PUSH HL ; the number
PUSH BC
LD BC,($7000) ; BC has screen address
LD HL,L1489 ; numbers bitmap
LD DE,$0005 ; 5 pixels tall
L144F: CP $00 ; found the
JR Z,L1457 ; corresponding
ADD HL,DE ; bitmap
DEC A
JR L144F ; loop until we found
L1457: PUSH HL ; HL has the bitmap address
POP DE ; HL -> DE
LD H,B ; BC -> HL
LD L,C
LD B,$05 ; process 5 pixels
L145D: LD A,($7002)
BIT 0,A ; odd/even character position?
JR Z,L146C ; jump if using the left side
LD A,(DE) ; get bitmap data
RRA ; right shift by 4 bits
RRA ; to the right nibble
RRA ; position
RRA ; and merge the two
OR (HL) ; numbers into one byte
JR L146D
L146C: LD A,(DE) ; get bitmap data
L146D: LD (HL),A ; draw number(s) on screen
INC H ; next screen row
INC DE ; next bitmap row
DJNZ L145D ; display five rows
LD A,($7002)
BIT 0,A ; odd/even character position?
JR Z,L1480 ; skip if only one side is used yet
LD HL,($7000) ; skip to next byte only if
INC HL ; both left-right side is filled
LD ($7000),HL ; with a 3-pixel wide number
L1480: XOR $01 ; swap bitween odd-even
LD ($7002),A ; and store it
POP BC
POP HL
POP DE
RET
; --------------------------------------------
; MINI NUMBERS CHARACTER SET FOR MICRO MONITOR
; --------------------------------------------
; Characters are 3 pixels wide and 5 pixels tall.
; Only the first 4 bits are used.
; number '0'
L1489: DEFB %11100000
DEFB %10100000
DEFB %10100000
DEFB %10100000
DEFB %11100000
; number '1'
DEFB %01100000
DEFB %10100000
DEFB %00100000
DEFB %00100000
DEFB %00100000
; number '2'
DEFB %11100000
DEFB %00100000
DEFB %11100000
DEFB %10000000
DEFB %11100000
; number '3'
DEFB %11100000
DEFB %00100000
DEFB %11100000
DEFB %00100000
DEFB %11100000
; number '4'
DEFB %10000000
DEFB %10000000
DEFB %10100000
DEFB %11100000
DEFB %00100000
; number '5'
DEFB %11100000
DEFB %10000000
DEFB %11100000
DEFB %00100000
DEFB %11100000
; number '6'
DEFB %11100000
DEFB %10000000
DEFB %11100000
DEFB %10100000
DEFB %11100000
; number '7'
DEFB %11100000
DEFB %00100000
DEFB %01000000
DEFB %01000000
DEFB %01000000
; number '8'
DEFB %11100000
DEFB %10100000
DEFB %11100000
DEFB %10100000
DEFB %11100000
; number '9'
DEFB %11100000
DEFB %10100000
DEFB %11100000
DEFB %00100000
DEFB %11100000
; symbol ':'
DEFB %00000000
DEFB %01000000
DEFB %00000000
DEFB %01000000
DEFB %00000000
; numeric keys conversion table
L14C0: DEFB $23,$00 ; key '0'
DEFB $24,$01 ; key '1'
DEFB $1C,$02 ; key '2'
DEFB $14,$03 ; key '3'
DEFB $0C,$04 ; key '4'
DEFB $04,$05 ; key '5'
DEFB $03,$06 ; key '6'
DEFB $0B,$07 ; key '7'
DEFB $13,$08 ; key '8'
DEFB $1B,$09 ; key '9'
DEFB $00
;; WAIT-SEC
L14D5: PUSH BC
IM 1 ; select Interrupt Mode 1 to synchronize
EI ; with vertical refresh
PUSH AF
LD B,$32 ; waits for 50 vertical refresh
L14DC: HALT ; which equals 1 sec on an european Spectrum
DJNZ L14DC
DI ; disable interrupts
POP AF
POP BC
RET
; -------------------------------
; 653 unused bytes: $14E3 - $176F
; -------------------------------
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF
; ----------------------------------------------------------------------------
; THE 'KEYBOARD SCANNING' ROUTINE - COPY FROM THE ORIGINAL ZX SPECTRUM 48K ROM
; ----------------------------------------------------------------------------
; Copied from $28E-$2BE (original) to $1770-$17A0 (MICRO-POKEer)
; Returns 1 or 2 keys in DE, most significant shift first if any
; key values 0-39 else 255
;; KEY-SCAN
L1770: LD L,$2F ; initial key value
; valid values are obtained by subtracting
; eight five times.
LD DE,$FFFF ; a buffer to receive 2 keys.
LD BC,$FEFE ; the commencing port address
; B holds 11111110 initially and is also
; used to count the 8 half-rows
;; KEY-LINE
L1778: IN A,(C) ; read the port to A - bits will be reset
; if a key is pressed else set.
CPL ; complement - pressed key-bits are now set
AND $1F ; apply 00011111 mask to pick up the
; relevant set bits.
JR Z,L178D ; forward to KEY-DONE if zero and therefore
; no keys pressed in row at all.
LD H,A ; transfer row bits to H
LD A,L ; load the initial key value to A
;; KEY-3KEYS
L1781: INC D ; now test the key buffer
RET NZ ; if we have collected 2 keys already
; then too many so quit.
;; KEY-BITS
L1783: SUB $08 ; subtract 8 from the key value
; cycling through key values (top = $27)
; e.g. 2F> 27>1F>17>0F>07
; 2E> 26>1E>16>0E>06
SRL H ; shift key bits right into carry.
JR NC,L1783 ; back to KEY-BITS if not pressed
; but if pressed we have a value (0-39d)
LD D,E ; transfer a possible previous key to D
LD E,A ; transfer the new key to E
JR NZ,L1781 ; back to KEY-3KEYS if there were more
; set bits - H was not yet zero.
;; KEY-DONE
L178D: DEC L ; cycles 2F>2E>2D>2C>2B>2A>29>28 for
; each half-row.
RLC B ; form next port address e.g. FEFE > FDFE
JR C,L1778 ; back to KEY-LINE if still more rows to do.
LD A,D ; now test if D is still FF ?
INC A ; if it is zero we have at most 1 key
; range now $01-$28 (1-40d)
RET Z ; return if one key or no key.
CP $28 ; is it capsshift (was $27) ?
RET Z ; return if so.
CP $19 ; is it symbol shift (was $18) ?
RET Z ; return also
LD A,E ; now test E
LD E,D ; but first switch
LD D,A ; the two keys.
CP $18 ; is it symbol shift ?
RET ; return (with zero set if it was).
; but with symbol shift now in D
DEFB $FF, $FF, $FF ; 7 unused bytes
DEFB $FF, $FF, $FF
DEFB $FF
L17A8: LD A,D ; check second key
CP $27 ; is it caps shift?
JP NZ,L007D ; if no jump back to MAIN-KEYS
; this allows only capital H keypress
;; SCROLL-MENU
L17AE: IM 1 ; select Interrupt Mode 1 to synchronize
; with the vertical refresh
EI ; enable interrupts
; this routine will fills up the bottom line
; with extra white paper and black ink
; the two corners will be white ink also
LD HL,$5AE0 ; last 'line' of attribute area
LD DE,$5AE2 ; address of the next word
LD (HL),$7F ; left corner color: white paper and white ink
INC HL
LD (HL),$78 ; 01111000 = white paper, black ink
LD BC,$001E ; copy the white paper, black ink color
LDIR ; 30 times
LD (HL),$7F ; right corner color: white paper and white ink
LD DE,L0890 ; pointer to menu text
LD BC,$015E ; length of menu text (L09EE-L0890)
;; SCROLL-GETBITMAP
L17C9: PUSH BC
LD HL,$0488 ; pointer to character set (actually 0588H from chr32)
LD A,(DE) ; get the next character from text
LD B,A ; and calculate the address
INC DE ; of the character bitmap
PUSH DE
LD DE,$0008 ; every character has 8 rows
;; SCROLL-PUTCHAR
L17D4: ADD HL,DE
DJNZ L17D4 ; HL contains the character bitmap address
LD DE,$50FF ; first pixel-row of the bottom right corner
LD B,$08 ; will copy 8 pixel-rows
L17DC: LD A,(HL) ; copy the character bitmap to the screen
LD (DE),A
INC HL ; increment to the next bitmap row
INC D ; increment to the next pixel-row
DJNZ L17DC
LD H,$08 ; scroll left by 8 pixels
;; SCROLL-CHAR
L17E4: LD DE,$50FF ; first pixel-row of the bottom right corner
LD B,$08 ; scroll left all 8 pixel-rows
L17E9: CALL L1803 ; call SCROLL-LEFT routine
INC D ; increment to the next pixel-row
DJNZ L17E9
HALT ; wait for interrupt (screen refresh)
DEC H
JR NZ,L17E4
POP DE
POP BC
DEC BC
LD A,$7F ; test the space key
IN A,($FE)
RRA ; if a space is pressed
RET NC ; return
LD A,B ; continue drawing menu text
OR C ; until finished
JR NZ,L17C9
JP L17AE ; restart the scroller
;; SCROLL-LEFT
L1803: PUSH BC ; scroll the bottom line left
PUSH DE ; with one pixel
PUSH HL ; except the left/right corners
EX DE,HL ; those will hide scroll edges (white on white)
LD B,$1F ; scroll only 30 characters
L1809: RL (HL) ; HL is the screen address
DEC HL
DJNZ L1809
POP HL
POP DE
POP BC
RET
; ------------------------------
; 1645 unused bytes: $1812-$1E7E
; ------------------------------
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF
; $1E7F unused subroutine which
; starts turbo loading from $5B00 (after attributes)
; to the end of memory ($FFFF) then exit from MICRO-POKEer
LD HL,($5B00)
EXX
LD SP,$5A00 ; set stack to $5A00?
LD DE,$A500 ; $A500 length
LD IX,$5B00 ; load into $5B00
LD A,$0F
SCF ; load data flag
RST 10H ; call turbo load routine
JP L052A ; jump to EXIT-POKER
L1E94: DEFB $00 ; type basic program
DEFM "LOADER " ; filename
DEFB $0A, $01 ; total length 266 bytes (incl vars)
DEFB $0A, $00 ; autostart line 10
DEFB $AF, $00 ; length of program 175 bytes
L1EA5: DEFB $03 ; type code
DEFM "SCREEN " ; filename
DEFB $02, $1B ; length 6914 bytes
DEFB $00, $40 ; start address $4000
DEFB $00, $80 ; unused (always $8000)
; $1EB6 - 7 unused bytes
DEFB $20, $6D, $02, $0A, $00, $C4, $00
; $1EBD - unused header
DEFB $03
DEFM "V&REW ª "
DEFB $02, $1B, $00, $40, $00, $80
; -----------------------------
; 306 unused bytes: $1ECE-$1FFF
; -----------------------------
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF
DEFB $FF, $FF
;end
; Acknowledgements
; ----------------
; The MICRO-POKEer device was made by Micro-Studio Hungary.
; The assembly formatting and the original ZX Spectrum ROM
; snippets are based on the Incomplete Spectrum ROM Assembly:
; http://www.wearmouth.demon.co.uk/zx82.htm
; Sjasm 0.42 can be downloaded from http://www.xl2s.tk/
;
; Credits
; -------
; Lajos Bicsak (bitbandit.org) for disassembling the MICRO-POKEer ROM.
;
; Known problems
; --------------
; Snapshots saved by "TURBO total RAM SAVE" option won't work with the
; saved Basic loader since it uses the Spectrum's original ROM loader.