aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJavier Degirolmo2012-08-14 22:50:15 -0300
committerJavier Degirolmo2012-08-14 22:50:15 -0300
commit2f83b4822b5825d58ab4a74e4e9e5f0be2cc78f2 (patch)
tree41f0f35eb562b1057d0996edaff55e87c461df16
parent6ab75ecb612fbbe2ec939bd758bbbe620e6d5040 (diff)
Put asm API into the *new* src-68k directory
-rw-r--r--src-68k/echo.68k263
-rw-r--r--src-68k/esf.68k161
2 files changed, 424 insertions, 0 deletions
diff --git a/src-68k/echo.68k b/src-68k/echo.68k
new file mode 100644
index 0000000..1d02800
--- /dev/null
+++ b/src-68k/echo.68k
@@ -0,0 +1,263 @@
+;****************************************************************************
+; Echo_Z80Request
+; Requests the Z80 bus
+;****************************************************************************
+
+Echo_Z80Request macro
+ move.w #$100, ($A11100) ; Request Z80 bus
+@Echo_WaitZ80\@:
+ btst.b #0, ($A11100) ; Did we get it yet?
+ bne.s @Echo_WaitZ80\@ ; Keep waiting
+ endm ; End of macro
+
+;****************************************************************************
+; Echo_Z80Release
+; Releases the Z80 bus
+;****************************************************************************
+
+Echo_Z80Release macro
+ move.w #$000, ($A11100) ; Release Z80 bus
+ endm ; End of macro
+
+;****************************************************************************
+; Echo_Z80Reset
+; Resets the Z80 and YM2612
+;****************************************************************************
+
+Echo_Z80Reset macro
+ move.w #$000, ($A11200) ; Assert reset line
+ rept $10 ; Wait until hardware resets
+ nop ; ...
+ endr ; ...
+ move.w #$100, ($A11200) ; Release reset line
+ endm ; End of macro
+
+;****************************************************************************
+; Echo_Init
+; Initializes Echo
+;
+; input a0.l ... Address of pointer list
+;****************************************************************************
+
+Echo_Init:
+ movem.l d0/a0-a1, -(sp) ; Save registers
+
+ Echo_Z80Reset ; May not work without this...
+ Echo_Z80Request ; We need the Z80 bus
+
+ move.b #$01, ($A01FFF) ; Command: load pointer list
+
+ move.l a0, d0 ; Easier to manipulate here
+ move.b d0, ($A01FFD) ; Store low address byte
+ lsr.l #7, d0 ; Get high address byte
+ lsr.b #1, d0 ; We skip one bit
+ bset.l #7, d0 ; Point into bank window
+ move.b d0, ($A01FFE) ; Store high address byte
+ lsr.w #8, d0 ; Get bank byte
+ move.w d0, d1 ; Parse 32X bit separately
+ lsr.w #1, d1 ; Put 32X bit in place
+ and.b #$7F, d0 ; Filter out unused bit from addresses
+ and.b #$80, d1 ; Filter out all but 32X bit
+ or.b d1, d0 ; Put everything together
+ move.b d0, ($A01FFC) ; Store bank byte
+
+ lea @Z80Program(pc), a0 ; Where Z80 program starts
+ lea ($A00000), a1 ; Where Z80 RAM starts
+ move.w #@Z80ProgSize-1, d0 ; Size of Z80 program (DBF adjusted)
+@LoadLoop: ; Go through all the program
+ move.b (a0)+, (a1)+ ; Copy byte into Z80 RAM
+ dbf d0, @LoadLoop ; Go for next byte
+
+ Echo_Z80Reset ; Now reset for real
+ Echo_Z80Release ; Let the Z80 go!
+
+ movem.l (sp)+, d0/a0-a1 ; Restore registers
+ rts ; End of subroutine
+
+;****************************************************************************
+; Echo Z80 program
+; It should be located wherever Echo_ProgFile was defined
+;****************************************************************************
+
+@Z80Program: incbin "\Echo_ProgFile"
+@Z80ProgSize equ *-@Z80Program
+ even
+
+;****************************************************************************
+; Echo_SendCommand
+; Sends an Echo command (no address parameter)
+;
+; input d0.b ... Echo command
+;****************************************************************************
+
+Echo_SendCommand:
+ move.w d1, -(sp) ; Save register
+
+ Echo_Z80Request ; We need the Z80 bus
+
+@Try:
+ tst.b ($A01FFF) ; Check if Echo is ready
+ beq.s @Ready ; Too busy?
+ Echo_Z80Release ; Let Echo continue
+ move.w #$FF, d1 ; Give it some time
+ dbf d1, * ; ...
+ Echo_Z80Request ; Get Z80 bus back
+ bra.s @Try ; Try again
+
+@Ready:
+ move.b d0, ($A01FFF) ; Write command ID
+ Echo_Z80Release ; We're done with the Z80 bus
+
+ move.w (sp)+, d1 ; Restore register
+ rts ; End of subroutine
+
+;****************************************************************************
+; Echo_SendCommandEx
+; Sends an Echo command (with address parameter)
+;
+; input d0.b ... Echo command
+; input a0.l ... Address parameter
+;****************************************************************************
+
+Echo_SendCommandEx:
+ movem.l d0-d1, -(sp) ; Save register
+
+ Echo_Z80Request ; We need the Z80 bus
+
+@Try:
+ tst.b ($A01FFF) ; Check if Echo is ready
+ beq.s @Ready ; Too busy?
+ Echo_Z80Release ; Let Echo continue
+ move.w #$FF, d1 ; Give it some time
+ dbf d1, * ; ...
+ Echo_Z80Request ; Get Z80 bus back
+ bra.s @Try ; Try again
+
+@Ready:
+ move.b d0, ($A01FFF) ; Write command ID
+
+ move.l a0, d0 ; Easier to manipulate here
+ move.b d0, ($A01FFD) ; Store low address byte
+ lsr.l #7, d0 ; Get high address byte
+ lsr.b #1, d0 ; We skip one bit
+ bset.l #7, d0 ; Point into bank window
+ move.b d0, ($A01FFE) ; Store high address byte
+
+ lsr.w #8, d0 ; Get bank byte
+ move.w d0, d1 ; Parse 32X bit separately
+ lsr.w #1, d1 ; Put 32X bit in place
+ and.b #$7F, d0 ; Filter out unused bit from addresses
+ and.b #$80, d1 ; Filter out all but 32X bit
+ or.b d1, d0 ; Put everything together
+ move.b d0, ($A01FFC) ; Store bank byte
+
+ Echo_Z80Release ; We're done with the Z80 bus
+
+ movem.l (sp)+, d0-d1 ; Restore register
+ rts ; End of subroutine
+
+;****************************************************************************
+; Echo_PlaySFX
+; Plays a SFX
+;
+; input a0.l ... Pointer to SFX data
+;****************************************************************************
+
+Echo_PlaySFX:
+ move.w d0, -(sp) ; Save register
+ move.b #$02, d0 ; Command $02 = play SFX
+ bsr Echo_SendCommandEx ; Send command to Echo
+ move.w (sp)+, d0 ; Restore register
+ rts ; End of subroutine
+
+;****************************************************************************
+; Echo_StopSFX
+; Stops SFX playback
+;****************************************************************************
+
+Echo_StopSFX:
+ move.w d0, -(sp) ; Save register
+ move.b #$03, d0 ; Command $03 = stop SFX
+ bsr Echo_SendCommand ; Send command to Echo
+ move.w (sp)+, d0 ; Restore register
+ rts ; End of subroutine
+
+;****************************************************************************
+; Echo_PlayBGM
+; Plays a BGM
+;
+; input a0.l ... Pointer to BGM data
+;****************************************************************************
+
+Echo_PlayBGM:
+ move.w d0, -(sp) ; Save register
+ move.b #$04, d0 ; Command $04 = play BGM
+ bsr Echo_SendCommandEx ; Send command to Echo
+ move.w (sp)+, d0 ; Restore register
+ rts ; End of subroutine
+
+;****************************************************************************
+; Echo_StopBGM
+; Stops BGM playback
+;****************************************************************************
+
+Echo_StopBGM:
+ move.w d0, -(sp) ; Save register
+ move.b #$05, d0 ; Command $05 = stop BGM
+ bsr Echo_SendCommand ; Send command to Echo
+ move.w (sp)+, d0 ; Restore register
+ rts ; End of subroutine
+
+;****************************************************************************
+; Echo_ResumeBGM
+; Resumes BGM playback
+;****************************************************************************
+
+Echo_ResumeBGM:
+ move.w d0, -(sp) ; Save register
+ move.b #$06, d0 ; Command $06 = resume BGM
+ bsr Echo_SendCommand ; Send command to Echo
+ move.w (sp)+, d0 ; Restore register
+ rts ; End of subroutine
+
+;****************************************************************************
+; Echo_GetStatus
+; Gets the current status of Echo
+;
+; output d0.w ... Echo status
+; Bit #0: SFX is playing
+; Bit #1: BGM is playing
+; Bit #15: command still not parsed
+;****************************************************************************
+
+Echo_GetStatus:
+ moveq #0, d0
+ Echo_Z80Request ; We need the Z80 bus
+ move.b ($A01FF0), d0 ; Get the status flags
+ tst.b ($A01FFF) ; Check if command still has to be parsed
+ beq.s @NotBusy ; Any commands left to be parsed?
+ bset.l #15, d0 ; If so, set the relevant flag
+@NotBusy:
+ Echo_Z80Release ; Let the Z80 go!
+ rts ; End of subroutine
+
+;****************************************************************************
+; Echo_ListEntry
+; Defines an entry in a pointer list
+;****************************************************************************
+
+Echo_ListEntry macro addr
+ dc.b $80|((addr)>>8&$7F) ; High byte of address
+ dc.b (addr)&$FF ; Low byte of address
+ dc.b ((addr)>>15&$7F)|((addr)>>16&$80) ; Bank number
+ endm
+
+;****************************************************************************
+; Echo_ListEnd
+; Ends a pointer list
+;****************************************************************************
+
+Echo_ListEnd macro
+ dc.b $00 ; End of list mark
+ even ; Just in case...
+ endm
diff --git a/src-68k/esf.68k b/src-68k/esf.68k
new file mode 100644
index 0000000..6abecd1
--- /dev/null
+++ b/src-68k/esf.68k
@@ -0,0 +1,161 @@
+;****************************************************************************
+; Channel ID constants
+;****************************************************************************
+
+ESF_FM1 equ $00 ; FM channel #1
+ESF_FM2 equ $01 ; FM channel #2
+ESF_FM3 equ $02 ; FM channel #3
+ESF_FM4 equ $04 ; FM channel #4
+ESF_FM5 equ $05 ; FM channel #5
+ESF_FM6 equ $06 ; FM channel #6
+ESF_PSG1 equ $08 ; PSG square channel #1
+ESF_PSG2 equ $09 ; PSG square channel #2
+ESF_PSG3 equ $0A ; PSG square channel #3
+ESF_PSG4 equ $0B ; PSG noise channel
+ESF_PCM equ $0C ; PCM channel
+
+;****************************************************************************
+; ESF_NoteOn
+; Start playing a note.
+;----------------------------------------------------------------------------
+; For FM channels:
+; ESF_NoteOn channel, octave, semitone
+; For square PSG channels:
+; ESF_NoteOn channel, octave, semitone
+; For noise PSG channel:
+; ESF_NoteOn channel, type
+; For PCM channel:
+; ESF_NoteOn channel, instrument
+;----------------------------------------------------------------------------
+; param channel ...... channel to play on
+; param octave ....... octave (0 to 7 for FM, 0 to 5 for PSG)
+; param semitone ..... semitone (0 to 11)
+; param type ......... noise type ($00 to $07)
+; param instrument ... drum instrument ID ($00 to $FF)
+;****************************************************************************
+
+ESF_NoteOn macro
+ dc.b $00+(\1)
+ if (\1)<ESF_PSG1
+ dc.b (\2)*32+(\3)*2+1
+ elseif (\1)<ESF_PSG4
+ dc.b (\2)*24+(\3)*2
+ else
+ dc.b \2
+ endc
+ endm
+
+;****************************************************************************
+; ESF_NoteOff
+; Stop playing a note.
+;----------------------------------------------------------------------------
+; Format:
+; ESF_NoteOff channel
+;----------------------------------------------------------------------------
+; param channel ...... channel to stop
+;****************************************************************************
+
+ESF_NoteOff macro
+ dc.b $10+(\1)
+ endm
+
+;****************************************************************************
+; ESF_SetVol
+; Set the volume of a channel.
+;----------------------------------------------------------------------------
+; Format:
+; ESF_SetVol channel, volume
+;----------------------------------------------------------------------------
+; param channel ... channel to modify
+; param volume .... new volume ($00 to $7F for FM, $00 to $0F for PSG)
+;****************************************************************************
+
+ESF_SetVol macro
+ dc.b $20+(\1)
+ dc.b (\2)
+ endm
+
+;****************************************************************************
+; ESF_SetFreq
+; Sets the frequency of a channel (allows note slides).
+;----------------------------------------------------------------------------
+; For FM channels:
+; ESF_SetFreq channel, octave, frequency
+; For square PSG channels:
+; ESF_SetFreq channel, frequency
+; For noise PSG channel:
+; ESF_SetFreq channel, type
+;----------------------------------------------------------------------------
+; param channel ..... affected channel
+; param octave ...... octave
+; param frequency ... frequency (0 to $7FF for FM, 0 to $3FF for PSG)
+; param type ........ noise type ($00 to $07)
+;****************************************************************************
+
+ESF_SetFreq macro
+ dc.b $30+(\1)
+ if (\1)<ESF_PSG1
+ dc.b ((\2)<<3)|((\3)>>8)
+ dc.b (\3)&$FF
+ elseif (\1)<ESF_PSG4
+ dc.b (\2)&$0F
+ dc.b (\2)>>6
+ else
+ dc.b (\2)
+ endc
+ endm
+
+;****************************************************************************
+; ESF_SetInstr
+; Set the instrument of a channel.
+;----------------------------------------------------------------------------
+; Format:
+; ESF_SetInstr channel, instrument
+;----------------------------------------------------------------------------
+; param channel ...... Channel to lock
+; param instrument ... Instrument ID ($00 to $FF)
+;****************************************************************************
+
+ESF_SetInstr macro
+ dc.b $40+(\1)
+ dc.b (\2)
+ endm
+
+;****************************************************************************
+; ESF_Lock
+; Lock SFX channel.
+;----------------------------------------------------------------------------
+; Format:
+; ESF_Lock channel
+;----------------------------------------------------------------------------
+; param channel ... Channel to lock
+;****************************************************************************
+
+ESF_Lock macro
+ dc.b $E0
+ dc.b (\1)
+ endm
+
+;****************************************************************************
+; ESF_Delay
+; Stop event.
+;----------------------------------------------------------------------------
+; Format:
+; ESF_Delay ticks
+;----------------------------------------------------------------------------
+; param ticks ... Ticks to wait (60 = 1 second)
+;****************************************************************************
+
+ESF_Delay macro
+ dc.b $FE
+ dc.b (\1)
+ endm
+
+;****************************************************************************
+; ESF_Stop
+; Stop event.
+;****************************************************************************
+
+ESF_Stop macro
+ dc.b $FF
+ endm