PHPで学ぶ コンピュータアーキテクチャ / Learning: computer architecture with PHP

PHPで学ぶ コンピュータアーキテクチャ / Learning: computer architecture with PHP

PHPカンファレンス関西2016の発表資料です

40575ebf9c2f4a6e3bcb68630f446a3b?s=128

HASEGAWA Tomoki

July 16, 2016
Tweet

Transcript

  1. PHPで学ぶ コンピュータアーキテクチャ Learning: computer architecture with PHP 長谷川智希 HASEGAWA Tomoki

  2. この資料は後ほど公開します This slide will be published later.

  3. はじめに Introduction

  4. このトークの内容 Contents of this talk

  5. 今風のカッコいいPHPの書き方 Modern style PHP coding.

  6. 今風のカッコいいPHPの書き方 Modern style PHP coding.

  7. 今風のカッコいいPHPの書き方 Modern style PHP coding. クールなライブラリやフレームワーク Cool libraries / frameworks.

  8. 今風のカッコいいPHPの書き方 Modern style PHP coding. クールなライブラリやフレームワーク Cool libraries / frameworks.

  9. 今風のカッコいいPHPの書き方 Modern style PHP coding. クールなライブラリやフレームワーク Cool libraries / frameworks.

    PHPをそんな風に使うのか!という驚き Exciting PHP usage.
  10. 今風のカッコいいPHPの書き方 Modern style PHP coding. クールなライブラリやフレームワーク Cool libraries / frameworks.

    PHPをそんな風に使うのか!という驚き Exciting PHP usage.
  11. 今風のカッコいいPHPの書き方 Modern style PHP coding. クールなライブラリやフレームワーク Cool libraries / frameworks.

    PHPをそんな風に使うのか!という驚き Exciting PHP usage. ゲームボーイの仕様の知識 Knowledge of GAMEBOY specs.
  12. 今風のカッコいいPHPの書き方 Modern style PHP coding. クールなライブラリやフレームワーク Cool libraries / frameworks.

    PHPをそんな風に使うのか!という驚き Exciting PHP usage. ゲームボーイの仕様の知識 Knowledge of GAMEBOY specs.
  13. None
  14. 今日の話: This story,

  15. あまりに話したくてLTでやってみた I tried to talk in LT.

  16. 時間が足りず会場の全員を 置き去り x 2 LT is too short for this

    story, All audience was one lap behind!!
  17. カンファレンスでなら時間が足りる! There is sufficient time if it was conference session!

  18. None
  19. 5/21 福岡公演 FUKUOKA

  20. 5/21 福岡公演 FUKUOKA 7/3 東京公演 TOKYO

  21. 5/21 福岡公演 FUKUOKA 7/16 大阪公演 OSAKA 7/3 東京公演 TOKYO

  22. 大分満足した It was considerably satisfied

  23. 千秋楽公演 It’s a final day of this talk

  24. #phpkansai / ブログ / 懇親会 面白かったら リアクションお願いします!

  25. ライフワーク: Web / iOSアプリ開発, ビール, 電子工作,
 サッカー観戦, レンタルカートレース, … 長谷川

    智希 Web / iOS App Development, Beer, IoT, Watch soccer match, Rental Kart Racing, … デジタルサーカス株式会社 副団長CTO Digital Circus, Inc. Vice-master CTO Tokyo, Japan Lifework: @tomzoh
  26. None
  27. None
  28. WE ARE HIRING!! Web Development Mobile App Development ( )

    (iOS, Android) http://www.dgcircus.com Omotesando, Tokyo
  29. 今日のテーマ Learning: computer architecture with PHP PHPで学ぶ コンピュータアーキテクチャ Today’s theme

  30. 今年2月23日 23, February

  31. None
  32. None
  33. terminal-gameboy-emulator

  34. #Z5SBOTGSPN+1&(WFSTJPOBOESFNPWFXIJUFCBDLHSPVOE0SJHJOBMCZ&WBO"NPT.FEJB(BNF#PZ'-KQH  1VCMJD%PNBJO IUUQTDPNNPOTXJLJNFEJBPSHXJOEFYQIQ DVSJE terminal-gameboy-emulator

  35. #Z5SBOTGSPN+1&(WFSTJPOBOESFNPWFXIJUFCBDLHSPVOE0SJHJOBMCZ&WBO"NPT.FEJB(BNF#PZ'-KQH  1VCMJD%PNBJO IUUQTDPNNPOTXJLJNFEJBPSHXJOEFYQIQ DVSJE terminal-gameboy-emulator

  36. terminal-gameboy-emulator

  37. エミュレータ エミュレータとは、機械装置やコンピュータのハードウェア (PC、ゲーム機など)の構造を、別の装置やソフトウェアで 模倣することで実現させたもの。 In computing, an emulator is hardware

    or software that enables one computer system to behave like another computer system. Emulator terminal-gameboy-emulator
  38. terminal-gameboy-emulator

  39. terminal-gameboy-emulator ??

  40. demo

  41. !?

  42. SUGOI

  43. EXCITING

  44. None
  45. None
  46. It’s

  47. We are er.

  48. WE CAN READ IT!!

  49. None
  50. ゲームボーイのCPU CPU of GAMEBOY

  51. ゲームボーイのCPU CPU of GAMEBOY IUUQTFOXJLJQFEJBPSHXJLJ(BNF@#PZ

  52. ゲームボーイのCPU CPU of GAMEBOY IUUQTFOXJLJQFEJBPSHXJLJ(BNF@#PZ

  53. #Z%SJLOBQBMN౤ߘऀࣗ਎ʹΑΔ࡞඼ $$දࣔܧঝ IUUQTDPNNPOTXJLJNFEJBPSHXJOEFYQIQ DVSJE #Z$$3+1(NPSJLPVEFSJWBUJWFXPSL6CDVMF͜ͷϑΝΠϧͷ೿ੜݩ$$3+1( ύϒϦοΫɾυϝΠϯ IUUQTDPNNPOTXJLJNFEJBPSHXJOEFYQIQ DVSJE #Zʢ:LBUTV UBML

    ʣ:LBUTV UBML TpMF ύϒϦοΫɾυϝΠϯ IUUQTDPNNPOTXJLJNFEJBPSHXJOEFYQIQ DVSJE
  54. #Z%SJLOBQBMN౤ߘऀࣗ਎ʹΑΔ࡞඼ $$දࣔܧঝ IUUQTDPNNPOTXJLJNFEJBPSHXJOEFYQIQ DVSJE #Z$$3+1(NPSJLPVEFSJWBUJWFXPSL6CDVMF͜ͷϑΝΠϧͷ೿ੜݩ$$3+1( ύϒϦοΫɾυϝΠϯ IUUQTDPNNPOTXJLJNFEJBPSHXJOEFYQIQ DVSJE #Zʢ:LBUTV UBML

    ʣ:LBUTV UBML TpMF ύϒϦοΫɾυϝΠϯ IUUQTDPNNPOTXJLJNFEJBPSHXJOEFYQIQ DVSJE
  55. レジスタ Registers Instructions 命令 Memory access and I/O メモリアクセスとI/O

  56. レジスタ Registers Instructions 命令 Memory access and I/O メモリアクセスとI/O

  57. LR35902の命令セット Instruction set of LR35902 http://www.pastraiser.com/cpu/gameboy/gameboy_opcodes.html

  58. LR35902 CPUのプログラム Program of CPU LR35902 +0 +1 +2 +3

    +4 +5 +6 +7 +8 +9 +A +B +C +D +E +F 01E0 01 E0 85 E1 D1 C1 F1 D9 AF 21 FF DF 0E 10 06 00 01F0 32 05 20 FC 0D 20 F9 3E 0D F3 E0 0F E0 FF AF E0 0200 42 E0 43 E0 A4 E0 41 E0 01 E0 02 EA 00 D0 EA 01 0210 D0 3E 80 E0 40 F0 44 FE 94 20 FA 3E 03 E0 40 3E 0220 E1 E0 47 E0 48 3E E5 E0 49 21 26 FF 3E 80 32 3E 0230 FF 32 36 77 21 06 FF 3E BF 22 3E 04 77 3E 01 EA 0240 00 20 31 FF CF AF 21 FF DF 06 00 32 05 20 FC 21 0250 FF CF 0E 10 06 00 32 05 20 FC 0D 20 F9 21 FF 9F 0260 0E 20 AF 06 00 32 05 20 FC 0D 20 F9 21 FF FE 06
  59. プログラムの実行 Program execution +0 +1 +2 +3 +4 +5 +6

    +7 +8 +9 +A +B +C +D +E +F 01E0 01 E0 85 E1 D1 C1 F1 D9 AF 21 FF DF 0E 10 06 00 01F0 32 05 20 FC 0D 20 F9 3E 0D F3 E0 0F E0 FF AF E0
  60. プログラムの実行 Program execution +0 +1 +2 +3 +4 +5 +6

    +7 +8 +9 +A +B +C +D +E +F 01E0 01 E0 85 E1 D1 C1 F1 D9 AF 21 FF DF 0E 10 06 00 01F0 32 05 20 FC 0D 20 F9 3E 0D F3 E0 0F E0 FF AF E0
  61. プログラムの実行 Program execution AF 21 DF FF 0E 10 06

    00 32 05 +0 +1 +2 +3 +4 +5 +6 +7 +8 +9 +A +B +C +D +E +F 01E0 01 E0 85 E1 D1 C1 F1 D9 AF 21 FF DF 0E 10 06 00 01F0 32 05 20 FC 0D 20 F9 3E 0D F3 E0 0F E0 FF AF E0
  62. プログラムの実行 Program execution AF 21 DF FF 0E 10 06

    00 32 05 XOR A LD HL, 0xFFDF LD C, 0x10 LD B, 0x00 LD (HL-), A DEC B +0 +1 +2 +3 +4 +5 +6 +7 +8 +9 +A +B +C +D +E +F 01E0 01 E0 85 E1 D1 C1 F1 D9 AF 21 FF DF 0E 10 06 00 01F0 32 05 20 FC 0D 20 F9 3E 0D F3 E0 0F E0 FF AF E0
  63. プログラムの実行 Program execution AF 21 DF FF 0E 10 06

    00 32 05 XOR A LD HL, 0xFFDF LD C, 0x10 LD B, 0x00 LD (HL-), A DEC B +0 +1 +2 +3 +4 +5 +6 +7 +8 +9 +A +B +C +D +E +F 01E0 01 E0 85 E1 D1 C1 F1 D9 AF 21 FF DF 0E 10 06 00 01F0 32 05 20 FC 0D 20 F9 3E 0D F3 E0 0F E0 FF AF E0 AをAでXOR HLに0xFFDFを入れる Cに0x10を入れる Bに0x00を入れる HLが指すアドレスにAの値を入れる Bを-1する Load 0xffdf into HL XOR A with A Load 0x10 into C Load 0x00 into B Load a value A has into memory address HL points at Decrement B
  64. レジスタ Registers Instructions 命令 Memory access and I/O メモリアクセスとI/O

  65. SHARP LR35902 のレジスタ SHARP LR35902 registers ʜ ʜ " '

    # $ % & ) - ʜ ʜ 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 レジスタ: CPUが持つ、プログラム言語で言う変数 Registers: Variables in programing language.
  66. プログラムカウンタ Program Counter +0 +1 +2 +3 +4 +5 +6

    +7 +8 +9 +A +B +C +D +E +F 01E0 01 E0 85 E1 D1 C1 F1 D9 AF 21 FF DF 0E 10 06 00 01F0 32 05 20 FC 0D 20 F9 3E 0D F3 E0 0F E0 FF AF E0 現在実行中の命令のアドレスを指す特殊なレジスタ。 A special register that contains the address of the instruction being executed now. PC
  67. プログラムカウンタ Program Counter +0 +1 +2 +3 +4 +5 +6

    +7 +8 +9 +A +B +C +D +E +F 01E0 01 E0 85 E1 D1 C1 F1 D9 AF 21 FF DF 0E 10 06 00 01F0 32 05 20 FC 0D 20 F9 3E 0D F3 E0 0F E0 FF AF E0 現在実行中の命令のアドレスを指す特殊なレジスタ。 A special register that contains the address of the instruction being executed now. PC
  68. プログラムカウンタ Program Counter +0 +1 +2 +3 +4 +5 +6

    +7 +8 +9 +A +B +C +D +E +F 01E0 01 E0 85 E1 D1 C1 F1 D9 AF 21 FF DF 0E 10 06 00 01F0 32 05 20 FC 0D 20 F9 3E 0D F3 E0 0F E0 FF AF E0 現在実行中の命令のアドレスを指す特殊なレジスタ。 A special register that contains the address of the instruction being executed now. PC
  69. プログラムカウンタ Program Counter +0 +1 +2 +3 +4 +5 +6

    +7 +8 +9 +A +B +C +D +E +F 01E0 01 E0 85 E1 D1 C1 F1 D9 AF 21 FF DF 0E 10 06 00 01F0 32 05 20 FC 0D 20 F9 3E 0D F3 E0 0F E0 FF AF E0 現在実行中の命令のアドレスを指す特殊なレジスタ。 A special register that contains the address of the instruction being executed now. PC
  70. プログラムカウンタ Program Counter +0 +1 +2 +3 +4 +5 +6

    +7 +8 +9 +A +B +C +D +E +F 01E0 01 E0 85 E1 D1 C1 F1 D9 AF 21 FF DF 0E 10 06 00 01F0 32 05 20 FC 0D 20 F9 3E 0D F3 E0 0F E0 FF AF E0 現在実行中の命令のアドレスを指す特殊なレジスタ。 A special register that contains the address of the instruction being executed now. PC
  71. プログラムカウンタ Program Counter +0 +1 +2 +3 +4 +5 +6

    +7 +8 +9 +A +B +C +D +E +F 01E0 01 E0 85 E1 D1 C1 F1 D9 AF 21 FF DF 0E 10 06 00 01F0 32 05 20 FC 0D 20 F9 3E 0D F3 E0 0F E0 FF AF E0 現在実行中の命令のアドレスを指す特殊なレジスタ。 A special register that contains the address of the instruction being executed now. PC
  72. プログラムカウンタ Program Counter +0 +1 +2 +3 +4 +5 +6

    +7 +8 +9 +A +B +C +D +E +F 01E0 01 E0 85 E1 D1 C1 F1 D9 AF 21 FF DF 0E 10 06 00 01F0 32 05 20 FC 0D 20 F9 3E 0D F3 E0 0F E0 FF AF E0 現在実行中の命令のアドレスを指す特殊なレジスタ。 A special register that contains the address of the instruction being executed now. AF 21 DF FF 0E 10 06 00 32 05 XOR A LD HL, 0xFFDF LD C, 0x10 LD B, 0x00 LD (HL-), A DEC B PC
  73. プログラムカウンタ Program Counter +0 +1 +2 +3 +4 +5 +6

    +7 +8 +9 +A +B +C +D +E +F 01E0 01 E0 85 E1 D1 C1 F1 D9 AF 21 FF DF 0E 10 06 00 01F0 32 05 20 FC 0D 20 F9 3E 0D F3 E0 0F E0 FF AF E0 現在実行中の命令のアドレスを指す特殊なレジスタ。 A special register that contains the address of the instruction being executed now. AF 21 DF FF 0E 10 06 00 32 05 XOR A LD HL, 0xFFDF LD C, 0x10 LD B, 0x00 LD (HL-), A DEC B PC
  74. プログラムカウンタ Program Counter +0 +1 +2 +3 +4 +5 +6

    +7 +8 +9 +A +B +C +D +E +F 01E0 01 E0 85 E1 D1 C1 F1 D9 AF 21 FF DF 0E 10 06 00 01F0 32 05 20 FC 0D 20 F9 3E 0D F3 E0 0F E0 FF AF E0 現在実行中の命令のアドレスを指す特殊なレジスタ。 A special register that contains the address of the instruction being executed now. AF 21 DF FF 0E 10 06 00 32 05 XOR A LD HL, 0xFFDF LD C, 0x10 LD B, 0x00 LD (HL-), A DEC B PC
  75. プログラムカウンタ Program Counter +0 +1 +2 +3 +4 +5 +6

    +7 +8 +9 +A +B +C +D +E +F 01E0 01 E0 85 E1 D1 C1 F1 D9 AF 21 FF DF 0E 10 06 00 01F0 32 05 20 FC 0D 20 F9 3E 0D F3 E0 0F E0 FF AF E0 現在実行中の命令のアドレスを指す特殊なレジスタ。 A special register that contains the address of the instruction being executed now. AF 21 DF FF 0E 10 06 00 32 05 XOR A LD HL, 0xFFDF LD C, 0x10 LD B, 0x00 LD (HL-), A DEC B PC
  76. プログラムカウンタ Program Counter +0 +1 +2 +3 +4 +5 +6

    +7 +8 +9 +A +B +C +D +E +F 01E0 01 E0 85 E1 D1 C1 F1 D9 AF 21 FF DF 0E 10 06 00 01F0 32 05 20 FC 0D 20 F9 3E 0D F3 E0 0F E0 FF AF E0 現在実行中の命令のアドレスを指す特殊なレジスタ。 A special register that contains the address of the instruction being executed now. AF 21 DF FF 0E 10 06 00 32 05 XOR A LD HL, 0xFFDF LD C, 0x10 LD B, 0x00 LD (HL-), A DEC B PC
  77. プログラムカウンタ Program Counter +0 +1 +2 +3 +4 +5 +6

    +7 +8 +9 +A +B +C +D +E +F 01E0 01 E0 85 E1 D1 C1 F1 D9 AF 21 FF DF 0E 10 06 00 01F0 32 05 20 FC 0D 20 F9 3E 0D F3 E0 0F E0 FF AF E0 現在実行中の命令のアドレスを指す特殊なレジスタ。 A special register that contains the address of the instruction being executed now. AF 21 DF FF 0E 10 06 00 32 05 XOR A LD HL, 0xFFDF LD C, 0x10 LD B, 0x00 LD (HL-), A DEC B PC
  78. LR35902 の命令 - LD LR35902 instructions - LD LD BC,

    0x1234 BCレジスタに0x1234を入れる。 Load BC register with 0x1234. LD (BC), A BCレジスタの指し示すメモリアドレスにAレジスタ の内容を入れる。 Load a value A register has into memory BC register points at.
  79. LR35902 の命令 - JP / CD LR35902 instructions - JP

    / CD JP 0x5678 0x5678番地にジャンプする。 Jump to location 0x5678. CALL 0x8181 スタックに現在のアドレスを入れて0x8181番地に ジャンプする。 Push current address to stack pointer, then jump to 0x8181. RET スタック先頭のアドレスにジャンプする。 Jump to the location of top of stack pointer.
  80. LR35902 の命令 - JP / CD LR35902 instructions - JP

    / CD JP 0x5678 0x5678番地にジャンプする。 Jump to location 0x5678. CALL 0x8181 スタックに現在のアドレスを入れて0x8181番地に ジャンプする。 Push current address to stack pointer, then jump to 0x8181. RET スタック先頭のアドレスにジャンプする。 Jump to the location of top of stack pointer. LD PC, 0x5678
  81. LR35902 の命令 - JP / CD LR35902 instructions - JP

    / CD JP 0x5678 0x5678番地にジャンプする。 Jump to location 0x5678. CALL 0x8181 スタックに現在のアドレスを入れて0x8181番地に ジャンプする。 Push current address to stack pointer, then jump to 0x8181. RET スタック先頭のアドレスにジャンプする。 Jump to the location of top of stack pointer.
  82. LR35902 の命令 - JP / CD LR35902 instructions - JP

    / CD JP 0x5678 0x5678番地にジャンプする。 Jump to location 0x5678. CALL 0x8181 スタックに現在のアドレスを入れて0x8181番地に ジャンプする。 Push current address to stack pointer, then jump to 0x8181. RET スタック先頭のアドレスにジャンプする。 Jump to the location of top of stack pointer. LD (SP), PC
 LD SP, SP+2
 LD PC, 0x8181
  83. LR35902 の命令 - JP / CD LR35902 instructions - JP

    / CD JP 0x5678 0x5678番地にジャンプする。 Jump to location 0x5678. CALL 0x8181 スタックに現在のアドレスを入れて0x8181番地に ジャンプする。 Push current address to stack pointer, then jump to 0x8181. RET スタック先頭のアドレスにジャンプする。 Jump to the location of top of stack pointer. LD (SP), PC
 LD SP, SP+2
 LD PC, 0x8181 LD PC, (SP) LD SP, SP-2
  84. レジスタ Registers Instructions 命令 Memory access and I/O メモリアクセスとI/O

  85. ゲームボーイのハードウェアコンポネント CPU I/O Keys Sound Video Display Com Port Memory

    • RAM • Game 
 Cartridge • Video RAM Hardware components of GAMEBOY
  86. GAMEBOYのメモリマップ Memory map of GAMEBOY $FFFF Interrupt Enable Flag I/O

    $FF80-$FFFE Zero Page - 127 bytes RAM $FF00-$FF7F Hardware I/O Registers I/O $FEA0-$FEFF Unusable Memory $FE00-$FE9F OAM - Object Attribute Memory Video RAM $E000-$FDFF Echo RAM - Reserved, Do Not Use $D000-$DFFF Internal RAM - Bank 1-7 (switchable - CGB only) RAM $C000-$CFFF Internal RAM - Bank 0 (fixed) $A000-$BFFF Cartridge RAM (If Available) Cartridge $9C00-$9FFF BG Map Data 2 Video RAM $9800-$9BFF BG Map Data 1 $8000-$97FF Character RAM $4000-$7FFF Cartridge ROM - Switchable Banks 1-xx Cartridge $0150-$3FFF Cartridge ROM - Bank 0 (fixed) $0100-$014F Cartridge Header Area $0000-$00FF Restart and Interrupt Vectors ROM IUUQXXXIVDLpOHBNFTDPN QJE #Z5SBOTGSPN+1&(WFSTJPOBOESFNPWFXIJUFCBDLHSPVOE0SJHJOBMCZ&WBO"NPT.FEJB(BNF#PZ'-KQH  1VCMJD%PNBJO IUUQTDPNNPOTXJLJNFEJBPSHXJOEFYQIQ DVSJE
  87. GAMEBOYのメモリマップ Memory map of GAMEBOY $FFFF Interrupt Enable Flag I/O

    $FF80-$FFFE Zero Page - 127 bytes RAM $FF00-$FF7F Hardware I/O Registers I/O $FEA0-$FEFF Unusable Memory $FE00-$FE9F OAM - Object Attribute Memory Video RAM $E000-$FDFF Echo RAM - Reserved, Do Not Use $D000-$DFFF Internal RAM - Bank 1-7 (switchable - CGB only) RAM $C000-$CFFF Internal RAM - Bank 0 (fixed) $A000-$BFFF Cartridge RAM (If Available) Cartridge $9C00-$9FFF BG Map Data 2 Video RAM $9800-$9BFF BG Map Data 1 $8000-$97FF Character RAM $4000-$7FFF Cartridge ROM - Switchable Banks 1-xx Cartridge $0150-$3FFF Cartridge ROM - Bank 0 (fixed) $0100-$014F Cartridge Header Area $0000-$00FF Restart and Interrupt Vectors ROM IUUQXXXIVDLpOHBNFTDPN QJE #Z5SBOTGSPN+1&(WFSTJPOBOESFNPWFXIJUFCBDLHSPVOE0SJHJOBMCZ&WBO"NPT.FEJB(BNF#PZ'-KQH  1VCMJD%PNBJO IUUQTDPNNPOTXJLJNFEJBPSHXJOEFYQIQ DVSJE
  88. GAMEBOYのメモリマップ Memory map of GAMEBOY $FFFF Interrupt Enable Flag I/O

    $FF80-$FFFE Zero Page - 127 bytes RAM $FF00-$FF7F Hardware I/O Registers I/O $FEA0-$FEFF Unusable Memory $FE00-$FE9F OAM - Object Attribute Memory Video RAM $E000-$FDFF Echo RAM - Reserved, Do Not Use $D000-$DFFF Internal RAM - Bank 1-7 (switchable - CGB only) RAM $C000-$CFFF Internal RAM - Bank 0 (fixed) $A000-$BFFF Cartridge RAM (If Available) Cartridge $9C00-$9FFF BG Map Data 2 Video RAM $9800-$9BFF BG Map Data 1 $8000-$97FF Character RAM $4000-$7FFF Cartridge ROM - Switchable Banks 1-xx Cartridge $0150-$3FFF Cartridge ROM - Bank 0 (fixed) $0100-$014F Cartridge Header Area $0000-$00FF Restart and Interrupt Vectors ROM IUUQXXXIVDLpOHBNFTDPN QJE #Z5SBOTGSPN+1&(WFSTJPOBOESFNPWFXIJUFCBDLHSPVOE0SJHJOBMCZ&WBO"NPT.FEJB(BNF#PZ'-KQH  1VCMJD%PNBJO IUUQTDPNNPOTXJLJNFEJBPSHXJOEFYQIQ DVSJE メモリマップドI/O Memory mapped I/O
  89. エミュレータのCPU命令実装 CPU instructions implementation of emulator

  90. CPU実装のソースファイル Source file of CPU implementation

  91. CPU実装のソースファイル Source file of CPU implementation

  92. class Opcode { public static function run(Core $core, $address) {

    $function = 'opcode'.$address; return Opcode::$function($core); } public static function opcode0(Core $core) { // Do Nothing... } public static function opcode1(Core $core) { $core->registerC = $core->memoryRead($core->programCounter); $core->registerB = $core->memoryRead(($core->programCounter + 1) & 0xFFFF); $core->programCounter = ($core->programCounter + 2) & 0xFFFF; } Opcodeの実装 Implementation of opcodes
  93. class Opcode { public static function run(Core $core, $address) {

    $function = 'opcode'.$address; return Opcode::$function($core); } public static function opcode0(Core $core) { // Do Nothing... } public static function opcode1(Core $core) { $core->registerC = $core->memoryRead($core->programCounter); $core->registerB = $core->memoryRead(($core->programCounter + 1) & 0xFFFF); $core->programCounter = ($core->programCounter + 2) & 0xFFFF; } Opcodeの実装 Implementation of opcodes 0x00 NOP
  94. class Opcode { public static function run(Core $core, $address) {

    $function = 'opcode'.$address; return Opcode::$function($core); } public static function opcode0(Core $core) { // Do Nothing... } public static function opcode1(Core $core) { $core->registerC = $core->memoryRead($core->programCounter); $core->registerB = $core->memoryRead(($core->programCounter + 1) & 0xFFFF); $core->programCounter = ($core->programCounter + 2) & 0xFFFF; } Opcodeの実装 Implementation of opcodes 0x01 LD BC, nn
  95. LD BC, 0x1234 BCレジスタに0x1234を入れる。 Load BC register with 0x1234.

  96. LD BC, d16 LD BC, d16 http://www.pastraiser.com/cpu/gameboy/gameboy_opcodes.html

  97. LD BC, d16 LD BC, d16 http://www.pastraiser.com/cpu/gameboy/gameboy_opcodes.html

  98. LD BC, d16 LD BC, d16 http://www.pastraiser.com/cpu/gameboy/gameboy_opcodes.html

  99. public static function opcode1(Core $core) { $core->registerC =
 $core->memoryRead($core->programCounter); $core->registerB

    = 
 $core->memoryRead(($core->programCounter + 1) & 0xFFFF); $core->programCounter = 
 ($core->programCounter + 2) & 0xFFFF; } LC BC, d16 の実装 Implementation of LD BC, d16 PC PC + 1 0x01 0x34 0x12 LD BC, d16 0x1234 Data Address
  100. public static function opcode1(Core $core) { $core->registerC =
 $core->memoryRead($core->programCounter); $core->registerB

    = 
 $core->memoryRead(($core->programCounter + 1) & 0xFFFF); $core->programCounter = 
 ($core->programCounter + 2) & 0xFFFF; } LC BC, d16 の実装 Implementation of LD BC, d16 PC PC + 1 0x01 0x34 0x12 LD BC, d16 0x1234 Data Address BCレジスタに指定したアドレスのメモリの値を入れる。 Load BC register with nn.
  101. public static function opcode1(Core $core) { $core->registerC =
 $core->memoryRead($core->programCounter); $core->registerB

    = 
 $core->memoryRead(($core->programCounter + 1) & 0xFFFF); $core->programCounter = 
 ($core->programCounter + 2) & 0xFFFF; } LC BC, d16 の実装 Implementation of LD BC, d16 PC PC + 1 0x01 0x34 0x12 LD BC, d16 0x1234 Data Address PCを次の命令まで進める。 Move PC register to next instruction.
  102. public static function opcode1(Core $core) { $core->registerC =
 $core->memoryRead($core->programCounter); $core->registerB

    = 
 $core->memoryRead(($core->programCounter + 1) & 0xFFFF); $core->programCounter = 
 ($core->programCounter + 2) & 0xFFFF; } LC BC, d16 の実装 Implementation of LD BC, d16 PC PC + 1 0x01 0x34 0x12 LD BC, d16 0x1234 Data Address
  103. QUIZ

  104. $core->memoryRead($core->programCounter); // //Main RAM, MBC RAM, GBC Main RAM, VRAM,

    etc. // //Main Core Memory public $memory = []; Core.php
  105. $core->memoryRead($core->programCounter); // //Main RAM, MBC RAM, GBC Main RAM, VRAM,

    etc. // //Main Core Memory public $memory = []; Core.php メインメモリは配列になっている。 Main memory is defined as array.

  106. $core->memoryRead($core->programCounter); // //Main RAM, MBC RAM, GBC Main RAM, VRAM,

    etc. // //Main Core Memory public $memory = []; Core.php メインメモリは配列になっている。 Main memory is defined as array.
 なぜ $core->memory[$core->programCounter] ではない? Q Why not $core->memory[$core->programCounter] ?
  107. GAMEBOYのメモリマップ Memory map of GAMEBOY $FFFF Interrupt Enable Flag I/O

    $FF80-$FFFE Zero Page - 127 bytes RAM $FF00-$FF7F Hardware I/O Registers I/O $FEA0-$FEFF Unusable Memory $FE00-$FE9F OAM - Object Attribute Memory Video RAM $E000-$FDFF Echo RAM - Reserved, Do Not Use $D000-$DFFF Internal RAM - Bank 1-7 (switchable - CGB only) RAM $C000-$CFFF Internal RAM - Bank 0 (fixed) $A000-$BFFF Cartridge RAM (If Available) Cartridge $9C00-$9FFF BG Map Data 2 Video RAM $9800-$9BFF BG Map Data 1 $8000-$97FF Character RAM $4000-$7FFF Cartridge ROM - Switchable Banks 1-xx Cartridge $0150-$3FFF Cartridge ROM - Bank 0 (fixed) $0100-$014F Cartridge Header Area $0000-$00FF Restart and Interrupt Vectors ROM IUUQXXXIVDLpOHBNFTDPN QJE #Z5SBOTGSPN+1&(WFSTJPOBOESFNPWFXIJUFCBDLHSPVOE0SJHJOBMCZ&WBO"NPT.FEJB(BNF#PZ'-KQH  1VCMJD%PNBJO IUUQTDPNNPOTXJLJNFEJBPSHXJOEFYQIQ DVSJE
  108. GAMEBOYのメモリマップ Memory map of GAMEBOY $FFFF Interrupt Enable Flag I/O

    $FF80-$FFFE Zero Page - 127 bytes RAM $FF00-$FF7F Hardware I/O Registers I/O $FEA0-$FEFF Unusable Memory $FE00-$FE9F OAM - Object Attribute Memory Video RAM $E000-$FDFF Echo RAM - Reserved, Do Not Use $D000-$DFFF Internal RAM - Bank 1-7 (switchable - CGB only) RAM $C000-$CFFF Internal RAM - Bank 0 (fixed) $A000-$BFFF Cartridge RAM (If Available) Cartridge $9C00-$9FFF BG Map Data 2 Video RAM $9800-$9BFF BG Map Data 1 $8000-$97FF Character RAM $4000-$7FFF Cartridge ROM - Switchable Banks 1-xx Cartridge $0150-$3FFF Cartridge ROM - Bank 0 (fixed) $0100-$014F Cartridge Header Area $0000-$00FF Restart and Interrupt Vectors ROM IUUQXXXIVDLpOHBNFTDPN QJE #Z5SBOTGSPN+1&(WFSTJPOBOESFNPWFXIJUFCBDLHSPVOE0SJHJOBMCZ&WBO"NPT.FEJB(BNF#PZ'-KQH  1VCMJD%PNBJO IUUQTDPNNPOTXJLJNFEJBPSHXJOEFYQIQ DVSJE A. メモリアクセスはそのアドレスに よって動作が違うから。 A. Because the result of memory access depends on its location. 

  109. エミュレータのI/O実装 I/O implementations of emulator

  110. ゲームボーイのハードウェアコンポネント CPU I/O Keys Sound Video Display Com Port Memory

    • RAM • Game 
 Cartridge • Video RAM Hardware components of GAMEBOY
  111. ゲームボーイのハードウェアコンポネント CPU I/O Keys Sound Video Display Com Port Memory

    • RAM • Game 
 Cartridge • Video RAM Hardware components of GAMEBOY CPUはキーにI/O経由でアクセスする CPU accesses keys through the I/O
  112. 実行のメインループ $keyboard = new Keyboard($core); while (true) { $core->run(); $keyboard->check();

    } boot.php Main loop of excution
  113. 実行のメインループ $keyboard = new Keyboard($core); while (true) { $core->run(); $keyboard->check();

    } boot.php メインループ Main loop.
 Main loop of excution
  114. キー状態の取得 public function __construct(Core $core) { $this->core = $core; exec('stty

    -icanon -echo'); $this->file = fopen('php://stdin', 'r'); stream_set_blocking($this->file, false); } public function check() { $key = fread($this->file, 1); if (!empty($key)) { $this->keyDown($key); } elseif (!empty($this->keyPressing)) { $this->keyUp($this->keyPressing); } $this->keyPressing = $key; } Get key status
  115. キー状態の取得 public function __construct(Core $core) { $this->core = $core; exec('stty

    -icanon -echo'); $this->file = fopen('php://stdin', 'r'); stream_set_blocking($this->file, false); } public function check() { $key = fread($this->file, 1); if (!empty($key)) { $this->keyDown($key); } elseif (!empty($this->keyPressing)) { $this->keyUp($this->keyPressing); } $this->keyPressing = $key; } Get key status 標準入力を開いて… Open standard in and...

  116. キー状態の取得 public function __construct(Core $core) { $this->core = $core; exec('stty

    -icanon -echo'); $this->file = fopen('php://stdin', 'r'); stream_set_blocking($this->file, false); } public function check() { $key = fread($this->file, 1); if (!empty($key)) { $this->keyDown($key); } elseif (!empty($this->keyPressing)) { $this->keyUp($this->keyPressing); } $this->keyPressing = $key; } Get key status 標準入力を開いて… Open standard in and...
 fread()で1文字取る! Get a character with fread!
  117. キー状態の取得 Get key status CPU GAMEBOY’s key ゲームボーイのキー CPU I/O

    I/O ゲームボーイソフトウェア GAMEBOY Software ゲームボーイエミュレータ PC keyboard PCのキーボード GAMEBOY Emulator PHP PHP
  118. GAMEBOYのメモリマップ Memory map of GAMEBOY $FFFF Interrupt Enable Flag I/O

    $FF80-$FFFE Zero Page - 127 bytes RAM $FF00-$FF7F Hardware I/O Registers I/O $FEA0-$FEFF Unusable Memory $FE00-$FE9F OAM - Object Attribute Memory Video RAM $E000-$FDFF Echo RAM - Reserved, Do Not Use $D000-$DFFF Internal RAM - Bank 1-7 (switchable - CGB only) RAM $C000-$CFFF Internal RAM - Bank 0 (fixed) $A000-$BFFF Cartridge RAM (If Available) Cartridge $9C00-$9FFF BG Map Data 2 Video RAM $9800-$9BFF BG Map Data 1 $8000-$97FF Character RAM $4000-$7FFF Cartridge ROM - Switchable Banks 1-xx Cartridge $0150-$3FFF Cartridge ROM - Bank 0 (fixed) $0100-$014F Cartridge Header Area $0000-$00FF Restart and Interrupt Vectors ROM IUUQXXXIVDLpOHBNFTDPN QJE #Z5SBOTGSPN+1&(WFSTJPOBOESFNPWFXIJUFCBDLHSPVOE0SJHJOBMCZ&WBO"NPT.FEJB(BNF#PZ'-KQH  1VCMJD%PNBJO IUUQTDPNNPOTXJLJNFEJBPSHXJOEFYQIQ DVSJE
  119. I/O 0xFF00 キー状態 FF00 -- JOYPAD [RW] Joypad port Bit5

    Bit4 | In order to scan the keys, output 0 into either Bit4 Bit3 DOWN START | or Bit5 of JOYPAD, wait for some time and read JOYPAD. Bit2 UP SELECT | Bits 0-3 will be set to zeroes if corresponding Bit1 LEFT B | buttons are pressed. Bits 6 and 7 are not used. Bits Bit0 RIGHT A | 0-3 are connected to input lines P10-P13. Bits 4 and 5 | are connected to ouput lines P14 and P15. IUUQGNTLPNLPOPSH(BNF#PZ5FDI4PGUXBSFIUNM キーの状態を読み取るには、0xFF00のビット4とビット5に 値を書き込み、その後ビット0〜ビット3の値を読み込む。 ビット4とビット5に書き込んだ値によってビット0〜ビッ ト3がどのキーに対応するかが変化する。 I/O 0xFF00 Key status
  120. I/O 読み込み public function memoryRead($address) { if ($address < 0x4000)

    { } elseif ($address >= 0xFF00) { switch ($address) { case 0xFF00: return 0xC0 | $this->memory[0xFF00]; break; I/O read
  121. I/O 書き込み I/O write 7 6 5 4 3 2

    1 0 - - P15 out P14 out P13 in P12 in P11 in P10 in - - 0 1 A B Select Start - - 1 0 → ← ↑ ↓ I/O port 0xFF00
  122. public function memoryWrite($address, $data) { if ($address < 0x8000) {

    //I/O Registers (GB + GBC): } elseif ($address == 0xFF00) { $this->memory[0xFF00] = ($data & 0x30) | (((($data & 0x20) == 0) ? ($this->JoyPad >> 4) : 0xF) & ((($data & 0x10) == 0) ? ($this->JoyPad & 0xF) : 0xF)); } elseif ($address == 0xFF02) { I/O 書き込み I/O write 7 6 5 4 3 2 1 0 - - P15 out P14 out P13 in P12 in P11 in P10 in - - 0 1 A B Select Start - - 1 0 → ← ↑ ↓ I/O port 0xFF00
  123. public function memoryWrite($address, $data) { if ($address < 0x8000) {

    //I/O Registers (GB + GBC): } elseif ($address == 0xFF00) { $this->memory[0xFF00] = ($data & 0x30) | (((($data & 0x20) == 0) ? ($this->JoyPad >> 4) : 0xF) & ((($data & 0x10) == 0) ? ($this->JoyPad & 0xF) : 0xF)); } elseif ($address == 0xFF02) { I/O 書き込み I/O write 7 6 5 4 3 2 1 0 - - P15 out P14 out P13 in P12 in P11 in P10 in - - 0 1 A B Select Start - - 1 0 → ← ↑ ↓ I/O port 0xFF00
  124. public function memoryWrite($address, $data) { if ($address < 0x8000) {

    //I/O Registers (GB + GBC): } elseif ($address == 0xFF00) { $this->memory[0xFF00] = ($data & 0x30) | (((($data & 0x20) == 0) ? ($this->JoyPad >> 4) : 0xF) & ((($data & 0x10) == 0) ? ($this->JoyPad & 0xF) : 0xF)); } elseif ($address == 0xFF02) { I/O 書き込み I/O write 7 6 5 4 3 2 1 0 - - P15 out P14 out P13 in P12 in P11 in P10 in - - 0 1 A B Select Start - - 1 0 → ← ↑ ↓ I/O port 0xFF00
  125. public function memoryWrite($address, $data) { if ($address < 0x8000) {

    //I/O Registers (GB + GBC): } elseif ($address == 0xFF00) { $this->memory[0xFF00] = ($data & 0x30) | (((($data & 0x20) == 0) ? ($this->JoyPad >> 4) : 0xF) & ((($data & 0x10) == 0) ? ($this->JoyPad & 0xF) : 0xF)); } elseif ($address == 0xFF02) { I/O 書き込み I/O write 7 6 5 4 3 2 1 0 - - P15 out P14 out P13 in P12 in P11 in P10 in - - 0 1 A B Select Start - - 1 0 → ← ↑ ↓ I/O port 0xFF00
  126. public function memoryWrite($address, $data) { if ($address < 0x8000) {

    //I/O Registers (GB + GBC): } elseif ($address == 0xFF00) { $this->memory[0xFF00] = ($data & 0x30) | (((($data & 0x20) == 0) ? ($this->JoyPad >> 4) : 0xF) & ((($data & 0x10) == 0) ? ($this->JoyPad & 0xF) : 0xF)); } elseif ($address == 0xFF02) { I/O 書き込み I/O write 7 6 5 4 3 2 1 0 - - P15 out P14 out P13 in P12 in P11 in P10 in - - 0 1 A B Select Start - - 1 0 → ← ↑ ↓ I/O port 0xFF00
  127. public function memoryWrite($address, $data) { if ($address < 0x8000) {

    //I/O Registers (GB + GBC): } elseif ($address == 0xFF00) { $this->memory[0xFF00] = ($data & 0x30) | (((($data & 0x20) == 0) ? ($this->JoyPad >> 4) : 0xF) & ((($data & 0x10) == 0) ? ($this->JoyPad & 0xF) : 0xF)); } elseif ($address == 0xFF02) { I/O 書き込み I/O write 7 6 5 4 3 2 1 0 - - P15 out P14 out P13 in P12 in P11 in P10 in - - 0 1 A B Select Start - - 1 0 → ← ↑ ↓ I/O port 0xFF00 7 6 5 4 3 2 1 0 A B Select Start → ← ↑ ↓ $this->JoyPad:
  128. public function memoryWrite($address, $data) { if ($address < 0x8000) {

    //I/O Registers (GB + GBC): } elseif ($address == 0xFF00) { $this->memory[0xFF00] = ($data & 0x30) | (((($data & 0x20) == 0) ? ($this->JoyPad >> 4) : 0xF) & ((($data & 0x10) == 0) ? ($this->JoyPad & 0xF) : 0xF)); } elseif ($address == 0xFF02) { I/O 書き込み I/O write 7 6 5 4 3 2 1 0 - - P15 out P14 out P13 in P12 in P11 in P10 in - - 0 1 A B Select Start - - 1 0 → ← ↑ ↓ I/O port 0xFF00 7 6 5 4 3 2 1 0 A B Select Start → ← ↑ ↓ $this->JoyPad:
  129. public function memoryWrite($address, $data) { if ($address < 0x8000) {

    //I/O Registers (GB + GBC): } elseif ($address == 0xFF00) { $this->memory[0xFF00] = ($data & 0x30) | (((($data & 0x20) == 0) ? ($this->JoyPad >> 4) : 0xF) & ((($data & 0x10) == 0) ? ($this->JoyPad & 0xF) : 0xF)); } elseif ($address == 0xFF02) { I/O 書き込み I/O write 7 6 5 4 3 2 1 0 - - P15 out P14 out P13 in P12 in P11 in P10 in - - 0 1 A B Select Start - - 1 0 → ← ↑ ↓ I/O port 0xFF00 7 6 5 4 3 2 1 0 A B Select Start → ← ↑ ↓ $this->JoyPad:
  130. public function memoryWrite($address, $data) { if ($address < 0x8000) {

    //I/O Registers (GB + GBC): } elseif ($address == 0xFF00) { $this->memory[0xFF00] = ($data & 0x30) | (((($data & 0x20) == 0) ? ($this->JoyPad >> 4) : 0xF) & ((($data & 0x10) == 0) ? ($this->JoyPad & 0xF) : 0xF)); } elseif ($address == 0xFF02) { I/O 書き込み I/O write 7 6 5 4 3 2 1 0 - - P15 out P14 out P13 in P12 in P11 in P10 in - - 0 1 A B Select Start - - 1 0 → ← ↑ ↓ I/O port 0xFF00 7 6 5 4 3 2 1 0 A B Select Start → ← ↑ ↓ $this->JoyPad:
  131. public function memoryWrite($address, $data) { if ($address < 0x8000) {

    //I/O Registers (GB + GBC): } elseif ($address == 0xFF00) { $this->memory[0xFF00] = ($data & 0x30) | (((($data & 0x20) == 0) ? ($this->JoyPad >> 4) : 0xF) & ((($data & 0x10) == 0) ? ($this->JoyPad & 0xF) : 0xF)); } elseif ($address == 0xFF02) { I/O 書き込み I/O write 7 6 5 4 3 2 1 0 - - P15 out P14 out P13 in P12 in P11 in P10 in - - 0 1 A B Select Start - - 1 0 → ← ↑ ↓ I/O port 0xFF00 7 6 5 4 3 2 1 0 A B Select Start → ← ↑ ↓ $this->JoyPad:
  132. public function memoryWrite($address, $data) { if ($address < 0x8000) {

    //I/O Registers (GB + GBC): } elseif ($address == 0xFF00) { $this->memory[0xFF00] = ($data & 0x30) | (((($data & 0x20) == 0) ? ($this->JoyPad >> 4) : 0xF) & ((($data & 0x10) == 0) ? ($this->JoyPad & 0xF) : 0xF)); } elseif ($address == 0xFF02) { I/O 書き込み I/O write 7 6 5 4 3 2 1 0 - - P15 out P14 out P13 in P12 in P11 in P10 in - - 0 1 A B Select Start - - 1 0 → ← ↑ ↓ I/O port 0xFF00 7 6 5 4 3 2 1 0 A B Select Start → ← ↑ ↓ $this->JoyPad:
  133. public function memoryWrite($address, $data) { if ($address < 0x8000) {

    //I/O Registers (GB + GBC): } elseif ($address == 0xFF00) { $this->memory[0xFF00] = ($data & 0x30) | (((($data & 0x20) == 0) ? ($this->JoyPad >> 4) : 0xF) & ((($data & 0x10) == 0) ? ($this->JoyPad & 0xF) : 0xF)); } elseif ($address == 0xFF02) { I/O 書き込み I/O write 7 6 5 4 3 2 1 0 - - P15 out P14 out P13 in P12 in P11 in P10 in - - 0 1 A B Select Start - - 1 0 → ← ↑ ↓ I/O port 0xFF00 7 6 5 4 3 2 1 0 A B Select Start → ← ↑ ↓ $this->JoyPad:
  134. GAMEBOYのI/O I/O of GAMEBOY https://ja.wikipedia.org/wiki/ゲームボーイ

  135. GAMEBOYのI/O I/O of GAMEBOY https://ja.wikipedia.org/wiki/ゲームボーイ

  136. GAMEBOYのI/O I/O of GAMEBOY https://ja.wikipedia.org/wiki/ゲームボーイ 45本 / 80本

  137. GAMEBOYのI/O I/O of GAMEBOY https://ja.wikipedia.org/wiki/ゲームボーイ 45本 / 80本

  138. GAMEBOYのI/O I/O of GAMEBOY https://ja.wikipedia.org/wiki/ゲームボーイ 45本 / 80本

  139. GAMEBOYのI/O I/O of GAMEBOY https://ja.wikipedia.org/wiki/ゲームボーイ 1pin 45本 / 80本

  140. GAMEBOYのI/O I/O of GAMEBOY https://ja.wikipedia.org/wiki/ゲームボーイ 1pin 24pin 45本 / 80本

  141. GAMEBOYのI/O I/O of GAMEBOY https://ja.wikipedia.org/wiki/ゲームボーイ 1pin 24pin 40pin 45本 /

    80本
  142. GAMEBOYのI/O I/O of GAMEBOY https://ja.wikipedia.org/wiki/ゲームボーイ 1pin 24pin 40pin 64pin 45本

    / 80本
  143. GAMEBOYのI/O I/O of GAMEBOY https://ja.wikipedia.org/wiki/ゲームボーイ 1pin 24pin 40pin 64pin 80pin

    45本 / 80本
  144. GAMEBOYのI/O I/O of GAMEBOY https://ja.wikipedia.org/wiki/ゲームボーイ 45本 / 80本

  145. 結論 Conclusion

  146. エミュレータのソースを読むのは楽しい

  147. Webアプリとも
 フレームワークとも フロントエンドの非同期アプリとも
 違う感じのコード群

  148. ハードウェアの動作を ソフトウェアで表現

  149. とても面白い

  150. 皆さんも是非読んでみてください

  151. Thanks WE ARE HIRING @tomzoh プリーズ #phpkansai / ブログ /

    懇親会
  152. Appendix

  153. http://www.hasegawa-tomoki.com/blog/2016/05/23/8bit-asm/

  154. リンク • http://marc.rawer.de/Gameboy/Docs/GBCPUman.pdf • 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 • http://www.z80.info/z80inst.txt Resources
  155. セットアップ How to run $ git clone https://github.com/gabrielrcouto/ php-terminal-gameboy-emulator.git $

    cd php-terminal-gameboy-emulator $ composer install -o $ bin/php-gameboy drmario.rom
  156. ROMいずこ How to get ROM file

  157. ROMいずこ How to get ROM file

  158. ROMいずこ How to get ROM file _人人人人人人人_ > drmario.gb <  ̄Y^Y^Y^Y^Y^Y ̄

  159. ROMいずこ How to get ROM file

  160. ROMいずこ How to get ROM file

  161. ROMいずこ How to get ROM file $rom = base64_decode(file_get_contents($argv[1])); $rom

    = file_get_contents($filename);
  162. ボトルネックはどこか PHP5.5.30 OSX Native FPS: 4 PHP7.0.1 VirtualBox FPS: 14

    We need more FPS
  163. タイルでの色表現 ゲームボーイは4色出せるが1色&パターンで表現している。 GAMEBOY’s display has 4 colors. PHP version uses

    only 1 color with pattern. Color using tile pattern
  164. アドレスバスとデータバス Data bus and address bus メモリ空間64KB 0x0000 to 0xffff

    0000000000000000 to 1111111111111111 16bits ビデオRAM8KB 0x0000 to 0x1fff 0000000000000000 to 0001111111111111 13bits
  165. Pentiumのアドレスバスとデータバス IUUQEPXOMPBEJOUFMDPNEFTJHOQFOUJVNEBUBTIUTQEG $$දࣔܧঝ IUUQTDPNNPOTXJLJNFEJBPSHXJOEFYQIQ DVSJE D0〜D63 A3〜A31 Data bus and

    address bus of Pentium
  166. ノイマン型コンピュータ http://e-words.jp/w/ノイマン型コンピュータ.html von Neumann architecture プログラムをデータとして記憶装置に格納し、
 これを順番に読み込んで実行するコンピュータ。 "DPNQVUFSXIJDIIBTBNFNPSZBOE$165IJT$16DBOJOUFSQSFUUIF DPOUFOUTPGNFNPSZFJUIFSBTJOTUSVDUJPOTPSBTEBUBBDDPSEJOHUPUIF GFUDIFYFDVUFDZDMF

    http://www.dictionary.com/browse/von-neumann-architecture
  167. エンディアン Endian

  168. エンディアン Endian PC PC + 1 0x01 0x34 0x12 LD

    BC, nn 0x1234 Data Address LD BC, 0x1234 BCレジスタに0x1234を入れる。 Load BC register with 0x1234.
  169. エンディアン Endian UTF-16のBOM = Byte Order Mark = ビッグエンディアンかリトルエンディアンか

  170. ストリームの非ブロックモード public function __construct(Core $core) { $this->core = $core; exec('stty

    -icanon -echo'); $this->file = fopen('php://stdin', 'r'); stream_set_blocking($this->file, false); } public function check() { $key = fread($this->file, 1); if (!empty($key)) { $this->keyDown($key); } elseif (!empty($this->keyPressing)) { $this->keyUp($this->keyPressing); } $this->keyPressing = $key; } Non-blocking mode on a stream
  171. ストリームの非ブロックモード public function __construct(Core $core) { $this->core = $core; exec('stty

    -icanon -echo'); $this->file = fopen('php://stdin', 'r'); stream_set_blocking($this->file, false); } public function check() { $key = fread($this->file, 1); if (!empty($key)) { $this->keyDown($key); } elseif (!empty($this->keyPressing)) { $this->keyUp($this->keyPressing); } $this->keyPressing = $key; } Non-blocking mode on a stream
  172. ストリームの非ブロックモード public function __construct(Core $core) { $this->core = $core; exec('stty

    -icanon -echo'); $this->file = fopen('php://stdin', 'r'); stream_set_blocking($this->file, false); } public function check() { $key = fread($this->file, 1); if (!empty($key)) { $this->keyDown($key); } elseif (!empty($this->keyPressing)) { $this->keyUp($this->keyPressing); } $this->keyPressing = $key; } Non-blocking mode on a stream ストリームのモードを非ブロックに設定 Set non-blocking mode on a stream.