6502 games chapter 01 and 02

This commit is contained in:
Tor-Eirik Bakke Lunde 2020-02-29 15:15:21 +01:00
parent 50832bba8a
commit bcd1d163f4
20 changed files with 875 additions and 0 deletions

View File

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

View File

@ -0,0 +1,3 @@
A9008D03CCA9FF8D02CC2C01CC10FBA2
0F8E00CC2C01CC1005CA10F530F18AA0
12A2FF2C01CC30E7CAD0F888D0F360

View File

@ -0,0 +1,40 @@
0400- I 4 ; 'GETKEY' KEYBOARD INPUT ROUTINE READS AND DEBOUNCES KEYBOARD. RETURNS WITH
0400- I 5 ; KEY NUMBER IN ACCUMULATOR IF KEY DOWN. OPERATION: SENDS NUMBERS 0-F TO 74154
0400- I 6 ; (4 TO 16 LINE DECODER), WHICH GROUNDS ONE SIDE OF KEYSWITCHES ONE AT A TIME.
0400- I 7 ; IF A KEY IS DOWN, PA7 OF VIA #3 WILL BE GROUNDED, AND THE CURRENT VALUE
0400- I 8 ; APPLIED TO THE 74154 BE THE KEY NUMBER. WHEN THE PROGRAM DETECTS A KEY CLOSE
0400- I 9 ; CHECKS FOR KEY CLOSURE FOR 50 MS. TO ELIMINATE BOUNCE.
0400- I 10 ; NOTE: IF NO KEY IS PRESSED, GETKEY WILL WAIT.
0400- I 11 ;
0400- I 12 .OR $0400 ; NOTE: BOOK PLACES $0100 INSIDE STACK, BUT WE HAVE
0400- I 13 .TA $0400 ; MORE MEMORY SO WE ASSEMBLE AT 0400 INSTEAD.
0400- I 14
CC03- I 15 DDR3A .EQ $CC03 ; USING RC-ONE ADDRESS DECODING SCHEME, PLACING
CC02- I 16 DDR3B .EQ $CC02 ; VIA3 AT $CC00 BY DEFAULT (INSTEAD OF $AC00)
CC01- I 17 PORT3A .EQ $CC01 ; TO FIT RC-ONE ADDRESS DECODING THOUGH ORIGINAL
CC00- I 18 PORT3B .EQ $CC00 ; CAN BE JUMPERED IF NEEDED/WANTED.
0400- I 19
0400-A9 00 I 20 ( 2) LDA #0
0402-8D 03 CC I 21 ( 4) STA DDR3A ; SET KEY STROBE PORT FOR INPUT
0405-A9 FF I 22 ( 2) LDA #$FF
0407-8D 02 CC I 23 ( 4) STA DDR3B ; SET KEYS FOR OUTPUT
040A-2C 01 CC I 24 ( 4) START BIT PORT3A ; SEE IF KEY IS STILL DOWN FROM LAST KEY CLOSURE:
040D- I 25 ; KEYSTROBE IN 'N' STATUS BIT.
040D-10 FB I 26 (2**) BPL START ; IF YES, WAIT FOR KEY RELEASE
040F-A2 0F I 27 ( 2) RSTART LDX #15 ; SET KEY COUNTER TO 15
0411-8E 00 CC I 28 ( 4) NXTKEY STX PORT3B ; OUTPUT KEY # TO 74154
0414-2C 01 CC I 29 ( 4) BIT PORT3A ; SEE IF KEY DOWN: STROBE IN 'N'
0417-10 05 I 30 (2**) BPL BOUNCE ; IF YES, GO DEBOUNCE
0419-CA I 31 ( 2) DEX ; DECREMENT KEY #
041A-10 F5 I 32 (2**) BPL NXTKEY ; NO, DO NEXT KEY
041C-30 F1 I 33 (2**) BMI RSTART ; START OVER
041E-8A I 34 ( 2) BOUNCE TXA ; SAVE KEY NUMBER IN A
041F-A0 12 I 35 ( 2) LDY #$12 ; OUTER LOOP CNT LOAD FOR DELAY OF 50 MS.
0421-A2 FF I 36 ( 2) LP1 LDX #$FF ; INNER 11 US. LOOP
0423-2C 01 CC I 37 ( 4) LP2 BIT PORT3A ; SEE IF KEY STILL DOWN
0426-30 E7 I 38 (2**) BMI RSTART ; IF NOT, KEY NOT VALID, RESTART
0428-CA I 39 ( 2) DEX
0429-D0 F8 I 40 (2**) BNE LP2 ; THIS LOOP USES 2115*5 US.
042B-88 I 41 ( 2) DEY
042C-D0 F3 I 42 (2**) BNE LP1 ; OUTER LOOP: TOTAL IS 50 MS.
042E-60 I 43 ( 6) RTS ; DONE: KEY IN A.

View File

@ -0,0 +1,32 @@
.CR 6502
.TF readkey.hex,hex
.LF readkey.list
;
; SMALL PROGRAM FOR THE KIM-1 COMPUTER THAT SEEKS TO DEMONSTRATE THE GET KEY
; ROUTINE FROM CH1 - ESSENTIALLY WE ATTEMPT TO READ THE KEY AND JUST OUTPUT
; IT ONTO THE DISPLAYS. THE BOOK DETAILS THE USE OF A SYM-1 COMPUTER, SO
; WHATEVER BUGS YOU MAY FIND CAN BE BLAMED ON ME AND NOT THE AUTHOR OF THE
; BOOK.
;
.OR $0200
.TA $0200
POINTL .EQ $FA ; ADDRESS LO ON DISPLAY
POINTH .EQ $FB ; ADDRESS HI ON DISPLAY
INH .EQ $F9 ; INPUTBUFFER HI
SCANDS .EQ $1F1F ; MONITOR FUNCTION TO OUTPUT A DIGIT
RC_ONE LDA #0
STA DDR3A ; SET KEY STROBE PORT FOR INPUT
LDA #$FF
STA DDR3B ; SET KEYS FOR OUTPUT
LDA #0
STA POINTH
STA POINTL
STA INH
LOOP JSR GETKEY ; GET THE KEY USING THE SUB-ROUTINE FROM THE BOOK,
STA INH ; WE'LL HAVE IT IN A SO STORE IT TO DATA DIGITS.
JSR SCANDS ; HAVE THE MONITOR OUTPUT THE VALUE
JMP LOOP ; DO IT ALL AGAIN
.IN ../../common/CH01-Getkey/getkey_routine.asm

View File

@ -0,0 +1,5 @@
A9008D03CCA9FF8D02CCA90085FB85FA
85F920270285F9201F1F4C1202A9008D
03CCA9FF8D02CC2C01CC10FBA20F8E00
CC2C01CC1005CA10F530F18AA012A2FF
2C01CC30E7CAD0F888D0F360

View File

@ -0,0 +1,66 @@
0000- 4 ;
0000- 5 ; SMALL PROGRAM FOR THE KIM-1 COMPUTER THAT SEEKS TO DEMONSTRATE THE GET KEY
0000- 6 ; ROUTINE FROM CH1 - ESSENTIALLY WE ATTEMPT TO READ THE KEY AND JUST OUTPUT
0000- 7 ; IT ONTO THE DISPLAYS. THE BOOK DETAILS THE USE OF A SYM-1 COMPUTER, SO
0000- 8 ; WHATEVER BUGS YOU MAY FIND CAN BE BLAMED ON ME AND NOT THE AUTHOR OF THE
0000- 9 ; BOOK.
0000- 10 ;
0200- 11 .OR $0200
0200- 12 .TA $0200
00FA- 13 POINTL .EQ $FA ; ADDRESS LO ON DISPLAY
00FB- 14 POINTH .EQ $FB ; ADDRESS HI ON DISPLAY
00F9- 15 INH .EQ $F9 ; INPUTBUFFER HI
1F1F- 16 SCANDS .EQ $1F1F ; MONITOR FUNCTION TO OUTPUT A DIGIT
0200- 17
0200-A9 00 18 ( 2) RC_ONE LDA #0
0202-8D 03 CC 19 ( 4) STA DDR3A ; SET KEY STROBE PORT FOR INPUT
0205-A9 FF 20 ( 2) LDA #$FF
0207-8D 02 CC 21 ( 4) STA DDR3B ; SET KEYS FOR OUTPUT
020A-A9 00 22 ( 2) LDA #0
020C-85 FB 23 ( 2) STA POINTH
020E-85 FA 24 ( 2) STA POINTL
0210-85 F9 25 ( 2) STA INH
0212-20 27 02 26 ( 6) LOOP JSR GETKEY ; GET THE KEY USING THE SUB-ROUTINE FROM THE BOOK,
0215-85 F9 27 ( 2) STA INH ; WE'LL HAVE IT IN A SO STORE IT TO DATA DIGITS.
0217-20 1F 1F 28 ( 6) JSR SCANDS ; HAVE THE MONITOR OUTPUT THE VALUE
021A-4C 12 02 29 ( 3) JMP LOOP ; DO IT ALL AGAIN
021D- 30
021D- 31 .IN ../../common/CH01-Getkey/getkey_routine.asm
021D- I 1 ; 'GETKEY' KEYBOARD INPUT ROUTINE READS AND DEBOUNCES KEYBOARD. RETURNS WITH
021D- I 2 ; KEY NUMBER IN ACCUMULATOR IF KEY DOWN. OPERATION: SENDS NUMBERS 0-F TO 74154
021D- I 3 ; (4 TO 16 LINE DECODER), WHICH GROUNDS ONE SIDE OF KEYSWITCHES ONE AT A TIME.
021D- I 4 ; IF A KEY IS DOWN, PA7 OF VIA #3 WILL BE GROUNDED, AND THE CURRENT VALUE
021D- I 5 ; APPLIED TO THE 74154 BE THE KEY NUMBER. WHEN THE PROGRAM DETECTS A KEY CLOSE
021D- I 6 ; CHECKS FOR KEY CLOSURE FOR 50 MS. TO ELIMINATE BOUNCE.
021D- I 7 ; NOTE: IF NO KEY IS PRESSED, GETKEY WILL WAIT.
021D- I 8 ;
CC03- I 9 DDR3A .EQ $CC03 ; USING RC-ONE ADDRESS DECODING SCHEME, PLACING
CC02- I 10 DDR3B .EQ $CC02 ; VIA3 AT $CC00 BY DEFAULT (INSTEAD OF $AC00)
CC01- I 11 PORT3A .EQ $CC01 ; TO FIT RC-ONE ADDRESS DECODING THOUGH ORIGINAL
CC00- I 12 PORT3B .EQ $CC00 ; CAN BE JUMPERED IF NEEDED/WANTED.
021D- I 13
021D-A9 00 I 14 ( 2) LDA #0
021F-8D 03 CC I 15 ( 4) STA DDR3A ; SET KEY STROBE PORT FOR INPUT
0222-A9 FF I 16 ( 2) LDA #$FF
0224-8D 02 CC I 17 ( 4) STA DDR3B ; SET KEYS FOR OUTPUT
0227-2C 01 CC I 18 ( 4) GETKEY BIT PORT3A ; SEE IF KEY IS STILL DOWN FROM LAST KEY CLOSURE:
022A- I 19 ; KEYSTROBE IN 'N' STATUS BIT.
022A-10 FB I 20 (2**) BPL GETKEY ; IF YES, WAIT FOR KEY RELEASE
022C-A2 0F I 21 ( 2) RSTART LDX #15 ; SET KEY COUNTER TO 15
022E-8E 00 CC I 22 ( 4) NXTKEY STX PORT3B ; OUTPUT KEY # TO 74154
0231-2C 01 CC I 23 ( 4) BIT PORT3A ; SEE IF KEY DOWN: STROBE IN 'N'
0234-10 05 I 24 (2**) BPL BOUNCE ; IF YES, GO DEBOUNCE
0236-CA I 25 ( 2) DEX ; DECREMENT KEY #
0237-10 F5 I 26 (2**) BPL NXTKEY ; NO, DO NEXT KEY
0239-30 F1 I 27 (2**) BMI RSTART ; START OVER
023B-8A I 28 ( 2) BOUNCE TXA ; SAVE KEY NUMBER IN A
023C-A0 12 I 29 ( 2) LDY #$12 ; OUTER LOOP CNT LOAD FOR DELAY OF 50 MS.
023E-A2 FF I 30 ( 2) LP1 LDX #$FF ; INNER 11 US. LOOP
0240-2C 01 CC I 31 ( 4) LP2 BIT PORT3A ; SEE IF KEY STILL DOWN
0243-30 E7 I 32 (2**) BMI RSTART ; IF NOT, KEY NOT VALID, RESTART
0245-CA I 33 ( 2) DEX
0246-D0 F8 I 34 (2**) BNE LP2 ; THIS LOOP USES 2115*5 US.
0248-88 I 35 ( 2) DEY
0249-D0 F3 I 36 (2**) BNE LP1 ; OUTER LOOP: TOTAL IS 50 MS.
024B-60 I 37 ( 6) RTS ; DONE: KEY IN A.
024C- 32

View File

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

View File

@ -0,0 +1,12 @@
.CR 6502
.TF music.hex,hex
.LF music.list
;
; MUSIC PLAYER FOR THE KIM-1 USING '6502 GAMES' HARDWARE, THIS ASSUMES THE
; BOARD IS JUMPERED FOR ADDRESSES $C000 AND $CC00 FOR VIA CHIPS. OTHER THAN
; THAT THE CODE IS UNCHANGED FROM THE BOOK.
;
.OR $0200
.TA $0200
.IN ../../common/CH02-Music/player.asm
.IN ../../common/CH01-Getkey/getkey_routine.asm

View File

@ -0,0 +1,17 @@
A90085001820E802C90FD00520870290
EFC90ED0062048021890EA8501207002
A500C9FFD00520870290DA4AA8A501B0
09290F990003E60090CB0A0A0A0A1900
03990003E60090BDA2008602A5024AAA
BD0003B004290F900629F04A4A4A4A20
7002A220209C02E602A502C50090DF60
C90DD006A254209C0260AABDD1028504
BDC40220A80260A9FF8504A94B20A802
A93820A802A94B20A8021860A0FFEAD0
0088D0FACAD0F5608503A9FF8D02CCA9
00A604A40388189000D0FA49FF8D00CC
CAD0F060FEE2C9BEA9968E867E777064
5E55606B72808F94A1AAB5BFD7E4A900
8D03CCA9FF8D02CC2C01CC10FBA20F8E
00CC2C01CC1005CA10F530F18AA012A2
FF2C01CC30E7CAD0F888D0F360

View File

@ -0,0 +1,209 @@
0000- 4 ;
0000- 5 ; MUSIC PLAYER FOR THE KIM-1 USING '6502 GAMES' HARDWARE, THIS ASSUMES THE
0000- 6 ; BOARD IS JUMPERED FOR ADDRESSES $C000 AND $CC00 FOR VIA CHIPS. OTHER THAN
0000- 7 ; THAT THE CODE IS UNCHANGED FROM THE BOOK.
0000- 8 ;
0200- 9 .OR $0200
0200- 10 .TA $0200
0200- 11 .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 ;
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
0003- I 12 FREQ .EQ $03 ; TEMPORARY STORAGE FOR FREQUENCY
0004- I 13 DUR .EQ $04 ; TEMP STORAGE FOR DURATION
0300- I 14 TABEG .EQ $0300 ; TABLE TO STORE MUSIC
CC00- I 15 PORT3B .EQ $CC00 ; VIA OUTPUT PORT B
CC02- I 16 DDR3B .EQ $CC02 ; 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
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
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- 12 .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 $CC03 ; USING RC-ONE ADDRESS DECODING SCHEME, PLACING
CC02- I 10 DDR3B .EQ $CC02 ; VIA3 AT $CC00 BY DEFAULT (INSTEAD OF $AC00)
CC01- I 11 PORT3A .EQ $CC01 ; TO FIT RC-ONE ADDRESS DECODING THOUGH ORIGINAL
CC00- I 12 PORT3B .EQ $CC00 ; 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.

View File

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

View File

@ -0,0 +1,7 @@
.CR 6502
.TF getkey.hex,hex
.LF getkey.list
.OR $0100 ; NOTE: BOOK PLACES $0100 INSIDE STACK, MEANING
.TA $0100 ; THAT ROUTINE MAY EASILY GET OVERWRITTEN.
.IN getkey_routine.asm

View File

@ -0,0 +1,3 @@
A9008D03CCA9FF8D02CC2C01CC10FBA2
0F8E00CC2C01CC1005CA10F530F18AA0
12A2FF2C01CC30E7CAD0F888D0F360

View File

@ -0,0 +1,41 @@
0000- 4
0400- 5 .OR $0400 ; NOTE: BOOK PLACES $0100 INSIDE STACK, BUT WE HAVE
0400- 6 .TA $0400 ; MORE MEMORY SO WE ASSEMBLE AT 0400 INSTEAD.
0400- 7 .IN getkey_routine.asm
0400- I 1 ; 'GETKEY' KEYBOARD INPUT ROUTINE READS AND DEBOUNCES KEYBOARD. RETURNS WITH
0400- I 2 ; KEY NUMBER IN ACCUMULATOR IF KEY DOWN. OPERATION: SENDS NUMBERS 0-F TO 74154
0400- I 3 ; (4 TO 16 LINE DECODER), WHICH GROUNDS ONE SIDE OF KEYSWITCHES ONE AT A TIME.
0400- I 4 ; IF A KEY IS DOWN, PA7 OF VIA #3 WILL BE GROUNDED, AND THE CURRENT VALUE
0400- I 5 ; APPLIED TO THE 74154 BE THE KEY NUMBER. WHEN THE PROGRAM DETECTS A KEY CLOSE
0400- I 6 ; CHECKS FOR KEY CLOSURE FOR 50 MS. TO ELIMINATE BOUNCE.
0400- I 7 ; NOTE: IF NO KEY IS PRESSED, GETKEY WILL WAIT.
0400- I 8 ;
CC03- I 9 DDR3A .EQ $CC03 ; USING RC-ONE ADDRESS DECODING SCHEME, PLACING
CC02- I 10 DDR3B .EQ $CC02 ; VIA3 AT $CC00 BY DEFAULT (INSTEAD OF $AC00)
CC01- I 11 PORT3A .EQ $CC01 ; TO FIT RC-ONE ADDRESS DECODING THOUGH ORIGINAL
CC00- I 12 PORT3B .EQ $CC00 ; CAN BE JUMPERED IF NEEDED/WANTED.
0400- I 13
0400-A9 00 I 14 ( 2) LDA #0
0402-8D 03 CC I 15 ( 4) STA DDR3A ; SET KEY STROBE PORT FOR INPUT
0405-A9 FF I 16 ( 2) LDA #$FF
0407-8D 02 CC I 17 ( 4) STA DDR3B ; SET KEYS FOR OUTPUT
040A-2C 01 CC I 18 ( 4) GETKEY BIT PORT3A ; SEE IF KEY IS STILL DOWN FROM LAST KEY CLOSURE:
040D- I 19 ; KEYSTROBE IN 'N' STATUS BIT.
040D-10 FB I 20 (2**) BPL GETKEY ; IF YES, WAIT FOR KEY RELEASE
040F-A2 0F I 21 ( 2) RSTART LDX #15 ; SET KEY COUNTER TO 15
0411-8E 00 CC I 22 ( 4) NXTKEY STX PORT3B ; OUTPUT KEY # TO 74154
0414-2C 01 CC I 23 ( 4) BIT PORT3A ; SEE IF KEY DOWN: STROBE IN 'N'
0417-10 05 I 24 (2**) BPL BOUNCE ; IF YES, GO DEBOUNCE
0419-CA I 25 ( 2) DEX ; DECREMENT KEY #
041A-10 F5 I 26 (2**) BPL NXTKEY ; NO, DO NEXT KEY
041C-30 F1 I 27 (2**) BMI RSTART ; START OVER
041E-8A I 28 ( 2) BOUNCE TXA ; SAVE KEY NUMBER IN A
041F-A0 12 I 29 ( 2) LDY #$12 ; OUTER LOOP CNT LOAD FOR DELAY OF 50 MS.
0421-A2 FF I 30 ( 2) LP1 LDX #$FF ; INNER 11 US. LOOP
0423-2C 01 CC I 31 ( 4) LP2 BIT PORT3A ; SEE IF KEY STILL DOWN
0426-30 E7 I 32 (2**) BMI RSTART ; IF NOT, KEY NOT VALID, RESTART
0428-CA I 33 ( 2) DEX
0429-D0 F8 I 34 (2**) BNE LP2 ; THIS LOOP USES 2115*5 US.
042B-88 I 35 ( 2) DEY
042C-D0 F3 I 36 (2**) BNE LP1 ; OUTER LOOP: TOTAL IS 50 MS.
042E-60 I 37 ( 6) RTS ; DONE: KEY IN A.

View File

@ -0,0 +1,37 @@
; 'GETKEY' KEYBOARD INPUT ROUTINE READS AND DEBOUNCES KEYBOARD. RETURNS WITH
; KEY NUMBER IN ACCUMULATOR IF KEY DOWN. OPERATION: SENDS NUMBERS 0-F TO 74154
; (4 TO 16 LINE DECODER), WHICH GROUNDS ONE SIDE OF KEYSWITCHES ONE AT A TIME.
; IF A KEY IS DOWN, PA7 OF VIA #3 WILL BE GROUNDED, AND THE CURRENT VALUE
; APPLIED TO THE 74154 BE THE KEY NUMBER. WHEN THE PROGRAM DETECTS A KEY CLOSE
; CHECKS FOR KEY CLOSURE FOR 50 MS. TO ELIMINATE BOUNCE.
; NOTE: IF NO KEY IS PRESSED, GETKEY WILL WAIT.
;
DDR3A .EQ $CC03 ; USING RC-ONE ADDRESS DECODING SCHEME, PLACING
DDR3B .EQ $CC02 ; VIA3 AT $CC00 BY DEFAULT (INSTEAD OF $AC00)
PORT3A .EQ $CC01 ; TO FIT RC-ONE ADDRESS DECODING THOUGH ORIGINAL
PORT3B .EQ $CC00 ; CAN BE JUMPERED IF NEEDED/WANTED.
LDA #0
STA DDR3A ; SET KEY STROBE PORT FOR INPUT
LDA #$FF
STA DDR3B ; SET KEYS FOR OUTPUT
GETKEY BIT PORT3A ; SEE IF KEY IS STILL DOWN FROM LAST KEY CLOSURE:
; KEYSTROBE IN 'N' STATUS BIT.
BPL GETKEY ; IF YES, WAIT FOR KEY RELEASE
RSTART LDX #15 ; SET KEY COUNTER TO 15
NXTKEY STX PORT3B ; OUTPUT KEY # TO 74154
BIT PORT3A ; SEE IF KEY DOWN: STROBE IN 'N'
BPL BOUNCE ; IF YES, GO DEBOUNCE
DEX ; DECREMENT KEY #
BPL NXTKEY ; NO, DO NEXT KEY
BMI RSTART ; START OVER
BOUNCE TXA ; SAVE KEY NUMBER IN A
LDY #$12 ; OUTER LOOP CNT LOAD FOR DELAY OF 50 MS.
LP1 LDX #$FF ; INNER 11 US. LOOP
LP2 BIT PORT3A ; SEE IF KEY STILL DOWN
BMI RSTART ; IF NOT, KEY NOT VALID, RESTART
DEX
BNE LP2 ; THIS LOOP USES 2115*5 US.
DEY
BNE LP1 ; OUTER LOOP: TOTAL IS 50 MS.
RTS ; DONE: KEY IN A.

View File

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

View File

@ -0,0 +1,8 @@
.CR 6502
.TF music.hex,hex
.LF music.list
.OR $0200
.TA $0200
.IN player.asm
.IN ../CH01-Getkey/getkey_routine.asm

View File

@ -0,0 +1,17 @@
A90085001820E802C90FD00520870290
EFC90ED0062048021890EA8501207002
A500C9FFD00520870290DA4AA8A501B0
09290F990003E60090CB0A0A0A0A1900
03990003E60090BDA2008602A5024AAA
BD0003B004290F900629F04A4A4A4A20
7002A220209C02E602A502C50090DF60
C90DD006A254209C0260AABDD1028504
BDC40220A80260A9FF8504A94B20A802
A93820A802A94B20A8021860A0FFEAD0
0088D0FACAD0F5608503A9FF8D02CCA9
00A604A40388189000D0FA49FF8D00CC
CAD0F060FEE2C9BEA9968E867E777064
5E55606B72808F94A1AAB5BFD7E4A900
8D03CCA9FF8D02CC2C01CC10FBA20F8E
00CC2C01CC1005CA10F530F18AA012A2
FF2C01CC30E7CAD0F888D0F360

View File

@ -0,0 +1,205 @@
0000- 4
0200- 5 .OR $0200
0200- 6 .TA $0200
0200- 7 .IN 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 ;
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
0003- I 12 FREQ .EQ $03 ; TEMPORARY STORAGE FOR FREQUENCY
0004- I 13 DUR .EQ $04 ; TEMP STORAGE FOR DURATION
0300- I 14 TABEG .EQ $0300 ; TABLE TO STORE MUSIC
CC00- I 15 PORT3B .EQ $CC00 ; VIA OUTPUT PORT B
CC02- I 16 DDR3B .EQ $CC02 ; 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
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
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- 8 .IN ../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 $CC03 ; USING RC-ONE ADDRESS DECODING SCHEME, PLACING
CC02- I 10 DDR3B .EQ $CC02 ; VIA3 AT $CC00 BY DEFAULT (INSTEAD OF $AC00)
CC01- I 11 PORT3A .EQ $CC01 ; TO FIT RC-ONE ADDRESS DECODING THOUGH ORIGINAL
CC00- I 12 PORT3B .EQ $CC00 ; 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.

View File

@ -0,0 +1,157 @@
; MUSIC PLAYER PROGRAM
; USES 16-KEY KEYBOARD AND BUFFERED SPEAKER
; PROGRAM PLAYS STORED MUSICAL NOTES. THERE ARE TWO MODES OF OPERATION: INPUT
; AND PLAY. INPUT MODE IS THE DEFAULT, AND ALL NON-COMMAND KEYS PRESSED PRESSED
; (0-D) ARE STORED FOR REPLAY. IF AN OVERFLOW OCCURS, THE USER IS WARMED WITH
; A THREE-TONE WARNING. THE SAME WARBLING TONE IS ALSO USED TO SIGNAL A RESTART
; OF THE PROGRAM.
;
PILEN .EQ $00 ; LENGTH OF NOTE LIST
TEMP .EQ $01 ; TEMPORARY STORAGE
PTR .EQ $02 ; CURRENT LOCATION IN LIST
FREQ .EQ $03 ; TEMPORARY STORAGE FOR FREQUENCY
DUR .EQ $04 ; TEMP STORAGE FOR DURATION
TABEG .EQ $0300 ; TABLE TO STORE MUSIC
PORT3B .EQ $CC00 ; VIA OUTPUT PORT B
DDR3B .EQ $CC02 ; VIA PORT B DIRECTION REGISTER
;
; COMMAND LINE INTERPRETER
; $F AS INPUT MEANS RESET POINTERS, START OVER.
; $E MEANS PLAY CURRENTLY STORED NOTES
; ANYTHING ELSE IS STORED FOR REPLAY.
;
START LDA #0 ; CLEAR NOTE LIST LENGTH
STA PILEN
CLC ; CLEAR NIBBLE MARKER
NXKEY JSR GETKEY
CMP #15 ; IS KEY #15?
BNE NXTST ; NO, DO NEXT TEST
JSR BEEP3 ; TELL USER OF CLEARING
BCC START ; CLEAR POINTERS AND START OVER
NXTST CMP #14 ; IS KEY #14?
BNE NUMKEY ; NO, KEY IS NOTE NUMBER
JSR PLAYEM ; PLAY NOTES
CLC
BCC NXKEY ; GET NEXT COMMAND
;
; ROUTINE TO LOAD NOT LIST WITH NOTES
;
NUMKEY STA TEMP ; SAVE KEY, FREE A
JSR PLAYIT ; PLAY NOTE
LDA PILEN ; GET LIST LENGTH
CMP #$FF ; OVERFLOW?
BNE OK ; NO, ADD NOTE TO LIST
JSR BEEP3 ; YES, WARN USER
BCC NXKEY ; RETURN TO INPUT MODE
OK LSR A ; SHIFT LOW BIT INTO NIBBLE POINTER
TAY ; USE SHIFTED NIBBLE POINTER AS BYTE INDEX
LDA TEMP ; RESTORE KEY#
BCS FINBYT ; IF BYTE ALREADY HAS A NIBBLE, FINISH IT AND STORE
AND #%00001111 ; 1ST NIBBLE. MASK HIGH NIBBLE
STA TABEG,Y ; SAVE UNFINISHED 1/2 BYTE
INC PILEN ; POINT TO NEXT NIBBLE
BCC NXKEY ; GET NEXT KEYSTROKE
FINBYT ASL A ; SHIFT NIBBLE 2 TO HIGH ORDER
ASL A
ASL A
ASL A
ORA TABEG,Y ; JOIN 2 NIBBLES AS BYTE
STA TABEG,Y ; ... AND STORE.
INC PILEN ; POINT TO NEXT NIBBLE IN NEXT BYTE
BCC NXKEY ; RETURN
;
; ROUTINE TO PLAY NOTES
;
PLAYEM LDX #0 ; CLEAR POINTER
STX PTR
LDA PTR ; LOAD ACCUMULATOR WITH CURRENT POINTER VALUE
LOOP LSR A ; SHIFT NIBBLE INDICATOR INTO CARRY
TAX ; USE SHIFTED NIBBLE POINTER AS BYTE POINTER
LDA TABEG,X ; LOAD NOTE TO PLAY
BCS ENDBYT ; LOW NIBBLE USED, GET HIGH
AND #%00001111 ; MASK OUT HIGH BITS
BCC FINISH ; PLAY NOTE
ENDBYT AND #%11110000 ; THROW AWAY LOW NIBBLE
LSR A ; SHIFT INTO LOW
LSR A
LSR A
LSR A
FINISH JSR PLAYIT ; CALCULATE CONSTANTS & PLAY
LDX #$20 ; BETWEEN-NOTE DELAY
JSR DELAY
INC PTR ; ONE NIBBLE USED
LDA PTR
CMP PILEN ; END OF LIST?
BCC LOOP ; NO, GET NEXT NOTE
RTS ; DONE
;
; ROUTINE TO DO TABLE LOOK UP, SEPARATE REST
;
PLAYIT CMP #13 ; REST?
BNE SOUND ; NO.
LDX #$54 ; DELAY = NOTE LENGTH = .21SEC
JSR DELAY
RTS
SOUND TAX ; USE KEYS AS INDEX..
LDA DURTAB,X ; ... TO FIND DURATION.
STA DUR ; STORE DURATION FOR USE
LDA NOTAB,X ; LOAD NOTE VALUE
JSR TONE
RTS
;
; ROUTINE TO MAKE 3 TONE SIGNAL
;
BEEP3 LDA #$FF ; DURATION FOR BEEPS
STA DUR
LDA #$4B ; CODE FOR E2
JSR TONE ; 1ST NOTE
LDA #$38 ; CODE FOR D2
JSR TONE
LDA #$4B
JSR TONE
CLC
RTS
;
; VARIABLE-LENGTH DELAY
;
DELAY LDY #$FF
DLY NOP
BNE DL0 ; (.+2 IN BOOK)
DL0 DEY
BNE DLY ; 10 US. LOOP
DEX
BNE DELAY ; LOOP TIME = 2556*[X]
RTS
;
; ROUTINE TO MAKE TONE: # OF 1/2 CYCLES IS IN 'DUR', AND 1/2 CYCLE TIME IS IN
; ACCUMULATOR. LOOP TIME = 20*[A]+26 US SINCE TWO RUNS THROUGH THE OUTER LOOP
; MAKES ONE CYCLE OF THE TONE.
;
TONE STA FREQ ; FREQ IS TEMP FOR # OF CYCLES
LDA #$FF ; SET UP DATA DIRECTION REGISTER
STA DDR3B
LDA #$00 ; A IS SENT TO PORT, START HI
LDX DUR
FL2 LDY FREQ
FL1 DEY
CLC
BCC FL0 ; (.+2 IN BOOK)
FL0 BNE FL1 ; INNER, 10 US LOOP.
EOR #$FF ; COMPLEMENT I/O PORT
STA PORT3B ; ... AND SET IT
DEX
BNE FL2 ; OUTER LOOP
RTS
;
; TABLE OF NOTE CONSTANTS
; CONTAINS:
; [OCTAVE BELOW MIDDLE C] : G,A,BCC
; [OCTAVE OF MIDDLE C] : C,D,E,F,F#,G,G#,A,B
; [OCTAVE ABOVE MIDDLE C] : C
;
NOTAB .HS FE.E2.C9.BE.A9.96.8E.86.7E.77.70.64.5E
;
; TABLE OF NOTE DURATIONS IN # OF 1/2 CYCLES SET FOR A NOTE LENGTH OF
; ABOUT .21 SEC.
;
DURTAB .HS 55.60.6B.72.80.8F.94.A1.AA.B5.BF.D7.E4