wip
[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
4276cd7a 116# check if some d-pad button (and modifier) is pressed
117.macro do_dpad bit op opq val modval
118 btst.b #\bit,d0
119 beq 1f
120 btst.b #4,d0 /* A pressed? */
121 bne 0f
122 \opq.l #\val,a6
123 bra input_end
1240:
125 \op.l #\modval,a6
126 bra input_end
1271:
128.endm
129
4db6e09f 130#################################################
131# #
132# DATA #
133# #
134#################################################
135
136colors:
4276cd7a 137 dc.w 0x0000,0x0eee,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000
138 dc.w 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000
139 dc.w 0x0000,0x02e2,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000
140 dc.w 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000
141 dc.w 0x0000,0x0e44,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000
142 dc.w 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000
570c4371 143colors_end:
144
4db6e09f 145
146sprite_data:
147 /* Y size link attr X */
570c4371 148 dc.w 0; dc.b 0x05; dc.b 0; dc.w 0x6002; dc.w 0
4db6e09f 149sprite_data_end:
150
4db6e09f 151##################################################
152# #
153# MAIN PROGRAM #
154# #
155##################################################
156
570c4371 157.align 2
158
4db6e09f 159main:
4276cd7a 160 /* mask irqs during init */
1286a1ba 161 move.w #0x2700,sr
162
163 movea.l #0,a6
4276cd7a 164 moveq.l #0,d7
1286a1ba 165
166 /* Init pads */
167 move.b #0x40,(0xa10009).l
168 move.b #0x40,(0xa10003).l
169
4db6e09f 170 /* Initialize VDP */
171 jsr init_gfx
172
173 /* Load color data */
0fc4f06b 174 movea.l #0,a0
175 movea.l #colors,a1
176 moveq.l #(colors_end-colors)/2,d0
4db6e09f 177 jsr load_colors
178
179 /* load patterns */
0fc4f06b 180 movea.l #0,a0
181 movea.l #font,a1
182 move.l #128,d0
4db6e09f 183 jsr load_tiles
184
185 /* generate A layer map */
1286a1ba 186 movea.l #0xe000,a1
4db6e09f 187 move.l #28-1,d4
188lmaploop0:
1286a1ba 189 movea.l a1,a0
4db6e09f 190 jsr load_prepare
191
570c4371 192 move.l #64/2-1,d3
0fc4f06b 1930: move.l #0x00000000,(a0)
4db6e09f 194 dbra d3,0b
195
1286a1ba 196 add.l #64*2,a1
4db6e09f 197 dbra d4,lmaploop0
198
199 /* generate B layer map */
0fc4f06b 200 movea.l #0xc000,a0
4db6e09f 201 jsr load_prepare
202
570c4371 203 move.l #64*28/2-1,d3
0fc4f06b 2040: move.l #0x00000000,(a0)
4db6e09f 205 dbra d3,0b
206
207 /* upload sprite data */
0fc4f06b 208 movea.l #0xfc00,a0
4db6e09f 209 jsr load_prepare
0fc4f06b 210 movea.l #sprite_data,a1
4db6e09f 211
212 move.l #(sprite_data_end-sprite_data)/2-1,d3
0fc4f06b 2130: move.l (a1)+,(a0)
4db6e09f 214 dbra d3,0b
215
1286a1ba 216 move.w #0x2000,sr
570c4371 217
4db6e09f 218##################################################
219# #
220# MAIN LOOP #
221# #
222##################################################
223
1286a1ba 224# global regs:
4276cd7a 225# a6 - page_start[31:8]|cursor_offs[7:0]
226# d7 - byte_mode[0]
1286a1ba 227
4db6e09f 228forever:
4db6e09f 229
4db6e09f 230
231 jsr wait_vsync
232 bra forever
233
234
235
1286a1ba 236VBL:
237 addq.l #1,(vtimer).l
4276cd7a 238 movem.l d0-d6/a0-a5,-(a7)
1286a1ba 239
240 /* draw main stuff */
4276cd7a 241 clr.l d1
1286a1ba 242 move.l a6,d0
4276cd7a 243 move.b d0,d1
1286a1ba 244 lsr.l #8,d0
245 move.l d0,a1 /* current addr */
4276cd7a 246 lsr.b #3,d1
247 neg.b d1
248 add.b #27-1,d1 /* line where the cursor sits */
249 swap d1
1286a1ba 250
251 movea.l #0xe004,a2
4276cd7a 252 move.l #27-1,d5 /* line counter for dbra */
253 or.l d1,d5
1286a1ba 254
255draw_column:
256 move.l a2,a0
257 jsr load_prepare
258
259 /* addr */
260 move.l a1,d2
261 moveq.l #6,d3
262 jsr print_hex_preped
263
264 /* 4 shorts */
4276cd7a 265 moveq.l #4,d3
1286a1ba 266 moveq.l #4-1,d4
267draw_shorts:
268 move.w #' ',(a0)
269 move.w (a1)+,d2
1286a1ba 270 jsr print_hex_preped
271 dbra d4,draw_shorts
272
4276cd7a 273 move.l d5,d0
274 swap d0
275 cmp.w d5,d0
276 beq draw_cursor
277
278draw_chars_pre:
279 move.l #(' '<<16)|' ',(a0)
1286a1ba 280
281 /* 8 chars */
282 subq.l #8,a1
283 moveq.l #8-1,d4
284draw_chars:
285 move.b (a1)+,d0
286 move.b d0,d1
287 sub.b #0x20,d1
288 cmp.b #0x60,d1
289 blo 0f
290 move.w #'.',d0
2910:
292 move.w d0,(a0)
293 dbra d4,draw_chars
294
295 add.w #0x80,a2
296 dbra d5,draw_column
297
4276cd7a 298 /* status bar */
299 movea.l #0xe004+64*2*27,a0
300 jsr load_prepare
301 move.l a6,d2
302 moveq.l #0,d3
303 move.b d2,d3
304 lsr.l #8,d2
305 add.l d3,d2
306 move.l #0x4006,d3
307 jsr print_hex_preped
308
1286a1ba 309 /* handle input */
310 jsr get_input /* x0cbrldu x1sa00du */
1286a1ba 311
4276cd7a 312 do_dpad 0, sub, subq, 0x0008, 0x0800
313 do_dpad 1, add, addq, 0x0008, 0x0800
314 do_dpad 10, sub, subq, 0x0001, 0xd800
315 do_dpad 11, add, addq, 0x0001, 0xd800
316input_end:
1286a1ba 317
4276cd7a 318 /* update addr */
319 move.l a6,d0
320 cmp.b #0xf0,d0
321 blo 0f
322 sub.l #0xd800,a6
323 add.w #0x00d8,a6
324 bra 1f
3250:
326 cmp.b #0xe0,d0
327 blo 1f
328 add.l #0xd800,a6
329 sub.w #0x00d8,a6
3301:
1286a1ba 331
332end:
4276cd7a 333 movem.l (a7)+,d0-d6/a0-a5
1286a1ba 334 rte
335
336
4276cd7a 337draw_cursor:
338 move.l a6,d0
339 and.l #7,d0 /* byte offs */
340 move.l d0,d1
341 lsr.b #1,d1 /* which word */
342 move.b d1,d2
343 lsl.b #2,d2
344 add.b d2,d1 /* num of chars to skip */
345 lsl.b #1,d1
346
347 /* FIXME */
348 move.w (-8,a1,d0),d2
349
350 lea (7*2,a2,d1),a0
351 jsr load_prepare
352
353 move.w #0x2004,d3
354 jsr print_hex_preped
355
356 move.l a2,a0
357 add.w #26*2,a0
358 jsr load_prepare /* restore a0 */
359
360 jmp draw_chars_pre
361
362
4db6e09f 363#################################################
364# #
365# Initialize VDP registers #
366# #
367#################################################
368
369init_gfx:
370 move.l #GFXCNTL,a3
570c4371 371 write_vdp_reg 0,(VDP0_E_DISPLAY | VDP0_PLTT_FULL)
372 write_vdp_reg 1,(VDP1_E_VBI | VDP1_E_DISPLAY | VDP1_E_DMA | VDP1_RESERVED)
4db6e09f 373 write_vdp_reg 2,(0xe000 >> 10) /* Screen map a adress */
374 write_vdp_reg 3,(0xe000 >> 10) /* Window address */
375 write_vdp_reg 4,(0xc000 >> 13) /* Screen map b address */
376 write_vdp_reg 5,(0xfc00 >> 9) /* Sprite address */
377 write_vdp_reg 6,0
570c4371 378 write_vdp_reg 7,0 /* Backdrop color */
4db6e09f 379 write_vdp_reg 10,1 /* Lines per hblank interrupt */
380 write_vdp_reg 11,0 /* 2-cell vertical scrolling */
570c4371 381 write_vdp_reg 12,(VDP12_SCREEN_V224 | VDP12_SCREEN_H320)
382 write_vdp_reg 13,(0x8000 >> 10) /* Horizontal scroll address */
4db6e09f 383 write_vdp_reg 15,2
570c4371 384 write_vdp_reg 16,(VDP16_MAP_V32 | VDP16_MAP_H64) /* layer size */
4db6e09f 385 write_vdp_reg 17,0
386 write_vdp_reg 18,0xff
387 rts
388
389
1286a1ba 390# read single phase from controller
391# a0 - addr
392# d0 - result
393get_input:
394 move.b #0x40,(0xa10003)
395 nop
396 nop
397 nop
398 move.b (0xa10003),d0
399 move.b #0x00,(0xa10003)
400 lsl.w #8,d0
401 nop
402 move.b (0xa10003),d0
403 eor.w #0xffff,d0
404# move.b #0x40,(0xa10003)
405 rts
406
0fc4f06b 407# Load tile data from ROM
408# a0: VRAM base
409# a1: pattern address
410# d0: number of tiles to load
411# destroys d1
4db6e09f 412
413load_tiles:
0fc4f06b 414 move.l d0,d1
415 VRAM_ADDR_var a0
416 move.l d0,(GFXCNTL).l
4db6e09f 417
0fc4f06b 418 move.l #GFXDATA,a0
419 lsl.w #3,d1
420 subq.l #1,d1
4210:
422 move.l (a1)+,(a0)
423 dbra d1,0b
4db6e09f 424
425 rts
426
427
570c4371 428# Prepare to write to VDP RAM @a3
0fc4f06b 429# sets a0 to VDP data port for convenience
430# a0: VRAM base
431# destroys d0
570c4371 432
4db6e09f 433load_prepare:
0fc4f06b 434 VRAM_ADDR_var a0
435 move.l d0,(GFXCNTL).l
436 move.l #GFXDATA,a0
4db6e09f 437 rts
438
439
0fc4f06b 440# Load color data from ROM
441# a0: CRAM base
442# a1: color list address
443# d0: number of colors to load
444# destroys d1
4db6e09f 445
446load_colors:
0fc4f06b 447 move.l d0,d1
448 CRAM_ADDR_var a0
449 move.l d0,(GFXCNTL).l
4db6e09f 450
0fc4f06b 451 move.l #GFXDATA,a0
452 subq.w #1,d1
4530:
454 move.w (a1)+,(a0)
455 dbra d1,0b
4db6e09f 456
457 rts
458
0fc4f06b 459
460# print
461# a0 - string
462# d0 - x
463# d1 - y
464# destroys a1
570c4371 465
466print:
0fc4f06b 467 move.l a0,a1
1286a1ba 468 XY2NT
0fc4f06b 469 jsr load_prepare
470 moveq.l #0,d0
570c4371 471
472_print_loop:
0fc4f06b 473 move.b (a1)+,d0
570c4371 474 beq _print_end
475
0fc4f06b 476 move.w d0,(a0)
570c4371 477 jmp _print_loop
478
479_print_end:
480 rts
481
4db6e09f 482
1286a1ba 483# print_hex
484# d0 - x
485# d1 - y
486# d2 - value
4276cd7a 487# d3 - digit_cnt[0:7]|tile_bits[11:15]
488# destroys a0, preserves d3
1286a1ba 489
490print_hex:
491 XY2NT
492 jsr load_prepare
493
494print_hex_preped:
4276cd7a 495 moveq.l #0,d0
496 move.b d3,d0
497 move.l d0,d1
1286a1ba 498 lsl.b #2,d0
499 ror.l d0,d2 /* prep value */
4276cd7a 500 subq.l #1,d1 /* count */
501 move.w d3,d0
502 and.w #0xf800,d0 /* keep upper bits in d0 */
1286a1ba 503
504_print_hex_loop:
505 rol.l #4,d2
506 move.b d2,d0
507 and.b #0xf,d0
1286a1ba 508
509 add.b #'0',d0
4276cd7a 510 cmp.b #'9',d0
511 ble 0f
512 addq.b #7,d0
5130:
1286a1ba 514 move.w d0,(a0)
4276cd7a 515 dbra d1,_print_hex_loop
1286a1ba 516
517 rts
518
519
4db6e09f 520#################################################
521# #
522# Wait for next VBlank interrupt #
523# #
524#################################################
525
526wait_vsync:
527 movea.l #vtimer,a0
528 move.l (a0),a1
529_wait_change:
530 stop #0x2000
531 cmp.l (a0),a1
532 beq _wait_change
533 rts
534
535
536#################################################
537# #
538# RAM DATA #
539# #
540#################################################
541
542.bss
570c4371 543
544# used by sega_gcc.s
4db6e09f 545.globl htimer
546.globl vtimer
547.globl rand_num
548htimer: .long 0
549vtimer: .long 0
550rand_num: .long 0
570c4371 551
552#
4db6e09f 553
554.end
555
556# vim:filetype=asmM68k