Reading
php-terminal-gameboy-emulator
Digital Circus, Inc.
HASEGAWA Tomki
HASEGAWA Tomoki
@tomzoh
Web / iOS App Development,
Rental Kart Race, Beer, IoT crafting, …
hasegawa

tomoki
Digital Circus, Inc. Vice-master CTO
Tokyo, Japan
Interests
・ Web Development
・ Mobile Apps Development
・ Service
( )
(iOS, Android)
(http://appbuilder.jp)
Twitter: @tomzoh
Twitter: @tomzoh
Today’s theme
Reading
php-terminal-gameboy-emulator
Today’s theme
Reading
php-terminal-gameboy-emulator
By Transfrom JPEG version and remove white background. Original by Evan-Amos. - Media:Game-Boy-FL.jpg,
Public Domain, https://commons.wikimedia.org/w/index.php?curid=37808150
23, February
😮
😮
😮
Awesome!!
😮
Awesome!!
Waste of talent!!
😮
Awesome!!
Waste of talent!! Cool!!
Source Files
Source Files
It’s PHP !
Source Files
It’s PHP !
We can read it.
Source Files
It’s PHP !
Yes, We can!
We can read it.
Source Files
It’s PHP !
Yes, We can!
Yes, We can!
We can read it.
Today’s theme
Reading
php-terminal-gameboy-emulator
Components of GAMEBOY
• CPU / Memory
• Display
• Sound
• Buttons
• Communication Port
Components of GAMEBOY
• CPU / Memory
• Display
• Sound
• Buttons
• Communication Port
Buttons
Buttons - Keyboard.php
<?php
namespace GameBoy;
class Keyboard
{
public $core;
public $file;
public $keyPressing = null;
public $started = false;
public function __construct(Core $core)
{
$this->core = $core;
exec('stty -icanon');
$this->file = fopen('php://stdin', 'r');
stream_set_blocking($this->file, false);
}
public function check()
{
Buttons - Keyboard.php
<?php
namespace GameBoy;
class Keyboard
{
public $core;
public $file;
public $keyPressing = null;
public $started = false;
public function __construct(Core $core)
{
$this->core = $core;
exec('stty -icanon');
$this->file = fopen('php://stdin', 'r');
stream_set_blocking($this->file, false);
}
public function check()
{
How to sense buttons
How to sense buttons
$this->file = fopen('php://stdin', 'r');
How to sense buttons
$this->file = fopen('php://stdin', 'r');
$key = fread($this->file, 1);
Simple
CPU / Memory
CPU
SHARP LR35902 instruction set
http://www.pastraiser.com/cpu/gameboy/gameboy_opcodes.html
1byte instructions Prefix CB instructions
144 instructions 256 instructions+
= 400 instructions
SHARP LR35902 resistors
http://www.pastraiser.com/cpu/gameboy/gameboy_opcodes.html
15 … 8 7 … 0
A F
B C
H L
15 … 8 7 … 0
SP (Stack Pointer)
PC (Program Counter)
8bit / 16bit resistors
16bit resistors
Flag registor
7 6 5 4 3 2 1 0
Z N H C 0 0 0 0
•Z - Zero Flag
•N - Subtract Flag
•H - Half Carry Flag
•C - Carry Flag
•0 - Not uses, always zero
Instruction in memory
0x0000 0x0001 0x0002 0x003 0x004 0x005 0x0301
0x01 0x01 0x03 0x3e 0x99 0x02 0x99
LD BC, d16 0x0301 LD A, d8 0x99 LD (BC), A
Data
Instruction
x0 x1 x2 xE
0x 3x
LD BC, d16
3 12
- - - -
NOP
1 4
- - - -
LD (BC), A
1 8
- - - -
Address
LD A, d8
2 8
- - - -
Instruction in memory
0x0000 0x0001 0x0002 0x003 0x004 0x005 0x0301
0x01 0x01 0x03 0x3e 0x99 0x02 0x99
LD BC, d16 0x0301 LD A, d8 0x99 LD (BC), A
Data
Instruction
x0 x1 x2 xE
0x 3x
LD BC, d16
3 12
- - - -
NOP
1 4
- - - -
LD (BC), A
1 8
- - - -
Length in bytes
Address
LD A, d8
2 8
- - - -
Instruction in memory
0x0000 0x0001 0x0002 0x003 0x004 0x005 0x0301
0x01 0x01 0x03 0x3e 0x99 0x02 0x99
LD BC, d16 0x0301 LD A, d8 0x99 LD (BC), A
Data
Instruction
x0 x1 x2 xE
0x 3x
LD BC, d16
3 12
- - - -
NOP
1 4
- - - -
LD (BC), A
1 8
- - - -
Duration in cyclesLength in bytes
Address
LD A, d8
2 8
- - - -
Instruction in memory
0x0000 0x0001 0x0002 0x003 0x004 0x005 0x0301
0x01 0x01 0x03 0x3e 0x99 0x02 0x99
LD BC, d16 0x0301 LD A, d8 0x99 LD (BC), A
Data
Instruction
x0 x1 x2 xE
0x 3x
LD BC, d16
3 12
- - - -
NOP
1 4
- - - -
LD (BC), A
1 8
- - - -
Duration in cycles
Flags affected
Length in bytes
Address
LD A, d8
2 8
- - - -
Instruction in memory
0x0000 0x0001 0x0002 0x003 0x004 0x005 0x0301
0x01 0x01 0x03 0x3e 0x99 0x02 0x99
LD BC, d16 0x0301 LD A, d8 0x99 LD (BC), A
Data
Instruction
x0 x1 x2 xE
0x 3x
LD BC, d16
3 12
- - - -
NOP
1 4
- - - -
LD (BC), A
1 8
- - - -
Address
LD A, d8
2 8
- - - -
Instruction in memory
0x0000 0x0001 0x0002 0x003 0x004 0x005 0x0301
0x01 0x01 0x03 0x3e 0x99 0x02 0x99
LD BC, d16 0x0301 LD A, d8 0x99 LD (BC), A
Data
Instruction
x0 x1 x2 xE
0x 3x
LD BC, d16
3 12
- - - -
NOP
1 4
- - - -
LD (BC), A
1 8
- - - -
Address
LD A, d8
2 8
- - - -
PC (Program Counter)
Instruction in memory
0x0000 0x0001 0x0002 0x003 0x004 0x005 0x0301
0x01 0x01 0x03 0x3e 0x99 0x02 0x99
LD BC, d16 0x0301 LD A, d8 0x99 LD (BC), A
Data
Instruction
Load 0x0301 into BC resistor
x0 x1 x2 xE
0x 3x
LD BC, d16
3 12
- - - -
NOP
1 4
- - - -
LD (BC), A
1 8
- - - -
Address
LD A, d8
2 8
- - - -
PC (Program Counter)
Instruction in memory
0x0000 0x0001 0x0002 0x003 0x004 0x005 0x0301
0x01 0x01 0x03 0x3e 0x99 0x02 0x99
LD BC, d16 0x0301 LD A, d8 0x99 LD (BC), A
Data
Instruction
x0 x1 x2 xE
0x 3x
LD BC, d16
3 12
- - - -
NOP
1 4
- - - -
LD (BC), A
1 8
- - - -
Address
LD A, d8
2 8
- - - -
PC (Program Counter)
Instruction in memory
0x0000 0x0001 0x0002 0x003 0x004 0x005 0x0301
0x01 0x01 0x03 0x3e 0x99 0x02 0x99
LD BC, d16 0x0301 LD A, d8 0x99 LD (BC), A
Data
Instruction
x0 x1 x2 xE
0x 3x
LD BC, d16
3 12
- - - -
NOP
1 4
- - - -
LD (BC), A
1 8
- - - -
Address
LD A, d8
2 8
- - - -
Load 0x99 into A resistor
PC (Program Counter)
Instruction in memory
0x0000 0x0001 0x0002 0x003 0x004 0x005 0x0301
0x01 0x01 0x03 0x3e 0x99 0x02 0x99
LD BC, d16 0x0301 LD A, d8 0x99 LD (BC), A
Data
Instruction
x0 x1 x2 xE
0x 3x
LD BC, d16
3 12
- - - -
NOP
1 4
- - - -
LD (BC), A
1 8
- - - -
Address
LD A, d8
2 8
- - - -
PC (Program Counter)
Instruction in memory
0x0000 0x0001 0x0002 0x003 0x004 0x005 0x0301
0x01 0x01 0x03 0x3e 0x99 0x02 0x99
LD BC, d16 0x0301 LD A, d8 0x99 LD (BC), A
Data
Instruction
Load A resistor’s value into memory
indicates with BC resistor
x0 x1 x2 xE
0x 3x
LD BC, d16
3 12
- - - -
NOP
1 4
- - - -
LD (BC), A
1 8
- - - -
Address
LD A, d8
2 8
- - - -
PC (Program Counter)
CPU - Opcode.php
<?php
namespace GameBoy;
class Opcode
{
public $functionsArray = [];
public function __construct()
{
//NOP
//#0x00:
$this->functionsArray[] = function ($parentObj) {
//Do Nothing...
};
//LD BC, nn
//#0x01:
$this->functionsArray[] = function ($parentObj) {
CPU - Opcode.php
<?php
namespace GameBoy;
class Opcode
{
public $functionsArray = [];
public function __construct()
{
//NOP
//#0x00:
$this->functionsArray[] = function ($parentObj) {
//Do Nothing...
};
//LD BC, nn
//#0x01:
$this->functionsArray[] = function ($parentObj) {
x0 x1 x2
0x
LD BC, d16
3 12
- - - -
NOP
1 4
- - - -
LD (BC), A
1 8
- - - -
CPU - Opcode.php
<?php
namespace GameBoy;
class Opcode
{
public $functionsArray = [];
public function __construct()
{
//NOP
//#0x00:
$this->functionsArray[] = function ($parentObj) {
//Do Nothing...
};
//LD BC, nn
//#0x01:
$this->functionsArray[] = function ($parentObj) {
Implementation of 0x00 NOP
x0 x1 x2
0x
LD BC, d16
3 12
- - - -
NOP
1 4
- - - -
LD (BC), A
1 8
- - - -
CPU - Opcode.php
<?php
namespace GameBoy;
class Opcode
{
public $functionsArray = [];
public function __construct()
{
//NOP
//#0x00:
$this->functionsArray[] = function ($parentObj) {
//Do Nothing...
};
//LD BC, nn
//#0x01:
$this->functionsArray[] = function ($parentObj) {
x0 x1 x2
0x
LD BC, d16
3 12
- - - -
NOP
1 4
- - - -
LD (BC), A
1 8
- - - -
Implementation of 0x01 LD BC, d16
//LD BC, nn
//#0x01:
$this->functionsArray[] = function ($parentObj) {
$parentObj->registerC =
$parentObj->memoryReader[$parentObj->programCounter]($parentObj, $parentObj->programCounter);
$parentObj->registerB =
$parentObj->memoryRead(($parentObj->programCounter + 1) & 0xFFFF);
$parentObj->programCounter = ($parentObj->programCounter + 2) & 0xFFFF;
};
Implementation of LD BC, d16
0x0000 0x0001 0x0002 0x003 0x004 0x005 0x0301
0x01 0x01 0x03 0x3e 0x99 0x02 0x99
LD BC, d16 0x0301 LD A, d8 0x99 LD (BC), A
Data
Instruction
Address
PC (Program Counter)
//LD BC, nn
//#0x01:
$this->functionsArray[] = function ($parentObj) {
$parentObj->registerC =
$parentObj->memoryReader[$parentObj->programCounter]($parentObj, $parentObj->programCounter);
$parentObj->registerB =
$parentObj->memoryRead(($parentObj->programCounter + 1) & 0xFFFF);
$parentObj->programCounter = ($parentObj->programCounter + 2) & 0xFFFF;
};
Implementation of LD BC, d16
0x0000 0x0001 0x0002 0x003 0x004 0x005 0x0301
0x01 0x01 0x03 0x3e 0x99 0x02 0x99
LD BC, d16 0x0301 LD A, d8 0x99 LD (BC), A
Data
Instruction
Address
PC (Program Counter)
C
//LD BC, nn
//#0x01:
$this->functionsArray[] = function ($parentObj) {
$parentObj->registerC =
$parentObj->memoryReader[$parentObj->programCounter]($parentObj, $parentObj->programCounter);
$parentObj->registerB =
$parentObj->memoryRead(($parentObj->programCounter + 1) & 0xFFFF);
$parentObj->programCounter = ($parentObj->programCounter + 2) & 0xFFFF;
};
Implementation of LD BC, d16
0x0000 0x0001 0x0002 0x003 0x004 0x005 0x0301
0x01 0x01 0x03 0x3e 0x99 0x02 0x99
LD BC, d16 0x0301 LD A, d8 0x99 LD (BC), A
Data
Instruction
Address
PC (Program Counter)
B
//LD BC, nn
//#0x01:
$this->functionsArray[] = function ($parentObj) {
$parentObj->registerC =
$parentObj->memoryReader[$parentObj->programCounter]($parentObj, $parentObj->programCounter);
$parentObj->registerB =
$parentObj->memoryRead(($parentObj->programCounter + 1) & 0xFFFF);
$parentObj->programCounter = ($parentObj->programCounter + 2) & 0xFFFF;
};
Implementation of LD BC, d16
0x0000 0x0001 0x0002 0x003 0x004 0x005 0x0301
0x01 0x01 0x03 0x3e 0x99 0x02 0x99
LD BC, d16 0x0301 LD A, d8 0x99 LD (BC), A
Data
Instruction
Address
PC (Program Counter)
Implementation of JP a16
x3
cx
JP a16
3 16
- - - -
Implementation of JP a16
x3
cx
JP a16
3 16
- - - -
Jump to address a16
Implementation of JP a16
x3
cx
JP a16
3 16
- - - -
Jump to address a16
0x0000 0x0001 0x0002
0xc3 0x29 0x03
JP a16 0x0329
Data
Instruction
Address
Implementation of JP a16
x3
cx
JP a16
3 16
- - - -
Jump to address a16
0x0000 0x0001 0x0002
0xc3 0x29 0x03
JP a16 0x0329
Data
Instruction
Address
Jump to address 0x0329
Implementation of JP a16
x3
cx
JP a16
3 16
- - - -
Jump to address a16
//JP nn
//#0xC3:
$this->functionsArray[] = function ($parentObj) {
$parentObj->programCounter =
($parentObj->memoryRead(($parentObj->programCounter + 1) & 0xFFFF) << 8) +
$parentObj->memoryReader[$parentObj->programCounter]($parentObj, $parentObj->programCounter);
};
0x0000 0x0001 0x0002
0xc3 0x29 0x03
JP a16 0x0329
Data
Instruction
Address
Jump to address 0x0329
Run loop
public function executeIteration()
{
$op = 0;
while ($this->stopEmulator == 0) {
$op = $this->memoryRead($this->programCounter);
$this->programCounter = ($this->programCounter + 1) & 0xFFFF;
$this->CPUTicks = $this->TICKTable[$op];
$this->OPCODE[$op]($this);
$this->updateCore();
}
}
Not difficult
Simple, Easy
Let’s read
php-terminal-gameboy-emulator
Thanks
@tomzoh
WE ARE HIRING
Drupal / Mobile App Engineer

Digital Circus, Inc. Tokyo, Japan
@tomzoh
Links
• https://en.wikipedia.org/wiki/Game_Boy
• http://www.pastraiser.com/cpu/gameboy/gameboy_opcodes.html
• http://gbdev.gg8.se/wiki/articles/The_Cartridge_Header
• http://gameboy.mongenel.com/dmg/asmmemmap.html
More FPS?
PHP5.5.30 OSX Native
FPS: 4
PHP7.0.1 VirtualBox
FPS: 14
Duration in cycles table
<?php
namespace GameBoy;
class TickTables
{
public static $primary = [
//Number of machine cycles for each instruction:
/* 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E, F*/
1, 3, 2, 2, 1, 1, 2, 1, 5, 2, 2, 2, 1, 1, 2, 1, //0
1, 3, 2, 2, 1, 1, 2, 1, 3, 2, 2, 2, 1, 1, 2, 1, //1
2, 3, 2, 2, 1, 1, 2, 1, 2, 2, 2, 2, 1, 1, 2, 1, //2
2, 3, 2, 2, 3, 3, 3, 1, 2, 2, 2, 2, 1, 1, 2, 1, //3
Duration in cycles table
<?php
namespace GameBoy;
class TickTables
{
public static $primary = [
//Number of machine cycles for each instruction:
/* 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E, F*/
1, 3, 2, 2, 1, 1, 2, 1, 5, 2, 2, 2, 1, 1, 2, 1, //0
1, 3, 2, 2, 1, 1, 2, 1, 3, 2, 2, 2, 1, 1, 2, 1, //1
2, 3, 2, 2, 1, 1, 2, 1, 2, 2, 2, 2, 1, 1, 2, 1, //2
2, 3, 2, 2, 3, 3, 3, 1, 2, 2, 2, 2, 1, 1, 2, 1, //3
1 machine cycle = 4 clocks
Duration in cycles table
<?php
namespace GameBoy;
class TickTables
{
public static $primary = [
//Number of machine cycles for each instruction:
/* 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E, F*/
1, 3, 2, 2, 1, 1, 2, 1, 5, 2, 2, 2, 1, 1, 2, 1, //0
1, 3, 2, 2, 1, 1, 2, 1, 3, 2, 2, 2, 1, 1, 2, 1, //1
2, 3, 2, 2, 1, 1, 2, 1, 2, 2, 2, 2, 1, 1, 2, 1, //2
2, 3, 2, 2, 3, 3, 3, 1, 2, 2, 2, 2, 1, 1, 2, 1, //3
1 machine cycle = 4 clocks
x4
cx
CALL NZ,a16
3 24/12
- - - -
Duration in cycles table
<?php
namespace GameBoy;
class TickTables
{
public static $primary = [
//Number of machine cycles for each instruction:
/* 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E, F*/
1, 3, 2, 2, 1, 1, 2, 1, 5, 2, 2, 2, 1, 1, 2, 1, //0
1, 3, 2, 2, 1, 1, 2, 1, 3, 2, 2, 2, 1, 1, 2, 1, //1
2, 3, 2, 2, 1, 1, 2, 1, 2, 2, 2, 2, 1, 1, 2, 1, //2
2, 3, 2, 2, 3, 3, 3, 1, 2, 2, 2, 2, 1, 1, 2, 1, //3
1 machine cycle = 4 clocks
x4
cx
CALL NZ,a16
3 24/12
- - - -Call address a16 if A resistor
is zero. It takes 24 clocks.
5月 チケット販売開始 /トーク募集開始

6月上旬 トーク募集〆切

6月下旬 タイムテーブル決定
iOS Developers Conference Japan 2016
2016.08.20 https://iosdc.jp
スポンサー企業さま、大絶賛募集中

Reading php terminal-gameboy-emulator

  • 1.
  • 2.
    HASEGAWA Tomoki @tomzoh Web /iOS App Development, Rental Kart Race, Beer, IoT crafting, … hasegawa
 tomoki Digital Circus, Inc. Vice-master CTO Tokyo, Japan Interests
  • 3.
    ・ Web Development ・Mobile Apps Development ・ Service ( ) (iOS, Android) (http://appbuilder.jp) Twitter: @tomzoh
  • 4.
  • 5.
  • 6.
  • 7.
    By Transfrom JPEGversion and remove white background. Original by Evan-Amos. - Media:Game-Boy-FL.jpg, Public Domain, https://commons.wikimedia.org/w/index.php?curid=37808150
  • 8.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
    Source Files It’s PHP! We can read it.
  • 20.
    Source Files It’s PHP! Yes, We can! We can read it.
  • 21.
    Source Files It’s PHP! Yes, We can! Yes, We can! We can read it.
  • 22.
  • 23.
    Components of GAMEBOY •CPU / Memory • Display • Sound • Buttons • Communication Port
  • 24.
    Components of GAMEBOY •CPU / Memory • Display • Sound • Buttons • Communication Port
  • 25.
  • 28.
    Buttons - Keyboard.php <?php namespaceGameBoy; class Keyboard { public $core; public $file; public $keyPressing = null; public $started = false; public function __construct(Core $core) { $this->core = $core; exec('stty -icanon'); $this->file = fopen('php://stdin', 'r'); stream_set_blocking($this->file, false); } public function check() {
  • 29.
    Buttons - Keyboard.php <?php namespaceGameBoy; class Keyboard { public $core; public $file; public $keyPressing = null; public $started = false; public function __construct(Core $core) { $this->core = $core; exec('stty -icanon'); $this->file = fopen('php://stdin', 'r'); stream_set_blocking($this->file, false); } public function check() {
  • 30.
    How to sensebuttons
  • 31.
    How to sensebuttons $this->file = fopen('php://stdin', 'r');
  • 32.
    How to sensebuttons $this->file = fopen('php://stdin', 'r'); $key = fread($this->file, 1);
  • 33.
  • 34.
  • 35.
  • 36.
    SHARP LR35902 instructionset http://www.pastraiser.com/cpu/gameboy/gameboy_opcodes.html 1byte instructions Prefix CB instructions 144 instructions 256 instructions+ = 400 instructions
  • 37.
    SHARP LR35902 resistors http://www.pastraiser.com/cpu/gameboy/gameboy_opcodes.html 15… 8 7 … 0 A F B C H L 15 … 8 7 … 0 SP (Stack Pointer) PC (Program Counter) 8bit / 16bit resistors 16bit resistors Flag registor 7 6 5 4 3 2 1 0 Z N H C 0 0 0 0 •Z - Zero Flag •N - Subtract Flag •H - Half Carry Flag •C - Carry Flag •0 - Not uses, always zero
  • 38.
    Instruction in memory 0x00000x0001 0x0002 0x003 0x004 0x005 0x0301 0x01 0x01 0x03 0x3e 0x99 0x02 0x99 LD BC, d16 0x0301 LD A, d8 0x99 LD (BC), A Data Instruction x0 x1 x2 xE 0x 3x LD BC, d16 3 12 - - - - NOP 1 4 - - - - LD (BC), A 1 8 - - - - Address LD A, d8 2 8 - - - -
  • 39.
    Instruction in memory 0x00000x0001 0x0002 0x003 0x004 0x005 0x0301 0x01 0x01 0x03 0x3e 0x99 0x02 0x99 LD BC, d16 0x0301 LD A, d8 0x99 LD (BC), A Data Instruction x0 x1 x2 xE 0x 3x LD BC, d16 3 12 - - - - NOP 1 4 - - - - LD (BC), A 1 8 - - - - Length in bytes Address LD A, d8 2 8 - - - -
  • 40.
    Instruction in memory 0x00000x0001 0x0002 0x003 0x004 0x005 0x0301 0x01 0x01 0x03 0x3e 0x99 0x02 0x99 LD BC, d16 0x0301 LD A, d8 0x99 LD (BC), A Data Instruction x0 x1 x2 xE 0x 3x LD BC, d16 3 12 - - - - NOP 1 4 - - - - LD (BC), A 1 8 - - - - Duration in cyclesLength in bytes Address LD A, d8 2 8 - - - -
  • 41.
    Instruction in memory 0x00000x0001 0x0002 0x003 0x004 0x005 0x0301 0x01 0x01 0x03 0x3e 0x99 0x02 0x99 LD BC, d16 0x0301 LD A, d8 0x99 LD (BC), A Data Instruction x0 x1 x2 xE 0x 3x LD BC, d16 3 12 - - - - NOP 1 4 - - - - LD (BC), A 1 8 - - - - Duration in cycles Flags affected Length in bytes Address LD A, d8 2 8 - - - -
  • 42.
    Instruction in memory 0x00000x0001 0x0002 0x003 0x004 0x005 0x0301 0x01 0x01 0x03 0x3e 0x99 0x02 0x99 LD BC, d16 0x0301 LD A, d8 0x99 LD (BC), A Data Instruction x0 x1 x2 xE 0x 3x LD BC, d16 3 12 - - - - NOP 1 4 - - - - LD (BC), A 1 8 - - - - Address LD A, d8 2 8 - - - -
  • 43.
    Instruction in memory 0x00000x0001 0x0002 0x003 0x004 0x005 0x0301 0x01 0x01 0x03 0x3e 0x99 0x02 0x99 LD BC, d16 0x0301 LD A, d8 0x99 LD (BC), A Data Instruction x0 x1 x2 xE 0x 3x LD BC, d16 3 12 - - - - NOP 1 4 - - - - LD (BC), A 1 8 - - - - Address LD A, d8 2 8 - - - - PC (Program Counter)
  • 44.
    Instruction in memory 0x00000x0001 0x0002 0x003 0x004 0x005 0x0301 0x01 0x01 0x03 0x3e 0x99 0x02 0x99 LD BC, d16 0x0301 LD A, d8 0x99 LD (BC), A Data Instruction Load 0x0301 into BC resistor x0 x1 x2 xE 0x 3x LD BC, d16 3 12 - - - - NOP 1 4 - - - - LD (BC), A 1 8 - - - - Address LD A, d8 2 8 - - - - PC (Program Counter)
  • 45.
    Instruction in memory 0x00000x0001 0x0002 0x003 0x004 0x005 0x0301 0x01 0x01 0x03 0x3e 0x99 0x02 0x99 LD BC, d16 0x0301 LD A, d8 0x99 LD (BC), A Data Instruction x0 x1 x2 xE 0x 3x LD BC, d16 3 12 - - - - NOP 1 4 - - - - LD (BC), A 1 8 - - - - Address LD A, d8 2 8 - - - - PC (Program Counter)
  • 46.
    Instruction in memory 0x00000x0001 0x0002 0x003 0x004 0x005 0x0301 0x01 0x01 0x03 0x3e 0x99 0x02 0x99 LD BC, d16 0x0301 LD A, d8 0x99 LD (BC), A Data Instruction x0 x1 x2 xE 0x 3x LD BC, d16 3 12 - - - - NOP 1 4 - - - - LD (BC), A 1 8 - - - - Address LD A, d8 2 8 - - - - Load 0x99 into A resistor PC (Program Counter)
  • 47.
    Instruction in memory 0x00000x0001 0x0002 0x003 0x004 0x005 0x0301 0x01 0x01 0x03 0x3e 0x99 0x02 0x99 LD BC, d16 0x0301 LD A, d8 0x99 LD (BC), A Data Instruction x0 x1 x2 xE 0x 3x LD BC, d16 3 12 - - - - NOP 1 4 - - - - LD (BC), A 1 8 - - - - Address LD A, d8 2 8 - - - - PC (Program Counter)
  • 48.
    Instruction in memory 0x00000x0001 0x0002 0x003 0x004 0x005 0x0301 0x01 0x01 0x03 0x3e 0x99 0x02 0x99 LD BC, d16 0x0301 LD A, d8 0x99 LD (BC), A Data Instruction Load A resistor’s value into memory indicates with BC resistor x0 x1 x2 xE 0x 3x LD BC, d16 3 12 - - - - NOP 1 4 - - - - LD (BC), A 1 8 - - - - Address LD A, d8 2 8 - - - - PC (Program Counter)
  • 51.
    CPU - Opcode.php <?php namespaceGameBoy; class Opcode { public $functionsArray = []; public function __construct() { //NOP //#0x00: $this->functionsArray[] = function ($parentObj) { //Do Nothing... }; //LD BC, nn //#0x01: $this->functionsArray[] = function ($parentObj) {
  • 52.
    CPU - Opcode.php <?php namespaceGameBoy; class Opcode { public $functionsArray = []; public function __construct() { //NOP //#0x00: $this->functionsArray[] = function ($parentObj) { //Do Nothing... }; //LD BC, nn //#0x01: $this->functionsArray[] = function ($parentObj) { x0 x1 x2 0x LD BC, d16 3 12 - - - - NOP 1 4 - - - - LD (BC), A 1 8 - - - -
  • 53.
    CPU - Opcode.php <?php namespaceGameBoy; class Opcode { public $functionsArray = []; public function __construct() { //NOP //#0x00: $this->functionsArray[] = function ($parentObj) { //Do Nothing... }; //LD BC, nn //#0x01: $this->functionsArray[] = function ($parentObj) { Implementation of 0x00 NOP x0 x1 x2 0x LD BC, d16 3 12 - - - - NOP 1 4 - - - - LD (BC), A 1 8 - - - -
  • 54.
    CPU - Opcode.php <?php namespaceGameBoy; class Opcode { public $functionsArray = []; public function __construct() { //NOP //#0x00: $this->functionsArray[] = function ($parentObj) { //Do Nothing... }; //LD BC, nn //#0x01: $this->functionsArray[] = function ($parentObj) { x0 x1 x2 0x LD BC, d16 3 12 - - - - NOP 1 4 - - - - LD (BC), A 1 8 - - - - Implementation of 0x01 LD BC, d16
  • 55.
    //LD BC, nn //#0x01: $this->functionsArray[]= function ($parentObj) { $parentObj->registerC = $parentObj->memoryReader[$parentObj->programCounter]($parentObj, $parentObj->programCounter); $parentObj->registerB = $parentObj->memoryRead(($parentObj->programCounter + 1) & 0xFFFF); $parentObj->programCounter = ($parentObj->programCounter + 2) & 0xFFFF; }; Implementation of LD BC, d16 0x0000 0x0001 0x0002 0x003 0x004 0x005 0x0301 0x01 0x01 0x03 0x3e 0x99 0x02 0x99 LD BC, d16 0x0301 LD A, d8 0x99 LD (BC), A Data Instruction Address PC (Program Counter)
  • 56.
    //LD BC, nn //#0x01: $this->functionsArray[]= function ($parentObj) { $parentObj->registerC = $parentObj->memoryReader[$parentObj->programCounter]($parentObj, $parentObj->programCounter); $parentObj->registerB = $parentObj->memoryRead(($parentObj->programCounter + 1) & 0xFFFF); $parentObj->programCounter = ($parentObj->programCounter + 2) & 0xFFFF; }; Implementation of LD BC, d16 0x0000 0x0001 0x0002 0x003 0x004 0x005 0x0301 0x01 0x01 0x03 0x3e 0x99 0x02 0x99 LD BC, d16 0x0301 LD A, d8 0x99 LD (BC), A Data Instruction Address PC (Program Counter) C
  • 57.
    //LD BC, nn //#0x01: $this->functionsArray[]= function ($parentObj) { $parentObj->registerC = $parentObj->memoryReader[$parentObj->programCounter]($parentObj, $parentObj->programCounter); $parentObj->registerB = $parentObj->memoryRead(($parentObj->programCounter + 1) & 0xFFFF); $parentObj->programCounter = ($parentObj->programCounter + 2) & 0xFFFF; }; Implementation of LD BC, d16 0x0000 0x0001 0x0002 0x003 0x004 0x005 0x0301 0x01 0x01 0x03 0x3e 0x99 0x02 0x99 LD BC, d16 0x0301 LD A, d8 0x99 LD (BC), A Data Instruction Address PC (Program Counter) B
  • 58.
    //LD BC, nn //#0x01: $this->functionsArray[]= function ($parentObj) { $parentObj->registerC = $parentObj->memoryReader[$parentObj->programCounter]($parentObj, $parentObj->programCounter); $parentObj->registerB = $parentObj->memoryRead(($parentObj->programCounter + 1) & 0xFFFF); $parentObj->programCounter = ($parentObj->programCounter + 2) & 0xFFFF; }; Implementation of LD BC, d16 0x0000 0x0001 0x0002 0x003 0x004 0x005 0x0301 0x01 0x01 0x03 0x3e 0x99 0x02 0x99 LD BC, d16 0x0301 LD A, d8 0x99 LD (BC), A Data Instruction Address PC (Program Counter)
  • 59.
    Implementation of JPa16 x3 cx JP a16 3 16 - - - -
  • 60.
    Implementation of JPa16 x3 cx JP a16 3 16 - - - - Jump to address a16
  • 61.
    Implementation of JPa16 x3 cx JP a16 3 16 - - - - Jump to address a16 0x0000 0x0001 0x0002 0xc3 0x29 0x03 JP a16 0x0329 Data Instruction Address
  • 62.
    Implementation of JPa16 x3 cx JP a16 3 16 - - - - Jump to address a16 0x0000 0x0001 0x0002 0xc3 0x29 0x03 JP a16 0x0329 Data Instruction Address Jump to address 0x0329
  • 63.
    Implementation of JPa16 x3 cx JP a16 3 16 - - - - Jump to address a16 //JP nn //#0xC3: $this->functionsArray[] = function ($parentObj) { $parentObj->programCounter = ($parentObj->memoryRead(($parentObj->programCounter + 1) & 0xFFFF) << 8) + $parentObj->memoryReader[$parentObj->programCounter]($parentObj, $parentObj->programCounter); }; 0x0000 0x0001 0x0002 0xc3 0x29 0x03 JP a16 0x0329 Data Instruction Address Jump to address 0x0329
  • 64.
    Run loop public functionexecuteIteration() { $op = 0; while ($this->stopEmulator == 0) { $op = $this->memoryRead($this->programCounter); $this->programCounter = ($this->programCounter + 1) & 0xFFFF; $this->CPUTicks = $this->TICKTable[$op]; $this->OPCODE[$op]($this); $this->updateCore(); } }
  • 65.
  • 66.
  • 67.
    Thanks @tomzoh WE ARE HIRING Drupal/ Mobile App Engineer
 Digital Circus, Inc. Tokyo, Japan @tomzoh
  • 68.
    Links • https://en.wikipedia.org/wiki/Game_Boy • http://www.pastraiser.com/cpu/gameboy/gameboy_opcodes.html •http://gbdev.gg8.se/wiki/articles/The_Cartridge_Header • http://gameboy.mongenel.com/dmg/asmmemmap.html
  • 69.
    More FPS? PHP5.5.30 OSXNative FPS: 4 PHP7.0.1 VirtualBox FPS: 14
  • 70.
    Duration in cyclestable <?php namespace GameBoy; class TickTables { public static $primary = [ //Number of machine cycles for each instruction: /* 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E, F*/ 1, 3, 2, 2, 1, 1, 2, 1, 5, 2, 2, 2, 1, 1, 2, 1, //0 1, 3, 2, 2, 1, 1, 2, 1, 3, 2, 2, 2, 1, 1, 2, 1, //1 2, 3, 2, 2, 1, 1, 2, 1, 2, 2, 2, 2, 1, 1, 2, 1, //2 2, 3, 2, 2, 3, 3, 3, 1, 2, 2, 2, 2, 1, 1, 2, 1, //3
  • 71.
    Duration in cyclestable <?php namespace GameBoy; class TickTables { public static $primary = [ //Number of machine cycles for each instruction: /* 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E, F*/ 1, 3, 2, 2, 1, 1, 2, 1, 5, 2, 2, 2, 1, 1, 2, 1, //0 1, 3, 2, 2, 1, 1, 2, 1, 3, 2, 2, 2, 1, 1, 2, 1, //1 2, 3, 2, 2, 1, 1, 2, 1, 2, 2, 2, 2, 1, 1, 2, 1, //2 2, 3, 2, 2, 3, 3, 3, 1, 2, 2, 2, 2, 1, 1, 2, 1, //3 1 machine cycle = 4 clocks
  • 72.
    Duration in cyclestable <?php namespace GameBoy; class TickTables { public static $primary = [ //Number of machine cycles for each instruction: /* 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E, F*/ 1, 3, 2, 2, 1, 1, 2, 1, 5, 2, 2, 2, 1, 1, 2, 1, //0 1, 3, 2, 2, 1, 1, 2, 1, 3, 2, 2, 2, 1, 1, 2, 1, //1 2, 3, 2, 2, 1, 1, 2, 1, 2, 2, 2, 2, 1, 1, 2, 1, //2 2, 3, 2, 2, 3, 3, 3, 1, 2, 2, 2, 2, 1, 1, 2, 1, //3 1 machine cycle = 4 clocks x4 cx CALL NZ,a16 3 24/12 - - - -
  • 73.
    Duration in cyclestable <?php namespace GameBoy; class TickTables { public static $primary = [ //Number of machine cycles for each instruction: /* 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E, F*/ 1, 3, 2, 2, 1, 1, 2, 1, 5, 2, 2, 2, 1, 1, 2, 1, //0 1, 3, 2, 2, 1, 1, 2, 1, 3, 2, 2, 2, 1, 1, 2, 1, //1 2, 3, 2, 2, 1, 1, 2, 1, 2, 2, 2, 2, 1, 1, 2, 1, //2 2, 3, 2, 2, 3, 3, 3, 1, 2, 2, 2, 2, 1, 1, 2, 1, //3 1 machine cycle = 4 clocks x4 cx CALL NZ,a16 3 24/12 - - - -Call address a16 if A resistor is zero. It takes 24 clocks.
  • 74.
    5月 チケット販売開始 /トーク募集開始
 6月上旬トーク募集〆切
 6月下旬 タイムテーブル決定 iOS Developers Conference Japan 2016 2016.08.20 https://iosdc.jp スポンサー企業さま、大絶賛募集中