Move slots and Status SmartPort call

This commit is contained in:
Ivan Izaguirre 2020-08-12 22:50:40 +02:00
parent 986172516f
commit 79a584fb95
3 changed files with 46 additions and 14 deletions

View File

@ -56,6 +56,18 @@ Portable emulator of an Apple II+ or //e. Written in Go.
- Pause (thanks a2geek) - Pause (thanks a2geek)
- ProDOS MLI calls tracing - ProDOS MLI calls tracing
By default the following configuration is launched:
- Enhanced Apple //e with 65c02 processor
- RAMworks card with 80 column, RGB (with Video7 modes) and 8Gb RAM is aux slot
- Memory Expansion card with 1Gb in slot 1
- VidHD card (SHR support) in slot 2
- FASTChip Accelerator card in slot 3
- ThunderClock Plus card in slot 4
- SmartPort card with 1 device in slot 5 (if an image is provided with -disk35)
- DiskII controller card in slot 6
- SmartPort card with 1 device in slot 7 (if an image is provided with -hd)
## Running the emulator ## Running the emulator
No installation required. [Download](https://github.com/ivanizag/apple2/releases) the single file executable `apple2xxx_xxx` for linux or Mac, SDL2 graphics or console. Build from source to get the latest features. No installation required. [Download](https://github.com/ivanizag/apple2/releases) the single file executable `apple2xxx_xxx` for linux or Mac, SDL2 graphics or console. Build from source to get the latest features.
@ -174,7 +186,7 @@ Only valid on SDL mode
-languageCardSlot int -languageCardSlot int
slot for the 16kb language card. -1 for none slot for the 16kb language card. -1 for none
-memoryExpSlot int -memoryExpSlot int
slot for the Memory Expansion card with 1GB. -1 for none (default 4) slot for the Memory Expansion card with 1GB. -1 for none (default 1)
-mhz float -mhz float
cpu speed in Mhz, use 0 for full speed. Use F5 to toggle. (default 1.0227142857142857) cpu speed in Mhz, use 0 for full speed. Use F5 to toggle. (default 1.0227142857142857)
-model string -model string
@ -194,7 +206,7 @@ Only valid on SDL mode
-saturnCardSlot int -saturnCardSlot int
slot for the 256kb Saturn card. -1 for none (default -1) slot for the 256kb Saturn card. -1 for none (default -1)
-thunderClockCardSlot int -thunderClockCardSlot int
slot for the ThunderClock Plus card. -1 for none (default 5) slot for the ThunderClock Plus card. -1 for none (default 4)
-traceCpu -traceCpu
dump to the console the CPU execution. Use F11 to toggle. dump to the console the CPU execution. Use F11 to toggle.
-traceHD -traceHD

View File

@ -71,7 +71,7 @@ func MainApple() *Apple2 {
"slot for the FASTChip accelerator card, -1 for none") "slot for the FASTChip accelerator card, -1 for none")
memoryExpansionCardSlot := flag.Int( memoryExpansionCardSlot := flag.Int(
"memoryExpSlot", "memoryExpSlot",
4, 1,
"slot for the Memory Expansion card with 1GB. -1 for none") "slot for the Memory Expansion card with 1GB. -1 for none")
ramWorksKb := flag.Int( ramWorksKb := flag.Int(
"ramworks", "ramworks",
@ -79,7 +79,7 @@ func MainApple() *Apple2 {
"memory to use with RAMWorks card, 0 for no card, max is 16384") "memory to use with RAMWorks card, 0 for no card, max is 16384")
thunderClockCardSlot := flag.Int( thunderClockCardSlot := flag.Int(
"thunderClockCardSlot", "thunderClockCardSlot",
5, 4,
"slot for the ThunderClock Plus card. -1 for none") "slot for the ThunderClock Plus card. -1 for none")
mono := flag.Bool( mono := flag.Bool(
"mono", "mono",
@ -247,10 +247,6 @@ func MainApple() *Apple2 {
if err != nil { if err != nil {
panic(err) panic(err)
} }
if *fastChipCardSlot == 5 {
// Don't use fastChipCard if the slot 5 is already in use
*fastChipCardSlot = 0
}
} }
if *fastChipCardSlot >= 0 { if *fastChipCardSlot >= 0 {

View File

@ -9,6 +9,7 @@ See:
Beneath Prodos, section 6-6, 7-13 and 5-8. (http://www.apple-iigs.info/doc/fichiers/beneathprodos.pdf) Beneath Prodos, section 6-6, 7-13 and 5-8. (http://www.apple-iigs.info/doc/fichiers/beneathprodos.pdf)
Apple IIc Technical Reference, 2nd Edition. Chapter 8. https://ia800207.us.archive.org/19/items/AppleIIcTechnicalReference2ndEd/Apple%20IIc%20Technical%20Reference%202nd%20ed.pdf Apple IIc Technical Reference, 2nd Edition. Chapter 8. https://ia800207.us.archive.org/19/items/AppleIIcTechnicalReference2ndEd/Apple%20IIc%20Technical%20Reference%202nd%20ed.pdf
https://prodos8.com/docs/technote/21/ https://prodos8.com/docs/technote/21/
https://prodos8.com/docs/technote/20/
*/ */
@ -29,8 +30,7 @@ func buildHardDiskRom(slot int) []uint8 {
0xa9, 0x20, // LDA #$20 0xa9, 0x20, // LDA #$20
0xa9, 0x00, // LDA #$00 0xa9, 0x00, // LDA #$00
0xa9, 0x03, // LDA #$03 0xa9, 0x03, // LDA #$03
0xa9, 0x3c, // LDA #$3c 0xa9, 0x00, // LDA #$00
// Alternate: 0xa9, 0x00, // LDA #$00 ; Not a Smartport device, but won't boot on ii+ ROM
// Boot code: SS will load block 0 in address $0800. The jump there. // Boot code: SS will load block 0 in address $0800. The jump there.
// Note: after execution the first block expects $42 to $47 to have // Note: after execution the first block expects $42 to $47 to have
@ -50,6 +50,12 @@ func buildHardDiskRom(slot int) []uint8 {
0x4c, 0x01, 0x08, // JMP $801 ; Jump to loaded boot sector 0x4c, 0x01, 0x08, // JMP $801 ; Jump to loaded boot sector
}) })
if slot == 7 {
// It should be 0 for SmartPort, but with 0 it's not bootable with the II+ ROM
// See http://www.1000bit.it/support/manuali/apple/technotes/udsk/tn.udsk.2.html
data[0x07] = 0x3c
}
// Entrypoints and Smartport body // Entrypoints and Smartport body
copy(data[0x40:], []uint8{ copy(data[0x40:], []uint8{
0x4c, 0x80, 0xc0 + uint8(slot), // JMP $cs80 ; Prodos Entrypoint 0x4c, 0x80, 0xc0 + uint8(slot), // JMP $cs80 ; Prodos Entrypoint
@ -115,12 +121,12 @@ func (c *cardHardDisk) assign(a *Apple2, slot int) {
address := uint16(a.mmu.Peek(0x44)) + uint16(a.mmu.Peek(0x45))<<8 address := uint16(a.mmu.Peek(0x44)) + uint16(a.mmu.Peek(0x45))<<8
block := uint16(a.mmu.Peek(0x46)) + uint16(a.mmu.Peek(0x47))<<8 block := uint16(a.mmu.Peek(0x46)) + uint16(a.mmu.Peek(0x47))<<8
if c.trace { if c.trace {
fmt.Printf("[CardHardDisk] Prodos command %v on unit $%x, block %v to $%x.\n", command, unit, block, address) fmt.Printf("[CardHardDisk] Prodos command %v on slot %v, unit $%x, block %v to $%x.\n", command, slot, unit, block, address)
} }
switch command { switch command {
case proDosDeviceCommandStatus: case proDosDeviceCommandStatus:
return proDosDeviceNoError return c.status(unit, address)
case proDosDeviceCommandRead: case proDosDeviceCommandRead:
return c.readBlock(block, address) return c.readBlock(block, address)
case proDosDeviceCommandWrite: case proDosDeviceCommandWrite:
@ -147,12 +153,12 @@ func (c *cardHardDisk) assign(a *Apple2, slot int) {
address := uint16(a.mmu.Peek(paramsAddress+2)) + uint16(a.mmu.Peek(paramsAddress+3))<<8 address := uint16(a.mmu.Peek(paramsAddress+2)) + uint16(a.mmu.Peek(paramsAddress+3))<<8
block := uint16(a.mmu.Peek(paramsAddress+4)) + uint16(a.mmu.Peek(paramsAddress+5))<<8 block := uint16(a.mmu.Peek(paramsAddress+4)) + uint16(a.mmu.Peek(paramsAddress+5))<<8
if c.trace { if c.trace {
fmt.Printf("[CardHardDisk] Smart port command %v on unit $%x, block %v to $%x.\n", command, unit, block, address) fmt.Printf("[CardHardDisk] Smart port command %v on slot %v, unit $%x, block %v to $%x.\n", command, slot, unit, block, address)
} }
switch command { switch command {
case proDosDeviceCommandStatus: case proDosDeviceCommandStatus:
return proDosDeviceNoError return c.status(unit, address)
case proDosDeviceCommandRead: case proDosDeviceCommandRead:
return c.readBlock(block, address) return c.readBlock(block, address)
case proDosDeviceCommandWrite: case proDosDeviceCommandWrite:
@ -218,6 +224,24 @@ func (c *cardHardDisk) writeBlock(block uint16, source uint16) uint8 {
return proDosDeviceNoError return proDosDeviceNoError
} }
func (c *cardHardDisk) status(unit uint8, dest uint16) uint8 {
if c.trace {
fmt.Printf("[CardHardDisk] Status for %v into $%x.\n", unit, dest)
}
// See http://www.1000bit.it/support/manuali/apple/technotes/smpt/tn.smpt.2.html
c.a.mmu.Poke(dest+0, 0x02) // One device
c.a.mmu.Poke(dest+1, 0xff) // No interrupt
c.a.mmu.Poke(dest+2, 0x00)
c.a.mmu.Poke(dest+3, 0x00) // Unknown manufacturer
c.a.mmu.Poke(dest+4, 0x01)
c.a.mmu.Poke(dest+5, 0x00) // Versión 1.0 final
c.a.mmu.Poke(dest+6, 0x00)
c.a.mmu.Poke(dest+7, 0x00) // Reserved
return proDosDeviceNoError
}
func (c *cardHardDisk) addDisk(disk *blockDisk) { func (c *cardHardDisk) addDisk(disk *blockDisk) {
c.disk = disk c.disk = disk
} }