Slide 1

Slide 1 text

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

Slide 2

Slide 2 text

今日のテーマ Learning: computer architecture with PHP PHPで学ぶ コンピュータアーキテクチャ Today’s theme

Slide 3

Slide 3 text

No content

Slide 4

Slide 4 text

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

Slide 5

Slide 5 text

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

Slide 6

Slide 6 text

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

Slide 7

Slide 7 text

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

Slide 8

Slide 8 text

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

Slide 9

Slide 9 text

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

Slide 10

Slide 10 text

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

Slide 11

Slide 11 text

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

Slide 12

Slide 12 text

No content

Slide 13

Slide 13 text

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

Slide 14

Slide 14 text

ライフワーク: Web / iOSアプリ開発, ビール, IoT,
 サッカー観戦, レンタルカートレース, … 長谷川 智希 Web / iOS App Development, Beer, IoT, Watch soccer match, Rental Kart Racing, … デジタルサーカス株式会社 副団長CTO Digital Circus, Inc. Vice-master CTO Tokyo, Japan Lifework: @tomzoh

Slide 15

Slide 15 text

No content

Slide 16

Slide 16 text

No content

Slide 17

Slide 17 text

WE ARE HIRING!! Web Development Mobile App Development ( ) (iOS, Android) http://www.dgcircus.com Omotesando, Tokyo

Slide 18

Slide 18 text

今日のテーマ Learning: computer architecture with PHP PHPで学ぶ コンピュータアーキテクチャ Today’s theme

Slide 19

Slide 19 text

今年2月23日 23, February

Slide 20

Slide 20 text

No content

Slide 21

Slide 21 text

No content

Slide 22

Slide 22 text

terminal-gameboy-emulator

Slide 23

Slide 23 text

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

Slide 24

Slide 24 text

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

Slide 25

Slide 25 text

terminal-gameboy-emulator

Slide 26

Slide 26 text

エミュレータ エミュレータとは、機械装置やコンピュータのハードウェア (PC、ゲーム機など)の構造を、別の装置やソフトウェアで 模倣することで実現させたもの。 In computing, an emulator is hardware or software that enables one computer system to behave like another computer system. Emulator terminal-gameboy-emulator

Slide 27

Slide 27 text

terminal-gameboy-emulator

Slide 28

Slide 28 text

terminal-gameboy-emulator ??

Slide 29

Slide 29 text

demo

Slide 30

Slide 30 text

!?

Slide 31

Slide 31 text

SUGOI

Slide 32

Slide 32 text

EXCITING

Slide 33

Slide 33 text

No content

Slide 34

Slide 34 text

No content

Slide 35

Slide 35 text

It’s

Slide 36

Slide 36 text

We are er.

Slide 37

Slide 37 text

WE CAN READ IT!!

Slide 38

Slide 38 text

No content

Slide 39

Slide 39 text

ゲームボーイのCPU CPU of GAMEBOY

Slide 40

Slide 40 text

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

Slide 41

Slide 41 text

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

Slide 42

Slide 42 text

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

Slide 43

Slide 43 text

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

Slide 44

Slide 44 text

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

Slide 45

Slide 45 text

命令 Instructions

Slide 46

Slide 46 text

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

Slide 47

Slide 47 text

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

Slide 48

Slide 48 text

プログラムの実行 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

Slide 49

Slide 49 text

プログラムの実行 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

Slide 50

Slide 50 text

プログラムの実行 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

Slide 51

Slide 51 text

プログラムの実行 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

Slide 52

Slide 52 text

プログラムの実行 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

Slide 53

Slide 53 text

レジスタ Registers

Slide 54

Slide 54 text

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.

Slide 55

Slide 55 text

プログラムカウンタ 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

Slide 56

Slide 56 text

プログラムカウンタ 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

Slide 57

Slide 57 text

プログラムカウンタ 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

Slide 58

Slide 58 text

プログラムカウンタ 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

Slide 59

Slide 59 text

プログラムカウンタ 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

Slide 60

Slide 60 text

プログラムカウンタ 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

Slide 61

Slide 61 text

プログラムカウンタ 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

Slide 62

Slide 62 text

プログラムカウンタ 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

Slide 63

Slide 63 text

プログラムカウンタ 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

Slide 64

Slide 64 text

プログラムカウンタ 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

Slide 65

Slide 65 text

プログラムカウンタ 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

Slide 66

Slide 66 text

プログラムカウンタ 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

Slide 67

Slide 67 text

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.

Slide 68

Slide 68 text

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.

Slide 69

Slide 69 text

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

Slide 70

Slide 70 text

メモリアクセスとI/O Memory access and I/O

Slide 71

Slide 71 text

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

Slide 72

Slide 72 text

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

Slide 73

Slide 73 text

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

Slide 74

Slide 74 text

エミュレータのCPU命令実装 CPU instructions implementation of emulator

Slide 75

Slide 75 text

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

Slide 76

Slide 76 text

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

Slide 77

Slide 77 text

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

Slide 78

Slide 78 text

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

Slide 79

Slide 79 text

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

Slide 80

Slide 80 text

LD BC, 0x1234 BCレジスタに0x1234を入れる。 Load BC register with 0x1234.

Slide 81

Slide 81 text

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, nn の実装 Implementation of LD BC, nn PC PC + 1 0x01 0x01 0x03 LD BC, nn 0x0301 Data Address

Slide 82

Slide 82 text

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, nn の実装 Implementation of LD BC, nn PC PC + 1 0x01 0x01 0x03 LD BC, nn 0x0301 Data Address BCレジスタに指定したアドレスのメモリの値を入れる。 Load BC register with nn.

Slide 83

Slide 83 text

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, nn の実装 Implementation of LD BC, nn PC PC + 1 0x01 0x01 0x03 LD BC, nn 0x0301 Data Address PCを次の命令まで進める。 Move PC register to next instruction.

Slide 84

Slide 84 text

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, nn の実装 Implementation of LD BC, nn PC PC + 1 0x01 0x01 0x03 LD BC, nn 0x0301 Data Address

Slide 85

Slide 85 text

QUIZ

Slide 86

Slide 86 text

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

Slide 87

Slide 87 text

$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.


Slide 88

Slide 88 text

$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] ?

Slide 89

Slide 89 text

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

Slide 90

Slide 90 text

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 a result of memory access depends on its location. 


Slide 91

Slide 91 text

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

Slide 92

Slide 92 text

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

Slide 93

Slide 93 text

ゲームボーイのハードウェアコンポネント 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

Slide 94

Slide 94 text

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

Slide 95

Slide 95 text

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

Slide 96

Slide 96 text

キー状態の取得 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

Slide 97

Slide 97 text

キー状態の取得 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...


Slide 98

Slide 98 text

キー状態の取得 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!

Slide 99

Slide 99 text

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

Slide 100

Slide 100 text

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

Slide 101

Slide 101 text

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

Slide 102

Slide 102 text

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

Slide 103

Slide 103 text

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

Slide 104

Slide 104 text

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

Slide 105

Slide 105 text

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

Slide 106

Slide 106 text

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:

Slide 107

Slide 107 text

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:

Slide 108

Slide 108 text

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:

Slide 109

Slide 109 text

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:

Slide 110

Slide 110 text

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:

Slide 111

Slide 111 text

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:

Slide 112

Slide 112 text

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:

Slide 113

Slide 113 text

結論 Conclusion

Slide 114

Slide 114 text

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

Slide 115

Slide 115 text

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

Slide 116

Slide 116 text

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

Slide 117

Slide 117 text

とても面白い

Slide 118

Slide 118 text

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

Slide 119

Slide 119 text

Thanks WE ARE HIRING Drupal / Mobile App Engineer
 Digital Circus, Inc. Tokyo, Japan @tomzoh

Slide 120

Slide 120 text

Appendix

Slide 121

Slide 121 text

セットアップ 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

Slide 122

Slide 122 text

ROMいずこ How to get ROM file

Slide 123

Slide 123 text

ROMいずこ How to get ROM file

Slide 124

Slide 124 text

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

Slide 125

Slide 125 text

ROMいずこ How to get ROM file

Slide 126

Slide 126 text

ROMいずこ How to get ROM file

Slide 127

Slide 127 text

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

Slide 128

Slide 128 text

ボトルネックはどこか PHP5.5.30 OSX Native FPS: 4 PHP7.0.1 VirtualBox FPS: 14 We need more FPS

Slide 129

Slide 129 text

エミュレータのビデオ実装 Video implementations of emulator

Slide 130

Slide 130 text

タイルでの色表現 ゲームボーイは4色出せるが1色&パターンで表現している。 GAMEBOY has 4 color display. PHP version uses only 1 color. Color using tile pattern

Slide 131

Slide 131 text

Pentiumのアドレスバスとデータバス IUUQEPXOMPBEJOUFMDPNEFTJHOQFOUJVNEBUBTIUTQEG $$දࣔܧঝ IUUQTDPNNPOTXJLJNFEJBPSHXJOEFYQIQ DVSJE D0〜D63 A3〜A31 Data bus and address bus of Pentium

Slide 132

Slide 132 text

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

Slide 133

Slide 133 text

エンディアン Endian UTF-16のBOM = Byte Order Mark = ビッグエンディアンかリトルエンディアンか

Slide 134

Slide 134 text

ストリームの非ブロックモード 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

Slide 135

Slide 135 text

ストリームの非ブロックモード 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

Slide 136

Slide 136 text

ストリームの非ブロックモード 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.


Slide 137

Slide 137 text

リンク • 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