Trace sofswitches per card

This commit is contained in:
Ivan Izaguirre 2024-01-27 17:19:44 +01:00
parent 0c615fc96c
commit b2cf890957
3 changed files with 70 additions and 23 deletions

View File

@ -24,6 +24,10 @@ type cardBuilder struct {
const noCardName = "empty"
var commonParams = []paramSpec{
{"tracess", "Trace softswitches", "false"},
}
var cardFactory map[string]*cardBuilder
func getCardFactory() map[string]*cardBuilder {
@ -31,7 +35,9 @@ func getCardFactory() map[string]*cardBuilder {
return cardFactory
}
cardFactory = make(map[string]*cardBuilder)
cardFactory["brainboard"] = newCardBrainBoardIIBuilder()
//cardFactory["brainboard"] = newCardBrainBoardBuilder()
cardFactory["brainboard2"] = newCardBrainBoardIIBuilder()
//cardFactory["dan2sd"] = newCardDan2ControllerBuilder()
cardFactory["diskii"] = newCardDisk2Builder()
cardFactory["diskiiseq"] = newCardDisk2SequencerBuilder()
cardFactory["fastchip"] = newCardFastChipBuilder()
@ -57,9 +63,9 @@ func availableCards() []string {
}
func setupCard(a *Apple2, slot int, paramString string) (Card, error) {
paramsArgs := splitConfigurationString(paramString, ',')
actualArgs := splitConfigurationString(paramString, ',')
cardName := paramsArgs[0]
cardName := actualArgs[0]
if cardName == "" || cardName == noCardName {
return nil, nil
}
@ -74,25 +80,29 @@ func setupCard(a *Apple2, slot int, paramString string) (Card, error) {
}
finalParams := make(map[string]string)
for _, commonParam := range commonParams {
finalParams[commonParam.name] = commonParam.defaultValue
}
if builder.defaultParams != nil {
for _, defaultParam := range *builder.defaultParams {
finalParams[defaultParam.name] = defaultParam.defaultValue
}
}
for i := 1; i < len(paramsArgs); i++ {
paramArgSides := splitConfigurationString(paramsArgs[i], '=')
for i := 1; i < len(actualArgs); i++ {
actualArgSides := splitConfigurationString(actualArgs[i], '=')
actualArgName := strings.ToLower(actualArgSides[0])
if _, ok := finalParams[paramArgSides[0]]; !ok {
return nil, fmt.Errorf("unknown parameter %s", paramArgSides[0])
if _, ok := finalParams[actualArgName]; !ok {
return nil, fmt.Errorf("unknown parameter %s", actualArgSides[0])
}
if len(paramArgSides) > 2 {
return nil, fmt.Errorf("invalid parameter value for %s", paramArgSides[0])
if len(actualArgSides) > 2 {
return nil, fmt.Errorf("invalid parameter value for %s", actualArgSides[0])
}
if len(paramArgSides) == 1 {
finalParams[paramArgSides[0]] = "true"
if len(actualArgSides) == 1 {
finalParams[actualArgName] = "true"
} else {
finalParams[paramArgSides[0]] = paramArgSides[1]
finalParams[actualArgName] = actualArgSides[1]
}
}
@ -101,6 +111,12 @@ func setupCard(a *Apple2, slot int, paramString string) (Card, error) {
return nil, err
}
// Common parameters
traceSS := paramsGetBool(finalParams, "tracess")
if traceSS {
a.io.traceSlot(slot)
}
cardBase, ok := card.(*cardBase)
if err == nil && ok {
cardBase.name = builder.name
@ -139,11 +155,28 @@ func paramsGetPath(params map[string]string, name string) string {
func paramsGetInt(params map[string]string, name string) (int, error) {
value, ok := params[name]
if !ok {
value = "0"
return 0, fmt.Errorf("missing parameter %s", name)
}
return strconv.Atoi(value)
}
// Returns a 1 based array of bools
func paramsGetDIPs(params map[string]string, name string, size int) ([]bool, error) {
value, ok := params[name]
if !ok {
return nil, fmt.Errorf("missing parameter %s", name)
}
if len(value) != 8 {
return nil, fmt.Errorf("DIP switches must be 8 characters long")
}
result := make([]bool, size+1)
for i := 0; i < 8; i++ {
result[i+1] = value[i] == '1'
}
return result, nil
}
func splitConfigurationString(s string, separator rune) []string {
// Split by comma, but not inside quotes
var result []string

View File

@ -29,9 +29,8 @@ type CardThunderClockPlus struct {
func newCardThunderClockPlusBuilder() *cardBuilder {
return &cardBuilder{
name: "ThunderClock+ Card",
description: "Clock card",
defaultParams: &[]paramSpec{},
name: "ThunderClock+ Card",
description: "Clock card",
buildFunc: func(params map[string]string) (Card, error) {
var c CardThunderClockPlus
err := c.loadRomFromResource("<internal>/ThunderclockPlusROM.bin")

View File

@ -16,7 +16,7 @@ type ioC0Page struct {
joysticks JoysticksProvider
mouse MouseProvider
apple2 *Apple2
trace bool
traceMask uint16 // A bit for each 16 softswitches
traceRegistrations bool
panicNotImplemented bool
}
@ -56,7 +56,16 @@ func newIoC0Page(a *Apple2) *ioC0Page {
}
func (p *ioC0Page) setTrace(trace bool) {
p.trace = trace
if trace {
p.traceMask = 0xffff
} else {
p.traceMask = 0x0000
}
}
func (p *ioC0Page) traceSlot(slot int) {
p.traceMask |= 1 << (8 + slot)
fmt.Printf("Slot %v traced %04x\n", slot, p.traceMask)
}
func (p *ioC0Page) setTraceRegistrations(traceRegistrations bool) {
@ -110,11 +119,17 @@ func (p *ioC0Page) setMouseProvider(m MouseProvider) {
p.mouse = m
}
func (p *ioC0Page) isTraced(address uint16) bool {
ss := address & 0xff
return ss != 0xc000 && // Do not trace the spammy keyboard softswitch
(p.traceMask&(1<<(ss>>4))) != 0
}
func (p *ioC0Page) peek(address uint16) uint8 {
pageAddress := uint8(address)
ss := p.softSwitchesR[pageAddress]
if ss == nil {
if p.trace {
if p.isTraced(address) {
fmt.Printf("Unknown softswitch on read to $%04x\n", address)
}
if p.panicNotImplemented {
@ -123,7 +138,7 @@ func (p *ioC0Page) peek(address uint16) uint8 {
return 0
}
value := ss()
if p.trace && address != 0xc000 {
if p.isTraced(address) {
name := p.softSwitchesRName[pageAddress]
fmt.Printf("Softswitch peek on $%04x %v: $%02x\n", address, name, value)
}
@ -134,15 +149,15 @@ func (p *ioC0Page) poke(address uint16, value uint8) {
pageAddress := uint8(address)
ss := p.softSwitchesW[pageAddress]
if ss == nil {
if p.trace {
fmt.Printf("Unknown softswitch on write to $%04x\n", address)
if p.isTraced(address) {
fmt.Printf("Unknown softswitch on write $%02x to $%04x\n", value, address)
}
if p.panicNotImplemented {
panic(fmt.Sprintf("Unknown softswitch on write to $%04x", address))
}
return
}
if p.trace && address != 0xc000 {
if p.isTraced(address) {
name := p.softSwitchesWName[pageAddress]
fmt.Printf("Softswitch poke on $%04x %v with $%02x\n", address, name, value)
}