func (sms *SMS) LoadROM(fileName string) { application.Logf("Reading from file %s", fileName) data, err := readROM(fileName) if err != nil { panic(err) } size := len(data) // Calculate number of pages from file size and create array appropriately numROMBanks := size / PAGE_SIZE sms.memory.romBanks = make([][]byte, numROMBanks) application.Logf("Found %d ROM banks", numROMBanks) for i := 0; i < numROMBanks; i++ { sms.memory.romBanks[i] = make([]byte, PAGE_SIZE) // Read file into pages array for j := 0; j < PAGE_SIZE; j++ { sms.memory.romBanks[i][j] = data[(i*PAGE_SIZE)+j] } } for i := 0; i < 3; i++ { sms.memory.pages[i] = byte(i % numROMBanks) } sms.memory.romPageMask = byte(numROMBanks - 1) sms.memory.maskedPage0 = sms.memory.pages[0] & sms.memory.romPageMask sms.memory.maskedPage1 = sms.memory.pages[1] & sms.memory.romPageMask sms.memory.maskedPage2 = sms.memory.pages[2] & sms.memory.romPageMask sms.memory.romBank0 = make([]byte, PAGE_SIZE) copy(sms.memory.romBank0, sms.memory.romBanks[sms.memory.maskedPage0][:]) }
func (l *watcherLoop) Run() { // Run the tests for the first time. execGoTest(l.paths) watcher, err := fsnotify.NewWatcher() for _, path := range l.paths { err = watcher.Watch(path) if err != nil { application.Fatal(err.Error()) } application.Printf("Start watching path %s", path) } for { select { case <-l.pause: l.pause <- 0 case <-l.terminate: watcher.Close() l.terminate <- 0 return case ev := <-watcher.Event: if ev.IsModify() { if matches(ev.Name, ".*\\.go$") { if application.Verbose { application.Logf("Event %s occured for file %s", ev, ev.Name) } // check if the same event was // registered for the same // file in the acceptable // TIME_DISCARD time window event := getEvent(ev.Name) if event == nil { event = addEvent(&eventOnFile{ev, time.Now()}) application.Logf("Run the tests") execGoTest(l.paths) } else if time.Now().Sub(event.time) > DISCARD_TIME { event.time = time.Now() application.Logf("Run the tests") execGoTest(l.paths) } else { if application.Verbose { application.Logf("Event %s was discarded for file %s", ev, ev.Name) } } } } case err := <-watcher.Error: application.Fatal(err.Error()) } } }
// Run runs the commandLoop. // The loop waits for commands sent to sms.command channel. func (l *commandLoop) Run() { for { select { case <-l.pause: l.pause <- 0 case <-l.terminate: l.terminate <- 0 case _cmd := <-l.emulatorLoop.sms.command: switch cmd := _cmd.(type) { case cmdRenderFrame: l.displayLoop.Display() <- l.emulatorLoop.sms.frame() case cmdLoadRom: l.emulatorLoop.sms.loadRom(cmd.fileName) case cmdJoypadEvent: l.emulatorLoop.sms.joypad(cmd.value, cmd.event) case cmdPauseEmulation: l.emulatorLoop.pauseEmulation <- 0 <-l.emulatorLoop.pauseEmulation cmd.paused <- l.emulatorLoop.sms.paused case cmdShowCurrentInstruction: prevAddr := z80.PreviousInstruction(l.emulatorLoop.sms.memory, l.emulatorLoop.sms.cpu.PC()) res, address, shift := z80.Disassemble(l.emulatorLoop.sms.memory, prevAddr, 0) if res != "shift " { application.Logf("0x%04x %s\n", l.emulatorLoop.sms.cpu.PC(), res) } res, address, shift = z80.Disassemble(l.emulatorLoop.sms.memory, l.emulatorLoop.sms.cpu.PC(), 0) if res != "shift " { application.Logf("0x%04x %s\n", l.emulatorLoop.sms.cpu.PC(), res) } for i := 0; i < 20; i++ { oldAddress := address res, address, shift = z80.Disassemble(l.emulatorLoop.sms.memory, address, shift) if res != "shift " { application.Logf("0x%04x %s\n", oldAddress, res) } // address++ } } } } }
func (p *Ports) WritePortInternal(address uint16, b byte, contend bool) { switch byte(address) { case 0x3f: // Nationalisation, pretend we're British. natbit := ((b >> 5) & 1) if (b & 1) == 0 { natbit = 1 } p.sms.joystick = (p.sms.joystick & ^(1 << 6)) | int(natbit<<6) natbit = ((b >> 7) & 1) if (b & 4) == 0 { natbit = 1 } p.sms.joystick = (p.sms.joystick & ^(1 << 7)) | int(natbit<<7) break case 0x7e, 0x7f: // soundChip.poke(val); break case 0xbd, 0xbf: p.sms.vdp.writeAddr(uint16(b)) break case 0xbe: p.sms.vdp.writeByte(b) break case 0xde, 0xdf: break // Unknown use case 0xf0, 0xf1, 0xf2: break // YM2413 sound support: TODO // default: // console.log('IO port ' + hexbyte(addr) + ' = ' + val); // break; default: application.Logf("Write to IO port %x\n", address) } }
func newSDL2xScreen(fullScreen bool) *sdl2xScreen { sdlMode := uint32(sdl.SWSURFACE) if fullScreen { application.Logf("%s", "Activate fullscreen mode") sdlMode = sdl.FULLSCREEN sdl.ShowCursor(sdl.DISABLE) } screenSurface := &sdlSurface{sdl.SetVideoMode(SCREEN_WIDTH*2, SCREEN_HEIGHT*2, 32, sdlMode)} if screenSurface.surface == nil { log.Printf("%s", sdl.GetError()) application.Exit() return nil } borderSurface := &sdlSurface{sdl.CreateRGBSurface(sdl.SWSURFACE, SCREEN_WIDTH*2, SCREEN_HEIGHT*2, 32, 0, 0, 0, 0)} if borderSurface.surface == nil { log.Printf("%s", sdl.GetError()) application.Exit() return nil } displaySurface := &sdlSurface{sdl.CreateRGBSurface(sdl.SWSURFACE, DISPLAY_WIDTH*2, DISPLAY_HEIGHT*2, 32, 0, 0, 0, 0)} if displaySurface.surface == nil { log.Printf("%s", sdl.GetError()) application.Exit() return nil } return &sdl2xScreen{screenSurface, borderSurface, displaySurface} }
// showDisassembled prints out disassembled code. func showDisassembled(instructions []z80.DebugInstruction) { arrow := "" for line, instr := range instructions { if line == 0 { arrow = "=>>" } else { arrow = "" } application.Logf(arrow+"\t0x%04x %s\n", instr.Address, instr.Mnemonic) } }
func (sms *SMS) joypad(value int, event byte) { switch event { case JOYPAD_DOWN: sms.joystick &= ^value break case JOYPAD_UP: sms.joystick |= value break default: application.Logf("%s", "Unknown joypad event") break } }
func (l *inputLoop) Run() { for { select { case <-l.pause: l.pause <- 0 case <-l.terminate: l.terminate <- 0 case _event := <-sdl.Events: switch e := _event.(type) { case sdl.QuitEvent: application.Exit() case sdl.KeyboardEvent: keyName := sdl.GetKeyName(sdl.Key(e.Keysym.Sym)) application.Logf("%d: %s\n", e.Keysym.Sym, keyName) if e.Type == sdl.KEYDOWN { l.sms.command <- cmdJoypadEvent{keyMap[keyName], JOYPAD_DOWN} } else if e.Type == sdl.KEYUP { l.sms.command <- cmdJoypadEvent{keyMap[keyName], JOYPAD_UP} } if e.Type == sdl.KEYDOWN && keyName == "p" { paused := make(chan bool) l.sms.paused = !l.sms.paused l.sms.command <- cmdPauseEmulation{paused} <-paused } if e.Type == sdl.KEYDOWN && keyName == "d" { l.sms.paused = true paused := make(chan bool) l.sms.command <- cmdPauseEmulation{paused} <-paused l.sms.command <- cmdShowCurrentInstruction{} } if e.Keysym.Sym == sdl.K_ESCAPE { application.Exit() } } } } }