byte mode, edit mode wip
[megadrive.git] / hexed / hexed.s
... / ...
CommitLineData
1##################################################
2# #
3# Assemble with gas #
4# --register-prefix-optional --bitwise-or #
5# #
6##################################################
7
8.text
9.globl main
10.globl VBL
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_STE, 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
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
76 move.l \adr,d0
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
82.endm
83
84
85.macro VRAM_ADDR_var adr
86 XRAM_ADDR_var \adr
87 or.l #0x40000000,d0
88.endm
89
90
91.macro CRAM_ADDR_var adr
92 XRAM_ADDR_var \adr
93 or.l #0xc0000000,d0
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
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
116# check if some d-pad button (and modifier) is pressed
117.macro do_dpad bit op val
118 btst.l #\bit,d0
119 beq 0f
120 \op.l \val,a6
121 bra dpad_end
1220:
123.endm
124
125#################################################
126# #
127# DATA #
128# #
129#################################################
130
131colors:
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
138colors_end:
139
140
141sprite_data:
142 /* Y size link attr X */
143 dc.w 0; dc.b 0x05; dc.b 0; dc.w 0x6002; dc.w 0
144sprite_data_end:
145
146##################################################
147# #
148# MAIN PROGRAM #
149# #
150##################################################
151
152.align 2
153
154main:
155 /* mask irqs during init */
156 move.w #0x2700,sr
157
158 movea.l #0,a6
159 moveq.l #0,d7
160 moveq.l #0,d6
161
162 /* Init pads */
163 move.b #0x40,(0xa10009).l
164 move.b #0x40,(0xa10003).l
165
166 /* Initialize VDP */
167 jsr init_gfx
168
169 /* Load color data */
170 movea.l #0,a0
171 movea.l #colors,a1
172 moveq.l #(colors_end-colors)/2,d0
173 jsr load_colors
174
175 /* load patterns */
176 movea.l #0,a0
177 movea.l #font,a1
178 move.l #128,d0
179 jsr load_tiles
180
181 /* generate A layer map */
182 movea.l #0xe000,a1
183 move.l #28-1,d4
184lmaploop0:
185 movea.l a1,a0
186 jsr load_prepare
187
188 move.l #64/2-1,d3
1890: move.l #0x00000000,(a0)
190 dbra d3,0b
191
192 add.l #64*2,a1
193 dbra d4,lmaploop0
194
195 /* generate B layer map */
196 movea.l #0xc000,a0
197 jsr load_prepare
198
199 move.l #64*28/2-1,d3
2000: move.l #0x00000000,(a0)
201 dbra d3,0b
202
203 /* upload sprite data */
204 movea.l #0xfc00,a0
205 jsr load_prepare
206 movea.l #sprite_data,a1
207
208 move.l #(sprite_data_end-sprite_data)/2-1,d3
2090: move.l (a1)+,(a0)
210 dbra d3,0b
211
212 move.w #0x2000,sr
213
214##################################################
215# #
216# MAIN LOOP #
217# #
218##################################################
219
220# global regs:
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]
224
225forever:
226
227
228 jsr wait_vsync
229 bra forever
230
231
232
233VBL:
234 addq.b #1,d7
235 movem.l d0-d5/a0-a5,-(a7)
236
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:
256 clr.l d1
257 move.l a6,d0
258 move.b d0,d1
259 lsr.l #8,d0
260 move.l d0,a1 /* current addr */
261 lsr.b #3,d1
262 neg.b d1
263 add.b #27-1,d1 /* line where the cursor sits */
264 swap d1
265
266 movea.l #0xe004,a2
267 move.l #27-1,d5 /* line counter for dbra */
268 or.l d1,d5
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 */
280 moveq.l #4,d3
281 moveq.l #4-1,d4
282draw_shorts:
283 move.w #' ',(a0)
284 move.w (a1)+,d2
285 jsr print_hex_preped
286 dbra d4,draw_shorts
287
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)
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
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
324 /* handle input */
325 jsr get_input /* x0cbrldu x1sa00du */
326
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:
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:
371 cmp.b #0xd8,d0
372 blo 1f
373 add.l #0xd800,a6
374 sub.w #0x00d8,a6
3751:
376
377vbl_end:
378 movem.l (a7)+,d0-d5/a0-a5
379 rte
380
381
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
391 move.w #0x2004,d3
392
393 btst.l #15,d7
394 beq draw_cursor_word
395
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:
407 lea (7*2,a2,d1),a0
408 jsr load_prepare
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
418##################### edit #######################
419
420mode_edit:
421 jmp vbl_end
422
423
424#################################################
425# #
426# Initialize VDP registers #
427# #
428#################################################
429
430init_gfx:
431 move.l #GFXCNTL,a3
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)
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
439 write_vdp_reg 7,0 /* Backdrop color */
440 write_vdp_reg 10,1 /* Lines per hblank interrupt */
441 write_vdp_reg 11,0 /* 2-cell vertical scrolling */
442 write_vdp_reg 12,(VDP12_SCREEN_V224 | VDP12_SCREEN_H320)
443 write_vdp_reg 13,(0x8000 >> 10) /* Horizontal scroll address */
444 write_vdp_reg 15,2
445 write_vdp_reg 16,(VDP16_MAP_V32 | VDP16_MAP_H64) /* layer size */
446 write_vdp_reg 17,0
447 write_vdp_reg 18,0xff
448 rts
449
450
451# read single phase from controller
452# #a0 - addr
453# d0 - result
454# destroys d1,d2
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
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
486 rts
487
488# Load tile data from ROM
489# a0: VRAM base
490# a1: pattern address
491# d0: number of tiles to load
492# destroys d1
493
494load_tiles:
495 move.l d0,d1
496 VRAM_ADDR_var a0
497 move.l d0,(GFXCNTL).l
498
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
505
506 rts
507
508
509# Prepare to write to VDP RAM @a3
510# sets a0 to VDP data port for convenience
511# a0: VRAM base
512# destroys d0
513
514load_prepare:
515 VRAM_ADDR_var a0
516 move.l d0,(GFXCNTL).l
517 move.l #GFXDATA,a0
518 rts
519
520
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
526
527load_colors:
528 move.l d0,d1
529 CRAM_ADDR_var a0
530 move.l d0,(GFXCNTL).l
531
532 move.l #GFXDATA,a0
533 subq.w #1,d1
5340:
535 move.w (a1)+,(a0)
536 dbra d1,0b
537
538 rts
539
540
541# print
542# a0 - string
543# d0 - x
544# d1 - y
545# destroys a1
546
547print:
548 move.l a0,a1
549 XY2NT
550 jsr load_prepare
551 moveq.l #0,d0
552
553_print_loop:
554 move.b (a1)+,d0
555 beq _print_end
556
557 move.w d0,(a0)
558 jmp _print_loop
559
560_print_end:
561 rts
562
563
564# print_hex
565# d0 - x
566# d1 - y
567# d2 - value
568# d3 - digit_cnt[0:7]|tile_bits[11:15]
569# destroys a0, preserves d3
570
571print_hex:
572 XY2NT
573 jsr load_prepare
574
575print_hex_preped:
576 moveq.l #0,d0
577 move.b d3,d0
578 move.l d0,d1
579 lsl.b #2,d0
580 ror.l d0,d2 /* prep value */
581 subq.l #1,d1 /* count */
582 move.w d3,d0
583 and.w #0xf800,d0 /* keep upper bits in d0 */
584
585_print_hex_loop:
586 rol.l #4,d2
587 move.b d2,d0
588 and.b #0xf,d0
589
590 add.b #'0',d0
591 cmp.b #'9',d0
592 ble 0f
593 addq.b #7,d0
5940:
595 move.w d0,(a0)
596 dbra d1,_print_hex_loop
597
598 rts
599
600
601#################################################
602# #
603# Wait for next VBlank interrupt #
604# #
605#################################################
606
607wait_vsync:
608 move.b d7,d0
609_wait_change:
610 stop #0x2000
611 cmp.b d7,d0
612 beq _wait_change
613 rts
614
615
616#################################################
617# #
618# RAM DATA #
619# #
620#################################################
621
622.bss
623
624# nothing :)
625
626.end
627
628# vim:filetype=asmM68k