 |
;----------------------------------------------------
; Disassembly of the Thayer's Quest ROMs
; by Jeff Kulczycki, Jun 19, 2001
;----------------------------------------------------
;
;----------------------------------------------------
; RAM VARIABLES (8k RAM at A000-BFFF)
;----------------------------------------------------
; Address Description
;----------------------------------------------------
; A000 OUT (4) Speech Register 0: Duration/Phonetic
; A100 OUT (3) Speech Register 1: Inflection
; A200 OUT (2) Speech Register 2: Speech Rate
; A300 OUT (1) Speech Register 3: Amplitude
; A400 OUT (0) Speech Register 4: Filter Frequency
; A500 Holds Copy of A000
;----------------------------------------------------
; A604-A605 Temp pointer to start of Speech Buffer
; A608-A609 Pointer to A400
; A60A-A60B Unknown
; A60E Unknown
; A612-A613 Save Phoneme entry starting location
; A614 Number of characters in Speech Buffer
; A615 Unknown - speech, characters, timer
; A618 Marker (0,1)
; A619
; A61C Z_Adder (+1,-1)
; A61D X_Adder (+1,-1)
; A61F A100 Speech Control Code (F0-FF)
; A620 Backslash Flag (1 = backslash in speech buffer, 0 = no backslash)
; A621 Question Flag, checks occurance of "WH" in speech buffer
; A630 Unknown
; A63A Equations: Number of chacters to the right of the equals sign
; A641 Pointer to End of Speech Buffer
; A64A Length of Player's (full) Name
; A64B-A68A String containing Player's (full) Name
; A68B Length of Player's First Name
; A68C-A6CA String containing Player's First Name
; A6CB-A6CE Copy of score
; A6CF Word Properties (Plural, Inflection Level, etc.)
; A6D0-A6D2 Speakable number (n) in digits
; A6D3 Unknown
; A6D4-A6D5 Previous phrase pointer to avoid repeating same phrase
; A6D6 Ring Buffer 0-3 to keep track of repeated phrases
; A6D9 Temp location: Save Timer
; Save word length for vulgarities
; A782 .0
; .1
; .5
; .7
; A783 .4 Coin Counter Hardware Increment
; .5 Set LDPlayer data bus as Input
; .6 LDPlayer ENTER
; .7 LDPlayer INT/EXT
; A784 Command Byte to LDPlayer
; A787 Number of SEARCH Retries
; A788 Attract Mode Count (1-8)
; A7B5-A7B7 BCD, Number after converted to BCD
; A794-A796 Number awaiting conversion to BCD
; A79A .3 0 = PR-7820, 1 = LD-V1000
;
;----------------------------------------------------
; Saved Game Banks
;----------------------------------------------------
; A800-A9FF SAVED GAME Bank 1
; AA00-ABFF SAVED GAME Bank 2
; AC00-ADFF SAVED GAME Bank 3
; AE00-AFFF SAVED GAME Bank 4
; B000-B1FF SAVED GAME Bank 5
; B200-B3FF SAVED GAME Bank 6
; B400-B5FF SAVED GAME Bank 7
; B600-B7FF SAVED GAME Bank 8
; B800-B9FF SAVED GAME Bank 9
; BA00-BBFF SAVED GAME Bank 10
;----------------------------------------------------
; Current Working BANK area
;----------------------------------------------------
; BC00 Bank Number of current SAVED GAME
; BC01 Unknown
; BC03 Buffer pointer to 32
; BC24-BC64 Player's Full Name? LABEL
; BC65-BC6A 6 bytes get copied from BE27
; BC6B-BC71 6 bytes get copied from BE27
; BC80 .0 0 = Audio Track1, 1 = Audio Track2
; BC81 Scene Index
; BC82
; BC83-BC84 Scene Jumpers
; BC85-BC86 Scene Jumpers
; BC87-BC9F Scene Jumpers (BC83)
; BCA0-BCBA Items in Inventory
; .0 1 = Item is valid (has key associated)
; .1 1 = Item Held
; .2 1 = ?
; BCC0 inventory2?
; BCE0 Index to Health Table (C97E) <Default 08h>
; BCE1 Wounds/Health
; BCE2-BCE4 Score
; BCE5 xxx Timer Control Register
; .0 1 = Timer ON, 0 = Timer OFF
; .1 1 = Timer Expired, 0 = Not expired
; BCE6-BCE7 xxx Timer Value
; BCE8 Number of Lives
; BCF0-BDFF Hints given to player
;----------------------------------------------------
; BE00 Index to Routine (Table1) 1 thru 8
; BE01 .0 1 = Exit Main Loop
; .1 1 = SAVE GAME in progress
; .2
; .6 Audio Status 0 = Single Channel,1 = Stereo
; .7 Audio Source 0 = AUDIO1, 1 = AUDIO2
; BE02 Index to Routine (Table2)
; BE03 .0 1 = Reset Main Loop
; .1 REPLAY
; .2 1 = Combine Mode enabled, waiting for object selection
; .3 1 = Drop Mode enabled, waiting for object selection
; .4 0 = Audio Track1, 1 = Audio Track2
; BE04 Game Timer Control Register
; .0 1 = Timer ON, 0 = Timer OFF
; .1 1 = Timer Expired, 0 = Not expired
; BE05-BE06 Game Timer Value
; BE07 Programmable Timer Control Register
; .0 1 = Timer ON, 0 = Timer OFF
; .1 1 = Timer Expired, 0 = Not expired
; BE08-BE09 Programmable Timer Value
; BE0A Keyboard Character Pressed
; BE0B .0 Keyboard Buffer Indicator
; .1 Unknown
; BE0C .0-.4 Unknown
; .5-.7 Unknown
; BE0D Number of Credits, Tens/Ones
; BE0E Number of Credits, Hundreds
; BE0F Hold DIP Switch A
; BE10 Coin Slot 1 Debounce
; BE11 Coin Slot 2 Debounce
; BE12 Unknown
; BE13-BE14 Number of
; BE15-BE16 Temp BANK address
; BE17 .0 Unknown
; .7 Unknown
; BE18 Temporary RAM Spot
; BE23 DecisionTimer Control Register
; .0 1 = Timer ON, 0 = Timer OFF
; .1 1 = Timer Expired, 0 = Not expired
; BE24-BE25 DecisionTimer Value
; BE27-BC2C Unknown -important-
; BE2D-BE2F Initials - "RDI"
; BE30
; BE31-BE37 Unknown
; BE44-BE46 score, ranking?
; BE48 Timer Register
; .0
; .7 ??
;----------------------------------------------------
; Scoreboard Output Port is F6/F7, Data as follows
; where x is the digit to store
;----------------------------------------------------
; 0x Player1 Game time Remaining 1
; 1x Player1 Game time Remaining 10
; 2x Player1 Game time Remaining 100
; 3x Player1 Game time Remaining 1000
; 4x Player1 Game time Remaining 10000
; 5x Player1 Game time Remaining 100000
; 6x Credits 10
; 7x Credits 1
; x = [0,1,2,3,4,5,6,7,8,9]
;----------------------------------------------------
; INPUT/OUTPUT PORTS
;----------------------------------------------------
; Address Description
; 00 Unknown
; 01 Unknown
; 02 Unknown
; 03 Unknown
; 04 Unknown
; 20 Unknown
; 80 Unknown
; C0 Reset Keyboard Input Ready
; A0 Unknown
; E0 Unknown
; F0 Input Byte from LDPlayer
; F1 DIP Switch B/Coin Slots/READY Status
; F2 DIP Switch A
; F3 Interrupt Request
; F4 Output Byte to LDPlayer
; F5 Hardware
; .4 Coin Counter Hardware Increment
; .5 Set LDPlayer data bus as Input
; .6 LDPlayer ENTER
; .7 LDPlayer INT/EXT
; F6 Scoreboard
; F7 Scoreboard
;----------------------------------------------------
; KEYBOARD CHARACTERS
;----------------------------------------------------
; F1 (080h) CLEAR
; F2 (081h) none
; F3 (082h) ENTER
; F4 (083h) SPACE
;----------------------------------------------------
; DEFINES
;----------------------------------------------------
org 0000h
CPU = Z180
globals on
;----------------------------------------------------
; Start of RESET
;----------------------------------------------------
Reset:
L0000: DI ; Disable Interrupts
IM 1 ; Set Interrupt Mode 1
LD SP,0BFFFh ; Set Stack Pointer to end of RAM
OUT (0C0h),A ; Reset Keyboard Data Ready Interrupt
OUT (0A0h),A
XOR A ; A = 0
LD (0BE43h),A ;
LD A,010h ;
LD (0BE0Ch),A ;
OUT (020h),A ; Set Keyboard to Output
LD B,0FFh ;
L0017: LD A,(0BFFFh) ;
DJNZ L0017 ;
CALL L1247 ; Initialize Speech Chip
LD HL,0BE2Dh ; Set up pointer to initials
CALL L003B ; Check if initials are "RDI"
JP NZ, L00BA ; Not RDI, so jump ahead
LD A,0F5h
OUT (080h),A ; Write to Keyboard Interface (COP421L)
LD HL,0BE17h
SET 7,(HL)
JP L0095 ;
;----------------------------------------------------
; Not Used
;----------------------------------------------------
DB 0FFh, 0FFh, 0FFh, 0FFh
;----------------------------------------------------
; IM 1 INTERRUPT JUMP POINT
;----------------------------------------------------
L0038: JP L01B1 ; Goto IM 1 Interrupt Routine
;----------------------------------------------------
; Check if initials are "RDI"
; HL = Start of Initials
;----------------------------------------------------
L003B: LD A,'R' ; Check for "R"
CP (HL) ; Is first initial a "R"?
RET NZ ; No, so return
INC HL ; Point to next initial
LD A,'D' ; Check for "D"
CP (HL) ; Is middle initial a "D"?
RET NZ ; No, so return
INC HL ; Point to next initial
LD A,'I' ; Check for "I"
CP (HL) ; Is last initial a "I"?
RET ; Return
;----------------------------------------------------
; Not Used
;----------------------------------------------------
DB 0FFh, 0FFh, 0FFh, 0FFh, 0FFh, 0FFh, 0FFh, 0FFh
DB 0FFh, 0FFh, 0FFh, 0FFh, 0FFh, 0FFh, 0FFh, 0FFh
DB 0FFh, 0FFh, 0FFh, 0FFh, 0FFh, 0FFh, 0FFh, 0FFh
DB 0FFh, 0FFh, 0FFh, 0FFh, 0FFh
HALT
;----------------------------------------------------
; UNKNOWN Check for F5 in BE27
;----------------------------------------------------
L0067: CALL L21B3 ; Check if Programmable Timer expired
JR Z,L0067 ; Still running so just loop
LD HL,0BE17h
RES 7,(HL)
BIT 0,(HL)
RET Z
RES 0,(HL)
CALL L169E
LD HL,0BE27h
LD B,006h ; Loop = 6
LD A,0F5h ; Check for an F5
L0080: CP (HL) ; Was there an F5?
JR Z,L0087 ; Yes, so erase all bytes
INC HL ; Check next byte
DJNZ L0080 ; Loop until all 6 bytes are checked
RET ; Not found so return
;----------------------------------------------------
; F5 is in important bytes so reset them to zero
;----------------------------------------------------
L0087: XOR A ; Reset to zero
LD B,006h ; Loop = 6
LD HL,0BE27h ;
L008D: LD (HL),A ; Reset to zero
INC HL ;
DJNZ L008D ; Loop until all bytes cleared
CALL L16D8 ;
RET ;
L0095: LD DE,00005h ; Programmable Timer = 5
CALL L21A7 ; Set Programmable Timer
EI ; Enable Interrupts
CALL L0067 ; Wait until Timer expires..?
LD HL,0BE01h ; Get GAME STATUS Register
BIT 1,(HL) ; Is there a game waiting to be saved?
CALL NZ,L0E10 ; Yes, so call Save Game
;----------------------------------------------------
; Clear out all 10 SAVED GAME Banks.
;----------------------------------------------------
LD B,00Ah ; Loop = 10
LD DE,00200h ; DE = 200h
LD IY,0A800h ; IY = Start of Game Banks
L00B0: RES 7,(IY+001h) ; Clear bit 7 of A801
ADD IY,DE ; IY = IY + 200h
DJNZ L00B0 ; Loop until all banks marked
JR L00FD ; Jump ahead
;----------------------------------------------------
; Clear Out RAM (A000-BFFF)
;----------------------------------------------------
L00BA: LD HL,0A000h ; Setup loop pointer A000
LD DE,0A001h ; Setup Loop pointer A000+1
LD BC,01FFFh ; Loop size is 2K
LD (HL),000h ; Clear out RAM location
LDIR ; Loop until all locations cleared
;----------------------------------------------------
; Label SAVED GAME Banks 1-10
;----------------------------------------------------
LD DE,00200h ; DE = 200, Size of Bank
LD A,001h ; A = 1, First label
LD B,00Ah ; Loop = 10, Number of Banks
LD IY,0A800h ; IY = A800,AA00,AC00,etc. Start of Banks
L00D2: LD (IY+000h),A ; Store label
INC A ; A = A + 1, Increment label
ADD IY,DE ; IY = IY + 200h, Point to next Bank
DJNZ L00D2 ; Loop until all banks labeled
LD A,0F5h ;
OUT (080h),A ; Write to Keyboard Interface (COP421L)
LD HL,0BE17h
SET 7,(HL)
LD DE,00005h ; Programmable Timer = 5
CALL L21A7 ; Set Programmable Timer
EI ; Enable Interrupts
CALL L0067
LD HL,0A782h
LD (HL),0C1h
;----------------------------------------------------
; Store RDI initials
;----------------------------------------------------
LD HL,0BE2Dh ; Point to initials
LD (HL),'R' ; Store "R" in first spot
INC HL ; Point to next spot
LD (HL),'D' ; Store "D" in next spot
INC HL ; Point to next spot
LD (HL),'I' ; Store "I" in next spot
;----------------------------------------------------
; Blank out Scoreboard
;----------------------------------------------------
L00FD: LD B,008h ; Loop = 8
LD A,00Fh ; A = 0F,1F,2F,3F,4F,5F,6F,7F
L0101: OUT (0F6h),A ; Write A to F6
OUT (0F7h),A ; Write A to F7
ADD A,010h ; A = A + 10h
DJNZ L0101 ; Loop unit B = 0
;----------------------------------------------------
; Set Scoreboard Credits to "00"
;----------------------------------------------------
LD A,060h ; Send "0" to Credit Tens
OUT (0F7h),A ; Output to Scoreboard
LD A,070h ; Send "0" to Credit Ones
OUT (0F7h),A ; Output to Scoreboard
;----------------------------------------------------
; Store DIP Switch reading
;----------------------------------------------------
IN A,(0F2h) ; Get DIP Switch A
LD (0BE0Fh),A ; Store DIP A
;----------------------------------------------------
; Initialize Variables
;----------------------------------------------------
XOR A ; A = 0
LD B,A ; B = 0
LD C,A ; C = 0
LD (0BE04h),A ; Clear Game Timer Control Register
LD (0BE05h),BC ; Clear Game Timer
LD (0BE0Dh),A ; Clear Number of Credits, Tens/Ones
LD (0BE0Eh),A ; Clear Number of Credits, Hundreds
LD (0BE48h),A ; Clear Timer Register
CALL 0C08Bh ; Wait until System is Initialized
IN A,(0F1h) ; Get DIP Switch B
BIT 0,A ; Test B1, Diagnostic Mode
JP Z,L1F9B ; Diagnostic Mode ON, so begin Diagnostics
JP L0136 ; Jump ahead one line
;----------------------------------------------------
; Main Loop, Start with attract and cycle
; thru all routines in the table
;----------------------------------------------------
L0136: CALL LC07F ; Start Running the Main Loop
JR L0136 ; Just loop here
;----------------------------------------------------
; Setup the Main Loop
;----------------------------------------------------
L013B: LD HL,0BE00h ; Routine Pointer
LD (HL),000h ; Reset Main loop to 1st routine (attract mode)
;----------------------------------------------------
; HL = Pointer to Routine Table
;----------------------------------------------------
L0140: LD A,(HL) ; Get A from HL
SLA A ; Multiply A by 2
LD HL,0C03Dh ; Get Pointer to Jump table
ADD A,L ; Add Index
LD L,A ; Create new pointer
JR NC,L014B ; Check if carry is clear
INC H ; Create new pointer
;----------------------------------------------------
; Get Routine Address from Table A
;----------------------------------------------------
L014B: LD E,(HL) ; E = Jump Address (low byte)
INC HL ; Point to next spot
LD D,(HL) ; D = Routine Address (high byte)
EX DE,HL ; Put Routine Address in HL
;----------------------------------------------------
; Execute the Routine
;----------------------------------------------------
CALL L01AF ; Execute Routine
;----------------------------------------------------
; Check if we need to reset the Main Loop
;----------------------------------------------------
LD HL,0BE01h ; Get GAME STATUS Register
BIT 0,(HL) ;
JR Z,L0164 ;
RES 0,(HL) ;
XOR A ;
LD (0A64Ah),A ; Clear Length of Full Name
LD (0A68Bh),A ; Clear Length of First Name
JR L013B ; Reset Main Loop
;----------------------------------------------------
; Loop through all the routines
;----------------------------------------------------
L0164: LD HL,0BE00h ; Get Routine
INC (HL) ; Point to next Routine
LD A,008h ; Total Number of Routines is 8
L016A: CP (HL) ; Have we done all 8 Routines?
JP NZ,L0140 ; No, so execute the Routine
LD (HL),003h ; Yes, so start over at Routine #3
JP L0140 ; Execute Routine
;----------------------------------------------------
; Get Jump Address from Table B
;----------------------------------------------------
L0173: LD HL,0BE03h ;
RES 1,(HL) ;
RES 3,(HL) ; Clear Drop Mode
;----------------------------------------------------
; Stop DecisionTimer
;----------------------------------------------------
LD HL,0BE23h ; Get DecisionTimer Control Register
LD (HL),000h ; Stop DecisionTimer
LD HL,0BE02h ;
LD (HL),000h ;
L0184: LD A,(HL) ; Get Routine B Pointer
SLA A ; Multiply by 2
LD HL,0C04Dh ; Get Jump Table B
ADD A,L ;
LD L,A ;
JR NC,L018F ;
INC H ;
L018F: LD E,(HL) ;
INC HL ;
LD D,(HL) ;
EX DE,HL ; Put Routine Address in HL
CALL L01AF ; Execute Routine
LD HL,0BE03h ; Get Register
BIT 0,(HL) ; Should we leave the main loop?
JR Z,L01A0 ; No, continue loop
RES 0,(HL) ; Process request to leave loop
RET ; Leave main loop
L01A0: LD HL,0BE02h ; Get Routine Index
INC (HL) ; Point to next Routine
LD A,019h ; There are #25 Routines
CP (HL) ; Have we run all 25?
JP NZ,L0184 ; No, so keep looping
LD (HL),00Bh ; Yes, so start over at Routine #11
JP L0184 ; Loop back
;----------------------------------------------------
; Jump to Address in HL
;----------------------------------------------------
L01AF: JP (HL) ; Jump to address in HL
L01B0: RET ; No need to return : Routine #7
;----------------------------------------------------
; IM 1 Interrupt Routine
;----------------------------------------------------
; Save all registers before entering interrupt
;----------------------------------------------------
L01B1: PUSH BC ; Save BC Register
PUSH DE ; Save DE Register
PUSH HL ; Save HL Register
PUSH AF ; Save AF Register
PUSH IX ; Save IX Register
PUSH IY ; Save IY Register
IN A,(040h) ; Get Interrupt Request Status
BIT 3,A ; Are there interrupts pending?
JR NZ,L01C8 ; Yes, begin Interrupt routines
XOR A ; A = 0
OUT (0E0h),A ; Reset interrupt
NOP ; Pause
IN A,(0E0h) ; Reset interrupt
JP L0352 ; Jump to end of interrupt
;----------------------------------------------------
; Begin Interrupt Functions
;----------------------------------------------------
L01C8: BIT 4,A ; Test for timer interrupt
JP NZ,L02AE ; No timer interrupt, so do next check
CALL L0416 ; Decrement All Timers
LD A,(0BE13h) ; Get Coin Counter Debounce
OR A
JR Z,L0213
LD C,A ; C
LD A,(0BE14h)
BIT 7,A
JR Z,L01FB
L01DE: DEC A
LD (0BE14h),A
AND 00Fh
JR NZ,L0213
LD A,(0A783h)
RES 4,A ; Clear Coin Counter
LD (0A783h),A
OUT (0F5h),A ; Write to Coin Counter Hardware
XOR A
LD (0BE14h),A
DEC C
LD A,C
LD (0BE13h),A
JR L0213
L01FB: OR A ; Coin Counter Debounce at zero?
JR NZ,L020F ; No, so skip ahead
LD A,083h
LD (0BE14h),A
LD A,(0A783h) ;
SET 4,A ; Increment Coin Counter
LD (0A783h),A
OUT (0F5h),A ; Write to Coin Counter Hardware
JR L0213
L020F: LD C,001h
JR L01DE
L0213: LD A,(0BE0Fh) ; Get DIP Switch A
AND 007h ; Test for Free Play
JR Z,L0282 ; Free Play set so skip ahead
LD HL,0BE04h ; Get Game Timer Control Register
BIT 1,(HL) ; Has Game Timer expired?
JR NZ,L0249 ; No, so start new game
BIT 0,(HL)
JR Z,L0282
LD A,(0BE0Eh)
OR A
JR NZ,L0282
LD A,(0BE0Dh)
CP 003h
JR NC,L0282
LD HL,0BE12h
DEC (HL)
BIT 4,(HL)
JR Z,L0244
;----------------------------------------------------
; Blank out scoreboard
;----------------------------------------------------
LD A,06Fh ; Blank in Credit Tens
OUT (0F7h),A ; Output to Scoreboard
LD A,07Fh ; Blank in Credit Ones
OUT (0F7h),A ; Output to Scoreboard
JR L0282 ;
L0244: CALL L0287 ; Update Credits on scoreboard
JR L0282
L0249: LD (HL),001h ; Start Game Timer
;----------------------------------------------------
; Get Time Units for Credit per DIP Settings
;----------------------------------------------------
LD HL,002A0h ; Point to Time Units Table
L024E: DEC A ; Check DIP Setting
JR Z,L0255 ; Correct DIP Setting so award Time
INC HL ; Increment Table Pointer
INC HL ; Increment Table Pointer
JR L024E ; Loop until DIP Setting found
;----------------------------------------------------
; Award Time Units
;----------------------------------------------------
L0255: LD A,(HL) ; Get Time Unit Value
INC HL ; Point to next spot
LD H,(HL) ; Get Time Unit Value
LD L,A ; HL = Time Unit Value
LD (0BE05h),HL ; Update Game Timer
;----------------------------------------------------
; Subtract 1 Credit
;----------------------------------------------------
LD A,(0BE0Dh) ; Get Number of Credits, Tens/Ones
SUB 001h ; Subtract 1 credit
DAA ; Make into a decimal number
LD (0BE0Dh),A ; Store Number of Credits, Tens/Ones
LD C,A ; C = Number of Credits
LD A,(0BE0Eh) ; Get Number of Credits, Hundreds
SBC A,000h ; Subtract one if carry is set
DAA ; Make into a decimal number
LD (0BE0Eh),A ; Store Number of Credits, Hundreds
OR C ; A = A OR C
LD C,A ; C = A, Store Credits temporarily
CALL L0287 ; Update Credits on scoreboard
LD A,C ; A = C, Get Credits
OR A ; Any Credits?
JR NZ,L0282 ; Yes, some credits remain, so jump ahead
;----------------------------------------------------
; No Credits Left
;----------------------------------------------------
LD HL,0BE48h
SET 7,(HL)
LD HL,0BE04h
LD (HL),000h ; Stop Timer3
L0282: OUT (0A0h),A
JP L0352 ; Jump to end of interrupt
;----------------------------------------------------
; Send Number of Credits to Scoreboard
;----------------------------------------------------
L0287: LD A,(0BE0Dh) ; Get Number of Credits
AND 00Fh ; Get lower nibble
OR 070h ; Store in Ones
OUT (0F7h),A ; Output to Scoreboard
LD A,(0BE0Dh) ; Get Number of Credits
SRL A ; Shift byte right
SRL A ; Shift byte right
SRL A ; Shift byte right
SRL A ; Shift byte right
OR 060h ; Store in Tens
OUT (0F7h),A ; Output to Scoreboard
RET ; Return
;----------------------------------------------------
; Time Unit Table
;----------------------------------------------------
L02A0: .word 305 ; 30 seconds
.word 458 ; 45 seconds
.word 610 ; 60 seconds
.word 712 ; 70 seconds
.word 814 ; 80 seconds
.word 966 ; 95 seconds
.word 1119 ; 110 seconds
;----------------------------------------------------
; Check for interrupts from Speech Chip and Keyboard
;----------------------------------------------------
L02AE: BIT 2,A ; Interrupt from Speech Chip?
JR NZ,L02B8 ; No, so skip speech stuff
CALL L1269 ; Send data to Speech Chip
JP L0352 ; Jump to end of interrupt
L02B8: BIT 5,A ; Interrupt from Keyboard?
JR NZ,L02C2 ; No, so skip keyboard stuff
CALL L0384 ; Process Keyboard Input
JP L0352 ; Jump to end of Interrupt
;----------------------------------------------------
; Check Coin Slots
;----------------------------------------------------
L02C2: IN A,(0F1h) ; Get DIP Switch B
LD C,A ; C = DIP Switch B
LD HL,0BE10h ; Coin Slot 1 Debounce Count
BIT 4,C ; Test Coin Slot 1
CALL L02D9 ; Call Coin Check
LD HL,0BE11h ; Coin Slot 2 Debounce Count
BIT 5,C ; Test Coin Slot 2
CALL L02D9 ; Call Coin Check
OUT (0F3h),A ; Request External Interrupt?
JR L0352 ; Jump to end of Interrupt
;----------------------------------------------------
; Debounce Coin Slots
;----------------------------------------------------
; Coin Slot must be pressed for 3 consecutive
; readings to register a coin insertion.
;----------------------------------------------------
; A = BE10, Debounce Coin Slot 1 Count
; A = BE11, Debounce Coin Slot 2 Count
;----------------------------------------------------
L02D9: LD A,(HL) ; Get Debounce Count
JR Z,L0319 ; Coin Slot pressed, so skip ahead
OR A ; Does Debounce Count = 0?
RET Z ; Yes, so return
CP 002h ; Debounce = 2?
JR NZ,L02E4 ; No, so check if it is 3
L02E2: INC (HL) ; Increment Debounce Count
RET ; Return
L02E4: CP 003h ; Debounce = 3?
JR NZ,L0316 ; No, so skip ahead
LD A,003h ; Add 3 Credits
CALL L0320 ; Award Credits and Time
IN A,(0F2h) ; Get DIP Switch A
BIT 3,A ; Test A4, Coins per Credit
JR NZ,L030F
LD A,(0BE0Eh)
OR A
JR NZ,L030F
LD A,(0BE0Dh)
CP 006h ; Are there 6 credits left?
JR NC,L030F
LD A,(0BE04h)
BIT 0,A ; Timer3 still running?
JR NZ,L030F ; Yes, so skip ahead
LD A,060h ; Send "0" to Credit Tens
OUT (0F7h),A ; Output to Scoreboard
LD A,070h ; Send "0" to Credit Ones
OUT (0F7h),A ; Output to Scoreboard
L030F: LD A,(0BE13h) ; Get Number of Coins
INC A ; Add 1 Coin
LD (0BE13h),A ; Store Number of Coins
L0316: LD (HL),000h ; Reset Debounce Count to zero
|