diff --git a/main.go b/main.go index 126ab85..77c73d5 100644 --- a/main.go +++ b/main.go @@ -23,7 +23,7 @@ var BuildTime = "2026-03-01" //go:embed hex/format.hex var serialBytes []byte -//go:embed bin/TYPE.COM +//go:embed bin/MB.COM var ramBytes []byte var needReset = false @@ -72,7 +72,13 @@ func mainWindow(computer *okean240.ComputerType, emuConfig *config.OkEmuConfig) raster := canvas.NewRasterWithPixels( func(x, y, w, h int) color.Color { - return computer.GetPixel(uint16(x/2), uint16(y/2)) + var xx uint16 + if computer.ScreenWidth() == 512 { + xx = uint16(x) + } else { + xx = uint16(x) / 2 + } + return computer.GetPixel(xx, uint16(y/2)) }) raster.Resize(fyne.NewSize(512, 512)) raster.SetMinSize(fyne.NewSize(512, 512)) @@ -130,7 +136,7 @@ func emulator(computer *okean240.ComputerType, raster *canvas.Raster, label *wid var freq uint64 = 0 nextSecond := time.Now().Add(time.Second).UnixMicro() - curScrWidth := 256 + //curScrWidth := 256 for range ticker.C { if needReset { computer.Reset(emuConfig) @@ -159,12 +165,12 @@ func emulator(computer *okean240.ComputerType, raster *canvas.Raster, label *wid // redraw screen here fyne.Do(func() { // check for screen mode changed - if computer.ScreenWidth() != curScrWidth { - curScrWidth = computer.ScreenWidth() - newSize := fyne.NewSize(float32(curScrWidth*2), float32(computer.ScreenHeight()*2)) - raster.SetMinSize(newSize) - raster.Resize(newSize) - } + //if computer.ScreenWidth() != curScrWidth { + // curScrWidth = computer.ScreenWidth() + // newSize := fyne.NewSize(float32(curScrWidth*2), float32(computer.ScreenHeight()*2)) + // raster.SetMinSize(newSize) + // raster.Resize(newSize) + //} // status for every 25 frames if frame%50 == 0 { label.SetText(fmt.Sprintf("Screen size: %dx%d F: %d", computer.ScreenWidth(), computer.ScreenHeight(), freq)) diff --git a/okean240/computer.go b/okean240/computer.go index 5db80e1..8be79d0 100644 --- a/okean240/computer.go +++ b/okean240/computer.go @@ -5,7 +5,7 @@ import ( "encoding/binary" "image/color" "okemu/config" - fdc2 "okemu/okean240/fdc" + "okemu/okean240/fdc" "okemu/okean240/pic" "okemu/okean240/pit" "okemu/okean240/usart" @@ -17,7 +17,7 @@ import ( ) type ComputerType struct { - cpu z80em.Z80Type + cpu *z80em.Z80Type memory Memory ioPorts [256]byte cycles uint64 @@ -28,10 +28,10 @@ type ComputerType struct { vRAM *RamBlock palette byte bgColor byte - dd70 *pit.I8253 - dd72 *usart.I8251 - dd75 *pic.I8259 - fdc *fdc2.FloppyDriveController + pit *pit.I8253 + usart *usart.I8251 + pic *pic.I8259 + fdc *fdc.FloppyDriveController kbdBuffer []byte vShift byte hShift byte @@ -41,7 +41,6 @@ const VRAMBlock0 = 3 const VRAMBlock1 = 7 const VidVsuBit = 0x80 const VidColorBit = 0x40 -const KbdBufferSize = 3 type ComputerInterface interface { Run() @@ -75,7 +74,7 @@ func New(cfg *config.OkEmuConfig) *ComputerType { c.memory = Memory{} c.memory.Init(cfg.MonitorFile, cfg.CPMFile) - c.cpu = *z80em.New(&c) + c.cpu = z80em.New(&c) c.cycles = 0 c.dd17EnableOut = false @@ -88,10 +87,10 @@ func New(cfg *config.OkEmuConfig) *ComputerType { c.vShift = 0 c.hShift = 0 - c.dd70 = pit.NewI8253() - c.dd72 = usart.NewI8251() - c.dd75 = pic.NewI8259() - c.fdc = fdc2.NewFDCType() + c.pit = pit.New() + c.usart = usart.New() + c.pic = pic.New() + c.fdc = fdc.New() return &c } @@ -120,9 +119,9 @@ func (c *ComputerType) Do() int { //} ticks := uint64(c.cpu.RunInstruction()) c.cycles += ticks - //if c.cpu.PC == 0x2C2 { - // log.Debugf("%4X: H:%X L:%X", c.cpu.PC, c.cpu.H, c.cpu.L) - //} + if c.cpu.PC == 0xFF26 { + 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) + } return int(ticks) } @@ -140,16 +139,16 @@ func (c *ComputerType) GetPixel(x uint16, y uint16) color.RGBA { } y += uint16(c.vShift) & 0x00ff - x += uint16(c.hShift) & 0x00ff + x += uint16(c.hShift-7) & 0x00ff // Color 256x256 mode - addr = ((x & 0xf8) << 6) | (y & 0xff) - if c.vShift != 0 { - addr -= 8 - } + addr = ((x & 0xf8) << 6) | y + //if c.vShift != 0 { + // addr -= 8 + //} cl := (c.vRAM.memory[addr&0x3fff] >> (x & 0x07)) & 1 - cl |= (c.vRAM.memory[(addr+0x100)&0x3fff] >> (x & 0x07)) & 1 << 1 + cl |= ((c.vRAM.memory[(addr+0x100)&0x3fff] >> (x & 0x07)) & 1) << 1 if cl == 0 { resColor = BgColorPalette[c.bgColor] } else { @@ -159,18 +158,22 @@ func (c *ComputerType) GetPixel(x uint16, y uint16) color.RGBA { if x > 511 { return CWhite } + + // Shifts + y += uint16(c.vShift) & 0x00ff + x += uint16(c.hShift-7) & 0x001ff + // Mono 512x256 mode - y += uint16(c.vShift) - addr = ((x & 0xf8) << 5) | (y & 0xff) - pix := c.vRAM.memory[addr]&(1<> (x & 0x07) & 1 if c.palette == 6 { - if !pix { + if pix == 0 { resColor = CBlack } else { resColor = CLGreen } } else { - if !pix { + if pix == 0 { resColor = BgColorPalette[c.bgColor] } else { resColor = MonoPalette[c.bgColor] @@ -194,17 +197,17 @@ func (c *ComputerType) Cycles() uint64 { func (c *ComputerType) TimerClk() { // DD70 KR580VI53 CLK0, CKL1 @ 1.5MHz - c.dd70.Tick(0) - c.dd70.Tick(1) + c.pit.Tick(0) + c.pit.Tick(1) // IRQ from timer - if c.dd70.Fired(0) { - c.dd75.SetIRQ(RstTimerNo) + if c.pit.Fired(0) { + c.pic.SetIRQ(RstTimerNo) //c.ioPorts[PIC_DD75RS] |= Rst4Mask } // clock for SIO KR580VV51 - if c.dd70.Fired(1) { - c.dd72.Tick() + if c.pit.Fired(1) { + c.usart.Tick() } } @@ -217,7 +220,7 @@ func (c *ComputerType) SaveFloppy() { } func (c *ComputerType) SetSerialBytes(bytes []byte) { - c.dd72.SetRxBytes(bytes) + c.usart.SetRxBytes(bytes) } func (c *ComputerType) SetRamBytes(bytes []byte) { diff --git a/okean240/fdc/fdc.go b/okean240/fdc/fdc.go index 3450c6b..feff94d 100644 --- a/okean240/fdc/fdc.go +++ b/okean240/fdc/fdc.go @@ -321,7 +321,7 @@ func (f *FloppyDriveController) SaveFloppy() { } -func NewFDCType() *FloppyDriveController { +func New() *FloppyDriveController { sec := [SizeInSectors]SectorType{} for i := 0; i < SizeInSectors; i++ { sec[i] = make([]byte, SectorSize) diff --git a/okean240/ioports.go b/okean240/ioports.go index efdbe43..56a4365 100644 --- a/okean240/ioports.go +++ b/okean240/ioports.go @@ -14,13 +14,13 @@ func (c *ComputerType) IORead(port uint16) byte { switch port & 0x00ff { case PIC_DD75A: // PIO xx59, get IRR register - return c.dd75.IRR() + return c.pic.IRR() case UART_DD72RR: // USART VV51 CMD - return c.dd72.Status() + return c.usart.Status() case UART_DD72RD: // USART VV51 Data - return c.dd72.Receive() + return c.usart.Receive() case KBD_DD78PA: // Keyboard data return c.ioPorts[KBD_DD78PA] @@ -79,23 +79,23 @@ func (c *ComputerType) IOWrite(port uint16, val byte) { c.hShift = val case TMR_DD70CTR: // Timer VI63 config register - c.dd70.Configure(val) + c.pit.Configure(val) case TMR_DD70C1: // Timer VI63 counter0 register - c.dd70.Load(0, val) + c.pit.Load(0, val) case TMR_DD70C2: // Timer VI63 counter1 register - c.dd70.Load(1, val) + c.pit.Load(1, val) case TMR_DD70C3: // Timer VI63 counter2 register - c.dd70.Load(2, val) + c.pit.Load(2, val) case UART_DD72RR: // USART VV51 CMD - c.dd72.Command(val) + c.usart.Command(val) case UART_DD72RD: // USART VV51 Data - c.dd72.Send(val) + c.usart.Send(val) case FDC_CMD: c.fdc.SetCmd(val) case FDC_DATA: diff --git a/okean240/keyboard.go b/okean240/keyboard.go index 348dd3e..f01dc5f 100644 --- a/okean240/keyboard.go +++ b/okean240/keyboard.go @@ -10,7 +10,7 @@ func (c *ComputerType) PutKey(key *fyne.KeyEvent) { if code > 0 { //log.Debugf("PutKey keyName: %s", key.Name) c.ioPorts[KBD_DD78PA] = code - c.dd75.SetIRQ(RstKbdNo) + c.pic.SetIRQ(RstKbdNo) } } @@ -20,7 +20,7 @@ func (c *ComputerType) PutRune(key rune) { //log.Debugf("Put Rune: %c Lo: %x, Hi: %x", key, key&0xff, key>>8) c.ioPorts[KBD_DD78PA] = byte(key & 0xff) - c.dd75.SetIRQ(RstKbdNo) + c.pic.SetIRQ(RstKbdNo) } /* @@ -38,7 +38,7 @@ func (c *ComputerType) PutRune(key rune) { func (c *ComputerType) PutCtrlKey(key byte) { c.ioPorts[KBD_DD78PA] = key - c.dd75.SetIRQ(RstKbdNo) + c.pic.SetIRQ(RstKbdNo) //c.ioPorts[PIC_DD75RS] |= Rst1Mask c.ioPorts[KBD_DD78PB] &= 0x1f | 0x20 } diff --git a/okean240/pic/pic8259.go b/okean240/pic/pic8259.go index fd78f69..67e7a01 100644 --- a/okean240/pic/pic8259.go +++ b/okean240/pic/pic8259.go @@ -47,7 +47,7 @@ func (c *I8259) SetIRQ(irq byte) { } } -func NewI8259() *I8259 { +func New() *I8259 { return &I8259{ irr: 0, } diff --git a/okean240/pit/pit8253.go b/okean240/pit/pit8253.go index a9a944a..1de7999 100644 --- a/okean240/pit/pit8253.go +++ b/okean240/pit/pit8253.go @@ -47,7 +47,7 @@ type I8253Interface interface { Start(chNo int) bool } -func NewI8253() *I8253 { +func New() *I8253 { return &I8253{ //chNo: 0, channel: [3]Timer8253Ch{ diff --git a/okean240/remapkey.go b/okean240/remapkey.go index 47b23a1..4e3f4e7 100644 --- a/okean240/remapkey.go +++ b/okean240/remapkey.go @@ -4,7 +4,7 @@ import "fyne.io/fyne/v2" var RemapCmdKey = map[fyne.KeyName]byte{ fyne.KeyEscape: 0x1B, - fyne.KeyReturn: 0x0A, + fyne.KeyReturn: 0x0D, fyne.KeyTab: 0x09, fyne.KeyBackspace: 0x08, fyne.KeyInsert: 0x00, @@ -29,7 +29,7 @@ var RemapCmdKey = map[fyne.KeyName]byte{ fyne.KeyF10: 0x00, fyne.KeyF11: 0x00, fyne.KeyF12: 0x00, - fyne.KeyEnter: 0x0D, + fyne.KeyEnter: 0x0A, fyne.KeyUnknown: 0x00, } diff --git a/okean240/usart/usart8251.go b/okean240/usart/usart8251.go index 7950dbd..4b669cf 100644 --- a/okean240/usart/usart8251.go +++ b/okean240/usart/usart8251.go @@ -47,7 +47,7 @@ type I8251Interface interface { Receive() byte } -func NewI8251() *I8251 { +func New() *I8251 { return &I8251{ counter: 0, mode: 0,