0000-                  4       ;
0000-                  5       ; MUSIC PLAYER FOR THE BE6502 USING '6502 GAMES' HARDWARE. BOARD SHOULD BE
0000-                  6       ; JUMPERED WITH VIA CHIPS AT THE ADDRESSES SPECIFIED BELOW. OTHER THAN THAT
0000-                  7       ; THE CODE IS UNCHANGED FROM THE BOOK.
0000-                  8       ;
4000-                  9       VIA1    .EQ     $4000       ; GAME BOARD (VIA #1)
4C00-                 10       VIA3    .EQ     $4C00       ; GAME BOARD (VIA #3)
0000-                 11
8000-                 12               .OR     $8000
8000-                 13               .TA     $0000
8000-20 DE 80         14 (  6) BE6502  JSR     INITKEY
8003-                 15               .IN     ../../common/CH04-Hexguess/game.asm
8003-            I     1       ;   'HEXGUESS'
8003-            I     2       ;   HEXADECIMAL NUMBER GUESSING GAME.
8003-            I     3       ; THE OBJECT OF THE GAME IS TO GUESS A HEXADECIMAL NUMBER THAT THE COMPUTER HAS
8003-            I     4       ; THOUGHT UP. WHEN THE COMPUTER 'BEEPS', A GUESS SHOULD BE ENTERED. GUESSES ARE
8003-            I     5       ; TWO DIGIT HEXADECIMAL NUMBERS, WHEN TWO DIGITS HAVE BEEN RECEIVED THE
8003-            I     6       ; COMPUTER WILL DISPLAY THE NEARNESS OF THE GUESS BY LIGHTING A NUMBER OF LEDS
8003-            I     7       ; PROPORTIONAL TO THE CLOSENESS OF THE GUESS. TEN GUESSES ARE ALLOWED. IF A
8003-            I     8       ; GUESS IS CORRECT, THEN THE COMPUTER WILL FLASH THE LEDS AND MAKE A WARBLING
8003-            I     9       ; TONE.
8003-            I    10       ;
8003-            I    11       ;
8003-            I    12       ; 6522 VIA #1 ADDRESSES:
4004-            I    13       TIMER   .EQ     VIA1+4      ; LOW LATCH OF TIMER 1
4003-            I    14       DDR1A   .EQ     VIA1+3      ; PORT A DATA DIRECTION REGISTER
4002-            I    15       DDR1B   .EQ     VIA1+2      ; PORT B DATA DIRECTION REGISTER
4001-            I    16       PORT1A  .EQ     VIA1+1      ; PORT A
4000-            I    17       PORT1B  .EQ     VIA1        ; PORT B
8003-            I    18       ; 6522 VIA #3 ADDRESSES:
4C03-            I    19       DDR3A   .EQ     VIA3+3      ; PORT A DATA DIRECTION REGISTER
4C02-            I    20       DDR3B   .EQ     VIA3+2      ; PORT B DATA DIRECTION REGISTER
4C00-            I    21       PORT3B  .EQ     VIA3        ; PORT B
4C01-            I    22       PORT3A  .EQ     VIA3+1      ; PORT A
8003-            I    23       ; STORAGES:
0000-            I    24       ZP      .EQ     $00
0000-            I    25       GUESS   .EQ     ZP
0001-            I    26       GUESSN  .EQ     ZP+1
0002-            I    27       DUR     .EQ     ZP+2
0003-            I    28       FREQ    .EQ     ZP+3
0004-            I    29       NUMBER  .EQ     ZP+4
8003-            I    30
8003-A9 FF       I    31 (  2)         LDA     #$FF        ; SET UP DATA DIRECTION REGISTERS
8005-8D 03 40    I    32 (  4)         STA     DDR1A
8008-8D 02 40    I    33 (  4)         STA     DDR1B
800B-8D 02 4C    I    34 (  4)         STA     DDR3B
800E-85 02       I    35 (  3)         STA     DUR         ; SET UP TONE DURATIONS.
8010-A9 0A       I    36 (  2) START   LDA     #$0A        ; 10 GUESSES ALLOWED
8012-85 01       I    37 (  3)         STA     GUESSN
8014-A9 00       I    38 (  2)         LDA     #0          ; BLANK LEDS
8016-8D 01 40    I    39 (  4)         STA     PORT1A
8019-8D 00 40    I    40 (  4)         STA     PORT1B
801C-AD 04 40    I    41 (  4)         LDA     TIMER       ; GET RANDOM NUMBER TO GUESS
801F-85 04       I    42 (  3)         STA     NUMBER      ; ... AND SAVE.
8021-A9 20       I    43 (  2) GETGES  LDA     #$20        ; SET UP SHORT HIGH TONE TO SIGNAL USER TO
8023-            I    44                                   ;  INPUT GUESS.
8023-20 99 80    I    45 (  6)         JSR     TONE        ; MAKE BEEP.
8026-20 B9 80    I    46 (  6)         JSR     GETKEY      ; GET HIGH ORDER USER GUESS
8029-0A          I    47 (  2)         ASL     A           ; SHIFT INTO HIGH ORDER POSITION
802A-0A          I    48 (  2)         ASL     A
802B-0A          I    49 (  2)         ASL     A
802C-0A          I    50 (  2)         ASL     A
802D-85 00       I    51 (  3)         STA     GUESS       ; SAVE
802F-20 B9 80    I    52 (  6)         JSR     GETKEY      ; GET LOW ORDER USER GUESS
8032-29 0F       I    53 (  2)         AND     #%00001111  ; MASK HIGH ORDER BITS.
8034-05 00       I    54 (  3)         ORA     GUESS       ; ADD HIGH ORDER NIBBLE.
8036-85 00       I    55 (  3)         STA     GUESS       ; FINAL PRODUCT SAVED.
8038-A5 04       I    56 (  3)         LDA     NUMBER      ; GET NUMBER FOR COMPARE
803A-38          I    57 (  2)         SEC                 ; SUBTRACT GUESS FROM NUMBER TO DETERMINE THE
803B-E5 00       I    58 (  3)         SBC     GUESS       ;  NEARNESS OF THE GUESS.
803D-B0 05       I    59 (2**)         BCS     ALRIGHT     ; POSITIVE VALUE NEEDS NO FIX.
803F-49 FF       I    60 (  2)         EOR     #%11111111  ; MAKE DISTANCE ABSOLUTE
8041-38          I    61 (  2)         SEC                 ; MAKE IT A TWO'S COMPLEMENT
8042-69 00       I    62 (  2)         ADC     #00         ; ... NOT JUST A ONE'S COMPLEMENT.
8044-A2 00       I    63 (  2) ALRIGHT LDX     #00         ; SET CLOSENESS COUNTER TO DISTANT
8046-DD B0 80    I    64 ( 4*) LOOP    CMP     LIMITS,X    ; COMPARE NEARNESS OF GUESS TO TABLE OF LIMITS
8049-            I    65                                   ;  TO SEE HOW MANY LIGHTS TO LIGHT.
8049-B0 27       I    66 (2**)         BCS     SIGNAL      ; NEARNESS IS BIGGER THAN LIMIT, SO GO
804B-            I    67                                   ;  LIGHT INDICATOR INSTEAD.
804B-E8          I    68 (  2)         INX                 ; LOOK AT NEXT CLOSENESS LEVEL.
804C-E0 09       I    69 (  2)         CPX     #9          ; ALL NINE LEVELS TRIED?
804E-D0 F6       I    70 (2**)         BNE     LOOP        ; NO, TRY NEXT LEVEL.
8050-A9 0B       I    71 (  2) WIN     LDA     #11         ; YES; WIN! LOAD NUMBER OF BLINKS
8052-85 00       I    72 (  3)         STA     GUESS       ; USE GUESS AS TEMP
8054-A9 FF       I    73 (  2)         LDA     #$FF        ; LIGHT LEDS
8056-8D 01 40    I    74 (  4)         STA     PORT1A
8059-8D 00 40    I    75 (  4)         STA     PORT1B
805C-A9 32       I    76 (  2) WOW     LDA     #50         ; TONE VALUE
805E-20 99 80    I    77 (  6)         JSR     TONE        ; MAKE WIN SIGNAL
8061-A9 FF       I    78 (  2)         LDA     #$FF
8063-4D 01 40    I    79 (  4)         EOR     PORT1A      ; COMPLEMENT PORTS
8066-8D 01 40    I    80 (  4)         STA     PORT1A
8069-8D 00 40    I    81 (  4)         STA     PORT1B
806C-C6 00       I    82 (  5)         DEC     GUESS       ; BLINKS/TONES DONE?
806E-D0 EC       I    83 (2**)         BNE     WOW         ; NO, DO AGAIN.
8070-F0 9E       I    84 (2**)         BEQ     START       ; YES, START NEW GAME.
8072-E8          I    85 (  2) SIGNAL  INX                 ; INCREMENT CLOSENESS LEVEL COUNTER SO AT
8073-            I    86                                   ;  LEAST 1 LED IS LIT.
8073-A9 00       I    87 (  2)         LDA     #0          ; CLEAR HIGH LED PORT
8075-8D 00 40    I    88 (  4)         STA     PORT1B
8078-20 91 80    I    89 (  6)         JSR     LITE        ; GET LED PATTERN
807B-8D 01 40    I    90 (  4)         STA     PORT1A      ; SET LEDS
807E-90 05       I    91 (2**)         BCC     CC          ; IF CARRY SET PB0 = 1
8080-A9 01       I    92 (  2)         LDA     #01
8082-8D 00 40    I    93 (  4)         STA     PORT1B
8085-C6 01       I    94 (  5) CC      DEC     GUESSN      ; ONE GUESS USED
8087-D0 98       I    95 (2**)         BNE     GETGES      ; SOME LEFT, GET NEXT.
8089-A9 BE       I    96 (  2)         LDA     #$BE        ; LOW TONE SIGNALS LOSE
808B-20 99 80    I    97 (  6)         JSR     TONE
808E-4C 10 80    I    98 (  3)         JMP     START       ; NEW GAME
8091-            I    99       ;
8091-            I   100       ; SUBROUTINE 'LITE'
8091-            I   101       ; ROUTINE TO MAKE PATTERN OF LIT LEDS BY SHIFTING A STRING OF ONES TO THE
8091-            I   102       ; LEFT IN THE ACCUMULATOR UNTIL THE BIT POSITION CORRESPONDING TO THE NUMBER
8091-            I   103       ; IN X IS REACHED.
8091-            I   104       ;
8091-A9 00       I   105 (  2) LITE    LDA     #0          ; CLEAR ACCUMULATOR FOR PATTERN
8093-38          I   106 (  2) SHIFT   SEC                 ; MAKE LOW BIT HIGH.
8094-2A          I   107 (  2)         ROL     A           ; SHIFT IT IN
8095-CA          I   108 (  2)         DEX                 ; ONE BIT DONE...
8096-D0 FB       I   109 (2**)         BNE     SHIFT       ;  LOOP IF NOT DONE.
8098-60          I   110 (  6)         RTS                 ; RETURN
8099-            I   111       ;
8099-            I   112       ; SUBROUTINE 'TONE'
8099-            I   113       ; TONE GENERATION ROUTINE.
8099-            I   114       ;
8099-85 03       I   115 (  3) TONE    STA     FREQ
809B-A9 00       I   116 (  2)         LDA     #0
809D-A6 02       I   117 (  3)         LDX     DUR
809F-A4 03       I   118 (  3) FL2     LDY     FREQ
80A1-88          I   119 (  2) FL1     DEY
80A2-18          I   120 (  2)         CLC
80A3-90 00       I   121 (2**)         BCC     FL0         ; (.+2 IN BOOK)
80A5-D0 FA       I   122 (2**) FL0     BNE     FL1
80A7-49 FF       I   123 (  2)         EOR     #$FF
80A9-8D 00 4C    I   124 (  4)         STA     PORT3B
80AC-CA          I   125 (  2)         DEX
80AD-D0 F0       I   126 (2**)         BNE     FL2
80AF-60          I   127 (  6)         RTS
80B0-            I   128       ;
80B0-            I   129       ; TABLE OF LIMITS FOR CLOSENESS LEVELS.
80B0-            I   130       ;
80B0-C8 80 40 20 
     10 08 04 02 
     01          I   131       LIMITS  .HS     C8.80.40.20.10.08.04.02.01
80B9-                 16               .IN     ../../common/CH01-Getkey/getkey_routine.asm
80B9-            I     1       ; 'GETKEY' KEYBOARD INPUT ROUTINE READS AND DEBOUNCES KEYBOARD. RETURNS WITH
80B9-            I     2       ; KEY NUMBER IN ACCUMULATOR IF KEY DOWN. OPERATION: SENDS NUMBERS 0-F TO 74154
80B9-            I     3       ; (4 TO 16 LINE DECODER), WHICH GROUNDS ONE SIDE OF KEYSWITCHES ONE AT A TIME.
80B9-            I     4       ; IF A KEY IS DOWN, PA7 OF VIA #3 WILL BE GROUNDED, AND THE CURRENT VALUE
80B9-            I     5       ; APPLIED TO THE 74154 BE THE KEY NUMBER. WHEN THE PROGRAM DETECTS A KEY CLOSE
80B9-            I     6       ; CHECKS FOR KEY CLOSURE FOR 50 MS. TO ELIMINATE BOUNCE.
80B9-            I     7       ; NOTE: IF NO KEY IS PRESSED, GETKEY WILL WAIT.
80B9-            I     8       ;
80B9-2C 01 4C    I     9 (  4) GETKEY  BIT     PORT3A      ; SEE IF KEY IS STILL DOWN FROM LAST KEY CLOSURE:
80BC-            I    10                                   ;  KEYSTROBE IN 'N' STATUS BIT.
80BC-10 FB       I    11 (2**)         BPL     GETKEY      ; IF YES, WAIT FOR KEY RELEASE
80BE-A2 0F       I    12 (  2) RSTART  LDX     #15         ; SET KEY COUNTER TO 15
80C0-8E 00 4C    I    13 (  4) NXTKEY  STX     PORT3B      ; OUTPUT KEY # TO 74154
80C3-2C 01 4C    I    14 (  4)         BIT     PORT3A      ; SEE IF KEY DOWN: STROBE IN 'N'
80C6-10 05       I    15 (2**)         BPL     BOUNCE      ;  IF YES, GO DEBOUNCE
80C8-CA          I    16 (  2)         DEX                 ;   DECREMENT KEY #
80C9-10 F5       I    17 (2**)         BPL     NXTKEY      ;  NO, DO NEXT KEY
80CB-30 F1       I    18 (2**)         BMI     RSTART      ; START OVER
80CD-8A          I    19 (  2) BOUNCE  TXA                 ; SAVE KEY NUMBER IN A
80CE-A0 12       I    20 (  2)         LDY     #$12        ; OUTER LOOP CNT LOAD FOR DELAY OF 50 MS.
80D0-A2 FF       I    21 (  2) LP1     LDX     #$FF        ; INNER 11 US. LOOP
80D2-2C 01 4C    I    22 (  4) LP2     BIT     PORT3A      ; SEE IF KEY STILL DOWN
80D5-30 E7       I    23 (2**)         BMI     RSTART      ; IF NOT, KEY NOT VALID, RESTART
80D7-CA          I    24 (  2)         DEX
80D8-D0 F8       I    25 (2**)         BNE     LP2         ; THIS LOOP USES 2115*5 US.
80DA-88          I    26 (  2)         DEY
80DB-D0 F3       I    27 (2**)         BNE     LP1         ; OUTER LOOP: TOTAL IS 50 MS.
80DD-60          I    28 (  6)         RTS                 ; DONE: KEY IN A.
80DE-            I    29       ;
80DE-            I    30       ; SUBROUTINE 'INITKEY'
80DE-            I    31       ; TAKES CARE OF INITIALIZING VIA #3 FOR USING WITH THE GETKEY ROUTINE FROM
80DE-            I    32       ; THE CODE.
80DE-            I    33       ;
80DE-A9 00       I    34 (  2) INITKEY LDA     #0
80E0-8D 03 4C    I    35 (  4)         STA     DDR3A       ; SET KEY STROBE PORT FOR INPUT
80E3-A9 FF       I    36 (  2)         LDA     #$FF
80E5-8D 02 4C    I    37 (  4)         STA     DDR3B       ; SET KEYS FOR OUTPUT
80E8-60          I    38 (  6)         RTS
80E9-                 17       ;
80E9-                 18       ; STORE CPU INITIALIZATION VECTORS AT THE END OF THE EEPROM.
80E9-                 19       ;
FFFA                 20               .NO     $FFFA,$FF
FFFA-00 80            21               .DA     BE6502      ; NMI VECTOR
FFFC-00 80            22               .DA     BE6502      ; RESET VECTOR
FFFE-00 80            23               .DA     BE6502      ; IRQ VECTOR
