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
52 .equ MMODE_START_MENU, 4
53 .equ MMODE_GOTO_PREDEF, 5
55 .equ predef_addr_cnt, ((predef_addrs_end-predef_addrs)/4)
57 ##################################################
61 ##################################################
64 # Write val to VDP register reg
65 .macro write_vdp_r_dst reg val dst
66 move.w #((\reg << 8) + 0x8000 + \val),\dst
69 # Write val to VDP register reg, vdp addr in a3
70 .macro write_vdp_reg reg val
71 write_vdp_r_dst \reg, \val, (a3)
74 /* For immediate addresses */
75 .macro VRAM_ADDR reg adr
76 move.l #(((0x4000 + (\adr & 0x3fff)) << 16) + (\adr >> 14)),\reg
79 .macro CRAM_ADDR reg adr
80 move.l #(((0xc000 + (\adr & 0x3fff)) << 16) + (\adr >> 14)),\reg
84 # make VDP word from address adr and store in d0
85 .macro XRAM_ADDR_var adr
95 .macro VRAM_ADDR_var adr
101 .macro CRAM_ADDR_var adr
107 .macro VSCROLL_ADDR reg adr
108 move.l #(((0x4000 + (\adr & 0x3fff)) << 16) + ((\adr >> 14) | 0x10)),\reg
112 .macro HSCROLL_ADDR reg adr
113 move.l #(((0x4000 + (\adr & 0x3fff)) << 16) + (\adr >> 14)),\reg
117 # convert tile coords in d0, d1 to nametable addr to a0
126 # check if some d-pad button (and modifier) is pressed
127 .macro do_dpad bit op val
135 # convert a6 to normal addr
137 .macro mk_a6_addr reg
145 .macro change_mode mode_new mode_back
147 or.w #(\mode_back<<11)|(\mode_new<<8),d7
150 .macro menu_text str x y pal
154 move.l #0x8000|(\pal<<13),d2
158 #################################################
162 #################################################
165 dc.w 0x0000,0x0eee,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000
166 dc.w 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000
167 dc.w 0x0000,0x02e2,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000
168 dc.w 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000
169 dc.w 0x0000,0x0e44,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000
170 dc.w 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000
175 /* Y size link attr X */
176 dc.w 0; dc.b 0x05; dc.b 0; dc.w 0x6002; dc.w 0
180 dc.l 0x000000, 0x200000, 0x400000, 0xa00000, 0xa10000
181 dc.l 0xa11100, 0xa12000, 0xa13000, 0xc00000
185 dc.l 0x000000, 0x7fffff
186 dc.l 0xe00000, 0xffffff
187 dc.l 0xa00000, 0xa163ff /* FIXME */
198 .ascii "Go to address\0"
200 .ascii "Go to (predef)\0"
202 .ascii "DTACK safety\0"
204 ##################################################
208 ##################################################
211 # a6 = page_start[31:8]|cursor_offs[7:0]
212 # d7 = old_inputs[31:16]|edit_bytes[15:14]|g_mode_old[13:11]|g_mode[10:8]|irq_cnt[7:0]
213 # d6 = edit_word_save[31:15]|edit_done[7]|no_dtack_detect[4]|autorep_cnt[3:0]
215 # edit: edit_word[31:8]|edit_pos[4:2]|byte_cnt[1:0]
221 /* mask irqs during init */
248 move.b #0x40,(0xa10009).l
249 move.b #0x40,(0xa10003).l
254 /* Load color data */
257 moveq.l #(colors_end-colors)/2,d0
266 /* generate A layer map */
274 0: move.l #0x00000000,(a0)
280 /* generate B layer map */
285 0: move.l #0x00000000,(a0)
288 /* upload sprite data */
291 movea.l #sprite_data,a1
293 move.l #(sprite_data_end-sprite_data)/2-1,d3
299 ##################################################
308 movem.l d0-d4/a0-a5,-(a7)
314 move.l (jumptab,pc,d0),a0
319 dc.l mode_edit_val /* edit val in editor */
322 dc.l mode_goto_predef
326 ##################### main #######################
333 move.l d0,a1 /* current addr */
336 add.b #27-1,d1 /* line where the cursor sits */
340 move.l #27-1,d5 /* line counter for dbra */
362 # draw unreadable areas
364 bne draw_row_unsafe_words
366 draw_row_unsafe_bytes:
371 move.l #'?'|('?'<<16),(a0)
379 beq draw_cursor_unsafe_byte
380 bra draw_chars_unsafe
382 draw_row_unsafe_words:
387 move.l #'?'|('?'<<16),(a0)
388 move.l #'?'|('?'<<16),(a0)
391 move.l #(' '<<16)|' ',(a0)
396 beq draw_cursor_unsafe_word
399 move.l #'?'|('?'<<16),(a0)
400 move.l #'?'|('?'<<16),(a0)
401 move.l #'?'|('?'<<16),(a0)
402 move.l #'?'|('?'<<16),(a0)
404 move.l #(' '<<16)|' ',(a0)
444 move.l #(' '<<16)|' ',(a0)
466 move.l #(' '<<16)|' ',(a0)
486 jsr get_input /* x0cbrldu x1sa00du */
488 btst.l #16+4,d0 /* A - scroll modifier */
491 do_dpad 16+0, sub, #0x0800
492 do_dpad 16+1, add, #0x0800
493 do_dpad 16+10, sub, #0xd800
494 do_dpad 16+11, add, #0xd800
501 do_dpad 0, subq, #0x0008
502 do_dpad 1, addq, #0x0008
523 btst.l #12,d0 /* B - switch byte/word mode */
526 add.w #0x4000,d7 /* changes between 01 10 */
529 sub.l d1,a6 /* make even, just in case */
532 btst.l #13,d0 /* C - edit selected byte */
535 change_mode MMODE_EDIT_VAL, MMODE_MAIN
536 write_vdp_r_dst 12,(VDP12_SCREEN_V224 | VDP12_SCREEN_H320 | VDP12_STE),(GFXCNTL)
539 btst.l #5,d0 /* Start - menu */
543 change_mode MMODE_START_MENU, MMODE_MAIN
544 write_vdp_r_dst 12,(VDP12_SCREEN_V224 | VDP12_SCREEN_H320 | VDP12_STE),(GFXCNTL)
548 movem.l (a7)+,d0-d4/a0-a5
552 draw_cursor_unsafe_byte:
554 and.l #7,d0 /* byte offs */
557 add.b d1,d0 /* d0 *= 3 (chars) */
561 move.l #(0x2000|'?'|((0x2000|'?')<<16)),(a0)
565 jsr load_prepare /* restore a0 */
566 jmp draw_chars_unsafe
568 draw_cursor_unsafe_word:
570 and.l #7,d0 /* byte offs */
572 lsr.b #1,d1 /* which word */
575 add.b d2,d1 /* num of chars to skip */
580 move.l #(0x2000|'?'|((0x2000|'?')<<16)),d0
586 jsr load_prepare /* restore a0 */
587 jmp draw_chars_unsafe
592 and.l #7,d0 /* byte offs */
598 add.b d1,d0 /* d0 *= 3 (chars) */
606 jsr load_prepare /* restore a0 */
612 and.l #7,d0 /* byte offs */
614 lsr.b #1,d1 /* which word */
617 add.b d2,d1 /* num of chars to skip */
628 jsr load_prepare /* restore a0 */
633 #################### hedit #######################
637 bne mode_hedit_finish
639 /* read val to edit */
655 change_mode MMODE_VAL_INPUT, MMODE_EDIT_VAL
674 ##################### goto #######################
685 or.b #3,d5 /* 3 bytes */
687 change_mode MMODE_VAL_INPUT, MMODE_GOTO
707 ################### val edit #####################
711 movea.l #0xe000+14*2+11*64*2,a1
742 and.b #3,d3 /* edit field bytes */
760 lsr.b #1,d1 /* length in bytes */
764 and.b #7,d1 /* nibble to edit */
768 sub.b #1,d3 /* chars to shift out */
779 jsr get_input /* x0cbrldu x1sa00du */
786 add.b d1,d1 /* nibble count */
787 sub.b #1,d1 /* max n.t.e. val */
790 and.b #7,d2 /* nibble to edit */
802 lsl.l d1,d3 /* mask */
803 lsl.l d1,d4 /* what to add/sub */
848 btst.l #4,d0 /* A - confirm */
851 move.w d7,d1 /* back to prev mode */
861 ################### start menu ###################
868 menu_text txt_about, 13, 9, 1
869 menu_text txt_goto, 13, 11, 0
870 menu_text txt_goto_predef, 13, 12, 0
871 menu_text txt_dtack, 13, 13, 0
872 menu_text txt_a_confirm, 13, 15, 2
874 /* dtack safety on/off */
875 movea.l #0xe000+26*2+13*64*2,a0
877 move.w #0x8000|'O',(a0)
880 move.w #0x8000|'N',(a0)
883 move.w #0x8000|'F',(a0)
884 move.w #0x8000|'F',(a0)
888 movea.l #0xe000+11*2+11*64*2,a0
898 jsr get_input /* x0cbrldu x1sa00du */
907 or.b #1,d2 /* up -1, down 1 */
922 btst.l #4,d0 /* A - confirm */
927 change_mode MMODE_GOTO, MMODE_MAIN
934 change_mode MMODE_GOTO_PREDEF, MMODE_MAIN
954 movea.l #0xe000+10*2+8*64*2,a1
968 ################### goto predef ##################
972 movea.l #0xe000+14*2+8*64*2,a1
973 move.l #predef_addr_cnt+2-1,d1
986 movea.l #0xe000+17*2+9*64*2,a1
988 move.w #predef_addr_cnt-1,d4
999 movea.l #0xe000+15*2+9*64*2,a0
1008 jsr get_input /* x0cbrldu x1sa00du */
1015 or.b #1,d2 /* up -1, down 1 */
1019 move.b #predef_addr_cnt-1,d5
1021 cmp.b #predef_addr_cnt-1,d5
1028 btst.l #4,d0 /* A - confirm */
1036 jmp mode_goto_finish
1048 # go back to main mode
1050 bclr.l #7,d6 /* not edited */
1051 change_mode MMODE_MAIN, MMODE_MAIN
1052 write_vdp_r_dst 12,(VDP12_SCREEN_V224 | VDP12_SCREEN_H320),(GFXCNTL)
1056 #################################################
1058 # Initialize VDP registers #
1060 #################################################
1064 write_vdp_reg 0,(VDP0_E_DISPLAY | VDP0_PLTT_FULL)
1065 write_vdp_reg 1,(VDP1_E_VBI | VDP1_E_DISPLAY | VDP1_E_DMA | VDP1_RESERVED)
1066 write_vdp_reg 2,(0xe000 >> 10) /* Screen map a adress */
1067 write_vdp_reg 3,(0xe000 >> 10) /* Window address */
1068 write_vdp_reg 4,(0xc000 >> 13) /* Screen map b address */
1069 write_vdp_reg 5,(0xfc00 >> 9) /* Sprite address */
1071 write_vdp_reg 7,0 /* Backdrop color */
1072 write_vdp_reg 10,1 /* Lines per hblank interrupt */
1073 write_vdp_reg 11,0 /* 2-cell vertical scrolling */
1074 write_vdp_reg 12,(VDP12_SCREEN_V224 | VDP12_SCREEN_H320)
1075 write_vdp_reg 13,(0x8000 >> 10) /* Horizontal scroll address */
1077 write_vdp_reg 16,(VDP16_MAP_V32 | VDP16_MAP_H64) /* layer size */
1079 write_vdp_reg 18,0xff
1083 # determine if address packed in a6 is safe
1084 # a1 - address to check
1085 # destroys d0-d2, strips upper bits from a1
1091 move.w #(safe_addrs_end - safe_addrs)/8-1,d2
1114 # read single phase from controller
1119 move.b #0x40,(0xa10003)
1123 move.b (0xa10003),d0
1124 move.b #0x00,(0xa10003)
1127 move.b (0xa10003),d0
1132 eor.w d0,d1 /* changed btns */
1133 move.w d0,d7 /* old val */
1135 and.w d0,d1 /* what changed now */
1140 and.b #0x0f,d2 /* do autorepeat */
1151 # Load tile data from ROM
1153 # a1: pattern address
1154 # d0: number of tiles to load
1160 move.l d0,(GFXCNTL).l
1172 # Prepare to write to VDP RAM @a0
1173 # sets a0 to VDP data port for convenience
1179 move.l d0,(GFXCNTL).l
1184 # Load color data from ROM
1186 # a1: color list address
1187 # d0: number of colors to load
1193 move.l d0,(GFXCNTL).l
1208 # d2 - tile_bits[15:11]
1233 # d3 - tile_bits[15:11]|digit_cnt[7:0]
1234 # destroys a0, preserves d3
1245 ror.l d0,d2 /* prep value */
1246 subq.l #1,d1 /* count */
1248 and.w #0xf800,d0 /* keep upper bits in d0 */
1261 dbra d1,_print_hex_loop
1266 #################################################
1268 # Wait for next VBlank interrupt #
1270 #################################################
1281 #################################################
1285 #################################################
1293 # vim:filetype=asmM68k