Additional floppy drive C 720k

This commit is contained in:
Роман Бойков 2026-03-10 15:00:22 +03:00
parent e28b052cbf
commit ed43a19a10
8 changed files with 213 additions and 139 deletions

View File

@ -15,6 +15,8 @@ type OkEmuConfig struct {
LogLevel string `yaml:"logLevel"` LogLevel string `yaml:"logLevel"`
MonitorFile string `yaml:"monitorFile"` MonitorFile string `yaml:"monitorFile"`
CPMFile string `yaml:"cpmFile"` CPMFile string `yaml:"cpmFile"`
FloppyB string `yaml:"floppyB"`
FloppyC string `yaml:"floppyC"`
} }
var config *OkEmuConfig var config *OkEmuConfig

Binary file not shown.

29
main.go
View File

@ -7,6 +7,7 @@ import (
"okemu/config" "okemu/config"
"okemu/logger" "okemu/logger"
"okemu/okean240" "okemu/okean240"
"sync/atomic"
"time" "time"
"fyne.io/fyne/v2" "fyne.io/fyne/v2"
@ -23,10 +24,11 @@ var BuildTime = "2026-03-01"
//go:embed hex/format.hex //go:embed hex/format.hex
var serialBytes []byte var serialBytes []byte
//go:embed bin/TET.COM //go:embed bin/FORMAT.COM
var ramBytes []byte var ramBytes []byte
var needReset = false var needReset = false
var fullSpeed atomic.Bool
func main() { func main() {
@ -107,9 +109,12 @@ func mainWindow(computer *okean240.ComputerType) (*fyne.Window, *canvas.Raster,
widget.NewButton("RUN", func() { widget.NewButton("RUN", func() {
computer.SetRamBytes(ramBytes) computer.SetRamBytes(ramBytes)
}), }),
//widget.NewButton("DUMP", func() { widget.NewButton("DUMP", func() {
// computer.Dump(0x399, 15000) computer.Dump(0x100, 15000)
//}), }),
widget.NewCheck("Full speed", func(b bool) {
fullSpeed.Store(b)
}),
widget.NewSeparator(), widget.NewSeparator(),
widget.NewButton("Reset", func() { widget.NewButton("Reset", func() {
needReset = true needReset = true
@ -152,31 +157,31 @@ func screen(computer *okean240.ComputerType, raster *canvas.Raster, label *widge
} }
} }
const ticksPerTicker uint64 = 3 const ticksPerTact uint64 = 3
func emulator(computer *okean240.ComputerType) { func emulator(computer *okean240.ComputerType) {
ticker := time.NewTicker(66 * time.Nanosecond) ticker := time.NewTicker(66 * time.Nanosecond)
var ticks uint64 = 0 var ticks uint64 = 0
var nextClock uint64 = ticks + ticksPerTicker var nextClock = ticks + ticksPerTact
//var ticksCPU = 3 //var ticksCPU = 3
for range ticker.C { for range ticker.C {
//for {
//time.Sleep(133 * time.Nanosecond)
ticks++ ticks++
if ticks%10 == 0 { if ticks%10 == 0 {
// 1.5 MHz // 1.5 MHz
computer.TimerClk() computer.TimerClk()
} }
if fullSpeed.Load() {
computer.Do()
} else {
if ticks >= nextClock { if ticks >= nextClock {
nextClock = ticks + computer.Do()*ticksPerTicker nextClock = ticks + computer.Do()*ticksPerTact
} }
}
//computer.Do()
if needReset { if needReset {
computer.Reset() computer.Reset()
needReset = false needReset = false
} }
//if ticks > ticksCPU {
//ticksCPU = ticks + computer.Do()*2
//}
} }
} }

View File

@ -2,20 +2,25 @@ package okean240
import ( import (
_ "embed" _ "embed"
"encoding/binary"
"image/color" "image/color"
"okemu/config" "okemu/config"
"okemu/okean240/fdc" "okemu/okean240/fdc"
"okemu/okean240/pic" "okemu/okean240/pic"
"okemu/okean240/pit" "okemu/okean240/pit"
"okemu/okean240/usart" "okemu/okean240/usart"
"okemu/z80/js" "os"
//"okemu/z80"
"okemu/z80/c99"
//"okemu/z80/js"
"fyne.io/fyne/v2" "fyne.io/fyne/v2"
log "github.com/sirupsen/logrus" log "github.com/sirupsen/logrus"
) )
type ComputerType struct { type ComputerType struct {
cpu *js.Z80 cpu *c99.Z80
memory Memory memory Memory
ioPorts [256]byte ioPorts [256]byte
cycles uint64 cycles uint64
@ -73,7 +78,7 @@ func New(cfg *config.OkEmuConfig) *ComputerType {
c.memory = Memory{} c.memory = Memory{}
c.memory.Init(cfg.MonitorFile, cfg.CPMFile) c.memory.Init(cfg.MonitorFile, cfg.CPMFile)
c.cpu = js.New(&c) c.cpu = c99.New(&c)
c.cycles = 0 c.cycles = 0
c.dd17EnableOut = false c.dd17EnableOut = false
@ -90,7 +95,7 @@ func New(cfg *config.OkEmuConfig) *ComputerType {
c.pit = pit.New() c.pit = pit.New()
c.usart = usart.New() c.usart = usart.New()
c.pic = pic.New() c.pic = pic.New()
c.fdc = fdc.New() c.fdc = fdc.New(cfg)
return &c return &c
} }
@ -110,14 +115,11 @@ func (c *ComputerType) Reset() {
} }
func (c *ComputerType) Do() uint64 { func (c *ComputerType) Do() uint64 {
//s := c.cpu.GetState()
//if s.PC == 0xe0db {
// log.Debugf("breakpoint")
//}
ticks := c.cpu.RunInstruction() ticks := c.cpu.RunInstruction()
c.cycles += ticks c.cycles += ticks
//if c.cpu.PC == 0xFF26 { //pc := c.cpu.GetState().PC
// log.Debugf("%4X: H:%X L:%X A:%X B: %X C: %X D: %X E: %X", c.cpu.PC, c.cpu.H, c.cpu.L, c.cpu.A, c.cpu.B, c.cpu.C, c.cpu.D, c.cpu.E) //if pc >= 0xfea3 && pc <= 0xff25 {
// c.cpu.DebugOutput()
//} //}
return ticks return ticks
} }
@ -245,25 +247,28 @@ func (c *ComputerType) SetRamBytes(bytes []byte) {
//c.cpu.PC = 0x100 //c.cpu.PC = 0x100
} }
//func (c *ComputerType) Dump(start uint16, length uint16) { func (c *ComputerType) Dump(start uint16, length uint16) {
// file, err := os.Create("dump.dat") file, err := os.Create("dump.dat")
// if err != nil { if err != nil {
// log.Error(err) log.Error(err)
// return return
// } }
// defer func(file *os.File) { defer func(file *os.File) {
// err := file.Close() err := file.Close()
// if err != nil { if err != nil {
// log.Error(err) log.Error(err)
// } }
// }(file) }(file)
//
// var buffer []byte var buffer []byte
// for addr := 0; addr < 65535; addr++ { for addr := start; addr < start+length; addr++ {
// buffer = append(buffer, c.memory.MemRead(uint16(addr))) buffer = append(buffer, c.memory.MemRead(addr))
// } }
// err = binary.Write(file, binary.LittleEndian, buffer) _, err = file.Write(buffer)
// if err != nil { err = binary.Write(file, binary.LittleEndian, buffer)
// log.Error("Save memory dump failed:", err) if err != nil {
// } log.Error("Save memory dump failed:", err)
//} } else {
log.Debug("Memory dump saved successfully")
}
}

View File

@ -8,7 +8,9 @@ package fdc
*/ */
import ( import (
"bytes"
"encoding/binary" "encoding/binary"
"okemu/config"
"os" "os"
"slices" "slices"
"strconv" "strconv"
@ -18,6 +20,7 @@ import (
// Floppy parameters // Floppy parameters
const ( const (
TotalDrives = 2
FloppySizeK = 720 FloppySizeK = 720
SectorSize = 512 SectorSize = 512
SideCount = 2 SideCount = 2
@ -69,14 +72,16 @@ type FloppyDriveController struct {
sectorNo byte sectorNo byte
trackNo byte trackNo byte
drq byte drq byte
// FloppyStorage // FloppyStorage B and C
sectors [SizeInSectors]SectorType sectors [TotalDrives][SizeInSectors]SectorType
data byte data byte
status byte status byte
lastCmd byte lastCmd byte
//curSector *SectorType //curSector *SectorType
bytePtr uint16 bytePtr uint16
trackBuffer []byte trackBuffer []byte
floppyBFile string
floppyCFile string
} }
type FloppyDriveControllerInterface interface { type FloppyDriveControllerInterface interface {
@ -95,8 +100,12 @@ type FloppyDriveControllerInterface interface {
Sector() byte Sector() byte
} }
func getSectorNo(side byte, track byte, sector byte) uint16 {
return uint16(side)*SectorsPerSide + uint16(track)*SectorPerTrack + uint16(sector) - 1
}
func (f *FloppyDriveController) GetSectorNo() uint16 { func (f *FloppyDriveController) GetSectorNo() uint16 {
return uint16(f.sideNo)*SectorsPerSide + uint16(f.trackNo)*SectorPerTrack + uint16(f.sectorNo) - 1 return getSectorNo(f.sideNo, f.trackNo, f.sectorNo)
} }
func (f *FloppyDriveController) SetFloppy(val byte) { func (f *FloppyDriveController) SetFloppy(val byte) {
@ -104,14 +113,14 @@ func (f *FloppyDriveController) SetFloppy(val byte) {
f.sideNo = val >> 5 & 0x01 f.sideNo = val >> 5 & 0x01
f.ddEn = val >> 4 & 0x01 f.ddEn = val >> 4 & 0x01
f.init = val >> 3 & 0x01 f.init = val >> 3 & 0x01
f.drive = val >> 2 & 0x01 f.drive = (^val) >> 2 & 0x01
f.mot1 = val >> 1 & 0x01 f.mot1 = val >> 1 & 0x01
f.mot0 = val & 0x01 f.mot0 = val & 0x01
} }
func (f *FloppyDriveController) GetFloppy() byte { func (f *FloppyDriveController) GetFloppy() byte {
// RD: 7-MOTST, 6-SSEL, 5,4-x , 3-DRSEL, 2-MOT1, 1-MOT0, 0-INT // RD: 7-MOTST, 6-SSEL, 5,4-x , 3-DRSEL, 2-MOT1, 1-MOT0, 0-INT
floppy := f.intRq | (f.mot0 << 1) | (f.mot1 << 2) | (f.drive << 3) | (f.sideNo << 6) | (f.motSt << 7) floppy := f.intRq | (f.mot0 << 1) | (f.mot1 << 2) | ((^f.drive & 1) << 3) | (f.sideNo << 6) | (f.motSt << 7)
return floppy return floppy
} }
@ -119,34 +128,34 @@ func (f *FloppyDriveController) SetCmd(value byte) {
f.lastCmd = value >> 4 f.lastCmd = value >> 4
switch f.lastCmd { switch f.lastCmd {
case CmdRestore: case CmdRestore:
log.Debug("CMD Restore (seek trackNo 0)") log.Trace("CMD Restore (seek trackNo 0)")
f.trackNo = 0 f.trackNo = 0
f.status = StatusTR0 | StatusHeadLoaded // TR0 & Head loaded f.status = StatusTR0 | StatusHeadLoaded // TR0 & Head loaded
case CmdSeek: case CmdSeek:
log.Debugf("CMD Seek %x", value&0xf) log.Tracef("CMD Seek %x", value&0xf)
f.status = StatusHeadLoaded f.status = StatusHeadLoaded
f.trackNo = f.data f.trackNo = f.data
case CmdStep: case CmdStep:
log.Debugf("CMD Step %x", value&0xf) log.Tracef("CMD Step %x", value&0xf)
f.status = StatusHeadLoaded f.status = StatusHeadLoaded
f.trackNo = f.data f.trackNo = f.data
case CmdStepIn: case CmdStepIn:
log.Debugf("CMD StepIn (Next track) %x", value&0xf) log.Tracef("CMD StepIn (Next track) %x", value&0xf)
f.status = StatusHeadLoaded f.status = StatusHeadLoaded
if f.trackNo < TracksCount { if f.trackNo < TracksCount {
f.trackNo++ f.trackNo++
} }
case CmdStepOut: case CmdStepOut:
log.Debugf("CMD StepOut (Previous track) %x", value&0xf) log.Tracef("CMD StepOut (Previous track) %x", value&0xf)
f.status = StatusHeadLoaded f.status = StatusHeadLoaded
if f.trackNo > 0 { if f.trackNo > 0 {
f.trackNo-- f.trackNo--
} }
case CmdReadSector: case CmdReadSector:
sectorNo := f.GetSectorNo() sectorNo := f.GetSectorNo()
log.Debugf("CMD Read single sectorNo: %d", sectorNo) log.Tracef("CMD Read single sectorNo: %d", sectorNo)
if sectorNo < SizeInSectors { if sectorNo < SizeInSectors {
f.trackBuffer = slices.Clone(f.sectors[sectorNo]) f.trackBuffer = slices.Clone(f.sectors[f.drive][sectorNo])
f.drq = 1 f.drq = 1
f.status = 0x00 f.status = 0x00
} else { } else {
@ -157,14 +166,14 @@ func (f *FloppyDriveController) SetCmd(value byte) {
sectorNo := f.GetSectorNo() sectorNo := f.GetSectorNo()
f.trackBuffer = []byte{} f.trackBuffer = []byte{}
for c := 0; c < SectorPerTrack; c++ { for c := 0; c < SectorPerTrack; c++ {
f.trackBuffer = slices.Concat(f.trackBuffer, f.sectors[sectorNo]) f.trackBuffer = slices.Concat(f.trackBuffer, f.sectors[f.drive][sectorNo])
sectorNo++ sectorNo++
} }
f.drq = 1 f.drq = 1
f.status = 0x0 f.status = 0x0
case CmdWriteSector: case CmdWriteSector:
sectorNo := f.GetSectorNo() sectorNo := f.GetSectorNo()
log.Debugf("CMD Write Sector %d", sectorNo) log.Tracef("CMD Write Sector %d", sectorNo)
if sectorNo < SizeInSectors { if sectorNo < SizeInSectors {
f.bytePtr = 0 f.bytePtr = 0
f.drq = 1 f.drq = 1
@ -175,12 +184,12 @@ func (f *FloppyDriveController) SetCmd(value byte) {
f.status = StatusRNF f.status = StatusRNF
} }
case CmdWriteTrack: case CmdWriteTrack:
log.Debugf("CMD Write Track %x", f.trackNo) log.Tracef("CMD Write Track %x", f.trackNo)
f.status = 0x00 f.status = 0x00
f.trackBuffer = []byte{} f.trackBuffer = []byte{}
f.drq = 1 f.drq = 1
default: default:
log.Debugf("Unknown CMD: %x VAL: %x", f.lastCmd, value&0xf) log.Errorf("Unknown CMD: %x VAL: %x", f.lastCmd, value&0xf)
} }
} }
@ -189,7 +198,7 @@ func (f *FloppyDriveController) Status() byte {
} }
func (f *FloppyDriveController) SetTrackNo(value byte) { func (f *FloppyDriveController) SetTrackNo(value byte) {
//log.Debugf("FDC Track: %d", value) //log.Tracef("FDC Track: %d", value)
if value > TracksCount { if value > TracksCount {
f.status |= 0x10 /// RNF f.status |= 0x10 /// RNF
log.Error("Track not found!") log.Error("Track not found!")
@ -199,17 +208,17 @@ func (f *FloppyDriveController) SetTrackNo(value byte) {
} }
func (f *FloppyDriveController) SetSectorNo(value byte) { func (f *FloppyDriveController) SetSectorNo(value byte) {
//log.Debugf("FDC Sector: %d", value) //log.Tracef("FDC Sector: %d", value)
if value > SectorPerTrack { if value > SectorPerTrack {
f.status |= 0x10 f.status |= 0x10
log.Error("Record not found!") log.Errorf("Record not found %d!", value)
} else { } else {
f.sectorNo = value f.sectorNo = value
} }
} }
func (f *FloppyDriveController) SetData(value byte) { func (f *FloppyDriveController) SetData(value byte) {
//log.Debugf("FCD Data: %d", value) //log.Tracef("FCD Data: %d", value)
if f.lastCmd == CmdWriteTrack { if f.lastCmd == CmdWriteTrack {
if len(f.trackBuffer) < TrackBufferSize { if len(f.trackBuffer) < TrackBufferSize {
f.trackBuffer = append(f.trackBuffer, value) f.trackBuffer = append(f.trackBuffer, value)
@ -217,6 +226,7 @@ func (f *FloppyDriveController) SetData(value byte) {
f.status = 0x00 f.status = 0x00
} else { } else {
//f.dump() //f.dump()
f.writeTrack()
f.drq = 0 f.drq = 0
f.status = 0x00 f.status = 0x00
f.lastCmd = CmdNoCommand f.lastCmd = CmdNoCommand
@ -232,13 +242,44 @@ func (f *FloppyDriveController) SetData(value byte) {
} }
if len(f.trackBuffer) == SectorSize { if len(f.trackBuffer) == SectorSize {
f.drq = 0 f.drq = 0
f.sectors[f.GetSectorNo()] = slices.Clone(f.trackBuffer) f.sectors[f.drive][f.GetSectorNo()] = slices.Clone(f.trackBuffer)
f.lastCmd = CmdNoCommand f.lastCmd = CmdNoCommand
} }
} }
f.data = value f.data = value
} }
const SectorInfoSize = 626
const SectorInfoOffset = 0x0092
const TrackNoOffset = 0x0010
const SideNoOffset = 0x0011
const SectorNoOffset = 0x0012
const SectorLengthOffset = 0x0013
const SectorDataOffset = 0x003b
var SectorLengths = []int{128, 256, 512, 1024}
func (f *FloppyDriveController) writeTrack() {
// skip header
ptr := SectorInfoOffset
// repeat for every sector on track
for sec := 0; sec < SectorPerTrack; sec++ {
// get info from header
trackNo := f.trackBuffer[ptr+TrackNoOffset]
sideNo := f.trackBuffer[ptr+SideNoOffset]
sectorNo := f.trackBuffer[ptr+SectorNoOffset]
sectorLength := SectorLengths[f.trackBuffer[ptr+SectorLengthOffset]&0x03]
// get sector data
sectorData := f.trackBuffer[ptr+SectorDataOffset : ptr+SectorDataOffset+sectorLength]
absSector := getSectorNo(sideNo, trackNo, sectorNo)
log.Debugf("Write Drive: %d; side:%d; T: %d S: %d Len: %d Data: [%X..%X]; Abs sector: %d", f.drive, sideNo, trackNo, sectorNo, len(sectorData), sectorData[0], sectorData[len(sectorData)-1], absSector)
// write data to sector buffer
f.sectors[f.drive][absSector] = slices.Clone(sectorData)
// shift pointer to next sector info block
ptr += SectorInfoSize
}
}
func (f *FloppyDriveController) Data() byte { func (f *FloppyDriveController) Data() byte {
switch f.lastCmd { switch f.lastCmd {
case CmdReadSector, CmdReadSectorMulti: case CmdReadSector, CmdReadSectorMulti:
@ -263,70 +304,26 @@ func (f *FloppyDriveController) Drq() byte {
} }
func (f *FloppyDriveController) LoadFloppy() { func (f *FloppyDriveController) LoadFloppy() {
log.Debug("Load Floppy content.") log.Debug("Load Floppy B")
file, err := os.Open("floppy.okd") loadFloppy(&f.sectors[0], f.floppyBFile)
if err != nil { log.Debug("Load Floppy C")
log.Error(err) loadFloppy(&f.sectors[1], f.floppyCFile)
return
}
defer func(file *os.File) {
err := file.Close()
if err != nil {
log.Error(err)
}
}(file)
for sector := 0; sector < SizeInSectors; sector++ {
var n int
n, err = file.Read(f.sectors[sector])
if n != SectorSize {
log.Error("Load floppy error, sector size: %d <> %d", n, SectorSize)
}
// err = binary.Read(file, binary.LittleEndian, f.sectors[sector])
if err != nil {
log.Error("Load floppy content failed:", err)
break
}
}
} }
func (f *FloppyDriveController) SaveFloppy() { func (f *FloppyDriveController) SaveFloppy() {
log.Debug("Save Floppy content.") log.Debug("Save Floppy B")
file, err := os.Create("floppy.okd") saveFloppy(&f.sectors[0], f.floppyBFile)
if err != nil { log.Debug("Save Floppy C")
log.Error(err) saveFloppy(&f.sectors[1], f.floppyCFile)
return
}
defer func(file *os.File) {
err := file.Close()
if err != nil {
log.Error(err)
}
}(file)
// Write the struct to the file in little-endian byte order
for sector := 0; sector < SizeInSectors; sector++ {
var n int
n, err = file.Write(f.sectors[sector])
if n != SectorSize {
log.Errorf("Save floppy error, sector %d size: %d <> %d", sector, n, SectorSize)
}
if err != nil {
log.Error("Save floppy content failed:", err)
break
}
} }
} func New(conf *config.OkEmuConfig) *FloppyDriveController {
sec := [2][SizeInSectors]SectorType{}
func New() *FloppyDriveController { // for each drive
sec := [SizeInSectors]SectorType{} for d := 0; d < TotalDrives; d++ {
// for each sector
for i := 0; i < SizeInSectors; i++ { for i := 0; i < SizeInSectors; i++ {
sec[i] = make([]byte, SectorSize) sec[d][i] = bytes.Repeat([]byte{0xe5}, SectorSize)
for s := 0; s < SectorSize; s++ {
sec[i][s] = 0xE5
} }
} }
return &FloppyDriveController{ return &FloppyDriveController{
@ -342,11 +339,13 @@ func New() *FloppyDriveController {
lastCmd: 0xff, lastCmd: 0xff,
sectors: sec, sectors: sec,
bytePtr: 0xffff, bytePtr: 0xffff,
floppyBFile: conf.FloppyB,
floppyCFile: conf.FloppyC,
} }
} }
func (f *FloppyDriveController) dump() { func (f *FloppyDriveController) dump() {
log.Debug("Dump Buffer content.") log.Trace("Dump Buffer content.")
file, err := os.Create("track-" + strconv.Itoa(int(f.trackNo)) + ".dat") file, err := os.Create("track-" + strconv.Itoa(int(f.trackNo)) + ".dat")
if err != nil { if err != nil {
log.Error(err) log.Error(err)
@ -375,3 +374,58 @@ func (f *FloppyDriveController) Sector() byte {
} }
// //
func loadFloppy(sectors *[SizeInSectors]SectorType, fileName string) {
log.Debugf("Load Floppy content from file %s.", fileName)
file, err := os.Open(fileName)
if err != nil {
log.Error(err)
return
}
defer func(file *os.File) {
err := file.Close()
if err != nil {
log.Error(err)
}
}(file)
for sector := 0; sector < SizeInSectors; sector++ {
var n int
n, err = file.Read(sectors[sector])
if n != SectorSize {
log.Error("Load floppy error, sector size: %d <> %d", n, SectorSize)
}
if err != nil {
log.Error("Load floppy content failed:", err)
break
}
}
}
func saveFloppy(sectors *[SizeInSectors]SectorType, fileName string) {
log.Debugf("Save Floppy to file %s.", fileName)
file, err := os.Create(fileName)
if err != nil {
log.Error(err)
return
}
defer func(file *os.File) {
err := file.Close()
if err != nil {
log.Error(err)
}
}(file)
for sector := 0; sector < SizeInSectors; sector++ {
var n int
n, err = file.Write(sectors[sector])
if n != SectorSize {
log.Errorf("Save floppy error, sector %d size: %d <> %d", sector, n, SectorSize)
}
if err != nil {
log.Error("Save floppy content failed:", err)
break
}
}
}

View File

@ -2,3 +2,5 @@ logFile: "okemu.log"
logLevel: "info" logLevel: "info"
monitorFile: "rom/MON_r8_9c6c6546.bin" monitorFile: "rom/MON_r8_9c6c6546.bin"
cpmFile: "rom/CPM_r8_bc0695e4.bin" cpmFile: "rom/CPM_r8_bc0695e4.bin"
floppyB: "floppy/floppyB.okd"
floppyC: "floppy/floppyC.okd"

View File

@ -155,7 +155,7 @@ func (z *Z80) updateXY(result byte) {
z.xf = result&0x08 != 0 z.xf = result&0x08 != 0
} }
func (z *Z80) debugOutput() { func (z *Z80) DebugOutput() {
log.Debugf("PC: %04X, AF: %04X, BC: %04X, DE: %04X, HL: %04X, SP: %04X, IX: %04X, IY: %04X, I: %02X, R: %02X", log.Debugf("PC: %04X, AF: %04X, BC: %04X, DE: %04X, HL: %04X, SP: %04X, IX: %04X, IY: %04X, I: %02X, R: %02X",
z.pc, (uint16(z.a)<<8)|uint16(z.get_f()), z.get_bc(), z.get_de(), z.get_hl(), z.sp, z.pc, (uint16(z.a)<<8)|uint16(z.get_f()), z.get_bc(), z.get_de(), z.get_hl(), z.sp,
z.ix, z.iy, z.i, z.r) z.ix, z.iy, z.i, z.r)
@ -163,3 +163,7 @@ func (z *Z80) debugOutput() {
log.Debugf("\t(%02X %02X %02X %02X), cyc: %d\n", z.rb(z.pc), z.rb(z.pc+1), log.Debugf("\t(%02X %02X %02X %02X), cyc: %d\n", z.rb(z.pc), z.rb(z.pc+1),
z.rb(z.pc+2), z.rb(z.pc+3), z.cyc) z.rb(z.pc+2), z.rb(z.pc+3), z.cyc)
} }
func (z *Z80) Reset() {
}

View File

@ -22,6 +22,8 @@ type CPUInterface interface {
GetState() *Z80CPU GetState() *Z80CPU
// SetState Set current CPU state // SetState Set current CPU state
SetState(state *Z80CPU) SetState(state *Z80CPU)
// DebugOutput out current CPU state
DebugOutput()
} }
// FlagsType - Processor flags // FlagsType - Processor flags