;-------------------------------------------------------------------- ; 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