The document discusses a PHP implementation of a Game Boy emulator that runs in the terminal. It explains how the emulator works, including how it simulates the Game Boy's CPU, memory, display, sound, buttons and communication port in PHP code. It provides code examples for emulating the CPU instructions and reading button input from the keyboard.
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
7. 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
28. 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()
{
29. 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()
{
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
48. 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)
49.
50.
51. 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) {
52. 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
- - - -
53. 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
- - - -
54. 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
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)