#define SekNotPolling PicoCpuMM68k.not_polling\r
#define SekNotPollingS68k PicoCpuMS68k.not_polling\r
\r
-#define SekInterrupt(irq) { \\r
- void *oldcontext = m68ki_cpu_p; \\r
- m68k_set_context(&PicoCpuMM68k); \\r
- m68k_set_irq(irq); \\r
- m68k_set_context(oldcontext); \\r
-}\r
-#define SekIrqLevel (PicoCpuMM68k.int_level >> 8)\r
+// avoid m68k_set_irq() for delaying to work\r
+#define SekInterrupt(irq) PicoCpuMM68k.int_level = (irq) << 8\r
+#define SekIrqLevel (PicoCpuMM68k.int_level >> 8)\r
\r
#endif\r
#endif // EMU_M68K\r
\r
-// while running, cnt represents target of current timeslice\r
-// while not in SekRun(), it's actual cycles done\r
-// (but always use SekCyclesDone() if you need current position)\r
-// cnt may change if timeslice is ended prematurely or extended,\r
-// so we use SekCycleAim for the actual target\r
-extern unsigned int SekCycleCnt;\r
-extern unsigned int SekCycleAim;\r
-\r
// number of cycles done (can be checked anywhere)\r
-#define SekCyclesDone() (SekCycleCnt - SekCyclesLeft)\r
+#define SekCyclesDone() (Pico.t.m68c_cnt - SekCyclesLeft)\r
\r
// burn cycles while not in SekRun() and while in\r
-#define SekCyclesBurn(c) SekCycleCnt += c\r
+#define SekCyclesBurn(c) Pico.t.m68c_cnt += c\r
#define SekCyclesBurnRun(c) { \\r
SekCyclesLeft -= c; \\r
}\r
\r
// note: sometimes may extend timeslice to delay an irq\r
#define SekEndRun(after) { \\r
- SekCycleCnt -= SekCyclesLeft - (after); \\r
+ Pico.t.m68c_cnt -= SekCyclesLeft - (after); \\r
SekCyclesLeft = after; \\r
}\r
\r
#define z80_nmi() drZ80.Z80IF |= 8\r
\r
#define z80_cyclesLeft drZ80.cycles\r
+#define z80_subCLeft(c) drZ80.cycles -= c\r
#define z80_pc() (drZ80.Z80PC - drZ80.Z80PC_BASE)\r
\r
#elif defined(_USE_CZ80)\r
#define z80_nmi() Cz80_Set_IRQ(&CZ80, IRQ_LINE_NMI, 0)\r
\r
#define z80_cyclesLeft (CZ80.ICount - CZ80.ExtraCycles)\r
+#define z80_subCLeft(c) CZ80.ICount -= c\r
#define z80_pc() Cz80_Get_Reg(&CZ80, CZ80_PC)\r
\r
#else\r
\r
#define Z80_STATE_SIZE 0x60\r
\r
-extern unsigned int last_z80_sync;\r
-extern int z80_cycle_cnt; /* 'done' z80 cycles before z80_run() */\r
-extern int z80_cycle_aim;\r
-extern int z80_scanline;\r
-extern int z80_scanline_cycles; /* cycles done until z80_scanline */\r
-\r
#define z80_resetCycles() \\r
- last_z80_sync = SekCyclesDone(); \\r
- z80_cycle_cnt = z80_cycle_aim = z80_scanline = z80_scanline_cycles = 0;\r
+ Pico.t.z80c_cnt = Pico.t.z80c_aim = Pico.t.z80_scanline = 0\r
\r
#define z80_cyclesDone() \\r
- (z80_cycle_aim - z80_cyclesLeft)\r
+ (Pico.t.z80c_aim - z80_cyclesLeft)\r
\r
-#define cycles_68k_to_z80(x) ((x)*957 >> 11)\r
+#define cycles_68k_to_z80(x) ((x) * 3823 >> 13)\r
\r
// ----------------------- SH2 CPU -----------------------\r
\r
#define OSC_NTSC 53693100\r
#define OSC_PAL 53203424\r
\r
+// PicoVideo.debug_p\r
+#define PVD_KILL_A (1 << 0)\r
+#define PVD_KILL_B (1 << 1)\r
+#define PVD_KILL_S_LO (1 << 2)\r
+#define PVD_KILL_S_HI (1 << 3)\r
+#define PVD_KILL_32X (1 << 4)\r
+#define PVD_FORCE_A (1 << 5)\r
+#define PVD_FORCE_B (1 << 6)\r
+#define PVD_FORCE_S (1 << 7)\r
+\r
+// PicoVideo.status, not part of real SR\r
+#define SR_PAL (1 << 0)\r
+#define SR_DMA (1 << 1)\r
+#define SR_HB (1 << 2)\r
+#define SR_VB (1 << 3)\r
+#define SR_ODD (1 << 4)\r
+#define SR_C (1 << 5)\r
+#define SR_SOVR (1 << 6)\r
+#define SR_F (1 << 7)\r
+#define SR_FULL (1 << 8)\r
+#define SR_EMPT (1 << 9)\r
+// not part of real SR\r
+#define PVS_ACTIVE (1 << 16)\r
+#define PVS_VB2 (1 << 17) // ignores forced blanking\r
+\r
struct PicoVideo\r
{\r
unsigned char reg[0x20];\r
unsigned char pending; // 1 if waiting for second half of 32-bit command\r
unsigned char type; // Command type (v/c/vsram read/write)\r
unsigned short addr; // Read/Write address\r
- int status; // Status bits\r
+ unsigned int status; // Status bits (SR) and extra flags\r
unsigned char pending_ints; // pending interrupts: ??VH????\r
signed char lwrite_cnt; // VDP write count during active display line\r
unsigned short v_counter; // V-counter\r
- unsigned char pad[0x10];\r
+ unsigned short debug; // raw debug register\r
+ unsigned char debug_p; // ... parsed: PVD_*\r
+ unsigned char addr_u; // bit16 of .addr\r
+ unsigned char hint_cnt;\r
+ unsigned char pad[0x0b];\r
};\r
\r
struct PicoMisc\r
unsigned char pad[0x4e];\r
};\r
\r
-// some assembly stuff depend on these, do not touch!\r
-struct Pico\r
+// emu state and data for the asm code\r
+struct PicoEState\r
+{\r
+ int DrawScanline;\r
+ int rendstatus;\r
+ void *DrawLineDest; // draw destination\r
+ unsigned char *HighCol;\r
+ int *HighPreSpr;\r
+ struct Pico *Pico;\r
+ void *PicoMem_vram;\r
+ void *PicoMem_cram;\r
+ int *PicoOpt;\r
+ unsigned char *Draw2FB;\r
+ unsigned short HighPal[0x100];\r
+};\r
+\r
+struct PicoMem\r
{\r
unsigned char ram[0x10000]; // 0x00000 scratch ram\r
union { // vram is byteswapped for easier reads when drawing\r
};\r
unsigned char zram[0x2000]; // 0x20000 Z80 ram\r
unsigned char ioports[0x10]; // XXX: fix asm and mv\r
- unsigned char pad[0xf0]; // unused\r
- unsigned short cram[0x40]; // 0x22100\r
- unsigned short vsram[0x40]; // 0x22180\r
-\r
- unsigned char *rom; // 0x22200\r
- unsigned int romsize; // 0x22204 (on 32bits)\r
-\r
- struct PicoMisc m;\r
- struct PicoVideo video;\r
- struct PicoMS ms;\r
+ unsigned short cram[0x40]; // 0x22010\r
+ unsigned char pad[0x70]; // 0x22050 DrawStripVSRam reads 0 from here\r
+ unsigned short vsram[0x40]; // 0x22100\r
};\r
\r
// sram\r
#define SRF_ENABLED (1 << 0)\r
#define SRF_EEPROM (1 << 1)\r
\r
-struct PicoSRAM\r
+struct PicoCartSave\r
{\r
unsigned char *data; // actual data\r
unsigned int start; // start address in 68k address space\r
unsigned int size;\r
};\r
\r
-// MCD\r
-#include "cd/cd_sys.h"\r
-#include "cd/LC89510.h"\r
+struct PicoTiming\r
+{\r
+ // while running, cnt represents target of current timeslice\r
+ // while not in SekRun(), it's actual cycles done\r
+ // (but always use SekCyclesDone() if you need current position)\r
+ // _cnt may change if timeslice is ended prematurely or extended,\r
+ // so we use _aim for the actual target\r
+ unsigned int m68c_cnt;\r
+ unsigned int m68c_aim;\r
+ unsigned int m68c_frame_start; // m68k cycles\r
+ unsigned int m68c_line_start;\r
+\r
+ unsigned int z80c_cnt; // z80 cycles done (this frame)\r
+ unsigned int z80c_aim;\r
+ int z80_scanline;\r
+};\r
\r
+// run tools/mkoffsets pico/pico_int_o32.h if you change these\r
+// careful with savestate compat\r
+struct Pico\r
+{\r
+ struct PicoVideo video;\r
+ struct PicoMisc m;\r
+ struct PicoTiming t;\r
+ struct PicoCartSave sv;\r
+ struct PicoEState est;\r
+ struct PicoMS ms;\r
+\r
+ unsigned char *rom;\r
+ unsigned int romsize;\r
+};\r
+\r
+// MCD\r
#define PCM_MIXBUF_LEN ((12500000 / 384) / 50 + 1)\r
\r
struct mcd_pcm\r
\r
struct mcd_misc\r
{\r
- unsigned short hint_vector;\r
- unsigned char busreq; // not s68k_regs[1]\r
- unsigned char s68k_pend_ints;\r
- unsigned int state_flags; // 04\r
- unsigned int stopwatch_base_c;\r
- unsigned short m68k_poll_a;\r
- unsigned short m68k_poll_cnt;\r
- unsigned short s68k_poll_a;\r
- unsigned short s68k_poll_cnt;\r
- unsigned int s68k_poll_clk;\r
- unsigned char bcram_reg; // 18: battery-backed RAM cart register\r
- unsigned char dmna_ret_2m;\r
- unsigned short pad3;\r
- int pad4[9];\r
+ unsigned short hint_vector;\r
+ unsigned char busreq; // not s68k_regs[1]\r
+ unsigned char s68k_pend_ints;\r
+ unsigned int state_flags; // 04\r
+ unsigned int stopwatch_base_c;\r
+ unsigned short m68k_poll_a;\r
+ unsigned short m68k_poll_cnt;\r
+ unsigned short s68k_poll_a;\r
+ unsigned short s68k_poll_cnt;\r
+ unsigned int s68k_poll_clk;\r
+ unsigned char bcram_reg; // 18: battery-backed RAM cart register\r
+ unsigned char dmna_ret_2m;\r
+ unsigned char need_sync;\r
+ unsigned char pad3;\r
+ int pad4[9];\r
};\r
\r
typedef struct\r
unsigned char pcm_ram[0x10000];\r
unsigned char pcm_ram_b[0x10][0x1000];\r
};\r
- union {\r
- unsigned char s68k_regs[0x200]; // 110000: GA, not CPU regs\r
- union {\r
- struct {\r
- unsigned char h;\r
- unsigned char l;\r
- } byte;\r
- } regs[0x200/2];\r
- };\r
+ unsigned char s68k_regs[0x200]; // 110000: GA, not CPU regs\r
unsigned char bram[0x2000]; // 110200: 8K\r
struct mcd_misc m; // 112200: misc\r
struct mcd_pcm pcm; // 112240:\r
- _scd_toc TOC; // not to be saved\r
- CDD cdd;\r
- _scd scd;\r
+ void *cdda_stream;\r
+ int cdda_type;\r
int pcm_mixbuf[PCM_MIXBUF_LEN * 2];\r
int pcm_mixpos;\r
char pcm_mixbuf_dirty;\r
int CM_compareRun(int cyc, int is_sub);\r
\r
// draw.c\r
+void PicoDrawInit(void);\r
PICO_INTERNAL void PicoFrameStart(void);\r
void PicoDrawSync(int to, int blank_last_line);\r
-void BackFill(int reg7, int sh);\r
-void FinalizeLine555(int sh, int line);\r
+void BackFill(int reg7, int sh, struct PicoEState *est);\r
+void FinalizeLine555(int sh, int line, struct PicoEState *est);\r
extern int (*PicoScanBegin)(unsigned int num);\r
extern int (*PicoScanEnd)(unsigned int num);\r
-extern int DrawScanline;\r
#define MAX_LINE_SPRITES 29\r
extern unsigned char HighLnSpr[240][3 + MAX_LINE_SPRITES];\r
extern void *DrawLineDestBase;\r
extern int DrawLineDestIncrement;\r
\r
// draw2.c\r
+void PicoDraw2Init(void);\r
PICO_INTERNAL void PicoFrameFull();\r
\r
// mode4.c\r
unsigned char cdc_reg_r(void);\r
unsigned short cdc_host_r(void);\r
\r
+// cd/cdd.c\r
+void cdd_reset(void);\r
+int cdd_context_save(unsigned char *state);\r
+int cdd_context_load(unsigned char *state);\r
+int cdd_context_load_old(unsigned char *state);\r
+void cdd_read_data(unsigned char *dst);\r
+void cdd_read_audio(unsigned int samples);\r
+void cdd_update(void);\r
+void cdd_process(void);\r
+\r
+// cd/cd_image.c\r
+int load_cd_image(const char *cd_img_name, int *type);\r
+\r
// cd/gfx.c\r
void gfx_init(void);\r
void gfx_start(unsigned int base);\r
\r
// pico.c\r
extern struct Pico Pico;\r
-extern struct PicoSRAM SRam;\r
+extern struct PicoMem PicoMem;\r
extern int PicoPadInt[2];\r
extern int emustatus;\r
-extern int scanlines_total;\r
extern void (*PicoResetHook)(void);\r
extern void (*PicoLineHook)(void);\r
PICO_INTERNAL int CheckDMA(void);\r
void SekInterruptClearS68k(int irq);\r
\r
// sound/sound.c\r
-PICO_INTERNAL void cdda_start_play();\r
extern short cdda_out_buffer[2*1152];\r
extern int PsndLen_exc_cnt;\r
extern int PsndLen_exc_add;\r
extern int timer_a_next_oflow, timer_a_step; // in z80 cycles\r
extern int timer_b_next_oflow, timer_b_step;\r
\r
+void cdda_start_play(int lba_base, int lba_offset, int lb_len);\r
+\r
void ym2612_sync_timers(int z80_cycles, int mode_old, int mode_new);\r
void ym2612_pack_state(void);\r
void ym2612_unpack_state(void);\r
\r
\r
// videoport.c\r
-extern int line_base_cycles;\r
PICO_INTERNAL_ASM void PicoVideoWrite(unsigned int a,unsigned short d);\r
PICO_INTERNAL_ASM unsigned int PicoVideoRead(unsigned int a);\r
-PICO_INTERNAL_ASM unsigned int PicoVideoRead8(unsigned int a);\r
-extern int (*PicoDmaHook)(unsigned int source, int len, unsigned short **srcp, unsigned short **limitp);\r
+unsigned char PicoVideoRead8DataH(void);\r
+unsigned char PicoVideoRead8DataL(void);\r
+unsigned char PicoVideoRead8CtlH(void);\r
+unsigned char PicoVideoRead8CtlL(void);\r
+unsigned char PicoVideoRead8HV_H(void);\r
+unsigned char PicoVideoRead8HV_L(void);\r
+extern int (*PicoDmaHook)(unsigned int source, int len, unsigned short **base, unsigned int *mask);\r
\r
// misc.c\r
PICO_INTERNAL_ASM void memcpy16(unsigned short *dest, unsigned short *src, int count);\r
PICO_INTERNAL_ASM void memcpy16bswap(unsigned short *dest, void *src, int count);\r
-PICO_INTERNAL_ASM void memcpy32(int *dest, int *src, int count); // 32bit word count\r
-PICO_INTERNAL_ASM void memset32(int *dest, int c, int count);\r
+PICO_INTERNAL_ASM void memcpy32(void *dest, const void *src, int count); // 32bit word count\r
+PICO_INTERNAL_ASM void memset32(void *dest, int c, int count);\r
\r
// eeprom.c\r
void EEPROM_write8(unsigned int a, unsigned int d);\r
PICO_INTERNAL_ASM void wram_2M_to_1M(unsigned char *m);\r
PICO_INTERNAL_ASM void wram_1M_to_2M(unsigned char *m);\r
\r
-// cd/buffering.c\r
-PICO_INTERNAL void PicoCDBufferRead(void *dest, int lba);\r
-\r
// sound/sound.c\r
PICO_INTERNAL void PsndReset(void);\r
+PICO_INTERNAL void PsndStartFrame(void);\r
PICO_INTERNAL void PsndDoDAC(int line_to);\r
+PICO_INTERNAL void PsndDoPSG(int line_to);\r
PICO_INTERNAL void PsndClear(void);\r
PICO_INTERNAL void PsndGetSamples(int y);\r
PICO_INTERNAL void PsndGetSamplesMS(void);\r
-extern int PsndDacLine;\r
+extern int PsndDacLine, PsndPsgLine;\r
\r
// sms.c\r
#ifndef NO_SMS\r
void p32x_schedule_hint(SH2 *sh2, int m68k_cycles);\r
\r
// 32x/memory.c\r
-struct Pico32xMem *Pico32xMem;\r
+extern struct Pico32xMem *Pico32xMem;\r
unsigned int PicoRead8_32x(unsigned int a);\r
unsigned int PicoRead16_32x(unsigned int a);\r
void PicoWrite8_32x(unsigned int a, unsigned int d);\r
\r
// 32x/draw.c\r
void PicoDrawSetOutFormat32x(pdso_t which, int use_32x_line_mode);\r
-void FinalizeLine32xRGB555(int sh, int line);\r
+void FinalizeLine32xRGB555(int sh, int line, struct PicoEState *est);\r
void PicoDraw32xLayer(int offs, int lines, int mdbg);\r
void PicoDraw32xLayerMdOnly(int offs, int lines);\r
extern int (*PicoScan32xBegin)(unsigned int num);\r
\r
#endif // PICO_INTERNAL_INCLUDED\r
\r
+// vim:shiftwidth=2:ts=2:expandtab\r