Share
Embed
Learning Computer Architecture Using php-terminal-gameboy-emulator
PHP勉強会 #100の発表資料です。
HASEGAWA Tomoki
March 30, 2016
Transcript
78 slides
-
勉強会 • 楽しみましょう! • 今年はPHPカンファレンスが、北海道、福岡、関西、東京 都開催されます。 • 普段の勉強会とはまた違った楽しみが! • 遠征ならではの楽しさも!長谷川全通予定。
• お友達がいるとより楽しいので是非PHP勉強会でお友達を 作ってみてください。 -
HASEGAWA Tomoki @tomzoh Web / Mobile App Development, Watch soccer
matches, Rental Kart Racing, Beer, IoT, … hasegawa tomoki Digital Circus, Inc. Vice-master CTO Tokyo, Japan Interests -
ɾ 8FC%FWFMPQNFOU ɾ .PCJMF"QQ%FWFMPQNFOU ɾ 4FSWJDF ʢʣ ʢJ04 "OESPJE
ʢIUUQBQQCVJMEFSKQʣ 5XJUUFS!UPN[PI -
Source Files OMG. It’s PHP ! Yes, We can! We
can read it. -
Source Files OMG. It’s PHP ! Yes, We can! Yes,
We can! We can read it. -
Components of GAMEBOY • CPU / Memory • Display •
Sound • Buttons • Communication Port • ROM Cartridge #Z5SBOTGSPN+1&(WFSTJPOBOESFNPWFXIJUFCBDLHSPVOE0SJHJOBMCZ&WBO"NPT.FEJB(BNF#PZ'-KQH 1VCMJD%PNBJO IUUQTDPNNPOTXJLJNFEJBPSHXJOEFYQIQ DVSJE -
Components of GAMEBOY • CPU / Memory • Display •
Sound • Buttons • Communication Port • ROM Cartridge #Z5SBOTGSPN+1&(WFSTJPOBOESFNPWFXIJUFCBDLHSPVOE0SJHJOBMCZ&WBO"NPT.FEJB(BNF#PZ'-KQH 1VCMJD%PNBJO IUUQTDPNNPOTXJLJNFEJBPSHXJOEFYQIQ DVSJE -
Common CPU architecture • Registers レジスタ • Memory Access メモリアクセス
• Program Counter プログラムカウンタ • Instruction Set 命令セット • I/O Access, Interrupt I/Oアクセス, 割り込み -
Memory Access メモリアクセス • Memory stores data including program. メモリには命令を含むデータが格納される。
• Each data is 8bit value and has address. The address is represented as hex value. それぞれのデータは8bit=1byteの値で、16進数で表現されるアドレスを持つ。 IUUQXXXNKDOOFUKQQPUBGVMMNTYNPOIUNM -
Memory Access メモリアクセス • Memory stores data including program. メモリには命令を含むデータが格納される。
• Each data is 8bit value and has address. The address is represented as hex value. それぞれのデータは8bit=1byteの値で、16進数で表現されるアドレスを持つ。 IUUQXXXNKDOOFUKQQPUBGVMMNTYNPOIUNM -
Registers レジスタ • Variables in programing language. プログラム言語で言うところの変数。 • Stores
only integer value. 整数値のみ格納可能。 • LR35902 has 7 8bit registers and 2 16bit registers. LR35902は7つの8bitレジスタと2つの16ビットレジスタを持っている。 • 8bit registers of LR35902 can be used as 16bit register. LR35902の8bitレジスタは16ビットレジスタとしても使える。 -
SHARP LR35902 registers http://www.pastraiser.com/cpu/gameboy/gameboy_opcodes.html ʜ ʜ " ' # $
) - ʜ ʜ 41 4UBDL1PJOUFS 1$ 1SPHSBN$PVOUFS 8bit / 16bit registers 16bit registers Flag register ; / ) $ •Z - Zero Flag •N - Subtract Flag •H - Half Carry Flag •C - Carry Flag •0 - Not uses, always zero -
Program Counter プログラムカウンタ • A special register that contains the
address of the instruction being executed now. 現在実行中の命令のアドレスを指す特殊なレジスタ。 • As each instruction gets fetched, the program counter incremented, and holds the memory address of the next instruction. 命令が読み込まれるとプログラムカウンタの値は加算され、次の命令のアドレスを指 す。 -
Instruction Set 命令セット • Only primitive instructions. CPUは通常原始的な命令しか持たない。 • Instruction
set: load a value into register, jump, conditional jump etc. レジスタに値を入れる、ジャンプする、条件付きでジャンプする、などの命令の集合。 • No functions, No loops. Some CPU including LR35902 has no multiplication / division. 関数やループ命令は無い。LR35902を含むいくつかのCPUではかけ算や割り算命令も無 い。 -
SHARP LR35902 instruction set http://www.pastraiser.com/cpu/gameboy/gameboy_opcodes.html 1byte instructions Prefix CB instructions
243 instructions 256 instructions + = 499 instructions -
LR35902 instruction - LD LD BC, 0x1234 Load 0x1234 into
BC register. BCレジスタに0x1234を入れる。 LD (BC), A Load a value A register has into memory BC register points at. BCレジスタの指し示すメモリアドレスにAレジスタの内容を 入れる。 -
LR35902 instruction - JP / JR JP 0x5678 Jump to
address 0x5678. 0x5678番地にジャンプする。 JR C,0x20 Jump to calculated address with respect to itself if carry flag is set. 前の命令でキャリーフラグがセットされていれば現在の番地 +0x20番地にジャンプする。 -
Assembler / Machine Code 38 27 2A 28 B6 7C
B7 20 11 CD E1 1C 30 1B JR C, 0x27 LD HL, (0xB628) LD A,H OR A JR NZ, 0x11 CALL 0x1CE1 JR NC, 0x1B 38 27 2A 28 B6 7C B7 20 11 CD E1 1C 30 1B -
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 Memory Instruction x0 x1 x2 xE 0x 3x 0x01 LD BC, d16 0x00 NOP 0x02 LD (BC), A Address 0x3e LD A, d8 -
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 Memory Instruction Load 0x0301 into BC register x0 x1 x2 xE 0x 3x 0x01 LD BC, d16 0x00 NOP 0x02 LD (BC), A Address 0x3e LD A, d8 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 Memory Instruction x0 x1 x2 xE 0x 3x 0x01 LD BC, d16 0x00 NOP 0x02 LD (BC), A Address 0x3e LD A, d8 Load 0x99 into A register 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 Memory Instruction Load A register’s value into memory indicates with BC register x0 x1 x2 xE 0x 3x 0x01 LD BC, d16 0x00 NOP 0x02 LD (BC), A Address 0x3e LD A, d8 PC (Program Counter) -
CPU - Opcode.php class Opcode { public $functionsArray = [];
public function __construct() { //NOP //#0x00: $this->functionsArray[] = function ($parentObj) { }; //LD BC, nn //#0x01: $this->functionsArray[] = function ($parentObj) { }; //LD (BC), A //#0x02: $this->functionsArray[] = function ($parentObj) { }; -
CPU - Opcode.php class Opcode { public $functionsArray = [];
public function __construct() { //NOP //#0x00: $this->functionsArray[] = function ($parentObj) { }; //LD BC, nn //#0x01: $this->functionsArray[] = function ($parentObj) { }; //LD (BC), A //#0x02: $this->functionsArray[] = function ($parentObj) { }; Implementation of instructions 命令の実装 -
CPU - Opcode.php class Opcode { public $functionsArray = [];
public function __construct() { //NOP //#0x00: $this->functionsArray[] = function ($parentObj) { }; //LD BC, nn //#0x01: $this->functionsArray[] = function ($parentObj) { }; //LD (BC), A //#0x02: $this->functionsArray[] = function ($parentObj) { }; 0x00 NOP Implementation of instructions 命令の実装 -
CPU - Opcode.php class Opcode { public $functionsArray = [];
public function __construct() { //NOP //#0x00: $this->functionsArray[] = function ($parentObj) { }; //LD BC, nn //#0x01: $this->functionsArray[] = function ($parentObj) { }; //LD (BC), A //#0x02: $this->functionsArray[] = function ($parentObj) { }; 0x01 LD BC, d16 Implementation of instructions 命令の実装 -
CPU - Opcode.php class Opcode { public $functionsArray = [];
public function __construct() { //NOP //#0x00: $this->functionsArray[] = function ($parentObj) { }; //LD BC, nn //#0x01: $this->functionsArray[] = function ($parentObj) { }; //LD (BC), A //#0x02: $this->functionsArray[] = function ($parentObj) { }; 0x02 LD (BC), A Implementation of instructions 命令の実装 -
//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 0x01 0x01 0x03 0x3e 0x99 LD BC, d16 0x0301 LD A, d8 0x99 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 0x01 0x01 0x03 0x3e 0x99 LD BC, d16 0x0301 LD A, d8 0x99 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 0x01 0x01 0x03 0x3e 0x99 LD BC, d16 0x0301 LD A, d8 0x99 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 0x01 0x01 0x03 0x3e 0x99 LD BC, d16 0x0301 LD A, d8 0x99 Data Instruction Address PC (Program Counter) -
Implementation of JP a16 0x0000 0x0001 0x0002 0xc3 0x29 0x03
JP a16 0x0329 Data Instruction Address PC (Program Counter) -
Implementation of JP a16 0x0000 0x0001 0x0002 0xc3 0x29 0x03
JP a16 0x0329 Data Instruction Address Jump to address 0x0329 PC (Program Counter) -
Implementation of JP 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 PC (Program Counter) -
Thanks @tomzoh WE ARE HIRING Drupal / Mobile App Engineer
Digital Circus, Inc. Tokyo, Japan @tomzoh -
Thanks @tomzoh WE ARE HIRING Drupal / Mobile App Engineer
Digital Circus, Inc. Tokyo, Japan -
5月 チケット販売開始 /トーク募集開始 6月上旬 トーク募集〆切 6月下旬 タイムテーブル決定 iOS Developers Conference
Japan 2016 2016.08.20 https://iosdc.jp スポンサー企業さま、大絶賛募集中 -
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(); } } -
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 -
SHARP LR35902 registers http://www.pastraiser.com/cpu/gameboy/gameboy_opcodes.html ʜ ʜ " ' # $
) - ʜ ʜ 41 4UBDL1PJOUFS 1$ 1SPHSBN$PVOUFS 8bit / 16bit registers 16bit registers Flag registor ; / ) $ •Z - Zero Flag •N - Subtract Flag •H - Half Carry Flag •C - Carry Flag •0 - Not uses, always zero “stack overflow” -
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 register is zero. It takes 24 clocks.