; >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; This is free software: you can redistribute it and/or modify
; it under the terms of the GNU General Public License as published by
; the Free Software Foundation, either version 3 of the License, or
; (at your option) any later version.
;
; This software is distributed in the hope that it will be useful,
; but WITHOUT ANY WARRANTY; without even the implied warranty of
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
; GNU General Public License for more details.
;
; You should have received a copy of the GNU General Public License
; along with Foobar. If not, see .
; >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; simplifying macros and functions
; ===========================================================================
; define the even pseudo-instruction
even macro
if (*)&1
dc.b 0 ;ds.b 1
endif
endm
; ===========================================================================
; makes a VDP address difference
vdpCommDelta function addr,((addr&$3FFF)<<16)|((addr&$C000)>>14)
; ---------------------------------------------------------------------------
; makes a VDP command
vdpComm function addr,type,rwd,(((type&rwd)&3)<<30)|((addr&$3FFF)<<16)|(((type&rwd)&$FC)<<2)|((addr&$C000)>>14)
; ---------------------------------------------------------------------------
; values for the type argument
VRAM = %100001
CRAM = %101011
VSRAM = %100101
; ---------------------------------------------------------------------------
; values for the rwd argument
READ = %001100
WRITE = %000111
DMA = %100111
; ---------------------------------------------------------------------------
; Like vdpComm, but starting from an address contained in a register
vdpCommReg macro reg,type,rwd,clr
lsl.l #2,reg ; Move high bits into (word-swapped) position, accidentally moving everything else
if ((type&rwd)&3)<>0
addq.w #((type&rwd)&3),reg ; Add upper access type bits
endif
ror.w #2,reg ; Put upper access type bits into place, also moving all other bits into their correct (word-swapped) places
swap reg ; Put all bits in proper places
if clr <> 0
andi.w #3,reg ; Strip whatever junk was in upper word of reg
endif
if ((type&rwd)&$FC)==$20
tas.b reg ; Add in the DMA flag -- tas fails on memory, but works on registers
elseif ((type&rwd)&$FC)<>0
ori.w #(((type&rwd)&$FC)<<2),reg ; Add in missing access type bits
endif
endm
; ---------------------------------------------------------------------------
; tells the VDP to copy a region of 68k memory to VRAM or CRAM or VSRAM
dma68kToVDP macro source,dest,length,type
lea (VDP_control_port).l,a5
move.l #(($9400|((((length)>>1)&$FF00)>>8))<<16)|($9300|(((length)>>1)&$FF)),(a5)
move.l #(($9600|((((source)>>1)&$FF00)>>8))<<16)|($9500|(((source)>>1)&$FF)),(a5)
move.w #$9700|(((((source)>>1)&$FF0000)>>16)&$7F),(a5)
move.w #((vdpComm(dest,type,DMA)>>16)&$FFFF),(a5)
move.w #(vdpComm(dest,type,DMA)&$FFFF),(DMA_data_thunk).w
move.w (DMA_data_thunk).w,(a5)
endm
; ---------------------------------------------------------------------------
; tells the VDP to fill a region of VRAM with a certain byte
dmaFillVRAM macro byte,addr,length
lea (VDP_control_port).l,a5
move.w #$8F01,(a5) ; VRAM pointer increment: $0001
move.l #(($9400|((((length)-1)&$FF00)>>8))<<16)|($9300|(((length)-1)&$FF)),(a5) ; DMA length ...
move.w #$9780,(a5) ; VRAM fill
move.l #$40000080|(((addr)&$3FFF)<<16)|(((addr)&$C000)>>14),(a5) ; Start at ...
move.w #(byte)<<8,(VDP_data_port).l ; Fill with byte
.loop:
move.w (a5),d1
btst #1,d1
bne.s .loop ; busy loop until the VDP is finished filling...
move.w #$8F02,(a5) ; VRAM pointer increment: $0002
endm
; ===========================================================================
; calculates initial loop counter value for a dbra loop
; that writes n bytes total at 4 bytes per iteration
bytesToLcnt function n,n>>2-1
; ---------------------------------------------------------------------------
; calculates initial loop counter value for a dbra loop
; that writes n bytes total at 2 bytes per iteration
bytesToWcnt function n,n>>1-1
; ===========================================================================
; Definition of RAM constants that can work in both 16- and 32-bit
; address modes.
ramaddr function x,-(-x)&$FFFFFFFF
; ===========================================================================
enableInts macro
move #$2300,sr
endm
; ---------------------------------------------------------------------------
disableInts macro
move #$2700,sr
endm
; ===========================================================================
signmask function val,nBits,-(-(val&$80))&(1<<(nBits-1))
signextend function val,nBits,(val+signmask(val,nBits))!signmask(val,nBits)
bit2mask function bit,signextend(1<