mirror of
https://github.com/AppleWin/AppleWin.git
synced 2024-12-21 17:31:23 +00:00
Added new SmartPort Harddisk Controller (HDC) firmware for Enhanced //e. (@burniouf) . remove the old DOSMaster entrypoints. . firmware ID byte (at $FE) defaults to 4 ProDOS block devices (was 2 with older v2 f/w). Enhanced //e defaults to using SP f/w, and older Apple II's still use the older v2 f/w. Support up to 8 units per HDC (currently limited to 4GiB capacity for each unit). Save-state: save HDC firmware in state file. New slot-specific switches to configure each HDC's firmware: -s<N> -hdc-[sp|bm2|bm4]. New switch to select old non-SP firmware for all HDCs: -hdc-firmware-v2.
This commit is contained in:
parent
72f0c03981
commit
b371e3436f
@ -90,6 +90,7 @@
|
||||
<ClInclude Include="source\LanguageCard.h" />
|
||||
<ClInclude Include="source\Log.h" />
|
||||
<ClInclude Include="source\Memory.h" />
|
||||
<ClInclude Include="source\MemoryDefs.h" />
|
||||
<ClInclude Include="source\Mockingboard.h" />
|
||||
<ClInclude Include="source\MockingboardCardManager.h" />
|
||||
<ClInclude Include="source\MockingboardDefs.h" />
|
||||
|
@ -618,6 +618,9 @@
|
||||
<ClInclude Include="source\MockingboardDefs.h">
|
||||
<Filter>Source Files\Emulator</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="source\MemoryDefs.h">
|
||||
<Filter>Source Files\Emulator</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Image Include="resource\Applewin.bmp">
|
||||
|
379
firmware/HDD-SmartPort/HDC-SmartPort.a65
Normal file
379
firmware/HDD-SmartPort/HDC-SmartPort.a65
Normal file
@ -0,0 +1,379 @@
|
||||
;--------------------------------------
|
||||
;AppleWin : An Apple //e emulator for Windows
|
||||
;
|
||||
;Copyright (C) 1994-1996, Michael O'Brien
|
||||
;Copyright (C) 1999-2001, Oliver Schmidt
|
||||
;Copyright (C) 2002-2005, Tom Charlesworth
|
||||
;Copyright (C) 2006-2024, Tom Charlesworth, Michael Pohoreski
|
||||
;
|
||||
;AppleWin is free software; you can redistribute it and/or modify
|
||||
;it under the terms of the GNU General Public License as published by
|
||||
;the Free Software Foundation; either version 2 of the License, or
|
||||
;(at your option) any later version.
|
||||
;
|
||||
;AppleWin is distributed in the hope that it will be useful,
|
||||
;but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
;MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
;GNU General Public License for more details.
|
||||
;
|
||||
;You should have received a copy of the GNU General Public License
|
||||
;along with AppleWin; if not, write to the Free Software
|
||||
;Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
;
|
||||
|
||||
; Description: SmartPort firmware for Hard Disk Controller card
|
||||
;
|
||||
; Author: Copyright (c) 2024, Rémy Gibert
|
||||
; . derived from works: Copyright (c) 2005, Robert Hoem
|
||||
;
|
||||
|
||||
;--------------------------------------
|
||||
!cpu 6502 ; Compatible with all Apple2's
|
||||
!to "HDC-SmartPort.bin", plain
|
||||
!sl "HDC-SmartPort.labels"
|
||||
;--------------------------------------
|
||||
!src "IO_Apple.inc"
|
||||
!src "IO_Applewin.inc"
|
||||
!src "MON.inc"
|
||||
!src "ProDOS.inc"
|
||||
;--------------------------------------
|
||||
; SP commands
|
||||
;--------------------------------------
|
||||
SP_Cmd_status = $00
|
||||
SP_Cmd_status_STATUS = $00
|
||||
SP_Cmd_status_GETDCB = $01
|
||||
SP_Cmd_status_GETNL = $02
|
||||
SP_Cmd_status_GETDIB = $03
|
||||
SP_Cmd_readblock = $01
|
||||
SP_Cmd_writeblock = $02
|
||||
SP_Cmd_format = $03
|
||||
SP_Cmd_control = $04
|
||||
SP_Cmd_init = $05
|
||||
SP_Cmd_open = $06
|
||||
SP_Cmd_close = $07
|
||||
SP_Cmd_read = $08
|
||||
SP_Cmd_write = $09
|
||||
|
||||
SP_Cmd_extended = $40
|
||||
;--------------------------------------
|
||||
; ZP locations
|
||||
;--------------------------------------
|
||||
Ptr1 = $3C
|
||||
|
||||
BLK_Cmd = $42
|
||||
BLK_Cmd_Status = $0
|
||||
BLK_Cmd_Read = $1
|
||||
BLK_Cmd_Write = $2
|
||||
BLK_Cmd_Format = $3
|
||||
|
||||
BLK_UnitNum = $43
|
||||
BLK_MemPtr = $44
|
||||
BLK_BlockNum = $46
|
||||
;--------------------------------------
|
||||
; Screen holes (scratch space)
|
||||
;--------------------------------------
|
||||
Slot_n0 = $478
|
||||
|
||||
; = $4F8
|
||||
; = $578
|
||||
; = $5F8
|
||||
|
||||
; = $678
|
||||
; = $6F8
|
||||
; = $778
|
||||
;Slot_C8 = $7F8 ; IRQ protocol for handling $C800 space properly
|
||||
|
||||
; Screen holes,Cn indexed
|
||||
|
||||
; = $478-$C0
|
||||
; = $4F8-$C0
|
||||
; = $578-$C0
|
||||
; = $5F8-$C0
|
||||
|
||||
; = $678-$C0
|
||||
; = $6F8-$C0
|
||||
; = $778-$C0
|
||||
; = $7F8-$C0
|
||||
|
||||
;--------------------------------------
|
||||
BootBlocklA3 = $800
|
||||
BootBlocklA2 = $801
|
||||
;--------------------------------------
|
||||
; The Autoboot rom will call this.
|
||||
; This is also the entry point for such things as IN#7 and PR#7
|
||||
; Autoboot and ProDOS look at the following few opcodes to detect block devices
|
||||
; NB. $Cn07 should be $00 for a SmartPort Interface, but changing this means that it won't autoboot on ][, ][+ and unenhanced IIe.
|
||||
; . ref: http://www.1000bit.it/support/manuali/apple/technotes/udsk/tn.udsk.2.html
|
||||
;--------------------------------------
|
||||
|
||||
!zone code
|
||||
|
||||
* = $0000 ; org $0000 - position-independent code, so doesn't matter (but the other fixed org positions need to be on the same page)
|
||||
|
||||
|
||||
Cn_start lda #$20
|
||||
lda #$00
|
||||
cmp #$03 ; will set C=0
|
||||
|
||||
lda #$00 ; SP mode
|
||||
; lda #$3C ; BLK mode
|
||||
bcc Cn_Bootstrap
|
||||
|
||||
Cn_Entry_BLK sec ; $Cn0A - BLK entrypoint
|
||||
bcs Cn_Entry
|
||||
|
||||
Cn_Entry_SP clc ; $Cn0D - SmartPort entrypoint
|
||||
|
||||
Cn_Entry php
|
||||
sei ; disable ints, in case an int handler races our $0000/RTS and stack accesses!
|
||||
;--------------------------------------
|
||||
; NB. need RAM that's guaranteed to be both read & writeable:
|
||||
; . can't use $0200-$BFFF, due to eg. RAMRD=0/RAMWRT=1 combination
|
||||
; . can't use LC as ROM might be enabled.
|
||||
; So use ZP (specifically $0000) as whatever the state of ALTZP, both read & write will be to the same physical memory location.
|
||||
;--------------------------------------
|
||||
lda $00 ; save $00
|
||||
ldx #$60 ; opcode RTS
|
||||
stx $00
|
||||
jsr $0000 ; RTS immediately (NB. can't use $FF58, since LC RAM may be switched in)
|
||||
sta $00 ; restore $00
|
||||
|
||||
tsx
|
||||
lda $0100,x ; $Cn
|
||||
asl
|
||||
asl
|
||||
asl
|
||||
asl
|
||||
sta Slot_n0
|
||||
|
||||
plp ; + restore int status
|
||||
bcs Cn_BLK ; C=1: ProDOS mode .....
|
||||
;--------------------------------------
|
||||
; C=0: fall through to SmartPort...
|
||||
;--------------------------------------
|
||||
lda Ptr1 ; X = Stack Ptr from TSX above
|
||||
pha
|
||||
|
||||
lda Ptr1+1
|
||||
pha
|
||||
|
||||
lda $102,x ; jsr LO byte
|
||||
sta Ptr1
|
||||
; clc ; from bcs above
|
||||
adc #3
|
||||
sta $102,x ; jsr LO byte
|
||||
|
||||
lda $103,x ; jsr HI byte
|
||||
sta Ptr1+1
|
||||
adc #0
|
||||
sta $103,x ; jsr HI byte
|
||||
|
||||
ldy #1 ; CMD byte
|
||||
bne Cn_SP ; Always
|
||||
;--------------------------------------
|
||||
Cn_Sloop jmp MON_SLOOP
|
||||
;--------------------------------------
|
||||
Cn_Bootstrap bit IO_IIE_OPENAPPLE
|
||||
bmi Cn_Sloop
|
||||
|
||||
jsr MON_RTS ; ROM supposed to be enabled at BOOT time or PR#7
|
||||
|
||||
tsx
|
||||
lda $0100,x ; $Cn
|
||||
asl
|
||||
asl
|
||||
asl
|
||||
asl
|
||||
sta Slot_n0
|
||||
|
||||
; Lets check to see if there's an image ready
|
||||
; Slot n, disk 1
|
||||
|
||||
tax ; A=%0SSS0000
|
||||
sta IO_Unitnum,x ; b7=0 (and b6:4=SSS) => disk 1
|
||||
|
||||
lda #BLK_Cmd_Status
|
||||
sta IO_Command,x
|
||||
|
||||
lda IO_Execute,x ; Post: A=STATUS (BLK_Cmd_Status completes immediately, no need to check STATUS.b7 busy bit)
|
||||
; on error A = 0eeeeee1, where eeeeee = Standard ProDOS error codes (see ProDOS.inc)
|
||||
|
||||
lsr ; Post: C=0 or 1
|
||||
bcs Cn_Sloop ; no image ready, boot Slot n-1 image instead
|
||||
;--------------------------------------
|
||||
; image ready. Lets boot from it.
|
||||
; we want to load block 1 from disk 1 to $800 then jump there
|
||||
; Pre: X = Slot# << 4
|
||||
;--------------------------------------
|
||||
lda #$1
|
||||
sta BLK_Cmd
|
||||
stx BLK_UnitNum ; DSSS0000, where D=0 (ie. disk 1)
|
||||
lda #$0
|
||||
sta BLK_MemPtr
|
||||
sta BLK_BlockNum
|
||||
sta BLK_BlockNum+1
|
||||
lda #$8
|
||||
sta BLK_MemPtr+1
|
||||
|
||||
; clc ; C = 0 from bcs Cn_Sloop
|
||||
|
||||
;--------------------------------------
|
||||
; entry point for BLK driver
|
||||
; simple really. Copy the command from BLK_Cmd..BLK_BlockNum+1
|
||||
; to our I/O ports then execute command
|
||||
|
||||
; Pre:
|
||||
; X = Slot# << 4
|
||||
; C = 0 from Cn_Bootstrap
|
||||
; C = 1 from Cn_Entry_BLK
|
||||
; Post:
|
||||
; C = IO_Status b0
|
||||
; A = result of IO_Execute
|
||||
; Read or write command
|
||||
; X = Slot# << 4
|
||||
; Y = command
|
||||
; Status command
|
||||
; X = low byte of disk size
|
||||
; Y = high byte of disk size
|
||||
;--------------------------------------
|
||||
Cn_BLK php
|
||||
|
||||
ldx Slot_n0
|
||||
|
||||
ldy #0
|
||||
|
||||
- lda BLK_Cmd,y
|
||||
sta IO_BlkCmdFifo,x ; BLK_Cmd's are $0x
|
||||
iny ; BLK_UnitNum's are DSSS0000 : if SSS does NOT match physical slot...
|
||||
; ...hardware should handle the remap by adding +2 to the REAL dev_ID
|
||||
cpy #6 ; that way, a BLK controller can support 4 devices (see $CnFE byte below)
|
||||
bcc -
|
||||
|
||||
- lda IO_Execute,x ; A = result of IO_Execute (NB. instantaneous 512 byte r/w!)
|
||||
bmi - ; b7=busy doing DMA?
|
||||
|
||||
plp ; restore C
|
||||
bcs Cn_BLK_Done ; from Cn_Entry_BLK
|
||||
|
||||
lsr ; Post: C=0 or 1
|
||||
bcs Cn_Sloop ; Boot Failed....
|
||||
|
||||
jmp BootBlocklA2 ; Success, run $801 BOOT code for Apple ][ (not /// at $800)
|
||||
|
||||
Cn_BLK_Done lsr ; Post: C=0 or 1
|
||||
|
||||
ldy BLK_Cmd ; Was it status ?
|
||||
bne + ; no, go home
|
||||
|
||||
pha ; Save result
|
||||
ldy IO_Imgsizehi,x ; Get high byte of size
|
||||
lda IO_Imgsizelo,x ; Get low byte of size
|
||||
tax ; Transfer into X
|
||||
pla ; Get back status call result
|
||||
|
||||
+ rts
|
||||
;--------------------------------------
|
||||
Cn_SP lda (Ptr1),y ; CMD byte
|
||||
|
||||
cmp #SP_Cmd_format
|
||||
bcs Cn_SP_E_BADCALL ; only STATUS, READBLOCK & WRITEBLOCK supported
|
||||
|
||||
ldx Slot_n0
|
||||
|
||||
sta IO_SPCmdFifo,x ; Smartport calls = $8x (OR'd with $80 by h/w), Statuscode written at IO_StatusCode
|
||||
|
||||
iny ; param LO
|
||||
lda (Ptr1),y
|
||||
pha
|
||||
|
||||
iny ; param HI
|
||||
lda (Ptr1),y
|
||||
|
||||
sta Ptr1+1
|
||||
pla
|
||||
sta Ptr1 ; Now Ptr1 = Param list
|
||||
|
||||
ldy #0 ; Param Cnt
|
||||
|
||||
lda (Ptr1),y
|
||||
cmp #3 ; STATUS, READBLOCK & WRITEBLOCK = all 3 parameters
|
||||
sec
|
||||
bne Cn_SP_E_BADCNT
|
||||
|
||||
- iny ; UnitNum (B), MemPtr (L/H), DiskBlock (L/M/H) -> IO (R,W)
|
||||
lda (Ptr1),y ; UnitNum (B), MemPtr (L/H), StatusCode (B) -> IO (S)
|
||||
sta IO_SPCmdFifo,x ; UnitNum Range is 0 (smartport controller itself), 1,2,3.....
|
||||
cpy #6 ; blockNums are 24-bit for SP calls
|
||||
bcc -
|
||||
|
||||
- lda IO_Execute,x ; A = result of IO_Execute (NB. instantaneous 512 byte r/w!)
|
||||
bmi - ; b7=busy doing DMA?
|
||||
|
||||
lsr ; get C=1 & A = ERROR CODE ... or C=0 & A = 0
|
||||
|
||||
tax ; Save Error Code
|
||||
|
||||
!byte $2C ; BIT ABS
|
||||
|
||||
Cn_SP_E_BADCALL ldx #E_BADCALL
|
||||
|
||||
!byte $2C ; BIT ABS
|
||||
|
||||
Cn_SP_E_BADCNT ldx #E_BADCNT
|
||||
|
||||
pla
|
||||
sta Ptr1+1
|
||||
|
||||
pla
|
||||
sta Ptr1
|
||||
|
||||
txa ; Restore Error Code
|
||||
|
||||
ldx #0
|
||||
ldy #2 ; exit returning YX = $0200 bytes transferred if success
|
||||
|
||||
rts ; or C=1 & A=ERROR CODE
|
||||
;--------------------------------------
|
||||
|
||||
!zone data
|
||||
|
||||
;--------------------------------------
|
||||
; datablock. This starts near the end of the firmware (at offset $CnFB)
|
||||
;
|
||||
; $CnFB :
|
||||
; 7 : 1 = Support Extended commands
|
||||
; 6 : [Reserved]
|
||||
; 5 : [Reserved]
|
||||
; 4 : [Reserved]
|
||||
; 3 : [Reserved]
|
||||
; 2 : [Reserved]
|
||||
; 1 : 1 = Supports SCSI devices (Helps ProDOS build SP device list)
|
||||
; 0 : 1 = Supports RAMDisk Card
|
||||
;
|
||||
; $CnFC/D : size in blocks (BLK) if $0000 Software must issue a BLK Status Call to get size in blocks
|
||||
;
|
||||
; $CnFE = status bits (BAP p7-14)
|
||||
; 7 = medium is removable
|
||||
; 6 = device is interruptable
|
||||
; 5-4 = number of volumes (0..3 means 1..4)
|
||||
; 3 = device supports Format call
|
||||
; 2 = device can be written to
|
||||
; 1 = device can be read from (must be 1)
|
||||
; 0 = device status can be read (must be 1)
|
||||
;
|
||||
; $C7 = Removable, Interruptable, #Volumes=1, Supports write/read/status
|
||||
; $D7 = Removable, Interruptable, #Volumes=2, Supports write/read/status
|
||||
; $F7 = Removable, Interruptable, #Volumes=4, Supports write/read/status
|
||||
; $BF = Removable, Interruptable, #Volumes=4, Supports format/write/read/status (KEGS / IIGS)
|
||||
;
|
||||
; $CnFF = offset to BLK entry point
|
||||
;--------------------------------------
|
||||
@checkCsFB
|
||||
*= $00FB ; org $00FB
|
||||
!warn "CsFB padding = ", * - @checkCsFB
|
||||
;--------------------------------------
|
||||
!byte $00 ; Smart port ID Type byte
|
||||
!word $0000 ; how many blocks are on the device. Zero means use status call
|
||||
!byte $F7 ; specifics about the device (number of drives, read/write/format capability, etc)
|
||||
!byte <Cn_Entry_BLK ; entry point offset for ProDOS (must be $0a)
|
||||
;--------------------------------------
|
BIN
firmware/HDD-SmartPort/HDC-SmartPort.bin
Normal file
BIN
firmware/HDD-SmartPort/HDC-SmartPort.bin
Normal file
Binary file not shown.
31
firmware/HDD-SmartPort/IO_Apple.inc
Normal file
31
firmware/HDD-SmartPort/IO_Apple.inc
Normal file
@ -0,0 +1,31 @@
|
||||
;--------------------------------------
|
||||
; All ][
|
||||
;--------------------------------------
|
||||
IO_KBD = $C000 ; R
|
||||
IO_KBDSTROBE = $C010 ; W
|
||||
|
||||
IO_CLRPAGE2 = $C054 ; W
|
||||
IO_SETPAGE2 = $C055 ; W
|
||||
|
||||
IO_RROMBNK2 = $C082 ; R
|
||||
;--------------------------------------
|
||||
; IIe Specific
|
||||
;--------------------------------------
|
||||
IO_IIE_CLR80STORE = $C000 ; W
|
||||
IO_IIE_SET80STORE = $C001 ; W
|
||||
IO_IIE_CLR80DISP = $C00C ; W
|
||||
IO_IIE_SET80DISP = $C00D ; W
|
||||
IO_IIE_CLRALTCHAR = $C00E ; W
|
||||
IO_IIE_SETALTCHAR = $C00F ; W
|
||||
|
||||
IO_IIE_RD80STORE = $C018 ; R
|
||||
IO_IIE_RDALTCHAR = $C01E ; R
|
||||
IO_IIE_RD80DISP = $C01F ; R
|
||||
|
||||
IO_IIE_OPENAPPLE = $C061 ; R
|
||||
IO_IIE_SOLIDAPPLE = $C062 ; R
|
||||
;--------------------------------------
|
||||
; IIgs Specific
|
||||
;--------------------------------------
|
||||
IO_IIGS_DMAREG = $00C037 ; R,W
|
||||
;--------------------------------------
|
33
firmware/HDD-SmartPort/IO_AppleWin.inc
Normal file
33
firmware/HDD-SmartPort/IO_AppleWin.inc
Normal file
@ -0,0 +1,33 @@
|
||||
;--------------------------------------
|
||||
; Applewin HD Controller IOs
|
||||
;--------------------------------------
|
||||
IO_Execute = $c080 ; R : Execute command & return IO_Status. Then on subsequent IO_Execute reads just return IO_Status
|
||||
IO_Status = $c081 ; R : b7=busy, b6..b1=ProDOS error code, b0=error
|
||||
;--------------------------------------
|
||||
IO_Command = $c082 ; W : BLK = $00 status, $01 read, $02 write. SP = $80 status, $81 read, $82 write,
|
||||
IO_Unitnum = $c083 ; W : BLK = DSSS0000 if SSS != n from CnXX, add 2 to D (4 drives support). SP = $00,$01.....
|
||||
IO_MemPtr = $c084 ; W : 16-bit values
|
||||
;IO_MemPtrH = $c085 ; W
|
||||
;--------------------------------------
|
||||
IO_StatusCode = $c086 ; W : write SP status code $00, $03
|
||||
;(see HDC-SmartPort.a65 : SP_Commands)
|
||||
;--------------------------------------
|
||||
IO_BlockNum = $c086 ; W : BLK = 16-bit values. SP = 24-bit values, see below
|
||||
;IO_BlockNumM = $c087 ; W
|
||||
;IO_BlockNumH = $c088 ; W : 3rd byte for SP 24-bit blocknum
|
||||
;--------------------------------------
|
||||
IO_Nextbyte = $c088 ; R : legacy read-only port (still supported by AppleWin)
|
||||
IO_Imgsizelo = $c089 ; R
|
||||
IO_Imgsizehi = $c08a ; R
|
||||
;--------------------------------------
|
||||
IO_BlkCmdFifo = $c089 ; W : a 6-deep FIFO to write: command, unitNum, memPtr(2), blockNum(2)
|
||||
IO_SPCmdFifo = $c08a ; W : a 7-deep FIFO to write: command, unitNum, memPtr(2), blockNum(3); first byte gets OR'd with $80 (ie. to indicate it's an SP command)
|
||||
;--------------------------------------
|
||||
; Notes on accesses to I/O registers:
|
||||
; . ROR ABS16,X and ROL ABS16,X - only used for $C081+s*$10 STATUS register:
|
||||
; 6502: double read (old data), write (old data), write (new data). The writes are harmless as writes to STATUS are ignored.
|
||||
; 65C02: double read (old data), write (new data). The write is harmless as writes to STATUS are ignored.
|
||||
; . STA ABS16,X does a false-read. This is harmless for writable I/O registers, since the false-read has no side effect.
|
||||
;--------------------------------------
|
||||
|
||||
|
26
firmware/HDD-SmartPort/MON.inc
Normal file
26
firmware/HDD-SmartPort/MON.inc
Normal file
@ -0,0 +1,26 @@
|
||||
;--------------------------------------
|
||||
CH = $24 ; CURSOR HORIZONTAL
|
||||
CV = $25 ; CURSOR VERTICAL
|
||||
|
||||
BASL = $28 ; TEXT BASE LOW
|
||||
BASH = $29 ; TEXT BASE HIGH
|
||||
|
||||
INVFLG = $32 ; NORMAL/INVERSE /FLASH (FF,7F,3F)
|
||||
;--------------------------------------
|
||||
MON_POWERUP = $3F2
|
||||
MON_POWERUPBYTE = $3F4
|
||||
;--------------------------------------
|
||||
MON_SLOOP = $FABA
|
||||
MON_SETTXT = $FB39
|
||||
MON_HOME = $FC58
|
||||
MON_VTABA = $FC24
|
||||
MON_CR = $FC62
|
||||
MON_CROUT = $FD8E
|
||||
MON_PRBYTE = $FDDA
|
||||
MON_COUT = $FDED
|
||||
MON_INVERSE = $FE80
|
||||
MON_NORM = $FE84
|
||||
MON_IN0 = $FE89
|
||||
MON_PR0 = $FE93
|
||||
MON_RTS = $FF58
|
||||
;--------------------------------------
|
19
firmware/HDD-SmartPort/ProDOS.inc
Normal file
19
firmware/HDD-SmartPort/ProDOS.inc
Normal file
@ -0,0 +1,19 @@
|
||||
;--------------------------------------
|
||||
; ProDOS defines
|
||||
;--------------------------------------
|
||||
PRODOS_MAXPATH = 64
|
||||
;--------------------------------------
|
||||
; Error codes
|
||||
;--------------------------------------
|
||||
E_BADCALL = $01 ; Bad Call Number
|
||||
E_BADCNT = $04 ; Bad Parameter Count
|
||||
E_BUSERR = $06 ; Communications Error
|
||||
E_BADCTL = $21 ; Invalid Status Code
|
||||
|
||||
E_IO = $27 ; I/O Error
|
||||
E_NODEV = $28 ; No Device Connected
|
||||
E_WRTPROT = $2B ; Write Protected
|
||||
E_BADBLOCK = $2D ; Invalid Block Number
|
||||
E_DSKSWIT = $2E ; Disk Switched
|
||||
E_OFFLINE = $2F ; Device Offline
|
||||
;--------------------------------------
|
11
firmware/HDD-SmartPort/build.bat
Normal file
11
firmware/HDD-SmartPort/build.bat
Normal file
@ -0,0 +1,11 @@
|
||||
@REM ACME only ever returns 0!
|
||||
acme.exe HDC-SmartPort.a65
|
||||
@IF %ERRORLEVEL% NEQ 0 goto error
|
||||
|
||||
copy HDC-SmartPort.bin ..\..\resource
|
||||
@goto end
|
||||
|
||||
:error
|
||||
@echo "ACME failed"
|
||||
|
||||
:end
|
@ -332,6 +332,7 @@ IDR_DISK2_16SECTOR_FW FIRMWARE "Disk2.rom"
|
||||
IDR_SSC_FW FIRMWARE "SSC.rom"
|
||||
IDR_HDDRVR_FW FIRMWARE "Hddrvr.bin"
|
||||
IDR_HDDRVR_V2_FW FIRMWARE "Hddrvr-v2.bin"
|
||||
IDR_HDC_SMARTPORT_FW FIRMWARE "HDC-SmartPort.bin"
|
||||
IDR_PRINTDRVR_FW FIRMWARE "Parallel.rom"
|
||||
IDR_MOCKINGBOARD_D_FW FIRMWARE "Mockingboard-D.rom"
|
||||
IDR_MOUSEINTERFACE_FW FIRMWARE "MouseInterface.rom"
|
||||
|
BIN
resource/HDC-SmartPort.bin
Normal file
BIN
resource/HDC-SmartPort.bin
Normal file
Binary file not shown.
@ -55,6 +55,7 @@
|
||||
#define IDR_BASE_64A_ROM 153
|
||||
#define IDR_BASE64A_VIDEO_ROM 154
|
||||
#define IDR_HDDRVR_V2_FW 155
|
||||
#define IDR_HDC_SMARTPORT_FW 156
|
||||
#define IDC_KEYB_BUFFER_ENABLE 1005
|
||||
#define IDC_SAVESTATE 1006
|
||||
#define IDC_SAVESTATE_ON_EXIT 1007
|
||||
|
@ -188,6 +188,21 @@ bool ProcessCmdLine(LPSTR lpCmdLine)
|
||||
}
|
||||
if (strcmp(lpCmdLine, "hdc") == 0)
|
||||
g_cmdLine.slotInsert[slot] = CT_GenericHDD;
|
||||
if (strcmp(lpCmdLine, "hdc-sp") == 0)
|
||||
{
|
||||
g_cmdLine.slotInsert[slot] = CT_GenericHDD;
|
||||
g_cmdLine.slotInfo[slot].useHdcFirmwareMode = HdcSmartPort;
|
||||
}
|
||||
if (strcmp(lpCmdLine, "hdc-bm2") == 0)
|
||||
{
|
||||
g_cmdLine.slotInsert[slot] = CT_GenericHDD;
|
||||
g_cmdLine.slotInfo[slot].useHdcFirmwareMode = HdcBlockMode2Devices;
|
||||
}
|
||||
if (strcmp(lpCmdLine, "hdc-bm4") == 0)
|
||||
{
|
||||
g_cmdLine.slotInsert[slot] = CT_GenericHDD;
|
||||
g_cmdLine.slotInfo[slot].useHdcFirmwareMode = HdcBlockMode4Devices;
|
||||
}
|
||||
if (strcmp(lpCmdLine, "saturn") == 0 || strcmp(lpCmdLine, "saturn128") == 0) // Support Saturn128 card in slot 1-7 too (GH#1279)
|
||||
g_cmdLine.slotInsert[slot] = CT_Saturn128K;
|
||||
if (strcmp(lpCmdLine, "megaaudio") == 0)
|
||||
@ -237,11 +252,12 @@ bool ProcessCmdLine(LPSTR lpCmdLine)
|
||||
g_cmdLine.szImageName_drive[slot][drive] = lpCmdLine;
|
||||
}
|
||||
}
|
||||
else if (lpCmdLine[3] == 'h' && (lpCmdLine[4] == '1' || lpCmdLine[4] == '2')) // -s[1..7]h[1|2] <dsk-image>
|
||||
else if (lpCmdLine[3] == 'h' && (lpCmdLine[4] >= '1' || lpCmdLine[4] <= '8')) // -s[1..7]h[1|2|...|8] <dsk-image>
|
||||
{
|
||||
const UINT drive = lpCmdLine[4] == '1' ? HARDDISK_1 : HARDDISK_2;
|
||||
const UINT drive = lpCmdLine[4] - '1';
|
||||
bool badDrive = drive >= NUM_HARDDISKS;
|
||||
|
||||
if (slot != SLOT5 && slot != SLOT7)
|
||||
if (badDrive || (slot != SLOT5 && slot != SLOT7))
|
||||
{
|
||||
LogFileOutput("Unsupported arg: %s\n", lpCmdLine);
|
||||
}
|
||||
@ -641,6 +657,10 @@ bool ProcessCmdLine(LPSTR lpCmdLine)
|
||||
{
|
||||
g_cmdLine.useHdcFirmwareV1 = true;
|
||||
}
|
||||
else if (strcmp(lpCmdLine, "-hdc-firmware-v2") == 0)
|
||||
{
|
||||
g_cmdLine.useHdcFirmwareV2 = true;
|
||||
}
|
||||
else // unsupported
|
||||
{
|
||||
LogFileOutput("Unsupported arg: %s\n", lpCmdLine);
|
||||
|
@ -14,9 +14,11 @@ struct CmdLine
|
||||
SlotInfo()
|
||||
{
|
||||
isDiskII13 = false;
|
||||
useHdcFirmwareMode = HdcDefault;
|
||||
}
|
||||
|
||||
bool isDiskII13;
|
||||
HdcMode useHdcFirmwareMode;
|
||||
};
|
||||
|
||||
CmdLine()
|
||||
@ -35,6 +37,7 @@ struct CmdLine
|
||||
supportExtraMBCardTypes = false;
|
||||
noDisk2StepperDefer = false;
|
||||
useHdcFirmwareV1 = false;
|
||||
useHdcFirmwareV2 = false;
|
||||
szSnapshotName = NULL;
|
||||
szScreenshotFilename = NULL;
|
||||
uHarddiskNumBlocks = 0;
|
||||
@ -80,6 +83,7 @@ struct CmdLine
|
||||
bool supportExtraMBCardTypes;
|
||||
bool noDisk2StepperDefer; // debug
|
||||
bool useHdcFirmwareV1; // debug
|
||||
bool useHdcFirmwareV2;
|
||||
SS_CARDTYPE slotInsert[NUM_SLOTS];
|
||||
SlotInfo slotInfo[NUM_SLOTS];
|
||||
LPCSTR szImageName_drive[NUM_SLOTS][NUM_DRIVES];
|
||||
|
@ -121,8 +121,7 @@ enum AppMode_e
|
||||
#define REGVALUE_GAME_IO_TYPE "Game I/O type"
|
||||
#define REGVALUE_LAST_DISK_1 "Last Disk Image 1"
|
||||
#define REGVALUE_LAST_DISK_2 "Last Disk Image 2"
|
||||
#define REGVALUE_LAST_HARDDISK_1 "Last Harddisk Image 1"
|
||||
#define REGVALUE_LAST_HARDDISK_2 "Last Harddisk Image 2"
|
||||
#define REGVALUE_LAST_HARDDISK_ "Last Harddisk Image "
|
||||
|
||||
// Preferences
|
||||
#define REG_PREFS "Preferences"
|
||||
|
@ -9,6 +9,7 @@ void LogFileTimeUntilFirstKeyReadReset(void);
|
||||
void LogFileTimeUntilFirstKeyRead(void);
|
||||
|
||||
extern const UINT16* GetOldAppleWinVersion(void);
|
||||
extern UINT16 g_AppleWinVersion[4];
|
||||
extern std::string g_VERSIONSTRING; // Constructed in WinMain()
|
||||
|
||||
void SetAppleWinVersion(UINT16 major, UINT16 minor, UINT16 fix, UINT16 fix_minor);
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -26,15 +26,25 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
#include "Card.h"
|
||||
#include "DiskImage.h"
|
||||
#include "DiskImageHelper.h"
|
||||
#include "MemoryDefs.h" // APPLE_SLOT_SIZE
|
||||
|
||||
enum HardDrive_e
|
||||
{
|
||||
HARDDISK_1 = 0,
|
||||
HARDDISK_2,
|
||||
NUM_HARDDISKS
|
||||
NUM_BLK_HARDDISKS = 2,
|
||||
NUM_HARDDISKS = 8
|
||||
};
|
||||
|
||||
const UINT kHarddiskMaxNumBlocks = 0xffff; // Maximum number of blocks we can report.
|
||||
enum HdcMode
|
||||
{
|
||||
HdcDefault, HdcSmartPort, HdcBlockMode2Devices, HdcBlockMode4Devices
|
||||
};
|
||||
|
||||
// For SP read/write block cmds, a 24-bit blockNum => 8GiB capacity
|
||||
// . but eg. in CImageBase::ReadBlock() only 32-bit byte positions are supported (ie. 4GiB capacity)
|
||||
const UINT kHarddiskMaxNumBlocks = 0x007FFFFF; // Maximum number of blocks we can report.
|
||||
const UINT kMaxSmartPortUnits = NUM_HARDDISKS;
|
||||
|
||||
class HardDiskDrive
|
||||
{
|
||||
@ -98,10 +108,11 @@ public:
|
||||
bool Select(const int iDrive);
|
||||
bool Insert(const int iDrive, const std::string& pathname);
|
||||
void Unplug(const int iDrive);
|
||||
bool IsDriveUnplugged(const int iDrive);
|
||||
void LoadLastDiskImage(const int iDrive);
|
||||
void SetUserNumBlocks(UINT numBlocks) { m_userNumBlocks = numBlocks; }
|
||||
void UseHdcFirmwareV1(void) { m_useHdcFirmwareV1 = true; }
|
||||
void UseHdcFirmwareV2(void) { m_useHdcFirmwareV2 = true; }
|
||||
void SetHdcFirmwareMode(HdcMode hdcMode) { m_useHdcFirmwareMode = hdcMode; }
|
||||
|
||||
void GetLightStatus(Disk_Status_e* pDisk1Status);
|
||||
bool ImageSwap(void);
|
||||
@ -121,19 +132,36 @@ private:
|
||||
const std::string& DiskGetBaseName(const int iDrive);
|
||||
bool SelectImage(const int drive, LPCSTR pszFilename);
|
||||
void UpdateLightStatus(HardDiskDrive* pHDD);
|
||||
UINT GetImageSizeInBlocks(ImageInfo* const pImageInfo);
|
||||
void SaveSnapshotHDDUnit(YamlSaveHelper& yamlSaveHelper, UINT unit);
|
||||
bool LoadSnapshotHDDUnit(YamlLoadHelper& yamlLoadHelper, UINT unit);
|
||||
BYTE GetNumConnectedDevices(void);
|
||||
BYTE GetProDOSBlockDeviceUnit(void);
|
||||
HardDiskDrive* GetUnit(void);
|
||||
BYTE CmdExecute(HardDiskDrive* pHDD);
|
||||
BYTE CmdStatus(HardDiskDrive* pHDD);
|
||||
void SetIdString(WORD addr, const char* str);
|
||||
BYTE SmartPortCmdStatus(HardDiskDrive* pHDD);
|
||||
UINT GetImageSizeInBlocks(ImageInfo* const pImageInfo, const bool is16bit = false);
|
||||
void SaveSnapshotHDDUnit(YamlSaveHelper& yamlSaveHelper, const UINT unit);
|
||||
bool LoadSnapshotHDDUnit(YamlLoadHelper& yamlLoadHelper, const UINT unit, const UINT version);
|
||||
|
||||
//
|
||||
|
||||
BYTE m_unitNum; // b7=unit
|
||||
BYTE m_command;
|
||||
BYTE m_fifoIdx;
|
||||
BYTE m_statusCode;
|
||||
UINT64 m_notBusyCycle;
|
||||
UINT m_userNumBlocks;
|
||||
bool m_useHdcFirmwareV1;
|
||||
bool m_useHdcFirmwareV2;
|
||||
HdcMode m_useHdcFirmwareMode;
|
||||
|
||||
bool m_saveDiskImage; // Save the DiskImage name to Registry
|
||||
|
||||
HardDiskDrive m_hardDiskDrive[NUM_HARDDISKS];
|
||||
HardDiskDrive m_smartPortController; // unit-0 is the SmartPort controller
|
||||
|
||||
bool m_saveStateFirmwareV1;
|
||||
bool m_saveStateFirmwareV2;
|
||||
BYTE m_saveStateFirmware[APPLE_SLOT_SIZE];
|
||||
bool m_saveStateFirmwareValid;
|
||||
};
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
#include "Common.h"
|
||||
#include "Card.h"
|
||||
#include "MemoryDefs.h"
|
||||
|
||||
// Memory Flag
|
||||
#define MF_80STORE 0x00000001
|
||||
@ -22,23 +23,6 @@
|
||||
#define MF_LANGCARD_MASK (MF_WRITERAM|MF_HIGHRAM|MF_BANK2)
|
||||
|
||||
|
||||
enum
|
||||
{
|
||||
// Note: All are in bytes!
|
||||
TEXT_PAGE1_BEGIN = 0x0400,
|
||||
|
||||
APPLE_SLOT_SIZE = 0x0100, // 1 page = $Cx00 .. $CxFF (slot 1 .. 7)
|
||||
APPLE_IO_BEGIN = 0xC000,
|
||||
APPLE_SLOT_BEGIN = 0xC100, // each slot has 1 page reserved for it
|
||||
APPLE_SLOT_END = 0xC7FF, //
|
||||
|
||||
FIRMWARE_EXPANSION_SIZE = 0x0800, // 8 pages = $C800 .. $CFFF
|
||||
FIRMWARE_EXPANSION_BEGIN = 0xC800, // [C800,CFFF)
|
||||
FIRMWARE_EXPANSION_END = 0xCFFF, //
|
||||
|
||||
MEMORY_LENGTH = 0x10000
|
||||
};
|
||||
|
||||
enum MemoryInitPattern_e
|
||||
{
|
||||
MIP_ZERO
|
||||
|
18
source/MemoryDefs.h
Normal file
18
source/MemoryDefs.h
Normal file
@ -0,0 +1,18 @@
|
||||
#pragma once
|
||||
|
||||
enum
|
||||
{
|
||||
// Note: All are in bytes!
|
||||
TEXT_PAGE1_BEGIN = 0x0400,
|
||||
|
||||
APPLE_SLOT_SIZE = 0x0100, // 1 page = $Cx00 .. $CxFF (slot 1 .. 7)
|
||||
APPLE_IO_BEGIN = 0xC000,
|
||||
APPLE_SLOT_BEGIN = 0xC100, // each slot has 1 page reserved for it
|
||||
APPLE_SLOT_END = 0xC7FF, //
|
||||
|
||||
FIRMWARE_EXPANSION_SIZE = 0x0800, // 8 pages = $C800 .. $CFFF
|
||||
FIRMWARE_EXPANSION_BEGIN = 0xC800, // [C800,CFFF)
|
||||
FIRMWARE_EXPANSION_END = 0xCFFF, //
|
||||
|
||||
MEMORY_LENGTH = 0x10000
|
||||
};
|
@ -1,7 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include "Card.h"
|
||||
#include "Memory.h"
|
||||
|
||||
class ParallelPrinterCard : public Card
|
||||
{
|
||||
|
@ -283,10 +283,13 @@ void LoadConfiguration(bool loadImages)
|
||||
GetCurrentDirectory(sizeof(szFilename), szFilename);
|
||||
SetCurrentImageDir(szFilename);
|
||||
|
||||
if (loadImages && GetCardMgr().QuerySlot(SLOT7) == CT_GenericHDD)
|
||||
for (UINT slot = SLOT1; slot <= SLOT7; slot++)
|
||||
{
|
||||
dynamic_cast<HarddiskInterfaceCard&>(GetCardMgr().GetRef(SLOT7)).LoadLastDiskImage(HARDDISK_1);
|
||||
dynamic_cast<HarddiskInterfaceCard&>(GetCardMgr().GetRef(SLOT7)).LoadLastDiskImage(HARDDISK_2);
|
||||
if (loadImages && GetCardMgr().QuerySlot(slot) == CT_GenericHDD)
|
||||
{
|
||||
for (UINT i = 0; i < NUM_HARDDISKS; i++)
|
||||
dynamic_cast<HarddiskInterfaceCard&>(GetCardMgr().GetRef(slot)).LoadLastDiskImage(i);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
@ -429,29 +432,33 @@ void InsertHardDisks(const UINT slot, LPCSTR szImageName_harddisk[NUM_HARDDISKS]
|
||||
{
|
||||
_ASSERT(slot == 5 || slot == 7);
|
||||
|
||||
if (!szImageName_harddisk[HARDDISK_1] && !szImageName_harddisk[HARDDISK_2])
|
||||
// If no HDDs then just return (and don't insert an HDC into this slot)
|
||||
bool res = true;
|
||||
for (UINT i = 0; i < NUM_HARDDISKS; i++)
|
||||
res &= szImageName_harddisk[i] == NULL;
|
||||
if (res)
|
||||
return;
|
||||
|
||||
if (GetCardMgr().QuerySlot(slot) != CT_GenericHDD)
|
||||
GetCardMgr().Insert(slot, CT_GenericHDD); // Enable the Harddisk controller card
|
||||
|
||||
bool bRes = true;
|
||||
|
||||
if (szImageName_harddisk[HARDDISK_1])
|
||||
res = true;
|
||||
for (UINT i = 0; i < NUM_HARDDISKS; i++)
|
||||
{
|
||||
bRes = DoHardDiskInsert(slot, HARDDISK_1, szImageName_harddisk[HARDDISK_1]);
|
||||
LogFileOutput("Init: DoHardDiskInsert(HDD1), res=%d\n", bRes);
|
||||
GetFrame().FrameRefreshStatus(DRAW_LEDS | DRAW_DISK_STATUS); // harddisk activity LED
|
||||
bBoot = true;
|
||||
if (szImageName_harddisk[i])
|
||||
{
|
||||
res &= DoHardDiskInsert(slot, i, szImageName_harddisk[i]);
|
||||
LogFileOutput("Init: DoHardDiskInsert(HDD-%d), res=%d\n", i, res);
|
||||
|
||||
if (i == HARDDISK_1)
|
||||
{
|
||||
GetFrame().FrameRefreshStatus(DRAW_LEDS | DRAW_DISK_STATUS); // harddisk activity LED
|
||||
bBoot = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (szImageName_harddisk[HARDDISK_2])
|
||||
{
|
||||
bRes &= DoHardDiskInsert(slot, HARDDISK_2, szImageName_harddisk[HARDDISK_2]);
|
||||
LogFileOutput("Init: DoHardDiskInsert(HDD2), res=%d\n", bRes);
|
||||
}
|
||||
|
||||
if (!bRes)
|
||||
if (!res)
|
||||
GetFrame().FrameMessageBox("Failed to insert harddisk(s) - see log file", "Warning", MB_ICONASTERISK | MB_OK);
|
||||
}
|
||||
|
||||
|
@ -784,19 +784,19 @@ static void RepeatInitialization(void)
|
||||
|
||||
if (g_cmdLine.slotInsert[SLOT5] != CT_Empty)
|
||||
{
|
||||
if (GetCardMgr().QuerySlot(SLOT5) != CT_Disk2) // Ignore if already got Disk2 in slot 5
|
||||
if (GetCardMgr().QuerySlot(SLOT5) != g_cmdLine.slotInsert[SLOT5]) // Ignore if already got this card type in slot 5
|
||||
GetCardMgr().Insert(SLOT5, g_cmdLine.slotInsert[SLOT5]);
|
||||
}
|
||||
|
||||
if (g_cmdLine.slotInsert[SLOT6] == CT_Disk2) // For now just support Disk2 in slot 6
|
||||
{
|
||||
if (GetCardMgr().QuerySlot(SLOT6) != CT_Disk2) // Ignore if already got Disk2 in slot 6
|
||||
if (GetCardMgr().QuerySlot(SLOT6) != g_cmdLine.slotInsert[SLOT6]) // Ignore if already got this card type in slot 6
|
||||
GetCardMgr().Insert(SLOT6, g_cmdLine.slotInsert[SLOT6]);
|
||||
}
|
||||
|
||||
if (g_cmdLine.slotInsert[SLOT7] != CT_Empty)
|
||||
{
|
||||
if (GetCardMgr().QuerySlot(SLOT7) != CT_GenericHDD) // Ignore if already got HDC in slot 7
|
||||
if (GetCardMgr().QuerySlot(SLOT7) != g_cmdLine.slotInsert[SLOT7]) // Ignore if already got this card type in slot 7
|
||||
GetCardMgr().Insert(SLOT7, g_cmdLine.slotInsert[SLOT7]);
|
||||
}
|
||||
|
||||
@ -809,6 +809,9 @@ static void RepeatInitialization(void)
|
||||
dynamic_cast<HarddiskInterfaceCard&>(GetCardMgr().GetRef(i)).SetUserNumBlocks(g_cmdLine.uHarddiskNumBlocks);
|
||||
if (g_cmdLine.useHdcFirmwareV1)
|
||||
dynamic_cast<HarddiskInterfaceCard&>(GetCardMgr().GetRef(i)).UseHdcFirmwareV1();
|
||||
if (g_cmdLine.useHdcFirmwareV2)
|
||||
dynamic_cast<HarddiskInterfaceCard&>(GetCardMgr().GetRef(i)).UseHdcFirmwareV2();
|
||||
dynamic_cast<HarddiskInterfaceCard&>(GetCardMgr().GetRef(i)).SetHdcFirmwareMode(g_cmdLine.slotInfo[i].useHdcFirmwareMode);
|
||||
}
|
||||
}
|
||||
|
||||
@ -855,10 +858,12 @@ static void RepeatInitialization(void)
|
||||
g_cmdLine.szImageName_drive[SLOT6][DRIVE_1] = g_cmdLine.szImageName_drive[SLOT6][DRIVE_2] = NULL; // Don't insert on a restart
|
||||
|
||||
InsertHardDisks(SLOT5, g_cmdLine.szImageName_harddisk[SLOT5], temp);
|
||||
g_cmdLine.szImageName_harddisk[SLOT5][HARDDISK_1] = g_cmdLine.szImageName_harddisk[SLOT5][HARDDISK_2] = NULL; // Don't insert on a restart
|
||||
for (UINT i = 0; i < NUM_HARDDISKS; i++)
|
||||
g_cmdLine.szImageName_harddisk[SLOT5][i] = NULL; // Don't insert on a restart
|
||||
|
||||
InsertHardDisks(SLOT7, g_cmdLine.szImageName_harddisk[SLOT7], g_cmdLine.bBoot);
|
||||
g_cmdLine.szImageName_harddisk[SLOT7][HARDDISK_1] = g_cmdLine.szImageName_harddisk[SLOT7][HARDDISK_2] = NULL; // Don't insert on a restart
|
||||
for (UINT i = 0; i < NUM_HARDDISKS; i++)
|
||||
g_cmdLine.szImageName_harddisk[SLOT7][i] = NULL; // Don't insert on a restart
|
||||
|
||||
if (g_cmdLine.bSlotEmpty[SLOT7])
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user