Hamazing/source/framework/musicplayers/lightspeedplayer_cia.asm

135 lines
4.2 KiB
NASM
Raw Normal View History

2023-05-22 16:17:35 +02:00
;*****************************************************************
;
; Light Speed Player v1.11
; Fastest Amiga MOD player ever :)
; Written By Arnaud Carré (aka Leonard / OXYGENE)
; Slightly modified by platon42 for demo framework.
;
; https://github.com/arnaud-carre/LSPlayer
; twitter: @leonard_coder
;
; "cia" player version ( or "less effort" )
;
; Warnings:
; a) this file is provided for "easy of use". But if you're working
; on a cycle-optimizated demo effect, please call LightSpeedPlayer from your
; own existing interrupt and use copper to set DMACON 11 raster lines later
;
; b) this code doesn't restore any amiga OS stuff.
; ( are you a cycle-optimizer or what? :) )
;
; --------How to use---------
;
; bsr LSP_MusicDriver_CIA_Start : Init LSP player code and install CIA interrupt
; a0: LSP music data(any memory)
; a1: LSP sound bank(chip memory)
; a2: VBR (CPU Vector Base Register) ( use 0 if 68000 )
; d0: 0=PAL, 1=NTSC
;
; bsr LSP_MusicDriver_CIA_Stop : Stop LSP music replay
;
;*****************************************************************
LSP_MusicDriver_CIA_Stop:
move.b #$7f,$bfd000+ciaicr
move.w #INTF_EXTER,intena(a5)
move.w #INTF_EXTER,intreq(a5)
move.w #DMAF_AUDIO,dmacon(a5)
rts
LSP_MusicDriver_CIA_Start:
move.w d0,-(sp)
lea .dmaCon+1(pc),a2 ; DMACON byte patch address
clr.b (a2)
move.l a2,fw_LspDmaConPatch(a6)
bsr LSP_MusicInit ; init the LSP player ( whatever fast or insane version )
move.w fw_LspCurrentBpm(a6),d0
move.w d0,fw_LspLastCiaBpm(a6)
moveq #1,d1
and.w (sp)+,d1
; d0: music BPM
; d1: PAL(0) or NTSC(1)
.LSP_IrqInstall
move.w #INTF_EXTER,intena(a5) ; disable CIA interrupt
lea .LSP_MainIrq(pc),a0
move.l fw_VBR(a6),a2
move.l a0,$78(a2)
lea $bfd000,a0
move.b #$7f,ciaicr(a0)
move.b #CIACRAF_LOAD,ciacra(a0)
move.b #CIACRBF_LOAD,ciacrb(a0)
lsl.w #2,d1
move.l .palClocks(pc,d1.w),d1 ; PAL or NTSC clock
move.l d1,fw_LspCiaClock(a6)
divu.w d0,d1
move.b d1,ciatalo(a0)
lsr.w #8,d1
move.b d1,ciatahi(a0)
move.b #CIAICRF_SETCLR|CIAICRF_TA|CIAICRF_TB,ciaicr(a0)
move.b #CIACRAF_START|CIACRAF_LOAD,ciacra(a0)
move.b #496&$ff,ciatblo(a0) ; set timer b to 496 ( to set DMACON )
move.b #496>>8,ciatbhi(a0)
move.w #INTF_EXTER,intreq(a5) ; clear any req CIA
move.w #INTF_SETCLR|INTF_EXTER,intena(a5) ; CIA interrupt enabled
rts
.palClocks
dc.l 1773447,1789773
.dmaCon
dc.w $8000 ; we won't put this into the framework variables to the avoid need for relocation
.LSP_MainIrq
btst.b #CIAICRB_TA,$bfd000+ciaicr
beq.s .skipa
PUSHM d0-d2/a0-a6
; call player tick
lea $dff000,a5
move.l fw_BasePtr(pc),a6
bsr LSP_MusicPlayTick ; LSP main music driver tick
; check if BMP changed in the middle of the music
lea $bfd000,a4
move.w fw_LspCurrentBpm(a6),d0 ; current music BPM
cmp.w fw_LspLastCiaBpm(a6),d0
beq.s .noChg
move.w d0,fw_LspLastCiaBpm(a6) ; current BPM
move.l fw_LspCiaClock(a6),d1
divu.w d0,d1
move.b d1,ciatalo(a4)
lsr.w #8,d1
move.b d1,ciatahi(a4)
.noChg lea .LSP_DmaconIrq(pc),a0
move.l fw_VBR(a6),a1
move.l a0,$78(a1)
move.b #CIACRBF_START|CIACRBF_RUNMODE|CIACRBF_LOAD,ciacrb(a4) ; start timerB, one shot
POPM
.skipa
move.w #INTF_EXTER,$dff000+intreq
move.w #INTF_EXTER,$dff000+intreq
nop
rte
.LSP_DmaconIrq
btst.b #CIAICRB_TB,$bfd000+ciaicr
beq.s .skipb
PUSHM a0/a1
move.w .dmaCon(pc),$dff000+dmacon
move.l fw_BasePtr(pc),a1
lea .LSP_MainIrq(pc),a0
move.l fw_VBR(a1),a1
move.l a0,$78(a1)
POPM
.skipb
move.w #INTF_EXTER,$dff000+intreq
move.w #INTF_EXTER,$dff000+intreq
nop
rte