jmp opt and cleanups
[megadrive.git] / hexed / hexed.s
index ba9de49..ca17291 100644 (file)
@@ -7,6 +7,7 @@
 
 .text
 .globl main
+.globl INT
 .globl VBL
 
 ##################################################
@@ -28,7 +29,7 @@
 .equ VDP1_E_DMA,       0x10
 .equ VDP1_NTSC,                0x00
 .equ VDP1_PAL,         0x08
-.equ VDP1_RESERVED,    0x04
+.equ VDP1_MODE5,       0x04
 
 .equ VDP12_STE,                0x08
 .equ VDP12_SCREEN_V224,        0x00
@@ -51,6 +52,7 @@
 .equ MMODE_GOTO,       3
 .equ MMODE_START_MENU, 4
 .equ MMODE_GOTO_PREDEF,        5
+.equ MMODE_JMP_ADDR,   6
 
 .equ predef_addr_cnt,  ((predef_addrs_end-predef_addrs)/4)
 
        write_vdp_r_dst \reg, \val, (a3)
 .endm
 
-/* For immediate addresses */
-.macro VRAM_ADDR reg adr
-       move.l #(((0x4000 + (\adr & 0x3fff)) << 16) + (\adr >> 14)),\reg
-.endm
-
-.macro CRAM_ADDR reg adr
-       move.l  #(((0xc000 + (\adr & 0x3fff)) << 16) + (\adr >> 14)),\reg
+# Set up address in VDP, control port in dst
+.macro VRAM_ADDR adr dst
+       move.l #(((0x4000 | (\adr & 0x3fff)) << 16) | (\adr >> 14)),\dst
 .endm
 
 
 .endm
 
 
-.macro VSCROLL_ADDR reg adr
-       move.l  #(((0x4000 + (\adr & 0x3fff)) << 16) + ((\adr >> 14) | 0x10)),\reg
-.endm
-
-
-.macro HSCROLL_ADDR reg adr
-       move.l #(((0x4000 + (\adr & 0x3fff)) << 16) + (\adr >> 14)),\reg
-.endm
-
-
 # convert tile coords in d0, d1 to nametable addr to a0
 .macro XY2NT
        lsl.w           #6,d1
@@ -168,6 +156,8 @@ colors:
        dc.w    0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000
        dc.w 0x0000,0x0e44,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000
        dc.w    0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000
+       dc.w 0x0000,0x044e,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000
+       dc.w    0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000
 colors_end:
 
 
@@ -178,14 +168,16 @@ sprite_data_end:
 
 predef_addrs:
        dc.l 0x000000, 0x200000, 0x400000, 0xa00000, 0xa10000
-       dc.l 0xa11100, 0xa12000, 0xa13000, 0xc00000
+       dc.l 0xa11100, 0xa12000, 0xa13000, 0xa14000, 0xc00000
 predef_addrs_end:
 
 safe_addrs:
        dc.l 0x000000, 0x7fffff
        dc.l 0xe00000, 0xffffff
-       dc.l 0xa00000, 0xa163ff         /* FIXME */
-       /* TODO: VDP */
+       dc.l 0xa00000, 0xa100ff
+       dc.l 0xa11000, 0xa113ff
+       dc.l 0xa12000, 0xa120ff
+       dc.l 0xa13000, 0xa130ff
 safe_addrs_end:
 
 txt_edit:
@@ -198,8 +190,14 @@ txt_goto:
        .ascii  "Go to address\0"
 txt_goto_predef:
        .ascii  "Go to (predef)\0"
+txt_jmp_addr:
+       .ascii  "Jump to address\0"
 txt_dtack:
        .ascii  "DTACK safety\0"
+txt_dtack_err:
+       .ascii  "DTACK err?\0"
+txt_exc:
+       .ascii  "Exception \0"
 
 ##################################################
 #                                                #
@@ -257,11 +255,24 @@ main:
        moveq.l         #(colors_end-colors)/2,d0
        jsr             load_colors
 
-       /* load patterns */
-       movea.l         #0,a0
-       movea.l         #font,a1
-       move.l          #128,d0
-       jsr             load_tiles
+       /* load font patterns */
+       lea             GFXDATA,a0
+       lea             font,a1
+       VRAM_ADDR       0,(GFXCNTL)
+       move.w          #128*8,d3
+font_loop:
+       moveq.l         #8-1,d2
+       moveq.l         #0,d1
+       move.b          (a1)+,d0
+0:
+       lsr.b           #1,d0
+       roxl.l          #1,d1
+       ror.l           #5,d1
+       dbra            d2,0b
+
+       rol.l           #1,d1           /* fixup */
+       move.l          d1,(a0)
+       dbra            d3,font_loop
 
        /* generate A layer map */
        movea.l         #0xe000,a1
@@ -294,6 +305,15 @@ lmaploop0:
 0:     move.l          (a1)+,(a0)
        dbra            d3,0b
 
+       /* wait for vsync before unmask */
+       move.l          #GFXCNTL,a3
+0:
+       move.w          (a3),d0
+       and.b           #8,d0
+       nop
+       nop
+       beq             0b
+
         move.w         #0x2000,sr
 
 ##################################################
@@ -303,9 +323,20 @@ forever:
        bra             forever
 
 
+INT:
+       /* let's hope VRAM is already set up.. */
+       lea             txt_exc,a0
+       move.l          #9,d0
+       move.l          #27,d1
+       move.l          #0xe000,d2
+       jsr             print
+       bra             forever
+
+##################################################
+
 VBL:
        addq.b          #1,d7
-       movem.l         d0-d4/a0-a5,-(a7)
+#      movem.l         d0-d4/a0-a5,-(a7)
 
        moveq.l         #0,d0
        move.w          d7,d0
@@ -320,13 +351,20 @@ jumptab:
        dc.l            mode_goto
        dc.l            mode_start_menu
        dc.l            mode_goto_predef
-       dc.l            mode_main
+       dc.l            mode_jmp_addr
        dc.l            mode_main
 
 ##################### main #######################
 
 mode_main:
-       clr.l           d1
+       /* assume we will hang */
+       lea             txt_dtack_err,a0
+       move.l          #9,d0
+       move.l          #27,d1
+       move.l          #0xe000,d2
+       jsr             print
+
+       moveq.l         #0,d1
        move.l          a6,d0
        move.b          d0,d1
        lsr.l           #8,d0
@@ -356,20 +394,41 @@ draw_row:
        btst.l          #4,d6
        bne             draw_row_safe
 
-       bsr             is_addr_safe
-       bne             draw_row_safe
+       bsr             get_safety_mask
+       cmp.b           #0xf,d0
+       beq             draw_row_safe
 
-# draw unreadable areas
+# unsafe or partially safe
+draw_row_hsafe:
+       move.l          d0,d4
+       swap            d4              /* mask in upper word */
        btst.l          #15,d7
-       bne             draw_row_unsafe_words
+       bne             draw_row_hsafe_words_pre
 
-draw_row_unsafe_bytes:
+draw_row_hsafe_bytes_pre:
        /* 8 bytes */
-       moveq.l         #8-1,d4
-0:
+       moveq.l         #2,d3
+       move.w          #3,d4
+
+draw_row_hsafe_bytes:
+       move.w          #' ',(a0)
+       move.b          d4,d0
+       add.b           #16,d0
+       btst.l          d0,d4
+       bne             0f
+       move.l          #'?'|('?'<<16),(a0)
        move.w          #' ',(a0)
        move.l          #'?'|('?'<<16),(a0)
-       dbra            d4,0b
+       bra             1f
+0:
+       move.b          (0,a1),d2
+       jsr             print_hex_preped
+       move.w          #' ',(a0)
+       move.b          (1,a1),d2
+       jsr             print_hex_preped
+1:
+       addq.l          #2,a1
+       dbra            d4,draw_row_hsafe_bytes
 
        move.w          #' ',(a0)
 
@@ -377,16 +436,28 @@ draw_row_unsafe_bytes:
        swap            d0
        cmp.w           d5,d0
        beq             draw_cursor_unsafe_byte
-       bra             draw_chars_unsafe
+       bra             draw_chars_hsafe_pre
 
-draw_row_unsafe_words:
+draw_row_hsafe_words_pre:
        /* 4 shorts */
-       moveq.l         #4-1,d4
-0:
+       moveq.l         #4,d3
+       move.w          #3,d4
+
+draw_row_hsafe_words:
        move.w          #' ',(a0)
+       move.b          d4,d0
+       add.b           #16,d0
+       btst.l          d0,d4
+       bne             0f
        move.l          #'?'|('?'<<16),(a0)
        move.l          #'?'|('?'<<16),(a0)
-       dbra            d4,0b
+       bra             1f
+0:
+       move.w          (a1),d2
+       jsr             print_hex_preped
+1:
+       addq.l          #2,a1
+       dbra            d4,draw_row_hsafe_words
 
        move.l          #(' '<<16)|' ',(a0)
 
@@ -395,14 +466,52 @@ draw_row_unsafe_words:
        cmp.w           d5,d0
        beq             draw_cursor_unsafe_word
 
-draw_chars_unsafe:
-       move.l          #'?'|('?'<<16),(a0)
-       move.l          #'?'|('?'<<16),(a0)
-       move.l          #'?'|('?'<<16),(a0)
+draw_chars_hsafe_pre:
+       subq.l          #8,a1
+       move.w          #3,d4
+       moveq.l         #0,d0
+
+draw_chars_hsafe:
+       move.b          d4,d0
+       add.b           #16,d0
+       btst.l          d0,d4
+       bne             0f
        move.l          #'?'|('?'<<16),(a0)
+       bra             draw_chars_hsafe_next
+0:
+       btst.l          #15,d7          /* must perform correct read type */
+       bne             0f              /* doing byte reads on security reg hangs */
+       move.b          (0,a1),d0
+       lsl.l           #8,d0
+       move.b          (1,a1),d0
+       bra             1f
+0:
+       move.w          (a1),d0
+1:
+       ror.l           #8,d0
+       move.b          d0,d1
+       sub.b           #0x20,d1
+       cmp.b           #0x60,d1
+       blo             0f
+       move.b          #'.',d0
+0:
+       move.w          d0,(a0)
+
+       move.b          #0,d0
+       rol.l           #8,d0
+       move.b          d0,d1
+       sub.b           #0x20,d1
+       cmp.b           #0x60,d1
+       blo             0f
+       move.b          #'.',d0
+0:
+       move.w          d0,(a0)
+
+draw_chars_hsafe_next:
+       addq.l          #2,a1
+       dbra            d4,draw_chars_hsafe
 
        move.l          #(' '<<16)|' ',(a0)
-       addq.l          #8,a1
        add.w           #0x80,a2
        dbra            d5,draw_row
        bra             draw_status_bar
@@ -468,6 +577,7 @@ draw_chars:
        add.w           #0x80,a2
        dbra            d5,draw_row
 
+
 draw_status_bar:
        /* status bar */
        move.l          a2,a0
@@ -480,7 +590,14 @@ draw_status_bar:
        mk_a6_addr      d2
        move.l          #0x4006,d3
        jsr             print_hex_preped
-       move.w          #' ',(a0)
+
+       /* clear error */
+       moveq.l         #5-1,d0
+0:
+       move.l          #' '|(' '<<16),(a0)
+       move.l          #' '|(' '<<16),(a0)
+       dbra            d0,0b
+
 
        /* handle input */
        jsr             get_input               /* x0cbrldu x1sa00du */
@@ -545,7 +662,7 @@ input_noc:
 
 input_nos:
 vbl_end:
-       movem.l         (a7)+,d0-d4/a0-a5
+#      movem.l         (a7)+,d0-d4/a0-a5
        rte
 
 
@@ -563,7 +680,7 @@ draw_cursor_unsafe_byte:
        move.l          a2,a0
        add.w           #31*2,a0
        jsr             load_prepare    /* restore a0 */
-       jmp             draw_chars_unsafe
+       jmp             draw_chars_hsafe_pre
 
 draw_cursor_unsafe_word:
        move.l          a6,d0
@@ -584,7 +701,7 @@ draw_cursor_unsafe_word:
        move.l          a2,a0
        add.w           #29*2,a0
        jsr             load_prepare    /* restore a0 */
-       jmp             draw_chars_unsafe
+       jmp             draw_chars_hsafe_pre
 
 
 draw_cursor_byte:
@@ -868,11 +985,12 @@ mode_start_menu:
        menu_text       txt_about,       13,  9, 1
        menu_text       txt_goto,        13, 11, 0
        menu_text       txt_goto_predef, 13, 12, 0
-       menu_text       txt_dtack,       13, 13, 0
-       menu_text       txt_a_confirm,   13, 15, 2
+       menu_text       txt_jmp_addr,    13, 13, 0
+       menu_text       txt_dtack,       13, 14, 0
+       menu_text       txt_a_confirm,   13, 16, 2
 
        /* dtack safety on/off */
-       movea.l         #0xe000+26*2+13*64*2,a0
+       movea.l         #0xe000+26*2+14*64*2,a0
        jsr             load_prepare
        move.w          #0x8000|'O',(a0)
        btst.l          #4,d6
@@ -908,9 +1026,9 @@ mode_start_menu:
        add.b           d2,d1
        cmp.b           #0,d1
        bge             0f
-       move.b          #2,d1
+       move.b          #3,d1
 0:
-       cmp.b           #2,d1
+       cmp.b           #3,d1
        ble             0f
        move.b          #0,d1
 0:
@@ -937,6 +1055,12 @@ msm_no_ud:
 0:
        cmp.b           #2,d1
        bne             0f
+       change_mode     MMODE_JMP_ADDR, MMODE_MAIN
+       bsr             start_menu_box
+       jmp             vbl_end
+0:
+       cmp.b           #3,d1
+       bne             0f
        bchg.l          #4,d6
        jmp             vbl_end
 0:
@@ -952,7 +1076,7 @@ msm_no_bc:
 
 start_menu_box:
        movea.l         #0xe000+10*2+8*64*2,a1
-       move.w          #9-1,d1
+       move.w          #10-1,d1
 0:
        move.w          a1,a0
        jsr             load_prepare
@@ -1044,6 +1168,24 @@ mgp_no_a:
 mgp_no_bc:
        jmp             vbl_end
 
+##################### jmp ########################
+
+mode_jmp_addr:
+       btst.l          #7,d6
+       bne             mode_jmp_finish
+
+       moveq.l         #0,d5
+       or.b            #3,d5           /* 3 bytes */
+       bclr.l          #7,d6
+       change_mode     MMODE_VAL_INPUT, MMODE_JMP_ADDR
+       jmp             vbl_end
+
+mode_jmp_finish:
+       lsr.l           #8,d5
+       write_vdp_r_dst 1,(VDP1_E_DISPLAY | VDP1_MODE5),(GFXCNTL)       /* disable vint */
+       move.l          d5,a0
+       jmp             (a0)
+
 
 # go back to main mode
 return_to_main:
@@ -1062,7 +1204,7 @@ return_to_main:
 init_gfx:
        move.l          #GFXCNTL,a3
        write_vdp_reg   0,(VDP0_E_DISPLAY | VDP0_PLTT_FULL)
-       write_vdp_reg   1,(VDP1_E_VBI | VDP1_E_DISPLAY | VDP1_E_DMA | VDP1_RESERVED)
+       write_vdp_reg   1,(VDP1_E_VBI | VDP1_E_DISPLAY | VDP1_MODE5)
        write_vdp_reg   2,(0xe000 >> 10)        /* Screen map a adress */
        write_vdp_reg   3,(0xe000 >> 10)        /* Window address */
        write_vdp_reg   4,(0xc000 >> 13)        /* Screen map b address */
@@ -1080,10 +1222,10 @@ init_gfx:
        rts
 
 
-# determine if address packed in a6 is safe
+# get mask of bits representing safe words
 #  a1 - address to check
 #  destroys d0-d2, strips upper bits from a1
-is_addr_safe:
+get_safety_mask:
        move.l          a1,d1
        lsl.l           #8,d1
        lsr.l           #8,d1
@@ -1100,14 +1242,48 @@ is_addr_safe:
        addq.l          #4,a1
        dbra            d2,0b
 
-addr_unsafe:
        move.l          d1,a1
-       moveq.l         #0,d0
+
+       moveq.l         #0x0c,d0
+       cmp.l           #0xa14000,d1
+       beq             gsm_rts
+
+       moveq.l         #0x08,d0
+       cmp.l           #0xa14100,d1
+       beq             gsm_rts
+
+       /* check for VDP address */
+       move.l          d1,d0
+       swap            d0
+       and.b           #0xe0,d0
+       cmp.b           #0xc0,d0
+       bne             addr_unsafe     /* not vdp */
+
+       move.l          d1,d0
+       and.l           #0x0700e0,d0
+       bne             addr_unsafe
+
+       move.l          d1,d0
+       and.b           #0x1f,d0
+       cmp.b           #0x04,d0
+       blt             addr_hsafe_3    /* data port */
+       cmp.b           #0x10,d0
+       blt             addr_safe       /* below PSG */
+       cmp.b           #0x18,d0
+       bge             addr_safe       /* above PSG */
+
+addr_unsafe:
+       moveq.l         #0,d0           /* skip line */
+       rts
+
+addr_hsafe_3:
+       moveq.l         #3,d0           /* skip 2 words */
        rts
 
 addr_safe:
        move.l          d1,a1
-       moveq.l         #1,d0
+       moveq.l         #0xf,d0
+gsm_rts:
        rts
 
 
@@ -1148,27 +1324,6 @@ get_input:
        move.w          d1,d0
        rts
 
-# Load tile data from ROM
-#  a0: VRAM base
-#  a1: pattern address
-#  d0: number of tiles to load
-#  destroys d1
-
-load_tiles:
-       move.l          d0,d1
-       VRAM_ADDR_var   a0
-       move.l          d0,(GFXCNTL).l
-       
-       move.l          #GFXDATA,a0
-       lsl.w           #3,d1
-       subq.l          #1,d1
-0:
-       move.l          (a1)+,(a0)
-       dbra            d1,0b
-
-       rts
-
-
 # Prepare to write to VDP RAM @a0
 # sets a0 to VDP data port for convenience
 #  a0: VRAM base
@@ -1263,11 +1418,7 @@ _print_hex_loop:
        rts
 
 
-#################################################
-#                                               #
-#       Wait for next VBlank interrupt          #
-#                                               #
-#################################################
+# wait vertical sync
 
 wait_vsync:
        move.b          d7,d0