1 ##################################################
4 # --register-prefix-optional --bitwise-or #
6 ##################################################
13 ##################################################
15 # Register and bitmask definitions #
17 ##################################################
19 .equ GFXDATA, 0xc00000
20 .equ GFXCNTL, 0xc00004
23 .equ VDP0_E_DISPLAY, 0x02
24 .equ VDP0_PLTT_FULL, 0x04
26 .equ VDP1_SMS_MODE, 0x80
27 .equ VDP1_E_DISPLAY, 0x40
35 .equ VDP12_SCREEN_V224, 0x00
36 .equ VDP12_SCREEN_V448, 0x04
37 .equ VDP12_PROGRESSIVE, 0x00
38 .equ VDP12_INTERLACED, 0x02
39 .equ VDP12_SCREEN_H256, 0x00
40 .equ VDP12_SCREEN_H320, 0x81
42 .equ VDP16_MAP_V32, 0x00
43 .equ VDP16_MAP_V64, 0x10
44 .equ VDP16_MAP_V128, 0x30
45 .equ VDP16_MAP_H32, 0x00
46 .equ VDP16_MAP_H64, 0x01
47 .equ VDP16_MAP_H128, 0x03
50 .equ MMODE_VAL_INPUT, 1
51 .equ MMODE_EDIT_VAL, 2
53 .equ MMODE_START_MENU, 4
54 .equ MMODE_GOTO_PREDEF, 5
55 .equ MMODE_JMP_ADDR, 6
57 .equ predef_addr_cnt, ((predef_addrs_end-predef_addrs)/4)
59 ##################################################
63 ##################################################
66 # Write val to VDP register reg
67 .macro write_vdp_r_dst reg val dst
68 move.w #((\reg << 8) + 0x8000 + \val),\dst
71 # Write val to VDP register reg, vdp addr in a3
72 .macro write_vdp_reg reg val
73 write_vdp_r_dst \reg, \val, (a3)
76 # Set up address in VDP, control port in dst
77 .macro VRAM_ADDR adr dst
78 move.l #(((0x4000 | (\adr & 0x3fff)) << 16) | (\adr >> 14)),\dst
82 # make VDP word from address adr and store in d0
83 .macro XRAM_ADDR_var adr
93 .macro VRAM_ADDR_var adr
99 .macro CRAM_ADDR_var adr
105 # convert tile coords in d0, d1 to nametable addr to a0
114 # check if some d-pad button (and modifier) is pressed
115 .macro do_dpad bit op val
123 # convert a6 to normal addr
125 .macro mk_a6_addr reg
133 .macro change_mode mode_new mode_back
135 or.w #(\mode_back<<11)|(\mode_new<<8),d7
138 .macro menu_text str x y pal
142 move.l #0x8000|(\pal<<13),d2
146 #################################################
150 #################################################
153 dc.w 0x0000,0x0eee,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000
154 dc.w 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000
155 dc.w 0x0000,0x02e2,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000
156 dc.w 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000
157 dc.w 0x0000,0x0e44,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000
158 dc.w 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000
159 dc.w 0x0000,0x044e,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000
160 dc.w 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000
165 /* Y size link attr X */
166 dc.w 0; dc.b 0x05; dc.b 0; dc.w 0x6002; dc.w 0
170 dc.l 0x000000, 0x200000, 0x400000, 0xa00000, 0xa10000
171 dc.l 0xa11100, 0xa12000, 0xa13000, 0xa14000, 0xc00000
175 dc.l 0x000000, 0x7fffff
176 dc.l 0xe00000, 0xffffff
177 dc.l 0xa00000, 0xa100ff
178 dc.l 0xa11000, 0xa113ff
179 dc.l 0xa12000, 0xa120ff
180 dc.l 0xa13000, 0xa130ff
190 .ascii "Go to address\0"
192 .ascii "Go to (predef)\0"
194 .ascii "Jump to address\0"
196 .ascii "DTACK safety\0"
198 .ascii "DTACK err?\0"
200 .ascii "Exception \0"
202 ##################################################
206 ##################################################
209 # a6 = page_start[31:8]|cursor_offs[7:0]
210 # d7 = old_inputs[31:16]|edit_bytes[15:14]|g_mode_old[13:11]|g_mode[10:8]|irq_cnt[7:0]
211 # d6 = edit_word_save[31:15]|edit_done[7]|no_dtack_detect[4]|autorep_cnt[3:0]
213 # edit: edit_word[31:8]|edit_pos[4:2]|byte_cnt[1:0]
219 /* mask irqs during init */
246 move.b #0x40,(0xa10009).l
247 move.b #0x40,(0xa10003).l
252 /* Load color data */
255 moveq.l #(colors_end-colors)/2,d0
258 /* load font patterns */
261 VRAM_ADDR 0,(GFXCNTL)
273 rol.l #1,d1 /* fixup */
277 /* generate A layer map */
285 0: move.l #0x00000000,(a0)
291 /* generate B layer map */
296 0: move.l #0x00000000,(a0)
299 /* upload sprite data */
302 movea.l #sprite_data,a1
304 move.l #(sprite_data_end-sprite_data)/2-1,d3
308 /* wait for vsync before unmask */
319 ##################################################
327 /* let's hope VRAM is already set up.. */
335 ##################################################
339 # movem.l d0-d4/a0-a5,-(a7)
345 move.l (jumptab,pc,d0),a0
350 dc.l mode_edit_val /* edit val in editor */
353 dc.l mode_goto_predef
357 ##################### main #######################
360 /* assume we will hang */
371 move.l d0,a1 /* current addr */
374 add.b #27-1,d1 /* line where the cursor sits */
378 move.l #27-1,d5 /* line counter for dbra */
401 # unsafe or partially safe
404 swap d4 /* mask in upper word */
406 bne draw_row_hsafe_words_pre
408 draw_row_hsafe_bytes_pre:
413 draw_row_hsafe_bytes:
419 move.l #'?'|('?'<<16),(a0)
421 move.l #'?'|('?'<<16),(a0)
431 dbra d4,draw_row_hsafe_bytes
438 beq draw_cursor_unsafe_byte
439 bra draw_chars_hsafe_pre
441 draw_row_hsafe_words_pre:
446 draw_row_hsafe_words:
452 move.l #'?'|('?'<<16),(a0)
453 move.l #'?'|('?'<<16),(a0)
460 dbra d4,draw_row_hsafe_words
462 move.l #(' '<<16)|' ',(a0)
467 beq draw_cursor_unsafe_word
469 draw_chars_hsafe_pre:
479 move.l #'?'|('?'<<16),(a0)
480 bra draw_chars_hsafe_next
482 btst.l #15,d7 /* must perform correct read type */
483 bne 0f /* doing byte reads on security reg hangs */
510 draw_chars_hsafe_next:
512 dbra d4,draw_chars_hsafe
514 move.l #(' '<<16)|' ',(a0)
553 move.l #(' '<<16)|' ',(a0)
575 move.l #(' '<<16)|' ',(a0)
597 move.l #' '|(' '<<16),(a0)
598 move.l #' '|(' '<<16),(a0)
603 jsr get_input /* x0cbrldu x1sa00du */
605 btst.l #16+4,d0 /* A - scroll modifier */
608 do_dpad 16+0, sub, #0x0800
609 do_dpad 16+1, add, #0x0800
610 do_dpad 16+10, sub, #0xd800
611 do_dpad 16+11, add, #0xd800
618 do_dpad 0, subq, #0x0008
619 do_dpad 1, addq, #0x0008
640 btst.l #12,d0 /* B - switch byte/word mode */
643 add.w #0x4000,d7 /* changes between 01 10 */
646 sub.l d1,a6 /* make even, just in case */
649 btst.l #13,d0 /* C - edit selected byte */
652 change_mode MMODE_EDIT_VAL, MMODE_MAIN
653 write_vdp_r_dst 12,(VDP12_SCREEN_V224 | VDP12_SCREEN_H320 | VDP12_STE),(GFXCNTL)
656 btst.l #5,d0 /* Start - menu */
660 change_mode MMODE_START_MENU, MMODE_MAIN
661 write_vdp_r_dst 12,(VDP12_SCREEN_V224 | VDP12_SCREEN_H320 | VDP12_STE),(GFXCNTL)
665 # movem.l (a7)+,d0-d4/a0-a5
669 draw_cursor_unsafe_byte:
671 and.l #7,d0 /* byte offs */
674 add.b d1,d0 /* d0 *= 3 (chars) */
678 move.l #(0x2000|'?'|((0x2000|'?')<<16)),(a0)
682 jsr load_prepare /* restore a0 */
683 jmp draw_chars_hsafe_pre
685 draw_cursor_unsafe_word:
687 and.l #7,d0 /* byte offs */
689 lsr.b #1,d1 /* which word */
692 add.b d2,d1 /* num of chars to skip */
697 move.l #(0x2000|'?'|((0x2000|'?')<<16)),d0
703 jsr load_prepare /* restore a0 */
704 jmp draw_chars_hsafe_pre
709 and.l #7,d0 /* byte offs */
715 add.b d1,d0 /* d0 *= 3 (chars) */
723 jsr load_prepare /* restore a0 */
729 and.l #7,d0 /* byte offs */
731 lsr.b #1,d1 /* which word */
734 add.b d2,d1 /* num of chars to skip */
745 jsr load_prepare /* restore a0 */
750 #################### hedit #######################
754 bne mode_hedit_finish
756 /* read val to edit */
772 change_mode MMODE_VAL_INPUT, MMODE_EDIT_VAL
791 ##################### goto #######################
802 or.b #3,d5 /* 3 bytes */
804 change_mode MMODE_VAL_INPUT, MMODE_GOTO
824 ################### val edit #####################
828 movea.l #0xe000+14*2+11*64*2,a1
859 and.b #3,d3 /* edit field bytes */
877 lsr.b #1,d1 /* length in bytes */
881 and.b #7,d1 /* nibble to edit */
885 sub.b #1,d3 /* chars to shift out */
896 jsr get_input /* x0cbrldu x1sa00du */
903 add.b d1,d1 /* nibble count */
904 sub.b #1,d1 /* max n.t.e. val */
907 and.b #7,d2 /* nibble to edit */
919 lsl.l d1,d3 /* mask */
920 lsl.l d1,d4 /* what to add/sub */
965 btst.l #4,d0 /* A - confirm */
968 move.w d7,d1 /* back to prev mode */
978 ################### start menu ###################
985 menu_text txt_about, 13, 9, 1
986 menu_text txt_goto, 13, 11, 0
987 menu_text txt_goto_predef, 13, 12, 0
988 menu_text txt_jmp_addr, 13, 13, 0
989 menu_text txt_dtack, 13, 14, 0
990 menu_text txt_a_confirm, 13, 16, 2
992 /* dtack safety on/off */
993 movea.l #0xe000+26*2+14*64*2,a0
995 move.w #0x8000|'O',(a0)
998 move.w #0x8000|'N',(a0)
1001 move.w #0x8000|'F',(a0)
1002 move.w #0x8000|'F',(a0)
1006 movea.l #0xe000+11*2+11*64*2,a0
1016 jsr get_input /* x0cbrldu x1sa00du */
1025 or.b #1,d2 /* up -1, down 1 */
1040 btst.l #4,d0 /* A - confirm */
1045 change_mode MMODE_GOTO, MMODE_MAIN
1052 change_mode MMODE_GOTO_PREDEF, MMODE_MAIN
1058 change_mode MMODE_JMP_ADDR, MMODE_MAIN
1078 movea.l #0xe000+10*2+8*64*2,a1
1092 ################### goto predef ##################
1096 movea.l #0xe000+14*2+8*64*2,a1
1097 move.l #predef_addr_cnt+2-1,d1
1109 /* draw addresses */
1110 movea.l #0xe000+17*2+9*64*2,a1
1112 move.w #predef_addr_cnt-1,d4
1118 jsr print_hex_preped
1123 movea.l #0xe000+15*2+9*64*2,a0
1132 jsr get_input /* x0cbrldu x1sa00du */
1139 or.b #1,d2 /* up -1, down 1 */
1143 move.b #predef_addr_cnt-1,d5
1145 cmp.b #predef_addr_cnt-1,d5
1152 btst.l #4,d0 /* A - confirm */
1160 jmp mode_goto_finish
1171 ##################### jmp ########################
1178 or.b #3,d5 /* 3 bytes */
1180 change_mode MMODE_VAL_INPUT, MMODE_JMP_ADDR
1185 write_vdp_r_dst 1,(VDP1_E_DISPLAY | VDP1_MODE5),(GFXCNTL) /* disable vint */
1190 # go back to main mode
1192 bclr.l #7,d6 /* not edited */
1193 change_mode MMODE_MAIN, MMODE_MAIN
1194 write_vdp_r_dst 12,(VDP12_SCREEN_V224 | VDP12_SCREEN_H320),(GFXCNTL)
1198 #################################################
1200 # Initialize VDP registers #
1202 #################################################
1206 write_vdp_reg 0,(VDP0_E_DISPLAY | VDP0_PLTT_FULL)
1207 write_vdp_reg 1,(VDP1_E_VBI | VDP1_E_DISPLAY | VDP1_MODE5)
1208 write_vdp_reg 2,(0xe000 >> 10) /* Screen map a adress */
1209 write_vdp_reg 3,(0xe000 >> 10) /* Window address */
1210 write_vdp_reg 4,(0xc000 >> 13) /* Screen map b address */
1211 write_vdp_reg 5,(0xfc00 >> 9) /* Sprite address */
1213 write_vdp_reg 7,0 /* Backdrop color */
1214 write_vdp_reg 10,1 /* Lines per hblank interrupt */
1215 write_vdp_reg 11,0 /* 2-cell vertical scrolling */
1216 write_vdp_reg 12,(VDP12_SCREEN_V224 | VDP12_SCREEN_H320)
1217 write_vdp_reg 13,(0x8000 >> 10) /* Horizontal scroll address */
1219 write_vdp_reg 16,(VDP16_MAP_V32 | VDP16_MAP_H64) /* layer size */
1221 write_vdp_reg 18,0xff
1225 # get mask of bits representing safe words
1226 # a1 - address to check
1227 # destroys d0-d2, strips upper bits from a1
1233 move.w #(safe_addrs_end - safe_addrs)/8-1,d2
1255 /* check for VDP address */
1260 bne addr_unsafe /* not vdp */
1269 blt addr_hsafe_3 /* data port */
1271 blt addr_safe /* below PSG */
1273 bge addr_safe /* above PSG */
1276 moveq.l #0,d0 /* skip line */
1280 moveq.l #3,d0 /* skip 2 words */
1290 # read single phase from controller
1295 move.b #0x40,(0xa10003)
1299 move.b (0xa10003),d0
1300 move.b #0x00,(0xa10003)
1303 move.b (0xa10003),d0
1308 eor.w d0,d1 /* changed btns */
1309 move.w d0,d7 /* old val */
1311 and.w d0,d1 /* what changed now */
1316 and.b #0x0f,d2 /* do autorepeat */
1327 # Prepare to write to VDP RAM @a0
1328 # sets a0 to VDP data port for convenience
1334 move.l d0,(GFXCNTL).l
1339 # Load color data from ROM
1341 # a1: color list address
1342 # d0: number of colors to load
1348 move.l d0,(GFXCNTL).l
1363 # d2 - tile_bits[15:11]
1388 # d3 - tile_bits[15:11]|digit_cnt[7:0]
1389 # destroys a0, preserves d3
1400 ror.l d0,d2 /* prep value */
1401 subq.l #1,d1 /* count */
1403 and.w #0xf800,d0 /* keep upper bits in d0 */
1416 dbra d1,_print_hex_loop
1421 # wait vertical sync
1432 #################################################
1436 #################################################
1444 # vim:filetype=asmM68k