From 835122bc0c583a74707847f350349e6050b42bb5 Mon Sep 17 00:00:00 2001 From: notaz Date: Sat, 31 Aug 2013 02:23:57 +0300 Subject: [PATCH] sms: add pause support --- cpu/DrZ80/drz80.h | 2 +- cpu/DrZ80/drz80.s | 37 +++++++++++++++++++++++++++++++++++-- pico/pico_int.h | 7 ++++++- pico/sms.c | 7 ++++++- 4 files changed, 48 insertions(+), 5 deletions(-) diff --git a/cpu/DrZ80/drz80.h b/cpu/DrZ80/drz80.h index 708f0a9..05773f9 100644 --- a/cpu/DrZ80/drz80.h +++ b/cpu/DrZ80/drz80.h @@ -52,7 +52,7 @@ struct DrZ80 int cycles; /*0x44 - Cycles pending to be executed yet */ int previouspc; /*0x48 - Previous PC */ unsigned char Z80_IRQ; /*0x4C - Set IRQ Number (must be halfword aligned) */ - unsigned char Z80IF; /*0x4D - Interrupt Flags: bit1=_IFF1, bit2=_IFF2, bit3=_HALT */ + unsigned char Z80IF; /*0x4D - Interrupt Flags: bit0=_IFF1, bit1=_IFF2, bit2=_HALT, b3=NMI */ unsigned char Z80IM; /*0x4E - Set IRQ Mode */ unsigned char spare; /*0x4F - N/A */ unsigned int z80irqvector; /*0x50 - Set IRQ Vector i.e. 0xFF=RST */ diff --git a/cpu/DrZ80/drz80.s b/cpu/DrZ80/drz80.s index edb29df..ff2a6b8 100644 --- a/cpu/DrZ80/drz80.s +++ b/cpu/DrZ80/drz80.s @@ -97,6 +97,7 @@ DrZ80Ver: .long 0x0001 .equ Z80_IF1, 1<<0 .equ Z80_IF2, 1<<1 .equ Z80_HALT, 1<<2 + .equ Z80_NMI, 1<<3 ;@--------------------------------------- @@ -1359,9 +1360,11 @@ DrZ80Run: .if INTERRUPT_MODE == 0 ;@ check ints + tst r0,#(Z80_NMI<<8) + blne DoNMI tst r0,#0xff movne r0,r0,lsr #8 - tstne r0,#1 + tstne r0,#Z80_IF1 blne DoInterrupt .endif @@ -1515,6 +1518,36 @@ DoInterrupt_end: ldmfd sp!,{pc} ;@ return .endif +DoNMI: + stmfd sp!,{lr} + + bic r0,r0,#((Z80_NMI|Z80_HALT|Z80_IF1)<<8) + strh r0,[cpucontext,#z80irq] @ 0x4C, irq and IFF bits + + ;@ push pc on stack + ldr r0,[cpucontext,#z80pc_base] + sub r2,z80pc,r0 + opPUSHareg r2 + + ;@ read new pc from vector address +.if UPDATE_CONTEXT + str z80pc,[cpucontext,#z80pc_pointer] +.endif + mov r0,#0x66 +.if DRZ80_XMAP + rebasepc +.else + stmfd sp!,{r3,r12} + mov lr,pc + ldr pc,[cpucontext,#z80_rebasePC] ;@ r0=new pc - external function sets z80pc_base and returns new z80pc in r0 + ldmfd sp!,{r3,r12} + mov z80pc,r0 +.endif + ldrh r0,[cpucontext,#z80irq] @ 0x4C, irq and IFF bits + eatcycles 11 + ldmfd sp!,{pc} + + .data .align 4 @@ -5615,7 +5648,7 @@ ei_return: ;@ check ints tst r0,#0xff movne r0,r0,lsr #8 - tstne r0,#1 + tstne r0,#Z80_IF1 blne DoInterrupt ;@ continue diff --git a/pico/pico_int.h b/pico/pico_int.h index 690c233..1acc1b0 100644 --- a/pico/pico_int.h +++ b/pico/pico_int.h @@ -174,6 +174,8 @@ extern struct DrZ80 drZ80; #define z80_run(cycles) ((cycles) - DrZ80Run(&drZ80, cycles)) #define z80_run_nr(cycles) DrZ80Run(&drZ80, cycles) #define z80_int() drZ80.Z80_IRQ = 1 +#define z80_int() drZ80.Z80_IRQ = 1 +#define z80_nmi() drZ80.Z80IF |= 8 #define z80_cyclesLeft drZ80.cycles #define z80_pc() (drZ80.Z80PC - drZ80.Z80PC_BASE) @@ -184,6 +186,7 @@ extern struct DrZ80 drZ80; #define z80_run(cycles) Cz80_Exec(&CZ80, cycles) #define z80_run_nr(cycles) Cz80_Exec(&CZ80, cycles) #define z80_int() Cz80_Set_IRQ(&CZ80, 0, HOLD_LINE) +#define z80_nmi() Cz80_Set_IRQ(&CZ80, IRQ_LINE_NMI, 0) #define z80_cyclesLeft (CZ80.ICount - CZ80.ExtraCycles) #define z80_pc() Cz80_Get_Reg(&CZ80, CZ80_PC) @@ -193,6 +196,7 @@ extern struct DrZ80 drZ80; #define z80_run(cycles) (cycles) #define z80_run_nr(cycles) #define z80_int() +#define z80_nmi() #endif @@ -313,7 +317,8 @@ struct PicoMS { unsigned char carthw[0x10]; unsigned char io_ctl; - unsigned char pad[0x4f]; + unsigned char nmi_state; + unsigned char pad[0x4e]; }; // some assembly stuff depend on these, do not touch! diff --git a/pico/sms.c b/pico/sms.c index 58905bd..8c44d51 100644 --- a/pico/sms.c +++ b/pico/sms.c @@ -11,7 +11,6 @@ * - remaining status flags (OVR/COL) * - RAM support in mapper * - region support - * - Pause button (NMI) * - SN76496 DAC-like usage * - H counter */ @@ -256,8 +255,14 @@ void PicoFrameMS(void) int skip = PicoSkipFrame; int lines_vis = 192; int hint; // Hint counter + int nmi; int y; + nmi = (PicoPad[0] >> 7) & 1; + if (!Pico.ms.nmi_state && nmi) + z80_nmi(); + Pico.ms.nmi_state = nmi; + PicoFrameStartMode4(); hint = pv->reg[0x0a]; -- 2.39.2