byte mode, edit mode 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
fbad1b76 33.equ VDP12_STE, 0x08
4db6e09f 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
fbad1b76 117.macro do_dpad bit op val
118 btst.l #\bit,d0
119 beq 0f
120 \op.l \val,a6
121 bra dpad_end
4276cd7a 1220:
4276cd7a 123.endm
124
4db6e09f 125#################################################
126# #
127# DATA #
128# #
129#################################################
130
131colors:
4276cd7a 132 dc.w 0x0000,0x0eee,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000
133 dc.w 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000
134 dc.w 0x0000,0x02e2,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000
135 dc.w 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000
136 dc.w 0x0000,0x0e44,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000
137 dc.w 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000
570c4371 138colors_end:
139
4db6e09f 140
141sprite_data:
142 /* Y size link attr X */
570c4371 143 dc.w 0; dc.b 0x05; dc.b 0; dc.w 0x6002; dc.w 0
4db6e09f 144sprite_data_end:
145
4db6e09f 146##################################################
147# #
148# MAIN PROGRAM #
149# #
150##################################################
151
570c4371 152.align 2
153
4db6e09f 154main:
4276cd7a 155 /* mask irqs during init */
1286a1ba 156 move.w #0x2700,sr
157
158 movea.l #0,a6
4276cd7a 159 moveq.l #0,d7
fbad1b76 160 moveq.l #0,d6
1286a1ba 161
162 /* Init pads */
163 move.b #0x40,(0xa10009).l
164 move.b #0x40,(0xa10003).l
165
4db6e09f 166 /* Initialize VDP */
167 jsr init_gfx
168
169 /* Load color data */
0fc4f06b 170 movea.l #0,a0
171 movea.l #colors,a1
172 moveq.l #(colors_end-colors)/2,d0
4db6e09f 173 jsr load_colors
174
175 /* load patterns */
0fc4f06b 176 movea.l #0,a0
177 movea.l #font,a1
178 move.l #128,d0
4db6e09f 179 jsr load_tiles
180
181 /* generate A layer map */
1286a1ba 182 movea.l #0xe000,a1
4db6e09f 183 move.l #28-1,d4
184lmaploop0:
1286a1ba 185 movea.l a1,a0
4db6e09f 186 jsr load_prepare
187
570c4371 188 move.l #64/2-1,d3
0fc4f06b 1890: move.l #0x00000000,(a0)
4db6e09f 190 dbra d3,0b
191
1286a1ba 192 add.l #64*2,a1
4db6e09f 193 dbra d4,lmaploop0
194
195 /* generate B layer map */
0fc4f06b 196 movea.l #0xc000,a0
4db6e09f 197 jsr load_prepare
198
570c4371 199 move.l #64*28/2-1,d3
0fc4f06b 2000: move.l #0x00000000,(a0)
4db6e09f 201 dbra d3,0b
202
203 /* upload sprite data */
0fc4f06b 204 movea.l #0xfc00,a0
4db6e09f 205 jsr load_prepare
0fc4f06b 206 movea.l #sprite_data,a1
4db6e09f 207
208 move.l #(sprite_data_end-sprite_data)/2-1,d3
0fc4f06b 2090: move.l (a1)+,(a0)
4db6e09f 210 dbra d3,0b
211
1286a1ba 212 move.w #0x2000,sr
570c4371 213
4db6e09f 214##################################################
215# #
216# MAIN LOOP #
217# #
218##################################################
219
1286a1ba 220# global regs:
fbad1b76 221# a6 = page_start[31:8]|cursor_offs[7:0]
222# d7 = old_inputs[31:16]|byte_mode[15]|g_mode[10:8]|irq_cnt[7:0]
223# d6 = autorep_cnt[3:0]
1286a1ba 224
4db6e09f 225forever:
4db6e09f 226
4db6e09f 227
228 jsr wait_vsync
229 bra forever
230
231
232
1286a1ba 233VBL:
fbad1b76 234 addq.b #1,d7
235 movem.l d0-d5/a0-a5,-(a7)
1286a1ba 236
fbad1b76 237 moveq.l #0,d0
238 move.w d7,d0
239 lsr.w #6,d0
240 and.w #0x1c,d0
241 move.l (jumptab,pc,d0),a0
242 jmp (a0)
243jumptab:
244 dc.l mode_main
245 dc.l mode_edit
246 dc.l mode_main
247 dc.l mode_main
248 dc.l mode_main
249 dc.l mode_main
250 dc.l mode_main
251 dc.l mode_main
252
253##################### main #######################
254
255mode_main:
4276cd7a 256 clr.l d1
1286a1ba 257 move.l a6,d0
4276cd7a 258 move.b d0,d1
1286a1ba 259 lsr.l #8,d0
260 move.l d0,a1 /* current addr */
4276cd7a 261 lsr.b #3,d1
262 neg.b d1
263 add.b #27-1,d1 /* line where the cursor sits */
264 swap d1
1286a1ba 265
266 movea.l #0xe004,a2
4276cd7a 267 move.l #27-1,d5 /* line counter for dbra */
268 or.l d1,d5
1286a1ba 269
270draw_column:
271 move.l a2,a0
272 jsr load_prepare
273
274 /* addr */
275 move.l a1,d2
276 moveq.l #6,d3
277 jsr print_hex_preped
278
279 /* 4 shorts */
4276cd7a 280 moveq.l #4,d3
1286a1ba 281 moveq.l #4-1,d4
282draw_shorts:
283 move.w #' ',(a0)
284 move.w (a1)+,d2
1286a1ba 285 jsr print_hex_preped
286 dbra d4,draw_shorts
287
4276cd7a 288 move.l d5,d0
289 swap d0
290 cmp.w d5,d0
291 beq draw_cursor
292
293draw_chars_pre:
294 move.l #(' '<<16)|' ',(a0)
1286a1ba 295
296 /* 8 chars */
297 subq.l #8,a1
298 moveq.l #8-1,d4
299draw_chars:
300 move.b (a1)+,d0
301 move.b d0,d1
302 sub.b #0x20,d1
303 cmp.b #0x60,d1
304 blo 0f
305 move.w #'.',d0
3060:
307 move.w d0,(a0)
308 dbra d4,draw_chars
309
310 add.w #0x80,a2
311 dbra d5,draw_column
312
4276cd7a 313 /* status bar */
314 movea.l #0xe004+64*2*27,a0
315 jsr load_prepare
316 move.l a6,d2
317 moveq.l #0,d3
318 move.b d2,d3
319 lsr.l #8,d2
320 add.l d3,d2
321 move.l #0x4006,d3
322 jsr print_hex_preped
323
1286a1ba 324 /* handle input */
325 jsr get_input /* x0cbrldu x1sa00du */
1286a1ba 326
fbad1b76 327 btst.l #16+4,d0 /* A - scroll modifier */
328 beq input_noa
329
330 do_dpad 16+0, sub, #0x0800
331 do_dpad 16+1, add, #0x0800
332 do_dpad 16+10, sub, #0xd800
333 do_dpad 16+11, add, #0xd800
334input_noa:
335 moveq.l #0,d1
336 btst.l #15,d7
337 seq d1
338 neg.b d1 /* 1 if word sel */
339 add.b #1,d1
340
341 do_dpad 0, subq, #0x0008
342 do_dpad 1, addq, #0x0008
343 do_dpad 10, sub, d1
344 do_dpad 11, add, d1
345
346dpad_end:
347 moveq.l #0,d1
348 btst.l #12,d0 /* B - switch byte/word mode */
349 beq input_nob
350 bchg.l #15,d7
351 move.l a6,d1
352 and.l #1,d1
353 sub.l d1,a6 /* make even, just in case */
354
355input_nob:
356 btst.l #13,d0 /* C - edit selected byte */
357 beq input_noc
358# and.w #0xf8ff,d7
359 or.w #0x0100,d7 /* switch to edit mode */
360 write_vdp_reg 12,(VDP12_SCREEN_V224 | VDP12_SCREEN_H320 | VDP12_STE)
361
362input_noc:
4276cd7a 363 /* update addr */
364 move.l a6,d0
365 cmp.b #0xf0,d0
366 blo 0f
367 sub.l #0xd800,a6
368 add.w #0x00d8,a6
369 bra 1f
3700:
fbad1b76 371 cmp.b #0xd8,d0
4276cd7a 372 blo 1f
373 add.l #0xd800,a6
374 sub.w #0x00d8,a6
3751:
1286a1ba 376
fbad1b76 377vbl_end:
378 movem.l (a7)+,d0-d5/a0-a5
1286a1ba 379 rte
380
381
4276cd7a 382draw_cursor:
383 move.l a6,d0
384 and.l #7,d0 /* byte offs */
385 move.l d0,d1
386 lsr.b #1,d1 /* which word */
387 move.b d1,d2
388 lsl.b #2,d2
389 add.b d2,d1 /* num of chars to skip */
390 lsl.b #1,d1
fbad1b76 391 move.w #0x2004,d3
4276cd7a 392
fbad1b76 393 btst.l #15,d7
394 beq draw_cursor_word
4276cd7a 395
fbad1b76 396draw_cursor_byte:
397 move.b (-8,a1,d0),d2
398 and.b #1,d0
399 lsl.b #2,d0
400 add.b d0,d1
401 subq.b #2,d3
402 bra 0f
403
404draw_cursor_word:
405 move.w (-8,a1,d0),d2
4060:
4276cd7a 407 lea (7*2,a2,d1),a0
408 jsr load_prepare
4276cd7a 409 jsr print_hex_preped
410
411 move.l a2,a0
412 add.w #26*2,a0
413 jsr load_prepare /* restore a0 */
414
415 jmp draw_chars_pre
416
417
fbad1b76 418##################### edit #######################
419
420mode_edit:
421 jmp vbl_end
422
423
4db6e09f 424#################################################
425# #
426# Initialize VDP registers #
427# #
428#################################################
429
430init_gfx:
431 move.l #GFXCNTL,a3
570c4371 432 write_vdp_reg 0,(VDP0_E_DISPLAY | VDP0_PLTT_FULL)
433 write_vdp_reg 1,(VDP1_E_VBI | VDP1_E_DISPLAY | VDP1_E_DMA | VDP1_RESERVED)
4db6e09f 434 write_vdp_reg 2,(0xe000 >> 10) /* Screen map a adress */
435 write_vdp_reg 3,(0xe000 >> 10) /* Window address */
436 write_vdp_reg 4,(0xc000 >> 13) /* Screen map b address */
437 write_vdp_reg 5,(0xfc00 >> 9) /* Sprite address */
438 write_vdp_reg 6,0
570c4371 439 write_vdp_reg 7,0 /* Backdrop color */
4db6e09f 440 write_vdp_reg 10,1 /* Lines per hblank interrupt */
441 write_vdp_reg 11,0 /* 2-cell vertical scrolling */
570c4371 442 write_vdp_reg 12,(VDP12_SCREEN_V224 | VDP12_SCREEN_H320)
443 write_vdp_reg 13,(0x8000 >> 10) /* Horizontal scroll address */
4db6e09f 444 write_vdp_reg 15,2
570c4371 445 write_vdp_reg 16,(VDP16_MAP_V32 | VDP16_MAP_H64) /* layer size */
4db6e09f 446 write_vdp_reg 17,0
447 write_vdp_reg 18,0xff
448 rts
449
450
1286a1ba 451# read single phase from controller
fbad1b76 452# #a0 - addr
1286a1ba 453# d0 - result
fbad1b76 454# destroys d1,d2
1286a1ba 455get_input:
456 move.b #0x40,(0xa10003)
457 nop
458 nop
459 nop
460 move.b (0xa10003),d0
461 move.b #0x00,(0xa10003)
462 lsl.w #8,d0
463 nop
464 move.b (0xa10003),d0
465 eor.w #0xffff,d0
fbad1b76 466
467 swap d7
468 move.w d7,d1
469 eor.w d0,d1 /* changed btns */
470 move.w d0,d7 /* old val */
471 swap d7
472 and.w d0,d1 /* what changed now */
473 bne 0f
474
475 addq.b #1,d6
476 move.b d6,d2
477 and.b #7,d2 /* do autorepeat every 8 frames */
478 cmp.b #7,d2
479 bne 1f
480 move.w d0,d1
4810:
482 and.b #0xf8,d6
4831:
484 swap d0
485 move.w d1,d0
1286a1ba 486 rts
487
0fc4f06b 488# Load tile data from ROM
489# a0: VRAM base
490# a1: pattern address
491# d0: number of tiles to load
492# destroys d1
4db6e09f 493
494load_tiles:
0fc4f06b 495 move.l d0,d1
496 VRAM_ADDR_var a0
497 move.l d0,(GFXCNTL).l
4db6e09f 498
0fc4f06b 499 move.l #GFXDATA,a0
500 lsl.w #3,d1
501 subq.l #1,d1
5020:
503 move.l (a1)+,(a0)
504 dbra d1,0b
4db6e09f 505
506 rts
507
508
570c4371 509# Prepare to write to VDP RAM @a3
0fc4f06b 510# sets a0 to VDP data port for convenience
511# a0: VRAM base
512# destroys d0
570c4371 513
4db6e09f 514load_prepare:
0fc4f06b 515 VRAM_ADDR_var a0
516 move.l d0,(GFXCNTL).l
517 move.l #GFXDATA,a0
4db6e09f 518 rts
519
520
0fc4f06b 521# Load color data from ROM
522# a0: CRAM base
523# a1: color list address
524# d0: number of colors to load
525# destroys d1
4db6e09f 526
527load_colors:
0fc4f06b 528 move.l d0,d1
529 CRAM_ADDR_var a0
530 move.l d0,(GFXCNTL).l
4db6e09f 531
0fc4f06b 532 move.l #GFXDATA,a0
533 subq.w #1,d1
5340:
535 move.w (a1)+,(a0)
536 dbra d1,0b
4db6e09f 537
538 rts
539
0fc4f06b 540
541# print
542# a0 - string
543# d0 - x
544# d1 - y
545# destroys a1
570c4371 546
547print:
0fc4f06b 548 move.l a0,a1
1286a1ba 549 XY2NT
0fc4f06b 550 jsr load_prepare
551 moveq.l #0,d0
570c4371 552
553_print_loop:
0fc4f06b 554 move.b (a1)+,d0
570c4371 555 beq _print_end
556
0fc4f06b 557 move.w d0,(a0)
570c4371 558 jmp _print_loop
559
560_print_end:
561 rts
562
4db6e09f 563
1286a1ba 564# print_hex
565# d0 - x
566# d1 - y
567# d2 - value
4276cd7a 568# d3 - digit_cnt[0:7]|tile_bits[11:15]
569# destroys a0, preserves d3
1286a1ba 570
571print_hex:
572 XY2NT
573 jsr load_prepare
574
575print_hex_preped:
4276cd7a 576 moveq.l #0,d0
577 move.b d3,d0
578 move.l d0,d1
1286a1ba 579 lsl.b #2,d0
580 ror.l d0,d2 /* prep value */
4276cd7a 581 subq.l #1,d1 /* count */
582 move.w d3,d0
583 and.w #0xf800,d0 /* keep upper bits in d0 */
1286a1ba 584
585_print_hex_loop:
586 rol.l #4,d2
587 move.b d2,d0
588 and.b #0xf,d0
1286a1ba 589
590 add.b #'0',d0
4276cd7a 591 cmp.b #'9',d0
592 ble 0f
593 addq.b #7,d0
5940:
1286a1ba 595 move.w d0,(a0)
4276cd7a 596 dbra d1,_print_hex_loop
1286a1ba 597
598 rts
599
600
4db6e09f 601#################################################
602# #
603# Wait for next VBlank interrupt #
604# #
605#################################################
606
607wait_vsync:
fbad1b76 608 move.b d7,d0
4db6e09f 609_wait_change:
610 stop #0x2000
fbad1b76 611 cmp.b d7,d0
4db6e09f 612 beq _wait_change
613 rts
614
615
616#################################################
617# #
618# RAM DATA #
619# #
620#################################################
621
622.bss
570c4371 623
fbad1b76 624# nothing :)
4db6e09f 625
626.end
627
628# vim:filetype=asmM68k