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