Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /* type and settings for compiler, common header
- *
- * Copyright (C) 2018 moecmks
- * This file is part of KS3578.
- *
- * do What The Fuck you want to Public License
- *
- * Version 1.0, March 2000
- * Copyright (C) 2000 Banlu Kemiyatorn (]d).
- * 136 Nives 7 Jangwattana 14 Laksi Bangkok
- * Everyone is permitted to copy and distribute verbatim copies
- * of this license document, but changing it is not allowed.
- *
- * Ok, the purpose of this license is simple
- * and you just
- *
- * DO WHAT THE FUCK YOU WANT TO.
- */
- #ifndef _CONFIG_H
- #define _CONFIG_H 1
- #ifdef _WIN32
- # if defined (_UNICODE) || defined (UNICODE)
- # define UCS2
- # endif
- # define _CRT_SECURE_NO_DEPRECATE
- #endif
- #include <stdint.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <process.h>
- #include <assert.h>
- #include <string.h>
- #include <math.h>
- #ifdef __cplusplus
- # define ks_null nullptr
- #else
- # define ks_null ((void *)0)
- #endif
- #ifndef STATIC_DEFINED
- # define STATIC static
- #endif
- typedef int ks_bool;
- # define ks_false 0
- # define ks_true 1
- typedef int8_t ks_int8;
- typedef int16_t ks_int16;
- typedef int32_t ks_int32;
- typedef int64_t ks_int64;
- typedef uint8_t ks_uint8;
- typedef uint16_t ks_uint16;
- typedef uint32_t ks_uint32;
- typedef uint64_t ks_uint64;
- typedef float ks_float;
- typedef double ks_double;
- typedef signed int ks_int;
- typedef unsigned int ks_uint;
- typedef intptr_t ks_intptr;
- typedef unsigned int ks_uint;
- typedef void ks_void;
- # define KS_UINT8_CAST(x) ((ks_uint8)(x))
- # define KS_UINT16_CAST(x) ((ks_uint16)(x))
- # define KS_UINT32_CAST(x) ((ks_uint32)(x))
- # define KS_UINT64_CAST(x) ((ks_uint64)(x))
- # define KS_INT8_CAST(x) ((ks_int8)(x))
- # define KS_INT16_CAST(x) ((ks_int16)(x))
- # define KS_INT32_CAST(x) ((ks_int32)(x))
- # define KS_INT64_CAST(x) ((ks_int64)(x))
- # define KS_FLOAT_CAST(x) ((ks_float)(x))
- # define KS_DOUBLE_CAST(x) ((ks_double)(x))
- #if defined (_MSC_VER) || defined (__ICC) || defined (__INTEL_COMPILER) /* MSVC/ICC starting... */
- # define ks_finline static __forceinline
- # define ks_dinline __declspec(noinline)
- # define ks_callstd __stdcall
- # define ks_callc __cdecl
- # define ks_cvalign(x) __declspec(align(x))
- # define ks_cvimpl __declspec(dllexport)
- #elif defined (__GNUC__) || defined (__GNUG__) /* MSVC/ICC end... GNUC starting */
- # define ks_finline static __attribute__((always_inline))
- # define ks_dinline __attribute__((noinline))
- # define ks_callstd __attribute__((stdcall))
- # define ks_callc __attribute__((cdecl))
- # define ks_cvalign(x) __attribute__((aligned(x)))
- # define ks_cvimpl __attribute__((dllexport))
- #else /* unsupported */
- # error unsupported compiler!
- #endif
- # define KS_CMP_EQUAL 0
- # define KS_CMP_ABOVE 1
- # define KS_CMP_LOW 2
- # define KS_CMP_NaN 3
- ks_finline
- int ks_cmp0_double (ks_double *value) {
- /* XXX: IEEE754 */
- ks_int64 *v = (ks_int64 *)(value);
- /* S:nocare M and E is 0 */
- if (! (v[0] & 0x7FFFFFFFFFFFFFFF)) /* -0 or +0*/
- return KS_CMP_EQUAL;
- if ( ( ((ks_int32 *)&v[0])[1] & 0x80000000))
- return KS_CMP_LOW;
- else
- return KS_CMP_ABOVE;
- }
- #ifdef _WIN32
- # ifdef _MSC_VER
- # define _DEBUG_BREAK() _asm int 3
- # else
- # endif
- #endif
- /* some hardware settings. */
- #define TIMER_DIVIDER_SAME_FREQ_BOTH_CBG_DMG_BASE_DMG
- #define JOYPAD_FREQ_IN_DMG 50.3
- #define JOYPAD_FREQ_IN_CGB 50.3
- #define JOYPAD_INTERRUPT_GEN_ENABLE
- #define JOYPAD_LOAD_ACTION_IN_P1415_ALLOPEN 3 /* 0:OR 1:AND 2:XOR 3:AND-NOT */
- #define TIMER_RESET_IN_RESET_FREQ_MOD_
- #define PPU_POST_RENDER_TIME 0 /* 0:VBLANK START 1:VBLANK END. */
- /* #define PPU_SPRITE_LIMIT10_IN_SCANLINE */
- #ifdef UCS2
- typedef wchar_t host_char;
- #else
- typedef char host_char;
- #endif
- #endif
- /* private object for gameboy
- *
- * Copyright (C) 2018 moecmks
- * This file is part of KS3578.
- *
- * do What The Fuck you want to Public License
- *
- * Version 1.0, March 2000
- * Copyright (C) 2000 Banlu Kemiyatorn (]d).
- * 136 Nives 7 Jangwattana 14 Laksi Bangkok
- * Everyone is permitted to copy and distribute verbatim copies
- * of this license document, but changing it is not allowed.
- *
- * Ok, the purpose of this license is simple
- * and you just
- *
- * DO WHAT THE FUCK YOU WANT TO.
- */
- #ifndef _INTERNAL_H
- #define _INTERNAL_H 1
- #include "conf.h"
- #include "gameboy.h"
- #include "list.h"
- struct gameboy;
- struct controller;
- struct divider;
- struct timer;
- struct cpu;
- struct ppu;
- struct cartidge;
- struct serial;
- struct apu;
- struct machine_setup;
- struct romheader;
- /*-\
- \-*/
- static const
- struct machine_setup {
- ks_double cpu_freq;
- ks_double vsync_freq;
- ks_double clk_ms;
- ks_double clk_ns;
- ks_double frame_cycles;
- ks_double line_cycles;
- ks_double oam_cycles;
- ks_double oambg_b_cycles;
- ks_double oambg_hbl_cycles;
- ks_double vbl_clk_last;
- ks_double oambg_clk_st;
- ks_double hbl_clk_st_b;
- ks_double vbl_clk_st;
- ks_double oam_clk_pick_per;
- ks_double oam_clk_add_hbl_per;
- ks_double cgb_gbp_p;
- ks_double gbp_cgb_p;
- ks_double oamdma_clks;
- ks_double gdma_clks_b;
- ks_double gdma_clks_per16; // always 7.63 us (DMG/CGB)
- ks_double hdma_clks_per16; // always 8 us (DMG/CGB)
- ks_double joypad_gen_freq;
- } std_machine = {
- 4194304.0, /* cpu_freq*/
- 59.73, /* vsync_freq*/
- 4194304.0/1000.0, /* clk_ms*/
- 4194304.0/1000000.0, /* clk_ns*/
- 4194304.0/59.73, /* frame_cycles*/
- 4194304.0/59.73/154.0, /* line_cycles*/
- 80.992010239999985, /* oam_cycles*/
- 173.51835647999999, /* oambg_b_cycles*/
- (70221.061443161/154.0) - 80.992010239999985, /* oambg_hbl_cycles*/
- 4559.809184621, /* vbl_clk_last*/
- 80.99201023999998, /* oambg_clk_st*/
- 173.51835647999999 + 80.992010239999985, /* hbl_clk_st_b*/
- 70221.061443161 - 4559.809184621, /* vbl_clk_st*/
- 80.992010239999985 / 10.0, /* oam_clk_pick_per*/
- 12.549357568000001, /* oam_clk_add_hbl_per*/
- 8400000.0/ 4194304.0, /* cgb_gbp_p*/
- 4194304.0/ 8400000.0, /* gbp_cgb_p*/
- 671.08864000000005, /* oamdma_clks*/
- (4194304.0*220.0)/1000000.0, /* gdma_clks_b*/
- (4194304.0*7.63)/1000000.0,/* gdma_clks_per16*/
- (4194304.0*8.00)/1000000.0,/* hdma_clks_per16*/
- (4194304.0)/JOYPAD_FREQ_IN_DMG /* joypad_gen_freq*/
- }, adv_machine = {
- 8400000.0, /* cpu_freq*/
- 59.73, /* vsync_freq*/
- 8400000.0/1000.0, /* clk_ms*/
- 8400000.0/1000000.0, /* clk_ns*/
- 8400000.0/59.73, /* frame_cycles*/
- 8400000.0/59.73/154.0, /* line_cycles*/
- 162.20400000000001, /* oam_cycles*/
- 347.50799999999998, /* oambg_b_cycles*/
- (8400000.0/59.73/154.0) - 162.20400000000001, /* oambg_hbl_cycles*/
- 9132.0031048810633, /* vbl_clk_last*/
- 162.20400000000001, /* oambg_clk_st*/
- 347.50799999999998 + 162.20400000000001, /* hbl_clk_st_b*/
- (8400000.0/59.73) - 9132.0031048810633, /* vbl_clk_st*/
- 162.20400000000001 / 10.0, /* oam_clk_pick_per*/
- 25.132800000000003, /* oam_clk_add_hbl_per*/
- 8400000.0/ 4194304.0, /* cgb_gbp_p*/
- 4194304.0/ 8400000.0, /* gbp_cgb_p*/
- 671.08864000000005, /* oamdma_clks*/
- (8400000.0*110.0)/1000000.0, /* gdma_clks_b*/
- (8400000.0*7.63)/1000000.0,/* gdma_clks_per16*/
- (8400000.0*8.00)/1000000.0,/* hdma_clks_per16*/
- (8400000.0)/JOYPAD_FREQ_IN_CGB /* joypad_gen_freq*/
- };
- struct romheader {
- ks_uint8 title[16];
- ks_uint16 curlic;
- ks_uint8 sgb;
- ks_uint8 ctype;
- ks_uint8 promsize;
- ks_uint8 ramsize;
- ks_uint8 targetcode;
- ks_uint8 anclic;
- ks_uint8 maskver;
- ks_uint8 hdcrc;
- ks_uint16 gcrc;
- };
- struct controller {
- ks_uint8 reg00_P1;
- /* for gamebot update host keybuf and IRQ */
- void (*clks) (struct controller *);
- void *obj;
- void *ubdata_user;
- /* pad infos for gameboy*.*/
- struct controller_pad gb_pad;
- struct gameboy *gb;
- };
- struct cpu {
- /* XXX:memory order dep. don't set struct align!*/
- union { struct { ks_uint8 F; ks_uint8 A; }; ks_uint16 AF; };
- union { struct { ks_uint8 C; ks_uint8 B; }; ks_uint16 BC; };
- union { struct { ks_uint8 E; ks_uint8 D; }; ks_uint16 DE; };
- union { struct { ks_uint8 L; ks_uint8 H; }; ks_uint16 HL; };
- union { struct { ks_uint8 SL; ks_uint8 SH; }; ks_uint16 SP; };
- union { struct { ks_uint8 PL; ks_uint8 PH; }; ks_uint16 PC; };
- /* Interrupt Master Enable*/
- ks_uint8 IME;
- /* for Halt */
- ks_bool halt;
- /* for stop */
- ks_bool stop;
- /* for halt bug */
- ks_int _backup;
- /* for speed mode */
- ks_uint8 reg4D_key1;
- /* gameboy object */
- struct gameboy *gb;
- };
- struct oam {
- union {
- struct {
- ks_uint8 y;
- ks_uint8 x;
- ks_uint8 id;
- ks_uint8 attr;
- };
- ks_uint8 blk[4];
- };
- };
- struct pal {
- union {
- struct {
- ks_uint8 _lo;
- ks_uint8 _hi;
- };
- ks_uint16 rgb15;
- ks_uint8 blk[2];
- };
- };
- /* for ppu:: spi_ca */
- #define PIXEL_SPRITE_NOTRANS 1
- #define PIXEL_SPRITE_BACK 2
- /* LCDC Status MASK */
- #define LCDS_MODE_FLAG_HBLANK 0
- #define LCDS_MODE_FLAG_VLANK 1
- #define LCDS_MODE_FLAG_SERACH_OAM 2
- #define LCDS_MODE_FLAG_SERACH_OAMVRAM 3
- #define LCDS_MODE_FLAG_ALL_MASK 3
- /* LCDC Status Interrupt MASK */
- #define LCDS_INTERRUPET_LINE_MASK 0x40
- #define LCDS_INTERRUPET_HBLANK_MASK 0x10
- #define LCDS_INTERRUPET_VBLANK_MASK 0x08
- #define LCDS_INTERRUPET_OAM_MASK 0x20
- #define LCDS_INTERRUPET_ALL_MASK (LCDS_INTERRUPET_LINE_MASK|LCDS_INTERRUPET_HBLANK_MASK|LCDS_INTERRUPET_VBLANK_MASK|LCDS_INTERRUPET_OAM_MASK)
- /* LCDC Control MASK */
- #define LCDC_DISPLAY_MASK 0x80
- #define LCDC_WINDOW_MASK 0x20
- #define LCDC_OAM_SIZE16_MASK 0x04
- #define LCDC_OAM_MASK 0x02
- #define LCD_OAM_FLIP_Y_MASK 0x40
- #define LCD_OAM_FLIP_X_MASK 0x20
- #define LCD_OAM_BACKGROUND_MASK 0x80
- struct ppu {
- ks_uint16 *bufb; /* for alignmem */
- ks_uint8 ram[0x4000]; /* 8K for DMG, 16 for CGB */
- struct _oamlineframe /* sprite line buffer cache *.*/
- {
- ks_uint16 attr;
- ks_uint16 pixel;
- } olf[176];
- struct gameboy *gb;
- struct oam sp[40];
- struct pal bg_pal[8][4]; /* pal for CGB */
- struct pal sp_pal[8][4]; /* pal for CGB */
- struct ppu_framebuffer fmebuf;
- ks_uint16 bg_pal_dmg[4]; /* pal for DMG */
- ks_uint16 sp_pal_dmg[2][4]; /* pal for DMG */
- ks_uint16 bg_pal_dmgT[4]; /* pal for DMG */
- ks_uint16 sp_pal_dmgT[2][4]; /* pal for DMG */
- ks_uint8 reg40_LCDC;
- ks_uint8 reg40_NMIf;
- ks_uint8 reg41_LCDS;
- ks_uint8 reg41_LCDM_T;
- ks_uint8 reg41_IRQf;
- ks_uint8 reg42_SCY;
- ks_uint8 reg43_SCX;
- ks_uint8 reg44_LY;
- ks_uint8 reg44_LY_T;
- ks_uint8 reg45_LYC;
- ks_uint8 reg46_DMA;
- ks_uint8 reg47_BGP;
- ks_uint8 reg48_OBP0;
- ks_uint8 reg49_OBP1;
- ks_uint8 reg4A_WY;
- ks_uint8 reg4A_WYRSC;
- ks_uint8 reg4A_WYLineHit;
- ks_uint8 reg4B_WX;
- ks_uint8 reg4F_VBK;
- ks_uint8 reg51_HDMA1;
- ks_uint8 reg52_HDMA2;
- ks_uint8 reg53_HDMA3;
- ks_uint8 reg54_HDMA4;
- ks_uint8 reg55_HDMA5;
- ks_uint8 reg68_BCPS;
- ks_uint8 reg69_BCPD;
- ks_uint8 reg6A_OCPS;
- ks_uint8 reg6B_OCPD;
- ks_int32 vscan;
- ks_int32 vscanR;
- ks_int32 vscan40;
- ks_int32 xscanR;
- ks_int32 uscan;
- ks_int32 uscanR;
- ks_bool hdma_gen;
- ks_uint16 hdma_src;
- ks_uint16 hdma_dst;
- ks_uint16 hdma_r16;
- ks_double hdma_clk;
- ks_double hbl_clks_st;
- ks_double oambg_clks_divider21;
- void (*bgwin_done) (struct ppu *_5028, ks_int16 scanline);
- void (*sprite_done) (struct ppu *_5028, ks_int delta);
- void (*device_blit) (struct ppu *_5028, void *obj, struct ppu_framebuffer *fbuf); /*blit for host devcice */
- void *obj;
- void (*clks) (struct ppu *);
- };
- struct gameboy {
- struct controller *joypad;
- struct cpu *lr35902;
- struct ppu *lh5028;
- struct apu *apu;
- struct cartridge *cart;
- struct divider *divider;
- struct timer *timer;
- struct serial *serial;
- struct machine_setup *mach_tools;
- ks_double cpu_clks;
- ks_double cpu_clks_total;
- ks_double cpu_clks_timer; // cur full - block
- ks_double cpu_clks_timerdbg; // cur full - block
- ks_double cpu_clks_joypad; // cur full - block
- ks_double cpu_clks_divider; // cur full - block
- ks_double cpu_clks_ppu; // cur full - block
- ks_double cpu_clks_apu; // cur full - block
- ks_double cpu_clks_cart; // cur full - block
- ks_double cpu_clks_serial; // RS232 Serial Port for CGB/ DMG.
- ks_double cpu_clks_dma;
- ks_double deflect_ms;
- ks_uint8 reg01_SB;
- ks_uint8 reg02_SC;
- ks_uint8 reg0F_IF; /* interrupt flags register */
- ks_uint8 reg56_IC;
- ks_uint8 reg70_SVBK;
- ks_uint8 regFF_IE; /* Interrupt enable register */
- /* work ram. */
- ks_uint8 wram[0x8000];
- /* high ram. */
- ks_uint8 hram[0x200];
- /* unknow mem, io read/write */
- ks_uint8 unknow_ram[0x10000];
- /* controller drv */
- void (*controller_hostdrv)
- (struct gameboy *, void *controller_drvobj,
- struct controller_pad *, /* gb-self for recv joypadbuffer */
- struct controller_pad * /* host-edge 1?pulse gen:nodone */);
- void *controller_drvobj;
- /* display drv */
- void (*display_hostdrv)
- (struct gameboy *, void *display_drvobj,
- struct ppu_framebuffer *fmebuf);
- void *display_drvobj;
- /* sound drv */
- };
- struct timer {
- ks_uint8 reg05_TIMA;
- ks_uint8 reg06_TMA;
- ks_uint8 reg07_TAC;
- ks_double freq_tab[4];
- void (*clks) (struct timer *);
- ks_double timestamp;
- struct gameboy *gb;
- };
- struct divider {
- ks_uint8 reg04_DIV;
- ks_double freq;
- void (*clks) (struct divider *);
- ks_double timestamp;
- struct gameboy *gb;
- };
- struct apu {
- ks_uint8 reg10_NR10;
- ks_uint8 reg11_NR11;
- ks_uint8 reg12_NR12;
- ks_uint8 reg13_NR13;
- ks_uint8 reg14_NR14;
- ks_uint8 reg16_NR21;
- ks_uint8 reg17_NR22;
- ks_uint8 reg18_NR23;
- ks_uint8 reg19_NR24;
- ks_uint8 reg1A_NR30;
- ks_uint8 reg1B_NR31;
- ks_uint8 reg1C_NR32;
- ks_uint8 reg1D_NR33;
- ks_uint8 reg1E_NR34;
- ks_uint8 reg20_NR41;
- ks_uint8 reg21_NR42;
- ks_uint8 reg22_NR43;
- ks_uint8 reg23_NR44;
- ks_uint8 reg24_NR50;
- ks_uint8 reg25_NR51;
- ks_uint8 reg26_NR52;
- ks_uint8 reg30_AUD3WAVERAM;
- ks_uint8 reg31_AUD3WAVERAM;
- ks_uint8 reg32_AUD3WAVERAM;
- ks_uint8 reg33_AUD3WAVERAM;
- ks_uint8 reg34_AUD3WAVERAM;
- ks_uint8 reg35_AUD3WAVERAM;
- ks_uint8 reg36_AUD3WAVERAM;
- ks_uint8 reg37_AUD3WAVERAM;
- ks_uint8 reg38_AUD3WAVERAM;
- ks_uint8 reg39_AUD3WAVERAM;
- ks_uint8 reg3A_AUD3WAVERAM;
- ks_uint8 reg3B_AUD3WAVERAM;
- ks_uint8 reg3C_AUD3WAVERAM;
- ks_uint8 reg3D_AUD3WAVERAM;
- ks_uint8 reg3E_AUD3WAVERAM;
- ks_uint8 reg3F_AUD3WAVERAM;
- ks_uint8 reg76_PCMChannel1_2;
- ks_uint8 reg77_PCMChannel3_4;
- void (*clks) (struct apu *);
- struct gameboy *gb;
- };
- struct serial {
- void (*clks) (struct serial *);
- struct gameboy *gb;
- };
- /* cartridge device type */
- #define MBC_0 0
- #define MBC_1 1
- #define MBC_2 2
- #define MBC_3 3
- #define MBC_4 4
- #define MBC_5 5
- #define MBC_6 6
- #define MBC_7 7
- #define TAMA5 8
- #define HUCL1 9
- #define HUCL3 10
- #define MMM0 11
- #define POCKER_CAM 12
- /* MBC1 */
- #define MBC1_MODE0_2MROM_8KRAM 0
- #define MBC1_MODE1_512KROM_32KRAM 1
- typedef int mbc1_cart_mode;
- struct mbc1_chip {
- mbc1_cart_mode mode;
- ks_bool ram_en;
- ks_uint16 prombank;
- ks_uint16 srambank;
- ks_uint16 bankcac;
- };
- struct cartridge {
- struct romheader header;
- ks_bool s_latch;
- ks_bool battery;
- ks_uint8 *promworks;
- ks_uint8 *sramworks;
- ks_uint8 promsize;
- ks_uint8 sramsize;
- void (*clks) (struct cartridge *);
- ks_uint8 (*read) (struct cartridge *cartridge, ks_uint16 address);
- ks_void (*write) (struct cartridge *cartridge, ks_uint16 address, ks_uint8 value);
- union {
- struct mbc1_chip *mbc1;
- void *ubdata_user;
- };
- struct gameboy *gb;
- };
- #define IRQ_1 0x01 /* VBLANK (NMI) */
- #define IRQ_2 0x02 /* LCDC */
- #define IRQ_3 0x04 /* Programmable timer */
- #define IRQ_4 0x08 /* Serial port switching */
- #define IRQ_5 0x10 /* P14-15 Descent edge acknowledge */
- #define IRQ_NIL 0xFF /* P14-15 Descent edge acknowledge */
- #define IRQ_1_ADDRESS 0x40 /* VBLANK (NMI) */
- #define IRQ_2_ADDRESS 0x48 /* LCDC */
- #define IRQ_3_ADDRESS 0x50 /* Programmable timer */
- #define IRQ_4_ADDRESS 0x58 /* Serial port switching */
- #define IRQ_5_ADDRESS 0x60 /* P14-15 Descent edge acknowledge */
- /* gameboy internal done **/
- int gameboy_resume_ifstop (struct gameboy *gb);
- double gameboy_getcycles (struct gameboy *gb);
- double gameboy_get_ppuclks (struct gameboy *gb, ks_bool *stride_frame);
- void gameboy_setcycles (struct gameboy *gb, double cycles);
- ks_uint8 ks_callstd gameboy_mmu_read (struct gameboy *gb, ks_uint16 address);
- ks_uint16 ks_callstd gameboy_mmu_read_w (struct gameboy *gb, ks_uint16 address);
- ks_void ks_callstd gameboy_mmu_write (struct gameboy *gb, ks_uint16 address, ks_uint8 value);
- ks_void ks_callstd gameboy_mmu_write_w (struct gameboy *gb, ks_uint16 address, ks_uint16 value);
- int gameboy_resume_ifstop (struct gameboy *gb);
- int gameboy_hdma_copy (struct gameboy *gb);
- #endif
- /* controller (PL0-PL5, with DAN215)
- * Game boy's joypad information read and write
- *
- * Copyright (C) 2018 moecmks
- * This file is part of KS3578.
- *
- * do What The Fuck you want to Public License
- *
- * Version 1.0, March 2000
- * Copyright (C) 2000 Banlu Kemiyatorn (]d).
- * 136 Nives 7 Jangwattana 14 Laksi Bangkok
- * Everyone is permitted to copy and distribute verbatim copies
- * of this license document, but changing it is not allowed.
- *
- * Ok, the purpose of this license is simple
- * and you just
- *
- * DO WHAT THE FUCK YOU WANT TO.
- */
- #include "gameboy.h"
- #include "internal.h"
- /* for internal call */
- #define joypad_hostdrv ubdata_user
- /* Assert IRQ_5 Interrupt Gen MACRO */
- #ifndef IRQ_5
- # define IRQ_5 0x10
- #endif
- #ifndef JOYPAD_INTERRUPT_GEN_ENABLE
- # undef IRQ_5
- # define IRQ_5 0
- #endif
- static
- void default_update (struct controller *ctl, void *obj, struct controller_pad *gb_infos, struct controller_pad *host_infos) {
- printf ("%s:%s please set joypad callback( controller_setupdate function)\n", __FILE__, __LINE__);
- assert (0);
- }
- void controller_write (struct controller *ctl, ks_uint8 value) {
- ctl->reg00_P1 = value & 0x30;
- }
- /* Gameboy Joypad Infos:http://gbdev.gg8.se/files/docs/mirrors/pandocs.html#joypadinput */
- ks_uint8 controller_read (struct controller *ctl) {
- ks_uint8 value =ctl->reg00_P1 & 0x30;
- switch (value) {
- case 0x00: /* maybe result direction | action ??*/
- value = ctl->reg00_P1 & 0xF0;
- value|= 0x0F;
- #if (JOYPAD_LOAD_ACTION_IN_P1415_ALLOPEN == 0)
- if (ctl->gb_pad.right || ctl->gb_pad.a) value &= ~0x01; /*Right ||A*/
- if (ctl->gb_pad.left || ctl->gb_pad.b) value &= ~0x02; /*Left ||B */
- if (ctl->gb_pad.up || ctl->gb_pad.select) value &= ~0x04; /*Up ||Select */
- if (ctl->gb_pad.down || ctl->gb_pad.start) value &= ~0x08; /*Down || Start*/
- #elif (JOYPAD_LOAD_ACTION_IN_P1415_ALLOPEN == 1)
- if (ctl->gb_pad.right && ctl->gb_pad.a) value &= ~0x01; /*Right ||A*/
- if (ctl->gb_pad.left && ctl->gb_pad.b) value &= ~0x02; /*Left ||B */
- if (ctl->gb_pad.up && ctl->gb_pad.select) value &= ~0x04; /*Up ||Select */
- if (ctl->gb_pad.down && ctl->gb_pad.start) value &= ~0x08; /*Down || Start*/
- #elif (JOYPAD_LOAD_ACTION_IN_P1415_ALLOPEN == 2)
- if ((!!ctl->gb_pad.right) ^ !!ctl->gb_pad.a) value &= ~0x01; /*Right ||A*/
- if ((!!ctl->gb_pad.left) ^ !!ctl->gb_pad.b) value &= ~0x02; /*Left ||B */
- if ((!!ctl->gb_pad.up) ^ !!ctl->gb_pad.select) value &= ~0x04; /*Up ||Select */
- if ((!!ctl->gb_pad.down) ^ !!ctl->gb_pad.start) value &= ~0x08; /*Down || Start*/
- #elif (JOYPAD_LOAD_ACTION_IN_P1415_ALLOPEN == 3)
- if (!(ctl->gb_pad.right && ctl->gb_pad.a)) value &= ~0x01; /*Right ||A*/
- if (!(ctl->gb_pad.left && ctl->gb_pad.b)) value &= ~0x02; /*Left ||B */
- if (!(ctl->gb_pad.up && ctl->gb_pad.select)) value &= ~0x04; /*Up ||Select */
- if (!(ctl->gb_pad.down && ctl->gb_pad.start)) value &= ~0x08; /*Down || Start*/
- #else
- # error "JOYPAD_LOAD_ACTION_IN_P1415_ALLOPEN define error."
- #endif
- break;
- case 0x30: /* reset device ?*/
- return 0xFF;
- case 0x20: /* p14 out, set button, active low*/
- value = ctl->reg00_P1 & 0xF0;
- value|= 0x0F;
- if (ctl->gb_pad.right) value &= ~0x01; /*Right */
- if (ctl->gb_pad.left) value &= ~0x02; /*Left */
- if (ctl->gb_pad.up) value &= ~0x04; /*Up */
- if (ctl->gb_pad.down) value &= ~0x08; /*Down */
- break;
- case 0x10: /* p15 out, set direction, active low */
- value = ctl->reg00_P1 & 0xF0;
- value|= 0x0F;
- if (ctl->gb_pad.a) value &= ~0x01; /*A */
- if (ctl->gb_pad.b) value &= ~0x02; /*B */
- if (ctl->gb_pad.select) value &= ~0x04; /*Select */
- if (ctl->gb_pad.start) value &= ~0x08; /*Start */
- break;
- }
- return value;
- }
- void controller_uninit (struct controller **ctl) {
- struct controller *ctl_;
- assert (ctl != ks_null);
- ctl_ = *ctl;
- *ctl = ks_null;
- if (ctl_ != ks_null)
- free (ctl_);
- else ;
- }
- void controller_setupdate_ (struct controller *ctl, void (*update)
- (struct controller *,
- void *,
- struct controller_pad *, /* self */
- struct controller_pad * /* host edge */), void *obj){
- assert (ctl != ks_null);
- assert (update != ks_null);
- ctl->joypad_hostdrv = update;
- ctl->obj = obj;
- }
- static
- void controller_update_hostdrv (struct controller *ctl) {
- if (ctl->gb->cpu_clks_joypad > ctl->gb->mach_tools->joypad_gen_freq) {
- ks_bool edge_gen =ks_false;
- /* temrp cache for check edge (high to low*/
- struct controller_pad edge;
- assert (ctl != ks_null);
- memset (& edge, 0, sizeof (edge));
- /*call hostdrv*/
- ((void (*)(struct controller *, void *,
- struct controller_pad *,
- struct controller_pad *))(ctl->joypad_hostdrv)) (ctl, ctl->obj, & ctl->gb_pad, & edge);
- ctl->gb->cpu_clks_joypad -= ctl->gb->mach_tools->joypad_gen_freq; /* sub a clk block */
- /* there is a bouncing phenomenon similar to electrical components flutter in real gameboy,
- making joypad interrupt very difficult to use. */
- /* check register */
- switch (ctl->reg00_P1 & 0x30) {
- case 0x30: /* close device*/
- return ;
- case 0x00: /* any button press will cause interrupt requested, resume stop command */
- if (edge.right || edge.a) edge_gen = ks_true; /*Right ||A*/
- if (edge.left || edge.b) edge_gen = ks_true; /*Left ||B */
- if (edge.up || edge.select) edge_gen = ks_true; /*Up ||Select */
- if (edge.down || edge.start) edge_gen = ks_true; /*Down || Start*/
- case 0x20: /* p14 out, button, */
- if (edge.right) edge_gen = ks_true; /*Right */
- if (edge.left) edge_gen = ks_true; /*Left */
- if (edge.up) edge_gen = ks_true; /*Up */
- if (edge.down) edge_gen = ks_true; /*Down */
- break;
- case 0x10: /* p15 out, direction */
- if (edge.a) edge_gen = ks_true; /*A */
- if (edge.b) edge_gen = ks_true; /*B */
- if (edge.select) edge_gen = ks_true; /*Select */
- if (edge.start) edge_gen = ks_true; /*Start */
- break;
- }
- if (edge_gen != ks_false) {
- /* Set interrupt flags */
- # if 1
- /* try resume gameboy from stop, (if stop) */
- if (ctl->gb->lr35902->stop != ks_false) {
- ctl->gb->lr35902->stop = ks_false;
- ctl->gb->reg0F_IF |= IRQ_5;
- }
- # else
- /* IRQ_5 is the lowest priority interruption.*/
- ctl->gb->reg0F_IF |= IRQ_5;
- /* try resume gameboy from stop, (if stop) */
- gameboy_resume_ifstop (ctl->gb);
- # endif
- }
- }
- }
- int controller_init (struct controller **ctl) {
- struct controller *ctl_ =ks_null;
- assert (ctl != ks_null);
- ctl_ = (struct controller *)
- calloc (sizeof (struct controller), 1);
- ctl_->joypad_hostdrv = default_update;
- ctl_->obj = ks_null;
- ctl_->clks = controller_update_hostdrv;
- assert (ctl_ != ks_null);
- // memset (& ctl_->gb_pad, 0x01, sizeof (ctl_->gb_pad));
- * ctl = ctl_;
- return 0;
- }
- /* Game boy's GPU and LCD Screen
- * LCD is Sharp LH5028 http://www.datasheetarchive.com/pdf/download.php?id=c615e5d8551c6b559c3db61b709b3234af856c&type=O&term=LH5028
- *
- * This part of the source code is actually not very good.
- * It looks terrible.
- *
- * Copyright (C) 2018 moecmks
- * This file is part of KS3578.
- *
- * do What The Fuck you want to Public License
- *
- * Version 1.0, March 2000
- * Copyright (C) 2000 Banlu Kemiyatorn (]d).
- * 136 Nives 7 Jangwattana 14 Laksi Bangkok
- * Everyone is permitted to copy and distribute verbatim copies
- * of this license document, but changing it is not allowed.
- *
- * Ok, the purpose of this license is simple
- * and you just
- *
- * DO WHAT THE FUCK YOU WANT TO.
- */
- #include "gameboy.h"
- #include "internal.h"
- static
- void default_update (struct ppu *_5028, void *obj, struct ppu_framebuffer *fbuf) {
- printf ("%s:%s please set ppu_update callback( controller_setupdate function)\n", __FILE__, __LINE__);
- assert (0);
- }
- void ppu_setupdate_ (struct ppu *lh5028, void (*update)
- (struct ppu *,
- void *,
- struct ppu_framebuffer *), void *obj)
- {
- lh5028->device_blit = update;
- lh5028->obj = obj;
- }
- int ppu_reset (struct ppu *lh5028) {
- /* init register http://gbdev.gg8.se/files/docs/mirrors/pandocs.html#powerupsequence */
- lh5028->reg40_LCDC = 0x91;
- lh5028->reg42_SCY = 0x00;
- lh5028->reg43_SCX = 0x00;
- lh5028->reg45_LYC = 0x00;
- lh5028->reg47_BGP = 0xFC;
- lh5028->reg48_OBP0 = 0xFF;
- lh5028->reg49_OBP1 = 0xFF;
- lh5028->reg4A_WY = 0x00;
- lh5028->reg4B_WX = 0x00;
- /* reset cache */
- lh5028->reg41_LCDM_T = lh5028->reg41_LCDS;
- lh5028->hbl_clks_st = 9999.8;
- return 0;
- }
- void ppu_uninit (struct ppu **lh5028);
- void ppu_write (struct ppu *lh5028, ks_uint16 address, ks_uint8 value) {
- ks_uint8 c, s;
- switch (address) {
- case 0xFF40: /* FF40 - LCDC - LCD Control (R/W) **/
- /*Bit 7 - LCD Display Enable (0=Off, 1=On)
- Bit 6 - Window Tile Map Display Select (0=9800-9BFF, 1=9C00-9FFF)
- Bit 5 - Window Display Enable (0=Off, 1=On)
- Bit 4 - BG & Window Tile Data Select (0=8800-97FF, 1=8000-8FFF)
- Bit 3 - BG Tile Map Display Select (0=9800-9BFF, 1=9C00-9FFF)
- Bit 2 - OBJ (Sprite) Size (0=8x8, 1=8x16)
- Bit 1 - OBJ (Sprite) Display Enable (0=Off, 1=On)
- Bit 0 - BG/Window Display/Priority (0=Off, 1=On)
- */
- if (!(lh5028->reg40_LCDC & LCDC_DISPLAY_MASK)&& (value & LCDC_DISPLAY_MASK)) {
- /* re-enable display */
- # if 0
- lh5028->gb->cpu_clks_ppu = 0.0;
- lh5028->reg41_LCDM_T =LCDS_MODE_FLAG_SERACH_OAM;
- lh5028->reg41_IRQf |= LCDS_INTERRUPET_ALL_MASK;
- lh5028->reg41_LCDS &= ~3;
- lh5028->reg41_LCDS |= LCDS_MODE_FLAG_SERACH_OAM;
- lh5028->reg40_NMIf = 1;
- lh5028->vscan = -1;
- lh5028->vscanR = 0;
- lh5028->vscan40 = 0;
- lh5028->uscan = -1;
- lh5028->uscanR = 0;
- lh5028->win_stuff = ks_false;
- lh5028->hbl_clks_st = 9999.8;
- lh5028->reg44_LY = 0;
- # endif
- lh5028->reg4A_WYRSC = 0;
- }
- if (!(value & LCDC_DISPLAY_MASK))
- lh5028->reg44_LY = 0;
- else ;
- lh5028->reg40_LCDC = value;
- break;
- case 0xFF41: /* FF41 - STAT - LCDC Status (R/W) */
- /*Bit 6 - LYC=LY Coincidence Interrupt (1=Enable) (Read/Write)
- Bit 5 - Mode 2 OAM Interrupt (1=Enable) (Read/Write)
- Bit 4 - Mode 1 V-Blank Interrupt (1=Enable) (Read/Write)
- Bit 3 - Mode 0 H-Blank Interrupt (1=Enable) (Read/Write)
- Bit 2 - Coincidence Flag (0:LYC<>LY, 1:LYC=LY) (Read Only)
- Bit 1-0 - Mode Flag (Read Only)
- 0: During H-Blank
- 1: During V-Blank
- 2: During Searching OAM
- 3: During Transferring Data to LCD Driver
- */
- lh5028->reg41_LCDS &= 7;
- lh5028->reg41_LCDS |= (value & ~7);
- break;
- case 0xFF42: /* FF42 - SCY - Scroll Y (R/W) */
- lh5028->reg42_SCY = value;
- break;
- case 0xFF43: /* FF43 - SCX - Scroll X (R/W) */
- lh5028->reg43_SCX = value;
- break;
- case 0xFF44: /* FF44 - LY - LCDC Y-Coordinate (R) */
- _DEBUG_BREAK();
- break;
- case 0xFF45: /* FF45 - LYC - LY Compare (R/W) */
- lh5028->reg45_LYC = value;
- break;
- case 0xFF4A: /* FF4A - WY - Window Y Position (R/W) */
- lh5028->reg4A_WY = value;
- break;
- case 0xFF4B: /* FF4B - WX - Window X Position minus 7 (R/W) */
- lh5028->reg4B_WX = value;
- break;
- case 0xFF47: /* FF47 - BGP - BG Palette Data (R/W) - Non CGB Mode Only */
- // value = 0xE8;
- lh5028->bg_pal_dmg[0] = lh5028->bg_pal_dmgT[(value & 0x03) >> 0];
- lh5028->bg_pal_dmg[1] = lh5028->bg_pal_dmgT[(value & 0x0C) >> 2];
- lh5028->bg_pal_dmg[2] = lh5028->bg_pal_dmgT[(value & 0x30) >> 4];
- lh5028->bg_pal_dmg[3] = lh5028->bg_pal_dmgT[(value & 0xC0) >> 6];
- lh5028->reg47_BGP = value;
- break ;
- case 0xFF48: /* FF48 - OBP0 - Object Palette 0 Data (R/W) - Non CGB Mode Only */
- lh5028->sp_pal_dmg[0][0] = lh5028->sp_pal_dmgT[0][(value & 0x03) >> 0];
- lh5028->sp_pal_dmg[0][1] = lh5028->sp_pal_dmgT[0][(value & 0x0C) >> 2];
- lh5028->sp_pal_dmg[0][2] = lh5028->sp_pal_dmgT[0][(value & 0x30) >> 4];
- lh5028->sp_pal_dmg[0][3] = lh5028->sp_pal_dmgT[0][(value & 0xC0) >> 6];
- lh5028->reg48_OBP0 = value;
- break ;
- case 0xFF49: /* FF49 - OBP1 - Object Palette 1 Data (R/W) - Non CGB Mode Only */
- lh5028->sp_pal_dmg[1][0] = lh5028->sp_pal_dmgT[1][(value & 0x03) >> 0];
- lh5028->sp_pal_dmg[1][1] = lh5028->sp_pal_dmgT[1][(value & 0x0C) >> 2];
- lh5028->sp_pal_dmg[1][2] = lh5028->sp_pal_dmgT[1][(value & 0x30) >> 4];
- lh5028->sp_pal_dmg[1][3] = lh5028->sp_pal_dmgT[1][(value & 0xC0) >> 6];
- lh5028->reg49_OBP1 = value;
- break ;
- case 0xFF68: /* FF68 - BCPS/BGPI - CGB Mode Only - Background Palette Index */
- lh5028->reg68_BCPS = value;
- break ;
- case 0xFF69: /* FF69 - BCPD/BGPD - CGB Mode Only - Background Palette Data */
- s = lh5028->reg68_BCPS;
- c = s & 0x3F;
- if (c & 1)
- lh5028->bg_pal[c >> 3][(c & 7) >> 1]._hi = value;
- else
- lh5028->bg_pal[c >> 3][(c & 7) >> 1]._lo = value;
- if (s & 0x80) {
- c = (c + 1) & 0x3F;
- lh5028->reg68_BCPS &= ~0x3F;
- lh5028->reg68_BCPS |= c;
- }
- lh5028->reg69_BCPD = value;
- break;
- case 0xFF6A: /* FF6A - OCPS/OBPI - CGB Mode Only - Sprite Palette Index */
- lh5028->reg6A_OCPS = value;
- break;
- case 0xFF6B: /* FF6B - OCPD/OBPD - CGB Mode Only - Sprite Palette Data */
- s = lh5028->reg6A_OCPS;
- c = s & 0x3F;
- if (c & 1)
- lh5028->sp_pal[c >> 3][(c & 7) >> 1]._hi = value;
- else
- lh5028->sp_pal[c >> 3][(c & 7) >> 1]._lo = value;
- if (s & 0x80) {
- c = (c + 1) & 0x3F;
- lh5028->reg6A_OCPS &= ~0x3F;
- lh5028->reg6A_OCPS |= c;
- }
- lh5028->reg6B_OCPD = value;
- break;
- case 0xFF46: /* FF46 - DMA - DMA Transfer and Start Address (R/W) */
- for (c = 0; c != 160; c++) {
- s = gameboy_mmu_read (lh5028->gb, value * 256 + c);
- ((ks_int8 *)& lh5028->sp[0])[c] = s;
- }
- /* OAMDMA ~ 160 us
- OAMDMA is a parallel DMA */
- /* lh5028->gb->cpu_clks_dma += lh5028->gb->mach_tools->oamdma_clks; */
- lh5028->reg46_DMA = value;
- break ;
- case 0xFF51: /* FF51 - HDMA1 - CGB Mode Only - New DMA Source, High */
- lh5028->reg51_HDMA1 = value;
- break;
- case 0xFF52: /* FF52 - HDMA2 - CGB Mode Only - New DMA Source, Low*/
- lh5028->reg52_HDMA2 = value;
- break;
- case 0xFF53: /* FF53 - HDMA3 - CGB Mode Only - New DMA Destination, High */
- lh5028->reg53_HDMA3 = value;
- break;
- case 0xFF54: /* FF54 - HDMA4 - CGB Mode Only - New DMA Destination, Low*/
- lh5028->reg54_HDMA4 = value;
- break;
- case 0xFF55: /* FF55 - HDMA5 - CGB Mode Only - New DMA Length/Mode/Start */
- if (value & 0x80) {
- /* H-Blank DMA. **/
- lh5028->hdma_src = lh5028->reg51_HDMA1 * 256 + lh5028->reg52_HDMA2;
- lh5028->hdma_dst = lh5028->reg53_HDMA3 * 256 + lh5028->reg54_HDMA4;
- lh5028->hdma_src &= 0xFFF0;
- lh5028->hdma_dst &= 0xFFF0;
- lh5028->hdma_r16 = value & 0x7F;
- lh5028->hdma_r16 ++;
- lh5028->hdma_gen = ks_true;
- /* set HDMA uncompelete/active */
- lh5028->reg55_HDMA5 &= 0x7F;
- } else {
- /* GDMA **/
- ks_uint16 src = lh5028->reg51_HDMA1 * 256 + lh5028->reg52_HDMA2;
- ks_uint16 dst = lh5028->reg53_HDMA3 * 256 + lh5028->reg54_HDMA4;
- ks_uint16 id = 0;
- ks_uint16 K;
- src &= 0xFFF0;
- dst &= 0xFFF0;
- K = value & 0x7F;
- K+= 1;
- /* copy it*/
- for (; id != K; id++) {
- ks_uint16 c;
- for (c =0; c != 16; c++) {
- s = gameboy_mmu_read (lh5028->gb, src + id *16 + c);
- gameboy_mmu_write (lh5028->gb, dst + id *16 + c, s);
- }
- }
- /* burning OAM clks */
- /* It takes (220 + (n * 7.63)) microseconds in single speed
- and (110 + (n * 7.63)) microseconds in double speed mode */
- lh5028->gb->cpu_clks_dma += (lh5028->gb->mach_tools->gdma_clks_b
- + lh5028->gb->mach_tools->gdma_clks_per16 * (ks_double) K);
- /* lh5028->reg55_HDMA5 |= 0x80;/* set GDMA compelete/unactive */
- }
- lh5028->reg55_HDMA5 = value;
- break;
- case 0xFF4F: /* FF4F - VBK - CGB Mode Only - VRAM Bank (R/W) */
- lh5028->reg4F_VBK = value;
- break;
- default:
- return;
- }
- }
- ks_uint8 ppu_read (struct ppu *lh5028, ks_uint16 address) {
- switch (address) {
- case 0xFF40: /* FF40 - LCDC - LCD Control (R/W) **/
- /*Bit 7 - LCD Display Enable (0=Off, 1=On)
- Bit 6 - Window Tile Map Display Select (0=9800-9BFF, 1=9C00-9FFF)
- Bit 5 - Window Display Enable (0=Off, 1=On)
- Bit 4 - BG & Window Tile Data Select (0=8800-97FF, 1=8000-8FFF)
- Bit 3 - BG Tile Map Display Select (0=9800-9BFF, 1=9C00-9FFF)
- Bit 2 - OBJ (Sprite) Size (0=8x8, 1=8x16)
- Bit 1 - OBJ (Sprite) Display Enable (0=Off, 1=On)
- Bit 0 - BG/Window Display/Priority (0=Off, 1=On)
- */
- return lh5028->reg40_LCDC;
- case 0xFF41: /* FF41 - STAT - LCDC Status (R/W) */
- /*Bit 6 - LYC=LY Coincidence Interrupt (1=Enable) (Read/Write)
- Bit 5 - Mode 2 OAM Interrupt (1=Enable) (Read/Write)
- Bit 4 - Mode 1 V-Blank Interrupt (1=Enable) (Read/Write)
- Bit 3 - Mode 0 H-Blank Interrupt (1=Enable) (Read/Write)
- Bit 2 - Coincidence Flag (0:LYC<>LY, 1:LYC=LY) (Read Only)
- Bit 1-0 - Mode Flag (Mode 0-3, see below) (Read Only)
- 0: During H-Blank
- 1: During V-Blank
- 2: During Searching OAM
- 3: During Transferring Data to LCD Driver
- */
- return lh5028->reg41_LCDS;
- case 0xFF42: /* FF42 - SCY - Scroll Y (R/W) */
- return lh5028->reg42_SCY;
- case 0xFF43: /* FF43 - SCX - Scroll X (R/W) */
- return lh5028->reg43_SCX;
- case 0xFF44: /* FF44 - LY - LCDC Y-Coordinate (R) */
- return lh5028->reg44_LY;
- case 0xFF45: /* FF45 - LYC - LY Compare (R/W) */
- return lh5028->reg45_LYC;
- case 0xFF4A: /* FF4A - WY - Window Y Position (R/W) */
- return lh5028->reg4A_WY;
- case 0xFF4B: /* FF4B - WX - Window X Position minus 7 (R/W) */
- return lh5028->reg4B_WX;
- case 0xFF47: /* FF47 - BGP - BG Palette Data (R/W) - Non CGB Mode Only */
- return lh5028->reg47_BGP;
- case 0xFF48: /* FF48 - OBP0 - Object Palette 0 Data (R/W) - Non CGB Mode Only */
- return lh5028->reg48_OBP0;
- case 0xFF49: /* FF49 - OBP1 - Object Palette 1 Data (R/W) - Non CGB Mode Only */
- return lh5028->reg49_OBP1;
- case 0xFF68: /* FF68 - BCPS/BGPI - CGB Mode Only - Background Palette Index */
- return lh5028->reg68_BCPS;
- case 0xFF69: /* FF69 - BCPD/BGPD - CGB Mode Only - Background Palette Data */
- return lh5028->reg69_BCPD;
- case 0xFF6A: /* FF6A - OCPS/OBPI - CGB Mode Only - Sprite Palette Index */
- return lh5028->reg6A_OCPS;
- case 0xFF6B: /* FF6B - OCPD/OBPD - CGB Mode Only - Sprite Palette Data */
- return lh5028->reg6B_OCPD;
- case 0xFF46: /* FF46 - DMA - DMA Transfer and Start Address (R/W) */
- return lh5028->reg46_DMA;
- case 0xFF51: /* FF51 - HDMA1 - CGB Mode Only - New DMA Source, High */
- return lh5028->reg51_HDMA1;
- case 0xFF52: /* FF52 - HDMA2 - CGB Mode Only - New DMA Source, Low*/
- return lh5028->reg52_HDMA2;
- case 0xFF53: /* FF53 - HDMA3 - CGB Mode Only - New DMA Destination, High */
- return lh5028->reg53_HDMA3;
- case 0xFF54: /* FF54 - HDMA4 - CGB Mode Only - New DMA Destination, Low*/
- return lh5028->reg54_HDMA4;
- case 0xFF55: /* FF55 - HDMA5 - CGB Mode Only - New DMA Length/Mode/Start */
- return lh5028->reg55_HDMA5;
- case 0xFF4F: /* FF4F - VBK - CGB Mode Only - VRAM Bank (R/W) */
- return lh5028->reg4F_VBK;
- break;
- default:
- return 0xFF;
- }
- }
- static /* this method for gameboy color */
- void bgwin_render_cgb (struct ppu *lh5028, ks_int16 scanline) {
- struct {
- union { ks_uint16 blk;
- struct { ks_uint8 lo; ks_uint8 hi; }; };
- } chrdat, chrcac;
- /* always scan 168 pixel in every line (21 tiles),
- evenif omfx is ZERO .
- fit buffer offset, so that every time we can scan a complete tile,
- no matter how much omfx is.
- */
- ks_int32 omfx;
- ks_int32 ofx;
- ks_int32 obx;
- ks_int32 omfy;
- ks_int32 ofy;
- ks_int32 vsc;
- ks_uint8 tid;
- ks_int8 tat;
- ks_int32 tidaddr;
- ks_uint16 pixcac;
- ks_uint8 *tdat;
- ks_int32 rxpos;
- ks_uint32 c, q, c2, s;
- ks_int32 c3;
- ks_uint16 *vptrWinDrawStart;
- ks_uint16 *vptrScrollStart;
- /* check current scan region in BG or WINDOW (if WINDOW enable)*/
- if ( (lh5028->reg40_LCDC & 0x20)) {
- /* draw window */
- goto windraw;
- } else {
- /* draw background */
- vsc = lh5028->uscanR;
- omfx = lh5028->reg43_SCX & 7;
- ofx = lh5028->reg43_SCX >> 3;
- omfy = lh5028->reg42_SCY & 7;
- ofy = lh5028->reg42_SCY >> 3;
- ofx = ofx + vsc;
- ofy = ofy + scanline;
- omfy = ofy & 7;
- ofy = ofy >> 3;
- ofx = ofx - (ofx & 32);
- ofy = ofy - (ofy & 32);
- obx = vsc << 3;
- vptrScrollStart = & lh5028->fmebuf.buf[scanline *(lh5028->fmebuf.pitch/sizeof (lh5028->fmebuf.buf[0]))-omfx];
- /* pick tileid and attr from ::Bit 3 - BG Tile Map Display Select (0=9800-9BFF, 1=9C00-9FFF) */
- tidaddr = 0x9800 + (((lh5028->reg40_LCDC & 0x08) >> 3) << 10);
- tidaddr = (tidaddr-0x8000)+(ofy<< 5)+ofx;
- tid = lh5028->ram[tidaddr]; // fetch tileid
- tat = lh5028->ram[tidaddr+0x2000]; // fetch tileattr.
- tdat = & lh5028->ram[((tat & 0x08)>>3)<<13]; // bank select.
- # if 1
- if (lh5028->reg40_LCDC & 0x10) // 0x8000 unsigned address
- tdat = & tdat[tid<<4];
- else //
- tdat = & tdat[0x1000+(((ks_int8)tid)<<4)]; // TODO: done.
- # else
- cti16 = (lh5028->reg40_LCDC & 0x10) << 8;
- cti16^= 0x1000;
- tdat = & tdat[cti16+((ks_int8)(cti16 >>5)) & (((ks_int8)tid) << 4)];
- # endif
- # if 1
- if (tat & 0x40) // check vflip ?
- tdat = & tdat[(7-omfy)*2];
- else
- tdat = & tdat[omfy*2];
- # else
- ctu8 = (tat & 0x40) >> 3; // 8
- ctu8 = ctu8 - (ctu8 >> 3);// 0 or 7
- tdat = & tdat[(ctu8^omfy)<<1];
- # endif
- chrdat.blk = *(ks_uint16 *)tdat;
- /* check x flip */
- if (tat & 0x20) {
- chrcac.blk = chrdat.blk & 0x8080;
- pixcac = pixcac | (chrcac.lo << 7) | (chrcac.hi << 8);
- chrcac.blk = chrdat.blk & 0x4040;
- pixcac = pixcac | (chrcac.lo << 6) | (chrcac.hi << 7);
- chrcac.blk = chrdat.blk & 0x2020;
- pixcac = pixcac | (chrcac.lo << 5) | (chrcac.hi << 6);
- chrcac.blk = chrdat.blk & 0x1010;
- pixcac = pixcac | (chrcac.lo << 4) | (chrcac.hi << 5);
- chrcac.blk = chrdat.blk & 0x0808;
- pixcac = pixcac | (chrcac.lo << 3) | (chrcac.hi << 4);
- chrcac.blk = chrdat.blk & 0x0404;
- pixcac = pixcac | (chrcac.lo << 2) | (chrcac.hi << 3);
- chrcac.blk = chrdat.blk & 0x0202;
- pixcac = pixcac | (chrcac.lo << 1) | (chrcac.hi << 2);
- chrcac.blk = chrdat.blk & 0x0101;
- pixcac = pixcac | (chrcac.lo << 0) | (chrcac.hi << 1);
- } else {
- chrcac.blk = chrdat.blk & 0x8080;
- pixcac = pixcac | (chrcac.lo >> 7) | (chrcac.hi >> 6);
- chrcac.blk = chrdat.blk & 0x4040;
- pixcac = pixcac | (chrcac.lo >> 4) | (chrcac.hi >> 3);
- chrcac.blk = chrdat.blk & 0x2020;
- pixcac = pixcac | (chrcac.lo >> 1) | (chrcac.hi >> 0);
- chrcac.blk = chrdat.blk & 0x1010;
- pixcac = pixcac | (chrcac.lo << 2) | (chrcac.hi << 3);
- chrcac.blk = chrdat.blk & 0x0808;
- pixcac = pixcac | (chrcac.lo << 5) | (chrcac.hi << 6);
- chrcac.blk = chrdat.blk & 0x0404;
- pixcac = pixcac | (chrcac.lo << 8) | (chrcac.hi << 9);
- chrcac.blk = chrdat.blk & 0x0202;
- pixcac = pixcac | (chrcac.lo <<11) | (chrcac.hi <<12);
- chrcac.blk = chrdat.blk & 0x0101;
- pixcac = pixcac | (chrcac.lo <<14) | (chrcac.hi <<15);
- }
- rxpos = obx - omfx;
- q = tat&7;
- if (!(lh5028->reg40_LCDC & 0x01)) {
- vptrScrollStart = & vptrScrollStart[obx];
- /* When Bit 0 is cleared, the background and window lose their priority,
- the sprites will be always displayed on top of background and window,
- independently of the priority flags in OAM and BG Map attributes.
- */
- for (c = 0; c != 8; c++) {
- s = rxpos+c;
- if (lh5028->olf[s].attr & PIXEL_SPRITE_NOTRANS) // spline ptr to +8
- vptrScrollStart[c] = lh5028->olf[s].pixel;
- else
- vptrScrollStart[c] = lh5028->bg_pal[q][pixcac & 3].rgb15;
- pixcac >>= 2;
- }
- } else if (tat & 0x80) { // BG pri.
- vptrScrollStart = & vptrScrollStart[obx];
- for (c = 0; c != 8; c++) {
- vptrScrollStart[c] = lh5028->bg_pal[q][pixcac & 3].rgb15;
- pixcac >>= 2;
- }
- } else {
- for (c = 0; c != 8; c++) {
- s = rxpos+c;
- c2 = pixcac & 3;
- if (lh5028->olf[s].attr & PIXEL_SPRITE_NOTRANS)
- if (!(lh5028->olf[s].attr & PIXEL_SPRITE_BACK))
- vptrScrollStart[c] = lh5028->olf[s].pixel;
- else if ( c2 == 0)
- vptrScrollStart[c] = lh5028->olf[s].pixel;
- else
- vptrScrollStart[c] = lh5028->bg_pal[q][c2].rgb15;
- else
- vptrScrollStart[c] = lh5028->bg_pal[q][c2].rgb15;
- pixcac >>= 2;
- }
- }
- rxpos = obx - omfx; // -7 | 25
- rxpos+= 8; // 1 | 33
- rxpos+= 7; // 8 | 40
- if ( (lh5028->reg40_LCDC & 0x20)
- && (lh5028->reg4B_WX <= 166 && lh5028->reg4B_WX < rxpos) /* check X**/
- && (lh5028->reg4A_WY <= scanline && (lh5028->reg4A_WY <= 143)))
- {
- lh5028->xscanR = 0;
- q = 15 - omfx; // 8 | 16-> 9
- // 7->0
- // 8->1
- while (lh5028->reg4B_WX >= q) // 15 >= q / 16
- {
- lh5028->xscanR ++; // 1 or 2
- q += 8;
- }
- goto windraw;
- }
- }
- return ;
- windraw:
- ofx = lh5028->uscanR - lh5028->xscanR; // espl x
- c = scanline - lh5028->reg4A_WY; // total - y
- omfx = 0;
- omfy = c & 7;
- ofy = c >> 3;
- c3 = ((ks_int8)lh5028->reg4B_WX)-7;
- c3 = c3 + (ofx<<3);
- vptrWinDrawStart = & lh5028->fmebuf.buf[scanline *(lh5028->fmebuf.pitch/sizeof (lh5028->fmebuf.buf[0]))+c3];
- /* pick tileid and attr from ::Bit 6 - Tile Tile Map Display Select (0=9800-9BFF, 1=9C00-9FFF) */
- tidaddr = 0x9800 + (((lh5028->reg40_LCDC & 0x40) >> 6) << 10);
- tidaddr = (tidaddr-0x8000)+(ofy<< 5)+ofx;
- tid = lh5028->ram[tidaddr]; // fetch tileid
- tat = lh5028->ram[tidaddr+0x2000]; // fetch tileattr.
- tdat = & lh5028->ram[((tat & 0x08)>>3)<<13]; // bank select.
- # if 1
- if (lh5028->reg40_LCDC & 0x10) // 0x8000 unsigned address
- tdat = & tdat[tid<<4];
- else //
- tdat = & tdat[0x1000+(((ks_int8)tid)<<4)]; // TODO: done.
- # else
- cti16 = (lh5028->reg40_LCDC & 0x10) << 8;
- cti16^= 0x1000;
- tdat = & tdat[cti16+((ks_int8)(cti16 >>5)) & (((ks_int8)tid) << 4)];
- # endif
- # if 1
- if (tat & 0x40) // check vflip ?
- tdat = & tdat[(7-omfy)*2];
- else
- tdat = & tdat[omfy*2];
- # else
- ctu8 = (tat & 0x40) >> 3; // 8
- ctu8 = ctu8 - (ctu8 >> 3);// 0 or 7
- tdat = & tdat[(ctu8^omfy)<<1];
- # endif
- chrdat.blk = *(ks_uint16 *)tdat;
- /* check x flip */
- if (tat & 0x20) {
- chrcac.blk = chrdat.blk & 0x8080;
- pixcac = pixcac | (chrcac.lo << 7) | (chrcac.hi << 8);
- chrcac.blk = chrdat.blk & 0x4040;
- pixcac = pixcac | (chrcac.lo << 6) | (chrcac.hi << 7);
- chrcac.blk = chrdat.blk & 0x2020;
- pixcac = pixcac | (chrcac.lo << 5) | (chrcac.hi << 6);
- chrcac.blk = chrdat.blk & 0x1010;
- pixcac = pixcac | (chrcac.lo << 4) | (chrcac.hi << 5);
- chrcac.blk = chrdat.blk & 0x0808;
- pixcac = pixcac | (chrcac.lo << 3) | (chrcac.hi << 4);
- chrcac.blk = chrdat.blk & 0x0404;
- pixcac = pixcac | (chrcac.lo << 2) | (chrcac.hi << 3);
- chrcac.blk = chrdat.blk & 0x0202;
- pixcac = pixcac | (chrcac.lo << 1) | (chrcac.hi << 2);
- chrcac.blk = chrdat.blk & 0x0101;
- pixcac = pixcac | (chrcac.lo << 0) | (chrcac.hi << 1);
- } else {
- chrcac.blk = chrdat.blk & 0x8080;
- pixcac = pixcac | (chrcac.lo >> 7) | (chrcac.hi >> 6);
- chrcac.blk = chrdat.blk & 0x4040;
- pixcac = pixcac | (chrcac.lo >> 4) | (chrcac.hi >> 3);
- chrcac.blk = chrdat.blk & 0x2020;
- pixcac = pixcac | (chrcac.lo >> 1) | (chrcac.hi >> 0);
- chrcac.blk = chrdat.blk & 0x1010;
- pixcac = pixcac | (chrcac.lo << 2) | (chrcac.hi << 3);
- chrcac.blk = chrdat.blk & 0x0808;
- pixcac = pixcac | (chrcac.lo << 5) | (chrcac.hi << 6);
- chrcac.blk = chrdat.blk & 0x0404;
- pixcac = pixcac | (chrcac.lo << 8) | (chrcac.hi << 9);
- chrcac.blk = chrdat.blk & 0x0202;
- pixcac = pixcac | (chrcac.lo <<11) | (chrcac.hi <<12);
- chrcac.blk = chrdat.blk & 0x0101;
- pixcac = pixcac | (chrcac.lo <<14) | (chrcac.hi <<15);
- }
- q = tat&7;
- if (!(lh5028->reg40_LCDC & 0x01)) {
- for (c = 0; c != 8; c++) {
- s = c3+c;
- if (lh5028->olf[s].attr & PIXEL_SPRITE_NOTRANS) // spline ptr to +8
- vptrWinDrawStart[c] = lh5028->olf[s].pixel;
- else
- vptrWinDrawStart[c] = lh5028->bg_pal[q][pixcac & 3].rgb15;
- pixcac >>= 2;
- }
- } else if (tat & 0x80) { // BG pri.
- for (c = 0; c != 8; c++) {
- vptrWinDrawStart[c] = lh5028->bg_pal[q][pixcac & 3].rgb15;
- pixcac >>= 2;
- }
- } else {
- for (c = 0; c != 8; c++) {
- s = c3+c;
- c2 = pixcac & 3;
- if (lh5028->olf[s].attr & PIXEL_SPRITE_NOTRANS)
- if (!(lh5028->olf[s].attr & PIXEL_SPRITE_BACK))
- vptrWinDrawStart[c] = lh5028->olf[s].pixel;
- else if ( c2 == 0)
- vptrWinDrawStart[c] = lh5028->olf[s].pixel;
- else
- vptrWinDrawStart[c] = lh5028->bg_pal[q][c2].rgb15;
- else
- vptrWinDrawStart[c] = lh5028->bg_pal[q][c2].rgb15;
- pixcac >>= 2;
- }
- }
- }
- static /* this method for gameboy */
- void bgwin_render_dmg (struct ppu *lh5028, ks_int16 scanline) {
- struct {
- union { ks_uint16 blk;
- struct { ks_uint8 lo; ks_uint8 hi; }; };
- } chrdat, chrcac;
- /* always scan 168 pixel in every line (21 tiles),
- evenif omfx is ZERO .
- fit buffer offset, so that every time we can scan a complete tile,
- no matter how much omfx is.
- */
- ks_int32 omfx;
- ks_int32 ofx;
- ks_int32 obx;
- ks_int32 omfy;
- ks_int32 ofy;
- ks_int32 vsc;
- ks_uint8 tid;
- ks_int32 tidaddr;
- ks_uint16 pixcac;
- ks_uint8 *tdat;
- ks_int32 rxpos;
- ks_uint32 c, q, c2, s;
- ks_int32 c3;
- ks_uint16 *vptrWinDrawStart;
- ks_uint16 *vptrScrollStart;
- /* check current scan region in BG or WINDOW (if WINDOW enable)*/
- if ( lh5028->reg4A_WYLineHit != 0 && (lh5028->reg40_LCDC & LCDC_WINDOW_MASK)) {
- /* draw window */
- goto windraw;
- } else {
- /* draw background */
- vsc = lh5028->uscanR;
- omfx = lh5028->reg43_SCX & 7;
- ofx = lh5028->reg43_SCX >> 3;
- omfy = lh5028->reg42_SCY & 7;
- ofy = lh5028->reg42_SCY >> 0;
- ofx = ofx + vsc;
- ofy = ofy + scanline;
- omfy = ofy & 7;
- ofy = ofy >> 3;
- ofx = ofx - (ofx & 32);
- ofy = ofy - (ofy & 32);
- obx = vsc << 3;
- vptrScrollStart = & lh5028->fmebuf.buf[scanline *(lh5028->fmebuf.pitch/sizeof (lh5028->fmebuf.buf[0]))-omfx];
- /* pick tileid and attr from ::Bit 3 - BG Tile Map Display Select (0=9800-9BFF, 1=9C00-9FFF) */
- tidaddr = 0x9800 + (((lh5028->reg40_LCDC & 0x08) >> 3) << 10);
- tidaddr = (tidaddr-0x8000)+(ofy<< 5)+ofx;
- tid = lh5028->ram[tidaddr]; // fetch tileid
- tdat = & lh5028->ram[0];
- # if 1
- if (lh5028->reg40_LCDC & 0x10) // 0x8000 unsigned address
- tdat = & tdat[tid<<4];
- else //
- tdat = & tdat[0x1000+(((ks_int8)tid)*16)]; // TODO: done.
- # else
- c2 = (lh5028->reg40_LCDC & 0x10) << 8;
- c2^= 0x1000;
- tdat = & tdat[c2+((ks_int8)(c2 >>5)) & (((ks_int8)tid) << 4)];
- # endif
- tdat = & tdat[omfy*2];
- chrdat.blk = *(ks_uint16 *)tdat;
- chrcac.blk = chrdat.blk & 0x8080;
- pixcac = (chrcac.lo >> 7) | (chrcac.hi >> 6);
- chrcac.blk = chrdat.blk & 0x4040;
- pixcac = pixcac | (chrcac.lo >> 4) | (chrcac.hi >> 3);
- chrcac.blk = chrdat.blk & 0x2020;
- pixcac = pixcac | (chrcac.lo >> 1) | (chrcac.hi >> 0);
- chrcac.blk = chrdat.blk & 0x1010;
- pixcac = pixcac | (chrcac.lo << 2) | (chrcac.hi << 3);
- chrcac.blk = chrdat.blk & 0x0808;
- pixcac = pixcac | (chrcac.lo << 5) | (chrcac.hi << 6);
- chrcac.blk = chrdat.blk & 0x0404;
- pixcac = pixcac | (chrcac.lo << 8) | (chrcac.hi << 9);
- chrcac.blk = chrdat.blk & 0x0202;
- pixcac = pixcac | (chrcac.lo <<11) | (chrcac.hi <<12);
- chrcac.blk = chrdat.blk & 0x0101;
- pixcac = pixcac | (chrcac.lo <<14) | (chrcac.hi <<15);
- rxpos = obx - omfx;
- if (!(lh5028->reg40_LCDC & 0x01)) {
- vptrScrollStart = & vptrScrollStart[obx];
- /* When Bit 0 is cleared, both background and window become blank (white),
- ie. the Window Display Bit (Bit 5) is ignored in that case.
- Only Sprites may still be displayed (if enabled in Bit 1).
- */
- for (c = 0; c != 8; c++) {
- s = rxpos+c;
- if (lh5028->olf[s].attr & PIXEL_SPRITE_NOTRANS) // spline ptr to +8
- vptrScrollStart[c] = lh5028->olf[s].pixel;
- else
- // vptrScrollStart[c] = lh5028->bg_pal_dmg[0];
- vptrScrollStart[c] = lh5028->bg_pal_dmgT[0];
- pixcac >>= 2;
- }
- } else {
- vptrScrollStart = & vptrScrollStart[obx];
- for (c = 0; c != 8; c++) {
- s = rxpos+c;
- c2 = pixcac & 3;
- if (lh5028->olf[s].attr & PIXEL_SPRITE_NOTRANS)
- if (!(lh5028->olf[s].attr & PIXEL_SPRITE_BACK))
- vptrScrollStart[c] = lh5028->olf[s].pixel;
- else if ( c2 == 0)
- vptrScrollStart[c] = lh5028->olf[s].pixel;
- else
- vptrScrollStart[c] = lh5028->bg_pal_dmg[pixcac & 3];
- else
- vptrScrollStart[c] = lh5028->bg_pal_dmg[pixcac & 3];
- pixcac >>= 2;
- }
- }
- rxpos = obx - omfx; // -7 | 25
- rxpos+= 8; // 1 | 33
- rxpos+= 7; // 8 | 40
- if ((lh5028->reg40_LCDC & 0x20)
- && (lh5028->reg4B_WX <= 166 && lh5028->reg4B_WX < rxpos) /* check X**/
- && (lh5028->reg4A_WY <= scanline && (lh5028->reg4A_WY <= 143)))
- {
- lh5028->xscanR = 0;
- q = 15 - omfx; // 8 | 16-> 9
- lh5028->reg4A_WYLineHit = 1;
- // 7->0
- // 8->1
- while (lh5028->reg4B_WX >= q) // 15 >= q / 16
- {
- lh5028->xscanR ++; // 1 or 2
- q += 8;
- }
- goto windraw;
- }
- }
- return ;
- windraw:
- // return ;
- ofx = lh5028->uscanR - lh5028->xscanR; // espl x
- c = lh5028->reg4A_WYRSC;
- omfx = 0;
- omfy = c & 7;
- ofy = c >> 3;
- c3 = lh5028->reg4B_WX - 7;
- c3 = c3 + (ofx<<3);
- vptrWinDrawStart = & lh5028->fmebuf.buf[scanline *(lh5028->fmebuf.pitch/sizeof (lh5028->fmebuf.buf[0]))+c3];
- /* pick tileid and attr from ::Bit 6 - Tile Tile Map Display Select (0=9800-9BFF, 1=9C00-9FFF) */
- tidaddr = 0x9800 + (((lh5028->reg40_LCDC & 0x40) >> 6) << 10);
- tidaddr = (tidaddr-0x8000)+(ofy<< 5)+ofx;
- tid = lh5028->ram[tidaddr]; // fetch tileid
- tdat = & lh5028->ram[0]; // bank select.
- # if 1
- if (lh5028->reg40_LCDC & 0x10) // 0x8000 unsigned address
- tdat = & tdat[tid<<4];
- else //
- tdat = & tdat[0x1000+(((ks_int8)tid)*16)]; // TODO: done.
- # else
- cti16 = (lh5028->reg40_LCDC & 0x10) << 8;
- cti16^= 0x1000;
- tdat = & tdat[cti16+((ks_int8)(cti16 >>5)) & (((ks_int8)tid) << 4)];
- # endif
- tdat = & tdat[omfy*2];
- chrdat.blk = *(ks_uint16 *)tdat;
- chrcac.blk = chrdat.blk & 0x8080;
- pixcac = (chrcac.lo >> 7) | (chrcac.hi >> 6);
- chrcac.blk = chrdat.blk & 0x4040;
- pixcac = pixcac | (chrcac.lo >> 4) | (chrcac.hi >> 3);
- chrcac.blk = chrdat.blk & 0x2020;
- pixcac = pixcac | (chrcac.lo >> 1) | (chrcac.hi >> 0);
- chrcac.blk = chrdat.blk & 0x1010;
- pixcac = pixcac | (chrcac.lo << 2) | (chrcac.hi << 3);
- chrcac.blk = chrdat.blk & 0x0808;
- pixcac = pixcac | (chrcac.lo << 5) | (chrcac.hi << 6);
- chrcac.blk = chrdat.blk & 0x0404;
- pixcac = pixcac | (chrcac.lo << 8) | (chrcac.hi << 9);
- chrcac.blk = chrdat.blk & 0x0202;
- pixcac = pixcac | (chrcac.lo <<11) | (chrcac.hi <<12);
- chrcac.blk = chrdat.blk & 0x0101;
- pixcac = pixcac | (chrcac.lo <<14) | (chrcac.hi <<15);
- if (!(lh5028->reg40_LCDC & 0x01)) {
- for (c = 0; c != 8; c++) {
- s = c3+c;
- if (lh5028->olf[s].attr & PIXEL_SPRITE_NOTRANS) // spline ptr to +8
- vptrWinDrawStart[c] = lh5028->olf[s].pixel;
- else
- vptrWinDrawStart[c] = lh5028->bg_pal_dmg[0];
- }
- } else {
- for (c = 0; c != 8; c++) {
- s = c3+c;
- c2 = pixcac & 3;
- if (lh5028->olf[s].attr & PIXEL_SPRITE_NOTRANS)
- if (!(lh5028->olf[s].attr & PIXEL_SPRITE_BACK))
- vptrWinDrawStart[c] = lh5028->olf[s].pixel;
- else if ( c2 == 0)
- vptrWinDrawStart[c] = lh5028->olf[s].pixel;
- else
- vptrWinDrawStart[c] = lh5028->bg_pal_dmg[pixcac & 3];
- else
- vptrWinDrawStart[c] = lh5028->bg_pal_dmg[pixcac & 3];
- pixcac >>= 2;
- }
- }
- }
- static /* this method for gameboy color */
- void sprite_render_cgb (struct ppu *lh5028, ks_int16 scanline) {
- }
- static /* this method for gameboy */
- void sprite_render_dmg (struct ppu *lh5028, ks_int delta) {
- struct {
- union {
- ks_uint16 blk;
- struct {
- ks_uint8 lo;
- ks_uint8 hi;
- };
- };
- } chrdat, chrcac;
- while (delta > 0 && (lh5028->vscan40 < 40) && (lh5028->vscanR < 10)) {
- ks_intptr size16 = (lh5028->reg40_LCDC & LCDC_OAM_SIZE16_MASK) ? 0 : 8;
- struct oam *ops = & lh5028->sp[lh5028->vscan40];
- lh5028->vscan40++;
- if ( !(ops->y == 0 || ops->y >= 160
- || ops->x == 0 || ops->x >= 168)
- && (lh5028->reg44_LY >= (ops->y - 16))
- && (lh5028->reg44_LY < (ops->y - size16)))
- {
- /*draw scanline */
- ks_uint16 pixcac ;
- ks_uint8 *chr;
- ks_uint32 id;
- ks_int x;
- lh5028->vscanR++;
- delta--;
- if (size16 == 0)
- chr = & lh5028->ram[(ops->id & 0xFE)<<4]; // always pointer tile16's high part in init state .
- else
- chr = & lh5028->ram[(ops->id & 0xFF)<<4];
- if (size16 == 0) {
- if (ops->attr & LCD_OAM_FLIP_Y_MASK) {
- int cc = lh5028->reg44_LY - (ops->y - 16);
- /* get oppo base tile byte8 (^source pos[high or low])*/
- if (cc < 7) /* high, switch to low */ {
- cc = 7 -cc; /* flip Y in one tile */
- cc<<= 1;
- cc += 16;
- } else { /* low switch to high, nodone, already in high.*/
- cc = 15 -cc; /* flip Y in one tile */
- cc<<= 1;
- }
- chrdat.blk = *(ks_int16 *)& chr[cc];
- } else {
- int cc = lh5028->reg44_LY - (ops->y - 16);
- cc<<= 1;
- chrdat.blk = *(ks_int16 *)& chr[cc];
- }
- } else {
- if (ops->attr & LCD_OAM_FLIP_Y_MASK) {
- int cc = lh5028->reg44_LY - (ops->y - 16);
- cc = 7 -cc; /* flip Y in one tile */
- cc *= 2;
- chrdat.blk = *(ks_int16 *)& chr[cc];
- } else {
- int cc = lh5028->reg44_LY - (ops->y - 16);
- cc *= 2;
- chrdat.blk = *(ks_int16 *)& chr[cc];
- }
- }
- /* mix gbc's pixel (d1d0)
- * see GBCPUman.pdf:: 2.8.1. Tiles
- * check x flip
- */
- if (ops->attr & LCD_OAM_FLIP_X_MASK) {
- chrcac.blk = chrdat.blk & 0x8080;
- pixcac = (chrcac.lo << 7) | (chrcac.hi << 8);
- chrcac.blk = chrdat.blk & 0x4040;
- pixcac = pixcac | (chrcac.lo << 6) | (chrcac.hi << 7);
- chrcac.blk = chrdat.blk & 0x2020;
- pixcac = pixcac | (chrcac.lo << 5) | (chrcac.hi << 6);
- chrcac.blk = chrdat.blk & 0x1010;
- pixcac = pixcac | (chrcac.lo << 4) | (chrcac.hi << 5);
- chrcac.blk = chrdat.blk & 0x0808;
- pixcac = pixcac | (chrcac.lo << 3) | (chrcac.hi << 4);
- chrcac.blk = chrdat.blk & 0x0404;
- pixcac = pixcac | (chrcac.lo << 2) | (chrcac.hi << 3);
- chrcac.blk = chrdat.blk & 0x0202;
- pixcac = pixcac | (chrcac.lo << 1) | (chrcac.hi << 2);
- chrcac.blk = chrdat.blk & 0x0101;
- pixcac = pixcac | (chrcac.lo << 0) | (chrcac.hi << 1);
- } else {
- chrcac.blk = chrdat.blk & 0x8080;
- pixcac = (chrcac.lo >> 7) | (chrcac.hi >> 6);
- chrcac.blk = chrdat.blk & 0x4040;
- pixcac = pixcac | (chrcac.lo >> 4) | (chrcac.hi >> 3);
- chrcac.blk = chrdat.blk & 0x2020;
- pixcac = pixcac | (chrcac.lo >> 1) | (chrcac.hi >> 0);
- chrcac.blk = chrdat.blk & 0x1010;
- pixcac = pixcac | (chrcac.lo << 2) | (chrcac.hi << 3);
- chrcac.blk = chrdat.blk & 0x0808;
- pixcac = pixcac | (chrcac.lo << 5) | (chrcac.hi << 6);
- chrcac.blk = chrdat.blk & 0x0404;
- pixcac = pixcac | (chrcac.lo << 8) | (chrcac.hi << 9);
- chrcac.blk = chrdat.blk & 0x0202;
- pixcac = pixcac | (chrcac.lo <<11) | (chrcac.hi <<12);
- chrcac.blk = chrdat.blk & 0x0101;
- pixcac = pixcac | (chrcac.lo <<14) | (chrcac.hi <<15);
- }
- x = ops->x - 8;
- for (id = 8; id != 0; id--) {
- ks_uint8 idpal = pixcac & 3;
- /* check trans or */
- if (lh5028->olf[x].attr & PIXEL_SPRITE_NOTRANS) {
- /* notrans */
- if (lh5028->olf[x].attr & PIXEL_SPRITE_BACK) {
- if (!(ops->attr & LCD_OAM_BACKGROUND_MASK) && idpal != 0) {
- # if 1 /* maybe error, it's not a big problem. */
- /* cur pick oam is foreground sprite */
- lh5028->olf[x].pixel = lh5028->sp_pal_dmg[(ops->attr & 0x10) >> 4][idpal];
- lh5028->olf[x].attr = PIXEL_SPRITE_NOTRANS;
- # endif
- }
- } else {
- /* nodone in foreground sprite */
- }
- } else {
- /* trans, write directly */
- lh5028->olf[x].pixel = lh5028->sp_pal_dmg[(ops->attr & 0x10) >> 4][idpal];
- lh5028->olf[x].attr = 0;
- if (ops->attr & LCD_OAM_BACKGROUND_MASK)
- lh5028->olf[x].attr |= PIXEL_SPRITE_BACK;
- if (idpal != 0)
- lh5028->olf[x].attr |= PIXEL_SPRITE_NOTRANS;
- }
- x ++;
- pixcac >>= 2;
- }
- }
- }
- }
- /* XXX:so bad */
- static
- void ticks (struct ppu *lh5028) {
- ks_int32 scanline;
- ks_int16 interv;
- ks_int16 delta;
- ks_double clkline;
- if (lh5028->gb->cpu_clks_ppu > lh5028->gb->mach_tools->frame_cycles) {
- lh5028->gb->cpu_clks_ppu -= lh5028->gb->mach_tools->frame_cycles; // sub a frame block
- /* vblank Interrupt, check missing interruption */
- if (lh5028->reg40_NMIf != 0 && (lh5028->reg40_LCDC & LCDC_DISPLAY_MASK))
- lh5028->gb->reg0F_IF |= IRQ_1;
- /* vblank stat Interrupt, check missing interruption */
- if ((lh5028->reg40_LCDC & LCDC_DISPLAY_MASK)
- && (lh5028->reg41_IRQf & lh5028->reg41_LCDS & LCDS_INTERRUPET_VBLANK_MASK))
- lh5028->gb->reg0F_IF |= IRQ_2;
- /* the beginning of a new frame reset ppu's context */
- lh5028->reg41_IRQf |= LCDS_INTERRUPET_ALL_MASK;
- lh5028->reg40_NMIf = 1;
- lh5028->vscan = -1;
- lh5028->vscanR = 0;
- lh5028->vscan40 = 0;
- lh5028->uscan = -1;
- }
- scanline = (ks_int32) (lh5028->gb->cpu_clks_ppu/ lh5028->gb->mach_tools->line_cycles);
- clkline = lh5028->gb->cpu_clks_ppu - lh5028->gb->mach_tools->line_cycles * (ks_double) scanline;
- /* clear mask */
- lh5028->reg41_LCDS &= ~LCDS_MODE_FLAG_ALL_MASK;
- lh5028->reg44_LY = scanline;
- /*
- PPU time series
- Mode 0: The LCD controller is in the H-Blank period and
- the CPU can access both the display RAM (8000h-9FFFh)
- and OAM (FE00h-FE9Fh)
- Mode 1: The LCD controller is in the V-Blank period (or the
- display is disabled) and the CPU can access both the
- display RAM (8000h-9FFFh) and OAM (FE00h-FE9Fh)
- Mode 2: The LCD controller is reading from OAM memory.
- The CPU <cannot> access OAM memory (FE00h-FE9Fh)
- during this period.
- Mode 3: The LCD controller is reading from both OAM and VRAM,
- The CPU <cannot> access OAM and VRAM during this period.
- CGB Mode: Cannot access Palette Data (FF69,FF6B) either.
- The following are typical when the display is enabled:
- Mode 2 2_____2_____2_____2_____2_____2___________________2____
- Mode 3 _33____33____33____33____33____33__________________3___
- Mode 0 ___000___000___000___000___000___000________________000
- Mode 1 ____________________________________11111111111111_____
- The Mode Flag goes through the values 0, 2, and 3 at a cycle of about 109uS.
- 0 is present about 48.6uS, 2 about 19uS,
- and 3 about 41uS. This is interrupted every 16.6ms by the VBlank (1).
- The mode flag stays set at 1 for about 1.08 ms.
- Mode 0 is present between 201-207 clks, 2 about 77-83 clks, and 3 about 169-175 clks.
- A complete cycle through these states takes 456 clks.
- VBlank lasts 4560 clks. A complete screen refresh occurs every 70224 clks.)
- */
- if (lh5028->reg44_LY_T != lh5028->reg44_LY) {
- lh5028->reg41_IRQf |= LCDS_INTERRUPET_LINE_MASK;
- lh5028->reg4A_WYLineHit = 0;
- }
- /* check FF41::Bit 2 Coincidence Flag (0:LYC<>LY, 1:LYC=LY) (Read Only)*/
- if (lh5028->reg44_LY != lh5028->reg45_LYC)
- lh5028->reg41_LCDS &= ~0x04;
- else {
- if ((lh5028->reg40_LCDC & LCDC_DISPLAY_MASK)
- && (lh5028->reg41_IRQf & lh5028->reg41_LCDS & LCDS_INTERRUPET_LINE_MASK)) {
- lh5028->reg41_IRQf &= ~LCDS_INTERRUPET_LINE_MASK;
- lh5028->gb->reg0F_IF |= IRQ_2;
- }
- lh5028->reg41_LCDS |= 0x04;
- }
- /* check mode */
- if (lh5028->gb->cpu_clks_ppu < lh5028->gb->mach_tools->vbl_clk_st) {
- if (clkline > lh5028->hbl_clks_st) {
- /* ------------------------------ MODE0-HBLANK ------------------------------ */
- lh5028->reg41_LCDS |= LCDS_MODE_FLAG_HBLANK;
- /* check edge */
- if (lh5028->reg41_LCDM_T != LCDS_MODE_FLAG_HBLANK) {
- /* oamvram to current, (low to high) */
- while (lh5028->uscanR < 21) {
- lh5028->bgwin_done (lh5028, scanline);
- lh5028->uscanR ++;
- }
- if (lh5028->reg4A_WYLineHit != 0)
- lh5028->reg4A_WYRSC++;
- /* reset next mode-2 | mode- 3*/
- lh5028->reg41_IRQf |= LCDS_INTERRUPET_OAM_MASK | LCDS_INTERRUPET_VBLANK_MASK;
- lh5028->vscan = -1;
- lh5028->vscan40 = 0;
- lh5028->uscan = -1;
- lh5028->vscanR = 0;
- lh5028->uscanR = 0;
- /* check HDMA. **/
- if (lh5028->reg44_LY >= 0 && lh5028->reg44_LY <= 143 && lh5028->hdma_gen && lh5028->hdma_r16) {
- /* copy 16 bytes */
- ks_uint16 c;
- for (c =0; c != 16; c++) {
- ks_uint8 s;
- s = gameboy_mmu_read (lh5028->gb, lh5028->hdma_src + c);
- gameboy_mmu_write (lh5028->gb, lh5028->hdma_dst + c, s);
- }
- lh5028->hdma_src += 16;
- lh5028->hdma_dst += 16;
- lh5028->hdma_r16 --;
- /* add hdma cycles, ~ 8us */
- lh5028->gb->cpu_clks_dma += (lh5028->gb->mach_tools->clk_ns * 8.0);
- }
- /* in HDMA, no hblank perido */
- lh5028->reg41_IRQf &= ~LCDS_INTERRUPET_HBLANK_MASK;
- }
- /* check hblank interrupt */
- if ((lh5028->reg40_LCDC & LCDC_DISPLAY_MASK)
- && (lh5028->reg41_IRQf & lh5028->reg41_LCDS & LCDS_INTERRUPET_HBLANK_MASK)) {
- lh5028->reg41_IRQf &= ~LCDS_INTERRUPET_HBLANK_MASK;
- lh5028->gb->reg0F_IF |= IRQ_2;
- }
- } else if (clkline > lh5028->gb->mach_tools->oambg_clk_st) {
- /* ------------------------------ MODE3-OAMBG ------------------------------ */
- clkline -= lh5028->gb->mach_tools->oambg_clk_st; // sub, get start clcks epls.
- lh5028->reg41_LCDS |= LCDS_MODE_FLAG_SERACH_OAMVRAM;
- /* check edge */
- if (lh5028->reg41_LCDM_T != LCDS_MODE_FLAG_SERACH_OAMVRAM) {
- lh5028->sprite_done (lh5028, 10);
- /* check sprite interrupt */
- if ((lh5028->reg40_LCDC & LCDC_DISPLAY_MASK)
- && (lh5028->reg41_IRQf & lh5028->reg41_LCDS & LCDS_INTERRUPET_OAM_MASK))
- lh5028->gb->reg0F_IF |= IRQ_2;
- /* adjust BGOAM clk */
- lh5028->hbl_clks_st = (lh5028->gb->mach_tools->oambg_b_cycles +
- lh5028->vscanR * lh5028->gb->mach_tools->oam_clk_add_hbl_per);
- lh5028->oambg_clks_divider21 =
- lh5028->hbl_clks_st / 21.0;
- lh5028->hbl_clks_st += lh5028->gb->mach_tools->oam_cycles;
- lh5028->reg41_IRQf |= (LCDS_INTERRUPET_OAM_MASK | LCDS_INTERRUPET_HBLANK_MASK | LCDS_INTERRUPET_VBLANK_MASK);
- }
- /* check render bg *.*/
- if ((interv = KS_INT16_CAST (clkline/ lh5028->oambg_clks_divider21)) != lh5028->uscan
- && ((lh5028->reg40_LCDC & LCDC_DISPLAY_MASK))) {
- delta = interv - lh5028->uscan;
- lh5028->uscan += delta;
- do {
- lh5028->bgwin_done (lh5028, scanline);
- lh5028->uscanR ++;
- } while (--delta);
- }
- } else {
- /* ------------------------------ MODE2-OAM ------------------------------ */
- lh5028->reg41_LCDS |= LCDS_MODE_FLAG_SERACH_OAM;
- lh5028->hbl_clks_st = 571583.0;
- lh5028->reg40_NMIf = 1;
- /* check edge */
- if (lh5028->reg41_LCDM_T == LCDS_MODE_FLAG_HBLANK) {
- /* hblank to current, (low to high), check stride interrupt */
- if ((lh5028->reg40_LCDC & LCDC_DISPLAY_MASK)
- && (lh5028->reg41_IRQf & lh5028->reg41_LCDS & LCDS_MODE_FLAG_HBLANK))
- lh5028->gb->reg0F_IF |= IRQ_2;
- lh5028->reg41_IRQf |= (LCDS_INTERRUPET_HBLANK_MASK | LCDS_INTERRUPET_VBLANK_MASK);
- /* clear sprite ctx */
- memset (& lh5028->olf[0], 0, sizeof (lh5028->olf));
- }
- /* check render oam *.*/
- if ( (lh5028->reg40_LCDC & LCDC_OAM_MASK)
- && lh5028->vscan != (interv = KS_INT16_CAST (clkline/ lh5028->gb->mach_tools->oam_clk_pick_per))) {
- delta = interv - lh5028->vscan;
- lh5028->vscan += delta;
- /* render sprite */
- lh5028->sprite_done (lh5028, delta);
- }
- /* check sprite interrupt */
- if ( (lh5028->reg40_LCDC & LCDC_DISPLAY_MASK)
- && (lh5028->reg41_IRQf & lh5028->reg41_LCDS & LCDS_INTERRUPET_OAM_MASK)) {
- lh5028->reg41_IRQf &= ~LCDS_INTERRUPET_OAM_MASK;
- lh5028->gb->reg0F_IF |= IRQ_2;
- }
- }
- } else {
- /* ------------------------------ MODE1-VLANK ------------------------------ */
- lh5028->reg41_LCDS |= LCDS_MODE_FLAG_VLANK;
- /* check edge */
- if (lh5028->reg41_LCDM_T != LCDS_MODE_FLAG_VLANK) {
- /* post device render */
- lh5028->device_blit (lh5028, lh5028->obj, & lh5028->fmebuf);
- /* check stride */
- if ((lh5028->reg40_LCDC & LCDC_DISPLAY_MASK)
- && (lh5028->reg41_IRQf & lh5028->reg41_LCDS & LCDS_INTERRUPET_HBLANK_MASK))
- lh5028->gb->reg0F_IF |= IRQ_2;
- lh5028->reg4A_WYRSC = 0;
- lh5028->reg41_IRQf |= (LCDS_INTERRUPET_HBLANK_MASK | LCDS_INTERRUPET_OAM_MASK);
- }
- if (lh5028->reg40_NMIf != 0 && (lh5028->reg40_LCDC & LCDC_DISPLAY_MASK)) {
- lh5028->reg40_NMIf = 0;
- lh5028->gb->reg0F_IF |= IRQ_1;
- }
- if ((lh5028->reg40_LCDC & LCDC_DISPLAY_MASK)
- && (lh5028->reg41_IRQf & lh5028->reg41_LCDS & LCDS_INTERRUPET_VBLANK_MASK)) {
- lh5028->reg41_IRQf &= ~LCDS_INTERRUPET_VBLANK_MASK;
- lh5028->gb->reg0F_IF |= IRQ_2;
- }
- }
- lh5028->reg44_LY_T = lh5028->reg44_LY;
- lh5028->reg41_LCDM_T = lh5028->reg41_LCDS & LCDS_MODE_FLAG_ALL_MASK;
- }
- int ppu_cgb_mode (struct ppu *lh5028) {
- lh5028->bgwin_done = bgwin_render_cgb;
- lh5028->sprite_done = sprite_render_dmg;
- return 0;
- }
- int ppu_dmg_mode (struct ppu *lh5028) {
- lh5028->bgwin_done = bgwin_render_dmg;
- lh5028->sprite_done = sprite_render_dmg;
- return 0;
- }
- int ppu_init (struct ppu **lh5028) {
- struct ppu *sys = ks_null;
- assert (lh5028 != ks_null);
- sys = (struct ppu *)calloc (sizeof (struct ppu), 1);
- assert (sys != ks_null);
- *lh5028 = sys;
- if (1) {
- /* init dmg palette
- 0 White
- 1 Light gray
- 2 Dark gray
- 3 Black
- */
- ks_uint16 color[4] = {
- # if 0
- (0x1F << 0) | (0x1F << 5) | (0x1F << 10), /* color index 0*/
- (0x15 << 0) | (0x15 << 5) | (0x15 << 10), /* color index 1*/
- (0x0A << 0) | (0x0A << 5) | (0x0A << 10), /* color index 2*/
- (0x00 << 0) | (0x00 << 5) | (0x00 << 10) /* color index 3*/
- # else
- // fce88c:0
- // dcb45c:1
- // 987c3c:2
- // 4c3c1c:0
- // ((0x) >> 3)
- (((0x8c) >> 3) << 0) | (((0xe8) >> 3) << 5) | (((0xfc) >> 3) << 10), /* color index 0*/
- (((0x5c) >> 3) << 0) | (((0xb4) >> 3) << 5) | (((0xdc) >> 3) << 10), /* color index 1*/
- (((0x3c) >> 3) << 0) | (((0x7c) >> 3) << 5) | (((0x98) >> 3) << 10), /* color index 2*/
- (((0x1c) >> 3) << 0) | (((0x3c) >> 3) << 5) | (((0x4c) >> 3) << 10) /* color index 3*/
- # endif
- };
- ks_uint16 Q;
- for (Q = 0; Q != 4; Q++) {
- sys->bg_pal_dmgT[Q] = color[Q];
- sys->sp_pal_dmgT[0][Q] = color[Q];
- sys->sp_pal_dmgT[1][Q] = color[Q];
- }
- }
- sys->fmebuf.w = 160;
- sys->fmebuf.h = 144;
- sys->fmebuf.pitch = 512;
- sys->bufb = (ks_uint16 *)malloc ( (sys->fmebuf.w + 96) * (sys->fmebuf.h + 16) * 2 + 128);
- sys->fmebuf.buf = (ks_uint16 *)(((((intptr_t)& sys->bufb[0]) + 31) & -32) + 16);
- sys->device_blit = default_update;
- sys->clks = ticks;
- sys->reg41_LCDM_T =LCDS_MODE_FLAG_SERACH_OAM;
- // value = 0xE8;
- sys->bg_pal_dmg[0] = sys->bg_pal_dmgT[(0xFC & 0x03) >> 0];
- sys->bg_pal_dmg[1] = sys->bg_pal_dmgT[(0xFC & 0x0C) >> 2];
- sys->bg_pal_dmg[2] = sys->bg_pal_dmgT[(0xFC & 0x30) >> 4];
- sys->bg_pal_dmg[3] = sys->bg_pal_dmgT[(0xFC & 0xC0) >> 6];
- return 0;
- }
- /* timer about TIMA, TMA, TAC
- *
- * Copyright (C) 2018 moecmks
- * This file is part of KS3578.
- *
- * do What The Fuck you want to Public License
- *
- * Version 1.0, March 2000
- * Copyright (C) 2000 Banlu Kemiyatorn (]d).
- * 136 Nives 7 Jangwattana 14 Laksi Bangkok
- * Everyone is permitted to copy and distribute verbatim copies
- * of this license document, but changing it is not allowed.
- *
- * Ok, the purpose of this license is simple
- * and you just
- *
- * DO WHAT THE FUCK YOU WANT TO.
- */
- #include "gameboy.h"
- #include "internal.h"
- void timer_write (struct timer *timer, ks_uint16 addr, ks_uint8 value) {
- switch (addr) {
- case 0xFF05: /* TIMA */
- timer->reg05_TIMA = value;
- break;
- case 0xFF06: /* TMA */
- timer->reg06_TMA = value;
- break;
- case 0xFF07: /* TAC */
- if ( (value & 0x04) && !(timer->reg07_TAC & 0x04)) {
- timer->timestamp = timer->gb->cpu_clks_timer; /* low to high, open pulse, init timestamp. */
- timer->reg05_TIMA = timer->reg06_TMA;
- }
- timer->reg07_TAC = value;
- break;
- default:
- assert(0);
- }
- #ifdef TIMER_RESET_IN_RESET_FREQ_MOD_
- timer->timestamp = timer->gb->cpu_clks_timer;
- #endif
- }
- ks_uint8 timer_read (struct timer *timer, ks_uint16 addr) {
- switch (addr) {
- case 0xFF05: /* TIMA */
- return timer->reg05_TIMA;
- case 0xFF06: /* TMA */
- return timer->reg06_TMA;
- case 0xFF07: /* TAC */
- return timer->reg07_TAC;
- default:
- assert(0);
- }
- return 0;
- }
- /*XXX: this function looks bad. */
- static
- void timer_update (struct timer *timer) {
- /* !must update gameboy's context about timer before this call */
- /* double cpu_clks_timer;
- double cpu_clks_el */
- ks_double elap;
- ks_int32 coub;
- ks_double calc_cac;
- assert (timer != ks_null);
- /* enable timing???*/
- if ( !(timer->reg07_TAC & 0x04))
- return ;
- else ;
- /* get elapsed cpu time */
- elap = timer->gb->cpu_clks_timer - timer->timestamp;
- /* convert to basic frequency of timer */
- calc_cac = timer->freq_tab[timer->reg07_TAC & 3];
- coub = 0;
- while (elap > calc_cac) {
- /* update timer */
- if (timer->reg05_TIMA == 0xFF) {
- /* overflow, IRQ_3 interrupt will requested */
- timer->reg05_TIMA = timer->reg06_TMA;
- timer->gb->reg0F_IF |= IRQ_3;
- } else {
- timer->reg05_TIMA ++;
- }
- elap -= calc_cac;
- coub = 1;
- }
- /* update timestamp */
- if (coub != 0) {
- timer->gb->cpu_clks_timer = elap;
- timer->timestamp = 0.0;
- }
- }
- int timer_init (struct timer **timer) {
- struct timer *timer_ =ks_null;
- assert (timer != ks_null);
- timer_ = (struct timer *)
- calloc (sizeof (struct timer), 1);
- timer_->clks = timer_update;
- assert (timer_ != ks_null);
- * timer = timer_;
- return 0;
- }
- void timer_cgb_mode (struct timer *timer) {
- #ifdef TIMER_DIVIDER_SAME_FREQ_BOTH_CBG_DMG_BASE_DMG
- timer->freq_tab[0] = 2047.998;
- timer->freq_tab[1] = 31.998;
- timer->freq_tab[2] = 127.998;
- timer->freq_tab[3] = 511.998;
- #else
- timer->freq_tab[0] = 1023.998;
- timer->freq_tab[1] = 15.998;
- timer->freq_tab[2] = 63.998;
- timer->freq_tab[3] = 255.998;
- #endif
- }
- void timer_dmg_mode (struct timer *timer) {
- timer->freq_tab[0] = 1023.998;
- timer->freq_tab[1] = 15.998;
- timer->freq_tab[2] = 63.998;
- timer->freq_tab[3] = 255.998;
- }
- void timer_uninit (struct timer **timer) {
- struct timer *timer_;
- assert (timer != ks_null);
- timer_ = *timer;
- *timer = ks_null;
- if (timer_ != ks_null)
- free (timer_);
- else ;
- }
- void divider_write (struct divider *divider, ks_uint8 value) {
- divider->reg04_DIV = value;
- }
- ks_uint8 divider_read (struct divider *divider) {
- return divider->reg04_DIV;
- }
- void divider_cgb_mode (struct divider *divider) {
- #ifdef TIMER_DIVIDER_SAME_FREQ_BOTH_CBG_DMG_BASE_DMG
- divider->freq = 512.0;
- #else
- divider->freq = 256.0;
- #endif
- }
- void divider_dmg_mode (struct divider *divider) {
- divider->freq = 256.0;
- }
- /*XXX: this function looks bad. */
- static
- void divider_update (struct divider *divider) {
- /* !must update gameboy's context about divider before this call */
- /* double cpu_clks_divider;
- double cpu_clks_el */
- ks_double elap;
- ks_int32 coub;
- assert (divider != ks_null);
- /* get elapsed cpu time */
- elap = divider->gb->cpu_clks_divider - divider->timestamp;
- coub = 0;
- while (elap > divider->freq) {
- /* update divider */
- divider->reg04_DIV++;
- elap -= divider->freq;
- coub = 1;
- }
- /* update timestamp */
- if (coub != 0) {
- divider->gb->cpu_clks_divider = elap;
- divider->timestamp = 0.0;
- }
- }
- int divider_init (struct divider **divider) {
- struct divider *divider_ =ks_null;
- assert (divider != ks_null);
- divider_ = (struct divider *)
- calloc (sizeof (struct divider), 1);
- divider_->clks = divider_update;
- assert (divider_ != ks_null);
- * divider = divider_;
- divider_dmg_mode (divider_);
- return 0;
- }
- void divider_uninit (struct divider **divider) {
- struct divider *divider_;
- assert (divider != ks_null);
- divider_ = *divider;
- *divider = ks_null;
- if (divider_ != ks_null)
- free (divider_);
- else ;
- }
- ;; cpu_optick.asm
- ;; Sharp LR35902 Chip Opcode for GameBoy
- ;;
- ;; Copyright (C) 2018 moecmks
- ;; This file is part of KS3578.
- ;;
- ;; do What The Fuck you want to Public License
- ;;
- ;; Version 1.0, March 2000
- ;; Copyright (C) 2000 Banlu Kemiyatorn (]d).
- ;; 136 Nives 7 Jangwattana 14 Laksi Bangkok
- ;; Everyone is permitted to copy and distribute verbatim copies
- ;; of this license document, but changing it is not allowed.
- ;;
- ;; Ok, the purpose of this license is simple
- ;; and you just
- ;;
- ;; DO WHAT THE FUCK YOU WANT TO.
- ;;
- .686 ; create 32 bit code
- .model flat, stdcall ; 32 bit memory model
- option casemap :none ; case sensitive
- ;; Sharp LR35902 Chip opcode mapper
- ;; http://www.pastraiser.com/cpu/gameboy/gameboy_opcodes.html
- ;; Z80 Chip opcode mapper
- ;; http://clrhome.org/table/
- ;; Register F Mask
- ;; The register flag field is different from the standard, in order to optimize instruction operation.
- Z_FLAG equ 040H
- H_FLAG equ 010H
- N_FLAG equ 002H
- C_FLAG equ 001H
- ZC_FLAG equ 041H
- ;; extern memory/IO read/write
- extrn gameboy_mmu_read@8:proc ;; prototype ks_uint8 __stdcall gameboy_mmu_read (void;;gameboy, ks_uint16 addresss)
- extrn gameboy_mmu_write@12:proc ;; prototype void __stdcall gameboy_mmu_write (void;;gameboy, ks_uint16 addresss, ks_uint8 value)
- extrn gameboy_mmu_read_w@8:proc ;; prototype ks_uint16 __stdcall gameboy_mmu_read_w (void;;gameboy, ks_uint16 addresss)
- extrn gameboy_mmu_write_w@12:proc ;; prototype void __stdcall gameboy_mmu_write_w (void;;gameboy, ks_uint16 addresss, ks_uint16 value)
- ;; define union .
- defREG macro lo, hi
- union
- struct
- lo db ?
- hi db ?
- ends
- hi&lo dw ?
- ends
- endm
- defREG2 macro lo, hi, blk
- union
- struct
- lo db ?
- hi db ?
- ends
- blk dw ?
- ends
- endm
- ;; XXX:memory order dep.
- cpu struct
- defREG F, A ;; A (Accumulator)
- ;; probably the most commonly used register.
- ;; Many instructions have special extended operation codes for accumulators.
- ;; F (Program status byte)
- ;; defREG C, B ;; A2008: syntax error : C
- union
- struct
- C_ db ?
- B db ?
- ends
- BC dw ?
- ends ;; Register BC, without special explanation.
- defREG E, D ;; Register DE, without special explanation.
- defREG L, H ;; Register HL, which is mostly used to address 16-bit address data,
- ;; also has the basic properties of BC, DE registers
- defREG2 SP_LO, SP_HI, SP_ ;; Stack Pointer.
- defREG2 PC_LO, PC_HI, PC ;; Program Pointer.
- IME db ? ;; Interrupt Master Enable
- halt dd ? ;; for Halt
- stop dd ? ;; for stop
- key1 db ?
- gameboy dd ?
- cpu ends
- .code
- ;; prototype ks_int32 cpu_optick (struct cpu;;cpu_);
- cpu_optick proc C
- option prologue:none, epilogue:none
- push ebx ;U - save old frame
- push edi ;V - save old frame
- push esi
- nop
- YG_PF_8 equ bl
- YG_PF equ ebx
- YG_PC equ esi
- YG_GP equ edi
- _GB_INT3_ASSERT macro address
- .if [YG_GP].PC == address
- int 3
- .endif
- endm
- ; ebx <- save now P (cpu's PSB reg)
- ; esi <- save now PC (cpu's EIP reg)
- ; edi <- save regs root
- ; eax <- calc temp or final calc out reslt
- ; ecx <- calc temp
- ; edx <- calc temp
- mov YG_GP, [esp+4+12] ;; fetch CPU struct
- mov si, [YG_GP].PC
- mov bl, [YG_GP].F
- assume edi:ptr cpu
- ;;_GB_INT3_ASSERT 00994H
- ; Fetch Opcode, PC++
- push YG_PC
- push [YG_GP].gameboy
- call gameboy_mmu_read@8
- inc YG_PC
- and eax, 255
- jmp dword ptr[OPTAB+eax*4]
- EmptyMacro macro
- endm
- SetCyclesAndRet macro Cycles
- ;; write back PC
- mov [YG_GP].PC, si
- mov eax, Cycles
- jmp V_EXIT
- endm
- SetCyclesRetP macro Cycles
- ;; write back PC
- mov [YG_GP].F, bl
- SetCyclesAndRet Cycles
- endm
- ;; Register access-write unwind
- B_Write equ mov [YG_GP].B, al
- C_Write equ mov [YG_GP].C_, al
- D_Write equ mov [YG_GP].D, al
- E_Write equ mov [YG_GP].E, al
- H_Write equ mov [YG_GP].H, al
- L_Write equ mov [YG_GP].L, al
- A_Write equ mov [YG_GP].A, al
- F_Write equ mov [YG_GP].F, al
- SP_Write equ mov [YG_GP].SP_, ax
- DE_Write equ mov [YG_GP].DE, ax
- BC_Write equ mov [YG_GP].BC, ax
- HL_Write equ mov [YG_GP].HL, ax
- AF_Write equ mov [YG_GP].AF, ax
- PC_Write equ mov [YG_GP].PC, ax
- ;; (Imm16) := Z80Register:BYTE
- xImm16_WriteReg8 macro _Reg
- mov cl, [YG_GP]._Reg
- push ecx
- push eax
- push [YG_GP].gameboy
- call gameboy_mmu_write@12
- endm
- ;; (Imm16) := Z80Register:WORD
- xImm16_WriteReg16 macro _Reg
- mov cx, [YG_GP]._Reg
- push ecx
- push eax
- push [YG_GP].gameboy
- call gameboy_mmu_write_w@12
- endm
- ;; (Imm16) := Z80Register-SP
- xImm16_WriteRegSP macro
- xImm16_WriteReg16 SP_
- endm
- ;; (Imm16) := Z80Register-A
- xImm16_WriteRegA macro
- xImm16_WriteReg8 A
- endm
- ;; (Z80Register:WORD ) := Value8:eax::al
- xRegister_WriteReg8 macro _Reg
- push eax
- mov ax, [YG_GP]._Reg
- push eax
- push [YG_GP].gameboy
- call gameboy_mmu_write@12
- endm
- ;; Unwind4
- xBC_Write equ xRegister_WriteReg8 BC
- xDE_Write equ xRegister_WriteReg8 DE
- xHL_Write equ xRegister_WriteReg8 HL
- xAF_Write equ xRegister_WriteReg8 AF
- xPC_Write equ xRegister_WriteReg8 PC
- xHL_Write_Inc macro
- xHL_Write
- inc [YG_GP].HL
- endm
- xHL_Write_Dec macro
- xHL_Write
- dec [YG_GP].HL
- endm
- ;; Register access-read unwind
- B_Read equ mov al, [YG_GP].B
- C_Read equ mov al, [YG_GP].C_
- D_Read equ mov al, [YG_GP].D
- E_Read equ mov al, [YG_GP].E
- H_Read equ mov al, [YG_GP].H
- L_Read equ mov al, [YG_GP].L
- A_Read equ mov al, [YG_GP].A
- BC_Read equ mov ax, [YG_GP].BC
- DE_Read equ mov ax, [YG_GP].DE
- HL_Read equ mov ax, [YG_GP].HL
- SP_Read equ mov ax, [YG_GP].SP_
- AF_Read equ mov ax, [YG_GP].AF
- ;; Imm8:eax::al := FetchPC++
- Imm8_Read macro
- push esi
- push [YG_GP].gameboy
- call gameboy_mmu_read@8
- inc esi
- endm
- ;; Imm16:eax::ax := FetchPC, FetchPC +=2
- Imm16_Read macro
- push esi
- push [YG_GP].gameboy
- call gameboy_mmu_read_w@8
- add esi, 2
- endm
- Read_ByxX86SpecRegister macro _Reg
- ;; _Reg:x86Register
- push _Reg
- push [YG_GP].gameboy
- call gameboy_mmu_read@8
- endm
- Imm8Read_ExpandAddress16 macro
- Imm8_Read
- and eax, 000FFh
- add eax, 0FF00h
- endm
- Imm8_ExpandSignWord macro
- Imm8_Read
- movsx eax, al
- endm
- C_ExpandAddress16 macro
- movzx eax, [YG_GP].C_
- add eax, 0FF00h
- endm
- Imm8Read_ExpandAddress16_Fetch macro
- Imm8Read_ExpandAddress16
- Read_ByxX86SpecRegister eax
- endm
- Imm16Read_Address_Fetch macro
- Imm16_Read
- Read_ByxX86SpecRegister eax
- endm
- C_ExpandAddress16_Fetch macro
- mov al, [YG_GP].C_
- add eax, 0FF00h
- Read_ByxX86SpecRegister eax
- endm
- xRegister_Read macro _Reg
- mov ax, [YG_GP].&_Reg
- push eax
- push [YG_GP].gameboy
- call gameboy_mmu_read@8
- endm
- ;; Unwind5
- xBC_Read equ xRegister_Read BC
- xDE_Read equ xRegister_Read DE
- xHL_Read equ xRegister_Read HL
- xAF_Read equ xRegister_Read AF
- xPC_Read equ xRegister_Read PC
- xHL_Read_Inc macro
- xHL_Read
- inc [YG_GP].HL
- endm
- xHL_Read_Dec macro
- xHL_Read
- dec [YG_GP].HL
- endm
- LD@Imm8 macro OpCase, Cycles_, WriteOrExt
- OpCase&:
- Imm8_Read
- WriteOrExt
- SetCyclesAndRet Cycles_
- endm
- LD@Imm8 OP06, 8, B_Write ;; LD B Imm8, 2, Cycles:8
- LD@Imm8 OP0E, 8, C_Write ;; LD C Imm8, 2, Cycles:8
- LD@Imm8 OP16, 8, D_Write ;; LD D Imm8, 2, Cycles:8
- LD@Imm8 OP1E, 8, E_Write ;; LD E Imm8, 2, Cycles:8
- LD@Imm8 OP26, 8, H_Write ;; LD H Imm8, 2, Cycles:8
- LD@Imm8 OP2E, 8, L_Write ;; LD L Imm8, 2, Cycles:8
- LD@Imm8 OP36,12, xHL_Write ;; LD xHL Imm8, 2, Cycles:8
- LD@Imm8 OP3E, 8, A_Write ;; LD A Imm8, 2, Cycles:8
- LD@Imm16 macro OpCase, Cycles_, lrReg
- OpCase&:
- Imm16_Read
- mov [YG_GP].&lrReg, ax
- SetCyclesAndRet Cycles_
- endm
- LD@Imm16 OP01, 12, BC ;; LD BC Imm16, 3 Cycles:12
- LD@Imm16 OP11, 12, DE ;; LD DE Imm16, 3 Cycles:12
- LD@Imm16 OP21, 12, HL ;; LD HL Imm16, 3 Cycles:12
- LD@Imm16 OP31, 12, SP_ ;; LD SP Imm16, 3 Cycles:12
- LD@RxHLToRxHL macro OpCase, Cycles_, ReadOrExt, WriteOrExt
- OpCase&:
- ReadOrExt
- WriteOrExt
- SetCyclesAndRet Cycles_
- endm
- LD@RxHLToRxHL OP40, 4, B_Read, B_Write ;; LD B B, 1 Cycles:4
- LD@RxHLToRxHL OP41, 4, C_Read, B_Write ;; LD B C, 1 Cycles:4
- LD@RxHLToRxHL OP42, 4, D_Read, B_Write ;; LD B D, 1 Cycles:4
- LD@RxHLToRxHL OP43, 4, E_Read, B_Write ;; LD B E, 1 Cycles:4
- LD@RxHLToRxHL OP44, 4, H_Read, B_Write ;; LD B H, 1 Cycles:4
- LD@RxHLToRxHL OP45, 4, L_Read, B_Write ;; LD B L, 1 Cycles:4
- LD@RxHLToRxHL OP46, 8, xHL_Read, B_Write ;; LD B xHL, 1 Cycles:8
- LD@RxHLToRxHL OP47, 4, A_Read, B_Write ;; LD B A, 1 Cycles:4
- LD@RxHLToRxHL OP48, 4, B_Read, C_Write ;; LD C B, 1 Cycles:4
- LD@RxHLToRxHL OP49, 4, C_Read, C_Write ;; LD C C, 1 Cycles:4
- LD@RxHLToRxHL OP4A, 4, D_Read, C_Write ;; LD C D, 1 Cycles:4
- LD@RxHLToRxHL OP4B, 4, E_Read, C_Write ;; LD C E, 1 Cycles:4
- LD@RxHLToRxHL OP4C, 4, H_Read, C_Write ;; LD C H, 1 Cycles:4
- LD@RxHLToRxHL OP4D, 4, L_Read, C_Write ;; LD C L, 1 Cycles:4
- LD@RxHLToRxHL OP4E, 8, xHL_Read, C_Write ;; LD C xHL, 1 Cycles:8
- LD@RxHLToRxHL OP4F, 4, A_Read, C_Write ;; LD C A, 1 Cycles:4
- LD@RxHLToRxHL OP50, 4, B_Read, D_Write ;; LD D B, 1 Cycles:4
- LD@RxHLToRxHL OP51, 4, C_Read, D_Write ;; LD D C, 1 Cycles:4
- LD@RxHLToRxHL OP52, 4, D_Read, D_Write ;; LD D D, 1 Cycles:4
- LD@RxHLToRxHL OP53, 4, E_Read, D_Write ;; LD D E, 1 Cycles:4
- LD@RxHLToRxHL OP54, 4, H_Read, D_Write ;; LD D H, 1 Cycles:4
- LD@RxHLToRxHL OP55, 4, L_Read, D_Write ;; LD D L, 1 Cycles:4
- LD@RxHLToRxHL OP56, 8, xHL_Read, D_Write ;; LD D xHL, 1 Cycles:8
- LD@RxHLToRxHL OP57, 4, A_Read, D_Write ;; LD D A, 1 Cycles:4
- LD@RxHLToRxHL OP58, 4, B_Read, E_Write ;; LD E B, 1 Cycles:4
- LD@RxHLToRxHL OP59, 4, C_Read, E_Write ;; LD E C, 1 Cycles:4
- LD@RxHLToRxHL OP5A, 4, D_Read, E_Write ;; LD E D, 1 Cycles:4
- LD@RxHLToRxHL OP5B, 4, E_Read, E_Write ;; LD E E, 1 Cycles:4
- LD@RxHLToRxHL OP5C, 4, H_Read, E_Write ;; LD E H, 1 Cycles:4
- LD@RxHLToRxHL OP5D, 4, L_Read, E_Write ;; LD E L, 1 Cycles:4
- LD@RxHLToRxHL OP5E, 8, xHL_Read, E_Write ;; LD E xHL, 1 Cycles:8
- LD@RxHLToRxHL OP5F, 4, A_Read, E_Write ;; LD E A, 1 Cycles:4
- LD@RxHLToRxHL OP60, 4, B_Read, H_Write ;; LD H B, 1 Cycles:4
- LD@RxHLToRxHL OP61, 4, C_Read, H_Write ;; LD H C, 1 Cycles:4
- LD@RxHLToRxHL OP62, 4, D_Read, H_Write ;; LD H D, 1 Cycles:4
- LD@RxHLToRxHL OP63, 4, E_Read, H_Write ;; LD H E, 1 Cycles:4
- LD@RxHLToRxHL OP64, 4, H_Read, H_Write ;; LD H H, 1 Cycles:4
- LD@RxHLToRxHL OP65, 4, L_Read, H_Write ;; LD H L, 1 Cycles:4
- LD@RxHLToRxHL OP66, 8, xHL_Read, H_Write ;; LD H xHL, 1 Cycles:8
- LD@RxHLToRxHL OP67, 4, A_Read, H_Write ;; LD H A, 1 Cycles:4
- LD@RxHLToRxHL OP68, 4, B_Read, L_Write ;; LD L B, 1 Cycles:4
- LD@RxHLToRxHL OP69, 4, C_Read, L_Write ;; LD L C, 1 Cycles:4
- LD@RxHLToRxHL OP6A, 4, D_Read, L_Write ;; LD L D, 1 Cycles:4
- LD@RxHLToRxHL OP6B, 4, E_Read, L_Write ;; LD L E, 1 Cycles:4
- LD@RxHLToRxHL OP6C, 4, H_Read, L_Write ;; LD L H, 1 Cycles:4
- LD@RxHLToRxHL OP6D, 4, L_Read, L_Write ;; LD L L, 1 Cycles:4
- LD@RxHLToRxHL OP6E, 8, xHL_Read, L_Write ;; LD L xHL, 1 Cycles:8
- LD@RxHLToRxHL OP6F, 4, A_Read, L_Write ;; LD L A, 1 Cycles:4
- LD@RxHLToRxHL OP70, 8, B_Read, xHL_Write ;; LD xHL B, 1 Cycles:8
- LD@RxHLToRxHL OP71, 8, C_Read, xHL_Write ;; LD xHL C, 1 Cycles:8
- LD@RxHLToRxHL OP72, 8, D_Read, xHL_Write ;; LD xHL D, 1 Cycles:8
- LD@RxHLToRxHL OP73, 8, E_Read, xHL_Write ;; LD xHL E, 1 Cycles:8
- LD@RxHLToRxHL OP74, 8, H_Read, xHL_Write ;; LD xHL H, 1 Cycles:8
- LD@RxHLToRxHL OP75, 8, L_Read, xHL_Write ;; LD xHL L, 1 Cycles:8
- ;; LD@RxHLToRxHL OP76, 8, xHL_Read, xHL_Write ;; LD xHL xHL, 1 Cycles:8
- LD@RxHLToRxHL OP02, 8, A_Read, xBC_Write ;; LD xBC A, 1 Cycles:8
- LD@RxHLToRxHL OP12, 8, A_Read, xDE_Write ;; LD xDE A, 1 Cycles:8
- LD@RxHLToRxHL OP77, 8, A_Read, xHL_Write ;; LD xHL A, 1 Cycles:8
- LD@RxHLToRxHL OP22, 8, A_Read, xHL_Write_Inc;; LD xHL++ A, 1 Cycles:8
- LD@RxHLToRxHL OP32, 8, A_Read, xHL_Write_Dec ;; LD xHL-- A, 1 Cycles:8
- LD@RxHLToRxHL OP78, 4, B_Read, A_Write ;; LD A B, 1 Cycles:4
- LD@RxHLToRxHL OP79, 4, C_Read, A_Write ;; LD A C, 1 Cycles:4
- LD@RxHLToRxHL OP7A, 4, D_Read, A_Write ;; LD A D, 1 Cycles:4
- LD@RxHLToRxHL OP7B, 4, E_Read, A_Write ;; LD A E, 1 Cycles:4
- LD@RxHLToRxHL OP7C, 4, H_Read, A_Write ;; LD A H, 1 Cycles:4
- LD@RxHLToRxHL OP7D, 4, L_Read, A_Write ;; LD A L, 1 Cycles:4
- LD@RxHLToRxHL OP0A, 8, xBC_Read, A_Write ;; LD A xBC, 1 Cycles:8
- LD@RxHLToRxHL OP1A, 8, xDE_Read, A_Write ;; LD A xDE, 1 Cycles:8
- LD@RxHLToRxHL OP7E, 8, xHL_Read, A_Write ;; LD A xHL, 1 Cycles:8
- LD@RxHLToRxHL OP2A, 8, xHL_Read_Inc, A_Write ;; LD A xHL++, 1 Cycles:8
- LD@RxHLToRxHL OP3A, 8, xHL_Read_Dec, A_Write ;; LD A xHL--, 1 Cycles:8
- LD@RxHLToRxHL OP7F, 4, A_Read, A_Write ;; LD A A, 1 Cycles:4
- ;; MISC LD
- LD@RxHLToRxHL OP08,20, Imm16_Read, xImm16_WriteRegSP ;; LD (Imm16) SP, 3 Cycles:20
- LD@RxHLToRxHL OPEA,16, Imm16_Read, xImm16_WriteRegA ;; LD (Imm16) A, 3 Cycles:16
- LD@RxHLToRxHL OPE0,12, Imm8Read_ExpandAddress16, xImm16_WriteRegA ;; LD (Imm8+0FF00h) A, 2 Cycles:12
- LD@RxHLToRxHL OPE2, 8, C_ExpandAddress16, xImm16_WriteRegA ;; LD (C+0FF00h) A, 2 Cycles:8
- LD@RxHLToRxHL OPF0,12, Imm8Read_ExpandAddress16_Fetch, A_Write ;; LD A, (Imm8+0FF00h) 2 Cycles:12
- LD@RxHLToRxHL OPF2, 8, C_ExpandAddress16_Fetch, A_Write ;; LD A, (C+0FF00h) 2 Cycles:8
- LD@RxHLToRxHL OPFA,16, Imm16Read_Address_Fetch, A_Write ;; LD A, (Imm16) 3 Cycles:16
- LD@RxHLToRxHL OPF9, 8, HL_Read, SP_Write ;; LD SP HL 1 Cycles:8
- OPF8: ;; LD HL SP+Imm8(sign8) 2 Cycles:12
- Imm8_Read
- ;; Clear Reg-f
- ;;xor YG_PF, YG_PF
- xor edx, edx
- ;; ext sign
- movsx ax, al
- mov cx, [YG_GP].SP_
- and ecx, 0FFFFh
- and eax, 0FFFFh
- lea edx, [ecx+eax]
- ;; SetH
- mov [YG_GP].HL, dx
- xor cx, ax
- mov ax, dx
- xor cx, ax
- and cx, 01000h
- shr cx, 8
- ;;or YG_PF, ecx
- ;; SetC
- and dx, 010000h
- shr dx, 16
- ;;or YG_PF, edx
- SetCyclesRetP 12
- ;; ALU, LOGIC 0x8x- 0xBx---------------------------------------------------------------------------------------
- Add$c_xHLrToA macro atomic_it, Cycles
- ;; atomic_it 0(add) or 1(adc)
- ;; source value <- eax
- ;; target <- always register A
- and eax, 0FFh ;; Value &= 0xFF
- and YG_PF, atomic_it
- shr YG_PF, 1 ;; check c-flags
- movzx edx, [YG_GP].A
- mov ecx, edx ;; temp WORD := A
- adc ecx, eax ;; temp WORD := A + Value
- mov [YG_GP].A, cl ;; always write back A.
- xor dx, ax
- mov ax, cx
- xor ax, dx ;; temp WORD:= temp WORD^(A ^Value)
- and ax, 010h
- or YG_PF, eax ;; SetH
- or YG_PF_8, ch ;; SetC
- test cl, cl
- setz cl
- shl ecx, 6
- or YG_PF, ecx ;; SetZ XXX:ZTable
- endm
- CmpSub$bc_xHLrToA macro atomic_it, Cycles, Register ;; [YG_GP].A || cl for cmp opcode
- ;; source <- eax
- ;; target <- always register A or nodone
- and eax, 0FFh ;; Value &= 0xFF
- and YG_PF, atomic_it
- shr YG_PF, 1 ;; check c-flags
- movzx edx, [YG_GP].A
- mov ecx, edx ;; temp WORD := A
- sbb ecx, eax ;; temp WORD := A - Value
- mov Register, cl ;; always write back A.
- xor dx, ax
- mov ax, cx
- xor ax, dx ;; temp WORD:= temp WORD^(A ^Value)
- and ax, 010h
- or YG_PF, eax ;; SetH
- mov eax, ecx
- shr ax, 15
- or YG_PF_8, al ;; SetC
- test cl, cl
- setz cl
- shl ecx, 6
- or YG_PF, ecx ;; SetZ XXX:ZTable
- or YG_PF, N_FLAG ;; SetN
- endm
- ;; XOR | OR | AND do unwind base .
- Logic_T macro Cycles, initFlags, LogicOp
- ;; source <- eax
- ;; target <- always register A
- ;; clear psb .
- mov YG_PF, initFlags
- movzx edx, [YG_GP].A
- LogicOp eax, edx
- ;; always write back A.
- mov [YG_GP].A, al
- ;; SetZ XXX:ZTable
- test al, al
- setz al
- shl eax, 6
- or YG_PF, eax
- endm
- ;; unwind
- Add_ macro Cycles
- Add$c_xHLrToA 0, Cycles
- endm
- Adc_ macro Cycles
- Add$c_xHLrToA 1, Cycles
- endm
- Sub_ macro Cycles
- CmpSub$bc_xHLrToA 0, Cycles, [YG_GP].A
- endm
- Sbc_ macro Cycles
- CmpSub$bc_xHLrToA 1, Cycles, [YG_GP].A
- endm
- Cmp_ macro Cycles
- CmpSub$bc_xHLrToA 0, Cycles, cl
- endm
- And_ macro Cycles
- Logic_T Cycles, H_FLAG, and
- endm
- Xor_ macro Cycles
- Logic_T Cycles, 0, xor
- endm
- Or_ macro Cycles
- Logic_T Cycles, 0, or
- endm
- AddWord_ macro
- ;; source <- eax
- ;; target <- always register HL
- ;; clear psb . save old Z
- and YG_PF, Z_FLAG
- movzx ecx, [YG_GP].HL
- and eax, 0FFFFh
- lea edx, [eax+ecx]
- ;; always write back HL.
- mov [YG_GP].HL, dx
- ;; SetH
- xor cx, ax
- mov ax, dx
- xor cx, ax
- and cx, 01000h
- shr cx, 8
- or YG_PF, ecx
- ;; SetC
- and edx, 010000h
- shr edx, 16
- or YG_PF, edx
- endm
- ;; TO SP
- AddWord2_ macro
- ;; source <- eax
- ;; target <- always register SP
- ;; clear psb . save old Z
- ;; xor YG_PF, YG_PF
- movzx ecx, [YG_GP].SP_
- and eax, 0FFFFh
- lea edx, [eax+ecx]
- ;; always write back SP.
- mov [YG_GP].SP_, dx
- ;; SetH
- xor cx, ax
- mov ax, dx
- xor cx, ax
- and cx, 01000h
- shr cx, 8
- ;;or YG_PF, ecx
- ;; SetC
- and dx, 010000h
- shr dx, 16
- ;;or YG_PF, edx
- endm
- DecWord_ macro
- dec eax
- endm
- IncWord_ macro
- inc eax
- endm
- Inc_ macro ;; -----------------------
- ;; source <- eax
- ;; clear psb . save old Z
- and YG_PF, C_FLAG
- and eax, 0FFh
- lea edx, [eax+1]
- mov ecx, edx
- ;; SetH
- xor cx, ax
- and cx, 010h
- or YG_PF, ecx
- mov eax, edx
- test dl, dl
- setz dl
- shl dl, 6
- or YG_PF, edx
- endm
- Dec_ macro ;; -----------------------
- ;; source <- eax
- ;; clear psb . save old Z
- and YG_PF, C_FLAG
- or YG_PF, N_FLAG
- and eax, 0FFh
- lea edx, [eax-1]
- mov ecx, edx
- ;; SetH
- xor cx, ax
- and cx, 010h
- or YG_PF, ecx
- mov eax, edx
- test dl, dl
- setz dl
- shl dl, 6
- or YG_PF, edx
- endm
- ;; --- Include OP, imm8 and ADD Word Register.
- Opcode@MainALU macro Opcode, Cycles, ReadOrExt, Op, WriteOrExt
- Opcode&:
- ReadOrExt
- Op
- WriteOrExt
- SetCyclesRetP Cycles
- endm
- Opcode@MainALU OP80, 4, B_Read, Add_, EmptyMacro ;; ADD A, B 1 Cycles:4
- Opcode@MainALU OP81, 4, C_Read, Add_, EmptyMacro ;; ADD A, C 1 Cycles:4
- Opcode@MainALU OP82, 4, D_Read, Add_, EmptyMacro ;; ADD A, D 1 Cycles:4
- Opcode@MainALU OP83, 4, E_Read, Add_, EmptyMacro ;; ADD A, E 1 Cycles:4
- Opcode@MainALU OP84, 4, H_Read, Add_, EmptyMacro ;; ADD A, H 1 Cycles:4
- Opcode@MainALU OP85, 4, L_Read, Add_, EmptyMacro ;; ADD A, L 1 Cycles:4
- Opcode@MainALU OP86, 8, xHL_Read, Add_, EmptyMacro ;; ADD A, xHL 1 Cycles:8
- Opcode@MainALU OP87, 4, A_Read, Add_, EmptyMacro ;; ADD A, A 1 Cycles:4
- Opcode@MainALU OPC6, 8, Imm8_Read, Add_, EmptyMacro ;; ADD A, Imm8 2 Cycles:8
- Opcode@MainALU OP09, 8, BC_Read, AddWord_, HL_Write ;; ADD HL, BC 1 Cycles:8
- Opcode@MainALU OP19, 8, DE_Read, AddWord_, HL_Write ;; ADD HL, DE 1 Cycles:8
- Opcode@MainALU OP29, 8, HL_Read, AddWord_, HL_Write ;; ADD HL, HL 1 Cycles:8
- Opcode@MainALU OP39, 8, SP_Read, AddWord_, HL_Write ;; ADD HL, SP 1 Cycles:8
- Opcode@MainALU OPE8,16, Imm8_ExpandSignWord, AddWord2_, EmptyMacro ;; ADD SP, SignImm8 2 Cycles:16
- Opcode@MainALU OP88, 4, B_Read, Adc_, EmptyMacro ;; ADC A, B 1 Cycles:4
- Opcode@MainALU OP89, 4, C_Read, Adc_, EmptyMacro ;; ADC A, C 1 Cycles:4
- Opcode@MainALU OP8A, 4, D_Read, Adc_, EmptyMacro ;; ADC A, D 1 Cycles:4
- Opcode@MainALU OP8B, 4, E_Read, Adc_, EmptyMacro ;; ADC A, E 1 Cycles:4
- Opcode@MainALU OP8C, 4, H_Read, Adc_, EmptyMacro ;; ADC A, H 1 Cycles:4
- Opcode@MainALU OP8D, 4, L_Read, Adc_, EmptyMacro ;; ADC A, L 1 Cycles:4
- Opcode@MainALU OP8E, 8, xHL_Read, Adc_, EmptyMacro ;; ADC A, xHL 1 Cycles:8
- Opcode@MainALU OP8F, 4, A_Read, Adc_, EmptyMacro ;; ADC A, A 1 Cycles:4
- Opcode@MainALU OPCE, 8, Imm8_Read, Adc_, EmptyMacro ;; ADC A, Imm8 2 Cycles:8
- Opcode@MainALU OP03, 8, BC_Read, IncWord_, BC_Write ;; INC BC Cycles:8
- Opcode@MainALU OP13, 8, DE_Read, IncWord_, DE_Write ;; INC DE Cycles:8
- Opcode@MainALU OP23, 8, HL_Read, IncWord_, HL_Write ;; INC HL Cycles:8
- Opcode@MainALU OP33, 8, SP_Read, IncWord_, SP_Write ;; INC SP Cycles:8
- Opcode@MainALU OP04, 4, B_Read, Inc_, B_Write ;; INC B 1 Cycles:4
- Opcode@MainALU OP14, 4, D_Read, Inc_, D_Write ;; INC D 1 Cycles:4
- Opcode@MainALU OP24, 4, H_Read, Inc_, H_Write ;; INC H 1 Cycles:4
- Opcode@MainALU OP34, 4, xHL_Read, Inc_, xHL_Write ;; INC xHL 1 Cycles:4
- Opcode@MainALU OP0C, 4, C_Read, Inc_, C_Write ;; INC C 1 Cycles:4
- Opcode@MainALU OP1C, 4, E_Read, Inc_, E_Write ;; INC E 1 Cycles:4
- Opcode@MainALU OP2C,12, L_Read, Inc_, L_Write ;; INC L 1 Cycles:12
- Opcode@MainALU OP3C, 4, A_Read, Inc_, A_Write ;; INC A 1 Cycles:4
- Opcode@MainALU OP90, 4, B_Read, Sub_, EmptyMacro ;; SUB A, B 1 Cycles:4
- Opcode@MainALU OP91, 4, C_Read, Sub_, EmptyMacro ;; SUB A, C 1 Cycles:4
- Opcode@MainALU OP92, 4, D_Read, Sub_, EmptyMacro ;; SUB A, D 1 Cycles:4
- Opcode@MainALU OP93, 4, E_Read, Sub_, EmptyMacro ;; SUB A, E 1 Cycles:4
- Opcode@MainALU OP94, 4, H_Read, Sub_, EmptyMacro ;; SUB A, H 1 Cycles:4
- Opcode@MainALU OP95, 4, L_Read, Sub_, EmptyMacro ;; SUB A, L 1 Cycles:4
- Opcode@MainALU OP96, 8, xHL_Read, Sub_, EmptyMacro ;; SUB A, xHL 1 Cycles:8
- Opcode@MainALU OP97, 4, A_Read, Sub_, EmptyMacro ;; SUB A, A 1 Cycles:4
- Opcode@MainALU OPD6, 8, Imm8_Read, Sub_, EmptyMacro ;; SUB A, Imm8 2 Cycles:8
- Opcode@MainALU OP98, 4, B_Read, Sbc_, EmptyMacro ;; SBC A, B 1 Cycles:4
- Opcode@MainALU OP99, 4, C_Read, Sbc_, EmptyMacro ;; SBC A, C 1 Cycles:4
- Opcode@MainALU OP9A, 4, D_Read, Sbc_, EmptyMacro ;; SBC A, D 1 Cycles:4
- Opcode@MainALU OP9B, 4, E_Read, Sbc_, EmptyMacro ;; SBC A, E 1 Cycles:4
- Opcode@MainALU OP9C, 4, H_Read, Sbc_, EmptyMacro ;; SBC A, H 1 Cycles:4
- Opcode@MainALU OP9D, 4, L_Read, Sbc_, EmptyMacro ;; SBC A, L 1 Cycles:4
- Opcode@MainALU OP9E, 8, xHL_Read, Sbc_, EmptyMacro ;; SBC A, xHL 1 Cycles:8
- Opcode@MainALU OP9F, 4, A_Read, Sbc_, EmptyMacro ;; SBC A, A 1 Cycles:4
- Opcode@MainALU OPDE, 8, Imm8_Read, Sbc_, EmptyMacro ;; SBC A, Imm8 2 Cycles:8
- Opcode@MainALU OP0B, 8, BC_Read, DecWord_, BC_Write ;; DEC BC Cycles:8
- Opcode@MainALU OP1B, 8, DE_Read, DecWord_, DE_Write ;; DEC DE Cycles:8
- Opcode@MainALU OP2B, 8, HL_Read, DecWord_, HL_Write ;; DEC HL Cycles:8
- Opcode@MainALU OP3B, 8, SP_Read, DecWord_, SP_Write ;; DEC SP Cycles:8
- Opcode@MainALU OP05, 4, B_Read, Dec_, B_Write ;; DEC B 1 Cycles:4
- Opcode@MainALU OP15, 4, D_Read, Dec_, D_Write ;; DEC D 1 Cycles:4
- Opcode@MainALU OP25, 4, H_Read, Dec_, H_Write ;; DEC H 1 Cycles:4
- Opcode@MainALU OP35, 4, xHL_Read, Dec_, xHL_Write ;; DEC xHL 1 Cycles:4
- Opcode@MainALU OP0D, 4, C_Read, Dec_, C_Write ;; DEC C 1 Cycles:4
- Opcode@MainALU OP1D, 4, E_Read, Dec_, E_Write ;; DEC E 1 Cycles:4
- Opcode@MainALU OP2D,12, L_Read, Dec_, L_Write ;; DEC L 1 Cycles:12
- Opcode@MainALU OP3D, 4, A_Read, Dec_, A_Write ;; DEC A 1 Cycles:4
- Opcode@MainALU OPA0, 4, B_Read, And_, EmptyMacro ;; AND A, B 1 Cycles:4
- Opcode@MainALU OPA1, 4, C_Read, And_, EmptyMacro ;; AND A, C 1 Cycles:4
- Opcode@MainALU OPA2, 4, D_Read, And_, EmptyMacro ;; AND A, D 1 Cycles:4
- Opcode@MainALU OPA3, 4, E_Read, And_, EmptyMacro ;; AND A, E 1 Cycles:4
- Opcode@MainALU OPA4, 4, H_Read, And_, EmptyMacro ;; AND A, H 1 Cycles:4
- Opcode@MainALU OPA5, 4, L_Read, And_, EmptyMacro ;; AND A, L 1 Cycles:4
- Opcode@MainALU OPA6, 8, xHL_Read, And_, EmptyMacro ;; AND A, xHL 1 Cycles:8
- Opcode@MainALU OPA7, 4, A_Read, And_, EmptyMacro ;; AND A, A 1 Cycles:4
- Opcode@MainALU OPE6, 8, Imm8_Read, And_, EmptyMacro ;; AND A, Imm8 2 Cycles:8
- Opcode@MainALU OPA8, 4, B_Read, Xor_, EmptyMacro ;; XOR A, B 1 Cycles:4
- Opcode@MainALU OPA9, 4, C_Read, Xor_, EmptyMacro ;; XOR A, C 1 Cycles:4
- Opcode@MainALU OPAA, 4, D_Read, Xor_, EmptyMacro ;; XOR A, D 1 Cycles:4
- Opcode@MainALU OPAB, 4, E_Read, Xor_, EmptyMacro ;; XOR A, E 1 Cycles:4
- Opcode@MainALU OPAC, 4, H_Read, Xor_, EmptyMacro ;; XOR A, H 1 Cycles:4
- Opcode@MainALU OPAD, 4, L_Read, Xor_, EmptyMacro ;; XOR A, L 1 Cycles:4
- Opcode@MainALU OPAE, 8, xHL_Read, Xor_, EmptyMacro ;; XOR A, xHL 1 Cycles:8
- Opcode@MainALU OPAF, 4, A_Read, Xor_, EmptyMacro ;; XOR A, A 1 Cycles:4
- Opcode@MainALU OPEE, 8, Imm8_Read, Xor_, EmptyMacro ;; XOR A, Imm8 2 Cycles:8
- Opcode@MainALU OPB0, 4, B_Read, Or_, EmptyMacro ;; OR A, B 1 Cycles:4
- Opcode@MainALU OPB1, 4, C_Read, Or_, EmptyMacro ;; OR A, C 1 Cycles:4
- Opcode@MainALU OPB2, 4, D_Read, Or_, EmptyMacro ;; OR A, D 1 Cycles:4
- Opcode@MainALU OPB3, 4, E_Read, Or_, EmptyMacro ;; OR A, E 1 Cycles:4
- Opcode@MainALU OPB4, 4, H_Read, Or_, EmptyMacro ;; OR A, H 1 Cycles:4
- Opcode@MainALU OPB5, 4, L_Read, Or_, EmptyMacro ;; OR A, L 1 Cycles:4
- Opcode@MainALU OPB6, 8, xHL_Read, Or_, EmptyMacro ;; OR A, xHL 1 Cycles:8
- Opcode@MainALU OPB7, 4, A_Read, Or_, EmptyMacro ;; OR A, A 1 Cycles:4
- Opcode@MainALU OPF6, 8, Imm8_Read, Or_, EmptyMacro ;; OR A, Imm8 2 Cycles:8
- Opcode@MainALU OPB8, 4, B_Read, Cmp_, EmptyMacro ;; CP A, B 1 Cycles:4
- Opcode@MainALU OPB9, 4, C_Read, Cmp_, EmptyMacro ;; CP A, C 1 Cycles:4
- Opcode@MainALU OPBA, 4, D_Read, Cmp_, EmptyMacro ;; CP A, D 1 Cycles:4
- Opcode@MainALU OPBB, 4, E_Read, Cmp_, EmptyMacro ;; CP A, E 1 Cycles:4
- Opcode@MainALU OPBC, 4, H_Read, Cmp_, EmptyMacro ;; CP A, H 1 Cycles:4
- Opcode@MainALU OPBD, 4, L_Read, Cmp_, EmptyMacro ;; CP A, L 1 Cycles:4
- Opcode@MainALU OPBE, 8, xHL_Read, Cmp_, EmptyMacro ;; CP A, xHL 1 Cycles:8
- Opcode@MainALU OPBF, 4, A_Read, Cmp_, EmptyMacro ;; CP A, A 1 Cycles:4
- Opcode@MainALU OPFE, 8, Imm8_Read, Cmp_, EmptyMacro ;; CP A, Imm8 2 Cycles:8
- PushWord_ macro ;; -----------------------
- ;; source <- eax
- mov cx, [YG_GP].SP_
- sub cx, 2
- mov [YG_GP].SP_, cx
- push eax
- push ecx
- push [YG_GP].gameboy
- call gameboy_mmu_write_w@12
- endm
- PopWord_ macro ;; -----------------------
- mov cx, [YG_GP].SP_
- push ecx
- add cx, 2
- mov [YG_GP].SP_, cx
- push [YG_GP].gameboy
- call gameboy_mmu_read_w@8
- endm
- ;; ---
- Opcode@MainStackOperate macro Opcode, Cycles, ReadOrExt, Op, WriteOrExt
- Opcode&:
- ReadOrExt
- Op
- WriteOrExt
- SetCyclesAndRet Cycles
- endm
- Opcode@MainStackOperate OPC1,12, PopWord_, EmptyMacro, BC_Write ;; POP BC 1 Cycles:12
- Opcode@MainStackOperate OPD1,12, PopWord_, EmptyMacro, DE_Write ;; POP DE 1 Cycles:12
- Opcode@MainStackOperate OPE1,12, PopWord_, EmptyMacro, HL_Write ;; POP HL 1 Cycles:12
- Opcode@MainStackOperate OPF1,12, PopWord_, EmptyMacro, AF_Write ;; POP AF 1 Cycles:12
- Opcode@MainStackOperate OPC5,16, BC_Read, EmptyMacro, PushWord_ ;; PUSH BC 1 Cycles:16
- Opcode@MainStackOperate OPD5,16, DE_Read, EmptyMacro, PushWord_ ;; PUSH DE 1 Cycles:16
- Opcode@MainStackOperate OPE5,16, HL_Read, EmptyMacro, PushWord_ ;; PUSH HL 1 Cycles:16
- Opcode@MainStackOperate OPF5,16, AF_Read, EmptyMacro, PushWord_ ;; PUSH AF 1 Cycles:16
- Opcode@Rst macro Opcode, Cycles, Vector
- Opcode&:
- mov ax, si
- PushWord_
- mov si, Vector
- SetCyclesRetP Cycles
- endm
- Opcode@Rst OPC7,16, 000H ;; RST 00H 1 Cycles:16
- Opcode@Rst OPD7,16, 010H ;; RST 10H 1 Cycles:16
- Opcode@Rst OPE7,16, 020H ;; RST 20H 1 Cycles:16
- Opcode@Rst OPF7,16, 030H ;; RST 30H 1 Cycles:16
- Opcode@Rst OPCF,16, 008H ;; RST 08H 1 Cycles:16
- Opcode@Rst OPDF,16, 018H ;; RST 18H 1 Cycles:16
- Opcode@Rst OPEF,16, 028H ;; RST 28H 1 Cycles:16
- Opcode@Rst OPFF,16, 038H ;; RST 38H 1 Cycles:16
- Opcode@JR macro Opcode, Flags, OpNOT
- Opcode&:
- mov eax, YG_PF
- and eax, Flags
- xor eax, OpNOT
- jne @F
- inc esi
- SetCyclesRetP 8
- @@:
- Imm8_Read
- movsx eax, al
- add esi, eax
- SetCyclesRetP 12
- endm
- Opcode@JR OP20,Z_FLAG, Z_FLAG ;; JR NZ
- Opcode@JR OP30,C_FLAG, C_FLAG ;; JR NC
- Opcode@JR OP28,Z_FLAG, 0 ;; JR Z
- Opcode@JR OP38,C_FLAG, 0 ;; JR C
- Opcode@JR OP18,0, 1 ;; JR R8
- Opcode@JP macro Opcode, Flags, OpNOT
- Opcode&:
- mov eax, YG_PF
- and eax, Flags
- xor eax, OpNOT
- jne @F
- add esi, 2
- SetCyclesRetP 12
- @@:
- Imm16_Read
- mov esi, eax
- SetCyclesRetP 16
- endm
- Opcode@JP OPC2,Z_FLAG, Z_FLAG ;; JP NZ
- Opcode@JP OPD2,C_FLAG, C_FLAG ;; JP NC
- Opcode@JP OPCA,Z_FLAG, 0 ;; JP Z
- Opcode@JP OPDA,C_FLAG, 0 ;; JP C
- Opcode@JP OPC3,0, 1 ;; JP A16
- OPE9:
- mov si, [YG_GP].HL
- mov [YG_GP].PC, ax
- SetCyclesAndRet 4
- ;; LD@RxHLToRxHL OPE9, 4, HL_Read, PC_Write ;; JP (HL), Same as LD PC HL, 1 Cycles:4
- Opcode@CALL macro Opcode, Flags, OpNOT
- Opcode&:
- mov eax, YG_PF
- and eax, Flags
- xor eax, OpNOT
- jne @F
- add esi, 2
- SetCyclesRetP 12
- @@:
- lea eax, [YG_PC+2]
- PushWord_
- Imm16_Read
- mov esi, eax
- SetCyclesRetP 24
- endm
- Opcode@CALL OPC4,Z_FLAG, Z_FLAG ;; CALL NZ
- Opcode@CALL OPD4,C_FLAG, C_FLAG ;; CALL NC
- Opcode@CALL OPCC,Z_FLAG, 0 ;; CALL Z
- Opcode@CALL OPDC,C_FLAG, 0 ;; CALL C
- Opcode@CALL OPCD,0, 1 ;; CALL
- Opcode@RET macro Opcode, Flags, OpNOT, RetHitCycles
- Opcode&:
- mov eax, YG_PF
- and eax, Flags
- xor eax, OpNOT
- jne @F
- SetCyclesRetP 8
- @@:
- PopWord_
- mov YG_PC, eax
- SetCyclesRetP RetHitCycles
- endm
- Opcode@RETI macro Opcode, Flags, OpNOT, RetHitCycles
- Opcode&:
- mov eax, YG_PF
- and eax, Flags
- xor eax, OpNOT
- jne @F
- SetCyclesRetP 8
- @@:
- PopWord_
- mov YG_PC, eax
- mov [YG_GP].IME, 1
- SetCyclesRetP RetHitCycles
- endm
- Opcode@RET OPC0,Z_FLAG, Z_FLAG, 20 ;; RET NZ
- Opcode@RET OPD0,C_FLAG, C_FLAG, 20 ;; RET NC
- Opcode@RET OPC8,Z_FLAG, 0, 20 ;; RET Z
- Opcode@RET OPD8,C_FLAG, 0, 20 ;; RET C
- Opcode@RET OPC9,0, 1, 16 ;; RET
- Opcode@RETI OPD9,0, 1, 16 ;; RETI
- ;; MISC 8.
- OP76: ; Halt, not backup PC in my source code ^_^
- mov [YG_GP].halt, 1
- SetCyclesAndRet 4
- OP10: ; Stop, Check CGB speed mode
- movzx eax, [YG_GP].key1
- test eax, 1
- je @F
- xor eax, 080H ;; switch to "other" speed
- and eax, 0FEH ;; reset LSB see gb-programming-manual.pdf::2.6.2 CPU Operating Speed
- ;; for simplicity, I will not simulate the huge waste of time brought by handover.
- mov [YG_GP].key1, al
- SetCyclesAndRet 080000004H
- @@:mov [YG_GP].stop, 1
- add YG_PC, 1 ;; skip one byte (should is 00)
- OP00: ; NOP
- SetCyclesAndRet 4
- OPF3: ; DI
- mov [YG_GP].IME, 0
- SetCyclesAndRet 4
- OPFB: ; EI
- mov [YG_GP].IME, 1
- SetCyclesAndRet 4
- OP07: ; RLCA
- rol [YG_GP].A, 1
- setc YG_PF_8
- SetCyclesRetP 4
- OP17: ; RLA
- shr YG_PF_8, 1
- rcl [YG_GP].A, 1
- setc YG_PF_8
- SetCyclesRetP 4
- OP0F: ; RRCA
- ror [YG_GP].A, 1
- setc YG_PF_8
- SetCyclesRetP 4
- OP1F: ; RRA
- shr YG_PF_8, 1
- rcr [YG_GP].A, 1
- setc YG_PF_8
- SetCyclesRetP 4
- OP27: ; DAA
- SetCyclesRetP 4
- mov al, [YG_GP].A
- and YG_PF_8, N_FLAG
- jne DAS_Proc
- ;; DAA.
- daa
- mov [YG_GP].A, al
- setc YG_PF_8 ;; SETC
- setz al
- shl al, 6
- or YG_PF_8, al
- SetCyclesRetP 4
- DAS_Proc:
- ;; DAS
- das
- mov [YG_GP].A, al
- setc YG_PF_8 ;; SETC
- setz al
- shl al, 6
- or YG_PF_8, al
- or YG_PF_8, N_FLAG
- SetCyclesRetP 4
- OP37: ; SCF
- and YG_PF_8, Z_FLAG
- or YG_PF_8, C_FLAG
- SetCyclesRetP 4
- OP2F: ; CPL
- not [YG_GP].A
- or YG_PF_8, N_FLAG
- or YG_PF_8, H_FLAG
- SetCyclesRetP 4
- OP3F: ; CCF
- and YG_PF_8, ZC_FLAG
- xor YG_PF_8, C_FLAG
- SetCyclesRetP 4
- ;; rortoe shift with
- RLC_ macro Cycles
- rol al, 1
- setc YG_PF_8
- test al, al
- setz dl
- shl dl, 6
- or YG_PF_8, dl
- endm
- ;; rortoe shift with
- RRC_ macro Cycles
- ror al, 1
- setc YG_PF_8
- test al, al
- setz dl
- shl dl, 6
- or YG_PF_8, dl
- endm
- ;; logic shift with carry
- RL_ macro Cycles
- shr YG_PF_8, 1
- rcl al, 1
- setc YG_PF_8
- test al, al
- setz dl
- shl dl, 6
- or YG_PF_8, dl
- endm
- ;; logic shift with carry
- RR_ macro Cycles
- shr YG_PF_8, 1
- rcr al, 1
- setc YG_PF_8
- test al, al
- setz dl
- shl dl, 6
- or YG_PF_8, dl
- endm
- ;; logic shift
- RL_N_ macro Cycles
- shl al, 1
- setc YG_PF_8
- test al, al
- setz dl
- shl dl, 6
- or YG_PF_8, dl
- endm
- ;; logic shift
- RR_N_ macro Cycles
- shr al, 1
- setc YG_PF_8
- test al, al
- setz dl
- shl dl, 6
- or YG_PF_8, dl
- endm
- ;; arith shift save msb
- RRS_N_ macro Cycles
- sar al, 1
- setc YG_PF_8
- setz dl
- shl dl, 6
- or YG_PF_8, dl
- endm
- ;; swap byte-lo 4bit and byte-hi 4bit
- SWAP_ macro Cycles
- ror al, 4
- test al, al
- setz cl
- shl cl, 6
- mov YG_PF, ecx
- endm
- ;; Set
- Opcode@SetBit macro Opcode, Cycles, ReadOrExt, BitOrder, WriteOrExt
- Opcode&:
- ReadOrExt
- mov ecx, 1
- shl ecx, BitOrder
- or eax, ecx
- WriteOrExt
- SetCyclesAndRet Cycles
- endm
- Opcode@ResBit macro Opcode, Cycles, ReadOrExt, BitOrder, WriteOrExt
- Opcode&:
- ReadOrExt
- mov ecx, 1
- shl ecx, BitOrder
- not ecx
- and eax, ecx
- WriteOrExt
- SetCyclesAndRet Cycles
- endm
- Opcode@TestBit macro Opcode, Cycles, ReadOrExt, BitOrder
- Opcode&:
- ReadOrExt
- and YG_PF, C_FLAG
- or YG_PF, H_FLAG
- mov ecx, 1
- shl ecx, BitOrder
- test al, cl
- setz al
- shl eax, 6
- or YG_PF, eax
- SetCyclesRetP Cycles
- endm
- OPCB: ;; ---------------------------------- Perfix CB -----------------------------------------------------------------------------
- Imm8_Read
- and eax, 255
- jmp dword ptr[CBTAB+eax*4]
- ;; --- Include OP, imm8 and ADD Word Register.
- Opcode@MainALUExt macro Opcode, Cycles, ReadOrExt, Op, WriteOrExt
- Opcode&:
- ReadOrExt
- Op
- WriteOrExt
- SetCyclesRetP Cycles
- endm
- Opcode@MainALUExt CB00, 8, B_Read, RLC_, B_Write ;; RLC B 2 Cycles:8
- Opcode@MainALUExt CB01, 8, C_Read, RLC_, C_Write ;; RLC C 2 Cycles:8
- Opcode@MainALUExt CB02, 8, D_Read, RLC_, D_Write ;; RLC D 2 Cycles:8
- Opcode@MainALUExt CB03, 8, E_Read, RLC_, E_Write ;; RLC E 2 Cycles:8
- Opcode@MainALUExt CB04, 8, H_Read, RLC_, H_Write ;; RLC H 2 Cycles:8
- Opcode@MainALUExt CB05, 8, L_Read, RLC_, L_Write ;; RLC L 2 Cycles:8
- Opcode@MainALUExt CB06,16, xHL_Read, RLC_, xHL_Write ;; RLC xHL 2 Cycles:16
- Opcode@MainALUExt CB07, 8, A_Read, RLC_, A_Write ;; RLC A 2 Cycles:8
- Opcode@MainALUExt CB08, 8, B_Read, RRC_, B_Write ;; RRC B 2 Cycles:8
- Opcode@MainALUExt CB09, 8, C_Read, RRC_, C_Write ;; RRC C 2 Cycles:8
- Opcode@MainALUExt CB0A, 8, D_Read, RRC_, D_Write ;; RRC D 2 Cycles:8
- Opcode@MainALUExt CB0B, 8, E_Read, RRC_, E_Write ;; RRC E 2 Cycles:8
- Opcode@MainALUExt CB0C, 8, H_Read, RRC_, H_Write ;; RRC H 2 Cycles:8
- Opcode@MainALUExt CB0D, 8, L_Read, RRC_, L_Write ;; RRC L 2 Cycles:8
- Opcode@MainALUExt CB0E,16, xHL_Read, RRC_, xHL_Write ;; RRC xHL 2 Cycles:16
- Opcode@MainALUExt CB0F, 8, A_Read, RRC_, A_Write ;; RRC A 2 Cycles:8
- Opcode@MainALUExt CB10, 8, B_Read, RL_, B_Write ;; RL B 2 Cycles:8
- Opcode@MainALUExt CB11, 8, C_Read, RL_, C_Write ;; RL C 2 Cycles:8
- Opcode@MainALUExt CB12, 8, D_Read, RL_, D_Write ;; RL D 2 Cycles:8
- Opcode@MainALUExt CB13, 8, E_Read, RL_, E_Write ;; RL E 2 Cycles:8
- Opcode@MainALUExt CB14, 8, H_Read, RL_, H_Write ;; RL H 2 Cycles:8
- Opcode@MainALUExt CB15, 8, L_Read, RL_, L_Write ;; RL L 2 Cycles:8
- Opcode@MainALUExt CB16,16, xHL_Read, RL_, xHL_Write ;; RL xHL 2 Cycles:16
- Opcode@MainALUExt CB17, 8, A_Read, RL_, A_Write ;; RL A 2 Cycles:8
- Opcode@MainALUExt CB18, 8, B_Read, RR_, B_Write ;; RR B 2 Cycles:8
- Opcode@MainALUExt CB19, 8, C_Read, RR_, C_Write ;; RR C 2 Cycles:8
- Opcode@MainALUExt CB1A, 8, D_Read, RR_, D_Write ;; RR D 2 Cycles:8
- Opcode@MainALUExt CB1B, 8, E_Read, RR_, E_Write ;; RR E 2 Cycles:8
- Opcode@MainALUExt CB1C, 8, H_Read, RR_, H_Write ;; RR H 2 Cycles:8
- Opcode@MainALUExt CB1D, 8, L_Read, RR_, L_Write ;; RR L 2 Cycles:8
- Opcode@MainALUExt CB1E,16, xHL_Read, RR_, xHL_Write ;; RR xHL 2 Cycles:16
- Opcode@MainALUExt CB1F, 8, A_Read, RR_, A_Write ;; RR A 2 Cycles:8
- Opcode@MainALUExt CB20, 8, B_Read, RL_N_, B_Write ;; SLA B 2 Cycles:8
- Opcode@MainALUExt CB21, 8, C_Read, RL_N_, C_Write ;; SLA C 2 Cycles:8
- Opcode@MainALUExt CB22, 8, D_Read, RL_N_, D_Write ;; SLA D 2 Cycles:8
- Opcode@MainALUExt CB23, 8, E_Read, RL_N_, E_Write ;; SLA E 2 Cycles:8
- Opcode@MainALUExt CB24, 8, H_Read, RL_N_, H_Write ;; SLA H 2 Cycles:8
- Opcode@MainALUExt CB25, 8, L_Read, RL_N_, L_Write ;; SLA L 2 Cycles:8
- Opcode@MainALUExt CB26,16, xHL_Read, RL_N_, xHL_Write ;; SLA xHL 2 Cycles:16
- Opcode@MainALUExt CB27, 8, A_Read, RL_N_, A_Write ;; SLA A 2 Cycles:8
- Opcode@MainALUExt CB28, 8, B_Read, RRS_N_, B_Write ;; SRA B 2 Cycles:8
- Opcode@MainALUExt CB29, 8, C_Read, RRS_N_, C_Write ;; SRA C 2 Cycles:8
- Opcode@MainALUExt CB2A, 8, D_Read, RRS_N_, D_Write ;; SRA D 2 Cycles:8
- Opcode@MainALUExt CB2B, 8, E_Read, RRS_N_, E_Write ;; SRA E 2 Cycles:8
- Opcode@MainALUExt CB2C, 8, H_Read, RRS_N_, H_Write ;; SRA H 2 Cycles:8
- Opcode@MainALUExt CB2D, 8, L_Read, RRS_N_, L_Write ;; SRA L 2 Cycles:8
- Opcode@MainALUExt CB2E,16, xHL_Read, RRS_N_, xHL_Write ;; SRA xHL 2 Cycles:16
- Opcode@MainALUExt CB2F, 8, A_Read, RRS_N_, A_Write ;; SRA A 2 Cycles:8
- Opcode@MainALUExt CB30, 8, B_Read, SWAP_, B_Write ;; SWAP B 2 Cycles:8
- Opcode@MainALUExt CB31, 8, C_Read, SWAP_, C_Write ;; SWAP C 2 Cycles:8
- Opcode@MainALUExt CB32, 8, D_Read, SWAP_, D_Write ;; SWAP D 2 Cycles:8
- Opcode@MainALUExt CB33, 8, E_Read, SWAP_, E_Write ;; SWAP E 2 Cycles:8
- Opcode@MainALUExt CB34, 8, H_Read, SWAP_, H_Write ;; SWAP H 2 Cycles:8
- Opcode@MainALUExt CB35, 8, L_Read, SWAP_, L_Write ;; SWAP L 2 Cycles:8
- Opcode@MainALUExt CB36,16, xHL_Read, SWAP_, xHL_Write ;; SWAP xHL 2 Cycles:16
- Opcode@MainALUExt CB37, 8, A_Read, SWAP_, A_Write ;; SWAP A 2 Cycles:8
- Opcode@MainALUExt CB38, 8, B_Read, RR_N_, B_Write ;; SRL B 2 Cycles:8
- Opcode@MainALUExt CB39, 8, C_Read, RR_N_, C_Write ;; SRL C 2 Cycles:8
- Opcode@MainALUExt CB3A, 8, D_Read, RR_N_, D_Write ;; SRL D 2 Cycles:8
- Opcode@MainALUExt CB3B, 8, E_Read, RR_N_, E_Write ;; SRL E 2 Cycles:8
- Opcode@MainALUExt CB3C, 8, H_Read, RR_N_, H_Write ;; SRL H 2 Cycles:8
- Opcode@MainALUExt CB3D, 8, L_Read, RR_N_, L_Write ;; SRL L 2 Cycles:8
- Opcode@MainALUExt CB3E,16, xHL_Read, RR_N_, xHL_Write ;; SRL xHL 2 Cycles:16
- Opcode@MainALUExt CB3F, 8, A_Read, RR_N_, A_Write ;; SRL A 2 Cycles:8
- Opcode@TestBit CB40, 8, B_Read, 0 ;; BIT B, 0 Cycles:8
- Opcode@TestBit CB41, 8, C_Read, 0 ;; BIT C, 0 Cycles:8
- Opcode@TestBit CB42, 8, D_Read, 0 ;; BIT D, 0 Cycles:8
- Opcode@TestBit CB43, 8, E_Read, 0 ;; BIT E, 0 Cycles:8
- Opcode@TestBit CB44, 8, H_Read, 0 ;; BIT H, 0 Cycles:8
- Opcode@TestBit CB45, 8, L_Read, 0 ;; BIT L, 0 Cycles:8
- Opcode@TestBit CB46,16, xHL_Read, 0 ;; BIT xHL, 0 Cycles:16
- Opcode@TestBit CB47, 8, A_Read, 0 ;; BIT A, 0 Cycles:8
- Opcode@TestBit CB48, 8, B_Read, 1 ;; BIT B, 1 Cycles:8
- Opcode@TestBit CB49, 8, C_Read, 1 ;; BIT C, 1 Cycles:8
- Opcode@TestBit CB4A, 8, D_Read, 1 ;; BIT D, 1 Cycles:8
- Opcode@TestBit CB4B, 8, E_Read, 1 ;; BIT E, 1 Cycles:8
- Opcode@TestBit CB4C, 8, H_Read, 1 ;; BIT H, 1 Cycles:8
- Opcode@TestBit CB4D, 8, L_Read, 1 ;; BIT L, 1 Cycles:8
- Opcode@TestBit CB4E,16, xHL_Read, 1 ;; BIT xHL, 1 Cycles:16
- Opcode@TestBit CB4F, 8, A_Read, 1 ;; BIT A, 1 Cycles:8
- Opcode@TestBit CB50, 8, B_Read, 2 ;; BIT B, 2 Cycles:8
- Opcode@TestBit CB51, 8, C_Read, 2 ;; BIT C, 2 Cycles:8
- Opcode@TestBit CB52, 8, D_Read, 2 ;; BIT D, 2 Cycles:8
- Opcode@TestBit CB53, 8, E_Read, 2 ;; BIT E, 2 Cycles:8
- Opcode@TestBit CB54, 8, H_Read, 2 ;; BIT H, 2 Cycles:8
- Opcode@TestBit CB55, 8, L_Read, 2 ;; BIT L, 2 Cycles:8
- Opcode@TestBit CB56,16, xHL_Read, 2 ;; BIT xHL, 2 Cycles:16
- Opcode@TestBit CB57, 8, A_Read, 2 ;; BIT A, 2 Cycles:8
- Opcode@TestBit CB58, 8, B_Read, 3 ;; BIT B, 3 Cycles:8
- Opcode@TestBit CB59, 8, C_Read, 3 ;; BIT C, 3 Cycles:8
- Opcode@TestBit CB5A, 8, D_Read, 3 ;; BIT D, 3 Cycles:8
- Opcode@TestBit CB5B, 8, E_Read, 3 ;; BIT E, 3 Cycles:8
- Opcode@TestBit CB5C, 8, H_Read, 3 ;; BIT H, 3 Cycles:8
- Opcode@TestBit CB5D, 8, L_Read, 3 ;; BIT L, 3 Cycles:8
- Opcode@TestBit CB5E,16, xHL_Read, 3 ;; BIT xHL, 3 Cycles:16
- Opcode@TestBit CB5F, 8, A_Read, 3 ;; BIT A, 3 Cycles:8
- Opcode@TestBit CB60, 8, B_Read, 4 ;; BIT B, 4 Cycles:8
- Opcode@TestBit CB61, 8, C_Read, 4 ;; BIT C, 4 Cycles:8
- Opcode@TestBit CB62, 8, D_Read, 4 ;; BIT D, 4 Cycles:8
- Opcode@TestBit CB63, 8, E_Read, 4 ;; BIT E, 4 Cycles:8
- Opcode@TestBit CB64, 8, H_Read, 4 ;; BIT H, 4 Cycles:8
- Opcode@TestBit CB65, 8, L_Read, 4 ;; BIT L, 4 Cycles:8
- Opcode@TestBit CB66,16, xHL_Read, 4 ;; BITxHLD, 4 Cycles:16
- Opcode@TestBit CB67, 8, A_Read, 4 ;; BIT A, 4 Cycles:8
- Opcode@TestBit CB68, 8, B_Read, 5 ;; BIT B, 5 Cycles:8
- Opcode@TestBit CB69, 8, C_Read, 5 ;; BIT C, 5 Cycles:8
- Opcode@TestBit CB6A, 8, D_Read, 5 ;; BIT D, 5 Cycles:8
- Opcode@TestBit CB6B, 8, E_Read, 5 ;; BIT E, 5 Cycles:8
- Opcode@TestBit CB6C, 8, H_Read, 5 ;; BIT H, 5 Cycles:8
- Opcode@TestBit CB6D, 8, L_Read, 5 ;; BIT L, 5 Cycles:8
- Opcode@TestBit CB6E,16, xHL_Read, 5 ;; BIT xHL, 5 Cycles:16
- Opcode@TestBit CB6F, 8, A_Read, 5 ;; BIT A, 5 Cycles:8
- Opcode@TestBit CB70, 8, B_Read, 6 ;; BIT B, 6 Cycles:8
- Opcode@TestBit CB71, 8, C_Read, 6 ;; BIT C, 6 Cycles:8
- Opcode@TestBit CB72, 8, D_Read, 6 ;; BIT D, 6 Cycles:8
- Opcode@TestBit CB73, 8, E_Read, 6 ;; BIT E, 6 Cycles:8
- Opcode@TestBit CB74, 8, H_Read, 6 ;; BIT H, 6 Cycles:8
- Opcode@TestBit CB75, 8, L_Read, 6 ;; BIT L, 6 Cycles:8
- Opcode@TestBit CB76,16, xHL_Read, 6 ;; BIT xHL, 6 Cycles:16
- Opcode@TestBit CB77, 8, A_Read, 6 ;; BIT A, 6 Cycles:8
- Opcode@TestBit CB78, 8, B_Read, 7 ;; BIT B, 7 Cycles:8
- Opcode@TestBit CB79, 8, C_Read, 7 ;; BIT C, 7 Cycles:8
- Opcode@TestBit CB7A, 8, D_Read, 7 ;; BIT D, 7 Cycles:8
- Opcode@TestBit CB7B, 8, E_Read, 7 ;; BIT E, 7 Cycles:8
- Opcode@TestBit CB7C, 8, H_Read, 7 ;; BIT H, 7 Cycles:8
- Opcode@TestBit CB7D, 8, L_Read, 7 ;; BIT L, 7 Cycles:8
- Opcode@TestBit CB7E,16, xHL_Read, 7 ;; BIT xHL, 7 Cycles:16
- Opcode@TestBit CB7F, 8, A_Read, 7 ;; BIT A, 7 Cycles:8
- Opcode@ResBit CB80, 8, B_Read, 0, B_Write ;; RES B, 0 Cycles:8
- Opcode@ResBit CB81, 8, C_Read, 0, C_Write ;; RES C, 0 Cycles:8
- Opcode@ResBit CB82, 8, D_Read, 0, D_Write ;; RES D, 0 Cycles:8
- Opcode@ResBit CB83, 8, E_Read, 0, E_Write ;; RES E, 0 Cycles:8
- Opcode@ResBit CB84, 8, H_Read, 0, H_Write ;; RES H, 0 Cycles:8
- Opcode@ResBit CB85, 8, L_Read, 0, L_Write ;; RES L, 0 Cycles:8
- Opcode@ResBit CB86,16, xHL_Read, 0, xHL_Write ;; RES xHL, 0 Cycles:16
- Opcode@ResBit CB87, 8, A_Read, 0, A_Write ;; RES A, 0 Cycles:8
- Opcode@ResBit CB88, 8, B_Read, 1, B_Write ;; RES B, 1 Cycles:8
- Opcode@ResBit CB89, 8, C_Read, 1, C_Write ;; RES C, 1 Cycles:8
- Opcode@ResBit CB8A, 8, D_Read, 1, D_Write ;; RES D, 1 Cycles:8
- Opcode@ResBit CB8B, 8, E_Read, 1, E_Write ;; RES E, 1 Cycles:8
- Opcode@ResBit CB8C, 8, H_Read, 1, H_Write ;; RES H, 1 Cycles:8
- Opcode@ResBit CB8D, 8, L_Read, 1, L_Write ;; RES L, 1 Cycles:8
- Opcode@ResBit CB8E,16, xHL_Read, 1, xHL_Write ;; RES xHL, 1 Cycles:16
- Opcode@ResBit CB8F, 8, A_Read, 1, A_Write ;; RES A, 1 Cycles:8
- Opcode@ResBit CB90, 8, B_Read, 2, B_Write ;; RES B, 2 Cycles:8
- Opcode@ResBit CB91, 8, C_Read, 2, C_Write ;; RES C, 2 Cycles:8
- Opcode@ResBit CB92, 8, D_Read, 2, D_Write ;; RES D, 2 Cycles:8
- Opcode@ResBit CB93, 8, E_Read, 2, E_Write ;; RES E, 2 Cycles:8
- Opcode@ResBit CB94, 8, H_Read, 2, H_Write ;; RES H, 2 Cycles:8
- Opcode@ResBit CB95, 8, L_Read, 2, L_Write ;; RES L, 2 Cycles:8
- Opcode@ResBit CB96,16, xHL_Read, 2, xHL_Write ;; RES xHL, 2 Cycles:16
- Opcode@ResBit CB97, 8, A_Read, 2, A_Write ;; RES A, 2 Cycles:8
- Opcode@ResBit CB98, 8, B_Read, 3, B_Write ;; RES B, 3 Cycles:8
- Opcode@ResBit CB99, 8, C_Read, 3, C_Write ;; RES C, 3 Cycles:8
- Opcode@ResBit CB9A, 8, D_Read, 3, D_Write ;; RES D, 3 Cycles:8
- Opcode@ResBit CB9B, 8, E_Read, 3, E_Write ;; RES E, 3 Cycles:8
- Opcode@ResBit CB9C, 8, H_Read, 3, H_Write ;; RES H, 3 Cycles:8
- Opcode@ResBit CB9D, 8, L_Read, 3, L_Write ;; RES L, 3 Cycles:8
- Opcode@ResBit CB9E,16, xHL_Read, 3, xHL_Write ;; RES xHL, 3 Cycles:16
- Opcode@ResBit CB9F, 8, A_Read, 3, A_Write ;; RES A, 3 Cycles:8
- Opcode@ResBit CBA0, 8, B_Read, 4, B_Write ;; RES B, 4 Cycles:8
- Opcode@ResBit CBA1, 8, C_Read, 4, C_Write ;; RES C, 4 Cycles:8
- Opcode@ResBit CBA2, 8, D_Read, 4, D_Write ;; RES D, 4 Cycles:8
- Opcode@ResBit CBA3, 8, E_Read, 4, E_Write ;; RES E, 4 Cycles:8
- Opcode@ResBit CBA4, 8, H_Read, 4, H_Write ;; RES H, 4 Cycles:8
- Opcode@ResBit CBA5, 8, L_Read, 4, L_Write ;; RES L, 4 Cycles:8
- Opcode@ResBit CBA6,16, xHL_Read, 4, xHL_Write ;; RES xHL, 4 Cycles:16
- Opcode@ResBit CBA7, 8, A_Read, 4, A_Write ;; RES A, 4 Cycles:8
- Opcode@ResBit CBA8, 8, B_Read, 5, B_Write ;; RES B, 5 Cycles:8
- Opcode@ResBit CBA9, 8, C_Read, 5, C_Write ;; RES C, 5 Cycles:8
- Opcode@ResBit CBAA, 8, D_Read, 5, D_Write ;; RES D, 5 Cycles:8
- Opcode@ResBit CBAB, 8, E_Read, 5, E_Write ;; RES E, 5 Cycles:8
- Opcode@ResBit CBAC, 8, H_Read, 5, H_Write ;; RES H, 5 Cycles:8
- Opcode@ResBit CBAD, 8, L_Read, 5, L_Write ;; RES L, 5 Cycles:8
- Opcode@ResBit CBAE,16, xHL_Read, 5, xHL_Write ;; RES xHL, 5 Cycles:16
- Opcode@ResBit CBAF, 8, A_Read, 5, A_Write ;; RES A, 5 Cycles:8
- Opcode@ResBit CBB0, 8, B_Read, 6, B_Write ;; RES B, 6 Cycles:8
- Opcode@ResBit CBB1, 8, C_Read, 6, C_Write ;; RES C, 6 Cycles:8
- Opcode@ResBit CBB2, 8, D_Read, 6, D_Write ;; RES D, 6 Cycles:8
- Opcode@ResBit CBB3, 8, E_Read, 6, E_Write ;; RES E, 6 Cycles:8
- Opcode@ResBit CBB4, 8, H_Read, 6, H_Write ;; RES H, 6 Cycles:8
- Opcode@ResBit CBB5, 8, L_Read, 6, L_Write ;; RES L, 6 Cycles:8
- Opcode@ResBit CBB6,16, xHL_Read, 6, xHL_Write ;; RES xHL, 6 Cycles:16
- Opcode@ResBit CBB7, 8, A_Read, 6, A_Write ;; RES A, 6 Cycles:8
- Opcode@ResBit CBB8, 8, B_Read, 7, B_Write ;; RES B, 7 Cycles:8
- Opcode@ResBit CBB9, 8, C_Read, 7, C_Write ;; RES C, 7 Cycles:8
- Opcode@ResBit CBBA, 8, D_Read, 7, D_Write ;; RES D, 7 Cycles:8
- Opcode@ResBit CBBB, 8, E_Read, 7, E_Write ;; RES E, 7 Cycles:8
- Opcode@ResBit CBBC, 8, H_Read, 7, H_Write ;; RES H, 7 Cycles:8
- Opcode@ResBit CBBD, 8, L_Read, 7, L_Write ;; RES L, 7 Cycles:8
- Opcode@ResBit CBBE,16, xHL_Read, 7, xHL_Write ;; RES xHL, 7 Cycles:16
- Opcode@ResBit CBBF, 8, A_Read, 7, A_Write ;; RES A, 7 Cycles:8
- Opcode@SetBit CBC0, 8, B_Read, 0, B_Write ;; SET B, 0 Cycles:8
- Opcode@SetBit CBC1, 8, C_Read, 0, C_Write ;; SET C, 0 Cycles:8
- Opcode@SetBit CBC2, 8, D_Read, 0, D_Write ;; SET D, 0 Cycles:8
- Opcode@SetBit CBC3, 8, E_Read, 0, E_Write ;; SET E, 0 Cycles:8
- Opcode@SetBit CBC4, 8, H_Read, 0, H_Write ;; SET H, 0 Cycles:8
- Opcode@SetBit CBC5, 8, L_Read, 0, L_Write ;; SET L, 0 Cycles:8
- Opcode@SetBit CBC6,16, xHL_Read, 0, xHL_Write ;; SET xHL, 0 Cycles:16
- Opcode@SetBit CBC7, 8, A_Read, 0, A_Write ;; SET A, 0 Cycles:8
- Opcode@SetBit CBC8, 8, B_Read, 1, B_Write ;; SET B, 1 Cycles:8
- Opcode@SetBit CBC9, 8, C_Read, 1, C_Write ;; SET C, 1 Cycles:8
- Opcode@SetBit CBCA, 8, D_Read, 1, D_Write ;; SET D, 1 Cycles:8
- Opcode@SetBit CBCB, 8, E_Read, 1, E_Write ;; SET E, 1 Cycles:8
- Opcode@SetBit CBCC, 8, H_Read, 1, H_Write ;; SET H, 1 Cycles:8
- Opcode@SetBit CBCD, 8, L_Read, 1, L_Write ;; SET L, 1 Cycles:8
- Opcode@SetBit CBCE,16, xHL_Read, 1, xHL_Write ;; SET xHL, 1 Cycles:16
- Opcode@SetBit CBCF, 8, A_Read, 1, A_Write ;; SET A, 1 Cycles:8
- Opcode@SetBit CBD0, 8, B_Read, 2, B_Write ;; SET B, 2 Cycles:8
- Opcode@SetBit CBD1, 8, C_Read, 2, C_Write ;; SET C, 2 Cycles:8
- Opcode@SetBit CBD2, 8, D_Read, 2, D_Write ;; SET D, 2 Cycles:8
- Opcode@SetBit CBD3, 8, E_Read, 2, E_Write ;; SET E, 2 Cycles:8
- Opcode@SetBit CBD4, 8, H_Read, 2, H_Write ;; SET H, 2 Cycles:8
- Opcode@SetBit CBD5, 8, L_Read, 2, L_Write ;; SET L, 2 Cycles:8
- Opcode@SetBit CBD6,16, xHL_Read, 2, xHL_Write ;; SET xHL, 2 Cycles:16
- Opcode@SetBit CBD7, 8, A_Read, 2, A_Write ;; SET A, 2 Cycles:8
- Opcode@SetBit CBD8, 8, B_Read, 3, B_Write ;; SET B, 3 Cycles:8
- Opcode@SetBit CBD9, 8, C_Read, 3, C_Write ;; SET C, 3 Cycles:8
- Opcode@SetBit CBDA, 8, D_Read, 3, D_Write ;; SET D, 3 Cycles:8
- Opcode@SetBit CBDB, 8, E_Read, 3, E_Write ;; SET E, 3 Cycles:8
- Opcode@SetBit CBDC, 8, H_Read, 3, H_Write ;; SET H, 3 Cycles:8
- Opcode@SetBit CBDD, 8, L_Read, 3, L_Write ;; SET L, 3 Cycles:8
- Opcode@SetBit CBDE,16, xHL_Read, 3, xHL_Write ;; SET xHL, 3 Cycles:16
- Opcode@SetBit CBDF, 8, A_Read, 3, A_Write ;; SET A, 3 Cycles:8
- Opcode@SetBit CBE0, 8, B_Read, 4, B_Write ;; SET B, 4 Cycles:8
- Opcode@SetBit CBE1, 8, C_Read, 4, C_Write ;; SET C, 4 Cycles:8
- Opcode@SetBit CBE2, 8, D_Read, 4, D_Write ;; SET D, 4 Cycles:8
- Opcode@SetBit CBE3, 8, E_Read, 4, E_Write ;; SET E, 4 Cycles:8
- Opcode@SetBit CBE4, 8, H_Read, 4, H_Write ;; SET H, 4 Cycles:8
- Opcode@SetBit CBE5, 8, L_Read, 4, L_Write ;; SET L, 4 Cycles:8
- Opcode@SetBit CBE6,16, xHL_Read, 4, xHL_Write ;; SET xHL, 4 Cycles:16
- Opcode@SetBit CBE7, 8, A_Read, 4, A_Write ;; SET A, 4 Cycles:8
- Opcode@SetBit CBE8, 8, B_Read, 5, B_Write ;; SET B, 5 Cycles:8
- Opcode@SetBit CBE9, 8, C_Read, 5, C_Write ;; SET C, 5 Cycles:8
- Opcode@SetBit CBEA, 8, D_Read, 5, D_Write ;; SET D, 5 Cycles:8
- Opcode@SetBit CBEB, 8, E_Read, 5, E_Write ;; SET E, 5 Cycles:8
- Opcode@SetBit CBEC, 8, H_Read, 5, H_Write ;; SET H, 5 Cycles:8
- Opcode@SetBit CBED, 8, L_Read, 5, L_Write ;; SET L, 5 Cycles:8
- Opcode@SetBit CBEE,16, xHL_Read, 5, xHL_Write ;; SET xHL, 5 Cycles:16
- Opcode@SetBit CBEF, 8, A_Read, 5, A_Write ;; SET A, 5 Cycles:8
- Opcode@SetBit CBF0, 8, B_Read, 6, B_Write ;; SET B, 6 Cycles:8
- Opcode@SetBit CBF1, 8, C_Read, 6, C_Write ;; SET C, 6 Cycles:8
- Opcode@SetBit CBF2, 8, D_Read, 6, D_Write ;; SET D, 6 Cycles:8
- Opcode@SetBit CBF3, 8, E_Read, 6, E_Write ;; SET E, 6 Cycles:8
- Opcode@SetBit CBF4, 8, H_Read, 6, H_Write ;; SET H, 6 Cycles:8
- Opcode@SetBit CBF5, 8, L_Read, 6, L_Write ;; SET L, 6 Cycles:8
- Opcode@SetBit CBF6,16, xHL_Read, 6, xHL_Write ;; SET xHL, 6 Cycles:16
- Opcode@SetBit CBF7, 8, A_Read, 6, A_Write ;; SET A, 6 Cycles:8
- Opcode@SetBit CBF8, 8, B_Read, 7, B_Write ;; SET B, 7 Cycles:8
- Opcode@SetBit CBF9, 8, C_Read, 7, C_Write ;; SET C, 7 Cycles:8
- Opcode@SetBit CBFA, 8, D_Read, 7, D_Write ;; SET D, 7 Cycles:8
- Opcode@SetBit CBFB, 8, E_Read, 7, E_Write ;; SET E, 7 Cycles:8
- Opcode@SetBit CBFC, 8, H_Read, 7, H_Write ;; SET H, 7 Cycles:8
- Opcode@SetBit CBFD, 8, L_Read, 7, L_Write ;; SET L, 7 Cycles:8
- Opcode@SetBit CBFE,16, xHL_Read, 7, xHL_Write ;; SET xHL, 7 Cycles:16
- Opcode@SetBit CBFF, 8, A_Read, 7, A_Write ;; SET A, 7 Cycles:8
- V_EXIT:
- pop esi
- pop edi
- pop ebx
- ret
- OPD3:
- OPDB:
- OPDD:
- OPE3:
- OPE4:
- OPEB:
- OPEC:
- OPED:
- OPF4:
- OPFC:
- OPFD: ud2
- align 16
- OPTAB dd OP00, OP01, OP02, OP03, OP04, OP05, OP06, OP07, OP08, OP09, OP0A, OP0B, OP0C, OP0D, OP0E, OP0F
- dd OP10, OP11, OP12, OP13, OP14, OP15, OP16, OP17, OP18, OP19, OP1A, OP1B, OP1C, OP1D, OP1E, OP1F
- dd OP20, OP21, OP22, OP23, OP24, OP25, OP26, OP27, OP28, OP29, OP2A, OP2B, OP2C, OP2D, OP2E, OP2F
- dd OP30, OP31, OP32, OP33, OP34, OP35, OP36, OP37, OP38, OP39, OP3A, OP3B, OP3C, OP3D, OP3E, OP3F
- dd OP40, OP41, OP42, OP43, OP44, OP45, OP46, OP47, OP48, OP49, OP4A, OP4B, OP4C, OP4D, OP4E, OP4F
- dd OP50, OP51, OP52, OP53, OP54, OP55, OP56, OP57, OP58, OP59, OP5A, OP5B, OP5C, OP5D, OP5E, OP5F
- dd OP60, OP61, OP62, OP63, OP64, OP65, OP66, OP67, OP68, OP69, OP6A, OP6B, OP6C, OP6D, OP6E, OP6F
- dd OP70, OP71, OP72, OP73, OP74, OP75, OP76, OP77, OP78, OP79, OP7A, OP7B, OP7C, OP7D, OP7E, OP7F
- dd OP80, OP81, OP82, OP83, OP84, OP85, OP86, OP87, OP88, OP89, OP8A, OP8B, OP8C, OP8D, OP8E, OP8F
- dd OP90, OP91, OP92, OP93, OP94, OP95, OP96, OP97, OP98, OP99, OP9A, OP9B, OP9C, OP9D, OP9E, OP9F
- dd OPA0, OPA1, OPA2, OPA3, OPA4, OPA5, OPA6, OPA7, OPA8, OPA9, OPAA, OPAB, OPAC, OPAD, OPAE, OPAF
- dd OPB0, OPB1, OPB2, OPB3, OPB4, OPB5, OPB6, OPB7, OPB8, OPB9, OPBA, OPBB, OPBC, OPBD, OPBE, OPBF
- dd OPC0, OPC1, OPC2, OPC3, OPC4, OPC5, OPC6, OPC7, OPC8, OPC9, OPCA, OPCB, OPCC, OPCD, OPCE, OPCF
- dd OPD0, OPD1, OPD2, OPD3, OPD4, OPD5, OPD6, OPD7, OPD8, OPD9, OPDA, OPDB, OPDC, OPDD, OPDE, OPDF
- dd OPE0, OPE1, OPE2, OPE3, OPE4, OPE5, OPE6, OPE7, OPE8, OPE9, OPEA, OPEB, OPEC, OPED, OPEE, OPEF
- dd OPF0, OPF1, OPF2, OPF3, OPF4, OPF5, OPF6, OPF7, OPF8, OPF9, OPFA, OPFB, OPFC, OPFD, OPFE, OPFF
- align 16
- CBTAB dd CB00, CB01, CB02, CB03, CB04, CB05, CB06, CB07, CB08, CB09, CB0A, CB0B, CB0C, CB0D, CB0E, CB0F
- dd CB10, CB11, CB12, CB13, CB14, CB15, CB16, CB17, CB18, CB19, CB1A, CB1B, CB1C, CB1D, CB1E, CB1F
- dd CB20, CB21, CB22, CB23, CB24, CB25, CB26, CB27, CB28, CB29, CB2A, CB2B, CB2C, CB2D, CB2E, CB2F
- dd CB30, CB31, CB32, CB33, CB34, CB35, CB36, CB37, CB38, CB39, CB3A, CB3B, CB3C, CB3D, CB3E, CB3F
- dd CB40, CB41, CB42, CB43, CB44, CB45, CB46, CB47, CB48, CB49, CB4A, CB4B, CB4C, CB4D, CB4E, CB4F
- dd CB50, CB51, CB52, CB53, CB54, CB55, CB56, CB57, CB58, CB59, CB5A, CB5B, CB5C, CB5D, CB5E, CB5F
- dd CB60, CB61, CB62, CB63, CB64, CB65, CB66, CB67, CB68, CB69, CB6A, CB6B, CB6C, CB6D, CB6E, CB6F
- dd CB70, CB71, CB72, CB73, CB74, CB75, CB76, CB77, CB78, CB79, CB7A, CB7B, CB7C, CB7D, CB7E, CB7F
- dd CB80, CB81, CB82, CB83, CB84, CB85, CB86, CB87, CB88, CB89, CB8A, CB8B, CB8C, CB8D, CB8E, CB8F
- dd CB90, CB91, CB92, CB93, CB94, CB95, CB96, CB97, CB98, CB99, CB9A, CB9B, CB9C, CB9D, CB9E, CB9F
- dd CBA0, CBA1, CBA2, CBA3, CBA4, CBA5, CBA6, CBA7, CBA8, CBA9, CBAA, CBAB, CBAC, CBAD, CBAE, CBAF
- dd CBB0, CBB1, CBB2, CBB3, CBB4, CBB5, CBB6, CBB7, CBB8, CBB9, CBBA, CBBB, CBBC, CBBD, CBBE, CBBF
- dd CBC0, CBC1, CBC2, CBC3, CBC4, CBC5, CBC6, CBC7, CBC8, CBC9, CBCA, CBCB, CBCC, CBCD, CBCE, CBCF
- dd CBD0, CBD1, CBD2, CBD3, CBD4, CBD5, CBD6, CBD7, CBD8, CBD9, CBDA, CBDB, CBDC, CBDD, CBDE, CBDF
- dd CBE0, CBE1, CBE2, CBE3, CBE4, CBE5, CBE6, CBE7, CBE8, CBE9, CBEA, CBEB, CBEC, CBED, CBEE, CBEF
- dd CBF0, CBF1, CBF2, CBF3, CBF4, CBF5, CBF6, CBF7, CBF8, CBF9, CBFA, CBFB, CBFC, CBFD, CBFE, CBFF
- cpu_optick endp
- end
- ;; cpu_optick.asm (version2 for NASM Assembler)
- ;; Sharp LR35902 Chip Opcode for GameBoy
- ;;
- ;; Copyright (C) 2018 moecmks
- ;; This file is part of KS3578.
- ;;
- ;; do What The Fuck you want to Public License
- ;;
- ;; Version 1.0, March 2000
- ;; Copyright (C) 2000 Banlu Kemiyatorn (]d).
- ;; 136 Nives 7 Jangwattana 14 Laksi Bangkok
- ;; Everyone is permitted to copy and distribute verbatim copies
- ;; of this license document, but changing it is not allowed.
- ;;
- ;; Ok, the purpose of this license is simple
- ;; and you just
- ;;
- ;; DO WHAT THE FUCK YOU WANT TO.
- ;;
- ;; Sharp LR35902 Chip opcode mapper
- ;; http://www.pastraiser.com/cpu/gameboy/gameboy_opcodes.html
- ;; Z80 Chip opcode mapper
- ;; http://clrhome.org/table/
- ;;
- ;; The Fleg Register consists of the following bits:
- ;; 7 6 5 4 3 2 1 0
- ;; Z N H C 0 0 0 0
- Z_FLAG equ 0x80
- N_FLAG equ 0x40
- H_FLAG equ 0x20
- C_FLAG equ 0x10
- %if 1
- extern _gameboy_mmu_read@8 ;; prototype ks_uint8 __stdcall _gameboy_mmu_read (void;;gameboy, ks_uint16 addresss)
- extern _gameboy_mmu_write@12 ;; prototype void __stdcall _gameboy_mmu_write (void;;gameboy, ks_uint16 addresss, ks_uint8 value)
- extern _gameboy_mmu_read_w@8 ;; prototype ks_uint8 __stdcall _gameboy_mmu_read_w (void;;gameboy, ks_uint16 addresss)
- extern _gameboy_mmu_write_w@12 ;; prototype void __stdcall _gameboy_mmu_write_w (void;;gameboy, ks_uint16 addresss, ks_uint8 value)
- %define MmuRead _gameboy_mmu_read@8
- %define MmuReadWord _gameboy_mmu_read_w@8
- %define MmuWrite _gameboy_mmu_write@12
- %define MmuWriteWord _gameboy_mmu_write_w@12
- %endif
- ;; define union .
- %macro defREG 2 ; 1:low, 2:hi
- .%1: resb 1
- .%2: resb 1
- .%2%1: equ .%1
- %endmacro
- %macro defREG2 3 ; 1:low, 2:hi 3:comb another.
- .%1: resb 1
- .%2: resb 1
- .%3: equ .%1
- %endmacro
- struc lr35902 ; structure definition
- defREG F, A
- defREG C, B
- defREG E, D
- defREG L, H
- defREG2 SP_LO, SP_HI, SP
- defREG2 PC_LO, PC_HI, PC
- .IME: resb 1
- .halt: resd 1
- .stop: resd 1
- ._backup: resd 1
- .key1: resb 1
- .gameboy: resd 1
- endstruc
- %macro xImm16_WriteReg 2 ;; eax:Imm16 %1 lr35902::reg %2:word or byte
- movzx ecx, %2 [YG_GP+lr35902.%1]
- push ecx
- push eax
- push dword [YG_GP+lr35902.gameboy]
- call MmuWriteWord
- %endmacro
- %macro xRegister_Read 1
- mov ax, word [YG_GP+lr35902.%1]
- push eax
- push dword [YG_GP+lr35902.gameboy]
- call MmuRead
- %endmacro
- %macro xImm16_WriteRegSP 0
- movzx ecx, word [YG_GP+lr35902.SP]
- push ecx
- push eax
- push dword [YG_GP+lr35902.gameboy]
- call MmuWriteWord
- %endmacro
- %macro xImm16_WriteRegA 0
- movzx ecx, byte [YG_GP+lr35902.A]
- push ecx
- push eax
- push dword [YG_GP+lr35902.gameboy]
- call MmuWrite
- %endmacro
- %macro xRegister_WriteReg 4
- ;; eax:Register
- ;; %1 lr35902::reg
- ;; %2:word or byte
- ;; %3 Offset add
- ;; %4 bit mask 0xFF or 0xFFFF
- and eax, %4
- add eax, %3
- push eax
- movzx eax, %2 [YG_GP+lr35902.%1]
- push eax
- push dword [YG_GP+lr35902.gameboy]
- call MmuWrite
- %endmacro
- %macro SetCyclesAndRet 1 ;; %1: burning cpu clk.
- ;; write back PC
- mov [YG_GP+lr35902.PC], si
- mov eax, %1
- jmp V_EXIT
- %endmacro
- %macro SetCyclesRetP 1 ;; %1: burning cpu clk.
- ;; write back F
- mov [YG_GP+lr35902.F], bl
- SetCyclesAndRet %1
- %endmacro
- ;; Register access-read unwind
- %macro B_Read 0
- mov al, [YG_GP+lr35902.B]
- %endmacro
- %macro C_Read 0
- mov al, [YG_GP+lr35902.C]
- %endmacro
- %macro D_Read 0
- mov al, [YG_GP+lr35902.D]
- %endmacro
- %macro E_Read 0
- mov al, [YG_GP+lr35902.E]
- %endmacro
- %macro H_Read 0
- mov al, [YG_GP+lr35902.H]
- %endmacro
- %macro L_Read 0
- mov al, [YG_GP+lr35902.L]
- %endmacro
- %macro A_Read 0
- mov al, [YG_GP+lr35902.A]
- %endmacro
- %macro F_Read 0
- mov al, [YG_GP+lr35902.F]
- %endmacro
- %macro BC_Read 0
- mov ax, [YG_GP+lr35902.BC]
- %endmacro
- %macro DE_Read 0
- mov ax, [YG_GP+lr35902.DE]
- %endmacro
- %macro HL_Read 0
- mov ax, [YG_GP+lr35902.HL]
- %endmacro
- %macro AF_Read 0
- mov ax, [YG_GP+lr35902.AF]
- %endmacro
- %macro SP_Read 0
- mov ax, [YG_GP+lr35902.SP]
- %endmacro
- %macro xBC_Read 0
- xRegister_Read BC
- %endmacro
- %macro xDE_Read 0
- xRegister_Read DE
- %endmacro
- %macro xHL_Read 0
- xRegister_Read HL
- %endmacro
- %macro xHL_Read_Inc 0
- xHL_Read
- inc word [YG_GP+lr35902.HL]
- %endmacro
- %macro xHL_Read_Dec 0
- xHL_Read
- dec word [YG_GP+lr35902.HL]
- %endmacro
- %macro xAF_Read 0
- xRegister_Read AF
- %endmacro
- %macro xPC_Read 0
- xRegister_Read PC
- %endmacro
- ;; Register access-write unwind
- %macro B_Write 0
- mov [YG_GP+lr35902.B], al
- %endmacro
- %macro C_Write 0
- mov [YG_GP+lr35902.C], al
- %endmacro
- %macro D_Write 0
- mov [YG_GP+lr35902.D], al
- %endmacro
- %macro E_Write 0
- mov [YG_GP+lr35902.E], al
- %endmacro
- %macro H_Write 0
- mov [YG_GP+lr35902.H], al
- %endmacro
- %macro L_Write 0
- mov [YG_GP+lr35902.L], al
- %endmacro
- %macro A_Write 0
- mov [YG_GP+lr35902.A], al
- %endmacro
- %macro F_Write 0
- mov [YG_GP+lr35902.F], al
- %endmacro
- %macro BC_Write 0
- mov [YG_GP+lr35902.BC], ax
- %endmacro
- %macro DE_Write 0
- mov [YG_GP+lr35902.DE], ax
- %endmacro
- %macro HL_Write 0
- mov [YG_GP+lr35902.HL], ax
- %endmacro
- %macro AF_Write 0
- mov [YG_GP+lr35902.AF], ax
- %endmacro
- %macro SP_Write 0
- mov [YG_GP+lr35902.SP], ax
- %endmacro
- %macro xBC_Write 0
- xRegister_WriteReg BC, word, 0, 0xFFFF
- %endmacro
- %macro xDE_Write 0
- xRegister_WriteReg DE, word, 0, 0xFFFF
- %endmacro
- %macro xHL_Write 0
- xRegister_WriteReg HL, word, 0, 0xFFFF
- %endmacro
- %macro xHL_Write_Inc 0
- xRegister_WriteReg HL, word, 0, 0xFFFF
- inc word [YG_GP+lr35902.HL]
- %endmacro
- %macro xHL_Write_Dec 0
- xRegister_WriteReg HL, word, 0, 0xFFFF
- dec word [YG_GP+lr35902.HL]
- %endmacro
- %macro Imm8_Read 0
- push esi
- push dword [YG_GP+lr35902.gameboy]
- call MmuRead
- inc esi
- %endmacro
- %macro Imm16_Read 0
- push esi
- push dword [YG_GP+lr35902.gameboy]
- call MmuReadWord
- add esi, 2
- %endmacro
- %macro Read_ByxX86SpecRegister 1
- ;; %1:x86Register
- push %1
- push dword [YG_GP+lr35902.gameboy]
- call MmuRead
- %endmacro
- %macro Imm8Read_ExpandAddress16 0
- Imm8_Read
- and eax, 000FFh
- add eax, 0FF00h
- %endmacro
- %macro Imm8_ExpandSignWord 0
- Imm8_Read
- movsx eax, al
- %endmacro
- %macro C_ExpandAddress16 0
- movzx eax, byte [YG_GP+lr35902.C]
- add eax, 0FF00h
- %endmacro
- %macro Imm8Read_ExpandAddress16_Fetch 0
- Imm8Read_ExpandAddress16
- Read_ByxX86SpecRegister eax
- %endmacro
- %macro Imm16Read_Address_Fetch 0
- Imm16_Read
- Read_ByxX86SpecRegister eax
- %endmacro
- %macro C_ExpandAddress16_Fetch 0
- mov al, [YG_GP+lr35902.C]
- add eax, 0FF00h
- Read_ByxX86SpecRegister eax
- %endmacro
- %macro EmptyMacro 0
- %endmacro
- ;; ld r(xHL), r(xHL)
- %macro lr35902@LD@RxHLToRxHL 4
- ;; %1 OpCase
- ;; %2 Cycles_
- ;; %3 ReadOrExt
- ;; %4 WriteOrExt
- %1:
- %3
- %4
- SetCyclesAndRet %2
- %endmacro
- ;; ld r, imm8/imm16
- %macro lr35902@LD@Imm 4
- ;; %1 OpCase
- ;; %2 Immread
- ;; %3 Cycles_
- ;; %4 WriteOrExt
- %1:
- %2
- %4
- SetCyclesAndRet %3
- %endmacro
- ;; arith/logic main
- %macro OP_Add$c_xHLrToA 1
- ;; %1: atomic_it 0(add) or C_FLAG(adc)
- ;; source value <- eax
- and eax, 0xFF ;; Value &= 0xFF
- and YG_PF, %1
- shr YG_PF, 5 ;; check c-flags
- movzx edx, byte [YG_GP+lr35902.A]
- mov ecx, edx ;; temp WORD := A
- adc ecx, eax ;; temp WORD := A + Value
- mov [YG_GP+lr35902.A], cl ;; always write back A.
- test cl, cl
- setz YG_PF_8
- shl YG_PF_8, 7 ;; z flag set
- xor dx, ax
- mov ax, cx
- xor ax, dx ;; temp WORD:= temp WORD^(A ^Value)
- and ax, 0x10
- shl ax, 1
- or YG_PF, eax ;; h flag set
- shl ch, 4
- or YG_PF_8, ch ;; c flag set
- %endmacro
- %macro AddWord_ 0
- ;; source <- eax
- ;; target <- always register HL
- ;; clear psb . save old Z
- and YG_PF, Z_FLAG
- movzx ecx, word [YG_GP+lr35902.HL]
- and eax, 0xFFFF
- lea edx, [eax+ecx]
- ;; always write back HL.
- mov word [YG_GP+lr35902.HL], dx
- xor cx, ax
- mov ax, dx
- xor cx, ax
- and cx, 01000h
- shl cx, 1
- or YG_PF_8, ch ;; h flag set
- and edx, 010000h
- shr edx, 12
- or YG_PF, edx ;; c flag set
- %endmacro
- %macro AddWord2_ 0
- ;; source <- eax
- ;; target <- always register SP
- movsx eax, al
- xor YG_PF, YG_PF
- movzx ecx, word [YG_GP+lr35902.SP]
- and eax, 0xFFFF
- lea edx, [eax+ecx]
- ;; always write back HL.
- mov word [YG_GP+lr35902.SP], dx
- xor cx, ax
- mov ax, dx
- xor cx, ax
- and cx, 0x0110 ;; C|H
- mov YG_PF_8, ch
- shl YG_PF_8, 4
- shl cl, 1
- or YG_PF_8, cl
- and YG_PF, (H_FLAG| C_FLAG)
- %endmacro
- %macro OP_CmpSub$bc_xHLrToA 2
- ;; %1: atomic_it 0(sub) or C_FLAG(sbc)
- ;; %2: [YG_GP+lr35902.A] || cl for cmp opcode
- ;; source value <- eax
- and eax, 0xFF ;; Value &= 0xFF
- and YG_PF, %1
- shr YG_PF, 5 ;; check c-flags
- movzx edx, byte [YG_GP+lr35902.A]
- mov ecx, edx ;; temp WORD := A
- sbb ecx, eax ;; temp WORD := A - Value
- mov %2, cl ;; always write back A.
- test cl, cl
- setz YG_PF_8
- shl YG_PF_8, 7 ;; z flag set
- xor dx, ax
- mov ax, cx
- xor ax, dx ;; temp WORD:= temp WORD^(A ^Value)
- and ax, 0x10
- shl ax, 1
- or YG_PF, eax ;; h flag set
- and ecx, 0x8000
- shr ecx, 11
- or YG_PF, ecx ;; c flag set
- or YG_PF, N_FLAG ;; n flag set
- %endmacro
- ;; XOR | OR | AND do unwind base .
- %macro OP_Logic_T 2
- ;; %1: initFlags
- ;; %2: LogicOp
- ;; source <- eax
- ;; target <- always register A
- mov YG_PF, %1
- movzx edx, byte [YG_GP+lr35902.A]
- %2 al, dl
- ;; always write back A.
- mov [YG_GP+lr35902.A], al
- setz al
- shl eax, 7
- or YG_PF, eax ;; z flag set
- %endmacro
- ;; unwind
- %macro Add_ 0
- OP_Add$c_xHLrToA 0
- %endmacro
- %macro Adc_ 0
- OP_Add$c_xHLrToA C_FLAG
- %endmacro
- %macro Sub_ 0
- OP_CmpSub$bc_xHLrToA 0, [YG_GP+lr35902.A]
- %endmacro
- %macro Sbc_ 0
- OP_CmpSub$bc_xHLrToA C_FLAG, [YG_GP+lr35902.A]
- %endmacro
- %macro Cmp_ 0
- OP_CmpSub$bc_xHLrToA 0, cl
- %endmacro
- %macro And_ 0
- OP_Logic_T H_FLAG, and
- %endmacro
- %macro Xor_ 0
- OP_Logic_T 0, xor
- %endmacro
- %macro Or_ 0
- OP_Logic_T 0, or
- %endmacro
- %macro DecWord_ 0
- dec eax
- %endmacro
- %macro IncWord_ 0
- inc eax
- %endmacro
- %macro Inc_ 0 ;; ----------------------- DEC RxHL
- ;; source <- eax
- ;; clear psb . save old C
- and YG_PF, C_FLAG
- add al, 1
- setz dl
- shl dl, 7
- or YG_PF, edx ;; z flag set
- test eax, 15 ;; 0xNF+1 := 0xC0 (C:= N+1)
- setz dl
- shl dl, 5
- or YG_PF, edx ;; h flag set
- %endmacro
- %macro Dec_ 0 ;; ----------------------- INC RxHL
- ;; source <- eax
- ;; clear psb . save old C
- and YG_PF, C_FLAG
- sub al, 1
- setz dl
- shl dl, 7
- or YG_PF, edx ;; z flag set
- lea ecx, [eax+1]
- test ecx, 15 ;; 0xN0-1 := 0xCF (C:= N-1)
- setz dl
- shl dl, 5
- or YG_PF, edx ;; h flag set
- or YG_PF, N_FLAG ;; n flag set
- %endmacro
- %macro lr35902@JP 3 ;; ------------------------- JMP/Jcc
- ;; %1 Opcode,
- ;; %2 Flags
- ;; %3 OpNOT
- %1:
- mov eax, YG_PF
- and eax, %2
- xor eax, %3
- jne %%JP_skip
- add esi, 2
- SetCyclesRetP 12
- %%JP_skip:
- Imm16_Read
- mov esi, eax
- SetCyclesRetP 16
- %endmacro
- %macro lr35902@Rst 2 ;; ------------------------- Rst
- ;; %1 Opcode
- ;; %2 Vector
- %1:
- mov ax, si
- OP_PushWord
- mov si, %2
- SetCyclesAndRet 16
- %endmacro
- %macro lr35902@JR 3 ;; -------------------------- JMP Short/Jcc Short
- ;; %1 Opcode
- ;; %2 Flags
- ;; %3 OpNOT
- %1:
- mov eax, YG_PF
- and eax, %2
- xor eax, %3
- jne %%JR_skip
- inc esi
- SetCyclesRetP 8
- %%JR_skip:
- Imm8_Read
- movsx eax, al
- add esi, eax
- SetCyclesRetP 12
- %endmacro
- %macro lr35902@CALL 3 ;; ------------------------ sub routine call
- ;; %1 Opcode
- ;; %2 Flags
- ;; %3 OpNOT
- %1:
- mov eax, YG_PF
- and eax, %2
- xor eax, %3
- jne %%CALL_Skip
- add esi, 2
- SetCyclesRetP 12
- %%CALL_Skip:
- lea eax, [YG_PC+2]
- OP_PushWord
- Imm16_Read
- mov esi, eax
- SetCyclesRetP 24
- %endmacro
- %macro lr35902@RET 4 ;; --------------------------- sub_call return
- ;; %1 Opcode
- ;; %2 Flags
- ;; %3 OpNOT
- ;; %4 RetHitCycles
- %1:
- mov eax, YG_PF
- and eax, %2
- xor eax, %3
- jne %%RET_skip
- SetCyclesRetP 8
- %%RET_skip:
- OP_PopWord
- mov YG_PC, eax
- SetCyclesRetP %4
- %endmacro
- %macro lr35902@RETI 4
- %1:
- OP_PopWord
- mov YG_PC, eax
- mov byte [YG_GP+lr35902.IME], 1
- SetCyclesAndRet 16
- %endmacro
- %macro OP_PushWord 0 ;; ----------------------- Stack Push Base
- ;; source <- eax
- ;; --SP Push High
- ;; --SP Push Low
- mov cx, [YG_GP+lr35902.SP]
- sub cx, 2
- mov [YG_GP+lr35902.SP], cx
- push eax
- push ecx
- push dword [YG_GP+lr35902.gameboy]
- call MmuWriteWord
- %endmacro
- %macro OP_PopWord 0 ;; ----------------------- Stack Pop Base
- ;; target <- eax
- ;; Pop Low ++SP
- ;; Pop High ++SP
- mov cx, [YG_GP+lr35902.SP]
- push ecx
- add cx, 2
- mov [YG_GP+lr35902.SP], cx
- push dword [YG_GP+lr35902.gameboy]
- call MmuReadWord
- %endmacro
- %macro AF_StackPopStuff 0 ;; -----------------------
- and eax, 0xFFF0
- %endmacro
- %macro AF_StackPushStuff 0 ;; -----------------------
- %endmacro
- %macro lr35902@MainALU 5
- ;; %1 OpCase
- ;; %2 Cycles
- ;; %3 ReadOrExt
- ;; %4 Op
- ;; %5 WriteOrExt
- %1:
- %3
- %4
- %5
- SetCyclesRetP %2
- %endmacro
- %macro lr35902@MainALUExt 5
- ;; %1 OpCase
- ;; %2 Cycles
- ;; %3 ReadOrExt
- ;; %4 Op
- ;; %5 WriteOrExt
- %1:
- %3
- %4
- %5
- SetCyclesRetP %2
- %endmacro
- ;; rortoe shift with
- %macro RLC_ 0
- rol al, 1
- setc YG_PF_8
- shl YG_PF_8, 4
- test al, al
- setz dl
- shl dl, 7
- or YG_PF_8, dl
- %endmacro
- ;; rortoe shift with
- %macro RRC_ 0
- ror al, 1
- setc YG_PF_8
- shl YG_PF_8, 4
- test al, al
- setz dl
- shl dl, 7
- or YG_PF_8, dl
- %endmacro
- ;; logic shift with carry
- %macro RL_ 0
- shr YG_PF_8, 5
- rcl al, 1
- setc YG_PF_8
- shl YG_PF_8, 4
- test al, al
- setz dl
- shl dl, 7
- or YG_PF_8, dl
- %endmacro
- ;; logic shift with carry
- %macro RR_ 0
- shr YG_PF_8, 5
- rcr al, 1
- setc YG_PF_8
- shl YG_PF_8, 4
- test al, al
- setz dl
- shl dl, 7
- or YG_PF_8, dl
- %endmacro
- ;; logic shift
- %macro RL_N_ 0
- shl al, 1
- setc YG_PF_8
- shl YG_PF_8, 4
- test al, al
- setz dl
- shl dl, 7
- or YG_PF_8, dl
- %endmacro
- ;; logic shift
- %macro RR_N_ 0
- shr al, 1
- setc YG_PF_8
- shl YG_PF_8, 4
- test al, al
- setz dl
- shl dl, 7
- or YG_PF_8, dl
- %endmacro
- ;; arith shift save msb
- %macro RRS_N_ 0
- sar al, 1
- setc YG_PF_8
- shl YG_PF_8, 4
- test al, al
- setz dl
- shl dl, 7
- or YG_PF_8, dl
- %endmacro
- ;; swap byte-lo 4bit and byte-hi 4bit
- %macro SWAP_ 0
- ror al, 4
- test al, al
- setz cl
- shl cl, 7
- mov YG_PF, ecx
- %endmacro
- ;; Set
- %macro lr35902@SetBit 5
- ;; %1 Opcode
- ;; %2 Cycles
- ;; %3 ReadOrExt
- ;; %4 BitOrder
- ;; %5 WriteOrExt
- %1:
- %3
- mov ecx, 1
- shl ecx, %4
- or eax, ecx
- %5
- SetCyclesAndRet %2
- %endmacro
- %macro lr35902@ResBit 5
- ;; %1 Opcode
- ;; %2 Cycles
- ;; %3 ReadOrExt
- ;; %4 BitOrder
- ;; %5 WriteOrExt
- %1:
- %3
- mov ecx, 1
- shl ecx, %4
- not ecx
- and al, cl
- %5
- SetCyclesRetP %2
- %endmacro
- %macro lr35902@TestBit 4
- ;; %1 Opcode
- ;; %2 Cycles
- ;; %3 ReadOrExt
- ;; %4 BitOrder
- %1:
- %3
- and YG_PF, C_FLAG
- or YG_PF, H_FLAG
- mov ecx, 1
- shl ecx, %4
- test al, cl
- setz al
- shl eax, 7
- or YG_PF, eax
- SetCyclesRetP %2
- %endmacro
- ;; lr35902@MainStack OPC1,12, PopWord_, EmptyMacro, BC_Write ;; POP BC 1 Cycles:12
- %macro lr35902@MainStack 5
- ;; %1 OpCase
- ;; %2 Cycles
- ;; %3 ReadOrExt
- ;; %4 Op
- ;; %5 WriteOrExt
- %1:
- %3
- %4
- %5
- SetCyclesAndRet %2
- %endmacro
- section .text
- global _cpu_optick
- _cpu_optick:
- push ebx ;U - save old frame
- push edi ;V - save old frame
- push esi
- nop
- %define YG_PF_8 bl
- %define YG_PF ebx
- %define YG_PC esi
- %define YG_GP edi
- ; ebx <- save now P (cpu's PSB reg)
- ; esi <- save now PC (cpu's EIP reg)
- ; edi <- save regs root
- ; eax <- calc temp or final calc out reslt
- ; ecx <- calc temp
- ; edx <- calc temp
- mov YG_GP, [esp+4+12] ;; fetch CPU struct
- mov si, [YG_GP+lr35902.PC]
- mov bl, [YG_GP+lr35902.F]
- ; Fetch Opcode, PC++
- push YG_PC
- push dword [YG_GP+lr35902.gameboy]
- call MmuRead
- inc YG_PC
- add YG_PC, [YG_GP+lr35902._backup]
- and eax, 255
- jmp dword [OPTAB+eax*4]
- lr35902@LD@Imm OP06, Imm8_Read, 8, B_Write ;; LD B Imm8, 2, Cycles:8
- lr35902@LD@Imm OP0E, Imm8_Read, 8, C_Write ;; LD C Imm8, 2, Cycles:8
- lr35902@LD@Imm OP16, Imm8_Read, 8, D_Write ;; LD D Imm8, 2, Cycles:8
- lr35902@LD@Imm OP1E, Imm8_Read, 8, E_Write ;; LD E Imm8, 2, Cycles:8
- lr35902@LD@Imm OP26, Imm8_Read, 8, H_Write ;; LD H Imm8, 2, Cycles:8
- lr35902@LD@Imm OP2E, Imm8_Read, 8, L_Write ;; LD L Imm8, 2, Cycles:8
- lr35902@LD@Imm OP36, Imm8_Read, 12, xHL_Write ;; LD xHL Imm8, 2, Cycles:8
- lr35902@LD@Imm OP3E, Imm8_Read, 8, A_Write ;; LD A Imm8, 2, Cycles:8
- lr35902@LD@Imm OP01, Imm16_Read, 12, BC_Write ;; LD BC Imm16, 3 Cycles:12
- lr35902@LD@Imm OP11, Imm16_Read, 12, DE_Write ;; LD DE Imm16, 3 Cycles:12
- lr35902@LD@Imm OP21, Imm16_Read, 12, HL_Write ;; LD HL Imm16, 3 Cycles:12
- lr35902@LD@Imm OP31, Imm16_Read, 12, SP_Write ;; LD SP Imm16, 3 Cycles:12
- lr35902@LD@RxHLToRxHL OP40, 4, B_Read, B_Write ;; LD B B, 1 Cycles:4
- lr35902@LD@RxHLToRxHL OP41, 4, C_Read, B_Write ;; LD B C, 1 Cycles:4
- lr35902@LD@RxHLToRxHL OP42, 4, D_Read, B_Write ;; LD B D, 1 Cycles:4
- lr35902@LD@RxHLToRxHL OP43, 4, E_Read, B_Write ;; LD B E, 1 Cycles:4
- lr35902@LD@RxHLToRxHL OP44, 4, H_Read, B_Write ;; LD B H, 1 Cycles:4
- lr35902@LD@RxHLToRxHL OP45, 4, L_Read, B_Write ;; LD B L, 1 Cycles:4
- lr35902@LD@RxHLToRxHL OP46, 8, xHL_Read, B_Write ;; LD B xHL, 1 Cycles:8
- lr35902@LD@RxHLToRxHL OP47, 4, A_Read, B_Write ;; LD B A, 1 Cycles:4
- lr35902@LD@RxHLToRxHL OP48, 4, B_Read, C_Write ;; LD C B, 1 Cycles:4
- lr35902@LD@RxHLToRxHL OP49, 4, C_Read, C_Write ;; LD C C, 1 Cycles:4
- lr35902@LD@RxHLToRxHL OP4A, 4, D_Read, C_Write ;; LD C D, 1 Cycles:4
- lr35902@LD@RxHLToRxHL OP4B, 4, E_Read, C_Write ;; LD C E, 1 Cycles:4
- lr35902@LD@RxHLToRxHL OP4C, 4, H_Read, C_Write ;; LD C H, 1 Cycles:4
- lr35902@LD@RxHLToRxHL OP4D, 4, L_Read, C_Write ;; LD C L, 1 Cycles:4
- lr35902@LD@RxHLToRxHL OP4E, 8, xHL_Read, C_Write ;; LD C xHL, 1 Cycles:8
- lr35902@LD@RxHLToRxHL OP4F, 4, A_Read, C_Write ;; LD C A, 1 Cycles:4
- lr35902@LD@RxHLToRxHL OP50, 4, B_Read, D_Write ;; LD D B, 1 Cycles:4
- lr35902@LD@RxHLToRxHL OP51, 4, C_Read, D_Write ;; LD D C, 1 Cycles:4
- lr35902@LD@RxHLToRxHL OP52, 4, D_Read, D_Write ;; LD D D, 1 Cycles:4
- lr35902@LD@RxHLToRxHL OP53, 4, E_Read, D_Write ;; LD D E, 1 Cycles:4
- lr35902@LD@RxHLToRxHL OP54, 4, H_Read, D_Write ;; LD D H, 1 Cycles:4
- lr35902@LD@RxHLToRxHL OP55, 4, L_Read, D_Write ;; LD D L, 1 Cycles:4
- lr35902@LD@RxHLToRxHL OP56, 8, xHL_Read, D_Write ;; LD D xHL, 1 Cycles:8
- lr35902@LD@RxHLToRxHL OP57, 4, A_Read, D_Write ;; LD D A, 1 Cycles:4
- lr35902@LD@RxHLToRxHL OP58, 4, B_Read, E_Write ;; LD E B, 1 Cycles:4
- lr35902@LD@RxHLToRxHL OP59, 4, C_Read, E_Write ;; LD E C, 1 Cycles:4
- lr35902@LD@RxHLToRxHL OP5A, 4, D_Read, E_Write ;; LD E D, 1 Cycles:4
- lr35902@LD@RxHLToRxHL OP5B, 4, E_Read, E_Write ;; LD E E, 1 Cycles:4
- lr35902@LD@RxHLToRxHL OP5C, 4, H_Read, E_Write ;; LD E H, 1 Cycles:4
- lr35902@LD@RxHLToRxHL OP5D, 4, L_Read, E_Write ;; LD E L, 1 Cycles:4
- lr35902@LD@RxHLToRxHL OP5E, 8, xHL_Read, E_Write ;; LD E xHL, 1 Cycles:8
- lr35902@LD@RxHLToRxHL OP5F, 4, A_Read, E_Write ;; LD E A, 1 Cycles:4
- lr35902@LD@RxHLToRxHL OP60, 4, B_Read, H_Write ;; LD H B, 1 Cycles:4
- lr35902@LD@RxHLToRxHL OP61, 4, C_Read, H_Write ;; LD H C, 1 Cycles:4
- lr35902@LD@RxHLToRxHL OP62, 4, D_Read, H_Write ;; LD H D, 1 Cycles:4
- lr35902@LD@RxHLToRxHL OP63, 4, E_Read, H_Write ;; LD H E, 1 Cycles:4
- lr35902@LD@RxHLToRxHL OP64, 4, H_Read, H_Write ;; LD H H, 1 Cycles:4
- lr35902@LD@RxHLToRxHL OP65, 4, L_Read, H_Write ;; LD H L, 1 Cycles:4
- lr35902@LD@RxHLToRxHL OP66, 8, xHL_Read, H_Write ;; LD H xHL, 1 Cycles:8
- lr35902@LD@RxHLToRxHL OP67, 4, A_Read, H_Write ;; LD H A, 1 Cycles:4
- lr35902@LD@RxHLToRxHL OP68, 4, B_Read, L_Write ;; LD L B, 1 Cycles:4
- lr35902@LD@RxHLToRxHL OP69, 4, C_Read, L_Write ;; LD L C, 1 Cycles:4
- lr35902@LD@RxHLToRxHL OP6A, 4, D_Read, L_Write ;; LD L D, 1 Cycles:4
- lr35902@LD@RxHLToRxHL OP6B, 4, E_Read, L_Write ;; LD L E, 1 Cycles:4
- lr35902@LD@RxHLToRxHL OP6C, 4, H_Read, L_Write ;; LD L H, 1 Cycles:4
- lr35902@LD@RxHLToRxHL OP6D, 4, L_Read, L_Write ;; LD L L, 1 Cycles:4
- lr35902@LD@RxHLToRxHL OP6E, 8, xHL_Read, L_Write ;; LD L xHL, 1 Cycles:8
- lr35902@LD@RxHLToRxHL OP6F, 4, A_Read, L_Write ;; LD L A, 1 Cycles:4
- lr35902@LD@RxHLToRxHL OP70, 8, B_Read, xHL_Write ;; LD xHL B, 1 Cycles:8
- lr35902@LD@RxHLToRxHL OP71, 8, C_Read, xHL_Write ;; LD xHL C, 1 Cycles:8
- lr35902@LD@RxHLToRxHL OP72, 8, D_Read, xHL_Write ;; LD xHL D, 1 Cycles:8
- lr35902@LD@RxHLToRxHL OP73, 8, E_Read, xHL_Write ;; LD xHL E, 1 Cycles:8
- lr35902@LD@RxHLToRxHL OP74, 8, H_Read, xHL_Write ;; LD xHL H, 1 Cycles:8
- lr35902@LD@RxHLToRxHL OP75, 8, L_Read, xHL_Write ;; LD xHL L, 1 Cycles:8
- lr35902@LD@RxHLToRxHL OP02, 8, A_Read, xBC_Write ;; LD xBC A, 1 Cycles:8
- lr35902@LD@RxHLToRxHL OP12, 8, A_Read, xDE_Write ;; LD xDE A, 1 Cycles:8
- lr35902@LD@RxHLToRxHL OP77, 8, A_Read, xHL_Write ;; LD xHL A, 1 Cycles:8
- lr35902@LD@RxHLToRxHL OP22, 8, A_Read, xHL_Write_Inc;; LD xHL++ A, 1 Cycles:8
- lr35902@LD@RxHLToRxHL OP32, 8, A_Read, xHL_Write_Dec ;; LD xHL-- A, 1 Cycles:8
- lr35902@LD@RxHLToRxHL OP78, 4, B_Read, A_Write ;; LD A B, 1 Cycles:4
- lr35902@LD@RxHLToRxHL OP79, 4, C_Read, A_Write ;; LD A C, 1 Cycles:4
- lr35902@LD@RxHLToRxHL OP7A, 4, D_Read, A_Write ;; LD A D, 1 Cycles:4
- lr35902@LD@RxHLToRxHL OP7B, 4, E_Read, A_Write ;; LD A E, 1 Cycles:4
- lr35902@LD@RxHLToRxHL OP7C, 4, H_Read, A_Write ;; LD A H, 1 Cycles:4
- lr35902@LD@RxHLToRxHL OP7D, 4, L_Read, A_Write ;; LD A L, 1 Cycles:4
- lr35902@LD@RxHLToRxHL OP0A, 8, xBC_Read, A_Write ;; LD A xBC, 1 Cycles:8
- lr35902@LD@RxHLToRxHL OP1A, 8, xDE_Read, A_Write ;; LD A xDE, 1 Cycles:8
- lr35902@LD@RxHLToRxHL OP7E, 8, xHL_Read, A_Write ;; LD A xHL, 1 Cycles:8
- lr35902@LD@RxHLToRxHL OP2A, 8, xHL_Read_Inc, A_Write ;; LD A xHL++, 1 Cycles:8
- lr35902@LD@RxHLToRxHL OP3A, 8, xHL_Read_Dec, A_Write ;; LD A xHL--, 1 Cycles:8
- lr35902@LD@RxHLToRxHL OP7F, 4, A_Read, A_Write ;; LD A A, 1 Cycles:4
- ;; MISC LD
- lr35902@LD@RxHLToRxHL OP08,20, Imm16_Read, xImm16_WriteRegSP ;; LD (Imm16) SP, 3 Cycles:20
- lr35902@LD@RxHLToRxHL OPEA,16, Imm16_Read, xImm16_WriteRegA ;; LD (Imm16) A, 3 Cycles:16
- lr35902@LD@RxHLToRxHL OPE0,12, Imm8Read_ExpandAddress16, xImm16_WriteRegA ;; LD (Imm8+0FF00h) A, 2 Cycles:12
- lr35902@LD@RxHLToRxHL OPE2, 8, C_ExpandAddress16, xImm16_WriteRegA ;; LD (C+0FF00h) A, 2 Cycles:8
- lr35902@LD@RxHLToRxHL OPF0,12, Imm8Read_ExpandAddress16_Fetch, A_Write ;; LD A, (Imm8+0FF00h) 2 Cycles:12
- lr35902@LD@RxHLToRxHL OPF2, 8, C_ExpandAddress16_Fetch, A_Write ;; LD A, (C+0FF00h) 2 Cycles:8
- lr35902@LD@RxHLToRxHL OPFA,16, Imm16Read_Address_Fetch, A_Write ;; LD A, (Imm16) 3 Cycles:16
- lr35902@LD@RxHLToRxHL OPF9, 8, HL_Read, SP_Write ;; LD SP HL 1 Cycles:8
- lr35902@MainALU OP80, 4, B_Read, Add_, EmptyMacro ;; ADD A, B 1 Cycles:4
- lr35902@MainALU OP81, 4, C_Read, Add_, EmptyMacro ;; ADD A, C 1 Cycles:4
- lr35902@MainALU OP82, 4, D_Read, Add_, EmptyMacro ;; ADD A, D 1 Cycles:4
- lr35902@MainALU OP83, 4, E_Read, Add_, EmptyMacro ;; ADD A, E 1 Cycles:4
- lr35902@MainALU OP84, 4, H_Read, Add_, EmptyMacro ;; ADD A, H 1 Cycles:4
- lr35902@MainALU OP85, 4, L_Read, Add_, EmptyMacro ;; ADD A, L 1 Cycles:4
- lr35902@MainALU OP86, 8, xHL_Read, Add_, EmptyMacro ;; ADD A, xHL 1 Cycles:8
- lr35902@MainALU OP87, 4, A_Read, Add_, EmptyMacro ;; ADD A, A 1 Cycles:4
- lr35902@MainALU OPC6, 8, Imm8_Read, Add_, EmptyMacro ;; ADD A, Imm8 2 Cycles:8
- lr35902@MainALU OP09, 8, BC_Read, AddWord_, HL_Write ;; ADD HL, BC 1 Cycles:8
- lr35902@MainALU OP19, 8, DE_Read, AddWord_, HL_Write ;; ADD HL, DE 1 Cycles:8
- lr35902@MainALU OP29, 8, HL_Read, AddWord_, HL_Write ;; ADD HL, HL 1 Cycles:8
- lr35902@MainALU OP39, 8, SP_Read, AddWord_, HL_Write ;; ADD HL, SP 1 Cycles:8
- lr35902@MainALU OPE8,16, Imm8_ExpandSignWord, AddWord2_, EmptyMacro ;; ADD SP, SignImm8 2 Cycles:16
- lr35902@MainALU OP88, 4, B_Read, Adc_, EmptyMacro ;; ADC A, B 1 Cycles:4
- lr35902@MainALU OP89, 4, C_Read, Adc_, EmptyMacro ;; ADC A, C 1 Cycles:4
- lr35902@MainALU OP8A, 4, D_Read, Adc_, EmptyMacro ;; ADC A, D 1 Cycles:4
- lr35902@MainALU OP8B, 4, E_Read, Adc_, EmptyMacro ;; ADC A, E 1 Cycles:4
- lr35902@MainALU OP8C, 4, H_Read, Adc_, EmptyMacro ;; ADC A, H 1 Cycles:4
- lr35902@MainALU OP8D, 4, L_Read, Adc_, EmptyMacro ;; ADC A, L 1 Cycles:4
- lr35902@MainALU OP8E, 8, xHL_Read, Adc_, EmptyMacro ;; ADC A, xHL 1 Cycles:8
- lr35902@MainALU OP8F, 4, A_Read, Adc_, EmptyMacro ;; ADC A, A 1 Cycles:4
- lr35902@MainALU OPCE, 8, Imm8_Read, Adc_, EmptyMacro ;; ADC A, Imm8 2 Cycles:8
- lr35902@MainALU OP03, 8, BC_Read, IncWord_, BC_Write ;; INC BC Cycles:8
- lr35902@MainALU OP13, 8, DE_Read, IncWord_, DE_Write ;; INC DE Cycles:8
- lr35902@MainALU OP23, 8, HL_Read, IncWord_, HL_Write ;; INC HL Cycles:8
- lr35902@MainALU OP33, 8, SP_Read, IncWord_, SP_Write ;; INC SP Cycles:8
- lr35902@MainALU OP04, 4, B_Read, Inc_, B_Write ;; INC B 1 Cycles:4
- lr35902@MainALU OP14, 4, D_Read, Inc_, D_Write ;; INC D 1 Cycles:4
- lr35902@MainALU OP24, 4, H_Read, Inc_, H_Write ;; INC H 1 Cycles:4
- lr35902@MainALU OP34, 4, xHL_Read, Inc_, xHL_Write ;; INC xHL 1 Cycles:4
- lr35902@MainALU OP0C, 4, C_Read, Inc_, C_Write ;; INC C 1 Cycles:4
- lr35902@MainALU OP1C, 4, E_Read, Inc_, E_Write ;; INC E 1 Cycles:4
- lr35902@MainALU OP2C,12, L_Read, Inc_, L_Write ;; INC L 1 Cycles:12
- lr35902@MainALU OP3C, 4, A_Read, Inc_, A_Write ;; INC A 1 Cycles:4
- lr35902@MainALU OP90, 4, B_Read, Sub_, EmptyMacro ;; SUB A, B 1 Cycles:4
- lr35902@MainALU OP91, 4, C_Read, Sub_, EmptyMacro ;; SUB A, C 1 Cycles:4
- lr35902@MainALU OP92, 4, D_Read, Sub_, EmptyMacro ;; SUB A, D 1 Cycles:4
- lr35902@MainALU OP93, 4, E_Read, Sub_, EmptyMacro ;; SUB A, E 1 Cycles:4
- lr35902@MainALU OP94, 4, H_Read, Sub_, EmptyMacro ;; SUB A, H 1 Cycles:4
- lr35902@MainALU OP95, 4, L_Read, Sub_, EmptyMacro ;; SUB A, L 1 Cycles:4
- lr35902@MainALU OP96, 8, xHL_Read, Sub_, EmptyMacro ;; SUB A, xHL 1 Cycles:8
- lr35902@MainALU OP97, 4, A_Read, Sub_, EmptyMacro ;; SUB A, A 1 Cycles:4
- lr35902@MainALU OPD6, 8, Imm8_Read, Sub_, EmptyMacro ;; SUB A, Imm8 2 Cycles:8
- lr35902@MainALU OP98, 4, B_Read, Sbc_, EmptyMacro ;; SBC A, B 1 Cycles:4
- lr35902@MainALU OP99, 4, C_Read, Sbc_, EmptyMacro ;; SBC A, C 1 Cycles:4
- lr35902@MainALU OP9A, 4, D_Read, Sbc_, EmptyMacro ;; SBC A, D 1 Cycles:4
- lr35902@MainALU OP9B, 4, E_Read, Sbc_, EmptyMacro ;; SBC A, E 1 Cycles:4
- lr35902@MainALU OP9C, 4, H_Read, Sbc_, EmptyMacro ;; SBC A, H 1 Cycles:4
- lr35902@MainALU OP9D, 4, L_Read, Sbc_, EmptyMacro ;; SBC A, L 1 Cycles:4
- lr35902@MainALU OP9E, 8, xHL_Read, Sbc_, EmptyMacro ;; SBC A, xHL 1 Cycles:8
- lr35902@MainALU OP9F, 4, A_Read, Sbc_, EmptyMacro ;; SBC A, A 1 Cycles:4
- lr35902@MainALU OPDE, 8, Imm8_Read, Sbc_, EmptyMacro ;; SBC A, Imm8 2 Cycles:8
- lr35902@MainALU OP0B, 8, BC_Read, DecWord_, BC_Write ;; DEC BC Cycles:8
- lr35902@MainALU OP1B, 8, DE_Read, DecWord_, DE_Write ;; DEC DE Cycles:8
- lr35902@MainALU OP2B, 8, HL_Read, DecWord_, HL_Write ;; DEC HL Cycles:8
- lr35902@MainALU OP3B, 8, SP_Read, DecWord_, SP_Write ;; DEC SP Cycles:8
- lr35902@MainALU OP05, 4, B_Read, Dec_, B_Write ;; DEC B 1 Cycles:4
- lr35902@MainALU OP15, 4, D_Read, Dec_, D_Write ;; DEC D 1 Cycles:4
- lr35902@MainALU OP25, 4, H_Read, Dec_, H_Write ;; DEC H 1 Cycles:4
- lr35902@MainALU OP35, 4, xHL_Read, Dec_, xHL_Write ;; DEC xHL 1 Cycles:4
- lr35902@MainALU OP0D, 4, C_Read, Dec_, C_Write ;; DEC C 1 Cycles:4
- lr35902@MainALU OP1D, 4, E_Read, Dec_, E_Write ;; DEC E 1 Cycles:4
- lr35902@MainALU OP2D,12, L_Read, Dec_, L_Write ;; DEC L 1 Cycles:12
- lr35902@MainALU OP3D, 4, A_Read, Dec_, A_Write ;; DEC A 1 Cycles:4
- lr35902@MainALU OPA0, 4, B_Read, And_, EmptyMacro ;; AND A, B 1 Cycles:4
- lr35902@MainALU OPA1, 4, C_Read, And_, EmptyMacro ;; AND A, C 1 Cycles:4
- lr35902@MainALU OPA2, 4, D_Read, And_, EmptyMacro ;; AND A, D 1 Cycles:4
- lr35902@MainALU OPA3, 4, E_Read, And_, EmptyMacro ;; AND A, E 1 Cycles:4
- lr35902@MainALU OPA4, 4, H_Read, And_, EmptyMacro ;; AND A, H 1 Cycles:4
- lr35902@MainALU OPA5, 4, L_Read, And_, EmptyMacro ;; AND A, L 1 Cycles:4
- lr35902@MainALU OPA6, 8, xHL_Read, And_, EmptyMacro ;; AND A, xHL 1 Cycles:8
- lr35902@MainALU OPA7, 4, A_Read, And_, EmptyMacro ;; AND A, A 1 Cycles:4
- lr35902@MainALU OPE6, 8, Imm8_Read, And_, EmptyMacro ;; AND A, Imm8 2 Cycles:8
- lr35902@MainALU OPA8, 4, B_Read, Xor_, EmptyMacro ;; XOR A, B 1 Cycles:4
- lr35902@MainALU OPA9, 4, C_Read, Xor_, EmptyMacro ;; XOR A, C 1 Cycles:4
- lr35902@MainALU OPAA, 4, D_Read, Xor_, EmptyMacro ;; XOR A, D 1 Cycles:4
- lr35902@MainALU OPAB, 4, E_Read, Xor_, EmptyMacro ;; XOR A, E 1 Cycles:4
- lr35902@MainALU OPAC, 4, H_Read, Xor_, EmptyMacro ;; XOR A, H 1 Cycles:4
- lr35902@MainALU OPAD, 4, L_Read, Xor_, EmptyMacro ;; XOR A, L 1 Cycles:4
- lr35902@MainALU OPAE, 8, xHL_Read, Xor_, EmptyMacro ;; XOR A, xHL 1 Cycles:8
- lr35902@MainALU OPAF, 4, A_Read, Xor_, EmptyMacro ;; XOR A, A 1 Cycles:4
- lr35902@MainALU OPEE, 8, Imm8_Read, Xor_, EmptyMacro ;; XOR A, Imm8 2 Cycles:8
- lr35902@MainALU OPB0, 4, B_Read, Or_, EmptyMacro ;; OR A, B 1 Cycles:4
- lr35902@MainALU OPB1, 4, C_Read, Or_, EmptyMacro ;; OR A, C 1 Cycles:4
- lr35902@MainALU OPB2, 4, D_Read, Or_, EmptyMacro ;; OR A, D 1 Cycles:4
- lr35902@MainALU OPB3, 4, E_Read, Or_, EmptyMacro ;; OR A, E 1 Cycles:4
- lr35902@MainALU OPB4, 4, H_Read, Or_, EmptyMacro ;; OR A, H 1 Cycles:4
- lr35902@MainALU OPB5, 4, L_Read, Or_, EmptyMacro ;; OR A, L 1 Cycles:4
- lr35902@MainALU OPB6, 8, xHL_Read, Or_, EmptyMacro ;; OR A, xHL 1 Cycles:8
- lr35902@MainALU OPB7, 4, A_Read, Or_, EmptyMacro ;; OR A, A 1 Cycles:4
- lr35902@MainALU OPF6, 8, Imm8_Read, Or_, EmptyMacro ;; OR A, Imm8 2 Cycles:8
- lr35902@MainALU OPB8, 4, B_Read, Cmp_, EmptyMacro ;; CP A, B 1 Cycles:4
- lr35902@MainALU OPB9, 4, C_Read, Cmp_, EmptyMacro ;; CP A, C 1 Cycles:4
- lr35902@MainALU OPBA, 4, D_Read, Cmp_, EmptyMacro ;; CP A, D 1 Cycles:4
- lr35902@MainALU OPBB, 4, E_Read, Cmp_, EmptyMacro ;; CP A, E 1 Cycles:4
- lr35902@MainALU OPBC, 4, H_Read, Cmp_, EmptyMacro ;; CP A, H 1 Cycles:4
- lr35902@MainALU OPBD, 4, L_Read, Cmp_, EmptyMacro ;; CP A, L 1 Cycles:4
- lr35902@MainALU OPBE, 8, xHL_Read, Cmp_, EmptyMacro ;; CP A, xHL 1 Cycles:8
- lr35902@MainALU OPBF, 4, A_Read, Cmp_, EmptyMacro ;; CP A, A 1 Cycles:4
- lr35902@MainALU OPFE, 8, Imm8_Read, Cmp_, EmptyMacro ;; CP A, Imm8 2 Cycles:8
- lr35902@MainStack OPC1,12, OP_PopWord, EmptyMacro, BC_Write ;; POP BC 1 Cycles:12
- lr35902@MainStack OPD1,12, OP_PopWord, EmptyMacro, DE_Write ;; POP DE 1 Cycles:12
- lr35902@MainStack OPE1,12, OP_PopWord, EmptyMacro, HL_Write ;; POP HL 1 Cycles:12
- lr35902@MainStack OPF1,12, OP_PopWord, AF_StackPopStuff, AF_Write ;; POP AF 1 Cycles:12
- lr35902@MainStack OPC5,16, BC_Read, EmptyMacro, OP_PushWord ;; PUSH BC 1 Cycles:16
- lr35902@MainStack OPD5,16, DE_Read, EmptyMacro, OP_PushWord ;; PUSH DE 1 Cycles:16
- lr35902@MainStack OPE5,16, HL_Read, EmptyMacro, OP_PushWord ;; PUSH HL 1 Cycles:16
- lr35902@MainStack OPF5,16, AF_Read, AF_StackPushStuff, OP_PushWord ;; PUSH AF 1 Cycles:16
- lr35902@JP OPC2,Z_FLAG, Z_FLAG ;; JP NZ
- lr35902@JP OPD2,C_FLAG, C_FLAG ;; JP NC
- lr35902@JP OPCA,Z_FLAG, 0 ;; JP Z
- lr35902@JP OPDA,C_FLAG, 0 ;; JP C
- lr35902@JP OPC3,0, 1 ;; JP A16
- lr35902@Rst OPC7, 000H ;; RST 00H 1 Cycles:16
- lr35902@Rst OPD7, 010H ;; RST 10H 1 Cycles:16
- lr35902@Rst OPE7, 020H ;; RST 20H 1 Cycles:16
- lr35902@Rst OPF7, 030H ;; RST 30H 1 Cycles:16
- lr35902@Rst OPCF, 008H ;; RST 08H 1 Cycles:16
- lr35902@Rst OPDF, 018H ;; RST 18H 1 Cycles:16
- lr35902@Rst OPEF, 028H ;; RST 28H 1 Cycles:16
- lr35902@Rst OPFF, 038H ;; RST 38H 1 Cycles:16
- lr35902@CALL OPC4,Z_FLAG, Z_FLAG ;; CALL NZ
- lr35902@CALL OPD4,C_FLAG, C_FLAG ;; CALL NC
- lr35902@CALL OPCC,Z_FLAG, 0 ;; CALL Z
- lr35902@CALL OPDC,C_FLAG, 0 ;; CALL C
- lr35902@CALL OPCD,0, 1 ;; CALL
- lr35902@JR OP20,Z_FLAG, Z_FLAG ;; JR NZ
- lr35902@JR OP30,C_FLAG, C_FLAG ;; JR NC
- lr35902@JR OP28,Z_FLAG, 0 ;; JR Z
- lr35902@JR OP38,C_FLAG, 0 ;; JR C
- lr35902@JR OP18,0, 1 ;; JR R8
- lr35902@RET OPC0,Z_FLAG, Z_FLAG, 20 ;; RET NZ
- lr35902@RET OPD0,C_FLAG, C_FLAG, 20 ;; RET NC
- lr35902@RET OPC8,Z_FLAG, 0, 20 ;; RET Z
- lr35902@RET OPD8,C_FLAG, 0, 20 ;; RET C
- lr35902@RET OPC9,0, 1, 16 ;; RET
- lr35902@RETI OPD9,0, 1, 16 ;; RETI
- ;; MISC
- OPF8: ;; ------------------------------------------- LD HL SP+Imm8(sign8) 2 Cycles:12
- Imm8_Read
- ;; ext sign
- movsx eax, al
- movzx ecx, word[YG_GP+lr35902.SP]
- and eax, 0xFFFF
- lea edx, [ecx+eax]
- mov [YG_GP+lr35902.HL], dx ;; write back HL
- xor ecx, eax
- xor ecx, edx
- and cx, 0x0110 ;; C|H
- mov YG_PF_8, ch
- shl YG_PF_8, 4
- shl cl, 1
- or YG_PF_8, cl
- and YG_PF, (H_FLAG| C_FLAG)
- SetCyclesRetP 12
- OP76: ; Halt, not backup PC in my source code ^_^
- mov dword [YG_GP+lr35902.halt], 1
- SetCyclesAndRet 4
- OP10: ; Stop, Check CGB speed mode
- movzx eax, byte [YG_GP+lr35902.key1]
- test eax, 1
- je Stop_Skip
- xor eax, 0x80 ;; switch to "other" speed
- and eax, 0xFE ;; reset LSB see gb-programming-manual.pdf::2.6.2 CPU Operating Speed
- ;; for simplicity, I will not simulate the huge waste of time brought by handover.
- mov [YG_GP+lr35902.key1], al
- add YG_PC, 1 ;; skip one byte (should is 00)
- SetCyclesAndRet 0x80000004
- Stop_Skip:
- mov dword [YG_GP+lr35902.stop], 1
- add YG_PC, 1 ;; skip one byte (should is 00)
- SetCyclesAndRet 4
- OPF3: ; DI
- mov byte [YG_GP+lr35902.IME], 0
- SetCyclesAndRet 4
- OPFB: ; EI
- mov byte [YG_GP+lr35902.IME], 1
- SetCyclesAndRet 4
- OP07: ; RLCA
- rol byte [YG_GP+lr35902.A], 1
- setc YG_PF_8
- shl YG_PF_8, 4
- SetCyclesRetP 4
- OP17: ; RLA
- shr YG_PF_8, 5
- rcl byte [YG_GP+lr35902.A], 1
- setc YG_PF_8
- shl YG_PF_8, 4
- SetCyclesRetP 4
- OP0F: ; RRCA
- ror byte [YG_GP+lr35902.A], 1
- setc YG_PF_8
- shl YG_PF_8, 4
- SetCyclesRetP 4
- OP1F: ; RRA
- shr YG_PF_8, 5
- rcr byte [YG_GP+lr35902.A], 1
- setc YG_PF_8
- shl YG_PF_8, 4
- SetCyclesRetP 4
- OP27: ; BCD Adjust
- movzx eax, byte [YG_GP+lr35902.A]
- test YG_PF_8, N_FLAG
- jne DAS_Proc
- ;; DAA.
- ;; Check DAA-low
- test YG_PF, H_FLAG
- jne DAA_Low
- mov ecx, eax
- and ecx, 0x0F
- cmp ecx, 9
- jbe DAA_LowSkip
- DAA_Low:
- add eax, 6
- DAA_LowSkip:
- ;; Check DAA-High
- test YG_PF, C_FLAG
- jne DAA_High
- mov ecx, eax
- cmp ecx, 0x9F
- jbe DAA_HighSkip
- DAA_High:
- add eax, 0x60
- DAA_HighSkip:
- ;; Check Z, C
- and YG_PF, C_FLAG
- mov ecx, eax
- and ecx, 0x100
- shl ecx, 4
- or YG_PF_8, ch
- test al, al
- setz cl
- shl cl, 7
- or YG_PF_8, cl ;; z_flag done
- mov [YG_GP+lr35902.A], al
- SetCyclesRetP 4
- DAS_Proc:
- ;; DAS
- ;; Check DAS-low
- test YG_PF, H_FLAG
- je DAS_LowSkip
- sub eax, 6
- and eax, 0xFF
- DAS_LowSkip:
- ;; Check DAS-High
- test YG_PF, C_FLAG
- je DAS_HighSkip
- sub eax, 0x60
- DAS_HighSkip:
- ;; Check Z, C
- and YG_PF, C_FLAG
- mov ecx, eax
- and ecx, 0x100
- shl ecx, 4
- or YG_PF_8, ch
- test al, al
- setz cl
- shl cl, 7
- or YG_PF_8, cl ;; z_flag done
- or YG_PF_8, N_FLAG ;; n_flag done
- mov [YG_GP+lr35902.A], al
- SetCyclesRetP 4
- OP37: ; SCF
- and YG_PF, Z_FLAG
- or YG_PF, C_FLAG
- SetCyclesRetP 4
- OP2F: ; CPL
- not byte [YG_GP+lr35902.A]
- or YG_PF, N_FLAG
- or YG_PF, H_FLAG
- SetCyclesRetP 4
- OP3F: ; CCF
- and YG_PF, (Z_FLAG |C_FLAG)
- xor YG_PF, C_FLAG
- SetCyclesRetP 4
- OPE9:
- mov si, [YG_GP+lr35902.HL]
- SetCyclesAndRet 4
- OPCB: ;; DD Perfix(BITS) for Z80/lr35902
- Imm8_Read
- and eax, 255
- jmp dword [CBTAB+eax*4]
- ;; --------------------------------------------------------------
- ;; --------------------------------------------------------------
- ;; --------------------------------------------------------------
- ;; --------------------------------------------------------------
- ;; --------------------------------------------------------------
- ;; Bit Opcode DOne
- ;; --------------------------------------------------------------
- lr35902@MainALUExt CB00, 8, B_Read, RLC_, B_Write ;; RLC B 2 Cycles:8
- lr35902@MainALUExt CB01, 8, C_Read, RLC_, C_Write ;; RLC C 2 Cycles:8
- lr35902@MainALUExt CB02, 8, D_Read, RLC_, D_Write ;; RLC D 2 Cycles:8
- lr35902@MainALUExt CB03, 8, E_Read, RLC_, E_Write ;; RLC E 2 Cycles:8
- lr35902@MainALUExt CB04, 8, H_Read, RLC_, H_Write ;; RLC H 2 Cycles:8
- lr35902@MainALUExt CB05, 8, L_Read, RLC_, L_Write ;; RLC L 2 Cycles:8
- lr35902@MainALUExt CB06,16, xHL_Read, RLC_, xHL_Write ;; RLC xHL 2 Cycles:16
- lr35902@MainALUExt CB07, 8, A_Read, RLC_, A_Write ;; RLC A 2 Cycles:8
- lr35902@MainALUExt CB08, 8, B_Read, RRC_, B_Write ;; RRC B 2 Cycles:8
- lr35902@MainALUExt CB09, 8, C_Read, RRC_, C_Write ;; RRC C 2 Cycles:8
- lr35902@MainALUExt CB0A, 8, D_Read, RRC_, D_Write ;; RRC D 2 Cycles:8
- lr35902@MainALUExt CB0B, 8, E_Read, RRC_, E_Write ;; RRC E 2 Cycles:8
- lr35902@MainALUExt CB0C, 8, H_Read, RRC_, H_Write ;; RRC H 2 Cycles:8
- lr35902@MainALUExt CB0D, 8, L_Read, RRC_, L_Write ;; RRC L 2 Cycles:8
- lr35902@MainALUExt CB0E,16, xHL_Read, RRC_, xHL_Write ;; RRC xHL 2 Cycles:16
- lr35902@MainALUExt CB0F, 8, A_Read, RRC_, A_Write ;; RRC A 2 Cycles:8
- lr35902@MainALUExt CB10, 8, B_Read, RL_, B_Write ;; RL B 2 Cycles:8
- lr35902@MainALUExt CB11, 8, C_Read, RL_, C_Write ;; RL C 2 Cycles:8
- lr35902@MainALUExt CB12, 8, D_Read, RL_, D_Write ;; RL D 2 Cycles:8
- lr35902@MainALUExt CB13, 8, E_Read, RL_, E_Write ;; RL E 2 Cycles:8
- lr35902@MainALUExt CB14, 8, H_Read, RL_, H_Write ;; RL H 2 Cycles:8
- lr35902@MainALUExt CB15, 8, L_Read, RL_, L_Write ;; RL L 2 Cycles:8
- lr35902@MainALUExt CB16,16, xHL_Read, RL_, xHL_Write ;; RL xHL 2 Cycles:16
- lr35902@MainALUExt CB17, 8, A_Read, RL_, A_Write ;; RL A 2 Cycles:8
- lr35902@MainALUExt CB18, 8, B_Read, RR_, B_Write ;; RR B 2 Cycles:8
- lr35902@MainALUExt CB19, 8, C_Read, RR_, C_Write ;; RR C 2 Cycles:8
- lr35902@MainALUExt CB1A, 8, D_Read, RR_, D_Write ;; RR D 2 Cycles:8
- lr35902@MainALUExt CB1B, 8, E_Read, RR_, E_Write ;; RR E 2 Cycles:8
- lr35902@MainALUExt CB1C, 8, H_Read, RR_, H_Write ;; RR H 2 Cycles:8
- lr35902@MainALUExt CB1D, 8, L_Read, RR_, L_Write ;; RR L 2 Cycles:8
- lr35902@MainALUExt CB1E,16, xHL_Read, RR_, xHL_Write ;; RR xHL 2 Cycles:16
- lr35902@MainALUExt CB1F, 8, A_Read, RR_, A_Write ;; RR A 2 Cycles:8
- lr35902@MainALUExt CB20, 8, B_Read, RL_N_, B_Write ;; SLA B 2 Cycles:8
- lr35902@MainALUExt CB21, 8, C_Read, RL_N_, C_Write ;; SLA C 2 Cycles:8
- lr35902@MainALUExt CB22, 8, D_Read, RL_N_, D_Write ;; SLA D 2 Cycles:8
- lr35902@MainALUExt CB23, 8, E_Read, RL_N_, E_Write ;; SLA E 2 Cycles:8
- lr35902@MainALUExt CB24, 8, H_Read, RL_N_, H_Write ;; SLA H 2 Cycles:8
- lr35902@MainALUExt CB25, 8, L_Read, RL_N_, L_Write ;; SLA L 2 Cycles:8
- lr35902@MainALUExt CB26,16, xHL_Read, RL_N_, xHL_Write ;; SLA xHL 2 Cycles:16
- lr35902@MainALUExt CB27, 8, A_Read, RL_N_, A_Write ;; SLA A 2 Cycles:8
- lr35902@MainALUExt CB28, 8, B_Read, RRS_N_, B_Write ;; SRA B 2 Cycles:8
- lr35902@MainALUExt CB29, 8, C_Read, RRS_N_, C_Write ;; SRA C 2 Cycles:8
- lr35902@MainALUExt CB2A, 8, D_Read, RRS_N_, D_Write ;; SRA D 2 Cycles:8
- lr35902@MainALUExt CB2B, 8, E_Read, RRS_N_, E_Write ;; SRA E 2 Cycles:8
- lr35902@MainALUExt CB2C, 8, H_Read, RRS_N_, H_Write ;; SRA H 2 Cycles:8
- lr35902@MainALUExt CB2D, 8, L_Read, RRS_N_, L_Write ;; SRA L 2 Cycles:8
- lr35902@MainALUExt CB2E,16, xHL_Read, RRS_N_, xHL_Write ;; SRA xHL 2 Cycles:16
- lr35902@MainALUExt CB2F, 8, A_Read, RRS_N_, A_Write ;; SRA A 2 Cycles:8
- lr35902@MainALUExt CB30, 8, B_Read, SWAP_, B_Write ;; SWAP B 2 Cycles:8
- lr35902@MainALUExt CB31, 8, C_Read, SWAP_, C_Write ;; SWAP C 2 Cycles:8
- lr35902@MainALUExt CB32, 8, D_Read, SWAP_, D_Write ;; SWAP D 2 Cycles:8
- lr35902@MainALUExt CB33, 8, E_Read, SWAP_, E_Write ;; SWAP E 2 Cycles:8
- lr35902@MainALUExt CB34, 8, H_Read, SWAP_, H_Write ;; SWAP H 2 Cycles:8
- lr35902@MainALUExt CB35, 8, L_Read, SWAP_, L_Write ;; SWAP L 2 Cycles:8
- lr35902@MainALUExt CB36,16, xHL_Read, SWAP_, xHL_Write ;; SWAP xHL 2 Cycles:16
- lr35902@MainALUExt CB37, 8, A_Read, SWAP_, A_Write ;; SWAP A 2 Cycles:8
- lr35902@MainALUExt CB38, 8, B_Read, RR_N_, B_Write ;; SRL B 2 Cycles:8
- lr35902@MainALUExt CB39, 8, C_Read, RR_N_, C_Write ;; SRL C 2 Cycles:8
- lr35902@MainALUExt CB3A, 8, D_Read, RR_N_, D_Write ;; SRL D 2 Cycles:8
- lr35902@MainALUExt CB3B, 8, E_Read, RR_N_, E_Write ;; SRL E 2 Cycles:8
- lr35902@MainALUExt CB3C, 8, H_Read, RR_N_, H_Write ;; SRL H 2 Cycles:8
- lr35902@MainALUExt CB3D, 8, L_Read, RR_N_, L_Write ;; SRL L 2 Cycles:8
- lr35902@MainALUExt CB3E,16, xHL_Read, RR_N_, xHL_Write ;; SRL xHL 2 Cycles:16
- lr35902@MainALUExt CB3F, 8, A_Read, RR_N_, A_Write ;; SRL A 2 Cycles:8
- lr35902@TestBit CB40, 8, B_Read, 0 ;; BIT B, 0 Cycles:8
- lr35902@TestBit CB41, 8, C_Read, 0 ;; BIT C, 0 Cycles:8
- lr35902@TestBit CB42, 8, D_Read, 0 ;; BIT D, 0 Cycles:8
- lr35902@TestBit CB43, 8, E_Read, 0 ;; BIT E, 0 Cycles:8
- lr35902@TestBit CB44, 8, H_Read, 0 ;; BIT H, 0 Cycles:8
- lr35902@TestBit CB45, 8, L_Read, 0 ;; BIT L, 0 Cycles:8
- lr35902@TestBit CB46,16, xHL_Read, 0 ;; BIT xHL, 0 Cycles:16
- lr35902@TestBit CB47, 8, A_Read, 0 ;; BIT A, 0 Cycles:8
- lr35902@TestBit CB48, 8, B_Read, 1 ;; BIT B, 1 Cycles:8
- lr35902@TestBit CB49, 8, C_Read, 1 ;; BIT C, 1 Cycles:8
- lr35902@TestBit CB4A, 8, D_Read, 1 ;; BIT D, 1 Cycles:8
- lr35902@TestBit CB4B, 8, E_Read, 1 ;; BIT E, 1 Cycles:8
- lr35902@TestBit CB4C, 8, H_Read, 1 ;; BIT H, 1 Cycles:8
- lr35902@TestBit CB4D, 8, L_Read, 1 ;; BIT L, 1 Cycles:8
- lr35902@TestBit CB4E,16, xHL_Read, 1 ;; BIT xHL, 1 Cycles:16
- lr35902@TestBit CB4F, 8, A_Read, 1 ;; BIT A, 1 Cycles:8
- lr35902@TestBit CB50, 8, B_Read, 2 ;; BIT B, 2 Cycles:8
- lr35902@TestBit CB51, 8, C_Read, 2 ;; BIT C, 2 Cycles:8
- lr35902@TestBit CB52, 8, D_Read, 2 ;; BIT D, 2 Cycles:8
- lr35902@TestBit CB53, 8, E_Read, 2 ;; BIT E, 2 Cycles:8
- lr35902@TestBit CB54, 8, H_Read, 2 ;; BIT H, 2 Cycles:8
- lr35902@TestBit CB55, 8, L_Read, 2 ;; BIT L, 2 Cycles:8
- lr35902@TestBit CB56,16, xHL_Read, 2 ;; BIT xHL, 2 Cycles:16
- lr35902@TestBit CB57, 8, A_Read, 2 ;; BIT A, 2 Cycles:8
- lr35902@TestBit CB58, 8, B_Read, 3 ;; BIT B, 3 Cycles:8
- lr35902@TestBit CB59, 8, C_Read, 3 ;; BIT C, 3 Cycles:8
- lr35902@TestBit CB5A, 8, D_Read, 3 ;; BIT D, 3 Cycles:8
- lr35902@TestBit CB5B, 8, E_Read, 3 ;; BIT E, 3 Cycles:8
- lr35902@TestBit CB5C, 8, H_Read, 3 ;; BIT H, 3 Cycles:8
- lr35902@TestBit CB5D, 8, L_Read, 3 ;; BIT L, 3 Cycles:8
- lr35902@TestBit CB5E,16, xHL_Read, 3 ;; BIT xHL, 3 Cycles:16
- lr35902@TestBit CB5F, 8, A_Read, 3 ;; BIT A, 3 Cycles:8
- lr35902@TestBit CB60, 8, B_Read, 4 ;; BIT B, 4 Cycles:8
- lr35902@TestBit CB61, 8, C_Read, 4 ;; BIT C, 4 Cycles:8
- lr35902@TestBit CB62, 8, D_Read, 4 ;; BIT D, 4 Cycles:8
- lr35902@TestBit CB63, 8, E_Read, 4 ;; BIT E, 4 Cycles:8
- lr35902@TestBit CB64, 8, H_Read, 4 ;; BIT H, 4 Cycles:8
- lr35902@TestBit CB65, 8, L_Read, 4 ;; BIT L, 4 Cycles:8
- lr35902@TestBit CB66,16, xHL_Read, 4 ;; BITxHLD, 4 Cycles:16
- lr35902@TestBit CB67, 8, A_Read, 4 ;; BIT A, 4 Cycles:8
- lr35902@TestBit CB68, 8, B_Read, 5 ;; BIT B, 5 Cycles:8
- lr35902@TestBit CB69, 8, C_Read, 5 ;; BIT C, 5 Cycles:8
- lr35902@TestBit CB6A, 8, D_Read, 5 ;; BIT D, 5 Cycles:8
- lr35902@TestBit CB6B, 8, E_Read, 5 ;; BIT E, 5 Cycles:8
- lr35902@TestBit CB6C, 8, H_Read, 5 ;; BIT H, 5 Cycles:8
- lr35902@TestBit CB6D, 8, L_Read, 5 ;; BIT L, 5 Cycles:8
- lr35902@TestBit CB6E,16, xHL_Read, 5 ;; BIT xHL, 5 Cycles:16
- lr35902@TestBit CB6F, 8, A_Read, 5 ;; BIT A, 5 Cycles:8
- lr35902@TestBit CB70, 8, B_Read, 6 ;; BIT B, 6 Cycles:8
- lr35902@TestBit CB71, 8, C_Read, 6 ;; BIT C, 6 Cycles:8
- lr35902@TestBit CB72, 8, D_Read, 6 ;; BIT D, 6 Cycles:8
- lr35902@TestBit CB73, 8, E_Read, 6 ;; BIT E, 6 Cycles:8
- lr35902@TestBit CB74, 8, H_Read, 6 ;; BIT H, 6 Cycles:8
- lr35902@TestBit CB75, 8, L_Read, 6 ;; BIT L, 6 Cycles:8
- lr35902@TestBit CB76,16, xHL_Read, 6 ;; BIT xHL, 6 Cycles:16
- lr35902@TestBit CB77, 8, A_Read, 6 ;; BIT A, 6 Cycles:8
- lr35902@TestBit CB78, 8, B_Read, 7 ;; BIT B, 7 Cycles:8
- lr35902@TestBit CB79, 8, C_Read, 7 ;; BIT C, 7 Cycles:8
- lr35902@TestBit CB7A, 8, D_Read, 7 ;; BIT D, 7 Cycles:8
- lr35902@TestBit CB7B, 8, E_Read, 7 ;; BIT E, 7 Cycles:8
- lr35902@TestBit CB7C, 8, H_Read, 7 ;; BIT H, 7 Cycles:8
- lr35902@TestBit CB7D, 8, L_Read, 7 ;; BIT L, 7 Cycles:8
- lr35902@TestBit CB7E,16, xHL_Read, 7 ;; BIT xHL, 7 Cycles:16
- lr35902@TestBit CB7F, 8, A_Read, 7 ;; BIT A, 7 Cycles:8
- lr35902@ResBit CB80, 8, B_Read, 0, B_Write ;; RES B, 0 Cycles:8
- lr35902@ResBit CB81, 8, C_Read, 0, C_Write ;; RES C, 0 Cycles:8
- lr35902@ResBit CB82, 8, D_Read, 0, D_Write ;; RES D, 0 Cycles:8
- lr35902@ResBit CB83, 8, E_Read, 0, E_Write ;; RES E, 0 Cycles:8
- lr35902@ResBit CB84, 8, H_Read, 0, H_Write ;; RES H, 0 Cycles:8
- lr35902@ResBit CB85, 8, L_Read, 0, L_Write ;; RES L, 0 Cycles:8
- lr35902@ResBit CB86,16, xHL_Read, 0, xHL_Write ;; RES xHL, 0 Cycles:16
- lr35902@ResBit CB87, 8, A_Read, 0, A_Write ;; RES A, 0 Cycles:8
- lr35902@ResBit CB88, 8, B_Read, 1, B_Write ;; RES B, 1 Cycles:8
- lr35902@ResBit CB89, 8, C_Read, 1, C_Write ;; RES C, 1 Cycles:8
- lr35902@ResBit CB8A, 8, D_Read, 1, D_Write ;; RES D, 1 Cycles:8
- lr35902@ResBit CB8B, 8, E_Read, 1, E_Write ;; RES E, 1 Cycles:8
- lr35902@ResBit CB8C, 8, H_Read, 1, H_Write ;; RES H, 1 Cycles:8
- lr35902@ResBit CB8D, 8, L_Read, 1, L_Write ;; RES L, 1 Cycles:8
- lr35902@ResBit CB8E,16, xHL_Read, 1, xHL_Write ;; RES xHL, 1 Cycles:16
- lr35902@ResBit CB8F, 8, A_Read, 1, A_Write ;; RES A, 1 Cycles:8
- lr35902@ResBit CB90, 8, B_Read, 2, B_Write ;; RES B, 2 Cycles:8
- lr35902@ResBit CB91, 8, C_Read, 2, C_Write ;; RES C, 2 Cycles:8
- lr35902@ResBit CB92, 8, D_Read, 2, D_Write ;; RES D, 2 Cycles:8
- lr35902@ResBit CB93, 8, E_Read, 2, E_Write ;; RES E, 2 Cycles:8
- lr35902@ResBit CB94, 8, H_Read, 2, H_Write ;; RES H, 2 Cycles:8
- lr35902@ResBit CB95, 8, L_Read, 2, L_Write ;; RES L, 2 Cycles:8
- lr35902@ResBit CB96,16, xHL_Read, 2, xHL_Write ;; RES xHL, 2 Cycles:16
- lr35902@ResBit CB97, 8, A_Read, 2, A_Write ;; RES A, 2 Cycles:8
- lr35902@ResBit CB98, 8, B_Read, 3, B_Write ;; RES B, 3 Cycles:8
- lr35902@ResBit CB99, 8, C_Read, 3, C_Write ;; RES C, 3 Cycles:8
- lr35902@ResBit CB9A, 8, D_Read, 3, D_Write ;; RES D, 3 Cycles:8
- lr35902@ResBit CB9B, 8, E_Read, 3, E_Write ;; RES E, 3 Cycles:8
- lr35902@ResBit CB9C, 8, H_Read, 3, H_Write ;; RES H, 3 Cycles:8
- lr35902@ResBit CB9D, 8, L_Read, 3, L_Write ;; RES L, 3 Cycles:8
- lr35902@ResBit CB9E,16, xHL_Read, 3, xHL_Write ;; RES xHL, 3 Cycles:16
- lr35902@ResBit CB9F, 8, A_Read, 3, A_Write ;; RES A, 3 Cycles:8
- lr35902@ResBit CBA0, 8, B_Read, 4, B_Write ;; RES B, 4 Cycles:8
- lr35902@ResBit CBA1, 8, C_Read, 4, C_Write ;; RES C, 4 Cycles:8
- lr35902@ResBit CBA2, 8, D_Read, 4, D_Write ;; RES D, 4 Cycles:8
- lr35902@ResBit CBA3, 8, E_Read, 4, E_Write ;; RES E, 4 Cycles:8
- lr35902@ResBit CBA4, 8, H_Read, 4, H_Write ;; RES H, 4 Cycles:8
- lr35902@ResBit CBA5, 8, L_Read, 4, L_Write ;; RES L, 4 Cycles:8
- lr35902@ResBit CBA6,16, xHL_Read, 4, xHL_Write ;; RES xHL, 4 Cycles:16
- lr35902@ResBit CBA7, 8, A_Read, 4, A_Write ;; RES A, 4 Cycles:8
- lr35902@ResBit CBA8, 8, B_Read, 5, B_Write ;; RES B, 5 Cycles:8
- lr35902@ResBit CBA9, 8, C_Read, 5, C_Write ;; RES C, 5 Cycles:8
- lr35902@ResBit CBAA, 8, D_Read, 5, D_Write ;; RES D, 5 Cycles:8
- lr35902@ResBit CBAB, 8, E_Read, 5, E_Write ;; RES E, 5 Cycles:8
- lr35902@ResBit CBAC, 8, H_Read, 5, H_Write ;; RES H, 5 Cycles:8
- lr35902@ResBit CBAD, 8, L_Read, 5, L_Write ;; RES L, 5 Cycles:8
- lr35902@ResBit CBAE,16, xHL_Read, 5, xHL_Write ;; RES xHL, 5 Cycles:16
- lr35902@ResBit CBAF, 8, A_Read, 5, A_Write ;; RES A, 5 Cycles:8
- lr35902@ResBit CBB0, 8, B_Read, 6, B_Write ;; RES B, 6 Cycles:8
- lr35902@ResBit CBB1, 8, C_Read, 6, C_Write ;; RES C, 6 Cycles:8
- lr35902@ResBit CBB2, 8, D_Read, 6, D_Write ;; RES D, 6 Cycles:8
- lr35902@ResBit CBB3, 8, E_Read, 6, E_Write ;; RES E, 6 Cycles:8
- lr35902@ResBit CBB4, 8, H_Read, 6, H_Write ;; RES H, 6 Cycles:8
- lr35902@ResBit CBB5, 8, L_Read, 6, L_Write ;; RES L, 6 Cycles:8
- lr35902@ResBit CBB6,16, xHL_Read, 6, xHL_Write ;; RES xHL, 6 Cycles:16
- lr35902@ResBit CBB7, 8, A_Read, 6, A_Write ;; RES A, 6 Cycles:8
- lr35902@ResBit CBB8, 8, B_Read, 7, B_Write ;; RES B, 7 Cycles:8
- lr35902@ResBit CBB9, 8, C_Read, 7, C_Write ;; RES C, 7 Cycles:8
- lr35902@ResBit CBBA, 8, D_Read, 7, D_Write ;; RES D, 7 Cycles:8
- lr35902@ResBit CBBB, 8, E_Read, 7, E_Write ;; RES E, 7 Cycles:8
- lr35902@ResBit CBBC, 8, H_Read, 7, H_Write ;; RES H, 7 Cycles:8
- lr35902@ResBit CBBD, 8, L_Read, 7, L_Write ;; RES L, 7 Cycles:8
- lr35902@ResBit CBBE,16, xHL_Read, 7, xHL_Write ;; RES xHL, 7 Cycles:16
- lr35902@ResBit CBBF, 8, A_Read, 7, A_Write ;; RES A, 7 Cycles:8
- lr35902@SetBit CBC0, 8, B_Read, 0, B_Write ;; SET B, 0 Cycles:8
- lr35902@SetBit CBC1, 8, C_Read, 0, C_Write ;; SET C, 0 Cycles:8
- lr35902@SetBit CBC2, 8, D_Read, 0, D_Write ;; SET D, 0 Cycles:8
- lr35902@SetBit CBC3, 8, E_Read, 0, E_Write ;; SET E, 0 Cycles:8
- lr35902@SetBit CBC4, 8, H_Read, 0, H_Write ;; SET H, 0 Cycles:8
- lr35902@SetBit CBC5, 8, L_Read, 0, L_Write ;; SET L, 0 Cycles:8
- lr35902@SetBit CBC6,16, xHL_Read, 0, xHL_Write ;; SET xHL, 0 Cycles:16
- lr35902@SetBit CBC7, 8, A_Read, 0, A_Write ;; SET A, 0 Cycles:8
- lr35902@SetBit CBC8, 8, B_Read, 1, B_Write ;; SET B, 1 Cycles:8
- lr35902@SetBit CBC9, 8, C_Read, 1, C_Write ;; SET C, 1 Cycles:8
- lr35902@SetBit CBCA, 8, D_Read, 1, D_Write ;; SET D, 1 Cycles:8
- lr35902@SetBit CBCB, 8, E_Read, 1, E_Write ;; SET E, 1 Cycles:8
- lr35902@SetBit CBCC, 8, H_Read, 1, H_Write ;; SET H, 1 Cycles:8
- lr35902@SetBit CBCD, 8, L_Read, 1, L_Write ;; SET L, 1 Cycles:8
- lr35902@SetBit CBCE,16, xHL_Read, 1, xHL_Write ;; SET xHL, 1 Cycles:16
- lr35902@SetBit CBCF, 8, A_Read, 1, A_Write ;; SET A, 1 Cycles:8
- lr35902@SetBit CBD0, 8, B_Read, 2, B_Write ;; SET B, 2 Cycles:8
- lr35902@SetBit CBD1, 8, C_Read, 2, C_Write ;; SET C, 2 Cycles:8
- lr35902@SetBit CBD2, 8, D_Read, 2, D_Write ;; SET D, 2 Cycles:8
- lr35902@SetBit CBD3, 8, E_Read, 2, E_Write ;; SET E, 2 Cycles:8
- lr35902@SetBit CBD4, 8, H_Read, 2, H_Write ;; SET H, 2 Cycles:8
- lr35902@SetBit CBD5, 8, L_Read, 2, L_Write ;; SET L, 2 Cycles:8
- lr35902@SetBit CBD6,16, xHL_Read, 2, xHL_Write ;; SET xHL, 2 Cycles:16
- lr35902@SetBit CBD7, 8, A_Read, 2, A_Write ;; SET A, 2 Cycles:8
- lr35902@SetBit CBD8, 8, B_Read, 3, B_Write ;; SET B, 3 Cycles:8
- lr35902@SetBit CBD9, 8, C_Read, 3, C_Write ;; SET C, 3 Cycles:8
- lr35902@SetBit CBDA, 8, D_Read, 3, D_Write ;; SET D, 3 Cycles:8
- lr35902@SetBit CBDB, 8, E_Read, 3, E_Write ;; SET E, 3 Cycles:8
- lr35902@SetBit CBDC, 8, H_Read, 3, H_Write ;; SET H, 3 Cycles:8
- lr35902@SetBit CBDD, 8, L_Read, 3, L_Write ;; SET L, 3 Cycles:8
- lr35902@SetBit CBDE,16, xHL_Read, 3, xHL_Write ;; SET xHL, 3 Cycles:16
- lr35902@SetBit CBDF, 8, A_Read, 3, A_Write ;; SET A, 3 Cycles:8
- lr35902@SetBit CBE0, 8, B_Read, 4, B_Write ;; SET B, 4 Cycles:8
- lr35902@SetBit CBE1, 8, C_Read, 4, C_Write ;; SET C, 4 Cycles:8
- lr35902@SetBit CBE2, 8, D_Read, 4, D_Write ;; SET D, 4 Cycles:8
- lr35902@SetBit CBE3, 8, E_Read, 4, E_Write ;; SET E, 4 Cycles:8
- lr35902@SetBit CBE4, 8, H_Read, 4, H_Write ;; SET H, 4 Cycles:8
- lr35902@SetBit CBE5, 8, L_Read, 4, L_Write ;; SET L, 4 Cycles:8
- lr35902@SetBit CBE6,16, xHL_Read, 4, xHL_Write ;; SET xHL, 4 Cycles:16
- lr35902@SetBit CBE7, 8, A_Read, 4, A_Write ;; SET A, 4 Cycles:8
- lr35902@SetBit CBE8, 8, B_Read, 5, B_Write ;; SET B, 5 Cycles:8
- lr35902@SetBit CBE9, 8, C_Read, 5, C_Write ;; SET C, 5 Cycles:8
- lr35902@SetBit CBEA, 8, D_Read, 5, D_Write ;; SET D, 5 Cycles:8
- lr35902@SetBit CBEB, 8, E_Read, 5, E_Write ;; SET E, 5 Cycles:8
- lr35902@SetBit CBEC, 8, H_Read, 5, H_Write ;; SET H, 5 Cycles:8
- lr35902@SetBit CBED, 8, L_Read, 5, L_Write ;; SET L, 5 Cycles:8
- lr35902@SetBit CBEE,16, xHL_Read, 5, xHL_Write ;; SET xHL, 5 Cycles:16
- lr35902@SetBit CBEF, 8, A_Read, 5, A_Write ;; SET A, 5 Cycles:8
- lr35902@SetBit CBF0, 8, B_Read, 6, B_Write ;; SET B, 6 Cycles:8
- lr35902@SetBit CBF1, 8, C_Read, 6, C_Write ;; SET C, 6 Cycles:8
- lr35902@SetBit CBF2, 8, D_Read, 6, D_Write ;; SET D, 6 Cycles:8
- lr35902@SetBit CBF3, 8, E_Read, 6, E_Write ;; SET E, 6 Cycles:8
- lr35902@SetBit CBF4, 8, H_Read, 6, H_Write ;; SET H, 6 Cycles:8
- lr35902@SetBit CBF5, 8, L_Read, 6, L_Write ;; SET L, 6 Cycles:8
- lr35902@SetBit CBF6,16, xHL_Read, 6, xHL_Write ;; SET xHL, 6 Cycles:16
- lr35902@SetBit CBF7, 8, A_Read, 6, A_Write ;; SET A, 6 Cycles:8
- lr35902@SetBit CBF8, 8, B_Read, 7, B_Write ;; SET B, 7 Cycles:8
- lr35902@SetBit CBF9, 8, C_Read, 7, C_Write ;; SET C, 7 Cycles:8
- lr35902@SetBit CBFA, 8, D_Read, 7, D_Write ;; SET D, 7 Cycles:8
- lr35902@SetBit CBFB, 8, E_Read, 7, E_Write ;; SET E, 7 Cycles:8
- lr35902@SetBit CBFC, 8, H_Read, 7, H_Write ;; SET H, 7 Cycles:8
- lr35902@SetBit CBFD, 8, L_Read, 7, L_Write ;; SET L, 7 Cycles:8
- lr35902@SetBit CBFE,16, xHL_Read, 7, xHL_Write ;; SET xHL, 7 Cycles:16
- lr35902@SetBit CBFF, 8, A_Read, 7, A_Write ;; SET A, 7 Cycles:8
- ;; --------------------------------------------------------------
- ;; --------------------------------------------------------------
- ;; --------------------------------------------------------------
- ;; --------------------------------------------------------------
- ;; --------------------------------------------------------------
- ;; Ub Code for lr35902
- ;; --------------------------------------------------------------
- OPDD: ;; DD Perfix(IX) for Z80
- OPFD: ;; FD Perfix(IY) for Z80
- OPED: ;; ED Perfix(EXTD) for Z80
- OPD3: ;; out (*),a for Z80
- OPDB: ;; in a,(*) for Z80
- OPE3: ;; ex (sp),hl for Z80
- OPE4: ;; call po,** for Z80
- OPEB: ;; ex de,hl for Z80
- OPEC: ;; call pe,** for Z80
- OPF4: ;; call p,** for Z80
- OPFC: ;; call m,** for Z80
- int 3
- OP00: ;; NOP
- mov [YG_GP+lr35902.PC], si
- mov eax, 4
- V_EXIT:
- mov dword [YG_GP+lr35902._backup], 0
- pop esi
- pop edi
- pop ebx
- ret
- align 16
- OPTAB dd OP00, OP01, OP02, OP03, OP04, OP05, OP06, OP07, OP08, OP09, OP0A, OP0B, OP0C, OP0D, OP0E, OP0F,\
- OP10, OP11, OP12, OP13, OP14, OP15, OP16, OP17, OP18, OP19, OP1A, OP1B, OP1C, OP1D, OP1E, OP1F,\
- OP20, OP21, OP22, OP23, OP24, OP25, OP26, OP27, OP28, OP29, OP2A, OP2B, OP2C, OP2D, OP2E, OP2F,\
- OP30, OP31, OP32, OP33, OP34, OP35, OP36, OP37, OP38, OP39, OP3A, OP3B, OP3C, OP3D, OP3E, OP3F,\
- OP40, OP41, OP42, OP43, OP44, OP45, OP46, OP47, OP48, OP49, OP4A, OP4B, OP4C, OP4D, OP4E, OP4F,\
- OP50, OP51, OP52, OP53, OP54, OP55, OP56, OP57, OP58, OP59, OP5A, OP5B, OP5C, OP5D, OP5E, OP5F,\
- OP60, OP61, OP62, OP63, OP64, OP65, OP66, OP67, OP68, OP69, OP6A, OP6B, OP6C, OP6D, OP6E, OP6F,\
- OP70, OP71, OP72, OP73, OP74, OP75, OP76, OP77, OP78, OP79, OP7A, OP7B, OP7C, OP7D, OP7E, OP7F,\
- OP80, OP81, OP82, OP83, OP84, OP85, OP86, OP87, OP88, OP89, OP8A, OP8B, OP8C, OP8D, OP8E, OP8F,\
- OP90, OP91, OP92, OP93, OP94, OP95, OP96, OP97, OP98, OP99, OP9A, OP9B, OP9C, OP9D, OP9E, OP9F,\
- OPA0, OPA1, OPA2, OPA3, OPA4, OPA5, OPA6, OPA7, OPA8, OPA9, OPAA, OPAB, OPAC, OPAD, OPAE, OPAF,\
- OPB0, OPB1, OPB2, OPB3, OPB4, OPB5, OPB6, OPB7, OPB8, OPB9, OPBA, OPBB, OPBC, OPBD, OPBE, OPBF,\
- OPC0, OPC1, OPC2, OPC3, OPC4, OPC5, OPC6, OPC7, OPC8, OPC9, OPCA, OPCB, OPCC, OPCD, OPCE, OPCF,\
- OPD0, OPD1, OPD2, OPD3, OPD4, OPD5, OPD6, OPD7, OPD8, OPD9, OPDA, OPDB, OPDC, OPDD, OPDE, OPDF,\
- OPE0, OPE1, OPE2, OPE3, OPE4, OPE5, OPE6, OPE7, OPE8, OPE9, OPEA, OPEB, OPEC, OPED, OPEE, OPEF,\
- OPF0, OPF1, OPF2, OPF3, OPF4, OPF5, OPF6, OPF7, OPF8, OPF9, OPFA, OPFB, OPFC, OPFD, OPFE, OPFF
- CBTAB dd CB00, CB01, CB02, CB03, CB04, CB05, CB06, CB07, CB08, CB09, CB0A, CB0B, CB0C, CB0D, CB0E, CB0F,\
- CB10, CB11, CB12, CB13, CB14, CB15, CB16, CB17, CB18, CB19, CB1A, CB1B, CB1C, CB1D, CB1E, CB1F,\
- CB20, CB21, CB22, CB23, CB24, CB25, CB26, CB27, CB28, CB29, CB2A, CB2B, CB2C, CB2D, CB2E, CB2F,\
- CB30, CB31, CB32, CB33, CB34, CB35, CB36, CB37, CB38, CB39, CB3A, CB3B, CB3C, CB3D, CB3E, CB3F,\
- CB40, CB41, CB42, CB43, CB44, CB45, CB46, CB47, CB48, CB49, CB4A, CB4B, CB4C, CB4D, CB4E, CB4F,\
- CB50, CB51, CB52, CB53, CB54, CB55, CB56, CB57, CB58, CB59, CB5A, CB5B, CB5C, CB5D, CB5E, CB5F,\
- CB60, CB61, CB62, CB63, CB64, CB65, CB66, CB67, CB68, CB69, CB6A, CB6B, CB6C, CB6D, CB6E, CB6F,\
- CB70, CB71, CB72, CB73, CB74, CB75, CB76, CB77, CB78, CB79, CB7A, CB7B, CB7C, CB7D, CB7E, CB7F,\
- CB80, CB81, CB82, CB83, CB84, CB85, CB86, CB87, CB88, CB89, CB8A, CB8B, CB8C, CB8D, CB8E, CB8F,\
- CB90, CB91, CB92, CB93, CB94, CB95, CB96, CB97, CB98, CB99, CB9A, CB9B, CB9C, CB9D, CB9E, CB9F,\
- CBA0, CBA1, CBA2, CBA3, CBA4, CBA5, CBA6, CBA7, CBA8, CBA9, CBAA, CBAB, CBAC, CBAD, CBAE, CBAF,\
- CBB0, CBB1, CBB2, CBB3, CBB4, CBB5, CBB6, CBB7, CBB8, CBB9, CBBA, CBBB, CBBC, CBBD, CBBE, CBBF,\
- CBC0, CBC1, CBC2, CBC3, CBC4, CBC5, CBC6, CBC7, CBC8, CBC9, CBCA, CBCB, CBCC, CBCD, CBCE, CBCF,\
- CBD0, CBD1, CBD2, CBD3, CBD4, CBD5, CBD6, CBD7, CBD8, CBD9, CBDA, CBDB, CBDC, CBDD, CBDE, CBDF,\
- CBE0, CBE1, CBE2, CBE3, CBE4, CBE5, CBE6, CBE7, CBE8, CBE9, CBEA, CBEB, CBEC, CBED, CBEE, CBEF,\
- CBF0, CBF1, CBF2, CBF3, CBF4, CBF5, CBF6, CBF7, CBF8, CBF9, CBFA, CBFB, CBFC, CBFD, CBFE, CBFF
- /* nintendo gameboy
- * https://en.wikipedia.org/wiki/Game_Boy
- *
- * Copyright (C) 2018 moecmks
- * This file is part of KS3578.
- *
- * do What The Fuck you want to Public License
- *
- * Version 1.0, March 2000
- * Copyright (C) 2000 Banlu Kemiyatorn (]d).
- * 136 Nives 7 Jangwattana 14 Laksi Bangkok
- * Everyone is permitted to copy and distribute verbatim copies
- * of this license document, but changing it is not allowed.
- *
- * Ok, the purpose of this license is simple
- * and you just
- *
- * DO WHAT THE FUCK YOU WANT TO.
- */
- #include "gameboy.h"
- #include "internal.h"
- void controller_setupdate_ (struct controller *ctl, void (*update)
- (struct controller *,
- void *,
- struct controller_pad *, /* self */
- struct controller_pad * /* host edge */), void *obj);
- void ppu_setupdate_ (struct ppu *ppu, void (*update)
- (struct ppu *,
- void *,
- struct ppu_framebuffer *), void *obj);
- static
- void controller_hostdrv_s (struct gameboy *gb, void *controller_drvobj,
- struct controller_pad *gb_pad, /* gb-self for recv joypadbuffer */
- struct controller_pad *hostedge /* host-edge 1?pulse gen:nodone */)
- {
- printf ("%s:%s please set controller_hostdrv\n", __FILE__, __LINE__);
- assert (0);
- }
- static
- void display_hostdrv_s (struct gameboy *gb,
- void *display_drvobj,
- struct ppu_framebuffer *fmebuf)
- {
- printf ("%s:%s please set display_hostdrv\n", __FILE__, __LINE__);
- assert (0);
- }
- static
- void controller_hostdrv_route (struct controller *ctl, void *obj, struct controller_pad *gb_infos, struct controller_pad *host_infos) {
- ctl->gb->controller_hostdrv (ctl->gb, obj, gb_infos, host_infos);
- }
- static
- void lcdvideo_hostdrv_route (struct ppu *ppu, void *obj, struct ppu_framebuffer *fbuf) {
- ppu->gb->display_hostdrv (ppu->gb, obj, fbuf);
- }
- void gameboy_controller_setupdate (struct gameboy *gb, void (*controller_hostdrv)
- (struct gameboy *,
- void *,
- struct controller_pad *, /* gb-self for recv joypadbuffer */
- struct controller_pad * /* host-edge */), void *obj)
- {
- gb->controller_hostdrv = controller_hostdrv;
- gb->controller_drvobj = obj;
- controller_setupdate_ (gb->joypad, controller_hostdrv_route, obj);
- }
- void gameboy_lcdvideo_setupdate (struct gameboy *gb, void (*lcdvideo_hostdrv)
- (struct gameboy *,
- void *,
- struct ppu_framebuffer *), void *obj)
- {
- gb->display_hostdrv = lcdvideo_hostdrv;
- gb->display_drvobj = obj;
- ppu_setupdate_ (gb->lh5028, lcdvideo_hostdrv_route, obj);
- }
- extern
- ks_int ks_callc
- cpu_optick (struct cpu *cpu_);
- ks_finline
- ks_void
- internaldev_clks (struct gameboy *gb, ks_double clks) {
- /* update internal device divider */
- gb->cpu_clks_total += clks;
- gb->cpu_clks_divider += clks;
- gb->cpu_clks_ppu += clks;
- gb->cpu_clks_timer += clks;
- gb->cpu_clks_joypad += clks;
- gb->cpu_clks_apu += clks;
- gb->cpu_clks_cart += clks;
- gb->cpu_clks_serial += clks;
- /* update device */
- gb->divider->clks (gb->divider);
- gb->lh5028->clks (gb->lh5028);
- gb->timer->clks (gb->timer);
- gb->joypad->clks (gb->joypad);
- gb->apu->clks (gb->apu);
- gb->cart->clks (gb->cart);
- gb->serial->clks (gb->serial);
- }
- void /* gameboy's main function */
- gameboy_run_ms (struct gameboy *gb, ks_double exec_ms /*neg disable */) {
- ks_int opclks_;
- ks_double opclks;
- ks_double clks_b;
- ks_bool fadjust;
- ks_uint8 imask;
- ks_double cpu_clks;
- ks_double op_ms;
- ks_double oc_ms;
- static ks_uint16 PC_cac;
- oc_ms = gb->deflect_ms;
- gb->deflect_ms += exec_ms;
- if (ks_cmp0_double (& gb->deflect_ms) == KS_CMP_ABOVE) {
- op_ms = exec_ms - oc_ms;
- gb->deflect_ms = 0.0;
- clks_b = op_ms * gb->mach_tools->clk_ms;
- cpu_clks = clks_b;
- /* device done loop */
- while (ks_true) {
- /* check remain clks */
- if (ks_cmp0_double (& cpu_clks) != KS_CMP_ABOVE) {
- /* cycles burning out **/
- gb->deflect_ms = cpu_clks / gb->mach_tools->clk_ms;
- break ;
- } else {
- /* remain clks to run, first check dma run. */
- if (ks_cmp0_double (& gb->cpu_clks_dma) == KS_CMP_ABOVE) {
- /* DMA active, exec nop instruction, clks:4 */
- gb->cpu_clks_dma -= 4.0;
- cpu_clks -= 4.0; /* XXX:stride clks for next DMA. */
- internaldev_clks (gb, 4.0);
- continue ;
- } else if (gb->lh5028->hdma_gen != ks_false && !gb->lh5028->hdma_r16) {
- gb->lh5028->hdma_gen = ks_false;
- gb->lh5028->reg55_HDMA5 |= 0x80; /* Set unactive */
- }
- /* check stop, about stop opcode
- see http://gbdev.gg8.se/wiki/articles/Joypad_Input
- http://www.devrs.com/gb/files/faqs.html#STOP */
- if (gb->lr35902->stop != ks_false) {
- /* XXX: in fact not close APU. */
- cpu_clks -= 4.0;
- gb->cpu_clks_joypad += 4.0;
- gb->joypad->clks (gb->joypad);
- continue;
- }
- /* check halt, about halt opcode
- see. http://www.devrs.com/gb/files/faqs.html#HALT */
- if (gb->lr35902->halt != ks_false/* && gb->lr35902->IME != 0*/) {
- cpu_clks -= 4.0;
- internaldev_clks (gb, 4.0);
- fadjust = ks_false;
- if ((gb->reg0F_IF & gb->regFF_IE & 0x1F) != 0) {
- gb->lr35902->halt = ks_false; /* close halt*/
- if (gb->lr35902->IME == 0) {
- /* halt bug gen, read next byte twice */
- gb->lr35902->_backup = 0;
- }
- }
- goto check_interrupt;
- }
- /* run cpu opcode */
- // if (gb->lr35902->PC == 0x1E48)
- // _DEBUG_BREAK ();
- // if (gb->lr35902->PC == 0x1E66)
- // _DEBUG_BREAK ();
- PC_cac = gb->lr35902->PC;
- opclks_ = cpu_optick (gb->lr35902);
- // assert (opclks_ < 5);
- printf ("pc:%04x prombank:%d\n", gb->lr35902->PC, gb->cart->mbc1->prombank);
- if (gb->lr35902->PC == 0x1E65)
- _DEBUG_BREAK ();
- /* check KEY1 */
- fadjust = ks_true;
- if (opclks_ & 0x80000000)
- opclks_ &= 0x7FFFFFFF;
- else fadjust = ks_false;
- opclks = (ks_double) opclks_;
- cpu_clks -= opclks_;
- internaldev_clks (gb, opclks_);
- check_interrupt:
- if (gb->lr35902->IME != 0) {
- if ((imask = (gb->reg0F_IF & gb->regFF_IE & 0x1F)) != 0) {
- /* Interrupt Service Routine According to Z80 datasheets,
- the following occurs when control is being transferred to an interrupt handler: */
- ks_uint16 iaddr;
- gb->lr35902->halt = ks_false; /* close halt*/
- gb->lr35902->_backup = 0;
- if (imask & IRQ_1) {
- iaddr = IRQ_1_ADDRESS; imask= IRQ_1; }
- else if (imask & IRQ_2) {
- iaddr = IRQ_2_ADDRESS; imask= IRQ_2; }
- else if (imask & IRQ_3) {
- iaddr = IRQ_3_ADDRESS; imask= IRQ_3; }
- else if (imask & IRQ_4) {
- iaddr = IRQ_4_ADDRESS; imask= IRQ_4; }
- else if (imask & IRQ_5) {
- iaddr = IRQ_5_ADDRESS; imask= IRQ_5; }
- /* 1. Two wait states are executed
- (2 machine cycles pass while nothing occurs, presumably the CPU is executing NOPs during this time). */
- cpu_clks -= 8.0;
- internaldev_clks (gb, 8.0);
- gb->reg0F_IF &=~imask; /*close interrupr request mask */
- gb->lr35902->IME = 0; /* reset IME. */
- gameboy_mmu_write (gb, gb->lr35902->SP - 1, gb->lr35902->PH);
- gameboy_mmu_write (gb, gb->lr35902->SP - 2, gb->lr35902->PL);
- gb->lr35902->SP -= 2;
- /* 2. The current PC is pushed onto the stack, this process consumes 2 more machine cycles. */
- cpu_clks -= 8.0;
- internaldev_clks (gb, 8.0);
- /* 3. The high byte of the PC is set to 0,
- the low byte is set to the address of the handler ($40,$48,$50,$58,$60).
- This consumes one last machine cycle. */
- gb->lr35902->PC = iaddr;
- cpu_clks -= 4.0;
- internaldev_clks (gb, 4.0);
- }
- }
- if (fadjust != ks_false) {
- /* freq adjust in all device */
- if (gb->lr35902->reg4D_key1 & 0x80) {
- /* normal to double freq */
- cpu_clks *= std_machine.cgb_gbp_p;
- gb->cpu_clks_ppu *= std_machine.cgb_gbp_p;
- gb->lh5028->hbl_clks_st *= std_machine.cgb_gbp_p;
- gb->lh5028->oambg_clks_divider21 *= std_machine.cgb_gbp_p;
- gb->mach_tools = (struct machine_setup *)& adv_machine;
- } else {
- /* double freq to normal */
- cpu_clks *= adv_machine.gbp_cgb_p;
- gb->cpu_clks_ppu *= adv_machine.gbp_cgb_p;
- gb->lh5028->hbl_clks_st *= adv_machine.gbp_cgb_p;
- gb->lh5028->oambg_clks_divider21 *= adv_machine.gbp_cgb_p;
- gb->mach_tools = (struct machine_setup *)& std_machine;
- }
- }
- }
- }
- }
- }
- int apu_init (struct apu **apu);
- int ppu_init (struct ppu **ppu);
- int cpu_init (struct cpu **cpu);
- int controller_init (struct controller **controller);
- int timer_init (struct timer **timer);
- int divider_init (struct divider **divider_);
- int cartridge_init (struct cartridge ** cartridge);
- int serial_init (struct serial ** serial);
- int gameboy_init (struct gameboy **gb) {
- struct gameboy *gb_ =ks_null;
- assert (gb != ks_null);
- gb_ = (struct gameboy *)
- calloc (sizeof (struct gameboy), 1);
- apu_init (& gb_->apu);
- ppu_init (& gb_->lh5028);
- cpu_init (& gb_->lr35902);
- controller_init (& gb_->joypad);
- timer_init (& gb_->timer);
- divider_init (& gb_->divider);
- cartridge_init (& gb_->cart);
- serial_init (& gb_->serial);
- /* lnk child objects */
- gb_->apu->gb = gb_;
- gb_->lh5028->gb = gb_;
- gb_->lr35902->gb = gb_;
- gb_->joypad->gb = gb_;
- gb_->timer->gb = gb_;
- gb_->divider->gb = gb_;
- gb_->cart->gb = gb_;
- gb_->serial->gb = gb_;
- gb_->controller_hostdrv = controller_hostdrv_s;
- gb_->display_hostdrv = display_hostdrv_s;
- ppu_setupdate_ (gb_->lh5028, lcdvideo_hostdrv_route, ks_null);
- controller_setupdate_ (gb_->joypad, controller_hostdrv_route, ks_null);
- gb_->reg70_SVBK = 1;
- gb_->regFF_IE = 0;
- * gb = gb_;
- return 0;
- }
- void divider_write (struct divider *divider, ks_uint8 value);
- void timer_write (struct timer *timer, ks_uint16 addr, ks_uint8 value);
- void ppu_write (struct ppu *ppu, ks_uint16 addr, ks_uint8 value);
- void apu_write (struct apu *apu, ks_uint16 addr, ks_uint8 value);
- void serial_write (struct serial *apu, ks_uint16 addr, ks_uint8 value);
- void cartridge_write (struct cartridge *cart, ks_uint16 addr, ks_uint8 value);
- void controller_write (struct controller *cart, ks_uint8 value);
- void
- ks_callstd gameboy_mmu_write (struct gameboy *gb, ks_uint16 address, ks_uint8 value) {
- switch (address >> 13) {
- case 0x00: /* Memmap- 0x0000-0x1FFF*/
- case 0x01: /* Memmap- 0x2000-0x3FFF*/
- case 0x02: /* Memmap- 0x4000-0x5FFF*/
- case 0x03: /* Memmap- 0x6000-0x7FFF*/
- case 0x05: /* Memmap- 0xA000-0xBFFF*/
- gb->cart->write (gb->cart, address, value); /* Program ROM BANK0 or BANK1-NN */
- break;
- case 0x04: /* Memmap- 0x8000-0x9FFF*/
- gb->lh5028->ram[address-0x8000+(gb->lh5028->reg4F_VBK&1)*0x2000] = value;
- break;
- case 0x07: /* Memmap- 0xE000-0xFFFF*/
- if (address <= 0xFDFF) /* echo ram. same as nes's mirror ram. */
- case 0x06: /* Memmap- 0xC000-0xDFFF*/
- if (address & 0x1000)
- gb->wram[(address & 0x0FFF)+(gb->reg70_SVBK & 7)*0x1000] = value;
- else
- gb->wram[address & 0x0FFF] = value;
- else if (address <= 0xFE9F)
- ((ks_int8 *)&gb->lh5028->sp[0])[address-0xFE00] = value;
- else if (address <= 0xFEFF) /* Not Usable */
- default:
- gb->unknow_ram[address] = value;
- else
- switch (address) {
- case 0xFF00: /* P1 */
- controller_write (gb->joypad, value);
- break;
- case 0xFF01: /* SB */
- case 0xFF02: /* SC */
- serial_write (gb->serial, address, value);
- break;
- case 0xFF04: /* DIV */
- divider_write (gb->divider, value);
- break;
- case 0xFF05: /* TIMA*/
- case 0xFF06: /* TMA */
- case 0xFF07: /* TAC */
- timer_write (gb->timer, address, value);
- break;
- case 0xFF10: /* NR10 */
- case 0xFF11: /* NR11 */
- case 0xFF12: /* NR12 */
- case 0xFF13: /* NR13 */
- case 0xFF14: /* NR14 */
- case 0xFF16: /* NR21 */
- case 0xFF17: /* NR22 */
- case 0xFF18: /* NR23 */
- case 0xFF19: /* NR24 */
- case 0xFF1A: /* NR30 */
- case 0xFF1B: /* NR31 */
- case 0xFF1C: /* NR32 */
- case 0xFF1D: /* NR33 */
- case 0xFF1E: /* NR34 */
- case 0xFF20: /* NR41 */
- case 0xFF21: /* NR42 */
- case 0xFF22: /* NR43 */
- case 0xFF23: /* NR44 */
- case 0xFF24: /* NR50 */
- case 0xFF25: /* NR51 */
- case 0xFF26: /* NR52 */
- case 0xFF30: /* AUD3WAVERAM */
- case 0xFF31: /* AUD3WAVERAM */
- case 0xFF32: /* AUD3WAVERAM */
- case 0xFF33: /* AUD3WAVERAM */
- case 0xFF34: /* AUD3WAVERAM */
- case 0xFF35: /* AUD3WAVERAM */
- case 0xFF36: /* AUD3WAVERAM */
- case 0xFF37: /* AUD3WAVERAM */
- case 0xFF38: /* AUD3WAVERAM */
- case 0xFF39: /* AUD3WAVERAM */
- case 0xFF3A: /* AUD3WAVERAM */
- case 0xFF3B: /* AUD3WAVERAM */
- case 0xFF3C: /* AUD3WAVERAM */
- case 0xFF3D: /* AUD3WAVERAM */
- case 0xFF3E: /* AUD3WAVERAM */
- case 0xFF3F: /* AUD3WAVERAM */
- apu_write (gb->apu, address, value);
- break;
- case 0xFF40: /* LCDC */
- case 0xFF41: /* LCDS */
- case 0xFF42: /* SCY */
- case 0xFF43: /* SCX */
- case 0xFF44: /* LY */
- case 0xFF45: /* LYC */
- case 0xFF46: /* OAMDMA */
- case 0xFF47: /* BGP -DMG Only */
- case 0xFF48: /* OBP0 -DMG Only */
- case 0xFF49: /* OBP1 -DMG Only */
- case 0xFF4A: /* WY */
- case 0xFF4B: /* WX */
- case 0xFF4F: /* VBK -CBG Only*/
- case 0xFF51: /* HDMA1 -CBG Only*/
- case 0xFF52: /* HDMA2 -CBG Only*/
- case 0xFF53: /* HDMA3 -CBG Only*/
- case 0xFF54: /* HDMA4 -CBG Only*/
- case 0xFF55: /* HDMA5 -CBG Only*/
- case 0xFF68: /* BCPS -CBG Only*/
- case 0xFF69: /* BCPD -CBG Only*/
- case 0xFF6A: /* OCPS -CBG Only*/
- case 0xFF6B: /* OCPD -CBG Only*/
- ppu_write (gb->lh5028, address, value);
- break;
- case 0xFF56: /* RP -CBG Only*/
- break;
- case 0xFF70: /* SVBK -CBG Only*/
- if ((gb->reg70_SVBK = (value & 7)) == 0)
- gb->reg70_SVBK = 1;
- break;
- case 0xFF4D: /* KEY1 -CBG Only*/
- gb->lr35902->reg4D_key1 = value;
- break;
- case 0xFFFF: /* Interrupt Enable */
- gb->regFF_IE = value;
- break;
- case 0xFF0F: /* IF */
- gb->reg0F_IF = value;
- break;
- default:
- if (address >= 0xFF80)
- gb->hram[address-0xFF80] = value;
- break;
- }
- break;
- }
- }
- ks_void
- ks_callstd gameboy_mmu_write_w (struct gameboy *gb, ks_uint16 address, ks_uint16 value) {
- gameboy_mmu_write (gb, address, value & 0xFF);
- gameboy_mmu_write (gb, address+1, value>> 8);
- }
- ks_uint8 divider_read (struct divider *divider);
- ks_uint8 timer_read (struct timer *timer, ks_uint16 addr);
- ks_uint8 ppu_read (struct ppu *ppu, ks_uint16 addr);
- ks_uint8 apu_read (struct apu *apu, ks_uint16 addr);
- ks_uint8 serial_read (struct serial *apu, ks_uint16 addr);
- ks_uint8 cartridge_read (struct cartridge *cart, ks_uint16 addr);
- ks_uint8 controller_read (struct controller *controller);
- ks_uint8
- ks_callstd gameboy_mmu_read (struct gameboy *gb, ks_uint16 address) {
- switch (address >> 13) {
- case 0x00: /* Memmap- 0x0000-0x1FFF - BANK-0 */
- case 0x01: /* Memmap- 0x2000-0x3FFF - BANK-0 */
- case 0x02: /* Memmap- 0x4000-0x5FFF - BANK-N */
- case 0x03: /* Memmap- 0x6000-0x7FFF - BANK-N */
- case 0x05: /* Memmap- 0xA000-0xBFFF - SRAM/RAM/EXT */
- return gb->cart->read (gb->cart, address);
- case 0x04: /* Memmap- 0x8000-0x9FFF*/
- return gb->lh5028->ram[(address & 0x1FFF) +(gb->lh5028->reg4F_VBK&1)*0x2000];
- case 0x07: /* Memmap- 0xE000-0xFFFF*/
- if (address <= 0xFDFF) /* echo ram. same as nes's mirror ram. */
- case 0x06: /* Memmap- 0xC000-0xDFFF*/
- if (address & 0x1000)
- return gb->wram[(address & 0x0FFF) +(gb->reg70_SVBK & 7)*0x1000];
- else
- return gb->wram[address & 0x0FFF];
- else if (address <= 0xFE9F)
- return ((ks_int8 *)&gb->lh5028->sp[0])[address-0xFE00];
- else if (address <= 0xFEFF) /* Not Usable */
- default:
- return gb->unknow_ram[address];
- else
- switch (address) {
- case 0xFF00: /* P1 */
- return controller_read (gb->joypad);
- case 0xFF01: /* SB */
- case 0xFF02: /* SC */
- return serial_read (gb->serial, address);
- case 0xFF04: /* DIV */
- return divider_read (gb->divider);
- case 0xFF05: /* TIMA*/
- case 0xFF06: /* TMA */
- case 0xFF07: /* TAC */
- return timer_read (gb->timer, address);
- case 0xFF10: /* NR10 */
- case 0xFF11: /* NR11 */
- case 0xFF12: /* NR12 */
- case 0xFF13: /* NR13 */
- case 0xFF14: /* NR14 */
- case 0xFF16: /* NR21 */
- case 0xFF17: /* NR22 */
- case 0xFF18: /* NR23 */
- case 0xFF19: /* NR24 */
- case 0xFF1A: /* NR30 */
- case 0xFF1B: /* NR31 */
- case 0xFF1C: /* NR32 */
- case 0xFF1D: /* NR33 */
- case 0xFF1E: /* NR34 */
- case 0xFF20: /* NR41 */
- case 0xFF21: /* NR42 */
- case 0xFF22: /* NR43 */
- case 0xFF23: /* NR44 */
- case 0xFF24: /* NR50 */
- case 0xFF25: /* NR51 */
- case 0xFF26: /* NR52 */
- case 0xFF30: /* AUD3WAVERAM */
- case 0xFF31: /* AUD3WAVERAM */
- case 0xFF32: /* AUD3WAVERAM */
- case 0xFF33: /* AUD3WAVERAM */
- case 0xFF34: /* AUD3WAVERAM */
- case 0xFF35: /* AUD3WAVERAM */
- case 0xFF36: /* AUD3WAVERAM */
- case 0xFF37: /* AUD3WAVERAM */
- case 0xFF38: /* AUD3WAVERAM */
- case 0xFF39: /* AUD3WAVERAM */
- case 0xFF3A: /* AUD3WAVERAM */
- case 0xFF3B: /* AUD3WAVERAM */
- case 0xFF3C: /* AUD3WAVERAM */
- case 0xFF3D: /* AUD3WAVERAM */
- case 0xFF3E: /* AUD3WAVERAM */
- case 0xFF3F: /* AUD3WAVERAM */
- return apu_read (gb->apu, address);
- case 0xFF40: /* LCDC */
- case 0xFF41: /* LCDS */
- case 0xFF42: /* SCY */
- case 0xFF43: /* SCX */
- case 0xFF44: /* LY */
- case 0xFF45: /* LYC */
- case 0xFF46: /* OAMDMA */
- case 0xFF47: /* BGP -DMG Only */
- case 0xFF48: /* OBP0 -DMG Only */
- case 0xFF49: /* OBP1 -DMG Only */
- case 0xFF4A: /* WY */
- case 0xFF4B: /* WX */
- case 0xFF4F: /* VBK -CBG Only*/
- case 0xFF51: /* HDMA1 -CBG Only*/
- case 0xFF52: /* HDMA2 -CBG Only*/
- case 0xFF53: /* HDMA3 -CBG Only*/
- case 0xFF54: /* HDMA4 -CBG Only*/
- case 0xFF55: /* HDMA5 -CBG Only*/
- case 0xFF68: /* BCPS -CBG Only*/
- case 0xFF69: /* BCPD -CBG Only*/
- case 0xFF6A: /* OCPS -CBG Only*/
- case 0xFF6B: /* OCPD -CBG Only*/
- return ppu_read (gb->lh5028, address);
- case 0xFF56: /* RP -CBG Only*/
- return 0xFF;
- case 0xFF70: /* SVBK -CBG Only*/
- return (gb->reg70_SVBK & 7);
- case 0xFF4D: /* KEY1 -CBG Only*/
- return gb->lr35902->reg4D_key1;
- case 0xFFFF: /* Interrupt Enable */
- return gb->regFF_IE;
- case 0xFF0F: /* IF */
- return gb->reg0F_IF;
- default:
- if (address >= 0xFF80) /* High RAM */
- return gb->hram[address-0xFF80];
- else
- return 0;
- }
- }
- return 0xFF;
- }
- ks_uint16
- ks_callstd gameboy_mmu_read_w (struct gameboy *gb, ks_uint16 address) {
- ks_uint16 u = gameboy_mmu_read (gb, address);
- ks_uint16 v = gameboy_mmu_read (gb, address+1) << 8;
- return (u |v);
- }
- int gameboy_loadrom (struct gameboy *gb, FILE *fp) {
- int cartridge_load (struct cartridge *cart, FILE *cartmem);
- return cartridge_load (gb->cart, fp);
- }
- #include "gameboy.h"
- #include "internal.h"
- /* Add mapper --*/
- int cartridge_load (struct cartridge *cart, FILE *cartmem) {
- static ks_uint8 nintendo_magicnumber[] =
- { 0xCE, 0xED, 0x66, 0x66, 0xCC, 0x0D, 0x00, 0x0B, 0x03, 0x73, 0x00, 0x83, 0x00, 0x0C, 0x00, 0x0D,
- 0x00, 0x08, 0x11, 0x1F, 0x88, 0x89, 0x00, 0x0E, 0xDC, 0xCC, 0x6E, 0xE6, 0xDD, 0xDD, 0xD9, 0x99,
- 0xBB, 0xBB, 0x67, 0x63, 0x6E, 0x0E, 0xEC, 0xCC, 0xDD, 0xDC, 0x99, 0x9F, 0xBB, 0xB9, 0x33, 0x3E };
- ks_bool bat;
- ks_bool ram, cgb, sgb;
- ks_uint8 magicnumber_buffer[sizeof(nintendo_magicnumber)];
- ks_uint8 *promworks;
- ks_uint8 *sramworks;
- int cartridge_mbc0_init (struct cartridge *cartridge);
- int cartridge_mbc1_init (struct cartridge *cartridge);
- int cartridge_mbc2_init (struct cartridge *cartridge);
- void cpu_reset (struct cpu *cpu);
- int ppu_reset (struct ppu *ppu);
- int ppu_cgb_mode (struct ppu *ppu);
- int ppu_dmg_mode (struct ppu *ppu);
- //extern int cartridge_mbc0_init (struct cartridge *cartridge);
- ks_int sig = -1;
- ks_int promsize;
- ks_int sramsize;
- ks_int calc;
- ks_int type;
- assert (cart != ks_null);
- assert (cartmem != ks_null);
- bat = ks_false;
- ram = ks_false;
- cgb = ks_false;
- sgb = ks_false;
- sramworks = ks_null;
- promworks = ks_null;
- if (fseek (cartmem, 0x104, SEEK_SET) != 0)
- return -1;
- if (fread (& magicnumber_buffer[0], sizeof (nintendo_magicnumber), 1, cartmem)
- != 1)
- return -1;
- if (memcmp (nintendo_magicnumber,
- magicnumber_buffer, sizeof (magicnumber_buffer) != 0))
- return -1;
- if (fseek (cartmem, 0x134, SEEK_SET) != 0)
- return -1;
- if (fread (& cart->infochunk[0], sizeof (cart->infochunk), 1, cartmem)
- != 1)
- return -1;
- /* x143/x146 - Check CGB/ SGB */
- cgb = !!(cart->infochunk[15] & 0x80);
- sgb = !!(cart->infochunk[18] == 0x03);
- /*
- 00h ROM ONLY 19h MBC5
- 01h MBC1 1Ah MBC5+RAM
- 02h MBC1+RAM 1Bh MBC5+RAM+BATTERY
- 03h MBC1+RAM+BATTERY 1Ch MBC5+RUMBLE
- 05h MBC2 1Dh MBC5+RUMBLE+RAM
- 06h MBC2+BATTERY 1Eh MBC5+RUMBLE+RAM+BATTERY
- 08h ROM+RAM 20h MBC6
- 09h ROM+RAM+BATTERY 22h MBC7+SENSOR+RUMBLE+RAM+BATTERY
- 0Bh MMM01
- 0Ch MMM01+RAM
- 0Dh MMM01+RAM+BATTERY
- 0Fh MBC3+TIMER+BATTERY
- 10h MBC3+TIMER+RAM+BATTERY FCh POCKET CAMERA
- 11h MBC3 FDh BANDAI TAMA5
- 12h MBC3+RAM FEh HuC3
- 13h MBC3+RAM+BATTERY FFh HuC1+RAM+BATTERY
- */
- /* check error device */
- switch (cart->infochunk[19]) {
- case 0x00:
- type = MBC_0;
- break;
- case 0x01:
- case 0x02:
- case 0x03:
- type = MBC_1;
- break;
- case 0x05:
- case 0x06:
- type = MBC_2;
- break;
- case 0x08:
- case 0x09:
- type = MBC_0;
- break;
- case 0x0B:
- case 0x0C:
- case 0x0D:
- type = MMM0;
- break;
- case 0x0F:
- case 0x10:
- case 0x11:
- case 0x12:
- case 0x13:
- type = MBC_3;
- break;
- case 0x19:
- case 0x1A:
- case 0x1B:
- case 0x1C:
- case 0x1D:
- case 0x1E:
- type = MBC_5;
- break;
- case 0x20:
- type = MBC_6;
- break;
- case 0x22:
- type = MBC_7;
- break;
- case 0xFC:
- type = POCKER_CAM;
- break;
- case 0xFD:
- type = TAMA5;
- break;
- case 0xFE:
- type = HUCL3;
- break;
- case 0xFF:
- type = HUCL1;
- break;
- default :
- return -1;
- }
- /* check prom size */
- switch (cart->infochunk[20]) {
- case 0x00: promsize = 2; break;
- case 0x01: promsize = 4; break;
- case 0x02: promsize = 8; break;
- case 0x03: promsize =16; break;
- case 0x04: promsize =32; break;
- case 0x05: promsize =64; if (type == MBC_1) promsize = 63; break;
- case 0x06: promsize =128; if (type == MBC_1) promsize = 125; break; break;
- case 0x07: promsize =256; break;
- case 0x08: promsize =512; break;
- case 0x52: promsize =72; break;
- case 0x53: promsize =80; break;
- case 0x54: promsize =96; break;
- default : return -1;
- }
- /* check sram size */
- switch (cart->infochunk[21]) {
- case 0x00: sramsize = 0; break;
- case 0x01: sramsize = 1; break; /* 2K sram, same as 8K */
- case 0x02: sramsize = 1; break;
- case 0x03: sramsize = 4; break;
- case 0x04: sramsize =16; break;
- case 0x05: sramsize = 8; break;
- default : return -1;
- }
- /* init prom and sram */
- promworks = (ks_uint8 *)malloc (promsize * 0x4000);
- sramworks = (ks_uint8 *)malloc (sramsize * 0x2000);
- assert (promworks != ks_null);
- assert (sramworks != ks_null); /* random data in init time */
- fseek (cartmem, 0, SEEK_END);
- calc = ftell(cartmem);
- if (calc != promsize * 0x4000)
- promsize = calc / 0x4000;
- if (fseek (cartmem, 0, SEEK_SET) != 0)
- goto _cleanup;
- if (fread (promworks, promsize * 0x4000, 1, cartmem) != 1)
- goto _cleanup;
- if (cart->promworks != ks_null)
- free (cart->promworks);
- if (cart->sramworks != ks_null)
- free (cart->sramworks);
- cart->promworks = promworks;
- cart->sramworks = sramworks;
- cart->cbgmode = cgb;
- cart->sgbmode = sgb;
- cart->promsize = promsize;
- cart->sramsize = sramsize;
- cart->type = type;
- cart->battery = bat;
- /* reset cart chip device */
- switch (type) {
- case MBC_0:
- cartridge_mbc0_init (cart);
- break;
- case MBC_1:
- case MBC_2:
- case MBC_3:
- case MBC_4:
- case MBC_5:
- case MBC_6:
- case MBC_7:
- case TAMA5:
- case HUCL1:
- case HUCL3:
- case MMM0:
- case POCKER_CAM:
- default :assert (0); /*never reach here */
- }
- if (cgb != ks_false)
- ppu_cgb_mode (cart->gb->lh5028);
- else
- ppu_dmg_mode (cart->gb->lh5028);
- cpu_reset (cart->gb->lr35902);
- ppu_reset (cart->gb->lh5028);
- /* set std freq. */
- cart->gb->mach_tools = (struct machine_setup *)& std_machine;
- return 0;
- _cleanup:
- free (sramworks);
- free (promworks);
- return -1;
- }
- int cartridge_init (struct cartridge **cartridge) {
- struct cartridge *cartridge_ =ks_null;
- assert (cartridge != ks_null);
- cartridge_ = (struct cartridge *)
- calloc (sizeof (struct cartridge), 1);
- cartridge_->clks = ks_null;
- assert (cartridge_ != ks_null);
- * cartridge = cartridge_;
- /* Settings cart type desc init --*/
- cartridge_->cartgt[0x00] = "ROM ONLY";
- cartridge_->cartgt[0x01] = "ROM+MBC1";
- cartridge_->cartgt[0x02] = "ROM+MBC1+RAM";
- cartridge_->cartgt[0x03] = "ROM+MBC1+RAM+Battery";
- cartridge_->cartgt[0x05] = "ROM+MBC2";
- cartridge_->cartgt[0x06] = "ROM+MBC2+Battery";
- cartridge_->cartgt[0x08] = "ROM+RAM";
- cartridge_->cartgt[0x09] = "ROM+RAM+Battery";
- cartridge_->cartgt[0x0B] = "ROM+MMM01";
- cartridge_->cartgt[0x0C] = "ROM+MMM01+RAM";
- cartridge_->cartgt[0x0D] = "ROM+MMM01+RAM+Battery";
- cartridge_->cartgt[0x0F] = "ROM+MBC3+Battery+Timer";
- cartridge_->cartgt[0x10] = "ROM+MBC3+RAM+Battery+Timer";
- cartridge_->cartgt[0x11] = "ROM+MBC3";
- cartridge_->cartgt[0x12] = "ROM+MBC3+RAM";
- cartridge_->cartgt[0x13] = "ROM+MBC3+RAM+Battery";
- cartridge_->cartgt[0x15] = "ROM+MBC4";
- cartridge_->cartgt[0x16] = "ROM+MBC4+RAM";
- cartridge_->cartgt[0x17] = "ROM+MBC4+RAM+Battery";
- cartridge_->cartgt[0x19] = "ROM+MBC5";
- cartridge_->cartgt[0x1A] = "ROM+MBC5+RAM";
- cartridge_->cartgt[0x1B] = "ROM+MBC5+RAM+Battery";
- cartridge_->cartgt[0x1C] = "ROM+MBC5+Rumble";
- cartridge_->cartgt[0x1D] = "ROM+MBC5+RAM+Rumble";
- cartridge_->cartgt[0x1E] = "ROM+MBC5+RAM+Battery+Rumble";
- cartridge_->cartgt[0x22] = "ROM+MBC5+Tilt";
- cartridge_->cartgt[0xFC] = "Nintendo Pocket Camera";
- cartridge_->cartgt[0xFD] = "Bandai TAMA5";
- cartridge_->cartgt[0xFE] = "Hudson HuC-3";
- cartridge_->cartgt[0xFF] = "Hudson HuC-1";
- /* Settings old licensee desc init --*/
- cartridge_->ancl[0x00] = "None";
- cartridge_->ancl[0x01] = "Nintendo"; /* homepage:https://www.nintendo.com */
- cartridge_->ancl[0x08] = "Capcom"; /* homepage:http://www.capcom.com*/
- cartridge_->ancl[0x09] = "Hot B Games"; /* wiki:https://en.wikipedia.org/wiki/Category:Hot_B_games */
- cartridge_->ancl[0x0A] = "Jaleco"; /* wiki:https://en.wikipedia.org/wiki/Jaleco*/
- cartridge_->ancl[0x0B] = "Coconuts Japan"; /* misc link:https://www.genkivideogames.com/japanese_imported_video_games.asp?pagetoshow=search&keywordtext=Coconuts%20Japan&searchtype=publisher*/
- cartridge_->ancl[0x0C] = "Elite Systems";/*wiki: https://en.wikipedia.org/wiki/Elite_Systems*/
- cartridge_->ancl[0x13] = "ËA"; /*homepage: https://www.ea.com/zh-cn */
- cartridge_->ancl[0x18] = "Hudson Soft"; /*homepage: http://www.hudsonsoft.net/what-we-do/ */
- cartridge_->ancl[0x19] = "ITC Entertainment"; /*wiki: https://en.wikipedia.org/wiki/ITC_Entertainment */
- cartridge_->ancl[0x1A] = "Yanoman"; /* MobyGames:https://www.mobygames.com/company/yanoman-corporation */
- cartridge_->ancl[0x1D] = "Nippon Clary"; /* giantbomb:https://www.giantbomb.com/nippon-clary-business/3010-6837/ */
- cartridge_->ancl[0x1F] = "Virgin"; /* wiki:https://en.wikipedia.org/wiki/Virgin_Interactive */
- /* homepage: https://www.virgingames.com/quick-login */
- cartridge_->ancl[0x24] = "PCM Complete"; /* https://segaretro.org/PCM_Complete | https://www.mobygames.com/company/pcm-complete */
- cartridge_->ancl[0x25] = "San-X"; /* homepage http://www.san-x.jp*/
- cartridge_->ancl[0x28] = "Kotobuki Systems";/*wiki: https://en.wikipedia.org/wiki/Kemco*/
- cartridge_->ancl[0x29] = "SETA"; /*wiki: https://en.wikipedia.org/wiki/SETA_Corporation */
- cartridge_->ancl[0x30] = "Atari,SA"; /*wiki: https://en.wikipedia.org/wiki/Atari,_SA */
- cartridge_->ancl[0x31] = "Nintendo"; /* homepage:https://www.nintendo.com */
- cartridge_->ancl[0x32] = "Bandai"; /*homepage: http://www.bandai.com */
- cartridge_->ancl[0x33] = "GameBoyColor"; /*new licensee */
- cartridge_->ancl[0x34] = "Konami"; /*homepage: https://www.konami.com/en/*/
- cartridge_->ancl[0x35] = "Hector"; /*N/A */
- cartridge_->ancl[0x38] = "Capcom"; /* homepage:http://www.capcom.com*/
- cartridge_->ancl[0x39] = "Banpresto"; /* homepage:http://www.banpresto.jp/prize/0008.html*/
- cartridge_->ancl[0x3C] = "Entertainment i"; /* truncated, see http://gbdev.gg8.se/wiki/articles/Gameboy_ROM_Header_Info#Licensee*/
- cartridge_->ancl[0x3E] = "Gremlin"; /* wiki: https://en.wikipedia.org/wiki/Gremlin_Interactive */
- cartridge_->ancl[0x41] = "Ubisoft"; /*homepage: https://www.ubisoft.com/en-US/ */
- cartridge_->ancl[0x42] = "Atlus"; /*homepage: https://atlus.com*/
- cartridge_->ancl[0x44] = "Malibu"; /*swiki: https://strategywiki.org/wiki/Category:Malibu*/
- cartridge_->ancl[0x46] = "Angel"; /*N/A*/
- cartridge_->ancl[0x47] = "Spectrum HoloByte"; /*wiki: https://en.wikipedia.org/wiki/Spectrum_HoloByte*/
- cartridge_->ancl[0x49] = "Irem"; /* wiki: https://en.wikipedia.org/wiki/Irem */
- cartridge_->ancl[0x4A] = "Virgin"; /* wiki:https://en.wikipedia.org/wiki/Virgin_Interactive */
- /* homepage: https://www.virgingames.com/quick-login */
- cartridge_->ancl[0x4D] = "Malibu"; /*swiki: https://strategywiki.org/wiki/Category:Malibu*/
- cartridge_->ancl[0x4F] = "US.Gold"; /*wiki: https://en.wikipedia.org/wiki/U.S._Gold */
- cartridge_->ancl[0x50] = "Absolute"; /*homepgae:http://www.absolutegamez.com */
- cartridge_->ancl[0x51] = "Acclaim"; /*wiki: https://en.wikipedia.org/wiki/Acclaim_Games*/
- cartridge_->ancl[0x52] = "Activision"; /*homepage: https://www.activision.com*/
- cartridge_->ancl[0x53] = "Sammy"; /*wiki: https://en.wikipedia.org/wiki/Sammy_Corporation*/
- cartridge_->ancl[0x54] = "GameTek"; /*wiki: https://en.wikipedia.org/wiki/GameTek*/
- cartridge_->ancl[0x55] = "Park Place"; /*maybe???: https://en.wikipedia.org/wiki/List_of_Jurassic_Park_video_games*/
- cartridge_->ancl[0x56] = "LJN"; /*avgn: http://avgn.wikia.com/wiki/LJN*/
- cartridge_->ancl[0x57] = "MATCHBOX"; /*homepage: http://play.matchbox.com/en_US/*/
- cartridge_->ancl[0x59] = "Milton Bradley"; /*wiki: https://en.wikipedia.org/wiki/Milton_Bradley_Company*/
- cartridge_->ancl[0x5A] = "Mindscape"; /*wiki: https://en.wikipedia.org/wiki/Mindscape*/
- cartridge_->ancl[0x5B] = "Romstar"; /*wiki: https://en.wikipedia.org/wiki/Romstar*/
- cartridge_->ancl[0x5C] = "Kaga Create"; /*wiki: https://en.wikipedia.org/wiki/Kaga_Create*/
- cartridge_->ancl[0x5D] = "Tradewest"; /*wiki: https://en.wikipedia.org/wiki/Tradewest*/
- cartridge_->ancl[0x60] = "Titus"; /*wiki: https://en.wikipedia.org/wiki/Titus_Interactive*/
- cartridge_->ancl[0x61] = "Virgin"; /* wiki:https://en.wikipedia.org/wiki/Virgin_Interactive */
- /* homepage: https://www.virgingames.com/quick-login */
- cartridge_->ancl[0x67] = "Ocean"; /*wiki: https://en.wikipedia.org/wiki/Ocean_Software*/
- cartridge_->ancl[0x69] = "ËA"; /*homepage: https://www.ea.com/zh-cn */
- cartridge_->ancl[0x6E] = "Elite Systems";/*wiki: https://en.wikipedia.org/wiki/Elite_Systems*/
- cartridge_->ancl[0x6F] = "Electro Brain";/*wiki: https://en.wikipedia.org/wiki/Electro_Brain*/
- cartridge_->ancl[0x70] = "Atari,SA"; /*wiki: https://en.wikipedia.org/wiki/Atari,_SA */
- cartridge_->ancl[0x71] = "Interplay"; /*wiki: https://en.wikipedia.org/wiki/Interplay_Entertainment*/
- cartridge_->ancl[0x72] = "Brøderbund"; /*moby: https://www.mobygames.com/company/brderbund-software-inc*/
- cartridge_->ancl[0x73] = "Sculptured"; /*maybe??: http://closinglogogroup.wikia.com/wiki/Sculptured_Software,_Inc.*/
- cartridge_->ancl[0x75] = "SCi Games"; /*wiki: https://en.wikipedia.org/wiki/SCi_Games*/
- cartridge_->ancl[0x78] = "THQ"; /*source is:t*hq wiki: https://en.wikipedia.org/wiki/THQ*/
- cartridge_->ancl[0x79] = "Accolade"; /*wiki: https://en.wikipedia.org/wiki/Accolade_(game_company)*/
- cartridge_->ancl[0x7A] = "Triffix"; /*wiki: https://en.wikipedia.org/wiki/Triffix_Entertainment*/
- cartridge_->ancl[0x7C] = "MicroProse"; /*homepage: http://www.microprose.com*/
- cartridge_->ancl[0x7F] = "Kemco";/*wiki: https://en.wikipedia.org/wiki/Kemco*/
- cartridge_->ancl[0x80] = "Misawa"; /*nseen64: https://www.unseen64.net/tag/misawa-entertainment/*/
- cartridge_->ancl[0x83] = "LOZC G"; /*wiki: https://en.wikipedia.org/wiki/Category:LOZC_G._Amusements_games*/
- cartridge_->ancl[0x86] = "Tokuma Shoten"; /*wiki: https://en.wikipedia.org/wiki/Tokuma_Shoten*/
- cartridge_->ancl[0x8B] = "Blue Planet"; /*wiki: https://en.wikipedia.org/wiki/Blue_Planet_Software*/
- cartridge_->ancl[0x8C] = "Tokai Communications"; /*wiki: https://en.wikipedia.org/wiki/Tokai_Communications*/
- cartridge_->ancl[0x8E] = "APE Games"; /*homepage: http://www.apegames.com*/
- cartridge_->ancl[0x8F] = "I'Max"; /*No find infos */
- cartridge_->ancl[0x91] = "Spike Chunsoft"; /*wiki: https://en.wikipedia.org/wiki/Spike_Chunsoft*/
- cartridge_->ancl[0x92] = "Video System"; /*No find infos*/
- cartridge_->ancl[0x93] = "Tsuburava"; /*No find infos */
- cartridge_->ancl[0x95] = "Varie"; /*wiki: https://en.wikipedia.org/wiki/Varie*/
- cartridge_->ancl[0x96] = "Yonezawa PR21"; /*wiki: https://en.wikipedia.org/wiki/Yonezawa_PR21*/
- cartridge_->ancl[0x97] = "Kaneko"; /*wiki: https://en.wikipedia.org/wiki/Kaneko*/
- cartridge_->ancl[0x99] = "Arcade"; /*wiki: https://en.wikipedia.org/wiki/Arcade_game*/
- cartridge_->ancl[0x9A] = "Nihon Bussan"; /*wiki: https://en.wikipedia.org/wiki/Nihon_Bussan*/
- cartridge_->ancl[0x9B] = "Tecmo"; /*wiki: https://en.wikipedia.org/wiki/Tecmo*/
- cartridge_->ancl[0x9C] = "Disney"; /*wiki: https://en.wikipedia.org/wiki/Walt_Disney_Imagineering*/
- cartridge_->ancl[0x9D] = "Banpresto"; /* homepage:http://www.banpresto.jp/prize/0008.html*/
- cartridge_->ancl[0x9F] = "Nova"; /*No find infos*/
- cartridge_->ancl[0xA1] = "Hori Electric"; /* https://www.giantbomb.com/hori-electric-co-ltd/3010-5917/*/
- cartridge_->ancl[0xA2] = "Bandai"; /*homepage: http://www.bandai.com */
- cartridge_->ancl[0xA4] = "Konami"; /*homepage: https://www.konami.com/en/*/
- cartridge_->ancl[0xA6] = "Kawada"; /*No find infos*/
- cartridge_->ancl[0xA7] = "Takara"; /*wiki: https://en.wikipedia.org/wiki/Takara**/
- cartridge_->ancl[0xA9] = "Technōs Japan"; /*wiki: https://en.wikipedia.org/wiki/Technōs_Japan*/
- cartridge_->ancl[0xAA] = "Brøderbund"; /*moby: https://www.mobygames.com/company/brderbund-software-inc*/
- cartridge_->ancl[0xAC] = "Toei Animation"; /*homepage: http://t
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement