You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

120 lines
1.8 KiB

  1. package main
  2. import (
  3. "flag"
  4. "fmt"
  5. )
  6. type chip8 struct {
  7. opcode uint16
  8. memory [4096]byte
  9. // register
  10. v [16]byte
  11. index uint16
  12. pc uint16
  13. gfx [64 * 32]byte
  14. delayTimer byte
  15. soundTimer byte
  16. stack [16]uint16
  17. sp int
  18. key [16]byte
  19. drawFlag bool
  20. }
  21. // Initialize registers and memory once
  22. func (c *chip8) initialize() {
  23. c.pc = 0x200
  24. c.opcode = 0
  25. c.index = 0
  26. c.sp = 0
  27. }
  28. func (c *chip8) emulateCycle() {
  29. // Fetch Opcode
  30. c.opcode = uint16(c.memory[c.pc])<<8 | uint16(c.memory[c.pc+1])
  31. // Decode Opcode
  32. // https://en.wikipedia.org/wiki/CHIP-8#Opcode_table
  33. // http://www.multigesture.net/wp-content/uploads/mirror/goldroad/chip8_instruction_set.shtml
  34. switch c.opcode & 0xF000 {
  35. case 0x0000:
  36. switch c.opcode & 0x000F {
  37. case 0x0000: // 0x00E0
  38. // clear screen
  39. // TODO
  40. c.pc += 2
  41. break
  42. case 0x000E: // 0x00EE
  43. // TODO
  44. break
  45. default:
  46. fmt.Printf("Unknown opcode [0x0000]: 0x%X\n", c.opcode)
  47. }
  48. case 0x2000:
  49. c.stack[c.sp] = c.pc
  50. c.sp++
  51. c.pc = c.opcode & 0x0FFF
  52. break
  53. case 0x6000:
  54. pos := (c.opcode & 0x0F00) >> 8
  55. c.v[pos] = byte(c.opcode)
  56. c.pc += 2
  57. break
  58. default:
  59. fmt.Printf("Unknown opcode: 0x%X\n", c.opcode)
  60. }
  61. // Update timers
  62. if c.delayTimer > 0 {
  63. c.delayTimer--
  64. }
  65. if c.soundTimer > 0 {
  66. if c.soundTimer == 1 {
  67. fmt.Printf("Beep!\n")
  68. }
  69. c.soundTimer--
  70. }
  71. }
  72. func (c *chip8) loadGame(filepath string) error {
  73. return nil
  74. }
  75. func (c *chip8) drawGraphics() {
  76. }
  77. func (c *chip8) setKeys() {
  78. }
  79. func main() {
  80. filepath := flag.String("file", "file-path", "file path of the input file")
  81. flag.Parse()
  82. // setupGraphics()
  83. // setupInput()
  84. var c chip8
  85. c.initialize()
  86. err := c.loadGame(*filepath)
  87. if err != nil {
  88. panic(err)
  89. }
  90. for {
  91. c.emulateCycle()
  92. if c.drawFlag {
  93. c.drawGraphics()
  94. c.setKeys()
  95. }
  96. }
  97. }