;ACME 0.96.4 !cpu 6502 ; Compatible with all Apple2's !to "CybernoidTest2", plain !sl "CybernoidTest2.labels" *=$4000 USE_AYDATA1 = 1 ;------------------------------------------------------------------------------ !source "..\Common\AppleDefs.a" !source "..\Common\MockingboardDefs.a" !source "..\Common\MB-Macros.a" ;------------------------------------------------------------------------------ zpTmp = $f9 pTonesTbl = $fa TmpL = $fc ; alias with pAYData pAYData = $fc MBBase = $fe MBBaseL = MBBase MBBaseH = MBBase+1 !zone code ;-------------------------------------- Entrypoint: lda zpTmp sta saveF9 lda pTonesTbl+0 sta saveFA lda pTonesTbl+1 sta saveFB lda pAYData+0 sta saveFC lda pAYData+1 sta saveFD lda MBBaseL sta saveFE lda MBBaseH sta saveFF jsr SF_GetMBSlot bne GotMBSlot ; MB not found! brk GotMBSlot: stx nMBBaseHi stx MB1x+2 stx MB2x+2 stx MB3x+2 stx MB4x+2 stx MB5x+2 stx MB6x+2 stx MB7x+2 stx MB8x+2 stx MB9x+2 stx MBAx+2 stx MBBx+2 stx MBCx+2 stx MB1y+2 stx MB2y+2 stx MB3y+2 stx MB4y+2 stx MB5y+2 stx MB6y+2 stx MB7y+2 stx MB8y+2 stx MB9y+2 stx MB7+2 ; lda #$07 ldy #SY6522_DDRB sta (MBBase),y ldy #SY6522_DDRB+$80 sta (MBBase),y lda #$ff ldy #SY6522_DDRA sta (MBBase),y ldy #SY6522_DDRA+$80 sta (MBBase),y lda #AY_RESET ldy #SY6522_ORB sta (MBBase),y ldy #SY6522_ORB+$80 sta (MBBase),y ; ; Setup Timer1 IRQ to trigger at 50Hz ; Apple CLK = 1.022727 MHz, so set Timer1=0x4fe7 sei lda #$e7 ldy #SY6522_TIMER1L_COUNTER sta (MBBase),y lda #$4f ldy #SY6522_TIMER1H_COUNTER sta (MBBase),y lda #1<<6 ldy #SY6522_ACR sta (MBBase),y ; Free running timer lda #1<<7 | 1<<6 ldy #SY6522_IER sta (MBBase),y ; Enable Timer1 IRQ lda #Interrupt ; ADDR_H sta IRQH jsr InitAYData jsr InitTones lda #0 sta AYDataDoneFlag sta nFrameNum+0 sta nFrameNum+1 sta nFrameNum+2 cli loop lda AYDataDoneFlag bne done lda $c000 bpl loop bit $c010 cmp #27+$80 ; ESC to quit beq done cmp #9+$80 ; TAB to toggle AY-chip bne + jsr toggle_ay bcs loop + jsr TonesInc bcs loop jsr TonesDec bcs loop pause ; step via one-shot mode sei lda #0 ldy #SY6522_ACR sta (MBBase),y lda nFrameNum+2 cli - cmp nFrameNum+2 beq - ldy nFrameNum+1 ; Second ldx nFrameNum+2 ; Frame# jsr $f940 ; PRNTYX - lda $c000 bpl - bit $c010 tax ; keycode lda #$e7 ldy #SY6522_TIMER1L_COUNTER sta (MBBase),y lda #$4f ldy #SY6522_TIMER1H_COUNTER sta (MBBase),y cpx #' '+$80 beq pause ; restart lda #1<<6 ldy #SY6522_ACR sta (MBBase),y ; Free running timer jmp loop done lda #1<<6 ldy #SY6522_IER sta (MBBase),y ; Disable Timer1 IRQ lda #AY_RESET ldy #SY6522_ORB sta (MBBase),y ldy #SY6522_ORB+$80 sta (MBBase),y lda saveF9 sta zpTmp lda saveFA sta pTonesTbl+0 lda saveFB sta pTonesTbl+1 lda saveFC sta pAYData+0 lda saveFD sta pAYData+1 lda saveFE sta MBBaseL lda saveFF sta MBBaseH rts ;-------------------------------------- Interrupt ; Pre: ; 6502 has pushed P ; Apple ROM has stored A to $45 (not Apple //e ROM!) ; txa pha tya pha jsr lefe5 ; ;; lda AYDataDoneFlag ;; bne .done lda pAYData+0 sta MBsmc1+1 sta MBsmc2+1 lda pAYData+1 sta MBsmc1+2 sta MBsmc2+2 ldx #AY_INACTIVE ldy #13 ; write AY regs from $D to $0 (like Cybernoid) - MB1x sty CARD_BASE+SY6522_ORA lda #AY_LATCH MB2x sta CARD_BASE+SY6522_ORB MB3x stx CARD_BASE+SY6522_ORB ; Set INACTIVE MBsmc1 lda AYData1,y MB4x sta CARD_BASE+SY6522_ORA lda #AY_WRITE MB5x sta CARD_BASE+SY6522_ORB MB6x stx CARD_BASE+SY6522_ORB ; Set INACTIVE dey ; MB7x sty CARD_BASE+SY6522_ORA lda #AY_LATCH MB8x sta CARD_BASE+SY6522_ORB MB9x stx CARD_BASE+SY6522_ORB ; Set INACTIVE MBsmc2 lda AYData1,y cpy #AY_NOISEPER bne + and #AY_NOISE_MASK + MBAx sta CARD_BASE+SY6522_ORA lda #AY_WRITE MBBx sta CARD_BASE+SY6522_ORB MBCx stx CARD_BASE+SY6522_ORB ; Set INACTIVE dey bpl - ; Verify AY writes lda pAYData+0 sta MBsmc3+1 lda pAYData+1 sta MBsmc3+2 ldx #AY_INACTIVE ldy #13 ; read AY regs from $D to $0 - lda #$ff ; Port-A direction = output MB1y sta CARD_BASE+SY6522_DDRA MB2y sty CARD_BASE+SY6522_ORA ; AY reg to read lda #AY_LATCH MB3y sta CARD_BASE+SY6522_ORB MB4y stx CARD_BASE+SY6522_ORB lda #$00 ; Port-A direction = input MB5y sta CARD_BASE+SY6522_DDRA lda #AY_READ MB6y sta CARD_BASE+SY6522_ORB MB7y stx CARD_BASE+SY6522_ORB MBsmc3 lda AYData1,y cpy #AY_NOISEPER bne + and #AY_NOISE_MASK + sta zpTmp MB8y lda CARD_BASE+SY6522_ORA ; and read it! cmp zpTmp beq + ; ERR Reg:Val(read):Val(expect) sty $404 ; reg# sta $406 ; value read lda zpTmp sta $408 ; value expected lda #'E'+$80 sta $400 lda #'R'+$80 sta $401 lda #'R'+$80 sta $402 lda #' '+$80 sta $403 lda #':'+$80 sta $405 lda #':'+$80 sta $407 + dey bpl - ; And finally Port-A = output lda #$ff MB9y sta CARD_BASE+SY6522_DDRA ; Setup for next AY-reg set clc lda pAYData+0 adc #14 sta pAYData+0 lda pAYData+1 adc #0 sta pAYData+1 ; $ff,$ff = end of data ldy #0 lda (pAYData),y iny and (pAYData),y cmp #$ff bne + ;; sta AYDataDoneFlag jsr InitAYData + ; .done lda #1<<6 MB7 sta CARD_BASE+SY6522_IFR ; Clear Timer1 IRQ flag pla tay pla tax lda $45 rti ;-------------------------------------- lefe5: inc nFrameNum+2 lda nFrameNum+2 cmp #50 bne .fnum_ok lda #0 sta nFrameNum+2 inc nFrameNum+1 lda nFrameNum+1 cmp #60 bne .fnum_ok lda #0 sta nFrameNum+1 inc nFrameNum+0 .fnum_ok: rts ;------------------------------------------------------------------------------ ; Skyfox MB detection routine: SF_GetMBSlot: ; Pre: ; Post: ; Z = 0 (NE) : MB detected ; X = HI(MB base address) ; (MBBase) = MB slot address ; jsr SF_Detect .Loop: stx TmpL jsr SF_Detect cpx TmpL bne .Loop cpx #$C8 rts ;-------------------------------------- SF_Detect: lda #0 sta MBBaseL lda #$c1 sta MBBaseH ldx #7 .SlotNext: ldy #$00+SY6522_TIMER1L_COUNTER jsr SF_GetTimerL bne .SlotLoop ldy #$80+SY6522_TIMER1L_COUNTER jsr SF_GetTimerL beq .SlotDone .SlotLoop: inc MBBaseH dex bne .SlotNext .SlotDone: ldx MBBaseH rts ;-------------------------------------- SF_GetTimerL: lda (MBBase),y cmp MBBaseL sbc (MBBase),y cmp #$08 rts ;-------------------------------------- InitAYData !if USE_AYDATA1 { lda #AYData1 sta pAYData+1 } else { lda #AYData2 sta pAYData+1 } rts ;-------------------------------------- toggle_ay sei lda #AY_RESET ldy #SY6522_ORB sta (MBBase),y ldy #SY6522_ORB+$80 sta (MBBase),y lda MB1x+1 ; ORA eor #$80 tax lda MB2x+1 ; ORB eor #$80 stx MB1x+1 sta MB2x+1 sta MB3x+1 stx MB4x+1 sta MB5x+1 sta MB6x+1 stx MB7x+1 sta MB8x+1 sta MB9x+1 stx MBAx+1 sta MBBx+1 sta MBCx+1 ; lda MB1y+1 eor #$80 sta MB1y+1 sta MB5y+1 sta MB9y+1 lda MB2y+1 eor #$80 sta MB2y+1 sta MB8y+1 lda MB3y+1 eor #$80 sta MB3y+1 sta MB4y+1 sta MB6y+1 sta MB7y+1 cli sec rts ;------------------------------------------------------------------------------ !zone data nMBBaseHi !byte 0 AYDataDoneFlag !byte 0 nFrameNum !byte 0,0,0 ; Minute:Second:FrameNum (@ 50Hz) saveF9 !byte 0 saveFA !byte 0 saveFB !byte 0 saveFC !byte 0 saveFD !byte 0 saveFE !byte 0 saveFF !byte 0 ;-------------------------------------- SetTones sei ; Even lines jsr InitAYData lda #TonesTbl sta pTonesTbl+1 ldy #0 ; TonesTbl index -- lda (pTonesTbl),y sta smc1+1 iny lda (pTonesTbl),y sta smc2+1 iny lda (pTonesTbl),y tax ; count iny tya pha ; TonesTbl index - ldy #0 smc1 lda #$00 sta (pAYData),y iny smc2 lda #$00 sta (pAYData),y clc lda pAYData+0 adc #14*2 ; alternate AY-reg sets sta pAYData+0 lda pAYData+1 adc #0 sta pAYData+1 dex bne - pla tay lda (pTonesTbl),y iny and (pTonesTbl),y dey cmp #$ff bne -- ; Odd lines jsr InitAYData clc lda pAYData+0 adc #14 ; 1st odd set sta pAYData+0 lda pAYData+1 adc #0 sta pAYData+1 lda #TonesTblOdd sta pTonesTbl+1 ldy #0 ; TonesTblOdd index -- lda (pTonesTbl),y sta smc3+1 iny lda (pTonesTbl),y sta smc4+1 iny lda (pTonesTbl),y tax ; count iny tya pha ; TonesTbl index - ldy #0 smc3 lda #$00 sta (pAYData),y iny smc4 lda #$00 sta (pAYData),y clc lda pAYData+0 adc #14*2 ; alternate AY-reg sets sta pAYData+0 lda pAYData+1 adc #0 sta pAYData+1 dex bne - pla tay lda (pTonesTbl),y iny and (pTonesTbl),y dey cmp #$ff bne -- jsr InitAYData cli rts ;-------------------------------------- PrintTones lda TonesTbl+0*3+1 sta $400 lda TonesTbl+0*3+0 sta $401 lda #$A0 sta $402 sta $403 !if USE_AYDATA1 { lda TonesTbl+1*3+1 sta $404 lda TonesTbl+1*3+0 sta $405 lda #$A0 sta $406 sta $407 lda TonesTbl+3*3+1 sta $408 lda TonesTbl+3*3+0 sta $409 lda #$A0 sta $40A sta $40B lda TonesTbl+4*3+1 sta $40C lda TonesTbl+4*3+0 sta $40D lda #$A0 sta $40E sta $40F lda TonesTbl+5*3+1 sta $410 lda TonesTbl+5*3+0 sta $411 lda #$A0 sta $412 sta $413 } else { lda TonesTbl+2*3+1 sta $404 lda TonesTbl+2*3+0 sta $405 lda #$A0 sta $406 sta $407 } sec rts ;-------------------------------------- TonesInc !if USE_AYDATA1 { ldy #0 cmp #'1'+$80 beq .inc iny cmp #'2'+$80 beq .inc iny ; skip 'evens' end marker iny cmp #'3'+$80 beq .inc iny cmp #'4'+$80 beq .inc iny cmp #'5'+$80 beq .inc } else { ldy #0 cmp #'1'+$80 beq .inc iny ; skip 'evens' end marker iny cmp #'2'+$80 beq .inc } clc rts .inc sty pTonesTbl tya asl ; =lsl clc adc pTonesTbl tay ; y=y*3 lda #TonesTbl sta pTonesTbl+1 clc lda (pTonesTbl),y adc #1 sta (pTonesTbl),y iny lda (pTonesTbl),y adc #0 sta (pTonesTbl),y jsr SetTones jmp PrintTones ;-------------------------------------- TonesDec !if USE_AYDATA1 { ldy #0 cmp #'Q'+$80 beq .dec iny cmp #'W'+$80 beq .dec iny ; skip 'evens' end marker iny cmp #'E'+$80 beq .dec iny cmp #'R'+$80 beq .dec iny cmp #'T'+$80 beq .dec } else { ldy #0 cmp #'Q'+$80 beq .dec iny ; skip 'evens' end marker iny cmp #'W'+$80 beq .dec } clc rts .dec sty pTonesTbl tya asl ; =lsl clc adc pTonesTbl tay ; y=y*3 lda #TonesTbl sta pTonesTbl+1 sec lda (pTonesTbl),y sbc #1 sta (pTonesTbl),y iny lda (pTonesTbl),y sbc #0 sta (pTonesTbl),y jsr SetTones jmp PrintTones ;-------------------------------------- InitTones !if USE_AYDATA1 { ldy #0*3 lda #$01 sta TonesTbl+0*3+1 lda #$e9 sta TonesTbl+0*3+0 ; lda #$02 sta TonesTbl+1*3+1 lda #$68 sta TonesTbl+1*3+0 ; lda #$00 sta TonesTbl+3*3+1 lda #$cd sta TonesTbl+3*3+0 ; lda #$00 sta TonesTbl+4*3+1 lda #$d9 sta TonesTbl+4*3+0 ; lda #$00 sta TonesTbl+5*3+1 lda #$f4 sta TonesTbl+5*3+0 } else { ldy #0*3 lda #$01 sta TonesTbl+0*3+1 lda #$e9 sta TonesTbl+0*3+0 ; lda #$00 sta TonesTbl+2*3+1 lda #$cd sta TonesTbl+2*3+0 } rts ;-------------------------------------- TonesTbl ; word freq, byte count !if USE_AYDATA1 { ; even sets !word $01e9 !byte 18 !word $0268 !byte 6 !word $ffff ; end !byte $ff TonesTblOdd ; odd sets !word $00cd !byte 6 !word $00d9 !byte 12 !word $00f4 !byte 6 !word $ffff ; end !byte $ff } else { ; even sets !word $01e9 !byte 1 !word $ffff ; end !byte $ff TonesTblOdd ; odd sets !word $00cd !byte 1 !word $ffff ; end !byte $ff } ;-------------------------------------- AYData1 ; A-period C-period Ena BVol Envelope ; B-period Noise AVol CVol ; Cybernoid AY-regs generated by AppleII Cybernoid (so has Mockingboard tone freqs) ; . loop around 1st noisy section !byte $E9,$01,$00,$00,$00,$00,$2F,$3E,$0D,$00,$00,$64,$00,$0A !byte $CD,$00,$00,$00,$00,$00,$2F,$3E,$0C,$00,$00,$64,$00,$0A !byte $E9,$01,$00,$00,$00,$00,$2F,$3E,$0B,$00,$00,$64,$00,$0A !byte $CD,$00,$00,$00,$00,$00,$2F,$3E,$0A,$00,$00,$64,$00,$0A !byte $E9,$01,$00,$00,$00,$00,$2F,$3E,$09,$00,$00,$64,$00,$0A !byte $CD,$00,$00,$00,$00,$00,$2F,$3E,$00,$00,$00,$64,$00,$0A !byte $E9,$01,$00,$00,$00,$00,$2F,$3E,$0D,$00,$00,$64,$00,$0A !byte $CD,$00,$00,$00,$00,$00,$2F,$3E,$0C,$00,$00,$64,$00,$0A !byte $E9,$01,$00,$00,$00,$00,$2F,$3E,$0B,$00,$00,$64,$00,$0A !byte $CD,$00,$00,$00,$00,$00,$2F,$3E,$0A,$00,$00,$64,$00,$0A !byte $E9,$01,$00,$00,$00,$00,$2F,$3E,$09,$00,$00,$64,$00,$0A !byte $CD,$00,$00,$00,$00,$00,$2F,$3E,$00,$00,$00,$64,$00,$0A !byte $E9,$01,$00,$00,$00,$00,$2F,$3E,$0D,$00,$00,$64,$00,$0A !byte $D9,$00,$00,$00,$00,$00,$2F,$3E,$0C,$00,$00,$64,$00,$0A !byte $E9,$01,$00,$00,$00,$00,$2F,$3E,$0B,$00,$00,$64,$00,$0A !byte $D9,$00,$00,$00,$00,$00,$2F,$3E,$0A,$00,$00,$64,$00,$0A !byte $E9,$01,$00,$00,$00,$00,$2F,$3E,$09,$00,$00,$64,$00,$0A !byte $D9,$00,$00,$00,$00,$00,$2F,$3E,$00,$00,$00,$64,$00,$0A !byte $E9,$01,$00,$00,$00,$00,$2F,$3E,$0D,$00,$00,$64,$00,$0A !byte $D9,$00,$00,$00,$00,$00,$2F,$3E,$0C,$00,$00,$64,$00,$0A !byte $E9,$01,$00,$00,$00,$00,$2F,$3E,$0B,$00,$00,$64,$00,$0A !byte $D9,$00,$00,$00,$00,$00,$2F,$3E,$0A,$00,$00,$64,$00,$0A !byte $E9,$01,$00,$00,$00,$00,$2F,$3E,$09,$00,$00,$64,$00,$0A !byte $D9,$00,$00,$00,$00,$00,$2F,$3E,$00,$00,$00,$64,$00,$0A !byte $E9,$01,$00,$00,$00,$00,$2F,$3E,$0D,$00,$00,$64,$00,$0A !byte $D9,$00,$00,$00,$00,$00,$2F,$3E,$0C,$00,$00,$64,$00,$0A !byte $E9,$01,$00,$00,$00,$00,$2F,$3E,$0B,$00,$00,$64,$00,$0A !byte $D9,$00,$00,$00,$00,$00,$2F,$3E,$0A,$00,$00,$64,$00,$0A !byte $E9,$01,$00,$00,$00,$00,$2F,$3E,$09,$00,$00,$64,$00,$0A !byte $D9,$00,$00,$00,$00,$00,$2F,$3E,$00,$00,$00,$64,$00,$0A !byte $E9,$01,$00,$00,$00,$00,$2F,$3E,$0D,$00,$00,$64,$00,$0A !byte $D9,$00,$00,$00,$00,$00,$2F,$3E,$0C,$00,$00,$64,$00,$0A !byte $E9,$01,$00,$00,$00,$00,$2F,$3E,$0B,$00,$00,$64,$00,$0A !byte $D9,$00,$00,$00,$00,$00,$2F,$3E,$0A,$00,$00,$64,$00,$0A !byte $E9,$01,$00,$00,$00,$00,$2F,$3E,$09,$00,$00,$64,$00,$0A !byte $D9,$00,$00,$00,$00,$00,$2F,$3E,$00,$00,$00,$64,$00,$0A !byte $68,$02,$00,$00,$00,$00,$2F,$3E,$0D,$00,$00,$64,$00,$0A !byte $F4,$00,$00,$00,$00,$00,$2F,$3E,$0C,$00,$00,$64,$00,$0A !byte $68,$02,$00,$00,$00,$00,$2F,$3E,$0B,$00,$00,$64,$00,$0A !byte $F4,$00,$00,$00,$00,$00,$2F,$3E,$0A,$00,$00,$64,$00,$0A !byte $68,$02,$00,$00,$00,$00,$2F,$3E,$09,$00,$00,$64,$00,$0A !byte $F4,$00,$00,$00,$00,$00,$2F,$3E,$00,$00,$00,$64,$00,$0A !byte $68,$02,$00,$00,$00,$00,$2F,$3E,$0D,$00,$00,$64,$00,$0A !byte $F4,$00,$00,$00,$00,$00,$2F,$3E,$0C,$00,$00,$64,$00,$0A !byte $68,$02,$00,$00,$00,$00,$2F,$3E,$0B,$00,$00,$64,$00,$0A !byte $F4,$00,$00,$00,$00,$00,$2F,$3E,$0A,$00,$00,$64,$00,$0A !byte $68,$02,$00,$00,$00,$00,$2F,$3E,$09,$00,$00,$64,$00,$0A !byte $F4,$00,$00,$00,$00,$00,$2F,$3E,$00,$00,$00,$64,$00,$0A !byte $ff,$ff AYData2 ; just freq modulation (no amplitude modulation) !byte $E9,$01,$00,$00,$00,$00,$2F,$3E,$0D,$00,$00,$64,$00,$0A !byte $CD,$00,$00,$00,$00,$00,$2F,$3E,$0D,$00,$00,$64,$00,$0A !byte $ff,$ff