Chapter 5

This commit is contained in:
Tor-Eirik Bakke Lunde 2020-03-02 20:05:09 +01:00
parent a311c252ca
commit 8a4310ad55
21 changed files with 2968 additions and 275 deletions

View File

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

View File

@ -0,0 +1,23 @@
.CR 65C02
.TF magicsquare.hex,hex
.LF magicsquare.list
;
; MAGIC SQUARE GAME FOR THE KIM-1 USING '6502 GAMES' HARDWARE. BOARD SHOULD BE
; JUMPERED WITH VIA CHIPS AT THE ADDRESSES SPECIFIED BELOW. OTHER THAN THAT
; THE CODE IS UNCHANGED FROM THE BOOK.
;
VIA1 .EQ $4000 ; GAME BOARD (VIA #1)
VIA3 .EQ $4C00 ; GAME BOARD (VIA #3)
.OR $8000
.TA $0000
BE6502 JSR INITKEY
.IN ../../common/CH05-MagicSquare/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,155 @@
0000- 4 ;
0000- 5 ; MAGIC SQUARE GAME FOR THE KIM-1 USING '6502 GAMES' HARDWARE. BOARD SHOULD BE
0000- 6 ; JUMPERED WITH VIA CHIPS AT THE ADDRESSES SPECIFIED BELOW. OTHER THAN THAT
0000- 7 ; THE CODE IS UNCHANGED FROM THE BOOK.
0000- 8 ;
4000- 9 VIA1 .EQ $4000 ; GAME BOARD (VIA #1)
4C00- 10 VIA3 .EQ $4C00 ; GAME BOARD (VIA #3)
0000- 11
8000- 12 .OR $8000
8000- 13 .TA $0000
8000-20 A4 80 14 ( 6) BE6502 JSR INITKEY
8003- 15 .IN ../../common/CH05-MagicSquare/game.asm
8003- I 1 ; 'MAGIC SQUARE'
8003- I 2 ; KEYS 1-9 ON THE HEX KEYBOARD ARE EACH ASSOCIATED WITH ON LED IN THE 3X3
8003- I 3 ; ARRAY. WHEN A KEY IS PRESSET, IT CHANGES THE PATTERN OF THE LIT LEDS IN THE
8003- I 4 ; ARRAY. THE OBJECT OF THE GAME IS TO CONVERT THE RANDOM PATTERN THE GAME
8003- I 5 ; STARTS WITH TO A SQUARE OF LIT LEDS BY PRESSING THE KEYS. THE LEDS WILL FLASH
8003- I 6 ; WHEN THE WINNING PATTERN IS ACHIEVED. KEY #0 CAN BE USED AT ANY TIME TO
8003- I 7 ; RESTART THE GAME WITH A NEW PATTERN.
8003- I 8 ;
8003- I 9 ;
4004- I 10 T1CL .EQ VIA1+4 ; LOW LATCH OF TIMER 1
4003- I 11 DDR1A .EQ VIA1+3 ; PORT A DATA DIRECTION REGISTER
4002- I 12 DDR1B .EQ VIA1+2 ; PORT B DATA DIRECTION REGISTER
4001- I 13 PORT1A .EQ VIA1+1 ; PORT A
4000- I 14 PORT2 .EQ VIA1
4000- I 15 PORT1B .EQ VIA1 ; PORT B
4C03- I 16 DDR3A .EQ VIA3+3 ; PORT A DATA DIRECTION REGISTER
4C02- I 17 DDR3B .EQ VIA3+2 ; PORT B DATA DIRECTION REGISTER
4C00- I 18 PORT3B .EQ VIA3 ; PORT B
4C01- I 19 PORT3A .EQ VIA3+1 ; PORT A
8003- I 20
0000- I 21 ZP .EQ $00
0000- I 22 TEMP .EQ ZP ; TEMPORARY STORAGE
8003- I 23 ;
8003- I 24 ; COMMENTS: THIS PROGRAM USES A TIMER REGISTER FOR A RANDOM NUMBER SOURCE. IF
8003- I 25 ; NONE IS AVAILABLE, A RANDOM NUMBER GENERATOR COULD BE USED, BUT DUE TO ITS
8003- I 26 ; REPEATABILITY, IT WOULD NOT WORK AS WELL. THIS PROGRAM USES THE REGISTERS OF
8003- I 27 ; VIA1 PORT A FOR THE STORAGE OF THE LED PATTERN. SINCE WHAT IS READ BY THE
8003- I 28 ; PROCESSOR IS THE POLARITY OF THE OUTPUT, AN EXCESSIVE LOAD ON THE LINES WOULD
8003- I 29 ; PREVENT THE PROGAM FROM WORKING CORRECTLY.
8003- I 30 ;
8003-A9 FF I 31 ( 2) LDA #$FF ; SET UP DATA DIRECTION REGISTERS
8005-8D 03 40 I 32 ( 4) STA DDR1A
8008-8D 02 40 I 33 ( 4) STA DDR1B
800B-AD 04 40 I 34 ( 4) START LDA T1CL ; GET 1ST RANDOM NUMBER
800E-8D 01 40 I 35 ( 4) STA PORT1A
8011-AD 04 40 I 36 ( 4) LDA T1CL ; ... AND SECOND.
8014-29 01 I 37 ( 2) AND #01 ; MASK OUT BOTTOM ROW LEDS
8016-8D 00 40 I 38 ( 4) STA PORT1B
8019-20 7F 80 I 39 ( 6) KEY JSR GETKEY
801C-C9 00 I 40 ( 2) CMP #0 ; KEY MUST BE 1-9: IS IT 0?
801E-F0 EB I 41 (2**) BEQ START ; YES, RESTART GAME WITH NEW BOARD.
8020-C9 0A I 42 ( 2) CMP #10 ; IS IT LESS THAN 10?
8022-10 F5 I 43 (2**) BPL KEY ; + IF KEY >=10, SO GET ANOTHER.
8024- I 44 ;
8024- I 45 ; FOLLOWING SECTION USES KEY NUMBER AS INDEX TO FIND IN TABLE A BIT PATTERN
8024- I 46 ; USED TO COMPLEMENT LEDS.
8024- I 47 ;
8024-38 I 48 ( 2) SEC ; DECREMENT A FOR TABLE ACCESS
8025-E9 01 I 49 ( 2) SBC #1
8027-0A I 50 ( 2) ASL A ; MULTIPLY A*2 (EACH ENTRY IN TABLE IS 2 BYTES)
8028-AA I 51 ( 2) TAX ; USE A AS INDEX
8029-AD 01 40 I 52 ( 4) LDA PORT1A ; GET PORT CONTENTS FOR COMPLEMENT
802C-5D 6E 80 I 53 ( 4*) EOR TABLE,X ; EOR PORT CONTENTS WITH PATTERN
802F-8D 01 40 I 54 ( 4) STA PORT1A ; RESTORE PORT1A
8032-AD 00 40 I 55 ( 4) LDA PORT1B ; DO SAME FOR PORT1B,
8035-5D 6F 80 I 56 ( 4*) EOR TABLE+1,X ; ... USING NEXT TABLE ENTRY.
8038-29 01 I 57 ( 2) AND #01 ; MASK OUT BOTTOM ROW LEDS
803A-8D 00 40 I 58 ( 4) STA PORT1B ; ... AND RESTORE.
803D- I 59 ;
803D- I 60 ; THIS SECTION CHECKS FOR WINNING PATTERN IN LEDS.
803D- I 61 ;
803D-4A I 62 ( 2) LSR A ; SHIFT BIT 0 OF PORT 1 INTO CARRY.
803E-90 D9 I 63 (2**) BCC KEY ; IF NOT WIN PATTERN, GET NEXT MOVE.
8040-AD 01 40 I 64 ( 4) LDA PORT1A ; LOAD PORT1A FOR WIN TEST
8043-C9 EF I 65 ( 2) CMP #%11101111 ; CHECK FOR WIN PATTERN
8045-D0 D2 I 66 (2**) BNE KEY ; NO WIN, GET NEXT MOVE
8047- I 67 ;
8047- I 68 ; WIN - BLINK LEDS EVERY 1/2 SECOND, 4 TIMES
8047- I 69 ;
8047-A9 0E I 70 ( 2) LDA #14
8049-85 00 I 71 ( 3) STA TEMP ; LOAD NUMBER OF BLINKS
804B-A2 20 I 72 ( 2) BLINK LDX #$20 ; DELAY CONSTANT FOR .08 SECOND
804D-A0 FF I 73 ( 2) DELAY LDY #$FF ; OUTER LOOP OF VARIABLE DELAY ROUTINE, WHOSE DELAY
804F- I 74 ; IS 2556 * (CONTENTS OF X ON ENTER
804F-EA I 75 ( 2) DLY NOP ; 10 MICROSECOND LOOP)
8050-D0 00 I 76 (2**) BNE DLY0
8052-88 I 77 ( 2) DLY0 DEY
8053-D0 FA I 78 (2**) BNE DLY
8055-CA I 79 ( 2) DEX
8056-D0 F5 I 80 (2**) BNE DELAY
8058-AD 01 40 I 81 ( 4) LDA PORT1A ; GET PORTS AND COMPLEMENT THEM
805B-49 FF I 82 ( 2) EOR #$FF
805D-8D 01 40 I 83 ( 4) STA PORT1A
8060-AD 00 40 I 84 ( 4) LDA PORT1B
8063-49 01 I 85 ( 2) EOR #1
8065-8D 00 40 I 86 ( 4) STA PORT1B
8068-C6 00 I 87 ( 5) DEC TEMP ; COUNT DOWN NUMBER OF BLINKS
806A-D0 DF I 88 (2**) BNE BLINK ; DO AGAIN IF NOT DONE
806C-F0 AB I 89 (2**) BEQ KEY
806E- I 90 ;
806E- I 91 ; TABLE OF CODES USED TO COMPLEMENT LEDS
806E- I 92 ;
806E-1B 00 07 36
00 49 00 BA
00 24 01 D8
00 C0 01 B0
01 I 93 TABLE .HS 1B.00.07.36.00.49.00.BA.00.24.01.D8.00.C0.01.B0.01
807F- 16 .IN ../../common/CH01-Getkey/getkey_routine.asm
807F- I 1 ; 'GETKEY' KEYBOARD INPUT ROUTINE READS AND DEBOUNCES KEYBOARD. RETURNS WITH
807F- I 2 ; KEY NUMBER IN ACCUMULATOR IF KEY DOWN. OPERATION: SENDS NUMBERS 0-F TO 74154
807F- I 3 ; (4 TO 16 LINE DECODER), WHICH GROUNDS ONE SIDE OF KEYSWITCHES ONE AT A TIME.
807F- I 4 ; IF A KEY IS DOWN, PA7 OF VIA #3 WILL BE GROUNDED, AND THE CURRENT VALUE
807F- I 5 ; APPLIED TO THE 74154 BE THE KEY NUMBER. WHEN THE PROGRAM DETECTS A KEY CLOSE
807F- I 6 ; CHECKS FOR KEY CLOSURE FOR 50 MS. TO ELIMINATE BOUNCE.
807F- I 7 ; NOTE: IF NO KEY IS PRESSED, GETKEY WILL WAIT.
807F- I 8 ;
807F-2C 01 4C I 9 ( 4) GETKEY BIT PORT3A ; SEE IF KEY IS STILL DOWN FROM LAST KEY CLOSURE:
8082- I 10 ; KEYSTROBE IN 'N' STATUS BIT.
8082-10 FB I 11 (2**) BPL GETKEY ; IF YES, WAIT FOR KEY RELEASE
8084-A2 0F I 12 ( 2) RSTART LDX #15 ; SET KEY COUNTER TO 15
8086-8E 00 4C I 13 ( 4) NXTKEY STX PORT3B ; OUTPUT KEY # TO 74154
8089-2C 01 4C I 14 ( 4) BIT PORT3A ; SEE IF KEY DOWN: STROBE IN 'N'
808C-10 05 I 15 (2**) BPL BOUNCE ; IF YES, GO DEBOUNCE
808E-CA I 16 ( 2) DEX ; DECREMENT KEY #
808F-10 F5 I 17 (2**) BPL NXTKEY ; NO, DO NEXT KEY
8091-30 F1 I 18 (2**) BMI RSTART ; START OVER
8093-8A I 19 ( 2) BOUNCE TXA ; SAVE KEY NUMBER IN A
8094-A0 12 I 20 ( 2) LDY #$12 ; OUTER LOOP CNT LOAD FOR DELAY OF 50 MS.
8096-A2 FF I 21 ( 2) LP1 LDX #$FF ; INNER 11 US. LOOP
8098-2C 01 4C I 22 ( 4) LP2 BIT PORT3A ; SEE IF KEY STILL DOWN
809B-30 E7 I 23 (2**) BMI RSTART ; IF NOT, KEY NOT VALID, RESTART
809D-CA I 24 ( 2) DEX
809E-D0 F8 I 25 (2**) BNE LP2 ; THIS LOOP USES 2115*5 US.
80A0-88 I 26 ( 2) DEY
80A1-D0 F3 I 27 (2**) BNE LP1 ; OUTER LOOP: TOTAL IS 50 MS.
80A3-60 I 28 ( 6) RTS ; DONE: KEY IN A.
80A4- I 29 ;
80A4- I 30 ; SUBROUTINE 'INITKEY'
80A4- I 31 ; TAKES CARE OF INITIALIZING VIA #3 FOR USING WITH THE GETKEY ROUTINE FROM
80A4- I 32 ; THE CODE.
80A4- I 33 ;
80A4-A9 00 I 34 ( 2) INITKEY LDA #0
80A6-8D 03 4C I 35 ( 4) STA DDR3A ; SET KEY STROBE PORT FOR INPUT
80A9-A9 FF I 36 ( 2) LDA #$FF
80AB-8D 02 4C I 37 ( 4) STA DDR3B ; SET KEYS FOR OUTPUT
80AE-60 I 38 ( 6) RTS
80AF- 17 ;
80AF- 18 ; STORE CPU INITIALIZATION VECTORS AT THE END OF THE EEPROM.
80AF- 19 ;
FFFA 20 .NO $FFFA,$FF
FFFA-00 80 21 .DA BE6502 ; NMI VECTOR
FFFC-00 80 22 .DA BE6502 ; RESET VECTOR
FFFE-00 80 23 .DA BE6502 ; IRQ VECTOR

View File

@ -11,5 +11,6 @@ VIA3 .EQ $CC00
.OR $0200
.TA $0200
RCONE JSR INITKEY
.IN ../../common/CH02-Music/player.asm
.IN ../../common/CH01-Getkey/getkey_routine.asm

View File

@ -1,17 +1,18 @@
A90085001820E802C90FD00520870290
EFC90ED0062048021890EA8501207002
A500C9FFD00520870290DA4AA8A501B0
09290F990003E60090CB0A0A0A0A1900
03990003E60090BDA2008602A5024AAA
BD0003B004290F900629F04A4A4A4A20
7002A220209C02E602A502C50090DF60
C90DD006A254209C0260AABDD1028504
BDC40220A80260A9FF8504A94B20A802
A93820A802A94B20A8021860A0FFEAD0
0088D0FACAD0F5608503A9FF8D02CCA9
00A604A40388189000D0FA49FF8D00CC
CAD0F060FEE2C9BEA9968E867E777064
5E55606B72808F94A1AAB5BFD7E4A900
8D03CCA9FF8D02CC2C01CC10FBA20F8E
00CC2C01CC1005CA10F530F18AA012A2
FF2C01CC30E7CAD0F888D0F360
200603A90085001820E102C90FD00520
8A0290EFC90ED006204B021890EA8501
207302A500C9FFD005208A0290DA4AA8
A501B009290F990003E60090CB0A0A0A
0A190003990003E60090BDA2008602A5
024AAABD0003B004290F900629F04A4A
4A4A207302A220209F02E602A502C500
90DF60C90DD006A254209F0260AABDD4
028504BDC70220AB0260A9FF8504A94B
20AB02A93820AB02A94B20AB021860A0
FFEAD00088D0FACAD0F5608503A9FF8D
02CCA900A604A40388189000D0FA49FF
8D00CCCAD0F060FEE2C9BEA9968E867E
7770645E55606B72808F94A1AAB5BFD7
E42C01CC10FBA20F8E00CC2C01CC1005
CA10F530F18AA012A2FF2C01CC30E7CA
D0F888D0F360A9008D03CCA9FF8D02CC
60

View File

@ -8,15 +8,16 @@ CC00- 10 VIA3 .EQ $CC00
0000- 11
0200- 12 .OR $0200
0200- 13 .TA $0200
0200- 14 .IN ../../common/CH02-Music/player.asm
0200- I 1 ; MUSIC PLAYER PROGRAM
0200- I 2 ; USES 16-KEY KEYBOARD AND BUFFERED SPEAKER
0200- I 3 ; PROGRAM PLAYS STORED MUSICAL NOTES. THERE ARE TWO MODES OF OPERATION: INPUT
0200- I 4 ; AND PLAY. INPUT MODE IS THE DEFAULT, AND ALL NON-COMMAND KEYS PRESSED PRESSED
0200- I 5 ; (0-D) ARE STORED FOR REPLAY. IF AN OVERFLOW OCCURS, THE USER IS WARMED WITH
0200- I 6 ; A THREE-TONE WARNING. THE SAME WARBLING TONE IS ALSO USED TO SIGNAL A RESTART
0200- I 7 ; OF THE PROGRAM.
0200- I 8 ;
0200-20 06 03 14 ( 6) RCONE JSR INITKEY
0203- 15 .IN ../../common/CH02-Music/player.asm
0203- I 1 ; MUSIC PLAYER PROGRAM
0203- I 2 ; USES 16-KEY KEYBOARD AND BUFFERED SPEAKER
0203- I 3 ; PROGRAM PLAYS STORED MUSICAL NOTES. THERE ARE TWO MODES OF OPERATION: INPUT
0203- I 4 ; AND PLAY. INPUT MODE IS THE DEFAULT, AND ALL NON-COMMAND KEYS PRESSED PRESSED
0203- I 5 ; (0-D) ARE STORED FOR REPLAY. IF AN OVERFLOW OCCURS, THE USER IS WARNED WITH
0203- I 6 ; A THREE-TONE WARNING. THE SAME WARBLING TONE IS ALSO USED TO SIGNAL A RESTART
0203- I 7 ; OF THE PROGRAM.
0203- I 8 ;
0000- I 9 PILEN .EQ $00 ; LENGTH OF NOTE LIST
0001- I 10 TEMP .EQ $01 ; TEMPORARY STORAGE
0002- I 11 PTR .EQ $02 ; CURRENT LOCATION IN LIST
@ -25,188 +26,193 @@ CC00- 10 VIA3 .EQ $CC00
0300- I 14 TABEG .EQ $0300 ; TABLE TO STORE MUSIC
CC00- I 15 PORT3B .EQ VIA3 ; VIA OUTPUT PORT B
CC02- I 16 DDR3B .EQ VIA3+2 ; VIA PORT B DIRECTION REGISTER
0200- I 17 ;
0200- I 18 ; COMMAND LINE INTERPRETER
0200- I 19 ; $F AS INPUT MEANS RESET POINTERS, START OVER.
0200- I 20 ; $E MEANS PLAY CURRENTLY STORED NOTES
0200- I 21 ; ANYTHING ELSE IS STORED FOR REPLAY.
0200- I 22 ;
0200-A9 00 I 23 ( 2) START LDA #0 ; CLEAR NOTE LIST LENGTH
0202-85 00 I 24 ( 2) STA PILEN
0204-18 I 25 ( 2) CLC ; CLEAR NIBBLE MARKER
0205-20 E8 02 I 26 ( 6) NXKEY JSR GETKEY
0208-C9 0F I 27 ( 2) CMP #15 ; IS KEY #15?
020A-D0 05 I 28 (2**) BNE NXTST ; NO, DO NEXT TEST
020C-20 87 02 I 29 ( 6) JSR BEEP3 ; TELL USER OF CLEARING
020F-90 EF I 30 (2**) BCC START ; CLEAR POINTERS AND START OVER
0211-C9 0E I 31 ( 2) NXTST CMP #14 ; IS KEY #14?
0213-D0 06 I 32 (2**) BNE NUMKEY ; NO, KEY IS NOTE NUMBER
0215-20 48 02 I 33 ( 6) JSR PLAYEM ; PLAY NOTES
0218-18 I 34 ( 2) CLC
0219-90 EA I 35 (2**) BCC NXKEY ; GET NEXT COMMAND
021B- I 36 ;
021B- I 37 ; ROUTINE TO LOAD NOT LIST WITH NOTES
021B- I 38 ;
021B-85 01 I 39 ( 2) NUMKEY STA TEMP ; SAVE KEY, FREE A
021D-20 70 02 I 40 ( 6) JSR PLAYIT ; PLAY NOTE
0220-A5 00 I 41 ( 3) LDA PILEN ; GET LIST LENGTH
0222-C9 FF I 42 ( 2) CMP #$FF ; OVERFLOW?
0224-D0 05 I 43 (2**) BNE OK ; NO, ADD NOTE TO LIST
0226-20 87 02 I 44 ( 6) JSR BEEP3 ; YES, WARN USER
0229-90 DA I 45 (2**) BCC NXKEY ; RETURN TO INPUT MODE
022B-4A I 46 ( 2) OK LSR A ; SHIFT LOW BIT INTO NIBBLE POINTER
022C-A8 I 47 ( 2) TAY ; USE SHIFTED NIBBLE POINTER AS BYTE INDEX
022D-A5 01 I 48 ( 3) LDA TEMP ; RESTORE KEY#
022F-B0 09 I 49 (2**) BCS FINBYT ; IF BYTE ALREADY HAS A NIBBLE, FINISH IT AND STORE
0231-29 0F I 50 ( 2) AND #%00001111 ; 1ST NIBBLE. MASK HIGH NIBBLE
0233-99 00 03 I 51 ( 5) STA TABEG,Y ; SAVE UNFINISHED 1/2 BYTE
0236-E6 00 I 52 ( 5) INC PILEN ; POINT TO NEXT NIBBLE
0238-90 CB I 53 (2**) BCC NXKEY ; GET NEXT KEYSTROKE
023A-0A I 54 ( 2) FINBYT ASL A ; SHIFT NIBBLE 2 TO HIGH ORDER
023B-0A I 55 ( 2) ASL A
023C-0A I 56 ( 2) ASL A
023D-0A I 57 ( 2) ASL A
023E-19 00 03 I 58 ( 4*) ORA TABEG,Y ; JOIN 2 NIBBLES AS BYTE
0241-99 00 03 I 59 ( 5) STA TABEG,Y ; ... AND STORE.
0244-E6 00 I 60 ( 5) INC PILEN ; POINT TO NEXT NIBBLE IN NEXT BYTE
0246-90 BD I 61 (2**) BCC NXKEY ; RETURN
0248- I 62 ;
0248- I 63 ; ROUTINE TO PLAY NOTES
0248- I 64 ;
0248-A2 00 I 65 ( 2) PLAYEM LDX #0 ; CLEAR POINTER
024A-86 02 I 66 ( 3) STX PTR
024C-A5 02 I 67 ( 3) LDA PTR ; LOAD ACCUMULATOR WITH CURRENT POINTER VALUE
024E-4A I 68 ( 2) LOOP LSR A ; SHIFT NIBBLE INDICATOR INTO CARRY
024F-AA I 69 ( 2) TAX ; USE SHIFTED NIBBLE POINTER AS BYTE POINTER
0250-BD 00 03 I 70 ( 4*) LDA TABEG,X ; LOAD NOTE TO PLAY
0253-B0 04 I 71 (2**) BCS ENDBYT ; LOW NIBBLE USED, GET HIGH
0255-29 0F I 72 ( 2) AND #%00001111 ; MASK OUT HIGH BITS
0257-90 06 I 73 (2**) BCC FINISH ; PLAY NOTE
0259-29 F0 I 74 ( 2) ENDBYT AND #%11110000 ; THROW AWAY LOW NIBBLE
025B-4A I 75 ( 2) LSR A ; SHIFT INTO LOW
025C-4A I 76 ( 2) LSR A
025D-4A I 77 ( 2) LSR A
025E-4A I 78 ( 2) LSR A
025F-20 70 02 I 79 ( 6) FINISH JSR PLAYIT ; CALCULATE CONSTANTS & PLAY
0262-A2 20 I 80 ( 2) LDX #$20 ; BETWEEN-NOTE DELAY
0264-20 9C 02 I 81 ( 6) JSR DELAY
0267-E6 02 I 82 ( 5) INC PTR ; ONE NIBBLE USED
0269-A5 02 I 83 ( 3) LDA PTR
026B-C5 00 I 84 ( 3) CMP PILEN ; END OF LIST?
026D-90 DF I 85 (2**) BCC LOOP ; NO, GET NEXT NOTE
026F-60 I 86 ( 6) RTS ; DONE
0270- I 87 ;
0270- I 88 ; ROUTINE TO DO TABLE LOOK UP, SEPARATE REST
0270- I 89 ;
0270-C9 0D I 90 ( 2) PLAYIT CMP #13 ; REST?
0272-D0 06 I 91 (2**) BNE SOUND ; NO.
0274-A2 54 I 92 ( 2) LDX #$54 ; DELAY = NOTE LENGTH = .21SEC
0276-20 9C 02 I 93 ( 6) JSR DELAY
0279-60 I 94 ( 6) RTS
027A-AA I 95 ( 2) SOUND TAX ; USE KEYS AS INDEX..
027B-BD D1 02 I 96 ( 4*) LDA DURTAB,X ; ... TO FIND DURATION.
027E-85 04 I 97 ( 2) STA DUR ; STORE DURATION FOR USE
0280-BD C4 02 I 98 ( 4*) LDA NOTAB,X ; LOAD NOTE VALUE
0283-20 A8 02 I 99 ( 6) JSR TONE
0286-60 I 100 ( 6) RTS
0287- I 101 ;
0287- I 102 ; ROUTINE TO MAKE 3 TONE SIGNAL
0287- I 103 ;
0287-A9 FF I 104 ( 2) BEEP3 LDA #$FF ; DURATION FOR BEEPS
0289-85 04 I 105 ( 2) STA DUR
028B-A9 4B I 106 ( 2) LDA #$4B ; CODE FOR E2
028D-20 A8 02 I 107 ( 6) JSR TONE ; 1ST NOTE
0290-A9 38 I 108 ( 2) LDA #$38 ; CODE FOR D2
0292-20 A8 02 I 109 ( 6) JSR TONE
0295-A9 4B I 110 ( 2) LDA #$4B
0297-20 A8 02 I 111 ( 6) JSR TONE
029A-18 I 112 ( 2) CLC
029B-60 I 113 ( 6) RTS
029C- I 114 ;
029C- I 115 ; VARIABLE-LENGTH DELAY
029C- I 116 ;
029C-A0 FF I 117 ( 2) DELAY LDY #$FF
029E-EA I 118 ( 2) DLY NOP
029F-D0 00 I 119 (2**) BNE DL0 ; (.+2 IN BOOK)
02A1-88 I 120 ( 2) DL0 DEY
02A2-D0 FA I 121 (2**) BNE DLY ; 10 US. LOOP
02A4-CA I 122 ( 2) DEX
02A5-D0 F5 I 123 (2**) BNE DELAY ; LOOP TIME = 2556*[X]
02A7-60 I 124 ( 6) RTS
02A8- I 125 ;
02A8- I 126 ; ROUTINE TO MAKE TONE: # OF 1/2 CYCLES IS IN 'DUR', AND 1/2 CYCLE TIME IS IN
02A8- I 127 ; ACCUMULATOR. LOOP TIME = 20*[A]+26 US SINCE TWO RUNS THROUGH THE OUTER LOOP
02A8- I 128 ; MAKES ONE CYCLE OF THE TONE.
02A8- I 129 ;
02A8-85 03 I 130 ( 2) TONE STA FREQ ; FREQ IS TEMP FOR # OF CYCLES
02AA-A9 FF I 131 ( 2) LDA #$FF ; SET UP DATA DIRECTION REGISTER
02AC-8D 02 CC I 132 ( 4) STA DDR3B
02AF-A9 00 I 133 ( 2) LDA #$00 ; A IS SENT TO PORT, START HI
02B1-A6 04 I 134 ( 3) LDX DUR
02B3-A4 03 I 135 ( 3) FL2 LDY FREQ
02B5-88 I 136 ( 2) FL1 DEY
02B6-18 I 137 ( 2) CLC
02B7-90 00 I 138 (2**) BCC FL0 ; (.+2 IN BOOK)
02B9-D0 FA I 139 (2**) FL0 BNE FL1 ; INNER, 10 US LOOP.
02BB-49 FF I 140 ( 2) EOR #$FF ; COMPLEMENT I/O PORT
02BD-8D 00 CC I 141 ( 4) STA PORT3B ; ... AND SET IT
02C0-CA I 142 ( 2) DEX
02C1-D0 F0 I 143 (2**) BNE FL2 ; OUTER LOOP
02C3-60 I 144 ( 6) RTS
02C4- I 145 ;
02C4- I 146 ; TABLE OF NOTE CONSTANTS
02C4- I 147 ; CONTAINS:
02C4- I 148 ; [OCTAVE BELOW MIDDLE C] : G,A,BCC
02C4- I 149 ; [OCTAVE OF MIDDLE C] : C,D,E,F,F#,G,G#,A,B
02C4- I 150 ; [OCTAVE ABOVE MIDDLE C] : C
02C4- I 151 ;
02C4-FE E2 C9 BE
CC03- I 17 DDR3A .EQ VIA3+3
CC01- I 18 PORT3A .EQ VIA3+1
CC00- I 19 PORT3B .EQ VIA3
0203- I 20
0203- I 21 ;
0203- I 22 ; COMMAND LINE INTERPRETER
0203- I 23 ; $F AS INPUT MEANS RESET POINTERS, START OVER.
0203- I 24 ; $E MEANS PLAY CURRENTLY STORED NOTES
0203- I 25 ; ANYTHING ELSE IS STORED FOR REPLAY.
0203- I 26 ;
0203-A9 00 I 27 ( 2) START LDA #0 ; CLEAR NOTE LIST LENGTH
0205-85 00 I 28 ( 2) STA PILEN
0207-18 I 29 ( 2) CLC ; CLEAR NIBBLE MARKER
0208-20 E1 02 I 30 ( 6) NXKEY JSR GETKEY
020B-C9 0F I 31 ( 2) CMP #15 ; IS KEY #15?
020D-D0 05 I 32 (2**) BNE NXTST ; NO, DO NEXT TEST
020F-20 8A 02 I 33 ( 6) JSR BEEP3 ; TELL USER OF CLEARING
0212-90 EF I 34 (2**) BCC START ; CLEAR POINTERS AND START OVER
0214-C9 0E I 35 ( 2) NXTST CMP #14 ; IS KEY #14?
0216-D0 06 I 36 (2**) BNE NUMKEY ; NO, KEY IS NOTE NUMBER
0218-20 4B 02 I 37 ( 6) JSR PLAYEM ; PLAY NOTES
021B-18 I 38 ( 2) CLC
021C-90 EA I 39 (2**) BCC NXKEY ; GET NEXT COMMAND
021E- I 40 ;
021E- I 41 ; ROUTINE TO LOAD NOT LIST WITH NOTES
021E- I 42 ;
021E-85 01 I 43 ( 2) NUMKEY STA TEMP ; SAVE KEY, FREE A
0220-20 73 02 I 44 ( 6) JSR PLAYIT ; PLAY NOTE
0223-A5 00 I 45 ( 3) LDA PILEN ; GET LIST LENGTH
0225-C9 FF I 46 ( 2) CMP #$FF ; OVERFLOW?
0227-D0 05 I 47 (2**) BNE OK ; NO, ADD NOTE TO LIST
0229-20 8A 02 I 48 ( 6) JSR BEEP3 ; YES, WARN USER
022C-90 DA I 49 (2**) BCC NXKEY ; RETURN TO INPUT MODE
022E-4A I 50 ( 2) OK LSR A ; SHIFT LOW BIT INTO NIBBLE POINTER
022F-A8 I 51 ( 2) TAY ; USE SHIFTED NIBBLE POINTER AS BYTE INDEX
0230-A5 01 I 52 ( 3) LDA TEMP ; RESTORE KEY#
0232-B0 09 I 53 (2**) BCS FINBYT ; IF BYTE ALREADY HAS A NIBBLE, FINISH IT AND STORE
0234-29 0F I 54 ( 2) AND #%00001111 ; 1ST NIBBLE. MASK HIGH NIBBLE
0236-99 00 03 I 55 ( 5) STA TABEG,Y ; SAVE UNFINISHED 1/2 BYTE
0239-E6 00 I 56 ( 5) INC PILEN ; POINT TO NEXT NIBBLE
023B-90 CB I 57 (2**) BCC NXKEY ; GET NEXT KEYSTROKE
023D-0A I 58 ( 2) FINBYT ASL A ; SHIFT NIBBLE 2 TO HIGH ORDER
023E-0A I 59 ( 2) ASL A
023F-0A I 60 ( 2) ASL A
0240-0A I 61 ( 2) ASL A
0241-19 00 03 I 62 ( 4*) ORA TABEG,Y ; JOIN 2 NIBBLES AS BYTE
0244-99 00 03 I 63 ( 5) STA TABEG,Y ; ... AND STORE.
0247-E6 00 I 64 ( 5) INC PILEN ; POINT TO NEXT NIBBLE IN NEXT BYTE
0249-90 BD I 65 (2**) BCC NXKEY ; RETURN
024B- I 66 ;
024B- I 67 ; ROUTINE TO PLAY NOTES
024B- I 68 ;
024B-A2 00 I 69 ( 2) PLAYEM LDX #0 ; CLEAR POINTER
024D-86 02 I 70 ( 3) STX PTR
024F-A5 02 I 71 ( 3) LDA PTR ; LOAD ACCUMULATOR WITH CURRENT POINTER VALUE
0251-4A I 72 ( 2) LOOP LSR A ; SHIFT NIBBLE INDICATOR INTO CARRY
0252-AA I 73 ( 2) TAX ; USE SHIFTED NIBBLE POINTER AS BYTE POINTER
0253-BD 00 03 I 74 ( 4*) LDA TABEG,X ; LOAD NOTE TO PLAY
0256-B0 04 I 75 (2**) BCS ENDBYT ; LOW NIBBLE USED, GET HIGH
0258-29 0F I 76 ( 2) AND #%00001111 ; MASK OUT HIGH BITS
025A-90 06 I 77 (2**) BCC FINISH ; PLAY NOTE
025C-29 F0 I 78 ( 2) ENDBYT AND #%11110000 ; THROW AWAY LOW NIBBLE
025E-4A I 79 ( 2) LSR A ; SHIFT INTO LOW
025F-4A I 80 ( 2) LSR A
0260-4A I 81 ( 2) LSR A
0261-4A I 82 ( 2) LSR A
0262-20 73 02 I 83 ( 6) FINISH JSR PLAYIT ; CALCULATE CONSTANTS & PLAY
0265-A2 20 I 84 ( 2) LDX #$20 ; BETWEEN-NOTE DELAY
0267-20 9F 02 I 85 ( 6) JSR DELAY
026A-E6 02 I 86 ( 5) INC PTR ; ONE NIBBLE USED
026C-A5 02 I 87 ( 3) LDA PTR
026E-C5 00 I 88 ( 3) CMP PILEN ; END OF LIST?
0270-90 DF I 89 (2**) BCC LOOP ; NO, GET NEXT NOTE
0272-60 I 90 ( 6) RTS ; DONE
0273- I 91 ;
0273- I 92 ; ROUTINE TO DO TABLE LOOK UP, SEPARATE REST
0273- I 93 ;
0273-C9 0D I 94 ( 2) PLAYIT CMP #13 ; REST?
0275-D0 06 I 95 (2**) BNE SOUND ; NO.
0277-A2 54 I 96 ( 2) LDX #$54 ; DELAY = NOTE LENGTH = .21SEC
0279-20 9F 02 I 97 ( 6) JSR DELAY
027C-60 I 98 ( 6) RTS
027D-AA I 99 ( 2) SOUND TAX ; USE KEYS AS INDEX..
027E-BD D4 02 I 100 ( 4*) LDA DURTAB,X ; ... TO FIND DURATION.
0281-85 04 I 101 ( 2) STA DUR ; STORE DURATION FOR USE
0283-BD C7 02 I 102 ( 4*) LDA NOTAB,X ; LOAD NOTE VALUE
0286-20 AB 02 I 103 ( 6) JSR TONE
0289-60 I 104 ( 6) RTS
028A- I 105 ;
028A- I 106 ; ROUTINE TO MAKE 3 TONE SIGNAL
028A- I 107 ;
028A-A9 FF I 108 ( 2) BEEP3 LDA #$FF ; DURATION FOR BEEPS
028C-85 04 I 109 ( 2) STA DUR
028E-A9 4B I 110 ( 2) LDA #$4B ; CODE FOR E2
0290-20 AB 02 I 111 ( 6) JSR TONE ; 1ST NOTE
0293-A9 38 I 112 ( 2) LDA #$38 ; CODE FOR D2
0295-20 AB 02 I 113 ( 6) JSR TONE
0298-A9 4B I 114 ( 2) LDA #$4B
029A-20 AB 02 I 115 ( 6) JSR TONE
029D-18 I 116 ( 2) CLC
029E-60 I 117 ( 6) RTS
029F- I 118 ;
029F- I 119 ; VARIABLE-LENGTH DELAY
029F- I 120 ;
029F-A0 FF I 121 ( 2) DELAY LDY #$FF
02A1-EA I 122 ( 2) DLY NOP
02A2-D0 00 I 123 (2**) BNE DL0 ; (.+2 IN BOOK)
02A4-88 I 124 ( 2) DL0 DEY
02A5-D0 FA I 125 (2**) BNE DLY ; 10 US. LOOP
02A7-CA I 126 ( 2) DEX
02A8-D0 F5 I 127 (2**) BNE DELAY ; LOOP TIME = 2556*[X]
02AA-60 I 128 ( 6) RTS
02AB- I 129 ;
02AB- I 130 ; ROUTINE TO MAKE TONE: # OF 1/2 CYCLES IS IN 'DUR', AND 1/2 CYCLE TIME IS IN
02AB- I 131 ; ACCUMULATOR. LOOP TIME = 20*[A]+26 US SINCE TWO RUNS THROUGH THE OUTER LOOP
02AB- I 132 ; MAKES ONE CYCLE OF THE TONE.
02AB- I 133 ;
02AB-85 03 I 134 ( 2) TONE STA FREQ ; FREQ IS TEMP FOR # OF CYCLES
02AD-A9 FF I 135 ( 2) LDA #$FF ; SET UP DATA DIRECTION REGISTER
02AF-8D 02 CC I 136 ( 4) STA DDR3B
02B2-A9 00 I 137 ( 2) LDA #$00 ; A IS SENT TO PORT, START HI
02B4-A6 04 I 138 ( 3) LDX DUR
02B6-A4 03 I 139 ( 3) FL2 LDY FREQ
02B8-88 I 140 ( 2) FL1 DEY
02B9-18 I 141 ( 2) CLC
02BA-90 00 I 142 (2**) BCC FL0 ; (.+2 IN BOOK)
02BC-D0 FA I 143 (2**) FL0 BNE FL1 ; INNER, 10 US LOOP.
02BE-49 FF I 144 ( 2) EOR #$FF ; COMPLEMENT I/O PORT
02C0-8D 00 CC I 145 ( 4) STA PORT3B ; ... AND SET IT
02C3-CA I 146 ( 2) DEX
02C4-D0 F0 I 147 (2**) BNE FL2 ; OUTER LOOP
02C6-60 I 148 ( 6) RTS
02C7- I 149 ;
02C7- I 150 ; TABLE OF NOTE CONSTANTS
02C7- I 151 ; CONTAINS:
02C7- I 152 ; [OCTAVE BELOW MIDDLE C] : G,A,BCC
02C7- I 153 ; [OCTAVE OF MIDDLE C] : C,D,E,F,F#,G,G#,A,B
02C7- I 154 ; [OCTAVE ABOVE MIDDLE C] : C
02C7- I 155 ;
02C7-FE E2 C9 BE
A9 96 8E 86
7E 77 70 64
5E I 152 NOTAB .HS FE.E2.C9.BE.A9.96.8E.86.7E.77.70.64.5E
02D1- I 153 ;
02D1- I 154 ; TABLE OF NOTE DURATIONS IN # OF 1/2 CYCLES SET FOR A NOTE LENGTH OF
02D1- I 155 ; ABOUT .21 SEC.
02D1- I 156 ;
02D1-55 60 6B 72
5E I 156 NOTAB .HS FE.E2.C9.BE.A9.96.8E.86.7E.77.70.64.5E
02D4- I 157 ;
02D4- I 158 ; TABLE OF NOTE DURATIONS IN # OF 1/2 CYCLES SET FOR A NOTE LENGTH OF
02D4- I 159 ; ABOUT .21 SEC.
02D4- I 160 ;
02D4-55 60 6B 72
80 8F 94 A1
AA B5 BF D7
E4 I 157 DURTAB .HS 55.60.6B.72.80.8F.94.A1.AA.B5.BF.D7.E4
02DE- 15 .IN ../../common/CH01-Getkey/getkey_routine.asm
02DE- I 1 ; 'GETKEY' KEYBOARD INPUT ROUTINE READS AND DEBOUNCES KEYBOARD. RETURNS WITH
02DE- I 2 ; KEY NUMBER IN ACCUMULATOR IF KEY DOWN. OPERATION: SENDS NUMBERS 0-F TO 74154
02DE- I 3 ; (4 TO 16 LINE DECODER), WHICH GROUNDS ONE SIDE OF KEYSWITCHES ONE AT A TIME.
02DE- I 4 ; IF A KEY IS DOWN, PA7 OF VIA #3 WILL BE GROUNDED, AND THE CURRENT VALUE
02DE- I 5 ; APPLIED TO THE 74154 BE THE KEY NUMBER. WHEN THE PROGRAM DETECTS A KEY CLOSE
02DE- I 6 ; CHECKS FOR KEY CLOSURE FOR 50 MS. TO ELIMINATE BOUNCE.
02DE- I 7 ; NOTE: IF NO KEY IS PRESSED, GETKEY WILL WAIT.
02DE- I 8 ;
CC03- I 9 DDR3A .EQ VIA3+3 ; USING RC-ONE ADDRESS DECODING SCHEME, PLACING
CC02- I 10 DDR3B .EQ VIA3+2 ; VIA3 AT $CC00 BY DEFAULT (INSTEAD OF $AC00)
CC01- I 11 PORT3A .EQ VIA3+1 ; TO FIT RC-ONE ADDRESS DECODING THOUGH ORIGINAL
CC00- I 12 PORT3B .EQ VIA3 ; CAN BE JUMPERED IF NEEDED/WANTED.
02DE- I 13
02DE-A9 00 I 14 ( 2) LDA #0
02E0-8D 03 CC I 15 ( 4) STA DDR3A ; SET KEY STROBE PORT FOR INPUT
02E3-A9 FF I 16 ( 2) LDA #$FF
02E5-8D 02 CC I 17 ( 4) STA DDR3B ; SET KEYS FOR OUTPUT
02E8-2C 01 CC I 18 ( 4) GETKEY BIT PORT3A ; SEE IF KEY IS STILL DOWN FROM LAST KEY CLOSURE:
02EB- I 19 ; KEYSTROBE IN 'N' STATUS BIT.
02EB-10 FB I 20 (2**) BPL GETKEY ; IF YES, WAIT FOR KEY RELEASE
02ED-A2 0F I 21 ( 2) RSTART LDX #15 ; SET KEY COUNTER TO 15
02EF-8E 00 CC I 22 ( 4) NXTKEY STX PORT3B ; OUTPUT KEY # TO 74154
02F2-2C 01 CC I 23 ( 4) BIT PORT3A ; SEE IF KEY DOWN: STROBE IN 'N'
02F5-10 05 I 24 (2**) BPL BOUNCE ; IF YES, GO DEBOUNCE
02F7-CA I 25 ( 2) DEX ; DECREMENT KEY #
02F8-10 F5 I 26 (2**) BPL NXTKEY ; NO, DO NEXT KEY
02FA-30 F1 I 27 (2**) BMI RSTART ; START OVER
02FC-8A I 28 ( 2) BOUNCE TXA ; SAVE KEY NUMBER IN A
02FD-A0 12 I 29 ( 2) LDY #$12 ; OUTER LOOP CNT LOAD FOR DELAY OF 50 MS.
02FF-A2 FF I 30 ( 2) LP1 LDX #$FF ; INNER 11 US. LOOP
0301-2C 01 CC I 31 ( 4) LP2 BIT PORT3A ; SEE IF KEY STILL DOWN
0304-30 E7 I 32 (2**) BMI RSTART ; IF NOT, KEY NOT VALID, RESTART
0306-CA I 33 ( 2) DEX
0307-D0 F8 I 34 (2**) BNE LP2 ; THIS LOOP USES 2115*5 US.
0309-88 I 35 ( 2) DEY
030A-D0 F3 I 36 (2**) BNE LP1 ; OUTER LOOP: TOTAL IS 50 MS.
030C-60 I 37 ( 6) RTS ; DONE: KEY IN A.
E4 I 161 DURTAB .HS 55.60.6B.72.80.8F.94.A1.AA.B5.BF.D7.E4
02E1- 16 .IN ../../common/CH01-Getkey/getkey_routine.asm
02E1- I 1 ; 'GETKEY' KEYBOARD INPUT ROUTINE READS AND DEBOUNCES KEYBOARD. RETURNS WITH
02E1- I 2 ; KEY NUMBER IN ACCUMULATOR IF KEY DOWN. OPERATION: SENDS NUMBERS 0-F TO 74154
02E1- I 3 ; (4 TO 16 LINE DECODER), WHICH GROUNDS ONE SIDE OF KEYSWITCHES ONE AT A TIME.
02E1- I 4 ; IF A KEY IS DOWN, PA7 OF VIA #3 WILL BE GROUNDED, AND THE CURRENT VALUE
02E1- I 5 ; APPLIED TO THE 74154 BE THE KEY NUMBER. WHEN THE PROGRAM DETECTS A KEY CLOSE
02E1- I 6 ; CHECKS FOR KEY CLOSURE FOR 50 MS. TO ELIMINATE BOUNCE.
02E1- I 7 ; NOTE: IF NO KEY IS PRESSED, GETKEY WILL WAIT.
02E1- I 8 ;
02E1-2C 01 CC I 9 ( 4) GETKEY BIT PORT3A ; SEE IF KEY IS STILL DOWN FROM LAST KEY CLOSURE:
02E4- I 10 ; KEYSTROBE IN 'N' STATUS BIT.
02E4-10 FB I 11 (2**) BPL GETKEY ; IF YES, WAIT FOR KEY RELEASE
02E6-A2 0F I 12 ( 2) RSTART LDX #15 ; SET KEY COUNTER TO 15
02E8-8E 00 CC I 13 ( 4) NXTKEY STX PORT3B ; OUTPUT KEY # TO 74154
02EB-2C 01 CC I 14 ( 4) BIT PORT3A ; SEE IF KEY DOWN: STROBE IN 'N'
02EE-10 05 I 15 (2**) BPL BOUNCE ; IF YES, GO DEBOUNCE
02F0-CA I 16 ( 2) DEX ; DECREMENT KEY #
02F1-10 F5 I 17 (2**) BPL NXTKEY ; NO, DO NEXT KEY
02F3-30 F1 I 18 (2**) BMI RSTART ; START OVER
02F5-8A I 19 ( 2) BOUNCE TXA ; SAVE KEY NUMBER IN A
02F6-A0 12 I 20 ( 2) LDY #$12 ; OUTER LOOP CNT LOAD FOR DELAY OF 50 MS.
02F8-A2 FF I 21 ( 2) LP1 LDX #$FF ; INNER 11 US. LOOP
02FA-2C 01 CC I 22 ( 4) LP2 BIT PORT3A ; SEE IF KEY STILL DOWN
02FD-30 E7 I 23 (2**) BMI RSTART ; IF NOT, KEY NOT VALID, RESTART
02FF-CA I 24 ( 2) DEX
0300-D0 F8 I 25 (2**) BNE LP2 ; THIS LOOP USES 2115*5 US.
0302-88 I 26 ( 2) DEY
0303-D0 F3 I 27 (2**) BNE LP1 ; OUTER LOOP: TOTAL IS 50 MS.
0305-60 I 28 ( 6) RTS ; DONE: KEY IN A.
0306- I 29 ;
0306- I 30 ; SUBROUTINE 'INITKEY'
0306- I 31 ; TAKES CARE OF INITIALIZING VIA #3 FOR USING WITH THE GETKEY ROUTINE FROM
0306- I 32 ; THE CODE.
0306- I 33 ;
0306-A9 00 I 34 ( 2) INITKEY LDA #0
0308-8D 03 CC I 35 ( 4) STA DDR3A ; SET KEY STROBE PORT FOR INPUT
030B-A9 FF I 36 ( 2) LDA #$FF
030D-8D 02 CC I 37 ( 4) STA DDR3B ; SET KEYS FOR OUTPUT
0310-60 I 38 ( 6) RTS

View File

@ -11,5 +11,6 @@ VIA3 .EQ $CC00
.OR $0200
.TA $0200
RCONE JSR INITKEY
.IN ../../common/CH04-Hexguess/game.asm
.IN ../../common/CH01-Getkey/getkey_routine.asm

View File

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

View File

@ -0,0 +1,16 @@
.CR 6502
.TF magicsquare.hex,hex
.LF magicsquare.list
;
; MAGIC SQUARE GAME FOR THE KIM-1 USING '6502 GAMES' HARDWARE. BOARD SHOULD BE
; JUMPERED WITH VIA CHIPS AT THE ADDRESSES SPECIFIED BELOW. OTHER THAN THAT
; THE CODE IS UNCHANGED FROM THE BOOK.
;
VIA1 .EQ $C000
VIA3 .EQ $CC00
.OR $0200
.TA $0200
RCONE JSR INITKEY
.IN ../../common/CH05-MagicSquare/game.asm
.IN ../../common/CH01-Getkey/getkey_routine.asm

View File

@ -0,0 +1,11 @@
20A402A9FF8D03C08D02C0AD04C08D01
C0AD04C029018D00C0207F02C900F0EB
C90A10F538E9010AAAAD01C05D6E028D
01C0AD00C05D6F0229018D00C04A90D9
AD01C0C9EFD0D2A90E8500A220A0FFEA
D00088D0FACAD0F5AD01C049FF8D01C0
AD00C049018D00C0C600D0DFF0AB1B00
0736004900BA002401D800C001B0012C
01CC10FBA20F8E00CC2C01CC1005CA10
F530F18AA012A2FF2C01CC30E7CAD0F8
88D0F360A9008D03CCA9FF8D02CC60

View File

@ -0,0 +1,148 @@
0000- 4 ;
0000- 5 ; MAGIC SQUARE GAME FOR THE KIM-1 USING '6502 GAMES' HARDWARE. BOARD SHOULD BE
0000- 6 ; JUMPERED WITH VIA CHIPS AT THE ADDRESSES SPECIFIED BELOW. OTHER THAN THAT
0000- 7 ; THE CODE IS UNCHANGED FROM THE BOOK.
0000- 8 ;
C000- 9 VIA1 .EQ $C000
CC00- 10 VIA3 .EQ $CC00
0000- 11
0200- 12 .OR $0200
0200- 13 .TA $0200
0200-20 A4 02 14 ( 6) JSR INITKEY
0203- 15 .IN ../../common/CH05-MagicSquare/game.asm
0203- I 1 ; 'MAGIC SQUARE'
0203- I 2 ; KEYS 1-9 ON THE HEX KEYBOARD ARE EACH ASSOCIATED WITH ON LED IN THE 3X3
0203- I 3 ; ARRAY. WHEN A KEY IS PRESSET, IT CHANGES THE PATTERN OF THE LIT LEDS IN THE
0203- I 4 ; ARRAY. THE OBJECT OF THE GAME IS TO CONVERT THE RANDOM PATTERN THE GAME
0203- I 5 ; STARTS WITH TO A SQUARE OF LIT LEDS BY PRESSING THE KEYS. THE LEDS WILL FLASH
0203- I 6 ; WHEN THE WINNING PATTERN IS ACHIEVED. KEY #0 CAN BE USED AT ANY TIME TO
0203- I 7 ; RESTART THE GAME WITH A NEW PATTERN.
0203- I 8 ;
0203- I 9 ;
C004- I 10 T1CL .EQ VIA1+4 ; LOW LATCH OF TIMER 1
C003- I 11 DDR1A .EQ VIA1+3 ; PORT A DATA DIRECTION REGISTER
C002- I 12 DDR1B .EQ VIA1+2 ; PORT B DATA DIRECTION REGISTER
C001- I 13 PORT1A .EQ VIA1+1 ; PORT A
C000- I 14 PORT2 .EQ VIA1
C000- I 15 PORT1B .EQ VIA1 ; PORT B
CC03- I 16 DDR3A .EQ VIA3+3 ; PORT A DATA DIRECTION REGISTER
CC02- I 17 DDR3B .EQ VIA3+2 ; PORT B DATA DIRECTION REGISTER
CC00- I 18 PORT3B .EQ VIA3 ; PORT B
CC01- I 19 PORT3A .EQ VIA3+1 ; PORT A
0203- I 20
0000- I 21 ZP .EQ $00
0000- I 22 TEMP .EQ ZP ; TEMPORARY STORAGE
0203- I 23 ;
0203- I 24 ; COMMENTS: THIS PROGRAM USES A TIMER REGISTER FOR A RANDOM NUMBER SOURCE. IF
0203- I 25 ; NONE IS AVAILABLE, A RANDOM NUMBER GENERATOR COULD BE USED, BUT DUE TO ITS
0203- I 26 ; REPEATABILITY, IT WOULD NOT WORK AS WELL. THIS PROGRAM USES THE REGISTERS OF
0203- I 27 ; VIA1 PORT A FOR THE STORAGE OF THE LED PATTERN. SINCE WHAT IS READ BY THE
0203- I 28 ; PROCESSOR IS THE POLARITY OF THE OUTPUT, AN EXCESSIVE LOAD ON THE LINES WOULD
0203- I 29 ; PREVENT THE PROGAM FROM WORKING CORRECTLY.
0203- I 30 ;
0203-A9 FF I 31 ( 2) LDA #$FF ; SET UP DATA DIRECTION REGISTERS
0205-8D 03 C0 I 32 ( 4) STA DDR1A
0208-8D 02 C0 I 33 ( 4) STA DDR1B
020B-AD 04 C0 I 34 ( 4) START LDA T1CL ; GET 1ST RANDOM NUMBER
020E-8D 01 C0 I 35 ( 4) STA PORT1A
0211-AD 04 C0 I 36 ( 4) LDA T1CL ; ... AND SECOND.
0214-29 01 I 37 ( 2) AND #01 ; MASK OUT BOTTOM ROW LEDS
0216-8D 00 C0 I 38 ( 4) STA PORT1B
0219-20 7F 02 I 39 ( 6) KEY JSR GETKEY
021C-C9 00 I 40 ( 2) CMP #0 ; KEY MUST BE 1-9: IS IT 0?
021E-F0 EB I 41 (2**) BEQ START ; YES, RESTART GAME WITH NEW BOARD.
0220-C9 0A I 42 ( 2) CMP #10 ; IS IT LESS THAN 10?
0222-10 F5 I 43 (2**) BPL KEY ; + IF KEY >=10, SO GET ANOTHER.
0224- I 44 ;
0224- I 45 ; FOLLOWING SECTION USES KEY NUMBER AS INDEX TO FIND IN TABLE A BIT PATTERN
0224- I 46 ; USED TO COMPLEMENT LEDS.
0224- I 47 ;
0224-38 I 48 ( 2) SEC ; DECREMENT A FOR TABLE ACCESS
0225-E9 01 I 49 ( 2) SBC #1
0227-0A I 50 ( 2) ASL A ; MULTIPLY A*2 (EACH ENTRY IN TABLE IS 2 BYTES)
0228-AA I 51 ( 2) TAX ; USE A AS INDEX
0229-AD 01 C0 I 52 ( 4) LDA PORT1A ; GET PORT CONTENTS FOR COMPLEMENT
022C-5D 6E 02 I 53 ( 4*) EOR TABLE,X ; EOR PORT CONTENTS WITH PATTERN
022F-8D 01 C0 I 54 ( 4) STA PORT1A ; RESTORE PORT1A
0232-AD 00 C0 I 55 ( 4) LDA PORT1B ; DO SAME FOR PORT1B,
0235-5D 6F 02 I 56 ( 4*) EOR TABLE+1,X ; ... USING NEXT TABLE ENTRY.
0238-29 01 I 57 ( 2) AND #01 ; MASK OUT BOTTOM ROW LEDS
023A-8D 00 C0 I 58 ( 4) STA PORT1B ; ... AND RESTORE.
023D- I 59 ;
023D- I 60 ; THIS SECTION CHECKS FOR WINNING PATTERN IN LEDS.
023D- I 61 ;
023D-4A I 62 ( 2) LSR A ; SHIFT BIT 0 OF PORT 1 INTO CARRY.
023E-90 D9 I 63 (2**) BCC KEY ; IF NOT WIN PATTERN, GET NEXT MOVE.
0240-AD 01 C0 I 64 ( 4) LDA PORT1A ; LOAD PORT1A FOR WIN TEST
0243-C9 EF I 65 ( 2) CMP #%11101111 ; CHECK FOR WIN PATTERN
0245-D0 D2 I 66 (2**) BNE KEY ; NO WIN, GET NEXT MOVE
0247- I 67 ;
0247- I 68 ; WIN - BLINK LEDS EVERY 1/2 SECOND, 4 TIMES
0247- I 69 ;
0247-A9 0E I 70 ( 2) LDA #14
0249-85 00 I 71 ( 2) STA TEMP ; LOAD NUMBER OF BLINKS
024B-A2 20 I 72 ( 2) BLINK LDX #$20 ; DELAY CONSTANT FOR .08 SECOND
024D-A0 FF I 73 ( 2) DELAY LDY #$FF ; OUTER LOOP OF VARIABLE DELAY ROUTINE, WHOSE DELAY
024F- I 74 ; IS 2556 * (CONTENTS OF X ON ENTER
024F-EA I 75 ( 2) DLY NOP ; 10 MICROSECOND LOOP)
0250-D0 00 I 76 (2**) BNE DLY0
0252-88 I 77 ( 2) DLY0 DEY
0253-D0 FA I 78 (2**) BNE DLY
0255-CA I 79 ( 2) DEX
0256-D0 F5 I 80 (2**) BNE DELAY
0258-AD 01 C0 I 81 ( 4) LDA PORT1A ; GET PORTS AND COMPLEMENT THEM
025B-49 FF I 82 ( 2) EOR #$FF
025D-8D 01 C0 I 83 ( 4) STA PORT1A
0260-AD 00 C0 I 84 ( 4) LDA PORT1B
0263-49 01 I 85 ( 2) EOR #1
0265-8D 00 C0 I 86 ( 4) STA PORT1B
0268-C6 00 I 87 ( 5) DEC TEMP ; COUNT DOWN NUMBER OF BLINKS
026A-D0 DF I 88 (2**) BNE BLINK ; DO AGAIN IF NOT DONE
026C-F0 AB I 89 (2**) BEQ KEY
026E- I 90 ;
026E- I 91 ; TABLE OF CODES USED TO COMPLEMENT LEDS
026E- I 92 ;
026E-1B 00 07 36
00 49 00 BA
00 24 01 D8
00 C0 01 B0
01 I 93 TABLE .HS 1B.00.07.36.00.49.00.BA.00.24.01.D8.00.C0.01.B0.01
027F- 16 .IN ../../common/CH01-Getkey/getkey_routine.asm
027F- I 1 ; 'GETKEY' KEYBOARD INPUT ROUTINE READS AND DEBOUNCES KEYBOARD. RETURNS WITH
027F- I 2 ; KEY NUMBER IN ACCUMULATOR IF KEY DOWN. OPERATION: SENDS NUMBERS 0-F TO 74154
027F- I 3 ; (4 TO 16 LINE DECODER), WHICH GROUNDS ONE SIDE OF KEYSWITCHES ONE AT A TIME.
027F- I 4 ; IF A KEY IS DOWN, PA7 OF VIA #3 WILL BE GROUNDED, AND THE CURRENT VALUE
027F- I 5 ; APPLIED TO THE 74154 BE THE KEY NUMBER. WHEN THE PROGRAM DETECTS A KEY CLOSE
027F- I 6 ; CHECKS FOR KEY CLOSURE FOR 50 MS. TO ELIMINATE BOUNCE.
027F- I 7 ; NOTE: IF NO KEY IS PRESSED, GETKEY WILL WAIT.
027F- I 8 ;
027F-2C 01 CC I 9 ( 4) GETKEY BIT PORT3A ; SEE IF KEY IS STILL DOWN FROM LAST KEY CLOSURE:
0282- I 10 ; KEYSTROBE IN 'N' STATUS BIT.
0282-10 FB I 11 (2**) BPL GETKEY ; IF YES, WAIT FOR KEY RELEASE
0284-A2 0F I 12 ( 2) RSTART LDX #15 ; SET KEY COUNTER TO 15
0286-8E 00 CC I 13 ( 4) NXTKEY STX PORT3B ; OUTPUT KEY # TO 74154
0289-2C 01 CC I 14 ( 4) BIT PORT3A ; SEE IF KEY DOWN: STROBE IN 'N'
028C-10 05 I 15 (2**) BPL BOUNCE ; IF YES, GO DEBOUNCE
028E-CA I 16 ( 2) DEX ; DECREMENT KEY #
028F-10 F5 I 17 (2**) BPL NXTKEY ; NO, DO NEXT KEY
0291-30 F1 I 18 (2**) BMI RSTART ; START OVER
0293-8A I 19 ( 2) BOUNCE TXA ; SAVE KEY NUMBER IN A
0294-A0 12 I 20 ( 2) LDY #$12 ; OUTER LOOP CNT LOAD FOR DELAY OF 50 MS.
0296-A2 FF I 21 ( 2) LP1 LDX #$FF ; INNER 11 US. LOOP
0298-2C 01 CC I 22 ( 4) LP2 BIT PORT3A ; SEE IF KEY STILL DOWN
029B-30 E7 I 23 (2**) BMI RSTART ; IF NOT, KEY NOT VALID, RESTART
029D-CA I 24 ( 2) DEX
029E-D0 F8 I 25 (2**) BNE LP2 ; THIS LOOP USES 2115*5 US.
02A0-88 I 26 ( 2) DEY
02A1-D0 F3 I 27 (2**) BNE LP1 ; OUTER LOOP: TOTAL IS 50 MS.
02A3-60 I 28 ( 6) RTS ; DONE: KEY IN A.
02A4- I 29 ;
02A4- I 30 ; SUBROUTINE 'INITKEY'
02A4- I 31 ; TAKES CARE OF INITIALIZING VIA #3 FOR USING WITH THE GETKEY ROUTINE FROM
02A4- I 32 ; THE CODE.
02A4- I 33 ;
02A4-A9 00 I 34 ( 2) INITKEY LDA #0
02A6-8D 03 CC I 35 ( 4) STA DDR3A ; SET KEY STROBE PORT FOR INPUT
02A9-A9 FF I 36 ( 2) LDA #$FF
02AB-8D 02 CC I 37 ( 4) STA DDR3B ; SET KEYS FOR OUTPUT
02AE-60 I 38 ( 6) RTS

View File

@ -146,63 +146,64 @@ CC03- I 17 DDR3A .EQ VIA3+3
02CC- I 134 ;
02CC- I 135 ; SUBROUTINE 'BLINK'
02CC- I 136 ; BLINKS LEDS WHOSE BITS ARE SET IN ACCUMULATOR ON ENTRY.
02CC-A2 14 I 137 ( 2) BLINK LDX #20 ; 20 BLINKS.
02CE-86 01 I 138 ( 3) STX CNTHI ; SET BLINK COUNTER.
02D0-85 02 I 139 ( 2) STA CNTLO ; BLINK REGISTER
02D2-A5 02 I 140 ( 3) BLOOP LDA CNTLO ; GET BLINK PATTERN
02D4-4D 00 C0 I 141 ( 4) EOR PORT1B ; BLINK LEDS.
02D7-8D 00 C0 I 142 ( 4) STA PORT1B
02DA-A9 0A I 143 ( 2) LDA #10 ; SHORT DELAY
02DC-20 E4 02 I 144 ( 6) JSR DELAY
02DF-C6 01 I 145 ( 5) DEC CNTHI
02E1-D0 EF I 146 (2**) BNE BLOOP ; LOOP IF NOT DONE.
02E3-60 I 147 ( 6) RTS
02E4- I 148 ;
02E4- I 149 ; SUBROUTINE 'DELAY'
02E4- I 150 ; CONTENTS OF ACCUMULATOR DETERMINES DELAY LENGTH.
02E4- I 151 ;
02E4-85 00 I 152 ( 2) DELAY STA TEMP
02E6-A0 10 I 153 ( 2) DL1 LDY #$10
02E8-A2 FF I 154 ( 2) DL2 LDX #$FF
02EA-CA I 155 ( 2) DL3 DEX
02EB-D0 FD I 156 (2**) BNE DL3
02ED-88 I 157 ( 2) DEY
02EE-D0 F8 I 158 (2**) BNE DL2
02F0-C6 00 I 159 ( 5) DEC TEMP
02F2-D0 F2 I 160 (2**) BNE DL1
02F4-60 I 161 ( 6) RTS
02F5- I 162 ;
02F5- I 163 ; SUBROUTINE 'RANDOM'
02F5- I 164 ; RANDOM NUMBER GENERATOR, RETURNS RANDOM NUMBER IN ACCUMULATOR.
02F5- I 165 ;
02F5-38 I 166 ( 2) RANDOM SEC
02F6-A5 09 I 167 ( 3) LDA SCR+1
02F8-65 0C I 168 ( 3) ADC SCR+4
02FA-65 0D I 169 ( 3) ADC SCR+5
02FC-85 08 I 170 ( 2) STA SCR
02FE-A2 04 I 171 ( 2) LDX #4
0300-B5 08 I 172 ( 4) RNDLP LDA SCR,X
0302-95 09 I 173 ( 4) STA SCR+1,X
0304-CA I 174 ( 2) DEX
0305-10 F9 I 175 (2**) BPL RNDLP
0307-60 I 176 ( 6) RTS
0308- I 177 ;
0308- I 178 ; TABLE OF 'REVERSED' NUMBERS FOR DISPLAY
0308- I 179 ; IN BITS 3-8 OF PORT1B, OR LEDS 12-15.
0308- I 180 ;
0308-02 I 181 NUMTAB .DA #%00000010
0309-82 I 182 .DA #%10000010
030A-22 I 183 .DA #%00100010
030B-A2 I 184 .DA #%10100010
030C-12 I 185 .DA #%00010010
030D-92 I 186 .DA #%10010010
030E-32 I 187 .DA #%00110010
030F-B2 I 188 .DA #%10110010
0310-0A I 189 .DA #%00001010
0311-8A I 190 .DA #%10001010
0312-2A I 191 .DA #%00101010
0313-AA I 192 .DA #%10101010
0314-1A I 193 .DA #%00011010
0315-9A I 194 .DA #%10011010
0316-3A I 195 .DA #%00111010
0317-BA I 196 .DA #%10111010
02CC- I 137 ;
02CC-A2 14 I 138 ( 2) BLINK LDX #20 ; 20 BLINKS.
02CE-86 01 I 139 ( 3) STX CNTHI ; SET BLINK COUNTER.
02D0-85 02 I 140 ( 2) STA CNTLO ; BLINK REGISTER
02D2-A5 02 I 141 ( 3) BLOOP LDA CNTLO ; GET BLINK PATTERN
02D4-4D 00 C0 I 142 ( 4) EOR PORT1B ; BLINK LEDS.
02D7-8D 00 C0 I 143 ( 4) STA PORT1B
02DA-A9 0A I 144 ( 2) LDA #10 ; SHORT DELAY
02DC-20 E4 02 I 145 ( 6) JSR DELAY
02DF-C6 01 I 146 ( 5) DEC CNTHI
02E1-D0 EF I 147 (2**) BNE BLOOP ; LOOP IF NOT DONE.
02E3-60 I 148 ( 6) RTS
02E4- I 149 ;
02E4- I 150 ; SUBROUTINE 'DELAY'
02E4- I 151 ; CONTENTS OF ACCUMULATOR DETERMINES DELAY LENGTH.
02E4- I 152 ;
02E4-85 00 I 153 ( 2) DELAY STA TEMP
02E6-A0 10 I 154 ( 2) DL1 LDY #$10
02E8-A2 FF I 155 ( 2) DL2 LDX #$FF
02EA-CA I 156 ( 2) DL3 DEX
02EB-D0 FD I 157 (2**) BNE DL3
02ED-88 I 158 ( 2) DEY
02EE-D0 F8 I 159 (2**) BNE DL2
02F0-C6 00 I 160 ( 5) DEC TEMP
02F2-D0 F2 I 161 (2**) BNE DL1
02F4-60 I 162 ( 6) RTS
02F5- I 163 ;
02F5- I 164 ; SUBROUTINE 'RANDOM'
02F5- I 165 ; RANDOM NUMBER GENERATOR, RETURNS RANDOM NUMBER IN ACCUMULATOR.
02F5- I 166 ;
02F5-38 I 167 ( 2) RANDOM SEC
02F6-A5 09 I 168 ( 3) LDA SCR+1
02F8-65 0C I 169 ( 3) ADC SCR+4
02FA-65 0D I 170 ( 3) ADC SCR+5
02FC-85 08 I 171 ( 2) STA SCR
02FE-A2 04 I 172 ( 2) LDX #4
0300-B5 08 I 173 ( 4) RNDLP LDA SCR,X
0302-95 09 I 174 ( 4) STA SCR+1,X
0304-CA I 175 ( 2) DEX
0305-10 F9 I 176 (2**) BPL RNDLP
0307-60 I 177 ( 6) RTS
0308- I 178 ;
0308- I 179 ; TABLE OF 'REVERSED' NUMBERS FOR DISPLAY
0308- I 180 ; IN BITS 3-8 OF PORT1B, OR LEDS 12-15.
0308- I 181 ;
0308-02 I 182 NUMTAB .DA #%00000010
0309-82 I 183 .DA #%10000010
030A-22 I 184 .DA #%00100010
030B-A2 I 185 .DA #%10100010
030C-12 I 186 .DA #%00010010
030D-92 I 187 .DA #%10010010
030E-32 I 188 .DA #%00110010
030F-B2 I 189 .DA #%10110010
0310-0A I 190 .DA #%00001010
0311-8A I 191 .DA #%10001010
0312-2A I 192 .DA #%00101010
0313-AA I 193 .DA #%10101010
0314-1A I 194 .DA #%00011010
0315-9A I 195 .DA #%10011010
0316-3A I 196 .DA #%00111010
0317-BA I 197 .DA #%10111010

View File

@ -12,11 +12,11 @@
; 6522 VIA #1 ADDRESSES:
TIMER .EQ VIA1+4 ; LOW LATCH OF TIMER 1
DDR1A .EQ VIA1+3 ; PORT A DATA DIRECTION REGISTER
DDR1B .EQ VIA1+3 ; PORT B DATA DIRECTION REGISTER
DDR1B .EQ VIA1+2 ; PORT B DATA DIRECTION REGISTER
PORT1A .EQ VIA1+1 ; PORT A
PORT1B .EQ VIA1 ; PORT B
; 6522 VIA #3 ADDRESSES:
DDR3A .EQ VIA3+1 ; PORT A DATA DIRECTION REGISTER
DDR3A .EQ VIA3+3 ; PORT A DATA DIRECTION REGISTER
DDR3B .EQ VIA3+2 ; PORT B DATA DIRECTION REGISTER
PORT3B .EQ VIA3 ; PORT B
PORT3A .EQ VIA3+1 ; PORT A

View File

@ -1,4 +1,4 @@
20DE02A9FF8D03C08D03C08D02CC8502
20DE02A9FF8D03C08D02C08D02CC8502
A90A8501A9008D01C08D00C0AD04C085
04A92020990220B9020A0A0A0A850020
B902290F05008500A50438E500B00549
@ -12,4 +12,4 @@ A9018D00C0C601D098A9BE2099024C10
C880402010080402012C01CC10FBA20F
8E00CC2C01CC1005CA10F530F18AA012
A2FF2C01CC30E7CAD0F888D0F360A900
8D01CCA9FF8D02CC60
8D03CCA9FF8D02CC60

View File

@ -25,11 +25,11 @@ CC00- 11 VIA3 .EQ $CC00
0203- I 12 ; 6522 VIA #1 ADDRESSES:
C004- I 13 TIMER .EQ VIA1+4 ; LOW LATCH OF TIMER 1
C003- I 14 DDR1A .EQ VIA1+3 ; PORT A DATA DIRECTION REGISTER
C003- I 15 DDR1B .EQ VIA1+3 ; PORT B DATA DIRECTION REGISTER
C002- I 15 DDR1B .EQ VIA1+2 ; PORT B DATA DIRECTION REGISTER
C001- I 16 PORT1A .EQ VIA1+1 ; PORT A
C000- I 17 PORT1B .EQ VIA1 ; PORT B
0203- I 18 ; 6522 VIA #3 ADDRESSES:
CC01- I 19 DDR3A .EQ VIA3+1 ; PORT A DATA DIRECTION REGISTER
CC03- I 19 DDR3A .EQ VIA3+3 ; PORT A DATA DIRECTION REGISTER
CC02- I 20 DDR3B .EQ VIA3+2 ; PORT B DATA DIRECTION REGISTER
CC00- I 21 PORT3B .EQ VIA3 ; PORT B
CC01- I 22 PORT3A .EQ VIA3+1 ; PORT A
@ -43,7 +43,7 @@ CC01- I 22 PORT3A .EQ VIA3+1 ; PORT A
0203- I 30
0203-A9 FF I 31 ( 2) LDA #$FF ; SET UP DATA DIRECTION REGISTERS
0205-8D 03 C0 I 32 ( 4) STA DDR1A
0208-8D 03 C0 I 33 ( 4) STA DDR1B
0208-8D 02 C0 I 33 ( 4) STA DDR1B
020B-8D 02 CC I 34 ( 4) STA DDR3B
020E-85 02 I 35 ( 2) STA DUR ; SET UP TONE DURATIONS.
0210-A9 0A I 36 ( 2) START LDA #$0A ; 10 GUESSES ALLOWED
@ -179,7 +179,7 @@ CC01- I 22 PORT3A .EQ VIA3+1 ; PORT A
02DE- I 32 ; THE CODE.
02DE- I 33 ;
02DE-A9 00 I 34 ( 2) INITKEY LDA #0
02E0-8D 01 CC I 35 ( 4) STA DDR3A ; SET KEY STROBE PORT FOR INPUT
02E0-8D 03 CC I 35 ( 4) STA DDR3A ; SET KEY STROBE PORT FOR INPUT
02E3-A9 FF I 36 ( 2) LDA #$FF
02E5-8D 02 CC I 37 ( 4) STA DDR3B ; SET KEYS FOR OUTPUT
02E8-60 I 38 ( 6) RTS

View File

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

View File

@ -0,0 +1,93 @@
; 'MAGIC SQUARE'
; KEYS 1-9 ON THE HEX KEYBOARD ARE EACH ASSOCIATED WITH ON LED IN THE 3X3
; ARRAY. WHEN A KEY IS PRESSET, IT CHANGES THE PATTERN OF THE LIT LEDS IN THE
; ARRAY. THE OBJECT OF THE GAME IS TO CONVERT THE RANDOM PATTERN THE GAME
; STARTS WITH TO A SQUARE OF LIT LEDS BY PRESSING THE KEYS. THE LEDS WILL FLASH
; WHEN THE WINNING PATTERN IS ACHIEVED. KEY #0 CAN BE USED AT ANY TIME TO
; RESTART THE GAME WITH A NEW PATTERN.
;
;
T1CL .EQ VIA1+4 ; LOW LATCH OF TIMER 1
DDR1A .EQ VIA1+3 ; PORT A DATA DIRECTION REGISTER
DDR1B .EQ VIA1+2 ; PORT B DATA DIRECTION REGISTER
PORT1A .EQ VIA1+1 ; PORT A
PORT2 .EQ VIA1
PORT1B .EQ VIA1 ; PORT B
DDR3A .EQ VIA3+3 ; PORT A DATA DIRECTION REGISTER
DDR3B .EQ VIA3+2 ; PORT B DATA DIRECTION REGISTER
PORT3B .EQ VIA3 ; PORT B
PORT3A .EQ VIA3+1 ; PORT A
ZP .EQ $00
TEMP .EQ ZP ; TEMPORARY STORAGE
;
; COMMENTS: THIS PROGRAM USES A TIMER REGISTER FOR A RANDOM NUMBER SOURCE. IF
; NONE IS AVAILABLE, A RANDOM NUMBER GENERATOR COULD BE USED, BUT DUE TO ITS
; REPEATABILITY, IT WOULD NOT WORK AS WELL. THIS PROGRAM USES THE REGISTERS OF
; VIA1 PORT A FOR THE STORAGE OF THE LED PATTERN. SINCE WHAT IS READ BY THE
; PROCESSOR IS THE POLARITY OF THE OUTPUT, AN EXCESSIVE LOAD ON THE LINES WOULD
; PREVENT THE PROGAM FROM WORKING CORRECTLY.
;
LDA #$FF ; SET UP DATA DIRECTION REGISTERS
STA DDR1A
STA DDR1B
START LDA T1CL ; GET 1ST RANDOM NUMBER
STA PORT1A
LDA T1CL ; ... AND SECOND.
AND #01 ; MASK OUT BOTTOM ROW LEDS
STA PORT1B
KEY JSR GETKEY
CMP #0 ; KEY MUST BE 1-9: IS IT 0?
BEQ START ; YES, RESTART GAME WITH NEW BOARD.
CMP #10 ; IS IT LESS THAN 10?
BPL KEY ; + IF KEY >=10, SO GET ANOTHER.
;
; FOLLOWING SECTION USES KEY NUMBER AS INDEX TO FIND IN TABLE A BIT PATTERN
; USED TO COMPLEMENT LEDS.
;
SEC ; DECREMENT A FOR TABLE ACCESS
SBC #1
ASL A ; MULTIPLY A*2 (EACH ENTRY IN TABLE IS 2 BYTES)
TAX ; USE A AS INDEX
LDA PORT1A ; GET PORT CONTENTS FOR COMPLEMENT
EOR TABLE,X ; EOR PORT CONTENTS WITH PATTERN
STA PORT1A ; RESTORE PORT1A
LDA PORT1B ; DO SAME FOR PORT1B,
EOR TABLE+1,X ; ... USING NEXT TABLE ENTRY.
AND #01 ; MASK OUT BOTTOM ROW LEDS
STA PORT1B ; ... AND RESTORE.
;
; THIS SECTION CHECKS FOR WINNING PATTERN IN LEDS.
;
LSR A ; SHIFT BIT 0 OF PORT 1 INTO CARRY.
BCC KEY ; IF NOT WIN PATTERN, GET NEXT MOVE.
LDA PORT1A ; LOAD PORT1A FOR WIN TEST
CMP #%11101111 ; CHECK FOR WIN PATTERN
BNE KEY ; NO WIN, GET NEXT MOVE
;
; WIN - BLINK LEDS EVERY 1/2 SECOND, 4 TIMES
;
LDA #14
STA TEMP ; LOAD NUMBER OF BLINKS
BLINK LDX #$20 ; DELAY CONSTANT FOR .08 SECOND
DELAY LDY #$FF ; OUTER LOOP OF VARIABLE DELAY ROUTINE, WHOSE DELAY
; IS 2556 * (CONTENTS OF X ON ENTER
DLY NOP ; 10 MICROSECOND LOOP)
BNE DLY0
DLY0 DEY
BNE DLY
DEX
BNE DELAY
LDA PORT1A ; GET PORTS AND COMPLEMENT THEM
EOR #$FF
STA PORT1A
LDA PORT1B
EOR #1
STA PORT1B
DEC TEMP ; COUNT DOWN NUMBER OF BLINKS
BNE BLINK ; DO AGAIN IF NOT DONE
BEQ KEY
;
; TABLE OF CODES USED TO COMPLEMENT LEDS
;
TABLE .HS 1B.00.07.36.00.49.00.BA.00.24.01.D8.00.C0.01.B0.01

View File

@ -0,0 +1,17 @@
.CR 6502
.TF magicsquare.hex,hex
.LF magicsquare.list
;
; HEX GUESSING GAME USING '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,11 @@
20A402A9FF8D03C08D02C0AD04C08D01
C0AD04C029018D00C0207F02C900F0EB
C90A10F538E9010AAAAD01C05D6E028D
01C0AD00C05D6F0229018D00C04A90D9
AD01C0C9EFD0D2A90E8500A220A0FFEA
D00088D0FACAD0F5AD01C049FF8D01C0
AD00C049018D00C0C600D0DFF0AB1B00
0736004900BA002401D800C001B0012C
01CC10FBA20F8E00CC2C01CC1005CA10
F530F18AA012A2FF2C01CC30E7CAD0F8
88D0F360A9008D03CCA9FF8D02CC60

View File

@ -0,0 +1,149 @@
0000- 4 ;
0000- 5 ; HEX GUESSING GAME USING '6502 GAMES' HARDWARE. BOARD SHOULD BE JUMPERED WITH
0000- 6 ; VIA CHIPS AT THE ADDRESSES SPECIFIED BELOW. OTHER THAN THAT THE CODE IS SHOULD
0000- 7 ; BE UNCHANGED FROM THE BOOK THOUGH THERE WILL BE SOME DIFFERENCES DUE TO
0000- 8 ; 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 A4 02 15 ( 6) BEGIN JSR INITKEY
0203- 16 .IN game.asm
0203- I 1 ; 'MAGIC SQUARE'
0203- I 2 ; KEYS 1-9 ON THE HEX KEYBOARD ARE EACH ASSOCIATED WITH ON LED IN THE 3X3
0203- I 3 ; ARRAY. WHEN A KEY IS PRESSET, IT CHANGES THE PATTERN OF THE LIT LEDS IN THE
0203- I 4 ; ARRAY. THE OBJECT OF THE GAME IS TO CONVERT THE RANDOM PATTERN THE GAME
0203- I 5 ; STARTS WITH TO A SQUARE OF LIT LEDS BY PRESSING THE KEYS. THE LEDS WILL FLASH
0203- I 6 ; WHEN THE WINNING PATTERN IS ACHIEVED. KEY #0 CAN BE USED AT ANY TIME TO
0203- I 7 ; RESTART THE GAME WITH A NEW PATTERN.
0203- I 8 ;
0203- I 9 ;
C004- I 10 T1CL .EQ VIA1+4 ; LOW LATCH OF TIMER 1
C003- I 11 DDR1A .EQ VIA1+3 ; PORT A DATA DIRECTION REGISTER
C002- I 12 DDR1B .EQ VIA1+2 ; PORT B DATA DIRECTION REGISTER
C001- I 13 PORT1A .EQ VIA1+1 ; PORT A
C000- I 14 PORT2 .EQ VIA1
C000- I 15 PORT1B .EQ VIA1 ; PORT B
CC03- I 16 DDR3A .EQ VIA3+3 ; PORT A DATA DIRECTION REGISTER
CC02- I 17 DDR3B .EQ VIA3+2 ; PORT B DATA DIRECTION REGISTER
CC00- I 18 PORT3B .EQ VIA3 ; PORT B
CC01- I 19 PORT3A .EQ VIA3+1 ; PORT A
0203- I 20
0000- I 21 ZP .EQ $00
0000- I 22 TEMP .EQ ZP ; TEMPORARY STORAGE
0203- I 23 ;
0203- I 24 ; COMMENTS: THIS PROGRAM USES A TIMER REGISTER FOR A RANDOM NUMBER SOURCE. IF
0203- I 25 ; NONE IS AVAILABLE, A RANDOM NUMBER GENERATOR COULD BE USED, BUT DUE TO ITS
0203- I 26 ; REPEATABILITY, IT WOULD NOT WORK AS WELL. THIS PROGRAM USES THE REGISTERS OF
0203- I 27 ; VIA1 PORT A FOR THE STORAGE OF THE LED PATTERN. SINCE WHAT IS READ BY THE
0203- I 28 ; PROCESSOR IS THE POLARITY OF THE OUTPUT, AN EXCESSIVE LOAD ON THE LINES WOULD
0203- I 29 ; PREVENT THE PROGAM FROM WORKING CORRECTLY.
0203- I 30 ;
0203-A9 FF I 31 ( 2) LDA #$FF ; SET UP DATA DIRECTION REGISTERS
0205-8D 03 C0 I 32 ( 4) STA DDR1A
0208-8D 02 C0 I 33 ( 4) STA DDR1B
020B-AD 04 C0 I 34 ( 4) START LDA T1CL ; GET 1ST RANDOM NUMBER
020E-8D 01 C0 I 35 ( 4) STA PORT1A
0211-AD 04 C0 I 36 ( 4) LDA T1CL ; ... AND SECOND.
0214-29 01 I 37 ( 2) AND #01 ; MASK OUT BOTTOM ROW LEDS
0216-8D 00 C0 I 38 ( 4) STA PORT1B
0219-20 7F 02 I 39 ( 6) KEY JSR GETKEY
021C-C9 00 I 40 ( 2) CMP #0 ; KEY MUST BE 1-9: IS IT 0?
021E-F0 EB I 41 (2**) BEQ START ; YES, RESTART GAME WITH NEW BOARD.
0220-C9 0A I 42 ( 2) CMP #10 ; IS IT LESS THAN 10?
0222-10 F5 I 43 (2**) BPL KEY ; + IF KEY >=10, SO GET ANOTHER.
0224- I 44 ;
0224- I 45 ; FOLLOWING SECTION USES KEY NUMBER AS INDEX TO FIND IN TABLE A BIT PATTERN
0224- I 46 ; USED TO COMPLEMENT LEDS.
0224- I 47 ;
0224-38 I 48 ( 2) SEC ; DECREMENT A FOR TABLE ACCESS
0225-E9 01 I 49 ( 2) SBC #1
0227-0A I 50 ( 2) ASL A ; MULTIPLY A*2 (EACH ENTRY IN TABLE IS 2 BYTES)
0228-AA I 51 ( 2) TAX ; USE A AS INDEX
0229-AD 01 C0 I 52 ( 4) LDA PORT1A ; GET PORT CONTENTS FOR COMPLEMENT
022C-5D 6E 02 I 53 ( 4*) EOR TABLE,X ; EOR PORT CONTENTS WITH PATTERN
022F-8D 01 C0 I 54 ( 4) STA PORT1A ; RESTORE PORT1A
0232-AD 00 C0 I 55 ( 4) LDA PORT1B ; DO SAME FOR PORT1B,
0235-5D 6F 02 I 56 ( 4*) EOR TABLE+1,X ; ... USING NEXT TABLE ENTRY.
0238-29 01 I 57 ( 2) AND #01 ; MASK OUT BOTTOM ROW LEDS
023A-8D 00 C0 I 58 ( 4) STA PORT1B ; ... AND RESTORE.
023D- I 59 ;
023D- I 60 ; THIS SECTION CHECKS FOR WINNING PATTERN IN LEDS.
023D- I 61 ;
023D-4A I 62 ( 2) LSR A ; SHIFT BIT 0 OF PORT 1 INTO CARRY.
023E-90 D9 I 63 (2**) BCC KEY ; IF NOT WIN PATTERN, GET NEXT MOVE.
0240-AD 01 C0 I 64 ( 4) LDA PORT1A ; LOAD PORT1A FOR WIN TEST
0243-C9 EF I 65 ( 2) CMP #%11101111 ; CHECK FOR WIN PATTERN
0245-D0 D2 I 66 (2**) BNE KEY ; NO WIN, GET NEXT MOVE
0247- I 67 ;
0247- I 68 ; WIN - BLINK LEDS EVERY 1/2 SECOND, 4 TIMES
0247- I 69 ;
0247-A9 0E I 70 ( 2) LDA #14
0249-85 00 I 71 ( 2) STA TEMP ; LOAD NUMBER OF BLINKS
024B-A2 20 I 72 ( 2) BLINK LDX #$20 ; DELAY CONSTANT FOR .08 SECOND
024D-A0 FF I 73 ( 2) DELAY LDY #$FF ; OUTER LOOP OF VARIABLE DELAY ROUTINE, WHOSE DELAY
024F- I 74 ; IS 2556 * (CONTENTS OF X ON ENTER
024F-EA I 75 ( 2) DLY NOP ; 10 MICROSECOND LOOP)
0250-D0 00 I 76 (2**) BNE DLY0
0252-88 I 77 ( 2) DLY0 DEY
0253-D0 FA I 78 (2**) BNE DLY
0255-CA I 79 ( 2) DEX
0256-D0 F5 I 80 (2**) BNE DELAY
0258-AD 01 C0 I 81 ( 4) LDA PORT1A ; GET PORTS AND COMPLEMENT THEM
025B-49 FF I 82 ( 2) EOR #$FF
025D-8D 01 C0 I 83 ( 4) STA PORT1A
0260-AD 00 C0 I 84 ( 4) LDA PORT1B
0263-49 01 I 85 ( 2) EOR #1
0265-8D 00 C0 I 86 ( 4) STA PORT1B
0268-C6 00 I 87 ( 5) DEC TEMP ; COUNT DOWN NUMBER OF BLINKS
026A-D0 DF I 88 (2**) BNE BLINK ; DO AGAIN IF NOT DONE
026C-F0 AB I 89 (2**) BEQ KEY
026E- I 90 ;
026E- I 91 ; TABLE OF CODES USED TO COMPLEMENT LEDS
026E- I 92 ;
026E-1B 00 07 36
00 49 00 BA
00 24 01 D8
00 C0 01 B0
01 I 93 TABLE .HS 1B.00.07.36.00.49.00.BA.00.24.01.D8.00.C0.01.B0.01
027F- 17 .IN ../CH01-Getkey/getkey_routine.asm
027F- I 1 ; 'GETKEY' KEYBOARD INPUT ROUTINE READS AND DEBOUNCES KEYBOARD. RETURNS WITH
027F- I 2 ; KEY NUMBER IN ACCUMULATOR IF KEY DOWN. OPERATION: SENDS NUMBERS 0-F TO 74154
027F- I 3 ; (4 TO 16 LINE DECODER), WHICH GROUNDS ONE SIDE OF KEYSWITCHES ONE AT A TIME.
027F- I 4 ; IF A KEY IS DOWN, PA7 OF VIA #3 WILL BE GROUNDED, AND THE CURRENT VALUE
027F- I 5 ; APPLIED TO THE 74154 BE THE KEY NUMBER. WHEN THE PROGRAM DETECTS A KEY CLOSE
027F- I 6 ; CHECKS FOR KEY CLOSURE FOR 50 MS. TO ELIMINATE BOUNCE.
027F- I 7 ; NOTE: IF NO KEY IS PRESSED, GETKEY WILL WAIT.
027F- I 8 ;
027F-2C 01 CC I 9 ( 4) GETKEY BIT PORT3A ; SEE IF KEY IS STILL DOWN FROM LAST KEY CLOSURE:
0282- I 10 ; KEYSTROBE IN 'N' STATUS BIT.
0282-10 FB I 11 (2**) BPL GETKEY ; IF YES, WAIT FOR KEY RELEASE
0284-A2 0F I 12 ( 2) RSTART LDX #15 ; SET KEY COUNTER TO 15
0286-8E 00 CC I 13 ( 4) NXTKEY STX PORT3B ; OUTPUT KEY # TO 74154
0289-2C 01 CC I 14 ( 4) BIT PORT3A ; SEE IF KEY DOWN: STROBE IN 'N'
028C-10 05 I 15 (2**) BPL BOUNCE ; IF YES, GO DEBOUNCE
028E-CA I 16 ( 2) DEX ; DECREMENT KEY #
028F-10 F5 I 17 (2**) BPL NXTKEY ; NO, DO NEXT KEY
0291-30 F1 I 18 (2**) BMI RSTART ; START OVER
0293-8A I 19 ( 2) BOUNCE TXA ; SAVE KEY NUMBER IN A
0294-A0 12 I 20 ( 2) LDY #$12 ; OUTER LOOP CNT LOAD FOR DELAY OF 50 MS.
0296-A2 FF I 21 ( 2) LP1 LDX #$FF ; INNER 11 US. LOOP
0298-2C 01 CC I 22 ( 4) LP2 BIT PORT3A ; SEE IF KEY STILL DOWN
029B-30 E7 I 23 (2**) BMI RSTART ; IF NOT, KEY NOT VALID, RESTART
029D-CA I 24 ( 2) DEX
029E-D0 F8 I 25 (2**) BNE LP2 ; THIS LOOP USES 2115*5 US.
02A0-88 I 26 ( 2) DEY
02A1-D0 F3 I 27 (2**) BNE LP1 ; OUTER LOOP: TOTAL IS 50 MS.
02A3-60 I 28 ( 6) RTS ; DONE: KEY IN A.
02A4- I 29 ;
02A4- I 30 ; SUBROUTINE 'INITKEY'
02A4- I 31 ; TAKES CARE OF INITIALIZING VIA #3 FOR USING WITH THE GETKEY ROUTINE FROM
02A4- I 32 ; THE CODE.
02A4- I 33 ;
02A4-A9 00 I 34 ( 2) INITKEY LDA #0
02A6-8D 03 CC I 35 ( 4) STA DDR3A ; SET KEY STROBE PORT FOR INPUT
02A9-A9 FF I 36 ( 2) LDA #$FF
02AB-8D 02 CC I 37 ( 4) STA DDR3B ; SET KEYS FOR OUTPUT
02AE-60 I 38 ( 6) RTS