Chapter 9

This commit is contained in:
Tor-Eirik Bakke Lunde 2020-03-21 21:07:34 +01:00
parent 04fc5fc504
commit 81f7f30da0
31 changed files with 9058 additions and 0 deletions

View File

@ -0,0 +1,4 @@
@echo off
sbasm.py slot_machine.asm
type slot_machine.list
pause

View File

@ -0,0 +1,24 @@
.CR 65C02
.TF slot_machine.hex,INT
.LF slot_machine.list
;
; SLOT MACHINE GAME FOR THE '6502 GAMES' HARDWARE, BOARD SHOULD BE JUMPERED
; WITH VIA CHIPS AT THE ADDRESSES SPECIFIED BELOW. OTHER THAN THAT THE CODE
; IS SHOULD BE UNCHANGED FROM THE BOOK THOUGH THERE WILL BE SOME DIFFERENCES
; DUE TO ASSEMBLER USED.
;
VIA1 .EQ $4000 ; GAME BOARD (VIA #1)
VIA3 .EQ $4C00 ; GAME BOARD (VIA #3)
.OR $8000
.TA $0000
BE6502 JSR INITKEY
.IN ../../common/CH07-SlotMachine/game.asm
.IN ../../common/CH01-Getkey/getkey_routine.asm
;
; STORE CPU INITIALIZATION VECTORS AT THE END OF THE EEPROM.
;
.NO $FFFA,$FF
.DA BE6502 ; NMI VECTOR
.DA BE6502 ; RESET VECTOR
.DA BE6502 ; IRQ VECTOR

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,368 @@
0000- 4 ;
0000- 5 ; SLOT MACHINE GAME FOR THE '6502 GAMES' HARDWARE, BOARD SHOULD BE JUMPERED
0000- 6 ; WITH VIA CHIPS AT THE ADDRESSES SPECIFIED BELOW. OTHER THAN THAT THE CODE
0000- 7 ; IS SHOULD BE UNCHANGED FROM THE BOOK THOUGH THERE WILL BE SOME DIFFERENCES
0000- 8 ; DUE TO ASSEMBLER USED.
0000- 9 ;
4000- 10 VIA1 .EQ $4000 ; GAME BOARD (VIA #1)
4C00- 11 VIA3 .EQ $4C00 ; GAME BOARD (VIA #3)
0000- 12
8000- 13 .OR $8000
8000- 14 .TA $0000
8000-20 D0 81 15 ( 6) BE6502 JSR INITKEY
8003- 16 .IN ../../common/CH07-SlotMachine/game.asm
8003- I 1 ; 'SLOT MACHINE'
8003- I 2 ; SLOT MACHINE SIMULATOR PROGRAM, PRESS ANY KEY TO START 'SPIN'. SCORE
8003- I 3 ; DETERMINED BY ARRAY 'SCORTB'. 8 POINTS INITIAL SCORE, ONE POINT PENALTY
8003- I 4 ; FOR EACH BAD SPIN.
8003- I 5
8003- I 6 ;
8003- I 7 ; I/O:
8003- I 8 ;
4000- I 9 PORT1B .EQ VIA1 ; PORT B
4001- I 10 PORT1A .EQ VIA1+1 ; PORT A
4002- I 11 DDR1B .EQ VIA1+2 ; PORT B DATA DIRECTION REGISTER
4003- I 12 DDR1A .EQ VIA1+3 ; PORT A DATA DIRECTION REGISTER
4004- I 13 T1CL .EQ VIA1+4
8003- I 14
4C00- I 15 PORT3B .EQ VIA3 ; PORT B
4C01- I 16 PORT3A .EQ VIA3+1 ; PORT A
4C02- I 17 DDR3B .EQ VIA3+2 ; PORT B DATA DIRECTION REGISTER
4C03- I 18 DDR3A .EQ VIA3+3 ; PORT A DATA DIRECTION REGISTER
8003- I 19
8003- I 20 ;
8003- I 21 ; VARIABLE STORAGE.
8003- I 22 ;
0000- I 23 ZP .EQ $00
0000- I 24 TEMP .EQ ZP ; TEMPORARY STORAGE.
0001- I 25 SCORTP .EQ ZP+1 ; TEMPORARY SCORE STORAGE
0002- I 26 SCORE .EQ ZP+2 ; SCORE.
0003- I 27 DUR .EQ ZP+3 ; DURATION OF TONES.
0004- I 28 FREQ .EQ ZP+4
0005- I 29 SPEEDS .EQ ZP+5 ; SPEEDS OF REVOLUTION FOR LEDS IN COLUMNS
0008- I 30 INDX .EQ ZP+8 ; DELAY COUNTERS FOR LED REVOLUTIONS.
000B- I 31 INCR .EQ ZP+11 ; POINTERS FOR LED POSITIONS:
8003- I 32 ; USED TO FETCH PATTERNS OUT OF TABLES.
000E- I 33 LTMSK .EQ ZP+14 ; PATTERNS FOR LIT LEDS
0011- I 34 VALUES .EQ ZP+17 ; NUMBER OF LIT LEDS IN EACH ROW.
0014- I 35 RND .EQ ZP+20 ; SCRATCHPAD FOR RND # GENERATOR.
8003- I 36
8003- I 37 ;
8003- I 38 ; MAIN PROGRAM
8003- I 39 ;
8003-A9 FF I 40 ( 2) LDA #$FF ; SET UP PORTS.
8005-8D 03 40 I 41 ( 4) STA DDR1A
8008-8D 02 40 I 42 ( 4) STA DDR1B
800B-8D 02 4C I 43 ( 4) STA DDR3B
800E-AD 04 40 I 44 ( 4) LDA T1CL ; GET SEED FOR RANDOM # GENERATOR.
8011-85 15 I 45 ( 3) STA RND+1
8013-A9 08 I 46 ( 2) START LDA #8 ; INITIAL SCORE IS EIGHT.
8015-85 02 I 47 ( 3) STA SCORE
8017-A8 I 48 ( 2) TAY ; SHOW INITIAL SCORE
8018-20 40 81 I 49 ( 6) JSR LIGHT
801B-20 AB 81 I 50 ( 6) KEY JSR GETKEY ; ANY KEY PRESSED STARTS PROGRAM.
801E-20 2A 80 I 51 ( 6) JSR DISPLY ; SPIN WHEELS
8021-20 AA 80 I 52 ( 6) JSR EVAL ; CHECK SCORE AND SHOW IT
8024-A5 02 I 53 ( 3) LDA SCORE
8026-D0 F3 I 54 (2**) BNE KEY ; IF SCORE <> 0, GET NEXT PLAY.
8028-F0 E9 I 55 (2**) BEQ START ; IF SCORE = 0; RESTART.
802A- I 56
802A- I 57 ;
802A- I 58 ; SUBROUTINE 'DISPLY'
802A- I 59 ; SUBROUTINE TO DISPLAY 'SPINNING' LEDS, FIND COMBINATION USED TO
802A- I 60 ; DETERMINE SCORE.
802A- I 61 ;
005A- I 62 LOLIM = 90
0087- I 63 HILIM = 135
0050- I 64 SPDPRM = 80
802A-A9 00 I 65 ( 2) DISPLY LDA #0 ; RESET POINTERS.
802C-85 0B I 66 ( 3) STA INCR
802E-85 0C I 67 ( 3) STA INCR+1
8030-85 0D I 68 ( 3) STA INCR+2
8032-A0 02 I 69 ( 2) LDRND LDY #2 ; SET INDEX FOR 3 ITERATIONS.
8034-20 83 81 I 70 ( 6) GETRND JSR RANDOM ; GET RANDOM #.
8037-C9 87 I 71 ( 2) CMP #HILIM ; TOO LARGE?
8039-B0 F9 I 72 (2**) BCS GETRND ; IF SO, GET ANOTHER.
803B-C9 5A I 73 ( 2) CMP #LOLIM ; TOO SMALL?
803D-90 F5 I 74 (2**) BCC GETRND ; IF SO, GET ANOTHER.
803F-99 08 00 I 75 ( 5) STA INDX,Y ; SAVE IN LOOP INDEXES AND
8042-99 05 00 I 76 ( 5) STA SPEEDS,Y ; LOOP SPEED COUNTERS.
8045-88 I 77 ( 2) DEY
8046-10 EC I 78 (2**) BPL GETRND ; GET NEXT RND #.
8048-A2 02 I 79 ( 2) UPDATE LDX #2 ; SET INDEX FOR THREE ITERATIONS.
804A-B4 05 I 80 ( 4) UPDTLP LDY SPEEDS,X ; IS SPEED(X) = 0?
804C-F0 44 I 81 (2**) BEQ NXTUPD ; IF SO, DO NEXT UPDATE.
804E-D6 08 I 82 ( 6) DEC INDX,X ; DECREMENT LOOP INDEX(X)
8050-D0 40 I 83 (2**) BNE NXTUPD ; IF LOOPINDEX(X) <> 0, DO NEXT UPDATE.
8052-B4 0B I 84 ( 4) LDY INCR,X ; INCREMENT POINTER(X).
8054-C8 I 85 ( 2) INY
8055-C0 03 I 86 ( 2) CPY #3 ; POINTER = 3?
8057-D0 02 I 87 (2**) BNE NORST ; IF NOT SKIP...
8059-A0 00 I 88 ( 2) LDY #0 ; ... RESET OF POINTER TO 0.
805B-94 0B I 89 ( 4) NORST STY INCR,X ; RESTORE POINTER(X).
805D-86 00 I 90 ( 3) STX TEMP ; MULTIPLY X BY 3 FOR ARRAY ACCESS.
805F-8A I 91 ( 2) TXA
8060-0A I 92 ( 2) ASL A
8061-18 I 93 ( 2) CLC
8062-65 00 I 94 ( 3) ADC TEMP
8064-75 0B I 95 ( 4) ADC INCR,X ; ADD COLUMN # TO PTR(X) FOR ROW#.
8066-A8 I 96 ( 2) TAY ; TRANSFER TO Y FOR INDEXING.
8067-B9 96 81 I 97 ( 4*) LDA LTABLE,Y ; GET PATTERN FOR LED.
806A-95 0E I 98 ( 4) STA LTMSK,X ; STORE IN LIGHT MASK(X).
806C-B4 05 I 99 ( 4) SPDUPD LDY SPEEDS,X ; INCREMENT SPEED (X).
806E-C8 I 100 ( 2) INY
806F-94 05 I 101 ( 4) STY SPEEDS,X ; RESTORE.
8071-94 08 I 102 ( 4) STY INDX,X ; RESET LOOP INDEX(X).
8073-A9 00 I 103 ( 2) LEDUPD LDA #0 ; UPDATE LIGHTS.
8075-8D 00 40 I 104 ( 4) STA PORT1B ; RESET LED #9
8078-A5 10 I 105 ( 3) LDA LTMSK+2 ; COMBINE PATTERN FOR OUTPUT.
807A-D0 07 I 106 (2**) BNE OFFLD9 ; IF MASK#3 <> 0, LED 9 OFF.
807C-A9 01 I 107 ( 2) LDA #01 ; TURN ON LED 9.
807E-8D 00 40 I 108 ( 4) STA PORT1B
8081-A9 00 I 109 ( 2) LDA #0 ; RESET A SO PATTERN WON'T BE BAD.
8083-05 0E I 110 ( 3) OFFLD9 ORA LTMSK ; COMBINE REST OF PATTERNS.
8085-05 0F I 111 ( 3) ORA LTMSK+1
8087-8D 01 40 I 112 ( 4) STA PORT1A ; SET LIGHTS.
808A-AD 00 4C I 113 ( 4) LDA PORT3B ; TOGGLE SPEAKER.
808D-49 FF I 114 ( 2) EOR #$FF
808F-8D 00 4C I 115 ( 4) STA PORT3B
8092-CA I 116 ( 2) NXTUPD DEX ; DECREMENT X FOR NEXT UPDATE.
8093-10 B5 I 117 (2**) BPL UPDTLP ; IF X >= 0, DO NEXT UPDATE.
8095-A0 50 I 118 ( 2) LDY #SPDPRM ; DELAY A BIT TO SLOW
8097-88 I 119 ( 2) WAIT DEY ; FLASHING OF LEDS.
8098-D0 FD I 120 (2**) BNE WAIT
809A-A5 05 I 121 ( 3) LDA SPEEDS ; CHECK IF ALL COLUMNS OF LEDS STOPPED.
809C-05 06 I 122 ( 3) ORA SPEEDS+1
809E-05 07 I 123 ( 3) ORA SPEEDS+2
80A0-D0 A6 I 124 (2**) BNE UPDATE ; IF NOT, DO NEXT SEQUENCE OF UPDATES.
80A2-A9 FF I 125 ( 2) LDA #$FF
80A4-85 03 I 126 ( 3) STA DUR ; DELAY TO SHOW USER PATTERN.
80A6-20 33 81 I 127 ( 6) JSR DELAY
80A9-60 I 128 ( 6) RTS ; ALL LEDS STOPPED, DONE.
80AA- I 129
80AA- I 130 ;
80AA- I 131 ; SUBROUTINE 'EVAL'
80AA- I 132 ; SUBROUTINE TO EVALUATE PRODUCT OF SPIN, AND DISPLAY SCORE WITH TONES FOR
80AA- I 133 ; WIN, LOSE, WIN+ENDGAME AND LOST+ENDGAME.
80AA- I 134 ;
0020- I 135 HITONE = $20
00F0- I 136 LOTONE = $F0
80AA-A9 00 I 137 ( 2) EVAL LDA #0 ; RESET VARIABLES.
80AC-85 11 I 138 ( 3) STA VALUES
80AE-85 12 I 139 ( 3) STA VALUES+1
80B0-85 13 I 140 ( 3) STA VALUES+2
80B2-85 01 I 141 ( 3) STA SCORTP
80B4-A0 02 I 142 ( 2) LDY #2 ; SET INDEX Y FOR 3 ITERATIONS TO COUNT # OF
80B6- I 143 ; LEDS ON IN EACH ROW.
80B6-B6 0B I 144 ( 4) CNTLP LDX INCR,Y ; CHECK POINTER(Y), ADDING
80B8-F6 11 I 145 ( 6) INC VALUES,X ; UP # OF LEDS ON IN EACH ROW.
80BA-88 I 146 ( 2) DEY
80BB-10 F9 I 147 (2**) BPL CNTLP ; LOOP IF NOT DONE.
80BD-A2 02 I 148 ( 2) LDX #2 ; SET INDEX X FOR 3 ITERATIONS
80BF- I 149 ; OF LOOP TO FIND SCORE.
80BF-8A I 150 ( 2) SCORLP TXA ; MULTIPLY INDEX BY FOUR FOR ARRAY ROW ACCESS.
80C0-0A I 151 ( 2) ASL A
80C1-0A I 152 ( 2) ASL A
80C2-18 I 153 ( 2) CLC ; ADD # OF LEDS ON IN ROW(X) TO...
80C3-75 11 I 154 ( 4) ADC VALUES,X ; ... ARRIVE AT COLUMN ADDRESS IN ARRAY.
80C5-A8 I 155 ( 2) TAY ; USE AS INDEX
80C6-B9 9F 81 I 156 ( 4*) LDA SCORTB,Y ; GET SCORE FOR THIS SPIN.
80C9-18 I 157 ( 2) CLC
80CA-65 01 I 158 ( 3) ADC SCORTP ; ADD TO ANY PREVIOUS SCORES
80CC- I 159 ; ACCUMULATED IN THIS LOOP.
80CC-85 01 I 160 ( 3) STA SCORTP ; RESTORE
80CE-CA I 161 ( 2) DEX
80CF-10 EE I 162 (2**) BPL SCORLP ; LOOP IF NOT DONE
80D1-A9 60 I 163 ( 2) LDA #$60 ; SET UP DURATIONS FOR TONES.
80D3-85 03 I 164 ( 3) STA DUR
80D5-A5 01 I 165 ( 3) LDA SCORTP ; GET SCORE FOR THIS SPIN.
80D7-F0 34 I 166 (2**) BEQ LOSE ; IF SCORE IS 0, LOSE A POINT.
80D9-E6 02 I 167 ( 5) WIN INC SCORE ; RAISE OVERALL SCORE BY ONE.
80DB-A4 02 I 168 ( 3) LDY SCORE ; GET SCORE
80DD-C0 10 I 169 ( 2) CPY #16 ; WIN WITH 16 POINTS?
80DF-F0 10 I 170 (2**) BEQ WINEND ; YES; WIN+ENDGAME.
80E1-20 40 81 I 171 ( 6) JSR LIGHT ; SHOW SCORE
80E4-A9 20 I 172 ( 2) LDA #HITONE ; PLAY HIGH BEEP.
80E6-20 67 81 I 173 ( 6) JSR TONE
80E9-20 33 81 I 174 ( 6) JSR DELAY ; SHORT DELAY.
80EC-C6 01 I 175 ( 5) DEC SCORTP ; DECREMENT SCORE TO BE ADDED TO...
80EE- I 176 ; OVERALL SCORE BY ONE.
80EE-D0 E9 I 177 (2**) BNE WIN ; LOOP IF SCORE TRANSFER NOT COMPLETE.
80F0-60 I 178 ( 6) RTS ; DONE, RETURN TO MAIN PROGRAM.
80F1-A9 FF I 179 ( 2) WINEND LDA #$FF ; TURN ALL LEDS ON TO SIGNAL WIN.
80F3-8D 01 40 I 180 ( 4) STA PORT1A
80F6-8D 00 40 I 181 ( 4) STA PORT1B
80F9-85 00 I 182 ( 3) STA TEMP ; SET FREQ PARAMETER FOR RISING WARBLE.
80FB-A9 00 I 183 ( 2) LDA #0
80FD-85 02 I 184 ( 3) STA SCORE ; CLEAR TO FLAG RESTART.
80FF-A9 04 I 185 ( 2) LDA #4
8101-85 03 I 186 ( 3) STA DUR ; SHORT DURATION FOR INDIVIDUAL BEEPS IN WARBLE.
8103-A5 00 I 187 ( 3) RISE LDA TEMP ; GET FREQUENCY...
8105-20 67 81 I 188 ( 6) JSR TONE ; ... FOR BEEP.
8108-C6 00 I 189 ( 5) DEC TEMP ; NEXT BEEP WILL BE HIGHER.
810A-D0 F7 I 190 (2**) BNE RISE ; DO NEXT BEEP IF NOT DONE.
810C-60 I 191 ( 6) RTS ; RETURN FOR RESTART.
810D-C6 02 I 192 ( 5) LOSE DEC SCORE ; IF SPIN BAD, SCORE=SCORE-1
810F-A4 02 I 193 ( 3) LDY SCORE ; SHOW SCORE
8111-20 40 81 I 194 ( 6) JSR LIGHT
8114-A9 F0 I 195 ( 2) LDA #LOTONE ; PLAY LOW LOSE TONE.
8116-20 67 81 I 196 ( 6) JSR TONE
8119-A4 02 I 197 ( 3) LDY SCORE ; GET SCORE TO SEE...
811B-F0 01 I 198 (2**) BEQ LOSEND ; ... IF GAME IS OVER.
811D-60 I 199 ( 6) RTS ; IF NOT, RETURN FOR NEXT SPIN.
811E-A9 00 I 200 ( 2) LOSEND LDA #0 ; SET TEMP FOR USE AS FREQUENCY PARAMETER
8120-85 00 I 201 ( 3) STA TEMP ; IN FALLING WARBLE.
8122-8D 01 40 I 202 ( 4) STA PORT1A ; CLEAR LED #1.
8125-A9 04 I 203 ( 2) LDA #4
8127-85 03 I 204 ( 3) STA DUR
8129-A5 00 I 205 ( 3) FALL LDA TEMP
812B-20 67 81 I 206 ( 6) JSR TONE ; PLAY BEEP.
812E-E6 00 I 207 ( 5) INC TEMP ; NEXT TONE WILL BE LOWER.
8130-D0 F7 I 208 (2**) BNE FALL
8132-60 I 209 ( 6) RTS ; RETURN FOR RESTART.
8133- I 210
8133- I 211 ;
8133- I 212 ; SUBROUTINE 'DELAY'
8133- I 213 ; VARIABLE LENGHT DELAY SUBROUTINE
8133- I 214 ; DELAY LENGTH = (2046*[DUR]+10) US.
8133- I 215 ;
8133-A4 03 I 216 ( 3) DELAY LDY DUR ; GET DELAY LENGHT.
8135-A2 FF I 217 ( 2) DL1 LDX #$FF ; SET COUNTER FOR INNER 2040 US. LOOP TO
8137-D0 00 I 218 (2**) DL2 BNE DL3 ; WASTE TIME.
8139-CA I 219 ( 2) DL3 DEX ; DECREMENT INNER LOOP COUNTER.
813A-D0 FB I 220 (2**) BNE DL2 ; LOOP UNTIL INNER LOOP DONE.
813C-88 I 221 ( 2) DEY ; DECREMENT OUTER LOOP COUNTER.
813D-D0 F6 I 222 (2**) BNE DL1 ; LOOP UNTIL DONE.
813F-60 I 223 ( 6) RTS ; RETURN.
8140- I 224
8140- I 225 ;
8140- I 226 ; SUBROUTINE 'LIGHT'
8140- I 227 ; SUBROUTINE TO LIGHT LEDS CORRESPONDING TO THE CONTENTS OF REGISTER Y ON
8140- I 228 ; ENTERING.
8140- I 229 ;
8140-A9 00 I 230 ( 2) LIGHT LDA #0 ; CLEAR ACCUMULATOR FOR BIT SHIFT.
8142-85 00 I 231 ( 3) STA TEMP ; CLEAR OVERFLOW FLAG
8144-8D 01 40 I 232 ( 4) STA PORT1A ; CLEAR LOW LEDS
8147-8D 00 40 I 233 ( 4) STA PORT1B ; CLEAR HIGH LEDS.
814A-C0 0F I 234 ( 2) CPY #15 ; CODE FOR UNCONNECTED BIT?
814C-F0 01 I 235 (2**) BEQ LIGHT0 ; IF SO, NO CHANGE.
814E-88 I 236 ( 2) DEY ; DECREMENT TO MATCH.
814F-38 I 237 ( 2) LIGHT0 SEC ; SET BIT TO BE SHIFTED HIGH.
8150-2A I 238 ( 2) LTSHFT ROL A ; SHIFT BIT LEFT.
8151-90 05 I 239 (2**) BCC LTCC ; IF CARRY SET, OVERFLOW HAS OCCURRED
8153- I 240 ; INTO HIGH BYTE.
8153-A2 FF I 241 ( 2) LDX #$FF ; SET OVERFLOW FLAG.
8155-86 00 I 242 ( 3) STX TEMP
8157-2A I 243 ( 2) ROL ; MOVE BIT OUT OF CARRY.
8158-88 I 244 ( 2) LTCC DEY ; ONE LESS BIT TO BE SHIFTED.
8159-10 F5 I 245 (2**) BPL LTSHFT ; SHIFT AGAIN IF NOT DONE.
815B-A6 00 I 246 ( 3) LDX TEMP ; GET OVERFLOW FLAG.
815D-D0 04 I 247 (2**) BNE HIBYTE ; IF FLAG <> 0, OVERFLOW: A CONTAINS HIGH BYTE.
815F-8D 01 40 I 248 ( 4) LOBYTE STA PORT1A ; STORE A IN LOW ORDER LEDS.
8162-60 I 249 ( 6) RTS ; RETURN.
8163-8D 00 40 I 250 ( 4) HIBYTE STA PORT1B ; STORE A IN HIGH ORDER LEDS.
8166-60 I 251 ( 6) RTS ; RETURN.
8167- I 252
8167- I 253 ;
8167- I 254 ; SUBROUTINE 'TONE'
8167- I 255 ; TONE GENERATION SUBROUTINE.
8167- I 256 ;
8167-85 04 I 257 ( 3) TONE STA FREQ
8169-A9 FF I 258 ( 2) LDA #$FF
816B-8D 00 4C I 259 ( 4) STA PORT3B
816E-A9 00 I 260 ( 2) LDA #0
8170-A6 03 I 261 ( 3) LDX DUR
8172-A4 04 I 262 ( 3) FL2 LDY FREQ
8174-88 I 263 ( 2) FL1 DEY
8175-18 I 264 ( 2) CLC
8176-90 00 I 265 (2**) BCC FL0
8178-D0 FA I 266 (2**) FL0 BNE FL1
817A-49 FF I 267 ( 2) EOR #$FF
817C-8D 00 4C I 268 ( 4) STA PORT3B
817F-CA I 269 ( 2) DEX
8180-D0 F0 I 270 (2**) BNE FL2
8182-60 I 271 ( 6) RTS
8183- I 272
8183- I 273 ;
8183- I 274 ; SUBROUTINE 'RANDOM'
8183- I 275 ; RANDOM NUMBER GENERATOR SUBROUTINE.
8183- I 276 ;
8183-38 I 277 ( 2) RANDOM SEC
8184-A5 15 I 278 ( 3) LDA RND+1
8186-65 18 I 279 ( 3) ADC RND+4
8188-65 19 I 280 ( 3) ADC RND+5
818A-85 14 I 281 ( 3) STA RND
818C-A2 04 I 282 ( 2) LDX #4
818E-B5 14 I 283 ( 4) RNDSH LDA RND,X
8190-95 15 I 284 ( 4) STA RND+1,X
8192-CA I 285 ( 2) DEX
8193-10 F9 I 286 (2**) BPL RNDSH
8195-60 I 287 ( 6) RTS
8196- I 288
8196- I 289 ;
8196- I 290 ; ARRAYS
8196- I 291 ;
8196- I 292
8196- I 293 ;
8196- I 294 ; ARRAY OF PATTERNS TO LIGHT LEDS, ARRAY ROWS CORRESPOND TO COLUMNS OF LED
8196- I 295 ; ARRAY, AND COLUMNS TO ROWS, FOR EXAMPLE, THIRD BYTE IN ROW ONE WILL LIGHT
8196- I 296 ; LED 7.
8196- I 297 ;
8196-01 08 40 02
10 80 04 20
00 I 298 LTABLE .HS 01.08.40.02.10.80.04.20.00
819F- I 299
819F- I 300 ;
819F- I 301 ; ARRAY OF SCORES RECEIVED FOR CERTAIN PATTERS OF LIT LEDS; ROWS CORRESPOND TO
819F- I 302 ; ROWS IN LED ARRAY. COLUMNS CORRESPOND TO NUMBER OF LEDS LIT IN THAT ROW.
819F- I 303 ; I.E. 3 LEDS IN MIDDLE ROW IS 3 PTS.
819F- I 304 ;
819F-00 00 00 00
00 00 01 03
00 00 00 00 I 305 SCORTB .HS 00.00.00.00.00.00.01.03.00.00.00.00
81AB- 17 .IN ../../common/CH01-Getkey/getkey_routine.asm
81AB- I 1 ; 'GETKEY' KEYBOARD INPUT ROUTINE READS AND DEBOUNCES KEYBOARD. RETURNS WITH
81AB- I 2 ; KEY NUMBER IN ACCUMULATOR IF KEY DOWN. OPERATION: SENDS NUMBERS 0-F TO 74154
81AB- I 3 ; (4 TO 16 LINE DECODER), WHICH GROUNDS ONE SIDE OF KEYSWITCHES ONE AT A TIME.
81AB- I 4 ; IF A KEY IS DOWN, PA7 OF VIA #3 WILL BE GROUNDED, AND THE CURRENT VALUE
81AB- I 5 ; APPLIED TO THE 74154 BE THE KEY NUMBER. WHEN THE PROGRAM DETECTS A KEY CLOSE
81AB- I 6 ; CHECKS FOR KEY CLOSURE FOR 50 MS. TO ELIMINATE BOUNCE.
81AB- I 7 ; NOTE: IF NO KEY IS PRESSED, GETKEY WILL WAIT.
81AB- I 8 ;
81AB-2C 01 4C I 9 ( 4) GETKEY BIT PORT3A ; SEE IF KEY IS STILL DOWN FROM LAST KEY CLOSURE:
81AE- I 10 ; KEYSTROBE IN 'N' STATUS BIT.
81AE-10 FB I 11 (2**) BPL GETKEY ; IF YES, WAIT FOR KEY RELEASE
81B0-A2 0F I 12 ( 2) RSTART LDX #15 ; SET KEY COUNTER TO 15
81B2-8E 00 4C I 13 ( 4) NXTKEY STX PORT3B ; OUTPUT KEY # TO 74154
81B5-2C 01 4C I 14 ( 4) BIT PORT3A ; SEE IF KEY DOWN: STROBE IN 'N'
81B8-10 05 I 15 (2**) BPL BOUNCE ; IF YES, GO DEBOUNCE
81BA-CA I 16 ( 2) DEX ; DECREMENT KEY #
81BB-10 F5 I 17 (2**) BPL NXTKEY ; NO, DO NEXT KEY
81BD-30 F1 I 18 (2**) BMI RSTART ; START OVER
81BF-8A I 19 ( 2) BOUNCE TXA ; SAVE KEY NUMBER IN A
81C0-A0 12 I 20 ( 2) LDY #$12 ; OUTER LOOP CNT LOAD FOR DELAY OF 50 MS.
81C2-A2 FF I 21 ( 2) LP1 LDX #$FF ; INNER 11 US. LOOP
81C4-2C 01 4C I 22 ( 4) LP2 BIT PORT3A ; SEE IF KEY STILL DOWN
81C7-30 E7 I 23 (2**) BMI RSTART ; IF NOT, KEY NOT VALID, RESTART
81C9-CA I 24 ( 2) DEX
81CA-D0 F8 I 25 (2**) BNE LP2 ; THIS LOOP USES 2115*5 US.
81CC-88 I 26 ( 2) DEY
81CD-D0 F3 I 27 (2**) BNE LP1 ; OUTER LOOP: TOTAL IS 50 MS.
81CF-60 I 28 ( 6) RTS ; DONE: KEY IN A.
81D0- I 29 ;
81D0- I 30 ; SUBROUTINE 'INITKEY'
81D0- I 31 ; TAKES CARE OF INITIALIZING VIA #3 FOR USING WITH THE GETKEY ROUTINE FROM
81D0- I 32 ; THE CODE.
81D0- I 33 ;
81D0-A9 00 I 34 ( 2) INITKEY LDA #0
81D2-8D 03 4C I 35 ( 4) STA DDR3A ; SET KEY STROBE PORT FOR INPUT
81D5-A9 FF I 36 ( 2) LDA #$FF
81D7-8D 02 4C I 37 ( 4) STA DDR3B ; SET KEYS FOR OUTPUT
81DA-60 I 38 ( 6) RTS
81DB- 18 ;
81DB- 19 ; STORE CPU INITIALIZATION VECTORS AT THE END OF THE EEPROM.
81DB- 20 ;
FFFA 21 .NO $FFFA,$FF
FFFA-00 80 22 .DA BE6502 ; NMI VECTOR
FFFC-00 80 23 .DA BE6502 ; RESET VECTOR
FFFE-00 80 24 .DA BE6502 ; IRQ VECTOR

View File

@ -0,0 +1,4 @@
@echo off
sbasm.py echo.asm
type echo.list
pause

View File

@ -0,0 +1,24 @@
.CR 65C02
.TF echo.hex,INT
.LF echo.list
;
; PATTERN/TONE RECALL AND ESP TEST PROGRAM. FOR THE '6502 GAMES' HARDWARE,
; BOARD SHOULD BE JUMPERED WITH VIA CHIPS AT THE ADDRESSES SPECIFIED BELOW.
; OTHER THAN THAT THE CODE IS SHOULD BE UNCHANGED FROM THE BOOK THOUGH THERE
; WILL BE SOME DIFFERENCES DUE TO ASSEMBLER USED.
;
VIA1 .EQ $4000 ; GAME BOARD (VIA #1)
VIA3 .EQ $4C00 ; GAME BOARD (VIA #3)
.OR $8000
.TA $0000
BE6502 JSR INITKEY
.IN ../../common/CH08-Echo/game.asm
.IN ../../common/CH01-Getkey/getkey_routine.asm
;
; STORE CPU INITIALIZATION VECTORS AT THE END OF THE EEPROM.
;
.NO $FFFA,$FF
.DA BE6502 ; NMI VECTOR
.DA BE6502 ; RESET VECTOR
.DA BE6502 ; IRQ VECTOR

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,281 @@
0000- 4 ;
0000- 5 ; PATTERN/TONE RECALL AND ESP TEST PROGRAM. FOR THE '6502 GAMES' HARDWARE,
0000- 6 ; BOARD SHOULD BE JUMPERED WITH VIA CHIPS AT THE ADDRESSES SPECIFIED BELOW.
0000- 7 ; OTHER THAN THAT THE CODE IS SHOULD BE UNCHANGED FROM THE BOOK THOUGH THERE
0000- 8 ; WILL BE SOME DIFFERENCES DUE TO ASSEMBLER USED.
0000- 9 ;
4000- 10 VIA1 .EQ $4000 ; GAME BOARD (VIA #1)
4C00- 11 VIA3 .EQ $4C00 ; GAME BOARD (VIA #3)
0000- 12
8000- 13 .OR $8000
8000- 14 .TA $0000
8000-20 58 81 15 ( 6) BE6502 JSR INITKEY
8003- 16 .IN ../../common/CH08-Echo/game.asm
8003- I 1 ; 'ECHO'
8003- I 2 ; PATTERN/TONE RECALL AND ESP TEST PROGRAM. THE USER GUESSES A PATTERN OF LIT
8003- I 3 ; LEDS AND THEIR ASSOCIATED TONES. THE TONE/LIGHT COMBINATION CAN BE PLAYED,
8003- I 4 ; SO THAT THE USER MUST REMEMBER IT AND REPLICATE IT CORRECTLY.
8003- I 5 ;
8003- I 6 ; OPERATING THE PROGRAM:
8003- I 7 ; THE BOTTOM ROW OF LEDS IS AN INDICATOR FOR PROGRAM STATUS; THE LEFT-MOST
8003- I 8 ; ONE ($10) INDICATES THAT THE PROGRAM IS EXPECTING THE USER TO INPUT THE
8003- I 9 ; LENGTH OF THE SEQUENCE TO BE GUESSED. THE SECOND FROM THE LEFT ($11)
8003- I 10 ; INDICATES THAT THE PROGRAM EXPECTS EITHER A GUESS (1-9), THE COMMAND TO
8003- I 11 ; RESTART THE GAME (0), OR THE COMMAND TO PLAY THE SEQUECE (A-F). THE KEYS
8003- I 12 ; ARE ASSOCIATED WITH THE LEDS 1-9.
8003- I 13 ;
8003- I 14 ; LOOKING AT THE SEQUENCE WHILE IN THE MIDDLE OF GUESSING IT WILL EREASE ALL
8003- I 15 ; PREVIOUS GUESSES (RESET GESNO AND ERRS TO 0). AFTER A WIN, THE PROGRAM
8003- I 16 ; RESTARTS.
8003- I 17
8003- I 18 ;
8003- I 19 ; I/O:
8003- I 20 ;
4000- I 21 PORT1B .EQ VIA1 ; PORT B
4001- I 22 PORT1A .EQ VIA1+1 ; PORT A
4002- I 23 DDR1B .EQ VIA1+2 ; PORT B DATA DIRECTION REGISTER
4003- I 24 DDR1A .EQ VIA1+3 ; PORT A DATA DIRECTION REGISTER
4004- I 25 T1CL .EQ VIA1+4
8003- I 26
4C00- I 27 PORT3B .EQ VIA3 ; PORT B
4C01- I 28 PORT3A .EQ VIA3+1 ; PORT A
4C02- I 29 DDR3B .EQ VIA3+2 ; PORT B DATA DIRECTION REGISTER
4C03- I 30 DDR3A .EQ VIA3+3 ; PORT A DATA DIRECTION REGISTER
8003- I 31
8003- I 32 ;
8003- I 33 ; VARIABLE STORAGE.
8003- I 34 ;
0000- I 35 ZP .EQ $00
0000- I 36 DIGITS .EQ ZP ; NUMBER OF DIGITS IN SEQUENCE
0001- I 37 GESNO .EQ ZP+1 ; NUMBER OF CORRECT GUESS, SPECIFIES
8003- I 38 ; WHERE THE USER IS IN THE SERIES.
0002- I 39 ERRS .EQ ZP+2 ; NUMBER OF ERRORS MADE IN THE SERIES.
0003- I 40 DUR .EQ ZP+3 ; TEMPORARY STORAGE FOR NOTE DURATION.
0004- I 41 FREQ .EQ ZP+4 ; TEMPORARY STORAGE FOR NOTE FREQUENCY.
0005- I 42 TEMP .EQ ZP+5 ; TEMPORARY STORAGE FOR X REGISTER.
0006- I 43 TABLE .EQ ZP+6 ; STORAGE FOR SEQUECE
000F- I 44 RND .EQ ZP+15 ; SCRATCHPAD FOR RANDOM # GENERATOR
8003- I 45
8003-A9 FF I 46 ( 2) START LDA #$FF ; SET UP DATA DIRECTION REGISTERS.
8005-8D 03 40 I 47 ( 4) STA DDR1A
8008-8D 02 40 I 48 ( 4) STA DDR1B
800B-8D 02 4C I 49 ( 4) STA DDR3B
800E-A9 00 I 50 ( 2) LDA #0 ; CLEAR VARIABLE STORAGES
8010-8D 01 40 I 51 ( 4) STA PORT1A ; ... AND LEDS
8013-85 02 I 52 ( 3) STA ERRS
8015-85 01 I 53 ( 3) STA GESNO
8017-AD 04 40 I 54 ( 4) LDA T1CL ; GET SEED FOR RND # GENERATOR
801A-85 10 I 55 ( 3) STA RND+1 ; AND STORE IN RND SCRATCHPAD.
801C-85 13 I 56 ( 3) STA RND+4
801E-A9 02 I 57 ( 2) LDA #%010 ; TURN LED #10 ON TO INDICATE
8020-8D 00 40 I 58 ( 4) STA PORT1B ; NEED FOR LENGTH INPUT.
8023-20 33 81 I 59 ( 6) DIGKEY JSR GETKEY ; GET LENGTH OF SERIES
8026-C9 00 I 60 ( 2) CMP #0 ; IS IT 0?
8028-F0 F9 I 61 (2**) BEQ DIGKEY ; IF YES, GET ANOTHER.
802A-C9 0A I 62 ( 2) CMP #10 ; LENGTH GREATER THAN 9?
802C-10 F5 I 63 (2**) BPL DIGKEY ; IF YES, GET ANOTHER.
802E-85 00 I 64 ( 3) STA DIGITS ; SAVE VALID LENGTH
8030-AA I 65 ( 2) TAX ; USE LENGTH-1 AS INDEX FOR FILLING...
8031-CA I 66 ( 2) DEX ; ... SERIES W/RANDOM VALUES.
8032-86 05 I 67 ( 3) FILL STX TEMP ; SAVE X FROM 'RANDOM'
8034-20 EA 80 I 68 ( 6) JSR RANDOM
8037-A6 05 I 69 ( 3) LDX TEMP ; RESTORE X
8039-F8 I 70 ( 2) SED ; DO A DECIMAL ADJUST
803A-18 I 71 ( 2) CLC
803B-69 00 I 72 ( 2) ADC #0
803D-D8 I 73 ( 2) CLD
803E-29 0F I 74 ( 2) AND #$0F ; REMOVE UPPER NIBBLE SO NUMBER IS <10
8040-F0 F0 I 75 (2**) BEQ FILL ; # CAN'T BE ZERO
8042-95 06 I 76 ( 4) STA TABLE,X ; STORE # IN TABLE
8044-CA I 77 ( 2) DEX ; DECREMENT FOR NEXT
8045-10 EB I 78 (2**) BPL FILL ; LOOP IF NOT DONE
8047-A9 00 I 79 ( 2) KEY LDA #0 ; CLEAR LEDS
8049-8D 01 40 I 80 ( 4) STA PORT1A
804C-A9 04 I 81 ( 2) LDA #%0100 ; TURN INPUT INDICATOR ON.
804E-8D 00 40 I 82 ( 4) STA PORT1B
8051-20 33 81 I 83 ( 6) JSR GETKEY ; GET GUESS OR PLAY COMMAND
8054-C9 00 I 84 ( 2) CMP #0 ; IS IT 0?
8056-F0 AB I 85 (2**) STRTJP BEQ START ; IF YES, RESTART.
8058-C9 0A I 86 ( 2) CMP #10 ; NUMBER < 10 ?
805A-30 22 I 87 (2**) BMI EVAL ; IF YES, EVALUATE GUESS.
805C- I 88 ;
805C- I 89 ; ROUTINE TO DISPLAY SERIES TO BE GUESSED BY LIGHTING LEDS AND PLAYING
805C- I 90 ; TONES IN SEQUECE.
805C- I 91 ;
805C-A2 00 I 92 ( 2) SHOW LDX #0
805E-86 01 I 93 ( 3) STX GESNO ; CLEAR CURRENT GUESS NUMBER
8060-86 02 I 94 ( 3) STX ERRS ; CLEAR CURRENT ERROR NUMBER
8062-B5 06 I 95 ( 4) SHOWLP LDA TABLE,X ; GET X-TH ENTRY IN SERIES TABLE.
8064-86 05 I 96 ( 3) STX TEMP ; SAVE X
8066-20 D2 80 I 97 ( 6) JSR LIGHT ; LIGHT LED # (TABLE(X))
8069-20 FD 80 I 98 ( 6) JSR PLAY ; PLAY TONE # (TABLE(X))
806C-A0 FF I 99 ( 2) LDY #$FF ; SET LOOP COUNTER FOR DELAY
806E-66 03 I 100 ( 5) DELAY ROR DUR ; WASTE TIME
8070-26 03 I 101 ( 5) ROL DUR
8072-88 I 102 ( 2) DEY ; COUNT DOWN
8073-D0 F9 I 103 (2**) BNE DELAY ; IF NOT DONE, WASTE SOME MORE TIME
8075-A6 05 I 104 ( 3) LDX TEMP ; RESTORE X
8077-E8 I 105 ( 2) INX ; INCREMENT INDEX TO SHOW NEXT
8078-E4 00 I 106 ( 3) CPX DIGITS ; ALL DIGITS SHOWN?
807A-D0 E6 I 107 (2**) BNE SHOWLP ; IF NOT, SHOW NEXT.
807C-F0 C9 I 108 (2**) BEQ KEY ; DONE, SO GET NEXT INPUT.
807E- I 109 ;
807E- I 110 ; ROUTINE TO EVALUATE GUESSES OF PLAYER.
807E- I 111 ;
807E-A6 01 I 112 ( 3) EVAL LDX GESNO ; GET NUMBER OF GUESS.
8080-D5 06 I 113 ( 4) CMP TABLE,X ; GUESS = CORRESPONDING DIGIT = ?
8082-F0 0D I 114 (2**) BEQ CORRECT ; IF YES, SHOW PLAYER.
8084-E6 02 I 115 ( 5) WRONG INC ERRS ; GUESS WRONG, ANOTHER ERROR FOR THE TALLY.
8086-A9 80 I 116 ( 2) LDA #$80 ; DURATION FOR LOW TONE TO INDICATE A
8088-85 03 I 117 ( 3) STA DUR ; BAD GUESS.
808A-A9 FF I 118 ( 2) LDA #$FF ; FREQUENCY CONSTANT
808C-20 07 81 I 119 ( 6) JSR PLYTON ; PLAY IT
808F-F0 06 I 120 (2**) BEQ ENDCHK ; CHECK FOR ENDGAME
8091-20 D2 80 I 121 ( 6) CORRECT JSR LIGHT ; VALIDATE CORRECT GUESS...
8094-20 FD 80 I 122 ( 6) JSR PLAY
8097-E6 01 I 123 ( 5) ENDCHK INC GESNO ; ONE MORE GUESS TAKEN.
8099-A5 00 I 124 ( 3) LDA DIGITS
809B-C5 01 I 125 ( 3) CMP GESNO ; ALL DIGITS GUESSED?
809D-D0 A8 I 126 (2**) BNE KEY ; IF NOT, GET NEXT.
809F-A5 02 I 127 ( 3) LDA ERRS ; GET NUMBER OF ERRORS.
80A1-C9 00 I 128 ( 2) CMP #0 ; ANY ERRORS?
80A3-F0 15 I 129 (2**) BEQ WIN ; IF NOT, PLAYER WINS.
80A5-20 D2 80 I 130 ( 6) LOSE JSR LIGHT ; SHOW NUMBER OF ERRORS.
80A8-A9 09 I 131 ( 2) LDA #9 ; PLAY 8 DESCENDING TONES
80AA-48 I 132 ( 3) LOSELP PHA
80AB-20 FD 80 I 133 ( 6) JSR PLAY
80AE-68 I 134 ( 4) PLA
80AF-38 I 135 ( 2) SEC
80B0-E9 01 I 136 ( 2) SBC #1
80B2-D0 F6 I 137 (2**) BNE LOSELP
80B4-85 01 I 138 ( 3) STA GESNO ; CLEAR VARIABLES
80B6-85 02 I 139 ( 3) STA ERRS
80B8-F0 8D I 140 (2**) BEQ KEY ; GET NEXT GUESS SEQUECE
80BA-A9 FF I 141 ( 2) WIN LDA #$FF ; TURN ALL LEDS ON FOR WIN
80BC-8D 01 40 I 142 ( 4) STA PORT1A
80BF-8D 00 40 I 143 ( 4) STA PORT1B
80C2-A9 01 I 144 ( 2) LDA #1 ; PLAY 8 ASCENDING TONES
80C4-48 I 145 ( 3) WINLP PHA
80C5-20 FD 80 I 146 ( 6) JSR PLAY
80C8-68 I 147 ( 4) PLA
80C9-18 I 148 ( 2) CLC
80CA-69 01 I 149 ( 2) ADC #01
80CC-C9 0A I 150 ( 2) CMP #10
80CE-D0 F4 I 151 (2**) BNE WINLP
80D0-F0 84 I 152 (2**) BEQ STRTJP ; USE DOUBLE-JUMP FOR RESTART
80D2- I 153 ;
80D2- I 154 ; SUBROUTINE 'LIGHT'
80D2- I 155 ; ROUTINE TO LIGHT N-TH LED, WHERE N IS THE NUMBER PASSED AS A PARAMETER IN
80D2- I 156 ; THE ACCUMULATOR.
80D2- I 157 ;
80D2-48 I 158 ( 3) LIGHT PHA ; SAVE A
80D3-A8 I 159 ( 2) TAY ; USE AS COUNTER IN Y
80D4-A9 00 I 160 ( 2) LDA #0 ; CLEAR A FOR BIT SHIFT
80D6-8D 00 40 I 161 ( 4) STA PORT1B ; CLEAR HI LEDS.
80D9-38 I 162 ( 2) SEC ; GENERATE HI BIT TO SHIFT LEFT.
80DA-2A I 163 ( 2) LTSHFT ROL A ; MOVE HI BIT LEFT.
80DB-88 I 164 ( 2) DEY ; DECREMENT COUNTER
80DC-D0 FC I 165 (2**) BNE LTSHFT ; SHIFTS DONE?
80DE-8D 01 40 I 166 ( 4) STA PORT1A ; STORE CORRECT PATTERN
80E1-90 05 I 167 (2**) BCC LTCC ; BIT 9 NOT HI, DONE.
80E3-A9 01 I 168 ( 2) LDA #1
80E5-8D 00 40 I 169 ( 4) STA PORT1B ; TURN LED 9 ON.
80E8-68 I 170 ( 4) LTCC PLA ; RESTORE A
80E9-60 I 171 ( 6) RTS
80EA- I 172 ;
80EA- I 173 ; SUBROUTINE 'RANDOM'
80EA- I 174 ; RANDOM NUMBER GENERATOR, RETURNS WITH NEW RANDOM NUMBER IN ACCUMULATOR.
80EA- I 175 ;
80EA-38 I 176 ( 2) RANDOM SEC
80EB-A5 10 I 177 ( 3) LDA RND+1
80ED-65 13 I 178 ( 3) ADC RND+4
80EF-65 14 I 179 ( 3) ADC RND+5
80F1-85 0F I 180 ( 3) STA RND
80F3-A2 04 I 181 ( 2) LDX #4
80F5-B5 0F I 182 ( 4) RNDLP LDA RND,X
80F7-95 10 I 183 ( 4) STA RND+1,X
80F9-CA I 184 ( 2) DEX
80FA-10 F9 I 185 (2**) BPL RNDLP
80FC-60 I 186 ( 6) RTS
80FD- I 187 ;
80FD- I 188 ; SUBROUTINE 'PLAY'
80FD- I 189 ; ROUTINE TO PLAY TONES WHOSE NUMBER IS PASSED IN BY ACCUMULATOR. IF ENTERED
80FD- I 190 ; AT PLYTON, IT WILL PLAY TONE WHOSE LENGTH IS IN DUR, FREQUENCY IN THE
80FD- I 191 ; ACCUMULATOR INSTEAD.
80FD-A8 I 192 ( 2) PLAY TAY ; USE TONE # AS INDEX...
80FE-88 I 193 ( 2) DEY ; DECREMENT TO MATCH TABLES
80FF-B9 2A 81 I 194 ( 4*) LDA DURTAB,Y ; GET DURATION FOR TONE N-TH TONE
8102-85 03 I 195 ( 3) STA DUR ; SAVE IT.
8104-B9 21 81 I 196 ( 4*) LDA NOTAB,Y ; GET FREQUENCY CONSTANT FOR N-TH TONE
8107-85 04 I 197 ( 3) PLYTON STA FREQ ; SAVE IT.
8109-A9 00 I 198 ( 2) LDA #0 ; SET SPKR PORT LO.
810B-8D 00 4C I 199 ( 4) STA PORT3B
810E-A6 03 I 200 ( 3) LDX DUR ; GET DURATION IN NUMBER OF 1/2 CYCLES.
8110-A4 04 I 201 ( 3) FL2 LDY FREQ ; GET FREQUENCY
8112-88 I 202 ( 2) FL1 DEY ; COUNT DOWN DELAY...
8113-18 I 203 ( 2) CLC ; WASTE TIME
8114-90 00 I 204 (2**) BCC FL0
8116-D0 FA I 205 (2**) FL0 BNE FL1 ; LOOP FOR DELAY
8118-49 FF I 206 ( 2) EOR #$FF ; COMPLEMENT PORT
811A-8D 00 4C I 207 ( 4) STA PORT3B
811D-CA I 208 ( 2) DEX ; COUNT DOWN DURATION...
811E-D0 F0 I 209 (2**) BNE FL2 ; LOOP UNTIL NOTE OVER.
8120-60 I 210 ( 6) RTS ; DONE.
8121- I 211 ;
8121- I 212 ; TABLE FOR NOTE FREQUENCIES.
8121- I 213 ;
8121-C9 BE A9 96
8E 7E 70 64
5E I 214 NOTAB .HS C9.BE.A9.96.8E.7E.70.64.5E
812A- I 215 ;
812A- I 216 ; TABLE FOR NOTE DURATIONS.
812A- I 217 ;
812A-6B 72 80 8F
94 AA BF D7
E4 I 218 DURTAB .HS 6B.72.80.8F.94.AA.BF.D7.E4
8133- 17 .IN ../../common/CH01-Getkey/getkey_routine.asm
8133- I 1 ; 'GETKEY' KEYBOARD INPUT ROUTINE READS AND DEBOUNCES KEYBOARD. RETURNS WITH
8133- I 2 ; KEY NUMBER IN ACCUMULATOR IF KEY DOWN. OPERATION: SENDS NUMBERS 0-F TO 74154
8133- I 3 ; (4 TO 16 LINE DECODER), WHICH GROUNDS ONE SIDE OF KEYSWITCHES ONE AT A TIME.
8133- I 4 ; IF A KEY IS DOWN, PA7 OF VIA #3 WILL BE GROUNDED, AND THE CURRENT VALUE
8133- I 5 ; APPLIED TO THE 74154 BE THE KEY NUMBER. WHEN THE PROGRAM DETECTS A KEY CLOSE
8133- I 6 ; CHECKS FOR KEY CLOSURE FOR 50 MS. TO ELIMINATE BOUNCE.
8133- I 7 ; NOTE: IF NO KEY IS PRESSED, GETKEY WILL WAIT.
8133- I 8 ;
8133-2C 01 4C I 9 ( 4) GETKEY BIT PORT3A ; SEE IF KEY IS STILL DOWN FROM LAST KEY CLOSURE:
8136- I 10 ; KEYSTROBE IN 'N' STATUS BIT.
8136-10 FB I 11 (2**) BPL GETKEY ; IF YES, WAIT FOR KEY RELEASE
8138-A2 0F I 12 ( 2) RSTART LDX #15 ; SET KEY COUNTER TO 15
813A-8E 00 4C I 13 ( 4) NXTKEY STX PORT3B ; OUTPUT KEY # TO 74154
813D-2C 01 4C I 14 ( 4) BIT PORT3A ; SEE IF KEY DOWN: STROBE IN 'N'
8140-10 05 I 15 (2**) BPL BOUNCE ; IF YES, GO DEBOUNCE
8142-CA I 16 ( 2) DEX ; DECREMENT KEY #
8143-10 F5 I 17 (2**) BPL NXTKEY ; NO, DO NEXT KEY
8145-30 F1 I 18 (2**) BMI RSTART ; START OVER
8147-8A I 19 ( 2) BOUNCE TXA ; SAVE KEY NUMBER IN A
8148-A0 12 I 20 ( 2) LDY #$12 ; OUTER LOOP CNT LOAD FOR DELAY OF 50 MS.
814A-A2 FF I 21 ( 2) LP1 LDX #$FF ; INNER 11 US. LOOP
814C-2C 01 4C I 22 ( 4) LP2 BIT PORT3A ; SEE IF KEY STILL DOWN
814F-30 E7 I 23 (2**) BMI RSTART ; IF NOT, KEY NOT VALID, RESTART
8151-CA I 24 ( 2) DEX
8152-D0 F8 I 25 (2**) BNE LP2 ; THIS LOOP USES 2115*5 US.
8154-88 I 26 ( 2) DEY
8155-D0 F3 I 27 (2**) BNE LP1 ; OUTER LOOP: TOTAL IS 50 MS.
8157-60 I 28 ( 6) RTS ; DONE: KEY IN A.
8158- I 29 ;
8158- I 30 ; SUBROUTINE 'INITKEY'
8158- I 31 ; TAKES CARE OF INITIALIZING VIA #3 FOR USING WITH THE GETKEY ROUTINE FROM
8158- I 32 ; THE CODE.
8158- I 33 ;
8158-A9 00 I 34 ( 2) INITKEY LDA #0
815A-8D 03 4C I 35 ( 4) STA DDR3A ; SET KEY STROBE PORT FOR INPUT
815D-A9 FF I 36 ( 2) LDA #$FF
815F-8D 02 4C I 37 ( 4) STA DDR3B ; SET KEYS FOR OUTPUT
8162-60 I 38 ( 6) RTS
8163- 18 ;
8163- 19 ; STORE CPU INITIALIZATION VECTORS AT THE END OF THE EEPROM.
8163- 20 ;
FFFA 21 .NO $FFFA,$FF
FFFA-00 80 22 .DA BE6502 ; NMI VECTOR
FFFC-00 80 23 .DA BE6502 ; RESET VECTOR
FFFE-00 80 24 .DA BE6502 ; IRQ VECTOR

View File

@ -0,0 +1,4 @@
@echo off
sbasm.py mind_bender.asm
type mind_bender.list
pause

View File

@ -0,0 +1,25 @@
.CR 65C02
.TF mind_bender.hex,INT
.LF mind_bender.list
;
; MASTERMIND-TYPE OF GAME FOR THE '6502 GAMES' HARDWARE, BOARD SHOULD BE
; JUMPERED WITH VIA CHIPS AT THE ADDRESSES SPECIFIED BELOW. OTHER THAN THAT
; THE CODE IS SHOULD BE UNCHANGED FROM THE BOOK THOUGH THERE WILL BE SOME
; DIFFERENCES DUE TO ASSEMBLER USED.
;
VIA1 .EQ $4000 ; GAME BOARD (VIA #1)
VIA3 .EQ $4C00 ; GAME BOARD (VIA #3)
.OR $8000
.TA $0000
BE6502 JSR INITKEY
.IN ../../common/CH09-MindBender/game.asm
.IN ../../common/CH01-Getkey/getkey_routine.asm
.IN ../../common/CH09-MindBender/interrupt.asm
;
; STORE CPU INITIALIZATION VECTORS AT THE END OF THE EEPROM.
;
.NO $FFFA,$FF
.DA BE6502 ; NMI VECTOR
.DA DOINT ; RESET VECTOR
.DA BE6502 ; IRQ VECTOR

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,306 @@
0000- 4 ;
0000- 5 ; MASTERMIND-TYPE OF GAME FOR THE '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 SHOULD BE UNCHANGED FROM THE BOOK THOUGH THERE WILL BE SOME
0000- 8 ; DIFFERENCES DUE TO ASSEMBLER USED.
0000- 9 ;
4000- 10 VIA1 .EQ $4000 ; GAME BOARD (VIA #1)
4C00- 11 VIA3 .EQ $4C00 ; GAME BOARD (VIA #3)
0000- 12
8000- 13 .OR $8000
8000- 14 .TA $0000
8000-20 53 81 15 ( 6) BE6502 JSR INITKEY
8003- 16 .IN ../../common/CH09-MindBender/game.asm
8003- I 1 ; 'MINDBENDER'
8003- I 2 ; PLAYS MINDBENDER GAME: USER SPECIFIES LENGTH OF NUMBER TO BE GUESSED, THEN
8003- I 3 ; GUESSES DIGITS, AND COMPUTER TELLS PLAYER HOW MANY OF THE DIGITS GUESSED
8003- I 4 ; WERE RIGHT, AND HOW MANY OF THOSE CORRECT DIGITS WERE IN THE CORRECT PLACE,
8003- I 5 ; UNTIL THE PLAYER CAN GUESS THE NUMBER ON THE BOARD. BLINKING LEDS INDICATE
8003- I 6 ; CORRECT VALUE & CORRECT DIGIT, AND NON-BLINKING LEDS SHOW CORRECT DIGIT
8003- I 7 ; VALUE, BUT WRONG PLACE.
8003- I 8 ;
8003- I 9 ; THE BOTTOM ROW OF LEDS IS USED TO SHOW THE MODE OF THE PROGRAM: IF THE
8003- I 10 ; LEFTMOST LEDS ARE LIT, THE PROGRAM EXPECTS A GUESS. THE PROGRAM REJECTS
8003- I 11 ; UNSUITABLE VALUES FOR A NUMBER LENGTH, WHICH CAN ONLY BE 1-9, A VALUE OTHER
8003- I 12 ; THAN 0-9 FOR A GUESS RESTARTS THE GAME.
8003- I 13 ;
8003- I 14 ; A LOW TONE DENOTES A BAD GUESS, A HIGH TONE, A WIN. AFTER A WIN, THE PROGRAM
8003- I 15 ; RESTARTS. AN INTERRUPT ROUTINE IS USED TO BLINK THE LEDS.
8003- I 16 ;
4000- I 17 PORT1B .EQ VIA1 ; PORT B
4001- I 18 PORT1A .EQ VIA1+1 ; PORT A
4002- I 19 DDR1B .EQ VIA1+2 ; PORT B DATA DIRECTION REGISTER
4003- I 20 DDR1A .EQ VIA1+3 ; PORT A DATA DIRECTION REGISTER
4004- I 21 T1LL .EQ VIA1+4 ; TIMER 1 LATCH LOW
4005- I 22 T1CH .EQ VIA1+5 ; TIMER 1 COUNTER HIGH
400E- I 23 IER .EQ VIA1+14 ; INTERRUPT ENABLE REGISTER
400B- I 24 ACR .EQ VIA1+11 ; AUXILLIARY CONTROL REGISTER
8003- I 25
4C00- I 26 PORT3B .EQ VIA3 ; PORT B
4C01- I 27 PORT3A .EQ VIA3+1 ; PORT A
4C02- I 28 DDR3B .EQ VIA3+2 ; PORT B DATA DIRECTION REGISTER
4C03- I 29 DDR3A .EQ VIA3+3 ; PORT A DATA DIRECTION REGISTER
8003- I 30
8003- I 31 ;
8003- I 32 ; VARIABLE STORAGE.
8003- I 33 ;
0000- I 34 ZP .EQ $00
0000- I 35 DIGITS .EQ ZP ; NUMBER OF DIGITS TO BE GUESSED
0001- I 36 DUR .EQ ZP+1 ; TONE DURATION CONSTANT
0002- I 37 XTEMP .EQ ZP+2 ; TEMP STORAGE FOR X REGISTER
0003- I 38 YTEMP .EQ ZP+3 ; TEMP STORAGE FOR Y REGISTER
0004- I 39 CNT .EQ ZP+4 ; KEEPS TRACK OF # OF MATCHES
0005- I 40 MASKA .EQ ZP+5 ; CONTAINS PATTERN EOR-ED WITH LED
8003- I 41 ; STATUS REGISTER A TO CAUSE BLINK
0006- I 42 MASKB .EQ ZP+6 ; LED PORT B BLINK MASK
0007- I 43 FREQ .EQ ZP+7 ; TEMPORARY STORAGE FOR TONE FREQUENCY
0008- I 44 CNT1 .EQ ZP+8 ; # OF CORRECT DIGITS IN RIGHT PLACE
0009- I 45 RND .EQ ZP+9 ; FIRST OF RANDOM # LOCATIONS
000F- I 46 DIG0 .EQ ZP+15 ; FIRST OF 9 DIGIT LOCATIONS
0012- I 47 ENTRY0 .EQ ZP+18 ; FIRST OF 9 GUESS LOCATIONS
A67E- I 48 IRQVECL .EQ $A67E ; INTERRUPT VECTOR LOW ORDER BYTE
A67F- I 49 IRQVECH .EQ $A67F ; AND HIGH ORDER
8003- I 50
8003- I 51 ;
8003- I 52 ; ROUTINE TO SET UP VARIABLES AND INTERRUPT TIMER FOR LED FLASHING.
8003- I 53 ;
8003-A9 EA I 54 ( 2) START LDA #$EA ; LOAD LOW INTERRUPT VECTOR
8005-8D 7E A6 I 55 ( 4) STA IRQVECL ; ... AND SET AT VECTOR LOCATION.
8008-A9 03 I 56 ( 2) LDA #$03 ; LOAD INTERRUPT VECTOR ...
800A-8D 7F A6 I 57 ( 4) STA IRQVECH ; ... AND STORE.
800D-A9 7F I 58 ( 2) LDA #$7F ; CLEAR INTERRUPT ENABLE REGISTER
800F-8D 0E 40 I 59 ( 4) STA IER
8012-A9 C0 I 60 ( 2) LDA #$C0 ; ENABLE TIMER 1 INTERRUPT
8014-8D 0E 40 I 61 ( 4) STA IER
8017-A9 40 I 62 ( 2) LDA #$40 ; ENABLE TIMER 1 IN FREE-RUN MODE
8019-8D 0B 40 I 63 ( 4) STA ACR
801C-A9 FF I 64 ( 2) LDA #$FF
801E-8D 04 40 I 65 ( 4) STA T1LL ; SET LOW LATCH ON TIMER 1
8021-8D 05 40 I 66 ( 4) STA T1CH ; SET LATCH HIGH & START COUNT
8024-58 I 67 ( 2) CLI ; ENABLE INTERRUPTS
8025-8D 03 40 I 68 ( 4) STA DDR1A ; SET VIA 1 PORT A FOR OUTPUT
8028-8D 02 40 I 69 ( 4) STA DDR1B ; SET VIA 1 PORT B FOR OUTPUT
802B-8D 02 4C I 70 ( 4) STA DDR3B ; SET VIA 3 PORT B FOR OUTPUT
802E-A9 00 I 71 ( 2) KEY1 LDA #0 ; CLEAR LEDS
8030-8D 01 40 I 72 ( 4) STA PORT1A
8033-8D 00 40 I 73 ( 4) STA PORT1B
8036-85 05 I 74 ( 3) STA MASKA ; CLEAR BLINK MASKS
8038-85 06 I 75 ( 3) STA MASKB
803A- I 76 ;
803A- I 77 ; ROUTINE TO GET NUMBER OF DIGITS TO GUESS, THEN FILL THE DIGITS WITH RANDOM
803A- I 78 ; NUMBERS FROM 0-9.
803A- I 79 ;
803A-A9 02 I 80 ( 2) LDA #%00000010 ; LIGHT LED TO SIGNAL USER TO
803C-8D 00 40 I 81 ( 4) STA PORT1B ; INPUT # OF DIGITS NEEDED.
803F-20 2E 81 I 82 ( 6) JSR GETKEY ; GET # OF DIGITS
8042-C9 0A I 83 ( 2) CMP #10 ; IF KEY# > 9, RESTART GAME
8044-10 E8 I 84 (2**) BPL KEY1
8046-C9 00 I 85 ( 2) CMP #0 ; CHECK FOR 0 DIGITS TO GUESS
8048-F0 E4 I 86 (2**) BEQ KEY1 ; ... 0 DIGITS NOT ALLOWED.
804A-85 00 I 87 ( 3) STA DIGITS ; STORE VALID # OF DIGITS
804C-AD 04 40 I 88 ( 4) LDA T1LL ; GET RANDOM #,
804F-85 0A I 89 ( 3) STA RND+1 ; USE IT TO START RANDOM
8051-85 0D I 90 ( 3) STA RND+4 ; NUMBER GENERATOR.
8053-85 0E I 91 ( 3) STA RND+5
8055-A4 00 I 92 ( 3) LDY DIGITS ; GET # OF DIGITS TO BE GUESSED
8057-88 I 93 ( 2) DEY ; ... AND COUNT DOWN TO 0, FILLING THEM WITH VALUES
8058-20 FF 80 I 94 ( 6) RAND JSR RANDOM ; GET RANDOM VALUE FOR DIGIT
805B-F8 I 95 ( 2) SED
805C-69 00 I 96 ( 2) ADC #00 ; DECIMAL ADJUST
805E-D8 I 97 ( 2) CLD
805F-29 0F I 98 ( 2) AND #%00001111 ; KEEP DIGIT < 10
8061-99 0F 00 I 99 ( 5) STA DIG0,Y ; SAVE IT IN DIGIT TABLE.
8064-88 I 100 ( 2) DEY
8065-10 F1 I 101 (2**) BPL RAND ; FILL NEXT DIGIT
8067- I 102 ;
8067- I 103 ; ROUTINE TO FILL GUESS TABLE WITH USERS GUESSES
8067- I 104 ;
8067-A9 00 I 105 ( 2) ENTER LDA #0 ; CLEAR ENTRY TABLE POINTER
8069-85 02 I 106 ( 3) STA XTEMP
806B-A9 06 I 107 ( 2) LDA #%00000110 ; LET USER KNOW THAT GUESSES
806D-0D 00 40 I 108 ( 4) ORA PORT1B ; SHOULD BE INPUT ...
8070-8D 00 40 I 109 ( 4) STA PORT1B ; ... WITHOUT CHANGING ARRAY
8073-20 2E 81 I 110 ( 6) KEY2 JSR GETKEY ; GET GUESS
8076-C9 0A I 111 ( 2) CMP #10 ; IS IT GREATER THAN 9?
8078-10 B4 I 112 (2**) BPL KEY1 ; IF YES, RESTART GAME.
807A-A6 02 I 113 ( 3) LDX XTEMP ; GET POINTER FOR INDEXING
807C-95 12 I 114 ( 4) STA ENTRY0,X ; STORE GUESS IN TABLE
807E-E8 I 115 ( 2) INX ; INCREMENT POINTER
807F-86 02 I 116 ( 3) STX XTEMP
8081-E4 00 I 117 ( 3) CPX DIGITS ; CORRECT # OF GUESSES FETCHED?
8083-D0 EE I 118 (2**) BNE KEY2 ; IF NOT, GET ANOTHER
8085- I 119 ;
8085- I 120 ; THIS ROUTINE COMPARES USERS GUESSES WITH DIGITS OF NUMBER TO GUESS. FOR
8085- I 121 ; EACH CORRECT DIGIT IN THE CORRECT PLACE, A BLINKING LED IS LIT, AND FOR
8085- I 122 ; EACH CORRECT DIGIT IN THE WRONG PLACE, A NON-BLINKING LED IS LIT.
8085- I 123 ;
8085-A2 00 I 124 ( 2) LDX #0 ; CLEAR FOLLOWING STORAGES:
8087-8E 01 40 I 125 ( 4) STX PORT1A ; LEDS
808A-8E 00 40 I 126 ( 4) STX PORT1B
808D-86 05 I 127 ( 3) STX MASKA ; BLINK MASKS
808F-86 06 I 128 ( 3) STX MASKB
8091-86 04 I 129 ( 3) STX CNT ; COUNT OF MATCHES
8093-86 08 I 130 ( 3) STX CNT1 ; COUNT OF RIGHT DIGITS
8095-B5 0F I 131 ( 4) DIGLP LDA DIG0,X ; LOAD 1ST DIGIT OF # FOR COMPARISON
8097-D5 12 I 132 ( 4) CMP ENTRY0,X ; RIGHT GUESS, RIGHT PLACE?
8099-D0 04 I 133 (2**) BNE ENTCMP ; NO, IS RIGHT GUESS IN WRONG PLACE?
809B-E6 08 I 134 ( 5) INC CNT1 ; ONE MORE RIGHT GUESS/RIGHT PLACE
809D-D0 10 I 135 (2**) BNE NEXTDIG ; EXAMINE NEXT DIGIT OF NUMBER
809F-A0 00 I 136 ( 2) ENTCMP LDY #0 ; RESET GUESS # PTR FOR COMPARES
80A1-D9 12 00 I 137 ( 4*) ENTRYLP CMP ENTRY0,Y ; RIGHT DIGIT, WRONG PLACE?
80A4-D0 04 I 138 (2**) BNE NEXTENT ; NO, SEE IF NEXT DIGIT IS.
80A6-E6 04 I 139 ( 5) INC CNT ; ONE MORE RIGHT DIGIT/WRONG PLACE
80A8-D0 05 I 140 (2**) BNE NEXTDIG ; EXAMINE NEXT DIGIT OF NUMBER
80AA-C8 I 141 ( 2) NEXTENT INY ; INCREMENT GUESS # POINTER
80AB-C4 00 I 142 ( 3) CPY DIGITS ; ALL GUESSES TESTED?
80AD-D0 F2 I 143 (2**) BNE ENTRYLP ; NO, TRY NEXT GUESS.
80AF-E8 I 144 ( 2) NEXTDIG INX ; INCREMENT DIGIT # POINTER
80B0-E4 00 I 145 ( 3) CPX DIGITS ; ALL DIGITS EVALUATED?
80B2-D0 E1 I 146 (2**) BNE DIGLP ; NO, CHECK NEXT DIGIT.
80B4-18 I 147 ( 2) CLC ; GET READY FOR ADD...
80B5-A5 04 I 148 ( 3) LDA CNT ; OF TOTAL MATCHES TO DETERMINE
80B7-65 08 I 149 ( 3) ADC CNT1 ; NUMBER OF LEDS TO LIGHT.
80B9-A8 I 150 ( 2) TAY ; TRANSFER A TO Y FOR 'LIGHT' ROUTINE
80BA-20 F1 80 I 151 ( 6) JSR LITE ; GET PATTERN TO LIGHT LEDS
80BD-8D 01 40 I 152 ( 4) STA PORT1A ; TURN LEDS ON
80C0-90 05 I 153 (2**) BCC CC ; IF CARRY=0, DON'T LIGHT PB0
80C2-A9 01 I 154 ( 2) LDA #1
80C4-8D 00 40 I 155 ( 4) STA PORT1B ; TURN PB0 ON.
80C7-A4 08 I 156 ( 3) CC LDY CNT1 ; LOAD # OF LEDS TO BLINK
80C9-20 F1 80 I 157 ( 6) JSR LITE ; GET PATTERN
80CC-85 05 I 158 ( 3) STA MASKA ; START TO BLINK LEDS
80CE-90 04 I 159 (2**) BCC TEST ; IF CARRY=0, PB0 WON'T BLINK
80D0-A9 01 I 160 ( 2) LDA #1
80D2-85 06 I 161 ( 3) STA MASKB
80D4- I 162 ;
80D4- I 163 ; ROUTINE TO TEST FOR WIN BY CHECKING IF # OF CORRECT DIGITS IN CORRECT
80D4- I 164 ; PLACES = NUMBER OF DIGITS. IF WIN, A HIGH PITCHED SOUND IS GENERATED, AND
80D4- I 165 ; IF ANY DIGIT IS WRONG, A LOW SOUND IS GENERATED INSTEAD.
80D4- I 166 ;
80D4-A6 08 I 167 ( 3) TEST LDX CNT1 ; LOAD NUMBER OF CORRECT DIGITS
80D6-E4 00 I 168 ( 3) CPX DIGITS ; ALL GUESSES CORRECT?
80D8-F0 0B I 169 (2**) BEQ WIN ; IF YES, PLAYER WINS
80DA-A9 72 I 170 ( 2) BAD LDA #$72
80DC-85 01 I 171 ( 3) STA DUR ; SET UP LENGTH OF LOW TONE
80DE-A9 BE I 172 ( 2) LDA #$BE ; TONE VALUE FOR LOW TONE
80E0-20 12 81 I 173 ( 6) JSR TONE ; SIGNAL BAD GUESSES WITH TONE
80E3-F0 82 I 174 (2**) BEQ ENTER ; GET NEXT GUESSES
80E5-A9 FF I 175 ( 2) WIN LDA #$FF ; DURATION FOR HIGH TONE
80E7-85 01 I 176 ( 3) STA DUR
80E9-A9 54 I 177 ( 2) LDA #$54 ; TONE VALUE FOR HIGH TONE
80EB-20 12 81 I 178 ( 6) JSR TONE ; SIGNAL WIN
80EE-4C 2E 80 I 179 ( 3) JMP KEY1 ; RESTART GAME
80F1- I 180 ;
80F1- I 181 ; ROUTINE TO FILL ACCUMULATOR WITH ONES, STARTING AT THE LOW ORDER END, UP
80F1- I 182 ; TO AND INCLUDING THE BIT POSITION CORRESPONDING TO THE # OF LEDS TO BE LIT
80F1- I 183 ; OR SET TO BLINKING.
80F1- I 184 ;
80F1-D0 04 I 185 (2**) LITE BNE STRTSH ; IF Y NOT ZERO, SHIFT ONES IN
80F3-A9 00 I 186 ( 2) LDA #0 ; SPECIAL CASE: RESULT IS NO ONES.
80F5-18 I 187 ( 2) CLC
80F6-60 I 188 ( 6) RTS
80F7-A9 00 I 189 ( 2) STRTSH LDA #0 ; CLEAR A SO PATTERN WILL SHOW
80F9-38 I 190 ( 2) SHIFT SEC ; MAKE A BIT HIGH
80FA-2A I 191 ( 2) ROL A ; SHIFT IT TO CORRECT POSITION
80FB-88 I 192 ( 2) DEY ; BY LOOPING TO # OF GUESS/DIGIT
80FC- I 193 ; MATCHES, AS PASSED IN Y
80FC-D0 FB I 194 (2**) BNE SHIFT ; LOOP UNTIL DONE
80FE-60 I 195 ( 6) RTS
80FF- I 196 ;
80FF- I 197 ; RANDOM NUMBER GENERATOR
80FF- I 198 ; USES NUMBERS A,B,C,D,E,F STORED AS RND THROUGH RND+5: ADDS B+E+F+1 AND
80FF- I 199 ; PLACES RESULT IN A, THEN SHIFTS A TO B, B TO C, ETC. THE NEW RANDOM NUMBER
80FF- I 200 ; WHICH IS BETWEEN 0 AND 255 INCLUSIVE IS IN THE ACCUMULATOR ON EXIT.
80FF- I 201 ;
80FF-38 I 202 ( 2) RANDOM SEC ; CARRY ADDS VALUE 1
8100-A5 0A I 203 ( 3) LDA RND+1 ; ADD A,B,E AND CARRY
8102-65 0D I 204 ( 3) ADC RND+4
8104-65 0E I 205 ( 3) ADC RND+5
8106-85 09 I 206 ( 3) STA RND
8108-A2 04 I 207 ( 2) LDX #4 ; SHIFT NUMBERS OVER
810A-B5 09 I 208 ( 4) RPL LDA RND,X
810C-95 0A I 209 ( 4) STA RND+1,X
810E-CA I 210 ( 2) DEX
810F-10 F9 I 211 (2**) BPL RPL
8111-60 I 212 ( 6) RTS
8112- I 213 ;
8112- I 214 ; TONE GENERATOR ROUTINE
8112- I 215 ; DURATION OF TONE (NUMBER OF CYCLES TO CREATE) SHOULD BE IN 'DUR' ON ENTRY,
8112- I 216 ; AND THE NOTE VALUE (FREQUENCY) IN THE ACCUMULATOR.
8112- I 217 ;
8112-85 07 I 218 ( 3) TONE STA FREQ
8114-A9 FF I 219 ( 2) LDA #$FF
8116-8D 00 4C I 220 ( 4) STA PORT3B
8119-A9 00 I 221 ( 2) LDA #$00
811B-A6 01 I 222 ( 3) LDX DUR
811D-A4 07 I 223 ( 3) FL2 LDY FREQ
811F-88 I 224 ( 2) FL1 DEY
8120-18 I 225 ( 2) CLC
8121-90 00 I 226 (2**) BCC FL0
8123-D0 FA I 227 (2**) FL0 BNE FL1
8125-49 FF I 228 ( 2) EOR #$FF
8127-8D 00 4C I 229 ( 4) STA PORT3B
812A-CA I 230 ( 2) DEX
812B-D0 F0 I 231 (2**) BNE FL2
812D-60 I 232 ( 6) RTS
812E- 17 .IN ../../common/CH01-Getkey/getkey_routine.asm
812E- I 1 ; 'GETKEY' KEYBOARD INPUT ROUTINE READS AND DEBOUNCES KEYBOARD. RETURNS WITH
812E- I 2 ; KEY NUMBER IN ACCUMULATOR IF KEY DOWN. OPERATION: SENDS NUMBERS 0-F TO 74154
812E- I 3 ; (4 TO 16 LINE DECODER), WHICH GROUNDS ONE SIDE OF KEYSWITCHES ONE AT A TIME.
812E- I 4 ; IF A KEY IS DOWN, PA7 OF VIA #3 WILL BE GROUNDED, AND THE CURRENT VALUE
812E- I 5 ; APPLIED TO THE 74154 BE THE KEY NUMBER. WHEN THE PROGRAM DETECTS A KEY CLOSE
812E- I 6 ; CHECKS FOR KEY CLOSURE FOR 50 MS. TO ELIMINATE BOUNCE.
812E- I 7 ; NOTE: IF NO KEY IS PRESSED, GETKEY WILL WAIT.
812E- I 8 ;
812E-2C 01 4C I 9 ( 4) GETKEY BIT PORT3A ; SEE IF KEY IS STILL DOWN FROM LAST KEY CLOSURE:
8131- I 10 ; KEYSTROBE IN 'N' STATUS BIT.
8131-10 FB I 11 (2**) BPL GETKEY ; IF YES, WAIT FOR KEY RELEASE
8133-A2 0F I 12 ( 2) RSTART LDX #15 ; SET KEY COUNTER TO 15
8135-8E 00 4C I 13 ( 4) NXTKEY STX PORT3B ; OUTPUT KEY # TO 74154
8138-2C 01 4C I 14 ( 4) BIT PORT3A ; SEE IF KEY DOWN: STROBE IN 'N'
813B-10 05 I 15 (2**) BPL BOUNCE ; IF YES, GO DEBOUNCE
813D-CA I 16 ( 2) DEX ; DECREMENT KEY #
813E-10 F5 I 17 (2**) BPL NXTKEY ; NO, DO NEXT KEY
8140-30 F1 I 18 (2**) BMI RSTART ; START OVER
8142-8A I 19 ( 2) BOUNCE TXA ; SAVE KEY NUMBER IN A
8143-A0 12 I 20 ( 2) LDY #$12 ; OUTER LOOP CNT LOAD FOR DELAY OF 50 MS.
8145-A2 FF I 21 ( 2) LP1 LDX #$FF ; INNER 11 US. LOOP
8147-2C 01 4C I 22 ( 4) LP2 BIT PORT3A ; SEE IF KEY STILL DOWN
814A-30 E7 I 23 (2**) BMI RSTART ; IF NOT, KEY NOT VALID, RESTART
814C-CA I 24 ( 2) DEX
814D-D0 F8 I 25 (2**) BNE LP2 ; THIS LOOP USES 2115*5 US.
814F-88 I 26 ( 2) DEY
8150-D0 F3 I 27 (2**) BNE LP1 ; OUTER LOOP: TOTAL IS 50 MS.
8152-60 I 28 ( 6) RTS ; DONE: KEY IN A.
8153- I 29 ;
8153- I 30 ; SUBROUTINE 'INITKEY'
8153- I 31 ; TAKES CARE OF INITIALIZING VIA #3 FOR USING WITH THE GETKEY ROUTINE FROM
8153- I 32 ; THE CODE.
8153- I 33 ;
8153-A9 00 I 34 ( 2) INITKEY LDA #0
8155-8D 03 4C I 35 ( 4) STA DDR3A ; SET KEY STROBE PORT FOR INPUT
8158-A9 FF I 36 ( 2) LDA #$FF
815A-8D 02 4C I 37 ( 4) STA DDR3B ; SET KEYS FOR OUTPUT
815D-60 I 38 ( 6) RTS
815E- 18 .IN ../../common/CH09-MindBender/interrupt.asm
815E- I 1 ;
815E- I 2 ; INTERRUPT-HANDLING ROUTINE
815E- I 3 ; COMPLEMENTS LEDS AT EACH INTERRUPT.
815E- I 4 ;
815E-48 I 5 ( 3) DOINT PHA ; SAVE ACCUMULATOR
815F-AD 01 40 I 6 ( 4) LDA PORT1A ; GET PORT FOR COMPLEMENTING
8162-45 05 I 7 ( 3) EOR MASKA ; COMPLEMENT NECESSARY BITS
8164-8D 01 40 I 8 ( 4) STA PORT1A ; STORE COMPLEMENTED CONTENTS
8167-AD 00 40 I 9 ( 4) LDA PORT1B ; DO SAME WITH PORT1B
816A-45 06 I 10 ( 3) EOR MASKB
816C-8D 00 40 I 11 ( 4) STA PORT1B
816F-AD 04 40 I 12 ( 4) LDA T1LL ; CLEAR INTERRUPT BIT IN VIA
8172-68 I 13 ( 4) PLA ; RESTORE ACCUMULATOR
8173-40 I 14 ( 6) RTI ; DONE, RESUME PROGRAM
8174- 19 ;
8174- 20 ; STORE CPU INITIALIZATION VECTORS AT THE END OF THE EEPROM.
8174- 21 ;
FFFA 22 .NO $FFFA,$FF
FFFA-00 80 23 .DA BE6502 ; NMI VECTOR
FFFC-5E 81 24 .DA DOINT ; RESET VECTOR
FFFE-00 80 25 .DA BE6502 ; IRQ VECTOR

View File

@ -0,0 +1,4 @@
@echo off
sbasm.py slot_machine.asm
type slot_machine.list
pause

View File

@ -0,0 +1,17 @@
.CR 6502
.TF slot_machine.hex,INT
.LF slot_machine.list
;
; SLOT MACHINE GAME FOR THE '6502 GAMES' HARDWARE, BOARD SHOULD BE JUMPERED
; WITH VIA CHIPS AT THE ADDRESSES SPECIFIED BELOW. OTHER THAN THAT THE CODE
; IS SHOULD BE UNCHANGED FROM THE BOOK THOUGH THERE WILL BE SOME DIFFERENCES
; DUE TO ASSEMBLER USED.
;
VIA1 .EQ $C000
VIA3 .EQ $CC00
.OR $0200
.TA $0200
BEGIN JSR INITKEY
.IN ../../common/CH07-SlotMachine/game.asm
.IN ../../common/CH01-Getkey/getkey_routine.asm

View File

@ -0,0 +1,31 @@
:1002000020D003A9FF8D03C08D02C08D02CCAD04A8
:10021000C08515A9088502A820400320AB03202A29
:100220000220AA02A502D0F3F0E9A900850B850CF3
:10023000850DA002208303C987B0F9C95A90F599AA
:1002400008009905008810ECA202B405F044D60815
:10025000D040B40BC8C003D002A000940B86008A23
:100260000A186500750BA8B99603950EB405C894D5
:10027000059408A9008D00C0A510D007A9018D0024
:10028000C0A900050E050F8D01C0AD00CC49FF8D42
:1002900000CCCA10B5A05088D0FDA50505060507FD
:1002A000D0A6A9FF850320330360A900851185121C
:1002B00085138501A002B60BF6118810F9A2028AF7
:1002C0000A0A187511A8B99F031865018501CA109B
:1002D000EEA9608503A501F034E602A402C010F087
:1002E00010204003A920206703203303C601D0E972
:1002F00060A9FF8D01C08D00C08500A9008502A9FD
:10030000048503A500206703C600D0F760C602A4D9
:1003100002204003A9F0206703A402F00160A900B5
:1003200085008D01C0A9048503A500206703E600B0
:10033000D0F760A403A2FFD000CAD0FB88D0F6603B
:10034000A90085008D01C08D00C0C00FF001883864
:100350002A9005A2FF86002A8810F5A600D0048DF9
:1003600001C0608D00C0608504A9FF8D00CCA9008C
:10037000A603A40488189000D0FA49FF8D00CCCAC7
:10038000D0F06038A515651865198514A204B51458
:100390009515CA10F9600108400210800420000081
:1003A00000000000000103000000002C01CC10FB45
:1003B000A20F8E00CC2C01CC1005CA10F530F18AAA
:1003C000A012A2FF2C01CC30E7CAD0F888D0F3608D
:0B03D000A9008D03CCA9FF8D02CC60BA
:00000001FF

View File

@ -0,0 +1,361 @@
0000- 4 ;
0000- 5 ; SLOT MACHINE GAME FOR THE '6502 GAMES' HARDWARE, BOARD SHOULD BE JUMPERED
0000- 6 ; WITH VIA CHIPS AT THE ADDRESSES SPECIFIED BELOW. OTHER THAN THAT THE CODE
0000- 7 ; IS SHOULD BE UNCHANGED FROM THE BOOK THOUGH THERE WILL BE SOME DIFFERENCES
0000- 8 ; DUE TO ASSEMBLER USED.
0000- 9 ;
C000- 10 VIA1 .EQ $C000
CC00- 11 VIA3 .EQ $CC00
0000- 12
0200- 13 .OR $0200
0200- 14 .TA $0200
0200-20 D0 03 15 ( 6) BEGIN JSR INITKEY
0203- 16 .IN ../../common/CH07-SlotMachine/game.asm
0203- I 1 ; 'SLOT MACHINE'
0203- I 2 ; SLOT MACHINE SIMULATOR PROGRAM, PRESS ANY KEY TO START 'SPIN'. SCORE
0203- I 3 ; DETERMINED BY ARRAY 'SCORTB'. 8 POINTS INITIAL SCORE, ONE POINT PENALTY
0203- I 4 ; FOR EACH BAD SPIN.
0203- I 5
0203- I 6 ;
0203- I 7 ; I/O:
0203- I 8 ;
C000- I 9 PORT1B .EQ VIA1 ; PORT B
C001- I 10 PORT1A .EQ VIA1+1 ; PORT A
C002- I 11 DDR1B .EQ VIA1+2 ; PORT B DATA DIRECTION REGISTER
C003- I 12 DDR1A .EQ VIA1+3 ; PORT A DATA DIRECTION REGISTER
C004- I 13 T1CL .EQ VIA1+4
0203- I 14
CC00- I 15 PORT3B .EQ VIA3 ; PORT B
CC01- I 16 PORT3A .EQ VIA3+1 ; PORT A
CC02- I 17 DDR3B .EQ VIA3+2 ; PORT B DATA DIRECTION REGISTER
CC03- I 18 DDR3A .EQ VIA3+3 ; PORT A DATA DIRECTION REGISTER
0203- I 19
0203- I 20 ;
0203- I 21 ; VARIABLE STORAGE.
0203- I 22 ;
0000- I 23 ZP .EQ $00
0000- I 24 TEMP .EQ ZP ; TEMPORARY STORAGE.
0001- I 25 SCORTP .EQ ZP+1 ; TEMPORARY SCORE STORAGE
0002- I 26 SCORE .EQ ZP+2 ; SCORE.
0003- I 27 DUR .EQ ZP+3 ; DURATION OF TONES.
0004- I 28 FREQ .EQ ZP+4
0005- I 29 SPEEDS .EQ ZP+5 ; SPEEDS OF REVOLUTION FOR LEDS IN COLUMNS
0008- I 30 INDX .EQ ZP+8 ; DELAY COUNTERS FOR LED REVOLUTIONS.
000B- I 31 INCR .EQ ZP+11 ; POINTERS FOR LED POSITIONS:
0203- I 32 ; USED TO FETCH PATTERNS OUT OF TABLES.
000E- I 33 LTMSK .EQ ZP+14 ; PATTERNS FOR LIT LEDS
0011- I 34 VALUES .EQ ZP+17 ; NUMBER OF LIT LEDS IN EACH ROW.
0014- I 35 RND .EQ ZP+20 ; SCRATCHPAD FOR RND # GENERATOR.
0203- I 36
0203- I 37 ;
0203- I 38 ; MAIN PROGRAM
0203- I 39 ;
0203-A9 FF I 40 ( 2) LDA #$FF ; SET UP PORTS.
0205-8D 03 C0 I 41 ( 4) STA DDR1A
0208-8D 02 C0 I 42 ( 4) STA DDR1B
020B-8D 02 CC I 43 ( 4) STA DDR3B
020E-AD 04 C0 I 44 ( 4) LDA T1CL ; GET SEED FOR RANDOM # GENERATOR.
0211-85 15 I 45 ( 2) STA RND+1
0213-A9 08 I 46 ( 2) START LDA #8 ; INITIAL SCORE IS EIGHT.
0215-85 02 I 47 ( 2) STA SCORE
0217-A8 I 48 ( 2) TAY ; SHOW INITIAL SCORE
0218-20 40 03 I 49 ( 6) JSR LIGHT
021B-20 AB 03 I 50 ( 6) KEY JSR GETKEY ; ANY KEY PRESSED STARTS PROGRAM.
021E-20 2A 02 I 51 ( 6) JSR DISPLY ; SPIN WHEELS
0221-20 AA 02 I 52 ( 6) JSR EVAL ; CHECK SCORE AND SHOW IT
0224-A5 02 I 53 ( 3) LDA SCORE
0226-D0 F3 I 54 (2**) BNE KEY ; IF SCORE <> 0, GET NEXT PLAY.
0228-F0 E9 I 55 (2**) BEQ START ; IF SCORE = 0; RESTART.
022A- I 56
022A- I 57 ;
022A- I 58 ; SUBROUTINE 'DISPLY'
022A- I 59 ; SUBROUTINE TO DISPLAY 'SPINNING' LEDS, FIND COMBINATION USED TO
022A- I 60 ; DETERMINE SCORE.
022A- I 61 ;
005A- I 62 LOLIM = 90
0087- I 63 HILIM = 135
0050- I 64 SPDPRM = 80
022A-A9 00 I 65 ( 2) DISPLY LDA #0 ; RESET POINTERS.
022C-85 0B I 66 ( 2) STA INCR
022E-85 0C I 67 ( 2) STA INCR+1
0230-85 0D I 68 ( 2) STA INCR+2
0232-A0 02 I 69 ( 2) LDRND LDY #2 ; SET INDEX FOR 3 ITERATIONS.
0234-20 83 03 I 70 ( 6) GETRND JSR RANDOM ; GET RANDOM #.
0237-C9 87 I 71 ( 2) CMP #HILIM ; TOO LARGE?
0239-B0 F9 I 72 (2**) BCS GETRND ; IF SO, GET ANOTHER.
023B-C9 5A I 73 ( 2) CMP #LOLIM ; TOO SMALL?
023D-90 F5 I 74 (2**) BCC GETRND ; IF SO, GET ANOTHER.
023F-99 08 00 I 75 ( 5) STA INDX,Y ; SAVE IN LOOP INDEXES AND
0242-99 05 00 I 76 ( 5) STA SPEEDS,Y ; LOOP SPEED COUNTERS.
0245-88 I 77 ( 2) DEY
0246-10 EC I 78 (2**) BPL GETRND ; GET NEXT RND #.
0248-A2 02 I 79 ( 2) UPDATE LDX #2 ; SET INDEX FOR THREE ITERATIONS.
024A-B4 05 I 80 ( 4) UPDTLP LDY SPEEDS,X ; IS SPEED(X) = 0?
024C-F0 44 I 81 (2**) BEQ NXTUPD ; IF SO, DO NEXT UPDATE.
024E-D6 08 I 82 ( 6) DEC INDX,X ; DECREMENT LOOP INDEX(X)
0250-D0 40 I 83 (2**) BNE NXTUPD ; IF LOOPINDEX(X) <> 0, DO NEXT UPDATE.
0252-B4 0B I 84 ( 4) LDY INCR,X ; INCREMENT POINTER(X).
0254-C8 I 85 ( 2) INY
0255-C0 03 I 86 ( 2) CPY #3 ; POINTER = 3?
0257-D0 02 I 87 (2**) BNE NORST ; IF NOT SKIP...
0259-A0 00 I 88 ( 2) LDY #0 ; ... RESET OF POINTER TO 0.
025B-94 0B I 89 ( 4) NORST STY INCR,X ; RESTORE POINTER(X).
025D-86 00 I 90 ( 3) STX TEMP ; MULTIPLY X BY 3 FOR ARRAY ACCESS.
025F-8A I 91 ( 2) TXA
0260-0A I 92 ( 2) ASL A
0261-18 I 93 ( 2) CLC
0262-65 00 I 94 ( 3) ADC TEMP
0264-75 0B I 95 ( 4) ADC INCR,X ; ADD COLUMN # TO PTR(X) FOR ROW#.
0266-A8 I 96 ( 2) TAY ; TRANSFER TO Y FOR INDEXING.
0267-B9 96 03 I 97 ( 4*) LDA LTABLE,Y ; GET PATTERN FOR LED.
026A-95 0E I 98 ( 4) STA LTMSK,X ; STORE IN LIGHT MASK(X).
026C-B4 05 I 99 ( 4) SPDUPD LDY SPEEDS,X ; INCREMENT SPEED (X).
026E-C8 I 100 ( 2) INY
026F-94 05 I 101 ( 4) STY SPEEDS,X ; RESTORE.
0271-94 08 I 102 ( 4) STY INDX,X ; RESET LOOP INDEX(X).
0273-A9 00 I 103 ( 2) LEDUPD LDA #0 ; UPDATE LIGHTS.
0275-8D 00 C0 I 104 ( 4) STA PORT1B ; RESET LED #9
0278-A5 10 I 105 ( 3) LDA LTMSK+2 ; COMBINE PATTERN FOR OUTPUT.
027A-D0 07 I 106 (2**) BNE OFFLD9 ; IF MASK#3 <> 0, LED 9 OFF.
027C-A9 01 I 107 ( 2) LDA #01 ; TURN ON LED 9.
027E-8D 00 C0 I 108 ( 4) STA PORT1B
0281-A9 00 I 109 ( 2) LDA #0 ; RESET A SO PATTERN WON'T BE BAD.
0283-05 0E I 110 ( 3) OFFLD9 ORA LTMSK ; COMBINE REST OF PATTERNS.
0285-05 0F I 111 ( 3) ORA LTMSK+1
0287-8D 01 C0 I 112 ( 4) STA PORT1A ; SET LIGHTS.
028A-AD 00 CC I 113 ( 4) LDA PORT3B ; TOGGLE SPEAKER.
028D-49 FF I 114 ( 2) EOR #$FF
028F-8D 00 CC I 115 ( 4) STA PORT3B
0292-CA I 116 ( 2) NXTUPD DEX ; DECREMENT X FOR NEXT UPDATE.
0293-10 B5 I 117 (2**) BPL UPDTLP ; IF X >= 0, DO NEXT UPDATE.
0295-A0 50 I 118 ( 2) LDY #SPDPRM ; DELAY A BIT TO SLOW
0297-88 I 119 ( 2) WAIT DEY ; FLASHING OF LEDS.
0298-D0 FD I 120 (2**) BNE WAIT
029A-A5 05 I 121 ( 3) LDA SPEEDS ; CHECK IF ALL COLUMNS OF LEDS STOPPED.
029C-05 06 I 122 ( 3) ORA SPEEDS+1
029E-05 07 I 123 ( 3) ORA SPEEDS+2
02A0-D0 A6 I 124 (2**) BNE UPDATE ; IF NOT, DO NEXT SEQUENCE OF UPDATES.
02A2-A9 FF I 125 ( 2) LDA #$FF
02A4-85 03 I 126 ( 2) STA DUR ; DELAY TO SHOW USER PATTERN.
02A6-20 33 03 I 127 ( 6) JSR DELAY
02A9-60 I 128 ( 6) RTS ; ALL LEDS STOPPED, DONE.
02AA- I 129
02AA- I 130 ;
02AA- I 131 ; SUBROUTINE 'EVAL'
02AA- I 132 ; SUBROUTINE TO EVALUATE PRODUCT OF SPIN, AND DISPLAY SCORE WITH TONES FOR
02AA- I 133 ; WIN, LOSE, WIN+ENDGAME AND LOST+ENDGAME.
02AA- I 134 ;
0020- I 135 HITONE = $20
00F0- I 136 LOTONE = $F0
02AA-A9 00 I 137 ( 2) EVAL LDA #0 ; RESET VARIABLES.
02AC-85 11 I 138 ( 2) STA VALUES
02AE-85 12 I 139 ( 2) STA VALUES+1
02B0-85 13 I 140 ( 2) STA VALUES+2
02B2-85 01 I 141 ( 2) STA SCORTP
02B4-A0 02 I 142 ( 2) LDY #2 ; SET INDEX Y FOR 3 ITERATIONS TO COUNT # OF
02B6- I 143 ; LEDS ON IN EACH ROW.
02B6-B6 0B I 144 ( 4) CNTLP LDX INCR,Y ; CHECK POINTER(Y), ADDING
02B8-F6 11 I 145 ( 6) INC VALUES,X ; UP # OF LEDS ON IN EACH ROW.
02BA-88 I 146 ( 2) DEY
02BB-10 F9 I 147 (2**) BPL CNTLP ; LOOP IF NOT DONE.
02BD-A2 02 I 148 ( 2) LDX #2 ; SET INDEX X FOR 3 ITERATIONS
02BF- I 149 ; OF LOOP TO FIND SCORE.
02BF-8A I 150 ( 2) SCORLP TXA ; MULTIPLY INDEX BY FOUR FOR ARRAY ROW ACCESS.
02C0-0A I 151 ( 2) ASL A
02C1-0A I 152 ( 2) ASL A
02C2-18 I 153 ( 2) CLC ; ADD # OF LEDS ON IN ROW(X) TO...
02C3-75 11 I 154 ( 4) ADC VALUES,X ; ... ARRIVE AT COLUMN ADDRESS IN ARRAY.
02C5-A8 I 155 ( 2) TAY ; USE AS INDEX
02C6-B9 9F 03 I 156 ( 4*) LDA SCORTB,Y ; GET SCORE FOR THIS SPIN.
02C9-18 I 157 ( 2) CLC
02CA-65 01 I 158 ( 3) ADC SCORTP ; ADD TO ANY PREVIOUS SCORES
02CC- I 159 ; ACCUMULATED IN THIS LOOP.
02CC-85 01 I 160 ( 2) STA SCORTP ; RESTORE
02CE-CA I 161 ( 2) DEX
02CF-10 EE I 162 (2**) BPL SCORLP ; LOOP IF NOT DONE
02D1-A9 60 I 163 ( 2) LDA #$60 ; SET UP DURATIONS FOR TONES.
02D3-85 03 I 164 ( 2) STA DUR
02D5-A5 01 I 165 ( 3) LDA SCORTP ; GET SCORE FOR THIS SPIN.
02D7-F0 34 I 166 (2**) BEQ LOSE ; IF SCORE IS 0, LOSE A POINT.
02D9-E6 02 I 167 ( 5) WIN INC SCORE ; RAISE OVERALL SCORE BY ONE.
02DB-A4 02 I 168 ( 3) LDY SCORE ; GET SCORE
02DD-C0 10 I 169 ( 2) CPY #16 ; WIN WITH 16 POINTS?
02DF-F0 10 I 170 (2**) BEQ WINEND ; YES; WIN+ENDGAME.
02E1-20 40 03 I 171 ( 6) JSR LIGHT ; SHOW SCORE
02E4-A9 20 I 172 ( 2) LDA #HITONE ; PLAY HIGH BEEP.
02E6-20 67 03 I 173 ( 6) JSR TONE
02E9-20 33 03 I 174 ( 6) JSR DELAY ; SHORT DELAY.
02EC-C6 01 I 175 ( 5) DEC SCORTP ; DECREMENT SCORE TO BE ADDED TO...
02EE- I 176 ; OVERALL SCORE BY ONE.
02EE-D0 E9 I 177 (2**) BNE WIN ; LOOP IF SCORE TRANSFER NOT COMPLETE.
02F0-60 I 178 ( 6) RTS ; DONE, RETURN TO MAIN PROGRAM.
02F1-A9 FF I 179 ( 2) WINEND LDA #$FF ; TURN ALL LEDS ON TO SIGNAL WIN.
02F3-8D 01 C0 I 180 ( 4) STA PORT1A
02F6-8D 00 C0 I 181 ( 4) STA PORT1B
02F9-85 00 I 182 ( 2) STA TEMP ; SET FREQ PARAMETER FOR RISING WARBLE.
02FB-A9 00 I 183 ( 2) LDA #0
02FD-85 02 I 184 ( 2) STA SCORE ; CLEAR TO FLAG RESTART.
02FF-A9 04 I 185 ( 2) LDA #4
0301-85 03 I 186 ( 2) STA DUR ; SHORT DURATION FOR INDIVIDUAL BEEPS IN WARBLE.
0303-A5 00 I 187 ( 3) RISE LDA TEMP ; GET FREQUENCY...
0305-20 67 03 I 188 ( 6) JSR TONE ; ... FOR BEEP.
0308-C6 00 I 189 ( 5) DEC TEMP ; NEXT BEEP WILL BE HIGHER.
030A-D0 F7 I 190 (2**) BNE RISE ; DO NEXT BEEP IF NOT DONE.
030C-60 I 191 ( 6) RTS ; RETURN FOR RESTART.
030D-C6 02 I 192 ( 5) LOSE DEC SCORE ; IF SPIN BAD, SCORE=SCORE-1
030F-A4 02 I 193 ( 3) LDY SCORE ; SHOW SCORE
0311-20 40 03 I 194 ( 6) JSR LIGHT
0314-A9 F0 I 195 ( 2) LDA #LOTONE ; PLAY LOW LOSE TONE.
0316-20 67 03 I 196 ( 6) JSR TONE
0319-A4 02 I 197 ( 3) LDY SCORE ; GET SCORE TO SEE...
031B-F0 01 I 198 (2**) BEQ LOSEND ; ... IF GAME IS OVER.
031D-60 I 199 ( 6) RTS ; IF NOT, RETURN FOR NEXT SPIN.
031E-A9 00 I 200 ( 2) LOSEND LDA #0 ; SET TEMP FOR USE AS FREQUENCY PARAMETER
0320-85 00 I 201 ( 2) STA TEMP ; IN FALLING WARBLE.
0322-8D 01 C0 I 202 ( 4) STA PORT1A ; CLEAR LED #1.
0325-A9 04 I 203 ( 2) LDA #4
0327-85 03 I 204 ( 2) STA DUR
0329-A5 00 I 205 ( 3) FALL LDA TEMP
032B-20 67 03 I 206 ( 6) JSR TONE ; PLAY BEEP.
032E-E6 00 I 207 ( 5) INC TEMP ; NEXT TONE WILL BE LOWER.
0330-D0 F7 I 208 (2**) BNE FALL
0332-60 I 209 ( 6) RTS ; RETURN FOR RESTART.
0333- I 210
0333- I 211 ;
0333- I 212 ; SUBROUTINE 'DELAY'
0333- I 213 ; VARIABLE LENGHT DELAY SUBROUTINE
0333- I 214 ; DELAY LENGTH = (2046*[DUR]+10) US.
0333- I 215 ;
0333-A4 03 I 216 ( 3) DELAY LDY DUR ; GET DELAY LENGHT.
0335-A2 FF I 217 ( 2) DL1 LDX #$FF ; SET COUNTER FOR INNER 2040 US. LOOP TO
0337-D0 00 I 218 (2**) DL2 BNE DL3 ; WASTE TIME.
0339-CA I 219 ( 2) DL3 DEX ; DECREMENT INNER LOOP COUNTER.
033A-D0 FB I 220 (2**) BNE DL2 ; LOOP UNTIL INNER LOOP DONE.
033C-88 I 221 ( 2) DEY ; DECREMENT OUTER LOOP COUNTER.
033D-D0 F6 I 222 (2**) BNE DL1 ; LOOP UNTIL DONE.
033F-60 I 223 ( 6) RTS ; RETURN.
0340- I 224
0340- I 225 ;
0340- I 226 ; SUBROUTINE 'LIGHT'
0340- I 227 ; SUBROUTINE TO LIGHT LEDS CORRESPONDING TO THE CONTENTS OF REGISTER Y ON
0340- I 228 ; ENTERING.
0340- I 229 ;
0340-A9 00 I 230 ( 2) LIGHT LDA #0 ; CLEAR ACCUMULATOR FOR BIT SHIFT.
0342-85 00 I 231 ( 2) STA TEMP ; CLEAR OVERFLOW FLAG
0344-8D 01 C0 I 232 ( 4) STA PORT1A ; CLEAR LOW LEDS
0347-8D 00 C0 I 233 ( 4) STA PORT1B ; CLEAR HIGH LEDS.
034A-C0 0F I 234 ( 2) CPY #15 ; CODE FOR UNCONNECTED BIT?
034C-F0 01 I 235 (2**) BEQ LIGHT0 ; IF SO, NO CHANGE.
034E-88 I 236 ( 2) DEY ; DECREMENT TO MATCH.
034F-38 I 237 ( 2) LIGHT0 SEC ; SET BIT TO BE SHIFTED HIGH.
0350-2A I 238 ( 2) LTSHFT ROL A ; SHIFT BIT LEFT.
0351-90 05 I 239 (2**) BCC LTCC ; IF CARRY SET, OVERFLOW HAS OCCURRED
0353- I 240 ; INTO HIGH BYTE.
0353-A2 FF I 241 ( 2) LDX #$FF ; SET OVERFLOW FLAG.
0355-86 00 I 242 ( 3) STX TEMP
0357-2A I 243 ( 2) ROL ; MOVE BIT OUT OF CARRY.
0358-88 I 244 ( 2) LTCC DEY ; ONE LESS BIT TO BE SHIFTED.
0359-10 F5 I 245 (2**) BPL LTSHFT ; SHIFT AGAIN IF NOT DONE.
035B-A6 00 I 246 ( 3) LDX TEMP ; GET OVERFLOW FLAG.
035D-D0 04 I 247 (2**) BNE HIBYTE ; IF FLAG <> 0, OVERFLOW: A CONTAINS HIGH BYTE.
035F-8D 01 C0 I 248 ( 4) LOBYTE STA PORT1A ; STORE A IN LOW ORDER LEDS.
0362-60 I 249 ( 6) RTS ; RETURN.
0363-8D 00 C0 I 250 ( 4) HIBYTE STA PORT1B ; STORE A IN HIGH ORDER LEDS.
0366-60 I 251 ( 6) RTS ; RETURN.
0367- I 252
0367- I 253 ;
0367- I 254 ; SUBROUTINE 'TONE'
0367- I 255 ; TONE GENERATION SUBROUTINE.
0367- I 256 ;
0367-85 04 I 257 ( 2) TONE STA FREQ
0369-A9 FF I 258 ( 2) LDA #$FF
036B-8D 00 CC I 259 ( 4) STA PORT3B
036E-A9 00 I 260 ( 2) LDA #0
0370-A6 03 I 261 ( 3) LDX DUR
0372-A4 04 I 262 ( 3) FL2 LDY FREQ
0374-88 I 263 ( 2) FL1 DEY
0375-18 I 264 ( 2) CLC
0376-90 00 I 265 (2**) BCC FL0
0378-D0 FA I 266 (2**) FL0 BNE FL1
037A-49 FF I 267 ( 2) EOR #$FF
037C-8D 00 CC I 268 ( 4) STA PORT3B
037F-CA I 269 ( 2) DEX
0380-D0 F0 I 270 (2**) BNE FL2
0382-60 I 271 ( 6) RTS
0383- I 272
0383- I 273 ;
0383- I 274 ; SUBROUTINE 'RANDOM'
0383- I 275 ; RANDOM NUMBER GENERATOR SUBROUTINE.
0383- I 276 ;
0383-38 I 277 ( 2) RANDOM SEC
0384-A5 15 I 278 ( 3) LDA RND+1
0386-65 18 I 279 ( 3) ADC RND+4
0388-65 19 I 280 ( 3) ADC RND+5
038A-85 14 I 281 ( 2) STA RND
038C-A2 04 I 282 ( 2) LDX #4
038E-B5 14 I 283 ( 4) RNDSH LDA RND,X
0390-95 15 I 284 ( 4) STA RND+1,X
0392-CA I 285 ( 2) DEX
0393-10 F9 I 286 (2**) BPL RNDSH
0395-60 I 287 ( 6) RTS
0396- I 288
0396- I 289 ;
0396- I 290 ; ARRAYS
0396- I 291 ;
0396- I 292
0396- I 293 ;
0396- I 294 ; ARRAY OF PATTERNS TO LIGHT LEDS, ARRAY ROWS CORRESPOND TO COLUMNS OF LED
0396- I 295 ; ARRAY, AND COLUMNS TO ROWS, FOR EXAMPLE, THIRD BYTE IN ROW ONE WILL LIGHT
0396- I 296 ; LED 7.
0396- I 297 ;
0396-01 08 40 02
10 80 04 20
00 I 298 LTABLE .HS 01.08.40.02.10.80.04.20.00
039F- I 299
039F- I 300 ;
039F- I 301 ; ARRAY OF SCORES RECEIVED FOR CERTAIN PATTERS OF LIT LEDS; ROWS CORRESPOND TO
039F- I 302 ; ROWS IN LED ARRAY. COLUMNS CORRESPOND TO NUMBER OF LEDS LIT IN THAT ROW.
039F- I 303 ; I.E. 3 LEDS IN MIDDLE ROW IS 3 PTS.
039F- I 304 ;
039F-00 00 00 00
00 00 01 03
00 00 00 00 I 305 SCORTB .HS 00.00.00.00.00.00.01.03.00.00.00.00
03AB- 17 .IN ../../common/CH01-Getkey/getkey_routine.asm
03AB- I 1 ; 'GETKEY' KEYBOARD INPUT ROUTINE READS AND DEBOUNCES KEYBOARD. RETURNS WITH
03AB- I 2 ; KEY NUMBER IN ACCUMULATOR IF KEY DOWN. OPERATION: SENDS NUMBERS 0-F TO 74154
03AB- I 3 ; (4 TO 16 LINE DECODER), WHICH GROUNDS ONE SIDE OF KEYSWITCHES ONE AT A TIME.
03AB- I 4 ; IF A KEY IS DOWN, PA7 OF VIA #3 WILL BE GROUNDED, AND THE CURRENT VALUE
03AB- I 5 ; APPLIED TO THE 74154 BE THE KEY NUMBER. WHEN THE PROGRAM DETECTS A KEY CLOSE
03AB- I 6 ; CHECKS FOR KEY CLOSURE FOR 50 MS. TO ELIMINATE BOUNCE.
03AB- I 7 ; NOTE: IF NO KEY IS PRESSED, GETKEY WILL WAIT.
03AB- I 8 ;
03AB-2C 01 CC I 9 ( 4) GETKEY BIT PORT3A ; SEE IF KEY IS STILL DOWN FROM LAST KEY CLOSURE:
03AE- I 10 ; KEYSTROBE IN 'N' STATUS BIT.
03AE-10 FB I 11 (2**) BPL GETKEY ; IF YES, WAIT FOR KEY RELEASE
03B0-A2 0F I 12 ( 2) RSTART LDX #15 ; SET KEY COUNTER TO 15
03B2-8E 00 CC I 13 ( 4) NXTKEY STX PORT3B ; OUTPUT KEY # TO 74154
03B5-2C 01 CC I 14 ( 4) BIT PORT3A ; SEE IF KEY DOWN: STROBE IN 'N'
03B8-10 05 I 15 (2**) BPL BOUNCE ; IF YES, GO DEBOUNCE
03BA-CA I 16 ( 2) DEX ; DECREMENT KEY #
03BB-10 F5 I 17 (2**) BPL NXTKEY ; NO, DO NEXT KEY
03BD-30 F1 I 18 (2**) BMI RSTART ; START OVER
03BF-8A I 19 ( 2) BOUNCE TXA ; SAVE KEY NUMBER IN A
03C0-A0 12 I 20 ( 2) LDY #$12 ; OUTER LOOP CNT LOAD FOR DELAY OF 50 MS.
03C2-A2 FF I 21 ( 2) LP1 LDX #$FF ; INNER 11 US. LOOP
03C4-2C 01 CC I 22 ( 4) LP2 BIT PORT3A ; SEE IF KEY STILL DOWN
03C7-30 E7 I 23 (2**) BMI RSTART ; IF NOT, KEY NOT VALID, RESTART
03C9-CA I 24 ( 2) DEX
03CA-D0 F8 I 25 (2**) BNE LP2 ; THIS LOOP USES 2115*5 US.
03CC-88 I 26 ( 2) DEY
03CD-D0 F3 I 27 (2**) BNE LP1 ; OUTER LOOP: TOTAL IS 50 MS.
03CF-60 I 28 ( 6) RTS ; DONE: KEY IN A.
03D0- I 29 ;
03D0- I 30 ; SUBROUTINE 'INITKEY'
03D0- I 31 ; TAKES CARE OF INITIALIZING VIA #3 FOR USING WITH THE GETKEY ROUTINE FROM
03D0- I 32 ; THE CODE.
03D0- I 33 ;
03D0-A9 00 I 34 ( 2) INITKEY LDA #0
03D2-8D 03 CC I 35 ( 4) STA DDR3A ; SET KEY STROBE PORT FOR INPUT
03D5-A9 FF I 36 ( 2) LDA #$FF
03D7-8D 02 CC I 37 ( 4) STA DDR3B ; SET KEYS FOR OUTPUT
03DA-60 I 38 ( 6) RTS

View File

@ -0,0 +1,4 @@
@echo off
sbasm.py echo.asm
type echo.list
pause

View File

@ -0,0 +1,17 @@
.CR 6502
.TF echo.hex,INT
.LF echo.list
;
; PATTERN/TONE RECALL AND ESP TEST PROGRAM. FOR THE '6502 GAMES' HARDWARE,
; BOARD SHOULD BE JUMPERED WITH VIA CHIPS AT THE ADDRESSES SPECIFIED BELOW.
; OTHER THAN THAT THE CODE IS SHOULD BE UNCHANGED FROM THE BOOK THOUGH THERE
; WILL BE SOME DIFFERENCES DUE TO ASSEMBLER USED.
;
VIA1 .EQ $C000
VIA3 .EQ $CC00
.OR $0200
.TA $0200
BEGIN JSR INITKEY
.IN ../../common/CH08-Echo/game.asm
.IN ../../common/CH01-Getkey/getkey_routine.asm

View File

@ -0,0 +1,24 @@
:10020000205803A9FF8D03C08D02C08D02CCA90028
:100210008D01C085028501AD04C085108513A9023A
:100220008D00C0203303C900F0F9C90A10F585001C
:10023000AACA860520EA02A605F8186900D8290F7F
:10024000F0F09506CA10EBA9008D01C0A9048D003D
:10025000C0203303C900F0ABC90A3022A2008601D6
:100260008602B506860520D20220FD02A0FF6603A5
:10027000260388D0F9A605E8E400D0E6F0C9A60177
:10028000D506F00DE602A9808503A9FF200703F03B
:100290000620D20220FD02E601A500C501D0A8A5D6
:1002A00002C900F01520D202A9094820FD026838D1
:1002B000E901D0F685018502F08DA9FF8D01C08D81
:1002C00000C0A9014820FD0268186901C90AD0F4DC
:1002D000F08448A8A9008D00C0382A88D0FC8D0180
:1002E000C09005A9018D00C0686038A51065136530
:1002F00014850FA204B50F9510CA10F960A888B92B
:100300002A038503B921038504A9008D00CCA60327
:10031000A40488189000D0FA49FF8D00CCCAD0F010
:1003200060C9BEA9968E7E70645E6B72808F94AA3F
:10033000BFD7E42C01CC10FBA20F8E00CC2C01CC3B
:100340001005CA10F530F18AA012A2FF2C01CC30A2
:10035000E7CAD0F888D0F360A9008D03CCA9FF8D3F
:0303600002CC606C
:00000001FF

View File

@ -0,0 +1,274 @@
0000- 4 ;
0000- 5 ; PATTERN/TONE RECALL AND ESP TEST PROGRAM. FOR THE '6502 GAMES' HARDWARE,
0000- 6 ; BOARD SHOULD BE JUMPERED WITH VIA CHIPS AT THE ADDRESSES SPECIFIED BELOW.
0000- 7 ; OTHER THAN THAT THE CODE IS SHOULD BE UNCHANGED FROM THE BOOK THOUGH THERE
0000- 8 ; WILL BE SOME DIFFERENCES DUE TO ASSEMBLER USED.
0000- 9 ;
C000- 10 VIA1 .EQ $C000
CC00- 11 VIA3 .EQ $CC00
0000- 12
0200- 13 .OR $0200
0200- 14 .TA $0200
0200-20 58 03 15 ( 6) BEGIN JSR INITKEY
0203- 16 .IN ../../common/CH08-Echo/game.asm
0203- I 1 ; 'ECHO'
0203- I 2 ; PATTERN/TONE RECALL AND ESP TEST PROGRAM. THE USER GUESSES A PATTERN OF LIT
0203- I 3 ; LEDS AND THEIR ASSOCIATED TONES. THE TONE/LIGHT COMBINATION CAN BE PLAYED,
0203- I 4 ; SO THAT THE USER MUST REMEMBER IT AND REPLICATE IT CORRECTLY.
0203- I 5 ;
0203- I 6 ; OPERATING THE PROGRAM:
0203- I 7 ; THE BOTTOM ROW OF LEDS IS AN INDICATOR FOR PROGRAM STATUS; THE LEFT-MOST
0203- I 8 ; ONE ($10) INDICATES THAT THE PROGRAM IS EXPECTING THE USER TO INPUT THE
0203- I 9 ; LENGTH OF THE SEQUENCE TO BE GUESSED. THE SECOND FROM THE LEFT ($11)
0203- I 10 ; INDICATES THAT THE PROGRAM EXPECTS EITHER A GUESS (1-9), THE COMMAND TO
0203- I 11 ; RESTART THE GAME (0), OR THE COMMAND TO PLAY THE SEQUECE (A-F). THE KEYS
0203- I 12 ; ARE ASSOCIATED WITH THE LEDS 1-9.
0203- I 13 ;
0203- I 14 ; LOOKING AT THE SEQUENCE WHILE IN THE MIDDLE OF GUESSING IT WILL EREASE ALL
0203- I 15 ; PREVIOUS GUESSES (RESET GESNO AND ERRS TO 0). AFTER A WIN, THE PROGRAM
0203- I 16 ; RESTARTS.
0203- I 17
0203- I 18 ;
0203- I 19 ; I/O:
0203- I 20 ;
C000- I 21 PORT1B .EQ VIA1 ; PORT B
C001- I 22 PORT1A .EQ VIA1+1 ; PORT A
C002- I 23 DDR1B .EQ VIA1+2 ; PORT B DATA DIRECTION REGISTER
C003- I 24 DDR1A .EQ VIA1+3 ; PORT A DATA DIRECTION REGISTER
C004- I 25 T1CL .EQ VIA1+4
0203- I 26
CC00- I 27 PORT3B .EQ VIA3 ; PORT B
CC01- I 28 PORT3A .EQ VIA3+1 ; PORT A
CC02- I 29 DDR3B .EQ VIA3+2 ; PORT B DATA DIRECTION REGISTER
CC03- I 30 DDR3A .EQ VIA3+3 ; PORT A DATA DIRECTION REGISTER
0203- I 31
0203- I 32 ;
0203- I 33 ; VARIABLE STORAGE.
0203- I 34 ;
0000- I 35 ZP .EQ $00
0000- I 36 DIGITS .EQ ZP ; NUMBER OF DIGITS IN SEQUENCE
0001- I 37 GESNO .EQ ZP+1 ; NUMBER OF CORRECT GUESS, SPECIFIES
0203- I 38 ; WHERE THE USER IS IN THE SERIES.
0002- I 39 ERRS .EQ ZP+2 ; NUMBER OF ERRORS MADE IN THE SERIES.
0003- I 40 DUR .EQ ZP+3 ; TEMPORARY STORAGE FOR NOTE DURATION.
0004- I 41 FREQ .EQ ZP+4 ; TEMPORARY STORAGE FOR NOTE FREQUENCY.
0005- I 42 TEMP .EQ ZP+5 ; TEMPORARY STORAGE FOR X REGISTER.
0006- I 43 TABLE .EQ ZP+6 ; STORAGE FOR SEQUECE
000F- I 44 RND .EQ ZP+15 ; SCRATCHPAD FOR RANDOM # GENERATOR
0203- I 45
0203-A9 FF I 46 ( 2) START LDA #$FF ; SET UP DATA DIRECTION REGISTERS.
0205-8D 03 C0 I 47 ( 4) STA DDR1A
0208-8D 02 C0 I 48 ( 4) STA DDR1B
020B-8D 02 CC I 49 ( 4) STA DDR3B
020E-A9 00 I 50 ( 2) LDA #0 ; CLEAR VARIABLE STORAGES
0210-8D 01 C0 I 51 ( 4) STA PORT1A ; ... AND LEDS
0213-85 02 I 52 ( 2) STA ERRS
0215-85 01 I 53 ( 2) STA GESNO
0217-AD 04 C0 I 54 ( 4) LDA T1CL ; GET SEED FOR RND # GENERATOR
021A-85 10 I 55 ( 2) STA RND+1 ; AND STORE IN RND SCRATCHPAD.
021C-85 13 I 56 ( 2) STA RND+4
021E-A9 02 I 57 ( 2) LDA #%010 ; TURN LED #10 ON TO INDICATE
0220-8D 00 C0 I 58 ( 4) STA PORT1B ; NEED FOR LENGTH INPUT.
0223-20 33 03 I 59 ( 6) DIGKEY JSR GETKEY ; GET LENGTH OF SERIES
0226-C9 00 I 60 ( 2) CMP #0 ; IS IT 0?
0228-F0 F9 I 61 (2**) BEQ DIGKEY ; IF YES, GET ANOTHER.
022A-C9 0A I 62 ( 2) CMP #10 ; LENGTH GREATER THAN 9?
022C-10 F5 I 63 (2**) BPL DIGKEY ; IF YES, GET ANOTHER.
022E-85 00 I 64 ( 2) STA DIGITS ; SAVE VALID LENGTH
0230-AA I 65 ( 2) TAX ; USE LENGTH-1 AS INDEX FOR FILLING...
0231-CA I 66 ( 2) DEX ; ... SERIES W/RANDOM VALUES.
0232-86 05 I 67 ( 3) FILL STX TEMP ; SAVE X FROM 'RANDOM'
0234-20 EA 02 I 68 ( 6) JSR RANDOM
0237-A6 05 I 69 ( 3) LDX TEMP ; RESTORE X
0239-F8 I 70 ( 2) SED ; DO A DECIMAL ADJUST
023A-18 I 71 ( 2) CLC
023B-69 00 I 72 ( 2) ADC #0
023D-D8 I 73 ( 2) CLD
023E-29 0F I 74 ( 2) AND #$0F ; REMOVE UPPER NIBBLE SO NUMBER IS <10
0240-F0 F0 I 75 (2**) BEQ FILL ; # CAN'T BE ZERO
0242-95 06 I 76 ( 4) STA TABLE,X ; STORE # IN TABLE
0244-CA I 77 ( 2) DEX ; DECREMENT FOR NEXT
0245-10 EB I 78 (2**) BPL FILL ; LOOP IF NOT DONE
0247-A9 00 I 79 ( 2) KEY LDA #0 ; CLEAR LEDS
0249-8D 01 C0 I 80 ( 4) STA PORT1A
024C-A9 04 I 81 ( 2) LDA #%0100 ; TURN INPUT INDICATOR ON.
024E-8D 00 C0 I 82 ( 4) STA PORT1B
0251-20 33 03 I 83 ( 6) JSR GETKEY ; GET GUESS OR PLAY COMMAND
0254-C9 00 I 84 ( 2) CMP #0 ; IS IT 0?
0256-F0 AB I 85 (2**) STRTJP BEQ START ; IF YES, RESTART.
0258-C9 0A I 86 ( 2) CMP #10 ; NUMBER < 10 ?
025A-30 22 I 87 (2**) BMI EVAL ; IF YES, EVALUATE GUESS.
025C- I 88 ;
025C- I 89 ; ROUTINE TO DISPLAY SERIES TO BE GUESSED BY LIGHTING LEDS AND PLAYING
025C- I 90 ; TONES IN SEQUECE.
025C- I 91 ;
025C-A2 00 I 92 ( 2) SHOW LDX #0
025E-86 01 I 93 ( 3) STX GESNO ; CLEAR CURRENT GUESS NUMBER
0260-86 02 I 94 ( 3) STX ERRS ; CLEAR CURRENT ERROR NUMBER
0262-B5 06 I 95 ( 4) SHOWLP LDA TABLE,X ; GET X-TH ENTRY IN SERIES TABLE.
0264-86 05 I 96 ( 3) STX TEMP ; SAVE X
0266-20 D2 02 I 97 ( 6) JSR LIGHT ; LIGHT LED # (TABLE(X))
0269-20 FD 02 I 98 ( 6) JSR PLAY ; PLAY TONE # (TABLE(X))
026C-A0 FF I 99 ( 2) LDY #$FF ; SET LOOP COUNTER FOR DELAY
026E-66 03 I 100 ( 5) DELAY ROR DUR ; WASTE TIME
0270-26 03 I 101 ( 5) ROL DUR
0272-88 I 102 ( 2) DEY ; COUNT DOWN
0273-D0 F9 I 103 (2**) BNE DELAY ; IF NOT DONE, WASTE SOME MORE TIME
0275-A6 05 I 104 ( 3) LDX TEMP ; RESTORE X
0277-E8 I 105 ( 2) INX ; INCREMENT INDEX TO SHOW NEXT
0278-E4 00 I 106 ( 3) CPX DIGITS ; ALL DIGITS SHOWN?
027A-D0 E6 I 107 (2**) BNE SHOWLP ; IF NOT, SHOW NEXT.
027C-F0 C9 I 108 (2**) BEQ KEY ; DONE, SO GET NEXT INPUT.
027E- I 109 ;
027E- I 110 ; ROUTINE TO EVALUATE GUESSES OF PLAYER.
027E- I 111 ;
027E-A6 01 I 112 ( 3) EVAL LDX GESNO ; GET NUMBER OF GUESS.
0280-D5 06 I 113 ( 4) CMP TABLE,X ; GUESS = CORRESPONDING DIGIT = ?
0282-F0 0D I 114 (2**) BEQ CORRECT ; IF YES, SHOW PLAYER.
0284-E6 02 I 115 ( 5) WRONG INC ERRS ; GUESS WRONG, ANOTHER ERROR FOR THE TALLY.
0286-A9 80 I 116 ( 2) LDA #$80 ; DURATION FOR LOW TONE TO INDICATE A
0288-85 03 I 117 ( 2) STA DUR ; BAD GUESS.
028A-A9 FF I 118 ( 2) LDA #$FF ; FREQUENCY CONSTANT
028C-20 07 03 I 119 ( 6) JSR PLYTON ; PLAY IT
028F-F0 06 I 120 (2**) BEQ ENDCHK ; CHECK FOR ENDGAME
0291-20 D2 02 I 121 ( 6) CORRECT JSR LIGHT ; VALIDATE CORRECT GUESS...
0294-20 FD 02 I 122 ( 6) JSR PLAY
0297-E6 01 I 123 ( 5) ENDCHK INC GESNO ; ONE MORE GUESS TAKEN.
0299-A5 00 I 124 ( 3) LDA DIGITS
029B-C5 01 I 125 ( 3) CMP GESNO ; ALL DIGITS GUESSED?
029D-D0 A8 I 126 (2**) BNE KEY ; IF NOT, GET NEXT.
029F-A5 02 I 127 ( 3) LDA ERRS ; GET NUMBER OF ERRORS.
02A1-C9 00 I 128 ( 2) CMP #0 ; ANY ERRORS?
02A3-F0 15 I 129 (2**) BEQ WIN ; IF NOT, PLAYER WINS.
02A5-20 D2 02 I 130 ( 6) LOSE JSR LIGHT ; SHOW NUMBER OF ERRORS.
02A8-A9 09 I 131 ( 2) LDA #9 ; PLAY 8 DESCENDING TONES
02AA-48 I 132 ( 3) LOSELP PHA
02AB-20 FD 02 I 133 ( 6) JSR PLAY
02AE-68 I 134 ( 4) PLA
02AF-38 I 135 ( 2) SEC
02B0-E9 01 I 136 ( 2) SBC #1
02B2-D0 F6 I 137 (2**) BNE LOSELP
02B4-85 01 I 138 ( 2) STA GESNO ; CLEAR VARIABLES
02B6-85 02 I 139 ( 2) STA ERRS
02B8-F0 8D I 140 (2**) BEQ KEY ; GET NEXT GUESS SEQUECE
02BA-A9 FF I 141 ( 2) WIN LDA #$FF ; TURN ALL LEDS ON FOR WIN
02BC-8D 01 C0 I 142 ( 4) STA PORT1A
02BF-8D 00 C0 I 143 ( 4) STA PORT1B
02C2-A9 01 I 144 ( 2) LDA #1 ; PLAY 8 ASCENDING TONES
02C4-48 I 145 ( 3) WINLP PHA
02C5-20 FD 02 I 146 ( 6) JSR PLAY
02C8-68 I 147 ( 4) PLA
02C9-18 I 148 ( 2) CLC
02CA-69 01 I 149 ( 2) ADC #01
02CC-C9 0A I 150 ( 2) CMP #10
02CE-D0 F4 I 151 (2**) BNE WINLP
02D0-F0 84 I 152 (2**) BEQ STRTJP ; USE DOUBLE-JUMP FOR RESTART
02D2- I 153 ;
02D2- I 154 ; SUBROUTINE 'LIGHT'
02D2- I 155 ; ROUTINE TO LIGHT N-TH LED, WHERE N IS THE NUMBER PASSED AS A PARAMETER IN
02D2- I 156 ; THE ACCUMULATOR.
02D2- I 157 ;
02D2-48 I 158 ( 3) LIGHT PHA ; SAVE A
02D3-A8 I 159 ( 2) TAY ; USE AS COUNTER IN Y
02D4-A9 00 I 160 ( 2) LDA #0 ; CLEAR A FOR BIT SHIFT
02D6-8D 00 C0 I 161 ( 4) STA PORT1B ; CLEAR HI LEDS.
02D9-38 I 162 ( 2) SEC ; GENERATE HI BIT TO SHIFT LEFT.
02DA-2A I 163 ( 2) LTSHFT ROL A ; MOVE HI BIT LEFT.
02DB-88 I 164 ( 2) DEY ; DECREMENT COUNTER
02DC-D0 FC I 165 (2**) BNE LTSHFT ; SHIFTS DONE?
02DE-8D 01 C0 I 166 ( 4) STA PORT1A ; STORE CORRECT PATTERN
02E1-90 05 I 167 (2**) BCC LTCC ; BIT 9 NOT HI, DONE.
02E3-A9 01 I 168 ( 2) LDA #1
02E5-8D 00 C0 I 169 ( 4) STA PORT1B ; TURN LED 9 ON.
02E8-68 I 170 ( 4) LTCC PLA ; RESTORE A
02E9-60 I 171 ( 6) RTS
02EA- I 172 ;
02EA- I 173 ; SUBROUTINE 'RANDOM'
02EA- I 174 ; RANDOM NUMBER GENERATOR, RETURNS WITH NEW RANDOM NUMBER IN ACCUMULATOR.
02EA- I 175 ;
02EA-38 I 176 ( 2) RANDOM SEC
02EB-A5 10 I 177 ( 3) LDA RND+1
02ED-65 13 I 178 ( 3) ADC RND+4
02EF-65 14 I 179 ( 3) ADC RND+5
02F1-85 0F I 180 ( 2) STA RND
02F3-A2 04 I 181 ( 2) LDX #4
02F5-B5 0F I 182 ( 4) RNDLP LDA RND,X
02F7-95 10 I 183 ( 4) STA RND+1,X
02F9-CA I 184 ( 2) DEX
02FA-10 F9 I 185 (2**) BPL RNDLP
02FC-60 I 186 ( 6) RTS
02FD- I 187 ;
02FD- I 188 ; SUBROUTINE 'PLAY'
02FD- I 189 ; ROUTINE TO PLAY TONES WHOSE NUMBER IS PASSED IN BY ACCUMULATOR. IF ENTERED
02FD- I 190 ; AT PLYTON, IT WILL PLAY TONE WHOSE LENGTH IS IN DUR, FREQUENCY IN THE
02FD- I 191 ; ACCUMULATOR INSTEAD.
02FD-A8 I 192 ( 2) PLAY TAY ; USE TONE # AS INDEX...
02FE-88 I 193 ( 2) DEY ; DECREMENT TO MATCH TABLES
02FF-B9 2A 03 I 194 ( 4*) LDA DURTAB,Y ; GET DURATION FOR TONE N-TH TONE
0302-85 03 I 195 ( 2) STA DUR ; SAVE IT.
0304-B9 21 03 I 196 ( 4*) LDA NOTAB,Y ; GET FREQUENCY CONSTANT FOR N-TH TONE
0307-85 04 I 197 ( 2) PLYTON STA FREQ ; SAVE IT.
0309-A9 00 I 198 ( 2) LDA #0 ; SET SPKR PORT LO.
030B-8D 00 CC I 199 ( 4) STA PORT3B
030E-A6 03 I 200 ( 3) LDX DUR ; GET DURATION IN NUMBER OF 1/2 CYCLES.
0310-A4 04 I 201 ( 3) FL2 LDY FREQ ; GET FREQUENCY
0312-88 I 202 ( 2) FL1 DEY ; COUNT DOWN DELAY...
0313-18 I 203 ( 2) CLC ; WASTE TIME
0314-90 00 I 204 (2**) BCC FL0
0316-D0 FA I 205 (2**) FL0 BNE FL1 ; LOOP FOR DELAY
0318-49 FF I 206 ( 2) EOR #$FF ; COMPLEMENT PORT
031A-8D 00 CC I 207 ( 4) STA PORT3B
031D-CA I 208 ( 2) DEX ; COUNT DOWN DURATION...
031E-D0 F0 I 209 (2**) BNE FL2 ; LOOP UNTIL NOTE OVER.
0320-60 I 210 ( 6) RTS ; DONE.
0321- I 211 ;
0321- I 212 ; TABLE FOR NOTE FREQUENCIES.
0321- I 213 ;
0321-C9 BE A9 96
8E 7E 70 64
5E I 214 NOTAB .HS C9.BE.A9.96.8E.7E.70.64.5E
032A- I 215 ;
032A- I 216 ; TABLE FOR NOTE DURATIONS.
032A- I 217 ;
032A-6B 72 80 8F
94 AA BF D7
E4 I 218 DURTAB .HS 6B.72.80.8F.94.AA.BF.D7.E4
0333- 17 .IN ../../common/CH01-Getkey/getkey_routine.asm
0333- I 1 ; 'GETKEY' KEYBOARD INPUT ROUTINE READS AND DEBOUNCES KEYBOARD. RETURNS WITH
0333- I 2 ; KEY NUMBER IN ACCUMULATOR IF KEY DOWN. OPERATION: SENDS NUMBERS 0-F TO 74154
0333- I 3 ; (4 TO 16 LINE DECODER), WHICH GROUNDS ONE SIDE OF KEYSWITCHES ONE AT A TIME.
0333- I 4 ; IF A KEY IS DOWN, PA7 OF VIA #3 WILL BE GROUNDED, AND THE CURRENT VALUE
0333- I 5 ; APPLIED TO THE 74154 BE THE KEY NUMBER. WHEN THE PROGRAM DETECTS A KEY CLOSE
0333- I 6 ; CHECKS FOR KEY CLOSURE FOR 50 MS. TO ELIMINATE BOUNCE.
0333- I 7 ; NOTE: IF NO KEY IS PRESSED, GETKEY WILL WAIT.
0333- I 8 ;
0333-2C 01 CC I 9 ( 4) GETKEY BIT PORT3A ; SEE IF KEY IS STILL DOWN FROM LAST KEY CLOSURE:
0336- I 10 ; KEYSTROBE IN 'N' STATUS BIT.
0336-10 FB I 11 (2**) BPL GETKEY ; IF YES, WAIT FOR KEY RELEASE
0338-A2 0F I 12 ( 2) RSTART LDX #15 ; SET KEY COUNTER TO 15
033A-8E 00 CC I 13 ( 4) NXTKEY STX PORT3B ; OUTPUT KEY # TO 74154
033D-2C 01 CC I 14 ( 4) BIT PORT3A ; SEE IF KEY DOWN: STROBE IN 'N'
0340-10 05 I 15 (2**) BPL BOUNCE ; IF YES, GO DEBOUNCE
0342-CA I 16 ( 2) DEX ; DECREMENT KEY #
0343-10 F5 I 17 (2**) BPL NXTKEY ; NO, DO NEXT KEY
0345-30 F1 I 18 (2**) BMI RSTART ; START OVER
0347-8A I 19 ( 2) BOUNCE TXA ; SAVE KEY NUMBER IN A
0348-A0 12 I 20 ( 2) LDY #$12 ; OUTER LOOP CNT LOAD FOR DELAY OF 50 MS.
034A-A2 FF I 21 ( 2) LP1 LDX #$FF ; INNER 11 US. LOOP
034C-2C 01 CC I 22 ( 4) LP2 BIT PORT3A ; SEE IF KEY STILL DOWN
034F-30 E7 I 23 (2**) BMI RSTART ; IF NOT, KEY NOT VALID, RESTART
0351-CA I 24 ( 2) DEX
0352-D0 F8 I 25 (2**) BNE LP2 ; THIS LOOP USES 2115*5 US.
0354-88 I 26 ( 2) DEY
0355-D0 F3 I 27 (2**) BNE LP1 ; OUTER LOOP: TOTAL IS 50 MS.
0357-60 I 28 ( 6) RTS ; DONE: KEY IN A.
0358- I 29 ;
0358- I 30 ; SUBROUTINE 'INITKEY'
0358- I 31 ; TAKES CARE OF INITIALIZING VIA #3 FOR USING WITH THE GETKEY ROUTINE FROM
0358- I 32 ; THE CODE.
0358- I 33 ;
0358-A9 00 I 34 ( 2) INITKEY LDA #0
035A-8D 03 CC I 35 ( 4) STA DDR3A ; SET KEY STROBE PORT FOR INPUT
035D-A9 FF I 36 ( 2) LDA #$FF
035F-8D 02 CC I 37 ( 4) STA DDR3B ; SET KEYS FOR OUTPUT
0362-60 I 38 ( 6) RTS

View File

@ -0,0 +1,4 @@
@echo off
sbasm.py echo.asm
type echo.list
pause

View File

@ -0,0 +1,17 @@
.CR 6502
.TF echo.hex,INT
.LF echo.list
;
; PATTERN/TONE RECALL AND ESP TEST PROGRAM. FOR THE '6502 GAMES' HARDWARE,
; BOARD SHOULD BE JUMPERED WITH VIA CHIPS AT THE ADDRESSES SPECIFIED BELOW.
; OTHER THAN THAT THE CODE IS SHOULD BE UNCHANGED FROM THE BOOK THOUGH THERE
; WILL BE SOME DIFFERENCES DUE TO ASSEMBLER USED.
;
VIA1 .EQ $C000
VIA3 .EQ $CC00
.OR $0200
.TA $0200
BEGIN JSR INITKEY
.IN game.asm
.IN ../CH01-Getkey/getkey_routine.asm

View File

@ -0,0 +1,24 @@
:10020000205803A9FF8D03C08D02C08D02CCA90028
:100210008D01C085028501AD04C085108513A9023A
:100220008D00C0203303C900F0F9C90A10F585001C
:10023000AACA860520EA02A605F8186900D8290F7F
:10024000F0F09506CA10EBA9008D01C0A9048D003D
:10025000C0203303C900F0ABC90A3022A2008601D6
:100260008602B506860520D20220FD02A0FF6603A5
:10027000260388D0F9A605E8E400D0E6F0C9A60177
:10028000D506F00DE602A9808503A9FF200703F03B
:100290000620D20220FD02E601A500C501D0A8A5D6
:1002A00002C900F01520D202A9094820FD026838D1
:1002B000E901D0F685018502F08DA9FF8D01C08D81
:1002C00000C0A9014820FD0268186901C90AD0F4DC
:1002D000F08448A8A9008D00C0382A88D0FC8D0180
:1002E000C09005A9018D00C0686038A51065136530
:1002F00014850FA204B50F9510CA10F960A888B92B
:100300002A038503B921038504A9008D00CCA60327
:10031000A40488189000D0FA49FF8D00CCCAD0F010
:1003200060C9BEA9968E7E70645E6B72808F94AA3F
:10033000BFD7E42C01CC10FBA20F8E00CC2C01CC3B
:100340001005CA10F530F18AA012A2FF2C01CC30A2
:10035000E7CAD0F888D0F360A9008D03CCA9FF8D3F
:0303600002CC606C
:00000001FF

View File

@ -0,0 +1,274 @@
0000- 4 ;
0000- 5 ; PATTERN/TONE RECALL AND ESP TEST PROGRAM. FOR THE '6502 GAMES' HARDWARE,
0000- 6 ; BOARD SHOULD BE JUMPERED WITH VIA CHIPS AT THE ADDRESSES SPECIFIED BELOW.
0000- 7 ; OTHER THAN THAT THE CODE IS SHOULD BE UNCHANGED FROM THE BOOK THOUGH THERE
0000- 8 ; WILL BE SOME DIFFERENCES DUE TO ASSEMBLER USED.
0000- 9 ;
C000- 10 VIA1 .EQ $C000
CC00- 11 VIA3 .EQ $CC00
0000- 12
0200- 13 .OR $0200
0200- 14 .TA $0200
0200-20 58 03 15 ( 6) BEGIN JSR INITKEY
0203- 16 .IN game.asm
0203- I 1 ; 'ECHO'
0203- I 2 ; PATTERN/TONE RECALL AND ESP TEST PROGRAM. THE USER GUESSES A PATTERN OF LIT
0203- I 3 ; LEDS AND THEIR ASSOCIATED TONES. THE TONE/LIGHT COMBINATION CAN BE PLAYED,
0203- I 4 ; SO THAT THE USER MUST REMEMBER IT AND REPLICATE IT CORRECTLY.
0203- I 5 ;
0203- I 6 ; OPERATING THE PROGRAM:
0203- I 7 ; THE BOTTOM ROW OF LEDS IS AN INDICATOR FOR PROGRAM STATUS; THE LEFT-MOST
0203- I 8 ; ONE ($10) INDICATES THAT THE PROGRAM IS EXPECTING THE USER TO INPUT THE
0203- I 9 ; LENGTH OF THE SEQUENCE TO BE GUESSED. THE SECOND FROM THE LEFT ($11)
0203- I 10 ; INDICATES THAT THE PROGRAM EXPECTS EITHER A GUESS (1-9), THE COMMAND TO
0203- I 11 ; RESTART THE GAME (0), OR THE COMMAND TO PLAY THE SEQUECE (A-F). THE KEYS
0203- I 12 ; ARE ASSOCIATED WITH THE LEDS 1-9.
0203- I 13 ;
0203- I 14 ; LOOKING AT THE SEQUENCE WHILE IN THE MIDDLE OF GUESSING IT WILL EREASE ALL
0203- I 15 ; PREVIOUS GUESSES (RESET GESNO AND ERRS TO 0). AFTER A WIN, THE PROGRAM
0203- I 16 ; RESTARTS.
0203- I 17
0203- I 18 ;
0203- I 19 ; I/O:
0203- I 20 ;
C000- I 21 PORT1B .EQ VIA1 ; PORT B
C001- I 22 PORT1A .EQ VIA1+1 ; PORT A
C002- I 23 DDR1B .EQ VIA1+2 ; PORT B DATA DIRECTION REGISTER
C003- I 24 DDR1A .EQ VIA1+3 ; PORT A DATA DIRECTION REGISTER
C004- I 25 T1CL .EQ VIA1+4
0203- I 26
CC00- I 27 PORT3B .EQ VIA3 ; PORT B
CC01- I 28 PORT3A .EQ VIA3+1 ; PORT A
CC02- I 29 DDR3B .EQ VIA3+2 ; PORT B DATA DIRECTION REGISTER
CC03- I 30 DDR3A .EQ VIA3+3 ; PORT A DATA DIRECTION REGISTER
0203- I 31
0203- I 32 ;
0203- I 33 ; VARIABLE STORAGE.
0203- I 34 ;
0000- I 35 ZP .EQ $00
0000- I 36 DIGITS .EQ ZP ; NUMBER OF DIGITS IN SEQUENCE
0001- I 37 GESNO .EQ ZP+1 ; NUMBER OF CORRECT GUESS, SPECIFIES
0203- I 38 ; WHERE THE USER IS IN THE SERIES.
0002- I 39 ERRS .EQ ZP+2 ; NUMBER OF ERRORS MADE IN THE SERIES.
0003- I 40 DUR .EQ ZP+3 ; TEMPORARY STORAGE FOR NOTE DURATION.
0004- I 41 FREQ .EQ ZP+4 ; TEMPORARY STORAGE FOR NOTE FREQUENCY.
0005- I 42 TEMP .EQ ZP+5 ; TEMPORARY STORAGE FOR X REGISTER.
0006- I 43 TABLE .EQ ZP+6 ; STORAGE FOR SEQUECE
000F- I 44 RND .EQ ZP+15 ; SCRATCHPAD FOR RANDOM # GENERATOR
0203- I 45
0203-A9 FF I 46 ( 2) START LDA #$FF ; SET UP DATA DIRECTION REGISTERS.
0205-8D 03 C0 I 47 ( 4) STA DDR1A
0208-8D 02 C0 I 48 ( 4) STA DDR1B
020B-8D 02 CC I 49 ( 4) STA DDR3B
020E-A9 00 I 50 ( 2) LDA #0 ; CLEAR VARIABLE STORAGES
0210-8D 01 C0 I 51 ( 4) STA PORT1A ; ... AND LEDS
0213-85 02 I 52 ( 2) STA ERRS
0215-85 01 I 53 ( 2) STA GESNO
0217-AD 04 C0 I 54 ( 4) LDA T1CL ; GET SEED FOR RND # GENERATOR
021A-85 10 I 55 ( 2) STA RND+1 ; AND STORE IN RND SCRATCHPAD.
021C-85 13 I 56 ( 2) STA RND+4
021E-A9 02 I 57 ( 2) LDA #%010 ; TURN LED #10 ON TO INDICATE
0220-8D 00 C0 I 58 ( 4) STA PORT1B ; NEED FOR LENGTH INPUT.
0223-20 33 03 I 59 ( 6) DIGKEY JSR GETKEY ; GET LENGTH OF SERIES
0226-C9 00 I 60 ( 2) CMP #0 ; IS IT 0?
0228-F0 F9 I 61 (2**) BEQ DIGKEY ; IF YES, GET ANOTHER.
022A-C9 0A I 62 ( 2) CMP #10 ; LENGTH GREATER THAN 9?
022C-10 F5 I 63 (2**) BPL DIGKEY ; IF YES, GET ANOTHER.
022E-85 00 I 64 ( 2) STA DIGITS ; SAVE VALID LENGTH
0230-AA I 65 ( 2) TAX ; USE LENGTH-1 AS INDEX FOR FILLING...
0231-CA I 66 ( 2) DEX ; ... SERIES W/RANDOM VALUES.
0232-86 05 I 67 ( 3) FILL STX TEMP ; SAVE X FROM 'RANDOM'
0234-20 EA 02 I 68 ( 6) JSR RANDOM
0237-A6 05 I 69 ( 3) LDX TEMP ; RESTORE X
0239-F8 I 70 ( 2) SED ; DO A DECIMAL ADJUST
023A-18 I 71 ( 2) CLC
023B-69 00 I 72 ( 2) ADC #0
023D-D8 I 73 ( 2) CLD
023E-29 0F I 74 ( 2) AND #$0F ; REMOVE UPPER NIBBLE SO NUMBER IS <10
0240-F0 F0 I 75 (2**) BEQ FILL ; # CAN'T BE ZERO
0242-95 06 I 76 ( 4) STA TABLE,X ; STORE # IN TABLE
0244-CA I 77 ( 2) DEX ; DECREMENT FOR NEXT
0245-10 EB I 78 (2**) BPL FILL ; LOOP IF NOT DONE
0247-A9 00 I 79 ( 2) KEY LDA #0 ; CLEAR LEDS
0249-8D 01 C0 I 80 ( 4) STA PORT1A
024C-A9 04 I 81 ( 2) LDA #%0100 ; TURN INPUT INDICATOR ON.
024E-8D 00 C0 I 82 ( 4) STA PORT1B
0251-20 33 03 I 83 ( 6) JSR GETKEY ; GET GUESS OR PLAY COMMAND
0254-C9 00 I 84 ( 2) CMP #0 ; IS IT 0?
0256-F0 AB I 85 (2**) STRTJP BEQ START ; IF YES, RESTART.
0258-C9 0A I 86 ( 2) CMP #10 ; NUMBER < 10 ?
025A-30 22 I 87 (2**) BMI EVAL ; IF YES, EVALUATE GUESS.
025C- I 88 ;
025C- I 89 ; ROUTINE TO DISPLAY SERIES TO BE GUESSED BY LIGHTING LEDS AND PLAYING
025C- I 90 ; TONES IN SEQUECE.
025C- I 91 ;
025C-A2 00 I 92 ( 2) SHOW LDX #0
025E-86 01 I 93 ( 3) STX GESNO ; CLEAR CURRENT GUESS NUMBER
0260-86 02 I 94 ( 3) STX ERRS ; CLEAR CURRENT ERROR NUMBER
0262-B5 06 I 95 ( 4) SHOWLP LDA TABLE,X ; GET X-TH ENTRY IN SERIES TABLE.
0264-86 05 I 96 ( 3) STX TEMP ; SAVE X
0266-20 D2 02 I 97 ( 6) JSR LIGHT ; LIGHT LED # (TABLE(X))
0269-20 FD 02 I 98 ( 6) JSR PLAY ; PLAY TONE # (TABLE(X))
026C-A0 FF I 99 ( 2) LDY #$FF ; SET LOOP COUNTER FOR DELAY
026E-66 03 I 100 ( 5) DELAY ROR DUR ; WASTE TIME
0270-26 03 I 101 ( 5) ROL DUR
0272-88 I 102 ( 2) DEY ; COUNT DOWN
0273-D0 F9 I 103 (2**) BNE DELAY ; IF NOT DONE, WASTE SOME MORE TIME
0275-A6 05 I 104 ( 3) LDX TEMP ; RESTORE X
0277-E8 I 105 ( 2) INX ; INCREMENT INDEX TO SHOW NEXT
0278-E4 00 I 106 ( 3) CPX DIGITS ; ALL DIGITS SHOWN?
027A-D0 E6 I 107 (2**) BNE SHOWLP ; IF NOT, SHOW NEXT.
027C-F0 C9 I 108 (2**) BEQ KEY ; DONE, SO GET NEXT INPUT.
027E- I 109 ;
027E- I 110 ; ROUTINE TO EVALUATE GUESSES OF PLAYER.
027E- I 111 ;
027E-A6 01 I 112 ( 3) EVAL LDX GESNO ; GET NUMBER OF GUESS.
0280-D5 06 I 113 ( 4) CMP TABLE,X ; GUESS = CORRESPONDING DIGIT = ?
0282-F0 0D I 114 (2**) BEQ CORRECT ; IF YES, SHOW PLAYER.
0284-E6 02 I 115 ( 5) WRONG INC ERRS ; GUESS WRONG, ANOTHER ERROR FOR THE TALLY.
0286-A9 80 I 116 ( 2) LDA #$80 ; DURATION FOR LOW TONE TO INDICATE A
0288-85 03 I 117 ( 2) STA DUR ; BAD GUESS.
028A-A9 FF I 118 ( 2) LDA #$FF ; FREQUENCY CONSTANT
028C-20 07 03 I 119 ( 6) JSR PLYTON ; PLAY IT
028F-F0 06 I 120 (2**) BEQ ENDCHK ; CHECK FOR ENDGAME
0291-20 D2 02 I 121 ( 6) CORRECT JSR LIGHT ; VALIDATE CORRECT GUESS...
0294-20 FD 02 I 122 ( 6) JSR PLAY
0297-E6 01 I 123 ( 5) ENDCHK INC GESNO ; ONE MORE GUESS TAKEN.
0299-A5 00 I 124 ( 3) LDA DIGITS
029B-C5 01 I 125 ( 3) CMP GESNO ; ALL DIGITS GUESSED?
029D-D0 A8 I 126 (2**) BNE KEY ; IF NOT, GET NEXT.
029F-A5 02 I 127 ( 3) LDA ERRS ; GET NUMBER OF ERRORS.
02A1-C9 00 I 128 ( 2) CMP #0 ; ANY ERRORS?
02A3-F0 15 I 129 (2**) BEQ WIN ; IF NOT, PLAYER WINS.
02A5-20 D2 02 I 130 ( 6) LOSE JSR LIGHT ; SHOW NUMBER OF ERRORS.
02A8-A9 09 I 131 ( 2) LDA #9 ; PLAY 8 DESCENDING TONES
02AA-48 I 132 ( 3) LOSELP PHA
02AB-20 FD 02 I 133 ( 6) JSR PLAY
02AE-68 I 134 ( 4) PLA
02AF-38 I 135 ( 2) SEC
02B0-E9 01 I 136 ( 2) SBC #1
02B2-D0 F6 I 137 (2**) BNE LOSELP
02B4-85 01 I 138 ( 2) STA GESNO ; CLEAR VARIABLES
02B6-85 02 I 139 ( 2) STA ERRS
02B8-F0 8D I 140 (2**) BEQ KEY ; GET NEXT GUESS SEQUECE
02BA-A9 FF I 141 ( 2) WIN LDA #$FF ; TURN ALL LEDS ON FOR WIN
02BC-8D 01 C0 I 142 ( 4) STA PORT1A
02BF-8D 00 C0 I 143 ( 4) STA PORT1B
02C2-A9 01 I 144 ( 2) LDA #1 ; PLAY 8 ASCENDING TONES
02C4-48 I 145 ( 3) WINLP PHA
02C5-20 FD 02 I 146 ( 6) JSR PLAY
02C8-68 I 147 ( 4) PLA
02C9-18 I 148 ( 2) CLC
02CA-69 01 I 149 ( 2) ADC #01
02CC-C9 0A I 150 ( 2) CMP #10
02CE-D0 F4 I 151 (2**) BNE WINLP
02D0-F0 84 I 152 (2**) BEQ STRTJP ; USE DOUBLE-JUMP FOR RESTART
02D2- I 153 ;
02D2- I 154 ; SUBROUTINE 'LIGHT'
02D2- I 155 ; ROUTINE TO LIGHT N-TH LED, WHERE N IS THE NUMBER PASSED AS A PARAMETER IN
02D2- I 156 ; THE ACCUMULATOR.
02D2- I 157 ;
02D2-48 I 158 ( 3) LIGHT PHA ; SAVE A
02D3-A8 I 159 ( 2) TAY ; USE AS COUNTER IN Y
02D4-A9 00 I 160 ( 2) LDA #0 ; CLEAR A FOR BIT SHIFT
02D6-8D 00 C0 I 161 ( 4) STA PORT1B ; CLEAR HI LEDS.
02D9-38 I 162 ( 2) SEC ; GENERATE HI BIT TO SHIFT LEFT.
02DA-2A I 163 ( 2) LTSHFT ROL A ; MOVE HI BIT LEFT.
02DB-88 I 164 ( 2) DEY ; DECREMENT COUNTER
02DC-D0 FC I 165 (2**) BNE LTSHFT ; SHIFTS DONE?
02DE-8D 01 C0 I 166 ( 4) STA PORT1A ; STORE CORRECT PATTERN
02E1-90 05 I 167 (2**) BCC LTCC ; BIT 9 NOT HI, DONE.
02E3-A9 01 I 168 ( 2) LDA #1
02E5-8D 00 C0 I 169 ( 4) STA PORT1B ; TURN LED 9 ON.
02E8-68 I 170 ( 4) LTCC PLA ; RESTORE A
02E9-60 I 171 ( 6) RTS
02EA- I 172 ;
02EA- I 173 ; SUBROUTINE 'RANDOM'
02EA- I 174 ; RANDOM NUMBER GENERATOR, RETURNS WITH NEW RANDOM NUMBER IN ACCUMULATOR.
02EA- I 175 ;
02EA-38 I 176 ( 2) RANDOM SEC
02EB-A5 10 I 177 ( 3) LDA RND+1
02ED-65 13 I 178 ( 3) ADC RND+4
02EF-65 14 I 179 ( 3) ADC RND+5
02F1-85 0F I 180 ( 2) STA RND
02F3-A2 04 I 181 ( 2) LDX #4
02F5-B5 0F I 182 ( 4) RNDLP LDA RND,X
02F7-95 10 I 183 ( 4) STA RND+1,X
02F9-CA I 184 ( 2) DEX
02FA-10 F9 I 185 (2**) BPL RNDLP
02FC-60 I 186 ( 6) RTS
02FD- I 187 ;
02FD- I 188 ; SUBROUTINE 'PLAY'
02FD- I 189 ; ROUTINE TO PLAY TONES WHOSE NUMBER IS PASSED IN BY ACCUMULATOR. IF ENTERED
02FD- I 190 ; AT PLYTON, IT WILL PLAY TONE WHOSE LENGTH IS IN DUR, FREQUENCY IN THE
02FD- I 191 ; ACCUMULATOR INSTEAD.
02FD-A8 I 192 ( 2) PLAY TAY ; USE TONE # AS INDEX...
02FE-88 I 193 ( 2) DEY ; DECREMENT TO MATCH TABLES
02FF-B9 2A 03 I 194 ( 4*) LDA DURTAB,Y ; GET DURATION FOR TONE N-TH TONE
0302-85 03 I 195 ( 2) STA DUR ; SAVE IT.
0304-B9 21 03 I 196 ( 4*) LDA NOTAB,Y ; GET FREQUENCY CONSTANT FOR N-TH TONE
0307-85 04 I 197 ( 2) PLYTON STA FREQ ; SAVE IT.
0309-A9 00 I 198 ( 2) LDA #0 ; SET SPKR PORT LO.
030B-8D 00 CC I 199 ( 4) STA PORT3B
030E-A6 03 I 200 ( 3) LDX DUR ; GET DURATION IN NUMBER OF 1/2 CYCLES.
0310-A4 04 I 201 ( 3) FL2 LDY FREQ ; GET FREQUENCY
0312-88 I 202 ( 2) FL1 DEY ; COUNT DOWN DELAY...
0313-18 I 203 ( 2) CLC ; WASTE TIME
0314-90 00 I 204 (2**) BCC FL0
0316-D0 FA I 205 (2**) FL0 BNE FL1 ; LOOP FOR DELAY
0318-49 FF I 206 ( 2) EOR #$FF ; COMPLEMENT PORT
031A-8D 00 CC I 207 ( 4) STA PORT3B
031D-CA I 208 ( 2) DEX ; COUNT DOWN DURATION...
031E-D0 F0 I 209 (2**) BNE FL2 ; LOOP UNTIL NOTE OVER.
0320-60 I 210 ( 6) RTS ; DONE.
0321- I 211 ;
0321- I 212 ; TABLE FOR NOTE FREQUENCIES.
0321- I 213 ;
0321-C9 BE A9 96
8E 7E 70 64
5E I 214 NOTAB .HS C9.BE.A9.96.8E.7E.70.64.5E
032A- I 215 ;
032A- I 216 ; TABLE FOR NOTE DURATIONS.
032A- I 217 ;
032A-6B 72 80 8F
94 AA BF D7
E4 I 218 DURTAB .HS 6B.72.80.8F.94.AA.BF.D7.E4
0333- 17 .IN ../CH01-Getkey/getkey_routine.asm
0333- I 1 ; 'GETKEY' KEYBOARD INPUT ROUTINE READS AND DEBOUNCES KEYBOARD. RETURNS WITH
0333- I 2 ; KEY NUMBER IN ACCUMULATOR IF KEY DOWN. OPERATION: SENDS NUMBERS 0-F TO 74154
0333- I 3 ; (4 TO 16 LINE DECODER), WHICH GROUNDS ONE SIDE OF KEYSWITCHES ONE AT A TIME.
0333- I 4 ; IF A KEY IS DOWN, PA7 OF VIA #3 WILL BE GROUNDED, AND THE CURRENT VALUE
0333- I 5 ; APPLIED TO THE 74154 BE THE KEY NUMBER. WHEN THE PROGRAM DETECTS A KEY CLOSE
0333- I 6 ; CHECKS FOR KEY CLOSURE FOR 50 MS. TO ELIMINATE BOUNCE.
0333- I 7 ; NOTE: IF NO KEY IS PRESSED, GETKEY WILL WAIT.
0333- I 8 ;
0333-2C 01 CC I 9 ( 4) GETKEY BIT PORT3A ; SEE IF KEY IS STILL DOWN FROM LAST KEY CLOSURE:
0336- I 10 ; KEYSTROBE IN 'N' STATUS BIT.
0336-10 FB I 11 (2**) BPL GETKEY ; IF YES, WAIT FOR KEY RELEASE
0338-A2 0F I 12 ( 2) RSTART LDX #15 ; SET KEY COUNTER TO 15
033A-8E 00 CC I 13 ( 4) NXTKEY STX PORT3B ; OUTPUT KEY # TO 74154
033D-2C 01 CC I 14 ( 4) BIT PORT3A ; SEE IF KEY DOWN: STROBE IN 'N'
0340-10 05 I 15 (2**) BPL BOUNCE ; IF YES, GO DEBOUNCE
0342-CA I 16 ( 2) DEX ; DECREMENT KEY #
0343-10 F5 I 17 (2**) BPL NXTKEY ; NO, DO NEXT KEY
0345-30 F1 I 18 (2**) BMI RSTART ; START OVER
0347-8A I 19 ( 2) BOUNCE TXA ; SAVE KEY NUMBER IN A
0348-A0 12 I 20 ( 2) LDY #$12 ; OUTER LOOP CNT LOAD FOR DELAY OF 50 MS.
034A-A2 FF I 21 ( 2) LP1 LDX #$FF ; INNER 11 US. LOOP
034C-2C 01 CC I 22 ( 4) LP2 BIT PORT3A ; SEE IF KEY STILL DOWN
034F-30 E7 I 23 (2**) BMI RSTART ; IF NOT, KEY NOT VALID, RESTART
0351-CA I 24 ( 2) DEX
0352-D0 F8 I 25 (2**) BNE LP2 ; THIS LOOP USES 2115*5 US.
0354-88 I 26 ( 2) DEY
0355-D0 F3 I 27 (2**) BNE LP1 ; OUTER LOOP: TOTAL IS 50 MS.
0357-60 I 28 ( 6) RTS ; DONE: KEY IN A.
0358- I 29 ;
0358- I 30 ; SUBROUTINE 'INITKEY'
0358- I 31 ; TAKES CARE OF INITIALIZING VIA #3 FOR USING WITH THE GETKEY ROUTINE FROM
0358- I 32 ; THE CODE.
0358- I 33 ;
0358-A9 00 I 34 ( 2) INITKEY LDA #0
035A-8D 03 CC I 35 ( 4) STA DDR3A ; SET KEY STROBE PORT FOR INPUT
035D-A9 FF I 36 ( 2) LDA #$FF
035F-8D 02 CC I 37 ( 4) STA DDR3B ; SET KEYS FOR OUTPUT
0362-60 I 38 ( 6) RTS

View File

@ -0,0 +1,218 @@
; 'ECHO'
; PATTERN/TONE RECALL AND ESP TEST PROGRAM. THE USER GUESSES A PATTERN OF LIT
; LEDS AND THEIR ASSOCIATED TONES. THE TONE/LIGHT COMBINATION CAN BE PLAYED,
; SO THAT THE USER MUST REMEMBER IT AND REPLICATE IT CORRECTLY.
;
; OPERATING THE PROGRAM:
; THE BOTTOM ROW OF LEDS IS AN INDICATOR FOR PROGRAM STATUS; THE LEFT-MOST
; ONE ($10) INDICATES THAT THE PROGRAM IS EXPECTING THE USER TO INPUT THE
; LENGTH OF THE SEQUENCE TO BE GUESSED. THE SECOND FROM THE LEFT ($11)
; INDICATES THAT THE PROGRAM EXPECTS EITHER A GUESS (1-9), THE COMMAND TO
; RESTART THE GAME (0), OR THE COMMAND TO PLAY THE SEQUECE (A-F). THE KEYS
; ARE ASSOCIATED WITH THE LEDS 1-9.
;
; LOOKING AT THE SEQUENCE WHILE IN THE MIDDLE OF GUESSING IT WILL EREASE ALL
; PREVIOUS GUESSES (RESET GESNO AND ERRS TO 0). AFTER A WIN, THE PROGRAM
; RESTARTS.
;
; I/O:
;
PORT1B .EQ VIA1 ; PORT B
PORT1A .EQ VIA1+1 ; PORT A
DDR1B .EQ VIA1+2 ; PORT B DATA DIRECTION REGISTER
DDR1A .EQ VIA1+3 ; PORT A DATA DIRECTION REGISTER
T1CL .EQ VIA1+4
PORT3B .EQ VIA3 ; PORT B
PORT3A .EQ VIA3+1 ; PORT A
DDR3B .EQ VIA3+2 ; PORT B DATA DIRECTION REGISTER
DDR3A .EQ VIA3+3 ; PORT A DATA DIRECTION REGISTER
;
; VARIABLE STORAGE.
;
ZP .EQ $00
DIGITS .EQ ZP ; NUMBER OF DIGITS IN SEQUENCE
GESNO .EQ ZP+1 ; NUMBER OF CORRECT GUESS, SPECIFIES
; WHERE THE USER IS IN THE SERIES.
ERRS .EQ ZP+2 ; NUMBER OF ERRORS MADE IN THE SERIES.
DUR .EQ ZP+3 ; TEMPORARY STORAGE FOR NOTE DURATION.
FREQ .EQ ZP+4 ; TEMPORARY STORAGE FOR NOTE FREQUENCY.
TEMP .EQ ZP+5 ; TEMPORARY STORAGE FOR X REGISTER.
TABLE .EQ ZP+6 ; STORAGE FOR SEQUECE
RND .EQ ZP+15 ; SCRATCHPAD FOR RANDOM # GENERATOR
START LDA #$FF ; SET UP DATA DIRECTION REGISTERS.
STA DDR1A
STA DDR1B
STA DDR3B
LDA #0 ; CLEAR VARIABLE STORAGES
STA PORT1A ; ... AND LEDS
STA ERRS
STA GESNO
LDA T1CL ; GET SEED FOR RND # GENERATOR
STA RND+1 ; AND STORE IN RND SCRATCHPAD.
STA RND+4
LDA #%010 ; TURN LED #10 ON TO INDICATE
STA PORT1B ; NEED FOR LENGTH INPUT.
DIGKEY JSR GETKEY ; GET LENGTH OF SERIES
CMP #0 ; IS IT 0?
BEQ DIGKEY ; IF YES, GET ANOTHER.
CMP #10 ; LENGTH GREATER THAN 9?
BPL DIGKEY ; IF YES, GET ANOTHER.
STA DIGITS ; SAVE VALID LENGTH
TAX ; USE LENGTH-1 AS INDEX FOR FILLING...
DEX ; ... SERIES W/RANDOM VALUES.
FILL STX TEMP ; SAVE X FROM 'RANDOM'
JSR RANDOM
LDX TEMP ; RESTORE X
SED ; DO A DECIMAL ADJUST
CLC
ADC #0
CLD
AND #$0F ; REMOVE UPPER NIBBLE SO NUMBER IS <10
BEQ FILL ; # CAN'T BE ZERO
STA TABLE,X ; STORE # IN TABLE
DEX ; DECREMENT FOR NEXT
BPL FILL ; LOOP IF NOT DONE
KEY LDA #0 ; CLEAR LEDS
STA PORT1A
LDA #%0100 ; TURN INPUT INDICATOR ON.
STA PORT1B
JSR GETKEY ; GET GUESS OR PLAY COMMAND
CMP #0 ; IS IT 0?
STRTJP BEQ START ; IF YES, RESTART.
CMP #10 ; NUMBER < 10 ?
BMI EVAL ; IF YES, EVALUATE GUESS.
;
; ROUTINE TO DISPLAY SERIES TO BE GUESSED BY LIGHTING LEDS AND PLAYING
; TONES IN SEQUECE.
;
SHOW LDX #0
STX GESNO ; CLEAR CURRENT GUESS NUMBER
STX ERRS ; CLEAR CURRENT ERROR NUMBER
SHOWLP LDA TABLE,X ; GET X-TH ENTRY IN SERIES TABLE.
STX TEMP ; SAVE X
JSR LIGHT ; LIGHT LED # (TABLE(X))
JSR PLAY ; PLAY TONE # (TABLE(X))
LDY #$FF ; SET LOOP COUNTER FOR DELAY
DELAY ROR DUR ; WASTE TIME
ROL DUR
DEY ; COUNT DOWN
BNE DELAY ; IF NOT DONE, WASTE SOME MORE TIME
LDX TEMP ; RESTORE X
INX ; INCREMENT INDEX TO SHOW NEXT
CPX DIGITS ; ALL DIGITS SHOWN?
BNE SHOWLP ; IF NOT, SHOW NEXT.
BEQ KEY ; DONE, SO GET NEXT INPUT.
;
; ROUTINE TO EVALUATE GUESSES OF PLAYER.
;
EVAL LDX GESNO ; GET NUMBER OF GUESS.
CMP TABLE,X ; GUESS = CORRESPONDING DIGIT = ?
BEQ CORRECT ; IF YES, SHOW PLAYER.
WRONG INC ERRS ; GUESS WRONG, ANOTHER ERROR FOR THE TALLY.
LDA #$80 ; DURATION FOR LOW TONE TO INDICATE A
STA DUR ; BAD GUESS.
LDA #$FF ; FREQUENCY CONSTANT
JSR PLYTON ; PLAY IT
BEQ ENDCHK ; CHECK FOR ENDGAME
CORRECT JSR LIGHT ; VALIDATE CORRECT GUESS...
JSR PLAY
ENDCHK INC GESNO ; ONE MORE GUESS TAKEN.
LDA DIGITS
CMP GESNO ; ALL DIGITS GUESSED?
BNE KEY ; IF NOT, GET NEXT.
LDA ERRS ; GET NUMBER OF ERRORS.
CMP #0 ; ANY ERRORS?
BEQ WIN ; IF NOT, PLAYER WINS.
LOSE JSR LIGHT ; SHOW NUMBER OF ERRORS.
LDA #9 ; PLAY 8 DESCENDING TONES
LOSELP PHA
JSR PLAY
PLA
SEC
SBC #1
BNE LOSELP
STA GESNO ; CLEAR VARIABLES
STA ERRS
BEQ KEY ; GET NEXT GUESS SEQUECE
WIN LDA #$FF ; TURN ALL LEDS ON FOR WIN
STA PORT1A
STA PORT1B
LDA #1 ; PLAY 8 ASCENDING TONES
WINLP PHA
JSR PLAY
PLA
CLC
ADC #01
CMP #10
BNE WINLP
BEQ STRTJP ; USE DOUBLE-JUMP FOR RESTART
;
; SUBROUTINE 'LIGHT'
; ROUTINE TO LIGHT N-TH LED, WHERE N IS THE NUMBER PASSED AS A PARAMETER IN
; THE ACCUMULATOR.
;
LIGHT PHA ; SAVE A
TAY ; USE AS COUNTER IN Y
LDA #0 ; CLEAR A FOR BIT SHIFT
STA PORT1B ; CLEAR HI LEDS.
SEC ; GENERATE HI BIT TO SHIFT LEFT.
LTSHFT ROL A ; MOVE HI BIT LEFT.
DEY ; DECREMENT COUNTER
BNE LTSHFT ; SHIFTS DONE?
STA PORT1A ; STORE CORRECT PATTERN
BCC LTCC ; BIT 9 NOT HI, DONE.
LDA #1
STA PORT1B ; TURN LED 9 ON.
LTCC PLA ; RESTORE A
RTS
;
; SUBROUTINE 'RANDOM'
; RANDOM NUMBER GENERATOR, RETURNS WITH NEW RANDOM NUMBER IN ACCUMULATOR.
;
RANDOM SEC
LDA RND+1
ADC RND+4
ADC RND+5
STA RND
LDX #4
RNDLP LDA RND,X
STA RND+1,X
DEX
BPL RNDLP
RTS
;
; SUBROUTINE 'PLAY'
; ROUTINE TO PLAY TONES WHOSE NUMBER IS PASSED IN BY ACCUMULATOR. IF ENTERED
; AT PLYTON, IT WILL PLAY TONE WHOSE LENGTH IS IN DUR, FREQUENCY IN THE
; ACCUMULATOR INSTEAD.
PLAY TAY ; USE TONE # AS INDEX...
DEY ; DECREMENT TO MATCH TABLES
LDA DURTAB,Y ; GET DURATION FOR TONE N-TH TONE
STA DUR ; SAVE IT.
LDA NOTAB,Y ; GET FREQUENCY CONSTANT FOR N-TH TONE
PLYTON STA FREQ ; SAVE IT.
LDA #0 ; SET SPKR PORT LO.
STA PORT3B
LDX DUR ; GET DURATION IN NUMBER OF 1/2 CYCLES.
FL2 LDY FREQ ; GET FREQUENCY
FL1 DEY ; COUNT DOWN DELAY...
CLC ; WASTE TIME
BCC FL0
FL0 BNE FL1 ; LOOP FOR DELAY
EOR #$FF ; COMPLEMENT PORT
STA PORT3B
DEX ; COUNT DOWN DURATION...
BNE FL2 ; LOOP UNTIL NOTE OVER.
RTS ; DONE.
;
; TABLE FOR NOTE FREQUENCIES.
;
NOTAB .HS C9.BE.A9.96.8E.7E.70.64.5E
;
; TABLE FOR NOTE DURATIONS.
;
DURTAB .HS 6B.72.80.8F.94.AA.BF.D7.E4

View File

@ -0,0 +1,4 @@
@echo off
sbasm.py mind_bender.asm
type mind_bender.list
pause

View File

@ -0,0 +1,232 @@
; 'MINDBENDER'
; PLAYS MINDBENDER GAME: USER SPECIFIES LENGTH OF NUMBER TO BE GUESSED, THEN
; GUESSES DIGITS, AND COMPUTER TELLS PLAYER HOW MANY OF THE DIGITS GUESSED
; WERE RIGHT, AND HOW MANY OF THOSE CORRECT DIGITS WERE IN THE CORRECT PLACE,
; UNTIL THE PLAYER CAN GUESS THE NUMBER ON THE BOARD. BLINKING LEDS INDICATE
; CORRECT VALUE & CORRECT DIGIT, AND NON-BLINKING LEDS SHOW CORRECT DIGIT
; VALUE, BUT WRONG PLACE.
;
; THE BOTTOM ROW OF LEDS IS USED TO SHOW THE MODE OF THE PROGRAM: IF THE
; LEFTMOST LEDS ARE LIT, THE PROGRAM EXPECTS A GUESS. THE PROGRAM REJECTS
; UNSUITABLE VALUES FOR A NUMBER LENGTH, WHICH CAN ONLY BE 1-9, A VALUE OTHER
; THAN 0-9 FOR A GUESS RESTARTS THE GAME.
;
; A LOW TONE DENOTES A BAD GUESS, A HIGH TONE, A WIN. AFTER A WIN, THE PROGRAM
; RESTARTS. AN INTERRUPT ROUTINE IS USED TO BLINK THE LEDS.
;
PORT1B .EQ VIA1 ; PORT B
PORT1A .EQ VIA1+1 ; PORT A
DDR1B .EQ VIA1+2 ; PORT B DATA DIRECTION REGISTER
DDR1A .EQ VIA1+3 ; PORT A DATA DIRECTION REGISTER
T1LL .EQ VIA1+4 ; TIMER 1 LATCH LOW
T1CH .EQ VIA1+5 ; TIMER 1 COUNTER HIGH
IER .EQ VIA1+14 ; INTERRUPT ENABLE REGISTER
ACR .EQ VIA1+11 ; AUXILLIARY CONTROL REGISTER
PORT3B .EQ VIA3 ; PORT B
PORT3A .EQ VIA3+1 ; PORT A
DDR3B .EQ VIA3+2 ; PORT B DATA DIRECTION REGISTER
DDR3A .EQ VIA3+3 ; PORT A DATA DIRECTION REGISTER
;
; VARIABLE STORAGE.
;
ZP .EQ $00
DIGITS .EQ ZP ; NUMBER OF DIGITS TO BE GUESSED
DUR .EQ ZP+1 ; TONE DURATION CONSTANT
XTEMP .EQ ZP+2 ; TEMP STORAGE FOR X REGISTER
YTEMP .EQ ZP+3 ; TEMP STORAGE FOR Y REGISTER
CNT .EQ ZP+4 ; KEEPS TRACK OF # OF MATCHES
MASKA .EQ ZP+5 ; CONTAINS PATTERN EOR-ED WITH LED
; STATUS REGISTER A TO CAUSE BLINK
MASKB .EQ ZP+6 ; LED PORT B BLINK MASK
FREQ .EQ ZP+7 ; TEMPORARY STORAGE FOR TONE FREQUENCY
CNT1 .EQ ZP+8 ; # OF CORRECT DIGITS IN RIGHT PLACE
RND .EQ ZP+9 ; FIRST OF RANDOM # LOCATIONS
DIG0 .EQ ZP+15 ; FIRST OF 9 DIGIT LOCATIONS
ENTRY0 .EQ ZP+18 ; FIRST OF 9 GUESS LOCATIONS
IRQVECL .EQ $A67E ; INTERRUPT VECTOR LOW ORDER BYTE
IRQVECH .EQ $A67F ; AND HIGH ORDER
;
; ROUTINE TO SET UP VARIABLES AND INTERRUPT TIMER FOR LED FLASHING.
;
START LDA #$EA ; LOAD LOW INTERRUPT VECTOR
STA IRQVECL ; ... AND SET AT VECTOR LOCATION.
LDA #$03 ; LOAD INTERRUPT VECTOR ...
STA IRQVECH ; ... AND STORE.
LDA #$7F ; CLEAR INTERRUPT ENABLE REGISTER
STA IER
LDA #$C0 ; ENABLE TIMER 1 INTERRUPT
STA IER
LDA #$40 ; ENABLE TIMER 1 IN FREE-RUN MODE
STA ACR
LDA #$FF
STA T1LL ; SET LOW LATCH ON TIMER 1
STA T1CH ; SET LATCH HIGH & START COUNT
CLI ; ENABLE INTERRUPTS
STA DDR1A ; SET VIA 1 PORT A FOR OUTPUT
STA DDR1B ; SET VIA 1 PORT B FOR OUTPUT
STA DDR3B ; SET VIA 3 PORT B FOR OUTPUT
KEY1 LDA #0 ; CLEAR LEDS
STA PORT1A
STA PORT1B
STA MASKA ; CLEAR BLINK MASKS
STA MASKB
;
; ROUTINE TO GET NUMBER OF DIGITS TO GUESS, THEN FILL THE DIGITS WITH RANDOM
; NUMBERS FROM 0-9.
;
LDA #%00000010 ; LIGHT LED TO SIGNAL USER TO
STA PORT1B ; INPUT # OF DIGITS NEEDED.
JSR GETKEY ; GET # OF DIGITS
CMP #10 ; IF KEY# > 9, RESTART GAME
BPL KEY1
CMP #0 ; CHECK FOR 0 DIGITS TO GUESS
BEQ KEY1 ; ... 0 DIGITS NOT ALLOWED.
STA DIGITS ; STORE VALID # OF DIGITS
LDA T1LL ; GET RANDOM #,
STA RND+1 ; USE IT TO START RANDOM
STA RND+4 ; NUMBER GENERATOR.
STA RND+5
LDY DIGITS ; GET # OF DIGITS TO BE GUESSED
DEY ; ... AND COUNT DOWN TO 0, FILLING THEM WITH VALUES
RAND JSR RANDOM ; GET RANDOM VALUE FOR DIGIT
SED
ADC #00 ; DECIMAL ADJUST
CLD
AND #%00001111 ; KEEP DIGIT < 10
STA DIG0,Y ; SAVE IT IN DIGIT TABLE.
DEY
BPL RAND ; FILL NEXT DIGIT
;
; ROUTINE TO FILL GUESS TABLE WITH USERS GUESSES
;
ENTER LDA #0 ; CLEAR ENTRY TABLE POINTER
STA XTEMP
LDA #%00000110 ; LET USER KNOW THAT GUESSES
ORA PORT1B ; SHOULD BE INPUT ...
STA PORT1B ; ... WITHOUT CHANGING ARRAY
KEY2 JSR GETKEY ; GET GUESS
CMP #10 ; IS IT GREATER THAN 9?
BPL KEY1 ; IF YES, RESTART GAME.
LDX XTEMP ; GET POINTER FOR INDEXING
STA ENTRY0,X ; STORE GUESS IN TABLE
INX ; INCREMENT POINTER
STX XTEMP
CPX DIGITS ; CORRECT # OF GUESSES FETCHED?
BNE KEY2 ; IF NOT, GET ANOTHER
;
; THIS ROUTINE COMPARES USERS GUESSES WITH DIGITS OF NUMBER TO GUESS. FOR
; EACH CORRECT DIGIT IN THE CORRECT PLACE, A BLINKING LED IS LIT, AND FOR
; EACH CORRECT DIGIT IN THE WRONG PLACE, A NON-BLINKING LED IS LIT.
;
LDX #0 ; CLEAR FOLLOWING STORAGES:
STX PORT1A ; LEDS
STX PORT1B
STX MASKA ; BLINK MASKS
STX MASKB
STX CNT ; COUNT OF MATCHES
STX CNT1 ; COUNT OF RIGHT DIGITS
DIGLP LDA DIG0,X ; LOAD 1ST DIGIT OF # FOR COMPARISON
CMP ENTRY0,X ; RIGHT GUESS, RIGHT PLACE?
BNE ENTCMP ; NO, IS RIGHT GUESS IN WRONG PLACE?
INC CNT1 ; ONE MORE RIGHT GUESS/RIGHT PLACE
BNE NEXTDIG ; EXAMINE NEXT DIGIT OF NUMBER
ENTCMP LDY #0 ; RESET GUESS # PTR FOR COMPARES
ENTRYLP CMP ENTRY0,Y ; RIGHT DIGIT, WRONG PLACE?
BNE NEXTENT ; NO, SEE IF NEXT DIGIT IS.
INC CNT ; ONE MORE RIGHT DIGIT/WRONG PLACE
BNE NEXTDIG ; EXAMINE NEXT DIGIT OF NUMBER
NEXTENT INY ; INCREMENT GUESS # POINTER
CPY DIGITS ; ALL GUESSES TESTED?
BNE ENTRYLP ; NO, TRY NEXT GUESS.
NEXTDIG INX ; INCREMENT DIGIT # POINTER
CPX DIGITS ; ALL DIGITS EVALUATED?
BNE DIGLP ; NO, CHECK NEXT DIGIT.
CLC ; GET READY FOR ADD...
LDA CNT ; OF TOTAL MATCHES TO DETERMINE
ADC CNT1 ; NUMBER OF LEDS TO LIGHT.
TAY ; TRANSFER A TO Y FOR 'LIGHT' ROUTINE
JSR LITE ; GET PATTERN TO LIGHT LEDS
STA PORT1A ; TURN LEDS ON
BCC CC ; IF CARRY=0, DON'T LIGHT PB0
LDA #1
STA PORT1B ; TURN PB0 ON.
CC LDY CNT1 ; LOAD # OF LEDS TO BLINK
JSR LITE ; GET PATTERN
STA MASKA ; START TO BLINK LEDS
BCC TEST ; IF CARRY=0, PB0 WON'T BLINK
LDA #1
STA MASKB
;
; ROUTINE TO TEST FOR WIN BY CHECKING IF # OF CORRECT DIGITS IN CORRECT
; PLACES = NUMBER OF DIGITS. IF WIN, A HIGH PITCHED SOUND IS GENERATED, AND
; IF ANY DIGIT IS WRONG, A LOW SOUND IS GENERATED INSTEAD.
;
TEST LDX CNT1 ; LOAD NUMBER OF CORRECT DIGITS
CPX DIGITS ; ALL GUESSES CORRECT?
BEQ WIN ; IF YES, PLAYER WINS
BAD LDA #$72
STA DUR ; SET UP LENGTH OF LOW TONE
LDA #$BE ; TONE VALUE FOR LOW TONE
JSR TONE ; SIGNAL BAD GUESSES WITH TONE
BEQ ENTER ; GET NEXT GUESSES
WIN LDA #$FF ; DURATION FOR HIGH TONE
STA DUR
LDA #$54 ; TONE VALUE FOR HIGH TONE
JSR TONE ; SIGNAL WIN
JMP KEY1 ; RESTART GAME
;
; ROUTINE TO FILL ACCUMULATOR WITH ONES, STARTING AT THE LOW ORDER END, UP
; TO AND INCLUDING THE BIT POSITION CORRESPONDING TO THE # OF LEDS TO BE LIT
; OR SET TO BLINKING.
;
LITE BNE STRTSH ; IF Y NOT ZERO, SHIFT ONES IN
LDA #0 ; SPECIAL CASE: RESULT IS NO ONES.
CLC
RTS
STRTSH LDA #0 ; CLEAR A SO PATTERN WILL SHOW
SHIFT SEC ; MAKE A BIT HIGH
ROL A ; SHIFT IT TO CORRECT POSITION
DEY ; BY LOOPING TO # OF GUESS/DIGIT
; MATCHES, AS PASSED IN Y
BNE SHIFT ; LOOP UNTIL DONE
RTS
;
; RANDOM NUMBER GENERATOR
; USES NUMBERS A,B,C,D,E,F STORED AS RND THROUGH RND+5: ADDS B+E+F+1 AND
; PLACES RESULT IN A, THEN SHIFTS A TO B, B TO C, ETC. THE NEW RANDOM NUMBER
; WHICH IS BETWEEN 0 AND 255 INCLUSIVE IS IN THE ACCUMULATOR ON EXIT.
;
RANDOM SEC ; CARRY ADDS VALUE 1
LDA RND+1 ; ADD A,B,E AND CARRY
ADC RND+4
ADC RND+5
STA RND
LDX #4 ; SHIFT NUMBERS OVER
RPL LDA RND,X
STA RND+1,X
DEX
BPL RPL
RTS
;
; TONE GENERATOR ROUTINE
; DURATION OF TONE (NUMBER OF CYCLES TO CREATE) SHOULD BE IN 'DUR' ON ENTRY,
; AND THE NOTE VALUE (FREQUENCY) IN THE ACCUMULATOR.
;
TONE STA FREQ
LDA #$FF
STA PORT3B
LDA #$00
LDX DUR
FL2 LDY FREQ
FL1 DEY
CLC
BCC FL0
FL0 BNE FL1
EOR #$FF
STA PORT3B
DEX
BNE FL2
RTS

View File

@ -0,0 +1,14 @@
;
; INTERRUPT-HANDLING ROUTINE
; COMPLEMENTS LEDS AT EACH INTERRUPT.
;
DOINT PHA ; SAVE ACCUMULATOR
LDA PORT1A ; GET PORT FOR COMPLEMENTING
EOR MASKA ; COMPLEMENT NECESSARY BITS
STA PORT1A ; STORE COMPLEMENTED CONTENTS
LDA PORT1B ; DO SAME WITH PORT1B
EOR MASKB
STA PORT1B
LDA T1LL ; CLEAR INTERRUPT BIT IN VIA
PLA ; RESTORE ACCUMULATOR
RTI ; DONE, RESUME PROGRAM

View File

@ -0,0 +1,19 @@
.CR 6502
.TF mind_bender.hex,INT
.LF mind_bender.list
;
; PATTERN/TONE RECALL AND ESP TEST PROGRAM. FOR THE '6502 GAMES' HARDWARE,
; BOARD SHOULD BE JUMPERED WITH VIA CHIPS AT THE ADDRESSES SPECIFIED BELOW.
; OTHER THAN THAT THE CODE IS SHOULD BE UNCHANGED FROM THE BOOK THOUGH THERE
; WILL BE SOME DIFFERENCES DUE TO ASSEMBLER USED.
;
VIA1 .EQ $C000
VIA3 .EQ $CC00
.OR $0200
.TA $0200
BEGIN JSR INITKEY
.IN game.asm
.IN ../../common/CH01-Getkey/getkey_routine.asm
.NO $03EA,$FF
.IN interrupt.asm

View File

@ -0,0 +1,33 @@
:10020000205303A9EA8D7EA6A9038D7FA6A97F8D21
:100210000EC0A9C08D0EC0A9408D0BC0A9FF8D04D2
:10022000C08D05C0588D03C08D02C08D02CCA900C1
:100230008D01C08D00C085058506A9028D00C020F6
:100240002E03C90A10E8C900F0E48500AD04C0859A
:100250000A850D850EA4008820FF02F86900D829C0
:100260000F990F008810F1A9008502A9060D00C0A2
:100270008D00C0202E03C90A10B4A6029512E8868C
:1002800002E400D0EEA2008E01C08E00C08605867A
:100290000686048608B50FD512D004E608D010A053
:1002A00000D91200D004E604D005C8C400D0F2E89A
:1002B000E400D0E118A5046508A820F1028D01C072
:1002C0009005A9018D00C0A40820F10285059004C5
:1002D000A9018506A608E400F00BA9728501A9BE54
:1002E000201203F082A9FF8501A9542012034C2E8D
:1002F00002D004A9001860A900382A88D0FB603811
:10030000A50A650D650E8509A204B509950ACA10EE
:10031000F9608507A9FF8D00CCA900A601A4078874
:10032000189000D0FA49FF8D00CCCAD0F0602C01A3
:10033000CC10FBA20F8E00CC2C01CC1005CA10F5FE
:1003400030F18AA012A2FF2C01CC30E7CAD0F88885
:10035000D0F360A9008D03CCA9FF8D02CC60FFFF14
:10036000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9D
:10037000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8D
:10038000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7D
:10039000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6D
:1003A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D
:1003B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4D
:1003C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3D
:1003D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2D
:1003E000FFFFFFFFFFFFFFFFFFFF48AD01C0450517
:1003F0008D01C0AD00C045068D00C0AD04C0684091
:00000001FF

View File

@ -0,0 +1,300 @@
0000- 4 ;
0000- 5 ; PATTERN/TONE RECALL AND ESP TEST PROGRAM. FOR THE '6502 GAMES' HARDWARE,
0000- 6 ; BOARD SHOULD BE JUMPERED WITH VIA CHIPS AT THE ADDRESSES SPECIFIED BELOW.
0000- 7 ; OTHER THAN THAT THE CODE IS SHOULD BE UNCHANGED FROM THE BOOK THOUGH THERE
0000- 8 ; WILL BE SOME DIFFERENCES DUE TO ASSEMBLER USED.
0000- 9 ;
C000- 10 VIA1 .EQ $C000
CC00- 11 VIA3 .EQ $CC00
0000- 12
0200- 13 .OR $0200
0200- 14 .TA $0200
0200-20 53 03 15 ( 6) BEGIN JSR INITKEY
0203- 16 .IN game.asm
0203- I 1 ; 'MINDBENDER'
0203- I 2 ; PLAYS MINDBENDER GAME: USER SPECIFIES LENGTH OF NUMBER TO BE GUESSED, THEN
0203- I 3 ; GUESSES DIGITS, AND COMPUTER TELLS PLAYER HOW MANY OF THE DIGITS GUESSED
0203- I 4 ; WERE RIGHT, AND HOW MANY OF THOSE CORRECT DIGITS WERE IN THE CORRECT PLACE,
0203- I 5 ; UNTIL THE PLAYER CAN GUESS THE NUMBER ON THE BOARD. BLINKING LEDS INDICATE
0203- I 6 ; CORRECT VALUE & CORRECT DIGIT, AND NON-BLINKING LEDS SHOW CORRECT DIGIT
0203- I 7 ; VALUE, BUT WRONG PLACE.
0203- I 8 ;
0203- I 9 ; THE BOTTOM ROW OF LEDS IS USED TO SHOW THE MODE OF THE PROGRAM: IF THE
0203- I 10 ; LEFTMOST LEDS ARE LIT, THE PROGRAM EXPECTS A GUESS. THE PROGRAM REJECTS
0203- I 11 ; UNSUITABLE VALUES FOR A NUMBER LENGTH, WHICH CAN ONLY BE 1-9, A VALUE OTHER
0203- I 12 ; THAN 0-9 FOR A GUESS RESTARTS THE GAME.
0203- I 13 ;
0203- I 14 ; A LOW TONE DENOTES A BAD GUESS, A HIGH TONE, A WIN. AFTER A WIN, THE PROGRAM
0203- I 15 ; RESTARTS. AN INTERRUPT ROUTINE IS USED TO BLINK THE LEDS.
0203- I 16 ;
C000- I 17 PORT1B .EQ VIA1 ; PORT B
C001- I 18 PORT1A .EQ VIA1+1 ; PORT A
C002- I 19 DDR1B .EQ VIA1+2 ; PORT B DATA DIRECTION REGISTER
C003- I 20 DDR1A .EQ VIA1+3 ; PORT A DATA DIRECTION REGISTER
C004- I 21 T1LL .EQ VIA1+4 ; TIMER 1 LATCH LOW
C005- I 22 T1CH .EQ VIA1+5 ; TIMER 1 COUNTER HIGH
C00E- I 23 IER .EQ VIA1+14 ; INTERRUPT ENABLE REGISTER
C00B- I 24 ACR .EQ VIA1+11 ; AUXILLIARY CONTROL REGISTER
0203- I 25
CC00- I 26 PORT3B .EQ VIA3 ; PORT B
CC01- I 27 PORT3A .EQ VIA3+1 ; PORT A
CC02- I 28 DDR3B .EQ VIA3+2 ; PORT B DATA DIRECTION REGISTER
CC03- I 29 DDR3A .EQ VIA3+3 ; PORT A DATA DIRECTION REGISTER
0203- I 30
0203- I 31 ;
0203- I 32 ; VARIABLE STORAGE.
0203- I 33 ;
0000- I 34 ZP .EQ $00
0000- I 35 DIGITS .EQ ZP ; NUMBER OF DIGITS TO BE GUESSED
0001- I 36 DUR .EQ ZP+1 ; TONE DURATION CONSTANT
0002- I 37 XTEMP .EQ ZP+2 ; TEMP STORAGE FOR X REGISTER
0003- I 38 YTEMP .EQ ZP+3 ; TEMP STORAGE FOR Y REGISTER
0004- I 39 CNT .EQ ZP+4 ; KEEPS TRACK OF # OF MATCHES
0005- I 40 MASKA .EQ ZP+5 ; CONTAINS PATTERN EOR-ED WITH LED
0203- I 41 ; STATUS REGISTER A TO CAUSE BLINK
0006- I 42 MASKB .EQ ZP+6 ; LED PORT B BLINK MASK
0007- I 43 FREQ .EQ ZP+7 ; TEMPORARY STORAGE FOR TONE FREQUENCY
0008- I 44 CNT1 .EQ ZP+8 ; # OF CORRECT DIGITS IN RIGHT PLACE
0009- I 45 RND .EQ ZP+9 ; FIRST OF RANDOM # LOCATIONS
000F- I 46 DIG0 .EQ ZP+15 ; FIRST OF 9 DIGIT LOCATIONS
0012- I 47 ENTRY0 .EQ ZP+18 ; FIRST OF 9 GUESS LOCATIONS
A67E- I 48 IRQVECL .EQ $A67E ; INTERRUPT VECTOR LOW ORDER BYTE
A67F- I 49 IRQVECH .EQ $A67F ; AND HIGH ORDER
0203- I 50
0203- I 51 ;
0203- I 52 ; ROUTINE TO SET UP VARIABLES AND INTERRUPT TIMER FOR LED FLASHING.
0203- I 53 ;
0203-A9 EA I 54 ( 2) START LDA #$EA ; LOAD LOW INTERRUPT VECTOR
0205-8D 7E A6 I 55 ( 4) STA IRQVECL ; ... AND SET AT VECTOR LOCATION.
0208-A9 03 I 56 ( 2) LDA #$03 ; LOAD INTERRUPT VECTOR ...
020A-8D 7F A6 I 57 ( 4) STA IRQVECH ; ... AND STORE.
020D-A9 7F I 58 ( 2) LDA #$7F ; CLEAR INTERRUPT ENABLE REGISTER
020F-8D 0E C0 I 59 ( 4) STA IER
0212-A9 C0 I 60 ( 2) LDA #$C0 ; ENABLE TIMER 1 INTERRUPT
0214-8D 0E C0 I 61 ( 4) STA IER
0217-A9 40 I 62 ( 2) LDA #$40 ; ENABLE TIMER 1 IN FREE-RUN MODE
0219-8D 0B C0 I 63 ( 4) STA ACR
021C-A9 FF I 64 ( 2) LDA #$FF
021E-8D 04 C0 I 65 ( 4) STA T1LL ; SET LOW LATCH ON TIMER 1
0221-8D 05 C0 I 66 ( 4) STA T1CH ; SET LATCH HIGH & START COUNT
0224-58 I 67 ( 2) CLI ; ENABLE INTERRUPTS
0225-8D 03 C0 I 68 ( 4) STA DDR1A ; SET VIA 1 PORT A FOR OUTPUT
0228-8D 02 C0 I 69 ( 4) STA DDR1B ; SET VIA 1 PORT B FOR OUTPUT
022B-8D 02 CC I 70 ( 4) STA DDR3B ; SET VIA 3 PORT B FOR OUTPUT
022E-A9 00 I 71 ( 2) KEY1 LDA #0 ; CLEAR LEDS
0230-8D 01 C0 I 72 ( 4) STA PORT1A
0233-8D 00 C0 I 73 ( 4) STA PORT1B
0236-85 05 I 74 ( 2) STA MASKA ; CLEAR BLINK MASKS
0238-85 06 I 75 ( 2) STA MASKB
023A- I 76 ;
023A- I 77 ; ROUTINE TO GET NUMBER OF DIGITS TO GUESS, THEN FILL THE DIGITS WITH RANDOM
023A- I 78 ; NUMBERS FROM 0-9.
023A- I 79 ;
023A-A9 02 I 80 ( 2) LDA #%00000010 ; LIGHT LED TO SIGNAL USER TO
023C-8D 00 C0 I 81 ( 4) STA PORT1B ; INPUT # OF DIGITS NEEDED.
023F-20 2E 03 I 82 ( 6) JSR GETKEY ; GET # OF DIGITS
0242-C9 0A I 83 ( 2) CMP #10 ; IF KEY# > 9, RESTART GAME
0244-10 E8 I 84 (2**) BPL KEY1
0246-C9 00 I 85 ( 2) CMP #0 ; CHECK FOR 0 DIGITS TO GUESS
0248-F0 E4 I 86 (2**) BEQ KEY1 ; ... 0 DIGITS NOT ALLOWED.
024A-85 00 I 87 ( 2) STA DIGITS ; STORE VALID # OF DIGITS
024C-AD 04 C0 I 88 ( 4) LDA T1LL ; GET RANDOM #,
024F-85 0A I 89 ( 2) STA RND+1 ; USE IT TO START RANDOM
0251-85 0D I 90 ( 2) STA RND+4 ; NUMBER GENERATOR.
0253-85 0E I 91 ( 2) STA RND+5
0255-A4 00 I 92 ( 3) LDY DIGITS ; GET # OF DIGITS TO BE GUESSED
0257-88 I 93 ( 2) DEY ; ... AND COUNT DOWN TO 0, FILLING THEM WITH VALUES
0258-20 FF 02 I 94 ( 6) RAND JSR RANDOM ; GET RANDOM VALUE FOR DIGIT
025B-F8 I 95 ( 2) SED
025C-69 00 I 96 ( 2) ADC #00 ; DECIMAL ADJUST
025E-D8 I 97 ( 2) CLD
025F-29 0F I 98 ( 2) AND #%00001111 ; KEEP DIGIT < 10
0261-99 0F 00 I 99 ( 5) STA DIG0,Y ; SAVE IT IN DIGIT TABLE.
0264-88 I 100 ( 2) DEY
0265-10 F1 I 101 (2**) BPL RAND ; FILL NEXT DIGIT
0267- I 102 ;
0267- I 103 ; ROUTINE TO FILL GUESS TABLE WITH USERS GUESSES
0267- I 104 ;
0267-A9 00 I 105 ( 2) ENTER LDA #0 ; CLEAR ENTRY TABLE POINTER
0269-85 02 I 106 ( 2) STA XTEMP
026B-A9 06 I 107 ( 2) LDA #%00000110 ; LET USER KNOW THAT GUESSES
026D-0D 00 C0 I 108 ( 4) ORA PORT1B ; SHOULD BE INPUT ...
0270-8D 00 C0 I 109 ( 4) STA PORT1B ; ... WITHOUT CHANGING ARRAY
0273-20 2E 03 I 110 ( 6) KEY2 JSR GETKEY ; GET GUESS
0276-C9 0A I 111 ( 2) CMP #10 ; IS IT GREATER THAN 9?
0278-10 B4 I 112 (2**) BPL KEY1 ; IF YES, RESTART GAME.
027A-A6 02 I 113 ( 3) LDX XTEMP ; GET POINTER FOR INDEXING
027C-95 12 I 114 ( 4) STA ENTRY0,X ; STORE GUESS IN TABLE
027E-E8 I 115 ( 2) INX ; INCREMENT POINTER
027F-86 02 I 116 ( 3) STX XTEMP
0281-E4 00 I 117 ( 3) CPX DIGITS ; CORRECT # OF GUESSES FETCHED?
0283-D0 EE I 118 (2**) BNE KEY2 ; IF NOT, GET ANOTHER
0285- I 119 ;
0285- I 120 ; THIS ROUTINE COMPARES USERS GUESSES WITH DIGITS OF NUMBER TO GUESS. FOR
0285- I 121 ; EACH CORRECT DIGIT IN THE CORRECT PLACE, A BLINKING LED IS LIT, AND FOR
0285- I 122 ; EACH CORRECT DIGIT IN THE WRONG PLACE, A NON-BLINKING LED IS LIT.
0285- I 123 ;
0285-A2 00 I 124 ( 2) LDX #0 ; CLEAR FOLLOWING STORAGES:
0287-8E 01 C0 I 125 ( 4) STX PORT1A ; LEDS
028A-8E 00 C0 I 126 ( 4) STX PORT1B
028D-86 05 I 127 ( 3) STX MASKA ; BLINK MASKS
028F-86 06 I 128 ( 3) STX MASKB
0291-86 04 I 129 ( 3) STX CNT ; COUNT OF MATCHES
0293-86 08 I 130 ( 3) STX CNT1 ; COUNT OF RIGHT DIGITS
0295-B5 0F I 131 ( 4) DIGLP LDA DIG0,X ; LOAD 1ST DIGIT OF # FOR COMPARISON
0297-D5 12 I 132 ( 4) CMP ENTRY0,X ; RIGHT GUESS, RIGHT PLACE?
0299-D0 04 I 133 (2**) BNE ENTCMP ; NO, IS RIGHT GUESS IN WRONG PLACE?
029B-E6 08 I 134 ( 5) INC CNT1 ; ONE MORE RIGHT GUESS/RIGHT PLACE
029D-D0 10 I 135 (2**) BNE NEXTDIG ; EXAMINE NEXT DIGIT OF NUMBER
029F-A0 00 I 136 ( 2) ENTCMP LDY #0 ; RESET GUESS # PTR FOR COMPARES
02A1-D9 12 00 I 137 ( 4*) ENTRYLP CMP ENTRY0,Y ; RIGHT DIGIT, WRONG PLACE?
02A4-D0 04 I 138 (2**) BNE NEXTENT ; NO, SEE IF NEXT DIGIT IS.
02A6-E6 04 I 139 ( 5) INC CNT ; ONE MORE RIGHT DIGIT/WRONG PLACE
02A8-D0 05 I 140 (2**) BNE NEXTDIG ; EXAMINE NEXT DIGIT OF NUMBER
02AA-C8 I 141 ( 2) NEXTENT INY ; INCREMENT GUESS # POINTER
02AB-C4 00 I 142 ( 3) CPY DIGITS ; ALL GUESSES TESTED?
02AD-D0 F2 I 143 (2**) BNE ENTRYLP ; NO, TRY NEXT GUESS.
02AF-E8 I 144 ( 2) NEXTDIG INX ; INCREMENT DIGIT # POINTER
02B0-E4 00 I 145 ( 3) CPX DIGITS ; ALL DIGITS EVALUATED?
02B2-D0 E1 I 146 (2**) BNE DIGLP ; NO, CHECK NEXT DIGIT.
02B4-18 I 147 ( 2) CLC ; GET READY FOR ADD...
02B5-A5 04 I 148 ( 3) LDA CNT ; OF TOTAL MATCHES TO DETERMINE
02B7-65 08 I 149 ( 3) ADC CNT1 ; NUMBER OF LEDS TO LIGHT.
02B9-A8 I 150 ( 2) TAY ; TRANSFER A TO Y FOR 'LIGHT' ROUTINE
02BA-20 F1 02 I 151 ( 6) JSR LITE ; GET PATTERN TO LIGHT LEDS
02BD-8D 01 C0 I 152 ( 4) STA PORT1A ; TURN LEDS ON
02C0-90 05 I 153 (2**) BCC CC ; IF CARRY=0, DON'T LIGHT PB0
02C2-A9 01 I 154 ( 2) LDA #1
02C4-8D 00 C0 I 155 ( 4) STA PORT1B ; TURN PB0 ON.
02C7-A4 08 I 156 ( 3) CC LDY CNT1 ; LOAD # OF LEDS TO BLINK
02C9-20 F1 02 I 157 ( 6) JSR LITE ; GET PATTERN
02CC-85 05 I 158 ( 2) STA MASKA ; START TO BLINK LEDS
02CE-90 04 I 159 (2**) BCC TEST ; IF CARRY=0, PB0 WON'T BLINK
02D0-A9 01 I 160 ( 2) LDA #1
02D2-85 06 I 161 ( 2) STA MASKB
02D4- I 162 ;
02D4- I 163 ; ROUTINE TO TEST FOR WIN BY CHECKING IF # OF CORRECT DIGITS IN CORRECT
02D4- I 164 ; PLACES = NUMBER OF DIGITS. IF WIN, A HIGH PITCHED SOUND IS GENERATED, AND
02D4- I 165 ; IF ANY DIGIT IS WRONG, A LOW SOUND IS GENERATED INSTEAD.
02D4- I 166 ;
02D4-A6 08 I 167 ( 3) TEST LDX CNT1 ; LOAD NUMBER OF CORRECT DIGITS
02D6-E4 00 I 168 ( 3) CPX DIGITS ; ALL GUESSES CORRECT?
02D8-F0 0B I 169 (2**) BEQ WIN ; IF YES, PLAYER WINS
02DA-A9 72 I 170 ( 2) BAD LDA #$72
02DC-85 01 I 171 ( 2) STA DUR ; SET UP LENGTH OF LOW TONE
02DE-A9 BE I 172 ( 2) LDA #$BE ; TONE VALUE FOR LOW TONE
02E0-20 12 03 I 173 ( 6) JSR TONE ; SIGNAL BAD GUESSES WITH TONE
02E3-F0 82 I 174 (2**) BEQ ENTER ; GET NEXT GUESSES
02E5-A9 FF I 175 ( 2) WIN LDA #$FF ; DURATION FOR HIGH TONE
02E7-85 01 I 176 ( 2) STA DUR
02E9-A9 54 I 177 ( 2) LDA #$54 ; TONE VALUE FOR HIGH TONE
02EB-20 12 03 I 178 ( 6) JSR TONE ; SIGNAL WIN
02EE-4C 2E 02 I 179 ( 3) JMP KEY1 ; RESTART GAME
02F1- I 180 ;
02F1- I 181 ; ROUTINE TO FILL ACCUMULATOR WITH ONES, STARTING AT THE LOW ORDER END, UP
02F1- I 182 ; TO AND INCLUDING THE BIT POSITION CORRESPONDING TO THE # OF LEDS TO BE LIT
02F1- I 183 ; OR SET TO BLINKING.
02F1- I 184 ;
02F1-D0 04 I 185 (2**) LITE BNE STRTSH ; IF Y NOT ZERO, SHIFT ONES IN
02F3-A9 00 I 186 ( 2) LDA #0 ; SPECIAL CASE: RESULT IS NO ONES.
02F5-18 I 187 ( 2) CLC
02F6-60 I 188 ( 6) RTS
02F7-A9 00 I 189 ( 2) STRTSH LDA #0 ; CLEAR A SO PATTERN WILL SHOW
02F9-38 I 190 ( 2) SHIFT SEC ; MAKE A BIT HIGH
02FA-2A I 191 ( 2) ROL A ; SHIFT IT TO CORRECT POSITION
02FB-88 I 192 ( 2) DEY ; BY LOOPING TO # OF GUESS/DIGIT
02FC- I 193 ; MATCHES, AS PASSED IN Y
02FC-D0 FB I 194 (2**) BNE SHIFT ; LOOP UNTIL DONE
02FE-60 I 195 ( 6) RTS
02FF- I 196 ;
02FF- I 197 ; RANDOM NUMBER GENERATOR
02FF- I 198 ; USES NUMBERS A,B,C,D,E,F STORED AS RND THROUGH RND+5: ADDS B+E+F+1 AND
02FF- I 199 ; PLACES RESULT IN A, THEN SHIFTS A TO B, B TO C, ETC. THE NEW RANDOM NUMBER
02FF- I 200 ; WHICH IS BETWEEN 0 AND 255 INCLUSIVE IS IN THE ACCUMULATOR ON EXIT.
02FF- I 201 ;
02FF-38 I 202 ( 2) RANDOM SEC ; CARRY ADDS VALUE 1
0300-A5 0A I 203 ( 3) LDA RND+1 ; ADD A,B,E AND CARRY
0302-65 0D I 204 ( 3) ADC RND+4
0304-65 0E I 205 ( 3) ADC RND+5
0306-85 09 I 206 ( 2) STA RND
0308-A2 04 I 207 ( 2) LDX #4 ; SHIFT NUMBERS OVER
030A-B5 09 I 208 ( 4) RPL LDA RND,X
030C-95 0A I 209 ( 4) STA RND+1,X
030E-CA I 210 ( 2) DEX
030F-10 F9 I 211 (2**) BPL RPL
0311-60 I 212 ( 6) RTS
0312- I 213 ;
0312- I 214 ; TONE GENERATOR ROUTINE
0312- I 215 ; DURATION OF TONE (NUMBER OF CYCLES TO CREATE) SHOULD BE IN 'DUR' ON ENTRY,
0312- I 216 ; AND THE NOTE VALUE (FREQUENCY) IN THE ACCUMULATOR.
0312- I 217 ;
0312-85 07 I 218 ( 2) TONE STA FREQ
0314-A9 FF I 219 ( 2) LDA #$FF
0316-8D 00 CC I 220 ( 4) STA PORT3B
0319-A9 00 I 221 ( 2) LDA #$00
031B-A6 01 I 222 ( 3) LDX DUR
031D-A4 07 I 223 ( 3) FL2 LDY FREQ
031F-88 I 224 ( 2) FL1 DEY
0320-18 I 225 ( 2) CLC
0321-90 00 I 226 (2**) BCC FL0
0323-D0 FA I 227 (2**) FL0 BNE FL1
0325-49 FF I 228 ( 2) EOR #$FF
0327-8D 00 CC I 229 ( 4) STA PORT3B
032A-CA I 230 ( 2) DEX
032B-D0 F0 I 231 (2**) BNE FL2
032D-60 I 232 ( 6) RTS
032E- 17 .IN ../../common/CH01-Getkey/getkey_routine.asm
032E- I 1 ; 'GETKEY' KEYBOARD INPUT ROUTINE READS AND DEBOUNCES KEYBOARD. RETURNS WITH
032E- I 2 ; KEY NUMBER IN ACCUMULATOR IF KEY DOWN. OPERATION: SENDS NUMBERS 0-F TO 74154
032E- I 3 ; (4 TO 16 LINE DECODER), WHICH GROUNDS ONE SIDE OF KEYSWITCHES ONE AT A TIME.
032E- I 4 ; IF A KEY IS DOWN, PA7 OF VIA #3 WILL BE GROUNDED, AND THE CURRENT VALUE
032E- I 5 ; APPLIED TO THE 74154 BE THE KEY NUMBER. WHEN THE PROGRAM DETECTS A KEY CLOSE
032E- I 6 ; CHECKS FOR KEY CLOSURE FOR 50 MS. TO ELIMINATE BOUNCE.
032E- I 7 ; NOTE: IF NO KEY IS PRESSED, GETKEY WILL WAIT.
032E- I 8 ;
032E-2C 01 CC I 9 ( 4) GETKEY BIT PORT3A ; SEE IF KEY IS STILL DOWN FROM LAST KEY CLOSURE:
0331- I 10 ; KEYSTROBE IN 'N' STATUS BIT.
0331-10 FB I 11 (2**) BPL GETKEY ; IF YES, WAIT FOR KEY RELEASE
0333-A2 0F I 12 ( 2) RSTART LDX #15 ; SET KEY COUNTER TO 15
0335-8E 00 CC I 13 ( 4) NXTKEY STX PORT3B ; OUTPUT KEY # TO 74154
0338-2C 01 CC I 14 ( 4) BIT PORT3A ; SEE IF KEY DOWN: STROBE IN 'N'
033B-10 05 I 15 (2**) BPL BOUNCE ; IF YES, GO DEBOUNCE
033D-CA I 16 ( 2) DEX ; DECREMENT KEY #
033E-10 F5 I 17 (2**) BPL NXTKEY ; NO, DO NEXT KEY
0340-30 F1 I 18 (2**) BMI RSTART ; START OVER
0342-8A I 19 ( 2) BOUNCE TXA ; SAVE KEY NUMBER IN A
0343-A0 12 I 20 ( 2) LDY #$12 ; OUTER LOOP CNT LOAD FOR DELAY OF 50 MS.
0345-A2 FF I 21 ( 2) LP1 LDX #$FF ; INNER 11 US. LOOP
0347-2C 01 CC I 22 ( 4) LP2 BIT PORT3A ; SEE IF KEY STILL DOWN
034A-30 E7 I 23 (2**) BMI RSTART ; IF NOT, KEY NOT VALID, RESTART
034C-CA I 24 ( 2) DEX
034D-D0 F8 I 25 (2**) BNE LP2 ; THIS LOOP USES 2115*5 US.
034F-88 I 26 ( 2) DEY
0350-D0 F3 I 27 (2**) BNE LP1 ; OUTER LOOP: TOTAL IS 50 MS.
0352-60 I 28 ( 6) RTS ; DONE: KEY IN A.
0353- I 29 ;
0353- I 30 ; SUBROUTINE 'INITKEY'
0353- I 31 ; TAKES CARE OF INITIALIZING VIA #3 FOR USING WITH THE GETKEY ROUTINE FROM
0353- I 32 ; THE CODE.
0353- I 33 ;
0353-A9 00 I 34 ( 2) INITKEY LDA #0
0355-8D 03 CC I 35 ( 4) STA DDR3A ; SET KEY STROBE PORT FOR INPUT
0358-A9 FF I 36 ( 2) LDA #$FF
035A-8D 02 CC I 37 ( 4) STA DDR3B ; SET KEYS FOR OUTPUT
035D-60 I 38 ( 6) RTS
03EA 18 .NO $03EA,$FF
03EA- 19 .IN interrupt.asm
03EA- I 1 ;
03EA- I 2 ; INTERRUPT-HANDLING ROUTINE
03EA- I 3 ; COMPLEMENTS LEDS AT EACH INTERRUPT.
03EA- I 4 ;
03EA-48 I 5 ( 3) DOINT PHA ; SAVE ACCUMULATOR
03EB-AD 01 C0 I 6 ( 4) LDA PORT1A ; GET PORT FOR COMPLEMENTING
03EE-45 05 I 7 ( 3) EOR MASKA ; COMPLEMENT NECESSARY BITS
03F0-8D 01 C0 I 8 ( 4) STA PORT1A ; STORE COMPLEMENTED CONTENTS
03F3-AD 00 C0 I 9 ( 4) LDA PORT1B ; DO SAME WITH PORT1B
03F6-45 06 I 10 ( 3) EOR MASKB
03F8-8D 00 C0 I 11 ( 4) STA PORT1B
03FB-AD 04 C0 I 12 ( 4) LDA T1LL ; CLEAR INTERRUPT BIT IN VIA
03FE-68 I 13 ( 4) PLA ; RESTORE ACCUMULATOR
03FF-40 I 14 ( 6) RTI ; DONE, RESUME PROGRAM