diff --git a/cardBuilder.go b/cardBuilder.go index 41a4702..7fc5039 100644 --- a/cardBuilder.go +++ b/cardBuilder.go @@ -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 diff --git a/cardThunderClockPlus.go b/cardThunderClockPlus.go index b99aa13..43e2918 100644 --- a/cardThunderClockPlus.go +++ b/cardThunderClockPlus.go @@ -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("/ThunderclockPlusROM.bin") diff --git a/ioC0Page.go b/ioC0Page.go index 514c6aa..13d0416 100644 --- a/ioC0Page.go +++ b/ioC0Page.go @@ -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) }