cleanup and vbl a0 corruption fix
[megadrive.git] / hexed / hexed.s
CommitLineData
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
112colors:
570c4371 113 dc.w 0x0000,0x0eee
114colors_end:
115
116# pattern:
4db6e09f 117
118
119sprite_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 122sprite_data_end:
123
570c4371 124hello:
125 .ascii "hello world"
4db6e09f 126
127##################################################
128# #
129# MAIN PROGRAM #
130# #
131##################################################
132
570c4371 133.align 2
134
4db6e09f 135main:
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
154lmaploop0:
0fc4f06b 155 movea.l a6,a0
4db6e09f 156 jsr load_prepare
157
570c4371 158 move.l #64/2-1,d3
0fc4f06b 1590: 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 1700: 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 1790: 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
195forever:
4db6e09f 196
4db6e09f 197
198 jsr wait_vsync
199 bra forever
200
201
202
203#################################################
204# #
205# Initialize VDP registers #
206# #
207#################################################
208
209init_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
236load_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
2440:
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 256load_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
269load_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
2760:
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
289print:
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
316wait_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
338htimer: .long 0
339vtimer: .long 0
340rand_num: .long 0
570c4371 341
342#
4db6e09f 343
344.end
345
346# vim:filetype=asmM68k