From 42fb80813ceb1f6bf130ce5bc360c7ccf382268f Mon Sep 17 00:00:00 2001 From: Roman Boykov Date: Thu, 5 Mar 2026 13:25:54 +0300 Subject: [PATCH] Refactoring PC components --- okean240/computer.go | 17 +- okean240/constants.go | 173 +------------------ okean240/fdc.go | 100 ----------- okean240/fdc/fdc.go | 177 ++++++++++++++++++++ okean240/ioports.go | 10 +- okean240/keyboard.go | 4 + okean240/palette.go | 4 +- okean240/pic/pic8259.go | 54 ++++++ okean240/{tmr8253.go => pit/pit8253.go} | 43 +++-- okean240/remapkey.go | 166 ++++++++++++++++++ okean240/{sio8251.go => usart/usart8251.go} | 29 ++-- 11 files changed, 469 insertions(+), 308 deletions(-) delete mode 100644 okean240/fdc.go create mode 100644 okean240/fdc/fdc.go create mode 100644 okean240/pic/pic8259.go rename okean240/{tmr8253.go => pit/pit8253.go} (84%) create mode 100644 okean240/remapkey.go rename okean240/{sio8251.go => usart/usart8251.go} (83%) diff --git a/okean240/computer.go b/okean240/computer.go index cceee8b..424751a 100644 --- a/okean240/computer.go +++ b/okean240/computer.go @@ -3,6 +3,9 @@ package okean240 import ( "image/color" "okemu/config" + fdc2 "okemu/okean240/fdc" + "okemu/okean240/pit" + "okemu/okean240/usart" "okemu/z80em" "fyne.io/fyne/v2" @@ -21,9 +24,9 @@ type ComputerType struct { vRAM *RamBlock palette byte bgColor byte - dd70 *Timer8253 - dd72 *Sio8251 - fdc *FDCType + dd70 *pit.I8253 + dd72 *usart.I8251 + fdc *fdc2.FloppyDriveController kbdBuffer []byte vShift byte hShift byte @@ -76,9 +79,9 @@ func New(cfg *config.OkEmuConfig) *ComputerType { c.vShift = 0 c.hShift = 0 - c.dd70 = NewTimer8253() - c.dd72 = NewSio8251() - c.fdc = NewFDCType() + c.dd70 = pit.NewI8253() + c.dd72 = usart.NewI8251() + c.fdc = fdc2.NewFDCType() return &c } @@ -113,7 +116,7 @@ func (c *ComputerType) GetPixel(x uint16, y uint16) color.RGBA { return CWhite } y += uint16(c.vShift) - // x += uint16(c.hShift >> 3) + x += uint16(c.hShift) // Color 256x256 mode addr = ((x & 0xf8) << 6) | (y & 0xff) if c.vShift != 0 { diff --git a/okean240/constants.go b/okean240/constants.go index d249197..d779c28 100644 --- a/okean240/constants.go +++ b/okean240/constants.go @@ -1,7 +1,5 @@ package okean240 -import "fyne.io/fyne/v2" - /* * КР580ВВ55 DD79 USER PORT */ @@ -35,8 +33,8 @@ const FDC_SECT = 0x22 // FDC_DATA FDC Data const FDC_DATA = 0x23 -// FDC_WAIT FDC Wait -const FDC_WAIT = 0x24 +// FDC_DRQ Read DRQ state from FDC +const FDC_DRQ = 0x24 /* * Floppy Controller port @@ -80,7 +78,7 @@ const TMR_DD70C3 = 0x62 TMR_DD70CTR Timer config: [sc1,sc0][rl1,rl0][m2,m1,m0][bcd] sc - timer, rl=01-LSB, 10-MSB, 11-LSB+MSB - mode 000 - intr on fin, + mode 000 - intRq on fin, 001 - one shot, x10 - rate gen, x11-sq wave @@ -99,7 +97,7 @@ const Rst1KbdFlag = 0x02 // Keyboard interrupt const Rst2SerFlag = 0x04 // Serial interface interrupt const RstЗLptFlag = 0x08 // Printer ready const Rst4TmrFlag = 0x10 // System timer -const Rst5PwrFlag = 0x20 // Power intr +const Rst5PwrFlag = 0x20 // Power intRq const Rst6UsrFlag = 0x40 // User device 1 interrupt const Rst7UsrFlag = 0x80 // User device 1 interrupt @@ -155,166 +153,3 @@ const DD67PC = 0xE2 * Set bit: [0][xxx][bbb][0|1] */ const DD67CTR = 0xE3 - -var RemapKey = map[fyne.KeyName]byte{ - fyne.KeyEscape: 0x1B, - fyne.KeyReturn: 0x0A, - fyne.KeyTab: 0x09, - fyne.KeyBackspace: 0x08, - fyne.KeyInsert: 0x00, - fyne.KeyDelete: 0x08, - fyne.KeyRight: 0x18, - fyne.KeyLeft: 0x08, - fyne.KeyDown: 0x0A, - fyne.KeyUp: 0x19, - fyne.KeyPageUp: 0x00, - fyne.KeyPageDown: 0x00, - fyne.KeyHome: 0x0C, - fyne.KeyEnd: 0x1A, - fyne.KeyF1: 0x00, - fyne.KeyF2: 0x00, - fyne.KeyF3: 0x00, - fyne.KeyF4: 0x00, - fyne.KeyF5: 0x00, - fyne.KeyF6: 0x00, - fyne.KeyF7: 0x00, - fyne.KeyF8: 0x00, - fyne.KeyF9: 0x00, - fyne.KeyF10: 0x00, - fyne.KeyF11: 0x00, - fyne.KeyF12: 0x00, - fyne.KeyEnter: 0x0D, - fyne.Key0: 0x30, - fyne.Key1: 0x31, - fyne.Key2: 0x32, - fyne.Key3: 0x33, - fyne.Key4: 0x34, - fyne.Key5: 0x35, - fyne.Key6: 0x36, - fyne.Key7: 0x37, - fyne.Key8: 0x38, - fyne.Key9: 0x39, - fyne.KeyA: 0x61, - fyne.KeyB: 0x62, - fyne.KeyC: 0x63, - fyne.KeyD: 0x64, - fyne.KeyE: 0x65, - fyne.KeyF: 0x66, - fyne.KeyG: 0x67, - fyne.KeyH: 0x68, - fyne.KeyI: 0x69, - fyne.KeyJ: 0x6a, - fyne.KeyK: 0x6b, - fyne.KeyL: 0x6c, - fyne.KeyM: 0x6d, - fyne.KeyN: 0x6e, - fyne.KeyO: 0x6f, - fyne.KeyP: 0x70, - fyne.KeyQ: 0x71, - fyne.KeyR: 0x72, - fyne.KeyS: 0x73, - fyne.KeyT: 0x74, - fyne.KeyU: 0x75, - fyne.KeyV: 0x76, - fyne.KeyW: 0x77, - fyne.KeyX: 0x78, - fyne.KeyY: 0x79, - fyne.KeyZ: 0x7A, - fyne.KeySpace: 0x20, - fyne.KeyApostrophe: 0x27, - fyne.KeyComma: 0x2c, - fyne.KeyMinus: 0x2d, - fyne.KeyPeriod: 0x2E, - fyne.KeySlash: 0x2F, - fyne.KeyBackslash: 0x5C, - fyne.KeyLeftBracket: 0x5B, - fyne.KeyRightBracket: 0x5D, - fyne.KeySemicolon: 0x3B, - fyne.KeyEqual: 0x3D, - fyne.KeyAsterisk: 0x2A, - fyne.KeyPlus: 0x2B, - fyne.KeyBackTick: 0x60, - fyne.KeyUnknown: 0x00, -} - -var RemapKeyShift = map[fyne.KeyName]byte{ - fyne.KeyEscape: 0x1B, - fyne.KeyReturn: 0x0A, - fyne.KeyTab: 0x09, - fyne.KeyBackspace: 0x08, - fyne.KeyInsert: 0x00, - fyne.KeyDelete: 0x08, - fyne.KeyRight: 0x18, - fyne.KeyLeft: 0x08, - fyne.KeyDown: 0x0A, - fyne.KeyUp: 0x19, - fyne.KeyPageUp: 0x00, - fyne.KeyPageDown: 0x00, - fyne.KeyHome: 0x0C, - fyne.KeyEnd: 0x1A, - fyne.KeyF1: 0x00, - fyne.KeyF2: 0x00, - fyne.KeyF3: 0x00, - fyne.KeyF4: 0x00, - fyne.KeyF5: 0x00, - fyne.KeyF6: 0x00, - fyne.KeyF7: 0x00, - fyne.KeyF8: 0x00, - fyne.KeyF9: 0x00, - fyne.KeyF10: 0x00, - fyne.KeyF11: 0x00, - fyne.KeyF12: 0x00, - fyne.KeyEnter: 0x0D, - - fyne.Key0: 0x29, - fyne.Key1: 0x21, - fyne.Key2: 0x40, - fyne.Key3: 0x23, - fyne.Key4: 0x24, - fyne.Key5: 0x25, - fyne.Key6: 0x5E, - fyne.Key7: 0x26, - fyne.Key8: 0x2A, - fyne.Key9: 0x28, - fyne.KeyA: 0x41, - fyne.KeyB: 0x42, - fyne.KeyC: 0x43, - fyne.KeyD: 0x44, - fyne.KeyE: 0x45, - fyne.KeyF: 0x46, - fyne.KeyG: 0x47, - fyne.KeyH: 0x48, - fyne.KeyI: 0x49, - fyne.KeyJ: 0x4a, - fyne.KeyK: 0x4b, - fyne.KeyL: 0x4c, - fyne.KeyM: 0x4d, - fyne.KeyN: 0x4e, - fyne.KeyO: 0x4f, - fyne.KeyP: 0x50, - fyne.KeyQ: 0x51, - fyne.KeyR: 0x52, - fyne.KeyS: 0x53, - fyne.KeyT: 0x54, - fyne.KeyU: 0x55, - fyne.KeyV: 0x56, - fyne.KeyW: 0x57, - fyne.KeyX: 0x58, - fyne.KeyY: 0x59, - fyne.KeyZ: 0x5A, - fyne.KeySpace: 0x20, - fyne.KeyApostrophe: 0x22, - fyne.KeyComma: 0x3C, - fyne.KeyMinus: 0x5F, - fyne.KeyPeriod: 0x3E, - fyne.KeySlash: 0x3F, - fyne.KeyBackslash: 0x7C, - fyne.KeyLeftBracket: 0x7B, - fyne.KeyRightBracket: 0x7D, - fyne.KeySemicolon: 0x3A, - fyne.KeyEqual: 0x2B, - fyne.KeyAsterisk: 0x7E, - fyne.KeyPlus: 0x7E, - fyne.KeyBackTick: 0x60, - fyne.KeyUnknown: 0x00, -} diff --git a/okean240/fdc.go b/okean240/fdc.go deleted file mode 100644 index 040c06c..0000000 --- a/okean240/fdc.go +++ /dev/null @@ -1,100 +0,0 @@ -package okean240 - -import log "github.com/sirupsen/logrus" - -const FloppySizeK = 360 -const SectorSize = 128 -const SectorPerTrack = 36 -const FloppySizeInS = FloppySizeK * 1024 / SectorSize -const TracksCount = FloppySizeInS / SectorPerTrack - -type SectorType []byte - -type FDCType struct { - // Floppy controller port - ssen byte - deenN byte - init byte - drsel byte - mot1 byte - mot0 byte - intr byte - motst byte - sector byte - track byte - // FloppyStorage - sectors [FloppySizeInS]SectorType - data byte -} - -type FDCTypeInterface interface { - SetFloppy() - GetFloppy() byte - SetCmd(value byte) - SetTrack(value byte) - SetSector(value byte) - SetData(value byte) - Data() byte -} - -func (f FDCType) SetFloppy(val byte) { - // WR: 5-SSEN, 4-#DDEN, 3-INIT, 2-DRSEL, 1-MOT1, 0-MOT0 - f.ssen = val >> 5 & 0x01 - f.deenN = val >> 4 & 0x01 - f.init = val >> 3 & 0x01 - f.drsel = val >> 2 & 0x01 - f.mot1 = val >> 1 & 0x01 - f.mot0 = val & 0x01 -} - -func (f FDCType) GetFloppy() byte { - // RD: 7-MOTST, 6-SSEL, 5,4-x , 3-DRSEL, 2-MOT1, 1-MOT0, 0-INT - floppy := f.intr | (f.mot0 << 1) | (f.mot1 << 2) | (f.drsel << 3) | (f.ssen << 6) | (f.motst << 7) - return floppy -} - -func (f FDCType) SetCmd(value byte) { - log.Debugf("FCD CMD: %x", value) -} - -func (f FDCType) SetTrack(value byte) { - log.Debugf("FCD Track: %d", value) - f.track = value -} - -func (f FDCType) SetSector(value byte) { - log.Debugf("FCD Sector: %d", value) - f.sector = value -} - -func (f FDCType) SetData(value byte) { - log.Debugf("FCD Data: %d", value) - f.data = value -} - -func (f FDCType) GetData() byte { - return f.data -} - -func NewFDCType() *FDCType { - sec := [FloppySizeInS]SectorType{} - for i := 0; i < FloppySizeInS; i++ { - sec[i] = make(SectorType, SectorSize) - for s := 0; s < 128; s++ { - sec[i][s] = 0 - } - } - return &FDCType{ - ssen: 0, - deenN: 0, - init: 0, - drsel: 0, - mot1: 0, - mot0: 0, - intr: 0, - motst: 0, - sectors: sec, - } -} - -// diff --git a/okean240/fdc/fdc.go b/okean240/fdc/fdc.go new file mode 100644 index 0000000..101fb0e --- /dev/null +++ b/okean240/fdc/fdc.go @@ -0,0 +1,177 @@ +package fdc + +/** +Floppy drive controller, based on +MB8877, К1818ВГ93 + +By Romych, 2025.03.05 +*/ + +import ( + log "github.com/sirupsen/logrus" +) + +const FloppySizeK = 360 + +const SectorSize = 128 +const SideCount = 2 +const SectorPerTrack = 36 + +const SizeInSectors = FloppySizeK * 1024 / SectorSize +const TracksCount = SizeInSectors / SideCount / SectorPerTrack +const SectorsPerSide = SizeInSectors / SideCount + +type SectorType []byte + +type FloppyDriveController struct { + // Floppy controller port + sideSel byte + ddEn byte + init byte + drSel byte + mot1 byte + mot0 byte + intRq byte + motSt byte + sector byte + track byte + drq byte + // FloppyStorage + sectors [SizeInSectors]SectorType + data byte + status byte + lastCmd byte + curSector *SectorType + bytePtr uint16 +} + +type FloppyDriveControllerInterface interface { + SetFloppy() + Floppy() byte + SetCmd(value byte) + Status() byte + SetTrack(value byte) + SetSector(value byte) + SetData(value byte) + Data() byte + Drq() byte +} + +func (f *FloppyDriveController) SetFloppy(val byte) { + // WR: 5-SSEN, 4-#DDEN, 3-INIT, 2-DRSEL, 1-MOT1, 0-MOT0 + f.sideSel = val >> 5 & 0x01 + f.ddEn = val >> 4 & 0x01 + f.init = val >> 3 & 0x01 + f.drSel = val >> 2 & 0x01 + f.mot1 = val >> 1 & 0x01 + f.mot0 = val & 0x01 +} + +func (f *FloppyDriveController) GetFloppy() byte { + // 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.drSel << 3) | (f.sideSel << 6) | (f.motSt << 7) + return floppy +} + +const ( + FdcCmdRestore byte = 0 + FdcCmdSeek byte = 1 + FdcCmdStep byte = 2 + FdcCmdReadSector byte = 8 +) + +func (f *FloppyDriveController) SetCmd(value byte) { + //log.Debugf("FCD CMD: %x", value) + f.lastCmd = value >> 4 + switch f.lastCmd { + case FdcCmdRestore: + log.Debug("CMD Restore (seek track 0)") + f.status = 0x24 // TR0 & Head loaded + f.track = 0 + case FdcCmdSeek: + log.Debugf("CMD Seek %x", value&0xf) + f.status = 0x04 // Head loaded + f.track = f.data + case FdcCmdStep: + log.Debugf("CMD Step %x", value&0xf) + f.status = 0x04 // Head loaded + f.track = f.data + case FdcCmdReadSector: + f.status = 0x04 + sectorNo := uint16(f.sideSel)*SectorsPerSide + uint16(f.track)*SectorPerTrack + uint16(f.sector) + log.Debugf("CMD Read single sector: %d", sectorNo) + if sectorNo >= SizeInSectors { + f.status = 0x10 // RNF - Record not found + } else { + f.curSector = &f.sectors[sectorNo] + f.bytePtr = 0 + f.drq = 1 + f.status = 0x00 + } + default: + log.Debugf("Unknown CMD: %x VAL: %x", f.lastCmd, value&0xf) + } +} + +func (f *FloppyDriveController) Status() byte { + return f.status +} + +func (f *FloppyDriveController) SetTrack(value byte) { + log.Debugf("FCD Track: %d", value) + f.track = value +} + +func (f *FloppyDriveController) SetSector(value byte) { + log.Debugf("FCD Sector: %d", value) + f.sector = value +} + +func (f *FloppyDriveController) SetData(value byte) { + log.Debugf("FCD Data: %d", value) + f.data = value +} + +func (f *FloppyDriveController) Data() byte { + if f.lastCmd == FdcCmdReadSector { + if f.bytePtr < SectorSize { + f.drq = 1 + f.data = (*f.curSector)[f.bytePtr] + f.bytePtr++ + } else { + f.drq = 0 + f.status = 0 + } + } + return f.data +} + +func (f *FloppyDriveController) Drq() byte { + return f.drq +} + +func NewFDCType() *FloppyDriveController { + sec := [SizeInSectors]SectorType{} + for i := 0; i < int(SizeInSectors); i++ { + sec[i] = make([]byte, SectorSize) + for s := 0; s < 128; s++ { + sec[i][s] = 0 + } + } + return &FloppyDriveController{ + sideSel: 0, + ddEn: 0, + init: 0, + drSel: 0, + mot1: 0, + mot0: 0, + intRq: 0, + motSt: 0, + drq: 0, + lastCmd: 0xff, + sectors: sec, + bytePtr: 0xffff, + } +} + +// diff --git a/okean240/ioports.go b/okean240/ioports.go index f3cb11c..401d8e2 100644 --- a/okean240/ioports.go +++ b/okean240/ioports.go @@ -28,8 +28,15 @@ func (c *ComputerType) IORead(port uint16) byte { return c.ioPorts[KBD_DD78PA] case KBD_DD78PB: return c.ioPorts[KBD_DD78PB] + case FDC_CMD: + return c.fdc.Status() + case FDC_DRQ: + return c.fdc.Drq() case FLOPPY: return c.fdc.GetFloppy() + case FDC_DATA: + return c.fdc.Data() + default: log.Debugf("IORead from port: %x", port) } @@ -89,13 +96,14 @@ func (c *ComputerType) IOWrite(port uint16, val byte) { c.dd72.Send(val) case FDC_CMD: c.fdc.SetCmd(val) + case FDC_DATA: + c.fdc.SetData(val) case FDC_TRACK: c.fdc.SetTrack(val) case FDC_SECT: c.fdc.SetSector(val) case FLOPPY: c.fdc.SetFloppy(val) - default: //log.Debugf("OUT to Unknown port (%x), %x", bp, val) diff --git a/okean240/keyboard.go b/okean240/keyboard.go index ddc60e2..3a44d0c 100644 --- a/okean240/keyboard.go +++ b/okean240/keyboard.go @@ -12,6 +12,8 @@ func (c *ComputerType) PutKey(key *fyne.KeyEvent) { return } + log.Debugf("PutKey keyName: %s", key.Name) + if len(c.kbdBuffer) < KbdBufferSize { var code byte @@ -24,6 +26,7 @@ func (c *ComputerType) PutKey(key *fyne.KeyEvent) { code = RemapKeyShift[key.Name] } c.ioPorts[KBD_DD78PB] &= 0x1f + if code != 0 { c.ioPorts[KBD_DD78PA] = code c.ioPorts[PIC_DD75RS] |= Rst1KbdFlag @@ -34,6 +37,7 @@ func (c *ComputerType) PutKey(key *fyne.KeyEvent) { case "LeftControl", "RightControl": c.ioPorts[KBD_DD78PB] |= 0x20 case "LeftShift", "RightShift": + log.Debug("Shift") c.ioPorts[KBD_DD78PB] |= 0x40 default: log.Debugf("Unhandled KeyName: %s code: %X", key.Name, key.Physical.ScanCode) diff --git a/okean240/palette.go b/okean240/palette.go index 1522340..379dbd4 100644 --- a/okean240/palette.go +++ b/okean240/palette.go @@ -7,12 +7,12 @@ var CLGreen = color.RGBA{R: 0x00, G: 0xff, B: 0, A: 0xff} var CGreen = color.RGBA{R: 0x12, G: 0x76, B: 0x22, A: 0xff} var CBlue = color.RGBA{R: 0x2A, G: 0x60, B: 0x99, A: 0xff} var CLBlue = color.RGBA{R: 0x72, G: 0x9F, B: 0xCF, A: 0xff} -var CCrimson = color.RGBA{R: 0x80, G: 0x00, B: 0x80, A: 0xff} +var CCrimson = color.RGBA{R: 0xbf, G: 0x00, B: 0xbf, A: 0xff} var CWhite = color.RGBA{R: 0xff, G: 0xff, B: 0xff, A: 0xff} var CYellow = color.RGBA{R: 0xff, G: 0xff, B: 0x00, A: 0xff} var CBlack = color.RGBA{R: 0, G: 0, B: 0, A: 0xff} -// R5 - Style Palette +//// R5 - Style Palette //var ColorPalette = [8][4]color.RGBA{ // {CBlack, CRed, CGreen, CBlue}, // 000 // {CWhite, CRed, CGreen, CBlue}, // 001 diff --git a/okean240/pic/pic8259.go b/okean240/pic/pic8259.go new file mode 100644 index 0000000..fd78f69 --- /dev/null +++ b/okean240/pic/pic8259.go @@ -0,0 +1,54 @@ +package pic + +/* + Programmable Interrupt Controller + i8058, MSM82C59, КР580ВН59 + + By Romych, 2025.03.05 +*/ + +import log "github.com/sirupsen/logrus" + +type I8259 struct { + irr byte +} + +type I8259Interface interface { + SetIRQ(irq byte) + IRR() byte +} + +func (c *I8259) IRR() byte { + irr := c.irr + // Reset the highest IR bit + if irr&0x80 != 0 { + c.irr &= 0x7F + } else if irr&0x40 != 0 { + c.irr &= 0x3F + } else if irr&0x20 != 0 { + c.irr &= 0x1F + } else if irr&0x08 != 0 { + c.irr &= 0x07 + } else if irr&0x04 != 0 { + c.irr &= 0x03 + } else if irr&0x02 != 0 { + c.irr &= 0x1 + } else { + c.irr = 0 + } + return irr +} + +func (c *I8259) SetIRQ(irq byte) { + if irq < 8 { + c.irr |= 1 << irq + } else { + log.Warnf("SetIRQ out of range [0..7]: %d", irq) + } +} + +func NewI8259() *I8259 { + return &I8259{ + irr: 0, + } +} diff --git a/okean240/tmr8253.go b/okean240/pit/pit8253.go similarity index 84% rename from okean240/tmr8253.go rename to okean240/pit/pit8253.go index 507133e..a9a944a 100644 --- a/okean240/tmr8253.go +++ b/okean240/pit/pit8253.go @@ -1,13 +1,10 @@ -package okean240 +package pit /* - Timer config byte: [sc1:0][rl1:0][m2:0][bcd] - sc1:0 - timer No - rl=01-LSB, 10-MSB, 11-LSB+MSB - mode 000 - intr on fin, - 001 - one shot, - x10 - rate gen, - x11 - sq wave + Programmable Interval Timer + i8053, MSM82C53, КР580ВИ53 + + By Romych, 2025.03.04 */ // Timer work modes @@ -36,12 +33,12 @@ type Timer8253Ch struct { started bool // true if timer started fired bool } -type Timer8253 struct { +type I8253 struct { //chNo byte channel [3]Timer8253Ch } -type Timer8253Interface interface { +type I8253Interface interface { //Init() Configure(value byte) Load(chNo int, value byte) @@ -50,8 +47,8 @@ type Timer8253Interface interface { Start(chNo int) bool } -func NewTimer8253() *Timer8253 { - return &Timer8253{ +func NewI8253() *I8253 { + return &I8253{ //chNo: 0, channel: [3]Timer8253Ch{ {0, 0, false, 0, 0, true, false, false}, @@ -61,7 +58,7 @@ func NewTimer8253() *Timer8253 { } } -func (t *Timer8253) Tick(chNo int) { +func (t *I8253) Tick(chNo int) { tmr := &t.channel[chNo] if tmr.started { tmr.counter-- @@ -87,11 +84,11 @@ func (t *Timer8253) Tick(chNo int) { } } -func (t *Timer8253) Counter(chNo int) uint16 { +func (t *I8253) Counter(chNo int) uint16 { return t.channel[chNo].counter } -func (t *Timer8253) Fired(chNo int) bool { +func (t *I8253) Fired(chNo int) bool { f := t.channel[chNo].fired if f { t.channel[chNo].fired = false @@ -99,11 +96,21 @@ func (t *Timer8253) Fired(chNo int) bool { return f } -func (t *Timer8253) Start(chNo int) bool { +func (t *I8253) Start(chNo int) bool { return t.channel[chNo].started } -func (t *Timer8253) Configure(value byte) { +/* + Timer config byte: [sc1:0][rl1:0][m2:0][bcd] + sc1:0 - timer No + rl=01-LSB, 10-MSB, 11-LSB+MSB + mode 000 - intRq on fin, + 001 - one shot, + x10 - rate gen, + x11 - sq wave +*/ + +func (t *I8253) Configure(value byte) { chNo := (value & 0xC0) >> 6 rl := value & 0x30 >> 4 t.channel[chNo].started = false @@ -114,7 +121,7 @@ func (t *Timer8253) Configure(value byte) { t.channel[chNo].load = 0 } -func (t *Timer8253) Load(chNo byte, value byte) { +func (t *I8253) Load(chNo byte, value byte) { timer := &t.channel[chNo] switch timer.rl { case TimerRLMsbLsb: diff --git a/okean240/remapkey.go b/okean240/remapkey.go new file mode 100644 index 0000000..f3bf7da --- /dev/null +++ b/okean240/remapkey.go @@ -0,0 +1,166 @@ +package okean240 + +import "fyne.io/fyne/v2" + +var RemapKey = map[fyne.KeyName]byte{ + fyne.KeyEscape: 0x1B, + fyne.KeyReturn: 0x0A, + fyne.KeyTab: 0x09, + fyne.KeyBackspace: 0x08, + fyne.KeyInsert: 0x00, + fyne.KeyDelete: 0x08, + fyne.KeyRight: 0x18, + fyne.KeyLeft: 0x08, + fyne.KeyDown: 0x0A, + fyne.KeyUp: 0x19, + fyne.KeyPageUp: 0x00, + fyne.KeyPageDown: 0x00, + fyne.KeyHome: 0x0C, + fyne.KeyEnd: 0x1A, + fyne.KeyF1: 0x00, + fyne.KeyF2: 0x00, + fyne.KeyF3: 0x00, + fyne.KeyF4: 0x00, + fyne.KeyF5: 0x00, + fyne.KeyF6: 0x00, + fyne.KeyF7: 0x00, + fyne.KeyF8: 0x00, + fyne.KeyF9: 0x00, + fyne.KeyF10: 0x00, + fyne.KeyF11: 0x00, + fyne.KeyF12: 0x00, + fyne.KeyEnter: 0x0D, + fyne.Key0: 0x30, + fyne.Key1: 0x31, + fyne.Key2: 0x32, + fyne.Key3: 0x33, + fyne.Key4: 0x34, + fyne.Key5: 0x35, + fyne.Key6: 0x36, + fyne.Key7: 0x37, + fyne.Key8: 0x38, + fyne.Key9: 0x39, + fyne.KeyA: 0x61, + fyne.KeyB: 0x62, + fyne.KeyC: 0x63, + fyne.KeyD: 0x64, + fyne.KeyE: 0x65, + fyne.KeyF: 0x66, + fyne.KeyG: 0x67, + fyne.KeyH: 0x68, + fyne.KeyI: 0x69, + fyne.KeyJ: 0x6a, + fyne.KeyK: 0x6b, + fyne.KeyL: 0x6c, + fyne.KeyM: 0x6d, + fyne.KeyN: 0x6e, + fyne.KeyO: 0x6f, + fyne.KeyP: 0x70, + fyne.KeyQ: 0x71, + fyne.KeyR: 0x72, + fyne.KeyS: 0x73, + fyne.KeyT: 0x74, + fyne.KeyU: 0x75, + fyne.KeyV: 0x76, + fyne.KeyW: 0x77, + fyne.KeyX: 0x78, + fyne.KeyY: 0x79, + fyne.KeyZ: 0x7A, + fyne.KeySpace: 0x20, + fyne.KeyApostrophe: 0x27, + fyne.KeyComma: 0x2c, + fyne.KeyMinus: 0x2d, + fyne.KeyPeriod: 0x2E, + fyne.KeySlash: 0x2F, + fyne.KeyBackslash: 0x5C, + fyne.KeyLeftBracket: 0x5B, + fyne.KeyRightBracket: 0x5D, + fyne.KeySemicolon: 0x3B, + fyne.KeyEqual: 0x3D, + fyne.KeyAsterisk: 0x2A, + fyne.KeyPlus: 0x2B, + fyne.KeyBackTick: 0x60, + fyne.KeyUnknown: 0x00, +} + +var RemapKeyShift = map[fyne.KeyName]byte{ + fyne.KeyEscape: 0x1B, + fyne.KeyReturn: 0x0A, + fyne.KeyTab: 0x09, + fyne.KeyBackspace: 0x08, + fyne.KeyInsert: 0x00, + fyne.KeyDelete: 0x08, + fyne.KeyRight: 0x18, + fyne.KeyLeft: 0x08, + fyne.KeyDown: 0x0A, + fyne.KeyUp: 0x19, + fyne.KeyPageUp: 0x00, + fyne.KeyPageDown: 0x00, + fyne.KeyHome: 0x0C, + fyne.KeyEnd: 0x1A, + fyne.KeyF1: 0x00, + fyne.KeyF2: 0x00, + fyne.KeyF3: 0x00, + fyne.KeyF4: 0x00, + fyne.KeyF5: 0x00, + fyne.KeyF6: 0x00, + fyne.KeyF7: 0x00, + fyne.KeyF8: 0x00, + fyne.KeyF9: 0x00, + fyne.KeyF10: 0x00, + fyne.KeyF11: 0x00, + fyne.KeyF12: 0x00, + fyne.KeyEnter: 0x0D, + + fyne.Key0: 0x29, + fyne.Key1: 0x21, + fyne.Key2: 0x40, + fyne.Key3: 0x23, + fyne.Key4: 0x24, + fyne.Key5: 0x25, + fyne.Key6: 0x5E, + fyne.Key7: 0x26, + fyne.Key8: 0x2A, + fyne.Key9: 0x28, + fyne.KeyA: 0x41, + fyne.KeyB: 0x42, + fyne.KeyC: 0x43, + fyne.KeyD: 0x44, + fyne.KeyE: 0x45, + fyne.KeyF: 0x46, + fyne.KeyG: 0x47, + fyne.KeyH: 0x48, + fyne.KeyI: 0x49, + fyne.KeyJ: 0x4a, + fyne.KeyK: 0x4b, + fyne.KeyL: 0x4c, + fyne.KeyM: 0x4d, + fyne.KeyN: 0x4e, + fyne.KeyO: 0x4f, + fyne.KeyP: 0x50, + fyne.KeyQ: 0x51, + fyne.KeyR: 0x52, + fyne.KeyS: 0x53, + fyne.KeyT: 0x54, + fyne.KeyU: 0x55, + fyne.KeyV: 0x56, + fyne.KeyW: 0x57, + fyne.KeyX: 0x58, + fyne.KeyY: 0x59, + fyne.KeyZ: 0x5A, + fyne.KeySpace: 0x20, + fyne.KeyApostrophe: 0x22, + fyne.KeyComma: 0x3C, + fyne.KeyMinus: 0x5F, + fyne.KeyPeriod: 0x3E, + fyne.KeySlash: 0x3F, + fyne.KeyBackslash: 0x7C, + fyne.KeyLeftBracket: 0x7B, + fyne.KeyRightBracket: 0x7D, + fyne.KeySemicolon: 0x3A, + fyne.KeyEqual: 0x2B, + fyne.KeyAsterisk: 0x7E, + fyne.KeyPlus: 0x7E, + fyne.KeyBackTick: 0x60, + fyne.KeyUnknown: 0x00, +} diff --git a/okean240/sio8251.go b/okean240/usart/usart8251.go similarity index 83% rename from okean240/sio8251.go rename to okean240/usart/usart8251.go index c6e7826..d7ef131 100644 --- a/okean240/sio8251.go +++ b/okean240/usart/usart8251.go @@ -1,4 +1,11 @@ -package okean240 +package usart + +/** +Universal Serial Asynchronous Receiver/Transmitter +i8051, MSM82C51, КР580ВВ51 + +By Romych, 2025.03.04 +*/ const I8251DSRFlag = 0x80 const I8251SynDetFlag = 0x40 @@ -17,7 +24,7 @@ const ( Sio8251LoadCommand ) -type Sio8251 struct { +type I8251 struct { counter uint64 mode byte initState byte @@ -29,7 +36,7 @@ type Sio8251 struct { txe bool } -type Sio8251Interface interface { +type I8251Interface interface { Tick() Status() byte Reset() @@ -38,8 +45,8 @@ type Sio8251Interface interface { Receive() byte } -func NewSio8251() *Sio8251 { - return &Sio8251{ +func NewI8251() *I8251 { + return &I8251{ counter: 0, mode: 0, initState: 0, @@ -50,12 +57,12 @@ func NewSio8251() *Sio8251 { } } -func (s *Sio8251) Tick() { +func (s *I8251) Tick() { s.counter++ } // Status i8251 status [RST,RQ_RX,RST_ERR,PAUSE,RX_EN,RX_RDY,TX_RDY] -func (s *Sio8251) Status() byte { +func (s *I8251) Status() byte { var status byte = 0 if len(s.bufferRx) > 0 { status |= I8251RxReadyFlag @@ -69,7 +76,7 @@ func (s *Sio8251) Status() byte { return status } -func (s *Sio8251) Reset() { +func (s *I8251) Reset() { s.counter = 0 s.mode = 0 s.initState = 0 @@ -79,7 +86,7 @@ func (s *Sio8251) Reset() { s.txe = false } -func (s *Sio8251) Command(value byte) { +func (s *I8251) Command(value byte) { switch s.initState { case Sio8251Reset: s.mode = value @@ -119,13 +126,13 @@ func (s *Sio8251) Command(value byte) { } -func (s *Sio8251) Send(value byte) { +func (s *I8251) Send(value byte) { if s.txe { s.bufferTx = append(s.bufferTx, value) } } -func (s *Sio8251) Receive() byte { +func (s *I8251) Receive() byte { if s.rxe { if len(s.bufferRx) > 0 { res := s.bufferRx[0]