diff --git a/.gitignore b/.gitignore index 6378da1..d00c189 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,4 @@ cpu.prof mem.prof mos6502go.test apple2e.rom +dos33_disk.dsk diff --git a/audio/audio.go b/audio/audio.go index 4cedd03..fa1c480 100644 --- a/audio/audio.go +++ b/audio/audio.go @@ -1,84 +1,9 @@ package audio import ( - "errors" "mos6502go/system" - - ebiten_audio "github.com/hajimehoshi/ebiten/audio" ) -var ( - audioContext *ebiten_audio.Context - player *ebiten_audio.Player - firstAudio bool - Mute bool -) - -type stream struct{} - -func (s *stream) Read(data []byte) (int, error) { - dataLen := len(data) - - if firstAudio { - // The first time, drain the audio queue - firstAudio = false - - for i := 0; i < len(system.AudioChannel); i++ { - <-system.AudioChannel - } - return dataLen, nil - } - - if dataLen%4 != 0 { - return 0, errors.New("dataLen % 4 must be 0") - } - - if Mute { - return dataLen, nil - } - - samples := dataLen / 4 - - for i := 0; i < dataLen; i++ { - data[i] = 0 - } - - for i := 0; i < samples; i++ { - b := <-system.AudioChannel - - data[4*i] = byte(b) - data[4*i+1] = byte(b >> 8) - data[4*i+2] = byte(b) - data[4*i+3] = byte(b >> 8) - } - - return dataLen, nil -} - -func (s *stream) Close() error { - return nil -} - -func Init() { - firstAudio = true - Mute = false - - var err error - audioContext, err = ebiten_audio.NewContext(system.AudioSampleRate) - if err != nil { - panic(err) - } - - // Pass the (infinite) stream to audio.NewPlayer. - // After calling Play, the stream never ends as long as the player object lives. - // var err error - player, err = ebiten_audio.NewPlayer(audioContext, &stream{}) - if err != nil { - panic(err) - } - player.Play() -} - func Click() { ForwardToFrameCycle() system.AudioAttenuationCounter = 400 diff --git a/audio/ebiten.go b/audio/ebiten.go new file mode 100644 index 0000000..9d4ea22 --- /dev/null +++ b/audio/ebiten.go @@ -0,0 +1,80 @@ +package audio + +import ( + "errors" + "mos6502go/system" + + ebiten_audio "github.com/hajimehoshi/ebiten/audio" +) + +var ( + audioContext *ebiten_audio.Context + player *ebiten_audio.Player + firstAudio bool + Mute bool +) + +type stream struct{} + +func (s *stream) Read(data []byte) (int, error) { + dataLen := len(data) + + if firstAudio { + // The first time, drain the audio queue + firstAudio = false + + for i := 0; i < len(system.AudioChannel); i++ { + <-system.AudioChannel + } + return dataLen, nil + } + + if dataLen%4 != 0 { + return 0, errors.New("dataLen % 4 must be 0") + } + + if Mute { + return dataLen, nil + } + + samples := dataLen / 4 + + for i := 0; i < dataLen; i++ { + data[i] = 0 + } + + for i := 0; i < samples; i++ { + b := <-system.AudioChannel + + data[4*i] = byte(b) + data[4*i+1] = byte(b >> 8) + data[4*i+2] = byte(b) + data[4*i+3] = byte(b >> 8) + } + + return dataLen, nil +} + +func (s *stream) Close() error { + return nil +} + +func InitEbiten() { + firstAudio = true + Mute = false + + var err error + audioContext, err = ebiten_audio.NewContext(system.AudioSampleRate) + if err != nil { + panic(err) + } + + // Pass the (infinite) stream to audio.NewPlayer. + // After calling Play, the stream never ends as long as the player object lives. + // var err error + player, err = ebiten_audio.NewPlayer(audioContext, &stream{}) + if err != nil { + panic(err) + } + player.Play() +} diff --git a/cmd/test-apple-iie-boot.go b/cmd/test-apple-iie-boot.go index 49e9718..2ce847b 100644 --- a/cmd/test-apple-iie-boot.go +++ b/cmd/test-apple-iie-boot.go @@ -86,7 +86,7 @@ func main() { keyboard.Init() video.Init() - audio.Init() + audio.InitEbiten() audio.Mute = *mute system.Init() diff --git a/dos33_boot_test.go b/dos33_boot_test.go new file mode 100644 index 0000000..7b95844 --- /dev/null +++ b/dos33_boot_test.go @@ -0,0 +1,43 @@ +package main_test + +import ( + "fmt" + "mos6502go/cpu" + "mos6502go/keyboard" + "mos6502go/mmu" + "mos6502go/system" + "mos6502go/video" + "testing" + "time" +) + +const DiskImage = "dos33_disk.dsk" + +func TestDOS33Boot(t *testing.T) { + cpu.InitInstructionDecoder() + mmu.InitRAM() + mmu.InitApple2eROM() + mmu.InitIO() + mmu.ReadDiskImage(DiskImage) + cpu.Init() + keyboard.Init() + video.Init() + system.Init() + cpu.Reset() + + system.FrameCycles = 0 + system.LastAudioCycles = 0 + showInstructions := false + var breakAddress uint16 + disableFirmwareWait := false + t0 := time.Now() + cpu.Run(showInstructions, &breakAddress, disableFirmwareWait, system.CpuFrequency*1000) + + // audio.ForwardToFrameCycle() + + elapsed := float64(time.Since(t0) / time.Millisecond) + fmt.Printf("CPU Cycles: %d\n", system.FrameCycles) + // fmt.Printf("Sound samples: %d\n", len(system.AudioChannel)) + fmt.Printf("Time elapsed: %0.2f ms\n", elapsed) + fmt.Printf("Speed: %0.2f cycles/ms\n", float64(system.FrameCycles)/elapsed) +}