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[31:8]|edit_done[7]|edit_pos[6:4]|autorep_cnt[3:0]
259 movem.l d0-d5/a0-a5,-(a7)
265 move.l (jumptab,pc,d0),a0
270 dc.l mode_edit_val /* edit val in editor */
277 ##################### main #######################
284 move.l d0,a1 /* current addr */
287 add.b #27-1,d1 /* line where the cursor sits */
291 move.l #27-1,d5 /* line counter for dbra */
318 move.l #(' '<<16)|' ',(a0)
338 movea.l #0xe004+64*2*27,a0
345 jsr get_input /* x0cbrldu x1sa00du */
347 btst.l #16+4,d0 /* A - scroll modifier */
350 do_dpad 16+0, sub, #0x0800
351 do_dpad 16+1, add, #0x0800
352 do_dpad 16+10, sub, #0xd800
353 do_dpad 16+11, add, #0xd800
360 do_dpad 0, subq, #0x0008
361 do_dpad 1, addq, #0x0008
382 btst.l #12,d0 /* B - switch byte/word mode */
385 add.w #0x4000,d7 /* changes between 01 10 */
388 sub.l d1,a6 /* make even, just in case */
391 btst.l #13,d0 /* C - edit selected byte */
394 change_mode MMODE_EDIT_VAL, MMODE_MAIN
395 write_vdp_reg 12,(VDP12_SCREEN_V224 | VDP12_SCREEN_H320 | VDP12_STE)
398 btst.l #5,d0 /* Start - goto */
401 change_mode MMODE_GOTO, MMODE_MAIN
402 write_vdp_reg 12,(VDP12_SCREEN_V224 | VDP12_SCREEN_H320 | VDP12_STE)
406 movem.l (a7)+,d0-d5/a0-a5
412 and.l #7,d0 /* byte offs */
414 lsr.b #1,d1 /* which word */
417 add.b d2,d1 /* num of chars to skip */
441 jsr load_prepare /* restore a0 */
446 #################### hedit #######################
450 bne mode_hedit_finish
452 /* read val to edit */
467 and.b #0x0f,d6 /* not done, reset pos */
468 change_mode MMODE_VAL_INPUT, MMODE_EDIT_VAL
486 and.l #0xf,d6 /* forget val and pos */
489 ##################### goto #######################
495 or.w #0xc000,d7 /* 3 bytes */
497 change_mode MMODE_VAL_INPUT, MMODE_GOTO
511 or.w #0x8000,d7 /* back to 2 bytes */
514 ################### val edit #####################
518 movea.l #0xe000+14*2+11*64*2,a1
568 lsr.b #1,d1 /* length in bytes */
572 and.b #7,d1 /* nibble to edit */
576 sub.b #1,d3 /* chars to shift out */
587 jsr get_input /* x0cbrldu x1sa00du */
595 add.b d1,d1 /* nibble count */
596 sub.b #1,d1 /* max n.t.e. val */
599 and.b #7,d2 /* nibble to edit */
611 lsl.l d1,d3 /* mask */
612 lsl.l d1,d4 /* what to add/sub */
654 and.l #0xf,d6 /* forget val and pos */
671 # go back to main mode
674 change_mode MMODE_MAIN, MMODE_MAIN
675 write_vdp_reg 12,(VDP12_SCREEN_V224 | VDP12_SCREEN_H320)
679 #################################################
681 # Initialize VDP registers #
683 #################################################
687 write_vdp_reg 0,(VDP0_E_DISPLAY | VDP0_PLTT_FULL)
688 write_vdp_reg 1,(VDP1_E_VBI | VDP1_E_DISPLAY | VDP1_E_DMA | VDP1_RESERVED)
689 write_vdp_reg 2,(0xe000 >> 10) /* Screen map a adress */
690 write_vdp_reg 3,(0xe000 >> 10) /* Window address */
691 write_vdp_reg 4,(0xc000 >> 13) /* Screen map b address */
692 write_vdp_reg 5,(0xfc00 >> 9) /* Sprite address */
694 write_vdp_reg 7,0 /* Backdrop color */
695 write_vdp_reg 10,1 /* Lines per hblank interrupt */
696 write_vdp_reg 11,0 /* 2-cell vertical scrolling */
697 write_vdp_reg 12,(VDP12_SCREEN_V224 | VDP12_SCREEN_H320)
698 write_vdp_reg 13,(0x8000 >> 10) /* Horizontal scroll address */
700 write_vdp_reg 16,(VDP16_MAP_V32 | VDP16_MAP_H64) /* layer size */
702 write_vdp_reg 18,0xff
706 # read single phase from controller
711 move.b #0x40,(0xa10003)
716 move.b #0x00,(0xa10003)
724 eor.w d0,d1 /* changed btns */
725 move.w d0,d7 /* old val */
727 and.w d0,d1 /* what changed now */
732 and.b #7,d2 /* do autorepeat every 8 frames */
743 # Load tile data from ROM
745 # a1: pattern address
746 # d0: number of tiles to load
752 move.l d0,(GFXCNTL).l
764 # Prepare to write to VDP RAM @a0
765 # sets a0 to VDP data port for convenience
771 move.l d0,(GFXCNTL).l
776 # Load color data from ROM
778 # a1: color list address
779 # d0: number of colors to load
785 move.l d0,(GFXCNTL).l
800 # d2 - tile_bits[15:11]
825 # d3 - digit_cnt[0:7]|tile_bits[11:15]
826 # destroys a0, preserves d3
837 ror.l d0,d2 /* prep value */
838 subq.l #1,d1 /* count */
840 and.w #0xf800,d0 /* keep upper bits in d0 */
853 dbra d1,_print_hex_loop
858 #################################################
860 # Wait for next VBlank interrupt #
862 #################################################
873 #################################################
877 #################################################
885 # vim:filetype=asmM68k