4db6e09f |
1 | ################################################## |
2 | # # |
3 | # Assemble with gas # |
4 | # --register-prefix-optional --bitwise-or # |
5 | # # |
6 | ################################################## |
7 | |
8 | .text |
9 | .globl main |
10 | |
11 | ################################################## |
12 | # # |
13 | # Register and bitmask definitions # |
14 | # # |
15 | ################################################## |
16 | |
17 | .equ GFXDATA, 0xc00000 |
18 | .equ GFXCNTL, 0xc00004 |
19 | |
20 | .equ VDP0_E_HBI, 0x10 |
21 | .equ VDP0_E_DISPLAY, 0x02 |
22 | .equ VDP0_PLTT_FULL, 0x04 |
23 | |
24 | .equ VDP1_SMS_MODE, 0x80 |
25 | .equ VDP1_E_DISPLAY, 0x40 |
26 | .equ VDP1_E_VBI, 0x20 |
27 | .equ VDP1_E_DMA, 0x10 |
28 | .equ VDP1_NTSC, 0x00 |
29 | .equ VDP1_PAL, 0x08 |
30 | .equ VDP1_RESERVED, 0x04 |
31 | |
32 | .equ VDP12_SPR_SHADOWS, 0x08 |
33 | .equ VDP12_SCREEN_V224, 0x00 |
34 | .equ VDP12_SCREEN_V448, 0x04 |
35 | .equ VDP12_PROGRESSIVE, 0x00 |
36 | .equ VDP12_INTERLACED, 0x02 |
37 | .equ VDP12_SCREEN_H256, 0x00 |
38 | .equ VDP12_SCREEN_H320, 0x81 |
39 | |
40 | .equ VDP16_MAP_V32, 0x00 |
41 | .equ VDP16_MAP_V64, 0x10 |
42 | .equ VDP16_MAP_V128, 0x30 |
43 | .equ VDP16_MAP_H32, 0x00 |
44 | .equ VDP16_MAP_H64, 0x01 |
45 | .equ VDP16_MAP_H128, 0x03 |
46 | |
47 | |
48 | |
49 | ################################################## |
50 | # # |
51 | # MACROS # |
52 | # # |
53 | ################################################## |
54 | |
55 | |
56 | /* Write val to VDP register reg */ |
57 | .macro write_vdp_reg reg val |
58 | move.w #((\reg << 8) + 0x8000 + \val),(a3) |
59 | .endm |
60 | |
61 | |
62 | /* For immediate addresses */ |
63 | .macro VRAM_ADDR reg adr |
64 | move.l #(((0x4000 + (\adr & 0x3fff)) << 16) + (\adr >> 14)),\reg |
65 | .endm |
66 | |
67 | |
0fc4f06b |
68 | .macro CRAM_ADDR reg adr |
69 | move.l #(((0xc000 + (\adr & 0x3fff)) << 16) + (\adr >> 14)),\reg |
70 | .endm |
71 | |
72 | |
73 | # make VDP word from address adr and store in d0 |
74 | .macro XRAM_ADDR_var adr |
570c4371 |
75 | move.l \adr,d0 |
0fc4f06b |
76 | lsl.l #8,d0 |
77 | lsl.l #8,d0 |
78 | rol.l #2,d0 |
79 | lsl.b #2,d0 |
80 | lsr.l #2,d0 |
4db6e09f |
81 | .endm |
82 | |
83 | |
0fc4f06b |
84 | .macro VRAM_ADDR_var adr |
85 | XRAM_ADDR_var \adr |
86 | or.l #0x40000000,d0 |
4db6e09f |
87 | .endm |
88 | |
89 | |
0fc4f06b |
90 | .macro CRAM_ADDR_var adr |
91 | XRAM_ADDR_var \adr |
92 | or.l #0xc0000000,d0 |
4db6e09f |
93 | .endm |
94 | |
95 | |
96 | .macro VSCROLL_ADDR reg adr |
97 | move.l #(((0x4000 + (\adr & 0x3fff)) << 16) + ((\adr >> 14) | 0x10)),\reg |
98 | .endm |
99 | |
100 | |
101 | .macro HSCROLL_ADDR reg adr |
102 | move.l #(((0x4000 + (\adr & 0x3fff)) << 16) + (\adr >> 14)),\reg |
103 | .endm |
104 | |
105 | |
106 | ################################################# |
107 | # # |
108 | # DATA # |
109 | # # |
110 | ################################################# |
111 | |
112 | colors: |
570c4371 |
113 | dc.w 0x0000,0x0eee |
114 | colors_end: |
115 | |
116 | # pattern: |
4db6e09f |
117 | |
118 | |
119 | sprite_data: |
120 | /* Y size link attr X */ |
570c4371 |
121 | dc.w 0; dc.b 0x05; dc.b 0; dc.w 0x6002; dc.w 0 |
4db6e09f |
122 | sprite_data_end: |
123 | |
570c4371 |
124 | hello: |
125 | .ascii "hello world" |
4db6e09f |
126 | |
127 | ################################################## |
128 | # # |
129 | # MAIN PROGRAM # |
130 | # # |
131 | ################################################## |
132 | |
570c4371 |
133 | .align 2 |
134 | |
4db6e09f |
135 | main: |
136 | /* Initialize VDP */ |
137 | jsr init_gfx |
138 | |
139 | /* Load color data */ |
0fc4f06b |
140 | movea.l #0,a0 |
141 | movea.l #colors,a1 |
142 | moveq.l #(colors_end-colors)/2,d0 |
4db6e09f |
143 | jsr load_colors |
144 | |
145 | /* load patterns */ |
0fc4f06b |
146 | movea.l #0,a0 |
147 | movea.l #font,a1 |
148 | move.l #128,d0 |
4db6e09f |
149 | jsr load_tiles |
150 | |
151 | /* generate A layer map */ |
570c4371 |
152 | movea.l #0xe000,a6 |
4db6e09f |
153 | move.l #28-1,d4 |
154 | lmaploop0: |
0fc4f06b |
155 | movea.l a6,a0 |
4db6e09f |
156 | jsr load_prepare |
157 | |
570c4371 |
158 | move.l #64/2-1,d3 |
0fc4f06b |
159 | 0: move.l #0x00000000,(a0) |
4db6e09f |
160 | dbra d3,0b |
161 | |
162 | add.l #64*2,a6 |
163 | dbra d4,lmaploop0 |
164 | |
165 | /* generate B layer map */ |
0fc4f06b |
166 | movea.l #0xc000,a0 |
4db6e09f |
167 | jsr load_prepare |
168 | |
570c4371 |
169 | move.l #64*28/2-1,d3 |
0fc4f06b |
170 | 0: move.l #0x00000000,(a0) |
4db6e09f |
171 | dbra d3,0b |
172 | |
173 | /* upload sprite data */ |
0fc4f06b |
174 | movea.l #0xfc00,a0 |
4db6e09f |
175 | jsr load_prepare |
0fc4f06b |
176 | movea.l #sprite_data,a1 |
4db6e09f |
177 | |
178 | move.l #(sprite_data_end-sprite_data)/2-1,d3 |
0fc4f06b |
179 | 0: move.l (a1)+,(a0) |
4db6e09f |
180 | dbra d3,0b |
181 | |
182 | jsr wait_vsync |
183 | |
570c4371 |
184 | movea.l #hello,a0 |
185 | moveq.l #1,d0 |
186 | moveq.l #1,d1 |
187 | jsr print |
188 | |
4db6e09f |
189 | ################################################## |
190 | # # |
191 | # MAIN LOOP # |
192 | # # |
193 | ################################################## |
194 | |
195 | forever: |
4db6e09f |
196 | |
4db6e09f |
197 | |
198 | jsr wait_vsync |
199 | bra forever |
200 | |
201 | |
202 | |
203 | ################################################# |
204 | # # |
205 | # Initialize VDP registers # |
206 | # # |
207 | ################################################# |
208 | |
209 | init_gfx: |
210 | move.l #GFXCNTL,a3 |
570c4371 |
211 | write_vdp_reg 0,(VDP0_E_DISPLAY | VDP0_PLTT_FULL) |
212 | write_vdp_reg 1,(VDP1_E_VBI | VDP1_E_DISPLAY | VDP1_E_DMA | VDP1_RESERVED) |
4db6e09f |
213 | write_vdp_reg 2,(0xe000 >> 10) /* Screen map a adress */ |
214 | write_vdp_reg 3,(0xe000 >> 10) /* Window address */ |
215 | write_vdp_reg 4,(0xc000 >> 13) /* Screen map b address */ |
216 | write_vdp_reg 5,(0xfc00 >> 9) /* Sprite address */ |
217 | write_vdp_reg 6,0 |
570c4371 |
218 | write_vdp_reg 7,0 /* Backdrop color */ |
4db6e09f |
219 | write_vdp_reg 10,1 /* Lines per hblank interrupt */ |
220 | write_vdp_reg 11,0 /* 2-cell vertical scrolling */ |
570c4371 |
221 | write_vdp_reg 12,(VDP12_SCREEN_V224 | VDP12_SCREEN_H320) |
222 | write_vdp_reg 13,(0x8000 >> 10) /* Horizontal scroll address */ |
4db6e09f |
223 | write_vdp_reg 15,2 |
570c4371 |
224 | write_vdp_reg 16,(VDP16_MAP_V32 | VDP16_MAP_H64) /* layer size */ |
4db6e09f |
225 | write_vdp_reg 17,0 |
226 | write_vdp_reg 18,0xff |
227 | rts |
228 | |
229 | |
0fc4f06b |
230 | # Load tile data from ROM |
231 | # a0: VRAM base |
232 | # a1: pattern address |
233 | # d0: number of tiles to load |
234 | # destroys d1 |
4db6e09f |
235 | |
236 | load_tiles: |
0fc4f06b |
237 | move.l d0,d1 |
238 | VRAM_ADDR_var a0 |
239 | move.l d0,(GFXCNTL).l |
4db6e09f |
240 | |
0fc4f06b |
241 | move.l #GFXDATA,a0 |
242 | lsl.w #3,d1 |
243 | subq.l #1,d1 |
244 | 0: |
245 | move.l (a1)+,(a0) |
246 | dbra d1,0b |
4db6e09f |
247 | |
248 | rts |
249 | |
250 | |
570c4371 |
251 | # Prepare to write to VDP RAM @a3 |
0fc4f06b |
252 | # sets a0 to VDP data port for convenience |
253 | # a0: VRAM base |
254 | # destroys d0 |
570c4371 |
255 | |
4db6e09f |
256 | load_prepare: |
0fc4f06b |
257 | VRAM_ADDR_var a0 |
258 | move.l d0,(GFXCNTL).l |
259 | move.l #GFXDATA,a0 |
4db6e09f |
260 | rts |
261 | |
262 | |
0fc4f06b |
263 | # Load color data from ROM |
264 | # a0: CRAM base |
265 | # a1: color list address |
266 | # d0: number of colors to load |
267 | # destroys d1 |
4db6e09f |
268 | |
269 | load_colors: |
0fc4f06b |
270 | move.l d0,d1 |
271 | CRAM_ADDR_var a0 |
272 | move.l d0,(GFXCNTL).l |
4db6e09f |
273 | |
0fc4f06b |
274 | move.l #GFXDATA,a0 |
275 | subq.w #1,d1 |
276 | 0: |
277 | move.w (a1)+,(a0) |
278 | dbra d1,0b |
4db6e09f |
279 | |
280 | rts |
281 | |
0fc4f06b |
282 | |
283 | # print |
284 | # a0 - string |
285 | # d0 - x |
286 | # d1 - y |
287 | # destroys a1 |
570c4371 |
288 | |
289 | print: |
0fc4f06b |
290 | move.l a0,a1 |
570c4371 |
291 | lsl.w #6,d1 |
292 | add.w d1,d0 |
570c4371 |
293 | lsl.w #1,d0 |
0fc4f06b |
294 | movea.l #0xe000,a0 |
295 | add.w d0,a0 |
296 | jsr load_prepare |
297 | moveq.l #0,d0 |
570c4371 |
298 | |
299 | _print_loop: |
0fc4f06b |
300 | move.b (a1)+,d0 |
570c4371 |
301 | beq _print_end |
302 | |
0fc4f06b |
303 | move.w d0,(a0) |
570c4371 |
304 | jmp _print_loop |
305 | |
306 | _print_end: |
307 | rts |
308 | |
4db6e09f |
309 | |
310 | ################################################# |
311 | # # |
312 | # Wait for next VBlank interrupt # |
313 | # # |
314 | ################################################# |
315 | |
316 | wait_vsync: |
317 | movea.l #vtimer,a0 |
318 | move.l (a0),a1 |
319 | _wait_change: |
320 | stop #0x2000 |
321 | cmp.l (a0),a1 |
322 | beq _wait_change |
323 | rts |
324 | |
325 | |
326 | ################################################# |
327 | # # |
328 | # RAM DATA # |
329 | # # |
330 | ################################################# |
331 | |
332 | .bss |
570c4371 |
333 | |
334 | # used by sega_gcc.s |
4db6e09f |
335 | .globl htimer |
336 | .globl vtimer |
337 | .globl rand_num |
338 | htimer: .long 0 |
339 | vtimer: .long 0 |
340 | rand_num: .long 0 |
570c4371 |
341 | |
342 | # |
4db6e09f |
343 | |
344 | .end |
345 | |
346 | # vim:filetype=asmM68k |