;-------------------------------------------------------------------- ; 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_FrameCounterLong(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) 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 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 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 the given frame ; ; In : d0.w - frame to wait for ; Out: May trash all registers! ; fw_WaitForFrame: PUTMSG 10,<"%d: Waiting for frame %d">,fw_FrameCounterLong(a6),d0 .loop cmp.w fw_FrameCounter(a6),d0 bmi.s .endwait PUSHM d0 IF FW_MULTITASKING_SUPPORT bra fw_VSyncWithTask ELSE bra fw_VSync ENDC POPM bra.s .loop .endwait PUTMSG 10,<"%d: Waiting done">,fw_FrameCounterLong(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: PUSHM d0/a0/a5/a6 lea $dff000,a5 move.w #INTF_COPER,intreq(a5) ;acknowledge the copper-irq. move.w #INTF_COPER,intreq(a5) ;acknowledge the copper-irq. move.l fw_BasePtr(pc),a6 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_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.w #INTF_VERTB,intreq(a5) ;acknowledge the VBL-irq. move.w #INTF_VERTB,intreq(a5) ;acknowledge the VBL-irq. move.l fw_BasePtr(pc),a6 addq.w #1,fw_FrameCounter(a6) IF (FW_MUSIC_SUPPORT&FW_VBL_MUSIC_IRQ) tst.w fw_MusicEnabled(a6) beq.s .skipmus bsr fw_MusicPlay .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 POPM nop rte