Hamazing/source/framework/framework_misc.asm
chrisly42 9c48c11cd1 Big "squashed" update to latest version of Framework.
- 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
2024-09-15 17:43:33 +02:00

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