Merge branch 'Smartport'

This commit is contained in:
Florian Reitz 2018-07-07 17:28:58 +02:00
commit e21bde80bd
11 changed files with 728 additions and 220 deletions

Binary file not shown.

View File

@ -1,102 +1,102 @@
:10000000A220A200A203A23C0878A960853D203D61 :10000000A220A200A203A20078A960853F203F00A1
:1000100000BABD00018DF807290F28853D0A0A0A9C :10001000BABD0001588DF807290F853FA80A0A0AC2
:100020000A852BAA2CFFCFA000B9DECAF0080980F0 :100020000A853EAA2CFFCFA000B916C9F00D0980A1
:10003000995007C810F32C61C0300520DEC9900B21 :10003000995007C810F3A9C520A8FC2C61C0100B6B
:10004000ADF8073A854164406C40002000C8A90122 :10004000ADF8073A854164406C40002000C8C90003
:100050008542A62B8643A9088545644464476446C7 :10005000D0EEA9088545644464476446207CCAB054
:100060002CFFCF2004CAA9018542A62B8643A90AEA :10006000DFA90A854564446447A9018546207CCA06
:10007000854564446447A90185462CFFCF2004CA06 :10007000B0CE4C01081890013808FAA004B93D0030
:10008000A62B4C0108D848A52B48A53D48A54048BB :10008000488810F9863D78A960853F203F00BABDB9
:10009000A541480878A960853D203D00BABD000112 :100090000001588DF807290F853FA80A0A0A0A852A
:1000A0008DF807290F28853D0A0A0A0A852BAA2CF4 :1000A0003EAA2CFFCF203DCA9004A92F8015A9801D
:1000B000FFCF20DEC99004A92F802CA9803C83C0EB :1000B0003C83C0D0052000C8B009A53D4828B03415
:1000C000F020A542F00DC901F00EC902F00FA90100 :1000C0002055CADAA63F9D7804689DF804989D786B
:1000D00038801420F6C9800F2004CA800A206DCA17 :1000D0000508689DF805A00068993D00C8C0059016
:1000E00080052000C890DBBA9D05016885416885C0 :1000E000F7BDF80548BD780548BDF80448BD78045B
:1000F0004068853D68852B6860000000FFFF97859C :1000F000FA7A2860182056CB80C900000000977556
:10010000A9039D81C0BD83C009019D83C0A9079D2E :10010000A9039D81C0BD83C009019D83C0A9079D2E
:1001100082C0A00AA9FF9D80C03C81C010FB88D08E :1001100082C0A00AA9FF9D80C03C81C010FB88D08E
:10012000F5BD83C029FE9D83C0A9058540A9CB8567 :10012000F5BD83C029FE9D83C0A93D8540A9C98531
:10013000412016C9202AC9C901D065A9118540A945 :1001300041206DC92081C9C901D065A9498540A95F
:10014000CB85412016C92043C9C901D056A43DB969 :10014000C98541206DC92098C9C901D056A43FB9BD
:10015000F805C9AAD04AA91D8540A9CB854120161A :10015000F805C9AAD04AA9558540A9C98541206D8D
:10016000C9202AC9A9298540A9CB85412016C920C3 :10016000C92081C9A9618540A9C98541206DC920DF
:100170002AC9C901F0E0C900D026A9238540A9CB2E :1001700081C9C901F0E0C900D026A95B8540A9C9A1
:1001800085412016C92043C9C900D014A43DB978BF :100180008541206DC92098C9C900D014A43FB97811
:10019000042940F048BD83C009109D83C04CEFC8BE :10019000042940F048BD83C009109D83C04CEFC8BE
:1001A0004C04C9A91D8540A9CB85412016C9A92F9A :1001A0004C04C9A9558540A9C98541206DC9A967D5
:1001B0008540A9CB85412016C9202AC9C901F0E391 :1001B0008540A9C98541206DC92081C9C901F0E3E5
:1001C000C900D0034CDDC8A90B8540A9CB854120CF :1001C000C900D0034CDDC8A9438540A9C985412099
:1001D00016C9202AC9C901F0F6C900D027A9178578 :1001D0006DC92081C9C901F0F6C900D027A94F8592
:1001E00040A9CB85412016C9202AC9C900D015BD18 :1001E00040A9C98541206DC92081C9C900D015BD6C
:1001F00083C009809D83C0BD81C009049D81C01852 :1001F00083C009809D83C0BD81C009049D81C01852
:10020000A000900338A027BD83C009019D83C0A929 :10020000A000900338A027BD83C009019D83C0A929
:10021000009D82C098605AA000B1409D80C03C8182 :10021000009D82C0986020204170706C655D5B53CA
:10022000C010FBC8C00690F17A60A9FF9D80C03C59 :10022000642076312E32202863293230313820463E
:1002300081C010FBBD80C08980D0EF48A9FF9D80A0 :100230006C6F7269616E20526569747A00400000CB
:10024000C06860202AC9485AA0044C52C9A9FF9D21 :100240000000954100000000F948000001AA875015
:1002500080C03C81C010FBBD80C04888D0EFA43D69 :1002500000000200FF7700000000FF7A00000000AD
:100260006899F805689978056899F8046899780498 :10026000FF6940000000776900000000FF5AA0000D
:100270007AA9FF9D80C06860DA5A8AA8A63DA54683 :10027000B1409D80C03C81C010FBC8C00690F17A9F
:100280009DF805A5479D7805A9009DF8049D780473 :1002800060A9FF9D80C03C81C010FBBD80C030F1E3
:10029000A9802543F005A9019DF804A9103983C060 :1002900048A9FF9D80C068602081C9485AA0044CCD
:1002A000D011A0091EF8053E78053EF8043E7804FA :1002A000A7C9A9FF9D80C03C81C010FBBD80C0488C
:1002B00088D0F17AFA605AA43D9D80C0B978049D37 :1002B00088D0EFA43F6899F805689978056899F89F
:1002C00080C0B9F8049D80C0B978059D80C0B9F898 :1002C00004689978047AA9FF9D80C06860DA5AA60C
:1002D000059D80C0A9FF9D80C0202AC97A6048A9D9 :1002D0003FA43EA5469DF805A5479D78059EF804D8
:1002E000403C83C018F00138686048A9203C83C0B6 :1002E0009E78049845432970F005A9029DF80424DE
:1002F00018F001386860A90020EAC99002A92BA271 :1002F000431007BDF8041A9DF804A9103983C0D033
:10030000FFA0FF602078C9BD83C029FE9D83C0A9DE :1003000011A0091EF8053E78053EF8043E780488E1
:100310005120B6C9C900D050A9FF9D80C0BD80C082 :10031000D0F17AFA605AA43F9D80C0B978049D80DC
:10032000C9FED0F4BD81C009109D81C0A9FF9D8088 :10032000C0B9F8049D80C0B978059D80C0B9F805B2
:10033000C0A000BD80C09144C8D0F8E645BD80C0D3 :100330009D80C0A9FF9D80C02081C97A6048A940E6
:100340009144C8D0F8C645BD80C0BD80C0BD80C046 :100340003C83C018F00138686048A9203C83C0187D
:10035000BD81C029EF9D81C018A9000848BD83C098 :10035000F001386860A542F00CC901F00BC902F049
:1003600009019D83C068286038A92780EE20EAC96A :100360000AA90138604C6ECA4C7CCA4CE5CAA90087
:10037000B0672078C9BD83C029FE9D83C0A95820DD :100370002049CA9002A92BA2FFA0FF6020CDC9BDD1
:10038000B6C9C900D04EA9FF9D80C0A9FE9D80C0FE :1003800083C029FE9D83C0A9512015CAC900D05041
:10039000A000B1449D80C0C8D0F8E645B1449D801E :10039000A9FF9D80C0BD80C0C9FED0F4BD81C00949
:1003A000C0C8D0F8C645A9FF9D80C09D80C09D8073 :1003A000109D81C0A9FF9D80C0A000BD80C0914468
:1003B000C0BD80C0291FC905D01A18A9000848A9C6 :1003B000C8D0F8E645BD80C09144C8D0F8C645BD58
:1003C000FF9D80C0BD80C0F0F6BD83C009019D8344 :1003C00080C0BD80C0BD80C0BD81C029EF9D81C0FF
:1003D000C068286038A92780E438A92B80DF202056 :1003D00018A9000848BD83C009019D83C068286032
:1003E0004170706C655D5B53642076312E3120283E :1003E00038A92780EE2049CAB06720CDC9BD83C097
:1003F00063293230313720466C6F7269616E20524A :1003F00029FE9D83C0A9582015CAC900D04EA9FF67
:100400006569747A0040000000009541000000001A :100400009D80C0A9FE9D80C0A000B1449D80C0C851
:10041000F948000001AA875000000200FF770000A1 :10041000D0F8E645B1449D80C0C8D0F8C645A9FFD4
:100420000000FF7A00000000FF69400000007769CB :100420009D80C09D80C09D80C0BD80C0291FC90522
:1004300000000000FF0000000000000000000000BD :10043000D01A18A5000848A9FF9D80C0BD80C0F053
:1004400000000000000000000000000000000000AC :10044000F6BD83C009019D83C068286038A9278054
:10045000000000000000000000000000000000009C :10045000E438A92B80DFA004B94800488810F9BA15
:10046000000000000000000000000000000000008C :10046000BD0D0185481869039D0D01BD0E0185492B
:10047000000000000000000000000000000000007C :1004700069009D0E01A001B1488542C8B148AAC8D3
:10048000000000000000000000000000000000006C :10048000B14885498648A901A642E00AB01AB24897
:10049000000000000000000000000000000000005C :10049000DDECCCD027A001B148A43F9978068A0AA8
:1004A000000000000000000000000000000000004C :1004A000AA20C0CBB002A900AAA00068994800C841
:1004B000000000000000000000000000000000003C :1004B000C00590F78AA002A200C90160A90480E8E3
:1004C000000000000000000000000000000000002C :1004C0007CF6CC2051CCA43FB97806D018A54CF0CE
:1004D000000000000000000000000000000000001C :1004D00004A9213860A904924AA007B909CD914A1C
:1004E000000000000000000000000000000000000C :1004E00088D0F81860A64CF016CAF008CACAF00FF7
:1004F00000000000000000000000000000000000FC :1004F000A9213860A901924AA8A900914A1860A9C7
:1005000000000000000000000000000000000000EB :10050000E8A63E203DCAB00209102049CA9002095F
:1005100000000000000000000000000000000000DB :1005100004924AA001A9FF914AC8914AC8A9009132
:1005200000000000000000000000000000000000CB :100520004AA54CF00CA004B90DCD914AC8C0199051
:1005300000000000000000000000000000000000BB :10053000F618602051CCA64CF00FCAF00CCAF00699
:1005400000000000000000000000000000000000AB :10054000CAF00ACAF003A92138A9001860A91F3807
:10055000000000000000000000000000000000009B :1005500060A002B148854AC8B148854BC8B14885FA
:10056000000000000000000000000000000000008B :100560004C60207CCC900160A63EA43F4C7CCA200D
:10057000000000000000000000000000000000007B :100570007CCC900160A63EA43F4CE5CAB97806F059
:10058000000000000000000000000000000000006B :1005800044C901F00EC902F00EC903F010C904F00D
:10059000000000000000000000000000000000005B :10059000118032A53E8010A53E0980800AA53E3A12
:1005A000000000000000000000000000000000004B :1005A0008005A53E3A09808543A002B1488544C82C
:1005B000000000000000000000000000000000003B :1005B000B1488545C8B1488546C8B1488547C8B1E6
:1005C000000000000000000000000000000000002B :1005C00048D0061860A9113860A92D3860B978069E
:1005D000000000000000000000000000000000001B :1005D000F004A9001860A9113860B9780618F00372
:1005E000000000000000000000000000000000000B :1005E000A9113860A9013860A92738600303030105
:1005F00000000000000000000000000000000000FB :1005F000030101010404C3CB62CC6FCCCDCC33CC5E
:1006000000000000000000000000000000000000EA :10060000DACCE4CCE4CCE8CCE8CC4000000B12001F
:1006100000000000000000000000000000000000DA :1006100000104150504C455D5B5344202020202069
:1006200000000000000000000000000000000000CA :10062000202002000B12000000000000000000006B
:1006300000000000000000000000000000000000BA :1006300000000000000000000000000000000000BA
:1006400000000000000000000000000000000000AA :1006400000000000000000000000000000000000AA
:10065000000000000000000000000000000000009A :10065000000000000000000000000000000000009A

View File

@ -19,6 +19,7 @@
<None Include="src\AppleIISd.s" /> <None Include="src\AppleIISd.s" />
<None Include="src\Helper.s" /> <None Include="src\Helper.s" />
<None Include="src\ProDOS.s" /> <None Include="src\ProDOS.s" />
<None Include="src\Smartport.s" />
</ItemGroup> </ItemGroup>
<PropertyGroup Label="Globals"> <PropertyGroup Label="Globals">
<ProjectGuid>{9EA7EC3D-1771-420F-932F-231A35ED1200}</ProjectGuid> <ProjectGuid>{9EA7EC3D-1771-420F-932F-231A35ED1200}</ProjectGuid>

View File

@ -19,6 +19,9 @@
<None Include="src\ProDOS.s"> <None Include="src\ProDOS.s">
<Filter>src</Filter> <Filter>src</Filter>
</None> </None>
<None Include="src\Smartport.s">
<Filter>src</Filter>
</None>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Filter Include="src"> <Filter Include="src">

View File

@ -9,8 +9,8 @@ The assembler sources are written for CC65. The [schematics](AppleIISd.pdf) are
## Features ## Features
* works with ProDOS and GS/OS * works with ProDOS and GS/OS
* up to 64MB storage space (2x 65535 blocks) * up to 128MB storage space (4x 65535 blocks)
* ProDOS driver in ROM * ProDOS and Smartport driver in ROM
* Auto boot * Auto boot
* Access LED * Access LED
* Card detect and write protect sensing * Card detect and write protect sensing
@ -27,6 +27,21 @@ The AppleIISd requires an enhanced IIe or IIgs computer. The ROM code uses some
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. 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.
## Smartport drive remapping
The AppleIISd features Smartport drivers in ROM to provide more than two drives in both GS/OS and ProDOS.
As ProDOS supports only two drives per slot, additional drives on a Smartport device are mapped to 'phantom slots'. Version prior to version 2 supported only the remapping of drives when the card was in slot 5. Starting with version 2, the remapping seems to work on all slots. The following list shows the assignments as slot/drive, when no other devices are attached:
* Slot 7: 7/1, 7/2, 4/1, 4/2
* Slot 6: 6/1, 6/2, 4/1, 4/1
* Slot 5: 5/1, 5/2, 2/1, 2/1
* Slot 4: 4/1, 4/2, 1/1, 1/2
* Slot 3: 80 col HW, not usable
* Slot 2: 2/1, 2/2, 4/1, 4/2
* Slot 1: 1/1, 1/2, 4/1, 4/2
When more devices are connected, things get a little confusing ;-)
## Building the sources ## Building the sources
Be sure to have the newest version of CC65 (V2.16) and some kind of Make instaled, then type one of the following comands: Be sure to have the newest version of CC65 (V2.16) and some kind of Make instaled, then type one of the following comands:
``` ```
@ -73,7 +88,7 @@ LDA $C0C0
## TODOs ## TODOs
* Much more testing * Much more testing
* SRAM option (may never work, though) * SRAM option (may never work, though)
* Enable 4 or 6 volumes under GS/OS * Enable more than 4 volumes under GS/OS
* Use 28 pin socket to support other EPROMS than 2716 and 2732 * Use 28 pin socket to support other EPROMS than 2716 and 2732
## Known Bugs ## Known Bugs

View File

@ -9,8 +9,8 @@ MEMORY {
MAIN: file = %O, define = yes, start = %S, size = $C000 - %S; MAIN: file = %O, define = yes, start = %S, size = $C000 - %S;
BSS: file = "", start = __MAIN_LAST__, size = $C000 - __MAIN_LAST__; BSS: file = "", start = __MAIN_LAST__, size = $C000 - __MAIN_LAST__;
SLOTROM: file = %O, fill = yes start = $C700, size = $00FC; SLOTROM: file = %O, fill = yes start = $C700, size = $00FB;
SLOTID: file = %O, start = $C7FC, size = $0004; SLOTID: file = %O, start = $C7FB, size = $0005;
EXTROM: file = %O, fill = yes start = $C800, size = $0700; EXTROM: file = %O, fill = yes start = $C800, size = $0700;
} }
SEGMENTS { SEGMENTS {

View File

@ -1,32 +1,50 @@
;******************************* ;*******************************
; ;
; Apple][Sd Firmware ; Apple][Sd Firmware
; Version 1.1 ; Version 1.2
; Defines ; Defines
; ;
; (c) Florian Reitz, 2017 ; (c) Florian Reitz, 2017 - 2018
; ;
; X register usually contains SLOT16 ; X register usually contains SLOT16
; Y register is used for counting or SLOT ; Y register is used for counting or SLOT
; ;
;******************************* ;*******************************
; Memory defines ; ZP locations
PSAVE := $3D ; P save location
SLOT16 := $2B ; $s0 -> slot * 16 SLOT16 := $3E ; $s0 -> slot * 16
SLOT := $3D ; $0s SLOT := $3F ; $0s
CMDLO := $40 CMDLO := $40
CMDHI := $41 CMDHI := $41
PDZPAREA = PSAVE
PDZPSIZE = CMDHI-PDZPAREA+1
; ProDOS
DCMD := $42 ; Command code DCMD := $42 ; Command code
BUFFER := $44 ; Buffer address DSNUMBER := $43 ; drive / slot number
BLOCK := $46 ; Block number BUFFER := $44 ; buffer pointer, two bytes
BLOCKNUM := $46 ; block number, two bytes
; Smartport
SMPARAMLIST := $48 ; parameter list, two bytes
SMCMDLIST := $4A ; command list, two bytes
SMCSCODE := $4C
SMZPAREA = SMPARAMLIST
SMZPSIZE = SMCSCODE-SMZPAREA+1
SMCMD = DCMD
; Ram equates, access with SLOT offset
R30 := $0478 R30 := $0478
R31 := $04F8 R31 := $04F8
R32 := $0578 R32 := $0578
R33 := $05F8 R33 := $05F8
DRVNUM := $0678
CURSLOT := $07F8 ; $Cs CURSLOT := $07F8 ; $Cs
; Rom equates
KNOWNRTS := $FF58
OAPPLE := $C061 ; open apple key OAPPLE := $C061 ; open apple key
DATA := $C080 DATA := $C080
CTRL := DATA+1 CTRL := DATA+1
@ -34,7 +52,6 @@ DIV := DATA+2
SS := DATA+3 SS := DATA+3
; Constants ; Constants
DUMMY = $FF DUMMY = $FF
FRX = $10 ; CTRL register FRX = $10 ; CTRL register
ECE = $04 ECE = $04
@ -43,3 +60,20 @@ SDHC = $10
WP = $20 WP = $20
CD = $40 CD = $40
INITED = $80 INITED = $80
SMDRIVERVER = $120B ; Version 1.2 Beta
; Error codes
NO_ERR = $00
ERR_BADCMD = $01
ERR_BADPCNT = $04
ERR_BUSERR = $06
ERR_BADUNIT = $11
ERR_NOINT = $1F
ERR_BADCTL = $21
ERR_BADCTLPARM = $22
ERR_IOERR = $27
ERR_NODRIVE = $28
ERR_NOWRITE = $2B
ERR_BADBLOCK = $2D
ERR_OFFLINE = $2F

View File

@ -1,23 +1,23 @@
;******************************* ;*******************************
; ;
; Apple][Sd Firmware ; Apple][Sd Firmware
; Version 1.1 ; Version 1.2
; Main source ; Main source
; ;
; (c) Florian Reitz, 2017 ; (c) Florian Reitz, 2017 - 2018
; ;
; X register usually contains SLOT16 ; X register usually contains SLOT16
; Y register is used for counting or SLOT ; Y register is used for counting or SLOT
; ;
;******************************* ;*******************************
.import PRODOS
.import SMARTPORT
.import GETR1 .import GETR1
.import GETR3 .import GETR3
.import SDCMD .import SDCMD
.import CARDDET .import CARDDET
.import STATUS
.import READ .import READ
.import WRITE
.include "AppleIISd.inc" .include "AppleIISd.inc"
@ -35,7 +35,8 @@
;******************************* ;*******************************
.segment "SLOTID" .segment "SLOTID"
.dbyt $FFFF ; 65535 blocks .byt $0 ; not extended, no SCSI, no RAM
.word $0000 ; use status call
.byt $97 ; Status bits .byt $97 ; Status bits
.byt <DRIVER ; LSB of driver .byt <DRIVER ; LSB of driver
@ -52,50 +53,50 @@
LDX #$20 LDX #$20
LDX #$00 LDX #$00
LDX #$03 LDX #$03
LDX #$3C LDX #$00 ; is Smartport controller
; find slot nr SEI ; find slot
PHP
SEI
LDA #$60 ; opcode for RTS LDA #$60 ; opcode for RTS
STA SLOT STA SLOT
JSR SLOT JSR SLOT
TSX TSX
LDA $0100,X LDA $0100,X
CLI
STA CURSLOT ; $Cs STA CURSLOT ; $Cs
AND #$0F AND #$0F
PLP
STA SLOT ; $0s STA SLOT ; $0s
TAY ; Y holds now SLOT
ASL A ASL A
ASL A ASL A
ASL A ASL A
ASL A ASL A
STA SLOT16 ; $s0 STA SLOT16 ; $s0
TAX ; X holds now SLOT16 TAX ; X holds now SLOT16
BIT $CFFF BIT $CFFF
LDY #0 ; display copyright message LDY #0 ; display copyright message
@DRAW: LDA TEXT,Y @DRAW: LDA TEXT,Y
BEQ @OAPPLE ; check for NULL BEQ @OAPPLE ; check for NULL
ORA #$80 ORA #$80 ; set MSB
STA $0750,Y ; put second to last line STA $0750,Y ; put second to last line
INY INY
BPL @DRAW BPL @DRAW
@OAPPLE: BIT OAPPLE ; check for OA key LDA #197
BMI @NEXTSLOT ; and skip boot if pressed JSR $FCA8 ; wait for 100 ms
JSR CARDDET @OAPPLE: BIT OAPPLE ; check for OA key
BCC @INIT BPL @INIT ; and skip boot if pressed
@NEXTSLOT: LDA CURSLOT ; skip boot when no card @NEXTSLOT: LDA CURSLOT ; skip boot when no card
DEC A DEC A
STA CMDHI STA CMDHI ; use CMDHI/LO as pointer
STZ CMDLO STZ CMDLO
JMP (CMDLO) JMP (CMDLO)
@INIT: JSR INIT @INIT: JSR INIT
CMP #NO_ERR
BNE @NEXTSLOT ; init not successful
;******************************* ;*******************************
; ;
@ -103,33 +104,23 @@
; ;
;******************************* ;*******************************
;@BOOT: CMP #0 ; load disk blocks 0 and 1 to $800 and $A00
; BNE @NEXTSLOT ; init not successful @BOOT: LDA #$08 ; load to $800
@BOOT: LDA #$01
STA DCMD ; load command
LDX SLOT16
STX $43 ; slot number
LDA #$08
STA BUFFER+1 ; buffer hi STA BUFFER+1 ; buffer hi
STZ BUFFER ; buffer lo STZ BUFFER ; buffer lo
STZ BLOCK+1 ; block hi STZ BLOCKNUM+1 ; block hi
STZ BLOCK ; block lo STZ BLOCKNUM ; block lo
BIT $CFFF JSR READ
JSR READ ; call driver BCS @NEXTSLOT ; load not successful
LDA #$01
STA DCMD ; load command
LDX SLOT16
STX $43 ; slot number
LDA #$0A LDA #$0A
STA BUFFER+1 ; buffer hi STA BUFFER+1 ; buffer hi
STZ BUFFER ; buffer lo STZ BUFFER ; buffer lo
STZ BLOCK+1 ; block hi STZ BLOCKNUM+1 ; block hi
LDA #$01 LDA #$01
STA BLOCK ; block lo STA BLOCKNUM ; block lo
BIT $CFFF JSR READ
JSR READ ; call driver BCS @NEXTSLOT ; load not successful
LDX SLOT16
JMP $801 ; goto bootloader JMP $801 ; goto bootloader
@ -139,78 +130,90 @@
; ;
;******************************* ;*******************************
DRIVER: CLD DRIVER: CLC ; ProDOS entry
BCC @PRODOS
SEC ; Smartport entry
@SAVEZP: PHA ; make room for retval @PRODOS: PHP ; transfer P to X
LDA SLOT16 ; save all ZP locations PLX
LDY #PDZPSIZE-1 ; save zeropage area for ProDOS
@SAVEZP: LDA PDZPAREA,Y
PHA PHA
LDA SLOT DEY
PHA BPL @SAVEZP
LDA CMDLO STX PSAVE ; save X (P)
PHA
LDA CMDHI ; Has this to be done every time this gets called or only on boot???
PHA
PHP
SEI SEI
LDA #$60 ; opcode for RTS LDA #$60 ; opcode for RTS
STA SLOT STA SLOT
JSR SLOT JSR SLOT
TSX TSX
LDA $0100,X LDA $0100,X
CLI
STA CURSLOT ; $Cs STA CURSLOT ; $Cs
AND #$0F AND #$0F
PLP
STA SLOT ; $0s STA SLOT ; $0s
TAY ; Y holds now SLOT
ASL A ASL A
ASL A ASL A
ASL A ASL A
ASL A ASL A
STA SLOT16 ; $s0 STA SLOT16 ; $s0
TAX ; X holds now SLOT16 TAX ; X holds now SLOT16
BIT $CFFF BIT $CFFF
JSR CARDDET JSR CARDDET
BCC @INITED BCC @INITED
LDA #$2F ; no card inserted LDA #ERR_OFFLINE; no card inserted
BRA @RESTZP BRA @END
@INITED: LDA #INITED ; check for init @INITED: LDA #INITED ; check for init
BIT SS,X BIT SS,X
BEQ @INIT BNE @DISP
JSR INIT
BCS @END ; Init failed
@CMD: LDA DCMD ; get command @DISP: LDA PSAVE ; get saved P value
BEQ @STATUS ; branch if cmd is 0 PHA ; and transfer to P
CMP #1 PLP
BEQ @READ BCS @SMARTPORT ; Smartport dispatcher
CMP #2 JSR PRODOS ; ProDOS dispatcher
BEQ @WRITE
LDA #1 ; unknown command
SEC
BRA @RESTZP
@STATUS: JSR STATUS @END: PHX
BRA @RESTZP LDX SLOT ; X holds $0s
@READ: JSR READ STA R30,X ; save A
BRA @RESTZP
@WRITE: JSR WRITE
BRA @RESTZP
@INIT: JSR INIT
BCC @CMD ; init ok
@RESTZP: TSX
STA $105,X ; save retval on stack
PLA ; restore all ZP locations
STA CMDHI
PLA PLA
STA CMDLO STA R31,X ; save X
TYA
STA R32,X ; save Y
PHP
PLA PLA
STA SLOT STA R33,X ; save P
PLA
STA SLOT16 LDY #0
PLA ; get retval @RESTZP: PLA ; restore zeropage area
STA PDZPAREA,Y
INY
CPY #PDZPSIZE
BCC @RESTZP
LDA R33,X ; get retval
PHA
LDA R32,X
PHA
LDA R31,X
PHA
LDA R30,X ; restore A
PLX ; restore X
PLY ; restore Y
PLP ; restore P
RTS RTS
@SMARTPORT: CLC
JSR SMARTPORT
BRA @END
;******************************* ;*******************************
; ;
@ -230,7 +233,7 @@ INIT: LDA #$03 ; set SPI mode 3
LDA SS,X LDA SS,X
ORA #SS0 ; set CS high ORA #SS0 ; set CS high
STA SS,X STA SS,X
LDA #7 LDA #7 ; set 400 kHz
STA DIV,X STA DIV,X
LDY #10 LDY #10
LDA #DUMMY LDA #DUMMY
@ -351,11 +354,11 @@ INIT: LDA #$03 ; set SPI mode 3
ORA #ECE ; enable 7MHz ORA #ECE ; enable 7MHz
STA CTRL,X STA CTRL,X
CLC ; all ok CLC ; all ok
LDY #0 LDY #NO_ERR
BCC @END1 BCC @END1
@IOERROR: SEC @IOERROR: SEC
LDY #$27 ; init error LDY #ERR_IOERR ; init error
@END1: LDA SS,X ; set CS high @END1: LDA SS,X ; set CS high
ORA #SS0 ORA #SS0
STA SS,X STA SS,X
@ -365,7 +368,7 @@ INIT: LDA #$03 ; set SPI mode 3
RTS RTS
TEXT: .asciiz " Apple][Sd v1.1 (c)2017 Florian Reitz" TEXT: .asciiz " Apple][Sd v1.2 (c)2018 Florian Reitz"
CMD0: .byt $40, $00, $00 CMD0: .byt $40, $00, $00
.byt $00, $00, $95 .byt $00, $00, $95

View File

@ -1,10 +1,10 @@
;******************************* ;*******************************
; ;
; Apple][Sd Firmware ; Apple][Sd Firmware
; Version 1.1 ; Version 1.2
; Helper functions ; Helper functions
; ;
; (c) Florian Reitz, 2017 ; (c) Florian Reitz, 2017 - 2018
; ;
; X register usually contains SLOT16 ; X register usually contains SLOT16
; Y register is used for counting or SLOT ; Y register is used for counting or SLOT
@ -55,8 +55,7 @@ GETR1: LDA #DUMMY
@WAIT: BIT CTRL,X @WAIT: BIT CTRL,X
BPL @WAIT BPL @WAIT
LDA DATA,X ; get response LDA DATA,X ; get response
BIT #$80 BMI GETR1 ; wait for MSB=0
BNE GETR1 ; wait for MSB=0
PHA PHA
LDA #DUMMY LDA #DUMMY
STA DATA,X ; send another dummy STA DATA,X ; send another dummy
@ -111,21 +110,26 @@ GETR3: JSR GETR1 ; get R1 first
GETBLOCK: PHX ; save X GETBLOCK: PHX ; save X
PHY ; save Y PHY ; save Y
TXA LDX SLOT ; SLOT is now in X
TAY ; SLOT16 is now in Y LDY SLOT16
LDX SLOT LDA BLOCKNUM ; store block num
LDA BLOCK ; store block num
STA R33,X ; in R30-R33 STA R33,X ; in R30-R33
LDA BLOCK+1 LDA BLOCKNUM+1
STA R32,X STA R32,X
LDA #0 STZ R31,X
STA R31,X STZ R30,X
STA R30,X
LDA #$80 ; drive number TYA ; get SLOT16
AND $43 EOR DSNUMBER
BEQ @SDHC ; D1 AND #$70 ; check only slot bits
LDA #1 ; D2 BEQ @DRIVE ; it is our slot
LDA #2 ; it is a phantom slot
STA R31,X
@DRIVE: BIT DSNUMBER ; drive number
BPL @SDHC ; D1
LDA R31,X ; D2
INC A
STA R31,X STA R31,X
@SDHC: LDA #SDHC @SDHC: LDA #SDHC
@ -173,6 +177,7 @@ COMMAND: PHY ; save Y
;******************************* ;*******************************
; ;
; Check for card detect ; Check for card detect
; X must contain SLOT16
; ;
; C Clear - card in slot ; C Clear - card in slot
; Set - no card in slot ; Set - no card in slot
@ -192,6 +197,7 @@ CARDDET: PHA
;******************************* ;*******************************
; ;
; Check for write protect ; Check for write protect
; X must contain SLOT16
; ;
; C Clear - card not protected ; C Clear - card not protected
; Set - card write protected ; Set - card write protected

View File

@ -1,16 +1,17 @@
;******************************* ;*******************************
; ;
; Apple][Sd Firmware ; Apple][Sd Firmware
; Version 1.1 ; Version 1.2
; ProDOS functions ; ProDOS functions
; ;
; (c) Florian Reitz, 2017 ; (c) Florian Reitz, 2017 - 2018
; ;
; X register usually contains SLOT16 ; X register usually contains SLOT16
; Y register is used for counting or SLOT ; Y register is used for counting or SLOT
; ;
;******************************* ;*******************************
.export PRODOS
.export STATUS .export STATUS
.export READ .export READ
.export WRITE .export WRITE
@ -26,6 +27,36 @@
.segment "EXTROM" .segment "EXTROM"
;*******************************
;
; ProDOS command dispatcher
;
; $42-$47 MLI input locations
; X Slot*16
; Y Slot
;
; C Clear - No error
; Set - Error
; A $00 - No error
; $01 - Unknown command
;
;*******************************
PRODOS: LDA DCMD ; get command
BEQ @STATUS ; branch if cmd is 0
CMP #1
BEQ @READ
CMP #2
BEQ @WRITE
LDA #ERR_BADCMD ; unknown command
SEC
RTS
@STATUS: JMP STATUS
@READ: JMP READ
@WRITE: JMP WRITE
;******************************* ;*******************************
; ;
; Status request ; Status request
@ -37,16 +68,15 @@
; Set - Error ; Set - Error
; A $00 - No error ; A $00 - No error
; $2B - Card write protected ; $2B - Card write protected
; $2F - No card inserted
; X - Blocks avail (low byte) ; X - Blocks avail (low byte)
; Y - Blocks avail (high byte) ; Y - Blocks avail (high byte)
; ;
;******************************* ;*******************************
STATUS: LDA #0 ; no error STATUS: LDA #NO_ERR ; Thanks for this one, Antoine!
JSR WRPROT JSR WRPROT
BCC @DONE BCC @DONE
LDA #$2B ; card write protected LDA #ERR_NOWRITE; card write protected
@DONE: LDX #$FF ; 32 MB partition @DONE: LDX #$FF ; 32 MB partition
LDY #$FF LDY #$FF
@ -109,7 +139,7 @@ READ: JSR GETBLOCK ; calc block address
AND #<~FRX AND #<~FRX
STA CTRL,X STA CTRL,X
CLC ; no error CLC ; no error
LDA #0 LDA #NO_ERR
@DONE: PHP @DONE: PHP
PHA PHA
@ -121,7 +151,7 @@ READ: JSR GETBLOCK ; calc block address
RTS RTS
@ERROR: SEC ; an error occured @ERROR: SEC ; an error occured
LDA #$27 LDA #ERR_IOERR
BRA @DONE BRA @DONE
@ -180,7 +210,7 @@ WRITE: JSR WRPROT
CMP #$05 CMP #$05
BNE @IOERROR ; check for write error BNE @IOERROR ; check for write error
CLC ; no error CLC ; no error
LDA #0 LDA NO_ERR
@DONE: PHP @DONE: PHP
PHA PHA
@ -197,9 +227,9 @@ WRITE: JSR WRPROT
RTS RTS
@IOERROR: SEC ; an error occured @IOERROR: SEC ; an error occured
LDA #$27 LDA #ERR_IOERR
BRA @DONE BRA @DONE
@WPERROR: SEC @WPERROR: SEC
LDA #$2B LDA #ERR_NOWRITE
BRA @DONE BRA @DONE

416
src/Smartport.s Normal file
View File

@ -0,0 +1,416 @@
;*******************************
;
; Apple][Sd Firmware
; Version 1.2
; Smartport functions
;
; (c) Florian Reitz, 2017 - 2018
;
; X register usually contains SLOT16
; Y register is used for counting or SLOT
;
;*******************************
.export SMARTPORT
.import READ
.import WRITE
.import CARDDET
.import WRPROT
.include "AppleIISd.inc"
.segment "EXTROM"
;*******************************
;
; Smartport command dispatcher
;
; $42-$47 MLI input locations
; X Slot*16
; Y Slot
;
; C Clear - No error
; Set - Error
; A $00 - No error
; $01 - Unknown command
;
;*******************************
SMARTPORT: LDY #SMZPSIZE-1 ; save zeropage area for Smarport
@SAVEZP: LDA SMZPAREA,Y
PHA
DEY
BPL @SAVEZP
TSX ; get call address
LDA $103+PDZPSIZE+SMZPSIZE,X
STA SMPARAMLIST ; store temporarily
CLC
ADC #3 ; adjust return address
STA $103+PDZPSIZE+SMZPSIZE,X
LDA $104+PDZPSIZE+SMZPSIZE,X
STA SMPARAMLIST+1
ADC #0
STA $104+PDZPSIZE+SMZPSIZE,X
LDY #1 ; get command code
LDA (SMPARAMLIST),Y
STA SMCMD
INY
LDA (SMPARAMLIST),Y
TAX
INY
LDA (SMPARAMLIST),Y
STA SMPARAMLIST+1 ; is now parameter list
STX SMPARAMLIST
LDA #ERR_BADCMD ; suspect bad command
LDX SMCMD
CPX #$09+1 ; command too large
BCS @END
LDA (SMPARAMLIST) ; parameter count
CMP REQPARAMCOUNT,X
BNE @COUNTMISMATCH
LDY #1 ; get drive number
LDA (SMPARAMLIST),Y
LDY SLOT
STA DRVNUM,Y
TXA ; SMCMD
ASL A ; shift for use of word addresses
TAX
JSR @JMPSPCOMMAND ; Y holds SLOT
BCS @END ; jump on error
LDA #NO_ERR
@END: TAX ; save retval
LDY #0 ; restore zeropage
@RESTZP: PLA
STA SMZPAREA,Y
INY
CPY #SMZPSIZE
BCC @RESTZP
TXA
LDY #2 ; highbyte of # bytes transferred
LDX #0 ; low byte of # bytes transferred
CMP #1 ; C=1 if A != NO_ERR
RTS
@COUNTMISMATCH:
LDA #ERR_BADPCNT
BRA @END
@JMPSPCOMMAND: ; use offset from cmd*2
JMP (SPDISPATCH,X)
; Smartport Status command
;
SMSTATUS: JSR GETCSLIST
LDY SLOT
LDA DRVNUM,Y
BNE @PARTITION ; status call for a partition
LDA SMCSCODE
BEQ @STATUS00 ; status call 0 for the bus
LDA #ERR_BADCTL ; calls other than 0 are not allowed
SEC
RTS
; TODO support partitions based on card size
@STATUS00: LDA #4 ; support 4 partitions
STA (SMCMDLIST)
LDY #7
@LOOP00: LDA STATUS00DATA-1,Y
STA (SMCMDLIST),Y
DEY
BNE @LOOP00
CLC
RTS
@PARTITION: LDX SMCSCODE
BEQ @STATUS03 ; 0: device status
DEX
BEQ @GETDCB ; 1: get DCB
DEX
DEX
BEQ @STATUS03 ; 3: get DIB
LDA #ERR_BADCTL
SEC
RTS
@GETDCB: LDA #1 ; return 'empty' DCB, one byte
STA (SMCMDLIST)
TAY
LDA #NO_ERR
STA (SMCMDLIST),Y
CLC
RTS
@STATUS03: LDA #$E8 ; block device, read, write, format,
; not online, no write-protect
LDX SLOT16
JSR CARDDET
BCS @WRPROT
ORA #$10 ; card inserted
@WRPROT: JSR WRPROT
BCC @STATUSBYTE
ORA #$04 ; SD card write-protected
@STATUSBYTE:STA (SMCMDLIST)
LDY #1 ; block count, always $00FFFF
LDA #$FF
STA (SMCMDLIST),Y
INY
STA (SMCMDLIST),Y
INY
LDA #0
STA (SMCMDLIST),Y
LDA SMCSCODE
BEQ @DONE ; done if code 0, else get DIB, 21 bytes
LDY #4
@LOOP: LDA STATUS3DATA-4,Y
STA (SMCMDLIST),Y
INY
CPY #21+4
BCC @LOOP
@DONE: CLC
RTS
; Smartport Control command
;
; no controls supported, yet
;
SMCONTROL: JSR GETCSLIST
LDX SMCSCODE
BEQ @RESET ; 0: Reset
DEX
BEQ @SETDCB ; 1: SetDCB
DEX
BEQ @NEWLINE ; 2: SetNewLine
DEX
BEQ @IRQ ; 3: ServiceInterrupt
DEX
BEQ @EJECT ; 4: Eject
@NEWLINE: LDA #ERR_BADCTL
SEC
@RESET:
@SETDCB:
@EJECT: LDA #NO_ERR ; only return OK
CLC
RTS
@IRQ: LDA #ERR_NOINT ; interrupts not supported
SEC
RTS
; Get control/status list pointer and code
;
GETCSLIST: LDY #2
LDA (SMPARAMLIST),Y
STA SMCMDLIST ; get buffer pointer
INY
LDA (SMPARAMLIST),Y
STA SMCMDLIST+1
INY
LDA (SMPARAMLIST),Y
STA SMCSCODE ; get status/control code
RTS
; Smartport Read Block command
;
; reads a 512-byte block using the ProDOS function
;
SMREADBLOCK:
JSR TRANSLATE
BCC @READ
RTS
@READ: LDX SLOT16
LDY SLOT
JMP READ ; call ProDOS read
; Smartport Write Block command
;
; writes a 512-byte block using the ProDOS function
;
SMWRITEBLOCK:
JSR TRANSLATE
BCC @WRITE
RTS
@WRITE: LDX SLOT16
LDY SLOT
JMP WRITE ; call ProDOS write
; Translates the Smartport unit number to a ProDOS device
; and prepares the block number
;
; Unit 0: entire chain, not supported
; Unit 1: this slot, drive 0
; Unit 2: this slot, drive 1
; Unit 3: phantom slot, drive 0
; Unit 4: phantom slot, drive 1
;
TRANSLATE: LDA DRVNUM,Y
BEQ @BADUNIT ; not supportd for unit 0
CMP #1
BEQ @UNIT1
CMP #2
BEQ @UNIT2
CMP #3
BEQ @UNIT3
CMP #4
BEQ @UNIT4
BRA @BADUNIT ; only 4 partitions are supported
@UNIT1: LDA SLOT16 ; this slot
BRA @STORE
@UNIT2: LDA SLOT16
ORA #$80 ; drive 1
BRA @STORE
@UNIT3: LDA SLOT16
DEC A ; phantom slot
BRA @STORE
@UNIT4: LDA SLOT16
DEC A ; phantom slot
ORA #$80 ; drive 1
@STORE: STA DSNUMBER ; store in ProDOS variable
LDY #2 ; get buffer pointer
LDA (SMPARAMLIST),Y
STA BUFFER
INY
LDA (SMPARAMLIST),Y
STA BUFFER+1
INY ; get block number
LDA (SMPARAMLIST),Y
STA BLOCKNUM
INY
LDA (SMPARAMLIST),Y
STA BLOCKNUM+1
INY
LDA (SMPARAMLIST),Y
BNE @BADBLOCK ; bit 23-16 need to be 0
CLC
RTS
@BADUNIT: LDA #ERR_BADUNIT
SEC
RTS
@BADBLOCK: LDA #ERR_BADBLOCK
SEC
RTS
; Smartport Format command
;
; supported, but doesn't do anything
; unit number must not be 0
;
SMFORMAT: LDA DRVNUM,Y
BEQ @ERROR
LDA #NO_ERR
CLC
RTS
@ERROR: LDA #ERR_BADUNIT
SEC
RTS
; Smartport Init comand
;
; supported, but doesn't do anything
; unit number must be 0
;
SMINIT: LDA DRVNUM,Y
CLC
BEQ @END ; error if not 0
LDA #ERR_BADUNIT
SEC
@END: RTS
; Smartport Open and Close commands
;
; supported for character devices, only
;
SMOPEN:
SMCLOSE: LDA #ERR_BADCMD
SEC
RTS
; Smartport Read Character and Write Character
;
; only 512-byte block operations are supported
;
SMREADCHAR:
SMWRITECHAR:
LDA #ERR_IOERR
SEC
RTS
; Required parameter counts for the commands
REQPARAMCOUNT:
.byt 3 ; 0 = status
.byt 3 ; 1 = read block
.byt 3 ; 2 = write block
.byt 1 ; 3 = format
.byt 3 ; 4 = control
.byt 1 ; 5 = init
.byt 1 ; 6 = open
.byt 1 ; 7 = close
.byt 4 ; 8 = read char
.byt 4 ; 9 = write char
; Command jump table
SPDISPATCH:
.word SMSTATUS
.word SMREADBLOCK
.word SMWRITEBLOCK
.word SMFORMAT
.word SMCONTROL
.word SMINIT
.word SMOPEN
.word SMCLOSE
.word SMREADCHAR
.word SMWRITECHAR
; Status 00 command data
STATUS00DATA:
.byt $40 ; no interrupts
.word $0000 ; unknown vendor
.word SMDRIVERVER ; driver version
.byt $00, $00 ; reserved
.assert(*-STATUS00DATA)=7, error, "STATUS00DATA must be 7 bytes long"
; Status 3 command data
STATUS3DATA:
.byt 16, "APPLE][SD " ; ID length and string, padded
.byt $02 ; hard disk
.byt $00 ; removable hard disk
.word SMDRIVERVER ; driver version
.assert (*-STATUS3DATA)=21, error, "STATUS3DATA must be 21 bytes long"