Skip to content

Commit

Permalink
Support for 13 sectors disks
Browse files Browse the repository at this point in the history
  • Loading branch information
ivanizag committed Jul 21, 2024
1 parent ad720f0 commit 20e18df
Show file tree
Hide file tree
Showing 23 changed files with 212 additions and 60 deletions.
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ Portable emulator of an Apple II+ or //e. Written in Go.
- DSK
- PO
- [WOZ 1.0 or 2.0](storage/WozSupportStatus.md) (read only)
- 13 Sector 5 1/4 diskettes. Uncompressed or compressed witth gzip or zip. Supported formats:
- NIB (read only)
- [WOZ 2.0](storage/WozSupportStatus.md) (read only)
- 3.5 disks in PO or 2MG format
- Hard disk in HDV or 2MG format with ProDOS and SmartPort support
- Emulated extension cards:
Expand Down Expand Up @@ -225,6 +228,7 @@ The available pre-configured models are:
2enh: Apple //e
2plus: Apple ][+
base64a: Base 64A
dos32: Apple ][+ with 13 sectors disk adapter and DOS 3.2x
swyft: swyft
The available cards are:
Expand Down
29 changes: 24 additions & 5 deletions cardDisk2.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ NIB: 35 tracks 6656 bytes, 232960 bytes
// CardDisk2 is a DiskII interface card
type CardDisk2 struct {
cardBase
sectors13 bool

selected int // q5, Only 0 and 1 supported
power bool // q4
drive [2]cardDisk2Drive
Expand Down Expand Up @@ -57,20 +59,22 @@ func newCardDisk2Builder() *cardBuilder {
{"disk2", "Diskette image for drive 2", ""},
{"tracktracer", "Trace how the disk head moves between tracks", "false"},
{"fast", "Enable CPU burst when accessing the disk", "true"},
{"sectors13", "Use 13 sectors per track ROM", "false"},
},
buildFunc: func(params map[string]string) (Card, error) {
var c CardDisk2
err := c.loadRomFromResource("<internal>/DISK2.rom", cardRomSimple)
if err != nil {
return nil, err
}
c.sectors13 = paramsGetBool(params, "sectors13")

disk1 := paramsGetPath(params, "disk1")
if disk1 != "" {
err := c.drive[0].insertDiskette(disk1)
if err != nil {
return nil, err
}
if c.drive[0].diskette.Is13Sectors() && !c.sectors13 {
// Auto configure for 13 sectors per track
c.sectors13 = true
}
}
disk2 := paramsGetPath(params, "disk2")
if disk2 != "" {
Expand All @@ -79,6 +83,17 @@ func newCardDisk2Builder() *cardBuilder {
return nil, err
}
}

P5RomFile := "<internal>/Apple Disk II 16 Sector Interface Card ROM P5 - 341-0027.bin"
if c.sectors13 {
P5RomFile = "<internal>/Apple Disk II 13 Sector Interface Card ROM P5 - 341-0009.bin"
}

err := c.loadRomFromResource(P5RomFile, cardRomSimple)
if err != nil {
return nil, err
}

trackTracer := paramsGetBool(params, "tracktracer")
if trackTracer {
c.trackTracer = makeTrackTracerLogger()
Expand All @@ -92,7 +107,11 @@ func newCardDisk2Builder() *cardBuilder {
// GetInfo returns smartPort info
func (c *CardDisk2) GetInfo() map[string]string {
info := make(map[string]string)
info["rom"] = "16 sector"
if c.sectors13 {
info["rom"] = "13 sector"
} else {
info["rom"] = "16 sector"
}
info["power"] = strconv.FormatBool(c.power)

info["D1 name"] = c.drive[0].name
Expand Down
42 changes: 30 additions & 12 deletions cardDisk2Sequencer.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,9 @@ See:
type CardDisk2Sequencer struct {
cardBase

p6ROM []uint8
sectors13 bool
p6ROM []uint8

q [8]bool // 8-bit latch SN74LS259
register uint8 // 8-bit shift/storage register SN74LS323
sequence uint8 // 4 bits stored in an hex flip-flop SN74LS174
Expand Down Expand Up @@ -66,31 +68,43 @@ func newCardDisk2SequencerBuilder() *cardBuilder {
},
buildFunc: func(params map[string]string) (Card, error) {
var c CardDisk2Sequencer
err := c.loadRomFromResource("<internal>/DISK2.rom", cardRomSimple)
if err != nil {
return nil, err
}

data, _, err := LoadResource("<internal>/DISK2P6.rom")
if err != nil {
return nil, err
}
c.p6ROM = data

disk1 := paramsGetString(params, "disk1")
if disk1 != "" {
err := c.drive[0].insertDiskette(disk1)
if err != nil {
return nil, err
}
c.sectors13 = c.drive[0].data.Info.BootSectorFormat == 2 // Woz 13 sector disk
}

disk2 := paramsGetString(params, "disk2")
if disk2 != "" {
err := c.drive[1].insertDiskette(disk2)
if err != nil {
return nil, err
}
}

P5RomFile := "<internal>/Apple Disk II 16 Sector Interface Card ROM P5 - 341-0027.bin"
P6RomFile := "<internal>/Apple Disk II 16 Sector Interface Card ROM P6 - 341-0028.bin"
if c.sectors13 {
P5RomFile = "<internal>/Apple Disk II 13 Sector Interface Card ROM P5 - 341-0009.bin"
// Buggy sequencer not need for 13 sectors disks to work
//P6RomFile = "<internal>/Apple Disk II 13 Sector Interface Card ROM P6 - 341-0010.bin"
}

err := c.loadRomFromResource(P5RomFile, cardRomSimple)
if err != nil {
return nil, err
}

data, _, err := LoadResource(P6RomFile)
if err != nil {
return nil, err
}
c.p6ROM = data

trackTracer := paramsGetBool(params, "tracktracer")
if trackTracer {
c.trackTracer = makeTrackTracerLogger()
Expand All @@ -103,7 +117,11 @@ func newCardDisk2SequencerBuilder() *cardBuilder {
// GetInfo returns card info
func (c *CardDisk2Sequencer) GetInfo() map[string]string {
info := make(map[string]string)
info["rom"] = "16 sector"
if c.sectors13 {
info["rom"] = "13 sector"
} else {
info["rom"] = "16 sector"
}
// TODO: add drives info
return info
}
Expand Down
3 changes: 0 additions & 3 deletions cardDisk2SequencerDrive.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,6 @@ func (d *cardDisk2SequencerDrive) insertDiskette(filename string) error {
if f.Info.DiskType != 1 {
return errors.New("only 5.25 disks are supported")
}
if f.Info.BootSectorFormat == 2 { // Info not available in WOZ 1.0
return errors.New("woz 13 sector disks are not supported")
}

d.data = f
d.writeProtected = !writeable
Expand Down
4 changes: 4 additions & 0 deletions configs/dos32.cfg
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
name: Apple ][ with 13 sectors disk adapter and DOS 3.2x
parent: 2
s0: multirom,bank=7,basic=0
s6: diskii,sectors13,disk1=<internal>/dos32.nib
8 changes: 6 additions & 2 deletions configuration.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,9 +63,13 @@ func (c *configuration) getHas(key string) (string, bool) {
return value, ok
}

func (c *configuration) has(key string) bool {
_, ok := c.getHas(key)
return ok
}

func (c *configuration) get(key string) string {
key = strings.ToLower(key)
value, ok := c.data[key]
value, ok := c.getHas(key)
if !ok {
// Should not happen
panic(fmt.Errorf("key %s not found", key))
Expand Down
1 change: 1 addition & 0 deletions doc/usage.txt
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ The available pre-configured models are:
2enh: Apple //e
2plus: Apple ][+
base64a: Base 64A
dos32: Apple ][+ with 13 sectors disk adapter and DOS 3.2x
swyft: swyft

The available cards are:
Expand Down
33 changes: 23 additions & 10 deletions e2e_boot_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,17 @@ import (
"testing"
)

func testBoots(t *testing.T, model string, disk string, cycles uint64, banner string, prompt string, col80 bool) {
overrides := newConfiguration()
func testBoots(t *testing.T, model string, disk string, overrides *configuration, cycles uint64, banner string, prompt string, col80 bool) {
if overrides == nil {
overrides = newConfiguration()
}

if disk != "" {
if overrides.has(confS6) {
t.Fatal("Do not set custom slot 6 configuration and custom disk")
}
overrides.set(confS6, "diskii,disk1=\""+disk+"\"")
} else {
} else if !overrides.has(confS6) {
overrides.set(confS6, "empty")
}

Expand All @@ -36,29 +42,36 @@ func testBoots(t *testing.T, model string, disk string, cycles uint64, banner st
}

func TestPlusBoots(t *testing.T) {
testBoots(t, "2plus", "", 200_000, "APPLE ][", "\n]", false)
testBoots(t, "2plus", "", nil, 200_000, "APPLE ][", "\n]", false)
}

func Test2EBoots(t *testing.T) {
testBoots(t, "2e", "", 200_000, "Apple ][", "\n]", false)
testBoots(t, "2e", "", nil, 200_000, "Apple ][", "\n]", false)
}

func Test2EnhancedBoots(t *testing.T) {
testBoots(t, "2enh", "", 200_000, "Apple //e", "\n]", false)
testBoots(t, "2enh", "", nil, 200_000, "Apple //e", "\n]", false)
}

func TestBase64Boots(t *testing.T) {
testBoots(t, "base64a", "", 1_000_000, "BASE 64A", "\n]", false)
testBoots(t, "base64a", "", nil, 1_000_000, "BASE 64A", "\n]", false)
}

func TestPlusDOS32Boots(t *testing.T) {
overrides := newConfiguration()
overrides.set(confS0, "multirom,bank=7,basic=0")
overrides.set(confS6, "diskii,sectors13,disk1=<internal>/dos32.nib")
testBoots(t, "2plus", "", overrides, 100_000_000, "MASTER DISKETTE VERSION 3.2 STANDARD", "\n>", false)
}

func TestPlusDOS33Boots(t *testing.T) {
testBoots(t, "2plus", "<internal>/dos33.dsk", 100_000_000, "DOS VERSION 3.3", "\n]", false)
testBoots(t, "2plus", "<internal>/dos33.dsk", nil, 100_000_000, "DOS VERSION 3.3", "\n]", false)
}

func TestProdDOSBoots(t *testing.T) {
testBoots(t, "2enh", "<internal>/ProDOS_2_4_3.po", 100_000_000, "BITSY BYE", "NEW VOL", false)
testBoots(t, "2enh", "<internal>/ProDOS_2_4_3.po", nil, 100_000_000, "BITSY BYE", "NEW VOL", false)
}

func TestCPM65Boots(t *testing.T) {
testBoots(t, "2enh", "<internal>/cpm65.po", 5_000_000, "CP/M-65 for the Apple II", "\nA>", true)
testBoots(t, "2enh", "<internal>/cpm65.po", nil, 5_000_000, "CP/M-65 for the Apple II", "\nA>", true)
}
6 changes: 3 additions & 3 deletions e2e_woz_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,9 @@ func TestWoz(t *testing.T) {
cycleLimit uint64
expectedTracks []int
}{
// How to being
// DOS 3.2, requires 13 sector disks
{"DOS3.3", all, "DOS 3.3 System Master.woz", 11_000_000, []int{0, 8, 0, 76, 68, 84, 68, 84, 68, 92, 16, 24}},
// How to begin
{"DOS 3.2", all, "DOS 3.2 System Master.woz", 7_000_000, []int{0, 72}},
{"DOS 3.3", all, "DOS 3.3 System Master.woz", 11_000_000, []int{0, 8, 0, 76, 68, 84, 68, 84, 68, 92, 16, 24}},

// Next choices
{"Bouncing Kamungas", all, "Bouncing Kamungas - Disk 1, Side A.woz", 30_000_000, []int{0, 32, 0, 40, 0}},
Expand Down
2 changes: 1 addition & 1 deletion noSlotClockDS1216.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ const (
nscStateEnabled = uint8(2)
)

func newNoSlotClockDS1216(a *Apple2, memory memoryHandler) *noSlotClockDS1216 {
func newNoSlotClockDS1216(_ *Apple2, memory memoryHandler) *noSlotClockDS1216 {
var nsc noSlotClockDS1216
nsc.memory = memory
nsc.state = nscStateDisabled
Expand Down
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
����



�ɈɈˈˈ��



�ɈɈˈ˸=��



�٘٘ۘۘݘ�



�٘٘ۘ۸���



�������



��������



����������P�



����������H�



H(H(H(H(H(H(



H(H(H(H(����



X8X8X8X8 �X8



X8X8X8X8����



hhhhhh



hhhh��xp



xxxx-xp



xxxx
Expand Down
File renamed without changes.
File renamed without changes.
1 change: 1 addition & 0 deletions resources/dos32.nib

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion softSwitches2.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ func buildNotImplementedSoftSwitchR(io *ioC0Page) softSwitchR {
}
}

func buildNotImplementedSoftSwitchW(io *ioC0Page) softSwitchW {
func buildNotImplementedSoftSwitchW(_ *ioC0Page) softSwitchW {
return func(uint8) {
// Do nothing
}
Expand Down
2 changes: 1 addition & 1 deletion storage/WozSupportStatus.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
## With the sequencer:
- How to begin
- DOS 3.3: Works
- DOS 3.2: **Unknown, 13 sector disks boot not supported**
- DOS 3.2: Works with 13 sectors ROM
- Next choices
- Bouncing Kamungas: Working
- Commando: Working
Expand Down
Loading

0 comments on commit 20e18df

Please sign in to comment.