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
212 lines
6.2 KiB
NASM
212 lines
6.2 KiB
NASM
;--------------------------------------------------------------------
|
|
; Multipart support for trackmos
|
|
;
|
|
; In my former demo system I used a6 as a base pointer to the demo
|
|
; framework and a4 as a pointer to my demo part variables. That
|
|
; seemed a bit wasteful and so the new system uses one pointer for
|
|
; both framework AND part variables for the current part. This,
|
|
; however, means that the framework base needs to be relocated
|
|
; depending on the part because, of course, the size of the
|
|
; local variables may vary.
|
|
;
|
|
; You must start your local variable space with
|
|
;
|
|
; STRUCTURE PartData,fw_SIZEOF
|
|
;
|
|
; and end it with
|
|
;
|
|
; LABEL pd_SIZEOF
|
|
;
|
|
;--------------------------------------------------------------------
|
|
; Allocate the part variables
|
|
;
|
|
; The first thing each demo part needs to do is to call InitPart.
|
|
; I repeat: Start your code with:
|
|
; IFD FW_DEMO_PART
|
|
; move.l #pd_SIZEOF,d0
|
|
; CALLFW InitPart
|
|
; ENDC
|
|
;
|
|
; Otherwise, no part variables are available via a6 and no other
|
|
; framework calls can be made (the jumping table is not available).
|
|
;
|
|
; After this call, a6 will be pointing to the new framework base
|
|
; with all your variable space cleared.
|
|
;
|
|
; Make sure that you don't free the memory allocated here until
|
|
; the end of your part! The demo framework will call
|
|
; RestoreFrameworkBase automatically at exit of your part.
|
|
;
|
|
; Flushes the caches (if available), too.
|
|
;
|
|
; In : d0 = pd_SIZEOF (part data structure size including fw_SIZEOF)
|
|
; Out: a6 = new base pointer
|
|
; Trashes: everything except a5/a6
|
|
;
|
|
fw_InitPart:
|
|
PUTMSG 10,<"%d: InitPart(%ld)">,fw_FrameCounter-2(a6),d0
|
|
PUSHM d0
|
|
bsr fw_RestoreFrameworkBase
|
|
POPM
|
|
|
|
DISABLE_INTS
|
|
move.l fw_PartFwBase(a6),a0
|
|
move.l d0,fw_PartDataSize(a6)
|
|
add.l #-FWLVOPOS,d0
|
|
bsr fw_AllocFast
|
|
lea -FWLVOPOS(a0),a1
|
|
PUTMSG 40,<"LVOs from %p to %p">,a1,a0
|
|
move.l a6,a0
|
|
move.l a6,a3
|
|
move.l a1,a6
|
|
move.w #(fw_SIZEOF/4)-1,d7
|
|
PUTMSG 40,<"Copying %d LW from %p to %p">,d7,a0,a1
|
|
.copynew
|
|
move.l (a0)+,(a1)+
|
|
dbra d7,.copynew
|
|
|
|
move.l a6,fw_PartFwBase(a6)
|
|
move.l fw_PartDataSize(a6),d7
|
|
sub.l #fw_SIZEOF-3,d7
|
|
lsr.l #2,d7
|
|
beq.s .skipclr
|
|
subq.w #1,d7
|
|
moveq.l #0,d0
|
|
.clrnew
|
|
move.l d0,(a1)+
|
|
dbra d7,.clrnew
|
|
.skipclr
|
|
move.l a6,a0
|
|
lea fw_lvo_offsets(pc),a1
|
|
.lvoloop
|
|
move.w (a1)+,d0
|
|
beq.s .lvodone
|
|
lea -2(a1,d0.w),a2
|
|
move.l a2,-(a0)
|
|
move.w #%0100111011111001,-(a0) ; $4ef9 jmp x.L
|
|
bra.s .lvoloop
|
|
.lvodone
|
|
|
|
IF FW_MULTITASKING_SUPPORT
|
|
; The task list header is now broken after copying! We need to fix it.
|
|
lea fw_Tasks(a6),a1
|
|
bsr fw_RelocateList
|
|
bsr fw_FixA6BaseInTaskStacks
|
|
ENDC
|
|
|
|
lea fw_BasePtr(pc),a0
|
|
move.l a6,(a0)
|
|
bsr fw_FlushCaches
|
|
ENABLE_INTS
|
|
PUTMSG 20,<"%d: InitPart done %p">,fw_FrameCounter-2(a6),a6
|
|
rts
|
|
|
|
;--------------------------------------------------------------------
|
|
; Restore global framework base
|
|
;
|
|
; Removes the custom framework variable space and makes the global
|
|
; one active again.
|
|
;
|
|
; Out: a6 = new base pointer
|
|
; Trashes: everything except a5/a6
|
|
;
|
|
fw_RestoreFrameworkBase:
|
|
PUTMSG 10,<"%d: RestoreFrameworkBase(%p)">,fw_FrameCounter-2(a6),a6
|
|
DISABLE_INTS
|
|
move.l fw_PartFwBase(a6),a0
|
|
move.l fw_PrimaryFwBase(a6),a1
|
|
PUTMSG 40,<"Part %p, Primary %p">,a0,a1
|
|
cmp.l a1,a0
|
|
beq.s .noold
|
|
move.l a0,a3
|
|
PUTMSG 40,<"Restore from %p to %p">,a0,a1
|
|
move.l a1,a6
|
|
move.w #(fw_SIZEOF/4)-1,d7
|
|
.copyold
|
|
move.l (a0)+,(a1)+
|
|
dbra d7,.copyold
|
|
|
|
IF FW_MULTITASKING_SUPPORT
|
|
bsr fw_FixA6BaseInTaskStacks
|
|
ENDC
|
|
|
|
move.l a6,fw_PartFwBase(a6)
|
|
clr.l fw_PartDataSize(a6)
|
|
|
|
IF FW_MULTITASKING_SUPPORT
|
|
; The task list header is now broken after copying! We need to fix it.
|
|
lea fw_Tasks(a6),a1
|
|
bsr.s fw_RelocateList
|
|
ENDC
|
|
|
|
lea fw_BasePtr(pc),a0
|
|
move.l a6,(a0)
|
|
.noold
|
|
ENABLE_INTS
|
|
rts
|
|
|
|
;--------------------------------------------------------------------
|
|
; Helper function to relocate a doubly-linked list
|
|
;
|
|
; When relocating the framework base structure, we need to fix the
|
|
; contents of lists, otherwise BadThings(TM) will happen.
|
|
; This function goes through the relocated list and fixes the linkage.
|
|
;
|
|
; In: a1 = ListHead
|
|
; Trashes: a0/a1
|
|
;
|
|
IF FW_MULTITASKING_SUPPORT
|
|
fw_RelocateList:
|
|
move.l LH_HEAD(a1),a0
|
|
subq.l #4,a0
|
|
cmp.l LH_TAILPRED(a1),a0
|
|
bne.s .nonewlist
|
|
PUTMSG 10,<"Fixup empty list %p">,a1
|
|
move.l a1,LH_TAILPRED(a1) ; fix empty list
|
|
addq.l #4,a1
|
|
move.l a1,-(a1)
|
|
bra.s .listfixed
|
|
.nonewlist
|
|
PUTMSG 10,<"Fixup existing list %p">,a1
|
|
move.l a1,4+LN_PRED(a0) ; fixup LN_PRED of first node (points to LH_HEAD)
|
|
move.l LH_TAILPRED(a1),a0 ; get last node
|
|
addq.l #4,a1 ; now points to LH_TAIL
|
|
move.l a1,LN_SUCC(a0) ; fixup LN_SUCC of last node (pointing to LH_TAIL)
|
|
.listfixed
|
|
rts
|
|
ENDC
|
|
|
|
;--------------------------------------------------------------------
|
|
; Running tasks will have the old framework base stored in their
|
|
; register context. We need to fix these occurrences. Note that
|
|
; this is not completely fool-proof, but should work for 99% of the
|
|
; cases (there shouldn't be framework-relative things).
|
|
;
|
|
; In: a3 = old base
|
|
; a6 = new base
|
|
fw_FixA6BaseInTaskStacks:
|
|
lea fw_Tasks(a3),a1
|
|
.loop
|
|
TSTNODE a1,a1
|
|
beq.s .done
|
|
move.l ft_USP(a1),a0
|
|
lea ft_StackEnd(a1),a2
|
|
.findloop
|
|
cmp.l a0,a2
|
|
beq.s .loop
|
|
cmp.l (a0),a3
|
|
bne.s .notmatched
|
|
PUTMSG 10,<"Replacing base at %p">,a0
|
|
move.l a6,(a0)
|
|
.notmatched
|
|
addq.l #2,a0
|
|
bra.s .findloop
|
|
.done rts
|
|
|
|
|
|
fw_lvo_offsets:
|
|
FWGENLVOTABLE SET 1
|
|
include "framework_lvos.i"
|
|
dc.w 0
|
|
FWGENLVOTABLE SET 0
|