chrisly42
9c48c11cd1
- Bugfix: WaitForFrame was completely broken. Now also caters for race-condition that would have waited one extra frame. - Bugfix: InitPart would overwrite innocent memory (reported by Gigabates and Losso) - Bugfix: Palette LERP had wrong bias. - Removed extra paths in include statement, use default include paths instead - Added Raspberry Casket no-jitter background calc mode (FW_MUSIC_PLAYER_CHOICE = 6) - Updated Raspberry Casket to V2.0 presto branch (WIP) - Removed fw_FrameCounterLong, use fw_FrameCounter-2 for debug purposes - Support for blue noise palette LERPing (like in Is Real). Provide your own blue noise table (4 KB), stuff it into fw_BlueNoiseTablePtr, set FW_PALETTE_LERP_SUPPORT to 2 - Music tick routine is now replaceable during runtime (fw_MusicTickRoutine) - Support for softints and audio interrupts - LMB exit can also be disabled dynamically when using FW_LMB_EXIT_SUPPORT = 2 and fw_DisableLMBExit != 0 - Added LSP Micro support and LSP Nano (custom format that uses note pitches instead of periods) - Minor other things
300 lines
8.1 KiB
NASM
300 lines
8.1 KiB
NASM
;--------------------------------------------------------------------
|
|
; Endlessly loops and indicate an error
|
|
;
|
|
; In : d0.w - errorcode
|
|
; Out: never returns
|
|
;
|
|
fw_Error:
|
|
ext.l d0
|
|
PUTMSG 10,<"Error %x (%d)">,d0,d0
|
|
.l0 move.w d0,color(a5)
|
|
bra.s .l0
|
|
|
|
;--------------------------------------------------------------------
|
|
; Sets the base copperlist and irq (empty screen).
|
|
;
|
|
; Background colour is unchanged, sprites and display are disabled.
|
|
;
|
|
; Out: Trashes d0/a0
|
|
;
|
|
fw_SetBaseCopper:
|
|
PUTMSG 10,<"%d: SetBaseCopper">,fw_FrameCounter-2(a6)
|
|
moveq.l #0,d0
|
|
IF FW_VBL_IRQ_SUPPORT
|
|
move.l d0,fw_VBlankIRQ(a6)
|
|
ENDC
|
|
IF FW_COPPER_IRQ_SUPPORT
|
|
move.l d0,fw_CopperIRQ(a6)
|
|
ENDC
|
|
move.w #DMAF_SPRITE|DMAF_RASTER|DMAF_COPPER,dmacon(a5) ; Disable sprite- and copper DMA to avoid race conditions overwriting cop1lc
|
|
bsr.s .clrspr
|
|
move.w #$0200,bplcon0(a5)
|
|
|
|
move.l fw_BaseCopperlist(a6),a0
|
|
move.l a0,cop1lc(a5)
|
|
|
|
move.l fw_VBR(a6),a0
|
|
move.l fw_DefaultIRQ(a6),$6c(a0)
|
|
IF FW_SOFT_IRQ_SUPPORT
|
|
lea fw_softint_irq(pc),a1
|
|
move.l a1,$64(a0)
|
|
ENDC
|
|
IF FW_AUDIO_IRQ_SUPPORT
|
|
move.l $70(a0),fw_OldSystemAudioIRQ(a6)
|
|
lea fw_audio_irq(pc),a1
|
|
move.l a1,$70(a0)
|
|
ENDC
|
|
|
|
move.w #INTF_BLIT,intena(a5) ; disable blitter interrupt
|
|
move.w #INTF_BLIT|INTF_COPER,intreq(a5)
|
|
IF FW_COPPER_IRQ_SUPPORT
|
|
move.w #INTF_SETCLR|INTF_INTEN|INTF_COPER|INTF_VERTB,intena(a5) ; enable vblank & copper interrupts
|
|
ELSE
|
|
move.w #INTF_SETCLR|INTF_INTEN|INTF_VERTB,intena(a5) ; enable vblank interrupt
|
|
ENDC
|
|
IF FW_SOFT_IRQ_SUPPORT
|
|
move.w #INTF_SOFTINT,intreq(a5)
|
|
move.w #INTF_SETCLR|INTF_SOFTINT,intena(a5) ; enable soft interrupt
|
|
ENDC
|
|
bsr.s fw_VSync
|
|
move.w #DMAF_SETCLR|DMAF_MASTER|DMAF_BLITTER|DMAF_RASTER|DMAF_COPPER,dmacon(a5)
|
|
.clrspr
|
|
moveq.l #0,d0
|
|
move.w d0,spr+0*8+sd_ctl(a5)
|
|
move.w d0,spr+1*8+sd_ctl(a5)
|
|
move.w d0,spr+2*8+sd_ctl(a5)
|
|
move.w d0,spr+3*8+sd_ctl(a5)
|
|
move.w d0,spr+4*8+sd_ctl(a5)
|
|
move.w d0,spr+5*8+sd_ctl(a5)
|
|
move.w d0,spr+6*8+sd_ctl(a5)
|
|
move.w d0,spr+7*8+sd_ctl(a5)
|
|
rts
|
|
|
|
;--------------------------------------------------------------------
|
|
; Sets a new copperlist (and waits for VBL)
|
|
;
|
|
; In: a0 = the new copperlist
|
|
;
|
|
fw_SetCopper:
|
|
move.l a0,cop1lc(a5)
|
|
IF FW_MULTITASKING_SUPPORT
|
|
bra fw_VSyncWithTask
|
|
ELSE
|
|
;bra.s fw_VSync
|
|
; fall through
|
|
ENDC
|
|
|
|
;--------------------------------------------------------------------
|
|
; Waits for the next vertical blank.
|
|
;
|
|
; This version does not allow other tasks to run in the background!
|
|
;
|
|
; Note: Also checks left mouse button for exit if configured.
|
|
;
|
|
; In : -
|
|
; Out: d0 is trashed
|
|
;
|
|
IFEQ FW_MULTITASKING_SUPPORT
|
|
fw_VSyncWithTask:
|
|
ENDC
|
|
fw_VSync:
|
|
IF FW_LMB_EXIT_SUPPORT
|
|
IFEQ FW_LMB_EXIT_SUPPORT-2
|
|
tst.w fw_DisableLMBExit(a6)
|
|
bne.s .noabort
|
|
ENDC
|
|
btst #6,$bfe001
|
|
beq .abortdemo
|
|
ENDC
|
|
.noabort
|
|
IF 1
|
|
move.w fw_FrameCounter(a6),d0
|
|
BLTHOGON
|
|
.loop cmp.w fw_FrameCounter(a6),d0
|
|
beq.s .loop
|
|
ELSE
|
|
;btst #DMAB_BLTDONE-8,dmaconr(a5)
|
|
;beq.s .vs1
|
|
BLTHOGON
|
|
.vs1 btst #0,vposr+1(a5)
|
|
beq.s .vs1
|
|
.vs0 btst #0,vposr+1(a5)
|
|
bne.s .vs0
|
|
ENDC
|
|
rts
|
|
|
|
IF FW_LMB_EXIT_SUPPORT
|
|
.abortdemo
|
|
move.l fw_DemoAbortStackPointer(a6),d0
|
|
beq.s .noabort
|
|
move.l d0,sp
|
|
rts
|
|
ENDC
|
|
|
|
;--------------------------------------------------------------------
|
|
; Waits until the global framecounter reaches at least the given frame
|
|
;
|
|
; In : d0.w - frame to wait for
|
|
; Out: May trash all registers!
|
|
;
|
|
fw_WaitForFrame:
|
|
PUTMSG 20,<"%d: Waiting for frame %d">,fw_FrameCounter-2(a6),d0
|
|
IF FW_MULTITASKING_SUPPORT
|
|
move.l #$1ff00,d1
|
|
and.l vposr(a5),d1
|
|
cmp.l #FW_MAX_VPOS_FOR_BG_TASK<<8,d1
|
|
ble.s .enoughtime
|
|
; we're close to the VBL, spin
|
|
BLTHOGON
|
|
.spin cmp.w fw_FrameCounter(a6),d0
|
|
bmi.s .endwait
|
|
; check if we have gone past the VBL
|
|
move.l #$1ff00,d1
|
|
and.l vposr(a5),d1
|
|
cmp.l #FW_MAX_VPOS_FOR_BG_TASK<<8,d1
|
|
bgt.s .spin
|
|
.enoughtime
|
|
.loop cmp.w fw_FrameCounter(a6),d0
|
|
bmi.s .endwait
|
|
move.w d0,-(sp)
|
|
bsr fw_VSyncWithTask
|
|
move.w (sp)+,d0
|
|
bra.s .loop
|
|
ELSE
|
|
.spin cmp.w fw_FrameCounter(a6),d0
|
|
bpl.s .spin
|
|
ENDC
|
|
.endwait
|
|
PUTMSG 20,<"%d: Waiting done">,fw_FrameCounter-2(a6)
|
|
rts
|
|
|
|
;--------------------------------------------------------------------
|
|
; Flushes the cache on Kick 2.0 or higher to avoid problems with SMC.
|
|
; (also after loading code).
|
|
;
|
|
fw_FlushCaches:
|
|
PUSHM a6
|
|
move.l 4.w,a6
|
|
cmp.w #37,LIB_VERSION(a6)
|
|
blo.s .lameos
|
|
CALL CacheClearU
|
|
.lameos
|
|
POPM
|
|
rts
|
|
|
|
;--------------------------------------------------------------------
|
|
|
|
IF FW_COPPER_IRQ_SUPPORT
|
|
fw_copper_irq:
|
|
IF FW_A5_A6_UNTOUCHED
|
|
PUSHM d0/a0/a5/a6
|
|
lea $dff000,a5
|
|
move.l fw_BasePtr(pc),a6
|
|
ELSE
|
|
PUSHM d0/a0
|
|
ENDC
|
|
move.w #INTF_COPER,intreq(a5) ;acknowledge the copper-irq.
|
|
move.w #INTF_COPER,intreq(a5) ;acknowledge the copper-irq.
|
|
move.l fw_CopperIRQ(a6),d0
|
|
beq.s .nocop
|
|
move.l d0,a0
|
|
jsr (a0)
|
|
.nocop POPM
|
|
nop
|
|
rte
|
|
ENDC
|
|
|
|
;--------------------------------------------------------------------
|
|
|
|
fw_vblank_standard_irq:
|
|
IF FW_COPPER_IRQ_SUPPORT
|
|
btst #INTB_COPER,$dff000+intreqr+1
|
|
bne.s fw_copper_irq
|
|
ENDC
|
|
|
|
IF FW_A5_A6_UNTOUCHED
|
|
IF FW_VBL_IRQ_SUPPORT|(FW_MUSIC_SUPPORT&FW_VBL_MUSIC_IRQ)
|
|
PUSHM d0-d3/a0-a3
|
|
ENDC
|
|
ELSE
|
|
IF FW_VBL_IRQ_SUPPORT|(FW_MUSIC_SUPPORT&FW_VBL_MUSIC_IRQ)
|
|
PUSHM d0-d3/a0-a3/a5/a6
|
|
ELSE
|
|
PUSHM a5/a6
|
|
ENDC
|
|
lea $dff000,a5
|
|
move.l fw_BasePtr(pc),a6
|
|
ENDC
|
|
move.w #INTF_VERTB,intreq(a5) ;acknowledge the VBL-irq.
|
|
move.w #INTF_VERTB,intreq(a5) ;acknowledge the VBL-irq.
|
|
|
|
addq.w #1,fw_FrameCounter(a6)
|
|
IF (FW_MUSIC_SUPPORT&FW_VBL_MUSIC_IRQ)
|
|
move.l fw_MusicTickRoutine(a6),d0
|
|
beq.s .skipmus
|
|
move.l d0,a0
|
|
jsr (a0) ; IRQ must maintain d4-d7/a4
|
|
.skipmus
|
|
ENDC
|
|
IF FW_VBL_IRQ_SUPPORT
|
|
move.l fw_VBlankIRQ(a6),d0
|
|
beq.s .novbl
|
|
move.l d0,a0
|
|
jsr (a0) ; IRQ must maintain d4-d7/a4
|
|
.novbl
|
|
ENDC
|
|
|
|
IF FW_A5_A6_UNTOUCHED
|
|
IF FW_VBL_IRQ_SUPPORT|(FW_MUSIC_SUPPORT&FW_VBL_MUSIC_IRQ)
|
|
POPM
|
|
ENDC
|
|
ELSE
|
|
POPM
|
|
ENDC
|
|
nop
|
|
rte
|
|
|
|
IF FW_SOFT_IRQ_SUPPORT
|
|
fw_softint_irq:
|
|
IFEQ FW_A5_A6_UNTOUCHED
|
|
PUSHM a5/a6
|
|
lea $dff000,a5
|
|
move.l fw_BasePtr(pc),a6
|
|
ENDC
|
|
move.w #INTF_SOFTINT,intreq(a5)
|
|
pea .skip(pc)
|
|
move.l fw_SoftIRQ(a6),-(sp)
|
|
beq.s .nopsy
|
|
rts
|
|
.nopsy addq.l #8,sp
|
|
.skip
|
|
IFEQ FW_A5_A6_UNTOUCHED
|
|
POPM
|
|
ENDC
|
|
nop
|
|
rte
|
|
ENDC
|
|
|
|
IF FW_AUDIO_IRQ_SUPPORT
|
|
fw_audio_irq:
|
|
PUTMSG 60,<"INT %lx">,$dff000+intenar
|
|
IFEQ FW_A5_A6_UNTOUCHED
|
|
PUSHM a5/a6
|
|
lea $dff000,a5
|
|
move.l fw_BasePtr(pc),a6
|
|
ENDC
|
|
move.w #INTF_AUD0|INTF_AUD1|INTF_AUD2|INTF_AUD3,intreq(a5)
|
|
pea .skip(pc)
|
|
move.l fw_AudioIRQ(a6),-(sp)
|
|
beq.s .noaud
|
|
rts ; IRQ must maintain d0-d7/a1-a4
|
|
.noaud addq.l #8,sp
|
|
.skip
|
|
IFEQ FW_A5_A6_UNTOUCHED
|
|
POPM
|
|
ENDC
|
|
nop
|
|
rte
|
|
|
|
ENDC
|