Skip to content

Commit

Permalink
[cpc] ga, crt, fdc (mario bros demo rhino)
Browse files Browse the repository at this point in the history
  • Loading branch information
laullon committed Apr 14, 2020
1 parent 4104231 commit 933b1af
Show file tree
Hide file tree
Showing 8 changed files with 208 additions and 157 deletions.
3 changes: 0 additions & 3 deletions emulator/fdc/fdc.go
Original file line number Diff line number Diff line change
@@ -1,13 +1,10 @@
package fdc

import (
"github.com/laullon/b2t80s/emulator"
"github.com/laullon/b2t80s/emulator/files"
)

type FDC interface {
emulator.PortManager // DEPRECATED

ReadData() byte
ReadStatus() byte
WriteData(val byte)
Expand Down
33 changes: 1 addition & 32 deletions emulator/fdc/fdc765.go
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ func (fdc *fdc765) LOAD_RESULT_WITH_CHRN() {

func (fdc *fdc765) isDriveReady() bool {
val := fdc.cmd.args[CMD_UNIT] & 0b111
println("isDriveReady", fdc.discActive, fdc.motor)
// println("isDriveReady", fdc.discActive, fdc.motor)
if fdc.discs[fdc.discActive] == nil || (!fdc.motor) {
val |= 0x48 // Abnormal Termination + Not Ready
}
Expand Down Expand Up @@ -220,34 +220,3 @@ func (fdc *fdc765) ReadStatus() byte {
func (fdc *fdc765) SetMotor(on bool) {
fdc.motor = on
}

// TODO: move theses 2 methods to a cpc specific
func (fdc *fdc765) ReadPort(port uint16) (byte, bool) {
if (port & (1 << 10)) == 0 {
f := ((port & (1 << 8)) >> (8 - 1)) | (port & 0x01)
switch f {
case 2:
return fdc.ReadStatus(), false
case 3:
return fdc.ReadData(), false
default:
panic(f)
}
} else {
panic(fmt.Sprintf("port: 0x%04X", port))
}
}

func (fdc *fdc765) WritePort(port uint16, data byte) {
if (port & (1 << 7)) == 0 {
f := ((port & 0x0100) >> (8 - 1)) | (port & 0x01)
switch f {
case 0:
fdc.motor = data == 1
case 3:
fdc.WriteData(data)
default:
panic(fmt.Sprintf("port: 0x%04X data: 0x%02X f:%d", port, data, f))
}
}
}
15 changes: 7 additions & 8 deletions machines/cpc/cpc.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import (
"github.com/laullon/b2t80s/data"
"github.com/laullon/b2t80s/emulator"
"github.com/laullon/b2t80s/emulator/ay8912"
"github.com/laullon/b2t80s/emulator/fdc"
"github.com/laullon/b2t80s/emulator/files"
"github.com/laullon/b2t80s/machines"
"github.com/laullon/b2t80s/z80"
Expand Down Expand Up @@ -79,11 +78,11 @@ func NewCPC(cpc464 bool, cassette emulator.Cassette) machines.Machine {
// cpu.RegisterPort(emulator.PortMask{Mask: 0xDF00, Value: 0xDF00}, mem)
cpu.RegisterPort(emulator.PortMask{Mask: 0x2000, Value: 0x0000}, mem)

fdc := fdc.New765()
fdc := NewCPCFDC765()
cpu.RegisterPort(emulator.PortMask{Mask: 0x0400, Value: 0x0000}, fdc)
if len(*machines.DskAFile) > 0 {
disc := files.LoadDsk(*machines.DskAFile)
fdc.SetDiscA(disc)
fdc.chip.SetDiscA(disc)
// fmt.Printf("%v\n", disc)
}
// if len(*dskBFile) > 0 {
Expand All @@ -105,10 +104,10 @@ func NewCPC(cpc464 bool, cassette emulator.Cassette) machines.Machine {
cpu.SetClock(cpc.clock)
mem.SetClock(cpc.clock)

cpc.clock.AddTicker(0, crtc)
cpc.clock.AddTicker(4, crtc)
cpc.clock.AddTicker(0, cassette)
cpc.clock.AddTicker(0, ga)
cpc.clock.AddTicker(2, ay8912)
cpc.clock.AddTicker(4, ga)
cpc.clock.AddTicker(4, ay8912)
cpc.clock.AddTicker(80, sound)

// if *machines.LoadSlow {
Expand Down Expand Up @@ -156,7 +155,7 @@ func (m *cpc) OnKeyEvent(event *fyne.KeyEvent) {
}

func (m *cpc) Display() image.Image {
return m.ga.displayScaled
return m.ga.display
}

func (m *cpc) GetVolumeControl() func(float64) {
Expand Down Expand Up @@ -184,7 +183,7 @@ func (m *cpc) Run() {
frames++
frameTime := time.Now().Sub(frameStart)
runTime := time.Now().Sub(runStart)
m.Debugger().SetStatus(fmt.Sprintf("frame rate:%6.2f time:%6.2fms (%v) (ear:%v) (crtc.sl:%d)", frames/runTime.Seconds(), float64(frameTime.Microseconds())/1000, wait, m.cassette.Ear(), m.ga.crtc.cycles))
m.Debugger().SetStatus(fmt.Sprintf("frame rate:%6.2f time:%6.2fms (%v) (ear:%v)", frames/runTime.Seconds(), float64(frameTime.Microseconds())/1000, wait, m.cassette.Ear()))
}
}()
}
Expand Down
65 changes: 23 additions & 42 deletions machines/cpc/crtc.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,14 @@ type crtcStatus struct {
vSync bool
hSync bool
disPen bool
ma uint16
ma uint32
ra int
}

type crtcCounters struct {
h int
sl int
row int
raster int
hcc int // horizontal char counter
vlc int // vertical line counter
vcc int // vertical char counter // ra
}

type crtc struct {
Expand All @@ -33,9 +33,6 @@ type crtc struct {
regs []byte
selectReg byte

cycles uint32
clock uint32

addr uint32

vSyncOn, vSyncOff int
Expand Down Expand Up @@ -63,7 +60,7 @@ func (crtc *crtc) WritePort(port uint16, data byte) {

case 1:
crtc.regs[crtc.selectReg] = data & regMasks[crtc.selectReg]
fmt.Printf("[crtc] reg: %2d = %d\n", crtc.selectReg, data)
// fmt.Printf("[crtc] reg: %2d = %d\n", crtc.selectReg, data)

crtc.recalcule()
default:
Expand All @@ -76,67 +73,51 @@ func (crtc *crtc) recalcule() {
// println("[crtc] addr:", crtc.addr)

crtc.vSyncOn = int(crtc.regs[7])
vSyncSize := int((crtc.regs[3] >> 4) & 0x0f)
vSyncSize := int((crtc.regs[3] >> 4) & 0x0f / 8)
crtc.vSyncOff = crtc.vSyncOn + vSyncSize
// println("[crtc] vSyncOn:", crtc.vSyncOn, "vSyncOff:", crtc.vSyncOff)

crtc.hSyncOn = int(crtc.regs[2])
hSyncSize := int(crtc.regs[3] & 0x0f)
crtc.hSyncOff = crtc.hSyncOn + hSyncSize
// println("[crtc] hSyncOn:", crtc.hSyncOn, "hSyncOff:", crtc.hSyncOff)

}

func (crtc *crtc) Tick() {
clock := crtc.cycles / 4
crtc.cycles++

if crtc.clock == clock {
return
}
crtc.clock = clock

R0 := int(crtc.regs[0])
R1 := int(crtc.regs[1])
R4 := int(crtc.regs[4])
R6 := int(crtc.regs[6])
R9 := int(crtc.regs[9])

if crtc.counters.h < R0 {
crtc.counters.h++
if crtc.counters.hcc < R0 {
crtc.counters.hcc++
} else {
crtc.counters.h = 0
if crtc.counters.sl < R9 {
crtc.counters.sl++
crtc.counters.hcc = 0
if crtc.counters.vlc < R9 {
crtc.counters.vlc++
} else {
crtc.counters.sl = 0
if crtc.counters.row < R4 {
crtc.counters.row++
crtc.counters.vlc = 0
if crtc.counters.vcc < R4 {
crtc.counters.vcc++
} else {
crtc.counters.row = 0
crtc.counters.vcc = 0
}
}
crtc.counters.raster = int(crtc.counters.row*(R9+1)) + int(crtc.counters.sl)
}

if crtc.counters.h == crtc.hSyncOff {
if crtc.counters.raster%52 == 0 {
crtc.cpu.Interrupt(true)
}
}

crtc.status.vSync = (crtc.counters.row >= crtc.vSyncOn) && (crtc.counters.row <= crtc.vSyncOff)
crtc.status.hSync = (crtc.counters.h >= crtc.hSyncOn) && (crtc.counters.h <= crtc.hSyncOff)
crtc.status.disPen = (crtc.counters.h < R1) && (crtc.counters.row < R6)
crtc.status.vSync = (crtc.counters.vcc >= crtc.vSyncOn) && (crtc.counters.vcc <= crtc.vSyncOff)
crtc.status.hSync = (crtc.counters.hcc >= crtc.hSyncOn) && (crtc.counters.hcc <= crtc.hSyncOff)
crtc.status.disPen = (crtc.counters.hcc < R1) && (crtc.counters.vcc < R6)

MA := crtc.addr + uint32(crtc.counters.row)*uint32(R1) + uint32(crtc.counters.h)
crtc.status.ma = uint16(((MA & 0x3FF) << 1) | ((uint32(crtc.counters.raster) & 7) << 11) | ((MA & 0x3000) << 2))
crtc.status.ma = crtc.addr + uint32(crtc.counters.vcc)*uint32(R1) + uint32(crtc.counters.hcc)
crtc.status.ra = crtc.counters.vlc

// if crtc.counters.h == 0 {
// fmt.Printf("=> %+v => %+v => 0x%04X\n", crtc.counters, crtc.status, crtc.status.ma)
// }
}

func (crtc *crtc) FrameEnded() {
crtc.cycles = 0
func (st *crtcStatus) getAddress() uint16 {
return uint16(((st.ma & 0x3FF) << 1) | ((uint32(st.ra) & 7) << 11) | ((st.ma & 0x3000) << 2))
}
44 changes: 44 additions & 0 deletions machines/cpc/fdc765.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package cpc

import (
"fmt"

"github.com/laullon/b2t80s/emulator/fdc"
)

type fdc765 struct {
chip fdc.FDC
}

func NewCPCFDC765() *fdc765 {
return &fdc765{
chip: fdc.New765(),
}
}

func (fdc *fdc765) ReadPort(port uint16) (byte, bool) {
if (port & (1 << 10)) == 0 {
f := ((port & (1 << 8)) >> (8 - 1)) | (port & 0x01)
switch f {
case 2:
return fdc.chip.ReadStatus(), false
case 3:
return fdc.chip.ReadData(), false
default:
panic(f)
}
} else {
panic(fmt.Sprintf("port: 0x%04X", port))
}
}

func (fdc *fdc765) WritePort(port uint16, data byte) {
switch port {
case 0xFA7E:
fdc.chip.SetMotor(data == 1)
case 0xFB7F:
fdc.chip.WriteData(data)
default:
fmt.Printf("port: 0x%04X data: 0x%02X \n", port, data)
}
}
Loading

0 comments on commit 933b1af

Please sign in to comment.