CPU 6502U ; enable undocumented instructions LIST OFF INCLUDE stella.h LIST ON ORG $80 StepAL DS 1 ; Low byte of channel 1 step StepAH DS 1 ; High byte of channel 1 step CntAL DS 1 ; Low byte of channel 1 count CntAH DS 1 ; High byte of channel 1 count StepBL DS 1 ; Low byte of channel 2 step StepBH DS 1 ; High byte of channel 2 step CntBL DS 1 ; Low byte of channel 2 count CntBH DS 1 ; High byte of channel 2 count KeyCode DS 1 ; last keycode KeyTmp DS 1 ; temp storage for new keypress Line DS 1 ; graphics line counter Index DS 1 ; index into P0data SwB DS 1 ; SwchB from previous frame SwB1 DS 1 ; SwchB from current frame Mode DS 1 ; even for red box, odd for blue box ; LIST MACRO ORG $F000 START: CLD ; LDX #$FF ; X = $FF ; TXS ; init stack pointer ; INX ; X = $00 ; TXA ; A = $00 ;@1: STA $00,X ; clear TIA registers and RAM, $00-$FF ; INX ; BNE @1 ; ends with X=$00 ; note about above init code: it leaves nice default P0 and P1 horizontal positions ; this is someone else's startup routine ; it takes one less byte than the above ; and leaves SP=$FF, X=$00 LDX #0 TXS PHA TXA @1 PHA DEX BNE @1 LDA #$FF ; set port A to output only STA SwACnt ; LDA #$40 ; set the background to ; STA CoLuBk ; some appropriate color LDA #$00 STA CoLuPf ; LDA #$00 ; set port B to input only STA SwBCnt ; set up P0/P1 position STA WSync LDX #6 ; delay for P0 position, 15 pixels per loop @2 DEX BPL @2 BMI .+2 STA ResP0 ; set P0 position NOP ; P1 will be 15 pixels later STA ResP1 ; set P1 position LDA #$F0 ; HMP1 value, right 1 pixel STA HMP1 ; set P1 adjustment STA WSync ; wait for start of line STA HMove ; move P1 JMP Top ; jump into main loop ; DoSound macro, 65 cycles (leaves 76-65 = 11 cycles per line) ; With LAX instr, 61 cycles (leaves 76-61 = 15 cycles per line) DoSound MACRO STA WSync ; 3 CLC ; 2 27 (29) cycles for this group LDA CntAL ; 3 ADC StepAL ; 3 STA CntAL ; 3 LAX CntAH ; 3 this delays the sound by one scan line, but saves 4 cycles ; LDA CntAH ;(3) ADC StepAH ; 3 STA CntAH ; 3 ; TAX ;(2) LDA SinTab,X ; 4 STA AudV0 ; 3 CLC ; 2 27 (29) cycles for this group, too LDA CntBL ; 3 ADC StepBL ; 3 STA CntBL ; 3 LAX CntBH ; 3 ; LDA CntBH ;(3) ADC StepBH ; 3 STA CntBH ; 3 ; TAX ;(2) LDA SinTab,X ; 4 STA AudV1 ; 3 ENDM Bottom: DoSound INY ; check for bottom of screen CPY #222 BNE Bottom Top: LDY #40 ; initialize scan line count LDA #$82 ; start blank, disable latch, dump ports STA VSync ; start vertical sync STA VBlank ; start vertical blanking @1: DoSound DEY CPY #38 BNE @1 LDA #0 ; end vertical sync STA VSync @2: DoSound DEY BNE @2 STY VBlank ; end vertical blank DoSound INY ; 2 LDA Mode ; 3 RORA ; 2 LDA #$40 ; 2 - $40 red for red box BCC @3 ; 2 LDA #$80 ; 2 - $80 blue for blue box (could also ASLA here) @3: STA CoLuBk ; 2 - set background color DoSound INY Row1: LDA #$EE ; 2 - scan first keypad row STA SwchA ; 3 @1: JSR DS1 ; give it some time to settle CPY #4 ; 3 BNE @1 ; 2 JSR DS1 LDA Inpt0 ; 3 check first key BMI @2 ; 2 DoSound INY ; 2 LDA Inpt1 ; 3 make sure second key is off BPL @4 ; 2 if both first and second key, ignore row LDX #1 ; 2 JMP DoKey ; 3 @2: DoSound INY LDX #2 ; check second key LDA Inpt1 BMI @3 JMP DoKey @3: DoSound INY LDX #3 ; check third key LDA Inpt4 BMI @4 JMP DoKey @4: DoSound INY LDA Inpt2 ; check first key BMI @5 DoSound INY LDA Inpt3 ; make sure second key is off BPL @7 ; if both first and second key, ignore row LDX #13 JMP DoKey @5: DoSound INY LDX #14 ; check second key LDA Inpt3 BMI @6 JMP DoKey @6: DoSound INY LDX #15 ; check third key LDA Inpt5 BMI @7 JMP DoKey @7: DoSound INY Row2: LDA #$DD ; scan second keypad row STA SwchA @1: JSR DS1 ; give it some time to settle CPY #16 BNE @1 JSR DS1 LDA Inpt0 ; check first key BMI @2 DoSound INY LDA Inpt1 ; make sure second key is off BPL @4 ; if both first and second key, ignore row LDX #4 JMP DoKey @2: DoSound INY LDX #5 ; check second key LDA Inpt1 BMI @3 JMP DoKey @3: DoSound INY LDX #6 ; check third key LDA Inpt4 BMI @4 JMP DoKey @4: DoSound INY LDA Inpt2 ; check first key BMI @5 DoSound INY LDA Inpt3 ; make sure second key is off BPL @7 ; if both first and second key, ignore row LDX #16 JMP DoKey @5: DoSound INY LDX #17 ; check second key LDA Inpt3 BMI @6 JMP DoKey @6: DoSound INY LDX #18 ; check third key LDA Inpt5 BMI @7 JMP DoKey @7: DoSound INY Row3: LDA #$BB ; scan third keypad row STA SwchA @1: JSR DS1 ; give it some time to settle CPY #28 BNE @1 JSR DS1 LDA Inpt0 ; check first key BMI @2 DoSound INY LDA Inpt1 ; make sure second key is off BPL @4 ; if both first and second key, ignore row LDX #7 JMP DoKey @2: DoSound INY LDX #8 ; check second key LDA Inpt1 BMI @3 JMP DoKey @3: DoSound INY LDX #9 ; check third key LDA Inpt4 BMI @4 JMP DoKey @4: DoSound INY LDA Inpt2 ; check first key BMI @5 DoSound INY LDA Inpt3 ; make sure second key is off BPL @7 ; if both first and second key, ignore row LDX #19 JMP DoKey @5: DoSound INY LDX #20 ; check second key LDA Inpt3 BMI @6 JMP DoKey @6: DoSound INY LDX #21 ; check third key LDA Inpt5 BMI @7 JMP DoKey @7: DoSound INY Row4: LDA #$77 ; scan fourth keypad row STA SwchA @1: JSR DS1 ; give it some time to settle CPY #40 BNE @1 JSR DS1 LDA Inpt0 ; check first key BMI @2 DoSound INY LDA Inpt1 ; make sure second key is off BPL @4 ; if both first and second key, ignore row LDX #10 JMP DoKey @2: DoSound INY LDX #11 ; check second key LDA Inpt1 BMI @3 JMP DoKey @3: DoSound INY LDX #12 ; check third key LDA Inpt4 BMI @4 JMP DoKey @4: DoSound INY LDA Inpt2 ; check first key BMI @5 DoSound INY LDA Inpt3 ; make sure second key is off BPL @7 ; if both first and second key, ignore row LDX #22 JMP DoKey @5: DoSound INY LDX #23 ; check second key LDA Inpt3 BMI @6 JMP DoKey @6: DoSound INY LDX #24 ; check third key LDA Inpt5 BMI @7 JMP DoKey @7: DoSound INY NoKey: LDX #0 ; no keys are down DoKey: STX KeyTmp ; 3 BEQ DoKey1 ; 2 DoSound INY ; 2 LDA Mode ; 3 - check for red/blue box mode LSRA ; 2 BCC DoKey1 ; 2 - branch if red box CLC ; 2 LDA KeyTmp ; 3 ADC #24 ; 2 - change key to 2nd set STA KeyTmp ; 3 DoKey1: DoSound INY ; 2 LDX KeyTmp ; 3 - is it the same key? CPX KeyCode ; 3 BNE @1 ; 2 JMP Middle ; 3 - ignore if same key @1: DoSound INY ; 2 (15 cycles for this group) LDX KeyTmp ; 3 STX KeyCode ; 3 LDA KeyTab1,X ; 4 STA StepAL ; 3 DoSound INY ; 2 (19 cycles for this group) LDX KeyTmp ; 3 LDA KeyTab2,X ; 4 STA StepAH ; 3 LDA KeyTab3,X ; 4 STA StepBL ; 3 DoSound INY LDX KeyTmp LDA KeyTab4,X STA StepBH Middle: DoSound INY ; 2 LDA #$1E ; 2 - bright yellow STA CoLuP0 ; 3 ; LDA #$05 ; double-size player LDA #$07 ; 2 - quad-size player STA NuSiz0 ; 3 LDA KeyCode ; 3 - get key code STA Index ; 3 - save for blue box compares DoSound INY ; 2 LDA Index ; 3 CMP #24+24 ; 2 - is it the last key? BNE @1 ; 2 - convert to set 1 if so JMP @31 @1: DoSound INY ; 2 LDA Index ; 3 CMP #24+16 ; 2 - is it 2nd set, 2nd pad, 2nd row or greater? BCC @2 ; 2 LDA #0 ; 2 - if so, display a blank STA Index ; 3 @2: DoSound INY ; 2 LDA Index ; 3 CMP #24+10 ; 2 - is it 2nd set, 1st pad, 4th row or greater? BCC @3 ; 2 ; SEC SBC #9 ; 2 - convert to extra six labels STA Index ; 3 BNE @4 ; 2 @3: DoSound INY ; 2 LDA Index ; 3 CMP #25 ; 2 - is it 2nd set? BCC @4 ; 2 ; SEC @31: SBC #24 ; 2 - make it 1st set STA Index ; 3 @4: DoSound INY ; 2 LDA Index ; 3 ASLA ; 2 - multiply by 8 ASLA ; 2 ASLA ; 2 STA Line ; 3 - store line number @50: DoSound INY ; check for middle of screen CPY #65 BNE @50 P0Loop: DoSound INY ; 2 - count line LDX Line ; 3 - get line number LDA P0data,X ; 4 - get data STA GrP0 ; 3 - set P0 data JSR DS1 INC Line ; 5 JSR DS1 JSR DS1 JSR DS1 CPY #60+5*8+2 ; 2 - is it 8 lines? BCS P0Done ; 2 - branch for 8 lines JMP P0Loop ; 3 P0Done: DoSound INY LDA #0 ; clear P0 data STA GrP0 ; logo code starts here DoSound INY ; 2 ; LDA #$1E ; bright yellow LDA #$8E ; 2 - bright blue ; LDA #$0E ; white STA CoLuP0 ; 3 STA CoLuP1 ; 3 JSR DS1 ; LDA #$00 ; one copy, single width ; LDA #$01 ; 2 copies close ; LDA #$04 ; 2 copies wide LDA #$05 ; 2 - double-size player STA NuSiz0 ; 3 STA NuSiz1 ; 3 Logo: DoSound INY ; check for bottom of screen CPY #130 BNE Logo LDA #0 STA Line DoSound INY LDA Mode LSRA BCC LogoLoop LDA #LogoData2-LogoData STA Line LogoLoop: DoSound INY ; count line LDX Line ; get line number LDA LogoData,X ; get data STA GrP0 ; set P0 data LDA LogoData+1,X ; get data STA GrP1 ; set P0 data DoSound INY ; count line INC Line INC Line JSR DS1 CPY #130+3*22 ; 8 lines? BCS LogoDone ; branch for 8 lines JMP LogoLoop LogoDone: DoSound INY LDA #0 STA GrP0 STA GrP1 Sel: DoSound INY ; 2 LDA SwchB ; 4 - get SwchB AND #$02 ; 2 - mask out SELECT switch STA SwB1 DoSound INY LDA SwB1 BNE @10 ; 2/3 CMP SwB ; 3 - has it just now changed? BEQ @10 ; 2/3 JSR DS1 INC Mode ; 5 @10: JSR DS1 LDA SwB1 STA SwB JMP Bottom ; DS1 takes 6 cycles from both scan lines for the JSR/RTS ; but it saves a LOT of code space DS1: DoSound ; 6 cycles for caller's JSR INY ; 2 cycles RTS ; 6 cycles IF . > $FCA8 ERROR Code area overflow! ENDIF ORG $FCA8 ; BIG WARNING: if any of the logo data crosses a page boundary, ; Bad Things =will= happen! LogoData: ; ======= ======= ======= ======= DB $44,$44 ; . # . . . # . . . # . . . # . . DB $AA,$AA ; # . # . # . # . # . # . # . # . DB $28,$AA ; . . # . # . . . # . # . # . # . DB $4E,$AA ; . # . . # # # . # . # . # . # . DB $8A,$AA ; # . . . # . # . # . # . # . # . DB $E4,$44 ; # # # . . # . . . # . . . # . . ; DB 0,0 ; DB $CE,$C0 ; # # . . # # # . # # . . . . . . ; DB $A8,$A0 ; # . # . # . . . # . # . . . . . ; DB $CE,$A0 ; # # . . # # # . # . # . . . . . ; DB $A8,$A0 ; # . # . # . . . # . # . . . . . ; DB $AE,$C0 ; # . # . # # # . # # . . . . . . ; DB 0,0 ; DB $0C,$4A ; . . . . # # . . . # . . # . # . ; DB $0A,$AA ; . . . . # . # . # . # . # . # . ; DB $0C,$A4 ; . . . . # # . . # . # . . # . . ; DB $0A,$AA ; . . . . # . # . # . # . # . # . ; DB $0C,$4A ; . . . . # # . . . # . . # . # . DB 0,0 ; ======= ======= ======= ======= DB $E7,$BC ; # # # . . # # # # . # # # # . . DB $94,$22 ; # . . # . # . . . . # . . . # . DB $94,$22 ; # . . # . # . . . . # . . . # . DB $E7,$22 ; # # # . . # # # . . # . . . # . DB $A4,$22 ; # . # . . # . . . . # . . . # . DB $94,$22 ; # . . # . # . . . . # . . . # . DB $97,$BC ; # . . # . # # # # . # # # # . . DB 0,0 ; ======= ======= ======= ======= DB $E3,$22 ; # # # . . . # # . . # . . . # . DB $94,$A2 ; # . . # . # . . # . # . . . # . DB $94,$94 ; # . . # . # . . # . . # . # . . DB $E4,$88 ; # # # . . # . . # . . . # . . . DB $94,$94 ; # . . # . # . . # . . # . # . . DB $94,$A2 ; # . . # . # . . # . # . . . # . DB $E3,$22 ; # # # . . . # # . . # . . . # . LogoData2: ; ======= ======= ======= ======= DB $44,$44 ; . # . . . # . . . # . . . # . . DB $AA,$AA ; # . # . # . # . # . # . # . # . DB $28,$AA ; . . # . # . . . # . # . # . # . DB $4E,$AA ; . # . . # # # . # . # . # . # . DB $8A,$AA ; # . . . # . # . # . # . # . # . DB $E4,$44 ; # # # . . # . . . # . . . # . . DB 0,0 ; ======= ======= ======= ======= DB $C8,$AE ; # # . . # . . . # . # . # # # . DB $A8,$A8 ; # . # . # . . . # . # . # . . . DB $A8,$A8 ; # . # . # . . . # . # . # . . . DB $C8,$AE ; # # . . # . . . # . # . # # # . DB $A8,$A8 ; # . # . # . . . # . # . # . . . DB $A8,$A8 ; # . # . # . . . # . # . # . . . DB $CE,$EE ; # # . . # # # . # # # . # # # . DB 0,0 ; ======= ======= ======= ======= DB $E3,$22 ; # # # . . . # # . . # . . . # . DB $94,$A2 ; # . . # . # . . # . # . . . # . DB $94,$94 ; # . . # . # . . # . . # . # . . DB $E4,$88 ; # # # . . # . . # . . . # . . . DB $94,$94 ; # . . # . # . . # . . # . # . . DB $94,$A2 ; # . . # . # . . # . # . . . # . DB $E3,$22 ; # # # . . . # # . . # . . . # . IF . > $FD00 ERROR Code area overflow! ENDIF ORG $FD00 P0data: DB 0,0,0,0,0,0,0,0 ; blank DB $08 ; . . . . # . . . DB $18 ; . . . # # . . . DB $38 ; . . # # # . . . DB $18 ; . . . # # . . . DB $18 ; . . . # # . . . DB $18 ; . . . # # . . . DB $7E ; . # # # # # # . DB 0 DB $3C ; . . # # # # . . DB $66 ; . # # . . # # . DB $06 ; . . . . . # # . DB $0C ; . . . . # # . . DB $18 ; . . . # # . . . DB $30 ; . . # # . . . . DB $7E ; . # # # # # # . DB 0 DB $3C ; . . # # # # . . DB $66 ; . # # . . # # . DB $06 ; . . . . . # # . DB $1C ; . . . # # # . . DB $06 ; . . . . . # # . DB $66 ; . # # . . # # . DB $3C ; . . # # # # . . DB 0 DB $0C ; . . . . # # . . DB $1C ; . . . # # # . . DB $3C ; . . # # # # . . DB $6C ; . # # . # # . . DB $FE ; # # # # # # # . DB $0C ; . . . . # # . . DB $0C ; . . . . # # . . DB 0 DB $7E ; . # # # # # # . DB $60 ; . # # . . . . . DB $7C ; . # # # # # . . DB $06 ; . . . . . # # . DB $06 ; . . . . . # # . DB $66 ; . # # . . # # . DB $3C ; . . # # # # . . DB 0 DB $3C ; . . # # # # . . DB $66 ; . # # . . # # . DB $60 ; . # # . . . . . DB $7C ; . # # # # # . . DB $66 ; . # # . . # # . DB $66 ; . # # . . # # . DB $3C ; . . # # # # . . DB 0 DB $7E ; . # # # # # # . DB $66 ; . # # . . # # . DB $0C ; . . . . # # . . DB $0C ; . . . . # # . . DB $18 ; . . . # # . . . DB $18 ; . . . # # . . . DB $18 ; . . . # # . . . DB 0 DB $3C ; . . # # # # . . DB $66 ; . # # . . # # . DB $66 ; . # # . . # # . DB $3C ; . . # # # # . . DB $66 ; . # # . . # # . DB $66 ; . # # . . # # . DB $3C ; . . # # # # . . DB 0 DB $3C ; . . # # # # . . DB $66 ; . # # . . # # . DB $66 ; . # # . . # # . DB $3E ; . . # # # # # . DB $06 ; . . . . . # # . DB $66 ; . # # . . # # . DB $3C ; . . # # # # . . DB 0 DB $66 ; . # # . . # # . DB $3C ; . . # # # # . . DB $18 ; . . . # # . . . DB $FF ; # # # # # # # # DB $18 ; . . . # # . . . DB $3C ; . . # # # # . . DB $66 ; . # # . . # # . DB 0 DB $3C ; . . # # # # . . DB $66 ; . # # . . # # . DB $66 ; . # # . . # # . DB $66 ; . # # . . # # . DB $66 ; . # # . . # # . DB $66 ; . # # . . # # . DB $3C ; . . # # # # . . DB 0 DB 0 DB $66 ; . # # . . # # . DB $FF ; # # # # # # # # DB $66 ; . # # . . # # . DB $66 ; . # # . . # # . DB $FF ; # # # # # # # # DB $66 ; . # # . . # # . DB 0 DB $18 ; . . . # # . . . DB $3C ; . . # # # # . . DB $66 ; . # # . . # # . DB $66 ; . # # . . # # . DB $7E ; . # # # # # # . DB $66 ; . # # . . # # . DB $66 ; . # # . . # # . DB 0 DB $38 ; . . # # # . . . ; red box coin DB $54 ; . # . # . # . . DB $BA ; # . # # # . # . DB $A2 ; # . # . . . # . DB $BA ; # . # # # . # . DB $54 ; . # . # . # . . DB $38 ; . . # # # . . . DB 0 DB $70 ; . # # # . . . . ; green box coin collect DB $80 ; # . . . . . . . DB $80 ; # . . . . . . . DB $70 ; . # # # . . . . DB $07 ; . . . . . # # # DB $08 ; . . . . # . . . DB $08 ; . . . . # . . . DB $07 ; . . . . . # # # DB $7C ; . # # # # # . . DB $66 ; . # # . . # # . DB $66 ; . # # . . # # . DB $7C ; . # # # # # . . DB $66 ; . # # . . # # . DB $66 ; . # # . . # # . DB $7C ; . # # # # # . . DB 0 DB $E0 ; # # # . . . . . ; dial tone DB $90 ; # . . # . . . . DB $90 ; # . . # . . . . DB $E0 ; # # # . . . . . DB $1F ; . . . # # # # # DB $04 ; . . . . . # . . DB $04 ; . . . . . # . . DB $04 ; . . . . . # . . DB $70 ; . # # # . . . . ; green box coin return DB $80 ; # . . . . . . . DB $80 ; # . . . . . . . DB $8E ; # . . . # # # . DB $79 ; . # # # # . . # DB $0E ; . . . . # # # . DB $09 ; . . . . # . . # DB $09 ; . . . . # . . # DB $3C ; . . # # # # . . DB $66 ; . # # . . # # . DB $60 ; . # # . . . . . DB $60 ; . # # . . . . . DB $60 ; . # # . . . . . DB $66 ; . # # . . # # . DB $3C ; . . # # # # . . DB 0 DB $E0 ; # # # . . . . . ; busy DB $90 ; # . . # . . . . DB $E0 ; # # # . . . . . DB $90 ; # . . # . . . . DB $EF ; # # # . # # # # DB $02 ; . . . . . . # . DB $04 ; . . . . . # . . DB $0F ; . . . . # # # # DB $60 ; . # # . . . . . ; green box operator release DB $90 ; # . . # . . . . DB $90 ; # . . # . . . . DB $9E ; # . . # # # # . DB $69 ; . # # . # . . # DB $0E ; . . . . # # # . DB $09 ; . . . . # . . # DB $09 ; . . . . # . . # DB $7C ; . # # # # # . . DB $66 ; . # # . . # # . DB $66 ; . # # . . # # . DB $66 ; . # # . . # # . DB $66 ; . # # . . # # . DB $66 ; . # # . . # # . DB $7C ; . # # # # # . . DB 0 DB $E0 ; # # # . . . . . ; ringback DB $90 ; # . . # . . . . DB $E0 ; # # # . . . . . DB $9E ; # . . # # # # . DB $99 ; # . . # # . . # DB $0E ; . . . . # # # . DB $09 ; . . . . # . . # DB $0E ; . . . . # # # . DB $38 ; . . # # # . . . ; 2600 DB $38 ; . . # # # . . . DB $38 ; . . # # # . . . DB $38 ; . . # # # . . . DB $54 ; . # . # . # . . DB $54 ; . # . # . # . . DB $92 ; # . . # . . # . DB 0 DB $90 ; # . . # . . . . DB $A0 ; # . # . . . . . DB $C0 ; # # . . . . . . DB $AE ; # . # . # # # . DB $99 ; # . . # # . . # DB $0E ; . . . . # # # . DB $08 ; . . . . # . . . DB $08 ; . . . . # . . . DB $3C ; . . # # # # . . DB $66 ; . # # . . # # . DB $66 ; . # # . . # # . DB $66 ; . # # . . # # . DB $66 ; . # # . . # # . DB $66 ; . # # . . # # . DB $3C ; . . # # # # . . DB 0 DB $70 ; . # # # . . . . DB $80 ; # . . . . . . . DB $60 ; . # # . . . . . DB $1F ; . . . # # # # # DB $E4 ; # # # . . # . . DB $04 ; . . . . . # . . DB $04 ; . . . . . # . . DB $04 ; . . . . . # . . DB 0 ; 11 / green box ringback DB $44 ; . # . . . # . . DB $CC ; # # . . # # . . DB $44 ; . # . . . # . . DB $44 ; . # . . . # . . DB $44 ; . # . . . # . . DB $EE ; # # # . # # # . DB 0 DB 0 DB $46 ; . # . . . # # . DB $C9 ; # # . . # . . # DB $42 ; . # . . . . # . DB $44 ; . # . . . # . . DB $48 ; . # . . # . . . DB $EF ; # # # . # # # # DB 0 DB $93 ; # . . # . . # # DB $A3 ; # . # . . . # # DB $C0 ; # # . . . . . . DB $AE ; # . # . # # # . DB $99 ; # . . # # . . # DB $0E ; . . . . # # # . DB $08 ; . . . . # . . . DB $08 ; . . . . # . . . IF . > $FE00 ERROR Code area overflow! ENDIF ; NOTE: SinTab must be page-aligned to keep loads and ; stores from taking an extra cycle when crossing a ; page boundary! SinTab: ORG $FE00 DB $08,$08,$08,$09,$09,$09,$09,$09 DB $0A,$0A,$0A,$0A,$0A,$0A,$0B,$0B DB $0B,$0B,$0B,$0B,$0C,$0C,$0C,$0C DB $0C,$0C,$0C,$0D,$0D,$0D,$0D,$0D DB $0D,$0D,$0D,$0E,$0E,$0E,$0E,$0E DB $0E,$0E,$0E,$0E,$0E,$0E,$0E,$0F DB $0F,$0F,$0F,$0F,$0F,$0F,$0F,$0F DB $0F,$0F,$0F,$0F,$0F,$0F,$0F,$0F DB $0F,$0F,$0F,$0F,$0F,$0F,$0F,$0F DB $0F,$0F,$0F,$0F,$0E,$0E,$0E,$0E DB $0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E DB $0D,$0D,$0D,$0D,$0D,$0D,$0D,$0D DB $0C,$0C,$0C,$0C,$0C,$0C,$0C,$0B DB $0B,$0B,$0B,$0B,$0B,$0A,$0A,$0A DB $0A,$0A,$0A,$09,$09,$09,$09,$09 DB $08,$08,$08,$08,$08,$07,$07,$07 DB $07,$07,$07,$06,$06,$06,$06,$06 DB $05,$05,$05,$05,$05,$05,$04,$04 DB $04,$04,$04,$04,$03,$03,$03,$03 DB $03,$03,$03,$02,$02,$02,$02,$02 DB $02,$02,$02,$01,$01,$01,$01,$01 DB $01,$01,$01,$01,$01,$01,$01,$00 DB $00,$00,$00,$00,$00,$00,$00,$00 DB $00,$00,$00,$00,$00,$00,$00,$00 DB $00,$00,$00,$00,$00,$00,$00,$00 DB $00,$00,$00,$00,$01,$01,$01,$01 DB $01,$01,$01,$01,$01,$01,$01,$01 DB $02,$02,$02,$02,$02,$02,$02,$02 DB $03,$03,$03,$03,$03,$03,$03,$04 DB $04,$04,$04,$04,$04,$05,$05,$05 DB $05,$05,$05,$06,$06,$06,$06,$06 DB $07,$07,$07,$07,$07,$08,$08,$08 NKeys EQU 49 SEG K0 KeyTab1 ORG $FF00 SEG K1 KeyTab2 ORG $FF00+NKeys SEG K2 KeyTab3 ORG $FF00+NKeys*2 SEG K3 KeyTab4 ORG $FF00+NKeys*3 SEG ORG $FF00+NKeys*4 ; macro to generate key frequency data ; F1 and F2 are the two tone frequencies in Hertz ; O1 and O2 are tweak offsets (if needed) in the form "-n" or "+n" KEY MACRO F1,F2,O1,O2 SEG K0 IF . >= $FF00+NKeys ERROR 'Too many keys in KeyTab!' ENDIF FREQ SET ((F1*$80000/15700)+4)/8 O1 SEG K0 DB L(FREQ) SEG K1 DB H(FREQ) FREQ SET ((F2*$80000/15700)+4)/8 O2 SEG K2 DB L(FREQ) SEG K3 DB H(FREQ) SEG ENDM ; values are f*4.1742675159 ((f/(15700/256))*256) ; a formula that works in my assembler is ((f*$80000/15700)+4/8) KEY 0, 0 ; no key, no sound KEY 697,1209 ; key 1, 1 = 697+1209 KEY 697,1336 ; key 2, 2 = 697+1336 KEY 697,1477 ; key 3, 3 = 697+1477 KEY 770,1209 ; key 4, 4 = 770+1209 KEY 770,1336 ; key 5, 5 = 770+1336 KEY 770,1477 ; key 6, 6 = 770+1477 KEY 852,1209 ; key 7, 7 = 852+1209 KEY 852,1336 ; key 8, 8 = 852+1336 KEY 852,1477 ; key 9, 9 = 852+1477 KEY 941,1209 ; key 10, * = 941+1209 KEY 941,1336 ; key 11, 0 = 941+1336 KEY 941,1477 ; key 12, # = 941+1477 KEY 697,1633 ; key 13, A = 697+1633 KEY 1700,2200 ; key 14, = 1700+2200 red (nickel = 66m, quarter = 33ms) KEY 700,1100 ; key 15, = 700+1100 green coin collect KEY 770,1633 ; key 16, B = 770+1633 KEY 350, 440 ; key 17, = 350+ 440 dial tone, (250 ms on, 250 ms off) KEY 1100,1700 ; key 18, = 1100+1700 green coin return KEY 852,1633 ; key 19, C = 852+1633 KEY 420, 620 ; key 20, = 420+ 620 busy KEY 950,1500 ; key 21, = 950+1500 green oper. release KEY 941,1633 ; key 22, D = 941+1633 KEY 440, 480 ; key 23 = 440+ 480 ringback (2000 ms on, 400 ms off) KEY 2600, 0 ; key 24, = 2600+ 0 2600 Hz KEY 700, 900 ; key 1, blue 1 = 700+900 KEY 700,1100 ; key 2, blue 2 = 700+1100 / green coin collect KEY 900,1100 ; key 3, blue 3 = 900+1100 KEY 700,1300 ; key 4, blue 4 = 700+1300 KEY 900,1300 ; key 5, blue 5 = 900+1300 KEY 1100,1300 ; key 6, blue 6 = 1100+1300 KEY 700,1500 ; key 7, blue 7 = 700+1500 KEY 900,1500 ; key 8, blue 8 = 900+1500 KEY 1100,1500 ; key 9, blue 9 = 1100+1500 KEY 1100,1700 ; key 10, blue KP1 = 1100+1700 / green coin return KEY 1300,1500 ; key 11, blue 0 = 1300+1500 KEY 1500,1700 ; key 12, blue ST = 1500+1700 KEY 700,1700 ; key 13, blue 11? = 700+1700 / green ringback KEY 900,1700 ; key 14, blue 12? = 900+1700 KEY 1300,1700 ; key 15, blue KP2 = 1300+1700 ; SIT NC KEY 985, 0 ; key 19, 985 Hz KEY 1428, 0, +2 ; key 17, 1428.5 Hz (needs adjustment to 5963/174B) KEY 1777, 0 ; key 18, 1777 Hz ; SIT INT KEY 913, 0 ; key 16, 913 Hz KEY 1371, 0 ; key 20, 1371 Hz KEY 1777, 0 ; key 21, 1777 Hz KEY 0, 0 ; key 22, undefined KEY 0, 0 ; key 23, undefined KEY 2600, 0 ; key 24, 2600 Hz DB '2600 tone dialer - Bruce Tomlin - copyright ' DB '2005/08/17' IF (. > $FFFA) | ( . < $FF00) ERROR Code area overflow! ENDIF ORG $FFFA DW START DW START DW START END