Slide 1

Slide 1 text

CVJMEFSTDPOUPLZP ϑΝϛίϯΤϛϡϨʔλ ͷ૑Γํ !CPLVXFC

Slide 2

Slide 2 text

!CPLVXFC IUUQCMPHCPLVXFCNF w ૊ΈࠐΈϋʔυιϑτ΢ΣΞΤϯδχΞ w 8FCϑϩϯτΤϯυΤϯδχΞ w ࢁ͔Β߱Γ͖ͯ·ͨ͠ CPLVXFC ࣗݾ঺հ

Slide 3

Slide 3 text

͍͞͠ΐʹ !3VTU8FC"TTFNCMZ XJUIFNTDSJQUFO Ͱ ϑΝϛίϯΤϛϡϨʔλΛ࣮૷ͯ͠Έͨ࿩͠Λ͢ΔηογϣϯͰ͢ !3VTU8FC"TTFNCMZͷجૅ΍ৄࡉʹ͸͋·Γ৮Ε·ͤΜ !ϑΝϛίϯͷϋʔυ΢ΣΞ΍੍໿ɺͦͷΤϛϡϨʔγϣϯํ๏ Λॏ఺తʹ͓࿩͢Δͭ΋ΓͰ͢

Slide 4

Slide 4 text

2ϑΝϛίϯͷ࣮ػͰ ༡Μͩ͜ͱ͋Δਓ"

Slide 5

Slide 5 text

%&.0 IUUQTHJUIVCDPNCPLVXFCSVTUZOFT

Slide 6

Slide 6 text

$16 31" 3*$0)੡ CJU.)[ 116 ϐΫνϟʔϓϩηοαϢχοτ31$ 30. ࠷େϓϩάϥϜ30.,J#ΩϟϥΫλ30.,J# 83". ϫʔΩϯά3".,J# 73". ϏσΦ3".,J# ࠷େൃ৭਺ ৭ ը໘ղ૾౓ ºϐΫηϧ α΢ϯυ ۣܗ೾ɺࡾ֯೾ɺϊΠζɺ%1$. ίϯτϩʔϥ ˢɺˣɺˡɺˠɺ"ɺ#ɺ45"35ɺ4&-&$5 ϑΝϛίϯͷεϖοΫ

Slide 7

Slide 7 text

$16 31" 116 31$ 73". ,J# 83". ,J# #6' Χηοτ .)[ .)[ /.* CJU116CVT CJU$16CVT "16 ϑΝϛίϯ σΟεϓϨΠ α΢ϯυ ίϯτϩʔϥ ϑΝϛίϯͷϒϩοΫਤ

Slide 8

Slide 8 text

ΤϛϡϨʔλΛ࡞Δʹ͸ ͜ΕΒͷσόΠεΛҰͭҰͭ ࣮૷͍ͯ͘͠ඞཁ͕͋Δ

Slide 9

Slide 9 text

·ͣ͸ϑΝϛίϯͷΧηοτ

Slide 10

Slide 10 text

2த਎͕Ͳ͏ͳͬͯΔ͔ ஌ͬͯ·͔͢ʁ

Slide 11

Slide 11 text

ϓϩάϥϜ30. "த਎͸͜͏ͳ͍ͬͯΔ

Slide 12

Slide 12 text

"த਎͸͜͏ͳ͍ͬͯΔ ΩϟϥΫλʔ30.

Slide 13

Slide 13 text

ຊମͱͷ઀ଓίωΫλ "த਎͸͜͏ͳ͍ͬͯΔ

Slide 14

Slide 14 text

------- GND -- |01 31| -- +5V CPU A11 -> |02 32| <- M2 CPU A10 -> |03 33| <- CPU A12 CPU A9 -> |04 34| <- CPU A13 CPU A8 -> |05 35| <- CPU A14 CPU A7 -> |06 36| <> CPU D7 CPU A6 -> |07 37| <> CPU D6 CPU A5 -> |08 38| <> CPU D5 CPU A4 -> |09 39| <> CPU D4 CPU A3 -> |10 40| <> CPU D3 CPU A2 -> |11 41| <> CPU D2 CPU A1 -> |12 42| <> CPU D1 CPU A0 -> |13 43| <> CPU D0 CPU R/W -> |14 44| <- /ROMSEL (/A15 + /M2) /IRQ <- |15 45| <- Audio from 2A03 GND -- |16 46| -> Audio to RF PPU /RD -> |17 47| <- PPU /WR CIRAM A10 <- |18 48| -> CIRAM /CE PPU A6 -> |19 49| <- PPU /A13 PPU A5 -> |20 50| <- PPU A7 PPU A4 -> |21 51| <- PPU A8 PPU A3 -> |22 52| <- PPU A9 PPU A2 -> |23 53| <- PPU A10 PPU A1 -> |24 54| <- PPU A11 PPU A0 -> |25 55| <- PPU A12 PPU D0 <> |26 56| <- PPU A13 PPU D1 <> |27 57| <> PPU D7 PPU D2 <> |28 58| <> PPU D6 PPU D3 <> |29 59| <> PPU D5 +5V -- |30 60| <> PPU D4 ------- ΧηοτͷίωΫλϐϯ഑ྻΛݟΔͱ $16116ͷCJUόε৴߸͕ͦΕͧΕ઀ଓ͞Ε͍ͯΔ Χηοτͷϐϯ഑ྻ $16ͷόε৴߸ 116ͷόε৴߸

Slide 15

Slide 15 text

ΩϟϥΫλʔ 30. 116 $16 ϑΝϛίϯຊମ ϓϩάϥϜ 30. Χηοτ $16όεΛհͯ͠ Ϧʔυ͞ΕΔ 116όεΛհͯ͠ Ϧʔυ͞ΕΔ Χηοτͱຊମͱͷόε઀ଓ

Slide 16

Slide 16 text

ϓϩάϥϜ30.ͱ͸

Slide 17

Slide 17 text

ήʔϜϓϩάϥϜ͕֨ೲ͞Εͨ30. $16͸ϓϩάϥϜ30.͔Β໋ྩϑΣονͯ͠ϓϩάϥϜ Λ࣮ߦ͢Δ void main() { char i; *(char*)0x2000 = 0x00; *(char*)0x2001 = 0x00; ͜Μͳͷ͕ "'''"ʜ ͜Μͳײ͡Ͱ٧·ͬͯΔ ϓϩάϥϜ30.ͱ͸

Slide 18

Slide 18 text

ΩϟϥΫλʔ30.ͱ͸

Slide 19

Slide 19 text

ºͷήʔϜը૾͕֨ೲ͞Εͨ30.ʢ࠷େ,J#ʣ എܠͱΩϟϥΫλʔͦΕͧΕͷσʔλ͕٧·ͬͯΔ 116͕ΩϟϥΫλʔ30.͔Βը૾σʔλΛಡΜͰ ը໘্ʹ഑ஔ͢Δ ΩϟϥΫλʔ30.ͱ͸

Slide 20

Slide 20 text

ՄࢹԽͯ͠ΈΔͱ

Slide 21

Slide 21 text

ҎԼ͸ઌఔͷσϞʮGBMMJOHʯͷΩϟϥΫλʔ30.ͷத਎ ΩϟϥΫλʔ30.ͱ͸

Slide 22

Slide 22 text

̔#ZUFº#ZUFͰºαΠζͷը૾͕දݱ͞ΕΔ ҎԼ͸30.಺ͷεϓϥΠτΠϯσοΫε͕ϋʔτϚʔΫͩͬͨ৔߹ͷྫ "EESFTTT %BUB Y Y Y Y' Y Y'' Y Y'' Y Y'' Y Y& Y Y$ Y Y "EESFTTT %BUB Y Y Y Y' Y" Y#' Y# Y#' Y$ Y'' Y% Y& Y& Y$ Y' Y ΩϟϥΫλʔ30.ͷσʔλ

Slide 23

Slide 23 text

ΤϛϡϨʔλͰ͸͜ΕΒͷ৘ใΛ Ͳ͏औΓѻ͑͹͍͍͔

Slide 24

Slide 24 text

J/&4ϑΥʔϚοτ

Slide 25

Slide 25 text

$POTUBOU&" /&4GPMMPXFECZ.4%04FOEPGpMF 4J[FPG13(30.JO,#VOJUT 4J[FPG$)330.JO,#VOJUT 7BMVFNFBOTUIFCPBSEVTFT$)33". 'MBHT 'MBHT 4J[FPG13(3".JO,#VOJUT 7BMVFJOGFST,#GPSDPNQBUJCJMJUZTFF13(3".DJSDVJU 'MBHT 'MBHT VOPGpDJBM ;FSPpMMFE #ZUF ,J#ZUF#MPDLTJ[F J/&4 IFBEFS J/&4 IFBEFS ϓϩάϥϜ30. ϓϩάϥϜ30. ΩϟϥΫλʔ30. ,J#ZUF#MPDLTJ[F J/&4IFBEFS ֦ுྖҬ J/&4ϑΥʔϚοτͷத਎ #ZIFBEFSͷ#ZUFʹ ֤30.ͷϒϩοΫαΠζ͕ ֨ೲ͞Ε͍ͯΔ

Slide 26

Slide 26 text

·ͣ͸OFTΛಡΜͰղੳͯ͠ ֤30.Λ੾Γग़ͯ͠΍Δඞཁ͕͋Δ

Slide 27

Slide 27 text

XBTN͔ΒOFTϑΝΠϧΛಡΉͷ͸େม ࠓճ͸+BWB4DSJQUଆͰOFTϑΝΠϧΛ GFUDIͯ͠3VTU XBTN ଆʹҾ͖౉͢͜ͱʹͨ͠

Slide 28

Slide 28 text

const run = Module.cwrap("run", null, ["number", "number"]); const res = await fetch("./PATH_TO_NES_FILE.nes"); const arrayBuf = await res.arrayBuffer(); const nes = new Uint8Array(arrayBuf); const size = nes.byteLength; const ptr = Module._malloc(size); const buf = new Uint8Array(Module.HEAPU8.buffer, ptr, size); buf.set(nes); run(size, buf.byteOffset); +BWB4DSJQUଆͷॳظԽॲཧ 3VTUଆͷؔ਺Λ+4 ͔Βݺ΂ΔΑ͏ʹ ͜Ε͸Ҿ਺

Slide 29

Slide 29 text

const run = Module.cwrap("run", null, ["number", "number"]); const res = await fetch("./PATH_TO_NES_FILE.nes"); const arrayBuf = await res.arrayBuffer(); const nes = new Uint8Array(arrayBuf); const size = nes.byteLength; const ptr = Module._malloc(size); const buf = new Uint8Array(Module.HEAPU8.buffer, ptr, size); buf.set(nes); run(size, buf.byteOffset); +BWB4DSJQUଆͷॳظԽॲཧ OFTϑΝΠϧΛϑΣον ͯ͠"SSBZ#VGGFSʹม׵

Slide 30

Slide 30 text

const run = Module.cwrap("run", null, ["number", "number"]); const res = await fetch("./PATH_TO_NES_FILE.nes"); const arrayBuf = await res.arrayBuffer(); const nes = new Uint8Array(arrayBuf); const size = nes.byteLength; const ptr = Module._malloc(size); const buf = new Uint8Array(Module.HEAPU8.buffer, ptr, size); buf.set(nes); run(size, buf.byteOffset); +BWB4DSJQUଆͷॳظԽॲཧ OFTϑΝΠϧ෼ͷྖҬΛ NBMMPDͰ֬อ ʢFNTDSJQUFOΛ࢖༻ͨ͠৔߹ .PEVMFʹੜ͑ͯΔʣ +4ଆ͔Β͸XBTNଆͷϝϞϦ͸"SSBZ#VGGFS ʹݟ͑ΔͷͰCZUF0GGTFUΛJ/&4σʔλͷઌ಄ ʢ͢ͳΘͪϙΠϯλʣͱͯ͠αΠζͱҰॹʹڭ͑ ͯ΍Δ

Slide 31

Slide 31 text

#[no_mangle] pub fn run(len: usize, ptr: *mut u8) { let buf: &mut [u8] = unsafe { std::slice::from_raw_parts_mut(ptr, len + 1) }; let cassette = parse(buf); let prom = Rom::new(cassette.program_rom); let crom = Rom::new(cassette.character_rom); // ... লུ …. } pub fn parse(buf: &mut [u8]) -> Cassette { let program_rom_pages = buf[4] as usize; let character_rom_pages = buf[5] as usize; let character_rom_start = NES_HEADER_SIZE + program_rom_pages * PROGRAM_ROM_SIZE; let character_rom_end = character_rom_start + character_rom_pages * CHARACTER_ROM_SIZE; Cassette { program_rom: buf[NES_HEADER_SIZE..character_rom_start].to_vec(), character_ram: buf[character_rom_start..character_rom_end].to_vec(), } } 3VTU XBTN ଆͷॳظԽॲཧ +4ଆ͔ΒJ/&4σʔλͷ αΠζͱϙΠϯλΛ΋Β͏ QBSTF֤ͯ͠30.Λ෼཭ ޙड़͢Δ$16͕ϓϩάϥϜ30. ͷ಺༰Λ࣮ߦ͢Ε͹ήʔϜ͕։࢝͢Δʣ

Slide 32

Slide 32 text

#[no_mangle] pub fn run(len: usize, ptr: *mut u8) { let buf: &mut [u8] = unsafe { std::slice::from_raw_parts_mut(ptr, len + 1) }; let cassette = parse(buf); let prom = Rom::new(cassette.program_rom); let crom = Rom::new(cassette.character_rom); // ... লུ …. } pub fn parse(buf: &mut [u8]) -> Cassette { let program_rom_pages = buf[4] as usize; let character_rom_pages = buf[5] as usize; let character_rom_start = NES_HEADER_SIZE + program_rom_pages * PROGRAM_ROM_SIZE; let character_rom_end = character_rom_start + character_rom_pages * CHARACTER_ROM_SIZE; Cassette { program_rom: buf[NES_HEADER_SIZE..character_rom_start].to_vec(), character_ram: buf[character_rom_start..character_rom_end].to_vec(), } } 3VTU XBTN ଆͷॳظԽॲཧ J/&4ϔομͷ৘ใ͔Β ֤30.Λ੾Γग़͢

Slide 33

Slide 33 text

build: mkdir -p wasm rm -rf target/wasm32-unknown-emscripten/release/deps/*.wasm rm -rf target/wasm32-unknown-emscripten/release/rustynes.js cargo rustc --release \ --target=wasm32-unknown-emscripten -- \ -C opt-level=3 \ -C link-args="-O3 -s -s EXPORTED_FUNCTIONS=['_run'] -s EXTRA_EXPORTED_RUNTIME_METHODS=['cwrap']" \ --verbose cp target/wasm32-unknown-emscripten/release/rustynes.js wasm/rustynes.js cp target/wasm32-unknown-emscripten/release/deps/*.wasm wasm/rustynes.wasm wasm-gc wasm/rustynes.wasm wasm/rustynes.wasm ϏϧυίϚϯυ +4ଆʹFYQPSU͢Δؔ਺Λ ࢦఆͯ͠΍Δඞཁ͕͋Δ

Slide 34

Slide 34 text

ϝϞϦʢ3".30.ʣ

Slide 35

Slide 35 text

pub struct Ram { pub field: Vec, } impl Ram { pub fn new(buf: Vec) -> Ram { Ram { field: buf } } pub fn read(&self, addr: u16) -> u8 { self.field[addr as usize] } pub fn write(&mut self, addr: u16, data: u8) { self.field[addr as usize] = data; } } 3".ͷ࣮૷

Slide 36

Slide 36 text

$16͕ϝϞϦʹͲͷΑ͏ʹ ΞΫηε͢Δ͔஌ͬͯ·͔͢ʁ ׂ Ѫ

Slide 37

Slide 37 text

ͲͷΑ͏ʹϝϞϦʹ ΞΫηε͢Δͷ͔ݟͯΈΔ ׂ Ѫ

Slide 38

Slide 38 text

ΞυϨε νοϓηϨΫτ Ϧʔυ σʔλ Y%&"% Y#& 43".ͷY%&"%൪஍ʹϦʔυΞΫηεΛߦ͍Y#&͕ಡΈग़͞ΕΔྫ 43".ͷϦʔυλΠϛϯάྫ όεʹ͸ଞʹ΋༷ʑͳσόΠε͕઀ଓ͞ΕΔ Մೳੑ͕͋ΔͷͰͲͷσόΠε͕༗ޮ͔ࣔ͢৴߸ νοϓηϨΫτɺΞυϨεɺϦʔυ৴߸ͳͲ Ϧʔυʹඞཁͳ৴߸͕ଗ͏ͱ3".͔Βσʔλ ׂ Ѫ

Slide 39

Slide 39 text

ΞυϨε νοϓηϨΫτ Ϧʔυ σʔλ Y%&"% Y#& 43".ͷY%&"%൪஍ʹϦʔυΞΫηεΛߦ͍Y#&͕ಡΈग़͞ΕΔྫ 43".ͷϦʔυλΠϛϯάྫ ͜ͷλΠϛϯάͰY#&Λϥον͢Δ σʔλ͸Ϧʔυ৴߸ͷ্ཱ͕ͪΓ΍ͦͷޙͷ $16ΫϩοΫͷ্ཱ͕ͪΓͰऔΓࠐ·ΕΔ΋ͷ͕ଟ͍ σόΠεʹϓϦϯτ͞Ε͍ͯΔ਺ࣈ͸͍͍ͩͨ͜͜ͷ਺ࣈ ʢDZDMF खݩͷ30.͸ͳͷͰ DZDMFOTҎ্ʹͯ͠Ͷͱ͍͏ҙຯ ׂ Ѫ

Slide 40

Slide 40 text

͢ͳΘͪɺ͜ΕΒͷ৴߸ΛλΠϛϯάΛकΓͭͭ ༩͑ͯ΍Ε͹Χηοτͷ30.͔Βσʔλ͕ಡΊΔ ׂ Ѫ

Slide 41

Slide 41 text

$16

Slide 42

Slide 42 text

w "QQMF**΍1$Τϯδϯʹ΋࠾༻͞Εͨϕʔε w ಈ࡞ΫϩοΫ͸.)[ w .04͔ΒෆཁͳػೳΛ࡟ͬͯ"16ͱ%"$Λ࣮૷ͨ͠ 3JDPI੡ͷΧελϜ඼ ϑΝϛίϯͷ$16

Slide 43

Slide 43 text

$16ͷϨδελҰཡ ໊শ αΠζ ৄࡉ " CJU ΞΩϡϜϨʔλ 9 CJU ΠϯσοΫεϨδελ : CJU ΠϯσοΫεϨδελ 4 CJU ελοΫϙΠϯλ 1 CJU εςʔλεϨδελ 1$ CJU ϓϩάϥϜΧ΢ϯλ ελοΫϙΠϯλ͸ϏοτͷΞυϨεۭؒΛࢦ͢ඞཁ͕͋Δ͕ ্ҐCJU͸Yʹݻఆ͞Ε͍ͯΔ ʢ83".ͷ͏ͪYʙY''ׂ͕Γ౰ͯΒΕΔʣ ͢ͳΘͪɺελοΫϙΠϯλϨδελ͕Y"ͷ৔߹ɺ ελοΫϙΠϯλ͸Y"ʹͳΔ ԋࢉ͸"ϨδελͰߦΘΕɺ9 :Ϩδελ͸ΠϯσοΫεʹ࢖༻͞ΕΔ


Slide 44

Slide 44 text

εςʔλεϨδελ CJU ໊শ ৄࡉ ಺༰ CJU / ωΨςΟϒ ԋࢉ݁ՌͷCJU͕ͷ࣌ʹηοτ CJU 7 Φʔόʔϑϩʔ 1ԋࢉ݁Ռ͕ΦʔόʔϑϩʔΛىͨ࣌͜͠ʹηο τ CJU 3 ༧໿ࡁΈ ৗʹηοτ͞Ε͍ͯΔ CJU # ϒϨʔΫϞʔυ #3,ൃੜ࣌ʹηοτɺ*32ൃੜ࣌ʹΫϦΞ CJU % σγϚϧϞʔυ σϑΥϧτɺ#$%Ϟʔυ ະ࣮૷ CJU * *32ېࢭ *32ڐՄɺ*32ېࢭ CJU ; θϩ ԋࢉ݁Ռ͕ͷ࣌ʹηοτ CJU $ ΩϟϦʔ ΩϟϦʔൃੜ࣌ʹηοτ εςʔλεϨδελͷৄࡉ CJU͸ৗʹͰɺCJU͸/&4Ͱ͸ະ࣮૷
 *32͸ׂΓࠐΈɺ#3,͸ιϑτ΢ΤΞׂΓࠐΈ

Slide 45

Slide 45 text

struct Status { negative: bool, overflow: bool, reserved: bool, break_mode: bool, decimal_mode: bool, interrupt: bool, zero: bool, carry: bool, } #[allow(non_snake_case)] pub struct Registers { A: u8, X: u8, Y: u8, SP: u8, PC: u16, P: Status, } $16ͷϨδελͷ࣮૷

Slide 46

Slide 46 text

ΞυϨε αΠζ ༻్ YʙY'' Y 83". YʙY''' 83".ͷϛϥʔ YʙY Y 116Ϩδελ YʙY''' 116Ϩδελͷϛϥʔ YʙY' Y "16*0ɺίϯτϩʔϥɺ%." YʙY''' Y'& ֦ு30. YʙY''' Y ֦ு3". YʙY#''' Y ϓϩάϥϜ30. Y$ʙY'''' Y ϓϩάϥϜ30. $16ͷϝϞϦϚοϓ Χηοτͷ ϓϩάϥϜ30.

Slide 47

Slide 47 text

impl<'a> CpuBus for Bus<'a> { fn read_word(&mut self, addr: u16) -> u16 { // …লུ… } fn read(&mut self, addr: u16) -> u8 { match addr { 0x0000...0x07FF => self.work_ram.read(addr), 0x0800...0x1FFF => self.work_ram.read(addr - 0x0800), 0x2000...0x3FFF => self.ppu.read(addr - 0x2000), 0x4016 => self.keypad.read(), 0x4017 => unimplemented!(), // 2player controller 0x4000...0x401F => self.apu.read(addr - 0x4000), 0x6000...0x7FFF => unimplemented!(), // battery back up ram 0x8000...0xBFFF => self.program_rom.read(addr - 0x8000), 0xC000...0xFFFF if self.program_rom.size() <= 0x4000 => self.program_rom.read(addr - 0xC000) 0xC000...0xFFFF => self.program_rom.read(addr - 0x8000), _ => panic!("[READ] There is an illegal address. (0x{:x}) access detected.", addr), } } fn write(&mut self, addr: u16, data: u8) { // …লུ… } } $16͸$QV#VTϞδϡʔϧΛհ֤ͯ͠σόΠεʹΞΫηε͢ΔΑ͏ʹ $16όεͷ࣮૷ ϝϞϦϚοϓΛ൓ө

Slide 48

Slide 48 text

$16͸Ͳͷ൪஍͔Β ͲͷλΠϛϯάͰىಈ͢Δ͔

Slide 49

Slide 49 text

ׂΓࠐΈ

Slide 50

Slide 50 text

ׂΓࠐΈ͕ൃੜ͢Δͱ$16͸ݱࡏͷ ίϯςΩετΛελοΫʹୀආ͠ ࢦఆΞυϨεʢׂΓࠐΈϕΫλςʔϒϧʣ ʹ֨ೲ͞Εͨ൪஍ΑΓ࣮ߦ։࢝ʢ࠶։ʣ͢Δ ͷׂΓࠐΈ

Slide 51

Slide 51 text

ͨͱ͑͹ɺϦηοτʢϑΝϛίϯͷ࢛֯ͷϘλϯͰ͢Ͷʣ΋ׂΓࠐΈͷҰछͰ Ϧηοτ͕ൃੜͨ͠৔߹Y'''$ɺY'''%͔ΒCJUͷΞυϨεΛϦʔυ͠ 1$ʢϓϩάϥϜΧ΢ϯλʣʹηοτ͠ɺηοτ͞ΕͨΞυϨε͔Β࣮ߦ͠·͢ ׂΓࠐΈ ԼҐόΠτ ্ҐόΠτ ֓ཁ /.* Y'''" Y'''# ϊϯϚεΧϥϒϧׂΓࠐΈͱݴͬͯ$16͸ଆͰϚεΫͰ͖ͳ ׂ͍ΓࠐΈͰ͢ɻ116ͷׂΓࠐΈग़ྗ৴߸͕઀ଓ͞Ε͍ͯ· ͢ 3&4&5 Y'''$ Y'''% ϦηοτϘλϯԡԼ࣌΍ిݯ౤ೖ࣌ʹ͔͔ΔׂΓࠐΈͰ͢ *32ɺ#3, Y'''& Y'''' #3,͸ιϑτ΢ΣΞׂΓࠐΈͰ#3,໋ྩΛ࣮ߦͨ͠ͱ͖ʹൃ ੜ͠·͢ɻ*32͸"16΍Χηοτʹ઀ଓ͞Ε͍ͯ·͢ ͷ৔߹ҎԼͷΑ͏ͳׂΓࠐΈཁҼ͕༻ҙ͞Ε͍ͯ·͢ ͷׂΓࠐΈ

Slide 52

Slide 52 text

ϦηοτׂΓࠐΈͷ৔߹

Slide 53

Slide 53 text

pub fn reset(registers: &mut T, bus: &mut U) { let pc = bus.read_word(0xFFFC); registers.set_PC(pc); } جຊతʹ͸ϓϩάϥϜ30.͸Yʹ഑ஔ͞Ε͍ͯΔͷͰ Y'''$͔ΒYɺY'''%͔ΒY͕Ϧʔυ͞ΕΔέʔε͕ଟ͍ ͦ͏͢Δͱ࣍αΠΫϧ͸ϓϩάϥϜ30.ͷઌ಄Ͱ͋ΔY͔Β࣮ߦ͞ΕΔ ϦηοτׂΓࠐΈͷ࣮૷ Y'''$Λ্ҐόΠτ Y'''%ΛԼҐόΠτ ͱͨ͠CJUΛϦʔυ Ϧʔυ͞ΕͨCJUͷΞυϨεΛ 1$ʢϓϩάϥϜΧ΢ϯλʣʹηοτ ࣍αΠΫϧ͸ηοτͨ͠ΞυϨε͔Β࣮ߦ͞ΕΔ

Slide 54

Slide 54 text

/.*ͷ৔߹

Slide 55

Slide 55 text

pub fn process_nmi(registers: &mut T, bus: &mut U) { registers.set_break(false); push((registers.get_PC() >> 8) as u8, registers, bus); push(registers.get_PC() as u8, registers, bus); push_status(registers, bus); registers.set_interrupt(true); let next = bus.read_word(0xFFFA); registers.set_PC(next); } /.*ͷ࣮૷ 1$ͷ্ҐCJUɺ1$ͷԼҐCJU ͷॱʹελοΫʹ164)

Slide 56

Slide 56 text

pub fn process_nmi(registers: &mut T, bus: &mut U) { registers.set_break(false); push((registers.get_PC() >> 8) as u8, registers, bus); push(registers.get_PC() as u8, registers, bus); push_status(registers, bus); registers.set_interrupt(true); let next = bus.read_word(0xFFFA); registers.set_PC(next); } /.*ͷ࣮૷ εςʔλεϨδελΛ ελοΫʹ164)

Slide 57

Slide 57 text

pub fn process_nmi(registers: &mut T, bus: &mut U) { registers.set_break(false); push((registers.get_PC() >> 8) as u8, registers, bus); push(registers.get_PC() as u8, registers, bus); push_status(registers, bus); registers.set_interrupt(true); let next = bus.read_word(0xFFFA); registers.set_PC(next); } /.*ͷ࣮૷ Y'''" Y'''#͔ΒΞυϨεΛ Ϧʔυ͠1$ʹηοτ

Slide 58

Slide 58 text

ྫ͑͹/.*લͷ1$͕YɺεςʔλεϨδελ͕Y"" ελοΫϙΠϯλ͕Y''ͩͱ͢Δͱ/.*ޙͷελοΫ͸ҎԼͷΠϝʔδ Y'' Y'&' Y'&& Y'&% Y'& ελοΫϙΠϯλ ʜ Y Y Y"" 1$ͷ্ҐΞυϨε 1$ͷԼҐΞυϨε εςʔλεϨδελ ࣍ճͷ164)͸͜͜ʹੵ·ΕΔ /.*ͷ࣮ߦޙͷελοΫΠϝʔδ

Slide 59

Slide 59 text

ͷ໋ྩ

Slide 60

Slide 60 text

Ͱ͸"%$ Ճࢉ 46# ݮࢉ ͳͲͷԋࢉͱ ԋࢉͷద༻ઌ΍ద༻ݩʢϨδελ΍ϝϞϦʣΛܾఆ͢Δ ΞυϨογϯάϞʔυ͕CJUͰදݱ͞Ε͍ͯΔ ͷ໋ྩ

Slide 61

Slide 61 text

ͨͱ͑͹

Slide 62

Slide 62 text

Y"͸-%"ͱ͍͏Ϩδελ"ʹ஋Λϩʔυ͢Δϩʔυ໋ྩͱ *NNFEJBUFͱ͍͏ଈ஋ΛऔΓѻ͏ΞυϨογϯάϞʔυ Y"͸-%"ͱ͍͏Ϩδελ"ʹ஋Λϩʔυ͢Δϩʔυ໋ྩͱ [FSPQBHFͱ͍͏্ҐCJU͕YͰ͋Δ൪஍Λૢ࡞͢ΔΞυϨογϯάϞʔυ ಉ͡-%"໋ྩͰ΋ΦϖϥϯυΛଈ஋ͱͯ͠ѻͬͨΓ্ҐYͷΞυϨεΛѻͬͨΓ ΞυϨγϯάϞʔυຖͷόϦΤʔγϣϯ͕͋Δ ԋࢉͷछྨºΞυϨογϯάϞʔυͰ໋ྩ͸໢ཏͰ͖ͦ͏ -%"໋ྩ

Slide 63

Slide 63 text

ུশ ໊લ ֓ཁ JNQM *NQMJFE ϨδελΛૢ࡞͢Δ " "DDVNVMBUPS "ϨδελΛૢ࡞͢Δ *NNFEJBUF Φϖίʔυ͕֨ೲ͞Ε͍ͯͨ࣍ͷ൪஍ʹ֨ೲ͞Ε͍ͯΔ஋Λσʔλͱͯ͠ѻ͏ [QH ;FSPQBHF YΛ্ҐΞυϨεɺ1$ʢΦϖίʔυͷ࣍ͷ൪஍ʣʹ֨ೲ͞Εͨ஋ΛԼҐΞυϨεͱͨ͠൪஍Λԋ ࢉର৅ͱ͢Δ [QH 9 [QH : ;FSPQBHF JOEFYFE YΛ্ҐΞυϨεɺ1$ʢΦϖίʔυͷ࣍ͷ൪஍ʣʹ֨ೲ͞Εͨ஋ʹ9Ϩδελ·ͨ͸:Ϩδελ ΛՃࢉͨ͠஋ΛԼҐΞυϨεͱͨ͠൪஍Λԋࢉର৅ͱ͢Δ BCT "CTPMVUF 1$ʢΦϖίʔυͷ࣍ͷ൪஍ʣʹ֨ೲ͞Εͨ஋ΛԼҐΞυϨεɺ1$ʢΦϖίʔυͷ࣍ͷ࣍ͷ൪஍ʣʹ ֨ೲ͞Εͨ஋Λ্ҐΞυϨεͱͨ͠൪஍Λԋࢉର৅ͱ͢Δ BCT 9 BCT : "CTPMVUF JOEFYFE "CTPMVUF"EESFTTJOHͰಘΒΕΔ஋ʹ9Ϩδελ·ͨ͸:ϨδελΛՃࢉͨ͠൪஍Λԋࢉର৅ͱ͢Δ SFM 3FMBUJWF 1$ʢΦϖίʔυͷ࣍ͷ൪஍ʣʹ֨ೲ͞Εͨ஋ͱͦͷ࣍ͷ൪஍ΛՃࢉͨ͠൪஍Λԋࢉର৅ͱ͢Δ 9 *OE *OEFYFE *OEJSFDU YΛ্ҐΞυϨεɺ1$ʢΦϖίʔυͷ࣍ͷ൪஍ʣʹ֨ೲ͞Εͨ஋ΛԼҐΞυϨεͱͨ͠൪஍ʹϨ δελ9ͷ஋ΛՃࢉɺͦͷ൪஍ͷ஋ΛԼҐΞυϨεɺͦͷ࣍ͷ൪஍ͷ஋Λ্ҐΞυϨεͱͨ͠൪஍Λ ԋࢉର৅ͱ͢Δ *OE : *OEJSFDU JOEFYFE YΛ্ҐΞυϨεɺ1$ʢΦϖίʔυͷ࣍ͷ൪஍ʣʹ֨ೲ͞Εͨ஋ΛԼҐΞυϨεͱͨ͠൪஍ͷ஋ ΛԼҐΞυϨεɺͦͷ࣍ͷ൪஍ͷ஋Λ্ҐΞυϨεͱͨ͠൪஍ʹϨδελ:ΛՃࢉͨ͠൪஍Λԋࢉର ৅ͱ͢Δ *OE "CTPMVUF JOEFYFE "CTPMVUF"EESFTTJOHͰಘΒΕΔ൪஍ʹ֨ೲ͞Ε͍ͯΔ஋ΛԼҐΞυϨεɺͦͷ࣍ͷ൪஍ʹ֨ೲ͞ Ε͍ͯΔ஋Λ্ҐΞυϨεͱͨ͠൪஍Λԋࢉର৅ͱ͢Δ ΞυϨογϯάϞʔυ

Slide 64

Slide 64 text

໋ྩද

Slide 65

Slide 65 text

ଟ͍

Slide 66

Slide 66 text

໋͍͔ͭ͘ྩΛϐοΫΞοϓ ͯ͠આ໌͠·͢

Slide 67

Slide 67 text

-%"JNN ଈ஋Λ"Ϩδελʹϩʔυ͢Δ

Slide 68

Slide 68 text

Yʹͱ͍͏໋ྩ͕֨ೲ͞Ε͍ͯΔ৔߹ ϝϞϦͱ࣮ߦखॱҎԼͷΑ͏ʹͳΔʢ1$΋Yͱ͢Δʣ -%" ʢY"ʣ Y Y" Y ʜ Y -%"" $16͸1$ ͢ͳΘͪY ͔Β໋ྩΛϑΣον͠1$Λ ϑΣον݁ՌY"͔Β-%"JNNͰ͋Δͱ൑ผ͞ΕΔ $16͸Y͔ΒΦϖϥϯυY"ΛϑΣον͠1$Λ Ϩδελ"ʹY"Λ֨ೲ͠ɺ࣍ͷ໋ྩ΁ -%"JNN ࣍ͷ໋ྩ ͜ͷ஋Λ"Ϩδελ ʹϩʔυ͢Δ 1$

Slide 69

Slide 69 text

pub fn lda_imm(operand: Word, registers: &mut T) { registers .set_A(operand as Data) .update_negative_by(operand as Data) .update_zero_by(operand as Data); } #[test] fn test_lda_immediate() { let mut reg = Registers::new(); lda_imm(0xA5, &mut reg); assert_eq!(reg.get_A(), 0xA5); } ଈ஋Λ"Ϩδελʹϩʔυ͢Δ -%"JNN "ϨδελʹΦϖϥϯυ ʹηοτ ηοτ͞Εͨ஋ʹରԠ͢Δ εςʔλεϑϥάΛηοτ

Slide 70

Slide 70 text

-%"[QH ্ҐΛYԼҐΛΦϖϥϯυͱͨ͠ΞυϨεʹ ֨ೲ͞Ε͍ͯΔ஋Λ"Ϩδελʹϩʔυ͢Δ

Slide 71

Slide 71 text

Yʹͱ͍͏໋ྩ͕֨ೲɺYʹ Y"͕֨ೲ͞Ε͍ͯΔ৔߹ϝϞϦͱ࣮ߦखॱҎԼͷΑ͏ʹͳΔ ʢ1$΋Yͱ͢Δʣ -%" ʢY"ʣ Y Y Y ʜ Y -%" $16͸1$ ͢ͳΘͪY ͔Β໋ྩΛϑΣον͠1$Λ ϑΣον݁ՌY"͔Β-%"[QHͰ͋Δͱ൑ผ͞ΕΔ $16͸Y͔ΒΦϖϥϯυYΛϑΣον͠1$Λ $16͸Y͔ΒY"ΛϦʔυ Ϩδελ"ʹY"Λ֨ೲ͠ɺ࣍ͷ໋ྩ΁ Y" Y ʜ Y ʜ Y ᶃY൪஍ͷ಺༰ΛϦʔυ ᶄY"Λ"Ϩδελʹηοτ -%"[QH ࣍ͷ໋ྩ 1$

Slide 72

Slide 72 text

pub fn lda(operand: Word, registers: &mut T, bus: &mut U) { let computed = bus.read(operand); registers .set_A(computed) .update_negative_by(computed) .update_zero_by(computed); } #[test] fn test_lda() { let mut reg = Registers::new(); let mut bus = MockBus::new(); bus.mem[0xAA] = 0xA5; lda(0xAA, &mut reg, &mut bus); assert_eq!(reg.get_A(), 0xA5); } -%"[QH ্ҐΛYԼҐΛΦϖϥϯυͱͨ͠ΞυϨεʹ ֨ೲ͞Ε͍ͯΔ஋Λ"Ϩδελʹϩʔυ͢Δϩʔυ͢Δ Φϖϥϯυͷ஋ΞυϨεͱͯ͠Ϧʔυ Ϧʔυ͞Εͨ஋Λ"Ϩδελʹηοτ

Slide 73

Slide 73 text

͜͜·Ͱͷ$16ͷಈ࡞Λ·ͱΊΔͱ

Slide 74

Slide 74 text

Ϧηοτ ແ͠ ແ͠ ༗Γ ༗Γ ׂΓࠐΈ ༗ແ Φϖϥϯυ ༗ແ Ϩδελͷ ঢ়ଶΛୀආ 1$͔Β໋ྩ ΛϑΣον 1$ 1$͔ΒΦϖϥϯυΛ ϑΣον 1$ ໋ྩΛ࣮ߦ ׂΓࠐΈϕΫλ ͷ஋Λ1$ ʹηοτ $16ͷಈ࡞Πϝʔδ Y'''$'''%ʹ ֨ೲ͞Εͨ൪஍͔Β։࢝

Slide 75

Slide 75 text

pub fn run( registers: &mut T, bus: &mut U, nmi: &mut bool, ) -> Data { if *nmi { process_nmi(registers, bus); *nmi = false; } let code = fetch(registers, bus); let ref map = opecode::MAP; let code = &*map.get(&code).unwrap(); let operand = fetch_operand(&code, registers, bus); match code.name { Instruction::LDA if code.mode == Addressing::Immediate => lda_imm(operand, registers), Instruction::LDA => lda(operand, registers, bus), // …লུ… } code.cycle } $16ͷ࣮૷ ׂΓࠐΈͷνΣοΫ

Slide 76

Slide 76 text

pub fn run( registers: &mut T, bus: &mut U, nmi: &mut bool, ) -> Data { if *nmi { process_nmi(registers, bus); *nmi = false; } let code = fetch(registers, bus); let ref map = opecode::MAP; let code = &*map.get(&code).unwrap(); let operand = fetch_operand(&code, registers, bus); match code.name { Instruction::LDA if code.mode == Addressing::Immediate => lda_imm(operand, registers), Instruction::LDA => lda(operand, registers, bus), // …লུ… } code.cycle } $16ͷ࣮૷ 1$͔Β໋ྩΛϑΣον σίʔυ ࣙॻ͔Β໋ྩͷछผɾΞυϨογϯά ϞʔυɺαΠΫϧ਺ͳͲΛҾ͍ͯ͘Δ

Slide 77

Slide 77 text

$16ͷ࣮૷ let mut m = HashMap::new(); m.insert(0xA9, Opecode { name: Instruction::LDA, mode: Addressing::Immediate, cycle: cycles[0xA9] }); m.insert(0xA5, Opecode { name: Instruction::LDA, mode: Addressing::ZeroPage, cycle: cycles[0xA5] }); m.insert(0xB5, Opecode { name: Instruction::LDA, mode: Addressing::ZeroPageX, cycle: cycles[0xB5] }); m.insert(0xAD, Opecode { name: Instruction::LDA, mode: Addressing::Absolute, cycle: cycles[0xAD] }); m.insert(0xBD, Opecode { name: Instruction::LDA, mode: Addressing::AbsoluteX, cycle: cycles[0xBD] }); m.insert(0xB9, Opecode { name: Instruction::LDA, mode: Addressing::AbsoluteY, cycle: cycles[0xB9] }); m.insert(0xA2, Opecode { name: Instruction::LDX, mode: Addressing::Immediate, cycle: cycles[0xA2] }); m.insert(0xA6, Opecode { name: Instruction::LDX, mode: Addressing::ZeroPage, cycle: cycles[0xA6] }); // …লུ… ΞυϨογϯάϞʔυ΍αΠΫϧ਺ Λ൑ผ

Slide 78

Slide 78 text

pub fn run( registers: &mut T, bus: &mut U, nmi: &mut bool, ) -> Data { if *nmi { process_nmi(registers, bus); *nmi = false; } let code = fetch(registers, bus); let ref map = opecode::MAP; let code = &*map.get(&code).unwrap(); let operand = fetch_operand(&code, registers, bus); match code.name { Instruction::LDA if code.mode == Addressing::Immediate => lda_imm(operand, registers), Instruction::LDA => lda(operand, registers, bus), // …লུ… } code.cycle } $16ͷ࣮૷ 1$͔ΒΦϖϥϯυΛϑΣον αΠΫϧ਺Λฦ͢ -%"JNNҎ֎ͷ-%"໋ྩ -%"JNN໋ྩ

Slide 79

Slide 79 text

͋ͱ͸໋֤ͭͭ͜͜ྩΛ࣮૷$

Slide 80

Slide 80 text

ͪͳΈʹޮ཰ͷ͍͍ςετํ๏͸

Slide 81

Slide 81 text

ςετ30.Λ࢖༻͢Δ

Slide 82

Slide 82 text

OFTUFTUOFT

Slide 83

Slide 83 text

116

Slide 84

Slide 84 text

w ϐΫνϟʔϓϩηογϯάϢχοτͷུ w 73".ͳͲͷ಺༰Λ΋ͱʹεϓϥΠτͱόοΫάϥ΢ϯυ ͷϨΠϠʔΛ߹੒ͯ͠ग़ྗ͢Δ w $16ͷഒͷΫϩοΫͰಈ࡞ w ͍Θ͹ݪ࢝తͳ(16ͱ͍ͬͯ΋͍͍͔΋ 116ͱ͸

Slide 85

Slide 85 text

116ͷϝϞϦϚοϓ

Slide 86

Slide 86 text

ΞυϨε αΠζ ֓ཁ YʙY''' Y ύλʔϯςʔϒϧ YʙY''' Y ύλʔϯςʔϒϧ YʙY#' Y$ ωʔϜςʔϒϧ Y$ʙY'' Y ଐੑςʔϒϧ YʙY#' Y$ ωʔϜςʔϒϧ Y$ʙY'' Y ଐੑςʔϒϧ YʙY##' Y$ ωʔϜςʔϒϧ Y#$ʙY#'' Y ଐੑςʔϒϧ Y$ʙY'#' Y$ ωʔϜςʔϒϧ Y'$ʙY''' Y ଐੑςʔϒϧ YʙY&'' YY&''ͷϛϥʔ Y'ʙY'' Y όοΫάϥ΢ϯυύϨοτςʔϒϧ Y'ʙY'' Y εϓϥΠτύϨοτςʔϒϧ Y'ʙY''' Y'Y''ͷϛϥʔ 116ͷϝϞϦϚοϓ Χηοτͷ ΩϟϥΫλʔ30.

Slide 87

Slide 87 text

Α͘Θ͔Βͳ͍ςʔϒϧ ͕͍ͬͺ͍

Slide 88

Slide 88 text

ϝϞϦϚοϓͷ֤߲໨ʹ͍ͭͯ આ໌͍ͯ͘͠

Slide 89

Slide 89 text

ωʔϜςʔϒϧ

Slide 90

Slide 90 text

73".ྖҬ಺഑ஔ͞ΕΔɺը໘ʹରͯ͠ͲͷΑ͏ʹ എܠλΠϧΛෑ͖٧ΊΔ͔ΛܾΊΔςʔϒϧ ը໘ղ૾౓͸YϐΫηϧͳͷͰYϐΫηϧͷλΠϧ͕ Yʢ͢ͳΘͪຕʣͰෑ͖٧ΊΒΕΔ͜ͱʹͳΔ ͳͷͰ ֤ωʔϜςʔϒϧͷαΠζ͸ Y$#ZUF ωʔϜςʔϒϧͱ͸

Slide 91

Slide 91 text

ͨͱ͑͹ҎԼͷը໘ͷ৔߹Y$ͷՕॴʹ)͕දࣔ͞͞ΕͯΔ ͢ͳΘͪɺɹɹʹ)Λද͢εϓϥΠτ൪߸Λॻ͖ࠐΊ͹͜ͷҐஔʹɹ͕දࣔ͞ΕΔ ωʔϜςʔϒϧ ͷઌ಄ λΠϧ λΠϧ ωʔϜςʔϒϧ ͷ$൪஍ʹ૬౰ Y$൪஍ ) ωʔϜςʔϒϧ ͷऴ୺ ωʔϜςʔϒϧͱ͸

Slide 92

Slide 92 text

)FMMP 8PSMEͷαϯϓϧ30.ͷΩϟϥΫλʔ30.ͷ಺༰͸ҎԼͷΑ͏ʹͳ͍ͬͯΔ )ͷΠϯσοΫε͸ͳͷͰ ɺɹɹʹ)Λද͢ΛϥΠτ͢Ε͹Α͍ Y$൪஍ ωʔϜςʔϒϧͱ͸

Slide 93

Slide 93 text

ଐੑςʔϒϧ

Slide 94

Slide 94 text

എܠʹͲͷύϨοτΛద༻͢Δ͔Λܾఆ͢Δςʔϒϧ ஫ҙ఺ͱͯ͠͸ύϨοτ͸YϐΫηϧͷϒϩοΫ୯Ґ ͢ͳΘͪʢYλΠϧʣʹύϨοτʢ̐৭ʣద༻͞ΕΔ ϒϩοΫʹ͖ͭCJUͷ৘ใΛ͓࣋ͬͯΓɺը໘YͳͷͰ YϒϩοΫϒϩοΫɺϒϩοΫʹ͖ͭCJU ͳͷͰόΠτͷྖҬΛ࢖༻͢Δ ଐੑςʔϒϧͱ͸

Slide 95

Slide 95 text

ྫ͑͹ଐੑςʔϒϧͷઌ಄൪஍Ͱ͋ΔY$൪஍͕Y&Ͱ͋Ε͹ @@@CͳͷͰҎԼͷΑ͏ʹϒϩοΫʹద༻͞ΕΔύϨοτ͕ܾఆ͢Δ ԾʹҎԼͷύϨοτ͕ઃఆ͞Ε͍ͯͨͱ͢Δͱ λΠϧ ϒϩοΫ λΠϧ ϒϩοΫ ͜ͷϒϩοΫ Y ͸ ͳͷͰ͕ ࢖༻Ͱ͖Δ ύϨοτ ͜ͷϒϩοΫ͸ ͜ͷϒϩοΫ͸ ͜ͷϒϩοΫ͸ ଐੑςʔϒϧͱ͸

Slide 96

Slide 96 text

ύϨοτςʔϒϧ

Slide 97

Slide 97 text

എܠ༻ʹ৭ͷύϨοτ͕ͭʢY'ʙY''ʣ εϓϥΠτ༻ʹ̐৭ͷύϨοτ͕ͭʢY'ʙY''ʣ ༻ҙ͞Ε͍ͯΔ ͨͩ͠ɺ֤എܠ༻ύϨοτͷઌ಄ͷ৭͸എܠ৭ ֤εϓϥΠτ༻ύϨοτͷઌ಄ͷ৭͸ಁ໌ͱͯ͠ѻΘΕΔ ಉ࣌ʹ࢖༻Ͱ͖Δ৭͸എܠ༻͸࠷େ৭ εϓϥΠτ༻͸࠷େ৭ಉ࣌ʹ࢖༻Ͱ͖Δ ύϨοτςʔϒϧͱ͸

Slide 98

Slide 98 text

ͨͱ͑͹εύʔϚϦΦϒϥβʔεͷΦʔϓχϯάը໘͸ҎԼͷΑ͏ͳ ύϨοτ͕ઃఆ͞Ε͍ͯΔ ύϨοτY' ύϨοτY' ύϨοτY' ύϨοτY'$ ύϨοτY' ύϨοτY' ύϨοτY' ύϨοτY'$ എܠ༻ύϨοτʢഎܠ৭৭৭YύϨοτͰ৭ʣ εϓϥΠτ༻ύϨοτʢ৭͸ಁ໌৭ͳͷͰ৭YύϨοτͰ৭ʣ ֤ςʔϒϧͷઌ಄ ͸ಁ໌৭ͱͯ͠ ѻΘΕΔ ಁ໌৭ ಁ໌৭ ಁ໌৭ ֤ςʔϒϧͷઌ಄ ͸എܠ৭ എܠ৭ എܠ৭ എܠ৭ ϚϦΦ͸ӈଆͷ৭Ͱදݱ͞Ε͍ͯΔ ύϨοτςʔϒϧͱ͸

Slide 99

Slide 99 text

஋ͱ৭ͱͷରԠ͸ʁ

Slide 100

Slide 100 text

IUUQTXJLJOFTEFWDPNXJOEFYQIQ116@QBMFUUFTΑΓ ϑΝϛίϯͷ৭͸116͕/54$৴߸Λ௚઀ੜ੒͢Δؔ܎্3(#Ͱ͸ͳ͘ ً౓ʢϧϛφϯεʣͱ৭౓ʢΫϩϚʣͰදݱ͞ΕΔ ͨͱ͑͹εʔύʔϚϦΦϒϥβʔεͷۭͷ৭͸Y͸ҎԼͷΑ͏ͳҙຯΛ΋ͭ Y @C ৗʹ ً౓ ৭౓ ύϨοτͷ৭ ً౓ ৭౓

Slide 101

Slide 101 text

116ͷϨδελΛோΊΔ

Slide 102

Slide 102 text

ΞυϨε ֓ཁ Y Y CJU આ໌ 7#MBOL࣌ʹׂΓࠐΈΛग़ྗ ৗʹ̍ εϓϥΠταΠζYY എܠ༻ύλʔϯςʔϒϧΞυϨεYY εϓϥΠτύλʔϯςʔϒϧΞυϨεYY 116ΞυϨεΠϯΫϦϝϯτ ωʔϜςʔϒϧࢦఆ CJU આ໌ എܠ৭CࠇC྘C੨C੺
 εϓϥΠτΠωʔϒϧσΟηʔϒϧΠωʔϒϧ എܠΠωʔϒϧσΟηʔϒϧΠωʔϒϧ εϓϥΠτͷը໘ࠨϐΫηϧඳըඳը͠ͳ͍ඳը͢Δ എܠͷը໘ࠨϐΫηϧඳըඳը͠ͳ͍ඳը͢Δ σΟεϓϨΠλΠϓΧϥʔϞϊΫϩ 116ͷϨδελ 8SJUF

Slide 103

Slide 103 text

ΞυϨε ֓ཁ Y εϓϥΠτϝϞϦΞυϨε YΛܦ༝ͯ͠εϓϥΠτϝϞϦ΁ॻ͖ࠐΉϏοτΞυϨεΛࢦఆ Y εϓϥΠτϝϞϦσʔλ YʹΑͬͯࢦఆ͞ΕͨεϓϥΠτϝϞϦΞυϨε΁σʔλΛॻ͖ࠐΉɻ ॻ͖ࠐΉ౓ʹεϓϥΠτϝϞϦΞυϨε͸ΠϯΫϦϝϯτ ͞ΕΔɻ Y എܠεΫϩʔϧΦϑηοτ ճϥΠτΛߦ͏͜ͱͰ9ɺ:ͷॱʹεΫϩʔϧ஋͕ઃఆ͞ΕΔ Y 116"%%3 116ϝϞϦΞυϨε YΛܦ༝ͯ͠116ϝϞϦ΁ॻ͖ࠐΉϏοτΞυϨεΛࢦఆ͢Δɻ্ҐϏοτɺԼҐϏοτͷॱ ʹॻ͖ࠐΉɻ Y 116%"5" 116ϝϞϦσʔλ YʹΑͬͯࢦఆ͞Εͨ116ϝϞϦΞυϨε΁σʔλΛॻ͖ࠐΉɻॻ͖ࠐΉ౓ʹϝϞϦΞυϨε͸Π ϯΫϦϝϯτ YͷϏοτʹΑͬͯɺ ͢Δɻ 116ͷϨδελ 8SJUF

Slide 104

Slide 104 text

ΞυϨε ֓ཁ Y Y εϓϥΠτϝϞϦσʔλ YʹΑͬͯࢦఆ͞ΕͨεϓϥΠτϝϞϦΞυϨε΁σʔλΛϦʔυ͢Δ Ϧʔυ͢Δ౓ʹεϓϥΠτϝϞϦΞυϨε͸ΠϯΫϦϝϯτ ͞ΕΔɻ Y 116ϝϞϦσʔλ YʹΑͬͯࢦఆ͞Εͨ116ϝϞϦΞυϨεͷσʔλΛϦʔυ͢Δ Ϧʔυ͢Δ౓ʹϝϞϦΞυϨε͸ΠϯΫϦϝϯτ YͷϏοτʹΑͬͯɺ ͢Δɻ CJU આ໌ 7CMBOL࣌ʹ εϓϥΠτώοτ࣌ʹ εΩϟϯϥΠϯεϓϥΠτ਺ɹݸҎԼݸҎ্ 3FTFSWFE 116ͷϨδελ 3FBE

Slide 105

Slide 105 text

͔͜͜Βॏཁͳ΋ͷΛൈ͖ग़ͯ͠ ౎౓આ໌͍͖ͯ͠·͢

Slide 106

Slide 106 text

தͰ΋ॏཁͳͷ͸

Slide 107

Slide 107 text

116"%%3116%"5"Ϩδελ

Slide 108

Slide 108 text

116ͷϝϞϦۭؒʢ73".ͳͲʣʹ$16͔ΒಡΈॻ͖͢ΔͨΊͷϨδελ $16 116 116"%%3 116%"5" 73". ΩϟϥΫλʔ30. 73".΍ΩϟϥΫλʔ30.͸116όεʹ઀ଓ͞Ε͓ͯΓ $16͔Β͸௚઀ΞΫηεͰ͖ͳ͍ ͦͷͨΊ116"%%3116%"5"Λհͯ͠ಡΈॻ͖͢Δ $16όε 116όε 116"%%3116%"5"Ϩδελ

Slide 109

Slide 109 text

Ͳ͏΍ͬͯ࢖͏͔

Slide 110

Slide 110 text

116ͷϝϞϦۭؒʢ73".ͳͲʣʹ$16͔ΒಡΈॻ͖͢ΔͨΊͷϨδελ 116"%%3 Y ʹ̎ճॻ͖ࠐΈ͜ͱͰ116ϝϞϦۭؒΛࢦఆ ྫ͑͹Y' YΛ116"%%3ʹॻ͖ࠐΉ͜ͱͰ 116ΞυϨε͕Y'ʹηοτ͞ΕΔ 116%"5" Y ʹϦʔυϥΠτ͢Δ͜ͱͰ116"%%3 Ͱࢦఆͨ͠116ϝϞϦۭؒΛಡΈॻ͖͢Δ͜ͱ͕Ͱ͖Δ ʢಡΈॻ͖Λ͢Δͱ116"%%3͸ࣗಈతʹ ·ͨ͸ ΠϯΫϦϝϯτ͞ΕΔʣ 116"%%3116%"5"Ϩδελ

Slide 111

Slide 111 text

͜͜·Ͱͷ࿩͔͠Β͢Δͱ 73".ͷ಺༰Λى఺ʹ Ճ޻͍͚ͯ͠͹ ϐΫηϧσʔλΛੜ੒Ͱ͖ͦ͏

Slide 112

Slide 112 text

ωʔϜςʔϒϧ͔ΒͲͷഎܠεϓϥΠτ͕഑ஔ͞Ε͍ͯΔ͔Ϧʔυ͢Δ Ϧʔυ͞ΕͨεϓϥΠτ൪߸ΛݩʹΧηοτ͔Βը૾σʔλΛಡΜͰ͘Δ ଐੑςʔϒϧ͔ΒഎܠεϓϥΠτʹద༻͞ΕΔύϨοτ൪߸ΛಡΜͰ͘Δ ύϨοτςʔϒϧ͔ΒύϨοτͷ৭ΛಡΜͰ͘Δ എܠεϓϥΠτͷCJU৘ใΛݩʹύϨοτ͔Βண৭͢Δ ͜ͷखॱͰωʔϜςʔϒϧ͔Β YQYͷϐΫηϧσʔλ͕ͭ͘ΕΔ͸ͣ 116ඳըखॱΠϝʔδ

Slide 113

Slide 113 text

΋͏ͪΐͬͱ۩ମతͳྫ

Slide 114

Slide 114 text

)FMMP 8PSMEͷ)ΛωʔϜςʔϒϧ͔ΒϐΫηϧσʔλʹͯ͠ΈΔྫ ωʔϜςʔϒϧͷΛϦʔυ͠εϓϥΠτ൪߸ΛಘΔ εϓϥΠτ͸ΩϟϥΫλʔ30.಺ʹ#ZUFͣͭฒΜͰ͍ΔͷͰ YYY͔Β#ZUFϦʔυ͠εϓϥΠτΛ૊ΈཱͯΔ Y$൪஍ Y ֘౰ͷ࠲ඪ͸ଐੑςʔϒϧͷΞυϨεY%"ʹ֘౰͢ΔͨΊ 73".ͷ͔ΒΞτϦϏϡʔτ͕Ϧʔυ͞ΕΔ Y%"൪஍ Y 116ඳըखॱΠϝʔδ ͜ΜͳεϓϥΠτ σʔλ͕ಘΒΕΔ

Slide 115

Slide 115 text

Ϧʔυ͞ΕͨΞτϦϏϡʔτ͔Β֘౰ϙδγϣϯͷύϨοτ൪߸Λ औΓग़͢ͱʹͳΔͷͰύϨοτ͕ద༻͞ΕΔ͜ͱ͕Θ͔Δ ύϨοτ͢ͳΘͪ73".ͷ#ZUFಡΉͱ ͕ϦʔυͰ͖Δɻ͜ΕΛΧϥʔίʔυදʹద༻͢Δͱ࣍ͷ৭Ͱ͋Δ͜ͱ͕Θ͔Δ ͨΊ3(#ʹม׵֤͠ϐΫηϧʹύϨοτΛద༻ͯ͠΍Δͱ׬੒ ύϨοτ̌ ׬੒✨ C Y'd Y' Y Y Y 116ඳըखॱΠϝʔδ )FMMP 8PSMEͷ)ΛωʔϜςʔϒϧ͔ΒϐΫηϧσʔλʹͯ͠ΈΔྫ

Slide 116

Slide 116 text

impl Tile { pub fn new( vram: &Ram, cram: &Ram, palette: &P, position: &SpritePosition, config: &SpriteConfig, ) -> Self { let block_id = get_block_id(position); let sprite_id = get_sprite_id(&vram, position, config); let attr = get_attribute(&vram, position, config); let palette_id = (attr >> (block_id * 2)) & 0x03; let sprite = build(&cram, sprite_id, config.offset_addr_by_background_table); Tile { sprite, palette: palette.get(palette_id, PaletteType::Background) } } } pub fn build(cram: &Ram, sprite_id: u8, offset: u16) -> Sprite { let mut sprite: Sprite = (0..8).into_iter().map(|_| vec![0; 8]).collect(); for i in 0..16 { for j in 0..8 { let addr = (sprite_id as u16) * 16 + i + offset; let ram = cram.read(addr); if ram & (0x80 >> j) as u8 != 0 { sprite[(i % 8) as usize][j] += (0x01 << (i / 8)) as u8; } } } sprite } 116ඳըखॱΠϝʔδ ࠲ඪ͔ΒϒϩοΫ൪߸ Λࢉग़ ࠲ඪͱωʔϜςʔϒϧ͔Β εϓϥΠτ൪߸Λࢉग़

Slide 117

Slide 117 text

impl Tile { pub fn new( vram: &Ram, cram: &Ram, palette: &P, position: &SpritePosition, config: &SpriteConfig, ) -> Self { let block_id = get_block_id(position); let sprite_id = get_sprite_id(&vram, position, config); let attr = get_attribute(&vram, position, config); let palette_id = (attr >> (block_id * 2)) & 0x03; let sprite = build(&cram, sprite_id, config.offset_addr_by_background_table); Tile { sprite, palette: palette.get(palette_id, PaletteType::Background) } } } pub fn build(cram: &Ram, sprite_id: u8, offset: u16) -> Sprite { let mut sprite: Sprite = (0..8).into_iter().map(|_| vec![0; 8]).collect(); for i in 0..16 { for j in 0..8 { let addr = (sprite_id as u16) * 16 + i + offset; let ram = cram.read(addr); if ram & (0x80 >> j) as u8 != 0 { sprite[(i % 8) as usize][j] += (0x01 << (i / 8)) as u8; } } } sprite } 116ඳըखॱΠϝʔδ ࠲ඪͱଐੑςʔϒϧ͔Β ΞτϦϏϡʔτΛࢉग़ ΞτϦϏϡʔτͱϒϩοΫ൪߸͔Β ύϨοτ൪߸Λࢉग़

Slide 118

Slide 118 text

impl Tile { pub fn new( vram: &Ram, cram: &Ram, palette: &P, position: &SpritePosition, config: &SpriteConfig, ) -> Self { let block_id = get_block_id(position); let sprite_id = get_sprite_id(&vram, position, config); let attr = get_attribute(&vram, position, config); let palette_id = (attr >> (block_id * 2)) & 0x03; let sprite = build(&cram, sprite_id, config.offset_addr_by_background_table); Tile { sprite, palette: palette.get(palette_id, PaletteType::Background) } } } pub fn build(cram: &Ram, sprite_id: u8, offset: u16) -> Sprite { let mut sprite: Sprite = (0..8).into_iter().map(|_| vec![0; 8]).collect(); for i in 0..16 { for j in 0..8 { let addr = (sprite_id as u16) * 16 + i + offset; let ram = cram.read(addr); if ram & (0x80 >> j) as u8 != 0 { sprite[(i % 8) as usize][j] += (0x01 << (i / 8)) as u8; } } } sprite } 116ඳըखॱΠϝʔδ εϓϥΠτ൪߸͔Β YͷϐΫηϧσʔλΛ ࡞੒

Slide 119

Slide 119 text

fn render_tile(&mut self, bg: &BackgroundCtx, x: usize, y: usize) { let offset_x = (bg.scroll_x % 8) as i32; let offset_y = (bg.scroll_y % 8) as i32; for i in 0..8 { for j in 0..8 { let x = (x + j) as i32 - offset_x; let y = (y + i) as i32 - offset_y; if x >= 0 as i32 && 0xFF >= x && y >= 0 as i32 && y < 224 { let color_id = bg.tile.palette[bg.tile.sprite[i][j] as usize]; let color = COLORS[color_id as usize]; let index = ((x + (y * 0x100)) * 4) as usize; self.buf[index] = color.0; self.buf[index + 1] = color.1; self.buf[index + 2] = color.2; if x < 8 { self.buf[index + 3] = 0; } } } } } pub static COLORS: &'static [(u8, u8, u8)] = &[ (0x80, 0x80, 0x80), (0x00, 0x3D, 0xA6), (0x00, 0x12, 0xB0), (0x44, 0x00, 0x96), …লུ… ]; 116ඳըखॱΠϝʔδ ً౓ɺ৭౓ͷσʔλΛ 3(#ʹม׵͢Δςʔϒϧ εϓϥΠτɺύϨοτ ͔Β3(#"ͷϐΫηϧσʔλ ʹม׵

Slide 120

Slide 120 text

ϐΫηϧσʔλ͸ಘΒΕ͕ͨ Ͳ͏΍ͬͯϒϥ΢βʹදࣔ͢Δ͔

Slide 121

Slide 121 text

$BOWBT

Slide 122

Slide 122 text

const canvas = document.querySelector("canvas"); const ctx = canvas.getContext("2d"); Module.NES = { ctx, canvas, image: ctx.createImageData(256, 240) }; mergeInto(LibraryManager.library, { canvas_render: function (ptr, len) { Module.NES.buf = new Uint8Array(Module.HEAPU8.buffer, ptr, len); Module.NES.image.data.set(Module.NES.buf); Module.NES.ctx.putImageData(Module.NES.image, 0, 0); }, }) +BWB4DSJQUଆͷॲཧ FNTDSJQUFOΛ࢖༻͍ͯ͠Δ৔߹ NFSHF*OUPΛ࢖༻ͯ͠+4ؔ਺Λ 3VTUଆʹެ։Ͱ͖Δ

Slide 123

Slide 123 text

const canvas = document.querySelector("canvas"); const ctx = canvas.getContext("2d"); Module.NES = { ctx, canvas, image: ctx.createImageData(256, 240) }; mergeInto(LibraryManager.library, { canvas_render: function (ptr, len) { Module.NES.buf = new Uint8Array(Module.HEAPU8.buffer, ptr, len); Module.NES.image.data.set(Module.NES.buf); Module.NES.ctx.putImageData(Module.NES.image, 0, 0); }, }) +BWB4DSJQUଆͷॲཧ 3VTUଆ͔ΒϐΫηϧσʔλͷ ϙΠϯλͱ௕͞Λ΋Βͬͯ *NBHF%BUBʹηοτ

Slide 124

Slide 124 text

extern "C" { fn canvas_render(ptr: *const u8, len: usize); } impl Renderer { pub fn render( &mut self, background: &BackgroundField, sprites: &SpritesWithCtx) { // …লུ… unsafe { canvas_render(self.buf.as_ptr(), self.buf.len()); } } 3VTU XBTN ଆͷॲཧ ͜Μͳ;͏ʹݺ΂Δ όοϑΝͷϙΠϯλͱ௕͞Λ ڭ͑ͯ͋͛Δ

Slide 125

Slide 125 text

͜ΕͰ73".ͷ಺༰Λ $BOWBTʹॻ͖ग़ͤͦ͏

Slide 126

Slide 126 text

͋ͱ͸$16ͱͷಉظͳͲ λΠϛϯάपΓ

Slide 127

Slide 127 text

ͦͷલʹ116ͷϝϞϦۭؒͷ ஫ҙ఺Λ͝঺հ ׂ Ѫ

Slide 128

Slide 128 text

116%"5"͔Β116ͷϝϞϦۭؒͷσʔλΛ$16͔ΒϦʔυͰ͖Δ͕ 116಺෦ʹ͸ϦʔυόοϑΝ͕ೖ͍ͬͯͯ116͔Βͷσʔλग़ྗ̍αΠΫϧ஗ΕΔ ͨͿΜҟͳΔΫϩοΫͷόε Λ·͙ͨͨΊ'*'0ΛೖΕͯಉظΛͱͬͯΔ ͨͩ͠ɺεϓϥΠτ3".ɺύϨοτςʔϒϧ͸আ͘ ʢ΍΍͍͜͠ʜʣ ͜Ε͸ʢଟ෼ʣεϓϥΠτ3".ɺύϨοτςʔϒϧ͸116ͷ಺෦ʹߏ੒͞Ε͍ͯͯ όεΛ·͍ͨͰ͍ͳ͍ʢ$16όε௚݁ʣ͡Όͳ͍͔ͱਪଌ ΤϛϡϨʔλ࡞ऀ͸͜ΕΛݟམͱ͢ͱপʹ͸·Δ 116ͷϝϞϦۭؒ஫ҙ఺ ׂ Ѫ

Slide 129

Slide 129 text

116ͷඳըλΠϛϯά

Slide 130

Slide 130 text

MJOFQJYFM جຊతʹ͸116DZDMFͰQJYFMͣͭඳը ࠨ͔Βը໘ͷӈ୺ʹ QJYFMͣͭඳը͍ͯ͘͠ EJTQMBZ 116ͷඳըλΠϛϯά

Slide 131

Slide 131 text

MJOFQJYFM ࣍ͷϥΠϯ΁ͷඳը४උΛؚΊΔͱMJOF͋ͨΓαΠΫϧඞཁ ࣍ͷϥΠϯ΁ͷ४උ ը໘ӈ୺·Ͱ౸ୡͨ͠Β ࣍ͷϥΠϯͷࠨ୺ʹ໭Δ ʢIWMBOL EJTQMBZ 116ͷඳըλΠϛϯά

Slide 132

Slide 132 text

MJOFQJYFM ը໘ͷӈԼ୺ʹ౸ୡ MJOF෼ ͨ͠Βը໘෼ͷඳը͕׬ྃ EJTQMBZ MJOF 116ඳըλΠϛϯά

Slide 133

Slide 133 text

MJOFQJYFM EJTQMBZ ࣍ͷඳըͷͨΊʹઌ಄΁໭Δ ͜ͷͨΊͷظؒΛͱݴ͍ MJOF෼ͷ࣌ؒΛཁ͢Δ Ұը໘ͷߋ৽ʹ͸ Y αΠΫϧ ඞཁͱͳΔ ͢ͳΘͪ 7CMBOL ը໘ͷӈԼ୺ʹ౸ୡ MJOF෼ ͨ͠Βը໘෼ͷඳը͕׬ྃ 116ඳըλΠϛϯά

Slide 134

Slide 134 text

MJOFQJYFM ͜ͷαΠΫϧΛඵؒʹճ '14 ܁Γฦ͢͜ͱͰ Ωϟϥ΍എܠ͕ͳΊΒ͔ʹಈ͖ήʔϜͱͯ͠੒ཱ͢Δ EJTQMBZ MJOF 116ඳըλΠϛϯά

Slide 135

Slide 135 text

116ͷσʔλߋ৽ͷ੍໿ ΤϛϡϨʔλ࡞ऀʹ͸ ͋·Γؔ܎ͳ͍͔΋

Slide 136

Slide 136 text

EJTQMBZ ඳըதʹ73".Λॻ͖׵͑Δͱը໘͕ΈͩΕͯ͠·͏ ඳըத 116ͷσʔλߋ৽ͷ੍໿

Slide 137

Slide 137 text

ඳըΛߦ͍ͬͯͳ͍7CMBOLதʹ73".Λॻ͖׵͑Δ $16͸116εςʔλεϨδελ·ͨ͸/.*ʹͯ 7MBOLͰ͋Δ͜ͱΛ஌Δ͜ͱ͕Ͱ͖Δ EJTQMBZ 7CMBOLத 116ͷσʔλߋ৽ͷ੍໿

Slide 138

Slide 138 text

pub fn run(&mut self, cycle: usize, nmi: &mut bool, mmc: &Mmc) -> bool { let cycle = self.cycle + cycle; if cycle < 341 { self.cycle = cycle; return false; } if self.line == 0 { self.background.clear(); } self.cycle = cycle - 341; self.line = self.line + 1; if self.line <= 240 && self.line % 8 == 0 { self.background.build_line( &self.ctx.vram, &self.ctx.cram, &self.ctx.palette, (tile_x, tile_y), ); } // …লུ… } 116ͷ࣮૷ 116αΠΫϧ਺ΛՃࢉ͍͖ͯ͠ MJOF׬͔ྃͨ͠Λ൑ఆ

Slide 139

Slide 139 text

pub fn run(&mut self, cycle: usize, nmi: &mut bool, mmc: &Mmc) -> bool { let cycle = self.cycle + cycle; if cycle < 341 { self.cycle = cycle; return false; } if self.line == 0 { self.background.clear(); } self.cycle = cycle - 341; self.line = self.line + 1; if self.line <= 240 && self.line % 8 == 0 { self.background.build_line( &self.ctx.vram, &self.ctx.cram, &self.ctx.palette, (tile_x, tile_y), ); } // …লུ… } 116ͷ࣮૷ ඳը۠ؒͰ͋Ε͹ ϥΠϯຖʹഎܠΛ ૊Έཱ͍ͯͯ͘ MJOFd

Slide 140

Slide 140 text

pub fn run(&mut self, cycle: usize, nmi: &mut bool, mmc: &Mmc) -> bool { //…লུ… if self.line == 241 { self.registers.set_vblank(); if self.registers.is_irq_enable() { *nmi = true; } } if self.line >= 262 { self.registers.clear_vblank(); self.line = 0; self.sprites = build_sprites( &self.ctx.cram, &self.ctx.sprite_ram, &self.ctx.palette, ); return true; } false } 116ͷ࣮૷ ׂΓࠐΈ༗ޮͰ͋Ε͹WCMBOL ࣌ʹ/.*ΛΞΫςΟϒʹઃఆ 7#MBOLϑϥάΛηοτ MJOF

Slide 141

Slide 141 text

pub fn run(&mut self, cycle: usize, nmi: &mut bool, mmc: &Mmc) -> bool { //…লུ… if self.line == 241 { self.registers.set_vblank(); if self.registers.is_irq_enable() { *nmi = true; } } if self.line >= 262 { self.registers.clear_vblank(); self.line = 0; self.sprites = build_sprites( &self.ctx.cram, &self.ctx.sprite_ram, &self.ctx.palette, ); return true; } false } 116ͷ࣮૷ ϥΠϯͰҰը໘෼ͷ ඳը͕׬੒ MJOF

Slide 142

Slide 142 text

͋ͱ͸$16ͱ116ɺඳըͷಉظΛ ͲͷΑ͏ʹͱΔ͔

Slide 143

Slide 143 text

ٯࢉͯ͘͠ͱྑͦ͞͏

Slide 144

Slide 144 text

ϑΝϛίϯ͸'14ɺ͢ͳΘͪNTຖʹ116͕ߋ৽ͨ͠ ը໘σʔλΛ࡞੒Ͱ͖Ε͹ྑ͍ લड़ͨ͠Α͏ʹը໘ͷߋ৽͸ 116αΠΫϧ ͳͷͰ NTຖʹ116͕ը໘ੜ੒͢Δ·Ͱ ໿ YαΠΫϧ $16Λ࣮ߦͯ͠΍Ε͹Α͍ 116ͷαΠΫϧ͸$16ͷഒ଎ʢഒͷΫϩοΫ͕ೖྗʣ $16ͱ116ͷಉظ

Slide 145

Slide 145 text

࣌ؒ NT NT ը໘෼ͷσʔλ͕ Ͱ͖Δ·Ͱ $16116Λ࣮ߦ ը໘෼ͷσʔλ͕ Ͱ͖Δ·Ͱ $16116Λ࣮ߦ ը໘෼ͷσʔλ͕ Ͱ͖Δ·Ͱ $16116Λ࣮ߦ ඳը ඳը ඳը ͜ΜͳΠϝʔδͰ࣮ߦ͍ͨ͠ NT $16ͱ116ͷಉظ

Slide 146

Slide 146 text

SFRVFTU"OJNBUJPO'SBNFΛ࢖͍͍ͨ '14Ͱಈ࡞͢ΔΑ͏ʹ͍͍ײ͡ʹ͕Μ͹ͬͯ͘ΕΔ΍ͭ

Slide 147

Slide 147 text

void emscripten_set_main_loop( em_callback_func func, int fps, int simulate_infinite_loop) FNTDSJQUFOΛ࢖༻͍ͯ͠Δ৔߹͍͕ͭ͜࢖͑Δ ୈೋҾ਺ʹΛηοτ͢ΔͱΛ ࢖ͬͯ͘ΕΔ SFRVFTU"OJNBUJPO'SBNF FNTDSJQUFO@TFU@NBJO@MPPQ ୈࡾҾ਺Ληοτ͢ΔͱແݶϧʔϓΛ γϛϡϨʔτ

Slide 148

Slide 148 text

MFUNBJO@MPPQcc\ nes::run(&mut ctx); }; externs::set_main_loop_callback(main_loop); pub fn run(ctx: &mut Context) { loop { // …লུ… let cycle: u16 = cpu::run(&mut ctx.cpu_registers, &mut cpu_bus, &mut ctx.nmi) as u16 let is_ready = ctx.ppu.run((cycle * 3) as usize, &mut ctx.nmi, &ctx.mmc); if is_ready { if ctx.ppu.background.0.len() != 0 { ctx.renderer.render(&ctx.ppu.background.0, &ctx.ppu.sprites); } break; } } } ϝΠϯϧʔϓͷ࣮૷ NTपظͰOFTSVOΛ࣮ߦ

Slide 149

Slide 149 text

MFUNBJO@MPPQcc\ nes::run(&mut ctx); }; externs::set_main_loop_callback(main_loop); pub fn run(ctx: &mut Context) { loop { // …লུ… let cycle: u16 = cpu::run(&mut ctx.cpu_registers, &mut cpu_bus, &mut ctx.nmi) as u16 let is_ready = ctx.ppu.run((cycle * 3) as usize, &mut ctx.nmi, &ctx.mmc); if is_ready { if ctx.ppu.background.0.len() != 0 { ctx.renderer.render(&ctx.ppu.background.0, &ctx.ppu.sprites); } break; } } } ϝΠϯϧʔϓͷ࣮૷ ߋ৽ͨ͠ը໘ͷϐΫηϧσʔλͷ४උ͕ Ͱ͖Δ·Ͱ$16ͱ116Λ࣮ߦ͢Δ $16ͷ࣮ߦαΠΫϧͷഒͷαΠΫϧΛ ౉͢ʢ116αΠΫϧ΁ͷม׵ʣOΛ࣮ߦ

Slide 150

Slide 150 text

MFUNBJO@MPPQcc\ nes::run(&mut ctx); }; externs::set_main_loop_callback(main_loop); pub fn run(ctx: &mut Context) { loop { // …লུ… let cycle: u16 = cpu::run(&mut ctx.cpu_registers, &mut cpu_bus, &mut ctx.nmi) as u16 let is_ready = ctx.ppu.run((cycle * 3) as usize, &mut ctx.nmi, &ctx.mmc); if is_ready { if ctx.ppu.background.0.len() != 0 { ctx.renderer.render(&ctx.ppu.background.0, &ctx.ppu.sprites); } break; } } } ϝΠϯϧʔϓͷ࣮૷ Ұը໘෼४උ͕Ͱ͖ͨΒϨϯμϦϯά

Slide 151

Slide 151 text

͜͜·Ͱ͕࣮૷Ͱ͖Ε͹ )FMMP 8PSME͕ඳըͰ͖ͦ͏

Slide 152

Slide 152 text

)&--0 803-%ͷαϯϓϧίʔυ ΛݟͯΈΔ

Slide 153

Slide 153 text

IUUQIQWFDUPSDPKQBVUIPST7"OFTTBNQMFIUNMΑΓ )&--0 803-%

Slide 154

Slide 154 text

)FMMP 8PSME char NesMain() { const char palettes[] = { 0x0f, 0x00, 0x10, 0x20, 0x0f, 0x06, 0x16, 0x26, 0x0f, 0x08, 0x18, 0x28, 0x0f, 0x0a, 0x1a, 0x2a }; const char string[] = "HELLO, WORLD!"; char i; *(char*)0x2000 = 0x00; *(char*)0x2001 = 0x00; *(char*)0x2006 = 0x3f; *(char*)0x2006 = 0x00; for (i = 0; i < 0x10; i ++) *(char*)0x2007 = palettes[i]; *(char*)0x2006 = 0x21; *(char*)0x2006 = 0xc9; for (i = 0; i < 13; i ++) *(char*)0x2007 = string[i]; *(char*)0x2000 = 0x08; *(char*)0x2001 = 0x1e; while (1); return 0; }

Slide 155

Slide 155 text

char NesMain() { const char palettes[] = { 0x0f, 0x00, 0x10, 0x20, 0x0f, 0x06, 0x16, 0x26, 0x0f, 0x08, 0x18, 0x28, 0x0f, 0x0a, 0x1a, 0x2a }; const char string[] = "HELLO, WORLD!"; എܠύϨοτσʔλ ৭෼Λࢦఆ ॻ͖ࠐΉจࣈྻ )FMMP 8PSME

Slide 156

Slide 156 text

*(char*)0x2000 = 0x00; *(char*)0x2001 = 0x00; *(char*)0x2006 = 0x3f; *(char*)0x2006 = 0x00; for (i = 0; i < 0x10; i ++) *(char*)0x2007 = palettes[i]; ඳը΍ׂΓࠐΈΛېࢭ Y' YΛYʹॻ͖ࠐΉ ͜ͱͰ116ΞυϨεY'Λࢦఆ ͭ·ΓഎܠύϨοτςʔϒϧྖҬ YʹσʔλΛॻ͖͜ΜͰ͍͘͜ͱͰ ઌʹࢦఆͨ͠Y'͔ΒॱʹQBMFUUTͷσʔλΛసૹ͍ͯ͘͠ 116ΞυϨε͸σʔλ͕ॻ͖ࠐ·ΕΔͨͼʹ116ଆͰࣗಈΠϯΫϦϝϯτ͞ΕΔ ͜ΕͰύϨοτσʔλͷసૹ͸0, )FMMP 8PSME

Slide 157

Slide 157 text

*(char*)0x2006 = 0x21; *(char*)0x2006 = 0xc9; for (i = 0; i < 13; i ++) *(char*)0x2007 = string[i]; *(char*)0x2000 = 0x08; *(char*)0x2001 = 0x1e; while (1); return 0; } Y Y$ΛYʹॻ͖ࠐΉ ͜ͱͰ116ΞυϨεY$Λࢦఆ Yʹॻ͖ࠐΉ͜ͱͰ Y$ʙʹA)&--0 803-%A Λసૹ ඳը։࢝ ͜ͷαϯϓϧ͸Ұ౓ը໘Λඳըͨ͠Β ߋ৽͞Εͳ͍ͷͰແݶϧʔϓ )FMMP 8PSME

Slide 158

Slide 158 text

)FMMP 8PSME

Slide 159

Slide 159 text

͜͜·ͰͰΑ͏΍͘ )&--0 803-%

Slide 160

Slide 160 text

ଞͷ30.Λಈ͔͢ʹ͸·ͩ·ͩ ػೳΛ࣮૷͠ͳͯ͘͸ͳΒͳ͍

Slide 161

Slide 161 text

εΫϩʔϧ

Slide 162

Slide 162 text

0x2000ʙ0x23BF 0x03C0 ωʔϜςʔϒϧ0 0x23C0ʙ0x23FF 0x0040 ଐੑςʔϒϧ0 0x2400ʙ0x27BF 0x03C0 ωʔϜςʔϒϧ1 0x27C0ʙ0x27FF 0x0040 ଐੑςʔϒϧ1 0x2800ʙ0x2BBF 0x03C0 ωʔϜςʔϒϧ2 0x2BC0ʙ0x2BFF 0x0040 ଐੑςʔϒϧ2 0x2C00ʙ0x2FBF 0x03C0 ωʔϜςʔϒϧ3 0x2FC0ʙ0x2FFF 0x0040 ଐੑςʔϒϧ3 116ͷϝϞϦϚοϓΛݟ௚͢ͱҎԼͷΑ͏ʹωʔϜςʔϒϧͱ ଐੑςʔϒϧͷηοτΛͭʢ͢ͳΘͪը໘෼ʣ࣋ͯΔΑ͏ʹͳ͍ͬͯΔ 116ͷϝϞϦϚοϓ ࠶

Slide 163

Slide 163 text

ը໘෼ͷςʔϒϧ͸ҎԼͷΑ͏ͳ഑ஔʹͳ͍ͬͯΔ ωʔϜଐੑςʔϒϧ YdY'' ωʔϜଐੑςʔϒϧ YdY'' ωʔϜଐੑςʔϒϧ YdY#'' ωʔϜଐੑςʔϒϧ Y$dY''' 116ͷωʔϜଐੑςʔϒϧͷ഑ஔ

Slide 164

Slide 164 text

ԣεΫϩʔϧήʔϜͷྫ

Slide 165

Slide 165 text

ҎԼͷΑ͏ʹTDSPMM@YΛࢦఆ͢Δ͜ͱͰσΟεϓϨΠʹ੾Γग़͢ྖҬΛมߋͰ͖Δ ωʔϜ ଐੑςʔϒϧ YdY'' ωʔϜ ଐੑςʔϒϧ YdY'' σΟεϓϨΠʹ͸ҎԼͷ෦෼͕੾Γग़͞Εͯ දࣔ͞ΕΔ TDSPMM@Y εΫϩʔϧͱදࣔྖҬͷؔ܎

Slide 166

Slide 166 text

εΫϩʔϧؔ͢ΔϨδελ͸ͭ ׂ Ѫ

Slide 167

Slide 167 text

ΞυϨε ֓ཁ Y എܠεΫϩʔϧΦϑηοτ ճϥΠτΛߦ͏͜ͱͰ9ɺ:ͷॱʹεΫϩʔϧ஋͕ઃఆ͞ΕΔ 1164$30--Ϩδελ αΠζ͕CJUͳͷͰd·ͰͷεΫϩʔϧ͕ઃఆͰ͖Δ ͜ͷͻͱͭͷϨδελͰYํ޲ɺZํ޲྆ํઃఆͰ͖ΔΑ͏ʹͳ͍ͬͯΔ ࠷ॳͷॻ͖ࠐΈ͕Yํ޲ɺೋճ໨ͷॻ͖ࠐΈ͕Zํ޲ͱͳΔ QYͣͭεΫϩʔϧ͍ͨ͠৔߹͸͜ͷϨδελΛ੍ޚ͢Δ ͔͠͠ɺ͜ͷϨδελ͚ͩͰ͸QYҎ্ͷεΫϩʔϧ͸ෆՄ ׂ Ѫ

Slide 168

Slide 168 text

116$53-Ϩδελ ΞυϨε ֓ཁ Y CJU આ໌ ʜ ʜলུʜ ωʔϜςʔϒϧࢦఆ 116$53-Ϩδελ Y ͷCJU͸ωʔϜςʔϒϧΛࢦఆ͢Δ͜ͱ͕Ͱ͖Δ ωʔϜ ଐੑςʔϒϧ ωʔϜ ଐੑςʔϒϧ ωʔϜ ଐੑςʔϒϧ ωʔϜ ଐੑςʔϒϧ ྫ͑͹ωʔϜςʔϒϧࢦఆ͕CͰ͋Ε͹͜ͷςʔϒϧ͕ࢦఆ͞Εͨ͜ͱʹͳΓ Yํ޲ʹQY෼εΫϩʔϧ͕Φϑηοτͨ͜͠ͱͱಉ౳ͱͳΔ ઌͷ1164$30--ͱ߹ΘͤΕ͹ QYҎ্ͷεΫϩʔϧ͕Մೳ ׂ Ѫ

Slide 169

Slide 169 text

͜ΕΒΛ࢖͏ͱ໘ന͍දݱ͕Մೳʹ

Slide 170

Slide 170 text

ϥελεΫϩʔϧ

Slide 171

Slide 171 text

ඳըͷ్தͰεΫϩʔϧ஋Λௐ੔͢Δ͜ͱͰը໘ͷ్த͔ΒεΫϩʔϧ͕Մೳ εΫϩʔϧ଎౓Λม͑Δ͜ͱͰͦΕͧΕҧͬͨ଎౓ͰεΫϩʔϧͤ͞Δ͜ͱ΋Մೳ ϥελεΫϩʔϧ

Slide 172

Slide 172 text

εϓϥΠτ

Slide 173

Slide 173 text

͜͜·Ͱઆ໌ͨ͠ͷ͸എܠͰ͕͢ɺΩϟϥΫλʔΛಈ͔͢ʹ͸ εϓϥΠτͱͯ͠ඳը͢Δඞཁ͕͋Δ എܠ εϓϥΠτ എܠ͸YͷλΠϧΛYݸ ը໘ʹෑ͖٧ΊͯεΫϩʔϧ౳Ͱ ಈ͔͢͜ͱ͕Ͱ͖Δ εϓϥΠτͰ͋Ε͹YZࣗ༝ʹઃఆՄೳ 8PYJBOHOJÁPOJÁP.PKPO5XJOT εϓϥΠτ

Slide 174

Slide 174 text

εϓϥΠτͷσʔλ͸Ͳ͜ʹॻ͔͘

Slide 175

Slide 175 text

116͸εϓϥΠτ༻ͷྖҬεϓϥΠτ3".Λ͍࣋ͬͯΔ 116ͷϝϞϦϚοϓʹ͸දݱ͞Ε͍ͯͳ͍͓ͦ͠Β͘116಺෦ͷྖҬʁ ΞυϨε ֓ཁ Y εϓϥΠτϝϞϦΞυϨε YΛܦ༝ͯ͠εϓϥΠτϝϞϦ΁ϦʔυϥΠτ͢ΔϏοτΞυϨεΛࢦఆ Y εϓϥΠτϝϞϦσʔλ YʹΑͬͯࢦఆ͞ΕͨεϓϥΠτϝϞϦΞυϨεʹ͍ͨͯ͠ϦʔυϥΠτΛߦ͏ ΞΫηε͢Δͨͼʹ౓ʹεϓϥΠτϝϞϦΞυϨε͸ΠϯΫϦϝϯτ ͞ΕΔɻ ΞΫηεํ๏͸116"%%3116%"5" YY ͱ΄΅ಉ͡ ҟͳΔ఺͸εϓϥΠτ3".ͷۭؒ͸CJUͰදݱͰ͖ΔͷͰ ΞυϨεΛઃఆ͢ΔͨΊʹ̎ճॻ͖ࠐΉඞཁ͸ͳ͍ #ZUF εϓϥΠτ3".

Slide 176

Slide 176 text

εϓϥΠτͭʹରͯ͠ҎԼͷ#ZUFͷઃఆΛ͍࣋ͬͯΔ #ZUF ֓ཁ :࠲ඪ εϓϥΠτΠϯσοΫε ΩϟϥΫλʔ30.಺ͷεϓϥΠτͷԿ൪໨ͷεϓϥΠτΛద༻͢Δ͔Λࢦఆ͢Δ 9࠲ඪ CJU આ໌ ਨ௚ํ޲൓స൓స͠ͳ͍൓స͢Δ ਫฏํ޲൓స൓స͠ͳ͍൓స͢Δ දࣔ༏ઌॱҐεϓϥΠτΛ༏ઌഎܠΛ༏ઌ ༧໿ ύϨοτ൪߸CύϨοτCύϨοτ CύϨοτCύϨοτ εϓϥΠτ3".͸#ZUFͳͷͰηοτͰ͖Δ ࠷େεϓϥΠτ εϓϥΠτ3".

Slide 177

Slide 177 text

εϓϥΠτʹؔ͢ΔϢχʔΫͳ࢓༷

Slide 178

Slide 178 text

εϓϥΠτώοτ ʢ௨শʰര஄ʱʣ

Slide 179

Slide 179 text

ΞυϨε ֓ཁ Y CJU આ໌ 7CMBOL࣌ʹ εϓϥΠτώοτ࣌ʹ εΩϟϯϥΠϯεϓϥΠτ਺ɹݸҎԼݸҎ্ 3FTFSWFE εϓϥΠτ̌ώοτ εϓϥΠτ3".ͷઌ಄ʹઃఆ͞ΕͨεϓϥΠτ͕ ϥΠϯόοϑΝʹల։͞ΕΔͱ116Ϩδελ Y ͷʮεϓϥΠτ̌ώοτʯϑϥάཱ͕ͭVOΛ࣮ߦ

Slide 180

Slide 180 text

༻్͸ʁ

Slide 181

Slide 181 text

࣮͸͜͜ʹಁ໌ͳ̌ര஄͕഑ஔ͞Ε͍ͯΔ 8PYJBOHOJÁPOJÁP.PKPO5XJOT εϓϥΠτ̌ώοτ

Slide 182

Slide 182 text

ʮεϓϥΠτ̌ώοτʯϑϥάΛݕग़͔ͯ͠Β εΫϩʔϧॲཧΛ։࢝͢Δ͜ͱʹΑΓ ݻఆϔομΛ࣮ݱ͍ͯ͠Δ ج४ͱͳΔεϓϥΠτʢ̌ര஄ʣ ͸͜͜ʹઃஔͯ͋͠Δ 8PYJBOHOJÁPOJÁP.PKPO5XJOT εϓϥΠτ̌ώοτ

Slide 183

Slide 183 text

εϓϥΠτͷ੍໿

Slide 184

Slide 184 text

࣮͸εϓϥΠτ͸ಉҰϥΠϯ্ʹͭ·Ͱ͔͠഑ஔͰ͖ͳ͍ 116͸ϥΠϯόοϑΝΛ͓࣋ͬͯΓ ϥΠϯຖʹεϓϥΠτͱഎܠͷ߹੒Λߦ͍ඳը͍ͯ͠Δ ͜ͷॲཧ͸ίετ͕ߴ͘࠷େͭ·Ͱ͔͠߹੒Ͱ͖ͳ͍Β͍͠ ౰࣌ͷϝϞϦͱίετͷؔ܎͔Β ϑϨʔϜόοϑΝʹ͸Ͱ͖ͳ͔ͬͨΜͩͱਪଌ ΞυϨε ֓ཁ Y CJU આ໌ ʜ ʜ εΩϟϯϥΠϯεϓϥΠτ਺ɹݸҎԼݸҎ্ ʜ ʜ ͜Ε͸্ه੍໿Λݕग़͢ΔͨΊͷػߏ ͕ͩɺόάͬͯΔͱͷӟ΋͋Γ Ͳͷఔ౓࢖༻͞Ε͍ͯͨͷ͔͸ෆ໌ εϓϥΠτͷ੍໿

Slide 185

Slide 185 text

ൃੜ͢Δ໰୊ͱରࡦʢະݕূʣ

Slide 186

Slide 186 text

࠶ݱ؀ڥ͕ͳ͍ͷͰະݕূͰ͕͢ʜ υϥΰϯΫΤετͰ͸֗ͷதͰ̐ਓͷύʔςΟͱଜਓ͕ ԣҰ௚ઢʹฒͿͱϥΠϯ্ͷεϓϥΠτ਺͕ͱͳΓ ύʔςΟϝϯόʔ΋͘͠͸ଜਓ͕ফ͑Δ ͦͷͨΊɺιϑτ΢ΣΞͰਓΛߴ଎ʹදࣔඇදࣔΛ܁Γฦ͢͜ͱͰ Ωϟϥ͕఺໓ͯ͠͠·͏΋ͷͷಉ࣌ʹදࣔ͢Δ͜ͱΛՄೳʹͨ͠ ͱ͍͏࿩͕͋͠ΔΒ͍͠ʢཁݕূʣ ΩϟϥεϓϥΠτͳͷͰ ਓͳΒͿͱεϓϥΠτʹ ͳͬͯ͠·͏ ଜਓ ਓύʔςΟ ൃੜ͢Δ໰୊ͱରࡦʢະݕূʣ

Slide 187

Slide 187 text

Ͱ΋ɺ͓Ε͸Ͱ͔͍ͬϘεΈͨ͜ͱ͕͋Δͧʂ ͱ͍͏ํ΋͍Δ͔΋

Slide 188

Slide 188 text

IUUQTXXXZPVUVCFDPNXBUDI W1(1EP1T3ΑΓ εϓϥΠτͰ͸ͳ͘ എܠͰඳը ͜Ε͸εϓϥΠτͰ͸ͳ͘എܠͰϘεΛදݱͯ͠ΔͬΆ͍ εϓϥΠτͰ͋Ε͹ෳࡶͳഎܠͷ্ʹ ߹੒ʢॏͳΓ͕දݱʣ͞Εͯදࣔ͞ΕΔ͕ എܠͰఢΛදݱͯ͠͠·͏ͱॏͶΔ͜ͱ͕Ͱ͖ͳ͍ ͳͷͰɺഎܠ͸ਅͬࠇʹͯ͠ΔͱࢥΘΕΔ ௨ৗഎܠͱͯ͠ඳը͢ΔͰ͋Ζ͏ ଍৔ΛεϓϥΠτͱͯ͠ඳը ͔ͭӈ͔Βࠨ΁Ҡಈͤ͞Δ͜ͱ ʹΑΓυϥΰϯ͕௥ͬͯ͘ΔΑ͏ʹ දݱ υϥΰϯͷ্ԼҠಈ͸ എܠεΫϩʔϧͰ࣮ݱ ͜͏͍͏΍ͭ

Slide 189

Slide 189 text

εϓϥΠτͷసૹύϑΥʔϚϯε

Slide 190

Slide 190 text

ͨͱ͑͹εϓϥΠτ3".#ZUFΛద౰ͳ஋ͰຒΊΔ ؆୯ͳॲཧΛߟ͑ͯΈΔ ldy $FF # 2cycle copysprites: sty $2004 # 4cycle dey # 2cycle bne copysprites # 2cycle YDZDMF dΛεϓϥΠτ3". ʹॻ͖ࠐΉ εϓϥΠτͷసૹύϑΥʔϚϯε

Slide 191

Slide 191 text

εϓϥΠτ΋എܠಉ༷7CMBOLͷظؒʹసૹ͢Δඞཁ͕͋Δ 7CMBOLͷظؒ͸$16ͷαΠΫϧ਺ʹ׵ࢉ͢Δͱ Y$ZDMF 116DMPDLMJOF 7CMBOLظؒʹ૬౰͢ΔMJOF਺ 116ΫϩοΫ͸ $16ΫϩοΫͷഒͳͷͰ ઌͷࢼࢉͰ$ZDMFͳͷͰʜ ͘͢͝୯७ͳॲཧͰ΋΄ͱΜͲͷ7CMBOLظؒΛઐ༗ͯ͠͠·͏ʜ εϓϥΠτͷసૹύϑΥʔϚϯε

Slide 192

Slide 192 text

ղܾࡦ͸ʜ

Slide 193

Slide 193 text

%." %JSFDUNFNPSZBDDFTT

Slide 194

Slide 194 text

௨ৗ$16͕ϩʔυ໋ྩ΍ετΞ໋ྩΛ࢖༻ͯ͠ϝϞϦؒͷ σʔλసૹ౳Λߦ͏ͱ͜ΖΛɺ$16Λհͣ͞σʔλసૹ ͯ͘͠ΕΔपลػೳʢϖϦϑΣϥϧʣ ૊ΈࠐΈͳͲ௿εϖοΫͳ$16Ͱ΋࢖͍ํ͕͸·Ε͹ ύϑΥʔϚϯεΛҾ্͖͛ΒΕΔʢ͔΋͠Εͳ͍ʣ௒ॏ ཁͳػߏ %."ͱ͸

Slide 195

Slide 195 text

͜Ε·Ͱʹࣗ෼͕ݟͨͷ͸ εΩϟφϝϞϦͷసૹ΍ϝϞϦϓϦϯλ &UFISOFUίϯτϩʔϥϝϞϦͷసૹͳͲ ͨͱ͑͹%."͕ͳ͍ͱҎԼͷΑ͏ͳखॱʹͳͬͨΓ͢Δ $16 εΩϟφ όε 3". ᶃεΩϟφ͔ΒϦʔυ ᶄ3".΁ϥΠτ %."ͱ͸

Slide 196

Slide 196 text

εΩϟφϝϞϦͷసૹྫ %."͕͋Ε͹ҎԼͷΑ͏ʹҰؾʹసૹͰ͖ͨΓ͢Δ ʢ৔߹͕͋Δʣ $16 εΩϟφ όε 3". ᶃεΩϟφ͔Β3". ΁సૹ %."ͱ͸

Slide 197

Slide 197 text

/&4ͷ৔߹Y൪஍ʹ஋Λॻ͖ࠐΉ͜ͱͰ%."͕ىಈ͠ ॻ͖ࠐΜͩ஋Λ্ҐΞυϨεɺYΛԼҐΞυϨεͱͨ͠ΞυϨ εΛى఺ʹ#ZUFΛεϓϥΠτ3".ʹసૹ͢Δ ΋͏ͪΐ͍۩ମతʹ͍͏ͱ ྫ͑͹YʹYΛॻ͖ࠐΜͩ৔߹ Y͔ΒY''·Ͱͷ#ZUF͕ εϓϥΠτ3".ʹసૹ͞ΕΔ సૹ͸$16αΠΫϧͰ׬ྃ͢ΔͷͰ $16Ͱ#ZUFసૹ͢ΔΑΓߴ଎ʹసૹͰ͖Δ ʢόε͕ઐ༗͞ΕΔͷͰ$16͸ͦͷؒఀࢭ͢Δʣ %." /&4ͷ%."͸͔ͳΓ௿ػೳ

Slide 198

Slide 198 text

ίϯτϩʔϥ

Slide 199

Slide 199 text

/&4ͷ৔߹Y൪஍ʹίϯτϩʔϥ͕഑ஔ͞Ε͍ͯΔ Y൪஍ʹY YΛॱʹॻ͖ࠐΉͱͦͷॠؒͷίϯτϩʔϥ ͷ֤εΠονͷঢ়ଶ͕ϥον͞ΕY൪஍ΛϦʔυ͢Δ͜ͱͰ ॱ࣍εΠονঢ়ଶΛಡΉ͜ͱ͕Ͱ͖Δ ॳճϦʔυ࣌͸"Ϙλϯͷঢ়ଶɺ࣍ͷϦʔυͰ#Ϙλϯͷঢ়ଶʜ ͱ͍ͬͨΑ͏ʹॱ࣍औಘ͢ΔͨΊશϘλϯͷঢ়ଶΛ஌Δʹ͸ ߹ܭճͷϦʔυ͕ඞཁ Ϧʔυ ରԠϘλϯ " # 4&-&$5 45"35 ্ Լ ࠨ ӈ ίϯτϩʔϥ ̎1͸Y

Slide 200

Slide 200 text

ϒϥ΢βͰͷΤϛϡϨʔγϣϯ

Slide 201

Slide 201 text

const convertKeyCode = keyCode => { switch (keyCode) { case 88: return 0x01; // X A case 90: return 0x02; // Z B case 65: return 0x04; // A SELECT case 83: return 0x08; // S START case 38: return 0x10; // ↑ ↑ case 40: return 0x20; // ↓ ↓ case 37: return 0x40; // ← ← case 39: return 0x80; // → → } }; document.addEventListener("keydown", e => { buf[size - 1] |= convertKeyCode(e.keyCode); }); document.addEventListener("keyup", e => { buf[size - 1] &= ~convertKeyCode(e.keyCode); }); +BWB4DSJQUଆͷॲཧ LFZEPXOVQΠϕϯτΛ MJTUFO OFTϑΝΠϧͷத਎Λ౉ͨ͢Ίͷ όοϑΝͷ຤ඌʹΩʔೖྗΛ ௨஌͢ΔͨΊͷྖҬ#ZUF෼֬ อͦ͜͠ʹঢ়ଶΛॻ͖ࠐΉ

Slide 202

Slide 202 text

let main_loop = || { let key_state = buf[len - 1]; keypad.update(key_state); // …লུ… }; impl Keypad { pub fn new() -> Self { // …লུ… } pub fn update(&mut self, data: Data) { self.buffer = data; } pub fn write(&mut self, data: Data) { // …লུ… } pub fn read(&mut self) -> u8 { let v = (0x01 << self.addr) as u8; let ret = ((self.register & v) >> self.addr) as u8; self.addr += 1; ret } } 3VTU XBTN ଆͷॲཧ ϝΠϯϧʔϓͰ+4͔Βड͚औͬͨ Ωʔͷঢ়ଶΛ൓ө Y͕Πʔυ͞ΕΔͨͼ " # 4&-&$5ʜͷॱʹ ஋Λฦ͢Α͏ʹ͓ͯ͘͠

Slide 203

Slide 203 text

"16 α΢ϯυ ׂ Ѫ

Slide 204

Slide 204 text

ϑΝϛίϯͷ৔߹"16 ΦʔσΟΦϓϩηογϯάϢχο τʣͱ%"$ σΟδλϧΞφϩάίϯόʔλ ͕$16ʹ ૊Έࠐ·Ε͍ͯΔ "16 α΢ϯυ νϟωϧ͸ۣܗ೾͕νϟωϧɺࡾ֯೾νϟωϧɺϊ Πζνϟωɺ%1$.νϟωϧͷνϟωϧ͕࢖༻Ͱ ͖ήʔϜͷԻ͸͜ͷνϟωϧͷ૊Έ߹ΘͤʹΑΓදݱ͞ ΕΔ ׂ Ѫ

Slide 205

Slide 205 text

IUUQTDPEFQFOJPHSFHIQFOYR8XR[ Πϝʔδ͸͜ͷDPEFQFO͕Θ͔Γ΍͍͢ "16 α΢ϯυ ׂ Ѫ

Slide 206

Slide 206 text

ϨδελΛோΊΔ ׂ Ѫ

Slide 207

Slide 207 text

ΞυϨε 38 ༻్ Y 8 ۣܗ೾$)੍ޚϨδελ Y 8 ۣܗ೾$)੍ޚϨδελ Y 8 ۣܗ೾$)प೾਺Ϩδελ Y 8 ۣܗ೾$)प೾਺Ϩδελ Y 8 ۣܗ೾$)੍ޚϨδελ Y 8 ۣܗ೾$)੍ޚϨδελ Y 8 ۣܗ೾$)प೾਺Ϩδελ Y 8 ۣܗ೾$)प೾਺Ϩδελ Y 8 ࡾ֯೾੍ޚϨδελ Y" 8 ࡾ֯೾प೾਺Ϩδελ Y# 8 ࡾ֯೾प೾਺Ϩδελ "16ͷϨδελҰཡ ׂ Ѫ

Slide 208

Slide 208 text

ΞυϨε 38 ༻్ Y$ 8 ϊΠζ੍ޚϨδελ Y& 8 ϊΠζཚ਺Ϩδελ Y' 8 ϊΠζ࣌ؒϨδελ Y 8 %1$.੍ޚϨδελ Y 8 %1$.੍ޚϨδελ Y 8 %1$.੍ޚϨδελ Y 8 %1$.੍ޚϨδελ Y 38 Ի੠νϟωϧ੍ޚϨδελ Y 38 ϑϨʔϜΧ΢ϯλ "16ͷϨδελҰཡ ׂ Ѫ

Slide 209

Slide 209 text

ۣܗ೾ΛΈ͍ͯ͘ ׂ Ѫ

Slide 210

Slide 210 text

Τϯϕϩʔϓ δΣωϨʔλ εΠʔϓ λΠϚʔ γʔέϯα ௕͞Χ΢ϯλ ۣܗ೾ͷߏ੒ ׂ Ѫ

Slide 211

Slide 211 text

ΞυϨε ֓ཁ Y CJU આ໌ σϡʔςΟൺCC CC ࠶ੜ࣌ؒΧ΢ϯλΠωʔϒϧ ΤϯϕϩʔϓσΟηʔϒϧ ϘϦϡʔϜ·ͨ͸ΤϯϕϩʔϓσΟόΠμ σϡʔςΟൺ ݮਰͷ଎౓ͳͲΛ੍ޚ ۣܗ೾Ϩδελ ׂ Ѫ

Slide 212

Slide 212 text

ΞυϨε ֓ཁ Y CJU આ໌ εΠʔϓΠωʔϒϧ प೾਺มԽ଎౓ प೾਺ͷมԽํ޲Լ্߱ঢ प೾਺มߋྔͷ৔߹มԽͳ͠ प೾਺ͷ૿ݮΛ੍ޚ ۣܗ೾Ϩδελ ׂ Ѫ

Slide 213

Slide 213 text

ΞυϨε ֓ཁ Y Y CJU આ໌ ύϧελΠϚʔԼҐCJU CJU આ໌ ΩʔΦϑΧ΢ϯλ ύϧελΠϚʔ্ҐCJU प೾਺ͱ࠶ੜ࣌ؒΛ੍ޚ ۣܗ೾Ϩδελ ׂ Ѫ

Slide 214

Slide 214 text

Ͳ͏΍ͬͯΤϛϡϨʔτ͢Δ͔ ׂ Ѫ

Slide 215

Slide 215 text

8FC"VEJP ׂ Ѫ

Slide 216

Slide 216 text

class Oscillator { constructor(type) { const AudioContext = window.AudioContext || window.webkitAudioContext this.context = new AudioContext(); this.oscillator = this.createOscillator({ kind: type }); // …লུ… } createOscillator(options = {}) { const oscillator = this.context.createOscillator(); // …লུ… return oscillator; } setPulseWidth(pulseWidth) { this.oscillator.setPeriodicWave(this.waves[`${pulseWidth}`]); } setFrequency(frequency) { this.oscillator.frequency.value = frequency; } changeFrequency(frequency) { this.oscillator.frequency.setValueAtTime(frequency, this.context.currentTime) } } +BWB4DSJQUଆͷॲཧ TFU1FSJPEJD8BWFͰ ΧελϜ೾ܗΛ࡞੒Ͱ͖Δ ׂ Ѫ

Slide 217

Slide 217 text

mergeInto(LibraryManager.library, { start_oscillator: function (index) { Module.NES.oscs[index].start(); }, set_oscillator_frequency: function (index, freq) { Module.NES.oscs[index].setFrequency(freq); }, change_oscillator_frequency: function (index, freq) { Module.NES.oscs[index].changeFrequency(freq); }, set_oscillator_volume: function (index, volume) { Module.NES.oscs[index].setVolume(volume); }, set_oscillator_pulse_width: function (index, width) { Module.NES.oscs[index].setPulseWidth(width); }, } 3VTU XBTN ଆ΁ͷϒϦοδ ࠶ͼNFSHF*OUPͰ 3VTUଆ΁ެ։ ׂ Ѫ

Slide 218

Slide 218 text

͋ͱ͸)[)[ͷपظͱ $16͔ΒͷΞΫηελΠϛϯά प೾਺΍ϘϦϡʔϜͷมಈ͕ൃੜ͢Δ ͷͰͦͷλΠϛϯάͰݺΜͰ΍Ε͹͍͍ ׂ Ѫ

Slide 219

Slide 219 text

pub fn update_counters(&mut self) { // …লུ… self.sweep_unit_counter += 1; self.change_frequency(); } pub fn update_envelope(&mut self) { // …লུ… unsafe { set_oscillator_volume(self.index, self.get_volume()); }; } fn change_frequency(&self) { unsafe { change_oscillator_frequency(self.index, self.frequency); } } 3VTU XBTN ଆͷॲཧ ׂ Ѫ

Slide 220

Slide 220 text

͜͜·ͰͰϑΝϛίϯຊମͷ ϋʔυ΢ΣΞ͸Ұ௨Γ࣮૷Ͱ͖ͨ͸ͣ

Slide 221

Slide 221 text

2͜ΕͰશͯͷ30.͕ಈ࡞͢Δ͔

Slide 222

Slide 222 text

"͠ͳ͍

Slide 223

Slide 223 text

..$ NFNPSZNBOBHFNFOUDPOUSPMMFS

Slide 224

Slide 224 text

Χηοτ಺ʹ..$ͱݺ͹ΕΔ ϝϞϦ؅ཧ༻ͷిࢠճ࿏Λ͍࣋ͬͯΔ Χηοτ͕͋Δ ͜ͷػߏʹΑΓϓϩάϥϜ30.࠷େLJ# ΩϟϥΫλʔ30.LJ#ͷ੍ݶ͸௒͑ΒΕΔ ..$

Slide 225

Slide 225 text

..$ʹΑΔϝϞϦͷϚοϐϯά৘ใ Λ.BQQFSͱݺͿ ..$

Slide 226

Slide 226 text

.BQQFSͷҰ෦ ·ͩ΄͔ʹ΋͋Δ .BQQFS

Slide 227

Slide 227 text

.BQQFS ࣮͸͍͕ͭ͜..$ ҎԼ͸.BQQFSͷج൘

Slide 228

Slide 228 text

.BQQFS

Slide 229

Slide 229 text

ຊདྷϥΠτͰ͖ͳ͍Ydͷۭؒ ʹόϯΫ൪߸Λॻ͖ࠐΉ͜ͱͰ࠷େ,J# ·Ͱ30.Λ࢖༻͢Δ͜ͱ͕Ͱ͖Δ .BQQFS

Slide 230

Slide 230 text

ͲΜͳճ࿏ʹͳͬͯΔ͔

Slide 231

Slide 231 text

$)3 30. $/ )$ "" "" %% 8& )$ͰσʔλΛϥον͠ ΞυϨεʹม׵ ΩϟϥΫλʔ30. όΠφϦΧ΢ϯλ .BQQFSͷճ࿏

Slide 232

Slide 232 text

impl Mmc { pub fn new(mapper: u8, bank: u8) -> Self { Mmc { bank, mapper } } pub fn set_bank(&mut self, bank: u8) { self.bank = bank; } pub fn create_chram_addr(&self, addr: u16) -> u16 { addr + (self.bank as u16) * 0x2000 } } .BQQFSͷ࣮૷ όϯΫͷઃఆ͔Β ΩϟϥΫλʔ30.΁ͷΞυϨε Λܭࢉͯ͠ฦ͢

Slide 233

Slide 233 text

ରԠ30.Λ૿΍͢ʹ͸ ֤ͭͭ͜͜.BQQFSͷରԠ͕ඞཁ

Slide 234

Slide 234 text

͜ΕΛ໢ཏ͢Δͱ͢΂ͯͷ 30.͕ಈ࡞͢Δ͸ͣ

Slide 235

Slide 235 text

ύϑΥʔϚϯε

Slide 236

Slide 236 text

DISPNF 8FC"TTFNCMZWT+BWB4DSJQU DISPNFDBOBSZ pSFGPY CJU pSFGPYEFWFMPQFSFEJUJPO C CJU TBGBSJ NT NT NT NT NT NT NT NT NT NT UJNF TNBMMFSJTCFUUFS 8FC"TTFNCMZ CPLVXFCSVTUZOFT +BWB4DSJQU CPLVXFCqPXOFT 8FC"VEJP$BOWBTΛσΟηʔϒϧʹͨ͠ঢ়ଶͰ ϝΠϯϧʔϓͷॲཧ࣌ؒճͷฏۉ஋Λൺֱ .BD#PPL"JS JODI &BSMZ ()[*OUFM$PSFJ(#.)[%%3 HJLPOFT

Slide 237

Slide 237 text

͍͞͝ʹ !ϑΝϛίϯΤϛϡϨʔλ͸ҰਓͰ࣮૷͢Δͷʹ΋खࠒͳαΠζ !$16΍%."ɺׂΓࠐΈͳͲͷಈ࡞Λֶ΂Δ !ઌਓͷۤ࿑ͷยྡྷΛຯΘ͑Δ !ࣗ෼΋99ݴޠͰ΍ͬͯΈΔ͔ʂͱࢥͬͯ΋Β͑ͨΒخ͍͠Ͱ͢

Slide 238

Slide 238 text

͋Γ͕ͱ͏͍͟͝·ͨ͠✨