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