wip, draws hex
[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
1286a1ba 10.globl VBL
4db6e09f 11
12##################################################
13# #
14# Register and bitmask definitions #
15# #
16##################################################
17
18.equ GFXDATA, 0xc00000
19.equ GFXCNTL, 0xc00004
20
21.equ VDP0_E_HBI, 0x10
22.equ VDP0_E_DISPLAY, 0x02
23.equ VDP0_PLTT_FULL, 0x04
24
25.equ VDP1_SMS_MODE, 0x80
26.equ VDP1_E_DISPLAY, 0x40
27.equ VDP1_E_VBI, 0x20
28.equ VDP1_E_DMA, 0x10
29.equ VDP1_NTSC, 0x00
30.equ VDP1_PAL, 0x08
31.equ VDP1_RESERVED, 0x04
32
33.equ VDP12_SPR_SHADOWS, 0x08
34.equ VDP12_SCREEN_V224, 0x00
35.equ VDP12_SCREEN_V448, 0x04
36.equ VDP12_PROGRESSIVE, 0x00
37.equ VDP12_INTERLACED, 0x02
38.equ VDP12_SCREEN_H256, 0x00
39.equ VDP12_SCREEN_H320, 0x81
40
41.equ VDP16_MAP_V32, 0x00
42.equ VDP16_MAP_V64, 0x10
43.equ VDP16_MAP_V128, 0x30
44.equ VDP16_MAP_H32, 0x00
45.equ VDP16_MAP_H64, 0x01
46.equ VDP16_MAP_H128, 0x03
47
48
49
50##################################################
51# #
52# MACROS #
53# #
54##################################################
55
56
57/* Write val to VDP register reg */
58.macro write_vdp_reg reg val
59 move.w #((\reg << 8) + 0x8000 + \val),(a3)
60.endm
61
62
63/* For immediate addresses */
64.macro VRAM_ADDR reg adr
65 move.l #(((0x4000 + (\adr & 0x3fff)) << 16) + (\adr >> 14)),\reg
66.endm
67
68
0fc4f06b 69.macro CRAM_ADDR reg adr
70 move.l #(((0xc000 + (\adr & 0x3fff)) << 16) + (\adr >> 14)),\reg
71.endm
72
73
74# make VDP word from address adr and store in d0
75.macro XRAM_ADDR_var adr
570c4371 76 move.l \adr,d0
0fc4f06b 77 lsl.l #8,d0
78 lsl.l #8,d0
79 rol.l #2,d0
80 lsl.b #2,d0
81 lsr.l #2,d0
4db6e09f 82.endm
83
84
0fc4f06b 85.macro VRAM_ADDR_var adr
86 XRAM_ADDR_var \adr
87 or.l #0x40000000,d0
4db6e09f 88.endm
89
90
0fc4f06b 91.macro CRAM_ADDR_var adr
92 XRAM_ADDR_var \adr
93 or.l #0xc0000000,d0
4db6e09f 94.endm
95
96
97.macro VSCROLL_ADDR reg adr
98 move.l #(((0x4000 + (\adr & 0x3fff)) << 16) + ((\adr >> 14) | 0x10)),\reg
99.endm
100
101
102.macro HSCROLL_ADDR reg adr
103 move.l #(((0x4000 + (\adr & 0x3fff)) << 16) + (\adr >> 14)),\reg
104.endm
105
106
1286a1ba 107# convert tile coords in d0, d1 to nametable addr to a0
108.macro XY2NT
109 lsl.w #6,d1
110 add.w d1,d0
111 lsl.w #1,d0
112 movea.l #0xe000,a0
113 add.w d0,a0
114.endm
115
4db6e09f 116#################################################
117# #
118# DATA #
119# #
120#################################################
121
122colors:
570c4371 123 dc.w 0x0000,0x0eee
124colors_end:
125
126# pattern:
4db6e09f 127
128
129sprite_data:
130 /* Y size link attr X */
570c4371 131 dc.w 0; dc.b 0x05; dc.b 0; dc.w 0x6002; dc.w 0
4db6e09f 132sprite_data_end:
133
570c4371 134hello:
135 .ascii "hello world"
4db6e09f 136
137##################################################
138# #
139# MAIN PROGRAM #
140# #
141##################################################
142
570c4371 143.align 2
144
4db6e09f 145main:
1286a1ba 146 /* mask irqs durinf init */
147 move.w #0x2700,sr
148
149 movea.l #0,a6
150
151 /* Init pads */
152 move.b #0x40,(0xa10009).l
153 move.b #0x40,(0xa10003).l
154
4db6e09f 155 /* Initialize VDP */
156 jsr init_gfx
157
158 /* Load color data */
0fc4f06b 159 movea.l #0,a0
160 movea.l #colors,a1
161 moveq.l #(colors_end-colors)/2,d0
4db6e09f 162 jsr load_colors
163
164 /* load patterns */
0fc4f06b 165 movea.l #0,a0
166 movea.l #font,a1
167 move.l #128,d0
4db6e09f 168 jsr load_tiles
169
170 /* generate A layer map */
1286a1ba 171 movea.l #0xe000,a1
4db6e09f 172 move.l #28-1,d4
173lmaploop0:
1286a1ba 174 movea.l a1,a0
4db6e09f 175 jsr load_prepare
176
570c4371 177 move.l #64/2-1,d3
0fc4f06b 1780: move.l #0x00000000,(a0)
4db6e09f 179 dbra d3,0b
180
1286a1ba 181 add.l #64*2,a1
4db6e09f 182 dbra d4,lmaploop0
183
184 /* generate B layer map */
0fc4f06b 185 movea.l #0xc000,a0
4db6e09f 186 jsr load_prepare
187
570c4371 188 move.l #64*28/2-1,d3
0fc4f06b 1890: move.l #0x00000000,(a0)
4db6e09f 190 dbra d3,0b
191
192 /* upload sprite data */
0fc4f06b 193 movea.l #0xfc00,a0
4db6e09f 194 jsr load_prepare
0fc4f06b 195 movea.l #sprite_data,a1
4db6e09f 196
197 move.l #(sprite_data_end-sprite_data)/2-1,d3
0fc4f06b 1980: move.l (a1)+,(a0)
4db6e09f 199 dbra d3,0b
200
1286a1ba 201 move.w #0x2000,sr
570c4371 202
4db6e09f 203##################################################
204# #
205# MAIN LOOP #
206# #
207##################################################
208
1286a1ba 209# global regs:
210# a6 - page[31:8],cursor_offs[7:0]
211
4db6e09f 212forever:
4db6e09f 213
4db6e09f 214
215 jsr wait_vsync
216 bra forever
217
218
219
1286a1ba 220VBL:
221 addq.l #1,(vtimer).l
222 movem.l d0-d7/a0-a5,-(a7)
223
224 /* draw main stuff */
225 clr.l d7
226 move.l a6,d0
227 lsr.l #8,d0
228 move.l d0,a1 /* current addr */
229
230 movea.l #0xe004,a2
231 move.l #27-1,d5
232
233draw_column:
234 move.l a2,a0
235 jsr load_prepare
236
237 /* addr */
238 move.l a1,d2
239 moveq.l #6,d3
240 jsr print_hex_preped
241
242 /* 4 shorts */
243 moveq.l #4-1,d4
244draw_shorts:
245 move.w #' ',(a0)
246 move.w (a1)+,d2
247 moveq.l #4,d3
248 jsr print_hex_preped
249 dbra d4,draw_shorts
250
251 move.w #' ',(a0)
252 move.w #' ',(a0)
253
254 /* 8 chars */
255 subq.l #8,a1
256 moveq.l #8-1,d4
257draw_chars:
258 move.b (a1)+,d0
259 move.b d0,d1
260 sub.b #0x20,d1
261 cmp.b #0x60,d1
262 blo 0f
263 move.w #'.',d0
2640:
265 move.w d0,(a0)
266 dbra d4,draw_chars
267
268 add.w #0x80,a2
269 dbra d5,draw_column
270
271 /* handle input */
272 jsr get_input /* x0cbrldu x1sa00du */
273 btst.b #0,d0
274 beq _in_nup
275 sub.l #0x0800,a6
276
277_in_nup:
278 btst.b #1,d0
279 beq _in_ndn
280 add.l #0x0800,a6
281
282_in_ndn:
283 btst.l #10,d0
284 beq _in_nleft
285 sub.l #0xd800,a6
286
287_in_nleft:
288 btst.b #11,d0
289 beq _in_nright
290 add.l #0xd800,a6
291
292_in_nright:
293
294end:
295 movem.l (a7)+,d0-d7/a0-a5
296 rte
297
298
4db6e09f 299#################################################
300# #
301# Initialize VDP registers #
302# #
303#################################################
304
305init_gfx:
306 move.l #GFXCNTL,a3
570c4371 307 write_vdp_reg 0,(VDP0_E_DISPLAY | VDP0_PLTT_FULL)
308 write_vdp_reg 1,(VDP1_E_VBI | VDP1_E_DISPLAY | VDP1_E_DMA | VDP1_RESERVED)
4db6e09f 309 write_vdp_reg 2,(0xe000 >> 10) /* Screen map a adress */
310 write_vdp_reg 3,(0xe000 >> 10) /* Window address */
311 write_vdp_reg 4,(0xc000 >> 13) /* Screen map b address */
312 write_vdp_reg 5,(0xfc00 >> 9) /* Sprite address */
313 write_vdp_reg 6,0
570c4371 314 write_vdp_reg 7,0 /* Backdrop color */
4db6e09f 315 write_vdp_reg 10,1 /* Lines per hblank interrupt */
316 write_vdp_reg 11,0 /* 2-cell vertical scrolling */
570c4371 317 write_vdp_reg 12,(VDP12_SCREEN_V224 | VDP12_SCREEN_H320)
318 write_vdp_reg 13,(0x8000 >> 10) /* Horizontal scroll address */
4db6e09f 319 write_vdp_reg 15,2
570c4371 320 write_vdp_reg 16,(VDP16_MAP_V32 | VDP16_MAP_H64) /* layer size */
4db6e09f 321 write_vdp_reg 17,0
322 write_vdp_reg 18,0xff
323 rts
324
325
1286a1ba 326# read single phase from controller
327# a0 - addr
328# d0 - result
329get_input:
330 move.b #0x40,(0xa10003)
331 nop
332 nop
333 nop
334 move.b (0xa10003),d0
335 move.b #0x00,(0xa10003)
336 lsl.w #8,d0
337 nop
338 move.b (0xa10003),d0
339 eor.w #0xffff,d0
340# move.b #0x40,(0xa10003)
341 rts
342
0fc4f06b 343# Load tile data from ROM
344# a0: VRAM base
345# a1: pattern address
346# d0: number of tiles to load
347# destroys d1
4db6e09f 348
349load_tiles:
0fc4f06b 350 move.l d0,d1
351 VRAM_ADDR_var a0
352 move.l d0,(GFXCNTL).l
4db6e09f 353
0fc4f06b 354 move.l #GFXDATA,a0
355 lsl.w #3,d1
356 subq.l #1,d1
3570:
358 move.l (a1)+,(a0)
359 dbra d1,0b
4db6e09f 360
361 rts
362
363
570c4371 364# Prepare to write to VDP RAM @a3
0fc4f06b 365# sets a0 to VDP data port for convenience
366# a0: VRAM base
367# destroys d0
570c4371 368
4db6e09f 369load_prepare:
0fc4f06b 370 VRAM_ADDR_var a0
371 move.l d0,(GFXCNTL).l
372 move.l #GFXDATA,a0
4db6e09f 373 rts
374
375
0fc4f06b 376# Load color data from ROM
377# a0: CRAM base
378# a1: color list address
379# d0: number of colors to load
380# destroys d1
4db6e09f 381
382load_colors:
0fc4f06b 383 move.l d0,d1
384 CRAM_ADDR_var a0
385 move.l d0,(GFXCNTL).l
4db6e09f 386
0fc4f06b 387 move.l #GFXDATA,a0
388 subq.w #1,d1
3890:
390 move.w (a1)+,(a0)
391 dbra d1,0b
4db6e09f 392
393 rts
394
0fc4f06b 395
396# print
397# a0 - string
398# d0 - x
399# d1 - y
400# destroys a1
570c4371 401
402print:
0fc4f06b 403 move.l a0,a1
1286a1ba 404 XY2NT
0fc4f06b 405 jsr load_prepare
406 moveq.l #0,d0
570c4371 407
408_print_loop:
0fc4f06b 409 move.b (a1)+,d0
570c4371 410 beq _print_end
411
0fc4f06b 412 move.w d0,(a0)
570c4371 413 jmp _print_loop
414
415_print_end:
416 rts
417
4db6e09f 418
1286a1ba 419# print_hex
420# d0 - x
421# d1 - y
422# d2 - value
423# d3 - digit cnt
424# destroys a0
425
426print_hex:
427 XY2NT
428 jsr load_prepare
429
430print_hex_preped:
431 move.l d3,d0
432 lsl.b #2,d0
433 ror.l d0,d2 /* prep value */
434 moveq.l #0,d0
435 subq.l #1,d3 /* count */
436
437_print_hex_loop:
438 rol.l #4,d2
439 move.b d2,d0
440 and.b #0xf,d0
441 cmp.b #0xa,d0
442 bge 1f
443
444 add.b #'0',d0
445 jmp 2f
4461:
447 add.b #0x37,d0
4482:
449 move.w d0,(a0)
450 dbra d3,_print_hex_loop
451
452 rts
453
454
4db6e09f 455#################################################
456# #
457# Wait for next VBlank interrupt #
458# #
459#################################################
460
461wait_vsync:
462 movea.l #vtimer,a0
463 move.l (a0),a1
464_wait_change:
465 stop #0x2000
466 cmp.l (a0),a1
467 beq _wait_change
468 rts
469
470
471#################################################
472# #
473# RAM DATA #
474# #
475#################################################
476
477.bss
570c4371 478
479# used by sega_gcc.s
4db6e09f 480.globl htimer
481.globl vtimer
482.globl rand_num
483htimer: .long 0
484vtimer: .long 0
485rand_num: .long 0
570c4371 486
487#
4db6e09f 488
489.end
490
491# vim:filetype=asmM68k