adjusted timing and fixed EI in DrZ80
[picodrive.git] / cpu / DrZ80 / drz80.s
index ee14013..846c636 100644 (file)
@@ -24,7 +24,7 @@
       .extern PicoRead8\r
       .extern Pico\r
       .extern z80_write\r
-      .extern ym2612_st\r
+      .extern ym2612_read_local_z80\r
 .endif\r
 \r
 DrZ80Ver: .long 0x0001\r
@@ -106,21 +106,6 @@ DrZ80Ver: .long 0x0001
 \r
 .if DRZ80_FOR_PICODRIVE\r
 \r
-.macro YM2612Read_and_ret8\r
-    ldr r0, =ym2612_st\r
-    ldr r0, [r0]\r
-    ldrb r0, [r0, #0x11]   ;@ ym2612_st->status\r
-    bx lr\r
-.endm\r
-\r
-.macro YM2612Read_and_ret16\r
-    ldr r0, =ym2612_st\r
-    ldr r0, [r0]\r
-    ldrb r0, [r0, #0x11]   ;@ ym2612_st->status\r
-    orr r0,r0,r0,lsl #8\r
-    bx lr\r
-.endm\r
-\r
 pico_z80_read8: @ addr\r
     cmp r0,#0x2000         @ Z80 RAM\r
     ldrlt r1,[cpucontext,#z80sp_base]\r
@@ -139,15 +124,18 @@ pico_z80_read8: @ addr
     eorlt r0,r0,#1         @ our ROM is byteswapped\r
     ldrltb r0,[r1,r0]\r
     bxlt lr\r
-       stmfd sp!,{r3,r12,lr}\r
+    stmfd sp!,{r3,r12,lr}\r
     bl PicoRead8\r
-       ldmfd sp!,{r3,r12,pc}\r
+    ldmfd sp!,{r3,r12,pc}\r
 1:\r
     mov r1,r0,lsr #13\r
     cmp r1,#2              @ YM2612 (0x4000-0x5fff)\r
     bne 0f\r
     and r0,r0,#3\r
-    YM2612Read_and_ret8\r
+    stmfd sp!,{r3,r12,lr}\r
+    str z80_icount,[cpucontext,#cycles_pointer]\r
+    bl ym2612_read_local_z80\r
+    ldmfd sp!,{r3,r12,pc}\r
 0:\r
     cmp r0,#0x4000\r
     movge r0,#0xff\r
@@ -197,7 +185,11 @@ pico_z80_read16: @ addr
     cmp r1,#2              @ YM2612 (0x4000-0x5fff)\r
     bne 0f\r
     and r0,r0,#3\r
-    YM2612Read_and_ret16\r
+    stmfd sp!,{r3,r12,lr}\r
+    str z80_icount,[cpucontext,#cycles_pointer]\r
+    bl ym2612_read_local_z80\r
+    orr r0,r0,r0,lsl #8\r
+    ldmfd sp!,{r3,r12,pc}\r
 0:\r
     cmp r0,#0x4000\r
     movge r0,#0xff\r
@@ -218,6 +210,7 @@ pico_z80_write8: @ data, addr
     bx lr\r
 1:\r
     stmfd sp!,{r3,r12,lr}\r
+    str z80_icount,[cpucontext,#cycles_pointer]\r
     bl z80_write\r
     ldmfd sp!,{r3,r12,pc}\r
 \r
@@ -231,14 +224,15 @@ pico_z80_write16: @ data, addr
     strb r0,[r2,#1]\r
     bx lr\r
 1:\r
-       stmfd sp!,{r3-r5,r12,lr}\r
+    stmfd sp!,{r3-r5,r12,lr}\r
+    str z80_icount,[cpucontext,#cycles_pointer]\r
     mov r4,r0\r
     mov r5,r1\r
-       bl z80_write\r
+    bl z80_write\r
     mov r0,r4,lsr #8\r
     add r1,r5,#1\r
-       bl z80_write\r
-       ldmfd sp!,{r3-r5,r12,pc}\r
+    bl z80_write\r
+    ldmfd sp!,{r3-r5,r12,pc}\r
 \r
     .pool\r
 .endif\r
@@ -366,8 +360,8 @@ pico_z80_write16: @ data, addr
      str z80pc,[cpucontext,#z80pc_pointer]\r
 .endif\r
 .if DRZ80_FOR_PICODRIVE\r
-    bic r0,r0,#0xfe000\r
     ldr r1,[cpucontext,#z80pc_base]\r
+    bic r0,r0,#0xfe000\r
     add z80pc,r1,r0\r
 .else\r
     stmfd sp!,{r3,r12}\r
@@ -1378,30 +1372,32 @@ DrZ80Run:
        mov z80_icount,r1                                               ;@ setup number of Tstates to execute\r
 \r
 .if INTERRUPT_MODE == 0\r
-       ldrh r0,[cpucontext,#z80irq] @ 0x4C\r
+       ldrh r0,[cpucontext,#z80irq] @ 0x4C, irq and IFF bits\r
 .endif\r
        ldmia cpucontext,{z80pc-z80sp}                  ;@ load Z80 registers\r
 \r
 .if INTERRUPT_MODE == 0\r
        ;@ check ints\r
-       tst r0,#1\r
-       movnes r0,r0,lsr #8\r
-    blne DoInterrupt\r
+       tst r0,#0xff\r
+       movne r0,r0,lsr #8\r
+       tstne r0,#1\r
+       blne DoInterrupt\r
 .endif\r
 \r
-       ldrb r0,[z80pc],#1    ;@ get first op code\r
        ldr opcodes,MAIN_opcodes_POINTER2\r
-       ldr pc,[opcodes,r0, lsl #2]  ;@ execute op code\r
 \r
-MAIN_opcodes_POINTER2: .word MAIN_opcodes\r
+       cmp z80_icount,#0     ;@ irq might have used all cycles\r
+       ldrplb r0,[z80pc],#1\r
+       ldrpl pc,[opcodes,r0, lsl #2]\r
 \r
 \r
 z80_execute_end:\r
        ;@ save registers in CPU context\r
        stmia cpucontext,{z80pc-z80sp}                  ;@ save Z80 registers\r
-    mov r0,z80_icount\r
+       mov r0,z80_icount\r
        ldmia sp!,{r4-r12,pc}                                   ;@ restore registers from stack and return to C code\r
 \r
+MAIN_opcodes_POINTER2: .word MAIN_opcodes\r
 .if INTERRUPT_MODE\r
 Interrupt_local: .word Interrupt\r
 .endif\r
@@ -1420,6 +1416,8 @@ DoInterrupt:
        ldmia cpucontext,{z80pc-z80sp}                  ;@ load Z80 registers\r
        mov pc,lr ;@ return\r
 .else\r
+\r
+       ;@ r0 == z80if\r
        stmfd sp!,{lr}\r
 \r
        tst r0,#4 ;@ check halt\r
@@ -1432,10 +1430,9 @@ DoInterrupt:
        strb r0,[cpucontext,#z80if]\r
 \r
        ;@ now check int mode\r
-    tst r1,#1\r
-    bne DoInterrupt_mode1\r
-    tst r1,#2\r
-    bne DoInterrupt_mode2\r
+       cmp r1,#1\r
+       beq DoInterrupt_mode1\r
+       bgt DoInterrupt_mode2\r
 \r
 DoInterrupt_mode0:\r
        ;@ get 3 byte vector\r
@@ -1465,6 +1462,7 @@ DoInterrupt_mode0:
        ;@ rebase new pc\r
        rebasepc\r
 \r
+       eatcycles 13\r
        b DoInterrupt_end\r
 \r
 1:\r
@@ -1479,6 +1477,7 @@ DoInterrupt_mode0:
        ;@ rebase new pc\r
        rebasepc\r
 \r
+       eatcycles 13\r
        b DoInterrupt_end\r
 \r
 DoInterrupt_mode1:\r
@@ -1488,6 +1487,7 @@ DoInterrupt_mode1:
        mov r0,#0x38\r
        rebasepc\r
 \r
+       eatcycles 13\r
        b DoInterrupt_end\r
 \r
 DoInterrupt_mode2:\r
@@ -1524,18 +1524,19 @@ DoInterrupt_mode2:
        ldmfd sp!,{r3,r12}\r
        mov z80pc,r0    \r
 .endif\r
+       eatcycles 17\r
 \r
 DoInterrupt_end:\r
        ;@ interupt accepted so callback irq interface\r
        ldr r0,[cpucontext, #z80irqcallback]\r
        tst r0,r0\r
+       streqb r0,[cpucontext,#z80irq]       ;@ default handling\r
        ldmeqfd sp!,{pc}\r
        stmfd sp!,{r3,r12}\r
        mov lr,pc\r
        mov pc,r0    ;@ call callback function\r
        ldmfd sp!,{r3,r12}\r
        ldmfd sp!,{pc} ;@ return\r
-\r
 .endif\r
 \r
 .data\r
@@ -4574,7 +4575,7 @@ opcode_3_8:
        tst z80f,#1<<CFlag\r
        bne opcode_1_8\r
        add z80pc,z80pc,#1\r
-       fetch 8\r
+       fetch 7\r
 ;@ADD HL,SP\r
 opcode_3_9:\r
 .if FAST_Z80SP\r
@@ -4592,7 +4593,7 @@ opcode_3_A:
        orr r0,r0,r1, lsl #8\r
        readmem8\r
        mov z80a,r0, lsl #24\r
-       fetch 11\r
+       fetch 13\r
 ;@DEC SP\r
 opcode_3_B:\r
        sub z80sp,z80sp,#1\r
@@ -4896,6 +4897,7 @@ opcode_7_6:
        ldrb r0,[cpucontext,#z80if]\r
        orr r0,r0,#Z80_HALT\r
        strb r0,[cpucontext,#z80if]\r
+       mov z80_icount,#0\r
        b z80_execute_end\r
 ;@LD (HL),A\r
 opcode_7_7:\r
@@ -5152,7 +5154,7 @@ opcode_B_F:
 ;@RET NZ\r
 opcode_C_0:\r
        tst z80f,#1<<ZFlag\r
-       beq opcode_C_9          ;@unconditional RET\r
+       beq opcode_C_9_cond             ;@unconditional RET\r
        fetch 5\r
 \r
 ;@POP BC\r
@@ -5195,8 +5197,11 @@ opcode_C_7:
 ;@RET Z\r
 opcode_C_8:\r
        tst z80f,#1<<ZFlag\r
-       bne opcode_C_9          ;@unconditional RET\r
+       bne opcode_C_9_cond             ;@unconditional RET\r
        fetch 5\r
+\r
+opcode_C_9_cond:\r
+       eatcycles 1\r
 ;@RET\r
 opcode_C_9:\r
     opPOP\r
@@ -5277,7 +5282,7 @@ opcode_C_F:
 ;@RET NC\r
 opcode_D_0:\r
        tst z80f,#1<<CFlag\r
-       beq opcode_C_9          ;@unconditional RET\r
+       beq opcode_C_9_cond             ;@unconditional RET\r
        fetch 5\r
 ;@POP DE\r
 opcode_D_1:\r
@@ -5319,7 +5324,7 @@ opcode_D_7:
 ;@RET C\r
 opcode_D_8:\r
        tst z80f,#1<<CFlag\r
-       bne opcode_C_9          ;@unconditional RET\r
+       bne opcode_C_9_cond             ;@unconditional RET\r
        fetch 5\r
 ;@EXX\r
 opcode_D_9:\r
@@ -5405,7 +5410,7 @@ opcode_D_F:
 ;@RET PO\r
 opcode_E_0:\r
        tst z80f,#1<<VFlag\r
-       beq opcode_C_9          ;@unconditional RET\r
+       beq opcode_C_9_cond             ;@unconditional RET\r
        fetch 5\r
 ;@POP HL\r
 opcode_E_1:\r
@@ -5460,7 +5465,7 @@ opcode_E_7:
 ;@RET PE\r
 opcode_E_8:\r
        tst z80f,#1<<VFlag\r
-       bne opcode_C_9          ;@unconditional RET\r
+       bne opcode_C_9_cond             ;@unconditional RET\r
        fetch 5\r
 ;@JP (HL)\r
 opcode_E_9:\r
@@ -5536,7 +5541,7 @@ opcode_E_F:
 ;@RET P\r
 opcode_F_0:\r
        tst z80f,#1<<SFlag\r
-       beq opcode_C_9          ;@unconditional RET\r
+       beq opcode_C_9_cond             ;@unconditional RET\r
        fetch 5\r
 ;@POP AF\r
 opcode_F_1:\r
@@ -5594,7 +5599,7 @@ opcode_F_7:
 ;@RET M\r
 opcode_F_8:\r
        tst z80f,#1<<SFlag\r
-       bne opcode_C_9          ;@unconditional RET\r
+       bne opcode_C_9_cond             ;@unconditional RET\r
        fetch 5\r
 ;@LD SP,HL\r
 opcode_F_9:\r
@@ -5605,7 +5610,7 @@ opcode_F_9:
 .else\r
        mov z80sp,z80hl, lsr #16\r
 .endif\r
-       fetch 4\r
+       fetch 6\r
 ;@JP M,$+3\r
 opcode_F_A:\r
        tst z80f,#1<<SFlag\r
@@ -5617,13 +5622,12 @@ EI_DUMMY_opcodes_POINTER: .word EI_DUMMY_opcodes
 ;@EI\r
 opcode_F_B:\r
        ldrb r1,[cpucontext,#z80if]\r
-       tst r1,#Z80_IF1\r
-       bne ei_return_exit\r
-\r
+       mov r2,opcodes\r
        orr r1,r1,#(Z80_IF1)|(Z80_IF2)\r
        strb r1,[cpucontext,#z80if]\r
 \r
-       mov r2,opcodes\r
+       ldrb r0,[z80pc],#1\r
+       eatcycles 4\r
        ldr opcodes,EI_DUMMY_opcodes_POINTER\r
        ldr pc,[r2,r0, lsl #2]\r
 \r
@@ -5631,16 +5635,17 @@ ei_return:
        ;@point that program returns from EI to check interupts\r
        ;@an interupt can not be taken directly after a EI opcode\r
        ;@ reset z80pc and opcode pointer\r
-       ldrh r0,[cpucontext,#z80irq] @ 0x4C\r
+       ldrh r0,[cpucontext,#z80irq] @ 0x4C, irq and IFF bits\r
        sub z80pc,z80pc,#1\r
        ldr opcodes,MAIN_opcodes_POINTER\r
        ;@ check ints\r
-       tst r0,#1\r
-       movnes r0,r0,lsr #8\r
-    blne DoInterrupt\r
+       tst r0,#0xff\r
+       movne r0,r0,lsr #8\r
+       tstne r0,#1\r
+       blne DoInterrupt\r
+\r
        ;@ continue\r
-ei_return_exit:\r
-       fetch 4\r
+       fetch 0\r
 \r
 ;@CALL M,NN\r
 opcode_F_C:\r
@@ -6647,7 +6652,7 @@ opcode_DD_NF:
 ;@     b end_loop\r
 \r
 opcode_DD_NF2:\r
-       fetch 15\r
+       fetch 23\r
 ;@ notaz: we don't want to deadlock here\r
 ;@     mov r0,#0xDD0000\r
 ;@     orr r0,r0,#0xCB00\r
@@ -8050,5 +8055,5 @@ opcode_ED_BB:
 ;@end_loop:\r
 ;@     b end_loop\r
 \r
-\r
+;@ vim:filetype=armasm\r
 \r