From 178968cc2fc4c32fb918ebb4ccd24d78b64cd73f Mon Sep 17 00:00:00 2001 From: Javier Degirolmo Date: Fri, 7 Oct 2011 12:17:54 -0300 Subject: Initial upload, Echo 0.8 UNSTABLE VERSION --- src-z80/core/bgm.z80 | 290 ++++++++++++++++++++++++++++++++++++++++++++ src-z80/core/main.z80 | 330 ++++++++++++++++++++++++++++++++++++++++++++++++++ src-z80/core/sfx.z80 | 316 +++++++++++++++++++++++++++++++++++++++++++++++ src-z80/core/vars.z80 | 70 +++++++++++ 4 files changed, 1006 insertions(+) create mode 100644 src-z80/core/bgm.z80 create mode 100644 src-z80/core/main.z80 create mode 100644 src-z80/core/sfx.z80 create mode 100644 src-z80/core/vars.z80 (limited to 'src-z80/core') diff --git a/src-z80/core/bgm.z80 b/src-z80/core/bgm.z80 new file mode 100644 index 0000000..f69235d --- /dev/null +++ b/src-z80/core/bgm.z80 @@ -0,0 +1,290 @@ +;**************************************************************************** +; PlayBGM [command $04] +; Plays a BGM +;**************************************************************************** + +PlayBGM: + PollPCM + call ClearBGM ; Clear BGM resources + PollPCM + + ld a, (RAM_Status) ; Show BGM playback in Echo's status + or $02 + ld (RAM_Status), a + + PollPCM + + ld hl, RAM_ComBank ; Get command parameters + ld c, (hl) + inc l + ld e, (hl) + inc l + ld d, (hl) + + PollPCM + + xor a ; Command parsed + ld (RAM_Command), a + + ld hl, RAM_BGMData ; Set BGM as playing + ld (hl), $01 + inc l ; No delays! + ld (hl), $01 + inc l ; Store BGM start bank + ld (hl), c + inc l ; Store BGM start address (low) + ld (hl), e + inc l ; Store BGM start address (high) + ld (hl), d + + PollPCM + + ld hl, ProcessBGM ; Tell Echo to process BGM + ld (DoTick_BGM+1), hl + + PollPCM + jp IdleLoop ; End of subroutine + +;**************************************************************************** +; ProcessBGM +; Processes a tick for a BGM +;**************************************************************************** + +ProcessBGM: + PollPCM + + ld hl, RAM_BGMData+1 ; BGM data address + + ld a, (hl) ; Delaying? + dec a + jp z, .nodelay + ld (hl), a + + jp DoTick_BGMSkip ; End of subroutine + +.nodelay: + PollPCM + + inc l + ld c, (hl) ; Get current address + inc l + ld e, (hl) + inc l + ld d, (hl) + ex de, hl + +ProcessBGMRun: + PollPCM ; Fetch next event + call GetParam + PollPCM + + ld a, b ; Parse byte + + cp $08 + jp c, NoteOnFMBGM ; Events $00-$07: note on FM + cp $0B + jp c, NoteOnPSGBGM ; Events $08-$0A: note on PSG (square) + jp z, NoteOnNoiseBGM ; Event $0B: note on PSG (noise) + cp $0C + jp z, PlayPCMBGM ; Event $0C: play PCM + + PollPCM + ld a, b + + cp $18 + jp c, NoteOffFMBGM ; Events $10-$17: note off FM + cp $1C + jp c, NoteOffPSGBGM ; Events $18-$1B: note off PSG + jp z, StopPCMBGM ; Event $1C: note off PCM + + PollPCM + ld a, b + + cp $FE + jp z, SetDelayBGM ; Event $FE: set delay + cp $FF + jp z, StopBGMEvent ; Event $FF: stop BGM + cp $FC + jp z, LoopBGM ; Event $FC: loop BGM + cp $FD + jp z, SetLoopBGM ; Event $FD: set loop point + + PollPCM + ld a, b + + cp $28 + jp c, SetFMVolBGM ; Events $28-$2B: set FM volume + cp $2C + jp c, SetPSGVolBGM ; Events $28-$2B: set PSG volume + + PollPCM + ld a, b + + cp $38 + jp c, SetNoteFMBGM ; Events $30-$37: set FM note + cp $3B + jp c, SetNotePSGBGM ; Events $38-$3A: set PSG note (square) + jp z, SetNoteNoiseBGM ; Event $3B: set PSG note (noise) + + PollPCM + ld a, b + + cp $48 + jp c, LoadFMBGM ; Events $40-$47: load FM instrument + cp $4C + jp c, LoadPSGBGM ; Events $48-$4B: load PSG instrument + + PollPCM + ld a, b + + cp $F8 ; Events $F0-$F7: set FM parameters + jp c, SetFMParamBGM + + PollPCM ; FFFFFFFFF bad event >:( + jp StopBGMEvent ; End of subroutine + +ProcessBGMSkip2: ; This is where we land after a locked event + PollPCM ; that had two bytes for the parameter + inc l ; Skip first byte + jp nz, .nobankskip2 + inc h + jp nz, .nobankskip2 + ld h, $80 + inc c +.nobankskip2: + +ProcessBGMSkip1: ; This is where we land after a locked event + PollPCM ; that had one byte for the parameter + inc l ; Skip byte + jp nz, .nobankskip1 + inc h + jp nz, .nobankskip1 + ld h, $80 + inc c +.nobankskip1: + +ProcessBGMSkip: ; This is where we land after a locked event + PollPCM ; without parameters + + jp ProcessBGMRun ; Keep processing + +;**************************************************************************** +; StopBGM* [command $05, event $FF] +; Stops BGM playback +;**************************************************************************** + +StopBGMEvent: + call StopBGM ; We're just a wrapper + jp DoTick_BGMSkip ; End of subroutine + +StopBGMCmd: + xor a ; Command parsed + ld (RAM_Command), a + call StopBGM ; We're just a wrapper + jp IdleLoop ; End of subroutine + +StopBGM: + ld a, (RAM_Status) ; Hide BGM playback in Echo's status + and $FD + ld (RAM_Status), a + + PollPCM + + call ClearBGM ; Clear BGM resources + PollPCM + + xor a ; Stop playback + ld (RAM_BGMPlaying), a + ld hl, DoTick_BGMSkip + ld (DoTick_BGM+1), hl + + ret ; End of subroutine + +;**************************************************************************** +; ClearBGM +; Clears BGM resources +;**************************************************************************** + +ClearBGM: + ld a, (RAM_Locked+6) ; Stop PCM playback if needed + or a + call z, StopPCM + + ld b, 4 ; Mute all non-locked PSG channels + ld de, RAM_PSGData+48 + ld hl, RAM_Locked+11 +.mutepsg: + PollPCM + ld a, (hl) + or a + jr nz, .nopsgmute + xor a + ld (de), a +.nopsgmute: + PollPCM + ld a, e + sub 16 + ld e, a + dec l + djnz .mutepsg + + ld b, 8 ; Mute all non-locked FM channels +.mutefm: + PollPCM + ld a, (hl) + or a + jr nz, .nofmmute + PollPCM + dec b + ld (ix+0), $28 + ld (ix+1), b + inc b +.nofmmute: + dec l + djnz .mutefm + + ret ; End of subroutine + +;**************************************************************************** +; LoopBGM [event $FC] +; Makes a BGM loop +;**************************************************************************** + +LoopBGM: + PollPCM + + ex de, hl ; Get looping address + inc l + ld c, (hl) + inc l + ld e, (hl) + inc l + ld d, (hl) + dec l + dec l + dec l + ex de, hl + + jp ProcessBGMRun ; End of subroutine + +;**************************************************************************** +; SetLoopBGM [event $FD] +; Sets the BGM loop point +;**************************************************************************** + +SetLoopBGM: + PollPCM + + ex de, hl + inc l ; Store loop point address + ld (hl), c + inc l + ld (hl), e + inc l + ld (hl), d + dec l + dec l + dec l + ex de, hl + + jp ProcessBGMRun ; End of subroutine diff --git a/src-z80/core/main.z80 b/src-z80/core/main.z80 new file mode 100644 index 0000000..4018a1b --- /dev/null +++ b/src-z80/core/main.z80 @@ -0,0 +1,330 @@ +;**************************************************************************** +; EntryPoint +; Where the program starts +;**************************************************************************** + +EntryPoint: + ld sp, RAM_Stack ; Init stack + + xor a ; Reset Echo status + ld (RAM_Status), a + + ld hl, $7F11 ; Mute PSG + ld (hl), $9F + ld (hl), $BF + ld (hl), $DF + ld (hl), $FF + xor a + ld (RAM_PSGData), a + ld (RAM_PSGData+16), a + ld (RAM_PSGData+32), a + ld (RAM_PSGData+48), a + + ld hl, $6000 ; Set default bank + ld (hl), l + ld (hl), l + ld (hl), l + ld (hl), l + ld (hl), l + ld (hl), l + ld (hl), l + ld (hl), l + ld (hl), l + + ;ex af, af' ; Set 9th bank bit to 0 by default + ;xor a ; (0 = $000000-$7FFFFF range aka MD mode) + ;ex af, af' ; (1 = $800000-$FFFFFF range aka 32X mode) + + ld ix, $4000 ; YM2612 I/O ports base address + ld iyh, $40 + + exx ; Init PCM playback status + ld bc, $0000 ; B = playing, C = bank + ld de, $0000 ; DE = address + ld hl, $6000 ; HL = always $6000 + exx + + ld (ix+0), $2B ; Disable DAC by default + ld (ix+1), $00 + + ld e, $7F ; Mute all FM channels + ld a, $40 + ld b, 4 +.mutefm: + ld (ix+0), a + ld (ix+1), e + ld (ix+2), a + ld (ix+3), e + inc a + ld (ix+0), a + ld (ix+1), e + ld (ix+2), a + ld (ix+3), e + inc a + ld (ix+0), a + ld (ix+1), e + ld (ix+2), a + ld (ix+3), e + inc a + inc a + djnz .mutefm + + ld (ix+0), $B4 ; Ensure all channels can be heard from both + ld (ix+1), $C0 ; speakers (by default they're mute!) + ld (ix+0), $B5 + ld (ix+1), $C0 + ld (ix+0), $B6 + ld (ix+1), $C0 + ld (ix+2), $B4 + ld (ix+3), $C0 + ld (ix+2), $B5 + ld (ix+3), $C0 + ld (ix+2), $B6 + ld (ix+3), $C0 + + ld (ix+0), $24 ; Init timers + ld (ix+1), $FE + ld (ix+0), $25 + ld (ix+1), $03 + ld (ix+0), $26 + ld (ix+0), $C9 + ld (ix+1), $FF + ld (ix+0), $27 + ld (ix+1), $3F + + jp IdleLoop ; Go into idle loop + +;**************************************************************************** +; PollPCM +; Used to update PCM while not idle +;**************************************************************************** + +PollPCM: macro + ld a, ($4000) + bit 0, a + call nz, UpdatePCM + endm + +;**************************************************************************** +; RunCommand +; Checks which command to run +;**************************************************************************** + +RunCommand: + dec a ; Command $01: load list + jp z, LoadList + dec a ; Command $02: play SFX + jp z, PlaySFX + dec a ; Command $03: stop SFX + jp z, StopSFXCmd + dec a ; Command $04: play BGM + jp z, PlayBGM + dec a ; Command $05: stop BGM + jp z, StopBGMCmd + + PollPCM + + xor a ; Bad command, ignore >:( + ld (RAM_Command), a + + PollPCM + +;**************************************************************************** +; IdleLoop +; Loop that runs when not processing SFX or BGM +;**************************************************************************** + +IdleLoop: + ld a, (RAM_Command) ; Look for commands + or a + jr nz, RunCommand + + PollPCM ; Poll PCM + + ld a, ($4000) ; Tick? + bit 1, a + jr nz, DoTick + bit 0, a ; Poll PCM again + call nz, UpdatePCM ; Not using macro for optimization purposes + + jp IdleLoop ; Keep idling + +;**************************************************************************** +; DoTick +; Called whenever a new tick triggers +;**************************************************************************** + +DoTick: + ld a, (ix+0) + bit 0, a + call nz, UpdatePCM + + ld (ix+0), $26 ; Reset timer +.timerset: + ld (ix+1), $C8 + ld (ix+0), $27 + ld (ix+1), $2F + + ld a, (.timerset+3) ; $C8 is too fast, $C9 is too slow + xor $01 ; So, we alternate between them to compensate + ld (.timerset+3), a + + PollPCM + +DoTick_SFX: ; Process SFXs + jp DoTick_SFXSkip +DoTick_SFXSkip: + + PollPCM + +DoTick_BGM: ; Process BGMs + jp DoTick_BGMSkip +DoTick_BGMSkip: + + PollPCM + + jp UpdatePSG ; Update PSG envelopes +DoTick_PSGSkip: + + PollPCM + + jp IdleLoop ; End of subroutine + +;**************************************************************************** +; BankSwitch +; Switches into a new bank (won't update player status!) +; +; input A .... New bank to switch into +; input HL ... Must be $6000 +; breaks ..... AF +;**************************************************************************** + +BankSwitch: macro + ld (hl), a + rrca + ld (hl), a + rrca + ld (hl), a + rrca + ld (hl), a + rrca + ld (hl), a + rrca + ld (hl), a + rrca + ld (hl), a + ld (hl), l + rrca + ld (hl), a + endm + +;**************************************************************************** +; LoadList [command $01] +; Loads the pointer list +;**************************************************************************** + +LoadList: + ld hl, RAM_ComBank ; Get command parameters + ld c, (hl) + inc l + ld e, (hl) + inc l + ld d, (hl) + ex de, hl + + xor a ; Command parsed + ld (RAM_Command), a + + ld a, c ; Do initial bank switch + ld de, $6000 + ex de, hl + BankSwitch + ex de, hl + + ld de, RAM_PointerList ; Where the pointer list starts + +.loop: + ld a, (hl) ; Get high address byte + or a ; Is it the end of the list? + jp z, .end ; If so, stop parsing list + ld (de), a ; Nope, store it in list + + inc d ; Get address for next byte + inc l + jr nz, .noswitch1 + inc h + jr nz, .noswitch1 + inc c + ld a, c + ld h, $60 + BankSwitch + ld h, $80 +.noswitch1: + + ld a, (hl) ; Get low address byte + ld (de), a ; Store it in pointer list + + inc d ; Get address for next byte + inc l + jr nz, .noswitch2 + inc h + jr nz, .noswitch2 + inc c + ld a, c + ld h, $60 + BankSwitch + ld h, $80 +.noswitch2: + + ld a, (hl) ; Get bank byte + ld (de), a ; Store it in pointer list + + dec d ; Get address for next byte + dec d + inc e + inc l + jr nz, .noswitch3 + inc h + jr nz, .noswitch3 + inc c + ld a, c + ld h, $60 + BankSwitch + ld h, $80 +.noswitch3: + + jp .loop ; Go for next byte + +.end: + ld a, c ; Store current bank + ld (RAM_LastBank), a + jp IdleLoop ; End of subroutine + +;**************************************************************************** +; GetParam +; Subroutine for getting the parameter byte +;**************************************************************************** + +GetParam: + ld a, (RAM_LastBank) ; Bank switch? + cp c + jp z, .noswitchp + ld a, c + ld (RAM_LastBank), a + exx + BankSwitch + exx +.noswitchp: + ld b, (hl) ; Get volume + + PollPCM + + inc l ; Get next address + jp nz, .nonewbankp + inc h + jp nz, .nonewbankp + ld h, $80 + inc c +.nonewbankp: + + ret ; End of subroutine diff --git a/src-z80/core/sfx.z80 b/src-z80/core/sfx.z80 new file mode 100644 index 0000000..b7e26aa --- /dev/null +++ b/src-z80/core/sfx.z80 @@ -0,0 +1,316 @@ +;**************************************************************************** +; PlaySFX [command $02] +; Plays a SFX +;**************************************************************************** + +PlaySFX: + PollPCM + call ClearSFX ; Clear SFX resources + PollPCM + + ld a, (RAM_Status) ; Show SFX playback in Echo's status + or $01 + ld (RAM_Status), a + + PollPCM + + ld hl, RAM_ComBank ; Get command parameters + ld c, (hl) + inc l + ld e, (hl) + inc l + ld d, (hl) + + PollPCM + + xor a ; Command parsed + ld (RAM_Command), a + + ld hl, RAM_SFXData ; Set SFX as playing + ld (hl), $01 + inc l ; No delays! + ld (hl), $01 + inc l ; Store SFX start bank + ld (hl), c + inc l ; Store SFX start address (low) + ld (hl), e + inc l ; Store SFX start address (high) + ld (hl), d + + PollPCM + + ld hl, ProcessSFX ; Tell Echo to process SFX + ld (DoTick_SFX+1), hl + + PollPCM + jp IdleLoop ; End of subroutine + +;**************************************************************************** +; ProcessSFX +; Processes a tick for a SFX +;**************************************************************************** + +ProcessSFX: + PollPCM + + ld hl, RAM_SFXData+1 ; SFX data address + + ld a, (hl) ; Delaying? + dec a + jp z, .nodelay + ld (hl), a + + jp DoTick_SFXSkip ; End of subroutine + +.nodelay: + PollPCM + + inc l ; Get current address + ld c, (hl) + inc l + ld e, (hl) + inc l + ld d, (hl) + ex de, hl + +ProcessSFXRun: + PollPCM ; Fetch next event + call GetParam + PollPCM + + ld a, b ; Parse byte + + cp $08 + jp c, NoteOnFMSFX ; Events $00-$07: note on FM + cp $0B + jp c, NoteOnPSGSFX ; Events $08-$0A: note on PSG (square) + jp z, NoteOnNoiseSFX ; Event $0B: note on PSG (noise) + cp $0C + jp z, PlayPCMSFX ; Event $0C: note on PCM + + PollPCM + ld a, b + + cp $18 + jp c, NoteOffFMSFX ; Events $10-$17: note off FM + cp $1C + jp c, NoteOffPSGSFX ; Events $18-$1B: note off PSG + jp z, StopPCMSFX ; Event $1C: note off PCM + + PollPCM + ld a, b + + cp $FE + jp z, SetDelaySFX ; Event $FE: set delay + cp $FF + jp z, StopSFXEvent ; Event $FF: stop SFX + + PollPCM + ld a, b + + cp $28 + jp c, SetFMVolSFX ; Events $28-$2B: set FM volume + cp $2C + jp c, SetPSGVolSFX ; Events $28-$2B: set PSG volume + + PollPCM + ld a, b + + cp $38 + jp c, SetNoteFMSFX ; Events $30-$37: set FM note + cp $3B + jp c, SetNotePSGSFX ; Events $38-$3A: set PSG note (square) + jp z, SetNoteNoiseSFX ; Event $3B: set PSG note (noise) + + PollPCM + ld a, b + + cp $48 + jp c, LoadFMSFX ; Events $40-$47: load FM instrument + cp $4C + jp c, LoadPSGSFX ; Events $48-$4B: load PSG instrument + + PollPCM + ld a, b + + cp $E8 + jp c, LockChannelFM ; Events $E0-$E7: lock FM channel + cp $EC + jp c, LockChannelPSG ; Events $E8-$EB: lock PSG channel + jp z, LockChannelPCM ; Event $EC: lock PCM channel + + PollPCM + ld a, b + + cp $F8 ; Events $F0-$F7: set FM parameters + jp c, SetFMParamSFX + +;**************************************************************************** +; StopSFX* [command $03, event $FF] +; Stops SFX playback +;**************************************************************************** + +StopSFXEvent: + call StopSFX ; We're just a wrapper + jp DoTick_SFXSkip ; End of subroutine + +StopSFXCmd: + xor a ; Command parsed + ld (RAM_Command), a + call StopSFX ; We're just a wrapper + jp IdleLoop ; End of subroutine + +StopSFX: + PollPCM + + ld a, (RAM_Status) ; Hide SFX playback in Echo's status + and $FE + ld (RAM_Status), a + + PollPCM + + xor a ; Stop playback + ld (RAM_SFXPlaying), a + ld hl, DoTick_SFXSkip + ld (DoTick_SFX+1), hl + + PollPCM + call ClearSFX ; Clear SFX resources + + PollPCM + ret ; End of subroutine + +;**************************************************************************** +; ClearSFX +; Clears SFX resources +;**************************************************************************** + +ClearSFX: + ld a, (RAM_Locked+6) ; Stop PCM playback if needed + or a + call nz, StopPCM + +;---------------------------------------------------------------------------- + + ld b, 4 ; Look for locked PSG channels + ld de, RAM_Locked+11 +.unlockpsg: + + PollPCM + + ld a, (de) ; Check if this channel needs unlocking + or a + jr z, .psgfree + xor a + ld (de), a + + PollPCM + + ld a, b ; Restore BGM volume + rrca + rrca + rrca + rrca + dec a + ld h, RAM_PSGData>>8 + ld l, a + ld c, (hl) + sub 15 + ld l, a + ld (hl), c + + PollPCM + push de + + ld a, l ; Restore BGM envelope + add 8 + ld l, a + add 12-8 + ld e, a + ld d, h + + PollPCM + + ld a, (de) + ld (hl), a + inc l + inc e + ld a, (de) + ld (hl), a + inc l + inc e + ld a, (de) + ld (hl), a + + pop de + PollPCM + +.psgfree: + dec e ; Go for next PSG channel to unlock + djnz .unlockpsg + +;---------------------------------------------------------------------------- + + ld b, 8 ; Look for locked FM channels +.unlockfm: + + PollPCM + + ld a, (de) ; Check if this channel needs unlocking + or a + jp z, .fmfree + xor a + ld (de), a + + dec b ; Mute FM channel + ld (ix+0), $28 + ld (ix+1), b + + PollPCM + + ld a, b + and $04 ; Determine which port to write + rrca + ld iyl, a + + ld a, b ; Kill ADSR + call KillFM + + PollPCM + + ld hl, RAM_BGMFMVol ; Restore BGM FM volume + ld a, b + add l + ld l, a + ld c, (hl) + ld a, l + add 8 + ld l, a + ld (hl), c + + PollPCM + + ld a, l ; Restore BGM FM instrument + sub 8*2 + ld l, a + push bc + push de + push hl + ld a, b + ld b, (hl) + call LoadFMDirect + pop hl + pop de + pop bc + + PollPCM + inc b +.fmfree: + PollPCM + dec e ; Go for next FM channel to unlock + dec b + jp nz, .unlockfm + +;---------------------------------------------------------------------------- + + ret ; End of subroutine diff --git a/src-z80/core/vars.z80 b/src-z80/core/vars.z80 new file mode 100644 index 0000000..ef9a676 --- /dev/null +++ b/src-z80/core/vars.z80 @@ -0,0 +1,70 @@ +;**************************************************************************** +; Player variables +;**************************************************************************** + + ds $100-($&$FF), $FF +RAM_PSGData: ds 4*16 ; PSG envelope data + ; ds 1 ... Channel volume + ; ds 1 ... Global volume + ; ds 3 ... Current address + ; ds 3 ... Looping address + ; ds 3 ... Start address + ; ds 1 ... Padding + ; ds 3 ... BGM instrument address + ; ds 1 ... BGM channel volume + +RAM_BGMFMInstr: ds 8 ; FM instruments used by BGM +RAM_BGMFMVol: ds 8 ; FM volumes used by BGM +RAM_FMVolume: ds 8 ; Volume of each FM channel +RAM_FMData: ds 8*5 ; FM info (for volume handling) + ; ds 8*1 ... Register $B0 + ; ds 8*1 ... Register $40 + ; ds 8*1 ... Register $44 + ; ds 8*1 ... Register $48 + ; ds 8*1 ... Register $4C + +RAM_LastBank: ds 1 ; Last accessed bank + +RAM_BGMData: ; Where BGM data starts +RAM_BGMPlaying: ds 1 ; Set if a BGM is playing +RAM_BGMDelay: ds 1 ; How many ticks to wait +RAM_BGMBank: ds 1 ; Current BGM bank +RAM_BGMAddress: ds 2 ; Current BGM address +RAM_BGMLoopPoint: ds 3 ; BGM loop point + +RAM_SFXData: ; Where SFX data starts +RAM_SFXPlaying: ds 1 ; Set if a SFX is playing +RAM_SFXDelay: ds 1 ; How many ticks to wait +RAM_SFXBank: ds 1 ; Current SFX bank +RAM_SFXAddress: ds 2 ; Current SFX address + +RAM_Locked: ds 12 ; Locked channels + +RAM_Scratch: ds 32 ; Scratch bytes, may be useful when + ; buffering to speed up to avoid bank + ; switching conflicts + +;**************************************************************************** +; Pointer list starts being stored from here +; $300 (768) bytes are needed to store the pointer list +; +; Format for a pointer list entry is as follows: +; RAM_PointerList[$000+n] = address high +; RAM_PointerList[$100+n] = address low +; RAM_PointerList[$200+n] = bank +;**************************************************************************** + + ds $100-($&$FF), $FF + +RAM_PointerList: equ $1C00 + +;**************************************************************************** +; 68000 communication variables +;**************************************************************************** + +RAM_Stack: equ $1FF0 ; Where stack starts + +RAM_Status: equ $1FF0 ; Current playback status +RAM_Command: equ $1FFF ; Command type +RAM_ComAddr: equ $1FFD ; Command address parameter +RAM_ComBank: equ $1FFC ; Command bank parameter -- cgit v1.2.3