1 ##################################################
4 # --register-prefix-optional --bitwise-or #
6 ##################################################
12 ##################################################
14 # Register and bitmask definitions #
16 ##################################################
18 .equ GFXDATA, 0xc00000
19 .equ GFXCNTL, 0xc00004
22 .equ VDP0_E_DISPLAY, 0x02
23 .equ VDP0_PLTT_FULL, 0x04
25 .equ VDP1_SMS_MODE, 0x80
26 .equ VDP1_E_DISPLAY, 0x40
31 .equ VDP1_RESERVED, 0x04
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
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
49 .equ MMODE_VAL_INPUT, 1
50 .equ MMODE_EDIT_VAL, 2
54 ##################################################
58 ##################################################
61 /* Write val to VDP register reg */
62 .macro write_vdp_reg reg val
63 move.w #((\reg << 8) + 0x8000 + \val),(a3)
67 /* For immediate addresses */
68 .macro VRAM_ADDR reg adr
69 move.l #(((0x4000 + (\adr & 0x3fff)) << 16) + (\adr >> 14)),\reg
73 .macro CRAM_ADDR reg adr
74 move.l #(((0xc000 + (\adr & 0x3fff)) << 16) + (\adr >> 14)),\reg
78 # make VDP word from address adr and store in d0
79 .macro XRAM_ADDR_var adr
89 .macro VRAM_ADDR_var adr
95 .macro CRAM_ADDR_var adr
101 .macro VSCROLL_ADDR reg adr
102 move.l #(((0x4000 + (\adr & 0x3fff)) << 16) + ((\adr >> 14) | 0x10)),\reg
106 .macro HSCROLL_ADDR reg adr
107 move.l #(((0x4000 + (\adr & 0x3fff)) << 16) + (\adr >> 14)),\reg
111 # convert tile coords in d0, d1 to nametable addr to a0
120 # check if some d-pad button (and modifier) is pressed
121 .macro do_dpad bit op val
129 # convert a6 to normal addr
131 .macro mk_a6_addr reg
139 .macro change_mode mode_new mode_back
141 or.w #(\mode_back<<11)|(\mode_new<<8),d7
144 #################################################
148 #################################################
151 dc.w 0x0000,0x0eee,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000
152 dc.w 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000
153 dc.w 0x0000,0x02e2,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000
154 dc.w 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000
155 dc.w 0x0000,0x0e44,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000
156 dc.w 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000
161 /* Y size link attr X */
162 dc.w 0; dc.b 0x05; dc.b 0; dc.w 0x6002; dc.w 0
170 ##################################################
174 ##################################################
179 /* mask irqs during init */
187 move.b #0x40,(0xa10009).l
188 move.b #0x40,(0xa10003).l
193 /* Load color data */
196 moveq.l #(colors_end-colors)/2,d0
205 /* generate A layer map */
213 0: move.l #0x00000000,(a0)
219 /* generate B layer map */
224 0: move.l #0x00000000,(a0)
227 /* upload sprite data */
230 movea.l #sprite_data,a1
232 move.l #(sprite_data_end-sprite_data)/2-1,d3
238 ##################################################
242 ##################################################
245 # a6 = page_start[31:8]|cursor_offs[7:0]
246 # d7 = old_inputs[31:16]|edit_bytes[15:14]|g_mode_old[13:11]|g_mode[10:8]|irq_cnt[7:0]
247 # d6 = edit_word_save[31:15]|edit_done[7]|autorep_cnt[3:0]
248 # d5 = edit_word[31:8]|edit_pos[4:2]|byte_cnt[1:0]; tmp in main mode
258 movem.l d0-d4/a0-a5,-(a7)
264 move.l (jumptab,pc,d0),a0
269 dc.l mode_edit_val /* edit val in editor */
276 ##################### main #######################
283 move.l d0,a1 /* current addr */
286 add.b #27-1,d1 /* line where the cursor sits */
290 move.l #27-1,d5 /* line counter for dbra */
317 move.l #(' '<<16)|' ',(a0)
337 movea.l #0xe004+64*2*27,a0
344 jsr get_input /* x0cbrldu x1sa00du */
346 btst.l #16+4,d0 /* A - scroll modifier */
349 do_dpad 16+0, sub, #0x0800
350 do_dpad 16+1, add, #0x0800
351 do_dpad 16+10, sub, #0xd800
352 do_dpad 16+11, add, #0xd800
359 do_dpad 0, subq, #0x0008
360 do_dpad 1, addq, #0x0008
381 btst.l #12,d0 /* B - switch byte/word mode */
384 add.w #0x4000,d7 /* changes between 01 10 */
387 sub.l d1,a6 /* make even, just in case */
390 btst.l #13,d0 /* C - edit selected byte */
393 change_mode MMODE_EDIT_VAL, MMODE_MAIN
394 write_vdp_reg 12,(VDP12_SCREEN_V224 | VDP12_SCREEN_H320 | VDP12_STE)
397 btst.l #5,d0 /* Start - goto */
400 change_mode MMODE_GOTO, MMODE_MAIN
401 write_vdp_reg 12,(VDP12_SCREEN_V224 | VDP12_SCREEN_H320 | VDP12_STE)
405 movem.l (a7)+,d0-d4/a0-a5
411 and.l #7,d0 /* byte offs */
413 lsr.b #1,d1 /* which word */
416 add.b d2,d1 /* num of chars to skip */
440 jsr load_prepare /* restore a0 */
445 #################### hedit #######################
449 bne mode_hedit_finish
451 /* read val to edit */
467 change_mode MMODE_VAL_INPUT, MMODE_EDIT_VAL
486 ##################### goto #######################
497 or.b #3,d5 /* 3 bytes */
499 change_mode MMODE_VAL_INPUT, MMODE_GOTO
519 ################### val edit #####################
523 movea.l #0xe000+14*2+11*64*2,a1
554 and.b #3,d3 /* edit field bytes */
572 lsr.b #1,d1 /* length in bytes */
576 and.b #7,d1 /* nibble to edit */
580 sub.b #1,d3 /* chars to shift out */
591 jsr get_input /* x0cbrldu x1sa00du */
598 add.b d1,d1 /* nibble count */
599 sub.b #1,d1 /* max n.t.e. val */
602 and.b #7,d2 /* nibble to edit */
614 lsl.l d1,d3 /* mask */
615 lsl.l d1,d4 /* what to add/sub */
660 btst.l #4,d0 /* A - confirm */
663 move.w d7,d1 /* back to prev mode */
673 # go back to main mode
675 bclr.l #7,d6 /* not edited */
676 change_mode MMODE_MAIN, MMODE_MAIN
677 write_vdp_reg 12,(VDP12_SCREEN_V224 | VDP12_SCREEN_H320)
681 #################################################
683 # Initialize VDP registers #
685 #################################################
689 write_vdp_reg 0,(VDP0_E_DISPLAY | VDP0_PLTT_FULL)
690 write_vdp_reg 1,(VDP1_E_VBI | VDP1_E_DISPLAY | VDP1_E_DMA | VDP1_RESERVED)
691 write_vdp_reg 2,(0xe000 >> 10) /* Screen map a adress */
692 write_vdp_reg 3,(0xe000 >> 10) /* Window address */
693 write_vdp_reg 4,(0xc000 >> 13) /* Screen map b address */
694 write_vdp_reg 5,(0xfc00 >> 9) /* Sprite address */
696 write_vdp_reg 7,0 /* Backdrop color */
697 write_vdp_reg 10,1 /* Lines per hblank interrupt */
698 write_vdp_reg 11,0 /* 2-cell vertical scrolling */
699 write_vdp_reg 12,(VDP12_SCREEN_V224 | VDP12_SCREEN_H320)
700 write_vdp_reg 13,(0x8000 >> 10) /* Horizontal scroll address */
702 write_vdp_reg 16,(VDP16_MAP_V32 | VDP16_MAP_H64) /* layer size */
704 write_vdp_reg 18,0xff
708 # read single phase from controller
713 move.b #0x40,(0xa10003)
718 move.b #0x00,(0xa10003)
726 eor.w d0,d1 /* changed btns */
727 move.w d0,d7 /* old val */
729 and.w d0,d1 /* what changed now */
734 and.b #7,d2 /* do autorepeat every 8 frames */
745 # Load tile data from ROM
747 # a1: pattern address
748 # d0: number of tiles to load
754 move.l d0,(GFXCNTL).l
766 # Prepare to write to VDP RAM @a0
767 # sets a0 to VDP data port for convenience
773 move.l d0,(GFXCNTL).l
778 # Load color data from ROM
780 # a1: color list address
781 # d0: number of colors to load
787 move.l d0,(GFXCNTL).l
802 # d2 - tile_bits[15:11]
827 # d3 - digit_cnt[0:7]|tile_bits[11:15]
828 # destroys a0, preserves d3
839 ror.l d0,d2 /* prep value */
840 subq.l #1,d1 /* count */
842 and.w #0xf800,d0 /* keep upper bits in d0 */
855 dbra d1,_print_hex_loop
860 #################################################
862 # Wait for next VBlank interrupt #
864 #################################################
875 #################################################
879 #################################################
887 # vim:filetype=asmM68k