Advertisement
xiahanlu

Untitled

Oct 21st, 2018
328
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 238.68 KB | None | 0 0
  1. /* type and settings for compiler, common header
  2.  *
  3.  * Copyright (C) 2018 moecmks
  4.  * This file is part of KS3578.
  5.  *
  6.  * do What The Fuck you want to Public License
  7.  *
  8.  * Version 1.0, March 2000
  9.  * Copyright (C) 2000 Banlu Kemiyatorn (]d).
  10.  * 136 Nives 7 Jangwattana 14 Laksi Bangkok
  11.  * Everyone is permitted to copy and distribute verbatim copies
  12.  * of this license document, but changing it is not allowed.
  13.  *
  14.  * Ok, the purpose of this license is simple
  15.  * and you just
  16.  *
  17.  * DO WHAT THE FUCK YOU WANT TO.
  18.  */
  19.  
  20. #ifndef _CONFIG_H
  21. #define _CONFIG_H 1
  22.  
  23. #ifdef _WIN32
  24. # if defined (_UNICODE) || defined (UNICODE)
  25. #  define UCS2
  26. # endif
  27. # define _CRT_SECURE_NO_DEPRECATE
  28. #endif
  29.  
  30. #include <stdint.h>
  31. #include <stdio.h>
  32. #include <stdlib.h>
  33. #include <string.h>
  34. #include <process.h>
  35. #include <assert.h>
  36. #include <string.h>
  37. #include <math.h>
  38.  
  39. #ifdef __cplusplus
  40. # define ks_null nullptr
  41. #else
  42. # define ks_null ((void *)0)
  43. #endif  
  44.  
  45. #ifndef STATIC_DEFINED
  46. # define STATIC static
  47. #endif
  48.  
  49. typedef int ks_bool;
  50. # define ks_false 0
  51. # define ks_true 1
  52.  
  53. typedef int8_t ks_int8;
  54. typedef int16_t ks_int16;
  55. typedef int32_t ks_int32;
  56. typedef int64_t ks_int64;
  57. typedef uint8_t ks_uint8;
  58. typedef uint16_t ks_uint16;
  59. typedef uint32_t ks_uint32;
  60. typedef uint64_t ks_uint64;
  61. typedef float ks_float;
  62. typedef double ks_double;
  63. typedef signed int ks_int;
  64. typedef unsigned int ks_uint;
  65. typedef intptr_t ks_intptr;
  66. typedef unsigned int ks_uint;
  67. typedef void ks_void;
  68.  
  69. # define KS_UINT8_CAST(x) ((ks_uint8)(x))
  70. # define KS_UINT16_CAST(x) ((ks_uint16)(x))
  71. # define KS_UINT32_CAST(x) ((ks_uint32)(x))
  72. # define KS_UINT64_CAST(x) ((ks_uint64)(x))
  73. # define KS_INT8_CAST(x) ((ks_int8)(x))
  74. # define KS_INT16_CAST(x) ((ks_int16)(x))
  75. # define KS_INT32_CAST(x) ((ks_int32)(x))
  76. # define KS_INT64_CAST(x) ((ks_int64)(x))
  77. # define KS_FLOAT_CAST(x) ((ks_float)(x))
  78. # define KS_DOUBLE_CAST(x) ((ks_double)(x))
  79.  
  80. #if defined (_MSC_VER) || defined (__ICC) || defined (__INTEL_COMPILER) /* MSVC/ICC starting... */
  81. # define ks_finline static  __forceinline
  82. # define ks_dinline         __declspec(noinline)
  83. # define ks_callstd         __stdcall
  84. # define ks_callc           __cdecl
  85. # define ks_cvalign(x)      __declspec(align(x))
  86. # define ks_cvimpl          __declspec(dllexport)
  87. #elif defined (__GNUC__) || defined (__GNUG__) /* MSVC/ICC end... GNUC starting */
  88. # define ks_finline static  __attribute__((always_inline))
  89. # define ks_dinline         __attribute__((noinline))
  90. # define ks_callstd         __attribute__((stdcall))
  91. # define ks_callc           __attribute__((cdecl))
  92. # define ks_cvalign(x)      __attribute__((aligned(x)))
  93. # define ks_cvimpl          __attribute__((dllexport))
  94. #else /* unsupported */
  95. # error unsupported compiler!
  96. #endif
  97. # define KS_CMP_EQUAL 0
  98. # define KS_CMP_ABOVE 1
  99. # define KS_CMP_LOW 2
  100. # define KS_CMP_NaN 3
  101.  
  102. ks_finline
  103. int ks_cmp0_double (ks_double *value) {
  104.   /*  XXX: IEEE754  */
  105.   ks_int64 *v = (ks_int64 *)(value);
  106.   /* S:nocare M and E is 0 */
  107.   if (! (v[0] & 0x7FFFFFFFFFFFFFFF)) /* -0 or +0*/
  108.     return KS_CMP_EQUAL;
  109.   if (  ( ((ks_int32 *)&v[0])[1] & 0x80000000))
  110.     return KS_CMP_LOW;
  111.   else
  112.     return KS_CMP_ABOVE;
  113. }
  114.  
  115. #ifdef _WIN32
  116. # ifdef _MSC_VER
  117. #  define _DEBUG_BREAK() _asm int 3
  118. # else
  119. # endif
  120. #endif
  121.  
  122. /* some hardware settings. */
  123. #define TIMER_DIVIDER_SAME_FREQ_BOTH_CBG_DMG_BASE_DMG
  124. #define JOYPAD_FREQ_IN_DMG 50.3
  125. #define JOYPAD_FREQ_IN_CGB 50.3
  126. #define JOYPAD_INTERRUPT_GEN_ENABLE
  127. #define JOYPAD_LOAD_ACTION_IN_P1415_ALLOPEN 3 /* 0:OR 1:AND 2:XOR 3:AND-NOT */
  128. #define TIMER_RESET_IN_RESET_FREQ_MOD_
  129. #define PPU_POST_RENDER_TIME 0 /* 0:VBLANK START 1:VBLANK END. */
  130. /* #define PPU_SPRITE_LIMIT10_IN_SCANLINE */
  131.  
  132. #ifdef UCS2
  133. typedef  wchar_t host_char;
  134. #else
  135. typedef  char host_char;
  136. #endif
  137.  
  138. #endif
  139. /* private object for gameboy
  140.  *
  141.  * Copyright (C) 2018 moecmks
  142.  * This file is part of KS3578.
  143.  *
  144.  * do What The Fuck you want to Public License
  145.  *
  146.  * Version 1.0, March 2000
  147.  * Copyright (C) 2000 Banlu Kemiyatorn (]d).
  148.  * 136 Nives 7 Jangwattana 14 Laksi Bangkok
  149.  * Everyone is permitted to copy and distribute verbatim copies
  150.  * of this license document, but changing it is not allowed.
  151.  *
  152.  * Ok, the purpose of this license is simple
  153.  * and you just
  154.  *
  155.  * DO WHAT THE FUCK YOU WANT TO.
  156.  */
  157.  
  158. #ifndef _INTERNAL_H
  159. #define _INTERNAL_H 1
  160.  
  161. #include "conf.h"
  162. #include "gameboy.h"
  163. #include "list.h"
  164.  
  165. struct gameboy;
  166. struct controller;
  167. struct divider;
  168. struct timer;
  169. struct cpu;
  170. struct ppu;
  171. struct cartidge;
  172. struct serial;
  173. struct apu;
  174. struct machine_setup;
  175. struct romheader;
  176. /*-\
  177. \-*/
  178. static const
  179. struct machine_setup {
  180.   ks_double cpu_freq;  
  181.   ks_double vsync_freq;
  182.   ks_double clk_ms;
  183.   ks_double clk_ns;
  184.   ks_double frame_cycles;
  185.   ks_double line_cycles;
  186.   ks_double oam_cycles;
  187.   ks_double oambg_b_cycles;
  188.   ks_double oambg_hbl_cycles;
  189.   ks_double vbl_clk_last;
  190.   ks_double oambg_clk_st;
  191.   ks_double hbl_clk_st_b;
  192.   ks_double vbl_clk_st;
  193.   ks_double oam_clk_pick_per;
  194.   ks_double oam_clk_add_hbl_per;
  195.   ks_double cgb_gbp_p;
  196.   ks_double gbp_cgb_p;
  197.   ks_double oamdma_clks;
  198.   ks_double gdma_clks_b;
  199.   ks_double gdma_clks_per16; // always 7.63 us (DMG/CGB)
  200.   ks_double hdma_clks_per16; // always 8 us (DMG/CGB)
  201.   ks_double joypad_gen_freq;
  202. } std_machine = {
  203.   4194304.0, /* cpu_freq*/  
  204.   59.73, /* vsync_freq*/
  205.   4194304.0/1000.0, /* clk_ms*/
  206.   4194304.0/1000000.0, /* clk_ns*/
  207.   4194304.0/59.73, /* frame_cycles*/
  208.   4194304.0/59.73/154.0, /* line_cycles*/
  209.   80.992010239999985, /* oam_cycles*/
  210.   173.51835647999999, /* oambg_b_cycles*/
  211.   (70221.061443161/154.0) - 80.992010239999985, /* oambg_hbl_cycles*/
  212.   4559.809184621, /* vbl_clk_last*/
  213.   80.99201023999998, /* oambg_clk_st*/
  214.   173.51835647999999 + 80.992010239999985, /* hbl_clk_st_b*/
  215.   70221.061443161 - 4559.809184621, /* vbl_clk_st*/
  216.   80.992010239999985 / 10.0, /* oam_clk_pick_per*/
  217.   12.549357568000001, /* oam_clk_add_hbl_per*/
  218.   8400000.0/ 4194304.0, /* cgb_gbp_p*/
  219.   4194304.0/ 8400000.0, /* gbp_cgb_p*/
  220.   671.08864000000005, /* oamdma_clks*/
  221.   (4194304.0*220.0)/1000000.0, /* gdma_clks_b*/
  222.   (4194304.0*7.63)/1000000.0,/* gdma_clks_per16*/
  223.   (4194304.0*8.00)/1000000.0,/* hdma_clks_per16*/
  224.   (4194304.0)/JOYPAD_FREQ_IN_DMG /* joypad_gen_freq*/
  225. }, adv_machine = { 
  226.   8400000.0, /* cpu_freq*/  
  227.   59.73, /* vsync_freq*/
  228.   8400000.0/1000.0, /* clk_ms*/
  229.   8400000.0/1000000.0, /* clk_ns*/
  230.   8400000.0/59.73, /* frame_cycles*/
  231.   8400000.0/59.73/154.0, /* line_cycles*/
  232.   162.20400000000001, /* oam_cycles*/
  233.   347.50799999999998, /* oambg_b_cycles*/
  234.   (8400000.0/59.73/154.0) - 162.20400000000001, /* oambg_hbl_cycles*/
  235.   9132.0031048810633, /* vbl_clk_last*/
  236.   162.20400000000001, /* oambg_clk_st*/
  237.   347.50799999999998 + 162.20400000000001, /* hbl_clk_st_b*/
  238.   (8400000.0/59.73) - 9132.0031048810633, /* vbl_clk_st*/
  239.   162.20400000000001 / 10.0, /* oam_clk_pick_per*/
  240.   25.132800000000003, /* oam_clk_add_hbl_per*/
  241.   8400000.0/ 4194304.0, /* cgb_gbp_p*/
  242.   4194304.0/ 8400000.0, /* gbp_cgb_p*/
  243.   671.08864000000005, /* oamdma_clks*/
  244.   (8400000.0*110.0)/1000000.0, /* gdma_clks_b*/
  245.   (8400000.0*7.63)/1000000.0,/* gdma_clks_per16*/
  246.   (8400000.0*8.00)/1000000.0,/* hdma_clks_per16*/
  247.   (8400000.0)/JOYPAD_FREQ_IN_CGB /* joypad_gen_freq*/
  248. };
  249.  
  250. struct romheader {
  251.   ks_uint8 title[16];
  252.   ks_uint16 curlic;
  253.   ks_uint8 sgb;
  254.   ks_uint8 ctype;
  255.   ks_uint8 promsize;
  256.   ks_uint8 ramsize;
  257.   ks_uint8 targetcode;
  258.   ks_uint8 anclic;
  259.   ks_uint8 maskver;
  260.   ks_uint8 hdcrc;
  261.   ks_uint16 gcrc;
  262. };
  263. struct controller  {
  264.   ks_uint8 reg00_P1;
  265.  
  266.   /* for gamebot update host keybuf and IRQ */
  267.   void (*clks) (struct controller *);
  268.  
  269.   void *obj;
  270.   void *ubdata_user;
  271.   /* pad infos for gameboy*.*/
  272.   struct controller_pad gb_pad;
  273.   struct gameboy *gb;
  274. };
  275.  
  276. struct cpu {
  277.   /*  XXX:memory order dep. don't set struct align!*/
  278.   union { struct { ks_uint8 F; ks_uint8 A; }; ks_uint16 AF; };
  279.   union { struct { ks_uint8 C; ks_uint8 B; }; ks_uint16 BC; };
  280.   union { struct { ks_uint8 E; ks_uint8 D; }; ks_uint16 DE; };
  281.   union { struct { ks_uint8 L; ks_uint8 H; }; ks_uint16 HL; };
  282.   union { struct { ks_uint8 SL; ks_uint8 SH; }; ks_uint16 SP; };
  283.   union { struct { ks_uint8 PL; ks_uint8 PH; }; ks_uint16 PC; };
  284.  
  285.    /* Interrupt Master Enable*/
  286.   ks_uint8 IME;
  287.  
  288.    /* for Halt */
  289.   ks_bool halt;  
  290.  
  291.    /* for stop */
  292.   ks_bool stop;
  293.  
  294.    /* for halt bug */
  295.   ks_int _backup;
  296.  
  297.    /* for speed mode */
  298.   ks_uint8 reg4D_key1;
  299.  
  300.    /* gameboy object  */
  301.   struct gameboy *gb;              
  302. };
  303. struct oam {
  304.   union {
  305.     struct {
  306.       ks_uint8 y;
  307.       ks_uint8 x;
  308.       ks_uint8 id;
  309.       ks_uint8 attr;
  310.     };
  311.     ks_uint8 blk[4];
  312.   };
  313. };
  314. struct pal {
  315.   union {
  316.     struct {
  317.       ks_uint8 _lo;
  318.       ks_uint8 _hi;
  319.     };
  320.     ks_uint16 rgb15;
  321.     ks_uint8 blk[2];
  322.   };
  323. };
  324.  
  325. /* for ppu:: spi_ca */
  326. #define PIXEL_SPRITE_NOTRANS 1
  327. #define PIXEL_SPRITE_BACK 2
  328.  
  329. /* LCDC Status MASK */
  330. #define LCDS_MODE_FLAG_HBLANK 0
  331. #define LCDS_MODE_FLAG_VLANK 1
  332. #define LCDS_MODE_FLAG_SERACH_OAM 2
  333. #define LCDS_MODE_FLAG_SERACH_OAMVRAM 3
  334. #define LCDS_MODE_FLAG_ALL_MASK 3
  335.  
  336. /* LCDC Status Interrupt MASK */
  337. #define LCDS_INTERRUPET_LINE_MASK 0x40
  338. #define LCDS_INTERRUPET_HBLANK_MASK 0x10
  339. #define LCDS_INTERRUPET_VBLANK_MASK 0x08
  340. #define LCDS_INTERRUPET_OAM_MASK 0x20
  341. #define LCDS_INTERRUPET_ALL_MASK (LCDS_INTERRUPET_LINE_MASK|LCDS_INTERRUPET_HBLANK_MASK|LCDS_INTERRUPET_VBLANK_MASK|LCDS_INTERRUPET_OAM_MASK)
  342.  
  343. /* LCDC Control MASK */
  344. #define LCDC_DISPLAY_MASK 0x80
  345. #define LCDC_WINDOW_MASK 0x20
  346. #define LCDC_OAM_SIZE16_MASK 0x04
  347. #define LCDC_OAM_MASK 0x02
  348.  
  349. #define LCD_OAM_FLIP_Y_MASK 0x40
  350. #define LCD_OAM_FLIP_X_MASK 0x20
  351. #define LCD_OAM_BACKGROUND_MASK 0x80
  352.  
  353. struct ppu {
  354.   ks_uint16 *bufb; /* for alignmem */
  355.   ks_uint8 ram[0x4000];  /* 8K for DMG, 16 for CGB */
  356.  
  357.   struct _oamlineframe /* sprite line buffer cache *.*/
  358.   {
  359.     ks_uint16 attr;
  360.     ks_uint16 pixel;
  361.   } olf[176];
  362.  
  363.   struct gameboy *gb;
  364.   struct oam sp[40];
  365.   struct pal bg_pal[8][4]; /* pal for CGB */
  366.   struct pal sp_pal[8][4]; /* pal for CGB */
  367.   struct ppu_framebuffer fmebuf;
  368.  
  369.   ks_uint16 bg_pal_dmg[4]; /* pal for DMG */
  370.   ks_uint16 sp_pal_dmg[2][4]; /* pal for DMG */
  371.  
  372.   ks_uint16 bg_pal_dmgT[4]; /* pal for DMG */
  373.   ks_uint16 sp_pal_dmgT[2][4]; /* pal for DMG */
  374.  
  375.   ks_uint8 reg40_LCDC;
  376.   ks_uint8 reg40_NMIf;
  377.   ks_uint8 reg41_LCDS;  
  378.   ks_uint8 reg41_LCDM_T;
  379.   ks_uint8 reg41_IRQf;
  380.   ks_uint8 reg42_SCY;
  381.   ks_uint8 reg43_SCX;    
  382.   ks_uint8 reg44_LY;
  383.   ks_uint8 reg44_LY_T;
  384.   ks_uint8 reg45_LYC;
  385.   ks_uint8 reg46_DMA;
  386.   ks_uint8 reg47_BGP;
  387.   ks_uint8 reg48_OBP0;
  388.   ks_uint8 reg49_OBP1;
  389.   ks_uint8 reg4A_WY;
  390.   ks_uint8 reg4A_WYRSC;
  391.   ks_uint8 reg4A_WYLineHit;
  392.   ks_uint8 reg4B_WX;
  393.   ks_uint8 reg4F_VBK;
  394.   ks_uint8 reg51_HDMA1;
  395.   ks_uint8 reg52_HDMA2;
  396.   ks_uint8 reg53_HDMA3;
  397.   ks_uint8 reg54_HDMA4;
  398.   ks_uint8 reg55_HDMA5;
  399.   ks_uint8 reg68_BCPS;
  400.   ks_uint8 reg69_BCPD;
  401.   ks_uint8 reg6A_OCPS;
  402.   ks_uint8 reg6B_OCPD;
  403.  
  404.   ks_int32 vscan;
  405.   ks_int32 vscanR;
  406.   ks_int32 vscan40;
  407.   ks_int32 xscanR;
  408.   ks_int32 uscan;
  409.   ks_int32 uscanR;
  410.  
  411.   ks_bool hdma_gen;
  412.  
  413.   ks_uint16 hdma_src;
  414.   ks_uint16 hdma_dst;
  415.   ks_uint16 hdma_r16;
  416.  
  417.   ks_double hdma_clk;
  418.   ks_double hbl_clks_st;
  419.   ks_double oambg_clks_divider21;
  420.  
  421.   void (*bgwin_done) (struct ppu *_5028, ks_int16 scanline);
  422.   void (*sprite_done) (struct ppu *_5028, ks_int delta);
  423.   void (*device_blit) (struct ppu *_5028, void *obj, struct ppu_framebuffer *fbuf); /*blit for host devcice */
  424.  
  425.   void *obj;
  426.   void (*clks) (struct ppu *);
  427. };
  428. struct gameboy {
  429.   struct controller *joypad;
  430.   struct cpu *lr35902;
  431.   struct ppu *lh5028;
  432.   struct apu *apu;
  433.   struct cartridge *cart;
  434.   struct divider *divider;
  435.   struct timer *timer;
  436.   struct serial *serial;
  437.   struct machine_setup *mach_tools;
  438.  
  439.   ks_double cpu_clks;
  440.   ks_double cpu_clks_total;
  441.   ks_double cpu_clks_timer; // cur full - block
  442.   ks_double cpu_clks_timerdbg; // cur full - block
  443.   ks_double cpu_clks_joypad; // cur full - block
  444.   ks_double cpu_clks_divider; // cur full - block
  445.   ks_double cpu_clks_ppu; // cur full - block
  446.   ks_double cpu_clks_apu; // cur full - block
  447.   ks_double cpu_clks_cart; // cur full - block
  448.   ks_double cpu_clks_serial; // RS232 Serial Port for CGB/ DMG.
  449.   ks_double cpu_clks_dma;
  450.   ks_double deflect_ms;
  451.  
  452.   ks_uint8 reg01_SB;
  453.   ks_uint8 reg02_SC;
  454.  
  455.   ks_uint8 reg0F_IF; /* interrupt flags register */
  456.   ks_uint8 reg56_IC;
  457.   ks_uint8 reg70_SVBK;
  458.   ks_uint8 regFF_IE; /* Interrupt enable register */
  459.  
  460.   /* work ram. */
  461.   ks_uint8 wram[0x8000];
  462.   /* high ram. */
  463.   ks_uint8 hram[0x200];
  464.   /* unknow mem, io read/write */
  465.   ks_uint8 unknow_ram[0x10000];
  466.  
  467.   /* controller drv */
  468.   void (*controller_hostdrv)
  469.              (struct gameboy *, void *controller_drvobj,
  470.                 struct controller_pad *, /* gb-self for recv joypadbuffer */
  471.              struct controller_pad * /* host-edge 1?pulse gen:nodone */);
  472.   void *controller_drvobj;
  473.  
  474.   /* display drv */
  475.   void (*display_hostdrv)
  476.              (struct gameboy *, void *display_drvobj,
  477.                 struct ppu_framebuffer *fmebuf);
  478.   void *display_drvobj;
  479.   /* sound drv */
  480.  
  481.  
  482. };
  483. struct timer {
  484.   ks_uint8 reg05_TIMA;
  485.   ks_uint8 reg06_TMA;
  486.   ks_uint8 reg07_TAC;
  487.   ks_double freq_tab[4];
  488.  
  489.   void (*clks) (struct timer *);
  490.   ks_double timestamp;
  491.  
  492.   struct gameboy *gb;
  493. };
  494. struct divider {
  495.   ks_uint8 reg04_DIV;
  496.   ks_double freq;
  497.  
  498.   void (*clks) (struct divider *);
  499.   ks_double timestamp;
  500.   struct gameboy *gb;
  501. };
  502.  
  503. struct apu {
  504.  
  505.   ks_uint8 reg10_NR10;
  506.   ks_uint8 reg11_NR11;
  507.   ks_uint8 reg12_NR12;
  508.   ks_uint8 reg13_NR13;
  509.   ks_uint8 reg14_NR14;
  510.   ks_uint8 reg16_NR21;
  511.   ks_uint8 reg17_NR22;
  512.   ks_uint8 reg18_NR23;
  513.   ks_uint8 reg19_NR24;
  514.   ks_uint8 reg1A_NR30;
  515.   ks_uint8 reg1B_NR31;
  516.   ks_uint8 reg1C_NR32;
  517.   ks_uint8 reg1D_NR33;
  518.   ks_uint8 reg1E_NR34;
  519.   ks_uint8 reg20_NR41;
  520.   ks_uint8 reg21_NR42;
  521.   ks_uint8 reg22_NR43;
  522.   ks_uint8 reg23_NR44;
  523.   ks_uint8 reg24_NR50;
  524.   ks_uint8 reg25_NR51;
  525.   ks_uint8 reg26_NR52;
  526.   ks_uint8 reg30_AUD3WAVERAM;
  527.   ks_uint8 reg31_AUD3WAVERAM;
  528.   ks_uint8 reg32_AUD3WAVERAM;
  529.   ks_uint8 reg33_AUD3WAVERAM;
  530.   ks_uint8 reg34_AUD3WAVERAM;
  531.   ks_uint8 reg35_AUD3WAVERAM;
  532.   ks_uint8 reg36_AUD3WAVERAM;
  533.   ks_uint8 reg37_AUD3WAVERAM;
  534.   ks_uint8 reg38_AUD3WAVERAM;
  535.   ks_uint8 reg39_AUD3WAVERAM;
  536.   ks_uint8 reg3A_AUD3WAVERAM;
  537.   ks_uint8 reg3B_AUD3WAVERAM;
  538.   ks_uint8 reg3C_AUD3WAVERAM;
  539.   ks_uint8 reg3D_AUD3WAVERAM;
  540.   ks_uint8 reg3E_AUD3WAVERAM;
  541.   ks_uint8 reg3F_AUD3WAVERAM;
  542.   ks_uint8 reg76_PCMChannel1_2;
  543.   ks_uint8 reg77_PCMChannel3_4;
  544.  
  545.   void (*clks) (struct apu *);
  546.   struct gameboy *gb;
  547. };
  548. struct serial {
  549.   void (*clks) (struct serial *);
  550.   struct gameboy *gb;
  551. };
  552.  
  553. /* cartridge device type */
  554. #define MBC_0 0
  555. #define MBC_1 1
  556. #define MBC_2 2
  557. #define MBC_3 3
  558. #define MBC_4 4
  559. #define MBC_5 5
  560. #define MBC_6 6
  561. #define MBC_7 7
  562. #define TAMA5 8
  563. #define HUCL1 9
  564. #define HUCL3 10
  565. #define MMM0 11
  566. #define POCKER_CAM 12
  567.  
  568. /* MBC1 */
  569. #define MBC1_MODE0_2MROM_8KRAM 0
  570. #define MBC1_MODE1_512KROM_32KRAM 1
  571. typedef int mbc1_cart_mode;
  572.  
  573. struct mbc1_chip {
  574.   mbc1_cart_mode mode;
  575.   ks_bool ram_en;
  576.   ks_uint16 prombank;
  577.   ks_uint16 srambank;
  578.   ks_uint16 bankcac;
  579. };
  580. struct cartridge {
  581.   struct romheader header;
  582.   ks_bool s_latch;
  583.   ks_bool battery;
  584.   ks_uint8 *promworks;
  585.   ks_uint8 *sramworks;
  586.   ks_uint8 promsize;
  587.   ks_uint8 sramsize;
  588.  
  589.   void (*clks) (struct cartridge *);
  590.   ks_uint8 (*read) (struct cartridge *cartridge, ks_uint16 address);
  591.   ks_void (*write) (struct cartridge *cartridge, ks_uint16 address, ks_uint8 value);
  592.  
  593.   union {
  594.     struct mbc1_chip *mbc1;
  595.     void *ubdata_user;
  596.   };
  597.   struct gameboy *gb;    
  598. };
  599.  
  600. #define IRQ_1 0x01  /*  VBLANK (NMI)  */
  601. #define IRQ_2 0x02  /*  LCDC  */
  602. #define IRQ_3 0x04  /*  Programmable timer */
  603. #define IRQ_4 0x08  /*  Serial port switching */
  604. #define IRQ_5 0x10  /*  P14-15 Descent edge acknowledge */
  605. #define IRQ_NIL 0xFF  /*  P14-15 Descent edge acknowledge */
  606.  
  607. #define IRQ_1_ADDRESS 0x40 /*  VBLANK (NMI)  */
  608. #define IRQ_2_ADDRESS 0x48 /*  LCDC  */
  609. #define IRQ_3_ADDRESS 0x50 /*  Programmable timer */
  610. #define IRQ_4_ADDRESS 0x58 /*  Serial port switching */
  611. #define IRQ_5_ADDRESS 0x60 /*  P14-15 Descent edge acknowledge */
  612.  
  613. /* gameboy internal done **/
  614. int gameboy_resume_ifstop (struct gameboy *gb);
  615. double gameboy_getcycles (struct gameboy *gb);
  616. double gameboy_get_ppuclks (struct gameboy *gb, ks_bool *stride_frame);
  617. void gameboy_setcycles (struct gameboy *gb, double cycles);
  618. ks_uint8 ks_callstd gameboy_mmu_read (struct gameboy *gb, ks_uint16 address);
  619. ks_uint16 ks_callstd gameboy_mmu_read_w (struct gameboy *gb, ks_uint16 address);
  620. ks_void ks_callstd gameboy_mmu_write (struct gameboy *gb, ks_uint16 address, ks_uint8 value);
  621. ks_void ks_callstd gameboy_mmu_write_w (struct gameboy *gb, ks_uint16 address, ks_uint16 value);
  622. int gameboy_resume_ifstop (struct gameboy *gb);
  623. int  gameboy_hdma_copy (struct gameboy *gb);
  624.  
  625. #endif
  626. /* controller (PL0-PL5, with DAN215)
  627.  * Game boy's joypad information read and write
  628.  *
  629.  * Copyright (C) 2018 moecmks
  630.  * This file is part of KS3578.
  631.  *
  632.  * do What The Fuck you want to Public License
  633.  *
  634.  * Version 1.0, March 2000
  635.  * Copyright (C) 2000 Banlu Kemiyatorn (]d).
  636.  * 136 Nives 7 Jangwattana 14 Laksi Bangkok
  637.  * Everyone is permitted to copy and distribute verbatim copies
  638.  * of this license document, but changing it is not allowed.
  639.  *
  640.  * Ok, the purpose of this license is simple
  641.  * and you just
  642.  *
  643.  * DO WHAT THE FUCK YOU WANT TO.
  644.  */
  645.  
  646. #include "gameboy.h"
  647. #include "internal.h"
  648.  
  649. /* for internal call */
  650. #define joypad_hostdrv ubdata_user
  651.  
  652. /* Assert IRQ_5 Interrupt Gen MACRO */
  653. #ifndef IRQ_5
  654. # define IRQ_5 0x10
  655. #endif
  656.  
  657. #ifndef JOYPAD_INTERRUPT_GEN_ENABLE
  658. # undef IRQ_5
  659. # define IRQ_5 0
  660. #endif
  661.  
  662. static
  663. void default_update (struct controller *ctl, void *obj, struct controller_pad *gb_infos, struct controller_pad *host_infos) {
  664.   printf ("%s:%s please set joypad callback( controller_setupdate function)\n", __FILE__, __LINE__);
  665.   assert (0);
  666. }
  667.  
  668. void controller_write (struct controller *ctl, ks_uint8 value) {
  669.   ctl->reg00_P1 = value & 0x30;
  670. }
  671.  
  672. /* Gameboy Joypad Infos:http://gbdev.gg8.se/files/docs/mirrors/pandocs.html#joypadinput */
  673. ks_uint8 controller_read (struct controller *ctl) {
  674.   ks_uint8 value =ctl->reg00_P1 & 0x30;
  675.   switch (value) {
  676.   case 0x00: /* maybe result direction | action ??*/
  677.     value = ctl->reg00_P1 & 0xF0;
  678.     value|= 0x0F;
  679. #if (JOYPAD_LOAD_ACTION_IN_P1415_ALLOPEN == 0)
  680.     if (ctl->gb_pad.right || ctl->gb_pad.a) value &= ~0x01; /*Right ||A*/
  681.     if (ctl->gb_pad.left || ctl->gb_pad.b) value &= ~0x02; /*Left ||B */
  682.     if (ctl->gb_pad.up || ctl->gb_pad.select) value &= ~0x04; /*Up ||Select */
  683.     if (ctl->gb_pad.down || ctl->gb_pad.start) value &= ~0x08; /*Down || Start*/
  684. #elif (JOYPAD_LOAD_ACTION_IN_P1415_ALLOPEN == 1)
  685.     if (ctl->gb_pad.right && ctl->gb_pad.a) value &= ~0x01; /*Right ||A*/
  686.     if (ctl->gb_pad.left && ctl->gb_pad.b) value &= ~0x02; /*Left ||B */
  687.     if (ctl->gb_pad.up && ctl->gb_pad.select) value &= ~0x04; /*Up ||Select */
  688.     if (ctl->gb_pad.down && ctl->gb_pad.start) value &= ~0x08; /*Down || Start*/
  689. #elif (JOYPAD_LOAD_ACTION_IN_P1415_ALLOPEN == 2)
  690.     if ((!!ctl->gb_pad.right) ^ !!ctl->gb_pad.a) value &= ~0x01; /*Right ||A*/
  691.     if ((!!ctl->gb_pad.left) ^ !!ctl->gb_pad.b) value &= ~0x02; /*Left ||B */
  692.     if ((!!ctl->gb_pad.up) ^ !!ctl->gb_pad.select) value &= ~0x04; /*Up ||Select */
  693.     if ((!!ctl->gb_pad.down) ^ !!ctl->gb_pad.start) value &= ~0x08; /*Down || Start*/
  694. #elif (JOYPAD_LOAD_ACTION_IN_P1415_ALLOPEN == 3)
  695.     if (!(ctl->gb_pad.right && ctl->gb_pad.a)) value &= ~0x01; /*Right ||A*/
  696.     if (!(ctl->gb_pad.left && ctl->gb_pad.b)) value &= ~0x02; /*Left ||B */
  697.     if (!(ctl->gb_pad.up && ctl->gb_pad.select)) value &= ~0x04; /*Up ||Select */
  698.     if (!(ctl->gb_pad.down && ctl->gb_pad.start)) value &= ~0x08; /*Down || Start*/
  699. #else
  700. # error "JOYPAD_LOAD_ACTION_IN_P1415_ALLOPEN define error."
  701. #endif
  702.     break;
  703.   case 0x30: /* reset device ?*/
  704.     return 0xFF;
  705.   case 0x20: /* p14 out, set button, active low*/
  706.     value = ctl->reg00_P1 & 0xF0;
  707.     value|= 0x0F;
  708.     if (ctl->gb_pad.right) value &= ~0x01; /*Right */
  709.     if (ctl->gb_pad.left) value &= ~0x02; /*Left */
  710.     if (ctl->gb_pad.up) value &= ~0x04; /*Up */
  711.     if (ctl->gb_pad.down) value &= ~0x08; /*Down */
  712.     break;
  713.   case 0x10: /* p15 out, set direction, active low */
  714.     value = ctl->reg00_P1 & 0xF0;
  715.     value|= 0x0F;
  716.     if (ctl->gb_pad.a) value &= ~0x01; /*A */
  717.     if (ctl->gb_pad.b) value &= ~0x02; /*B */
  718.     if (ctl->gb_pad.select) value &= ~0x04; /*Select */
  719.     if (ctl->gb_pad.start) value &= ~0x08; /*Start */
  720.     break;
  721.   }
  722.   return value;
  723. }
  724.  
  725. void controller_uninit (struct controller **ctl) {
  726.   struct controller *ctl_;
  727.   assert (ctl != ks_null);
  728.   ctl_ = *ctl;
  729.   *ctl = ks_null;
  730.   if (ctl_ != ks_null)
  731.     free (ctl_);
  732.   else ;
  733. }
  734.  
  735. void controller_setupdate_ (struct controller *ctl, void (*update)
  736.              (struct controller *,
  737.              void *,
  738.                 struct controller_pad *, /* self */
  739.              struct controller_pad * /* host edge */), void *obj){
  740.   assert (ctl != ks_null);
  741.   assert (update != ks_null);
  742.   ctl->joypad_hostdrv = update;
  743.   ctl->obj = obj;
  744. }
  745.  
  746. static
  747. void controller_update_hostdrv (struct controller *ctl) {
  748.  
  749.   if (ctl->gb->cpu_clks_joypad > ctl->gb->mach_tools->joypad_gen_freq) {
  750.     ks_bool edge_gen =ks_false;
  751.     /* temrp cache for check edge (high to low*/
  752.     struct controller_pad edge;
  753.     assert (ctl != ks_null);
  754.     memset (& edge, 0, sizeof (edge));
  755.     /*call hostdrv*/
  756.     ((void (*)(struct controller *, void *,
  757.                   struct controller_pad *,
  758.          struct controller_pad *))(ctl->joypad_hostdrv)) (ctl, ctl->obj, & ctl->gb_pad, & edge);
  759.     ctl->gb->cpu_clks_joypad -= ctl->gb->mach_tools->joypad_gen_freq; /* sub a clk block */
  760.     /* there is a bouncing phenomenon similar to electrical components flutter in real gameboy,
  761.        making joypad interrupt very difficult to use. */
  762.     /* check register */
  763.     switch (ctl->reg00_P1 & 0x30) {
  764.     case 0x30: /* close device*/
  765.       return ;
  766.     case 0x00: /* any button press will cause interrupt requested, resume stop command */
  767.       if (edge.right || edge.a) edge_gen = ks_true; /*Right ||A*/
  768.       if (edge.left || edge.b) edge_gen = ks_true; /*Left ||B */
  769.       if (edge.up || edge.select) edge_gen = ks_true; /*Up ||Select */
  770.       if (edge.down || edge.start) edge_gen = ks_true; /*Down || Start*/
  771.     case 0x20: /* p14 out, button, */
  772.       if (edge.right) edge_gen = ks_true; /*Right */
  773.       if (edge.left) edge_gen = ks_true; /*Left */
  774.       if (edge.up) edge_gen = ks_true; /*Up */
  775.       if (edge.down) edge_gen = ks_true; /*Down */
  776.       break;
  777.     case 0x10: /* p15 out, direction */
  778.       if (edge.a) edge_gen = ks_true; /*A */
  779.       if (edge.b) edge_gen = ks_true; /*B */
  780.       if (edge.select) edge_gen = ks_true; /*Select */
  781.       if (edge.start) edge_gen = ks_true; /*Start */
  782.       break;
  783.     }
  784.     if (edge_gen != ks_false) {
  785.       /* Set interrupt flags */
  786.   #   if 1
  787.       /* try resume gameboy from stop,  (if stop) */
  788.       if (ctl->gb->lr35902->stop != ks_false) {
  789.         ctl->gb->lr35902->stop = ks_false;
  790.         ctl->gb->reg0F_IF |= IRQ_5;
  791.       }
  792.   #   else
  793.       /* IRQ_5 is the lowest priority interruption.*/
  794.       ctl->gb->reg0F_IF |= IRQ_5;
  795.       /* try resume gameboy from stop,  (if stop) */
  796.       gameboy_resume_ifstop (ctl->gb);
  797.   #   endif
  798.     }
  799.   }
  800. }
  801.  
  802. int controller_init (struct controller **ctl) {
  803.   struct controller *ctl_ =ks_null;
  804.   assert (ctl != ks_null);
  805.  
  806.   ctl_ = (struct controller *)
  807.      calloc (sizeof (struct controller), 1);
  808.   ctl_->joypad_hostdrv = default_update;
  809.   ctl_->obj = ks_null;
  810.   ctl_->clks = controller_update_hostdrv;
  811.   assert (ctl_ != ks_null);
  812.   // memset (& ctl_->gb_pad, 0x01, sizeof (ctl_->gb_pad));
  813.   * ctl = ctl_;
  814.   return 0;
  815. }
  816. /* Game boy's GPU and LCD Screen
  817.  * LCD is Sharp LH5028 http://www.datasheetarchive.com/pdf/download.php?id=c615e5d8551c6b559c3db61b709b3234af856c&type=O&term=LH5028
  818.  *
  819.  * This part of the source code is actually not very good.
  820.  * It looks terrible.
  821.  *
  822.  * Copyright (C) 2018 moecmks
  823.  * This file is part of KS3578.
  824.  *
  825.  * do What The Fuck you want to Public License
  826.  *
  827.  * Version 1.0, March 2000
  828.  * Copyright (C) 2000 Banlu Kemiyatorn (]d).
  829.  * 136 Nives 7 Jangwattana 14 Laksi Bangkok
  830.  * Everyone is permitted to copy and distribute verbatim copies
  831.  * of this license document, but changing it is not allowed.
  832.  *
  833.  * Ok, the purpose of this license is simple
  834.  * and you just
  835.  *
  836.  * DO WHAT THE FUCK YOU WANT TO.
  837.  */
  838.  
  839. #include "gameboy.h"
  840. #include "internal.h"
  841.  
  842. static
  843. void default_update (struct ppu *_5028, void *obj, struct ppu_framebuffer *fbuf) {
  844.   printf ("%s:%s please set ppu_update callback( controller_setupdate function)\n", __FILE__, __LINE__);
  845.   assert (0);
  846. }
  847.  
  848. void ppu_setupdate_ (struct ppu *lh5028, void (*update)
  849.             (struct ppu *,
  850.             void *,
  851.               struct ppu_framebuffer *), void *obj)
  852. {
  853.   lh5028->device_blit = update;
  854.   lh5028->obj = obj;
  855. }
  856.  
  857. int ppu_reset (struct ppu *lh5028) {
  858.  
  859.   /* init register http://gbdev.gg8.se/files/docs/mirrors/pandocs.html#powerupsequence */
  860.   lh5028->reg40_LCDC = 0x91;
  861.   lh5028->reg42_SCY = 0x00;
  862.   lh5028->reg43_SCX = 0x00;
  863.   lh5028->reg45_LYC = 0x00;
  864.   lh5028->reg47_BGP = 0xFC;
  865.   lh5028->reg48_OBP0 = 0xFF;
  866.   lh5028->reg49_OBP1 = 0xFF;
  867.   lh5028->reg4A_WY = 0x00;
  868.   lh5028->reg4B_WX = 0x00;
  869.   /* reset cache */
  870.   lh5028->reg41_LCDM_T = lh5028->reg41_LCDS;
  871.  
  872.   lh5028->hbl_clks_st = 9999.8;
  873.   return 0;
  874. }
  875.  
  876. void ppu_uninit (struct ppu **lh5028);
  877.  
  878. void ppu_write (struct ppu *lh5028, ks_uint16 address, ks_uint8 value) {
  879.  
  880.   ks_uint8 c, s;
  881.   switch (address) {
  882.   case 0xFF40: /* FF40 - LCDC - LCD Control (R/W) **/
  883.     /*Bit 7 - LCD Display Enable             (0=Off, 1=On)
  884.       Bit 6 - Window Tile Map Display Select (0=9800-9BFF, 1=9C00-9FFF)
  885.       Bit 5 - Window Display Enable          (0=Off, 1=On)
  886.       Bit 4 - BG & Window Tile Data Select   (0=8800-97FF, 1=8000-8FFF)
  887.       Bit 3 - BG Tile Map Display Select     (0=9800-9BFF, 1=9C00-9FFF)
  888.       Bit 2 - OBJ (Sprite) Size              (0=8x8, 1=8x16)
  889.       Bit 1 - OBJ (Sprite) Display Enable    (0=Off, 1=On)
  890.       Bit 0 - BG/Window Display/Priority     (0=Off, 1=On)
  891.      */
  892.     if (!(lh5028->reg40_LCDC & LCDC_DISPLAY_MASK)&& (value & LCDC_DISPLAY_MASK)) {
  893.       /* re-enable display */
  894. #   if 0
  895.       lh5028->gb->cpu_clks_ppu = 0.0;
  896.       lh5028->reg41_LCDM_T =LCDS_MODE_FLAG_SERACH_OAM;
  897.       lh5028->reg41_IRQf |= LCDS_INTERRUPET_ALL_MASK;
  898.       lh5028->reg41_LCDS &= ~3;
  899.       lh5028->reg41_LCDS |= LCDS_MODE_FLAG_SERACH_OAM;
  900.       lh5028->reg40_NMIf = 1;
  901.       lh5028->vscan = -1;
  902.       lh5028->vscanR = 0;
  903.       lh5028->vscan40 = 0;
  904.       lh5028->uscan = -1;
  905.       lh5028->uscanR = 0;
  906.       lh5028->win_stuff = ks_false;
  907.       lh5028->hbl_clks_st = 9999.8;
  908.       lh5028->reg44_LY = 0;
  909.  
  910. #   endif
  911.       lh5028->reg4A_WYRSC = 0;
  912.     }
  913.     if (!(value & LCDC_DISPLAY_MASK))
  914.       lh5028->reg44_LY = 0;
  915.     else ;
  916.     lh5028->reg40_LCDC = value;
  917.     break;
  918.   case 0xFF41: /* FF41 - STAT - LCDC Status (R/W) */
  919.     /*Bit 6 - LYC=LY Coincidence Interrupt (1=Enable) (Read/Write)
  920.       Bit 5 - Mode 2 OAM Interrupt         (1=Enable) (Read/Write)
  921.       Bit 4 - Mode 1 V-Blank Interrupt     (1=Enable) (Read/Write)
  922.       Bit 3 - Mode 0 H-Blank Interrupt     (1=Enable) (Read/Write)
  923.       Bit 2 - Coincidence Flag  (0:LYC<>LY, 1:LYC=LY) (Read Only)
  924.       Bit 1-0 - Mode Flag                             (Read Only)
  925.               0: During H-Blank
  926.               1: During V-Blank
  927.               2: During Searching OAM
  928.               3: During Transferring Data to LCD Driver
  929.     */
  930.     lh5028->reg41_LCDS &= 7;
  931.     lh5028->reg41_LCDS |= (value & ~7);
  932.     break;
  933.   case 0xFF42: /* FF42 - SCY - Scroll Y (R/W) */
  934.     lh5028->reg42_SCY = value;
  935.     break;
  936.   case 0xFF43: /* FF43 - SCX - Scroll X (R/W) */
  937.     lh5028->reg43_SCX = value;
  938.     break;
  939.   case 0xFF44: /* FF44 - LY - LCDC Y-Coordinate (R) */
  940.     _DEBUG_BREAK();
  941.     break;
  942.   case 0xFF45: /* FF45 - LYC - LY Compare (R/W) */
  943.     lh5028->reg45_LYC = value;
  944.     break;
  945.   case 0xFF4A: /* FF4A - WY - Window Y Position (R/W) */
  946.     lh5028->reg4A_WY = value;
  947.     break;
  948.   case 0xFF4B: /* FF4B - WX - Window X Position minus 7 (R/W) */
  949.     lh5028->reg4B_WX = value;
  950.     break;
  951.   case 0xFF47: /* FF47 - BGP - BG Palette Data (R/W) - Non CGB Mode Only */
  952.     // value = 0xE8;
  953.     lh5028->bg_pal_dmg[0] = lh5028->bg_pal_dmgT[(value & 0x03) >> 0];
  954.     lh5028->bg_pal_dmg[1] = lh5028->bg_pal_dmgT[(value & 0x0C) >> 2];
  955.     lh5028->bg_pal_dmg[2] = lh5028->bg_pal_dmgT[(value & 0x30) >> 4];
  956.     lh5028->bg_pal_dmg[3] = lh5028->bg_pal_dmgT[(value & 0xC0) >> 6];
  957.     lh5028->reg47_BGP = value;
  958.     break ;
  959.   case 0xFF48: /* FF48 - OBP0 - Object Palette 0 Data (R/W) - Non CGB Mode Only */
  960.     lh5028->sp_pal_dmg[0][0] = lh5028->sp_pal_dmgT[0][(value & 0x03) >> 0];
  961.     lh5028->sp_pal_dmg[0][1] = lh5028->sp_pal_dmgT[0][(value & 0x0C) >> 2];
  962.     lh5028->sp_pal_dmg[0][2] = lh5028->sp_pal_dmgT[0][(value & 0x30) >> 4];
  963.     lh5028->sp_pal_dmg[0][3] = lh5028->sp_pal_dmgT[0][(value & 0xC0) >> 6];
  964.     lh5028->reg48_OBP0 = value;
  965.     break ;
  966.   case 0xFF49: /* FF49 - OBP1 - Object Palette 1 Data (R/W) - Non CGB Mode Only */
  967.     lh5028->sp_pal_dmg[1][0] = lh5028->sp_pal_dmgT[1][(value & 0x03) >> 0];
  968.     lh5028->sp_pal_dmg[1][1] = lh5028->sp_pal_dmgT[1][(value & 0x0C) >> 2];
  969.     lh5028->sp_pal_dmg[1][2] = lh5028->sp_pal_dmgT[1][(value & 0x30) >> 4];
  970.     lh5028->sp_pal_dmg[1][3] = lh5028->sp_pal_dmgT[1][(value & 0xC0) >> 6];
  971.     lh5028->reg49_OBP1 = value;
  972.     break ;
  973.   case 0xFF68: /* FF68 - BCPS/BGPI - CGB Mode Only - Background Palette Index */
  974.     lh5028->reg68_BCPS = value;
  975.     break ;
  976.   case 0xFF69: /* FF69 - BCPD/BGPD - CGB Mode Only - Background Palette Data */
  977.     s = lh5028->reg68_BCPS;
  978.     c = s & 0x3F;
  979.     if (c & 1)
  980.       lh5028->bg_pal[c >> 3][(c & 7) >> 1]._hi = value;
  981.     else
  982.       lh5028->bg_pal[c >> 3][(c & 7) >> 1]._lo = value;
  983.     if (s & 0x80) {
  984.       c = (c + 1) & 0x3F;
  985.       lh5028->reg68_BCPS &= ~0x3F;
  986.       lh5028->reg68_BCPS |= c;
  987.     }
  988.     lh5028->reg69_BCPD = value;
  989.     break;
  990.   case 0xFF6A: /* FF6A - OCPS/OBPI - CGB Mode Only - Sprite Palette Index */
  991.     lh5028->reg6A_OCPS = value;
  992.     break;
  993.   case 0xFF6B: /* FF6B - OCPD/OBPD - CGB Mode Only - Sprite Palette Data */
  994.     s = lh5028->reg6A_OCPS;
  995.     c = s & 0x3F;
  996.     if (c & 1)
  997.       lh5028->sp_pal[c >> 3][(c & 7) >> 1]._hi = value;
  998.     else
  999.       lh5028->sp_pal[c >> 3][(c & 7) >> 1]._lo = value;
  1000.     if (s & 0x80) {
  1001.       c = (c + 1) & 0x3F;
  1002.       lh5028->reg6A_OCPS &= ~0x3F;
  1003.       lh5028->reg6A_OCPS |= c;
  1004.     }
  1005.     lh5028->reg6B_OCPD = value;
  1006.     break;
  1007.   case 0xFF46: /* FF46 - DMA - DMA Transfer and Start Address (R/W) */
  1008.     for (c = 0; c != 160; c++) {
  1009.       s = gameboy_mmu_read (lh5028->gb, value * 256 + c);
  1010.       ((ks_int8 *)& lh5028->sp[0])[c] = s;
  1011.     }
  1012.     /* OAMDMA ~ 160 us
  1013.        OAMDMA is a parallel DMA */
  1014.     /* lh5028->gb->cpu_clks_dma += lh5028->gb->mach_tools->oamdma_clks; */
  1015.     lh5028->reg46_DMA = value;
  1016.     break ;
  1017.   case 0xFF51: /* FF51 - HDMA1 - CGB Mode Only - New DMA Source, High */
  1018.     lh5028->reg51_HDMA1 = value;
  1019.     break;
  1020.   case 0xFF52: /* FF52 - HDMA2 - CGB Mode Only - New DMA Source, Low*/
  1021.     lh5028->reg52_HDMA2 = value;
  1022.     break;
  1023.   case 0xFF53: /* FF53 - HDMA3 - CGB Mode Only - New DMA Destination, High */
  1024.     lh5028->reg53_HDMA3 = value;
  1025.     break;
  1026.   case 0xFF54: /* FF54 - HDMA4 - CGB Mode Only - New DMA Destination, Low*/
  1027.     lh5028->reg54_HDMA4 = value;
  1028.     break;
  1029.   case 0xFF55: /* FF55 - HDMA5 - CGB Mode Only - New DMA Length/Mode/Start */
  1030.     if (value & 0x80) {
  1031.       /* H-Blank DMA. **/
  1032.       lh5028->hdma_src = lh5028->reg51_HDMA1 * 256 + lh5028->reg52_HDMA2;
  1033.       lh5028->hdma_dst = lh5028->reg53_HDMA3 * 256 + lh5028->reg54_HDMA4;
  1034.       lh5028->hdma_src &= 0xFFF0;
  1035.       lh5028->hdma_dst &= 0xFFF0;
  1036.       lh5028->hdma_r16 = value & 0x7F;
  1037.       lh5028->hdma_r16 ++;
  1038.       lh5028->hdma_gen = ks_true;
  1039.       /* set HDMA uncompelete/active */
  1040.       lh5028->reg55_HDMA5 &= 0x7F;
  1041.     } else {
  1042.       /* GDMA **/
  1043.      
  1044.       ks_uint16 src = lh5028->reg51_HDMA1 * 256 + lh5028->reg52_HDMA2;
  1045.       ks_uint16 dst = lh5028->reg53_HDMA3 * 256 + lh5028->reg54_HDMA4;
  1046.       ks_uint16 id = 0;
  1047.       ks_uint16 K;
  1048.  
  1049.       src &= 0xFFF0;
  1050.       dst &= 0xFFF0;
  1051.       K = value & 0x7F;
  1052.       K+= 1;
  1053.       /* copy it*/
  1054.       for (; id != K; id++) {
  1055.         ks_uint16 c;
  1056.         for (c =0; c != 16; c++) {
  1057.           s = gameboy_mmu_read (lh5028->gb, src + id *16 + c);
  1058.           gameboy_mmu_write (lh5028->gb, dst + id *16 + c, s);
  1059.         }
  1060.       }
  1061.       /* burning OAM clks */
  1062.       /* It takes (220 + (n * 7.63)) microseconds in single speed
  1063.          and (110 + (n * 7.63)) microseconds in double speed mode */
  1064.       lh5028->gb->cpu_clks_dma += (lh5028->gb->mach_tools->gdma_clks_b
  1065.         + lh5028->gb->mach_tools->gdma_clks_per16 * (ks_double) K);
  1066.       /* lh5028->reg55_HDMA5 |= 0x80;/* set GDMA compelete/unactive */
  1067.     }
  1068.     lh5028->reg55_HDMA5 = value;
  1069.     break;
  1070.   case 0xFF4F: /* FF4F - VBK - CGB Mode Only - VRAM Bank (R/W) */
  1071.     lh5028->reg4F_VBK = value;
  1072.     break;
  1073.   default:
  1074.     return;
  1075.   }
  1076. }
  1077.  
  1078. ks_uint8 ppu_read (struct ppu *lh5028, ks_uint16 address) {
  1079.  
  1080.   switch (address) {
  1081.   case 0xFF40: /* FF40 - LCDC - LCD Control (R/W) **/
  1082.     /*Bit 7 - LCD Display Enable             (0=Off, 1=On)
  1083.       Bit 6 - Window Tile Map Display Select (0=9800-9BFF, 1=9C00-9FFF)
  1084.       Bit 5 - Window Display Enable          (0=Off, 1=On)
  1085.       Bit 4 - BG & Window Tile Data Select   (0=8800-97FF, 1=8000-8FFF)
  1086.       Bit 3 - BG Tile Map Display Select     (0=9800-9BFF, 1=9C00-9FFF)
  1087.       Bit 2 - OBJ (Sprite) Size              (0=8x8, 1=8x16)
  1088.       Bit 1 - OBJ (Sprite) Display Enable    (0=Off, 1=On)
  1089.       Bit 0 - BG/Window Display/Priority     (0=Off, 1=On)
  1090.      */
  1091.     return lh5028->reg40_LCDC;
  1092.   case 0xFF41: /* FF41 - STAT - LCDC Status (R/W) */
  1093.     /*Bit 6 - LYC=LY Coincidence Interrupt (1=Enable) (Read/Write)
  1094.       Bit 5 - Mode 2 OAM Interrupt         (1=Enable) (Read/Write)
  1095.       Bit 4 - Mode 1 V-Blank Interrupt     (1=Enable) (Read/Write)
  1096.       Bit 3 - Mode 0 H-Blank Interrupt     (1=Enable) (Read/Write)
  1097.       Bit 2 - Coincidence Flag  (0:LYC<>LY, 1:LYC=LY) (Read Only)
  1098.       Bit 1-0 - Mode Flag       (Mode 0-3, see below) (Read Only)
  1099.               0: During H-Blank
  1100.               1: During V-Blank
  1101.               2: During Searching OAM
  1102.               3: During Transferring Data to LCD Driver
  1103.     */
  1104.     return lh5028->reg41_LCDS;
  1105.   case 0xFF42: /* FF42 - SCY - Scroll Y (R/W) */
  1106.     return lh5028->reg42_SCY;
  1107.   case 0xFF43: /* FF43 - SCX - Scroll X (R/W) */
  1108.     return lh5028->reg43_SCX;
  1109.   case 0xFF44: /* FF44 - LY - LCDC Y-Coordinate (R) */
  1110.     return lh5028->reg44_LY;
  1111.   case 0xFF45: /* FF45 - LYC - LY Compare (R/W) */
  1112.     return lh5028->reg45_LYC;
  1113.   case 0xFF4A: /* FF4A - WY - Window Y Position (R/W) */
  1114.     return lh5028->reg4A_WY;
  1115.   case 0xFF4B: /* FF4B - WX - Window X Position minus 7 (R/W) */
  1116.     return lh5028->reg4B_WX;
  1117.   case 0xFF47: /* FF47 - BGP - BG Palette Data (R/W) - Non CGB Mode Only */
  1118.     return lh5028->reg47_BGP;
  1119.   case 0xFF48: /* FF48 - OBP0 - Object Palette 0 Data (R/W) - Non CGB Mode Only */
  1120.     return lh5028->reg48_OBP0;
  1121.   case 0xFF49: /* FF49 - OBP1 - Object Palette 1 Data (R/W) - Non CGB Mode Only */
  1122.     return lh5028->reg49_OBP1;
  1123.   case 0xFF68: /* FF68 - BCPS/BGPI - CGB Mode Only - Background Palette Index */
  1124.     return lh5028->reg68_BCPS;
  1125.   case 0xFF69: /* FF69 - BCPD/BGPD - CGB Mode Only - Background Palette Data */
  1126.     return lh5028->reg69_BCPD;
  1127.   case 0xFF6A: /* FF6A - OCPS/OBPI - CGB Mode Only - Sprite Palette Index */
  1128.     return lh5028->reg6A_OCPS;
  1129.   case 0xFF6B: /* FF6B - OCPD/OBPD - CGB Mode Only - Sprite Palette Data */
  1130.     return lh5028->reg6B_OCPD;
  1131.   case 0xFF46: /* FF46 - DMA - DMA Transfer and Start Address (R/W) */
  1132.     return lh5028->reg46_DMA;
  1133.   case 0xFF51: /* FF51 - HDMA1 - CGB Mode Only - New DMA Source, High */
  1134.     return lh5028->reg51_HDMA1;
  1135.   case 0xFF52: /* FF52 - HDMA2 - CGB Mode Only - New DMA Source, Low*/
  1136.     return lh5028->reg52_HDMA2;
  1137.   case 0xFF53: /* FF53 - HDMA3 - CGB Mode Only - New DMA Destination, High */
  1138.     return lh5028->reg53_HDMA3;
  1139.   case 0xFF54: /* FF54 - HDMA4 - CGB Mode Only - New DMA Destination, Low*/
  1140.     return lh5028->reg54_HDMA4;
  1141.   case 0xFF55: /* FF55 - HDMA5 - CGB Mode Only - New DMA Length/Mode/Start */
  1142.     return lh5028->reg55_HDMA5;
  1143.   case 0xFF4F: /* FF4F - VBK - CGB Mode Only - VRAM Bank (R/W) */
  1144.     return lh5028->reg4F_VBK;
  1145.     break;
  1146.   default:
  1147.     return 0xFF;
  1148.   }
  1149. }
  1150. static /* this method for gameboy color */
  1151. void bgwin_render_cgb (struct ppu *lh5028, ks_int16 scanline) {
  1152.   struct {
  1153.     union { ks_uint16 blk;
  1154.       struct { ks_uint8 lo; ks_uint8 hi; }; };
  1155.   } chrdat,  chrcac;
  1156.   /* always scan 168 pixel in every line (21 tiles),
  1157.     evenif omfx is ZERO .
  1158.       fit buffer offset, so that every time we can scan a complete tile,
  1159.           no matter how much omfx is.
  1160.     */
  1161.   ks_int32 omfx;
  1162.   ks_int32 ofx;
  1163.   ks_int32 obx;
  1164.   ks_int32 omfy;
  1165.   ks_int32 ofy;
  1166.   ks_int32 vsc;
  1167.   ks_uint8 tid;
  1168.   ks_int8 tat;
  1169.   ks_int32 tidaddr;
  1170.   ks_uint16 pixcac;
  1171.   ks_uint8 *tdat;
  1172.   ks_int32 rxpos;
  1173.   ks_uint32 c, q, c2, s;
  1174.   ks_int32 c3;
  1175.   ks_uint16 *vptrWinDrawStart;
  1176.   ks_uint16 *vptrScrollStart;
  1177.   /* check current scan region in BG or WINDOW (if WINDOW enable)*/
  1178.   if ( (lh5028->reg40_LCDC & 0x20)) {
  1179.     /* draw window  */
  1180.     goto windraw;
  1181.   } else {
  1182.     /* draw background */
  1183.     vsc = lh5028->uscanR;
  1184.     omfx = lh5028->reg43_SCX & 7;
  1185.     ofx = lh5028->reg43_SCX >> 3;
  1186.     omfy = lh5028->reg42_SCY & 7;
  1187.     ofy = lh5028->reg42_SCY >> 3;
  1188.     ofx = ofx + vsc;
  1189.     ofy = ofy + scanline;
  1190.     omfy = ofy & 7;
  1191.     ofy = ofy >> 3;
  1192.     ofx = ofx - (ofx & 32);
  1193.     ofy = ofy - (ofy & 32);  
  1194.     obx = vsc << 3;
  1195.     vptrScrollStart = & lh5028->fmebuf.buf[scanline *(lh5028->fmebuf.pitch/sizeof (lh5028->fmebuf.buf[0]))-omfx];
  1196.     /* pick tileid and attr from ::Bit 3 - BG Tile Map Display Select (0=9800-9BFF, 1=9C00-9FFF) */
  1197.     tidaddr = 0x9800 + (((lh5028->reg40_LCDC & 0x08) >> 3) << 10);
  1198.     tidaddr = (tidaddr-0x8000)+(ofy<< 5)+ofx;
  1199.     tid = lh5028->ram[tidaddr]; // fetch tileid
  1200.     tat = lh5028->ram[tidaddr+0x2000]; // fetch tileattr.
  1201.     tdat = & lh5028->ram[((tat & 0x08)>>3)<<13]; // bank select.
  1202. #   if  1
  1203.     if (lh5028->reg40_LCDC & 0x10) // 0x8000 unsigned address
  1204.       tdat = & tdat[tid<<4];
  1205.     else //
  1206.       tdat = & tdat[0x1000+(((ks_int8)tid)<<4)]; // TODO: done.
  1207. #   else
  1208.     cti16 = (lh5028->reg40_LCDC & 0x10) << 8;
  1209.     cti16^= 0x1000;
  1210.     tdat = & tdat[cti16+((ks_int8)(cti16 >>5)) & (((ks_int8)tid) << 4)];
  1211. #   endif
  1212. #   if  1
  1213.     if (tat & 0x40) // check vflip ?
  1214.       tdat = & tdat[(7-omfy)*2];
  1215.     else
  1216.       tdat = & tdat[omfy*2];
  1217. #   else
  1218.     ctu8 = (tat & 0x40) >> 3; // 8
  1219.     ctu8 = ctu8 - (ctu8 >> 3);// 0 or 7
  1220.     tdat = & tdat[(ctu8^omfy)<<1];
  1221. #   endif
  1222.     chrdat.blk = *(ks_uint16 *)tdat;
  1223.     /* check x flip  */
  1224.     if (tat & 0x20) {
  1225.       chrcac.blk = chrdat.blk & 0x8080;
  1226.       pixcac = pixcac | (chrcac.lo << 7) | (chrcac.hi << 8);
  1227.       chrcac.blk = chrdat.blk & 0x4040;
  1228.       pixcac = pixcac | (chrcac.lo << 6) | (chrcac.hi << 7);
  1229.       chrcac.blk = chrdat.blk & 0x2020;
  1230.       pixcac = pixcac | (chrcac.lo << 5) | (chrcac.hi << 6);
  1231.       chrcac.blk = chrdat.blk & 0x1010;
  1232.       pixcac = pixcac | (chrcac.lo << 4) | (chrcac.hi << 5);
  1233.       chrcac.blk = chrdat.blk & 0x0808;
  1234.       pixcac = pixcac | (chrcac.lo << 3) | (chrcac.hi << 4);
  1235.       chrcac.blk = chrdat.blk & 0x0404;
  1236.       pixcac = pixcac | (chrcac.lo << 2) | (chrcac.hi << 3);
  1237.       chrcac.blk = chrdat.blk & 0x0202;
  1238.       pixcac = pixcac | (chrcac.lo << 1) | (chrcac.hi << 2);
  1239.       chrcac.blk = chrdat.blk & 0x0101;
  1240.       pixcac = pixcac | (chrcac.lo << 0) | (chrcac.hi << 1);        
  1241.     } else {
  1242.       chrcac.blk = chrdat.blk & 0x8080;
  1243.       pixcac = pixcac | (chrcac.lo >> 7) | (chrcac.hi >> 6);
  1244.       chrcac.blk = chrdat.blk & 0x4040;
  1245.       pixcac = pixcac | (chrcac.lo >> 4) | (chrcac.hi >> 3);
  1246.       chrcac.blk = chrdat.blk & 0x2020;
  1247.       pixcac = pixcac | (chrcac.lo >> 1) | (chrcac.hi >> 0);
  1248.       chrcac.blk = chrdat.blk & 0x1010;
  1249.       pixcac = pixcac | (chrcac.lo << 2) | (chrcac.hi << 3);
  1250.       chrcac.blk = chrdat.blk & 0x0808;
  1251.       pixcac = pixcac | (chrcac.lo << 5) | (chrcac.hi << 6);
  1252.       chrcac.blk = chrdat.blk & 0x0404;
  1253.       pixcac = pixcac | (chrcac.lo << 8) | (chrcac.hi << 9);
  1254.       chrcac.blk = chrdat.blk & 0x0202;
  1255.       pixcac = pixcac | (chrcac.lo <<11) | (chrcac.hi <<12);
  1256.       chrcac.blk = chrdat.blk & 0x0101;
  1257.       pixcac = pixcac | (chrcac.lo <<14) | (chrcac.hi <<15);
  1258.     }
  1259.     rxpos = obx - omfx;
  1260.     q = tat&7;
  1261.     if (!(lh5028->reg40_LCDC & 0x01)) {
  1262.       vptrScrollStart = & vptrScrollStart[obx];
  1263.       /* When Bit 0 is cleared, the background and window lose their priority,
  1264.         the sprites will be always displayed on top of background and window,
  1265.         independently of the priority flags in OAM and BG Map attributes.
  1266.         */
  1267.       for (c = 0; c != 8; c++) {
  1268.         s = rxpos+c;
  1269.         if (lh5028->olf[s].attr & PIXEL_SPRITE_NOTRANS) // spline ptr to +8
  1270.           vptrScrollStart[c] = lh5028->olf[s].pixel;
  1271.         else
  1272.           vptrScrollStart[c] = lh5028->bg_pal[q][pixcac & 3].rgb15;
  1273.         pixcac >>= 2;
  1274.       }
  1275.     } else if (tat & 0x80) { // BG pri.
  1276.       vptrScrollStart = & vptrScrollStart[obx];
  1277.       for (c = 0; c != 8; c++) {
  1278.         vptrScrollStart[c] = lh5028->bg_pal[q][pixcac & 3].rgb15;
  1279.         pixcac >>= 2;
  1280.       }
  1281.     } else  {
  1282.       for (c = 0; c != 8; c++) {
  1283.         s = rxpos+c;
  1284.         c2 = pixcac & 3;
  1285.         if (lh5028->olf[s].attr & PIXEL_SPRITE_NOTRANS)
  1286.           if (!(lh5028->olf[s].attr & PIXEL_SPRITE_BACK))
  1287.             vptrScrollStart[c] = lh5028->olf[s].pixel;
  1288.           else if ( c2 == 0)
  1289.             vptrScrollStart[c] = lh5028->olf[s].pixel;
  1290.           else
  1291.             vptrScrollStart[c] = lh5028->bg_pal[q][c2].rgb15;
  1292.         else
  1293.           vptrScrollStart[c] = lh5028->bg_pal[q][c2].rgb15;
  1294.         pixcac >>= 2;
  1295.       }
  1296.     }
  1297.     rxpos = obx - omfx; // -7 | 25
  1298.     rxpos+= 8; // 1 | 33
  1299.     rxpos+= 7; // 8 | 40
  1300.     if ( (lh5028->reg40_LCDC & 0x20)
  1301.         && (lh5028->reg4B_WX <= 166 && lh5028->reg4B_WX < rxpos) /* check X**/
  1302.         && (lh5028->reg4A_WY <= scanline && (lh5028->reg4A_WY <= 143)))
  1303.     {
  1304.      
  1305.       lh5028->xscanR = 0;
  1306.       q = 15 - omfx; // 8 | 16-> 9
  1307.       // 7->0
  1308.       // 8->1
  1309.       while (lh5028->reg4B_WX >= q) // 15 >= q / 16
  1310.         {
  1311.           lh5028->xscanR ++; //  1 or 2
  1312.           q += 8;
  1313.         }
  1314.       goto windraw;
  1315.     }
  1316.   }
  1317.   return ;
  1318. windraw:
  1319.   ofx = lh5028->uscanR - lh5028->xscanR; // espl x
  1320.   c = scanline - lh5028->reg4A_WY; // total - y
  1321.   omfx = 0;
  1322.   omfy = c & 7;
  1323.   ofy = c >> 3;
  1324.   c3 = ((ks_int8)lh5028->reg4B_WX)-7;
  1325.   c3 = c3 + (ofx<<3);
  1326.   vptrWinDrawStart = & lh5028->fmebuf.buf[scanline *(lh5028->fmebuf.pitch/sizeof (lh5028->fmebuf.buf[0]))+c3];
  1327.   /* pick tileid and attr from ::Bit 6 - Tile Tile Map Display Select (0=9800-9BFF, 1=9C00-9FFF) */
  1328.   tidaddr = 0x9800 + (((lh5028->reg40_LCDC & 0x40) >> 6) << 10);
  1329.   tidaddr = (tidaddr-0x8000)+(ofy<< 5)+ofx;
  1330.   tid = lh5028->ram[tidaddr]; // fetch tileid
  1331.   tat = lh5028->ram[tidaddr+0x2000]; // fetch tileattr.
  1332.   tdat = & lh5028->ram[((tat & 0x08)>>3)<<13]; // bank select.
  1333. #   if  1
  1334.   if (lh5028->reg40_LCDC & 0x10) // 0x8000 unsigned address
  1335.     tdat = & tdat[tid<<4];
  1336.   else //
  1337.     tdat = & tdat[0x1000+(((ks_int8)tid)<<4)]; // TODO: done.
  1338. #   else
  1339.   cti16 = (lh5028->reg40_LCDC & 0x10) << 8;
  1340.   cti16^= 0x1000;
  1341.   tdat = & tdat[cti16+((ks_int8)(cti16 >>5)) & (((ks_int8)tid) << 4)];
  1342. #   endif
  1343. #   if  1
  1344.   if (tat & 0x40) // check vflip ?
  1345.     tdat = & tdat[(7-omfy)*2];
  1346.   else
  1347.     tdat = & tdat[omfy*2];
  1348. #   else
  1349.   ctu8 = (tat & 0x40) >> 3; // 8
  1350.   ctu8 = ctu8 - (ctu8 >> 3);// 0 or 7
  1351.   tdat = & tdat[(ctu8^omfy)<<1];
  1352. #   endif
  1353.   chrdat.blk = *(ks_uint16 *)tdat;
  1354.   /* check x flip  */
  1355.   if (tat & 0x20) {
  1356.     chrcac.blk = chrdat.blk & 0x8080;
  1357.     pixcac = pixcac | (chrcac.lo << 7) | (chrcac.hi << 8);
  1358.     chrcac.blk = chrdat.blk & 0x4040;
  1359.     pixcac = pixcac | (chrcac.lo << 6) | (chrcac.hi << 7);
  1360.     chrcac.blk = chrdat.blk & 0x2020;
  1361.     pixcac = pixcac | (chrcac.lo << 5) | (chrcac.hi << 6);
  1362.     chrcac.blk = chrdat.blk & 0x1010;
  1363.     pixcac = pixcac | (chrcac.lo << 4) | (chrcac.hi << 5);
  1364.     chrcac.blk = chrdat.blk & 0x0808;
  1365.     pixcac = pixcac | (chrcac.lo << 3) | (chrcac.hi << 4);
  1366.     chrcac.blk = chrdat.blk & 0x0404;
  1367.     pixcac = pixcac | (chrcac.lo << 2) | (chrcac.hi << 3);
  1368.     chrcac.blk = chrdat.blk & 0x0202;
  1369.     pixcac = pixcac | (chrcac.lo << 1) | (chrcac.hi << 2);
  1370.     chrcac.blk = chrdat.blk & 0x0101;
  1371.     pixcac = pixcac | (chrcac.lo << 0) | (chrcac.hi << 1);        
  1372.   } else {
  1373.     chrcac.blk = chrdat.blk & 0x8080;
  1374.     pixcac = pixcac | (chrcac.lo >> 7) | (chrcac.hi >> 6);
  1375.     chrcac.blk = chrdat.blk & 0x4040;
  1376.     pixcac = pixcac | (chrcac.lo >> 4) | (chrcac.hi >> 3);
  1377.     chrcac.blk = chrdat.blk & 0x2020;
  1378.     pixcac = pixcac | (chrcac.lo >> 1) | (chrcac.hi >> 0);
  1379.     chrcac.blk = chrdat.blk & 0x1010;
  1380.     pixcac = pixcac | (chrcac.lo << 2) | (chrcac.hi << 3);
  1381.     chrcac.blk = chrdat.blk & 0x0808;
  1382.     pixcac = pixcac | (chrcac.lo << 5) | (chrcac.hi << 6);
  1383.     chrcac.blk = chrdat.blk & 0x0404;
  1384.     pixcac = pixcac | (chrcac.lo << 8) | (chrcac.hi << 9);
  1385.     chrcac.blk = chrdat.blk & 0x0202;
  1386.     pixcac = pixcac | (chrcac.lo <<11) | (chrcac.hi <<12);
  1387.     chrcac.blk = chrdat.blk & 0x0101;
  1388.     pixcac = pixcac | (chrcac.lo <<14) | (chrcac.hi <<15);
  1389.   }
  1390.   q = tat&7;
  1391.   if (!(lh5028->reg40_LCDC & 0x01)) {
  1392.     for (c = 0; c != 8; c++) {
  1393.       s = c3+c;
  1394.       if (lh5028->olf[s].attr & PIXEL_SPRITE_NOTRANS) // spline ptr to +8
  1395.         vptrWinDrawStart[c] = lh5028->olf[s].pixel;
  1396.       else
  1397.         vptrWinDrawStart[c] = lh5028->bg_pal[q][pixcac & 3].rgb15;
  1398.       pixcac >>= 2;
  1399.     }
  1400.   } else if (tat & 0x80) { // BG pri.
  1401.     for (c = 0; c != 8; c++) {
  1402.       vptrWinDrawStart[c] = lh5028->bg_pal[q][pixcac & 3].rgb15;
  1403.       pixcac >>= 2;
  1404.     }
  1405.   } else  {
  1406.     for (c = 0; c != 8; c++) {
  1407.       s = c3+c;
  1408.       c2 = pixcac & 3;
  1409.       if (lh5028->olf[s].attr & PIXEL_SPRITE_NOTRANS)
  1410.         if (!(lh5028->olf[s].attr & PIXEL_SPRITE_BACK))
  1411.           vptrWinDrawStart[c] = lh5028->olf[s].pixel;
  1412.         else if ( c2 == 0)
  1413.           vptrWinDrawStart[c] = lh5028->olf[s].pixel;
  1414.         else
  1415.           vptrWinDrawStart[c] = lh5028->bg_pal[q][c2].rgb15;
  1416.       else
  1417.         vptrWinDrawStart[c] = lh5028->bg_pal[q][c2].rgb15;
  1418.       pixcac >>= 2;
  1419.     }
  1420.   }
  1421. }
  1422. static /* this method for gameboy */
  1423. void bgwin_render_dmg (struct ppu *lh5028, ks_int16 scanline) {
  1424.   struct {
  1425.     union { ks_uint16 blk;
  1426.       struct { ks_uint8 lo; ks_uint8 hi; }; };
  1427.   } chrdat,  chrcac;
  1428.   /* always scan 168 pixel in every line (21 tiles),
  1429.     evenif omfx is ZERO .
  1430.       fit buffer offset, so that every time we can scan a complete tile,
  1431.           no matter how much omfx is.
  1432.     */
  1433.   ks_int32 omfx;
  1434.   ks_int32 ofx;
  1435.   ks_int32 obx;
  1436.   ks_int32 omfy;
  1437.   ks_int32 ofy;
  1438.   ks_int32 vsc;
  1439.   ks_uint8 tid;
  1440.   ks_int32 tidaddr;
  1441.   ks_uint16 pixcac;
  1442.   ks_uint8 *tdat;
  1443.   ks_int32 rxpos;
  1444.   ks_uint32 c, q, c2, s;
  1445.   ks_int32 c3;
  1446.   ks_uint16 *vptrWinDrawStart;
  1447.   ks_uint16 *vptrScrollStart;
  1448.   /* check current scan region in BG or WINDOW (if WINDOW enable)*/
  1449.   if ( lh5028->reg4A_WYLineHit != 0 && (lh5028->reg40_LCDC & LCDC_WINDOW_MASK)) {
  1450.     /* draw window  */
  1451.     goto windraw;
  1452.   } else {
  1453.     /* draw background */
  1454.     vsc = lh5028->uscanR;
  1455.     omfx = lh5028->reg43_SCX & 7;
  1456.     ofx = lh5028->reg43_SCX >> 3;
  1457.     omfy = lh5028->reg42_SCY & 7;
  1458.     ofy = lh5028->reg42_SCY >> 0;
  1459.     ofx = ofx + vsc;
  1460.     ofy = ofy + scanline;
  1461.     omfy = ofy & 7;
  1462.     ofy = ofy >> 3;
  1463.     ofx = ofx - (ofx & 32);
  1464.     ofy = ofy - (ofy & 32);  
  1465.     obx = vsc << 3;
  1466.     vptrScrollStart = & lh5028->fmebuf.buf[scanline *(lh5028->fmebuf.pitch/sizeof (lh5028->fmebuf.buf[0]))-omfx];
  1467.     /* pick tileid and attr from ::Bit 3 - BG Tile Map Display Select (0=9800-9BFF, 1=9C00-9FFF) */
  1468.     tidaddr = 0x9800 + (((lh5028->reg40_LCDC & 0x08) >> 3) << 10);
  1469.     tidaddr = (tidaddr-0x8000)+(ofy<< 5)+ofx;
  1470.     tid = lh5028->ram[tidaddr]; // fetch tileid
  1471.     tdat = & lh5028->ram[0];
  1472. #   if  1
  1473.     if (lh5028->reg40_LCDC & 0x10) // 0x8000 unsigned address
  1474.       tdat = & tdat[tid<<4];
  1475.     else //
  1476.       tdat = & tdat[0x1000+(((ks_int8)tid)*16)]; // TODO: done.
  1477. #   else
  1478.     c2 = (lh5028->reg40_LCDC & 0x10) << 8;
  1479.     c2^= 0x1000;
  1480.     tdat = & tdat[c2+((ks_int8)(c2 >>5)) & (((ks_int8)tid) << 4)];
  1481. #   endif
  1482.     tdat = & tdat[omfy*2];
  1483.     chrdat.blk = *(ks_uint16 *)tdat;
  1484.     chrcac.blk = chrdat.blk & 0x8080;
  1485.     pixcac =          (chrcac.lo >> 7) | (chrcac.hi >> 6);
  1486.     chrcac.blk = chrdat.blk & 0x4040;
  1487.     pixcac = pixcac | (chrcac.lo >> 4) | (chrcac.hi >> 3);
  1488.     chrcac.blk = chrdat.blk & 0x2020;
  1489.     pixcac = pixcac | (chrcac.lo >> 1) | (chrcac.hi >> 0);
  1490.     chrcac.blk = chrdat.blk & 0x1010;
  1491.     pixcac = pixcac | (chrcac.lo << 2) | (chrcac.hi << 3);
  1492.     chrcac.blk = chrdat.blk & 0x0808;
  1493.     pixcac = pixcac | (chrcac.lo << 5) | (chrcac.hi << 6);
  1494.     chrcac.blk = chrdat.blk & 0x0404;
  1495.     pixcac = pixcac | (chrcac.lo << 8) | (chrcac.hi << 9);
  1496.     chrcac.blk = chrdat.blk & 0x0202;
  1497.     pixcac = pixcac | (chrcac.lo <<11) | (chrcac.hi <<12);
  1498.     chrcac.blk = chrdat.blk & 0x0101;
  1499.     pixcac = pixcac | (chrcac.lo <<14) | (chrcac.hi <<15);
  1500.     rxpos = obx - omfx;
  1501.    
  1502.     if (!(lh5028->reg40_LCDC & 0x01)) {
  1503.       vptrScrollStart = & vptrScrollStart[obx];
  1504.       /* When Bit 0 is cleared, both background and window become blank (white),
  1505.         ie. the Window Display Bit (Bit 5) is ignored in that case.
  1506.           Only Sprites may still be displayed (if enabled in Bit 1).
  1507.         */
  1508.       for (c = 0; c != 8; c++) {
  1509.         s = rxpos+c;
  1510.         if (lh5028->olf[s].attr & PIXEL_SPRITE_NOTRANS) // spline ptr to +8
  1511.           vptrScrollStart[c] = lh5028->olf[s].pixel;
  1512.         else
  1513.           // vptrScrollStart[c] = lh5028->bg_pal_dmg[0];
  1514.         vptrScrollStart[c] = lh5028->bg_pal_dmgT[0];
  1515.         pixcac >>= 2;
  1516.       }
  1517.     } else  {
  1518.       vptrScrollStart = & vptrScrollStart[obx];
  1519.       for (c = 0; c != 8; c++) {
  1520.         s = rxpos+c;
  1521.         c2 = pixcac & 3;
  1522.         if (lh5028->olf[s].attr & PIXEL_SPRITE_NOTRANS)
  1523.           if (!(lh5028->olf[s].attr & PIXEL_SPRITE_BACK))
  1524.             vptrScrollStart[c] = lh5028->olf[s].pixel;
  1525.           else if ( c2 == 0)
  1526.             vptrScrollStart[c] = lh5028->olf[s].pixel;
  1527.           else
  1528.             vptrScrollStart[c] = lh5028->bg_pal_dmg[pixcac & 3];
  1529.         else
  1530.           vptrScrollStart[c] = lh5028->bg_pal_dmg[pixcac & 3];
  1531.         pixcac >>= 2;
  1532.       }
  1533.     }
  1534.     rxpos = obx - omfx; // -7 | 25
  1535.     rxpos+= 8; // 1 | 33
  1536.     rxpos+= 7; // 8 | 40
  1537.     if ((lh5028->reg40_LCDC & 0x20)
  1538.         && (lh5028->reg4B_WX <= 166 && lh5028->reg4B_WX < rxpos) /* check X**/
  1539.         && (lh5028->reg4A_WY <= scanline && (lh5028->reg4A_WY <= 143)))
  1540.     {
  1541.       lh5028->xscanR = 0;
  1542.       q = 15 - omfx; // 8 | 16-> 9
  1543.       lh5028->reg4A_WYLineHit = 1;
  1544.       // 7->0
  1545.       // 8->1
  1546.       while (lh5028->reg4B_WX >= q) // 15 >= q / 16
  1547.         {
  1548.           lh5028->xscanR ++; //  1 or 2
  1549.           q += 8;
  1550.         }
  1551.       goto windraw;
  1552.     }
  1553.   }
  1554.   return ;
  1555. windraw:
  1556.   // return ;
  1557.   ofx = lh5028->uscanR - lh5028->xscanR; // espl x  
  1558.   c = lh5028->reg4A_WYRSC;
  1559.   omfx = 0;
  1560.   omfy = c & 7;
  1561.   ofy = c >> 3;
  1562.   c3 = lh5028->reg4B_WX - 7;
  1563.   c3 = c3 + (ofx<<3);
  1564.   vptrWinDrawStart = & lh5028->fmebuf.buf[scanline *(lh5028->fmebuf.pitch/sizeof (lh5028->fmebuf.buf[0]))+c3];
  1565.   /* pick tileid and attr from ::Bit 6 - Tile Tile Map Display Select (0=9800-9BFF, 1=9C00-9FFF) */
  1566.   tidaddr = 0x9800 + (((lh5028->reg40_LCDC & 0x40) >> 6) << 10);
  1567.   tidaddr = (tidaddr-0x8000)+(ofy<< 5)+ofx;
  1568.   tid = lh5028->ram[tidaddr]; // fetch tileid
  1569.   tdat = & lh5028->ram[0]; // bank select.
  1570. #   if  1
  1571.   if (lh5028->reg40_LCDC & 0x10) // 0x8000 unsigned address
  1572.     tdat = & tdat[tid<<4];
  1573.   else //
  1574.     tdat = & tdat[0x1000+(((ks_int8)tid)*16)]; // TODO: done.
  1575. #   else
  1576.   cti16 = (lh5028->reg40_LCDC & 0x10) << 8;
  1577.   cti16^= 0x1000;
  1578.   tdat = & tdat[cti16+((ks_int8)(cti16 >>5)) & (((ks_int8)tid) << 4)];
  1579. #   endif
  1580.   tdat = & tdat[omfy*2];
  1581.   chrdat.blk = *(ks_uint16 *)tdat;
  1582.   chrcac.blk = chrdat.blk & 0x8080;
  1583.   pixcac =          (chrcac.lo >> 7) | (chrcac.hi >> 6);
  1584.   chrcac.blk = chrdat.blk & 0x4040;
  1585.   pixcac = pixcac | (chrcac.lo >> 4) | (chrcac.hi >> 3);
  1586.   chrcac.blk = chrdat.blk & 0x2020;
  1587.   pixcac = pixcac | (chrcac.lo >> 1) | (chrcac.hi >> 0);
  1588.   chrcac.blk = chrdat.blk & 0x1010;
  1589.   pixcac = pixcac | (chrcac.lo << 2) | (chrcac.hi << 3);
  1590.   chrcac.blk = chrdat.blk & 0x0808;
  1591.   pixcac = pixcac | (chrcac.lo << 5) | (chrcac.hi << 6);
  1592.   chrcac.blk = chrdat.blk & 0x0404;
  1593.   pixcac = pixcac | (chrcac.lo << 8) | (chrcac.hi << 9);
  1594.   chrcac.blk = chrdat.blk & 0x0202;
  1595.   pixcac = pixcac | (chrcac.lo <<11) | (chrcac.hi <<12);
  1596.   chrcac.blk = chrdat.blk & 0x0101;
  1597.   pixcac = pixcac | (chrcac.lo <<14) | (chrcac.hi <<15);
  1598.  
  1599.   if (!(lh5028->reg40_LCDC & 0x01)) {
  1600.     for (c = 0; c != 8; c++) {
  1601.       s = c3+c;
  1602.       if (lh5028->olf[s].attr & PIXEL_SPRITE_NOTRANS) // spline ptr to +8
  1603.         vptrWinDrawStart[c] = lh5028->olf[s].pixel;
  1604.       else
  1605.         vptrWinDrawStart[c] = lh5028->bg_pal_dmg[0];
  1606.     }
  1607.   } else  {
  1608.     for (c = 0; c != 8; c++) {
  1609.       s = c3+c;
  1610.       c2 = pixcac & 3;
  1611.       if (lh5028->olf[s].attr & PIXEL_SPRITE_NOTRANS)
  1612.         if (!(lh5028->olf[s].attr & PIXEL_SPRITE_BACK))
  1613.           vptrWinDrawStart[c] = lh5028->olf[s].pixel;
  1614.         else if ( c2 == 0)
  1615.           vptrWinDrawStart[c] = lh5028->olf[s].pixel;
  1616.         else
  1617.           vptrWinDrawStart[c] = lh5028->bg_pal_dmg[pixcac & 3];
  1618.       else
  1619.         vptrWinDrawStart[c] = lh5028->bg_pal_dmg[pixcac & 3];
  1620.       pixcac >>= 2;
  1621.     }
  1622.   }
  1623. }
  1624. static /* this method for gameboy color */
  1625. void sprite_render_cgb (struct ppu *lh5028, ks_int16 scanline) {
  1626.  
  1627. }
  1628.  
  1629. static /* this method for gameboy */
  1630. void sprite_render_dmg (struct ppu *lh5028, ks_int delta) {
  1631.  
  1632.   struct {
  1633.     union {
  1634.       ks_uint16 blk;
  1635.       struct {
  1636.         ks_uint8 lo;
  1637.         ks_uint8 hi;
  1638.       };
  1639.     };
  1640.   } chrdat,  chrcac;
  1641.  
  1642.   while (delta > 0 && (lh5028->vscan40 < 40) && (lh5028->vscanR < 10)) {
  1643.     ks_intptr size16 = (lh5028->reg40_LCDC & LCDC_OAM_SIZE16_MASK) ? 0 : 8;
  1644.     struct oam *ops = & lh5028->sp[lh5028->vscan40];
  1645.     lh5028->vscan40++;
  1646.     if ( !(ops->y == 0  || ops->y >= 160
  1647.      || ops->x == 0 || ops->x >= 168)
  1648.      && (lh5028->reg44_LY >= (ops->y - 16))
  1649.      && (lh5028->reg44_LY < (ops->y - size16)))
  1650.     {
  1651.       /*draw scanline */
  1652.       ks_uint16 pixcac ;
  1653.       ks_uint8 *chr;
  1654.       ks_uint32 id;
  1655.       ks_int x;
  1656.  
  1657.       lh5028->vscanR++;
  1658.       delta--;
  1659.       if (size16 == 0)
  1660.         chr = & lh5028->ram[(ops->id & 0xFE)<<4]; // always pointer tile16's high part in init state .
  1661.       else
  1662.         chr = & lh5028->ram[(ops->id & 0xFF)<<4];
  1663.  
  1664.       if (size16 == 0) {
  1665.         if (ops->attr & LCD_OAM_FLIP_Y_MASK) {
  1666.           int cc = lh5028->reg44_LY - (ops->y - 16);
  1667.           /* get oppo base tile byte8 (^source pos[high or low])*/
  1668.           if (cc < 7) /* high, switch to low */ {
  1669.             cc = 7 -cc; /* flip Y in one tile */
  1670.             cc<<= 1;
  1671.             cc += 16;
  1672.           } else { /* low switch to high, nodone, already in high.*/    
  1673.             cc = 15 -cc; /* flip Y in one tile */
  1674.             cc<<= 1;
  1675.           }
  1676.           chrdat.blk = *(ks_int16 *)& chr[cc];
  1677.         } else {
  1678.           int cc = lh5028->reg44_LY - (ops->y - 16);
  1679.           cc<<= 1;
  1680.           chrdat.blk = *(ks_int16 *)& chr[cc];
  1681.         }
  1682.       } else {
  1683.         if (ops->attr & LCD_OAM_FLIP_Y_MASK) {
  1684.           int cc = lh5028->reg44_LY - (ops->y - 16);
  1685.           cc = 7 -cc; /* flip Y in one tile */
  1686.           cc *= 2;
  1687.           chrdat.blk = *(ks_int16 *)& chr[cc];
  1688.         } else {
  1689.           int cc = lh5028->reg44_LY - (ops->y - 16);
  1690.           cc *= 2;
  1691.           chrdat.blk = *(ks_int16 *)& chr[cc];
  1692.         }
  1693.       }
  1694.       /* mix gbc's pixel (d1d0)
  1695.        * see GBCPUman.pdf:: 2.8.1. Tiles
  1696.        * check x flip  
  1697.        */
  1698.       if (ops->attr & LCD_OAM_FLIP_X_MASK) {
  1699.         chrcac.blk = chrdat.blk & 0x8080;
  1700.         pixcac =          (chrcac.lo << 7) | (chrcac.hi << 8);
  1701.         chrcac.blk = chrdat.blk & 0x4040;
  1702.         pixcac = pixcac | (chrcac.lo << 6) | (chrcac.hi << 7);
  1703.         chrcac.blk = chrdat.blk & 0x2020;
  1704.         pixcac = pixcac | (chrcac.lo << 5) | (chrcac.hi << 6);
  1705.         chrcac.blk = chrdat.blk & 0x1010;
  1706.         pixcac = pixcac | (chrcac.lo << 4) | (chrcac.hi << 5);
  1707.         chrcac.blk = chrdat.blk & 0x0808;
  1708.         pixcac = pixcac | (chrcac.lo << 3) | (chrcac.hi << 4);
  1709.         chrcac.blk = chrdat.blk & 0x0404;
  1710.         pixcac = pixcac | (chrcac.lo << 2) | (chrcac.hi << 3);
  1711.         chrcac.blk = chrdat.blk & 0x0202;
  1712.         pixcac = pixcac | (chrcac.lo << 1) | (chrcac.hi << 2);
  1713.         chrcac.blk = chrdat.blk & 0x0101;
  1714.         pixcac = pixcac | (chrcac.lo << 0) | (chrcac.hi << 1);        
  1715.       } else {
  1716.         chrcac.blk = chrdat.blk & 0x8080;
  1717.         pixcac =         (chrcac.lo >> 7) | (chrcac.hi >> 6);
  1718.         chrcac.blk = chrdat.blk & 0x4040;
  1719.         pixcac = pixcac | (chrcac.lo >> 4) | (chrcac.hi >> 3);
  1720.         chrcac.blk = chrdat.blk & 0x2020;
  1721.         pixcac = pixcac | (chrcac.lo >> 1) | (chrcac.hi >> 0);
  1722.         chrcac.blk = chrdat.blk & 0x1010;
  1723.         pixcac = pixcac | (chrcac.lo << 2) | (chrcac.hi << 3);
  1724.         chrcac.blk = chrdat.blk & 0x0808;
  1725.         pixcac = pixcac | (chrcac.lo << 5) | (chrcac.hi << 6);
  1726.         chrcac.blk = chrdat.blk & 0x0404;
  1727.         pixcac = pixcac | (chrcac.lo << 8) | (chrcac.hi << 9);
  1728.         chrcac.blk = chrdat.blk & 0x0202;
  1729.         pixcac = pixcac | (chrcac.lo <<11) | (chrcac.hi <<12);
  1730.         chrcac.blk = chrdat.blk & 0x0101;
  1731.         pixcac = pixcac | (chrcac.lo <<14) | (chrcac.hi <<15);
  1732.       }
  1733.       x = ops->x - 8;
  1734.       for (id = 8; id != 0; id--) {
  1735.         ks_uint8 idpal = pixcac & 3;
  1736.         /* check trans or */
  1737.         if (lh5028->olf[x].attr & PIXEL_SPRITE_NOTRANS) {
  1738.           /* notrans */
  1739.           if (lh5028->olf[x].attr & PIXEL_SPRITE_BACK) {
  1740.             if (!(ops->attr & LCD_OAM_BACKGROUND_MASK) && idpal != 0) {
  1741. #             if  1 /* maybe error, it's not a big problem. */
  1742.               /* cur pick oam is foreground sprite */
  1743.               lh5028->olf[x].pixel = lh5028->sp_pal_dmg[(ops->attr & 0x10) >> 4][idpal];
  1744.               lh5028->olf[x].attr = PIXEL_SPRITE_NOTRANS;            
  1745. #             endif
  1746.             }
  1747.           } else {
  1748.             /* nodone in foreground sprite */
  1749.           }
  1750.         } else {
  1751.           /* trans, write directly */
  1752.           lh5028->olf[x].pixel = lh5028->sp_pal_dmg[(ops->attr & 0x10) >> 4][idpal];
  1753.           lh5028->olf[x].attr = 0;
  1754.  
  1755.           if (ops->attr & LCD_OAM_BACKGROUND_MASK)
  1756.             lh5028->olf[x].attr |= PIXEL_SPRITE_BACK;
  1757.           if (idpal != 0)
  1758.             lh5028->olf[x].attr |= PIXEL_SPRITE_NOTRANS;
  1759.         }
  1760.         x ++;
  1761.         pixcac >>= 2;
  1762.       }
  1763.     }
  1764.   }
  1765. }
  1766. /* XXX:so bad */
  1767. static
  1768. void ticks (struct ppu *lh5028) {
  1769.  
  1770.   ks_int32 scanline;
  1771.   ks_int16 interv;
  1772.   ks_int16 delta;
  1773.   ks_double clkline;
  1774.  
  1775.   if (lh5028->gb->cpu_clks_ppu > lh5028->gb->mach_tools->frame_cycles) {
  1776.     lh5028->gb->cpu_clks_ppu -= lh5028->gb->mach_tools->frame_cycles; // sub a frame block
  1777.     /* vblank Interrupt, check missing interruption */
  1778.     if (lh5028->reg40_NMIf != 0 && (lh5028->reg40_LCDC & LCDC_DISPLAY_MASK))
  1779.       lh5028->gb->reg0F_IF |= IRQ_1;
  1780.     /* vblank stat Interrupt, check missing interruption */
  1781.     if ((lh5028->reg40_LCDC & LCDC_DISPLAY_MASK)
  1782.        && (lh5028->reg41_IRQf & lh5028->reg41_LCDS & LCDS_INTERRUPET_VBLANK_MASK))
  1783.       lh5028->gb->reg0F_IF |= IRQ_2;
  1784.     /* the beginning of a new frame  reset ppu's context */
  1785.     lh5028->reg41_IRQf |= LCDS_INTERRUPET_ALL_MASK;
  1786.     lh5028->reg40_NMIf = 1;
  1787.     lh5028->vscan = -1;
  1788.     lh5028->vscanR = 0;
  1789.     lh5028->vscan40 = 0;
  1790.     lh5028->uscan = -1;
  1791.   }
  1792.   scanline = (ks_int32) (lh5028->gb->cpu_clks_ppu/ lh5028->gb->mach_tools->line_cycles);
  1793.   clkline = lh5028->gb->cpu_clks_ppu - lh5028->gb->mach_tools->line_cycles * (ks_double) scanline;
  1794.   /* clear mask */
  1795.   lh5028->reg41_LCDS &= ~LCDS_MODE_FLAG_ALL_MASK;
  1796.   lh5028->reg44_LY = scanline;
  1797.  
  1798.   /*
  1799.     PPU time series
  1800.  
  1801.     Mode 0: The LCD controller is in the H-Blank period and
  1802.          the CPU can access both the display RAM (8000h-9FFFh)
  1803.          and OAM (FE00h-FE9Fh)
  1804.  
  1805.     Mode 1: The LCD controller is in the V-Blank period (or the
  1806.          display is disabled) and the CPU can access both the
  1807.          display RAM (8000h-9FFFh) and OAM (FE00h-FE9Fh)
  1808.  
  1809.     Mode 2: The LCD controller is reading from OAM memory.
  1810.          The CPU <cannot> access OAM memory (FE00h-FE9Fh)
  1811.          during this period.
  1812.  
  1813.     Mode 3: The LCD controller is reading from both OAM and VRAM,
  1814.          The CPU <cannot> access OAM and VRAM during this period.
  1815.          CGB Mode: Cannot access Palette Data (FF69,FF6B) either.
  1816.     The following are typical when the display is enabled:
  1817.  
  1818.     Mode 2  2_____2_____2_____2_____2_____2___________________2____
  1819.     Mode 3  _33____33____33____33____33____33__________________3___
  1820.     Mode 0  ___000___000___000___000___000___000________________000
  1821.     Mode 1  ____________________________________11111111111111_____
  1822.  
  1823.     The Mode Flag goes through the values 0, 2, and 3 at a cycle of about 109uS.
  1824.     0 is present about 48.6uS, 2 about 19uS,
  1825.     and 3 about 41uS. This is interrupted every 16.6ms by the VBlank (1).
  1826.     The mode flag stays set at 1 for about 1.08 ms.
  1827.  
  1828.     Mode 0 is present between 201-207 clks, 2 about 77-83 clks, and 3 about 169-175 clks.
  1829.     A complete cycle through these states takes 456 clks.
  1830.     VBlank lasts 4560 clks. A complete screen refresh occurs every 70224 clks.)
  1831.  */
  1832.   if (lh5028->reg44_LY_T != lh5028->reg44_LY) {
  1833.     lh5028->reg41_IRQf |= LCDS_INTERRUPET_LINE_MASK;
  1834.     lh5028->reg4A_WYLineHit = 0;
  1835.   }
  1836.   /* check FF41::Bit 2 Coincidence Flag  (0:LYC<>LY, 1:LYC=LY) (Read Only)*/
  1837.   if (lh5028->reg44_LY != lh5028->reg45_LYC)
  1838.     lh5028->reg41_LCDS &= ~0x04;
  1839.   else {
  1840.     if ((lh5028->reg40_LCDC & LCDC_DISPLAY_MASK)
  1841.        && (lh5028->reg41_IRQf & lh5028->reg41_LCDS & LCDS_INTERRUPET_LINE_MASK)) {
  1842.        lh5028->reg41_IRQf &= ~LCDS_INTERRUPET_LINE_MASK;
  1843.        lh5028->gb->reg0F_IF |= IRQ_2;
  1844.     }
  1845.     lh5028->reg41_LCDS |= 0x04;
  1846.   }
  1847.  
  1848.   /* check mode */
  1849.   if (lh5028->gb->cpu_clks_ppu < lh5028->gb->mach_tools->vbl_clk_st) {
  1850.     if (clkline > lh5028->hbl_clks_st) {
  1851.       /* ------------------------------ MODE0-HBLANK ------------------------------ */
  1852.       lh5028->reg41_LCDS |= LCDS_MODE_FLAG_HBLANK;
  1853.       /*  check edge */
  1854.       if (lh5028->reg41_LCDM_T != LCDS_MODE_FLAG_HBLANK) {
  1855.         /* oamvram to current, (low to high) */    
  1856.         while (lh5028->uscanR < 21) {
  1857.           lh5028->bgwin_done (lh5028, scanline);
  1858.           lh5028->uscanR ++;
  1859.         }
  1860.         if (lh5028->reg4A_WYLineHit != 0)
  1861.           lh5028->reg4A_WYRSC++;
  1862.         /* reset next mode-2 | mode- 3*/
  1863.         lh5028->reg41_IRQf |= LCDS_INTERRUPET_OAM_MASK | LCDS_INTERRUPET_VBLANK_MASK;
  1864.         lh5028->vscan = -1;
  1865.         lh5028->vscan40 = 0;
  1866.         lh5028->uscan = -1;
  1867.         lh5028->vscanR = 0;
  1868.         lh5028->uscanR = 0;
  1869.         /* check HDMA. **/
  1870.         if (lh5028->reg44_LY >= 0 && lh5028->reg44_LY <= 143 && lh5028->hdma_gen && lh5028->hdma_r16)  {
  1871.           /* copy 16 bytes  */
  1872.           ks_uint16 c;
  1873.           for (c =0; c != 16; c++) {
  1874.             ks_uint8 s;
  1875.             s = gameboy_mmu_read (lh5028->gb, lh5028->hdma_src + c);
  1876.             gameboy_mmu_write (lh5028->gb, lh5028->hdma_dst + c, s);
  1877.           }
  1878.           lh5028->hdma_src += 16;
  1879.           lh5028->hdma_dst += 16;
  1880.           lh5028->hdma_r16 --;
  1881.           /* add hdma cycles, ~ 8us */
  1882.           lh5028->gb->cpu_clks_dma += (lh5028->gb->mach_tools->clk_ns * 8.0);
  1883.         }
  1884.         /* in HDMA, no hblank perido */
  1885.         lh5028->reg41_IRQf &= ~LCDS_INTERRUPET_HBLANK_MASK;
  1886.       }
  1887.       /* check hblank interrupt  */
  1888.       if ((lh5028->reg40_LCDC & LCDC_DISPLAY_MASK)
  1889.          && (lh5028->reg41_IRQf & lh5028->reg41_LCDS & LCDS_INTERRUPET_HBLANK_MASK)) {
  1890.          lh5028->reg41_IRQf &= ~LCDS_INTERRUPET_HBLANK_MASK;
  1891.          lh5028->gb->reg0F_IF |= IRQ_2;
  1892.       }
  1893.     } else if (clkline > lh5028->gb->mach_tools->oambg_clk_st) {
  1894.       /* ------------------------------ MODE3-OAMBG ------------------------------ */
  1895.       clkline -= lh5028->gb->mach_tools->oambg_clk_st; // sub, get start clcks epls.
  1896.       lh5028->reg41_LCDS |= LCDS_MODE_FLAG_SERACH_OAMVRAM;
  1897.       /* check edge */
  1898.       if (lh5028->reg41_LCDM_T != LCDS_MODE_FLAG_SERACH_OAMVRAM) {
  1899.         lh5028->sprite_done (lh5028, 10);
  1900.         /*  check sprite interrupt  */    
  1901.         if ((lh5028->reg40_LCDC & LCDC_DISPLAY_MASK)
  1902.            && (lh5028->reg41_IRQf & lh5028->reg41_LCDS & LCDS_INTERRUPET_OAM_MASK))
  1903.           lh5028->gb->reg0F_IF |= IRQ_2;
  1904.         /* adjust BGOAM clk */
  1905.         lh5028->hbl_clks_st = (lh5028->gb->mach_tools->oambg_b_cycles +
  1906.               lh5028->vscanR * lh5028->gb->mach_tools->oam_clk_add_hbl_per);
  1907.         lh5028->oambg_clks_divider21 =
  1908.             lh5028->hbl_clks_st / 21.0;
  1909.         lh5028->hbl_clks_st += lh5028->gb->mach_tools->oam_cycles;
  1910.         lh5028->reg41_IRQf |= (LCDS_INTERRUPET_OAM_MASK | LCDS_INTERRUPET_HBLANK_MASK | LCDS_INTERRUPET_VBLANK_MASK);
  1911.       }
  1912.       /* check render bg *.*/
  1913.       if ((interv = KS_INT16_CAST (clkline/ lh5028->oambg_clks_divider21)) != lh5028->uscan
  1914.         && ((lh5028->reg40_LCDC & LCDC_DISPLAY_MASK))) {
  1915.         delta = interv - lh5028->uscan;
  1916.         lh5028->uscan += delta;
  1917.         do {
  1918.           lh5028->bgwin_done (lh5028, scanline);
  1919.           lh5028->uscanR ++;
  1920.         }  while (--delta);
  1921.       }
  1922.     } else   {
  1923.       /* ------------------------------ MODE2-OAM ------------------------------ */
  1924.       lh5028->reg41_LCDS |= LCDS_MODE_FLAG_SERACH_OAM;
  1925.       lh5028->hbl_clks_st = 571583.0;
  1926.       lh5028->reg40_NMIf = 1;
  1927.       /* check edge */
  1928.       if (lh5028->reg41_LCDM_T == LCDS_MODE_FLAG_HBLANK) {
  1929.         /* hblank to current, (low to high), check stride interrupt */
  1930.         if ((lh5028->reg40_LCDC & LCDC_DISPLAY_MASK)
  1931.            && (lh5028->reg41_IRQf & lh5028->reg41_LCDS & LCDS_MODE_FLAG_HBLANK))
  1932.          lh5028->gb->reg0F_IF |= IRQ_2;
  1933.         lh5028->reg41_IRQf |= (LCDS_INTERRUPET_HBLANK_MASK | LCDS_INTERRUPET_VBLANK_MASK);
  1934.         /* clear sprite ctx */
  1935.         memset (& lh5028->olf[0], 0, sizeof (lh5028->olf));
  1936.       }
  1937.       /* check render oam *.*/
  1938.       if ( (lh5028->reg40_LCDC & LCDC_OAM_MASK)
  1939.         && lh5028->vscan != (interv = KS_INT16_CAST (clkline/ lh5028->gb->mach_tools->oam_clk_pick_per))) {
  1940.         delta = interv - lh5028->vscan;
  1941.         lh5028->vscan += delta;
  1942.         /* render sprite */
  1943.         lh5028->sprite_done (lh5028, delta);
  1944.       }
  1945.       /*  check sprite interrupt  */
  1946.       if (  (lh5028->reg40_LCDC & LCDC_DISPLAY_MASK)
  1947.          && (lh5028->reg41_IRQf & lh5028->reg41_LCDS & LCDS_INTERRUPET_OAM_MASK)) {
  1948.          lh5028->reg41_IRQf &= ~LCDS_INTERRUPET_OAM_MASK;
  1949.          lh5028->gb->reg0F_IF |= IRQ_2;
  1950.       }  
  1951.     }
  1952.   } else {
  1953.     /* ------------------------------ MODE1-VLANK ------------------------------ */
  1954.     lh5028->reg41_LCDS |= LCDS_MODE_FLAG_VLANK;
  1955.     /* check edge */
  1956.     if (lh5028->reg41_LCDM_T != LCDS_MODE_FLAG_VLANK) {
  1957.       /* post device render */
  1958.       lh5028->device_blit (lh5028, lh5028->obj, & lh5028->fmebuf);
  1959.       /* check stride */
  1960.       if ((lh5028->reg40_LCDC & LCDC_DISPLAY_MASK)
  1961.          && (lh5028->reg41_IRQf & lh5028->reg41_LCDS & LCDS_INTERRUPET_HBLANK_MASK))
  1962.        lh5028->gb->reg0F_IF |= IRQ_2;
  1963.       lh5028->reg4A_WYRSC = 0;
  1964.       lh5028->reg41_IRQf |= (LCDS_INTERRUPET_HBLANK_MASK | LCDS_INTERRUPET_OAM_MASK);
  1965.     }
  1966.     if (lh5028->reg40_NMIf != 0 && (lh5028->reg40_LCDC & LCDC_DISPLAY_MASK)) {
  1967.       lh5028->reg40_NMIf = 0;
  1968.       lh5028->gb->reg0F_IF |= IRQ_1;
  1969.     }
  1970.     if ((lh5028->reg40_LCDC & LCDC_DISPLAY_MASK)
  1971.         && (lh5028->reg41_IRQf & lh5028->reg41_LCDS & LCDS_INTERRUPET_VBLANK_MASK)) {
  1972.       lh5028->reg41_IRQf &= ~LCDS_INTERRUPET_VBLANK_MASK;
  1973.       lh5028->gb->reg0F_IF |= IRQ_2;
  1974.     }
  1975.   }
  1976.   lh5028->reg44_LY_T = lh5028->reg44_LY;
  1977.   lh5028->reg41_LCDM_T = lh5028->reg41_LCDS & LCDS_MODE_FLAG_ALL_MASK;
  1978. }
  1979.  
  1980. int ppu_cgb_mode (struct ppu *lh5028) {
  1981.   lh5028->bgwin_done = bgwin_render_cgb;
  1982.   lh5028->sprite_done = sprite_render_dmg;
  1983.   return 0;
  1984. }
  1985. int ppu_dmg_mode (struct ppu *lh5028) {
  1986.   lh5028->bgwin_done = bgwin_render_dmg;
  1987.   lh5028->sprite_done = sprite_render_dmg;
  1988.   return 0;
  1989. }
  1990.  
  1991. int ppu_init (struct ppu **lh5028) {
  1992.  
  1993.   struct ppu *sys = ks_null;
  1994.   assert (lh5028 != ks_null);
  1995.  
  1996.   sys = (struct ppu *)calloc (sizeof (struct ppu), 1);
  1997.   assert (sys != ks_null);
  1998.   *lh5028 = sys;
  1999.  
  2000.   if (1) {
  2001.     /* init dmg palette
  2002.      0  White
  2003.      1  Light gray
  2004.      2  Dark gray
  2005.      3  Black
  2006.      */
  2007.     ks_uint16 color[4] = {
  2008. #   if 0
  2009.       (0x1F << 0) | (0x1F << 5) | (0x1F << 10), /* color index 0*/
  2010.       (0x15 << 0) | (0x15 << 5) | (0x15 << 10),  /* color index 1*/
  2011.       (0x0A << 0) | (0x0A << 5) | (0x0A << 10),  /* color index 2*/
  2012.       (0x00 << 0) | (0x00 << 5) | (0x00 << 10)  /* color index 3*/
  2013. #   else
  2014.       // fce88c:0
  2015.       // dcb45c:1
  2016.       // 987c3c:2
  2017.       // 4c3c1c:0
  2018.       // ((0x) >> 3)
  2019.       (((0x8c) >> 3) << 0) | (((0xe8) >> 3) << 5) | (((0xfc) >> 3) << 10), /* color index 0*/
  2020.       (((0x5c) >> 3) << 0) | (((0xb4) >> 3) << 5) | (((0xdc) >> 3) << 10),  /* color index 1*/
  2021.       (((0x3c) >> 3) << 0) | (((0x7c) >> 3) << 5) | (((0x98) >> 3) << 10),  /* color index 2*/
  2022.       (((0x1c) >> 3) << 0) | (((0x3c) >> 3) << 5) | (((0x4c) >> 3) << 10)  /* color index 3*/
  2023. #   endif
  2024.     };
  2025.     ks_uint16 Q;
  2026.    
  2027.     for (Q = 0; Q != 4; Q++) {
  2028.       sys->bg_pal_dmgT[Q] = color[Q];
  2029.       sys->sp_pal_dmgT[0][Q] = color[Q];  
  2030.       sys->sp_pal_dmgT[1][Q] = color[Q];    
  2031.     }
  2032.   }
  2033.   sys->fmebuf.w = 160;
  2034.   sys->fmebuf.h = 144;
  2035.   sys->fmebuf.pitch = 512;
  2036.   sys->bufb = (ks_uint16 *)malloc ( (sys->fmebuf.w + 96) * (sys->fmebuf.h + 16) * 2 + 128);
  2037.   sys->fmebuf.buf = (ks_uint16 *)(((((intptr_t)& sys->bufb[0]) + 31) & -32) + 16);
  2038.   sys->device_blit = default_update;
  2039.   sys->clks = ticks;
  2040.   sys->reg41_LCDM_T =LCDS_MODE_FLAG_SERACH_OAM;
  2041.  
  2042. // value = 0xE8;
  2043.   sys->bg_pal_dmg[0] = sys->bg_pal_dmgT[(0xFC & 0x03) >> 0];
  2044.   sys->bg_pal_dmg[1] = sys->bg_pal_dmgT[(0xFC & 0x0C) >> 2];
  2045.   sys->bg_pal_dmg[2] = sys->bg_pal_dmgT[(0xFC & 0x30) >> 4];
  2046.   sys->bg_pal_dmg[3] = sys->bg_pal_dmgT[(0xFC & 0xC0) >> 6];
  2047.   return 0;
  2048. }
  2049. /* timer about TIMA, TMA, TAC
  2050.  *
  2051.  * Copyright (C) 2018 moecmks
  2052.  * This file is part of KS3578.
  2053.  *
  2054.  * do What The Fuck you want to Public License
  2055.  *
  2056.  * Version 1.0, March 2000
  2057.  * Copyright (C) 2000 Banlu Kemiyatorn (]d).
  2058.  * 136 Nives 7 Jangwattana 14 Laksi Bangkok
  2059.  * Everyone is permitted to copy and distribute verbatim copies
  2060.  * of this license document, but changing it is not allowed.
  2061.  *
  2062.  * Ok, the purpose of this license is simple
  2063.  * and you just
  2064.  *
  2065.  * DO WHAT THE FUCK YOU WANT TO.
  2066.  */
  2067.  
  2068. #include "gameboy.h"
  2069. #include "internal.h"
  2070.  
  2071. void timer_write (struct timer *timer, ks_uint16 addr, ks_uint8 value) {
  2072.  
  2073.   switch (addr) {
  2074.   case 0xFF05: /* TIMA */
  2075.     timer->reg05_TIMA = value;
  2076.     break;
  2077.   case 0xFF06: /* TMA */
  2078.     timer->reg06_TMA = value;
  2079.     break;
  2080.   case 0xFF07: /* TAC */
  2081.     if ( (value & 0x04) && !(timer->reg07_TAC & 0x04)) {
  2082.       timer->timestamp = timer->gb->cpu_clks_timer; /* low to high, open pulse, init timestamp. */
  2083.       timer->reg05_TIMA = timer->reg06_TMA;
  2084.     }
  2085.     timer->reg07_TAC = value;
  2086.     break;
  2087.   default:
  2088.     assert(0);
  2089.   }
  2090. #ifdef TIMER_RESET_IN_RESET_FREQ_MOD_
  2091.   timer->timestamp = timer->gb->cpu_clks_timer;
  2092. #endif
  2093. }
  2094.  
  2095. ks_uint8 timer_read (struct timer *timer, ks_uint16 addr) {
  2096.  
  2097.   switch (addr) {
  2098.   case 0xFF05: /* TIMA */
  2099.     return timer->reg05_TIMA;
  2100.   case 0xFF06: /* TMA */
  2101.     return timer->reg06_TMA;
  2102.   case 0xFF07: /* TAC */
  2103.     return timer->reg07_TAC;
  2104.   default:
  2105.     assert(0);
  2106.   }
  2107.   return 0;
  2108. }
  2109.  
  2110. /*XXX: this function looks bad. */
  2111. static
  2112. void timer_update (struct timer *timer) {
  2113.   /* !must update gameboy's context about timer before this call */
  2114.   /*   double cpu_clks_timer;
  2115.   double cpu_clks_el */
  2116.   ks_double elap;
  2117.   ks_int32 coub;
  2118.   ks_double calc_cac;
  2119.   assert (timer != ks_null);
  2120.   /* enable timing???*/
  2121.   if ( !(timer->reg07_TAC & 0x04))
  2122.     return  ;
  2123.   else ;
  2124.   /* get elapsed cpu time */
  2125.   elap = timer->gb->cpu_clks_timer - timer->timestamp;
  2126.   /* convert to basic frequency of timer */
  2127.   calc_cac = timer->freq_tab[timer->reg07_TAC & 3];
  2128.   coub = 0;
  2129.   while (elap > calc_cac) {
  2130.     /* update timer */
  2131.     if (timer->reg05_TIMA == 0xFF) {
  2132.       /* overflow, IRQ_3 interrupt will requested */
  2133.       timer->reg05_TIMA = timer->reg06_TMA;
  2134.       timer->gb->reg0F_IF |= IRQ_3;  
  2135.     } else {
  2136.       timer->reg05_TIMA ++;
  2137.     }
  2138.     elap -= calc_cac;
  2139.     coub = 1;
  2140.   }
  2141.   /* update timestamp */
  2142.   if (coub != 0) {
  2143.     timer->gb->cpu_clks_timer = elap;
  2144.     timer->timestamp = 0.0;
  2145.   }
  2146. }
  2147.  
  2148. int timer_init (struct timer **timer) {
  2149.   struct timer *timer_ =ks_null;
  2150.   assert (timer != ks_null);
  2151.  
  2152.   timer_ = (struct timer *)
  2153.      calloc (sizeof (struct timer), 1);
  2154.   timer_->clks = timer_update;
  2155.   assert (timer_ != ks_null);
  2156.   * timer = timer_;
  2157.   return 0;
  2158. }
  2159.  
  2160. void timer_cgb_mode (struct timer *timer) {
  2161. #ifdef TIMER_DIVIDER_SAME_FREQ_BOTH_CBG_DMG_BASE_DMG
  2162.   timer->freq_tab[0] = 2047.998;
  2163.   timer->freq_tab[1] = 31.998;
  2164.   timer->freq_tab[2] = 127.998;
  2165.   timer->freq_tab[3] = 511.998;
  2166. #else
  2167.   timer->freq_tab[0] = 1023.998;
  2168.   timer->freq_tab[1] = 15.998;
  2169.   timer->freq_tab[2] = 63.998;
  2170.   timer->freq_tab[3] = 255.998;
  2171. #endif
  2172. }
  2173.  
  2174. void timer_dmg_mode (struct timer *timer) {
  2175.   timer->freq_tab[0] = 1023.998;
  2176.   timer->freq_tab[1] = 15.998;
  2177.   timer->freq_tab[2] = 63.998;
  2178.   timer->freq_tab[3] = 255.998;
  2179. }
  2180.  
  2181. void timer_uninit (struct timer **timer) {
  2182.   struct timer *timer_;
  2183.   assert (timer != ks_null);
  2184.   timer_ = *timer;
  2185.   *timer = ks_null;
  2186.   if (timer_ != ks_null)
  2187.     free (timer_);
  2188.   else ;
  2189. }
  2190. void divider_write (struct divider *divider, ks_uint8 value) {
  2191.  
  2192.   divider->reg04_DIV = value;
  2193. }
  2194.  
  2195. ks_uint8 divider_read (struct divider *divider) {
  2196.  
  2197.   return divider->reg04_DIV;
  2198. }
  2199.  
  2200. void divider_cgb_mode (struct divider *divider) {
  2201. #ifdef TIMER_DIVIDER_SAME_FREQ_BOTH_CBG_DMG_BASE_DMG
  2202.   divider->freq = 512.0;
  2203. #else
  2204.   divider->freq = 256.0;
  2205. #endif
  2206. }
  2207.  
  2208. void divider_dmg_mode (struct divider *divider) {
  2209.   divider->freq = 256.0;
  2210. }
  2211.  
  2212. /*XXX: this function looks bad. */
  2213. static
  2214. void divider_update (struct divider *divider) {
  2215.   /* !must update gameboy's context about divider before this call */
  2216.   /*   double cpu_clks_divider;
  2217.   double cpu_clks_el */
  2218.   ks_double elap;
  2219.   ks_int32 coub;
  2220.   assert (divider != ks_null);
  2221.   /* get elapsed cpu time */
  2222.   elap = divider->gb->cpu_clks_divider - divider->timestamp;
  2223.   coub = 0;
  2224.   while (elap > divider->freq) {
  2225.     /* update divider */
  2226.     divider->reg04_DIV++;
  2227.     elap -= divider->freq;
  2228.     coub = 1;
  2229.   }
  2230.   /* update timestamp */
  2231.   if (coub != 0) {
  2232.     divider->gb->cpu_clks_divider = elap;
  2233.     divider->timestamp = 0.0;
  2234.   }
  2235. }
  2236.  
  2237. int divider_init (struct divider **divider) {
  2238.   struct divider *divider_ =ks_null;
  2239.   assert (divider != ks_null);
  2240.  
  2241.   divider_ = (struct divider *)
  2242.      calloc (sizeof (struct divider), 1);
  2243.   divider_->clks = divider_update;
  2244.   assert (divider_ != ks_null);
  2245.   * divider = divider_;
  2246.   divider_dmg_mode (divider_);
  2247.   return 0;
  2248. }
  2249.  
  2250. void divider_uninit (struct divider **divider) {
  2251.   struct divider *divider_;
  2252.   assert (divider != ks_null);
  2253.   divider_ = *divider;
  2254.   *divider = ks_null;
  2255.   if (divider_ != ks_null)
  2256.     free (divider_);
  2257.   else ;
  2258. }
  2259. ;; cpu_optick.asm
  2260. ;; Sharp LR35902 Chip Opcode for GameBoy
  2261. ;;
  2262. ;; Copyright (C) 2018 moecmks
  2263. ;; This file is part of KS3578.
  2264. ;;
  2265. ;; do What The Fuck you want to Public License
  2266. ;;
  2267. ;; Version 1.0, March 2000
  2268. ;; Copyright (C) 2000 Banlu Kemiyatorn (]d).
  2269. ;; 136 Nives 7 Jangwattana 14 Laksi Bangkok
  2270. ;; Everyone is permitted to copy and distribute verbatim copies
  2271. ;; of this license document, but changing it is not allowed.
  2272. ;;
  2273. ;; Ok, the purpose of this license is simple
  2274. ;; and you just
  2275. ;;
  2276. ;; DO WHAT THE FUCK YOU WANT TO.
  2277. ;;
  2278.  
  2279.   .686                      ; create 32 bit code          
  2280.   .model flat, stdcall      ; 32 bit memory model
  2281.   option casemap :none      ; case sensitive
  2282.  
  2283. ;; Sharp LR35902 Chip opcode mapper
  2284. ;; http://www.pastraiser.com/cpu/gameboy/gameboy_opcodes.html
  2285. ;; Z80 Chip opcode mapper
  2286. ;; http://clrhome.org/table/
  2287.  
  2288. ;; Register F Mask
  2289. ;; The register flag field is different from the standard, in order to optimize instruction operation.
  2290. Z_FLAG equ 040H
  2291. H_FLAG equ 010H
  2292. N_FLAG equ 002H
  2293. C_FLAG equ 001H
  2294. ZC_FLAG equ 041H
  2295.  
  2296. ;; extern memory/IO read/write
  2297. extrn gameboy_mmu_read@8:proc  ;; prototype ks_uint8 __stdcall gameboy_mmu_read (void;;gameboy, ks_uint16 addresss)
  2298. extrn gameboy_mmu_write@12:proc ;; prototype void __stdcall gameboy_mmu_write (void;;gameboy, ks_uint16 addresss, ks_uint8 value)
  2299. extrn gameboy_mmu_read_w@8:proc ;; prototype ks_uint16 __stdcall gameboy_mmu_read_w (void;;gameboy, ks_uint16 addresss)
  2300. extrn gameboy_mmu_write_w@12:proc ;; prototype void __stdcall gameboy_mmu_write_w (void;;gameboy, ks_uint16 addresss, ks_uint16 value)
  2301.  
  2302. ;;  define union .
  2303. defREG macro lo, hi
  2304.   union
  2305.     struct
  2306.       lo db ?
  2307.       hi db ?
  2308.     ends
  2309.     hi&lo dw ?
  2310.   ends
  2311. endm
  2312.  
  2313. defREG2 macro lo, hi, blk
  2314.   union
  2315.     struct
  2316.       lo db ?
  2317.       hi db ?
  2318.     ends
  2319.     blk dw ?
  2320.   ends
  2321. endm
  2322.  
  2323. ;;  XXX:memory order dep.
  2324. cpu struct
  2325.   defREG F, A  ;; A (Accumulator)
  2326.                ;; probably the most commonly used register.
  2327.                ;; Many instructions have special extended operation codes for accumulators.
  2328.                ;; F (Program status byte)
  2329.                
  2330.   ;; defREG C, B ;; A2008: syntax error : C
  2331.   union
  2332.     struct
  2333.       C_ db ?
  2334.       B db ?
  2335.     ends
  2336.     BC dw ?
  2337.   ends           ;; Register BC, without special explanation.
  2338.   defREG E, D    ;; Register DE, without special explanation.
  2339.   defREG L, H    ;; Register HL, which is mostly used to address 16-bit address data,
  2340.                  ;;                              also has the basic properties of BC, DE registers
  2341.   defREG2 SP_LO, SP_HI, SP_ ;; Stack Pointer.
  2342.   defREG2 PC_LO, PC_HI, PC ;; Program Pointer.
  2343.  
  2344.   IME db ?        ;; Interrupt Master Enable
  2345.  
  2346.   halt dd ?     ;; for Halt
  2347.  
  2348.   stop dd ?     ;; for stop
  2349.  
  2350.   key1 db ?  
  2351.  
  2352.   gameboy dd ?
  2353. cpu ends
  2354.  
  2355.     .code
  2356.  
  2357. ;;  prototype ks_int32 cpu_optick (struct cpu;;cpu_);
  2358. cpu_optick proc C
  2359.              option prologue:none, epilogue:none
  2360.  
  2361.         push ebx ;U -  save old frame      
  2362.         push edi ;V -  save old frame
  2363.         push esi
  2364.         nop  
  2365.        
  2366. YG_PF_8 equ bl        
  2367. YG_PF equ ebx
  2368. YG_PC equ esi
  2369. YG_GP equ edi
  2370.  
  2371. _GB_INT3_ASSERT macro address
  2372.   .if [YG_GP].PC == address
  2373.     int 3
  2374.   .endif
  2375. endm  
  2376.         ; ebx <- save now P (cpu's PSB reg)
  2377.        ; esi <- save now PC (cpu's EIP reg)
  2378.         ; edi <- save regs root
  2379.         ; eax <- calc temp or final calc out reslt
  2380.         ; ecx <- calc temp
  2381.         ; edx <- calc temp
  2382.        
  2383.         mov YG_GP, [esp+4+12]   ;; fetch CPU struct
  2384.         mov si, [YG_GP].PC  
  2385.         mov bl, [YG_GP].F
  2386.         assume edi:ptr cpu
  2387. ;;_GB_INT3_ASSERT 00994H
  2388.         ; Fetch Opcode, PC++
  2389.         push YG_PC
  2390.         push [YG_GP].gameboy
  2391.         call gameboy_mmu_read@8
  2392.         inc YG_PC
  2393.         and eax, 255
  2394.         jmp dword ptr[OPTAB+eax*4]
  2395.        
  2396. EmptyMacro macro
  2397. endm  
  2398.  
  2399. SetCyclesAndRet macro Cycles
  2400.   ;; write back PC
  2401.   mov [YG_GP].PC, si
  2402.   mov eax, Cycles
  2403.   jmp V_EXIT
  2404. endm
  2405.  
  2406. SetCyclesRetP macro Cycles
  2407.   ;; write back PC
  2408.   mov [YG_GP].F, bl
  2409.   SetCyclesAndRet Cycles
  2410. endm
  2411.  
  2412. ;;  Register access-write unwind
  2413. B_Write equ mov [YG_GP].B, al
  2414. C_Write equ mov [YG_GP].C_, al
  2415. D_Write equ mov [YG_GP].D, al
  2416. E_Write equ mov [YG_GP].E, al
  2417. H_Write equ mov [YG_GP].H, al
  2418. L_Write equ mov [YG_GP].L, al
  2419. A_Write equ mov [YG_GP].A, al
  2420. F_Write equ mov [YG_GP].F, al
  2421. SP_Write equ mov [YG_GP].SP_, ax
  2422. DE_Write equ mov [YG_GP].DE, ax
  2423. BC_Write equ mov [YG_GP].BC, ax
  2424. HL_Write equ mov [YG_GP].HL, ax
  2425. AF_Write equ mov [YG_GP].AF, ax
  2426. PC_Write equ mov [YG_GP].PC, ax
  2427.  
  2428. ;; (Imm16) := Z80Register:BYTE
  2429. xImm16_WriteReg8 macro _Reg
  2430.   mov cl, [YG_GP]._Reg
  2431.   push ecx
  2432.   push eax
  2433.   push [YG_GP].gameboy
  2434.   call gameboy_mmu_write@12  
  2435. endm
  2436.  
  2437. ;; (Imm16) := Z80Register:WORD
  2438. xImm16_WriteReg16 macro _Reg
  2439.   mov cx, [YG_GP]._Reg
  2440.   push ecx
  2441.   push eax
  2442.   push [YG_GP].gameboy
  2443.   call gameboy_mmu_write_w@12  
  2444. endm
  2445.  
  2446. ;; (Imm16) := Z80Register-SP
  2447. xImm16_WriteRegSP macro
  2448.   xImm16_WriteReg16 SP_
  2449. endm
  2450.  
  2451. ;; (Imm16) := Z80Register-A
  2452. xImm16_WriteRegA macro
  2453.   xImm16_WriteReg8 A
  2454. endm
  2455.  
  2456. ;; (Z80Register:WORD ) :=  Value8:eax::al
  2457. xRegister_WriteReg8 macro _Reg
  2458.   push eax
  2459.   mov ax, [YG_GP]._Reg
  2460.   push eax
  2461.   push [YG_GP].gameboy
  2462.   call gameboy_mmu_write@12
  2463. endm
  2464.  
  2465. ;; Unwind4
  2466. xBC_Write equ xRegister_WriteReg8 BC  
  2467. xDE_Write equ xRegister_WriteReg8 DE
  2468. xHL_Write equ xRegister_WriteReg8 HL
  2469. xAF_Write equ xRegister_WriteReg8 AF
  2470. xPC_Write equ xRegister_WriteReg8 PC
  2471.  
  2472. xHL_Write_Inc macro
  2473.   xHL_Write
  2474.   inc [YG_GP].HL
  2475. endm
  2476.  
  2477. xHL_Write_Dec macro
  2478.   xHL_Write
  2479.   dec [YG_GP].HL
  2480. endm
  2481.  
  2482. ;;  Register access-read unwind
  2483. B_Read equ  mov al, [YG_GP].B
  2484. C_Read equ  mov al, [YG_GP].C_
  2485. D_Read equ  mov al, [YG_GP].D
  2486. E_Read equ  mov al, [YG_GP].E
  2487. H_Read equ  mov al, [YG_GP].H
  2488. L_Read equ  mov al, [YG_GP].L
  2489. A_Read equ  mov al, [YG_GP].A
  2490. BC_Read equ  mov ax, [YG_GP].BC
  2491. DE_Read equ  mov ax, [YG_GP].DE
  2492. HL_Read equ  mov ax, [YG_GP].HL
  2493. SP_Read equ  mov ax, [YG_GP].SP_
  2494. AF_Read equ  mov ax, [YG_GP].AF
  2495.  
  2496. ;; Imm8:eax::al := FetchPC++
  2497. Imm8_Read macro
  2498.   push    esi
  2499.   push   [YG_GP].gameboy
  2500.   call    gameboy_mmu_read@8
  2501.   inc     esi
  2502. endm
  2503.  
  2504. ;; Imm16:eax::ax := FetchPC, FetchPC +=2
  2505. Imm16_Read macro
  2506.   push    esi
  2507.   push   [YG_GP].gameboy
  2508.   call    gameboy_mmu_read_w@8
  2509.   add     esi, 2
  2510. endm
  2511.  
  2512. Read_ByxX86SpecRegister macro _Reg
  2513.   ;;  _Reg:x86Register
  2514.   push    _Reg
  2515.   push   [YG_GP].gameboy
  2516.   call    gameboy_mmu_read@8
  2517. endm
  2518.  
  2519. Imm8Read_ExpandAddress16 macro
  2520.   Imm8_Read
  2521.   and eax, 000FFh
  2522.   add eax, 0FF00h
  2523. endm
  2524.  
  2525. Imm8_ExpandSignWord macro
  2526.   Imm8_Read
  2527.   movsx eax, al
  2528. endm
  2529.  
  2530. C_ExpandAddress16 macro
  2531.   movzx eax, [YG_GP].C_
  2532.   add eax, 0FF00h
  2533. endm
  2534.  
  2535. Imm8Read_ExpandAddress16_Fetch macro
  2536.   Imm8Read_ExpandAddress16
  2537.   Read_ByxX86SpecRegister eax
  2538. endm
  2539.  
  2540. Imm16Read_Address_Fetch macro
  2541.   Imm16_Read
  2542.   Read_ByxX86SpecRegister eax
  2543. endm
  2544.  
  2545. C_ExpandAddress16_Fetch macro
  2546.   mov al, [YG_GP].C_
  2547.   add eax, 0FF00h
  2548.   Read_ByxX86SpecRegister eax
  2549. endm
  2550.  
  2551. xRegister_Read macro _Reg
  2552.   mov ax, [YG_GP].&_Reg
  2553.   push eax
  2554.   push [YG_GP].gameboy
  2555.   call gameboy_mmu_read@8
  2556. endm
  2557.  
  2558. ;; Unwind5
  2559. xBC_Read equ xRegister_Read BC  
  2560. xDE_Read equ xRegister_Read DE
  2561. xHL_Read equ xRegister_Read HL
  2562. xAF_Read equ xRegister_Read AF
  2563. xPC_Read equ xRegister_Read PC
  2564.  
  2565. xHL_Read_Inc macro
  2566.   xHL_Read
  2567.   inc [YG_GP].HL
  2568. endm
  2569.  
  2570. xHL_Read_Dec macro
  2571.   xHL_Read
  2572.   dec [YG_GP].HL
  2573. endm
  2574.  
  2575. LD@Imm8 macro OpCase, Cycles_, WriteOrExt
  2576.  OpCase&:
  2577.     Imm8_Read
  2578.     WriteOrExt
  2579.     SetCyclesAndRet Cycles_
  2580. endm
  2581.       LD@Imm8 OP06, 8,  B_Write ;; LD B Imm8, 2, Cycles:8
  2582.       LD@Imm8 OP0E, 8,  C_Write ;; LD C Imm8, 2, Cycles:8
  2583.       LD@Imm8 OP16, 8,  D_Write ;; LD D Imm8, 2, Cycles:8
  2584.       LD@Imm8 OP1E, 8,  E_Write ;; LD E Imm8, 2, Cycles:8
  2585.       LD@Imm8 OP26, 8,  H_Write ;; LD H Imm8, 2, Cycles:8
  2586.       LD@Imm8 OP2E, 8,  L_Write ;; LD L Imm8, 2, Cycles:8
  2587.       LD@Imm8 OP36,12,  xHL_Write ;; LD xHL Imm8, 2, Cycles:8
  2588.       LD@Imm8 OP3E, 8,  A_Write ;; LD A Imm8, 2, Cycles:8
  2589.    
  2590. LD@Imm16 macro OpCase, Cycles_, lrReg
  2591.  OpCase&:
  2592.     Imm16_Read
  2593.     mov [YG_GP].&lrReg, ax
  2594.     SetCyclesAndRet Cycles_
  2595. endm    
  2596.       LD@Imm16 OP01, 12, BC ;; LD BC Imm16, 3 Cycles:12
  2597.       LD@Imm16 OP11, 12, DE ;; LD DE Imm16, 3 Cycles:12    
  2598.       LD@Imm16 OP21, 12, HL ;; LD HL Imm16, 3 Cycles:12    
  2599.       LD@Imm16 OP31, 12, SP_ ;; LD SP Imm16, 3 Cycles:12      
  2600.  
  2601. LD@RxHLToRxHL macro OpCase, Cycles_, ReadOrExt, WriteOrExt
  2602.  OpCase&:
  2603.     ReadOrExt
  2604.     WriteOrExt
  2605.     SetCyclesAndRet Cycles_
  2606. endm      
  2607.       LD@RxHLToRxHL OP40, 4, B_Read, B_Write ;; LD B B, 1 Cycles:4
  2608.       LD@RxHLToRxHL OP41, 4, C_Read, B_Write ;; LD B C, 1 Cycles:4
  2609.       LD@RxHLToRxHL OP42, 4, D_Read, B_Write ;; LD B D, 1 Cycles:4
  2610.       LD@RxHLToRxHL OP43, 4, E_Read, B_Write ;; LD B E, 1 Cycles:4
  2611.       LD@RxHLToRxHL OP44, 4, H_Read, B_Write ;; LD B H, 1 Cycles:4
  2612.       LD@RxHLToRxHL OP45, 4, L_Read, B_Write ;; LD B L, 1 Cycles:4
  2613.       LD@RxHLToRxHL OP46, 8, xHL_Read, B_Write ;; LD B xHL, 1 Cycles:8
  2614.       LD@RxHLToRxHL OP47, 4, A_Read, B_Write ;; LD B A, 1 Cycles:4  
  2615.      
  2616.       LD@RxHLToRxHL OP48, 4, B_Read, C_Write ;; LD C B, 1 Cycles:4
  2617.       LD@RxHLToRxHL OP49, 4, C_Read, C_Write ;; LD C C, 1 Cycles:4
  2618.       LD@RxHLToRxHL OP4A, 4, D_Read, C_Write ;; LD C D, 1 Cycles:4
  2619.       LD@RxHLToRxHL OP4B, 4, E_Read, C_Write ;; LD C E, 1 Cycles:4
  2620.       LD@RxHLToRxHL OP4C, 4, H_Read, C_Write ;; LD C H, 1 Cycles:4
  2621.       LD@RxHLToRxHL OP4D, 4, L_Read, C_Write ;; LD C L, 1 Cycles:4
  2622.       LD@RxHLToRxHL OP4E, 8, xHL_Read, C_Write ;; LD C xHL, 1 Cycles:8
  2623.       LD@RxHLToRxHL OP4F, 4, A_Read, C_Write ;; LD C A, 1 Cycles:4  
  2624.  
  2625.       LD@RxHLToRxHL OP50, 4, B_Read, D_Write ;; LD D B, 1 Cycles:4
  2626.       LD@RxHLToRxHL OP51, 4, C_Read, D_Write ;; LD D C, 1 Cycles:4
  2627.       LD@RxHLToRxHL OP52, 4, D_Read, D_Write ;; LD D D, 1 Cycles:4
  2628.       LD@RxHLToRxHL OP53, 4, E_Read, D_Write ;; LD D E, 1 Cycles:4
  2629.       LD@RxHLToRxHL OP54, 4, H_Read, D_Write ;; LD D H, 1 Cycles:4
  2630.       LD@RxHLToRxHL OP55, 4, L_Read, D_Write ;; LD D L, 1 Cycles:4
  2631.       LD@RxHLToRxHL OP56, 8, xHL_Read, D_Write ;; LD D xHL, 1 Cycles:8
  2632.       LD@RxHLToRxHL OP57, 4, A_Read, D_Write ;; LD D A, 1 Cycles:4  
  2633.      
  2634.       LD@RxHLToRxHL OP58, 4, B_Read, E_Write ;; LD E B, 1 Cycles:4
  2635.       LD@RxHLToRxHL OP59, 4, C_Read, E_Write ;; LD E C, 1 Cycles:4
  2636.       LD@RxHLToRxHL OP5A, 4, D_Read, E_Write ;; LD E D, 1 Cycles:4
  2637.       LD@RxHLToRxHL OP5B, 4, E_Read, E_Write ;; LD E E, 1 Cycles:4
  2638.       LD@RxHLToRxHL OP5C, 4, H_Read, E_Write ;; LD E H, 1 Cycles:4
  2639.       LD@RxHLToRxHL OP5D, 4, L_Read, E_Write ;; LD E L, 1 Cycles:4
  2640.       LD@RxHLToRxHL OP5E, 8, xHL_Read, E_Write ;; LD E xHL, 1 Cycles:8
  2641.       LD@RxHLToRxHL OP5F, 4, A_Read, E_Write ;; LD E A, 1 Cycles:4  
  2642.  
  2643.       LD@RxHLToRxHL OP60, 4, B_Read, H_Write ;; LD H B, 1 Cycles:4
  2644.       LD@RxHLToRxHL OP61, 4, C_Read, H_Write ;; LD H C, 1 Cycles:4
  2645.       LD@RxHLToRxHL OP62, 4, D_Read, H_Write ;; LD H D, 1 Cycles:4
  2646.       LD@RxHLToRxHL OP63, 4, E_Read, H_Write ;; LD H E, 1 Cycles:4
  2647.       LD@RxHLToRxHL OP64, 4, H_Read, H_Write ;; LD H H, 1 Cycles:4
  2648.       LD@RxHLToRxHL OP65, 4, L_Read, H_Write ;; LD H L, 1 Cycles:4
  2649.       LD@RxHLToRxHL OP66, 8, xHL_Read, H_Write ;; LD H xHL, 1 Cycles:8
  2650.       LD@RxHLToRxHL OP67, 4, A_Read, H_Write ;; LD H A, 1 Cycles:4  
  2651.      
  2652.       LD@RxHLToRxHL OP68, 4, B_Read, L_Write ;; LD L B, 1 Cycles:4
  2653.       LD@RxHLToRxHL OP69, 4, C_Read, L_Write ;; LD L C, 1 Cycles:4
  2654.       LD@RxHLToRxHL OP6A, 4, D_Read, L_Write ;; LD L D, 1 Cycles:4
  2655.       LD@RxHLToRxHL OP6B, 4, E_Read, L_Write ;; LD L E, 1 Cycles:4
  2656.       LD@RxHLToRxHL OP6C, 4, H_Read, L_Write ;; LD L H, 1 Cycles:4
  2657.       LD@RxHLToRxHL OP6D, 4, L_Read, L_Write ;; LD L L, 1 Cycles:4
  2658.       LD@RxHLToRxHL OP6E, 8, xHL_Read, L_Write ;; LD L xHL, 1 Cycles:8
  2659.       LD@RxHLToRxHL OP6F, 4, A_Read, L_Write ;; LD L A, 1 Cycles:4  
  2660.        
  2661.       LD@RxHLToRxHL OP70, 8, B_Read, xHL_Write ;; LD xHL B, 1 Cycles:8
  2662.       LD@RxHLToRxHL OP71, 8, C_Read, xHL_Write ;; LD xHL C, 1 Cycles:8
  2663.       LD@RxHLToRxHL OP72, 8, D_Read, xHL_Write ;; LD xHL D, 1 Cycles:8
  2664.       LD@RxHLToRxHL OP73, 8, E_Read, xHL_Write ;; LD xHL E, 1 Cycles:8
  2665.       LD@RxHLToRxHL OP74, 8, H_Read, xHL_Write ;; LD xHL H, 1 Cycles:8
  2666.       LD@RxHLToRxHL OP75, 8, L_Read, xHL_Write ;; LD xHL L, 1 Cycles:8
  2667.       ;; LD@RxHLToRxHL OP76, 8, xHL_Read, xHL_Write ;; LD xHL xHL, 1 Cycles:8
  2668.       LD@RxHLToRxHL OP02, 8, A_Read, xBC_Write ;; LD xBC A, 1 Cycles:8    
  2669.       LD@RxHLToRxHL OP12, 8, A_Read, xDE_Write ;; LD xDE A, 1 Cycles:8    
  2670.       LD@RxHLToRxHL OP77, 8, A_Read, xHL_Write ;; LD xHL A, 1 Cycles:8    
  2671.       LD@RxHLToRxHL OP22, 8, A_Read, xHL_Write_Inc;; LD xHL++ A, 1 Cycles:8  
  2672.       LD@RxHLToRxHL OP32, 8, A_Read, xHL_Write_Dec ;; LD xHL-- A, 1 Cycles:8  
  2673.        
  2674.       LD@RxHLToRxHL OP78, 4, B_Read, A_Write ;; LD A B, 1 Cycles:4
  2675.       LD@RxHLToRxHL OP79, 4, C_Read, A_Write ;; LD A C, 1 Cycles:4
  2676.       LD@RxHLToRxHL OP7A, 4, D_Read, A_Write ;; LD A D, 1 Cycles:4
  2677.       LD@RxHLToRxHL OP7B, 4, E_Read, A_Write ;; LD A E, 1 Cycles:4
  2678.       LD@RxHLToRxHL OP7C, 4, H_Read, A_Write ;; LD A H, 1 Cycles:4
  2679.       LD@RxHLToRxHL OP7D, 4, L_Read, A_Write ;; LD A L, 1 Cycles:4
  2680.       LD@RxHLToRxHL OP0A, 8, xBC_Read, A_Write ;; LD A xBC, 1 Cycles:8
  2681.       LD@RxHLToRxHL OP1A, 8, xDE_Read, A_Write ;; LD A xDE, 1 Cycles:8
  2682.       LD@RxHLToRxHL OP7E, 8, xHL_Read, A_Write ;; LD A xHL, 1 Cycles:8
  2683.       LD@RxHLToRxHL OP2A, 8, xHL_Read_Inc, A_Write ;; LD A xHL++, 1 Cycles:8
  2684.       LD@RxHLToRxHL OP3A, 8, xHL_Read_Dec, A_Write ;; LD A xHL--, 1 Cycles:8
  2685.       LD@RxHLToRxHL OP7F, 4, A_Read, A_Write ;; LD A A, 1 Cycles:4      
  2686. ;; MISC LD
  2687.       LD@RxHLToRxHL OP08,20, Imm16_Read, xImm16_WriteRegSP ;; LD (Imm16) SP, 3 Cycles:20
  2688.       LD@RxHLToRxHL OPEA,16, Imm16_Read, xImm16_WriteRegA ;; LD (Imm16) A, 3 Cycles:16
  2689.       LD@RxHLToRxHL OPE0,12, Imm8Read_ExpandAddress16, xImm16_WriteRegA ;; LD (Imm8+0FF00h) A, 2 Cycles:12
  2690.       LD@RxHLToRxHL OPE2, 8, C_ExpandAddress16, xImm16_WriteRegA ;; LD (C+0FF00h) A, 2 Cycles:8  
  2691.       LD@RxHLToRxHL OPF0,12, Imm8Read_ExpandAddress16_Fetch, A_Write ;; LD A, (Imm8+0FF00h)  2 Cycles:12
  2692.       LD@RxHLToRxHL OPF2, 8, C_ExpandAddress16_Fetch, A_Write ;; LD A, (C+0FF00h) 2 Cycles:8    
  2693.       LD@RxHLToRxHL OPFA,16, Imm16Read_Address_Fetch, A_Write ;; LD A, (Imm16) 3 Cycles:16
  2694.       LD@RxHLToRxHL OPF9, 8, HL_Read, SP_Write ;; LD SP HL 1 Cycles:8
  2695.      
  2696.       OPF8: ;; LD HL SP+Imm8(sign8) 2 Cycles:12
  2697.       Imm8_Read
  2698.      
  2699.       ;; Clear Reg-f
  2700.       ;;xor YG_PF, YG_PF
  2701.       xor edx, edx
  2702.       ;; ext sign
  2703.       movsx ax, al
  2704.       mov cx, [YG_GP].SP_
  2705.       and ecx, 0FFFFh
  2706.       and eax, 0FFFFh
  2707.       lea edx, [ecx+eax]
  2708.       ;; SetH
  2709.       mov [YG_GP].HL, dx
  2710.       xor cx, ax
  2711.       mov ax, dx
  2712.       xor cx, ax
  2713.       and cx, 01000h
  2714.       shr cx, 8
  2715.       ;;or YG_PF, ecx
  2716.       ;; SetC
  2717.       and dx, 010000h
  2718.       shr dx, 16
  2719.       ;;or YG_PF, edx
  2720.       SetCyclesRetP 12
  2721.      
  2722.       ;; ALU, LOGIC 0x8x- 0xBx---------------------------------------------------------------------------------------
  2723.  
  2724. Add$c_xHLrToA macro atomic_it, Cycles
  2725. ;; atomic_it 0(add) or 1(adc)
  2726. ;; source value <- eax
  2727. ;; target <- always register A
  2728.   and eax, 0FFh ;; Value &= 0xFF
  2729.   and YG_PF, atomic_it
  2730.   shr YG_PF, 1 ;; check c-flags
  2731.   movzx edx, [YG_GP].A
  2732.   mov ecx, edx ;; temp WORD := A
  2733.   adc ecx, eax ;; temp WORD := A + Value
  2734.   mov [YG_GP].A, cl  ;; always write back A.
  2735.   xor dx, ax  
  2736.   mov ax, cx  
  2737.   xor ax, dx  ;; temp WORD:= temp WORD^(A ^Value)
  2738.   and ax, 010h
  2739.   or YG_PF, eax   ;; SetH
  2740.   or YG_PF_8, ch  ;; SetC
  2741.   test cl, cl
  2742.   setz cl
  2743.   shl ecx, 6
  2744.   or YG_PF, ecx ;; SetZ  XXX:ZTable
  2745. endm
  2746.      
  2747. CmpSub$bc_xHLrToA macro atomic_it, Cycles, Register ;; [YG_GP].A || cl for cmp opcode
  2748. ;; source <- eax
  2749. ;; target <- always register A  or nodone
  2750.   and eax, 0FFh ;; Value &= 0xFF
  2751.   and YG_PF, atomic_it
  2752.   shr YG_PF, 1 ;; check c-flags
  2753.   movzx edx, [YG_GP].A
  2754.   mov ecx, edx ;; temp WORD := A
  2755.   sbb ecx, eax ;; temp WORD := A - Value
  2756.   mov Register, cl  ;; always write back A.
  2757.   xor dx, ax  
  2758.   mov ax, cx  
  2759.   xor ax, dx  ;; temp WORD:= temp WORD^(A ^Value)
  2760.   and ax, 010h
  2761.   or YG_PF, eax   ;; SetH
  2762.   mov eax, ecx
  2763.   shr ax, 15
  2764.   or YG_PF_8, al  ;; SetC
  2765.   test cl, cl
  2766.   setz cl
  2767.   shl ecx, 6
  2768.   or YG_PF, ecx ;; SetZ  XXX:ZTable
  2769.   or YG_PF, N_FLAG ;; SetN
  2770. endm
  2771.      
  2772. ;; XOR | OR | AND do unwind base .
  2773. Logic_T macro   Cycles, initFlags, LogicOp
  2774. ;; source <- eax
  2775. ;; target <- always register A
  2776.  
  2777. ;; clear psb .
  2778.   mov YG_PF, initFlags
  2779.   movzx edx, [YG_GP].A
  2780.   LogicOp eax, edx
  2781.   ;; always write back A.
  2782.   mov [YG_GP].A, al
  2783.  
  2784.   ;; SetZ  XXX:ZTable
  2785.   test al, al
  2786.   setz al
  2787.   shl eax, 6
  2788.   or YG_PF, eax
  2789. endm  
  2790.      
  2791. ;; unwind
  2792. Add_ macro Cycles
  2793.   Add$c_xHLrToA 0, Cycles
  2794. endm
  2795.  
  2796. Adc_ macro Cycles
  2797.   Add$c_xHLrToA 1, Cycles
  2798. endm
  2799.  
  2800. Sub_ macro Cycles
  2801.   CmpSub$bc_xHLrToA 0, Cycles, [YG_GP].A
  2802. endm  
  2803.      
  2804. Sbc_ macro Cycles
  2805.   CmpSub$bc_xHLrToA 1, Cycles, [YG_GP].A
  2806. endm      
  2807.  
  2808. Cmp_ macro Cycles
  2809.   CmpSub$bc_xHLrToA 0, Cycles, cl
  2810. endm  
  2811.      
  2812. And_ macro Cycles
  2813.   Logic_T Cycles, H_FLAG, and
  2814. endm  
  2815.      
  2816. Xor_ macro Cycles
  2817.   Logic_T Cycles, 0, xor
  2818. endm      
  2819.  
  2820. Or_ macro Cycles
  2821.   Logic_T Cycles, 0, or
  2822. endm      
  2823.  
  2824. AddWord_  macro
  2825. ;; source <- eax
  2826. ;; target <- always register HL
  2827.  
  2828. ;; clear psb . save old Z
  2829.   and YG_PF, Z_FLAG
  2830.   movzx ecx, [YG_GP].HL
  2831.   and eax, 0FFFFh
  2832.   lea edx, [eax+ecx]
  2833.   ;; always write back HL.
  2834.   mov [YG_GP].HL, dx
  2835.   ;; SetH
  2836.   xor cx, ax
  2837.   mov ax, dx
  2838.   xor cx, ax
  2839.   and cx, 01000h
  2840.   shr cx, 8
  2841.   or YG_PF, ecx
  2842.   ;; SetC
  2843.   and edx, 010000h
  2844.   shr edx, 16
  2845.   or YG_PF, edx
  2846. endm
  2847.  
  2848. ;; TO SP
  2849. AddWord2_  macro
  2850. ;; source <- eax
  2851. ;; target <- always register SP
  2852.  
  2853. ;; clear psb . save old Z
  2854.   ;; xor YG_PF, YG_PF
  2855.   movzx ecx, [YG_GP].SP_
  2856.   and eax, 0FFFFh
  2857.   lea edx, [eax+ecx]
  2858.   ;; always write back SP.
  2859.   mov [YG_GP].SP_, dx
  2860.   ;; SetH
  2861.   xor cx, ax
  2862.   mov ax, dx
  2863.   xor cx, ax
  2864.   and cx, 01000h
  2865.   shr cx, 8
  2866.   ;;or YG_PF, ecx
  2867.   ;; SetC
  2868.   and dx, 010000h
  2869.   shr dx, 16
  2870.   ;;or YG_PF, edx
  2871. endm
  2872.  
  2873.  
  2874. DecWord_  macro
  2875.   dec eax
  2876. endm
  2877.  
  2878. IncWord_  macro
  2879.   inc eax
  2880. endm
  2881.  
  2882. Inc_  macro  ;; -----------------------
  2883. ;; source <- eax
  2884. ;; clear psb . save old Z
  2885.   and YG_PF, C_FLAG
  2886.   and eax, 0FFh
  2887.   lea edx, [eax+1]
  2888.   mov ecx, edx
  2889.  
  2890.   ;; SetH
  2891.   xor cx, ax
  2892.   and cx, 010h
  2893.   or YG_PF, ecx
  2894.  
  2895.   mov eax, edx
  2896.   test dl, dl
  2897.   setz dl  
  2898.   shl dl, 6
  2899.   or YG_PF, edx
  2900. endm
  2901.  
  2902. Dec_  macro  ;; -----------------------
  2903. ;; source <- eax
  2904. ;; clear psb . save old Z
  2905.   and YG_PF, C_FLAG
  2906.   or YG_PF, N_FLAG
  2907.   and eax, 0FFh
  2908.   lea edx, [eax-1]
  2909.   mov ecx, edx
  2910.  
  2911.   ;; SetH
  2912.   xor cx, ax
  2913.   and cx, 010h
  2914.   or YG_PF, ecx
  2915.  
  2916.   mov eax, edx
  2917.   test dl, dl
  2918.   setz dl
  2919.   shl dl, 6
  2920.   or YG_PF, edx
  2921. endm
  2922.  
  2923. ;; --- Include OP, imm8 and ADD Word Register.
  2924. Opcode@MainALU  macro  Opcode, Cycles, ReadOrExt, Op, WriteOrExt
  2925.   Opcode&:
  2926.     ReadOrExt
  2927.     Op
  2928.     WriteOrExt
  2929.     SetCyclesRetP Cycles
  2930. endm
  2931.       Opcode@MainALU  OP80, 4, B_Read, Add_, EmptyMacro ;; ADD A, B  1 Cycles:4
  2932.       Opcode@MainALU  OP81, 4, C_Read, Add_, EmptyMacro ;; ADD A, C  1 Cycles:4    
  2933.       Opcode@MainALU  OP82, 4, D_Read, Add_, EmptyMacro ;; ADD A, D  1 Cycles:4
  2934.       Opcode@MainALU  OP83, 4, E_Read, Add_, EmptyMacro ;; ADD A, E  1 Cycles:4      
  2935.       Opcode@MainALU  OP84, 4, H_Read, Add_, EmptyMacro ;; ADD A, H  1 Cycles:4
  2936.       Opcode@MainALU  OP85, 4, L_Read, Add_, EmptyMacro ;; ADD A, L  1 Cycles:4    
  2937.       Opcode@MainALU  OP86, 8, xHL_Read, Add_, EmptyMacro ;; ADD A, xHL  1 Cycles:8
  2938.       Opcode@MainALU  OP87, 4, A_Read, Add_, EmptyMacro ;; ADD A, A  1 Cycles:4  
  2939.       Opcode@MainALU  OPC6, 8, Imm8_Read, Add_, EmptyMacro ;; ADD A, Imm8  2 Cycles:8
  2940.       Opcode@MainALU  OP09, 8, BC_Read, AddWord_, HL_Write ;; ADD HL, BC  1 Cycles:8    
  2941.       Opcode@MainALU  OP19, 8, DE_Read, AddWord_, HL_Write ;; ADD HL, DE  1 Cycles:8    
  2942.       Opcode@MainALU  OP29, 8, HL_Read, AddWord_, HL_Write ;; ADD HL, HL  1 Cycles:8    
  2943.       Opcode@MainALU  OP39, 8, SP_Read, AddWord_, HL_Write ;; ADD HL, SP  1 Cycles:8    
  2944.       Opcode@MainALU  OPE8,16, Imm8_ExpandSignWord, AddWord2_, EmptyMacro ;; ADD SP, SignImm8  2 Cycles:16
  2945.      
  2946.       Opcode@MainALU  OP88, 4, B_Read, Adc_, EmptyMacro ;; ADC A, B  1 Cycles:4
  2947.       Opcode@MainALU  OP89, 4, C_Read, Adc_, EmptyMacro ;; ADC A, C  1 Cycles:4    
  2948.       Opcode@MainALU  OP8A, 4, D_Read, Adc_, EmptyMacro ;; ADC A, D  1 Cycles:4
  2949.       Opcode@MainALU  OP8B, 4, E_Read, Adc_, EmptyMacro ;; ADC A, E  1 Cycles:4      
  2950.       Opcode@MainALU  OP8C, 4, H_Read, Adc_, EmptyMacro ;; ADC A, H  1 Cycles:4
  2951.       Opcode@MainALU  OP8D, 4, L_Read, Adc_, EmptyMacro ;; ADC A, L  1 Cycles:4    
  2952.       Opcode@MainALU  OP8E, 8, xHL_Read, Adc_, EmptyMacro ;; ADC A, xHL  1 Cycles:8
  2953.       Opcode@MainALU  OP8F, 4, A_Read, Adc_, EmptyMacro ;; ADC A, A  1 Cycles:4  
  2954.       Opcode@MainALU  OPCE, 8, Imm8_Read, Adc_, EmptyMacro ;; ADC A, Imm8  2 Cycles:8    
  2955.      
  2956.       Opcode@MainALU  OP03, 8, BC_Read, IncWord_, BC_Write ;; INC BC  Cycles:8
  2957.       Opcode@MainALU  OP13, 8, DE_Read, IncWord_, DE_Write ;; INC DE  Cycles:8
  2958.       Opcode@MainALU  OP23, 8, HL_Read, IncWord_, HL_Write ;; INC HL  Cycles:8
  2959.       Opcode@MainALU  OP33, 8, SP_Read, IncWord_, SP_Write ;; INC SP  Cycles:8
  2960.      
  2961.       Opcode@MainALU  OP04, 4, B_Read, Inc_, B_Write ;; INC B  1 Cycles:4
  2962.       Opcode@MainALU  OP14, 4, D_Read, Inc_, D_Write ;; INC D  1 Cycles:4    
  2963.       Opcode@MainALU  OP24, 4, H_Read, Inc_, H_Write ;; INC H  1 Cycles:4
  2964.       Opcode@MainALU  OP34, 4, xHL_Read, Inc_, xHL_Write ;; INC xHL  1 Cycles:4      
  2965.       Opcode@MainALU  OP0C, 4, C_Read, Inc_, C_Write ;; INC C  1 Cycles:4
  2966.       Opcode@MainALU  OP1C, 4, E_Read, Inc_, E_Write ;; INC E  1 Cycles:4    
  2967.       Opcode@MainALU  OP2C,12, L_Read, Inc_, L_Write ;; INC L  1 Cycles:12
  2968.       Opcode@MainALU  OP3C, 4, A_Read, Inc_, A_Write ;; INC A  1 Cycles:4      
  2969.      
  2970.       Opcode@MainALU  OP90, 4, B_Read, Sub_, EmptyMacro ;; SUB A, B  1 Cycles:4
  2971.       Opcode@MainALU  OP91, 4, C_Read, Sub_, EmptyMacro ;; SUB A, C  1 Cycles:4    
  2972.       Opcode@MainALU  OP92, 4, D_Read, Sub_, EmptyMacro ;; SUB A, D  1 Cycles:4
  2973.       Opcode@MainALU  OP93, 4, E_Read, Sub_, EmptyMacro ;; SUB A, E  1 Cycles:4      
  2974.       Opcode@MainALU  OP94, 4, H_Read, Sub_, EmptyMacro ;; SUB A, H  1 Cycles:4
  2975.       Opcode@MainALU  OP95, 4, L_Read, Sub_, EmptyMacro ;; SUB A, L  1 Cycles:4    
  2976.       Opcode@MainALU  OP96, 8, xHL_Read, Sub_, EmptyMacro ;; SUB A, xHL  1 Cycles:8
  2977.       Opcode@MainALU  OP97, 4, A_Read, Sub_, EmptyMacro ;; SUB A, A  1 Cycles:4  
  2978.       Opcode@MainALU  OPD6, 8, Imm8_Read, Sub_, EmptyMacro ;; SUB A, Imm8  2 Cycles:8
  2979.      
  2980.       Opcode@MainALU  OP98, 4, B_Read, Sbc_, EmptyMacro ;; SBC A, B  1 Cycles:4
  2981.       Opcode@MainALU  OP99, 4, C_Read, Sbc_, EmptyMacro ;; SBC A, C  1 Cycles:4    
  2982.       Opcode@MainALU  OP9A, 4, D_Read, Sbc_, EmptyMacro ;; SBC A, D  1 Cycles:4
  2983.       Opcode@MainALU  OP9B, 4, E_Read, Sbc_, EmptyMacro ;; SBC A, E  1 Cycles:4      
  2984.       Opcode@MainALU  OP9C, 4, H_Read, Sbc_, EmptyMacro ;; SBC A, H  1 Cycles:4
  2985.       Opcode@MainALU  OP9D, 4, L_Read, Sbc_, EmptyMacro ;; SBC A, L  1 Cycles:4    
  2986.       Opcode@MainALU  OP9E, 8, xHL_Read, Sbc_, EmptyMacro ;; SBC A, xHL  1 Cycles:8
  2987.       Opcode@MainALU  OP9F, 4, A_Read, Sbc_, EmptyMacro ;; SBC A, A  1 Cycles:4  
  2988.       Opcode@MainALU  OPDE, 8, Imm8_Read, Sbc_, EmptyMacro ;; SBC A, Imm8  2 Cycles:8
  2989.    
  2990.       Opcode@MainALU  OP0B, 8, BC_Read, DecWord_, BC_Write ;; DEC BC  Cycles:8
  2991.       Opcode@MainALU  OP1B, 8, DE_Read, DecWord_, DE_Write ;; DEC DE  Cycles:8
  2992.       Opcode@MainALU  OP2B, 8, HL_Read, DecWord_, HL_Write ;; DEC HL  Cycles:8
  2993.       Opcode@MainALU  OP3B, 8, SP_Read, DecWord_, SP_Write ;; DEC SP  Cycles:8
  2994.      
  2995.       Opcode@MainALU  OP05, 4, B_Read, Dec_, B_Write ;; DEC B  1 Cycles:4
  2996.       Opcode@MainALU  OP15, 4, D_Read, Dec_, D_Write ;; DEC D  1 Cycles:4    
  2997.       Opcode@MainALU  OP25, 4, H_Read, Dec_, H_Write ;; DEC H  1 Cycles:4
  2998.       Opcode@MainALU  OP35, 4, xHL_Read, Dec_, xHL_Write ;; DEC xHL  1 Cycles:4      
  2999.       Opcode@MainALU  OP0D, 4, C_Read, Dec_, C_Write ;; DEC C  1 Cycles:4
  3000.       Opcode@MainALU  OP1D, 4, E_Read, Dec_, E_Write ;; DEC E  1 Cycles:4    
  3001.       Opcode@MainALU  OP2D,12, L_Read, Dec_, L_Write ;; DEC L  1 Cycles:12
  3002.       Opcode@MainALU  OP3D, 4, A_Read, Dec_, A_Write ;; DEC A  1 Cycles:4  
  3003.      
  3004.       Opcode@MainALU  OPA0, 4, B_Read, And_, EmptyMacro ;; AND A, B  1 Cycles:4
  3005.       Opcode@MainALU  OPA1, 4, C_Read, And_, EmptyMacro ;; AND A, C  1 Cycles:4    
  3006.       Opcode@MainALU  OPA2, 4, D_Read, And_, EmptyMacro ;; AND A, D  1 Cycles:4
  3007.       Opcode@MainALU  OPA3, 4, E_Read, And_, EmptyMacro ;; AND A, E  1 Cycles:4      
  3008.       Opcode@MainALU  OPA4, 4, H_Read, And_, EmptyMacro ;; AND A, H  1 Cycles:4
  3009.       Opcode@MainALU  OPA5, 4, L_Read, And_, EmptyMacro ;; AND A, L  1 Cycles:4    
  3010.       Opcode@MainALU  OPA6, 8, xHL_Read, And_, EmptyMacro ;; AND A, xHL  1 Cycles:8
  3011.       Opcode@MainALU  OPA7, 4, A_Read, And_, EmptyMacro ;; AND A, A  1 Cycles:4  
  3012.       Opcode@MainALU  OPE6, 8, Imm8_Read, And_, EmptyMacro ;; AND A, Imm8  2 Cycles:8
  3013.        
  3014.       Opcode@MainALU  OPA8, 4, B_Read, Xor_, EmptyMacro ;; XOR A, B  1 Cycles:4
  3015.       Opcode@MainALU  OPA9, 4, C_Read, Xor_, EmptyMacro ;; XOR A, C  1 Cycles:4    
  3016.       Opcode@MainALU  OPAA, 4, D_Read, Xor_, EmptyMacro ;; XOR A, D  1 Cycles:4
  3017.       Opcode@MainALU  OPAB, 4, E_Read, Xor_, EmptyMacro ;; XOR A, E  1 Cycles:4      
  3018.       Opcode@MainALU  OPAC, 4, H_Read, Xor_, EmptyMacro ;; XOR A, H  1 Cycles:4
  3019.       Opcode@MainALU  OPAD, 4, L_Read, Xor_, EmptyMacro ;; XOR A, L  1 Cycles:4    
  3020.       Opcode@MainALU  OPAE, 8, xHL_Read, Xor_, EmptyMacro ;; XOR A, xHL  1 Cycles:8
  3021.       Opcode@MainALU  OPAF, 4, A_Read, Xor_, EmptyMacro ;; XOR A, A  1 Cycles:4  
  3022.       Opcode@MainALU  OPEE, 8, Imm8_Read, Xor_, EmptyMacro ;; XOR A, Imm8  2 Cycles:8
  3023.      
  3024.       Opcode@MainALU  OPB0, 4, B_Read, Or_, EmptyMacro ;; OR A, B  1 Cycles:4
  3025.       Opcode@MainALU  OPB1, 4, C_Read, Or_, EmptyMacro ;; OR A, C  1 Cycles:4    
  3026.       Opcode@MainALU  OPB2, 4, D_Read, Or_, EmptyMacro ;; OR A, D  1 Cycles:4
  3027.       Opcode@MainALU  OPB3, 4, E_Read, Or_, EmptyMacro ;; OR A, E  1 Cycles:4      
  3028.       Opcode@MainALU  OPB4, 4, H_Read, Or_, EmptyMacro ;; OR A, H  1 Cycles:4
  3029.       Opcode@MainALU  OPB5, 4, L_Read, Or_, EmptyMacro ;; OR A, L  1 Cycles:4    
  3030.       Opcode@MainALU  OPB6, 8, xHL_Read, Or_, EmptyMacro ;; OR A, xHL  1 Cycles:8
  3031.       Opcode@MainALU  OPB7, 4, A_Read, Or_, EmptyMacro ;; OR A, A  1 Cycles:4  
  3032.       Opcode@MainALU  OPF6, 8, Imm8_Read, Or_, EmptyMacro ;; OR A, Imm8  2 Cycles:8
  3033.      
  3034.       Opcode@MainALU  OPB8, 4, B_Read, Cmp_, EmptyMacro ;; CP A, B  1 Cycles:4
  3035.       Opcode@MainALU  OPB9, 4, C_Read, Cmp_, EmptyMacro ;; CP A, C  1 Cycles:4    
  3036.       Opcode@MainALU  OPBA, 4, D_Read, Cmp_, EmptyMacro ;; CP A, D  1 Cycles:4
  3037.       Opcode@MainALU  OPBB, 4, E_Read, Cmp_, EmptyMacro ;; CP A, E  1 Cycles:4      
  3038.       Opcode@MainALU  OPBC, 4, H_Read, Cmp_, EmptyMacro ;; CP A, H  1 Cycles:4
  3039.       Opcode@MainALU  OPBD, 4, L_Read, Cmp_, EmptyMacro ;; CP A, L  1 Cycles:4    
  3040.       Opcode@MainALU  OPBE, 8, xHL_Read, Cmp_, EmptyMacro ;; CP A, xHL  1 Cycles:8
  3041.       Opcode@MainALU  OPBF, 4, A_Read, Cmp_, EmptyMacro ;; CP A, A  1 Cycles:4  
  3042.       Opcode@MainALU  OPFE, 8, Imm8_Read, Cmp_, EmptyMacro ;; CP A, Imm8  2 Cycles:8
  3043.      
  3044. PushWord_  macro  ;; -----------------------
  3045. ;; source <- eax
  3046.   mov cx, [YG_GP].SP_
  3047.   sub cx, 2
  3048.   mov [YG_GP].SP_, cx
  3049.   push eax
  3050.   push ecx
  3051.   push [YG_GP].gameboy
  3052.   call gameboy_mmu_write_w@12
  3053. endm
  3054.  
  3055. PopWord_  macro  ;; -----------------------
  3056.   mov cx, [YG_GP].SP_
  3057.   push ecx
  3058.   add cx, 2
  3059.   mov [YG_GP].SP_, cx
  3060.   push [YG_GP].gameboy
  3061.   call gameboy_mmu_read_w@8
  3062. endm
  3063.  
  3064. ;; ---
  3065. Opcode@MainStackOperate  macro  Opcode, Cycles, ReadOrExt, Op, WriteOrExt
  3066.   Opcode&:
  3067.     ReadOrExt
  3068.     Op
  3069.     WriteOrExt
  3070.     SetCyclesAndRet Cycles
  3071. endm  
  3072.  
  3073.       Opcode@MainStackOperate  OPC1,12, PopWord_, EmptyMacro, BC_Write ;; POP BC  1 Cycles:12
  3074.       Opcode@MainStackOperate  OPD1,12, PopWord_, EmptyMacro, DE_Write ;; POP DE  1 Cycles:12    
  3075.       Opcode@MainStackOperate  OPE1,12, PopWord_, EmptyMacro, HL_Write ;; POP HL  1 Cycles:12
  3076.       Opcode@MainStackOperate  OPF1,12, PopWord_, EmptyMacro, AF_Write ;; POP AF  1 Cycles:12  
  3077.      
  3078.       Opcode@MainStackOperate  OPC5,16, BC_Read, EmptyMacro, PushWord_ ;; PUSH BC  1 Cycles:16
  3079.       Opcode@MainStackOperate  OPD5,16, DE_Read, EmptyMacro, PushWord_ ;; PUSH DE  1 Cycles:16    
  3080.       Opcode@MainStackOperate  OPE5,16, HL_Read, EmptyMacro, PushWord_ ;; PUSH HL  1 Cycles:16
  3081.       Opcode@MainStackOperate  OPF5,16, AF_Read, EmptyMacro, PushWord_ ;; PUSH AF  1 Cycles:16  
  3082.  
  3083. Opcode@Rst  macro  Opcode, Cycles, Vector
  3084.   Opcode&:
  3085.     mov ax, si
  3086.     PushWord_
  3087.     mov si, Vector
  3088.     SetCyclesRetP Cycles
  3089. endm  
  3090.  
  3091.       Opcode@Rst  OPC7,16, 000H ;; RST 00H  1 Cycles:16
  3092.       Opcode@Rst  OPD7,16, 010H ;; RST 10H  1 Cycles:16    
  3093.       Opcode@Rst  OPE7,16, 020H ;; RST 20H  1 Cycles:16
  3094.       Opcode@Rst  OPF7,16, 030H ;; RST 30H  1 Cycles:16  
  3095.       Opcode@Rst  OPCF,16, 008H ;; RST 08H  1 Cycles:16
  3096.       Opcode@Rst  OPDF,16, 018H ;; RST 18H  1 Cycles:16    
  3097.       Opcode@Rst  OPEF,16, 028H ;; RST 28H  1 Cycles:16
  3098.       Opcode@Rst  OPFF,16, 038H ;; RST 38H  1 Cycles:16    
  3099.      
  3100. Opcode@JR    macro  Opcode, Flags, OpNOT
  3101.    Opcode&:
  3102.       mov eax, YG_PF
  3103.       and eax, Flags
  3104.       xor eax, OpNOT
  3105.       jne @F
  3106.       inc esi
  3107.       SetCyclesRetP 8
  3108.     @@:
  3109.       Imm8_Read
  3110.       movsx eax, al
  3111.       add esi, eax
  3112.       SetCyclesRetP 12
  3113. endm
  3114.       Opcode@JR  OP20,Z_FLAG, Z_FLAG ;; JR NZ
  3115.       Opcode@JR  OP30,C_FLAG, C_FLAG ;; JR NC
  3116.       Opcode@JR  OP28,Z_FLAG, 0 ;; JR Z
  3117.       Opcode@JR  OP38,C_FLAG, 0 ;; JR C  
  3118.       Opcode@JR  OP18,0, 1 ;; JR R8
  3119.      
  3120. Opcode@JP    macro  Opcode, Flags, OpNOT
  3121.    Opcode&:
  3122.       mov eax, YG_PF
  3123.       and eax, Flags
  3124.       xor eax, OpNOT
  3125.       jne @F
  3126.       add esi, 2
  3127.       SetCyclesRetP 12
  3128.     @@:
  3129.       Imm16_Read
  3130.       mov esi, eax
  3131.       SetCyclesRetP 16
  3132. endm      
  3133.       Opcode@JP  OPC2,Z_FLAG, Z_FLAG ;; JP NZ
  3134.       Opcode@JP  OPD2,C_FLAG, C_FLAG ;; JP NC
  3135.       Opcode@JP  OPCA,Z_FLAG, 0 ;; JP Z
  3136.       Opcode@JP  OPDA,C_FLAG, 0 ;; JP C  
  3137.       Opcode@JP  OPC3,0, 1 ;; JP A16
  3138.     OPE9:
  3139.       mov si, [YG_GP].HL
  3140.       mov [YG_GP].PC, ax
  3141.       SetCyclesAndRet 4
  3142.       ;; LD@RxHLToRxHL OPE9, 4, HL_Read, PC_Write ;; JP (HL), Same as LD PC HL, 1 Cycles:4  
  3143.  
  3144. Opcode@CALL    macro  Opcode, Flags, OpNOT
  3145.    Opcode&:
  3146.       mov eax, YG_PF
  3147.       and eax, Flags
  3148.       xor eax, OpNOT
  3149.       jne @F
  3150.       add esi, 2
  3151.       SetCyclesRetP 12
  3152.     @@:
  3153.       lea eax, [YG_PC+2]
  3154.       PushWord_
  3155.       Imm16_Read
  3156.       mov esi, eax
  3157.       SetCyclesRetP 24
  3158. endm
  3159.       Opcode@CALL  OPC4,Z_FLAG, Z_FLAG ;; CALL NZ
  3160.       Opcode@CALL  OPD4,C_FLAG, C_FLAG ;; CALL NC
  3161.       Opcode@CALL  OPCC,Z_FLAG, 0 ;; CALL Z
  3162.       Opcode@CALL  OPDC,C_FLAG, 0 ;; CALL C  
  3163.       Opcode@CALL  OPCD,0, 1 ;; CALL  
  3164.      
  3165. Opcode@RET    macro  Opcode, Flags, OpNOT, RetHitCycles
  3166.    Opcode&:
  3167.       mov eax, YG_PF
  3168.       and eax, Flags
  3169.       xor eax, OpNOT
  3170.       jne @F
  3171.       SetCyclesRetP 8
  3172.     @@:
  3173.       PopWord_
  3174.       mov YG_PC, eax
  3175.       SetCyclesRetP RetHitCycles
  3176. endm      
  3177.  
  3178. Opcode@RETI    macro  Opcode, Flags, OpNOT, RetHitCycles
  3179.    Opcode&:
  3180.       mov eax, YG_PF
  3181.       and eax, Flags
  3182.       xor eax, OpNOT
  3183.       jne @F
  3184.       SetCyclesRetP 8
  3185.     @@:
  3186.       PopWord_
  3187.       mov YG_PC, eax
  3188.       mov [YG_GP].IME, 1
  3189.       SetCyclesRetP RetHitCycles
  3190. endm
  3191.  
  3192.       Opcode@RET  OPC0,Z_FLAG, Z_FLAG, 20 ;; RET NZ
  3193.       Opcode@RET  OPD0,C_FLAG, C_FLAG, 20 ;; RET NC
  3194.       Opcode@RET  OPC8,Z_FLAG, 0, 20 ;; RET Z
  3195.       Opcode@RET  OPD8,C_FLAG, 0, 20 ;; RET C  
  3196.       Opcode@RET  OPC9,0, 1, 16 ;; RET  
  3197.       Opcode@RETI OPD9,0, 1, 16 ;; RETI
  3198.      
  3199. ;;  MISC 8.
  3200.       OP76:   ; Halt,  not backup PC in my source code ^_^
  3201.         mov [YG_GP].halt, 1
  3202.         SetCyclesAndRet 4    
  3203.       OP10:   ; Stop, Check CGB speed mode
  3204.         movzx eax, [YG_GP].key1
  3205.         test eax, 1
  3206.         je @F
  3207.         xor eax, 080H ;; switch to "other" speed
  3208.         and eax, 0FEH ;; reset LSB  see gb-programming-manual.pdf::2.6.2 CPU Operating Speed
  3209.                       ;; for simplicity, I will not simulate the huge waste of time brought by handover.
  3210.         mov [YG_GP].key1, al
  3211.         SetCyclesAndRet 080000004H
  3212.      @@:mov [YG_GP].stop, 1
  3213.         add YG_PC, 1 ;; skip one byte (should is 00)
  3214.       OP00:   ; NOP
  3215.         SetCyclesAndRet 4          
  3216.       OPF3:   ; DI
  3217.         mov [YG_GP].IME, 0
  3218.         SetCyclesAndRet 4
  3219.       OPFB:   ; EI
  3220.         mov [YG_GP].IME, 1
  3221.         SetCyclesAndRet 4  
  3222.       OP07:   ; RLCA
  3223.         rol [YG_GP].A, 1
  3224.         setc YG_PF_8
  3225.         SetCyclesRetP 4
  3226.       OP17:   ; RLA
  3227.         shr YG_PF_8, 1
  3228.         rcl [YG_GP].A, 1
  3229.         setc YG_PF_8
  3230.         SetCyclesRetP 4    
  3231.       OP0F:   ; RRCA
  3232.         ror [YG_GP].A, 1
  3233.         setc YG_PF_8
  3234.         SetCyclesRetP 4
  3235.       OP1F:   ; RRA
  3236.         shr YG_PF_8, 1
  3237.         rcr [YG_GP].A, 1
  3238.         setc YG_PF_8
  3239.         SetCyclesRetP 4    
  3240.       OP27:   ; DAA  
  3241.         SetCyclesRetP 4    
  3242.         mov al, [YG_GP].A
  3243.         and YG_PF_8, N_FLAG
  3244.         jne DAS_Proc
  3245.         ;;  DAA.
  3246.         daa
  3247.         mov [YG_GP].A, al
  3248.         setc YG_PF_8  ;; SETC
  3249.         setz al
  3250.         shl al, 6
  3251.         or YG_PF_8, al
  3252.         SetCyclesRetP 4        
  3253.     DAS_Proc:
  3254.         ;;  DAS
  3255.         das    
  3256.         mov [YG_GP].A, al
  3257.         setc YG_PF_8  ;; SETC
  3258.         setz al
  3259.         shl al, 6
  3260.         or YG_PF_8, al
  3261.         or YG_PF_8, N_FLAG
  3262.         SetCyclesRetP 4    
  3263.       OP37:   ; SCF
  3264.         and YG_PF_8, Z_FLAG
  3265.         or YG_PF_8, C_FLAG  
  3266.         SetCyclesRetP 4    
  3267.       OP2F:   ; CPL  
  3268.         not [YG_GP].A
  3269.         or YG_PF_8, N_FLAG
  3270.         or YG_PF_8, H_FLAG
  3271.         SetCyclesRetP 4  
  3272.       OP3F:   ; CCF
  3273.         and YG_PF_8, ZC_FLAG
  3274.         xor YG_PF_8, C_FLAG  
  3275.         SetCyclesRetP 4
  3276.          
  3277.       ;; rortoe shift with  
  3278.       RLC_ macro Cycles
  3279.         rol al, 1
  3280.         setc YG_PF_8
  3281.         test al, al
  3282.         setz dl
  3283.         shl dl, 6
  3284.         or YG_PF_8, dl    
  3285.       endm
  3286.       ;; rortoe shift with  
  3287.       RRC_ macro Cycles
  3288.         ror al, 1
  3289.         setc YG_PF_8
  3290.         test al, al
  3291.         setz dl
  3292.         shl dl, 6
  3293.         or YG_PF_8, dl    
  3294.       endm      
  3295.       ;; logic shift with carry
  3296.       RL_ macro Cycles
  3297.         shr YG_PF_8, 1
  3298.         rcl al, 1
  3299.         setc YG_PF_8
  3300.         test al, al
  3301.         setz dl
  3302.         shl dl, 6
  3303.         or YG_PF_8, dl    
  3304.       endm
  3305.       ;; logic shift with carry
  3306.       RR_ macro Cycles
  3307.         shr YG_PF_8, 1
  3308.         rcr al, 1
  3309.         setc YG_PF_8
  3310.         test al, al
  3311.         setz dl
  3312.         shl dl, 6
  3313.         or YG_PF_8, dl    
  3314.       endm      
  3315.       ;; logic shift    
  3316.       RL_N_ macro Cycles
  3317.         shl al, 1
  3318.         setc YG_PF_8
  3319.         test al, al
  3320.         setz dl
  3321.         shl dl, 6
  3322.         or YG_PF_8, dl    
  3323.       endm
  3324.       ;; logic shift  
  3325.       RR_N_ macro Cycles
  3326.         shr al, 1
  3327.         setc YG_PF_8
  3328.         test al, al
  3329.         setz dl
  3330.         shl dl, 6
  3331.         or YG_PF_8, dl    
  3332.       endm    
  3333.       ;; arith shift  save msb
  3334.       RRS_N_ macro Cycles
  3335.         sar al, 1
  3336.         setc YG_PF_8
  3337.         setz dl
  3338.         shl dl, 6
  3339.         or YG_PF_8, dl    
  3340.       endm    
  3341.       ;; swap byte-lo 4bit and byte-hi 4bit
  3342.       SWAP_ macro Cycles
  3343.         ror al, 4
  3344.         test al, al
  3345.         setz cl
  3346.         shl cl, 6
  3347.         mov YG_PF, ecx
  3348.       endm        
  3349.        
  3350.       ;;  Set
  3351.       Opcode@SetBit macro Opcode, Cycles,  ReadOrExt, BitOrder, WriteOrExt
  3352.         Opcode&:
  3353.           ReadOrExt
  3354.           mov ecx, 1
  3355.           shl ecx, BitOrder
  3356.           or eax, ecx
  3357.           WriteOrExt
  3358.           SetCyclesAndRet Cycles
  3359.       endm
  3360.      
  3361.       Opcode@ResBit macro Opcode, Cycles,  ReadOrExt, BitOrder, WriteOrExt
  3362.         Opcode&:
  3363.           ReadOrExt
  3364.           mov ecx, 1
  3365.           shl ecx, BitOrder
  3366.           not ecx
  3367.           and eax, ecx
  3368.           WriteOrExt
  3369.           SetCyclesAndRet Cycles
  3370.       endm        
  3371.          
  3372.       Opcode@TestBit macro Opcode, Cycles,  ReadOrExt, BitOrder
  3373.         Opcode&:
  3374.           ReadOrExt
  3375.           and YG_PF, C_FLAG
  3376.           or YG_PF, H_FLAG
  3377.           mov ecx, 1
  3378.           shl ecx, BitOrder
  3379.           test al, cl
  3380.           setz al
  3381.           shl eax, 6
  3382.           or YG_PF, eax
  3383.           SetCyclesRetP Cycles
  3384.       endm      
  3385.        
  3386.       OPCB: ;; ---------------------------------- Perfix CB -----------------------------------------------------------------------------
  3387.         Imm8_Read
  3388.         and eax, 255
  3389.         jmp dword ptr[CBTAB+eax*4]
  3390.        
  3391.         ;; --- Include OP, imm8 and ADD Word Register.
  3392.         Opcode@MainALUExt  macro  Opcode, Cycles, ReadOrExt, Op, WriteOrExt
  3393.           Opcode&:
  3394.             ReadOrExt
  3395.             Op
  3396.             WriteOrExt
  3397.             SetCyclesRetP Cycles
  3398.         endm  
  3399.        
  3400.         Opcode@MainALUExt  CB00, 8, B_Read, RLC_, B_Write      ;; RLC B 2 Cycles:8
  3401.         Opcode@MainALUExt  CB01, 8, C_Read, RLC_, C_Write      ;; RLC C 2 Cycles:8
  3402.         Opcode@MainALUExt  CB02, 8, D_Read, RLC_, D_Write      ;; RLC D 2 Cycles:8
  3403.         Opcode@MainALUExt  CB03, 8, E_Read, RLC_, E_Write      ;; RLC E 2 Cycles:8    
  3404.         Opcode@MainALUExt  CB04, 8, H_Read, RLC_, H_Write      ;; RLC H 2 Cycles:8
  3405.         Opcode@MainALUExt  CB05, 8, L_Read, RLC_, L_Write      ;; RLC L 2 Cycles:8        
  3406.         Opcode@MainALUExt  CB06,16, xHL_Read, RLC_, xHL_Write      ;; RLC xHL 2 Cycles:16
  3407.         Opcode@MainALUExt  CB07, 8, A_Read, RLC_, A_Write      ;; RLC A 2 Cycles:8        
  3408.        
  3409.         Opcode@MainALUExt  CB08, 8, B_Read, RRC_, B_Write      ;; RRC B 2 Cycles:8
  3410.         Opcode@MainALUExt  CB09, 8, C_Read, RRC_, C_Write      ;; RRC C 2 Cycles:8
  3411.         Opcode@MainALUExt  CB0A, 8, D_Read, RRC_, D_Write      ;; RRC D 2 Cycles:8
  3412.         Opcode@MainALUExt  CB0B, 8, E_Read, RRC_, E_Write      ;; RRC E 2 Cycles:8    
  3413.         Opcode@MainALUExt  CB0C, 8, H_Read, RRC_, H_Write      ;; RRC H 2 Cycles:8
  3414.         Opcode@MainALUExt  CB0D, 8, L_Read, RRC_, L_Write      ;; RRC L 2 Cycles:8        
  3415.         Opcode@MainALUExt  CB0E,16, xHL_Read, RRC_, xHL_Write      ;; RRC xHL 2 Cycles:16
  3416.         Opcode@MainALUExt  CB0F, 8, A_Read, RRC_, A_Write      ;; RRC A 2 Cycles:8    
  3417.        
  3418.         Opcode@MainALUExt  CB10, 8, B_Read, RL_, B_Write      ;; RL B 2 Cycles:8
  3419.         Opcode@MainALUExt  CB11, 8, C_Read, RL_, C_Write      ;; RL C 2 Cycles:8
  3420.         Opcode@MainALUExt  CB12, 8, D_Read, RL_, D_Write      ;; RL D 2 Cycles:8
  3421.         Opcode@MainALUExt  CB13, 8, E_Read, RL_, E_Write      ;; RL E 2 Cycles:8    
  3422.         Opcode@MainALUExt  CB14, 8, H_Read, RL_, H_Write      ;; RL H 2 Cycles:8
  3423.         Opcode@MainALUExt  CB15, 8, L_Read, RL_, L_Write      ;; RL L 2 Cycles:8        
  3424.         Opcode@MainALUExt  CB16,16, xHL_Read, RL_, xHL_Write      ;; RL xHL 2 Cycles:16
  3425.         Opcode@MainALUExt  CB17, 8, A_Read, RL_, A_Write      ;; RL A 2 Cycles:8        
  3426.        
  3427.         Opcode@MainALUExt  CB18, 8, B_Read, RR_, B_Write      ;; RR B 2 Cycles:8
  3428.         Opcode@MainALUExt  CB19, 8, C_Read, RR_, C_Write      ;; RR C 2 Cycles:8
  3429.         Opcode@MainALUExt  CB1A, 8, D_Read, RR_, D_Write      ;; RR D 2 Cycles:8
  3430.         Opcode@MainALUExt  CB1B, 8, E_Read, RR_, E_Write      ;; RR E 2 Cycles:8    
  3431.         Opcode@MainALUExt  CB1C, 8, H_Read, RR_, H_Write      ;; RR H 2 Cycles:8
  3432.         Opcode@MainALUExt  CB1D, 8, L_Read, RR_, L_Write      ;; RR L 2 Cycles:8        
  3433.         Opcode@MainALUExt  CB1E,16, xHL_Read, RR_, xHL_Write      ;; RR xHL 2 Cycles:16
  3434.         Opcode@MainALUExt  CB1F, 8, A_Read, RR_, A_Write      ;; RR A 2 Cycles:8            
  3435.        
  3436.         Opcode@MainALUExt  CB20, 8, B_Read, RL_N_, B_Write      ;; SLA B 2 Cycles:8
  3437.         Opcode@MainALUExt  CB21, 8, C_Read, RL_N_, C_Write      ;; SLA C 2 Cycles:8
  3438.         Opcode@MainALUExt  CB22, 8, D_Read, RL_N_, D_Write      ;; SLA D 2 Cycles:8
  3439.         Opcode@MainALUExt  CB23, 8, E_Read, RL_N_, E_Write      ;; SLA E 2 Cycles:8    
  3440.         Opcode@MainALUExt  CB24, 8, H_Read, RL_N_, H_Write      ;; SLA H 2 Cycles:8
  3441.         Opcode@MainALUExt  CB25, 8, L_Read, RL_N_, L_Write      ;; SLA L 2 Cycles:8        
  3442.         Opcode@MainALUExt  CB26,16, xHL_Read, RL_N_, xHL_Write      ;; SLA xHL 2 Cycles:16
  3443.         Opcode@MainALUExt  CB27, 8, A_Read, RL_N_, A_Write      ;; SLA A 2 Cycles:8        
  3444.        
  3445.         Opcode@MainALUExt  CB28, 8, B_Read, RRS_N_, B_Write      ;; SRA B 2 Cycles:8
  3446.         Opcode@MainALUExt  CB29, 8, C_Read, RRS_N_, C_Write      ;; SRA C 2 Cycles:8
  3447.         Opcode@MainALUExt  CB2A, 8, D_Read, RRS_N_, D_Write      ;; SRA D 2 Cycles:8
  3448.         Opcode@MainALUExt  CB2B, 8, E_Read, RRS_N_, E_Write      ;; SRA E 2 Cycles:8    
  3449.         Opcode@MainALUExt  CB2C, 8, H_Read, RRS_N_, H_Write      ;; SRA H 2 Cycles:8
  3450.         Opcode@MainALUExt  CB2D, 8, L_Read, RRS_N_, L_Write      ;; SRA L 2 Cycles:8        
  3451.         Opcode@MainALUExt  CB2E,16, xHL_Read, RRS_N_, xHL_Write      ;; SRA xHL 2 Cycles:16
  3452.         Opcode@MainALUExt  CB2F, 8, A_Read, RRS_N_, A_Write      ;; SRA A 2 Cycles:8      
  3453.        
  3454.         Opcode@MainALUExt  CB30, 8, B_Read, SWAP_, B_Write      ;; SWAP B 2 Cycles:8
  3455.         Opcode@MainALUExt  CB31, 8, C_Read, SWAP_, C_Write      ;; SWAP C 2 Cycles:8
  3456.         Opcode@MainALUExt  CB32, 8, D_Read, SWAP_, D_Write      ;; SWAP D 2 Cycles:8
  3457.         Opcode@MainALUExt  CB33, 8, E_Read, SWAP_, E_Write      ;; SWAP E 2 Cycles:8    
  3458.         Opcode@MainALUExt  CB34, 8, H_Read, SWAP_, H_Write      ;; SWAP H 2 Cycles:8
  3459.         Opcode@MainALUExt  CB35, 8, L_Read, SWAP_, L_Write      ;; SWAP L 2 Cycles:8        
  3460.         Opcode@MainALUExt  CB36,16, xHL_Read, SWAP_, xHL_Write      ;; SWAP xHL 2 Cycles:16
  3461.         Opcode@MainALUExt  CB37, 8, A_Read, SWAP_, A_Write      ;; SWAP A 2 Cycles:8        
  3462.        
  3463.         Opcode@MainALUExt  CB38, 8, B_Read, RR_N_, B_Write      ;; SRL B 2 Cycles:8
  3464.         Opcode@MainALUExt  CB39, 8, C_Read, RR_N_, C_Write      ;; SRL C 2 Cycles:8
  3465.         Opcode@MainALUExt  CB3A, 8, D_Read, RR_N_, D_Write      ;; SRL D 2 Cycles:8
  3466.         Opcode@MainALUExt  CB3B, 8, E_Read, RR_N_, E_Write      ;; SRL E 2 Cycles:8    
  3467.         Opcode@MainALUExt  CB3C, 8, H_Read, RR_N_, H_Write      ;; SRL H 2 Cycles:8
  3468.         Opcode@MainALUExt  CB3D, 8, L_Read, RR_N_, L_Write      ;; SRL L 2 Cycles:8        
  3469.         Opcode@MainALUExt  CB3E,16, xHL_Read, RR_N_, xHL_Write      ;; SRL xHL 2 Cycles:16
  3470.         Opcode@MainALUExt  CB3F, 8, A_Read, RR_N_, A_Write      ;; SRL A 2 Cycles:8        
  3471.        
  3472.         Opcode@TestBit CB40, 8,  B_Read, 0 ;; BIT B, 0 Cycles:8
  3473.         Opcode@TestBit CB41, 8,  C_Read, 0 ;; BIT C, 0 Cycles:8        
  3474.         Opcode@TestBit CB42, 8,  D_Read, 0 ;; BIT D, 0 Cycles:8        
  3475.         Opcode@TestBit CB43, 8,  E_Read, 0 ;; BIT E, 0 Cycles:8    
  3476.         Opcode@TestBit CB44, 8,  H_Read, 0 ;; BIT H, 0 Cycles:8
  3477.         Opcode@TestBit CB45, 8,  L_Read, 0 ;; BIT L, 0 Cycles:8        
  3478.         Opcode@TestBit CB46,16,  xHL_Read, 0 ;; BIT xHL, 0 Cycles:16      
  3479.         Opcode@TestBit CB47, 8,  A_Read, 0 ;; BIT A, 0 Cycles:8        
  3480.      
  3481.         Opcode@TestBit CB48, 8,  B_Read, 1 ;; BIT B, 1 Cycles:8
  3482.         Opcode@TestBit CB49, 8,  C_Read, 1 ;; BIT C, 1 Cycles:8        
  3483.         Opcode@TestBit CB4A, 8,  D_Read, 1 ;; BIT D, 1 Cycles:8        
  3484.         Opcode@TestBit CB4B, 8,  E_Read, 1 ;; BIT E, 1 Cycles:8    
  3485.         Opcode@TestBit CB4C, 8,  H_Read, 1 ;; BIT H, 1 Cycles:8
  3486.         Opcode@TestBit CB4D, 8,  L_Read, 1 ;; BIT L, 1 Cycles:8        
  3487.         Opcode@TestBit CB4E,16,  xHL_Read, 1 ;; BIT xHL, 1 Cycles:16      
  3488.         Opcode@TestBit CB4F, 8,  A_Read, 1 ;; BIT A, 1 Cycles:8
  3489.  
  3490.         Opcode@TestBit CB50, 8,  B_Read, 2 ;; BIT B, 2 Cycles:8
  3491.         Opcode@TestBit CB51, 8,  C_Read, 2 ;; BIT C, 2 Cycles:8        
  3492.         Opcode@TestBit CB52, 8,  D_Read, 2 ;; BIT D, 2 Cycles:8        
  3493.         Opcode@TestBit CB53, 8,  E_Read, 2 ;; BIT E, 2 Cycles:8    
  3494.         Opcode@TestBit CB54, 8,  H_Read, 2 ;; BIT H, 2 Cycles:8
  3495.         Opcode@TestBit CB55, 8,  L_Read, 2 ;; BIT L, 2 Cycles:8        
  3496.         Opcode@TestBit CB56,16,  xHL_Read, 2 ;; BIT xHL, 2 Cycles:16      
  3497.         Opcode@TestBit CB57, 8,  A_Read, 2 ;; BIT A, 2 Cycles:8        
  3498.      
  3499.         Opcode@TestBit CB58, 8,  B_Read, 3 ;; BIT B, 3 Cycles:8
  3500.         Opcode@TestBit CB59, 8,  C_Read, 3 ;; BIT C, 3 Cycles:8        
  3501.         Opcode@TestBit CB5A, 8,  D_Read, 3 ;; BIT D, 3 Cycles:8        
  3502.         Opcode@TestBit CB5B, 8,  E_Read, 3 ;; BIT E, 3 Cycles:8    
  3503.         Opcode@TestBit CB5C, 8,  H_Read, 3 ;; BIT H, 3 Cycles:8
  3504.         Opcode@TestBit CB5D, 8,  L_Read, 3 ;; BIT L, 3 Cycles:8        
  3505.         Opcode@TestBit CB5E,16,  xHL_Read, 3 ;; BIT xHL, 3 Cycles:16      
  3506.         Opcode@TestBit CB5F, 8,  A_Read, 3 ;; BIT A, 3 Cycles:8
  3507.  
  3508.         Opcode@TestBit CB60, 8,  B_Read, 4 ;; BIT B, 4 Cycles:8
  3509.         Opcode@TestBit CB61, 8,  C_Read, 4 ;; BIT C, 4 Cycles:8        
  3510.         Opcode@TestBit CB62, 8,  D_Read, 4 ;; BIT D, 4 Cycles:8        
  3511.         Opcode@TestBit CB63, 8,  E_Read, 4 ;; BIT E, 4 Cycles:8    
  3512.         Opcode@TestBit CB64, 8,  H_Read, 4 ;; BIT H, 4 Cycles:8
  3513.         Opcode@TestBit CB65, 8,  L_Read, 4 ;; BIT L, 4 Cycles:8        
  3514.         Opcode@TestBit CB66,16,  xHL_Read, 4 ;; BITxHLD, 4 Cycles:16      
  3515.         Opcode@TestBit CB67, 8,  A_Read, 4 ;; BIT A, 4 Cycles:8        
  3516.      
  3517.         Opcode@TestBit CB68, 8,  B_Read, 5 ;; BIT B, 5 Cycles:8
  3518.         Opcode@TestBit CB69, 8,  C_Read, 5 ;; BIT C, 5 Cycles:8        
  3519.         Opcode@TestBit CB6A, 8,  D_Read, 5 ;; BIT D, 5 Cycles:8        
  3520.         Opcode@TestBit CB6B, 8,  E_Read, 5 ;; BIT E, 5 Cycles:8    
  3521.         Opcode@TestBit CB6C, 8,  H_Read, 5 ;; BIT H, 5 Cycles:8
  3522.         Opcode@TestBit CB6D, 8,  L_Read, 5 ;; BIT L, 5 Cycles:8        
  3523.         Opcode@TestBit CB6E,16,  xHL_Read, 5 ;; BIT xHL, 5 Cycles:16      
  3524.         Opcode@TestBit CB6F, 8,  A_Read, 5 ;; BIT A, 5 Cycles:8
  3525.        
  3526.         Opcode@TestBit CB70, 8,  B_Read, 6 ;; BIT B, 6 Cycles:8
  3527.         Opcode@TestBit CB71, 8,  C_Read, 6 ;; BIT C, 6 Cycles:8        
  3528.         Opcode@TestBit CB72, 8,  D_Read, 6 ;; BIT D, 6 Cycles:8        
  3529.         Opcode@TestBit CB73, 8,  E_Read, 6 ;; BIT E, 6 Cycles:8    
  3530.         Opcode@TestBit CB74, 8,  H_Read, 6 ;; BIT H, 6 Cycles:8
  3531.         Opcode@TestBit CB75, 8,  L_Read, 6 ;; BIT L, 6 Cycles:8        
  3532.         Opcode@TestBit CB76,16,  xHL_Read, 6 ;; BIT xHL, 6 Cycles:16      
  3533.         Opcode@TestBit CB77, 8,  A_Read, 6 ;; BIT A, 6 Cycles:8        
  3534.      
  3535.         Opcode@TestBit CB78, 8,  B_Read, 7 ;; BIT B, 7 Cycles:8
  3536.         Opcode@TestBit CB79, 8,  C_Read, 7 ;; BIT C, 7 Cycles:8        
  3537.         Opcode@TestBit CB7A, 8,  D_Read, 7 ;; BIT D, 7 Cycles:8        
  3538.         Opcode@TestBit CB7B, 8,  E_Read, 7 ;; BIT E, 7 Cycles:8    
  3539.         Opcode@TestBit CB7C, 8,  H_Read, 7 ;; BIT H, 7 Cycles:8
  3540.         Opcode@TestBit CB7D, 8,  L_Read, 7 ;; BIT L, 7 Cycles:8        
  3541.         Opcode@TestBit CB7E,16,  xHL_Read, 7 ;; BIT xHL, 7 Cycles:16      
  3542.         Opcode@TestBit CB7F, 8,  A_Read, 7 ;; BIT A, 7 Cycles:8
  3543.        
  3544.         Opcode@ResBit CB80, 8,  B_Read, 0, B_Write ;; RES B, 0 Cycles:8
  3545.         Opcode@ResBit CB81, 8,  C_Read, 0, C_Write ;; RES C, 0 Cycles:8        
  3546.         Opcode@ResBit CB82, 8,  D_Read, 0, D_Write ;; RES D, 0 Cycles:8        
  3547.         Opcode@ResBit CB83, 8,  E_Read, 0, E_Write ;; RES E, 0 Cycles:8    
  3548.         Opcode@ResBit CB84, 8,  H_Read, 0, H_Write ;; RES H, 0 Cycles:8
  3549.         Opcode@ResBit CB85, 8,  L_Read, 0, L_Write ;; RES L, 0 Cycles:8        
  3550.         Opcode@ResBit CB86,16,  xHL_Read, 0, xHL_Write ;; RES xHL, 0 Cycles:16      
  3551.         Opcode@ResBit CB87, 8,  A_Read, 0, A_Write ;; RES A, 0 Cycles:8        
  3552.      
  3553.         Opcode@ResBit CB88, 8,  B_Read, 1, B_Write ;; RES B, 1 Cycles:8
  3554.         Opcode@ResBit CB89, 8,  C_Read, 1, C_Write ;; RES C, 1 Cycles:8        
  3555.         Opcode@ResBit CB8A, 8,  D_Read, 1, D_Write ;; RES D, 1 Cycles:8        
  3556.         Opcode@ResBit CB8B, 8,  E_Read, 1, E_Write ;; RES E, 1 Cycles:8    
  3557.         Opcode@ResBit CB8C, 8,  H_Read, 1, H_Write ;; RES H, 1 Cycles:8
  3558.         Opcode@ResBit CB8D, 8,  L_Read, 1, L_Write ;; RES L, 1 Cycles:8        
  3559.         Opcode@ResBit CB8E,16,  xHL_Read, 1, xHL_Write ;; RES xHL, 1 Cycles:16      
  3560.         Opcode@ResBit CB8F, 8,  A_Read, 1, A_Write ;; RES A, 1 Cycles:8
  3561.  
  3562.         Opcode@ResBit CB90, 8,  B_Read, 2, B_Write ;; RES B, 2 Cycles:8
  3563.         Opcode@ResBit CB91, 8,  C_Read, 2, C_Write ;; RES C, 2 Cycles:8        
  3564.         Opcode@ResBit CB92, 8,  D_Read, 2, D_Write ;; RES D, 2 Cycles:8        
  3565.         Opcode@ResBit CB93, 8,  E_Read, 2, E_Write ;; RES E, 2 Cycles:8    
  3566.         Opcode@ResBit CB94, 8,  H_Read, 2, H_Write ;; RES H, 2 Cycles:8
  3567.         Opcode@ResBit CB95, 8,  L_Read, 2, L_Write ;; RES L, 2 Cycles:8        
  3568.         Opcode@ResBit CB96,16,  xHL_Read, 2, xHL_Write ;; RES xHL, 2 Cycles:16      
  3569.         Opcode@ResBit CB97, 8,  A_Read, 2, A_Write ;; RES A, 2 Cycles:8        
  3570.      
  3571.         Opcode@ResBit CB98, 8,  B_Read, 3, B_Write ;; RES B, 3 Cycles:8
  3572.         Opcode@ResBit CB99, 8,  C_Read, 3, C_Write ;; RES C, 3 Cycles:8        
  3573.         Opcode@ResBit CB9A, 8,  D_Read, 3, D_Write ;; RES D, 3 Cycles:8        
  3574.         Opcode@ResBit CB9B, 8,  E_Read, 3, E_Write ;; RES E, 3 Cycles:8    
  3575.         Opcode@ResBit CB9C, 8,  H_Read, 3, H_Write ;; RES H, 3 Cycles:8
  3576.         Opcode@ResBit CB9D, 8,  L_Read, 3, L_Write ;; RES L, 3 Cycles:8        
  3577.         Opcode@ResBit CB9E,16,  xHL_Read, 3, xHL_Write ;; RES xHL, 3 Cycles:16      
  3578.         Opcode@ResBit CB9F, 8,  A_Read, 3, A_Write ;; RES A, 3 Cycles:8
  3579.  
  3580.         Opcode@ResBit CBA0, 8,  B_Read, 4, B_Write ;; RES B, 4 Cycles:8
  3581.         Opcode@ResBit CBA1, 8,  C_Read, 4, C_Write ;; RES C, 4 Cycles:8        
  3582.         Opcode@ResBit CBA2, 8,  D_Read, 4, D_Write ;; RES D, 4 Cycles:8        
  3583.         Opcode@ResBit CBA3, 8,  E_Read, 4, E_Write ;; RES E, 4 Cycles:8    
  3584.         Opcode@ResBit CBA4, 8,  H_Read, 4, H_Write ;; RES H, 4 Cycles:8
  3585.         Opcode@ResBit CBA5, 8,  L_Read, 4, L_Write ;; RES L, 4 Cycles:8        
  3586.         Opcode@ResBit CBA6,16,  xHL_Read, 4, xHL_Write ;; RES xHL, 4 Cycles:16      
  3587.         Opcode@ResBit CBA7, 8,  A_Read, 4, A_Write ;; RES A, 4 Cycles:8        
  3588.      
  3589.         Opcode@ResBit CBA8, 8,  B_Read, 5, B_Write ;; RES B, 5 Cycles:8
  3590.         Opcode@ResBit CBA9, 8,  C_Read, 5, C_Write ;; RES C, 5 Cycles:8        
  3591.         Opcode@ResBit CBAA, 8,  D_Read, 5, D_Write ;; RES D, 5 Cycles:8        
  3592.         Opcode@ResBit CBAB, 8,  E_Read, 5, E_Write ;; RES E, 5 Cycles:8    
  3593.         Opcode@ResBit CBAC, 8,  H_Read, 5, H_Write ;; RES H, 5 Cycles:8
  3594.         Opcode@ResBit CBAD, 8,  L_Read, 5, L_Write ;; RES L, 5 Cycles:8        
  3595.         Opcode@ResBit CBAE,16,  xHL_Read, 5, xHL_Write ;; RES xHL, 5 Cycles:16      
  3596.         Opcode@ResBit CBAF, 8,  A_Read, 5, A_Write ;; RES A, 5 Cycles:8
  3597.        
  3598.         Opcode@ResBit CBB0, 8,  B_Read, 6, B_Write ;; RES B, 6 Cycles:8
  3599.         Opcode@ResBit CBB1, 8,  C_Read, 6, C_Write ;; RES C, 6 Cycles:8        
  3600.         Opcode@ResBit CBB2, 8,  D_Read, 6, D_Write ;; RES D, 6 Cycles:8        
  3601.         Opcode@ResBit CBB3, 8,  E_Read, 6, E_Write ;; RES E, 6 Cycles:8    
  3602.         Opcode@ResBit CBB4, 8,  H_Read, 6, H_Write ;; RES H, 6 Cycles:8
  3603.         Opcode@ResBit CBB5, 8,  L_Read, 6, L_Write ;; RES L, 6 Cycles:8        
  3604.         Opcode@ResBit CBB6,16,  xHL_Read, 6, xHL_Write ;; RES xHL, 6 Cycles:16      
  3605.         Opcode@ResBit CBB7, 8,  A_Read, 6, A_Write ;; RES A, 6 Cycles:8        
  3606.      
  3607.         Opcode@ResBit CBB8, 8,  B_Read, 7, B_Write ;; RES B, 7 Cycles:8
  3608.         Opcode@ResBit CBB9, 8,  C_Read, 7, C_Write ;; RES C, 7 Cycles:8        
  3609.         Opcode@ResBit CBBA, 8,  D_Read, 7, D_Write ;; RES D, 7 Cycles:8        
  3610.         Opcode@ResBit CBBB, 8,  E_Read, 7, E_Write ;; RES E, 7 Cycles:8    
  3611.         Opcode@ResBit CBBC, 8,  H_Read, 7, H_Write ;; RES H, 7 Cycles:8
  3612.         Opcode@ResBit CBBD, 8,  L_Read, 7, L_Write ;; RES L, 7 Cycles:8        
  3613.         Opcode@ResBit CBBE,16,  xHL_Read, 7, xHL_Write ;; RES xHL, 7 Cycles:16      
  3614.         Opcode@ResBit CBBF, 8,  A_Read, 7, A_Write ;; RES A, 7 Cycles:8
  3615.  
  3616.         Opcode@SetBit CBC0, 8,  B_Read, 0, B_Write ;; SET B, 0 Cycles:8
  3617.         Opcode@SetBit CBC1, 8,  C_Read, 0, C_Write ;; SET C, 0 Cycles:8        
  3618.         Opcode@SetBit CBC2, 8,  D_Read, 0, D_Write ;; SET D, 0 Cycles:8        
  3619.         Opcode@SetBit CBC3, 8,  E_Read, 0, E_Write ;; SET E, 0 Cycles:8    
  3620.         Opcode@SetBit CBC4, 8,  H_Read, 0, H_Write ;; SET H, 0 Cycles:8
  3621.         Opcode@SetBit CBC5, 8,  L_Read, 0, L_Write ;; SET L, 0 Cycles:8        
  3622.         Opcode@SetBit CBC6,16,  xHL_Read, 0, xHL_Write ;; SET xHL, 0 Cycles:16      
  3623.         Opcode@SetBit CBC7, 8,  A_Read, 0, A_Write ;; SET A, 0 Cycles:8        
  3624.      
  3625.         Opcode@SetBit CBC8, 8,  B_Read, 1, B_Write ;; SET B, 1 Cycles:8
  3626.         Opcode@SetBit CBC9, 8,  C_Read, 1, C_Write ;; SET C, 1 Cycles:8        
  3627.         Opcode@SetBit CBCA, 8,  D_Read, 1, D_Write ;; SET D, 1 Cycles:8        
  3628.         Opcode@SetBit CBCB, 8,  E_Read, 1, E_Write ;; SET E, 1 Cycles:8    
  3629.         Opcode@SetBit CBCC, 8,  H_Read, 1, H_Write ;; SET H, 1 Cycles:8
  3630.         Opcode@SetBit CBCD, 8,  L_Read, 1, L_Write ;; SET L, 1 Cycles:8        
  3631.         Opcode@SetBit CBCE,16,  xHL_Read, 1, xHL_Write ;; SET xHL, 1 Cycles:16      
  3632.         Opcode@SetBit CBCF, 8,  A_Read, 1, A_Write ;; SET A, 1 Cycles:8
  3633.  
  3634.         Opcode@SetBit CBD0, 8,  B_Read, 2, B_Write ;; SET B, 2 Cycles:8
  3635.         Opcode@SetBit CBD1, 8,  C_Read, 2, C_Write ;; SET C, 2 Cycles:8        
  3636.         Opcode@SetBit CBD2, 8,  D_Read, 2, D_Write ;; SET D, 2 Cycles:8        
  3637.         Opcode@SetBit CBD3, 8,  E_Read, 2, E_Write ;; SET E, 2 Cycles:8    
  3638.         Opcode@SetBit CBD4, 8,  H_Read, 2, H_Write ;; SET H, 2 Cycles:8
  3639.         Opcode@SetBit CBD5, 8,  L_Read, 2, L_Write ;; SET L, 2 Cycles:8        
  3640.         Opcode@SetBit CBD6,16,  xHL_Read, 2, xHL_Write ;; SET xHL, 2 Cycles:16      
  3641.         Opcode@SetBit CBD7, 8,  A_Read, 2, A_Write ;; SET A, 2 Cycles:8        
  3642.      
  3643.         Opcode@SetBit CBD8, 8,  B_Read, 3, B_Write ;; SET B, 3 Cycles:8
  3644.         Opcode@SetBit CBD9, 8,  C_Read, 3, C_Write ;; SET C, 3 Cycles:8        
  3645.         Opcode@SetBit CBDA, 8,  D_Read, 3, D_Write ;; SET D, 3 Cycles:8        
  3646.         Opcode@SetBit CBDB, 8,  E_Read, 3, E_Write ;; SET E, 3 Cycles:8    
  3647.         Opcode@SetBit CBDC, 8,  H_Read, 3, H_Write ;; SET H, 3 Cycles:8
  3648.         Opcode@SetBit CBDD, 8,  L_Read, 3, L_Write ;; SET L, 3 Cycles:8        
  3649.         Opcode@SetBit CBDE,16,  xHL_Read, 3, xHL_Write ;; SET xHL, 3 Cycles:16      
  3650.         Opcode@SetBit CBDF, 8,  A_Read, 3, A_Write ;; SET A, 3 Cycles:8
  3651.  
  3652.         Opcode@SetBit CBE0, 8,  B_Read, 4, B_Write ;; SET B, 4 Cycles:8
  3653.         Opcode@SetBit CBE1, 8,  C_Read, 4, C_Write ;; SET C, 4 Cycles:8        
  3654.         Opcode@SetBit CBE2, 8,  D_Read, 4, D_Write ;; SET D, 4 Cycles:8        
  3655.         Opcode@SetBit CBE3, 8,  E_Read, 4, E_Write ;; SET E, 4 Cycles:8    
  3656.         Opcode@SetBit CBE4, 8,  H_Read, 4, H_Write ;; SET H, 4 Cycles:8
  3657.         Opcode@SetBit CBE5, 8,  L_Read, 4, L_Write ;; SET L, 4 Cycles:8        
  3658.         Opcode@SetBit CBE6,16,  xHL_Read, 4, xHL_Write ;; SET xHL, 4 Cycles:16      
  3659.         Opcode@SetBit CBE7, 8,  A_Read, 4, A_Write ;; SET A, 4 Cycles:8        
  3660.      
  3661.         Opcode@SetBit CBE8, 8,  B_Read, 5, B_Write ;; SET B, 5 Cycles:8
  3662.         Opcode@SetBit CBE9, 8,  C_Read, 5, C_Write ;; SET C, 5 Cycles:8        
  3663.         Opcode@SetBit CBEA, 8,  D_Read, 5, D_Write ;; SET D, 5 Cycles:8        
  3664.         Opcode@SetBit CBEB, 8,  E_Read, 5, E_Write ;; SET E, 5 Cycles:8    
  3665.         Opcode@SetBit CBEC, 8,  H_Read, 5, H_Write ;; SET H, 5 Cycles:8
  3666.         Opcode@SetBit CBED, 8,  L_Read, 5, L_Write ;; SET L, 5 Cycles:8        
  3667.         Opcode@SetBit CBEE,16,  xHL_Read, 5, xHL_Write ;; SET xHL, 5 Cycles:16      
  3668.         Opcode@SetBit CBEF, 8,  A_Read, 5, A_Write ;; SET A, 5 Cycles:8
  3669.        
  3670.         Opcode@SetBit CBF0, 8,  B_Read, 6, B_Write ;; SET B, 6 Cycles:8
  3671.         Opcode@SetBit CBF1, 8,  C_Read, 6, C_Write ;; SET C, 6 Cycles:8        
  3672.         Opcode@SetBit CBF2, 8,  D_Read, 6, D_Write ;; SET D, 6 Cycles:8        
  3673.         Opcode@SetBit CBF3, 8,  E_Read, 6, E_Write ;; SET E, 6 Cycles:8    
  3674.         Opcode@SetBit CBF4, 8,  H_Read, 6, H_Write ;; SET H, 6 Cycles:8
  3675.         Opcode@SetBit CBF5, 8,  L_Read, 6, L_Write ;; SET L, 6 Cycles:8        
  3676.         Opcode@SetBit CBF6,16,  xHL_Read, 6, xHL_Write ;; SET xHL, 6 Cycles:16      
  3677.         Opcode@SetBit CBF7, 8,  A_Read, 6, A_Write ;; SET A, 6 Cycles:8        
  3678.      
  3679.         Opcode@SetBit CBF8, 8,  B_Read, 7, B_Write ;; SET B, 7 Cycles:8
  3680.         Opcode@SetBit CBF9, 8,  C_Read, 7, C_Write ;; SET C, 7 Cycles:8        
  3681.         Opcode@SetBit CBFA, 8,  D_Read, 7, D_Write ;; SET D, 7 Cycles:8        
  3682.         Opcode@SetBit CBFB, 8,  E_Read, 7, E_Write ;; SET E, 7 Cycles:8    
  3683.         Opcode@SetBit CBFC, 8,  H_Read, 7, H_Write ;; SET H, 7 Cycles:8
  3684.         Opcode@SetBit CBFD, 8,  L_Read, 7, L_Write ;; SET L, 7 Cycles:8        
  3685.         Opcode@SetBit CBFE,16,  xHL_Read, 7, xHL_Write ;; SET xHL, 7 Cycles:16      
  3686.         Opcode@SetBit CBFF, 8,  A_Read, 7, A_Write ;; SET A, 7 Cycles:8        
  3687. V_EXIT:
  3688.       pop esi
  3689.       pop edi
  3690.       pop ebx
  3691.       ret          
  3692. OPD3:
  3693. OPDB:
  3694. OPDD:
  3695. OPE3:
  3696. OPE4:
  3697. OPEB:
  3698. OPEC:
  3699. OPED:
  3700. OPF4:
  3701. OPFC:
  3702. OPFD: ud2
  3703.       align 16
  3704. OPTAB dd  OP00, OP01, OP02, OP03, OP04, OP05, OP06, OP07, OP08, OP09, OP0A, OP0B, OP0C, OP0D, OP0E, OP0F
  3705.       dd  OP10, OP11, OP12, OP13, OP14, OP15, OP16, OP17, OP18, OP19, OP1A, OP1B, OP1C, OP1D, OP1E, OP1F
  3706.       dd  OP20, OP21, OP22, OP23, OP24, OP25, OP26, OP27, OP28, OP29, OP2A, OP2B, OP2C, OP2D, OP2E, OP2F
  3707.       dd  OP30, OP31, OP32, OP33, OP34, OP35, OP36, OP37, OP38, OP39, OP3A, OP3B, OP3C, OP3D, OP3E, OP3F
  3708.       dd  OP40, OP41, OP42, OP43, OP44, OP45, OP46, OP47, OP48, OP49, OP4A, OP4B, OP4C, OP4D, OP4E, OP4F
  3709.       dd  OP50, OP51, OP52, OP53, OP54, OP55, OP56, OP57, OP58, OP59, OP5A, OP5B, OP5C, OP5D, OP5E, OP5F
  3710.       dd  OP60, OP61, OP62, OP63, OP64, OP65, OP66, OP67, OP68, OP69, OP6A, OP6B, OP6C, OP6D, OP6E, OP6F
  3711.       dd  OP70, OP71, OP72, OP73, OP74, OP75, OP76, OP77, OP78, OP79, OP7A, OP7B, OP7C, OP7D, OP7E, OP7F
  3712.       dd  OP80, OP81, OP82, OP83, OP84, OP85, OP86, OP87, OP88, OP89, OP8A, OP8B, OP8C, OP8D, OP8E, OP8F
  3713.       dd  OP90, OP91, OP92, OP93, OP94, OP95, OP96, OP97, OP98, OP99, OP9A, OP9B, OP9C, OP9D, OP9E, OP9F
  3714.       dd  OPA0, OPA1, OPA2, OPA3, OPA4, OPA5, OPA6, OPA7, OPA8, OPA9, OPAA, OPAB, OPAC, OPAD, OPAE, OPAF
  3715.       dd  OPB0, OPB1, OPB2, OPB3, OPB4, OPB5, OPB6, OPB7, OPB8, OPB9, OPBA, OPBB, OPBC, OPBD, OPBE, OPBF
  3716.       dd  OPC0, OPC1, OPC2, OPC3, OPC4, OPC5, OPC6, OPC7, OPC8, OPC9, OPCA, OPCB, OPCC, OPCD, OPCE, OPCF
  3717.       dd  OPD0, OPD1, OPD2, OPD3, OPD4, OPD5, OPD6, OPD7, OPD8, OPD9, OPDA, OPDB, OPDC, OPDD, OPDE, OPDF
  3718.       dd  OPE0, OPE1, OPE2, OPE3, OPE4, OPE5, OPE6, OPE7, OPE8, OPE9, OPEA, OPEB, OPEC, OPED, OPEE, OPEF
  3719.       dd  OPF0, OPF1, OPF2, OPF3, OPF4, OPF5, OPF6, OPF7, OPF8, OPF9, OPFA, OPFB, OPFC, OPFD, OPFE, OPFF
  3720.       align 16
  3721. CBTAB dd  CB00, CB01, CB02, CB03, CB04, CB05, CB06, CB07, CB08, CB09, CB0A, CB0B, CB0C, CB0D, CB0E, CB0F
  3722.       dd  CB10, CB11, CB12, CB13, CB14, CB15, CB16, CB17, CB18, CB19, CB1A, CB1B, CB1C, CB1D, CB1E, CB1F
  3723.       dd  CB20, CB21, CB22, CB23, CB24, CB25, CB26, CB27, CB28, CB29, CB2A, CB2B, CB2C, CB2D, CB2E, CB2F
  3724.       dd  CB30, CB31, CB32, CB33, CB34, CB35, CB36, CB37, CB38, CB39, CB3A, CB3B, CB3C, CB3D, CB3E, CB3F
  3725.       dd  CB40, CB41, CB42, CB43, CB44, CB45, CB46, CB47, CB48, CB49, CB4A, CB4B, CB4C, CB4D, CB4E, CB4F
  3726.       dd  CB50, CB51, CB52, CB53, CB54, CB55, CB56, CB57, CB58, CB59, CB5A, CB5B, CB5C, CB5D, CB5E, CB5F
  3727.       dd  CB60, CB61, CB62, CB63, CB64, CB65, CB66, CB67, CB68, CB69, CB6A, CB6B, CB6C, CB6D, CB6E, CB6F
  3728.       dd  CB70, CB71, CB72, CB73, CB74, CB75, CB76, CB77, CB78, CB79, CB7A, CB7B, CB7C, CB7D, CB7E, CB7F
  3729.       dd  CB80, CB81, CB82, CB83, CB84, CB85, CB86, CB87, CB88, CB89, CB8A, CB8B, CB8C, CB8D, CB8E, CB8F
  3730.       dd  CB90, CB91, CB92, CB93, CB94, CB95, CB96, CB97, CB98, CB99, CB9A, CB9B, CB9C, CB9D, CB9E, CB9F
  3731.       dd  CBA0, CBA1, CBA2, CBA3, CBA4, CBA5, CBA6, CBA7, CBA8, CBA9, CBAA, CBAB, CBAC, CBAD, CBAE, CBAF
  3732.       dd  CBB0, CBB1, CBB2, CBB3, CBB4, CBB5, CBB6, CBB7, CBB8, CBB9, CBBA, CBBB, CBBC, CBBD, CBBE, CBBF
  3733.       dd  CBC0, CBC1, CBC2, CBC3, CBC4, CBC5, CBC6, CBC7, CBC8, CBC9, CBCA, CBCB, CBCC, CBCD, CBCE, CBCF
  3734.       dd  CBD0, CBD1, CBD2, CBD3, CBD4, CBD5, CBD6, CBD7, CBD8, CBD9, CBDA, CBDB, CBDC, CBDD, CBDE, CBDF
  3735.       dd  CBE0, CBE1, CBE2, CBE3, CBE4, CBE5, CBE6, CBE7, CBE8, CBE9, CBEA, CBEB, CBEC, CBED, CBEE, CBEF
  3736.       dd  CBF0, CBF1, CBF2, CBF3, CBF4, CBF5, CBF6, CBF7, CBF8, CBF9, CBFA, CBFB, CBFC, CBFD, CBFE, CBFF
  3737.        
  3738. cpu_optick endp
  3739.  
  3740.   end
  3741. ;; cpu_optick.asm  (version2 for NASM Assembler)
  3742. ;; Sharp LR35902 Chip Opcode for GameBoy
  3743. ;;
  3744. ;; Copyright (C) 2018 moecmks
  3745. ;; This file is part of KS3578.
  3746. ;;
  3747. ;; do What The Fuck you want to Public License
  3748. ;;
  3749. ;; Version 1.0, March 2000
  3750. ;; Copyright (C) 2000 Banlu Kemiyatorn (]d).
  3751. ;; 136 Nives 7 Jangwattana 14 Laksi Bangkok
  3752. ;; Everyone is permitted to copy and distribute verbatim copies
  3753. ;; of this license document, but changing it is not allowed.
  3754. ;;
  3755. ;; Ok, the purpose of this license is simple
  3756. ;; and you just
  3757. ;;
  3758. ;; DO WHAT THE FUCK YOU WANT TO.
  3759. ;;
  3760. ;; Sharp LR35902 Chip opcode mapper
  3761. ;; http://www.pastraiser.com/cpu/gameboy/gameboy_opcodes.html
  3762. ;; Z80 Chip opcode mapper
  3763. ;; http://clrhome.org/table/
  3764. ;;
  3765.  
  3766. ;; The Fleg Register consists of the following bits:
  3767. ;; 7 6 5 4 3 2 1 0
  3768. ;; Z N H C 0 0 0 0
  3769. Z_FLAG equ 0x80
  3770. N_FLAG equ 0x40
  3771. H_FLAG equ 0x20
  3772. C_FLAG equ 0x10
  3773.  
  3774. %if 1
  3775. extern _gameboy_mmu_read@8  ;; prototype ks_uint8 __stdcall _gameboy_mmu_read (void;;gameboy, ks_uint16 addresss)
  3776. extern _gameboy_mmu_write@12 ;; prototype void __stdcall _gameboy_mmu_write (void;;gameboy, ks_uint16 addresss, ks_uint8 value)
  3777. extern _gameboy_mmu_read_w@8  ;; prototype ks_uint8 __stdcall _gameboy_mmu_read_w (void;;gameboy, ks_uint16 addresss)
  3778. extern _gameboy_mmu_write_w@12 ;; prototype void __stdcall _gameboy_mmu_write_w (void;;gameboy, ks_uint16 addresss, ks_uint8 value)
  3779. %define MmuRead _gameboy_mmu_read@8
  3780. %define MmuReadWord _gameboy_mmu_read_w@8
  3781. %define MmuWrite _gameboy_mmu_write@12
  3782. %define MmuWriteWord _gameboy_mmu_write_w@12
  3783. %endif
  3784.  
  3785. ;;  define union .
  3786. %macro  defREG 2            ; 1:low, 2:hi
  3787.   .%1: resb 1
  3788.   .%2: resb 1
  3789.   .%2%1: equ .%1
  3790. %endmacro
  3791.  
  3792. %macro  defREG2 3           ; 1:low, 2:hi 3:comb another.
  3793.   .%1: resb 1
  3794.   .%2: resb 1
  3795.   .%3: equ .%1
  3796. %endmacro
  3797.  
  3798. struc lr35902                         ; structure definition      
  3799.   defREG F, A
  3800.   defREG C, B
  3801.   defREG E, D
  3802.   defREG L, H
  3803.   defREG2 SP_LO, SP_HI, SP
  3804.   defREG2 PC_LO, PC_HI, PC
  3805.  
  3806.   .IME: resb 1
  3807.   .halt: resd 1
  3808.   .stop: resd 1
  3809.   ._backup: resd 1
  3810.   .key1: resb 1
  3811.   .gameboy: resd 1
  3812. endstruc
  3813.  
  3814. %macro xImm16_WriteReg 2 ;; eax:Imm16 %1 lr35902::reg %2:word or byte
  3815.   movzx ecx, %2 [YG_GP+lr35902.%1]
  3816.   push ecx
  3817.   push eax
  3818.   push dword [YG_GP+lr35902.gameboy]
  3819.   call MmuWriteWord
  3820. %endmacro
  3821. %macro xRegister_Read  1
  3822.   mov ax, word [YG_GP+lr35902.%1]
  3823.   push eax
  3824.   push dword [YG_GP+lr35902.gameboy]
  3825.   call MmuRead
  3826. %endmacro  
  3827. %macro xImm16_WriteRegSP 0
  3828.   movzx ecx, word [YG_GP+lr35902.SP]
  3829.   push ecx
  3830.   push eax
  3831.   push dword [YG_GP+lr35902.gameboy]
  3832.   call MmuWriteWord
  3833. %endmacro
  3834. %macro xImm16_WriteRegA 0
  3835.   movzx ecx, byte [YG_GP+lr35902.A]
  3836.   push ecx
  3837.   push eax
  3838.   push dword [YG_GP+lr35902.gameboy]
  3839.   call MmuWrite
  3840. %endmacro
  3841. %macro xRegister_WriteReg 4
  3842.   ;; eax:Register
  3843.   ;; %1 lr35902::reg
  3844.   ;; %2:word or byte
  3845.   ;; %3 Offset add
  3846.   ;; %4 bit mask 0xFF or 0xFFFF
  3847.   and eax, %4
  3848.   add eax, %3
  3849.   push eax
  3850.   movzx eax, %2 [YG_GP+lr35902.%1]
  3851.   push eax
  3852.   push dword [YG_GP+lr35902.gameboy]
  3853.   call MmuWrite
  3854. %endmacro
  3855. %macro SetCyclesAndRet 1 ;; %1: burning cpu clk.
  3856.   ;; write back PC
  3857.   mov [YG_GP+lr35902.PC], si
  3858.   mov eax, %1
  3859.   jmp V_EXIT
  3860. %endmacro        
  3861. %macro SetCyclesRetP 1  ;; %1: burning cpu clk.
  3862.   ;; write back F
  3863.   mov [YG_GP+lr35902.F], bl
  3864.   SetCyclesAndRet %1
  3865. %endmacro  
  3866.      
  3867. ;;  Register access-read unwind
  3868. %macro B_Read 0
  3869.   mov al, [YG_GP+lr35902.B]
  3870. %endmacro
  3871. %macro C_Read 0
  3872.   mov al, [YG_GP+lr35902.C]
  3873. %endmacro
  3874. %macro D_Read 0
  3875.   mov al, [YG_GP+lr35902.D]
  3876. %endmacro
  3877. %macro E_Read 0
  3878.   mov al, [YG_GP+lr35902.E]
  3879. %endmacro
  3880. %macro H_Read 0
  3881.   mov al, [YG_GP+lr35902.H]
  3882. %endmacro
  3883. %macro L_Read 0
  3884.   mov al, [YG_GP+lr35902.L]
  3885. %endmacro
  3886. %macro A_Read 0
  3887.   mov al, [YG_GP+lr35902.A]
  3888. %endmacro
  3889. %macro F_Read 0
  3890.   mov al, [YG_GP+lr35902.F]
  3891. %endmacro
  3892. %macro BC_Read 0
  3893.   mov ax, [YG_GP+lr35902.BC]
  3894. %endmacro
  3895. %macro DE_Read 0
  3896.   mov ax, [YG_GP+lr35902.DE]
  3897. %endmacro
  3898. %macro HL_Read 0
  3899.   mov ax, [YG_GP+lr35902.HL]
  3900. %endmacro
  3901. %macro AF_Read 0
  3902.   mov ax, [YG_GP+lr35902.AF]
  3903. %endmacro
  3904. %macro SP_Read 0
  3905.   mov ax, [YG_GP+lr35902.SP]
  3906. %endmacro
  3907. %macro xBC_Read 0
  3908.   xRegister_Read BC  
  3909. %endmacro
  3910. %macro xDE_Read 0
  3911.   xRegister_Read DE
  3912. %endmacro
  3913. %macro xHL_Read 0
  3914.   xRegister_Read HL
  3915. %endmacro
  3916. %macro xHL_Read_Inc 0
  3917.   xHL_Read
  3918.   inc word [YG_GP+lr35902.HL]
  3919. %endmacro  
  3920. %macro xHL_Read_Dec 0
  3921.   xHL_Read
  3922.   dec word [YG_GP+lr35902.HL]
  3923. %endmacro
  3924. %macro xAF_Read 0
  3925.   xRegister_Read AF
  3926. %endmacro
  3927. %macro xPC_Read 0
  3928.   xRegister_Read PC
  3929. %endmacro
  3930.  
  3931. ;;  Register access-write unwind
  3932. %macro B_Write 0
  3933.   mov [YG_GP+lr35902.B], al
  3934. %endmacro
  3935. %macro C_Write 0
  3936.   mov [YG_GP+lr35902.C], al
  3937. %endmacro
  3938. %macro D_Write 0
  3939.   mov [YG_GP+lr35902.D], al
  3940. %endmacro
  3941. %macro E_Write 0
  3942.   mov [YG_GP+lr35902.E], al
  3943. %endmacro
  3944. %macro H_Write 0
  3945.   mov [YG_GP+lr35902.H], al
  3946. %endmacro
  3947. %macro L_Write 0
  3948.   mov [YG_GP+lr35902.L], al
  3949. %endmacro
  3950. %macro A_Write 0
  3951.   mov [YG_GP+lr35902.A], al
  3952. %endmacro
  3953. %macro F_Write 0
  3954.   mov [YG_GP+lr35902.F], al
  3955. %endmacro
  3956. %macro BC_Write 0
  3957.   mov [YG_GP+lr35902.BC], ax
  3958. %endmacro
  3959. %macro DE_Write 0
  3960.   mov [YG_GP+lr35902.DE], ax
  3961. %endmacro
  3962. %macro HL_Write 0
  3963.   mov [YG_GP+lr35902.HL], ax
  3964. %endmacro
  3965. %macro AF_Write 0
  3966.   mov [YG_GP+lr35902.AF], ax
  3967. %endmacro
  3968. %macro SP_Write 0
  3969.   mov [YG_GP+lr35902.SP], ax
  3970. %endmacro
  3971. %macro  xBC_Write 0
  3972.   xRegister_WriteReg BC, word, 0, 0xFFFF  
  3973. %endmacro
  3974. %macro xDE_Write 0
  3975.   xRegister_WriteReg DE, word, 0, 0xFFFF
  3976. %endmacro
  3977. %macro xHL_Write 0
  3978.   xRegister_WriteReg HL, word, 0, 0xFFFF
  3979. %endmacro
  3980. %macro xHL_Write_Inc 0
  3981.   xRegister_WriteReg HL, word, 0, 0xFFFF
  3982.   inc word [YG_GP+lr35902.HL]
  3983. %endmacro
  3984. %macro xHL_Write_Dec 0
  3985.   xRegister_WriteReg HL, word, 0, 0xFFFF
  3986.   dec word [YG_GP+lr35902.HL]
  3987. %endmacro
  3988.  
  3989. %macro Imm8_Read 0
  3990.   push    esi
  3991.   push    dword [YG_GP+lr35902.gameboy]
  3992.   call    MmuRead
  3993.   inc     esi
  3994. %endmacro  
  3995. %macro Imm16_Read 0
  3996.   push    esi
  3997.   push    dword [YG_GP+lr35902.gameboy]
  3998.   call    MmuReadWord
  3999.   add     esi, 2
  4000. %endmacro  
  4001. %macro Read_ByxX86SpecRegister  1
  4002.   ;;  %1:x86Register
  4003.   push    %1
  4004.   push    dword [YG_GP+lr35902.gameboy]
  4005.   call    MmuRead
  4006. %endmacro
  4007. %macro Imm8Read_ExpandAddress16 0
  4008.   Imm8_Read
  4009.   and eax, 000FFh
  4010.   add eax, 0FF00h
  4011. %endmacro  
  4012. %macro Imm8_ExpandSignWord 0
  4013.   Imm8_Read
  4014.   movsx eax, al
  4015. %endmacro  
  4016. %macro C_ExpandAddress16 0
  4017.   movzx eax, byte [YG_GP+lr35902.C]
  4018.   add eax, 0FF00h
  4019. %endmacro  
  4020. %macro Imm8Read_ExpandAddress16_Fetch 0
  4021.   Imm8Read_ExpandAddress16
  4022.   Read_ByxX86SpecRegister eax
  4023. %endmacro  
  4024. %macro Imm16Read_Address_Fetch 0
  4025.   Imm16_Read
  4026.   Read_ByxX86SpecRegister eax
  4027. %endmacro  
  4028. %macro C_ExpandAddress16_Fetch 0
  4029.   mov al, [YG_GP+lr35902.C]
  4030.   add eax, 0FF00h
  4031.   Read_ByxX86SpecRegister eax
  4032. %endmacro  
  4033. %macro EmptyMacro 0
  4034. %endmacro
  4035.  
  4036. ;; ld r(xHL), r(xHL)
  4037. %macro lr35902@LD@RxHLToRxHL  4
  4038.  ;; %1 OpCase
  4039.  ;; %2 Cycles_
  4040.  ;; %3 ReadOrExt
  4041.  ;; %4 WriteOrExt
  4042.  %1:
  4043.     %3
  4044.     %4
  4045.     SetCyclesAndRet %2  
  4046. %endmacro
  4047.  
  4048. ;; ld r, imm8/imm16
  4049. %macro lr35902@LD@Imm  4
  4050.  ;; %1 OpCase
  4051.  ;; %2 Immread
  4052.  ;; %3 Cycles_
  4053.  ;; %4 WriteOrExt
  4054.   %1:
  4055.     %2
  4056.     %4
  4057.     SetCyclesAndRet %3
  4058. %endmacro  
  4059.  
  4060. ;; arith/logic main
  4061. %macro OP_Add$c_xHLrToA 1
  4062. ;; %1: atomic_it 0(add) or C_FLAG(adc)
  4063. ;; source value <- eax
  4064.   and eax, 0xFF ;; Value &= 0xFF
  4065.   and YG_PF, %1
  4066.   shr YG_PF, 5 ;; check c-flags
  4067.   movzx edx, byte [YG_GP+lr35902.A]
  4068.   mov ecx, edx ;; temp WORD := A
  4069.   adc ecx, eax ;; temp WORD := A + Value
  4070.   mov [YG_GP+lr35902.A], cl  ;; always write back A.
  4071.   test cl, cl
  4072.   setz YG_PF_8
  4073.   shl YG_PF_8, 7 ;; z flag set  
  4074.   xor dx, ax  
  4075.   mov ax, cx  
  4076.   xor ax, dx  ;; temp WORD:= temp WORD^(A ^Value)
  4077.   and ax, 0x10
  4078.   shl ax, 1
  4079.   or YG_PF, eax   ;; h flag set  
  4080.   shl ch, 4
  4081.   or YG_PF_8, ch  ;; c flag set  
  4082. %endmacro  
  4083.  
  4084. %macro AddWord_ 0
  4085. ;; source <- eax
  4086. ;; target <- always register HL
  4087.  
  4088. ;; clear psb . save old Z
  4089.   and YG_PF, Z_FLAG
  4090.   movzx ecx, word [YG_GP+lr35902.HL]
  4091.   and eax, 0xFFFF
  4092.   lea edx, [eax+ecx]
  4093.   ;; always write back HL.
  4094.   mov word [YG_GP+lr35902.HL], dx
  4095.   xor cx, ax
  4096.   mov ax, dx
  4097.   xor cx, ax
  4098.   and cx, 01000h
  4099.   shl cx, 1
  4100.   or YG_PF_8, ch   ;; h flag set  
  4101.   and edx, 010000h
  4102.   shr edx, 12
  4103.   or YG_PF, edx ;; c flag set  
  4104. %endmacro  
  4105.  
  4106. %macro AddWord2_ 0
  4107. ;; source <- eax
  4108. ;; target <- always register SP
  4109.   movsx eax, al
  4110.   xor YG_PF, YG_PF
  4111.   movzx ecx, word [YG_GP+lr35902.SP]
  4112.   and eax, 0xFFFF
  4113.   lea edx, [eax+ecx]
  4114.   ;; always write back HL.
  4115.   mov word [YG_GP+lr35902.SP], dx
  4116.   xor cx, ax
  4117.   mov ax, dx
  4118.   xor cx, ax
  4119.   and cx, 0x0110 ;; C|H
  4120.   mov YG_PF_8, ch
  4121.   shl YG_PF_8, 4
  4122.   shl cl, 1
  4123.   or YG_PF_8, cl
  4124.   and YG_PF, (H_FLAG| C_FLAG)
  4125. %endmacro
  4126.  
  4127. %macro OP_CmpSub$bc_xHLrToA 2
  4128. ;; %1: atomic_it 0(sub) or C_FLAG(sbc)
  4129. ;; %2: [YG_GP+lr35902.A] || cl for cmp opcode
  4130. ;; source value <- eax
  4131.   and eax, 0xFF ;; Value &= 0xFF
  4132.   and YG_PF, %1
  4133.   shr YG_PF, 5 ;; check c-flags
  4134.   movzx edx, byte [YG_GP+lr35902.A]
  4135.   mov ecx, edx ;; temp WORD := A
  4136.   sbb ecx, eax ;; temp WORD := A - Value
  4137.   mov %2, cl  ;; always write back A.
  4138.   test cl, cl
  4139.   setz YG_PF_8
  4140.   shl YG_PF_8, 7 ;; z flag set  
  4141.   xor dx, ax  
  4142.   mov ax, cx  
  4143.   xor ax, dx  ;; temp WORD:= temp WORD^(A ^Value)
  4144.   and ax, 0x10
  4145.   shl ax, 1
  4146.   or YG_PF, eax    ;; h flag set  
  4147.   and ecx, 0x8000
  4148.   shr ecx, 11
  4149.   or YG_PF, ecx  ;; c flag set  
  4150.   or YG_PF, N_FLAG ;; n flag set  
  4151. %endmacro  
  4152.      
  4153. ;; XOR | OR | AND do unwind base .
  4154. %macro OP_Logic_T 2
  4155. ;; %1: initFlags
  4156. ;; %2: LogicOp
  4157. ;; source <- eax
  4158. ;; target <- always register A
  4159.   mov YG_PF, %1
  4160.   movzx edx, byte [YG_GP+lr35902.A]
  4161.   %2 al, dl
  4162.   ;; always write back A.
  4163.   mov [YG_GP+lr35902.A], al
  4164.   setz al
  4165.   shl eax, 7
  4166.   or YG_PF, eax ;; z flag set  
  4167. %endmacro  
  4168.      
  4169. ;; unwind
  4170. %macro Add_  0
  4171.   OP_Add$c_xHLrToA 0
  4172. %endmacro  
  4173.  
  4174. %macro Adc_ 0
  4175.   OP_Add$c_xHLrToA C_FLAG
  4176. %endmacro  
  4177.  
  4178. %macro Sub_ 0
  4179.   OP_CmpSub$bc_xHLrToA 0, [YG_GP+lr35902.A]
  4180. %endmacro    
  4181.      
  4182. %macro Sbc_ 0
  4183.   OP_CmpSub$bc_xHLrToA C_FLAG, [YG_GP+lr35902.A]
  4184. %endmacro        
  4185.  
  4186. %macro Cmp_ 0
  4187.   OP_CmpSub$bc_xHLrToA 0, cl
  4188. %endmacro  
  4189.      
  4190. %macro And_ 0
  4191.   OP_Logic_T H_FLAG, and
  4192. %endmacro    
  4193.      
  4194. %macro Xor_  0
  4195.   OP_Logic_T 0, xor
  4196. %endmacro        
  4197.  
  4198. %macro Or_ 0
  4199.   OP_Logic_T 0, or
  4200. %endmacro      
  4201.  
  4202. %macro DecWord_  0
  4203.   dec eax
  4204. %endmacro  
  4205.  
  4206. %macro IncWord_  0
  4207.   inc eax
  4208. %endmacro
  4209.  
  4210. %macro Inc_  0 ;; ----------------------- DEC RxHL
  4211. ;; source <- eax
  4212. ;; clear psb . save old C
  4213.   and YG_PF, C_FLAG
  4214.   add al, 1
  4215.   setz dl
  4216.   shl dl, 7
  4217.   or YG_PF, edx ;; z flag set  
  4218.   test eax, 15 ;; 0xNF+1 := 0xC0 (C:= N+1)
  4219.   setz dl
  4220.   shl dl, 5
  4221.   or YG_PF, edx ;; h flag set  
  4222. %endmacro  
  4223.  
  4224. %macro Dec_ 0  ;; ----------------------- INC RxHL
  4225. ;; source <- eax
  4226. ;; clear psb . save old C
  4227.   and YG_PF, C_FLAG
  4228.   sub al, 1
  4229.   setz dl
  4230.   shl dl, 7
  4231.   or YG_PF, edx ;; z flag set  
  4232.   lea ecx, [eax+1]
  4233.   test ecx, 15 ;; 0xN0-1 := 0xCF (C:= N-1)
  4234.   setz dl
  4235.   shl dl, 5
  4236.   or YG_PF, edx ;; h flag set
  4237.   or YG_PF, N_FLAG ;; n flag set
  4238. %endmacro  
  4239.  
  4240. %macro lr35902@JP 3 ;; ------------------------- JMP/Jcc
  4241.  ;; %1 Opcode,
  4242.  ;; %2 Flags
  4243.  ;; %3 OpNOT
  4244.    %1:
  4245.       mov eax, YG_PF
  4246.       and eax, %2
  4247.       xor eax, %3
  4248.       jne %%JP_skip
  4249.       add esi, 2
  4250.       SetCyclesRetP 12
  4251.     %%JP_skip:
  4252.       Imm16_Read
  4253.       mov esi, eax
  4254.       SetCyclesRetP 16
  4255. %endmacro  
  4256.  
  4257. %macro lr35902@Rst 2 ;; ------------------------- Rst
  4258. ;; %1 Opcode
  4259. ;; %2 Vector
  4260.   %1:
  4261.     mov ax, si
  4262.     OP_PushWord
  4263.     mov si, %2
  4264.     SetCyclesAndRet 16
  4265. %endmacro  
  4266.  
  4267. %macro lr35902@JR  3 ;; -------------------------- JMP Short/Jcc Short
  4268. ;; %1 Opcode
  4269. ;; %2 Flags
  4270. ;; %3 OpNOT
  4271.    %1:
  4272.       mov eax, YG_PF
  4273.       and eax, %2
  4274.       xor eax, %3
  4275.       jne %%JR_skip
  4276.       inc esi
  4277.       SetCyclesRetP 8
  4278.     %%JR_skip:
  4279.       Imm8_Read
  4280.       movsx eax, al
  4281.       add esi, eax
  4282.       SetCyclesRetP 12
  4283. %endmacro
  4284.  
  4285. %macro lr35902@CALL   3 ;; ------------------------ sub routine call
  4286. ;; %1 Opcode
  4287. ;; %2 Flags
  4288. ;; %3 OpNOT
  4289.    %1:
  4290.       mov eax, YG_PF
  4291.       and eax, %2
  4292.       xor eax, %3
  4293.       jne %%CALL_Skip
  4294.       add esi, 2
  4295.       SetCyclesRetP 12
  4296.     %%CALL_Skip:
  4297.       lea eax, [YG_PC+2]
  4298.       OP_PushWord
  4299.       Imm16_Read
  4300.       mov esi, eax
  4301.       SetCyclesRetP 24
  4302. %endmacro  
  4303.  
  4304.  
  4305. %macro lr35902@RET 4 ;; --------------------------- sub_call return
  4306. ;; %1 Opcode
  4307. ;; %2 Flags
  4308. ;; %3 OpNOT
  4309. ;; %4 RetHitCycles
  4310.    %1:
  4311.       mov eax, YG_PF
  4312.       and eax, %2
  4313.       xor eax, %3
  4314.       jne %%RET_skip
  4315.       SetCyclesRetP 8
  4316.     %%RET_skip:
  4317.       OP_PopWord
  4318.       mov YG_PC, eax
  4319.       SetCyclesRetP %4
  4320. %endmacro    
  4321.      
  4322. %macro lr35902@RETI 4
  4323.  %1:
  4324.       OP_PopWord
  4325.       mov YG_PC, eax
  4326.       mov byte [YG_GP+lr35902.IME], 1
  4327.       SetCyclesAndRet 16    
  4328. %endmacro  
  4329.  
  4330. %macro OP_PushWord 0  ;; ----------------------- Stack Push Base
  4331. ;; source <- eax
  4332. ;; --SP Push High
  4333. ;; --SP Push Low
  4334.   mov cx, [YG_GP+lr35902.SP]
  4335.   sub cx, 2
  4336.   mov [YG_GP+lr35902.SP], cx
  4337.   push eax
  4338.   push ecx
  4339.   push dword [YG_GP+lr35902.gameboy]
  4340.   call MmuWriteWord
  4341. %endmacro  
  4342.  
  4343. %macro OP_PopWord  0  ;; ----------------------- Stack Pop Base
  4344. ;; target <- eax
  4345. ;; Pop Low ++SP
  4346. ;; Pop High ++SP
  4347.   mov cx, [YG_GP+lr35902.SP]
  4348.   push ecx
  4349.   add cx, 2
  4350.   mov [YG_GP+lr35902.SP], cx
  4351.   push dword [YG_GP+lr35902.gameboy]
  4352.   call MmuReadWord
  4353. %endmacro  
  4354.  
  4355. %macro AF_StackPopStuff  0  ;; -----------------------
  4356.   and eax, 0xFFF0
  4357. %endmacro  
  4358.  
  4359. %macro AF_StackPushStuff  0  ;; -----------------------
  4360. %endmacro  
  4361.  
  4362.  
  4363. %macro lr35902@MainALU 5
  4364.  ;; %1 OpCase
  4365.  ;; %2 Cycles
  4366.  ;; %3 ReadOrExt
  4367.  ;; %4 Op
  4368.  ;; %5 WriteOrExt
  4369.   %1:
  4370.     %3
  4371.     %4
  4372.     %5
  4373.     SetCyclesRetP %2
  4374. %endmacro
  4375.  
  4376. %macro lr35902@MainALUExt  5
  4377.  ;; %1 OpCase
  4378.  ;; %2 Cycles
  4379.  ;; %3 ReadOrExt
  4380.  ;; %4 Op
  4381.  ;; %5 WriteOrExt
  4382.   %1:
  4383.     %3
  4384.     %4
  4385.     %5
  4386.     SetCyclesRetP %2
  4387. %endmacro
  4388.        
  4389. ;; rortoe shift with  
  4390. %macro RLC_ 0
  4391.   rol al, 1
  4392.   setc YG_PF_8
  4393.   shl YG_PF_8, 4
  4394.   test al, al
  4395.   setz dl
  4396.   shl dl, 7
  4397.   or YG_PF_8, dl    
  4398. %endmacro  
  4399. ;; rortoe shift with  
  4400. %macro RRC_ 0
  4401.   ror al, 1
  4402.   setc YG_PF_8
  4403.   shl YG_PF_8, 4
  4404.   test al, al
  4405.   setz dl
  4406.   shl dl, 7
  4407.   or YG_PF_8, dl    
  4408. %endmacro        
  4409. ;; logic shift with carry
  4410. %macro RL_ 0
  4411.   shr YG_PF_8, 5
  4412.   rcl al, 1
  4413.   setc YG_PF_8
  4414.   shl YG_PF_8, 4
  4415.   test al, al
  4416.   setz dl
  4417.   shl dl, 7
  4418.   or YG_PF_8, dl    
  4419. %endmacro  
  4420. ;; logic shift with carry
  4421. %macro RR_ 0
  4422.   shr YG_PF_8, 5
  4423.   rcr al, 1
  4424.   setc YG_PF_8
  4425.   shl YG_PF_8, 4
  4426.   test al, al
  4427.   setz dl
  4428.   shl dl, 7
  4429.   or YG_PF_8, dl    
  4430. %endmacro        
  4431. ;; logic shift    
  4432. %macro RL_N_ 0
  4433.   shl al, 1
  4434.   setc YG_PF_8
  4435.   shl YG_PF_8, 4
  4436.   test al, al
  4437.   setz dl
  4438.   shl dl, 7
  4439.   or YG_PF_8, dl    
  4440. %endmacro  
  4441. ;; logic shift  
  4442. %macro RR_N_ 0
  4443.   shr al, 1
  4444.   setc YG_PF_8
  4445.   shl YG_PF_8, 4
  4446.   test al, al
  4447.   setz dl
  4448.   shl dl, 7
  4449.   or YG_PF_8, dl    
  4450. %endmacro    
  4451. ;; arith shift  save msb
  4452. %macro RRS_N_ 0
  4453.   sar al, 1
  4454.   setc YG_PF_8
  4455.   shl YG_PF_8, 4
  4456.   test al, al
  4457.   setz dl
  4458.   shl dl, 7
  4459.   or YG_PF_8, dl    
  4460. %endmacro      
  4461. ;; swap byte-lo 4bit and byte-hi 4bit
  4462. %macro SWAP_ 0
  4463.   ror al, 4
  4464.   test al, al
  4465.   setz cl
  4466.   shl cl, 7
  4467.   mov YG_PF, ecx
  4468. %endmacro          
  4469.  
  4470. ;;  Set
  4471. %macro lr35902@SetBit 5
  4472.  ;; %1 Opcode
  4473.  ;; %2 Cycles
  4474.  ;; %3 ReadOrExt
  4475.  ;; %4 BitOrder
  4476.  ;; %5 WriteOrExt
  4477.   %1:
  4478.     %3
  4479.     mov ecx, 1
  4480.     shl ecx, %4
  4481.     or eax, ecx
  4482.     %5
  4483.     SetCyclesAndRet %2
  4484. %endmacro  
  4485.  
  4486. %macro lr35902@ResBit 5
  4487.  ;; %1 Opcode
  4488.  ;; %2 Cycles
  4489.  ;; %3 ReadOrExt
  4490.  ;; %4 BitOrder
  4491.  ;; %5 WriteOrExt
  4492.   %1:
  4493.     %3
  4494.     mov ecx, 1
  4495.     shl ecx, %4
  4496.     not ecx
  4497.     and al, cl
  4498.     %5
  4499.     SetCyclesRetP %2
  4500. %endmacro          
  4501.    
  4502. %macro lr35902@TestBit 4
  4503.  ;; %1 Opcode
  4504.  ;; %2 Cycles
  4505.  ;; %3 ReadOrExt
  4506.  ;; %4 BitOrder
  4507.   %1:
  4508.     %3
  4509.     and YG_PF, C_FLAG
  4510.     or YG_PF, H_FLAG
  4511.     mov ecx, 1
  4512.     shl ecx, %4
  4513.     test al, cl
  4514.     setz al
  4515.     shl eax, 7
  4516.     or YG_PF, eax
  4517.     SetCyclesRetP %2
  4518. %endmacro  
  4519.      
  4520.      
  4521.      
  4522.         ;; lr35902@MainStack  OPC1,12, PopWord_, EmptyMacro, BC_Write ;; POP BC  1 Cycles:12
  4523. %macro lr35902@MainStack    5
  4524.  ;; %1 OpCase
  4525.  ;; %2 Cycles
  4526.  ;; %3 ReadOrExt
  4527.  ;; %4 Op
  4528.  ;; %5 WriteOrExt
  4529.   %1:
  4530.     %3
  4531.     %4
  4532.     %5
  4533.     SetCyclesAndRet %2
  4534. %endmacro
  4535.  
  4536.  
  4537. section .text
  4538. global _cpu_optick
  4539. _cpu_optick:
  4540.         push ebx ;U -  save old frame      
  4541.         push edi ;V -  save old frame
  4542.         push esi
  4543.         nop  
  4544.  
  4545. %define YG_PF_8 bl        
  4546. %define YG_PF ebx
  4547. %define YG_PC esi
  4548. %define YG_GP edi
  4549.  
  4550.         ; ebx <- save now P (cpu's PSB reg)
  4551.        ; esi <- save now PC (cpu's EIP reg)
  4552.         ; edi <- save regs root
  4553.         ; eax <- calc temp or final calc out reslt
  4554.         ; ecx <- calc temp
  4555.         ; edx <- calc temp
  4556.        
  4557.         mov YG_GP, [esp+4+12]   ;; fetch CPU struct
  4558.         mov si, [YG_GP+lr35902.PC]
  4559.         mov bl, [YG_GP+lr35902.F]
  4560.        
  4561.         ; Fetch Opcode, PC++
  4562.         push YG_PC
  4563.         push dword [YG_GP+lr35902.gameboy]
  4564.         call MmuRead
  4565.         inc YG_PC
  4566.         add YG_PC, [YG_GP+lr35902._backup]
  4567.         and eax, 255
  4568.         jmp dword [OPTAB+eax*4]
  4569.        
  4570.         lr35902@LD@Imm OP06, Imm8_Read, 8,  B_Write ;; LD B Imm8, 2, Cycles:8
  4571.         lr35902@LD@Imm OP0E, Imm8_Read, 8,  C_Write ;; LD C Imm8, 2, Cycles:8
  4572.         lr35902@LD@Imm OP16, Imm8_Read, 8,  D_Write ;; LD D Imm8, 2, Cycles:8
  4573.         lr35902@LD@Imm OP1E, Imm8_Read, 8,  E_Write ;; LD E Imm8, 2, Cycles:8
  4574.         lr35902@LD@Imm OP26, Imm8_Read, 8,  H_Write ;; LD H Imm8, 2, Cycles:8
  4575.         lr35902@LD@Imm OP2E, Imm8_Read, 8,  L_Write ;; LD L Imm8, 2, Cycles:8
  4576.         lr35902@LD@Imm OP36, Imm8_Read, 12, xHL_Write ;; LD xHL Imm8, 2, Cycles:8
  4577.         lr35902@LD@Imm OP3E, Imm8_Read, 8,  A_Write ;; LD A Imm8, 2, Cycles:8
  4578.      
  4579.         lr35902@LD@Imm OP01, Imm16_Read, 12, BC_Write ;; LD BC Imm16, 3 Cycles:12
  4580.         lr35902@LD@Imm OP11, Imm16_Read, 12, DE_Write ;; LD DE Imm16, 3 Cycles:12    
  4581.         lr35902@LD@Imm OP21, Imm16_Read, 12, HL_Write ;; LD HL Imm16, 3 Cycles:12    
  4582.         lr35902@LD@Imm OP31, Imm16_Read, 12, SP_Write ;; LD SP Imm16, 3 Cycles:12  
  4583.      
  4584.         lr35902@LD@RxHLToRxHL OP40, 4, B_Read, B_Write ;; LD B B, 1 Cycles:4
  4585.         lr35902@LD@RxHLToRxHL OP41, 4, C_Read, B_Write ;; LD B C, 1 Cycles:4
  4586.         lr35902@LD@RxHLToRxHL OP42, 4, D_Read, B_Write ;; LD B D, 1 Cycles:4
  4587.         lr35902@LD@RxHLToRxHL OP43, 4, E_Read, B_Write ;; LD B E, 1 Cycles:4
  4588.         lr35902@LD@RxHLToRxHL OP44, 4, H_Read, B_Write ;; LD B H, 1 Cycles:4
  4589.         lr35902@LD@RxHLToRxHL OP45, 4, L_Read, B_Write ;; LD B L, 1 Cycles:4
  4590.         lr35902@LD@RxHLToRxHL OP46, 8, xHL_Read, B_Write ;; LD B xHL, 1 Cycles:8
  4591.         lr35902@LD@RxHLToRxHL OP47, 4, A_Read, B_Write ;; LD B A, 1 Cycles:4  
  4592.        
  4593.         lr35902@LD@RxHLToRxHL OP48, 4, B_Read, C_Write ;; LD C B, 1 Cycles:4
  4594.         lr35902@LD@RxHLToRxHL OP49, 4, C_Read, C_Write ;; LD C C, 1 Cycles:4
  4595.         lr35902@LD@RxHLToRxHL OP4A, 4, D_Read, C_Write ;; LD C D, 1 Cycles:4
  4596.         lr35902@LD@RxHLToRxHL OP4B, 4, E_Read, C_Write ;; LD C E, 1 Cycles:4
  4597.         lr35902@LD@RxHLToRxHL OP4C, 4, H_Read, C_Write ;; LD C H, 1 Cycles:4
  4598.         lr35902@LD@RxHLToRxHL OP4D, 4, L_Read, C_Write ;; LD C L, 1 Cycles:4
  4599.         lr35902@LD@RxHLToRxHL OP4E, 8, xHL_Read, C_Write ;; LD C xHL, 1 Cycles:8
  4600.         lr35902@LD@RxHLToRxHL OP4F, 4, A_Read, C_Write ;; LD C A, 1 Cycles:4  
  4601.  
  4602.         lr35902@LD@RxHLToRxHL OP50, 4, B_Read, D_Write ;; LD D B, 1 Cycles:4
  4603.         lr35902@LD@RxHLToRxHL OP51, 4, C_Read, D_Write ;; LD D C, 1 Cycles:4
  4604.         lr35902@LD@RxHLToRxHL OP52, 4, D_Read, D_Write ;; LD D D, 1 Cycles:4
  4605.         lr35902@LD@RxHLToRxHL OP53, 4, E_Read, D_Write ;; LD D E, 1 Cycles:4
  4606.         lr35902@LD@RxHLToRxHL OP54, 4, H_Read, D_Write ;; LD D H, 1 Cycles:4
  4607.         lr35902@LD@RxHLToRxHL OP55, 4, L_Read, D_Write ;; LD D L, 1 Cycles:4
  4608.         lr35902@LD@RxHLToRxHL OP56, 8, xHL_Read, D_Write ;; LD D xHL, 1 Cycles:8
  4609.         lr35902@LD@RxHLToRxHL OP57, 4, A_Read, D_Write ;; LD D A, 1 Cycles:4  
  4610.        
  4611.         lr35902@LD@RxHLToRxHL OP58, 4, B_Read, E_Write ;; LD E B, 1 Cycles:4
  4612.         lr35902@LD@RxHLToRxHL OP59, 4, C_Read, E_Write ;; LD E C, 1 Cycles:4
  4613.         lr35902@LD@RxHLToRxHL OP5A, 4, D_Read, E_Write ;; LD E D, 1 Cycles:4
  4614.         lr35902@LD@RxHLToRxHL OP5B, 4, E_Read, E_Write ;; LD E E, 1 Cycles:4
  4615.         lr35902@LD@RxHLToRxHL OP5C, 4, H_Read, E_Write ;; LD E H, 1 Cycles:4
  4616.         lr35902@LD@RxHLToRxHL OP5D, 4, L_Read, E_Write ;; LD E L, 1 Cycles:4
  4617.         lr35902@LD@RxHLToRxHL OP5E, 8, xHL_Read, E_Write ;; LD E xHL, 1 Cycles:8
  4618.         lr35902@LD@RxHLToRxHL OP5F, 4, A_Read, E_Write ;; LD E A, 1 Cycles:4  
  4619.  
  4620.         lr35902@LD@RxHLToRxHL OP60, 4, B_Read, H_Write ;; LD H B, 1 Cycles:4
  4621.         lr35902@LD@RxHLToRxHL OP61, 4, C_Read, H_Write ;; LD H C, 1 Cycles:4
  4622.         lr35902@LD@RxHLToRxHL OP62, 4, D_Read, H_Write ;; LD H D, 1 Cycles:4
  4623.         lr35902@LD@RxHLToRxHL OP63, 4, E_Read, H_Write ;; LD H E, 1 Cycles:4
  4624.         lr35902@LD@RxHLToRxHL OP64, 4, H_Read, H_Write ;; LD H H, 1 Cycles:4
  4625.         lr35902@LD@RxHLToRxHL OP65, 4, L_Read, H_Write ;; LD H L, 1 Cycles:4
  4626.         lr35902@LD@RxHLToRxHL OP66, 8, xHL_Read, H_Write ;; LD H xHL, 1 Cycles:8
  4627.         lr35902@LD@RxHLToRxHL OP67, 4, A_Read, H_Write ;; LD H A, 1 Cycles:4  
  4628.        
  4629.         lr35902@LD@RxHLToRxHL OP68, 4, B_Read, L_Write ;; LD L B, 1 Cycles:4
  4630.         lr35902@LD@RxHLToRxHL OP69, 4, C_Read, L_Write ;; LD L C, 1 Cycles:4
  4631.         lr35902@LD@RxHLToRxHL OP6A, 4, D_Read, L_Write ;; LD L D, 1 Cycles:4
  4632.         lr35902@LD@RxHLToRxHL OP6B, 4, E_Read, L_Write ;; LD L E, 1 Cycles:4
  4633.         lr35902@LD@RxHLToRxHL OP6C, 4, H_Read, L_Write ;; LD L H, 1 Cycles:4
  4634.         lr35902@LD@RxHLToRxHL OP6D, 4, L_Read, L_Write ;; LD L L, 1 Cycles:4
  4635.         lr35902@LD@RxHLToRxHL OP6E, 8, xHL_Read, L_Write ;; LD L xHL, 1 Cycles:8
  4636.         lr35902@LD@RxHLToRxHL OP6F, 4, A_Read, L_Write ;; LD L A, 1 Cycles:4  
  4637.          
  4638.         lr35902@LD@RxHLToRxHL OP70, 8, B_Read, xHL_Write ;; LD xHL B, 1 Cycles:8
  4639.         lr35902@LD@RxHLToRxHL OP71, 8, C_Read, xHL_Write ;; LD xHL C, 1 Cycles:8
  4640.         lr35902@LD@RxHLToRxHL OP72, 8, D_Read, xHL_Write ;; LD xHL D, 1 Cycles:8
  4641.         lr35902@LD@RxHLToRxHL OP73, 8, E_Read, xHL_Write ;; LD xHL E, 1 Cycles:8
  4642.         lr35902@LD@RxHLToRxHL OP74, 8, H_Read, xHL_Write ;; LD xHL H, 1 Cycles:8
  4643.         lr35902@LD@RxHLToRxHL OP75, 8, L_Read, xHL_Write ;; LD xHL L, 1 Cycles:8
  4644.         lr35902@LD@RxHLToRxHL OP02, 8, A_Read, xBC_Write ;; LD xBC A, 1 Cycles:8    
  4645.         lr35902@LD@RxHLToRxHL OP12, 8, A_Read, xDE_Write ;; LD xDE A, 1 Cycles:8    
  4646.         lr35902@LD@RxHLToRxHL OP77, 8, A_Read, xHL_Write ;; LD xHL A, 1 Cycles:8    
  4647.         lr35902@LD@RxHLToRxHL OP22, 8, A_Read, xHL_Write_Inc;; LD xHL++ A, 1 Cycles:8  
  4648.         lr35902@LD@RxHLToRxHL OP32, 8, A_Read, xHL_Write_Dec ;; LD xHL-- A, 1 Cycles:8  
  4649.          
  4650.         lr35902@LD@RxHLToRxHL OP78, 4, B_Read, A_Write ;; LD A B, 1 Cycles:4
  4651.         lr35902@LD@RxHLToRxHL OP79, 4, C_Read, A_Write ;; LD A C, 1 Cycles:4
  4652.         lr35902@LD@RxHLToRxHL OP7A, 4, D_Read, A_Write ;; LD A D, 1 Cycles:4
  4653.         lr35902@LD@RxHLToRxHL OP7B, 4, E_Read, A_Write ;; LD A E, 1 Cycles:4
  4654.         lr35902@LD@RxHLToRxHL OP7C, 4, H_Read, A_Write ;; LD A H, 1 Cycles:4
  4655.         lr35902@LD@RxHLToRxHL OP7D, 4, L_Read, A_Write ;; LD A L, 1 Cycles:4
  4656.         lr35902@LD@RxHLToRxHL OP0A, 8, xBC_Read, A_Write ;; LD A xBC, 1 Cycles:8
  4657.         lr35902@LD@RxHLToRxHL OP1A, 8, xDE_Read, A_Write ;; LD A xDE, 1 Cycles:8
  4658.         lr35902@LD@RxHLToRxHL OP7E, 8, xHL_Read, A_Write ;; LD A xHL, 1 Cycles:8
  4659.         lr35902@LD@RxHLToRxHL OP2A, 8, xHL_Read_Inc, A_Write ;; LD A xHL++, 1 Cycles:8
  4660.         lr35902@LD@RxHLToRxHL OP3A, 8, xHL_Read_Dec, A_Write ;; LD A xHL--, 1 Cycles:8
  4661.         lr35902@LD@RxHLToRxHL OP7F, 4, A_Read, A_Write ;; LD A A, 1 Cycles:4      
  4662.   ;; MISC LD
  4663.         lr35902@LD@RxHLToRxHL OP08,20, Imm16_Read, xImm16_WriteRegSP ;; LD (Imm16) SP, 3 Cycles:20
  4664.         lr35902@LD@RxHLToRxHL OPEA,16, Imm16_Read, xImm16_WriteRegA ;; LD (Imm16) A, 3 Cycles:16
  4665.         lr35902@LD@RxHLToRxHL OPE0,12, Imm8Read_ExpandAddress16, xImm16_WriteRegA ;; LD (Imm8+0FF00h) A, 2 Cycles:12
  4666.         lr35902@LD@RxHLToRxHL OPE2, 8, C_ExpandAddress16, xImm16_WriteRegA ;; LD (C+0FF00h) A, 2 Cycles:8  
  4667.         lr35902@LD@RxHLToRxHL OPF0,12, Imm8Read_ExpandAddress16_Fetch, A_Write ;; LD A, (Imm8+0FF00h)  2 Cycles:12
  4668.         lr35902@LD@RxHLToRxHL OPF2, 8, C_ExpandAddress16_Fetch, A_Write ;; LD A, (C+0FF00h) 2 Cycles:8    
  4669.         lr35902@LD@RxHLToRxHL OPFA,16, Imm16Read_Address_Fetch, A_Write ;; LD A, (Imm16) 3 Cycles:16
  4670.         lr35902@LD@RxHLToRxHL OPF9, 8, HL_Read, SP_Write ;; LD SP HL 1 Cycles:8
  4671.        
  4672.         lr35902@MainALU  OP80, 4, B_Read, Add_, EmptyMacro ;; ADD A, B  1 Cycles:4
  4673.         lr35902@MainALU  OP81, 4, C_Read, Add_, EmptyMacro ;; ADD A, C  1 Cycles:4    
  4674.         lr35902@MainALU  OP82, 4, D_Read, Add_, EmptyMacro ;; ADD A, D  1 Cycles:4
  4675.         lr35902@MainALU  OP83, 4, E_Read, Add_, EmptyMacro ;; ADD A, E  1 Cycles:4      
  4676.         lr35902@MainALU  OP84, 4, H_Read, Add_, EmptyMacro ;; ADD A, H  1 Cycles:4
  4677.         lr35902@MainALU  OP85, 4, L_Read, Add_, EmptyMacro ;; ADD A, L  1 Cycles:4    
  4678.         lr35902@MainALU  OP86, 8, xHL_Read, Add_, EmptyMacro ;; ADD A, xHL  1 Cycles:8
  4679.         lr35902@MainALU  OP87, 4, A_Read, Add_, EmptyMacro ;; ADD A, A  1 Cycles:4  
  4680.         lr35902@MainALU  OPC6, 8, Imm8_Read, Add_, EmptyMacro ;; ADD A, Imm8  2 Cycles:8
  4681.         lr35902@MainALU  OP09, 8, BC_Read, AddWord_, HL_Write ;; ADD HL, BC  1 Cycles:8    
  4682.         lr35902@MainALU  OP19, 8, DE_Read, AddWord_, HL_Write ;; ADD HL, DE  1 Cycles:8    
  4683.         lr35902@MainALU  OP29, 8, HL_Read, AddWord_, HL_Write ;; ADD HL, HL  1 Cycles:8    
  4684.         lr35902@MainALU  OP39, 8, SP_Read, AddWord_, HL_Write ;; ADD HL, SP  1 Cycles:8    
  4685.         lr35902@MainALU  OPE8,16, Imm8_ExpandSignWord, AddWord2_, EmptyMacro ;; ADD SP, SignImm8  2 Cycles:16
  4686.        
  4687.         lr35902@MainALU  OP88, 4, B_Read, Adc_, EmptyMacro ;; ADC A, B  1 Cycles:4
  4688.         lr35902@MainALU  OP89, 4, C_Read, Adc_, EmptyMacro ;; ADC A, C  1 Cycles:4    
  4689.         lr35902@MainALU  OP8A, 4, D_Read, Adc_, EmptyMacro ;; ADC A, D  1 Cycles:4
  4690.         lr35902@MainALU  OP8B, 4, E_Read, Adc_, EmptyMacro ;; ADC A, E  1 Cycles:4      
  4691.         lr35902@MainALU  OP8C, 4, H_Read, Adc_, EmptyMacro ;; ADC A, H  1 Cycles:4
  4692.         lr35902@MainALU  OP8D, 4, L_Read, Adc_, EmptyMacro ;; ADC A, L  1 Cycles:4    
  4693.         lr35902@MainALU  OP8E, 8, xHL_Read, Adc_, EmptyMacro ;; ADC A, xHL  1 Cycles:8
  4694.         lr35902@MainALU  OP8F, 4, A_Read, Adc_, EmptyMacro ;; ADC A, A  1 Cycles:4  
  4695.         lr35902@MainALU  OPCE, 8, Imm8_Read, Adc_, EmptyMacro ;; ADC A, Imm8  2 Cycles:8    
  4696.        
  4697.         lr35902@MainALU  OP03, 8, BC_Read, IncWord_, BC_Write ;; INC BC  Cycles:8
  4698.         lr35902@MainALU  OP13, 8, DE_Read, IncWord_, DE_Write ;; INC DE  Cycles:8
  4699.         lr35902@MainALU  OP23, 8, HL_Read, IncWord_, HL_Write ;; INC HL  Cycles:8
  4700.         lr35902@MainALU  OP33, 8, SP_Read, IncWord_, SP_Write ;; INC SP  Cycles:8
  4701.        
  4702.         lr35902@MainALU  OP04, 4, B_Read, Inc_, B_Write ;; INC B  1 Cycles:4
  4703.         lr35902@MainALU  OP14, 4, D_Read, Inc_, D_Write ;; INC D  1 Cycles:4    
  4704.         lr35902@MainALU  OP24, 4, H_Read, Inc_, H_Write ;; INC H  1 Cycles:4
  4705.         lr35902@MainALU  OP34, 4, xHL_Read, Inc_, xHL_Write ;; INC xHL  1 Cycles:4      
  4706.         lr35902@MainALU  OP0C, 4, C_Read, Inc_, C_Write ;; INC C  1 Cycles:4
  4707.         lr35902@MainALU  OP1C, 4, E_Read, Inc_, E_Write ;; INC E  1 Cycles:4    
  4708.         lr35902@MainALU  OP2C,12, L_Read, Inc_, L_Write ;; INC L  1 Cycles:12
  4709.         lr35902@MainALU  OP3C, 4, A_Read, Inc_, A_Write ;; INC A  1 Cycles:4      
  4710.        
  4711.         lr35902@MainALU  OP90, 4, B_Read, Sub_, EmptyMacro ;; SUB A, B  1 Cycles:4
  4712.         lr35902@MainALU  OP91, 4, C_Read, Sub_, EmptyMacro ;; SUB A, C  1 Cycles:4    
  4713.         lr35902@MainALU  OP92, 4, D_Read, Sub_, EmptyMacro ;; SUB A, D  1 Cycles:4
  4714.         lr35902@MainALU  OP93, 4, E_Read, Sub_, EmptyMacro ;; SUB A, E  1 Cycles:4      
  4715.         lr35902@MainALU  OP94, 4, H_Read, Sub_, EmptyMacro ;; SUB A, H  1 Cycles:4
  4716.         lr35902@MainALU  OP95, 4, L_Read, Sub_, EmptyMacro ;; SUB A, L  1 Cycles:4    
  4717.         lr35902@MainALU  OP96, 8, xHL_Read, Sub_, EmptyMacro ;; SUB A, xHL  1 Cycles:8
  4718.         lr35902@MainALU  OP97, 4, A_Read, Sub_, EmptyMacro ;; SUB A, A  1 Cycles:4  
  4719.         lr35902@MainALU  OPD6, 8, Imm8_Read, Sub_, EmptyMacro ;; SUB A, Imm8  2 Cycles:8
  4720.        
  4721.         lr35902@MainALU  OP98, 4, B_Read, Sbc_, EmptyMacro ;; SBC A, B  1 Cycles:4
  4722.         lr35902@MainALU  OP99, 4, C_Read, Sbc_, EmptyMacro ;; SBC A, C  1 Cycles:4    
  4723.         lr35902@MainALU  OP9A, 4, D_Read, Sbc_, EmptyMacro ;; SBC A, D  1 Cycles:4
  4724.         lr35902@MainALU  OP9B, 4, E_Read, Sbc_, EmptyMacro ;; SBC A, E  1 Cycles:4      
  4725.         lr35902@MainALU  OP9C, 4, H_Read, Sbc_, EmptyMacro ;; SBC A, H  1 Cycles:4
  4726.         lr35902@MainALU  OP9D, 4, L_Read, Sbc_, EmptyMacro ;; SBC A, L  1 Cycles:4    
  4727.         lr35902@MainALU  OP9E, 8, xHL_Read, Sbc_, EmptyMacro ;; SBC A, xHL  1 Cycles:8
  4728.         lr35902@MainALU  OP9F, 4, A_Read, Sbc_, EmptyMacro ;; SBC A, A  1 Cycles:4  
  4729.         lr35902@MainALU  OPDE, 8, Imm8_Read, Sbc_, EmptyMacro ;; SBC A, Imm8  2 Cycles:8
  4730.      
  4731.         lr35902@MainALU  OP0B, 8, BC_Read, DecWord_, BC_Write ;; DEC BC  Cycles:8
  4732.         lr35902@MainALU  OP1B, 8, DE_Read, DecWord_, DE_Write ;; DEC DE  Cycles:8
  4733.         lr35902@MainALU  OP2B, 8, HL_Read, DecWord_, HL_Write ;; DEC HL  Cycles:8
  4734.         lr35902@MainALU  OP3B, 8, SP_Read, DecWord_, SP_Write ;; DEC SP  Cycles:8
  4735.        
  4736.         lr35902@MainALU  OP05, 4, B_Read, Dec_, B_Write ;; DEC B  1 Cycles:4
  4737.         lr35902@MainALU  OP15, 4, D_Read, Dec_, D_Write ;; DEC D  1 Cycles:4    
  4738.         lr35902@MainALU  OP25, 4, H_Read, Dec_, H_Write ;; DEC H  1 Cycles:4
  4739.         lr35902@MainALU  OP35, 4, xHL_Read, Dec_, xHL_Write ;; DEC xHL  1 Cycles:4      
  4740.         lr35902@MainALU  OP0D, 4, C_Read, Dec_, C_Write ;; DEC C  1 Cycles:4
  4741.         lr35902@MainALU  OP1D, 4, E_Read, Dec_, E_Write ;; DEC E  1 Cycles:4    
  4742.         lr35902@MainALU  OP2D,12, L_Read, Dec_, L_Write ;; DEC L  1 Cycles:12
  4743.         lr35902@MainALU  OP3D, 4, A_Read, Dec_, A_Write ;; DEC A  1 Cycles:4  
  4744.        
  4745.         lr35902@MainALU  OPA0, 4, B_Read, And_, EmptyMacro ;; AND A, B  1 Cycles:4
  4746.         lr35902@MainALU  OPA1, 4, C_Read, And_, EmptyMacro ;; AND A, C  1 Cycles:4    
  4747.         lr35902@MainALU  OPA2, 4, D_Read, And_, EmptyMacro ;; AND A, D  1 Cycles:4
  4748.         lr35902@MainALU  OPA3, 4, E_Read, And_, EmptyMacro ;; AND A, E  1 Cycles:4      
  4749.         lr35902@MainALU  OPA4, 4, H_Read, And_, EmptyMacro ;; AND A, H  1 Cycles:4
  4750.         lr35902@MainALU  OPA5, 4, L_Read, And_, EmptyMacro ;; AND A, L  1 Cycles:4    
  4751.         lr35902@MainALU  OPA6, 8, xHL_Read, And_, EmptyMacro ;; AND A, xHL  1 Cycles:8
  4752.         lr35902@MainALU  OPA7, 4, A_Read, And_, EmptyMacro ;; AND A, A  1 Cycles:4  
  4753.         lr35902@MainALU  OPE6, 8, Imm8_Read, And_, EmptyMacro ;; AND A, Imm8  2 Cycles:8
  4754.          
  4755.         lr35902@MainALU  OPA8, 4, B_Read, Xor_, EmptyMacro ;; XOR A, B  1 Cycles:4
  4756.         lr35902@MainALU  OPA9, 4, C_Read, Xor_, EmptyMacro ;; XOR A, C  1 Cycles:4    
  4757.         lr35902@MainALU  OPAA, 4, D_Read, Xor_, EmptyMacro ;; XOR A, D  1 Cycles:4
  4758.         lr35902@MainALU  OPAB, 4, E_Read, Xor_, EmptyMacro ;; XOR A, E  1 Cycles:4      
  4759.         lr35902@MainALU  OPAC, 4, H_Read, Xor_, EmptyMacro ;; XOR A, H  1 Cycles:4
  4760.         lr35902@MainALU  OPAD, 4, L_Read, Xor_, EmptyMacro ;; XOR A, L  1 Cycles:4    
  4761.         lr35902@MainALU  OPAE, 8, xHL_Read, Xor_, EmptyMacro ;; XOR A, xHL  1 Cycles:8
  4762.         lr35902@MainALU  OPAF, 4, A_Read, Xor_, EmptyMacro ;; XOR A, A  1 Cycles:4  
  4763.         lr35902@MainALU  OPEE, 8, Imm8_Read, Xor_, EmptyMacro ;; XOR A, Imm8  2 Cycles:8
  4764.        
  4765.         lr35902@MainALU  OPB0, 4, B_Read, Or_, EmptyMacro ;; OR A, B  1 Cycles:4
  4766.         lr35902@MainALU  OPB1, 4, C_Read, Or_, EmptyMacro ;; OR A, C  1 Cycles:4    
  4767.         lr35902@MainALU  OPB2, 4, D_Read, Or_, EmptyMacro ;; OR A, D  1 Cycles:4
  4768.         lr35902@MainALU  OPB3, 4, E_Read, Or_, EmptyMacro ;; OR A, E  1 Cycles:4      
  4769.         lr35902@MainALU  OPB4, 4, H_Read, Or_, EmptyMacro ;; OR A, H  1 Cycles:4
  4770.         lr35902@MainALU  OPB5, 4, L_Read, Or_, EmptyMacro ;; OR A, L  1 Cycles:4    
  4771.         lr35902@MainALU  OPB6, 8, xHL_Read, Or_, EmptyMacro ;; OR A, xHL  1 Cycles:8
  4772.         lr35902@MainALU  OPB7, 4, A_Read, Or_, EmptyMacro ;; OR A, A  1 Cycles:4  
  4773.         lr35902@MainALU  OPF6, 8, Imm8_Read, Or_, EmptyMacro ;; OR A, Imm8  2 Cycles:8
  4774.        
  4775.         lr35902@MainALU  OPB8, 4, B_Read, Cmp_, EmptyMacro ;; CP A, B  1 Cycles:4
  4776.         lr35902@MainALU  OPB9, 4, C_Read, Cmp_, EmptyMacro ;; CP A, C  1 Cycles:4    
  4777.         lr35902@MainALU  OPBA, 4, D_Read, Cmp_, EmptyMacro ;; CP A, D  1 Cycles:4
  4778.         lr35902@MainALU  OPBB, 4, E_Read, Cmp_, EmptyMacro ;; CP A, E  1 Cycles:4      
  4779.         lr35902@MainALU  OPBC, 4, H_Read, Cmp_, EmptyMacro ;; CP A, H  1 Cycles:4
  4780.         lr35902@MainALU  OPBD, 4, L_Read, Cmp_, EmptyMacro ;; CP A, L  1 Cycles:4    
  4781.         lr35902@MainALU  OPBE, 8, xHL_Read, Cmp_, EmptyMacro ;; CP A, xHL  1 Cycles:8
  4782.         lr35902@MainALU  OPBF, 4, A_Read, Cmp_, EmptyMacro ;; CP A, A  1 Cycles:4  
  4783.         lr35902@MainALU  OPFE, 8, Imm8_Read, Cmp_, EmptyMacro ;; CP A, Imm8  2 Cycles:8
  4784.  
  4785.         lr35902@MainStack  OPC1,12, OP_PopWord, EmptyMacro, BC_Write ;; POP BC  1 Cycles:12
  4786.         lr35902@MainStack  OPD1,12, OP_PopWord, EmptyMacro, DE_Write ;; POP DE  1 Cycles:12    
  4787.         lr35902@MainStack  OPE1,12, OP_PopWord, EmptyMacro, HL_Write ;; POP HL  1 Cycles:12
  4788.         lr35902@MainStack  OPF1,12, OP_PopWord, AF_StackPopStuff, AF_Write ;; POP AF  1 Cycles:12  
  4789.        
  4790.         lr35902@MainStack  OPC5,16, BC_Read, EmptyMacro, OP_PushWord ;; PUSH BC  1 Cycles:16
  4791.         lr35902@MainStack  OPD5,16, DE_Read, EmptyMacro, OP_PushWord ;; PUSH DE  1 Cycles:16    
  4792.         lr35902@MainStack  OPE5,16, HL_Read, EmptyMacro, OP_PushWord ;; PUSH HL  1 Cycles:16
  4793.         lr35902@MainStack  OPF5,16, AF_Read, AF_StackPushStuff, OP_PushWord ;; PUSH AF  1 Cycles:16  
  4794.    
  4795.         lr35902@JP  OPC2,Z_FLAG, Z_FLAG ;; JP NZ
  4796.         lr35902@JP  OPD2,C_FLAG, C_FLAG ;; JP NC
  4797.         lr35902@JP  OPCA,Z_FLAG, 0 ;; JP Z
  4798.         lr35902@JP  OPDA,C_FLAG, 0 ;; JP C  
  4799.         lr35902@JP  OPC3,0, 1 ;; JP A16    
  4800.        
  4801.         lr35902@Rst  OPC7, 000H ;; RST 00H  1 Cycles:16
  4802.         lr35902@Rst  OPD7, 010H ;; RST 10H  1 Cycles:16    
  4803.         lr35902@Rst  OPE7, 020H ;; RST 20H  1 Cycles:16
  4804.         lr35902@Rst  OPF7, 030H ;; RST 30H  1 Cycles:16  
  4805.         lr35902@Rst  OPCF, 008H ;; RST 08H  1 Cycles:16
  4806.         lr35902@Rst  OPDF, 018H ;; RST 18H  1 Cycles:16    
  4807.         lr35902@Rst  OPEF, 028H ;; RST 28H  1 Cycles:16
  4808.         lr35902@Rst  OPFF, 038H ;; RST 38H  1 Cycles:16    
  4809.        
  4810.         lr35902@CALL  OPC4,Z_FLAG, Z_FLAG ;; CALL NZ
  4811.         lr35902@CALL  OPD4,C_FLAG, C_FLAG ;; CALL NC
  4812.         lr35902@CALL  OPCC,Z_FLAG, 0 ;; CALL Z
  4813.         lr35902@CALL  OPDC,C_FLAG, 0 ;; CALL C  
  4814.         lr35902@CALL  OPCD,0, 1 ;; CALL  
  4815.      
  4816.         lr35902@JR  OP20,Z_FLAG, Z_FLAG ;; JR NZ
  4817.         lr35902@JR  OP30,C_FLAG, C_FLAG ;; JR NC
  4818.         lr35902@JR  OP28,Z_FLAG, 0 ;; JR Z
  4819.         lr35902@JR  OP38,C_FLAG, 0 ;; JR C  
  4820.         lr35902@JR  OP18,0, 1 ;; JR R8  
  4821.  
  4822.         lr35902@RET  OPC0,Z_FLAG, Z_FLAG, 20 ;; RET NZ
  4823.         lr35902@RET  OPD0,C_FLAG, C_FLAG, 20 ;; RET NC
  4824.         lr35902@RET  OPC8,Z_FLAG, 0, 20 ;; RET Z
  4825.         lr35902@RET  OPD8,C_FLAG, 0, 20 ;; RET C  
  4826.         lr35902@RET  OPC9,0, 1, 16 ;; RET  
  4827.         lr35902@RETI OPD9,0, 1, 16 ;; RETI
  4828. ;;  MISC
  4829.       OPF8: ;; -------------------------------------------  LD HL SP+Imm8(sign8) 2 Cycles:12
  4830.         Imm8_Read
  4831.         ;; ext sign
  4832.         movsx eax, al
  4833.         movzx ecx, word[YG_GP+lr35902.SP]
  4834.         and eax, 0xFFFF
  4835.         lea edx, [ecx+eax]
  4836.         mov [YG_GP+lr35902.HL], dx ;; write back HL
  4837.         xor ecx, eax
  4838.         xor ecx, edx
  4839.         and cx, 0x0110 ;; C|H
  4840.         mov YG_PF_8, ch
  4841.         shl YG_PF_8, 4
  4842.         shl cl, 1
  4843.         or YG_PF_8, cl
  4844.         and YG_PF, (H_FLAG| C_FLAG)
  4845.         SetCyclesRetP 12
  4846.       OP76:   ; Halt,  not backup PC in my source code ^_^
  4847.         mov dword [YG_GP+lr35902.halt], 1
  4848.         SetCyclesAndRet 4    
  4849.       OP10:   ; Stop, Check CGB speed mode
  4850.         movzx eax, byte [YG_GP+lr35902.key1]
  4851.         test eax, 1
  4852.         je Stop_Skip
  4853.         xor eax, 0x80 ;; switch to "other" speed
  4854.         and eax, 0xFE ;; reset LSB  see gb-programming-manual.pdf::2.6.2 CPU Operating Speed
  4855.                       ;; for simplicity, I will not simulate the huge waste of time brought by handover.
  4856.         mov [YG_GP+lr35902.key1], al
  4857.         add YG_PC, 1 ;; skip one byte (should is 00)      
  4858.         SetCyclesAndRet 0x80000004
  4859.      Stop_Skip:
  4860.         mov dword [YG_GP+lr35902.stop], 1
  4861.         add YG_PC, 1 ;; skip one byte (should is 00)    
  4862.         SetCyclesAndRet 4        
  4863.       OPF3:   ; DI
  4864.         mov byte [YG_GP+lr35902.IME], 0
  4865.         SetCyclesAndRet 4
  4866.       OPFB:   ; EI
  4867.         mov byte [YG_GP+lr35902.IME], 1
  4868.         SetCyclesAndRet 4  
  4869.       OP07:   ; RLCA
  4870.         rol byte [YG_GP+lr35902.A], 1
  4871.         setc YG_PF_8
  4872.         shl YG_PF_8, 4
  4873.         SetCyclesRetP 4
  4874.       OP17:   ; RLA
  4875.         shr YG_PF_8, 5
  4876.         rcl byte [YG_GP+lr35902.A], 1
  4877.         setc YG_PF_8
  4878.         shl YG_PF_8, 4
  4879.         SetCyclesRetP 4    
  4880.       OP0F:   ; RRCA
  4881.         ror byte [YG_GP+lr35902.A], 1
  4882.         setc YG_PF_8
  4883.         shl YG_PF_8, 4
  4884.         SetCyclesRetP 4
  4885.       OP1F:   ; RRA
  4886.         shr YG_PF_8, 5
  4887.         rcr byte [YG_GP+lr35902.A], 1
  4888.         setc YG_PF_8  
  4889.         shl YG_PF_8, 4
  4890.         SetCyclesRetP 4
  4891.       OP27:   ; BCD Adjust  
  4892.         movzx eax, byte [YG_GP+lr35902.A]
  4893.         test YG_PF_8, N_FLAG
  4894.         jne DAS_Proc
  4895.         ;;  DAA.
  4896.         ;;  Check DAA-low
  4897.         test YG_PF, H_FLAG
  4898.         jne DAA_Low
  4899.         mov ecx, eax
  4900.         and ecx, 0x0F
  4901.         cmp ecx, 9
  4902.         jbe DAA_LowSkip
  4903.         DAA_Low:
  4904.           add eax, 6
  4905.           DAA_LowSkip:
  4906.             ;; Check DAA-High
  4907.             test YG_PF, C_FLAG
  4908.             jne DAA_High
  4909.             mov ecx, eax  
  4910.             cmp ecx, 0x9F
  4911.             jbe DAA_HighSkip
  4912.             DAA_High:
  4913.               add eax, 0x60
  4914.               DAA_HighSkip:
  4915.                 ;; Check Z, C
  4916.                 and YG_PF, C_FLAG
  4917.                 mov ecx, eax
  4918.                 and ecx, 0x100
  4919.                 shl ecx, 4
  4920.                 or YG_PF_8, ch
  4921.                 test al, al
  4922.                 setz cl
  4923.                 shl cl, 7
  4924.                 or YG_PF_8, cl ;; z_flag done
  4925.                 mov [YG_GP+lr35902.A], al
  4926.                 SetCyclesRetP 4      
  4927.     DAS_Proc:
  4928.         ;;  DAS
  4929.         ;;  Check DAS-low
  4930.         test YG_PF, H_FLAG
  4931.         je DAS_LowSkip
  4932.         sub eax, 6
  4933.         and eax, 0xFF
  4934.           DAS_LowSkip:
  4935.             ;; Check DAS-High
  4936.             test YG_PF, C_FLAG
  4937.             je DAS_HighSkip
  4938.             sub eax, 0x60
  4939.               DAS_HighSkip:
  4940.                 ;; Check Z, C
  4941.                 and YG_PF, C_FLAG
  4942.                 mov ecx, eax
  4943.                 and ecx, 0x100
  4944.                 shl ecx, 4
  4945.                 or YG_PF_8, ch
  4946.                 test al, al
  4947.                 setz cl
  4948.                 shl cl, 7
  4949.                 or YG_PF_8, cl ;; z_flag done
  4950.                 or YG_PF_8, N_FLAG ;; n_flag done
  4951.                 mov [YG_GP+lr35902.A], al
  4952.                 SetCyclesRetP 4              
  4953.       OP37:   ; SCF
  4954.         and YG_PF, Z_FLAG
  4955.         or YG_PF, C_FLAG  
  4956.         SetCyclesRetP 4    
  4957.       OP2F:   ; CPL  
  4958.         not byte [YG_GP+lr35902.A]
  4959.         or YG_PF, N_FLAG
  4960.         or YG_PF, H_FLAG
  4961.         SetCyclesRetP 4  
  4962.       OP3F:   ; CCF
  4963.         and YG_PF, (Z_FLAG |C_FLAG)
  4964.         xor YG_PF, C_FLAG  
  4965.         SetCyclesRetP 4  
  4966.       OPE9:
  4967.         mov si, [YG_GP+lr35902.HL]
  4968.         SetCyclesAndRet 4    
  4969.       OPCB: ;; DD Perfix(BITS) for Z80/lr35902
  4970.         Imm8_Read
  4971.         and eax, 255
  4972.         jmp dword [CBTAB+eax*4]
  4973.         ;; --------------------------------------------------------------
  4974.         ;; --------------------------------------------------------------
  4975.         ;; --------------------------------------------------------------
  4976.         ;; --------------------------------------------------------------
  4977.         ;; --------------------------------------------------------------
  4978.         ;; Bit Opcode DOne
  4979.         ;; --------------------------------------------------------------
  4980.             lr35902@MainALUExt  CB00, 8, B_Read, RLC_, B_Write      ;; RLC B 2 Cycles:8
  4981.             lr35902@MainALUExt  CB01, 8, C_Read, RLC_, C_Write      ;; RLC C 2 Cycles:8
  4982.             lr35902@MainALUExt  CB02, 8, D_Read, RLC_, D_Write      ;; RLC D 2 Cycles:8
  4983.             lr35902@MainALUExt  CB03, 8, E_Read, RLC_, E_Write      ;; RLC E 2 Cycles:8    
  4984.             lr35902@MainALUExt  CB04, 8, H_Read, RLC_, H_Write      ;; RLC H 2 Cycles:8
  4985.             lr35902@MainALUExt  CB05, 8, L_Read, RLC_, L_Write      ;; RLC L 2 Cycles:8        
  4986.             lr35902@MainALUExt  CB06,16, xHL_Read, RLC_, xHL_Write      ;; RLC xHL 2 Cycles:16
  4987.             lr35902@MainALUExt  CB07, 8, A_Read, RLC_, A_Write      ;; RLC A 2 Cycles:8        
  4988.            
  4989.             lr35902@MainALUExt  CB08, 8, B_Read, RRC_, B_Write      ;; RRC B 2 Cycles:8
  4990.             lr35902@MainALUExt  CB09, 8, C_Read, RRC_, C_Write      ;; RRC C 2 Cycles:8
  4991.             lr35902@MainALUExt  CB0A, 8, D_Read, RRC_, D_Write      ;; RRC D 2 Cycles:8
  4992.             lr35902@MainALUExt  CB0B, 8, E_Read, RRC_, E_Write      ;; RRC E 2 Cycles:8    
  4993.             lr35902@MainALUExt  CB0C, 8, H_Read, RRC_, H_Write      ;; RRC H 2 Cycles:8
  4994.             lr35902@MainALUExt  CB0D, 8, L_Read, RRC_, L_Write      ;; RRC L 2 Cycles:8        
  4995.             lr35902@MainALUExt  CB0E,16, xHL_Read, RRC_, xHL_Write      ;; RRC xHL 2 Cycles:16
  4996.             lr35902@MainALUExt  CB0F, 8, A_Read, RRC_, A_Write      ;; RRC A 2 Cycles:8    
  4997.            
  4998.             lr35902@MainALUExt  CB10, 8, B_Read, RL_, B_Write      ;; RL B 2 Cycles:8
  4999.             lr35902@MainALUExt  CB11, 8, C_Read, RL_, C_Write      ;; RL C 2 Cycles:8
  5000.             lr35902@MainALUExt  CB12, 8, D_Read, RL_, D_Write      ;; RL D 2 Cycles:8
  5001.             lr35902@MainALUExt  CB13, 8, E_Read, RL_, E_Write      ;; RL E 2 Cycles:8    
  5002.             lr35902@MainALUExt  CB14, 8, H_Read, RL_, H_Write      ;; RL H 2 Cycles:8
  5003.             lr35902@MainALUExt  CB15, 8, L_Read, RL_, L_Write      ;; RL L 2 Cycles:8        
  5004.             lr35902@MainALUExt  CB16,16, xHL_Read, RL_, xHL_Write      ;; RL xHL 2 Cycles:16
  5005.             lr35902@MainALUExt  CB17, 8, A_Read, RL_, A_Write      ;; RL A 2 Cycles:8        
  5006.            
  5007.             lr35902@MainALUExt  CB18, 8, B_Read, RR_, B_Write      ;; RR B 2 Cycles:8
  5008.             lr35902@MainALUExt  CB19, 8, C_Read, RR_, C_Write      ;; RR C 2 Cycles:8
  5009.             lr35902@MainALUExt  CB1A, 8, D_Read, RR_, D_Write      ;; RR D 2 Cycles:8
  5010.             lr35902@MainALUExt  CB1B, 8, E_Read, RR_, E_Write      ;; RR E 2 Cycles:8    
  5011.             lr35902@MainALUExt  CB1C, 8, H_Read, RR_, H_Write      ;; RR H 2 Cycles:8
  5012.             lr35902@MainALUExt  CB1D, 8, L_Read, RR_, L_Write      ;; RR L 2 Cycles:8        
  5013.             lr35902@MainALUExt  CB1E,16, xHL_Read, RR_, xHL_Write      ;; RR xHL 2 Cycles:16
  5014.             lr35902@MainALUExt  CB1F, 8, A_Read, RR_, A_Write      ;; RR A 2 Cycles:8            
  5015.            
  5016.             lr35902@MainALUExt  CB20, 8, B_Read, RL_N_, B_Write      ;; SLA B 2 Cycles:8
  5017.             lr35902@MainALUExt  CB21, 8, C_Read, RL_N_, C_Write      ;; SLA C 2 Cycles:8
  5018.             lr35902@MainALUExt  CB22, 8, D_Read, RL_N_, D_Write      ;; SLA D 2 Cycles:8
  5019.             lr35902@MainALUExt  CB23, 8, E_Read, RL_N_, E_Write      ;; SLA E 2 Cycles:8    
  5020.             lr35902@MainALUExt  CB24, 8, H_Read, RL_N_, H_Write      ;; SLA H 2 Cycles:8
  5021.             lr35902@MainALUExt  CB25, 8, L_Read, RL_N_, L_Write      ;; SLA L 2 Cycles:8        
  5022.             lr35902@MainALUExt  CB26,16, xHL_Read, RL_N_, xHL_Write      ;; SLA xHL 2 Cycles:16
  5023.             lr35902@MainALUExt  CB27, 8, A_Read, RL_N_, A_Write      ;; SLA A 2 Cycles:8        
  5024.            
  5025.             lr35902@MainALUExt  CB28, 8, B_Read, RRS_N_, B_Write      ;; SRA B 2 Cycles:8
  5026.             lr35902@MainALUExt  CB29, 8, C_Read, RRS_N_, C_Write      ;; SRA C 2 Cycles:8
  5027.             lr35902@MainALUExt  CB2A, 8, D_Read, RRS_N_, D_Write      ;; SRA D 2 Cycles:8
  5028.             lr35902@MainALUExt  CB2B, 8, E_Read, RRS_N_, E_Write      ;; SRA E 2 Cycles:8    
  5029.             lr35902@MainALUExt  CB2C, 8, H_Read, RRS_N_, H_Write      ;; SRA H 2 Cycles:8
  5030.             lr35902@MainALUExt  CB2D, 8, L_Read, RRS_N_, L_Write      ;; SRA L 2 Cycles:8        
  5031.             lr35902@MainALUExt  CB2E,16, xHL_Read, RRS_N_, xHL_Write      ;; SRA xHL 2 Cycles:16
  5032.             lr35902@MainALUExt  CB2F, 8, A_Read, RRS_N_, A_Write      ;; SRA A 2 Cycles:8      
  5033.            
  5034.             lr35902@MainALUExt  CB30, 8, B_Read, SWAP_, B_Write      ;; SWAP B 2 Cycles:8
  5035.             lr35902@MainALUExt  CB31, 8, C_Read, SWAP_, C_Write      ;; SWAP C 2 Cycles:8
  5036.             lr35902@MainALUExt  CB32, 8, D_Read, SWAP_, D_Write      ;; SWAP D 2 Cycles:8
  5037.             lr35902@MainALUExt  CB33, 8, E_Read, SWAP_, E_Write      ;; SWAP E 2 Cycles:8    
  5038.             lr35902@MainALUExt  CB34, 8, H_Read, SWAP_, H_Write      ;; SWAP H 2 Cycles:8
  5039.             lr35902@MainALUExt  CB35, 8, L_Read, SWAP_, L_Write      ;; SWAP L 2 Cycles:8        
  5040.             lr35902@MainALUExt  CB36,16, xHL_Read, SWAP_, xHL_Write      ;; SWAP xHL 2 Cycles:16
  5041.             lr35902@MainALUExt  CB37, 8, A_Read, SWAP_, A_Write      ;; SWAP A 2 Cycles:8        
  5042.            
  5043.             lr35902@MainALUExt  CB38, 8, B_Read, RR_N_, B_Write      ;; SRL B 2 Cycles:8
  5044.             lr35902@MainALUExt  CB39, 8, C_Read, RR_N_, C_Write      ;; SRL C 2 Cycles:8
  5045.             lr35902@MainALUExt  CB3A, 8, D_Read, RR_N_, D_Write      ;; SRL D 2 Cycles:8
  5046.             lr35902@MainALUExt  CB3B, 8, E_Read, RR_N_, E_Write      ;; SRL E 2 Cycles:8    
  5047.             lr35902@MainALUExt  CB3C, 8, H_Read, RR_N_, H_Write      ;; SRL H 2 Cycles:8
  5048.             lr35902@MainALUExt  CB3D, 8, L_Read, RR_N_, L_Write      ;; SRL L 2 Cycles:8        
  5049.             lr35902@MainALUExt  CB3E,16, xHL_Read, RR_N_, xHL_Write      ;; SRL xHL 2 Cycles:16
  5050.             lr35902@MainALUExt  CB3F, 8, A_Read, RR_N_, A_Write      ;; SRL A 2 Cycles:8        
  5051.            
  5052.             lr35902@TestBit CB40, 8,  B_Read, 0 ;; BIT B, 0 Cycles:8
  5053.             lr35902@TestBit CB41, 8,  C_Read, 0 ;; BIT C, 0 Cycles:8        
  5054.             lr35902@TestBit CB42, 8,  D_Read, 0 ;; BIT D, 0 Cycles:8        
  5055.             lr35902@TestBit CB43, 8,  E_Read, 0 ;; BIT E, 0 Cycles:8    
  5056.             lr35902@TestBit CB44, 8,  H_Read, 0 ;; BIT H, 0 Cycles:8
  5057.             lr35902@TestBit CB45, 8,  L_Read, 0 ;; BIT L, 0 Cycles:8        
  5058.             lr35902@TestBit CB46,16,  xHL_Read, 0 ;; BIT xHL, 0 Cycles:16      
  5059.             lr35902@TestBit CB47, 8,  A_Read, 0 ;; BIT A, 0 Cycles:8        
  5060.          
  5061.             lr35902@TestBit CB48, 8,  B_Read, 1 ;; BIT B, 1 Cycles:8
  5062.             lr35902@TestBit CB49, 8,  C_Read, 1 ;; BIT C, 1 Cycles:8        
  5063.             lr35902@TestBit CB4A, 8,  D_Read, 1 ;; BIT D, 1 Cycles:8        
  5064.             lr35902@TestBit CB4B, 8,  E_Read, 1 ;; BIT E, 1 Cycles:8    
  5065.             lr35902@TestBit CB4C, 8,  H_Read, 1 ;; BIT H, 1 Cycles:8
  5066.             lr35902@TestBit CB4D, 8,  L_Read, 1 ;; BIT L, 1 Cycles:8        
  5067.             lr35902@TestBit CB4E,16,  xHL_Read, 1 ;; BIT xHL, 1 Cycles:16      
  5068.             lr35902@TestBit CB4F, 8,  A_Read, 1 ;; BIT A, 1 Cycles:8
  5069.  
  5070.             lr35902@TestBit CB50, 8,  B_Read, 2 ;; BIT B, 2 Cycles:8
  5071.             lr35902@TestBit CB51, 8,  C_Read, 2 ;; BIT C, 2 Cycles:8        
  5072.             lr35902@TestBit CB52, 8,  D_Read, 2 ;; BIT D, 2 Cycles:8        
  5073.             lr35902@TestBit CB53, 8,  E_Read, 2 ;; BIT E, 2 Cycles:8    
  5074.             lr35902@TestBit CB54, 8,  H_Read, 2 ;; BIT H, 2 Cycles:8
  5075.             lr35902@TestBit CB55, 8,  L_Read, 2 ;; BIT L, 2 Cycles:8        
  5076.             lr35902@TestBit CB56,16,  xHL_Read, 2 ;; BIT xHL, 2 Cycles:16      
  5077.             lr35902@TestBit CB57, 8,  A_Read, 2 ;; BIT A, 2 Cycles:8        
  5078.          
  5079.             lr35902@TestBit CB58, 8,  B_Read, 3 ;; BIT B, 3 Cycles:8
  5080.             lr35902@TestBit CB59, 8,  C_Read, 3 ;; BIT C, 3 Cycles:8        
  5081.             lr35902@TestBit CB5A, 8,  D_Read, 3 ;; BIT D, 3 Cycles:8        
  5082.             lr35902@TestBit CB5B, 8,  E_Read, 3 ;; BIT E, 3 Cycles:8    
  5083.             lr35902@TestBit CB5C, 8,  H_Read, 3 ;; BIT H, 3 Cycles:8
  5084.             lr35902@TestBit CB5D, 8,  L_Read, 3 ;; BIT L, 3 Cycles:8        
  5085.             lr35902@TestBit CB5E,16,  xHL_Read, 3 ;; BIT xHL, 3 Cycles:16      
  5086.             lr35902@TestBit CB5F, 8,  A_Read, 3 ;; BIT A, 3 Cycles:8
  5087.  
  5088.             lr35902@TestBit CB60, 8,  B_Read, 4 ;; BIT B, 4 Cycles:8
  5089.             lr35902@TestBit CB61, 8,  C_Read, 4 ;; BIT C, 4 Cycles:8        
  5090.             lr35902@TestBit CB62, 8,  D_Read, 4 ;; BIT D, 4 Cycles:8        
  5091.             lr35902@TestBit CB63, 8,  E_Read, 4 ;; BIT E, 4 Cycles:8    
  5092.             lr35902@TestBit CB64, 8,  H_Read, 4 ;; BIT H, 4 Cycles:8
  5093.             lr35902@TestBit CB65, 8,  L_Read, 4 ;; BIT L, 4 Cycles:8        
  5094.             lr35902@TestBit CB66,16,  xHL_Read, 4 ;; BITxHLD, 4 Cycles:16      
  5095.             lr35902@TestBit CB67, 8,  A_Read, 4 ;; BIT A, 4 Cycles:8        
  5096.          
  5097.             lr35902@TestBit CB68, 8,  B_Read, 5 ;; BIT B, 5 Cycles:8
  5098.             lr35902@TestBit CB69, 8,  C_Read, 5 ;; BIT C, 5 Cycles:8        
  5099.             lr35902@TestBit CB6A, 8,  D_Read, 5 ;; BIT D, 5 Cycles:8        
  5100.             lr35902@TestBit CB6B, 8,  E_Read, 5 ;; BIT E, 5 Cycles:8    
  5101.             lr35902@TestBit CB6C, 8,  H_Read, 5 ;; BIT H, 5 Cycles:8
  5102.             lr35902@TestBit CB6D, 8,  L_Read, 5 ;; BIT L, 5 Cycles:8        
  5103.             lr35902@TestBit CB6E,16,  xHL_Read, 5 ;; BIT xHL, 5 Cycles:16      
  5104.             lr35902@TestBit CB6F, 8,  A_Read, 5 ;; BIT A, 5 Cycles:8
  5105.            
  5106.             lr35902@TestBit CB70, 8,  B_Read, 6 ;; BIT B, 6 Cycles:8
  5107.             lr35902@TestBit CB71, 8,  C_Read, 6 ;; BIT C, 6 Cycles:8        
  5108.             lr35902@TestBit CB72, 8,  D_Read, 6 ;; BIT D, 6 Cycles:8        
  5109.             lr35902@TestBit CB73, 8,  E_Read, 6 ;; BIT E, 6 Cycles:8    
  5110.             lr35902@TestBit CB74, 8,  H_Read, 6 ;; BIT H, 6 Cycles:8
  5111.             lr35902@TestBit CB75, 8,  L_Read, 6 ;; BIT L, 6 Cycles:8        
  5112.             lr35902@TestBit CB76,16,  xHL_Read, 6 ;; BIT xHL, 6 Cycles:16      
  5113.             lr35902@TestBit CB77, 8,  A_Read, 6 ;; BIT A, 6 Cycles:8        
  5114.          
  5115.             lr35902@TestBit CB78, 8,  B_Read, 7 ;; BIT B, 7 Cycles:8
  5116.             lr35902@TestBit CB79, 8,  C_Read, 7 ;; BIT C, 7 Cycles:8        
  5117.             lr35902@TestBit CB7A, 8,  D_Read, 7 ;; BIT D, 7 Cycles:8        
  5118.             lr35902@TestBit CB7B, 8,  E_Read, 7 ;; BIT E, 7 Cycles:8    
  5119.             lr35902@TestBit CB7C, 8,  H_Read, 7 ;; BIT H, 7 Cycles:8
  5120.             lr35902@TestBit CB7D, 8,  L_Read, 7 ;; BIT L, 7 Cycles:8        
  5121.             lr35902@TestBit CB7E,16,  xHL_Read, 7 ;; BIT xHL, 7 Cycles:16      
  5122.             lr35902@TestBit CB7F, 8,  A_Read, 7 ;; BIT A, 7 Cycles:8
  5123.            
  5124.             lr35902@ResBit CB80, 8,  B_Read, 0, B_Write ;; RES B, 0 Cycles:8
  5125.             lr35902@ResBit CB81, 8,  C_Read, 0, C_Write ;; RES C, 0 Cycles:8        
  5126.             lr35902@ResBit CB82, 8,  D_Read, 0, D_Write ;; RES D, 0 Cycles:8        
  5127.             lr35902@ResBit CB83, 8,  E_Read, 0, E_Write ;; RES E, 0 Cycles:8    
  5128.             lr35902@ResBit CB84, 8,  H_Read, 0, H_Write ;; RES H, 0 Cycles:8
  5129.             lr35902@ResBit CB85, 8,  L_Read, 0, L_Write ;; RES L, 0 Cycles:8        
  5130.             lr35902@ResBit CB86,16,  xHL_Read, 0, xHL_Write ;; RES xHL, 0 Cycles:16      
  5131.             lr35902@ResBit CB87, 8,  A_Read, 0, A_Write ;; RES A, 0 Cycles:8        
  5132.          
  5133.             lr35902@ResBit CB88, 8,  B_Read, 1, B_Write ;; RES B, 1 Cycles:8
  5134.             lr35902@ResBit CB89, 8,  C_Read, 1, C_Write ;; RES C, 1 Cycles:8        
  5135.             lr35902@ResBit CB8A, 8,  D_Read, 1, D_Write ;; RES D, 1 Cycles:8        
  5136.             lr35902@ResBit CB8B, 8,  E_Read, 1, E_Write ;; RES E, 1 Cycles:8    
  5137.             lr35902@ResBit CB8C, 8,  H_Read, 1, H_Write ;; RES H, 1 Cycles:8
  5138.             lr35902@ResBit CB8D, 8,  L_Read, 1, L_Write ;; RES L, 1 Cycles:8        
  5139.             lr35902@ResBit CB8E,16,  xHL_Read, 1, xHL_Write ;; RES xHL, 1 Cycles:16      
  5140.             lr35902@ResBit CB8F, 8,  A_Read, 1, A_Write ;; RES A, 1 Cycles:8
  5141.  
  5142.             lr35902@ResBit CB90, 8,  B_Read, 2, B_Write ;; RES B, 2 Cycles:8
  5143.             lr35902@ResBit CB91, 8,  C_Read, 2, C_Write ;; RES C, 2 Cycles:8        
  5144.             lr35902@ResBit CB92, 8,  D_Read, 2, D_Write ;; RES D, 2 Cycles:8        
  5145.             lr35902@ResBit CB93, 8,  E_Read, 2, E_Write ;; RES E, 2 Cycles:8    
  5146.             lr35902@ResBit CB94, 8,  H_Read, 2, H_Write ;; RES H, 2 Cycles:8
  5147.             lr35902@ResBit CB95, 8,  L_Read, 2, L_Write ;; RES L, 2 Cycles:8        
  5148.             lr35902@ResBit CB96,16,  xHL_Read, 2, xHL_Write ;; RES xHL, 2 Cycles:16      
  5149.             lr35902@ResBit CB97, 8,  A_Read, 2, A_Write ;; RES A, 2 Cycles:8        
  5150.          
  5151.             lr35902@ResBit CB98, 8,  B_Read, 3, B_Write ;; RES B, 3 Cycles:8
  5152.             lr35902@ResBit CB99, 8,  C_Read, 3, C_Write ;; RES C, 3 Cycles:8        
  5153.             lr35902@ResBit CB9A, 8,  D_Read, 3, D_Write ;; RES D, 3 Cycles:8        
  5154.             lr35902@ResBit CB9B, 8,  E_Read, 3, E_Write ;; RES E, 3 Cycles:8    
  5155.             lr35902@ResBit CB9C, 8,  H_Read, 3, H_Write ;; RES H, 3 Cycles:8
  5156.             lr35902@ResBit CB9D, 8,  L_Read, 3, L_Write ;; RES L, 3 Cycles:8        
  5157.             lr35902@ResBit CB9E,16,  xHL_Read, 3, xHL_Write ;; RES xHL, 3 Cycles:16      
  5158.             lr35902@ResBit CB9F, 8,  A_Read, 3, A_Write ;; RES A, 3 Cycles:8
  5159.  
  5160.             lr35902@ResBit CBA0, 8,  B_Read, 4, B_Write ;; RES B, 4 Cycles:8
  5161.             lr35902@ResBit CBA1, 8,  C_Read, 4, C_Write ;; RES C, 4 Cycles:8        
  5162.             lr35902@ResBit CBA2, 8,  D_Read, 4, D_Write ;; RES D, 4 Cycles:8        
  5163.             lr35902@ResBit CBA3, 8,  E_Read, 4, E_Write ;; RES E, 4 Cycles:8    
  5164.             lr35902@ResBit CBA4, 8,  H_Read, 4, H_Write ;; RES H, 4 Cycles:8
  5165.             lr35902@ResBit CBA5, 8,  L_Read, 4, L_Write ;; RES L, 4 Cycles:8        
  5166.             lr35902@ResBit CBA6,16,  xHL_Read, 4, xHL_Write ;; RES xHL, 4 Cycles:16      
  5167.             lr35902@ResBit CBA7, 8,  A_Read, 4, A_Write ;; RES A, 4 Cycles:8        
  5168.          
  5169.             lr35902@ResBit CBA8, 8,  B_Read, 5, B_Write ;; RES B, 5 Cycles:8
  5170.             lr35902@ResBit CBA9, 8,  C_Read, 5, C_Write ;; RES C, 5 Cycles:8        
  5171.             lr35902@ResBit CBAA, 8,  D_Read, 5, D_Write ;; RES D, 5 Cycles:8        
  5172.             lr35902@ResBit CBAB, 8,  E_Read, 5, E_Write ;; RES E, 5 Cycles:8    
  5173.             lr35902@ResBit CBAC, 8,  H_Read, 5, H_Write ;; RES H, 5 Cycles:8
  5174.             lr35902@ResBit CBAD, 8,  L_Read, 5, L_Write ;; RES L, 5 Cycles:8        
  5175.             lr35902@ResBit CBAE,16,  xHL_Read, 5, xHL_Write ;; RES xHL, 5 Cycles:16      
  5176.             lr35902@ResBit CBAF, 8,  A_Read, 5, A_Write ;; RES A, 5 Cycles:8
  5177.            
  5178.             lr35902@ResBit CBB0, 8,  B_Read, 6, B_Write ;; RES B, 6 Cycles:8
  5179.             lr35902@ResBit CBB1, 8,  C_Read, 6, C_Write ;; RES C, 6 Cycles:8        
  5180.             lr35902@ResBit CBB2, 8,  D_Read, 6, D_Write ;; RES D, 6 Cycles:8        
  5181.             lr35902@ResBit CBB3, 8,  E_Read, 6, E_Write ;; RES E, 6 Cycles:8    
  5182.             lr35902@ResBit CBB4, 8,  H_Read, 6, H_Write ;; RES H, 6 Cycles:8
  5183.             lr35902@ResBit CBB5, 8,  L_Read, 6, L_Write ;; RES L, 6 Cycles:8        
  5184.             lr35902@ResBit CBB6,16,  xHL_Read, 6, xHL_Write ;; RES xHL, 6 Cycles:16      
  5185.             lr35902@ResBit CBB7, 8,  A_Read, 6, A_Write ;; RES A, 6 Cycles:8        
  5186.          
  5187.             lr35902@ResBit CBB8, 8,  B_Read, 7, B_Write ;; RES B, 7 Cycles:8
  5188.             lr35902@ResBit CBB9, 8,  C_Read, 7, C_Write ;; RES C, 7 Cycles:8        
  5189.             lr35902@ResBit CBBA, 8,  D_Read, 7, D_Write ;; RES D, 7 Cycles:8        
  5190.             lr35902@ResBit CBBB, 8,  E_Read, 7, E_Write ;; RES E, 7 Cycles:8    
  5191.             lr35902@ResBit CBBC, 8,  H_Read, 7, H_Write ;; RES H, 7 Cycles:8
  5192.             lr35902@ResBit CBBD, 8,  L_Read, 7, L_Write ;; RES L, 7 Cycles:8        
  5193.             lr35902@ResBit CBBE,16,  xHL_Read, 7, xHL_Write ;; RES xHL, 7 Cycles:16      
  5194.             lr35902@ResBit CBBF, 8,  A_Read, 7, A_Write ;; RES A, 7 Cycles:8
  5195.  
  5196.             lr35902@SetBit CBC0, 8,  B_Read, 0, B_Write ;; SET B, 0 Cycles:8
  5197.             lr35902@SetBit CBC1, 8,  C_Read, 0, C_Write ;; SET C, 0 Cycles:8        
  5198.             lr35902@SetBit CBC2, 8,  D_Read, 0, D_Write ;; SET D, 0 Cycles:8        
  5199.             lr35902@SetBit CBC3, 8,  E_Read, 0, E_Write ;; SET E, 0 Cycles:8    
  5200.             lr35902@SetBit CBC4, 8,  H_Read, 0, H_Write ;; SET H, 0 Cycles:8
  5201.             lr35902@SetBit CBC5, 8,  L_Read, 0, L_Write ;; SET L, 0 Cycles:8        
  5202.             lr35902@SetBit CBC6,16,  xHL_Read, 0, xHL_Write ;; SET xHL, 0 Cycles:16      
  5203.             lr35902@SetBit CBC7, 8,  A_Read, 0, A_Write ;; SET A, 0 Cycles:8        
  5204.          
  5205.             lr35902@SetBit CBC8, 8,  B_Read, 1, B_Write ;; SET B, 1 Cycles:8
  5206.             lr35902@SetBit CBC9, 8,  C_Read, 1, C_Write ;; SET C, 1 Cycles:8        
  5207.             lr35902@SetBit CBCA, 8,  D_Read, 1, D_Write ;; SET D, 1 Cycles:8        
  5208.             lr35902@SetBit CBCB, 8,  E_Read, 1, E_Write ;; SET E, 1 Cycles:8    
  5209.             lr35902@SetBit CBCC, 8,  H_Read, 1, H_Write ;; SET H, 1 Cycles:8
  5210.             lr35902@SetBit CBCD, 8,  L_Read, 1, L_Write ;; SET L, 1 Cycles:8        
  5211.             lr35902@SetBit CBCE,16,  xHL_Read, 1, xHL_Write ;; SET xHL, 1 Cycles:16      
  5212.             lr35902@SetBit CBCF, 8,  A_Read, 1, A_Write ;; SET A, 1 Cycles:8
  5213.  
  5214.             lr35902@SetBit CBD0, 8,  B_Read, 2, B_Write ;; SET B, 2 Cycles:8
  5215.             lr35902@SetBit CBD1, 8,  C_Read, 2, C_Write ;; SET C, 2 Cycles:8        
  5216.             lr35902@SetBit CBD2, 8,  D_Read, 2, D_Write ;; SET D, 2 Cycles:8        
  5217.             lr35902@SetBit CBD3, 8,  E_Read, 2, E_Write ;; SET E, 2 Cycles:8    
  5218.             lr35902@SetBit CBD4, 8,  H_Read, 2, H_Write ;; SET H, 2 Cycles:8
  5219.             lr35902@SetBit CBD5, 8,  L_Read, 2, L_Write ;; SET L, 2 Cycles:8        
  5220.             lr35902@SetBit CBD6,16,  xHL_Read, 2, xHL_Write ;; SET xHL, 2 Cycles:16      
  5221.             lr35902@SetBit CBD7, 8,  A_Read, 2, A_Write ;; SET A, 2 Cycles:8        
  5222.          
  5223.             lr35902@SetBit CBD8, 8,  B_Read, 3, B_Write ;; SET B, 3 Cycles:8
  5224.             lr35902@SetBit CBD9, 8,  C_Read, 3, C_Write ;; SET C, 3 Cycles:8        
  5225.             lr35902@SetBit CBDA, 8,  D_Read, 3, D_Write ;; SET D, 3 Cycles:8        
  5226.             lr35902@SetBit CBDB, 8,  E_Read, 3, E_Write ;; SET E, 3 Cycles:8    
  5227.             lr35902@SetBit CBDC, 8,  H_Read, 3, H_Write ;; SET H, 3 Cycles:8
  5228.             lr35902@SetBit CBDD, 8,  L_Read, 3, L_Write ;; SET L, 3 Cycles:8        
  5229.             lr35902@SetBit CBDE,16,  xHL_Read, 3, xHL_Write ;; SET xHL, 3 Cycles:16      
  5230.             lr35902@SetBit CBDF, 8,  A_Read, 3, A_Write ;; SET A, 3 Cycles:8
  5231.  
  5232.             lr35902@SetBit CBE0, 8,  B_Read, 4, B_Write ;; SET B, 4 Cycles:8
  5233.             lr35902@SetBit CBE1, 8,  C_Read, 4, C_Write ;; SET C, 4 Cycles:8        
  5234.             lr35902@SetBit CBE2, 8,  D_Read, 4, D_Write ;; SET D, 4 Cycles:8        
  5235.             lr35902@SetBit CBE3, 8,  E_Read, 4, E_Write ;; SET E, 4 Cycles:8    
  5236.             lr35902@SetBit CBE4, 8,  H_Read, 4, H_Write ;; SET H, 4 Cycles:8
  5237.             lr35902@SetBit CBE5, 8,  L_Read, 4, L_Write ;; SET L, 4 Cycles:8        
  5238.             lr35902@SetBit CBE6,16,  xHL_Read, 4, xHL_Write ;; SET xHL, 4 Cycles:16      
  5239.             lr35902@SetBit CBE7, 8,  A_Read, 4, A_Write ;; SET A, 4 Cycles:8        
  5240.          
  5241.             lr35902@SetBit CBE8, 8,  B_Read, 5, B_Write ;; SET B, 5 Cycles:8
  5242.             lr35902@SetBit CBE9, 8,  C_Read, 5, C_Write ;; SET C, 5 Cycles:8        
  5243.             lr35902@SetBit CBEA, 8,  D_Read, 5, D_Write ;; SET D, 5 Cycles:8        
  5244.             lr35902@SetBit CBEB, 8,  E_Read, 5, E_Write ;; SET E, 5 Cycles:8    
  5245.             lr35902@SetBit CBEC, 8,  H_Read, 5, H_Write ;; SET H, 5 Cycles:8
  5246.             lr35902@SetBit CBED, 8,  L_Read, 5, L_Write ;; SET L, 5 Cycles:8        
  5247.             lr35902@SetBit CBEE,16,  xHL_Read, 5, xHL_Write ;; SET xHL, 5 Cycles:16      
  5248.             lr35902@SetBit CBEF, 8,  A_Read, 5, A_Write ;; SET A, 5 Cycles:8
  5249.            
  5250.             lr35902@SetBit CBF0, 8,  B_Read, 6, B_Write ;; SET B, 6 Cycles:8
  5251.             lr35902@SetBit CBF1, 8,  C_Read, 6, C_Write ;; SET C, 6 Cycles:8        
  5252.             lr35902@SetBit CBF2, 8,  D_Read, 6, D_Write ;; SET D, 6 Cycles:8        
  5253.             lr35902@SetBit CBF3, 8,  E_Read, 6, E_Write ;; SET E, 6 Cycles:8    
  5254.             lr35902@SetBit CBF4, 8,  H_Read, 6, H_Write ;; SET H, 6 Cycles:8
  5255.             lr35902@SetBit CBF5, 8,  L_Read, 6, L_Write ;; SET L, 6 Cycles:8        
  5256.             lr35902@SetBit CBF6,16,  xHL_Read, 6, xHL_Write ;; SET xHL, 6 Cycles:16      
  5257.             lr35902@SetBit CBF7, 8,  A_Read, 6, A_Write ;; SET A, 6 Cycles:8        
  5258.          
  5259.             lr35902@SetBit CBF8, 8,  B_Read, 7, B_Write ;; SET B, 7 Cycles:8
  5260.             lr35902@SetBit CBF9, 8,  C_Read, 7, C_Write ;; SET C, 7 Cycles:8        
  5261.             lr35902@SetBit CBFA, 8,  D_Read, 7, D_Write ;; SET D, 7 Cycles:8        
  5262.             lr35902@SetBit CBFB, 8,  E_Read, 7, E_Write ;; SET E, 7 Cycles:8    
  5263.             lr35902@SetBit CBFC, 8,  H_Read, 7, H_Write ;; SET H, 7 Cycles:8
  5264.             lr35902@SetBit CBFD, 8,  L_Read, 7, L_Write ;; SET L, 7 Cycles:8        
  5265.             lr35902@SetBit CBFE,16,  xHL_Read, 7, xHL_Write ;; SET xHL, 7 Cycles:16      
  5266.             lr35902@SetBit CBFF, 8,  A_Read, 7, A_Write ;; SET A, 7 Cycles:8    
  5267.        
  5268.         ;; --------------------------------------------------------------
  5269.         ;; --------------------------------------------------------------
  5270.         ;; --------------------------------------------------------------
  5271.         ;; --------------------------------------------------------------
  5272.         ;; --------------------------------------------------------------
  5273.         ;; Ub Code for lr35902
  5274.         ;; --------------------------------------------------------------
  5275.        
  5276.       OPDD: ;; DD Perfix(IX) for Z80
  5277.       OPFD: ;; FD Perfix(IY) for Z80
  5278.       OPED: ;; ED Perfix(EXTD) for Z80    
  5279.       OPD3: ;; out (*),a for Z80
  5280.       OPDB: ;; in a,(*) for Z80
  5281.       OPE3: ;; ex (sp),hl for Z80
  5282.       OPE4: ;; call po,** for Z80
  5283.       OPEB: ;; ex de,hl for Z80
  5284.       OPEC: ;; call pe,** for Z80
  5285.       OPF4: ;; call p,** for Z80
  5286.       OPFC: ;; call m,** for Z80
  5287.         int 3
  5288.       OP00: ;; NOP
  5289.         mov [YG_GP+lr35902.PC], si
  5290.         mov eax, 4
  5291. V_EXIT:
  5292.         mov dword [YG_GP+lr35902._backup], 0
  5293.         pop esi
  5294.         pop edi
  5295.         pop ebx
  5296.         ret
  5297.        
  5298.        
  5299.         align 16      
  5300. OPTAB   dd  OP00, OP01, OP02, OP03, OP04, OP05, OP06, OP07, OP08, OP09, OP0A, OP0B, OP0C, OP0D, OP0E, OP0F,\
  5301.             OP10, OP11, OP12, OP13, OP14, OP15, OP16, OP17, OP18, OP19, OP1A, OP1B, OP1C, OP1D, OP1E, OP1F,\
  5302.             OP20, OP21, OP22, OP23, OP24, OP25, OP26, OP27, OP28, OP29, OP2A, OP2B, OP2C, OP2D, OP2E, OP2F,\
  5303.             OP30, OP31, OP32, OP33, OP34, OP35, OP36, OP37, OP38, OP39, OP3A, OP3B, OP3C, OP3D, OP3E, OP3F,\
  5304.             OP40, OP41, OP42, OP43, OP44, OP45, OP46, OP47, OP48, OP49, OP4A, OP4B, OP4C, OP4D, OP4E, OP4F,\
  5305.             OP50, OP51, OP52, OP53, OP54, OP55, OP56, OP57, OP58, OP59, OP5A, OP5B, OP5C, OP5D, OP5E, OP5F,\
  5306.             OP60, OP61, OP62, OP63, OP64, OP65, OP66, OP67, OP68, OP69, OP6A, OP6B, OP6C, OP6D, OP6E, OP6F,\
  5307.             OP70, OP71, OP72, OP73, OP74, OP75, OP76, OP77, OP78, OP79, OP7A, OP7B, OP7C, OP7D, OP7E, OP7F,\
  5308.             OP80, OP81, OP82, OP83, OP84, OP85, OP86, OP87, OP88, OP89, OP8A, OP8B, OP8C, OP8D, OP8E, OP8F,\
  5309.             OP90, OP91, OP92, OP93, OP94, OP95, OP96, OP97, OP98, OP99, OP9A, OP9B, OP9C, OP9D, OP9E, OP9F,\
  5310.             OPA0, OPA1, OPA2, OPA3, OPA4, OPA5, OPA6, OPA7, OPA8, OPA9, OPAA, OPAB, OPAC, OPAD, OPAE, OPAF,\
  5311.             OPB0, OPB1, OPB2, OPB3, OPB4, OPB5, OPB6, OPB7, OPB8, OPB9, OPBA, OPBB, OPBC, OPBD, OPBE, OPBF,\
  5312.             OPC0, OPC1, OPC2, OPC3, OPC4, OPC5, OPC6, OPC7, OPC8, OPC9, OPCA, OPCB, OPCC, OPCD, OPCE, OPCF,\
  5313.             OPD0, OPD1, OPD2, OPD3, OPD4, OPD5, OPD6, OPD7, OPD8, OPD9, OPDA, OPDB, OPDC, OPDD, OPDE, OPDF,\
  5314.             OPE0, OPE1, OPE2, OPE3, OPE4, OPE5, OPE6, OPE7, OPE8, OPE9, OPEA, OPEB, OPEC, OPED, OPEE, OPEF,\
  5315.             OPF0, OPF1, OPF2, OPF3, OPF4, OPF5, OPF6, OPF7, OPF8, OPF9, OPFA, OPFB, OPFC, OPFD, OPFE, OPFF
  5316. CBTAB   dd  CB00, CB01, CB02, CB03, CB04, CB05, CB06, CB07, CB08, CB09, CB0A, CB0B, CB0C, CB0D, CB0E, CB0F,\
  5317.             CB10, CB11, CB12, CB13, CB14, CB15, CB16, CB17, CB18, CB19, CB1A, CB1B, CB1C, CB1D, CB1E, CB1F,\
  5318.             CB20, CB21, CB22, CB23, CB24, CB25, CB26, CB27, CB28, CB29, CB2A, CB2B, CB2C, CB2D, CB2E, CB2F,\
  5319.             CB30, CB31, CB32, CB33, CB34, CB35, CB36, CB37, CB38, CB39, CB3A, CB3B, CB3C, CB3D, CB3E, CB3F,\
  5320.             CB40, CB41, CB42, CB43, CB44, CB45, CB46, CB47, CB48, CB49, CB4A, CB4B, CB4C, CB4D, CB4E, CB4F,\
  5321.             CB50, CB51, CB52, CB53, CB54, CB55, CB56, CB57, CB58, CB59, CB5A, CB5B, CB5C, CB5D, CB5E, CB5F,\
  5322.             CB60, CB61, CB62, CB63, CB64, CB65, CB66, CB67, CB68, CB69, CB6A, CB6B, CB6C, CB6D, CB6E, CB6F,\
  5323.             CB70, CB71, CB72, CB73, CB74, CB75, CB76, CB77, CB78, CB79, CB7A, CB7B, CB7C, CB7D, CB7E, CB7F,\
  5324.             CB80, CB81, CB82, CB83, CB84, CB85, CB86, CB87, CB88, CB89, CB8A, CB8B, CB8C, CB8D, CB8E, CB8F,\
  5325.             CB90, CB91, CB92, CB93, CB94, CB95, CB96, CB97, CB98, CB99, CB9A, CB9B, CB9C, CB9D, CB9E, CB9F,\
  5326.             CBA0, CBA1, CBA2, CBA3, CBA4, CBA5, CBA6, CBA7, CBA8, CBA9, CBAA, CBAB, CBAC, CBAD, CBAE, CBAF,\
  5327.             CBB0, CBB1, CBB2, CBB3, CBB4, CBB5, CBB6, CBB7, CBB8, CBB9, CBBA, CBBB, CBBC, CBBD, CBBE, CBBF,\
  5328.             CBC0, CBC1, CBC2, CBC3, CBC4, CBC5, CBC6, CBC7, CBC8, CBC9, CBCA, CBCB, CBCC, CBCD, CBCE, CBCF,\
  5329.             CBD0, CBD1, CBD2, CBD3, CBD4, CBD5, CBD6, CBD7, CBD8, CBD9, CBDA, CBDB, CBDC, CBDD, CBDE, CBDF,\
  5330.             CBE0, CBE1, CBE2, CBE3, CBE4, CBE5, CBE6, CBE7, CBE8, CBE9, CBEA, CBEB, CBEC, CBED, CBEE, CBEF,\
  5331.             CBF0, CBF1, CBF2, CBF3, CBF4, CBF5, CBF6, CBF7, CBF8, CBF9, CBFA, CBFB, CBFC, CBFD, CBFE, CBFF
  5332. /* nintendo gameboy
  5333.  * https://en.wikipedia.org/wiki/Game_Boy
  5334.  *
  5335.  * Copyright (C) 2018 moecmks
  5336.  * This file is part of KS3578.
  5337.  *
  5338.  * do What The Fuck you want to Public License
  5339.  *
  5340.  * Version 1.0, March 2000
  5341.  * Copyright (C) 2000 Banlu Kemiyatorn (]d).
  5342.  * 136 Nives 7 Jangwattana 14 Laksi Bangkok
  5343.  * Everyone is permitted to copy and distribute verbatim copies
  5344.  * of this license document, but changing it is not allowed.
  5345.  *
  5346.  * Ok, the purpose of this license is simple
  5347.  * and you just
  5348.  *
  5349.  * DO WHAT THE FUCK YOU WANT TO.
  5350.  */
  5351.  
  5352. #include "gameboy.h"
  5353. #include "internal.h"
  5354.  
  5355. void controller_setupdate_ (struct controller *ctl, void (*update)
  5356.             (struct controller *,
  5357.             void *,
  5358.               struct controller_pad *, /* self */
  5359.             struct controller_pad * /* host edge */), void *obj);
  5360. void ppu_setupdate_ (struct ppu *ppu, void (*update)
  5361.             (struct ppu *,
  5362.             void *,
  5363.               struct ppu_framebuffer *), void *obj);
  5364.  
  5365. static
  5366. void controller_hostdrv_s (struct gameboy *gb, void *controller_drvobj,
  5367.                          struct controller_pad *gb_pad, /* gb-self for recv joypadbuffer */
  5368.                          struct controller_pad *hostedge /* host-edge 1?pulse gen:nodone */)
  5369. {
  5370.   printf ("%s:%s please set controller_hostdrv\n", __FILE__, __LINE__);
  5371.   assert (0);
  5372. }
  5373.  
  5374. static
  5375. void display_hostdrv_s (struct gameboy *gb,
  5376.                       void *display_drvobj,
  5377.                       struct ppu_framebuffer *fmebuf)
  5378. {
  5379.   printf ("%s:%s please set display_hostdrv\n", __FILE__, __LINE__);
  5380.   assert (0);
  5381. }
  5382.  
  5383. static
  5384. void controller_hostdrv_route (struct controller *ctl, void *obj, struct controller_pad *gb_infos, struct controller_pad *host_infos) {
  5385.   ctl->gb->controller_hostdrv (ctl->gb, obj, gb_infos, host_infos);
  5386. }
  5387. static
  5388. void lcdvideo_hostdrv_route (struct ppu *ppu, void *obj, struct ppu_framebuffer *fbuf) {
  5389.   ppu->gb->display_hostdrv (ppu->gb, obj, fbuf);
  5390. }
  5391.  
  5392. void gameboy_controller_setupdate (struct gameboy *gb, void (*controller_hostdrv)
  5393.              (struct gameboy *,
  5394.              void *,
  5395.                 struct controller_pad *, /* gb-self for recv joypadbuffer */
  5396.              struct controller_pad * /* host-edge */), void *obj)
  5397. {
  5398.   gb->controller_hostdrv = controller_hostdrv;
  5399.   gb->controller_drvobj = obj;
  5400.  
  5401.   controller_setupdate_ (gb->joypad, controller_hostdrv_route, obj);
  5402. }
  5403.  
  5404. void gameboy_lcdvideo_setupdate (struct gameboy *gb, void (*lcdvideo_hostdrv)
  5405.              (struct gameboy *,
  5406.               void *,
  5407.               struct ppu_framebuffer *), void *obj)
  5408. {
  5409.   gb->display_hostdrv = lcdvideo_hostdrv;
  5410.   gb->display_drvobj = obj;
  5411.  
  5412.   ppu_setupdate_ (gb->lh5028, lcdvideo_hostdrv_route, obj);
  5413. }
  5414.  
  5415. extern
  5416. ks_int ks_callc
  5417. cpu_optick (struct cpu *cpu_);
  5418.  
  5419. ks_finline
  5420. ks_void
  5421. internaldev_clks (struct gameboy *gb, ks_double clks) {
  5422.   /* update internal device divider */
  5423.   gb->cpu_clks_total += clks;
  5424.   gb->cpu_clks_divider += clks;
  5425.   gb->cpu_clks_ppu += clks;
  5426.   gb->cpu_clks_timer += clks;
  5427.   gb->cpu_clks_joypad += clks;
  5428.   gb->cpu_clks_apu += clks;
  5429.   gb->cpu_clks_cart += clks;
  5430.   gb->cpu_clks_serial += clks;
  5431.   /* update device */
  5432.   gb->divider->clks (gb->divider);
  5433.   gb->lh5028->clks (gb->lh5028);
  5434.   gb->timer->clks (gb->timer);
  5435.   gb->joypad->clks (gb->joypad);
  5436.   gb->apu->clks (gb->apu);
  5437.   gb->cart->clks (gb->cart);
  5438.   gb->serial->clks (gb->serial);
  5439. }
  5440.  
  5441. void /* gameboy's main function */
  5442. gameboy_run_ms (struct gameboy *gb, ks_double exec_ms /*neg disable */) {
  5443.  
  5444.   ks_int opclks_;
  5445.   ks_double opclks;
  5446.   ks_double clks_b;
  5447.   ks_bool fadjust;
  5448.   ks_uint8 imask;
  5449.   ks_double cpu_clks;
  5450.   ks_double op_ms;
  5451.   ks_double oc_ms;
  5452.   static ks_uint16 PC_cac;
  5453.   oc_ms = gb->deflect_ms;
  5454.   gb->deflect_ms += exec_ms;
  5455.   if (ks_cmp0_double (& gb->deflect_ms) == KS_CMP_ABOVE) {
  5456.     op_ms = exec_ms -  oc_ms;
  5457.     gb->deflect_ms = 0.0;
  5458.     clks_b = op_ms * gb->mach_tools->clk_ms;
  5459.     cpu_clks = clks_b;
  5460.     /* device done loop */
  5461.     while (ks_true)  {
  5462.       /* check remain clks */
  5463.       if (ks_cmp0_double (& cpu_clks) != KS_CMP_ABOVE)  {
  5464.         /* cycles burning out **/
  5465.         gb->deflect_ms = cpu_clks / gb->mach_tools->clk_ms;
  5466.         break ;
  5467.       } else {
  5468.         /* remain clks to run, first check dma run. */
  5469.         if (ks_cmp0_double (& gb->cpu_clks_dma) == KS_CMP_ABOVE) {
  5470.           /* DMA active, exec nop instruction, clks:4 */
  5471.           gb->cpu_clks_dma -= 4.0;
  5472.           cpu_clks -= 4.0; /* XXX:stride clks for next DMA. */
  5473.           internaldev_clks (gb, 4.0);
  5474.           continue ;
  5475.         } else if (gb->lh5028->hdma_gen != ks_false && !gb->lh5028->hdma_r16) {
  5476.           gb->lh5028->hdma_gen = ks_false;
  5477.           gb->lh5028->reg55_HDMA5 |= 0x80; /* Set unactive */
  5478.         }
  5479.         /* check stop, about stop opcode
  5480.            see http://gbdev.gg8.se/wiki/articles/Joypad_Input
  5481.                http://www.devrs.com/gb/files/faqs.html#STOP */
  5482.         if (gb->lr35902->stop != ks_false) {
  5483.           /* XXX: in fact not close APU. */
  5484.           cpu_clks -= 4.0;
  5485.           gb->cpu_clks_joypad += 4.0;
  5486.           gb->joypad->clks (gb->joypad);
  5487.           continue;
  5488.         }
  5489.         /* check halt, about halt opcode
  5490.            see. http://www.devrs.com/gb/files/faqs.html#HALT */
  5491.         if (gb->lr35902->halt != ks_false/* && gb->lr35902->IME != 0*/) {  
  5492.           cpu_clks -= 4.0;
  5493.           internaldev_clks (gb, 4.0);
  5494.           fadjust = ks_false;
  5495.           if ((gb->reg0F_IF & gb->regFF_IE & 0x1F) != 0) {
  5496.             gb->lr35902->halt = ks_false;  /* close halt*/
  5497.             if (gb->lr35902->IME == 0) {
  5498.               /* halt bug gen, read next byte twice */
  5499.               gb->lr35902->_backup = 0;
  5500.             }
  5501.           }
  5502.           goto check_interrupt;
  5503.         }
  5504.         /* run cpu opcode */
  5505.                 //        if (gb->lr35902->PC == 0x1E48)
  5506.         // _DEBUG_BREAK ();
  5507.              //   if (gb->lr35902->PC == 0x1E66)
  5508.         // _DEBUG_BREAK ();
  5509.         PC_cac = gb->lr35902->PC;
  5510.         opclks_ = cpu_optick (gb->lr35902);
  5511.         // assert (opclks_ < 5);
  5512.        
  5513.         printf ("pc:%04x prombank:%d\n", gb->lr35902->PC, gb->cart->mbc1->prombank);
  5514.         if (gb->lr35902->PC == 0x1E65)
  5515.          _DEBUG_BREAK ();
  5516.         /* check KEY1 */
  5517.         fadjust = ks_true;
  5518.         if (opclks_ & 0x80000000)
  5519.           opclks_ &= 0x7FFFFFFF;
  5520.         else fadjust = ks_false;
  5521.         opclks = (ks_double) opclks_;
  5522.         cpu_clks -= opclks_;
  5523.         internaldev_clks (gb, opclks_);
  5524.   check_interrupt:
  5525.         if (gb->lr35902->IME != 0) {
  5526.           if ((imask = (gb->reg0F_IF & gb->regFF_IE & 0x1F)) != 0) {    
  5527.            /* Interrupt Service Routine According to Z80 datasheets,
  5528.               the following occurs when control is being transferred to an interrupt handler: */        
  5529.             ks_uint16 iaddr;
  5530.             gb->lr35902->halt = ks_false;  /* close halt*/
  5531.             gb->lr35902->_backup = 0;
  5532.             if (imask & IRQ_1) {
  5533.               iaddr = IRQ_1_ADDRESS; imask= IRQ_1; }
  5534.             else if (imask & IRQ_2) {
  5535.               iaddr = IRQ_2_ADDRESS; imask= IRQ_2; }
  5536.             else if (imask & IRQ_3) {
  5537.               iaddr = IRQ_3_ADDRESS; imask= IRQ_3; }
  5538.             else if (imask & IRQ_4) {
  5539.               iaddr = IRQ_4_ADDRESS; imask= IRQ_4; }
  5540.             else if (imask & IRQ_5) {
  5541.               iaddr = IRQ_5_ADDRESS; imask= IRQ_5; }
  5542.             /* 1. Two wait states are executed
  5543.               (2 machine cycles pass while nothing occurs, presumably the CPU is executing NOPs during this time). */
  5544.             cpu_clks -= 8.0;
  5545.             internaldev_clks (gb, 8.0);
  5546.             gb->reg0F_IF &=~imask; /*close interrupr request mask */
  5547.             gb->lr35902->IME = 0; /* reset IME. */
  5548.             gameboy_mmu_write (gb, gb->lr35902->SP - 1, gb->lr35902->PH);
  5549.             gameboy_mmu_write (gb, gb->lr35902->SP - 2, gb->lr35902->PL);
  5550.             gb->lr35902->SP -= 2;
  5551.             /* 2. The current PC is pushed onto the stack, this process consumes 2 more machine cycles. */
  5552.             cpu_clks -= 8.0;
  5553.             internaldev_clks (gb, 8.0);
  5554.             /* 3. The high byte of the PC is set to 0,
  5555.                   the low byte is set to the address of the handler ($40,$48,$50,$58,$60).
  5556.                   This consumes one last machine cycle. */
  5557.             gb->lr35902->PC = iaddr;
  5558.             cpu_clks -= 4.0;
  5559.             internaldev_clks (gb, 4.0);
  5560.           }
  5561.         }
  5562.         if (fadjust != ks_false) {
  5563.           /* freq adjust in all device  */
  5564.           if (gb->lr35902->reg4D_key1 & 0x80) {
  5565.             /* normal to double freq */
  5566.             cpu_clks *= std_machine.cgb_gbp_p;
  5567.             gb->cpu_clks_ppu *= std_machine.cgb_gbp_p;
  5568.             gb->lh5028->hbl_clks_st *= std_machine.cgb_gbp_p;
  5569.             gb->lh5028->oambg_clks_divider21 *= std_machine.cgb_gbp_p;
  5570.             gb->mach_tools = (struct machine_setup *)& adv_machine;
  5571.           } else {
  5572.             /* double freq to normal */
  5573.             cpu_clks *= adv_machine.gbp_cgb_p;
  5574.             gb->cpu_clks_ppu *= adv_machine.gbp_cgb_p;
  5575.             gb->lh5028->hbl_clks_st *= adv_machine.gbp_cgb_p;
  5576.             gb->lh5028->oambg_clks_divider21 *= adv_machine.gbp_cgb_p;
  5577.             gb->mach_tools = (struct machine_setup *)& std_machine;
  5578.           }
  5579.         }
  5580.       }
  5581.     }
  5582.   }
  5583. }
  5584.  
  5585. int apu_init (struct apu **apu);
  5586. int ppu_init (struct ppu **ppu);
  5587. int cpu_init (struct cpu **cpu);
  5588. int controller_init (struct controller **controller);
  5589. int timer_init (struct timer **timer);
  5590. int divider_init (struct divider **divider_);
  5591. int cartridge_init (struct cartridge ** cartridge);
  5592. int serial_init (struct serial ** serial);
  5593.  
  5594. int gameboy_init (struct gameboy **gb) {
  5595.  
  5596.   struct gameboy *gb_ =ks_null;
  5597.   assert (gb != ks_null);
  5598.  
  5599.   gb_ = (struct gameboy *)
  5600.      calloc (sizeof (struct gameboy), 1);
  5601.   apu_init (& gb_->apu);
  5602.   ppu_init (& gb_->lh5028);
  5603.   cpu_init (& gb_->lr35902);
  5604.   controller_init (& gb_->joypad);
  5605.   timer_init (& gb_->timer);
  5606.   divider_init (& gb_->divider);
  5607.   cartridge_init (& gb_->cart);
  5608.   serial_init (& gb_->serial);
  5609.  
  5610.   /* lnk child objects */
  5611.   gb_->apu->gb = gb_;
  5612.   gb_->lh5028->gb = gb_;
  5613.   gb_->lr35902->gb = gb_;
  5614.   gb_->joypad->gb = gb_;
  5615.   gb_->timer->gb = gb_;
  5616.   gb_->divider->gb = gb_;
  5617.   gb_->cart->gb = gb_;
  5618.   gb_->serial->gb = gb_;
  5619.  
  5620.   gb_->controller_hostdrv = controller_hostdrv_s;
  5621.   gb_->display_hostdrv = display_hostdrv_s;
  5622.  
  5623.   ppu_setupdate_ (gb_->lh5028, lcdvideo_hostdrv_route, ks_null);
  5624.   controller_setupdate_ (gb_->joypad, controller_hostdrv_route, ks_null);
  5625.  
  5626.   gb_->reg70_SVBK = 1;
  5627.   gb_->regFF_IE = 0;
  5628.  
  5629.  
  5630.   * gb = gb_;
  5631.   return 0;
  5632. }
  5633.  
  5634. void divider_write (struct divider *divider, ks_uint8 value);
  5635. void timer_write (struct timer *timer, ks_uint16 addr, ks_uint8 value);
  5636. void ppu_write (struct ppu *ppu, ks_uint16 addr, ks_uint8 value);
  5637. void apu_write (struct apu *apu, ks_uint16 addr, ks_uint8 value);
  5638. void serial_write (struct serial *apu, ks_uint16 addr, ks_uint8 value);
  5639. void cartridge_write (struct cartridge *cart, ks_uint16 addr, ks_uint8 value);
  5640. void controller_write (struct controller *cart, ks_uint8 value);
  5641.  
  5642. void
  5643. ks_callstd gameboy_mmu_write (struct gameboy *gb, ks_uint16 address, ks_uint8 value) {
  5644.  
  5645.   switch (address >> 13) {
  5646.   case 0x00: /* Memmap- 0x0000-0x1FFF*/
  5647.   case 0x01: /* Memmap- 0x2000-0x3FFF*/
  5648.   case 0x02: /* Memmap- 0x4000-0x5FFF*/
  5649.   case 0x03: /* Memmap- 0x6000-0x7FFF*/
  5650.   case 0x05: /* Memmap- 0xA000-0xBFFF*/
  5651.     gb->cart->write (gb->cart, address, value); /* Program ROM BANK0 or BANK1-NN */
  5652.     break;
  5653.   case 0x04: /* Memmap- 0x8000-0x9FFF*/
  5654.     gb->lh5028->ram[address-0x8000+(gb->lh5028->reg4F_VBK&1)*0x2000] = value;
  5655.     break;
  5656.   case 0x07: /* Memmap- 0xE000-0xFFFF*/
  5657.     if (address <= 0xFDFF) /* echo ram. same as nes's mirror ram. */
  5658.   case 0x06: /* Memmap- 0xC000-0xDFFF*/
  5659.       if (address & 0x1000)
  5660.         gb->wram[(address & 0x0FFF)+(gb->reg70_SVBK & 7)*0x1000] = value;
  5661.       else
  5662.         gb->wram[address & 0x0FFF] = value;
  5663.     else if (address <= 0xFE9F)
  5664.       ((ks_int8 *)&gb->lh5028->sp[0])[address-0xFE00] = value;
  5665.     else if (address <= 0xFEFF)  /* Not Usable */
  5666.   default:
  5667.       gb->unknow_ram[address] = value;
  5668.     else
  5669.       switch (address) {
  5670.       case 0xFF00: /* P1 */
  5671.         controller_write (gb->joypad, value);
  5672.         break;
  5673.       case 0xFF01: /* SB */
  5674.       case 0xFF02: /* SC */
  5675.         serial_write (gb->serial, address, value);
  5676.         break;
  5677.       case 0xFF04: /* DIV */
  5678.         divider_write (gb->divider, value);
  5679.         break;
  5680.       case 0xFF05: /* TIMA*/
  5681.       case 0xFF06: /* TMA */
  5682.       case 0xFF07: /* TAC */
  5683.         timer_write (gb->timer, address, value);
  5684.         break;
  5685.       case 0xFF10: /* NR10 */
  5686.       case 0xFF11: /* NR11 */
  5687.       case 0xFF12: /* NR12 */
  5688.       case 0xFF13: /* NR13 */
  5689.       case 0xFF14: /* NR14 */
  5690.       case 0xFF16: /* NR21 */
  5691.       case 0xFF17: /* NR22 */
  5692.       case 0xFF18: /* NR23 */
  5693.       case 0xFF19: /* NR24 */
  5694.       case 0xFF1A: /* NR30 */
  5695.       case 0xFF1B: /* NR31 */
  5696.       case 0xFF1C: /* NR32 */
  5697.       case 0xFF1D: /* NR33 */
  5698.       case 0xFF1E: /* NR34 */
  5699.       case 0xFF20: /* NR41 */
  5700.       case 0xFF21: /* NR42 */
  5701.       case 0xFF22: /* NR43 */
  5702.       case 0xFF23: /* NR44 */
  5703.       case 0xFF24: /* NR50 */
  5704.       case 0xFF25: /* NR51 */
  5705.       case 0xFF26: /* NR52 */
  5706.       case 0xFF30: /* AUD3WAVERAM */
  5707.       case 0xFF31: /* AUD3WAVERAM */
  5708.       case 0xFF32: /* AUD3WAVERAM */
  5709.       case 0xFF33: /* AUD3WAVERAM */
  5710.       case 0xFF34: /* AUD3WAVERAM */
  5711.       case 0xFF35: /* AUD3WAVERAM */
  5712.       case 0xFF36: /* AUD3WAVERAM */
  5713.       case 0xFF37: /* AUD3WAVERAM */
  5714.       case 0xFF38: /* AUD3WAVERAM */
  5715.       case 0xFF39: /* AUD3WAVERAM */
  5716.       case 0xFF3A: /* AUD3WAVERAM */
  5717.       case 0xFF3B: /* AUD3WAVERAM */
  5718.       case 0xFF3C: /* AUD3WAVERAM */
  5719.       case 0xFF3D: /* AUD3WAVERAM */
  5720.       case 0xFF3E: /* AUD3WAVERAM */
  5721.       case 0xFF3F: /* AUD3WAVERAM */
  5722.         apu_write (gb->apu, address, value);
  5723.         break;
  5724.       case 0xFF40: /* LCDC */
  5725.       case 0xFF41: /* LCDS */
  5726.       case 0xFF42: /* SCY */
  5727.       case 0xFF43: /* SCX */
  5728.       case 0xFF44: /* LY */
  5729.       case 0xFF45: /* LYC */
  5730.       case 0xFF46: /* OAMDMA */
  5731.       case 0xFF47: /* BGP -DMG Only */
  5732.       case 0xFF48: /* OBP0 -DMG Only */
  5733.       case 0xFF49: /* OBP1 -DMG Only */
  5734.       case 0xFF4A: /* WY */
  5735.       case 0xFF4B: /* WX */
  5736.       case 0xFF4F: /* VBK -CBG Only*/
  5737.       case 0xFF51: /* HDMA1 -CBG Only*/
  5738.       case 0xFF52: /* HDMA2 -CBG Only*/
  5739.       case 0xFF53: /* HDMA3 -CBG Only*/
  5740.       case 0xFF54: /* HDMA4 -CBG Only*/
  5741.       case 0xFF55: /* HDMA5 -CBG Only*/
  5742.       case 0xFF68: /* BCPS -CBG Only*/
  5743.       case 0xFF69: /* BCPD -CBG Only*/
  5744.       case 0xFF6A: /* OCPS -CBG Only*/
  5745.       case 0xFF6B: /* OCPD -CBG Only*/
  5746.         ppu_write (gb->lh5028, address, value);
  5747.         break;
  5748.       case 0xFF56: /* RP -CBG Only*/
  5749.         break;
  5750.       case 0xFF70: /* SVBK -CBG Only*/
  5751.         if ((gb->reg70_SVBK = (value & 7)) == 0)
  5752.           gb->reg70_SVBK = 1;
  5753.         break;
  5754.       case 0xFF4D: /* KEY1 -CBG Only*/
  5755.         gb->lr35902->reg4D_key1 = value;
  5756.         break;
  5757.       case 0xFFFF: /* Interrupt Enable */
  5758.         gb->regFF_IE = value;
  5759.         break;
  5760.       case 0xFF0F: /* IF */
  5761.         gb->reg0F_IF = value;  
  5762.         break;
  5763.       default:
  5764.         if (address >= 0xFF80)
  5765.           gb->hram[address-0xFF80] = value;
  5766.         break;
  5767.       }
  5768.     break;
  5769.   }
  5770. }
  5771.  
  5772. ks_void
  5773. ks_callstd gameboy_mmu_write_w (struct gameboy *gb, ks_uint16 address, ks_uint16 value) {
  5774.   gameboy_mmu_write (gb, address, value & 0xFF);
  5775.   gameboy_mmu_write (gb, address+1, value>> 8);
  5776. }
  5777.  
  5778. ks_uint8 divider_read (struct divider *divider);
  5779. ks_uint8 timer_read (struct timer *timer, ks_uint16 addr);
  5780. ks_uint8 ppu_read (struct ppu *ppu, ks_uint16 addr);
  5781. ks_uint8 apu_read (struct apu *apu, ks_uint16 addr);
  5782. ks_uint8 serial_read (struct serial *apu, ks_uint16 addr);
  5783. ks_uint8 cartridge_read (struct cartridge *cart, ks_uint16 addr);
  5784. ks_uint8 controller_read (struct controller *controller);
  5785.  
  5786. ks_uint8
  5787. ks_callstd gameboy_mmu_read (struct gameboy *gb, ks_uint16 address) {
  5788.  
  5789.   switch (address >> 13) {
  5790.   case 0x00: /* Memmap- 0x0000-0x1FFF - BANK-0 */
  5791.   case 0x01: /* Memmap- 0x2000-0x3FFF - BANK-0 */
  5792.   case 0x02: /* Memmap- 0x4000-0x5FFF - BANK-N */
  5793.   case 0x03: /* Memmap- 0x6000-0x7FFF - BANK-N */
  5794.   case 0x05: /* Memmap- 0xA000-0xBFFF - SRAM/RAM/EXT */
  5795.     return gb->cart->read (gb->cart, address);
  5796.   case 0x04: /* Memmap- 0x8000-0x9FFF*/
  5797.     return gb->lh5028->ram[(address & 0x1FFF) +(gb->lh5028->reg4F_VBK&1)*0x2000];
  5798.   case 0x07: /* Memmap- 0xE000-0xFFFF*/
  5799.     if (address <= 0xFDFF) /* echo ram. same as nes's mirror ram. */
  5800.   case 0x06: /* Memmap- 0xC000-0xDFFF*/
  5801.       if (address & 0x1000)
  5802.         return gb->wram[(address & 0x0FFF) +(gb->reg70_SVBK & 7)*0x1000];
  5803.       else
  5804.         return gb->wram[address & 0x0FFF];      
  5805.     else if (address <= 0xFE9F)
  5806.       return ((ks_int8 *)&gb->lh5028->sp[0])[address-0xFE00];
  5807.     else if (address <= 0xFEFF)  /* Not Usable */
  5808.   default:
  5809.       return gb->unknow_ram[address];
  5810.     else
  5811.       switch (address) {
  5812.       case 0xFF00: /* P1 */
  5813.         return controller_read (gb->joypad);
  5814.       case 0xFF01: /* SB */
  5815.       case 0xFF02: /* SC */
  5816.         return serial_read (gb->serial, address);
  5817.       case 0xFF04: /* DIV */
  5818.         return divider_read (gb->divider);
  5819.       case 0xFF05: /* TIMA*/
  5820.       case 0xFF06: /* TMA */
  5821.       case 0xFF07: /* TAC */
  5822.         return timer_read (gb->timer, address);  
  5823.       case 0xFF10: /* NR10 */
  5824.       case 0xFF11: /* NR11 */
  5825.       case 0xFF12: /* NR12 */
  5826.       case 0xFF13: /* NR13 */
  5827.       case 0xFF14: /* NR14 */
  5828.       case 0xFF16: /* NR21 */
  5829.       case 0xFF17: /* NR22 */
  5830.       case 0xFF18: /* NR23 */
  5831.       case 0xFF19: /* NR24 */
  5832.       case 0xFF1A: /* NR30 */
  5833.       case 0xFF1B: /* NR31 */
  5834.       case 0xFF1C: /* NR32 */
  5835.       case 0xFF1D: /* NR33 */
  5836.       case 0xFF1E: /* NR34 */
  5837.       case 0xFF20: /* NR41 */
  5838.       case 0xFF21: /* NR42 */
  5839.       case 0xFF22: /* NR43 */
  5840.       case 0xFF23: /* NR44 */
  5841.       case 0xFF24: /* NR50 */
  5842.       case 0xFF25: /* NR51 */
  5843.       case 0xFF26: /* NR52 */
  5844.       case 0xFF30: /* AUD3WAVERAM */
  5845.       case 0xFF31: /* AUD3WAVERAM */
  5846.       case 0xFF32: /* AUD3WAVERAM */
  5847.       case 0xFF33: /* AUD3WAVERAM */
  5848.       case 0xFF34: /* AUD3WAVERAM */
  5849.       case 0xFF35: /* AUD3WAVERAM */
  5850.       case 0xFF36: /* AUD3WAVERAM */
  5851.       case 0xFF37: /* AUD3WAVERAM */
  5852.       case 0xFF38: /* AUD3WAVERAM */
  5853.       case 0xFF39: /* AUD3WAVERAM */
  5854.       case 0xFF3A: /* AUD3WAVERAM */
  5855.       case 0xFF3B: /* AUD3WAVERAM */
  5856.       case 0xFF3C: /* AUD3WAVERAM */
  5857.       case 0xFF3D: /* AUD3WAVERAM */
  5858.       case 0xFF3E: /* AUD3WAVERAM */
  5859.       case 0xFF3F: /* AUD3WAVERAM */
  5860.         return apu_read (gb->apu, address);
  5861.       case 0xFF40: /* LCDC */
  5862.       case 0xFF41: /* LCDS */
  5863.       case 0xFF42: /* SCY */
  5864.       case 0xFF43: /* SCX */
  5865.       case 0xFF44: /* LY */
  5866.       case 0xFF45: /* LYC */
  5867.       case 0xFF46: /* OAMDMA */
  5868.       case 0xFF47: /* BGP -DMG Only */
  5869.       case 0xFF48: /* OBP0 -DMG Only */
  5870.       case 0xFF49: /* OBP1 -DMG Only */
  5871.       case 0xFF4A: /* WY */
  5872.       case 0xFF4B: /* WX */
  5873.       case 0xFF4F: /* VBK -CBG Only*/
  5874.       case 0xFF51: /* HDMA1 -CBG Only*/
  5875.       case 0xFF52: /* HDMA2 -CBG Only*/
  5876.       case 0xFF53: /* HDMA3 -CBG Only*/
  5877.       case 0xFF54: /* HDMA4 -CBG Only*/
  5878.       case 0xFF55: /* HDMA5 -CBG Only*/
  5879.       case 0xFF68: /* BCPS -CBG Only*/
  5880.       case 0xFF69: /* BCPD -CBG Only*/
  5881.       case 0xFF6A: /* OCPS -CBG Only*/
  5882.       case 0xFF6B: /* OCPD -CBG Only*/
  5883.         return ppu_read (gb->lh5028, address);
  5884.       case 0xFF56: /* RP -CBG Only*/
  5885.         return 0xFF;
  5886.       case 0xFF70: /* SVBK -CBG Only*/
  5887.         return (gb->reg70_SVBK & 7);
  5888.       case 0xFF4D: /* KEY1 -CBG Only*/
  5889.         return gb->lr35902->reg4D_key1;
  5890.       case 0xFFFF: /* Interrupt Enable */
  5891.         return gb->regFF_IE;
  5892.       case 0xFF0F: /* IF */
  5893.         return gb->reg0F_IF;
  5894.       default:
  5895.         if (address >= 0xFF80) /* High RAM */
  5896.           return gb->hram[address-0xFF80];
  5897.         else
  5898.           return 0;
  5899.       }
  5900.   }
  5901.   return 0xFF;
  5902. }
  5903.  
  5904. ks_uint16
  5905. ks_callstd gameboy_mmu_read_w (struct gameboy *gb, ks_uint16 address) {
  5906.   ks_uint16 u = gameboy_mmu_read (gb, address);
  5907.   ks_uint16 v = gameboy_mmu_read (gb, address+1) << 8;
  5908.   return (u |v);
  5909. }
  5910.  
  5911. int gameboy_loadrom (struct gameboy *gb, FILE *fp) {
  5912.   int cartridge_load (struct cartridge *cart, FILE *cartmem);
  5913.   return cartridge_load (gb->cart, fp);
  5914. }
  5915.  
  5916. #include "gameboy.h"
  5917. #include "internal.h"
  5918.  
  5919. /* Add mapper --*/
  5920. int cartridge_load (struct cartridge *cart, FILE *cartmem) {
  5921.  
  5922.   static ks_uint8 nintendo_magicnumber[] =
  5923.   { 0xCE, 0xED, 0x66, 0x66, 0xCC, 0x0D, 0x00, 0x0B, 0x03, 0x73, 0x00, 0x83, 0x00, 0x0C, 0x00, 0x0D,
  5924.     0x00, 0x08, 0x11, 0x1F, 0x88, 0x89, 0x00, 0x0E, 0xDC, 0xCC, 0x6E, 0xE6, 0xDD, 0xDD, 0xD9, 0x99,
  5925.     0xBB, 0xBB, 0x67, 0x63, 0x6E, 0x0E, 0xEC, 0xCC, 0xDD, 0xDC, 0x99, 0x9F, 0xBB, 0xB9, 0x33, 0x3E };
  5926.   ks_bool bat;
  5927.   ks_bool ram, cgb, sgb;
  5928.   ks_uint8 magicnumber_buffer[sizeof(nintendo_magicnumber)];
  5929.   ks_uint8 *promworks;
  5930.   ks_uint8 *sramworks;
  5931.  
  5932.   int cartridge_mbc0_init (struct cartridge *cartridge);
  5933.   int cartridge_mbc1_init (struct cartridge *cartridge);
  5934.   int cartridge_mbc2_init (struct cartridge *cartridge);
  5935.   void cpu_reset (struct cpu *cpu);
  5936.   int ppu_reset (struct ppu *ppu);
  5937.   int ppu_cgb_mode (struct ppu *ppu);
  5938.   int ppu_dmg_mode (struct ppu *ppu);
  5939.  
  5940.   //extern int cartridge_mbc0_init (struct cartridge *cartridge);
  5941.  
  5942.   ks_int sig = -1;
  5943.   ks_int promsize;
  5944.   ks_int sramsize;
  5945.   ks_int calc;
  5946.   ks_int type;
  5947.   assert (cart != ks_null);
  5948.   assert (cartmem != ks_null);
  5949.  
  5950.   bat = ks_false;
  5951.   ram = ks_false;
  5952.   cgb = ks_false;
  5953.   sgb = ks_false;
  5954.   sramworks = ks_null;
  5955.   promworks = ks_null;
  5956.  
  5957.   if (fseek (cartmem, 0x104, SEEK_SET) != 0)
  5958.     return -1;
  5959.   if (fread (& magicnumber_buffer[0], sizeof (nintendo_magicnumber), 1, cartmem)
  5960.       != 1)
  5961.     return -1;
  5962.   if (memcmp (nintendo_magicnumber,
  5963.                 magicnumber_buffer, sizeof (magicnumber_buffer) != 0))
  5964.     return -1;
  5965.   if (fseek (cartmem, 0x134, SEEK_SET) != 0)
  5966.     return -1;
  5967.   if (fread (& cart->infochunk[0], sizeof (cart->infochunk), 1, cartmem)
  5968.       != 1)
  5969.     return -1;
  5970.  
  5971.   /* x143/x146 - Check CGB/ SGB  */
  5972.   cgb = !!(cart->infochunk[15] & 0x80);
  5973.   sgb = !!(cart->infochunk[18] == 0x03);
  5974.  
  5975.   /*
  5976.    00h  ROM ONLY                 19h  MBC5
  5977.    01h  MBC1                     1Ah  MBC5+RAM
  5978.    02h  MBC1+RAM                 1Bh  MBC5+RAM+BATTERY
  5979.    03h  MBC1+RAM+BATTERY         1Ch  MBC5+RUMBLE
  5980.    05h  MBC2                     1Dh  MBC5+RUMBLE+RAM
  5981.    06h  MBC2+BATTERY             1Eh  MBC5+RUMBLE+RAM+BATTERY
  5982.    08h  ROM+RAM                  20h  MBC6
  5983.    09h  ROM+RAM+BATTERY          22h  MBC7+SENSOR+RUMBLE+RAM+BATTERY
  5984.    0Bh  MMM01
  5985.    0Ch  MMM01+RAM
  5986.    0Dh  MMM01+RAM+BATTERY
  5987.    0Fh  MBC3+TIMER+BATTERY
  5988.    10h  MBC3+TIMER+RAM+BATTERY   FCh  POCKET CAMERA
  5989.    11h  MBC3                     FDh  BANDAI TAMA5
  5990.    12h  MBC3+RAM                 FEh  HuC3
  5991.    13h  MBC3+RAM+BATTERY         FFh  HuC1+RAM+BATTERY
  5992.  */
  5993.  
  5994.   /* check error device */
  5995.   switch (cart->infochunk[19]) {
  5996.   case 0x00:
  5997.     type = MBC_0;
  5998.     break;
  5999.   case 0x01:
  6000.   case 0x02:
  6001.   case 0x03:
  6002.     type = MBC_1;
  6003.     break;
  6004.   case 0x05:
  6005.   case 0x06:
  6006.     type = MBC_2;
  6007.     break;
  6008.   case 0x08:
  6009.   case 0x09:
  6010.     type = MBC_0;
  6011.     break;
  6012.   case 0x0B:
  6013.   case 0x0C:
  6014.   case 0x0D:
  6015.     type = MMM0;
  6016.     break;
  6017.   case 0x0F:
  6018.   case 0x10:
  6019.   case 0x11:
  6020.   case 0x12:
  6021.   case 0x13:
  6022.     type = MBC_3;
  6023.     break;
  6024.   case 0x19:
  6025.   case 0x1A:
  6026.   case 0x1B:
  6027.   case 0x1C:
  6028.   case 0x1D:
  6029.   case 0x1E:
  6030.     type = MBC_5;
  6031.     break;  
  6032.   case 0x20:
  6033.     type = MBC_6;
  6034.     break;  
  6035.   case 0x22:
  6036.     type = MBC_7;
  6037.     break;  
  6038.   case 0xFC:
  6039.     type = POCKER_CAM;
  6040.     break;  
  6041.   case 0xFD:
  6042.     type = TAMA5;
  6043.     break;
  6044.   case 0xFE:
  6045.     type = HUCL3;
  6046.     break;
  6047.   case 0xFF:
  6048.     type = HUCL1;
  6049.     break;
  6050.   default :
  6051.     return -1;
  6052.   }
  6053.   /* check prom size */
  6054.   switch (cart->infochunk[20]) {
  6055.   case 0x00: promsize = 2; break;
  6056.   case 0x01: promsize = 4; break;
  6057.   case 0x02: promsize = 8; break;
  6058.   case 0x03: promsize =16; break;
  6059.   case 0x04: promsize =32; break;
  6060.   case 0x05: promsize =64; if (type == MBC_1) promsize = 63; break;
  6061.   case 0x06: promsize =128; if (type == MBC_1) promsize = 125; break; break;
  6062.   case 0x07: promsize =256; break;
  6063.   case 0x08: promsize =512; break;
  6064.   case 0x52: promsize =72; break;
  6065.   case 0x53: promsize =80; break;
  6066.   case 0x54: promsize =96; break;
  6067.   default : return -1;
  6068.   }
  6069.  
  6070.   /* check sram size */
  6071.   switch (cart->infochunk[21]) {
  6072.   case 0x00: sramsize = 0; break;
  6073.   case 0x01: sramsize = 1; break; /* 2K sram, same as 8K */
  6074.   case 0x02: sramsize = 1; break;
  6075.   case 0x03: sramsize = 4; break;
  6076.   case 0x04: sramsize =16; break;
  6077.   case 0x05: sramsize = 8; break;
  6078.   default : return -1;
  6079.   }
  6080.   /* init prom and sram */
  6081.   promworks = (ks_uint8 *)malloc (promsize * 0x4000);
  6082.   sramworks = (ks_uint8 *)malloc (sramsize * 0x2000);
  6083.   assert (promworks != ks_null);
  6084.   assert (sramworks != ks_null); /* random data in init time */
  6085.  
  6086.   fseek (cartmem, 0, SEEK_END);
  6087.   calc = ftell(cartmem);
  6088.  
  6089.   if (calc != promsize * 0x4000)
  6090.     promsize = calc / 0x4000;
  6091.   if (fseek (cartmem, 0, SEEK_SET) != 0)
  6092.     goto _cleanup;
  6093.   if (fread (promworks, promsize * 0x4000, 1, cartmem) != 1)
  6094.     goto _cleanup;
  6095.   if (cart->promworks != ks_null)
  6096.     free (cart->promworks);
  6097.   if (cart->sramworks != ks_null)
  6098.     free (cart->sramworks);
  6099.  
  6100.   cart->promworks = promworks;
  6101.   cart->sramworks = sramworks;
  6102.   cart->cbgmode = cgb;
  6103.   cart->sgbmode = sgb;
  6104.   cart->promsize = promsize;
  6105.   cart->sramsize = sramsize;
  6106.   cart->type = type;
  6107.   cart->battery = bat;
  6108.  
  6109.   /* reset cart chip device */
  6110.   switch (type) {
  6111.   case MBC_0:
  6112.     cartridge_mbc0_init (cart);
  6113.     break;
  6114.   case MBC_1:
  6115.   case MBC_2:
  6116.   case MBC_3:
  6117.   case MBC_4:
  6118.   case MBC_5:
  6119.   case MBC_6:
  6120.   case MBC_7:
  6121.   case TAMA5:
  6122.   case HUCL1:
  6123.   case HUCL3:
  6124.   case MMM0:
  6125.   case POCKER_CAM:
  6126.   default :assert (0); /*never reach here */
  6127.   }
  6128.   if (cgb != ks_false)
  6129.     ppu_cgb_mode (cart->gb->lh5028);
  6130.   else
  6131.     ppu_dmg_mode (cart->gb->lh5028);
  6132.   cpu_reset (cart->gb->lr35902);
  6133.   ppu_reset (cart->gb->lh5028);
  6134.   /* set std freq. */
  6135.   cart->gb->mach_tools = (struct machine_setup *)& std_machine;
  6136.   return 0;
  6137. _cleanup:
  6138.   free (sramworks);
  6139.   free (promworks);
  6140.   return -1;
  6141. }
  6142.  
  6143. int cartridge_init (struct cartridge **cartridge) {
  6144.   struct cartridge *cartridge_ =ks_null;
  6145.   assert (cartridge != ks_null);
  6146.  
  6147.   cartridge_ = (struct cartridge *)
  6148.      calloc (sizeof (struct cartridge), 1);
  6149.   cartridge_->clks = ks_null;
  6150.   assert (cartridge_ != ks_null);
  6151.   * cartridge = cartridge_;
  6152.  
  6153.   /* Settings cart type desc init --*/
  6154.   cartridge_->cartgt[0x00] = "ROM ONLY";
  6155.   cartridge_->cartgt[0x01] = "ROM+MBC1";
  6156.   cartridge_->cartgt[0x02] = "ROM+MBC1+RAM";
  6157.   cartridge_->cartgt[0x03] = "ROM+MBC1+RAM+Battery";
  6158.   cartridge_->cartgt[0x05] = "ROM+MBC2";
  6159.   cartridge_->cartgt[0x06] = "ROM+MBC2+Battery";
  6160.   cartridge_->cartgt[0x08] = "ROM+RAM";
  6161.   cartridge_->cartgt[0x09] = "ROM+RAM+Battery";
  6162.   cartridge_->cartgt[0x0B] = "ROM+MMM01";
  6163.   cartridge_->cartgt[0x0C] = "ROM+MMM01+RAM";
  6164.   cartridge_->cartgt[0x0D] = "ROM+MMM01+RAM+Battery";
  6165.   cartridge_->cartgt[0x0F] = "ROM+MBC3+Battery+Timer";
  6166.   cartridge_->cartgt[0x10] = "ROM+MBC3+RAM+Battery+Timer";
  6167.   cartridge_->cartgt[0x11] = "ROM+MBC3";
  6168.   cartridge_->cartgt[0x12] = "ROM+MBC3+RAM";
  6169.   cartridge_->cartgt[0x13] = "ROM+MBC3+RAM+Battery";
  6170.   cartridge_->cartgt[0x15] = "ROM+MBC4";
  6171.   cartridge_->cartgt[0x16] = "ROM+MBC4+RAM";
  6172.   cartridge_->cartgt[0x17] = "ROM+MBC4+RAM+Battery";
  6173.   cartridge_->cartgt[0x19] = "ROM+MBC5";
  6174.   cartridge_->cartgt[0x1A] = "ROM+MBC5+RAM";
  6175.   cartridge_->cartgt[0x1B] = "ROM+MBC5+RAM+Battery";
  6176.   cartridge_->cartgt[0x1C] = "ROM+MBC5+Rumble";
  6177.   cartridge_->cartgt[0x1D] = "ROM+MBC5+RAM+Rumble";
  6178.   cartridge_->cartgt[0x1E] = "ROM+MBC5+RAM+Battery+Rumble";
  6179.   cartridge_->cartgt[0x22] = "ROM+MBC5+Tilt";
  6180.   cartridge_->cartgt[0xFC] = "Nintendo Pocket Camera";
  6181.   cartridge_->cartgt[0xFD] = "Bandai TAMA5";
  6182.   cartridge_->cartgt[0xFE] = "Hudson HuC-3";
  6183.   cartridge_->cartgt[0xFF] = "Hudson HuC-1";
  6184.  
  6185.   /* Settings old licensee desc init --*/
  6186.   cartridge_->ancl[0x00] = "None";
  6187.   cartridge_->ancl[0x01] = "Nintendo"; /* homepage:https://www.nintendo.com */
  6188.   cartridge_->ancl[0x08] = "Capcom"; /* homepage:http://www.capcom.com*/
  6189.   cartridge_->ancl[0x09] = "Hot B Games"; /* wiki:https://en.wikipedia.org/wiki/Category:Hot_B_games */
  6190.   cartridge_->ancl[0x0A] = "Jaleco"; /* wiki:https://en.wikipedia.org/wiki/Jaleco*/
  6191.   cartridge_->ancl[0x0B] = "Coconuts Japan"; /* misc link:https://www.genkivideogames.com/japanese_imported_video_games.asp?pagetoshow=search&keywordtext=Coconuts%20Japan&searchtype=publisher*/
  6192.   cartridge_->ancl[0x0C] = "Elite Systems";/*wiki: https://en.wikipedia.org/wiki/Elite_Systems*/
  6193.   cartridge_->ancl[0x13] = "ËA"; /*homepage: https://www.ea.com/zh-cn */
  6194.   cartridge_->ancl[0x18] = "Hudson Soft"; /*homepage: http://www.hudsonsoft.net/what-we-do/ */
  6195.   cartridge_->ancl[0x19] = "ITC Entertainment"; /*wiki: https://en.wikipedia.org/wiki/ITC_Entertainment */
  6196.   cartridge_->ancl[0x1A] = "Yanoman"; /* MobyGames:https://www.mobygames.com/company/yanoman-corporation */
  6197.   cartridge_->ancl[0x1D] = "Nippon Clary"; /* giantbomb:https://www.giantbomb.com/nippon-clary-business/3010-6837/ */
  6198.   cartridge_->ancl[0x1F] = "Virgin"; /* wiki:https://en.wikipedia.org/wiki/Virgin_Interactive */
  6199.                                              /* homepage: https://www.virgingames.com/quick-login */
  6200.   cartridge_->ancl[0x24] = "PCM Complete"; /* https://segaretro.org/PCM_Complete | https://www.mobygames.com/company/pcm-complete */
  6201.   cartridge_->ancl[0x25] = "San-X"; /* homepage http://www.san-x.jp*/
  6202.   cartridge_->ancl[0x28] = "Kotobuki Systems";/*wiki: https://en.wikipedia.org/wiki/Kemco*/
  6203.   cartridge_->ancl[0x29] = "SETA"; /*wiki: https://en.wikipedia.org/wiki/SETA_Corporation */
  6204.   cartridge_->ancl[0x30] = "Atari,SA"; /*wiki: https://en.wikipedia.org/wiki/Atari,_SA */
  6205.   cartridge_->ancl[0x31] = "Nintendo"; /* homepage:https://www.nintendo.com */
  6206.   cartridge_->ancl[0x32] = "Bandai"; /*homepage: http://www.bandai.com */
  6207.   cartridge_->ancl[0x33] = "GameBoyColor"; /*new licensee */
  6208.   cartridge_->ancl[0x34] = "Konami"; /*homepage: https://www.konami.com/en/*/
  6209.   cartridge_->ancl[0x35] = "Hector"; /*N/A */
  6210.   cartridge_->ancl[0x38] = "Capcom"; /* homepage:http://www.capcom.com*/
  6211.   cartridge_->ancl[0x39] = "Banpresto"; /* homepage:http://www.banpresto.jp/prize/0008.html*/
  6212.   cartridge_->ancl[0x3C] = "Entertainment i"; /* truncated, see http://gbdev.gg8.se/wiki/articles/Gameboy_ROM_Header_Info#Licensee*/
  6213.   cartridge_->ancl[0x3E] = "Gremlin"; /* wiki: https://en.wikipedia.org/wiki/Gremlin_Interactive */
  6214.   cartridge_->ancl[0x41] = "Ubisoft"; /*homepage: https://www.ubisoft.com/en-US/ */
  6215.   cartridge_->ancl[0x42] = "Atlus"; /*homepage: https://atlus.com*/
  6216.   cartridge_->ancl[0x44] = "Malibu"; /*swiki: https://strategywiki.org/wiki/Category:Malibu*/
  6217.   cartridge_->ancl[0x46] = "Angel"; /*N/A*/
  6218.   cartridge_->ancl[0x47] = "Spectrum HoloByte"; /*wiki: https://en.wikipedia.org/wiki/Spectrum_HoloByte*/
  6219.   cartridge_->ancl[0x49] = "Irem"; /* wiki: https://en.wikipedia.org/wiki/Irem */
  6220.   cartridge_->ancl[0x4A] = "Virgin"; /* wiki:https://en.wikipedia.org/wiki/Virgin_Interactive */
  6221.                                              /* homepage: https://www.virgingames.com/quick-login */
  6222.   cartridge_->ancl[0x4D] = "Malibu"; /*swiki: https://strategywiki.org/wiki/Category:Malibu*/
  6223.   cartridge_->ancl[0x4F] = "US.Gold"; /*wiki: https://en.wikipedia.org/wiki/U.S._Gold */
  6224.   cartridge_->ancl[0x50] = "Absolute"; /*homepgae:http://www.absolutegamez.com */
  6225.   cartridge_->ancl[0x51] = "Acclaim"; /*wiki: https://en.wikipedia.org/wiki/Acclaim_Games*/
  6226.   cartridge_->ancl[0x52] = "Activision"; /*homepage: https://www.activision.com*/  
  6227.   cartridge_->ancl[0x53] = "Sammy"; /*wiki: https://en.wikipedia.org/wiki/Sammy_Corporation*/
  6228.   cartridge_->ancl[0x54] = "GameTek"; /*wiki: https://en.wikipedia.org/wiki/GameTek*/
  6229.   cartridge_->ancl[0x55] = "Park Place"; /*maybe???: https://en.wikipedia.org/wiki/List_of_Jurassic_Park_video_games*/
  6230.   cartridge_->ancl[0x56] = "LJN"; /*avgn: http://avgn.wikia.com/wiki/LJN*/  
  6231.   cartridge_->ancl[0x57] = "MATCHBOX"; /*homepage: http://play.matchbox.com/en_US/*/
  6232.   cartridge_->ancl[0x59] = "Milton Bradley"; /*wiki: https://en.wikipedia.org/wiki/Milton_Bradley_Company*/
  6233.   cartridge_->ancl[0x5A] = "Mindscape"; /*wiki: https://en.wikipedia.org/wiki/Mindscape*/
  6234.   cartridge_->ancl[0x5B] = "Romstar"; /*wiki: https://en.wikipedia.org/wiki/Romstar*/  
  6235.   cartridge_->ancl[0x5C] = "Kaga Create"; /*wiki: https://en.wikipedia.org/wiki/Kaga_Create*/
  6236.   cartridge_->ancl[0x5D] = "Tradewest"; /*wiki: https://en.wikipedia.org/wiki/Tradewest*/
  6237.   cartridge_->ancl[0x60] = "Titus"; /*wiki: https://en.wikipedia.org/wiki/Titus_Interactive*/
  6238.   cartridge_->ancl[0x61] = "Virgin"; /* wiki:https://en.wikipedia.org/wiki/Virgin_Interactive */
  6239.                                              /* homepage: https://www.virgingames.com/quick-login */
  6240.   cartridge_->ancl[0x67] = "Ocean"; /*wiki: https://en.wikipedia.org/wiki/Ocean_Software*/  
  6241.   cartridge_->ancl[0x69] = "ËA"; /*homepage: https://www.ea.com/zh-cn */
  6242.   cartridge_->ancl[0x6E] = "Elite Systems";/*wiki: https://en.wikipedia.org/wiki/Elite_Systems*/
  6243.   cartridge_->ancl[0x6F] = "Electro Brain";/*wiki: https://en.wikipedia.org/wiki/Electro_Brain*/
  6244.   cartridge_->ancl[0x70] = "Atari,SA"; /*wiki: https://en.wikipedia.org/wiki/Atari,_SA */
  6245.   cartridge_->ancl[0x71] = "Interplay"; /*wiki: https://en.wikipedia.org/wiki/Interplay_Entertainment*/
  6246.   cartridge_->ancl[0x72] = "Brøderbund"; /*moby: https://www.mobygames.com/company/brderbund-software-inc*/  
  6247.   cartridge_->ancl[0x73] = "Sculptured"; /*maybe??: http://closinglogogroup.wikia.com/wiki/Sculptured_Software,_Inc.*/
  6248.   cartridge_->ancl[0x75] = "SCi Games"; /*wiki: https://en.wikipedia.org/wiki/SCi_Games*/  
  6249.   cartridge_->ancl[0x78] = "THQ"; /*source is:t*hq wiki: https://en.wikipedia.org/wiki/THQ*/
  6250.   cartridge_->ancl[0x79] = "Accolade"; /*wiki: https://en.wikipedia.org/wiki/Accolade_(game_company)*/
  6251.   cartridge_->ancl[0x7A] = "Triffix"; /*wiki: https://en.wikipedia.org/wiki/Triffix_Entertainment*/
  6252.   cartridge_->ancl[0x7C] = "MicroProse"; /*homepage: http://www.microprose.com*/  
  6253.   cartridge_->ancl[0x7F] = "Kemco";/*wiki: https://en.wikipedia.org/wiki/Kemco*/
  6254.   cartridge_->ancl[0x80] = "Misawa"; /*nseen64: https://www.unseen64.net/tag/misawa-entertainment/*/
  6255.   cartridge_->ancl[0x83] = "LOZC G"; /*wiki: https://en.wikipedia.org/wiki/Category:LOZC_G._Amusements_games*/
  6256.   cartridge_->ancl[0x86] = "Tokuma Shoten"; /*wiki: https://en.wikipedia.org/wiki/Tokuma_Shoten*/  
  6257.   cartridge_->ancl[0x8B] = "Blue Planet"; /*wiki: https://en.wikipedia.org/wiki/Blue_Planet_Software*/
  6258.   cartridge_->ancl[0x8C] = "Tokai Communications"; /*wiki: https://en.wikipedia.org/wiki/Tokai_Communications*/
  6259.   cartridge_->ancl[0x8E] = "APE Games"; /*homepage: http://www.apegames.com*/
  6260.   cartridge_->ancl[0x8F] = "I'Max"; /*No find infos */  
  6261.   cartridge_->ancl[0x91] = "Spike Chunsoft"; /*wiki: https://en.wikipedia.org/wiki/Spike_Chunsoft*/
  6262.   cartridge_->ancl[0x92] = "Video System"; /*No find infos*/  
  6263.   cartridge_->ancl[0x93] = "Tsuburava"; /*No find infos */
  6264.   cartridge_->ancl[0x95] = "Varie"; /*wiki: https://en.wikipedia.org/wiki/Varie*/  
  6265.   cartridge_->ancl[0x96] = "Yonezawa PR21"; /*wiki: https://en.wikipedia.org/wiki/Yonezawa_PR21*/
  6266.   cartridge_->ancl[0x97] = "Kaneko"; /*wiki: https://en.wikipedia.org/wiki/Kaneko*/
  6267.   cartridge_->ancl[0x99] = "Arcade"; /*wiki: https://en.wikipedia.org/wiki/Arcade_game*/
  6268.   cartridge_->ancl[0x9A] = "Nihon Bussan"; /*wiki: https://en.wikipedia.org/wiki/Nihon_Bussan*/  
  6269.   cartridge_->ancl[0x9B] = "Tecmo"; /*wiki: https://en.wikipedia.org/wiki/Tecmo*/
  6270.   cartridge_->ancl[0x9C] = "Disney"; /*wiki: https://en.wikipedia.org/wiki/Walt_Disney_Imagineering*/
  6271.   cartridge_->ancl[0x9D] = "Banpresto"; /* homepage:http://www.banpresto.jp/prize/0008.html*/
  6272.   cartridge_->ancl[0x9F] = "Nova"; /*No find infos*/
  6273.   cartridge_->ancl[0xA1] = "Hori Electric"; /* https://www.giantbomb.com/hori-electric-co-ltd/3010-5917/*/  
  6274.   cartridge_->ancl[0xA2] = "Bandai"; /*homepage: http://www.bandai.com */
  6275.   cartridge_->ancl[0xA4] = "Konami"; /*homepage: https://www.konami.com/en/*/  
  6276.   cartridge_->ancl[0xA6] = "Kawada"; /*No find infos*/
  6277.   cartridge_->ancl[0xA7] = "Takara"; /*wiki: https://en.wikipedia.org/wiki/Takara**/
  6278.   cartridge_->ancl[0xA9] = "Technōs Japan"; /*wiki: https://en.wikipedia.org/wiki/Technōs_Japan*/
  6279.   cartridge_->ancl[0xAA] = "Brøderbund"; /*moby: https://www.mobygames.com/company/brderbund-software-inc*/  
  6280.   cartridge_->ancl[0xAC] = "Toei Animation"; /*homepage: http://t
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement