testpico: show that vres clear is separate
[megadrive.git] / hexed / transfer.S
index 4ab3aff..ef5bf5d 100644 (file)
@@ -92,6 +92,18 @@ recv_byte:
        recv_one_byte 1
        rts
 
+# receive 1 16bit word to d0
+#  in: a1 - data port
+#  trash: d1,d2
+recv_word:
+       recv_one_byte
+       move.b          d0,d2
+       recv_one_byte
+       lsl.w           #8,d2
+       move.b          d0,d2
+       move.w          d2,d0
+       rts
+
 # receive address/size to d0 (3 bytes BE)
 #  in: a1 - data port
 #  trash: d1,d2
@@ -108,6 +120,58 @@ recv_ad:
        move.l          d2,d0
        rts
 
+# send 1 byte in d0
+#  in: a1 - data port
+#  trash: d1,d2
+send_byte:
+       send_one_byte
+       rts
+
+.macro switch_to_output
+0: /*Lwait_tl_low: PC should switch to rx mode before lowering tl */
+       move.b          (a1),d0
+       btst.b          #4,d0
+       bne             0b /*Lwait_tl_low*/
+
+       move.b          #0x4f,(0xa1000b).l
+       move.b          #0x40,(a1)
+.endm
+
+.equ sat_maxsize, (80*8+0x200) /* sprites+max_align */
+
+# make sure cache is invalidated
+# note: VRAM copy doesn't seem to help here
+# note2: cache is updated as data is written
+#  in: d0 - vdp reg5, a0 = 0xc00000
+#  trash: d1,d2,a2
+invalidate_sprite_cache:
+       move.w          #0x8f02,4(a0)           /* auto increment 2 */
+       lsl.b           #1,d0                   /* upper byte of sat address */
+       move.b          d0,d1
+       lsr.b           #6,d1                   /* 15:14 dst addr */
+       and.b           #0x3f,d0                /* assemble cmd */
+       lsl.w           #8,d0
+       swap            d0
+       move.b          d1,d0
+       move.l          d0,4(a0)
+
+       move.l          #0xffe000,a2
+       move.l          #sat_maxsize/2-1,d2
+0:
+       move.w          (a0),(a2)+
+       dbra            d2,0b
+
+       bset            #30,d0                  /* VRAM write */
+       move.l          d0,4(a0)
+
+       move.l          #0xffe000,a2
+       move.l          #sat_maxsize/2-1,d2
+0:
+       move.w          (a2)+,(a0)
+       dbra            d2,0b
+       rts
+
+
 
 do_transfer:
        lea             0xa10005,a1
@@ -132,9 +196,13 @@ jumptab:
        bra             pcc_transfer_recv       /* sent to us */
        bra             pcc_transfer_send       /* recv from us */
        bra             pcc_jump
+       bra             pcc_io
+       bra             pcc_loadstate
+       bra             pcc_vram_send
        bra             pcc_test_code
 
 
+/* receive data from PC */
 pcc_transfer_recv:
        bsr             recv_ad
        move.l          d0,a0
@@ -149,19 +217,14 @@ tr_recv_loop:
        bra             return
 
 
+/* send data to PC */
 pcc_transfer_send:
        bsr             recv_ad
        move.l          d0,a0
        bsr             recv_ad
        move.l          d0,d3
 
-0: /*Lwait_tl_low:*/
-       move.b          (a1),d0
-       btst.b          #4,d0
-       bne             0b /*Lwait_tl_low*/
-
-       move.b          #0x4f,(0xa1000b).l
-       move.b          #0x40,(a1)
+       switch_to_output
 
 tr_send_loop:
        move.b          (a0)+,d0
@@ -171,16 +234,204 @@ tr_send_loop:
        bra             return
 
 
+/* call specified location */
 pcc_jump:
        bsr             recv_ad
        move.l          d0,a0
-       jmp             (a0)
+       jsr             (a0)
+       bra             return
+
 
+/* do simple i/o commands */
+pcc_io:
+       moveq.l         #0,d4
+       bsr             recv_byte
+       move.b          d0,d4
+       bsr             recv_byte
+       lsl.l           #8,d4
+       move.b          d0,d4
 
+pcc_io_loop:
+       move.b          #0x40,(0xa1000b).l      /* input mode */
+
+       sub.w           #1,d4
+       bmi             return
+
+       bsr             recv_byte
+       move.b          d0,d3                   /* cmd */
+
+       bsr             recv_ad
+       move.l          d0,a2                   /* addr */
+
+       cmp.b           #IOSEQ_W32, d3
+       beq             pcc_io_w32
+       cmp.b           #IOSEQ_W16, d3
+       beq             pcc_io_w16
+       cmp.b           #IOSEQ_W8, d3
+       bne             pcc_io_rx
+
+pcc_io_w8:
+       bsr             recv_byte
+       move.b          d0,(a2)
+       bra             pcc_io_loop
+
+pcc_io_w16:
+       bsr             recv_byte
+       move.b          d0,d3
+       bsr             recv_byte
+       lsl.w           #8,d3
+       move.b          d0,d3
+       move.w          d3,(a2)
+       bra             pcc_io_loop
+
+pcc_io_w32:
+       bsr             recv_byte
+       move.b          d0,d3
+       bsr             recv_byte
+       lsl.w           #8,d3
+       move.b          d0,d3
+       bsr             recv_byte
+       lsl.l           #8,d3
+       move.b          d0,d3
+       bsr             recv_byte
+       lsl.l           #8,d3
+       move.b          d0,d3
+       move.l          d3,(a2)
+       bra             pcc_io_loop
+
+pcc_io_rx:
+       switch_to_output
+
+       cmp.b           #IOSEQ_R32, d3
+       beq             pcc_io_r32
+       cmp.b           #IOSEQ_R16, d3
+       beq             pcc_io_r16
+       cmp.b           #IOSEQ_R8, d3
+       bne             return
+
+pcc_io_r8:
+       move.b          (a2),d0
+       bsr             send_byte
+       bra             pcc_io_loop
+
+pcc_io_r16:
+       move.w          (a2),d3
+       move.w          d3,d0
+       lsr.w           #8,d0
+       bsr             send_byte
+       move.b          d3,d0
+       bsr             send_byte
+       bra             pcc_io_loop
+
+pcc_io_r32:
+       move.l          (a2),d3
+       move.l          d3,d0
+       swap            d0
+       lsr.l           #8,d0
+       bsr             send_byte
+       move.l          d3,d0
+       swap            d0
+       bsr             send_byte
+       move.w          d3,d0
+       lsr.w           #8,d0
+       bsr             send_byte
+       move.b          d3,d0
+       bsr             send_byte
+       bra             pcc_io_loop
+
+
+/* PicoDrive savestate load */
+pcc_loadstate:
+       /* write VRAM */
+       move.l          #0xc00000,a0
+       move.w          #0x8f02,4(a0)           /* auto increment 2 */
+
+       move.l          #0x40000000,4(a0)
+       move.l          #0x10000/2-1,d3
+tr_do_vram_loop:
+       bsr             recv_word
+       move.w          d0,(a0)
+       dbra            d3, tr_do_vram_loop
+
+       /* write cram */
+       move.l          #0xc0000000,4(a0)
+       move.l          #0x80/2-1,d3
+tr_do_cram_loop:
+       bsr             recv_word
+       move.w          d0,(a0)
+       dbra            d3, tr_do_cram_loop
+
+       /* write vsram */
+       move.l          #0x40000010,4(a0)
+       move.l          #0x80/2-1,d3
+tr_do_vsram_loop:
+       bsr             recv_word
+       move.w          d0,(a0)
+       dbra            d3, tr_do_vsram_loop
+
+       /* recv and write regs */
+       lea             0xffe000,a3
+       move.l          a3,a2
+       moveq.l         #0x20-1,d3
+tr_do_vdpreg_recv_loop:
+       bsr             recv_byte
+       move.b          d0,(a2)+
+       dbra            d3, tr_do_vdpreg_recv_loop
+
+       move.l          a3,a2
+       moveq.l         #0,d3
+tr_do_vdpreg_loop:
+       move.b          d3,d1
+       or.b            #0x80,d1
+       lsl.w           #8,d1
+       move.b          (d3,a2),d1
+       move.w          d1,4(a0)
+       addq.l          #1,d3
+       cmp.b           #0x17,d3        /* FIXME: r23 might cause DMA or.. */
+       bne             0f              /* ..something and hang VDP.. */
+       add.b           #1,d3           /* ..so we skip it */
+0:
+       cmp.b           #0x20,d3
+       blt             tr_do_vdpreg_loop
+
+       moveq.l         #0,d0
+       move.b          5(a3),d0
+       bsr             invalidate_sprite_cache
+
+
+0:     bra             0b
+
+       bra             return
+
+
+pcc_vram_send:
+       /* write VRAM */
+       move.l          #0xc00000,a0
+       move.w          #0x8f02,4(a0)           /* auto increment 2 */
+       move.l          #0,4(a0)                /* VRAM read, addr 0 */
+       move.l          #0x10000/2-1,d4
+
+       switch_to_output
+
+tr_vram_send_loop:
+       move.w          (a0),d3
+       move.w          d3,d0
+       lsr.w           #8,d0
+       bsr             send_byte
+       move.b          d3,d0
+       bsr             send_byte
+       dbra            d4,tr_vram_send_loop
+
+       bra             return
+
+
+
+/* some random code */
 pcc_test_code:
        bra             return
 
 
+
 return:
        move.b          #0,(0xa1000b).l /* all inputs */
        move.l          #0xffe000,a1
@@ -189,7 +440,8 @@ return:
        move.l          d2,(a1)+
        move.l          d3,(a1)+
        move.l          a0,(a1)+
-       bra             return_to_main
+       rts
+#      bra             return_to_main
 
 
 # vim:filetype=asmM68k