|
;----------------------------------------------------
; 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
RET ; Return
L0319: CP 002h
JR C,L02E2
JR NZ,L0316
RET
;----------------------------------------------------
; Award Credits and Time
;----------------------------------------------------
; A = Number of Credits to add
;----------------------------------------------------
L0320: PUSH BC ; Save BC Register
PUSH HL ; Save HL Register
LD C,A ; C = A
LD A,(0BE0Dh) ; Get Number of Credits
ADD A,C ; Add to Number of Credits
DAA ; Make into a decimal number
LD (0BE0Dh),A ; Store number of credits
LD A,(0BE0Eh) ; Get Number of Credits, hundreds
ADC A,000h ; Add carry
DAA ; Make into decimal number
LD (0BE0Eh),A ; Store number of credits, hundreds
CALL L0287 ; Update Credits on scoreboard
LD A,(0BE0Fh) ; Get DIP Switch A
AND 007h ; Test for Free Play
JR Z,L034F ; Free Play set so skip ahead
;----------------------------------------------------
; Get Time Units for Credit per DIP Settings
;----------------------------------------------------
LD HL,002A0h ; Point to Time Units Table
L0341: DEC A ; Check DIP Setting
JR Z,L0348 ; Correct DIP Setting so award Time
INC HL ; Increment Table Pointer
INC HL ; Increment Table Pointer
JR L0341 ; Loop until DIP Setting found
;----------------------------------------------------
; Award Time Units
;----------------------------------------------------
L0348: 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
L034F: POP HL ; Restore HL Register
POP BC ; Restore BC Register
RET ; Return
;----------------------------------------------------
; Restore all registers upon leaving interrupt
;----------------------------------------------------
L0352: POP IY ; Restore IY Register
POP IX ; Restore IX Register
POP AF ; Restore AF Register
POP HL ; Restore HL Register
POP DE ; Restore DE Register
POP BC ; Restore BC Register
EI ; Enable Interrupts
RETI ; Return from Interrupt
;----------------------------------------------------
; Read Keyboard Status
;----------------------------------------------------
; HL = ?
;----------------------------------------------------
L035D: SET 0,(HL)
LD A,(0BE0Ch)
AND 01Fh
OR 020h
LD (0BE0Ch),A
OUT (020h),A ; Set Keyboard Mode to Input (20h)
L036B: IN A,(080h) ; Get Data from Keyboard
CP 0FAh ; Is keyboard ready?
JR NZ,L036B ; Wait here until ready
OUT (0C0h),A ; Reset Keyboard Data Ready Interrupt
LD A,0F5h
OUT (080h),A ; Write to Keyboard Interface (COP421L)
LD A,(0BE0Ch)
AND 01Fh
OR 000h
LD (0BE0Ch),A
OUT (020h),A
RET
;----------------------------------------------------
; Process Keyboard Input
;----------------------------------------------------
L0384: LD HL,0BE17h
BIT 7,(HL)
JR NZ,L035D ; Keyboard not ready so diagnose
LD A,(0BE0Ch)
AND 0E0h
CP 080h
JP Z,L03DD
CP 040h
JP Z,L03F7
LD HL,0BE0Bh ; Get Keyboard Buffer
RES 1,(HL)
IN A,(080h) ; Get character from Keyboard
CP 0F0h
JR Z,L03BC
CP 0F5h
JR NZ,L03AD
SET 2,(HL)
JR L03BC
L03AD: CP 0F3h
JR NZ,L03B5
RES 2,(HL)
JR L03BC
L03B5: SET 1,(HL) ;
SET 0,(HL) ; Mark Keyboard buffer full
LD (0BE0Ah),A ; Store character in Keypress location
L03BC: LD A,(0BE0Ch) ;
AND 01Fh
OR 020h
LD (0BE0Ch),A
OUT (020h),A ; Set Keyboard Mode to Input (20h)
L03C8: IN A,(080h) ; Get character from Keyboard
CP 0FAh
JR NZ,L03C8
LD A,(0BE0Ch)
AND 01Fh
OR 000h
LD (0BE0Ch),A
OUT (0C0h),A ; Reset Keyboard Data Ready Interrupt
OUT (020h),A
RET
L03DD: LD HL,0BE17h
SET 0,(HL)
LD A,(0BE0Ch)
AND 01Fh
OR 0A0h
LD (0BE0Ch),A
OUT (020h),A
L03EE: IN A,(080h) ; Get character from Keyboard
CP 0FAh
JR NZ,L03EE
OUT (0C0h),A ; Reset Keyboard Data Ready Interrupt
RET
L03F7: LD HL,0BE17h
SET 0,(HL)
IN A,(080h) ; Get character from Keyboard
LD (0BE26h),A
LD A,(0BE0Ch)
AND 01Fh
OR 020h
LD (0BE0Ch),A
OUT (020h),A ; Set Keyboard Mode to Input (20h)
L040D: IN A,(080h) ; Get status from Keyboard
CP 0FAh ; Check if keyboard ready
JR NZ,L040D ; Keyboard not ready so loop
OUT (0C0h),A ; Reset Keyboard Data Ready Interrupt
RET ; Return
;----------------------------------------------------
; Decrement All Timers
;----------------------------------------------------
L0416: LD HL,0BE23h ; Point to DecisionTimer
CALL L0458 ; Decrement DecisionTimer
LD HL,0BE07h ; Point to Programmable Timer
CALL L0458 ; Decrement Programmable Timer
LD HL,0BE04h ; Point to Insert Coin Timer
CALL L0458 ; Decrement Insert Coin Timer
;----------------------------------------------------
;
;----------------------------------------------------
LD HL,0BCE5h
BIT 0,(HL)
RET Z
CALL L0458 ; Decrement Timer
LD HL,0BCE5h
BIT 1,(HL)
RET Z
RES 1,(HL)
LD HL,001D6h
LD (0BCE6h),HL
LD B,00Fh ; 15 markers to check
LD HL,0BC9Fh ;
L0444: BIT 0,(HL) ;
DEC HL ;
JR Z,L0454 ;
CP (HL) ;
JR Z,L0454 ;
DEC (HL) ;
PUSH HL ;
LD HL,0BCE5h
SET 0,(HL) ; Start timer
POP HL
L0454: DEC HL
DJNZ L0444 ; Loop until all markers checked
RET ; Return
;----------------------------------------------------
; Decrement Timer Routine
;----------------------------------------------------
; HL = Pointer to Timer Control Register
; where:
; 00 = Timer Off
; 01 = Timer Enabled
; 02 = Timer Expired
; HL+1 = Timer (Low Byte)
; HL+2 = Timer (High Byte)
;----------------------------------------------------
L0458: BIT 0,(HL) ; Is timer enabled?
RET Z ; Timer not enabled so just leave
XOR A ; Check if timer is zero
INC HL ; Point to next Timer Byte
CP (HL) ; Is Timer byte at zero?
INC HL ; Point to next Timer Byte
L045F: JR NZ,L0469 ; Byte not at zero so decrement
CP (HL) ; Next byte at zero?
JR NZ,L0469 ; Byte not at zero so decrement
DEC HL ; Get Timer Control Register
L0465: DEC HL ; Get Timer Control Register
LD (HL),002h ; Mark Timer as "expired"
RET ; Return
;----------------------------------------------------
; Timer is enable and running so decrement it
;----------------------------------------------------
L0469: LD D,(HL) ; Get MSB of Timer
DEC HL ; Next byte
LD E,(HL) ; Get LSB of Timer
DEC DE ; Decrement Timer
LD (HL),E ; Store LSB of Timer
INC HL ; Next byte
LD (HL),D ; Store MSB of Timer
RET ; Return
;----------------------------------------------------
; Table A Routine #3: Get Scene Data
;----------------------------------------------------
; BC81h = Scene Index
;----------------------------------------------------
L0471: LD A,(0BC81h) ; Get Scene Index
L0474: LD L,A ; L = A
XOR A ; A = 0
LD H,A ; HL = Scene Index
ADD HL,HL ; HL = HL * 2
ADD HL,HL ; HL = HL * 2
ADD HL,HL ; HL = HL * 2
ADD HL,HL ; HL = HL * 2
LD C,L ; Move pointer into BC
LD B,H ; BC = HL * 16
;----------------------------------------------------
; Check which Audio Track is being used
;----------------------------------------------------
LD HL,0BE03h ; Get MODE Register
BIT 4,(HL) ; Check which Audio Track
JP NZ,L04A3 ; Use Audio Track 2, so skip ahead
;----------------------------------------------------
; Use Audio Track 1 Data
;----------------------------------------------------
LD HL,0D000h ; HL = Start of Scene Data (Audio Track 1)
ADD HL,BC ; Add Scene Index
PUSH HL ; Move Scene Pointer into IX
POP IX ; IX = Scene Data + Scene Index
LD A,(IX+00Ah) ; Get Val10
AND 0E0h ; Is bit set?
JR Z,L04AA ;
CP 060h ; Does Room require an item?
LD HL,0BC9Fh ; Load Pointer to inventory
JP Z,L04D1 ; No item required, jump ahead
CP 020h ; Does Room contain an item?
LD HL,0BCC0h ; Load Pointer to inventory2
JP Z,L04D1 ; Yes, Room has item, jump ahead
;----------------------------------------------------
; Use Audio Track 2 Data
;----------------------------------------------------
L04A3: LD HL,0D800h ; HL = Start of Scene Data (Audio Track 2)
ADD HL,BC ; Add Scene Index
PUSH HL ; Move Scene Pointer into IX
POP IX ; IX = Scene Data + Scene Index
L04AA: LD HL,0BE03h ;
BIT 1,(HL) ;
JR NZ,L04E3 ;
BIT 4,(IX+00Bh) ; Is player dead?
JR Z,L04E3 ; Yes, so just return
BIT 6,(IX+002h)
JR NZ,L04E3
LD D,(IX+00Dh) ; D = Wound value
LD A,(0BCE0h) ; Get Health Pointer
SUB D ; Subtract health
LD (0BCE0h),A ; Store new Health Pointer
DEC A
JP P,L04E3
LD A,(IX+00Ch) ; Next scene
JP L0474 ;
L04D1: LD A,(IX+00Ah) ; Get Item needed
AND 01Fh ; Extract pertinent information
ADD A,L ; Add item index to inventory index
LD L,A ; Point to inventory
JR NC,L04DB ; Skip for carry
INC H ; Point to inventory
L04DB: BIT 0,(HL) ; Is item on 1 or 2?
JP NZ,L04A3 ; Yes, so use Scene Index2
JP L04AA ; No, so continue with Index1
L04E3: RET ; Return
;----------------------------------------------------
; Routine #15: Check if Decision Timer is running
;----------------------------------------------------
L04E4: BIT 7,(IX+00Bh) ; Is scene timed? (Var0B)
RET Z ; No, so return
LD HL,0BE23h ; Get DecisionTimer Control Register
BIT 1,(HL) ; Is DecisionTimer running?
RET Z ; No, so just return
LD (HL),000h ; Stop DecisionTimer
LD A,(IX+00Ch) ; Get next scene
LD (0BC81h),A ;
LD HL,0BE03h ;
SET 0,(HL) ;
RES 4,(HL) ; Set Audio Track 1
RET ; Return
;----------------------------------------------------
; Start DecisionTimer
;----------------------------------------------------
; Load Value and Start Timer
;----------------------------------------------------
L04FF: BIT 7,(IX+00Bh) ; Is scene timed (Var0B)?
RET Z ; No, so return
LD L,(IX+00Dh) ; Get Timer Value (Var0D)
LD H,000 ; HL = Timer Value
SLA L ; HL = HL * 2
RL H ; Multiply Timer Value by 2
LD (0BE24h),HL ; Store DecisionTimer Value
LD HL,0BE23h ; Point to DecisionTimer Control Register
LD (HL),001h ; Start DecisionTimer
RET ; Return
;----------------------------------------------------
; Add Var09 to Scene Index? Unknown
;----------------------------------------------------
L0516: LD A,(IX+009h) ;
AND 0F0h
RET Z
SRL A
SRL A
SRL A
RES 0,A
LD HL,0BC81h ; HL = Scene Index
ADD A,L
LD L,A
JR NC,L052C
INC H
L052C: RES 0,(HL)
RES 1,(HL)
DEC HL
LD (HL),000h
CALL L05AC ; A = Number of something
CP 000h
RET NZ
LD HL,0BCE5h ;
LD (HL),A ;
INC HL ;
LD (HL),A ;
INC HL ;
LD (HL),A ;
RET ;
;----------------------------------------------------
; Check (Routine #8)
;----------------------------------------------------
L0542: LD A,(IX+009h)
AND 00Fh
RET Z
LD B,A
LD HL,0C986h
ADD A,L
LD L,A
JR NC,L0551
INC H
L0551: LD A,(HL)
LD C,A
LD A,B
LD HL,0BC81h
SLA A
ADD A,L
LD L,A
JR NC,L055E
INC H
L055E: BIT 0,(HL)
RET NZ
DEC HL
LD (HL),C
INC HL
SET 0,(HL)
RES 1,(HL)
CALL L05AC
CP 001h
RET NZ
LD HL,0BCE5h
SET 0,(HL)
RET
;----------------------------------------------------
; Table B Rountine #16: Unknown
; Check Locatons
; BC82h-BC9Fh
;----------------------------------------------------
L0574: XOR A ; A = 0
LD B,00Fh ; B = 15 Loop
LD HL,0BC9Fh ; HL = End of Marker
L057A: BIT 0,(HL) ; Test bit0 of Marker?
DEC HL ; Point to previous Marker
JR Z,L0582 ; Bit0 is off, so next marker
CP (HL) ; Is next Marker zero?
JR Z,L0586 ; Yes, so jump ahead
L0582: DEC HL ; Point to next marker
DJNZ L057A ; Have all 8 Marker's been checked?
RET ; Return
;----------------------------------------------------
; Marker Match B = 00 - 0F
;----------------------------------------------------
L0586: INC HL
RES 0,(HL) ; Mark as set
LD HL,0C995h ; Get Pointer to Marker Table
LD A,B ; Index into Table
ADD A,L ; HL = HL + B
LD L,A ; HL = HL + B
JR NC,L0592 ; HL = HL + B
INC H ; HL = HL + B
L0592: LD A,(HL) ; Get new scene index from table
LD (0BC81h),A ; Store new Scene Index
LD HL,0BE03h
SET 0,(HL)
RES 4,(HL) ; Set Audio Track 1
CALL L05AC
CP 000h
RET NZ
LD HL,0BCE5h
LD (HL),A
INC HL
LD (HL),A
INC HL
LD (HL),A
RET
;----------------------------------------------------
; Count Number of something
;----------------------------------------------------
; Return A = Number of occurances of bit 0
;----------------------------------------------------
L05AC: XOR A ; Number= 0
LD B,00Fh ; Loop = 15
LD HL,0BC83h
L05B2: BIT 0,(HL)
INC HL
INC HL
JR Z,L05B9
INC A
L05B9: DJNZ L05B2
RET
;----------------------------------------------------
; Rountine #6: Healing Place gives Full Strength
;----------------------------------------------------
L05BC: BIT 4,(IX+002h) ; Is this is healing place?
RET Z ; No, so return
LD A,(0BCE0h) ; Get Health Pointer
CP 008h ; Is player full health?
RET Z ; Yes, so return
LD A,008h ; Make full health
LD (0BCE0h),A ; Save Health Pointer
LD DE,0805Dh ; Phrase="You Have Been Healed"
CALL L1363 ; Call Speech Routine (phrase)
RET ; Return
;----------------------------------------------------
; Table B Rountine #20: Check Button: REPLAY
;----------------------------------------------------
L05D3: LD HL,0BE0Bh ; Check Keyboard Buffer
BIT 0,(HL) ; Has a key been pressed?
RET Z ; No, so return
LD A,(0BE0Ah) ; Get Keyboard Character
CP 035h ; Check if "REPLAY (5)" Pressed
RET NZ ; Not pressed, so return
RES 0,(HL) ; Clear Keyboard Buffer
BIT 7,(IX+00Bh) ; Is scene timed? (Var0B)
RET NZ ; Yes, so action is not allowed here
LD HL,0BE03h ;
SET 0,(HL) ;
SET 1,(HL) ;
RET ;
;----------------------------------------------------
; Table B Rountine #4: Award Points????
;----------------------------------------------------
L05EE: LD A,(0BE03h)
BIT 1,A
RET NZ
LD A,(0BC81h)
LD HL,0BCF0h
ADD A,L
LD L,A
JR NC,L05FF
INC H
L05FF: LD A,(HL)
L0600: BIT 7,(IX+002h)
JR NZ,L0613
AND 00Fh
CALL L0622
LD A,(HL)
AND 00Fh
CP 00Fh
RET Z
INC (HL)
RET
L0613: AND 0F0h
CALL L0622
AND 0F0h
CP 0F0h
RET Z
LD A,(HL)
ADD A,010h
LD (HL),A
RET
L0622: PUSH HL
JP NZ,L0661
CALL L0668 ; Award Points
LD A,(IX+008h) ; Get Scene Bonus
CP 0C9h ; Is Bonus = 201?
JR NZ,L064F
LD HL,0BE48h ; Get Timer Register
BIT 0,(HL)
JR NZ,L064F
;----------------------------------------------------
; Award Bonus Time
;----------------------------------------------------
LD HL,0BE04h ; Get Timer Register
RES 0,(HL) ; Stop Timer3
CALL L0287 ; Update Credits on scoreboard
LD DE,0009Fh ; Phrase = "Congratulations (*) You Have Won Bonus Time"
CALL L1363 ; Call Speech Routine (phrase)
LD A,001h ; Add 1 Credit
CALL L0320 ; Award Credits and Time
LD HL,0BE04h ; Point to Timer3 Register
SET 0,(HL) ; Start Timer3
L064F: LD HL,0BE01h ; Get GAME STATUS Register
RES 7,(HL)
L0654: BIT 3,(IX+007h) ; Check if scene requires single AUDIO
RES 6,(HL) ; Set Single Channel AUDIO
JR Z,L065E ; Single audio required so skip ahead
SET 6,(HL) ; Enable both AUDIO Channels
L065E: POP HL
LD A,(HL)
RET
L0661: LD HL,0BE01h ; Get GAME STATUS Register
SET 7,(HL)
JR L0654 ; Loop back
;----------------------------------------------------
; Award Bonus by adding it to score
;----------------------------------------------------
; L066B: A = Bonus Value
;----------------------------------------------------
L0668: LD A,(IX+008h) ; Get Bonus
L066B: LD HL,0BCE4h ; Get Score
ADD A,(HL) ; Add Bonus to Score LSB
LD (HL),A ; Store in Score
DEC HL ; Point to next Score byte
LD A,(HL) ;
ADC A,000h ;
LD (HL),A ;
DEC HL ;
LD A,(HL) ;
ADC A,000h ;
LD (HL),A ;
RET ; Return
;----------------------------------------------------
; Routine #7: Drop all items, Restore Spells
;----------------------------------------------------
L067B: BIT 5,(IX+002h) ;
RET Z ;
LD B,01Ah ; 26 items to check
LD HL,0BCA0h ; Point to inventory
LD DE,LC95F ; Point to Item Property Table
L0688: BIT 1,(HL) ; Is item being held?
JR Z,L0696 ; Not held so skip
EX DE,HL ; Set to check property
BIT 3,(HL) ; Is item property a spell?
EX DE,HL ; Set to check property
JR Z,L069F ;
SET 0,(HL) ;
L0694: RES 1,(HL) ; Drop item from inventory
L0696: INC HL ; Next inventory item
INC DE ; Next item property
DJNZ L0688 ; Loop until all items checked
XOR A ; Strength = 0
LD (0BCE1h),A ; Set Strength to 0
RET ; Return
L069F: SET 2,(HL) ; Mark item as used (no longer available)
JR L0694 ; Go back and check remaining items
;----------------------------------------------------
; Routine #4: Check for Wounds
;----------------------------------------------------
L06A3: BIT 4,(IX+00Bh) ; Is player dead?
RET Z ; Yes, so just return
LD HL,0C97Eh ; Point to health table
LD A,(0BCE0h) ; Get Health Index
ADD A,L ; Add Index to Health Table
LD L,A ; Add Index
JR NC,L06B3 ; Carry not set
INC H ; Add Index
L06B3: LD A,(0BCE1h) ; Get Strength
CP (HL) ; Compare Strenght to Health Table
JP M,L0723 ; Player is wounded
JR Z,L0723 ; Player is woudded
LD DE,00033h ; Phrase="(%) You Are Wounded"
CALL L1363 ; Call Speech Routine (phrase)
;----------------------------------------------------
; Player not strong enough, must drop item
;----------------------------------------------------
L06C2: LD DE,00034h ; Phrase="Choose The Item You Want To Drop (%)"
CALL L1363 ; Call Speech Routine (phrase)
;----------------------------------------------------
; Yell WAKEUP if player doesn't respond in time
;----------------------------------------------------
LD DE,000FFh ; Programmable Timer = FFh
CALL L21A7 ; Set Programmable Timer
L06CE: CALL L21B3 ; Check if Programmable Timer expired
JR Z,L06D8 ; Timer still running so skip ahead
CALL L085E ; Send a "Wake Up!" message to player
JR L06C2 ; Loop back and tell player to drop an item
L06D8: LD HL,0BE48h
BIT 7,(HL)
RET NZ
CALL L0DBF ; Check Keyboard
LD HL,0BE0Bh ; Get Keyboard Buffer
BIT 0,(HL) ; Has a key been pressed?
JR Z,L06CE ; No, so loop back and wait
RES 0,(HL) ; Clear Keyboard Buffer
LD HL,0BE07h ; Get Programmable Timer Control Register
LD (HL),000h ; Stop Programmable Timer
LD A,(0BE0Ah) ; Get Keyboard Character
BIT 6,A ; Was an item selected?
JR NZ,L0705 ; Yes, so goto Dropping Items
CP 032h ; Was the "2" (Inventory) key pressed?
JR NZ,L06C2 ; No, so tell player to choose another item
CALL L0CFA ; Inventory key pressed so goto Speak or Show Inventory
LD HL,0BE03h
BIT 0,(HL)
RET NZ
JR L06C2 ; Go back and Drop Item
L0705: CALL LC0A9 ; Do Dropping Items
LD HL,0C97Eh ; HL = Pointer to Health Table
LD A,(0BCE0h) ; Get
ADD A,L ;
LD L,A ;
JR NC,L0713 ;
INC H ;
;----------------------------------------------------
; Check player's strength
;----------------------------------------------------
L0713: LD A,(0BCE1h) ; Get Strength
CP (HL) ; Does player have enough strength?
JR Z,L071C ; Yes, enough strength so continue
JP P,L072B ; Must drop another item
L071C: LD DE,0007Ah ; Phrase="You Can Continue Now (%)"
CALL L1363 ; Call Speech Routine (phrase)
RET ; Leave Wounded Routine
L0723: LD DE,00033h ; Phrase="(%) You Are Wounded"
CALL L1363 ; Call Speech Routine (phrase)
JR L071C ; Let player continue
;----------------------------------------------------
; Must drop another item
;----------------------------------------------------
L072B: LD DE,000A2h ; Phrase = "Press Any Key To Continue"
CALL L1363 ; Call Speech Routine (phrase)
JR L06C2 ; Loop back and drop another item
;----------------------------------------------------
; Check Dropping Items
;----------------------------------------------------
L0733: LD A,(0BE0Ah) ; Get Keyboard Character
AND 01Fh ; Extract pertinent information
LD (0BE18h),A ; Store Item Number
CALL L11DF ; HL Points to Item in inventory
XOR A ; Check if zero
CP (HL) ; Is the item available?
RET Z ; No, not available so return
BIT 1,(HL) ; Is item in inventory?
JR NZ,L0767 ; Yes, so go to Drop Routine
CALL L136C ; Clear Speech Buffer
LD DE,00030h ; Phrase="Sorry (%) You Don't Have"
CALL L1383 ; Get Phrase from Table
LD A,(0BE18h) ; Get Item Number
LD E,A ; Point to Item Word
LD D,080h ; DE = Item
CALL L1383 ; Get Phrase from Table
CALL L21C1 ; Command Speech Chip to speak buffer
LD HL,0BCA0h ; HL = Start of Inventory
CALL L12F6 ; Speak Inventory
LD DE,000FFh ; Programmable Timer = 0FFh
CALL L21A7 ; Set Programmable Timer
RET ; Return
;----------------------------------------------------
; Drop Item
;----------------------------------------------------
L0767: CALL L136C ; Clear Speech Buffer
LD DE,00036h ; Phrase="(%) You Have Dropped"
CALL L1383 ; Get Phrase from Table
LD A,(0BE18h) ; Get Item Number to drop
LD E,A ; Point to Item Word
LD D,080h ; DE = Item Word
CALL L1383 ; Get Phrase from Table
CALL L21C1 ; Command Speech Chip to speak buffer
LD A,(0BE18h) ; Get Item Number to drop
LD DE,0C95Eh ; Add item number to Table start
ADD A,E ; Do addition
LD E,A ; Do addition
JR NC,L0787 ; Do addition
INC D ; DE = Table + Item Number
L0787: EX DE,HL ; HL = Item Properties
BIT 4,(HL) ; Check item's properties
EX DE,HL ; HL = Inventory Item
JR Z,L07A7 ; Not heavy, skip ahead
SET 0,(HL) ; Mark item as previously picked up
L078F: RES 1,(HL) ; Mark item as dropped
;----------------------------------------------------
; Adjust player's strength after dropping item
;----------------------------------------------------
LD A,(DE) ; Get Item Property
AND 007h ; Get Item Weight
LD B,A ; B = Item Weight
LD A,(0BCE1h) ; Get Strength
SUB B ; Adjust Strength with dropped item
LD (0BCE1h),A ; Save new Strength
LD HL,0BE07h ; Get Programmable Timer Control Register
RES 0,(HL) ; Disable Programmable Timer
LD HL,0BE03h ;
RES 3,(HL) ; Clear Drop Mode
RET ; Return
;----------------------------------------------------
;
;----------------------------------------------------
L07A7: SET 2,(HL) ;
JR L078F ;
;----------------------------------------------------
; Routine #14: Check if player pressed an ITEM key
;----------------------------------------------------
L07AB: LD HL,0BE0Bh ; Get Keyboard Buffer
BIT 0,(HL) ; Has a key been pressed?
RET Z ; No, so return
LD A,(0BE0Ah) ; Get keyboard character
BIT 6,A ; Is keypress an item?
RET Z ; No, so return
;----------------------------------------------------
; Check if item is in inventory
;----------------------------------------------------
AND 01Fh ; Get item number
LD (0BE18h),A ; Save item number
CALL L11DF ; Point to Item in Inventory
XOR A ; Check item status
CP (HL) ; Is item in inventory?
JR NZ,L07C9 ; Yes, so skip ahead
LD HL,0BE0Bh ; Get Keyboard Buffer
RES 0,(HL) ; Clear keyboard buffer
RET ; Return
;----------------------------------------------------
; Check for COMBINE Item Mode
;----------------------------------------------------
L07C9: LD HL,0BE03h ; Get MODE Register
BIT 2,(HL) ; Are we in COMBINE Mode?
JR Z,L07D4 ; No, so check next mode
CALL LC0AC ; Do Combining Items
RET ; Return
;----------------------------------------------------
; Check for DROP Item Mode
;----------------------------------------------------
L07D4: BIT 3,(HL) ; Are we in DROP Mode?
JR Z,L07E1 ; No do skip ahead
CALL LC0A9 ; Do Dropping Items
LD HL,0BE0Bh ; Get Keyboard Buffer
RES 0,(HL) ; Clear keyboard buffer
RET ; Return
;----------------------------------------------------
; Check for automatic pick up
;----------------------------------------------------
L07E1: BIT 7,(IX+002h) ; Does location utilize item?
JR Z,L0800 ; No, so skip ahead
LD A,(IX+00Ah) ; Get item located in room
LD B,A ; B = Item to be picked up
AND 060h ;
CP 060h ; Is the item automatically picked up?
JR NZ,L07F5 ; Yes, so jump ahead
CALL LC0AF ; Using or Picking up items
RET ; Return
;----------------------------------------------------
;
;----------------------------------------------------
L07F5: LD A,B ; Get item to be picked up
AND 020h ;
CP 020h ;
JR NZ,L0800 ;
CALL LC0B2 ;
RET ; Return
;----------------------------------------------------
; Item not used here
;----------------------------------------------------
L0800: LD HL,0BE0Bh ; Get Keyboard Buffer
RES 0,(HL) ; Clear Keyboard Buffer
CALL L136C ; Clear Speech Buffer
LD A,(0BE18h) ; Get item being used
LD E,A ; Make item into word
LD D,080h ; Setup word to speak
CALL L1383 ; Get Phrase from Table
LD A,(0BE18h) ; Get item being used
CALL L11DF ; Point to Item in Inventory
BIT 1,(HL) ; Is item in inventory?
LD DE,00031h ; Phrase="Won't Work Here (%)"
JR NZ,L0821 ; Item in inventory so skip ahead
;----------------------------------------------------
; Item not in inventory
;----------------------------------------------------
LD DE,00078h ; Phrase="Is Not Here (%)"
L0821: CALL L1383 ; Get Phrase from Table
CALL L21C1 ; Command Speech Chip to speak buffer
RET ; Return
;----------------------------------------------------
; Table B Rountine #19: Check Button: DROP ITEM
;----------------------------------------------------
L0828: LD HL,0BE03h ; Check Register
BIT 3,(HL) ; Are we in Drop Mode?
JR NZ,L0854 ; Yes we are so jump ahead
LD HL,0BE0Bh ; Check Keyboard Buffer
BIT 0,(HL) ; Has a key been pressed?
RET Z ; No, so return
LD A,(0BE0Ah) ; Get Keyboard Character
CP 033h ; Check if "DROP ITEM (3)" was pressed
RET NZ ; Not pressed, so return
RES 0,(HL) ; Clear Keyboard Buffer
BIT 7,(IX+00Bh) ; Is this scene timed? (Var0B)
RET NZ ; Yes, so action is not allowed here
L0842: LD DE,00034h ; Phrase="Choose The Item You Want To Drop (%)"
CALL L1363 ; Call Speech Routine (phrase)
LD DE,000FFh ; Programmable Timer = 0FFh
CALL L21A7 ; Set Programmable Timer
LD HL,0BE03h ; Get Register
SET 3,(HL) ; Set Drop Mode
RET ; Return
;----------------------------------------------------
; Drop Mode enable
;----------------------------------------------------
L0854: CALL L21B3 ; Check if Programmable Timer expired
RET Z ; Programmable Timer still running so return
CALL L085E ; Timed-out, so send Wake Up message to player
JR L0842 ; Ask Player which item to drop
RET ; Return
;----------------------------------------------------
; Speak "Wake Up" Message to player
;----------------------------------------------------
L085E: PUSH AF ; Save AF Register
LD IY,L12AF ; Random Phrase = "Act Lively"
CALL L15EE ; Speak Random Phrase
POP AF ; Restore AF Register
RET ; Return
;----------------------------------------------------
; Routine #2:
;----------------------------------------------------
L0868: CALL LC082 ; Enter Name in Keyboard
LD HL,0BE48h ;
BIT 7,(HL) ;
JR Z,L0880 ;
RES 7,(HL) ;
LD DE,0009Eh ; Phrase="Your Time Is Up (*)"
CALL L1363 ; Call Speech Routine (phrase)
L087A: LD HL,0BE01h ; Get GAME STATUS Register
SET 0,(HL) ; Request Exit Main Loop
RET ; Return
L0880: CALL LC088 ; Look for a Saved Game
CP 000h ; Have we found a saved game match?
JR Z,L0892 ; Yes, a saved game was found so skip ahead
CALL LC085 ; Check if First Name Basis is okay
XOR A ;
LD (0BCE9h),A ;
CALL LC091 ;
RET ;
;----------------------------------------------------
; A Saved Game was found
;----------------------------------------------------
L0892: CALL LC08E ; Welcome Player Back, Check lives
LD A,001h ;
CALL LC09D ;
CALL LC0A3 ; Retrieve Saved BANK data
RET ; Return
;----------------------------------------------------
; Cycle Routine #5: Wait until System is Initialized
;----------------------------------------------------
L089E: CALL L1C67 ; Initialize System
JR C,L089E ; Loop until System Initialized
RET ; Return
;----------------------------------------------------
; HL = HL + A * 2
; DE = (new HL), BC = 0
;----------------------------------------------------
L08A4: SLA A ;
ADD A,L ;
LD L,A ;
JR NC,L08AB ;
INC H ;
L08AB: LD E,(HL) ;
INC HL ;
LD D,(HL) ;
INC HL ;
LD BC,00000h ;
RET ;
;----------------------------------------------------
; Cycle Routine #6: Call all BATCH 2 routines
;----------------------------------------------------
L08B3: CALL LC094 ; #8
CALL LC097 ;
CALL LC09A ; #10 Initialize data in a Game BANK
CALL LC09D ; #11 routine
CALL LC0A0 ;
CALL LC0A3 ; #13 Retrieve Saved BANK data
RET ; Return
;----------------------------------------------------
; Welcome Player Back, Check lives
;----------------------------------------------------
L08C6: PUSH IY ; Save IY Register
LD IY,012CBh ; Random Phrase = "Nice To Have You Here Again (#)"
CALL L15EE ; Speak Random Phrase
POP IY ; Restore Save BANK address
CALL LC0A3 ; Retrieve Saved BANK data
PUSH IY ; Save BANK address (IY)
CALL LC085 ; Check if First Name Basis is okay
POP IY ; Restore BANK address (IY)
LD A,(0BCE8h) ; Get Number of Lives
CP 000h ; Any lives left?
JR NZ,L08EA ; Yes, so skip ahead
LD DE,00075h ; Phrase="Last Time You Played You Lost All Your Lives For I Will Start You Over"
CALL L1363 ; Call Speech Routine (phrase)
JR L0916 ; Initial a BANK and retreive saved game
;----------------------------------------------------
; Copy Score into speakable number
;----------------------------------------------------
L08EA: LD HL,0BCE2h ; HL = Pointer to Score
LD DE,0A6D0h ; Location of speakable number
LD BC,00003h ; Copy 3 bytes to (n) speakable number
LDIR ; Perform byte copy
LD DE,00076h ; Phrase="Last Time You Played Your Score Was (n)"
CALL L1363 ; Call Speech Routine (phrase)
CALL L0DAD ; "Out Of A Possible (n)"
LD HL,0BE0Bh ; Check Keyboard Buffer
L0901: RES 0,(HL) ; Clear Keyboard Buffer
LD DE,00061h ; Phrase="Do You Want To Continue Your Game (%)"
CALL L1363 ; Call Speech Routine (phrase)
CALL L19E7 ; Check for "YES" or "NO"
JR C,L08EA ; Timed out so repeat question
JR Z,L091D ; "YES" so jump ahead and continue
;----------------------------------------------------
; Do Not Continue Game
;----------------------------------------------------
LD DE,00062h ; Phrase="O K (%) I Will Start You Over Again"
CALL L1363 ; Call Speech Routine (phrase)
L0916: CALL LC09A ; Initialize data in a Game BANK
L0919: CALL LC0A3 ; Retrieve Saved BANK data
RET ; Return
;----------------------------------------------------
; Continue Game
;----------------------------------------------------
L091D: LD HL,0BE03h ;
SET 1,(HL) ;
JR L0919 ;
;----------------------------------------------------
; Copy Name Data (transfer, clear)
;----------------------------------------------------
L0924: PUSH IY ; Save BANK address
LD DE,08000h ; Phrase = "Thayer's Quest"
CALL L136C ; Clear Speech Buffer
CALL L1383 ; Get Phrase from Table
LD A,(0A614h) ; Get number of characters in buffer
INC A ; Add one character
CP 021h ; Are there more than 32 characters in buffer?
JR C,L0939 ; No, so continue
LD A,020h ; Limit buffer size to 32 characters
;----------------------------------------------------
; Copy Speech Buffer into BANK
;----------------------------------------------------
L0939: LD (IY+003h),A ; Save number of characters in buffer into BANK
LD HL,0A000h ; HL = Start of Speech Buffer
LD B,020h ; 32 characters to copy
INC IY
L0943: LD A,(HL)
LD (IY+003h),A
INC IY
INC HL
DJNZ L0943
POP IY
CALL L169E
;----------------------------------------------------
; Copy 6 bytes into memory
;----------------------------------------------------
PUSH IY ; IY + 6B = Destination
LD HL,0BE27h ; BE27-BE2D Source to copy from
LD B,006h ; Loop = 6 bytes
L0958: LD A,(HL) ; Get Data bytes
LD (IY+06Bh),A ; Store the byte
INC IY ; Point to next spot
INC HL ; Point to next spot
DJNZ L0958 ; Loop until all 6 bytes transferred
POP IY ;
PUSH IY ;
;----------------------------------------------------
; Copy Name Data to memory
;----------------------------------------------------
LD HL,0A64Ah ; Point to start of name data
LD B,041h ; Loop = 65 bytes
L096A: LD A,(HL) ; Get Name Data
LD (IY+024h),A ; Copy name data to BANK
INC IY ; Point to next spot
INC HL ; Point to next spot
DJNZ L096A ; Loop until all name data copied
POP IY ; Restore BANK address
RET ; Return
;----------------------------------------------------
; Cycle Routine #4: Look for a Saved Game
;----------------------------------------------------
; Check to see if the Player's Name shows up
; in any of the 10 Saved Game Banks.
;----------------------------------------------------
; RETURN A = Save Game Bank to use (default = 1)
; IY = Start of Bank Address (default = BA00)
;----------------------------------------------------
L0976: LD IY,0A800h ; IY = Start of Game Banks
LD B,00Ah ; Loop = 10 banks
LD DE,00200h ; DE = Size of each bank
L097F: PUSH BC ; Save Loop
PUSH IY ; Save Start of Game Banks
LD B,041h ; Loop = Size of space for Player's Name
LD HL,0A64Ah ; Point to start of Length of Name
L0987: LD A,(IY+024h) ; Get name character from bank
CP (HL) ; See if the character matches
JR NZ,L0992 ; No match, so try next bank
INC HL ; Check next character
INC IY ; Check next character
DJNZ L0987 ; Loop back and check all characters
;----------------------------------------------------
; See if a match was found
;----------------------------------------------------
L0992: POP IY ; IY = Start of the Saved Bank
LD A,B ; A = character left to check
POP BC ; BC = Bank number that matches
CP 000h ; Have all characters been matched?
RET Z ; Yes, so we have a match. Return.
;----------------------------------------------------
; Check remaining Banks
; then use default A = 1, IY = BA00
;----------------------------------------------------
ADD IY,DE ; Skip to the next bank
DJNZ L097F ; Loop back until all 10 banks are checked
LD A,001h ; No match so use Bank 1
RET ; Return
;----------------------------------------------------
; #11
;----------------------------------------------------
L09A0: CALL L169E ;
PUSH IY ; Save IY Register before copy
LD HL,0BE27h ;
LD B,006h ; Loop = 6
L09AA: LD A,(HL) ;
LD (IY+065h),A ;
INC IY ;
INC HL ;
DJNZ L09AA ; Loop until all 6 checked
POP IY ; Restore IY Register after copy
LD A,(IY+071h) ;
INC A ;
RET Z ;
LD (IY+071h),A
RET
L09BE: PUSH IY
POP HL
INC HL
INC HL
LD D,H
LD E,L
INC DE
LD BC,001FDh
LD (HL),000h
LDIR
RET
;----------------------------------------------------
; Retrieve Saved BANK data
;----------------------------------------------------
; IY = BANK location to copy from
;----------------------------------------------------
L09CE: PUSH IY ; Copy BANK address(IY) to HL
POP HL ; Location to copy from
LD DE,0BC00h ; Location to copy to
LD BC,00200h ; Number of bytes to copy
LDIR ; Copy all bytes
RET ; Return
;----------------------------------------------------
; BATCH 2: #8 Check all BANKs for ?
;----------------------------------------------------
L09DA: LD HL,0BE18h ;
LD (HL),064h ; 100
LD IY,0A800h ; Start of game BANKS
LD B,00Ah ; Loop = 10 banks
L09E5: LD A,(IY+001h) ; Get
CP 000h ; does bank need checking?
JR NZ,L09EF ; No, so skip ahead
CALL LC0A6 ; check bank
L09EF: LD DE,00200h ; DE = Size of BANK
ADD IY,DE ; Go to next BANK
DJNZ L09E5 ; Loop until all banks checked
LD IY,(0BE15h) ;
RET ; Return
;----------------------------------------------------
; check if bank data matches BE18-BE1C
;----------------------------------------------------
L09FB: LD HL,0BE18h ;
LD A,(IY+065h) ;
CP (HL) ;
JR Z,L0A07 ;
JR C,L0A2B ;
RET ; Return
;----------------------------------------------------
; 6 loop
;----------------------------------------------------
L0A07: INC HL ;
LD A,(IY+066h) ;
CP (HL) ;
JR Z,L0A11 ;
JR C,L0A2B ;
RET ;
;----------------------------------------------------
; 6 loop
;----------------------------------------------------
L0A11: INC HL ;
LD A,(IY+067h) ;
CP (HL) ;
JR Z,L0A1B ;
JR C,L0A2B ;
RET ;
;----------------------------------------------------
; 6 loop
;----------------------------------------------------
L0A1B: INC HL ;
LD A,(IY+069h) ;
CP (HL) ;
JR Z,L0A25 ;
JR C,L0A2B ;
RET ;
;----------------------------------------------------
; 6 loop
;----------------------------------------------------
L0A25: INC HL ;
LD A,(IY+06Ah) ;
CP (HL) ;
RET NC ;
;----------------------------------------------------
; 6 loop
;----------------------------------------------------
L0A2B: LD A,(IY+065h)
LD (0BE18h),A
LD A,(IY+066h)
LD (0BE19h),A
LD A,(IY+067h)
LD (0BE1Ah),A
LD A,(IY+069h)
LD (0BE1Bh),A
LD A,(IY+06Ah)
LD (0BE1Ch),A
LD (0BE15h),IY
RET ; Return
;----------------------------------------------------
; Initialize data in a New Game BANK
;----------------------------------------------------
L0A4E: PUSH IY ; Transfer BANK address to DE
POP DE ; DE = Saved BANK address
;----------------------------------------------------
; Clear BANK game data section BC80 - BDFF
;----------------------------------------------------
LD HL,0080h ; Point to section of BANK
ADD HL,DE ; Add 80h to BANK address
LD D,H ; Transfer sum back to DE
LD E,L ; Transfer sum back to DE
INC DE ; Add 1 to DE
LD BC,0017Fh ; Loop = 383 bytes
LD (HL),000h ; Setup clearing bytes
LDIR ; Loop until all bytes are cleared
;----------------------------------------------------
; Setup lives and health
;----------------------------------------------------
LD A,(LC000) ; Get initial number of lives
PUSH IY ; Setup BANK pointer
LD BC,0080h ; Point to lives/health area
ADD IY,BC ; Add to BANK pointer
LD (IY+060h),008h ; BCE0: Index to health table
LD (IY+068h),A ; BCE8: Number of lives
;----------------------------------------------------
; Determine which keys have no items associated
;----------------------------------------------------
POP IY ; Get BANK address
PUSH IY ; Transfer BANK address to DE
POP DE ; DE = BANK address
LD HL,000A0h ; Point to section of BANK
ADD HL,DE ; Add A0h to BANK address
LD DE,LC95F ; Point to item property table
LD B,01Ah ; Loop = 26 items to check
L0A7E: EX DE,HL ; Switch register
BIT 6,(HL) ; Does key have an item associated?
EX DE,HL ; Switch register
JR NZ,L0A86 ; Key has no item, so skip ahead
LD (HL),001h ; Mark item as valid
L0A86: INC HL ; Check next item property
INC DE ; Check next inventory location
DJNZ L0A7E ; Loop until all items checked
;----------------------------------------------------
; Setup initial item inventory BCA0-BCBA
;----------------------------------------------------
PUSH IY ; Save BANK address
PUSH IY ; Save BANK address
POP DE ; DE = BANK address
LD HL,000E1h ; Point to section of BANK
ADD HL,DE ; Add E1h to BANK address
EX DE,HL ; DE = Pointer to Strength (BCE1)
LD B,01Ah ; Loop = 26 items to check
LD HL,LC95F ; Point to Item Property Table
L0A99: BIT 5,(HL) ; Does player start game with this item?
JR Z,L0AB7 ; Do not start with this item, so skip ahead
;----------------------------------------------------
; Ajust player's strength when taking initial items
;----------------------------------------------------
LD A,(HL) ; Get item property
AND 007h ; Get item weight
LD C,A ; C = Item weight
LD A,(DE) ; Get Strength
ADD A,C ; Add weight to Strength
LD (DE),A ; Save Strength
;----------------------------------------------------
; Update inventory with item
;----------------------------------------------------
PUSH IY ; Save
PUSH BC ;
LD BC,00080h ; Point to section of BANK
ADD IY,BC ; Add 80h to BANK address
RES 0,(IY+020h) ; BCA0
SET 1,(IY+020h) ; BCA0
POP BC ;
POP IY ;
L0AB7: INC HL ;
INC IY ;
DJNZ L0A99 ; Loop until all items are checked
;----------------------------------------------------
; Setup
;----------------------------------------------------
POP IY ;
PUSH IY
POP DE
LD HL,000C0h
ADD HL,DE
LD B,020h ; Loop = 32
L0AC7: LD (HL),001h
INC HL
DJNZ L0AC7
LD A,(IY+072h)
INC A
RET Z
LD (IY+072h),A
RET
;----------------------------------------------------
; Table B Routine #5: Get Scene Frame Number/Scene Play Timer
;----------------------------------------------------
; (IX+0Fh)(IX+0Eh) = Scene Play Time
; (IX+01h)(IX+00h) = Starting Frame Number
;----------------------------------------------------
L0AD5: LD C,(IX+00Eh) ; Get BC
LD B,(IX+00Fh) ; BC = Scene Play Time
LD HL,0BE03h
BIT 1,(HL)
JR NZ,L0AE8
BIT 5,(IX+00Bh)
JR NZ,L0AF2 ; No, so skip ahead
L0AE8: LD E,(IX+000h) ; Get DE
LD D,(IX+001h) ; DE = Starting Frame Number for scene
CALL L1BE3 ; PLAY Scene with Timer
RET ; Return
L0AF2: CALL L1CB0 ; Send 2 PLAY commands
RET ; Return
;----------------------------------------------------
; Store Speakable Number for Speech
; A = Number (0-9)
;----------------------------------------------------
L0AF6: LD (0A6D2h),A ; Store A in Ones
XOR A ; A = 0
LD (0A6D1h),A ; Store zero in other spots
LD (0A6D0h),A ; Store zero in other spots
RET ; Return
;----------------------------------------------------
; Routine2: #3 Check if Player has Died
;----------------------------------------------------
L0B01: BIT 4,(IX+00Bh) ; Test if Player died
JR Z,L0B7A ; Yes, Player dead
BIT 6,(IX+002h)
RET Z
;----------------------------------------------------
; No lives left
;----------------------------------------------------
LD A,R ; A = Random Number
AND 003h ; A = number between 0-3
LD DE,08043h ; Phrase="(%) You Just Died"
ADD A,E ; Add Random Number
LD E,A ; Store Message Pointer
CALL L1363 ; Call Speech Routine (phrase)
XOR A ; Number of Lives = 0
LD (0BCE8h),A ; Set Number of Lives to zero
L0B1C: LD DE,00062h ; Phrase="O K (%) I Will Start You Over Again"
CALL L1363 ; Call Speech Routine (phrase)
CALL L0C00 ; Show Ranking and Speak Score
L0B25: LD A,(0BCE9h)
LD (0BE18h),A
LD IY,0BC00h ; Initialize start of Working BANK
CALL LC09A ; Initialize data in a Game BANK
LD A,(0BE0Fh) ; Get DIP Switch A
BIT 4,A ; Test A5, Lives per Game
JR NZ,L0B3E ; 3 Lives, so skip ahead
LD HL,0BCE8h ; HL = Number of Lives
LD (HL),005h ; Set Number of Live to 5
L0B3E: LD A,(0BE18h)
LD (0BCE9h),A
LD HL,0BE0Bh ; Check Keyboard Buffer
RES 0,(HL) ; Clear keyboard buffer
L0B49: LD DE,00096h ; Programmable Timer = 096h
CALL L21A7 ; Set Programmable Timer
LD DE,00090h ; Phrase="Press Any Key To Continue"
CALL L1363 ; Call Speech Routine (phrase)
L0B55: LD HL,0BE0Bh ; Get Keyboard Buffer
BIT 0,(HL) ; Has key been pressed?
JR NZ,L0B6B ; Yes, key pressed to skip ahead
LD HL,0BE48h ; Check Timer register
BIT 7,(HL) ; Has timer expired?
JP NZ,L087A
CALL L21B3 ; Check if Programmable Timer expired
JR Z,L0B55
JR L0B49 ; Reset timer
L0B6B: RES 0,(HL)
LD A,001h
LD (0BC81h),A
LD HL,0BE03h
RES 4,(HL) ; Set Audio Track 1
SET 0,(HL)
RET
;----------------------------------------------------
; Player died, lose one life
;----------------------------------------------------
L0B7A: BIT 6,(IX+002h)
RET Z
LD A,R ; A = Random Number
AND 003h ; A = number between 0-3
LD DE,08043h ; Phrase="(%) You Just Died"
ADD A,E ; Add Random number
LD E,A ; Store Message Pointer
CALL L1363 ; Call Speech Routine (phrase)
LD HL,0BCE8h ; Get Number of Lives
DEC (HL) ; Subtract 1
LD A,(HL) ; A = Number of Lives
CP 001h ; 1 life left?
JR Z,L0BA5 ; One life, so skip ahead
CALL L0AF6 ; n = Number of Lives
LD DE,0006Eh ; Phrase="You Have (n) Lives Left"
CALL L1363 ; Call Speech Routine (phrase)
LD A,(0BCE8h) ; Get Number of Lives
CP 000h ; Are there zero lives left?
JP Z,L0B1C ; No lives, so start over
L0BA5: LD DE,0007Fh ; Phrase = "?" <last life>
CALL Z,L1363 ; Call Speech Routine (phrase)
LD A,(IX+003h)
LD (0BC81h),A
LD HL,0BE03h
SET 0,(HL)
RES 4,(HL) ; Set Audio Track 1
RET ; Return
;----------------------------------------------------
; Check for Game Over (Play Clock Timer Expires)
;----------------------------------------------------
L0BB9: LD HL,0BE48h ; Get Play Clock Register
BIT 7,(HL) ; Test if Play Clock has expired
RET Z ; Clock still running, so return
RES 7,(HL) ; Stop Play Clock
LD DE,0009Eh ; Phrase="Your Time Is Up (*)"
CALL L1363 ; Call Speech Routine (phrase)
CALL L0C00 ; Show Ranking and Speak Score
CALL L0DF9 ; Do Save Game
LD HL,0BE03h
SET 0,(HL)
LD HL,0BE01h ; Get GAME STATUS Register
SET 0,(HL) ; Request Exit Main Loop
RET ; Return
;----------------------------------------------------
; Routine #5: Finished 1st part of Game
;----------------------------------------------------
L0BD8: BIT 3,(IX+00Bh)
RET Z
LD HL,0BCE8h
LD (HL),000h
LD BC,0000h ; Scene Play Time = 0
LD DE,(0C01Dh) ; Get Message "Congrats, mastered 1st part"
CALL L1BE3 ; PLAY Scene with Timer
LD DE,00096h ; Programmable Timer = 96h
CALL L21A7 ; Set Programmable Timer
L0BF2: CALL L21B3 ; Check if Programmable Timer expired
JR Z,L0BF2 ; Wait until Timer expires
CALL L0DFF ; Automatically save game
CALL L0C00 ; Show Ranking and Speak Score
JP L0B25
;----------------------------------------------------
; Show Ranking and Speak Score
;----------------------------------------------------
L0C00: CALL L0C15 ; A = Player Ranking
LD HL,0BE01h ; Get GAME STATUS Register
RES 7,(HL)
LD HL,0CA05h ; HL = Start of Player Rankings
CALL L08A4 ; DE = Pointer to scene (HL+A*2)
CALL L0D7A ; Play scene and timer
CALL L0D9C ; Speak Score
RET ; Return
;----------------------------------------------------
; Determine Player Ranking
;----------------------------------------------------
; Return A = Player Ranking (0 - 17)
;----------------------------------------------------
L0C15: LD A,(0BCE2h) ;
PUSH AF ;
LD HL,(0BCE3h) ;
PUSH HL ;
LD A,(0BC71h) ;
CP 003h ;
JR C,L0C2C ;
;----------------------------------------------------
; Award 200 point Bonus for each ...
;----------------------------------------------------
LD B,A ; B = number of seconds remaining
L0C25: LD A,0C8h ; Bonus = 200 points for each second
CALL L066B ; Add Bonus to Score
DJNZ L0C25 ; Loop until all bonus is awarded
;----------------------------------------------------
; Check how many hints were given
;----------------------------------------------------
L0C2C: LD HL,0BCF0h ;
LD C,000h ;
L0C31: BIT 7,C
JR NZ,L0C47
SET 7,C
LD A,(HL)
SRL A
SRL A
SRL A
SRL A
CP 002h
CALL NC,L0CC2 ;
JR L0C31 ;
L0C47: RES 7,C
LD A,(HL)
INC HL
AND 00Fh
CP 002h
CALL NC,L0CC2
DJNZ L0C31
;----------------------------------------------------
; Transfer score to temp location for calculation
;----------------------------------------------------
LD HL,0BE44h ; Point to temp location
LD (HL),000h ; Clear temp location
INC HL ; Next location
LD A,(0BCE2h) ; Get score byte
LD (HL),A ; Save in temp location (BE45)
INC HL ; Next location
LD A,(0BCE3h) ; Get score byte
LD (HL),A ; Save in temp location (BE46)
INC HL ; Next locatoin
LD A,(0BCE4h) ; Get score byte
LD (HL),A ; Save in temp locatoin (BE47)
;----------------------------------------------------
; Multiply score by 16
;----------------------------------------------------
XOR A ; Clear carry
RLD ; left 4 bits
DEC HL
RLD
DEC HL
RLD
DEC HL
RLD
INC HL
INC HL
INC HL
SLA (HL) ; m=m*2
DEC HL
RL (HL) ; Rotate Left
DEC HL
RL (HL) ; Rotate Left
DEC HL
RL (HL) ; Rotate Left
LD C,000h ; Start at lowest ranking
OR A ; Loop = 0
L0C85: LD HL,0BE46h ; Point to temp location
LD A,(HL) ; Get adjusted score
INC HL ; Next location
LD L,(HL) ; Get adjusted score
LD H,A ; HL = Adjusted Score
LD A,(0C005h) ; Get total possible points
LD E,A ; DE = total possible points
LD A,(0C004h) ; Get total possible points
LD D,A ; DE = total possible points
SBC HL,DE ; HL = HL - total possible points
;----------------------------------------------------
; Save the difference
;----------------------------------------------------
LD A,H
LD (0BE46h),A
LD A,L
LD (0BE47h),A
JR NC,L0CB0
LD HL,0BE45h
LD A,(HL)
SUB 001h
LD (HL),A
JR NC,L0CB0
DEC HL
LD A,(HL)
SUB 001h
LD (HL),A
JR C,L0CB3
L0CB0: INC BC ; Improve ranking by one
JR L0C85 ; Jump back and check other data
;----------------------------------------------------
; Save new score and return ranking
;----------------------------------------------------
L0CB3: POP HL ; HL is score
LD (0BCE3h),HL ; Save score
POP AF ; AF is score
LD (0BCE2h),A ; Save Score
LD A,C ; A = Ranking
CP 020h ; Is ranking greater than 32?
RET C ; No, so return
LD A,01Fh ; Ranking = 32
RET ; Return
;----------------------------------------------------
; Award Bonus
;----------------------------------------------------
L0CC2: PUSH BC
PUSH HL
DEC B
LD HL,0D000h ; HL = Start of Scene Data (Audio Track 1)
BIT 7,C
JR NZ,L0CCF
LD HL,0D800h ; HL = Start of Scene Data (Audio Track 2)
L0CCF: LD DE,00010h
L0CD2: INC B
JR C,L0CD8
ADD HL,DE
JR L0CD2
L0CD8: LD DE,00008h
ADD HL,DE
BIT 7,(HL) ; Do scene have bonus????
JR Z,L0CE4 ; No, so skip ahead
LD A,(HL) ; Get Bonus
CALL L066B ; Add Bonus to Score
L0CE4: POP HL ; Restore HL Register
POP BC ; Restore BC Register
RET ; Return
;----------------------------------------------------
; Table B Rountine #17: Check Button: ITEMS
;----------------------------------------------------
L0CE7: LD HL,0BE0Bh ; Check Keyboard Buffer
BIT 0,(HL) ; Has a key been pressed?
RET Z ; No, so return
LD A,(0BE0Ah) ; Get Keyboard Character
CP 032h ; Check if "ITEMS (2)" is Pressed
RET NZ ; "2" not pressed so return
RES 0,(HL) ; Clear Keyboard Buffer
BIT 7,(IX+00Bh) ; Is this scene timed? (Var0B)
RET NZ ; Yes, so action is not allowed here
;----------------------------------------------------
; Speak Inventory or Show Inventory?
;----------------------------------------------------
L0CFA: LD DE,00063h ; Phrase="Do You Want To See Your Item (%)"
CALL L1363 ; Call Speech Routine (phrase)
CALL L19E7 ; Check for "YES" or "NO"
JR C,L0CFA ; Timed out so repeat question
JR Z,L0D0E ; "YES" so check inventory
LD HL,0BCA0h ; HL = Start of Inventory
CALL L12F6 ; Speak Inventory
RET ; Return
L0D0E: CALL L0D12 ; Show Inventory
RET ; Return
;----------------------------------------------------
; Show Player's Inventory
;----------------------------------------------------
L0D12: LD HL,0A782h ;
SET 5,(HL) ;
LD A,(0BE01h) ;
PUSH AF ;
RES 7,A ;
LD (0BE01h),A ;
;----------------------------------------------------
; Scan inventory to see if empty handed
;----------------------------------------------------
LD HL,0BCA0h ; HL = Point to start of inventory
LD B,01Ah ; Number of items = A - Z (26)
L0D25: BIT 1,(HL) ; Is item being held?
JR NZ,L0D38 ; Yes, so show items
INC HL ; Check next item
DJNZ L0D25 ; Loop until all items checked
;----------------------------------------------------
; No items being held, show "You Have Nothing"
;----------------------------------------------------
LD HL,(0C039h) ; Get Pointer to Item Table
XOR A ; A=0, "You Have Nothing"
CALL L08A4 ; DE = Pointer to scene (HL+A*2)
CALL L0D7A ; Show Freeze Frame of Item
JR L0D69 ; Jump to end
L0D38: LD HL,(0C039h) ; Get Pointer to Item Table A
INC HL ; Point to next
INC HL ; Point to next, HL = HL + 2
XOR A ; A = 0, "You have acquired the following..."
CALL L08A4 ; DE = Pointer to scene (HL+A*2)
CALL L0D7A ; Show Freeze Frame of Message
LD B,01Ah ; 26 items to check
LD HL,0BCA0h ; HL = Start of Inventory
LD DE,(LC039) ; DE Points to Item Table A
INC DE ; Skip Inventory message frames
INC DE ; Skip Inventory message frames
INC DE ; Skip Inventory message frames
INC DE ; Skip Inventory message frames
XOR A ; A = 0, first item
L0D52: BIT 1,(HL) ; Is item in inventory?
JR Z,L0D65 ; Not in inventory, so skip ahead
;----------------------------------------------------
; Item is in inventory so show picture
;----------------------------------------------------
PUSH HL ; Save HL Register
PUSH DE ; Save DE Register
PUSH BC ; Save BC Register
PUSH AF ; Save AF Register
EX DE,HL ; HL = DE
CALL L08A4 ; DE = Pointer to scene (HL+A*2)
CALL L0D7A ; Show Freeze Frame of Item
POP AF ; Restore AF Register
POP BC ; Restore BC Register
POP DE ; Restore DE Register
POP HL ; Restore HL Register
L0D65: INC HL ; Check next item
INC A ; Next item
DJNZ L0D52 ; Loop until all items checked
L0D69: LD HL,0A782h
RES 5,(HL) ;
LD HL,0BE03h ;
SET 0,(HL)
SET 1,(HL)
POP AF
LD (0BE01h),A
RET
;----------------------------------------------------
; Play Message Frame from Disc for 2 seconds
; DE = Frame Number of Scene
;----------------------------------------------------
L0D7A: CALL L1BE3 ; PLAY Scene with Timer
LD DE,0003Ch ; Load Programmable Timer = 3Ch
CALL L21A7 ; Set Programmable Timer
L0D83: CALL L21B3 ; Check if Programmable Timer expired
JR Z,L0D83 ; Loop until timer expires
RET ; Return
;----------------------------------------------------
; Rountine #18: Check Button: GIVE SCORE
;----------------------------------------------------
L0D89: LD HL,0BE0Bh ; Get Keyboard Buffer
BIT 0,(HL) ; Has a key been pressed?
RET Z ; No, so return
LD A,(0BE0Ah) ; Get Keyboard Character
CP 034h ; Check if "GIVE SCORE (4)" Pressed
RET NZ ; Not pressed, so return
RES 0,(HL) ; Clear Keyboard Buffer
BIT 7,(IX+00Bh) ; Is scene timed? (Var0B)
RET NZ ; Yes, so action is not allowed here
;----------------------------------------------------
; Speak Score out of Possible Range
;----------------------------------------------------
L0D9C: LD HL,0BCE2h ; HL = Pointer to Score
LD DE,0A6D0h ; DE = Speakable Number (n)
LD BC,00003h ; Loop = 3 numbers to copy
LDIR ; Copy numbers to speak
LD DE,00038h ; Phrase="(%) Your Score Is (n)"
CALL L1363 ; Call Speech Routine (phrase)
L0DAD: LD HL,0C003h ; Get Total Possible Score
LD DE,0A6D0h ; DE = Speakable Number (n)
LD BC,00003h ; Loop = 3
LDIR ; Copy all digits
LD DE,0007Dh ; Phrase="Out Of A Possible (n)"
CALL L1363 ; Call Speech Routine (phrase)
RET ; Return
;----------------------------------------------------
; Table B Rountine #12: Check Keyboard
;----------------------------------------------------
L0DBF: CALL L2190 ; Keyboard check routine
RET C ; No keypress, so return
LD (0BE0Ah),A ; Put Keypress in buffer
LD HL,0BE0Bh ; Check Keyboard buffer
SET 0,(HL) ; Set buffer to full
RET ; Return
;----------------------------------------------------
; Table B Rountine #24: Check Button: HINT
;----------------------------------------------------
L0DCC: LD HL,0BE0Bh ; Check Keyboard Buffer
BIT 0,(HL) ; Has a key been pressed?
RET Z ; No, so return
LD A,(0BE0Ah) ; Get Keyboard Character
CP 039h ; Check if "HINT (9)" Pressed
RET NZ ; Not pressed, so return
RES 0,(HL) ; Clear Keyboard Buffer
BIT 7,(IX+00Bh) ; Is scene timed? (Var0B)
RET NZ ; Yes, so action is not allowed here
LD DE,0008Dh ; Phrase="(%) I Only Give Pointer When You Need Them"
CALL L1363 ; Call Speech Routine (phrase)
RET ; Return
;----------------------------------------------------
; Routine #22: Check Button: SAVE GAME
;----------------------------------------------------
L0DE6: LD HL,0BE0Bh ; Check Keyboard Buffer
BIT 0,(HL) ; Has a key been pressed?
RET Z ; No, so return
LD A,(0BE0Ah) ; Get Keyboard Character
CP 037h ; Check if "SAVE GAME (7)" Pressed
RET NZ
RES 0,(HL)
BIT 7,(IX+00Bh) ; Is scene timed? (Var0B)
RET NZ ; Yes, so action is not allowed here
;----------------------------------------------------
; Do Save Game
;----------------------------------------------------
L0DF9: LD DE,0007Bh ; Phrase="I Have Saved Your Game"
CALL L1363 ; Call Speech Routine (phrase)
L0DFF: LD HL,0BC80h ; Get Audio Track
LD (HL),000h ; Reset Audio Track
BIT 7,(IX+002h) ; Check Audio Track from data
JR Z,L0E0C ; Audio Track 1 selected, skip ahead
SET 0,(HL) ; Select Audio Track 2
L0E0C: CALL L0E10 ; Call SAVE GAME
RET ; Return
;----------------------------------------------------
; SAVE GAME
;----------------------------------------------------
; Copy Location BC00-BDFF to new SAVED GAME Bank
; BC00 = Bank number where to save game
;----------------------------------------------------
L0E10: LD A,(0BC00h) ; A = Index to correct Bank
LD B,A ; Loop = A
LD HL,0A600h ; HL = A600h
LD DE,00200h ; DE = 200h
L0E1A: ADD HL,DE ; HL = HL + 200h
DJNZ L0E1A ; Loop until correct Bank
;----------------------------------------------------
; Copy BC00-BDFF to correct Bank
;----------------------------------------------------
EX DE,HL ; DE = Bank Address
LD HL,0BE01h ; Get GAME STATUS Register
SET 1,(HL) ; SAVE in progress, set bit1
LD HL,0BC00h ; HL = BC00
LD BC,00200h ; Loop = 200
LDIR ; Copy Bank
LD HL,0BE01h ; HL = BE01
RES 1,(HL) ; SAVE complete, clear bit1
RET ; Return
;----------------------------------------------------
; Table B Rountine #23: Check Button: UPDATE
;----------------------------------------------------
L0E31: LD HL,0BE0Bh ; Check Keyboard Buffer
BIT 0,(HL) ; Has a key been pressed?
RET Z ; No, so return
LD A,(0BE0Ah) ; Get Keyboard Character
CP 038h ; Check if "UPDATE (8)" Pressed
RET NZ ; Key not pressed, so return
RES 0,(HL) ; Clear Keyboard Buffer
BIT 7,(IX+00Bh) ; Is scene timed? (Var0B)
RET NZ ; Yes, so action is not allowed here
LD DE,00089h ; Phrase="You Need A Voice Print To Update (%)"
CALL L1363 ; Call Speech Routine (phrase)
RET ; Return
;----------------------------------------------------
; Starting Number of Lives, Audio Track
;----------------------------------------------------
L0E4B: LD A,(0BE0Fh) ; Get DIP Switch A
BIT 4,A ; Test A5, Lives per Game
JR NZ,L0E58 ;
LD A,(LC001) ; Get Number of Lives (3)
LD (0BCE8h),A ; Store Number of Lives
L0E58: LD HL,0BC80h ;
BIT 0,(HL) ; Check which Audio Track to use
LD HL,0BE03h ;
RES 4,(HL) ; Set Audio Track 1
RET Z ; Audio Track 1 selected so return
SET 4,(HL) ; Set Audio Track 2
RET ; Return
;----------------------------------------------------
; Table B Rountine #1: Giving Hints
;----------------------------------------------------
L0E66: LD A,(0BC81h) ; Get Scene Index
LD HL,0BCF0h ; Point to RAM Hint Table
ADD A,L ; Add Scene Index to table
LD L,A ; Add Scene Index to table
JR NC,L0E71 ; Add
INC H ; HL = Pointer to spot in Hint RAM
L0E71: LD A,(HL) ; A = Hint RAM
BIT 7,(IX+002h) ; Var02 = Which Hint Table to use
JR NZ,L0E8B ; Use upper nibble RAM
AND 00Fh ; Use lower nibble RAM
L0E7A: LD C,A ; C = RAM Hint
LD A,(0BC81h) ; Get Scene Index
LD B,A ; B = Scene Index
;----------------------------------------------------
; Determine which Hint Table to use
; based on bit in Var02 of Scene Data
;----------------------------------------------------
SCF ; Carry = 1, Hint Table 2
BIT 7,(IX+002h) ; Var02 = Which Hint Table to use
JR NZ,L0E87 ; Clear so jump ahead
CCF ; else Carry = 0, use Hint Table (Audio Track 1)
L0E87: CALL L1629 ; Hint Request Processing
RET ; Return
L0E8B: AND 0F0h ; Get upper nibble
SRL A ; Shift upper nibble to lower
SRL A ; Shift upper nibble to lower
SRL A ; Shift upper nibble to lower
SRL A ; Shift upper nibble to lower
JR L0E7A ; Jump back
;----------------------------------------------------
; Routine #21 Check Button: COMBINE ACTION
;----------------------------------------------------
L0E97: LD HL,0BE0Bh ; Check Keyboard Buffer
BIT 0,(HL) ; Has a key been pressed?
RET Z ; No, so return
LD A,(0BE0Ah) ; Get Keyboard Character
CP 036h ; Check if "COMBINE ACTION (6)" is Pressed
RET NZ ; Not pressed to return
;----------------------------------------------------
; Check if COMBINE is available
;----------------------------------------------------
LD A,(IX+00Bh) ;
AND 007h ;
JR NZ,L0EB2 ;
LD DE,00032h ; Phrase="You Don't Have That Choice Here (%)"
CALL L1363 ; Call Speech Routine (phrase)
JR L0EC7 ; Leave routine
;----------------------------------------------------
; Reset COMBINE work area (6 bytes)
;----------------------------------------------------
L0EB2: LD DE,00077h ; Phrase="Choose The Item To Combine"
NEXT PAGE
|