Compare commits

..

1 Commits

Author SHA1 Message Date
Florian Reitz
65bff70367 Test with 8 drives for ProDOS 2.5 2020-02-09 17:48:42 +01:00
22 changed files with 270 additions and 346 deletions

5
.gitignore vendored
View File

@ -29,7 +29,6 @@ obj/
[Rr]elease*/
_ReSharper*/
[Tt]est[Rr]esult*
.vs/
*.opendb
**/Debug
@ -220,7 +219,3 @@ VHDL/_pace\.ucf
VHDL/AppleIISd\.tim
VHDL/AppleIISd\.jed
Firmware/AppleIISd.bin
Software/Flasher.bin

Binary file not shown.

View File

@ -1,102 +1,102 @@
:10000000A220A200A203A20078A960853F203F00A1
:10001000BABD0001588DF807290F853FA80A0A0AC2
:100020000A853EAA2CFFCFA000B907C9F00D0980B0
:100020000A853EAA2CFFCFA000B916C9F00D0980A1
:10003000995007C810F3A9C520A8FC2C61C0100B6B
:10004000ADF8073A854164406C40002000C8C90003
:10005000D0EEA9088545644464476446206ECAB062
:10006000DFA90A854564446447A9018546206ECA14
:10005000D0EEA9088545644464476446207ECAB052
:10006000DFA90A854564446447A9018546207ECA04
:10007000B0CE4C01081890013808FAA004B93D0030
:10008000488810F9863D78A960853F203F00BABDB9
:100090000001588DF807290F853FA80A0A0A0A852A
:1000A0003EAA2CFFCF202FCA9004A92F8015A9802B
:1000A0003EAA2CFFCF203FCA9004A92F8015A9801B
:1000B0003C83C0D0052000C8B009A53D4828B03415
:1000C0002047CADAA63F9D7804689DF804989D7879
:1000C0002057CADAA63F9D7804689DF804989D7869
:1000D0000508689DF805A00068993D00C8C0059016
:1000E000F7BDF80548BD780548BDF80448BD78045B
:1000F000FA7A2860182048CB80C900000000977564
:100100009E81C0A9019D83C0A00AA9FF9D80C03C1B
:1001100081C010FB88D0F5BD83C029FE9D83C0A996
:100120002F8540A9C98541205FC92073C9C901D065
:1001300065A93B8540A9C98541205FC9208AC9C9F5
:1001400001D056A43FB9F805C9AAD04AA9478540AD
:10015000A9C98541205FC92073C9A9538540A9C990
:100160008541205FC92073C9C901F0E0C900D026CC
:10017000A94D8540A9C98541205FC9208AC9C90008
:10018000D014A43FB978042940F048BD83C00910B9
:100190009D83C04CE5C84CFAC8A9478540A9C985CC
:1001A00041205FC9A9598540A9C98541205FC9205F
:1001B00073C9C901F0E3C900D0034CD3C8A9358580
:1001C00040A9C98541205FC92073C9C901F0F6C99A
:1001D00000D027A9418540A9C98541205FC9207366
:1001E000C9C900D015BD83C009809D83C0BD81C031
:1001F00009049D81C018A000900338A027BD83C0CA
:1002000009019D83C09860204170706C655D5B53EF
:10021000642076312E322E3220286329323032305B
:1002200020466C6F7269616E20526569747A004075
:1002300000000000954100000000F948000001AAFC
:10024000875000000200FF7700000000FF7A0000E6
:100250000000FF6940000000776900000000FF5ABD
:10026000A000B1409D80C03C81C010FBC8C006907A
:10027000F17A60A9FF9D80C03C81C010FBBD80C0A9
:1002800030F148A9FF9D80C068602073C9485AA01A
:10029000044C99C9A9FF9D80C03C81C010FBBD8062
:1002A000C04888D0EFA43F6899F805689978056838
:1002B00099F804689978047AA9FF9D80C06860DA8B
:1002C0005AA63FA43EA5469DF805A5479D78059EE4
:1002D000F8049E78049845432970F005A9029DF81A
:1002E0000424431007BDF8041A9DF804A9103983AB
:1002F000C0D011A0091EF8053E78053EF8043E78EE
:100300000488D0F17AFA605AA43F9D80C0B978047D
:100310009D80C0B9F8049D80C0B978059D80C0B9A2
:10032000F8059D80C0A9FF9D80C02073C97A6048F0
:10033000A9403C83C018F00138686048A9203C837C
:10034000C018F001386860A542F00CC901F00BC973
:1003500002F00AA90138604C60CA4C6ECA4CD7CA78
:10036000A900203BCA9002A92BA2FFA0FF6020BFDA
:10037000C9BD83C029FE9D83C0A9512007CAC900F9
:10038000D050A9FF9D80C0BD80C0C9FED0F4BD8102
:10039000C009109D81C0A9FF9D80C0A000BD80C084
:1003A0009144C8D0F8E645BD80C09144C8D0F8C695
:1003B00045BD80C0BD80C0BD80C0BD81C029EF9D4E
:1003C00081C018A9000848BD83C009019D83C06889
:1003D000286038A92780EE203BCAB06720BFC9BD7E
:1003E00083C029FE9D83C0A9582007CAC900D04EEA
:1003F000A9FF9D80C0A9FE9D80C0A000B1449D8042
:10040000C0C8D0F8E645B1449D80C0C8D0F8C64504
:10041000A9FF9D80C09D80C09D80C0BD80C0291F58
:10042000C905D01A18A9000848A9FF9D80C0BD8041
:10043000C0F0F6BD83C009019D83C068286038A95B
:100440002780E438A92B80DFA004B9480048881031
:10045000F9BABD0D0185481869039D0D01BD0E0156
:10046000854969009D0E01A001B1488542C8B14887
:10047000AAC8B14885498648A901A642E00AB01A2F
:10048000B248DDDECCD027A001B148A43F99780660
:100490008A0AAA20B2CBB002A900AAA00068994893
:1004A00000C8C00590F78AA002A200C90160A90493
:1004B00080E87CE8CC2043CCA43FB97806D018A5CE
:1004C0004CF004A9213860A904924AA007B9FBCCDA
:1004D000914A88D0F81860A64CF016CAF008CACA2B
:1004E000F00FA9213860A901924AA8A900914A18E1
:1004F00060A9E8A63E202FCAB0020910203BCA908E
:10050000020904924AA001A9FF914AC8914AC8A9C8
:1005100000914AA54CF00CA004B9FFCC914AC8C088
:100520001990F618602043CCA64CF00FCAF00CCA04
:10053000F006CAF00ACAF003A92138A9001860A978
:100540001F3860A002B148854AC8B148854BC8B180
:1005500048854C60206ECC900160A63EA43F4C6E56
:10056000CA206ECC900160A63EA43F4CD7CAB97891
:1005700006F044C901F00EC902F00EC903F010C91B
:1005800004F0118032A53E8010A53E0980800AA5A6
:100590003E3A8005A53E3A09808543A002B14885D0
:1005A00044C8B1488545C8B1488546C8B148854763
:1005B000C8B148D0061860A9113860A92D3860B9B3
:1005C0007806F004A9001860A9113860B9780618F7
:1005D000F003A9113860A9013860A9273860030326
:1005E0000301030101010404B5CB54CC61CCBFCCA1
:1005F00025CCCCCCD6CCD6CCDACCDACC4000000B97
:10060000120000104150504C455D5B5344202020A7
:100610002020202002000B1200000000000000003B
:1006200000000000000000000000000000000000CA
:1000F000FA7A2860182058CB80C900000000977554
:10010000A9039D81C0BD83C009019D83C0A9079D2E
:1001100082C0A00AA9FF9D80C03C81C010FB88D08E
:10012000F5BD83C029FE9D83C0A93F8540A9C9852F
:1001300041206FC92083C9C901D065A94B8540A959
:10014000C98541206FC9209AC9C901D056A43FB9B9
:10015000F805C9AAD04AA9578540A9C98541206F89
:10016000C92083C9A9638540A9C98541206FC920D9
:1001700083C9C901F0E0C900D026A95D8540A9C99D
:100180008541206FC9209AC9C900D014A43FB9780D
:10019000042940F048BD83C009109D83C04CEFC8BE
:1001A0004C04C9A9578540A9C98541206FC9A969CF
:1001B0008540A9C98541206FC92083C9C901F0E3E1
:1001C000C900D0034CDDC8A9458540A9C985412097
:1001D0006FC92083C9C901F0F6C900D027A951858C
:1001E00040A9C98541206FC92083C9C900D015BD68
:1001F00083C009809D83C0BD81C009049D81C01852
:10020000A000900338A027BD83C009019D83C0A929
:10021000009D82C09860204170706C655D5B536486
:100220002076312E322E3120286329323031382089
:10023000466C6F7269616E20526569747A20004065
:1002400000000000954100000000F948000001AAEC
:10025000875000000200FF7700000000FF7A0000D6
:100260000000FF6940000000776900000000FF5AAD
:10027000A000B1409D80C03C81C010FBC8C006906A
:10028000F17A60A9FF9D80C03C81C010FBBD80C099
:1002900030F148A9FF9D80C068602083C9485AA0FA
:1002A000044CA9C9A9FF9D80C03C81C010FBBD8042
:1002B000C04888D0EFA43F6899F805689978056828
:1002C00099F804689978047AA9FF9D80C06860DA7B
:1002D0005AA63FA43EA5469DF805A5479D78059ED4
:1002E000F8049E78049845432970F005A9029DF80A
:1002F0000424431007BDF8041A9DF804A91039839B
:10030000C0D011A0091EF8053E78053EF8043E78DD
:100310000488D0F17AFA605AA43F9D80C0B978046D
:100320009D80C0B9F8049D80C0B978059D80C0B992
:10033000F8059D80C0A9FF9D80C02083C97A6048D0
:10034000A9403C83C018F00138686048A9203C836C
:10035000C018F001386860A542F00CC901F00BC963
:1003600002F00AA90138604C70CA4C7ECA4CE7CA38
:10037000A900204BCA9002A92BA2FFA0FF6020CFAA
:10038000C9BD83C029FE9D83C0A9512017CAC900D9
:10039000D050A9FF9D80C0BD80C0C9FED0F4BD81F2
:1003A000C009109D81C0A9FF9D80C0A000BD80C074
:1003B0009144C8D0F8E645BD80C09144C8D0F8C685
:1003C00045BD80C0BD80C0BD80C0BD81C029EF9D3E
:1003D00081C018A9000848BD83C009019D83C06879
:1003E000286038A92780EE204BCAB06720CFC9BD4E
:1003F00083C029FE9D83C0A9582017CAC900D04ECA
:10040000A9FF9D80C0A9FE9D80C0A000B1449D8031
:10041000C0C8D0F8E645B1449D80C0C8D0F8C645F4
:10042000A9FF9D80C09D80C09D80C0BD80C0291F48
:10043000C905D01A18A9000848A9FF9D80C0BD8031
:10044000C0F0F6BD83C009019D83C068286038A94B
:100450002780E438A92B80DFA004B9480048881021
:10046000F9BABD0D0185481869039D0D01BD0E0146
:10047000854969009D0E01A001B1488542C8B14877
:10048000AAC8B14885498648A901A642E00AB01A1F
:10049000B248DDEECCD027A001B148A43F99780640
:1004A0008A0AAA20C2CBB002A900AAA00068994873
:1004B00000C8C00590F78AA002A200C90160A90483
:1004C00080E87CF8CC2053CCA43FB97806D018A59E
:1004D0004CF004A9213860A904924AA007B90BCDB9
:1004E000914A88D0F81860A64CF016CAF008CACA1B
:1004F000F00FA9213860A901924AA8A900914A18D1
:1005000060A9E8A63E203FCAB0020910204BCA905D
:10051000020904924AA001A9FF914AC8914AC8A9B8
:1005200000914AA54CF00CA004B90FCD914AC8C067
:100530001990F618602053CCA64CF00FCAF00CCAE4
:10054000F006CAF00ACAF003A92138A9001860A968
:100550001F3860A002B148854AC8B148854BC8B170
:1005600048854C60207ECC900160A63EA43F4C7E26
:10057000CA207ECC900160A63EA43F4CE7CAB97861
:1005800006F044C901F00EC902F00EC903F010C90B
:1005900004F0118032A53E8010A53E0980800AA596
:1005A0003E3A8005A53E3A09808543A002B14885C0
:1005B00044C8B1488545C8B1488546C8B148854753
:1005C000C8B148D0061860A9113860A92D3860B9A3
:1005D0007806F004A9001860A9113860B9780618E7
:1005E000F003A9113860A9013860A9273860030316
:1005F0000301030101010404C5CB64CC71CCCFCC51
:1006000035CCDCCCE6CCE6CCEACCEACC4000000B26
:10061000120000104150504C455D5B534420202097
:100620002020202002000B1200000000000000002B
:1006300000000000000000000000000000000000BA
:1006400000000000000000000000000000000000AA
:10065000000000000000000000000000000000009A

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -11,8 +11,8 @@
</ProjectConfiguration>
</ItemGroup>
<ItemGroup>
<None Include="..\AppleIISd.bin.map" />
<None Include="..\README.md" />
<None Include="AppleIISd.bin.map" />
<None Include="makefile" />
<None Include="Makefile.options" />
<None Include="obj\AppleIISd.lst" />

View File

@ -23,7 +23,7 @@
</None>
<None Include="Makefile.options" />
<None Include="..\README.md" />
<None Include="AppleIISd.bin.map" />
<None Include="..\AppleIISd.bin.map" />
</ItemGroup>
<ItemGroup>
<Filter Include="src">

View File

@ -1,5 +0,0 @@
make clean
make OPTIONS=mapfile,listing
java -jar ..\Binary\AppleCommander-ac-1.5.0.jar -d ..\Binary\Flasher.dsk appleiisd.bin
java -jar ..\Binary\AppleCommander-ac-1.5.0.jar -p ..\Binary\Flasher.dsk appleiisd.bin $00 < AppleIISd.bin
copy AppleIISd.bin ..\Binary

View File

@ -1,7 +0,0 @@
#!/bin/bash
make clean
make OPTIONS=mapfile,listing
java -jar ../Binary/AppleCommander-ac-1.5.0.jar -d ../Binary/Flasher.dsk appleiisd.bin
java -jar ../Binary/AppleCommander-ac-1.5.0.jar -p ../Binary/Flasher.dsk appleiisd.bin $00 < AppleIISd.bin
cp AppleIISd.bin ../Binary/

View File

@ -1,10 +1,10 @@
;*******************************
;
; Apple][Sd Firmware
; Version 1.2.3
; Version 1.3
; Defines
;
; (c) Florian Reitz, 2017 - 2021
; (c) Florian Reitz, 2017 - 2019
;
; X register usually contains SLOT16
; Y register is used for counting or SLOT
@ -44,9 +44,11 @@ DRVNUM := $0678
CURSLOT := $07F8 ; $Cs
; Rom equates
KNOWNRTS := $FF58
OAPPLE := $C061 ; open apple key
DATA := $C080
CTRL := DATA+1
DIV := DATA+2
SS := DATA+3
; Constants
@ -57,9 +59,9 @@ SS0 = $01 ; SS register
SDHC = $10
WP = $20
CD = $40
CARD_INIT = $80
INITED = $80
SMDRIVERVER = $120B ; Version 1.2 Beta
SMDRIVERVER = $130B ; Version 1.3 Beta
; Error codes
NO_ERR = $00

View File

@ -1,25 +1,22 @@
;*******************************
;
; Apple][Sd Firmware
; Version 1.2.3
; Version 1.3
; Main source
;
; (c) Florian Reitz, 2017 - 2021
; (c) Florian Reitz, 2017 - 2019
;
; X register usually contains SLOT16
; Y register is used for counting or SLOT
;
;*******************************
.export INIT
.import PRODOS
.import SMARTPORT
.import GETR1
.import GETR3
.import SDCMD
.import CARDDET
.import INITED
.import READ
.include "AppleIISd.inc"
@ -57,23 +54,25 @@
LDX #$00
LDX #$03
LDX #$00 ; is Smartport controller
;LDX #$3C ; is a disk controller
SEI ; find slot
BIT $CFFF
JSR KNOWNRTS
LDA #$60 ; opcode for RTS
STA SLOT
JSR SLOT
TSX
LDA $0100,X
CLI
STA CURSLOT ; $Cs
AND #$0F
STA SLOT ; $0s
TAY ; Y holds now SLOT
ASL A
ASL A
ASL A
ASL A
STA SLOT16 ; $s0
TAX ; X holds now SLOT16
BIT $CFFF
LDY #0 ; display copyright message
@DRAW: LDA TEXT,Y
@ -86,7 +85,7 @@
LDA #197
JSR $FCA8 ; wait for 100 ms
@OAPPLE: LDA OAPPLE ; check for OA key
@OAPPLE: BIT OAPPLE ; check for OA key
BPL @INIT ; and skip boot if pressed
@NEXTSLOT: LDA CURSLOT ; skip boot when no card
@ -96,6 +95,7 @@
JMP (CMDLO)
@INIT: JSR INIT
CMP #NO_ERR
BNE @NEXTSLOT ; init not successful
;*******************************
@ -110,8 +110,6 @@
STZ BUFFER ; buffer lo
STZ BLOCKNUM+1 ; block hi
STZ BLOCKNUM ; block lo
LDA SLOT16
STA DSNUMBER ; set to current slot
JSR READ
BCS @NEXTSLOT ; load not successful
@ -147,8 +145,9 @@ DRIVER: CLC ; ProDOS entry
; Has this to be done every time this gets called or only on boot???
SEI
BIT $CFFF
JSR KNOWNRTS
LDA #$60 ; opcode for RTS
STA SLOT
JSR SLOT
TSX
LDA $0100,X
CLI
@ -162,9 +161,16 @@ DRIVER: CLC ; ProDOS entry
ASL A
STA SLOT16 ; $s0
TAX ; X holds now SLOT16
BIT $CFFF
JSR INITED ; check for init
BCC @DISP
JSR CARDDET
BCC @INITED
LDA #ERR_OFFLINE; no card inserted
BRA @END
@INITED: LDA #INITED ; check for init
BIT SS,X
BNE @DISP
JSR INIT
BCS @END ; Init failed
@ -222,14 +228,18 @@ DRIVER: CLC ; ProDOS entry
;*******************************
.segment "EXTROM"
INIT: STZ CTRL,X ; reset SPI controller
LDA #SS0 ; set CS high
INIT: LDA #$03 ; set SPI mode 3
STA CTRL,X
LDA SS,X
ORA #SS0 ; set CS high
STA SS,X
LDA #7 ; set 400 kHz
STA DIV,X
LDY #10
LDA #DUMMY
@LOOP: LDA #DUMMY
STA DATA,X
@WAIT: LDA CTRL,X ; wait for TC (bit 7) to get high
@LOOP: STA DATA,X
@WAIT: BIT CTRL,X
BPL @WAIT
DEY
BNE @LOOP ; do 10 times
@ -338,7 +348,7 @@ INIT: STZ CTRL,X ; reset SPI controller
BNE @IOERROR ; error!
@END: LDA SS,X
ORA #CARD_INIT ; initialized
ORA #INITED ; initialized
STA SS,X
LDA CTRL,X
ORA #ECE ; enable 7MHz
@ -352,13 +362,13 @@ INIT: STZ CTRL,X ; reset SPI controller
@END1: LDA SS,X ; set CS high
ORA #SS0
STA SS,X
LDA #0 ; set div to 2
STA DIV,X
TYA ; retval in A
KNOWNRTS: RTS
RTS
TEXT: .asciiz " Apple][Sd v1.2.2 (c)2021 Florian Reitz"
.assert(*-TEXT)=40, error, "TEXT must be 40 bytes long"
TEXT: .asciiz " Apple][Sd v1.3 (c)2019 Florian Reitz "
CMD0: .byt $40, $00, $00
.byt $00, $00, $95

View File

@ -1,25 +1,23 @@
;*******************************
;
; Apple][Sd Firmware
; Version 1.2.3
; Version 1.3
; Helper functions
;
; (c) Florian Reitz, 2017 - 2021
; (c) Florian Reitz, 2017 - 2019
;
; X register usually contains SLOT16
; Y register is used for counting or SLOT
;
;*******************************
.export SDCMD
.export GETR1
.export GETR3
.export GETBLOCK
.export COMMAND
.export SDCMD
.export GETBLOCK
.export CARDDET
.export WRPROT
.export INITED
.export GETR1
.export GETR3
.include "AppleIISd.inc"
.segment "EXTROM"
@ -36,7 +34,7 @@ SDCMD: PHY
LDY #0
@LOOP: LDA (CMDLO),Y
STA DATA,X
@WAIT: LDA CTRL,X ; TC is in N
@WAIT: BIT CTRL,X ; TC is in N
BPL @WAIT
INY
CPY #6
@ -54,7 +52,7 @@ SDCMD: PHY
GETR1: LDA #DUMMY
STA DATA,X
@WAIT: LDA CTRL,X
@WAIT: BIT CTRL,X
BPL @WAIT
LDA DATA,X ; get response
BMI GETR1 ; wait for MSB=0
@ -79,7 +77,7 @@ GETR3: JSR GETR1 ; get R1 first
JMP @WAIT ; first byte is already there
@LOOP: LDA #DUMMY ; send dummy
STA DATA,X
@WAIT: LDA CTRL,X
@WAIT: BIT CTRL,X
BPL @WAIT
LDA DATA,X
PHA
@ -104,10 +102,13 @@ GETR3: JSR GETR1 ; get R1 first
;*******************************
;
; Calculate block address
; Unit number is in $43 DSSS0000
; Unit number is in $43 DSSS0000 / DSSS00DD
; Block no is in $46-47
; Address is in R30-R33
;
; Starting ProDOS 2.5a5 the unit number
; has been enhanced to DSSS00DD
;
;*******************************
GETBLOCK: PHX ; save X
@ -118,21 +119,35 @@ GETBLOCK: PHX ; save X
STA R33,X ; in R30-R33
LDA BLOCKNUM+1
STA R32,X
STZ R31,X
STZ R30,X
TYA ; get SLOT16
.if 1
LDA DSNUMBER ; calculate drive number
ASL A
AND #$07
ADC #$01
STA R31,X
.else
LDA DSNUMBER
AND #$03 ; mask extended drive bits (bits 0-1)
STA R31,X
BIT DSNUMBER ; check old drive number (bit 7)
BPL @PHANTOM
INC A ; increase by one
STA R31,X
.endif
.if 0
@PHANTOM: TYA ; get SLOT16
EOR DSNUMBER
AND #$70 ; check only slot bits
BEQ @DRIVE ; it is our slot
LDA #2 ; it is a phantom slot
STA R31,X
@DRIVE: LDA DSNUMBER ; drive number
BPL @SDHC ; D1
LDA R31,X ; D2
INC A
BEQ @SDHC ; it is our slot
LDA R31,X ; it is a phantom slot, multiply by 16
ASL A
ASL A
ASL A
ASL A
STA R31,X
.endif
@SDHC: LDA #SDHC
AND SS,Y ; if card is SDHC,
@ -146,7 +161,7 @@ GETBLOCK: PHX ; save X
DEY
BNE @LOOP
@END: PLY ; restore Y
@END: PLY ; restore Y
PLX ; restore X
RTS
@ -214,23 +229,3 @@ WRPROT: PHA
SEC
@DONE: PLA
RTS
;*******************************
;
; Check if card is initialized
; X must contain SLOT16
;
; C Clear - card initialized
; Set - card not initialized
;
;*******************************
INITED: PHA
LDA #CARD_INIT ; 0: card not initialized
BIT SS,X ; 1: card initialized
CLC
BNE @DONE
SEC
@DONE: PLA
RTS

View File

@ -1,10 +1,10 @@
;*******************************
;
; Apple][Sd Firmware
; Version 1.2.3
; Version 1.2
; ProDOS functions
;
; (c) Florian Reitz, 2017 - 2021
; (c) Florian Reitz, 2017 - 2018
;
; X register usually contains SLOT16
; Y register is used for counting or SLOT
@ -19,9 +19,6 @@
.import COMMAND
.import SDCMD
.import GETBLOCK
.import CARDDET
.import INITED
.import INIT
.import WRPROT
.import GETR1
.import GETR3
@ -70,7 +67,6 @@ PRODOS: LDA DCMD ; get command
; C Clear - No error
; Set - Error
; A $00 - No error
; $28 - No card inserted
; $2B - Card write protected
; X - Blocks avail (low byte)
; Y - Blocks avail (high byte)
@ -78,12 +74,7 @@ PRODOS: LDA DCMD ; get command
;*******************************
STATUS: LDA #NO_ERR ; Thanks for this one, Antoine!
JSR CARDDET
BCC @WRPROT
LDA #ERR_NODRIVE; no card inserted
BNE @DONE
@WRPROT: JSR WRPROT
JSR WRPROT
BCC @DONE
LDA #ERR_NOWRITE; card write protected
@ -103,20 +94,10 @@ STATUS: LDA #NO_ERR ; Thanks for this one, Antoine!
; Set - Error
; A $00 - No error
; $27 - Bad block number
; $28 - No card inserted
;
;*******************************
READ: JSR CARDDET ; check for card
BCS @NDERROR ; no card
JSR INITED ; check for initialization
BCC @GETBLOCK
JSR INIT ; initialize card
BCS @NDERROR ; init failed
@GETBLOCK: JSR GETBLOCK ; calc block address
READ: JSR GETBLOCK ; calc block address
LDA SS,X ; enable /CS
AND #<~SS0
@ -124,7 +105,7 @@ READ: JSR CARDDET ; check for card
LDA #$51 ; send CMD17
JSR COMMAND ; send command
CMP #0
BNE @IOERROR ; check for error
BNE @ERROR ; check for error
@GETTOK: LDA #DUMMY ; get data token
STA DATA,X
@ -169,14 +150,10 @@ READ: JSR CARDDET ; check for card
PLP
RTS
@IOERROR: SEC ; an error occured
@ERROR: SEC ; an error occured
LDA #ERR_IOERR
BRA @DONE
@NDERROR: SEC ; an error occured
LDA #ERR_NODRIVE
BRA @DONE
;*******************************
;

View File

@ -1,10 +1,10 @@
;*******************************
;
; Apple][Sd Firmware
; Version 1.2.3
; Version 1.2
; Smartport functions
;
; (c) Florian Reitz, 2017 - 2021
; (c) Florian Reitz, 2017 - 2018
;
; X register usually contains SLOT16
; Y register is used for counting or SLOT
@ -95,10 +95,8 @@ SMARTPORT: LDY #SMZPSIZE-1 ; save zeropage area for Smarport
BCC @RESTZP
TXA
;warum feste anzahl an bytes f<>r return wert?
LDY #2 ; highbyte of # bytes transferred
LDX #0 ; low byte of # bytes transferred
;warum wird mit #1 verglichen?
CMP #1 ; C=1 if A != NO_ERR
RTS

BIN
ProFile.zip Normal file

Binary file not shown.

View File

@ -26,13 +26,15 @@ The AppleIISd requires an enhanced IIe or IIgs computer. The ROM code uses some
* Apple IIe enhanced, 128k, Prodos 1.9
* Apple IIe enhanced, 64k, Prodos 1.9
When a 2732 type ROM is used, the binary image has to be programmed at offset 0x800, because A11 is always high for compatibility with 2716 type ROMs.
## Binary distribution
The following files in [Binary/](Binary) have been provided to eliminate the need to compile assembler or VHDL sources.
| File | Purpose |
| ---- | ------- |
| AppleIISd_xx44.jed | CPLD bitfiles for PC44 and VQ44 formfactors |
| AppleIISd.bin | 2k Firmware binary for EPROM |
| AppleIIDs.bin | 2k Firmware binary for EPROM |
| AppleIISd.hex | Same as above in INTEL-HEX format |
| AppleIISd.bom.txt | BOM for the board |
| AppleIISd.pdf | Schematic and layout |
@ -110,8 +112,6 @@ The control registers of the *AppleIISd* are mapped to the usual I/O space at **
**DATA** SPI data register - Is used for both input and output. When the register is written to, the controller will output the byte on the SPI bus. When it is read from, it reflects the data that was received over the SPI bus.
**PGMEN** Program Enable - Enable programing of the internal firmware eeprom. Should be reset immediately after writing to the device.
**ECE** External Clock Enable - This bit enables the the external clock input to the SPI controller. In the *AppleIISd*, this effectively switches the SPI clock between 500kHz (ECE = 0) and 3.5MHz (ECE = 1).
**FRX** Fast Receive mode - When set to 1, fast receive mode triggers shifting upon reading or writing the SPI Data register. When set to 0, shifting is only triggered by writing the SPI data register.
@ -133,10 +133,10 @@ The control registers of the *AppleIISd* are mapped to the usual I/O space at **
## TODOs
* Much more testing
* Enable more than 4 volumes under GS/OS
* Support for 6502 CPUs
* Support for CP/M
* Support for 6502 CPUs
## Known Bugs
* Does not work with some Z80 cards present
* Programs not startable from partitions 3 and 4 under ProDOS

View File

@ -1,5 +1,3 @@
make clean
make
java -jar ..\Binary\AppleCommander-ac-1.5.0.jar -d ..\Binary\Flasher.dsk flasher
java -jar ..\Binary\AppleCommander-ac-1.5.0.jar -as ..\Binary\Flasher.dsk flasher < Flasher.bin
copy Flasher.bin ..\Binary
java -jar AppleCommander-ac-1.5.0.jar -d flasher.dsk %~n1
java -jar AppleCommander-ac-1.5.0.jar -as flasher.dsk %~n1 < %1

View File

@ -1,7 +0,0 @@
#!/bin/bash
make clean
make
java -jar ../Binary/AppleCommander-ac-1.5.0.jar -d ../Binary/Flasher.dsk flasher
java -jar ../Binary/AppleCommander-ac-1.5.0.jar -as ../Binary/Flasher.dsk flasher < Flasher.bin
cp Flasher.bin ../Binary/

View File

@ -6,20 +6,16 @@ typedef unsigned short uint16;
typedef unsigned long uint32;
typedef unsigned char boolean;
#ifndef TRUE
#define TRUE 1
#endif
#ifndef FALSE
#define FALSE 0
#endif
#define SLOT_IO_START (volatile uint8*)0xC080
#define SLOT_ROM_START (volatile uint8*)0xC000
#define EXT_ROM_START (volatile uint8*)0xC800
#define SLOT_IO_START (uint8*)0xC080
#define SLOT_ROM_START (uint8*)0xC000
#define EXT_ROM_START (uint8*)0xC800
#define CFFF (volatile uint8*)0xCFFF
#define CFFF (uint8*)0xCFFF
typedef volatile struct
typedef struct
{
// data register
// +0
@ -44,9 +40,12 @@ typedef volatile struct
uint8 status;
} status;
// clock divisor register, unused
// clock divisor register
// +2
uint8 clkDiv;
union
{
unsigned clkDiv : 2;
};
// slave select and card state register
// +3
@ -57,8 +56,8 @@ typedef volatile struct
unsigned slaveSel : 1;
unsigned : 3;
unsigned sdhc : 1;
const unsigned wp : 1;
const unsigned card : 1;
unsigned wp : 1;
unsigned card : 1;
unsigned inited : 1;
};

View File

@ -1,14 +1,10 @@
#include "AppleIISd.h"
#include <assert.h>
#include <stdio.h>
#include <errno.h>
#include <conio.h>
#include <string.h>
#include <apple2enh.h>
// Binary can't be larger than 2k
#define BUFFER_SIZE 2048
#define BIN_FILE_NAME "AppleIISd.bin"
typedef enum
@ -18,33 +14,33 @@ typedef enum
STATE_2, // hyphen
STATE_3, // backslash
STATE_LAST // don't use
STATE_LAST // don't use
} STATE_CURSOR_T;
const char state_char[STATE_LAST] = { '|', '/', '-', '\\' };
static uint8 buffer[BUFFER_SIZE];
static void writeChip(const uint8* pSource, volatile uint8* pDest, uint16 length);
static boolean verifyChip(const uint8* pSource, volatile uint8* pDest, uint16 length);
static void printStatus(uint8 percentage);
boolean writeChip(const uint8* pSource, uint8* pDest, uint16 length);
void printStatus(uint8 percentage);
// Binary can't be larger than 2k
uint8 buffer[2048] = { 0 };
int main()
{
int retval = 1;
int retval = 0;
FILE* pFile;
char slotNum;
boolean erase = FALSE;
uint16 fileSize = 0;
APPLE_II_SD_T* pAIISD;
volatile uint8* pSlotRom = SLOT_ROM_START;
volatile uint8 dummy;
APPLE_II_SD_T* pAIISD = (APPLE_II_SD_T*)SLOT_IO_START;
uint8* pSlotRom = SLOT_ROM_START;
uint8* pExtRom = EXT_ROM_START;
videomode(VIDEOMODE_40COL);
clrscr();
cprintf("AppleIISd firmware flasher V1.2\r\n");
cprintf("(c) 2019-2020 Florian Reitz\r\n\r\n");
cprintf("AppleIISd firmware flasher\r\n");
cprintf("(c) 2019 Florian Reitz\r\n\r\n");
// ask for slot
cursor(1); // enable blinking cursor
cprintf("Slot number (1-7): ");
@ -52,18 +48,6 @@ int main()
slotNum -= 0x30;
cursor(0); // disable blinking cursor
if(slotNum == 0)
{
// erase device
erase = TRUE;
// ask for slot
cursor(1); // enable blinking cursor
cprintf("Erase device in slot number (1-7): ");
cscanf("%c", &slotNum);
slotNum -= 0x30;
cursor(0); // disable blinking cursor
}
// check if slot is valid
if((slotNum < 1) || (slotNum > 7))
{
@ -71,118 +55,98 @@ int main()
cgetc();
return 1; // failure
}
pAIISD = (APPLE_II_SD_T*)(SLOT_IO_START + (slotNum << 4));
((uint8*)pAIISD) += slotNum << 4;
pSlotRom += slotNum << 8;
if(erase)
// open file
pFile = fopen(BIN_FILE_NAME, "rb");
if(pFile)
{
fileSize = BUFFER_SIZE;
memset(buffer, 0, sizeof(buffer));
}
else
{
// open file
pFile = fopen(BIN_FILE_NAME, "rb");
if(pFile)
{
// read buffer
fileSize = fread(buffer, 1, sizeof(buffer), pFile);
fclose(pFile);
pFile = NULL;
// read buffer
uint16 fileSize = fread(buffer, 1, sizeof(buffer), pFile);
fclose(pFile);
pFile = NULL;
if(fileSize != BUFFER_SIZE)
if(fileSize == 2048)
{
// enable write
pAIISD->status.pgmen = 1;
// clear 0xCFFF
*CFFF = 0;
// write to SLOTROM
cprintf("\r\n\r\nFlashing SLOTROM: ");
if(writeChip(buffer, pSlotRom, 256))
{
cprintf("\r\nWrong file size: %d\r\n", fileSize);
// write to EXTROM
cprintf("\r\nFlashing EXTROM: ");
if(writeChip(buffer + 256, pExtRom, fileSize - 256))
{
cprintf("\r\n\r\nFlashing finished!\n");
}
else
{
retval = 1;
}
}
else
{
retval = 1;
}
// disable write
pAIISD->status.pgmen = 0;
}
else
{
cprintf("\r\nCan't open %s file\r\n", BIN_FILE_NAME);
fileSize = 0;
cprintf("\r\nWrong file size: %d\r\n", fileSize);
retval = 1;
}
}
if(fileSize == BUFFER_SIZE)
else
{
// enable write
pAIISD->status.pgmen = 1;
// write to SLOTROM
cprintf("\r\n\r\nFlashing SLOTROM: ");
writeChip(buffer, pSlotRom, 256);
cprintf("\r\nVerifying SLOTROM: ");
if(verifyChip(buffer, pSlotRom, 256))
{
// write to EXT_ROM
cprintf("\r\n\r\nFlashing EXTROM: ");
// clear CFFF and dummy read to enable correct EXT_ROM
dummy = *CFFF;
dummy = *pSlotRom;
writeChip(buffer + 256, EXT_ROM_START, fileSize - 256);
cprintf("\r\nVerifying EXTROM: ");
dummy = *CFFF;
dummy = *pSlotRom;
if(verifyChip(buffer + 256, EXT_ROM_START, fileSize - 256))
{
cprintf("\r\n\r\nFlashing finished!\n");
retval = 0;
}
}
// disable write
pAIISD->status.pgmen = 0;
cprintf("\r\nCan't open %s file\r\n", BIN_FILE_NAME);
retval = 1;
}
cgetc();
return retval;
}
static void writeChip(const uint8* pSource, volatile uint8* pDest, uint16 length)
boolean writeChip(const uint8* pSource, uint8* pDest, uint16 length)
{
uint32 i;
volatile uint8 readData;
uint8 data = 0;
for(i=0; i<length; i++)
{
pDest[i] = pSource[i];
printStatus((i * 100u / length) + 1);
// wait for write cycle
do
// set 0 if no source
if(pSource)
{
readData = pDest[i];
data = pSource[i];
}
while((readData & 0x80) != (pSource[i] & 0x80));
}
}
static boolean verifyChip(const uint8* pSource, volatile uint8* pDest, uint16 length)
{
uint32 i;
*pDest = data;
for(i=0; i<length; i++)
{
// use print as writecycle
printStatus((i * 100u / length) + 1);
if(pDest[i] != pSource[i])
if(*pDest != data)
{
// verification not successful
cprintf("\r\n\r\n!!! Verification failed at %p !!!\r\n", &pDest[i]);
cprintf("Was 0x%02hhX, should be 0x%02hhX\r\n", pDest[i], pSource[i]);
cprintf("\r\n\r\n!!! Flashing failed at %p !!!\r\n", pDest);
return FALSE;
}
pDest++;
}
return TRUE;
}
static void printStatus(uint8 percentage)
void printStatus(uint8 percentage)
{
static STATE_CURSOR_T state = STATE_0;
uint8 wait = 0;
@ -192,6 +156,11 @@ static void printStatus(uint8 percentage)
cprintf("% 3hhu%% %c", percentage, cState);
gotox(x);
while(wait < 0xff)
{
wait++;
}
state++;
if(state == STATE_LAST)
{