reading php terminal-gameboy-emulator

Post on 14-Apr-2017

2.944 Views

Category:

Software

0 Downloads

Preview:

Click to see full reader

TRANSCRIPT

Reading php-terminal-gameboy-emulator

Digital Circus, Inc. HASEGAWA Tomki

HASEGAWA Tomoki

@tomzoh

Web / iOS App Development,

Rental Kart Race, Beer, IoT crafting, …

hasegawatomoki

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() { $key = fread($this->file, 1);

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() { $key = fread($this->file, 1);

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 … 0A FB CH L

15 … 8 7 … 0SP (Stack Pointer)

PC (Program Counter)

8bit / 16bit resistors

16bit resistors

Flag registor

7 6 5 4 3 2 1 0Z 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 3xLD 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 3xLD 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 3xLD 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 3xLD 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 3xLD 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 3xLD 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 3xLD 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 3xLD 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 3xLD 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 3xLD 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 3xLD 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

0xLD 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

0xLD 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

0xLD 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

cxJP a16 3 16 - - - -

Implementation of JP a16

x3

cxJP a16 3 16 - - - -

Jump to address a16

Implementation of JP a16

x3

cxJP a16 3 16 - - - -

Jump to address a16

0x0000 0x0001 0x0002

0xc3 0x29 0x03

JP a16 0x0329

Data

Instruction

Address

Implementation of JP a16

x3

cxJP 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

cxJP 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 looppublic 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 EngineerDigital 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

cxCALL 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

cxCALL 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

スポンサー企業さま、大絶賛募集中

top related