예제 #1
0
파일: main.go 프로젝트: repos-dcpu16/dcpu16
func main() {
	// command-line flags
	flag.Var(&requestedRate, "rate", "Clock rate to run the machine at")
	// update usage
	flag.Usage = func() {
		fmt.Fprintf(os.Stderr, "usage: %s [flags] program\n", os.Args[0])
		flag.PrintDefaults()
	}
	flag.Parse()
	if flag.NArg() != 1 {
		flag.Usage()
		os.Exit(2)
	}
	program := flag.Arg(0)
	data, err := ioutil.ReadFile(program)
	if err != nil {
		fmt.Fprintln(os.Stderr, err)
		os.Exit(1)
	}
	// Interpret the file as Words
	words := make([]core.Word, len(data)/2)
	for i := 0; i < len(data)/2; i++ {
		w := core.Word(data[i*2])<<8 + core.Word(data[i*2+1])
		words[i] = w
	}

	// Set up a machine
	machine := new(dcpu.Machine)
	if err := machine.State.LoadProgram(words, 0); err != nil {
		fmt.Fprintln(os.Stderr, err)
		os.Exit(1)
	}
	if err := machine.Start(requestedRate); err != nil {
		fmt.Fprintln(os.Stderr, err)
		os.Exit(1)
	}
	var effectiveRate dcpu.ClockRate
	// now wait for the q key
	for {
		evt := termbox.PollEvent()
		if err := machine.HasError(); err != nil {
			fmt.Fprintln(os.Stderr, err)
			os.Exit(1)
		}
		if evt.Type == termbox.EventKey {
			if evt.Key == termbox.KeyCtrlC || (evt.Mod == 0 && evt.Ch == 'q') {
				effectiveRate = machine.EffectiveClockRate()
				if err := machine.Stop(); err != nil {
					fmt.Fprintln(os.Stderr, err)
					os.Exit(1)
				}
				break
			}
		}
	}
	if *printRate {
		fmt.Printf("Effective clock rate: %s\n", effectiveRate)
	}
}
예제 #2
0
파일: main.go 프로젝트: kballard/dcpu16
func main() {
	// command-line flags
	flag.Var(&requestedRate, "rate", "Clock rate to run the machine at")
	flag.Var(&screenRefreshRate, "screenRefreshRate", "Clock rate to refresh the screen at")
	// update usage
	flag.Usage = func() {
		fmt.Fprintf(os.Stderr, "usage: %s [flags] program\n", os.Args[0])
		flag.PrintDefaults()
	}
	flag.Parse()
	if flag.NArg() != 1 {
		flag.Usage()
		os.Exit(2)
	}
	program := flag.Arg(0)
	data, err := ioutil.ReadFile(program)
	if err != nil {
		fmt.Fprintln(os.Stderr, err)
		os.Exit(1)
	}
	// Interpret the file as Words
	words := make([]core.Word, len(data)/2)
	for i := 0; i < len(data)/2; i++ {
		b1, b2 := core.Word(data[i*2]), core.Word(data[i*2+1])
		var w core.Word
		if *littleEndian {
			w = b2<<8 + b1
		} else {
			w = b1<<8 + b2
		}
		words[i] = w
	}

	// Set up a machine
	machine := new(dcpu.Machine)
	machine.Video.RefreshRate = screenRefreshRate
	if err := machine.State.LoadProgram(words, 0); err != nil {
		fmt.Fprintln(os.Stderr, err)
		os.Exit(1)
	}
	if err := machine.Start(requestedRate); err != nil {
		fmt.Fprintln(os.Stderr, err)
		os.Exit(1)
	}
	// convert termbox event polling into a channel
	events := make(chan termbox.Event)
	go func() {
		for {
			events <- termbox.PollEvent()
		}
	}()
	var effectiveRate dcpu.ClockRate
	printErr := func(err error) {
		fmt.Fprintln(os.Stderr, err)
		machine.State.Ram.DumpMemory(os.Stderr, []int{int(machine.State.PC())})
		os.Exit(1)
	}
	// now wait for keyboard events
loop:
	for {
		select {
		case evt := <-events:
			if evt.Type == termbox.EventKey {
				if evt.Key == termbox.KeyCtrlC {
					effectiveRate = machine.EffectiveClockRate()
					if err := machine.Stop(); err != nil {
						printErr(err)
					}
					break loop
				}
				// else pass it to the keyboard
				if evt.Ch == 0 {
					// it's a key constant
					key := evt.Key
					if r, ok := keymapTermboxKeyToRune[key]; ok {
						machine.Keyboard.RegisterKeyTyped(r)
					} else if k, ok := keymapTermboxKeyToKey[key]; ok {
						machine.Keyboard.RegisterKeyPressed(k)
						machine.Keyboard.RegisterKeyReleased(k)
					}
				} else {
					ch := evt.Ch
					if r, ok := keymapRuneToRune[evt.Ch]; ok {
						ch = r
					}
					machine.Keyboard.RegisterKeyTyped(ch)
				}
			}
		case err := <-machine.ErrorC:
			machine.Stop() // unlike HasError(), ErrorC doesn't shut down the machine
			printErr(err)
		}
	}
	if *printRate {
		fmt.Printf("Effective clock rate: %s\n", effectiveRate)
	}
}