Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Learning Computer Architecture Using php-terminal-gameboy-emulator

Learning Computer Architecture Using php-terminal-gameboy-emulator

PHP勉強会 #100の発表資料です。

HASEGAWA Tomoki

March 30, 2016
Tweet

More Decks by HASEGAWA Tomoki

Other Decks in Technology

Transcript

  1. 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
  2. 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
  3. 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
  4. Common CPU architecture • Registers
 レジスタ • Memory Access
 メモリアクセス

    • Program Counter
 プログラムカウンタ • Instruction Set
 命令セット • I/O Access, Interrupt
 I/Oアクセス, 割り込み
  5. 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
  6. 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
  7. 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ビットレジスタとしても使える。
  8. 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
  9. 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.
 命令が読み込まれるとプログラムカウンタの値は加算され、次の命令のアドレスを指 す。
  10. 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ではかけ算や割り算命令も無 い。
  11. 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レジスタの内容を 入れる。
  12. 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番地にジャンプする。
  13. 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
  14. 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
  15. 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)
  16. 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)
  17. 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)
  18. 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) { };
  19. 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 命令の実装
  20. 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 命令の実装
  21. 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 命令の実装
  22. 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 命令の実装
  23. //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)
  24. //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
  25. //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
  26. //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)
  27. Implementation of JP a16 0x0000 0x0001 0x0002 0xc3 0x29 0x03

    JP a16 0x0329 Data Instruction Address PC (Program Counter)
  28. Implementation of JP a16 0x0000 0x0001 0x0002 0xc3 0x29 0x03

    JP a16 0x0329 Data Instruction Address Jump to address 0x0329 PC (Program Counter)
  29. 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)
  30. Thanks @tomzoh WE ARE HIRING Drupal / Mobile App Engineer


    Digital Circus, Inc. Tokyo, Japan @tomzoh
  31. 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(); } }
  32. 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”
  33. 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
  34. 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
  35. 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 - - - -
  36. 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.