Compare commits
	
		
			3 Commits
		
	
	
		
			5387152a21
			...
			792c245711
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 792c245711 | |||
| 8d2f6cab47 | |||
| ba4e098ba5 | 
							
								
								
									
										41
									
								
								cartridge.go
									
									
									
									
									
								
							
							
						
						
									
										41
									
								
								cartridge.go
									
									
									
									
									
								
							@ -3,8 +3,7 @@ package main
 | 
				
			|||||||
import (
 | 
					import (
 | 
				
			||||||
	"bytes"
 | 
						"bytes"
 | 
				
			||||||
	"encoding/binary"
 | 
						"encoding/binary"
 | 
				
			||||||
	"io"
 | 
						"fmt"
 | 
				
			||||||
	"log"
 | 
					 | 
				
			||||||
	"os"
 | 
						"os"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -215,6 +214,7 @@ var oldLicensees = map[byte]string{
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type ROMHeader struct {
 | 
					type ROMHeader struct {
 | 
				
			||||||
 | 
						_          [256]byte
 | 
				
			||||||
	EntryPoint [4]byte
 | 
						EntryPoint [4]byte
 | 
				
			||||||
	Logo       [48]byte
 | 
						Logo       [48]byte
 | 
				
			||||||
	// NOTE(m): Assuming "old" cartridges here. This may cause problems with newer cartridges.
 | 
						// NOTE(m): Assuming "old" cartridges here. This may cause problems with newer cartridges.
 | 
				
			||||||
@ -228,7 +228,7 @@ type ROMHeader struct {
 | 
				
			|||||||
	DestinationCode      byte
 | 
						DestinationCode      byte
 | 
				
			||||||
	OldLicenseeCode      byte
 | 
						OldLicenseeCode      byte
 | 
				
			||||||
	MaskROMVersionNumber byte
 | 
						MaskROMVersionNumber byte
 | 
				
			||||||
	HeaderChecksum       byte
 | 
						Checksum             byte
 | 
				
			||||||
	GlobalChecksum       [2]byte
 | 
						GlobalChecksum       [2]byte
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -242,32 +242,23 @@ type Cartridge struct {
 | 
				
			|||||||
	RAMSize     string
 | 
						RAMSize     string
 | 
				
			||||||
	Destination string
 | 
						Destination string
 | 
				
			||||||
	Version     int
 | 
						Version     int
 | 
				
			||||||
 | 
						Checksum    byte
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func Insert(filename string) Cartridge {
 | 
					func Insert(filename string) (Cartridge, error) {
 | 
				
			||||||
	file, err := os.Open(filename)
 | 
						cartridge := Cartridge{Filename: filename}
 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		log.Fatal(err)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	defer file.Close()
 | 
					 | 
				
			||||||
	cartridge := Cartridge{Filename: file.Name()}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Jump to start of header
 | 
						rom, err := os.ReadFile(filename)
 | 
				
			||||||
	_, err = file.Seek(0x0100, io.SeekStart)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		log.Fatal(err)
 | 
							return cartridge, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Read header
 | 
						// Read header
 | 
				
			||||||
	var header ROMHeader
 | 
						var header ROMHeader
 | 
				
			||||||
	err = binary.Read(file, binary.LittleEndian, &header)
 | 
						buffer := bytes.NewReader(rom)
 | 
				
			||||||
 | 
						err = binary.Read(buffer, binary.LittleEndian, &header)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		log.Fatal(err)
 | 
							return cartridge, nil
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// Validate the ROM by checking presence of the Nintendo logo
 | 
					 | 
				
			||||||
	if header.Logo != expectedLogo {
 | 
					 | 
				
			||||||
		log.Fatal("Invalid ROM file: No valid logo found!")
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Convert some header values
 | 
						// Convert some header values
 | 
				
			||||||
@ -292,10 +283,16 @@ func Insert(filename string) Cartridge {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
	cartridge.Version = int(header.MaskROMVersionNumber)
 | 
						cartridge.Version = int(header.MaskROMVersionNumber)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// TODO(m): Verify header checksum
 | 
						// Calculate and verify checksum
 | 
				
			||||||
 | 
						for address := uint16(0x0134); address <= uint16(0x014C); address++ {
 | 
				
			||||||
 | 
							cartridge.Checksum = cartridge.Checksum - rom[address] - 1
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if cartridge.Checksum != header.Checksum {
 | 
				
			||||||
 | 
							return cartridge, fmt.Errorf("ROM checksum failed: %X does not equal %X", cartridge.Checksum, header.Checksum)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// NOTE(m): Ignoring global checksum which is not used, except by one emulator.
 | 
						// NOTE(m): Ignoring global checksum which is not used, except by one emulator.
 | 
				
			||||||
	// See https://gbdev.io/pandocs/The_Cartridge_Header.html#014e-014f--global-checksum
 | 
						// See https://gbdev.io/pandocs/The_Cartridge_Header.html#014e-014f--global-checksum
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return cartridge
 | 
						return cartridge, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -6,16 +6,26 @@ import (
 | 
				
			|||||||
	"github.com/stretchr/testify/assert"
 | 
						"github.com/stretchr/testify/assert"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func TestInsertCartridge(t *testing.T) {
 | 
					func TestInsert(t *testing.T) {
 | 
				
			||||||
	cartridge := Insert("rom.gb")
 | 
						cartridge, err := Insert("./roms/dmg-acid2.gb")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	assert := assert.New(t)
 | 
						assert := assert.New(t)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	assert.Equal(cartridge.Title, "SEIKEN DENSETSU")
 | 
						assert.Nil(err)
 | 
				
			||||||
	assert.Equal(cartridge.Mapper, "MBC2+BATTERY")
 | 
						assert.Equal(cartridge.Filename, "./roms/dmg-acid2.gb")
 | 
				
			||||||
	assert.Equal(cartridge.Licensee, "Square")
 | 
						assert.Equal(cartridge.Title, "DMG-ACID2")
 | 
				
			||||||
 | 
						assert.Equal(cartridge.Mapper, "ROM ONLY")
 | 
				
			||||||
 | 
						assert.Equal(cartridge.Licensee, "None")
 | 
				
			||||||
	assert.False(cartridge.SGBSupport, "SGB support should be false")
 | 
						assert.False(cartridge.SGBSupport, "SGB support should be false")
 | 
				
			||||||
	assert.Equal(cartridge.ROMSize, 256)
 | 
						assert.Equal(cartridge.ROMSize, 32)
 | 
				
			||||||
	assert.Equal(cartridge.RAMSize, "0 - No RAM")
 | 
						assert.Equal(cartridge.RAMSize, "0 - No RAM")
 | 
				
			||||||
	assert.Equal(cartridge.Destination, "Overseas only")
 | 
						assert.Equal(cartridge.Destination, "Japan (and possibly overseas)")
 | 
				
			||||||
	assert.Equal(cartridge.Version, 0)
 | 
						assert.Equal(cartridge.Version, 0)
 | 
				
			||||||
 | 
						assert.Equal(cartridge.Checksum, byte(0x9F))
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func TestFailedChecksum(t *testing.T) {
 | 
				
			||||||
 | 
						_, err := Insert("./roms/failed-checksum.gb")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						assert.EqualError(t, err, "ROM checksum failed: 9F does not equal 41")
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										2
									
								
								main.go
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								main.go
									
									
									
									
									
								
							@ -10,7 +10,7 @@ func main() {
 | 
				
			|||||||
	// 	log.Fatalln("No rom file specified")
 | 
						// 	log.Fatalln("No rom file specified")
 | 
				
			||||||
	// }
 | 
						// }
 | 
				
			||||||
	// romPath := os.Args[1]
 | 
						// romPath := os.Args[1]
 | 
				
			||||||
	romPath := "rom.gb"
 | 
						romPath := "./roms/dmg-acid2.gb"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ui.Run(romPath)
 | 
						ui.Run(romPath)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										
											BIN
										
									
								
								roms/01-special.gb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								roms/01-special.gb
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								roms/02-interrupts.gb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								roms/02-interrupts.gb
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								roms/03-op sp,hl.gb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								roms/03-op sp,hl.gb
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								roms/04-op r,imm.gb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								roms/04-op r,imm.gb
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								roms/05-op rp.gb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								roms/05-op rp.gb
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								roms/06-ld r,r.gb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								roms/06-ld r,r.gb
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								roms/07-jr,jp,call,ret,rst.gb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								roms/07-jr,jp,call,ret,rst.gb
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								roms/08-misc instrs.gb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								roms/08-misc instrs.gb
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								roms/09-op r,r.gb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								roms/09-op r,r.gb
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								roms/10-bit ops.gb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								roms/10-bit ops.gb
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								roms/11-op a,(hl).gb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								roms/11-op a,(hl).gb
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								roms/cpu_instrs.gb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								roms/cpu_instrs.gb
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								roms/dmg-acid2.gb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								roms/dmg-acid2.gb
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								roms/failed-checksum.gb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								roms/failed-checksum.gb
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								roms/mem_timing.gb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								roms/mem_timing.gb
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							@ -51,10 +51,15 @@ func (c *Controller) Run() {
 | 
				
			|||||||
	running := true
 | 
						running := true
 | 
				
			||||||
	for running {
 | 
						for running {
 | 
				
			||||||
		for event := sdl.PollEvent(); event != nil; event = sdl.PollEvent() {
 | 
							for event := sdl.PollEvent(); event != nil; event = sdl.PollEvent() {
 | 
				
			||||||
			switch event.(type) {
 | 
								switch e := event.(type) {
 | 
				
			||||||
			case *sdl.QuitEvent:
 | 
								case *sdl.QuitEvent:
 | 
				
			||||||
				println("Quit")
 | 
					 | 
				
			||||||
				running = false
 | 
									running = false
 | 
				
			||||||
 | 
								case *sdl.KeyboardEvent:
 | 
				
			||||||
 | 
									if e.Type == sdl.KEYDOWN {
 | 
				
			||||||
 | 
										if e.Keysym.Sym == sdl.K_ESCAPE {
 | 
				
			||||||
 | 
											running = false
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user