This repository has been archived by the owner on Jan 5, 2025. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathMacros.asm
204 lines (169 loc) · 6.89 KB
/
Macros.asm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
; ---------------------------------------------------------------------------
; Set a VRAM address via the VDP control port.
; input: 16-bit VRAM address, control port (default is ($C00004).l)
; ---------------------------------------------------------------------------
locVRAM: macro loc,controlport
if ("controlport"=="")
move.l #($40000000+(((loc)&$3FFF)<<16)+(((loc)&$C000)>>14)),(vdp_control_port).l
else
move.l #($40000000+(((loc)&$3FFF)<<16)+(((loc)&$C000)>>14)),controlport
endif
endm
; ---------------------------------------------------------------------------
; DMA copy data from 68K (ROM/RAM) to the VRAM
; input: source, length, destination
; ---------------------------------------------------------------------------
writeVRAM: macro source,destination
lea (vdp_control_port).l,a5
move.l #$94000000+((((source_end-source)>>1)&$FF00)<<8)+$9300+(((source_end-source)>>1)&$FF),(a5)
move.l #$96000000+(((source>>1)&$FF00)<<8)+$9500+((source>>1)&$FF),(a5)
move.w #$9700+((((source>>1)&$FF0000)>>16)&$7F),(a5)
move.w #$4000+((destination)&$3FFF),(a5)
move.w #$80+(((destination)&$C000)>>14),(v_vdp_buffer2).w
move.w (v_vdp_buffer2).w,(a5)
endm
; ---------------------------------------------------------------------------
; DMA copy data from 68K (ROM/RAM) to the CRAM
; input: source, length, destination
; ---------------------------------------------------------------------------
writeCRAM: macro source,destination
lea (vdp_control_port).l,a5
move.l #$94000000+((((source_end-source)>>1)&$FF00)<<8)+$9300+(((source_end-source)>>1)&$FF),(a5)
move.l #$96000000+(((source>>1)&$FF00)<<8)+$9500+((source>>1)&$FF),(a5)
move.w #$9700+((((source>>1)&$FF0000)>>16)&$7F),(a5)
move.w #$C000+(destination&$3FFF),(a5)
move.w #$80+((destination&$C000)>>14),(v_vdp_buffer2).w
move.w (v_vdp_buffer2).w,(a5)
endm
; ---------------------------------------------------------------------------
; DMA fill VRAM with a value
; input: value, length, destination
; ---------------------------------------------------------------------------
fillVRAM: macro byte,start,end
lea (vdp_control_port).l,a5
move.w #$8F01,(a5) ; Set increment to 1, since DMA fill writes bytes
move.l #$94000000+((((end)-(start)-1)&$FF00)<<8)+$9300+(((end)-(start)-1)&$FF),(a5)
move.w #$9780,(a5)
move.l #$40000080+(((start)&$3FFF)<<16)+(((start)&$C000)>>14),(a5)
move.w #(byte)|(byte)<<8,(vdp_data_port).l
.wait: move.w (a5),d1
btst #1,d1
bne.s .wait
move.w #$8F02,(a5) ; Set increment back to 2, since the VDP usually operates on words
endm
; ---------------------------------------------------------------------------
; Fill portion of RAM with 0
; input: start, end
; ---------------------------------------------------------------------------
clearRAM: macro startAddress,endAddress
if "endAddress"<>""
.length := (endAddress)-(startAddress)
else
.length := startAddress_end-startAddress
endif
lea (startAddress).w,a1
moveq #0,d0
move.w #.length/4-1,d1
.loop:
move.l d0,(a1)+
dbf d1,.loop
if (endAddress-startAddress)&2
move.w d0,(a1)+
endif
if (endAddress-startAddress)&1
move.b d0,(a1)+
endif
endm
; ---------------------------------------------------------------------------
; Copy a tilemap from 68K (ROM/RAM) to the VRAM without using DMA
; input: source, destination, width [cells], height [cells]
; ---------------------------------------------------------------------------
copyTilemap: macro source,destination,width,height
lea (source).l,a1
locVRAM destination,d0
moveq #width,d1
moveq #height,d2
bsr.w TilemapToVRAM
endm
copyUncTilemap: macro destination,width,height
move.l #$40000000+((destination&$3FFF)<<16)+((destination&$C000)>>14),d0
moveq #width,d1
moveq #height,d2
bsr.w TilemapToVRAM
endm
; calculates initial loop counter value for a dbf loop
; that writes n bytes total at 4 bytes per iteration
bytesToLcnt function n,n>>2-1
; calculates initial loop counter value for a dbf loop
; that writes n bytes total at 2 bytes per iteration
bytesToWcnt function n,n>>1-1
; calculates initial loop counter value for a dbf loop
; that writes n bytes total at x bytes per iteration
bytesToXcnt function n,x,n/x-1
; ---------------------------------------------------------------------------
; start the Z80
; ---------------------------------------------------------------------------
startZ80: macro
move.w #0,(z80_bus_request).l
endm
; ---------------------------------------------------------------------------
; stop the Z80
; ---------------------------------------------------------------------------
stopZ80: macro
move.w #$100,(z80_bus_request).l
endm
; ---------------------------------------------------------------------------
; wait for Z80 to stop
; ---------------------------------------------------------------------------
waitZ80: macro
.wait: btst #0,(z80_bus_request).l
bne.s .wait
endm
; ---------------------------------------------------------------------------
; reset the Z80
; ---------------------------------------------------------------------------
resetZ80: macro
move.w #$100,(z80_reset).l
endm
resetZ80a: macro
move.w #0,(z80_reset).l
endm
; ---------------------------------------------------------------------------
; disable interrupts
; ---------------------------------------------------------------------------
disable_ints: macro
move #$2700,sr
endm
; ---------------------------------------------------------------------------
; enable interrupts
; ---------------------------------------------------------------------------
enable_ints: macro
move #$2300,sr
endm
; ---------------------------------------------------------------------------
; check if object moves out of range
; input: location to jump to if out of range, x-axis pos (obX(a0) by default)
; ---------------------------------------------------------------------------
out_of_range: macro exit,pos
if ("pos"<>"")
move.w pos,d0 ; get object position (if specified as not obX)
else
move.w obX(a0),d0 ; get object position
endif
andi.w #-$80,d0 ; round down to nearest $80
move.w (v_screenposx).w,d1 ; get screen position
subi.w #128,d1
andi.w #-$80,d1
sub.w d1,d0 ; approx distance between object and screen
cmpi.w #128+320+192,d0
bhi.ATTRIBUTE exit
endm
; ---------------------------------------------------------------------------
; produce a packed art-tile
; ---------------------------------------------------------------------------
make_art_tile function addr,pal,pri,((pri&1)<<15)|((pal&3)<<13)|addr
; ---------------------------------------------------------------------------
; turn a sample rate into a djnz loop counter
; ---------------------------------------------------------------------------
pcmLoopCounter function sampleRate,baseCycles, 1+(53693175/15/(sampleRate)-(baseCycles)+(13/2))/13
dpcmLoopCounter function sampleRate, pcmLoopCounter(sampleRate,425/2) ; 425 is the number of cycles zPlayPCMLoop takes.