diff --git a/AppleIISd.bin b/AppleIISd.bin
index bed1614..7fd6750 100644
Binary files a/AppleIISd.bin and b/AppleIISd.bin differ
diff --git a/AppleIISd.bom.txt b/AppleIISd.bom.txt
index e0f0d2a..d38cb14 100644
--- a/AppleIISd.bom.txt
+++ b/AppleIISd.bom.txt
@@ -1,10 +1,8 @@
-Stückliste exportiert aus /Volumes/Data/Users/bluemeanie/Documents/Git/AppleIISd/Hardware/SD_A2.sch am 01.12.17 16:16
-
-Qty Value Device Package Parts Description MF MPN OC_FARNELL OC_NEWARK
+Qty Value Device Package Parts Description
1 A2-50PINSLOT1-3 A2-50PIN-SL1-3 ST1 Apple ][ Peripheral Card Connector
1 LEDSQR2X5 LED2X5 LED1 LED
-1 MA03-1 MA03-1 SV1 PIN HEADER unknown unknown
-1 MA06-1 MA06-1 SV2 PIN HEADER unknown unknown
+1 MA03-1 MA03-1 SV1 PIN HEADER
+1 MA06-1 MA06-1 SV2 PIN HEADER
6 100k R-EU_R0603 R0603 R3, R5, R6, R7, R9, R11 RESISTOR, European symbol
9 100n C-EUC0603K C0603K C1, C3, C4, C5, C6, C7, C11, C12, C13 CAPACITOR, European symbol
1 104H-TDA0-R 104H-TDA0-R 104H-TDA0-R U$2
diff --git a/AppleIISd.hex b/AppleIISd.hex
index b5a017a..6a00ac3 100644
--- a/AppleIISd.hex
+++ b/AppleIISd.hex
@@ -1,71 +1,71 @@
:10000000A220A200A203A23C0878A960853D203D61
:1000100000BABD00018DF807290F28853D0A0A0A9C
-:100020000A852BAA2CFFCFA000B9B7CAF008098017
-:10003000995007C810F32C61C0300520B7C9900B48
+:100020000A852BAA2CFFCFA000B9DECAF0080980F0
+:10003000995007C810F32C61C0300520DEC9900B21
:10004000ADF8073A854164406C40002000C8A90122
:100050008542A62B8643A9088545644464476446C7
-:100060002CFFCF20DDC9A9018542A62B8643A90A12
-:10007000854564446447A90185462CFFCF20DDC92E
+:100060002CFFCF2004CAA9018542A62B8643A90AEA
+:10007000854564446447A90185462CFFCF2004CA06
:10008000A62B4C0108D848A52B48A53D48A54048BB
:10009000A541480878A960853D203D00BABD000112
:1000A0008DF807290F28853D0A0A0A0A852BAA2CF4
-:1000B000FFCF20B7C99004A92F802CA9803C83C012
+:1000B000FFCF20DEC99004A92F802CA9803C83C0EB
:1000C000F020A542F00DC901F00EC902F00FA90100
-:1000D00038801420CFC9800F20DDC9800A2046CA8D
+:1000D00038801420F6C9800F2004CA800A206DCA17
:1000E00080052000C890DBBA9D05016885416885C0
:1000F0004068853D68852B6860000000FFFF97859C
:10010000A9039D81C0BD83C009019D83C0A9079D2E
:1001100082C0A00AA9FF9D80C03C81C010FB88D08E
-:10012000F5BD83C029FE9D83C0A9DE8540A9CA858F
-:100130004120F2C82006C9C901D041A9EA8540A9D9
-:10014000CA854120F2C8201FC9C901D032A9F6854D
-:1001500040A9CA854120F2C82006C9A9FC8540A94A
-:10016000CA854120F2C82006C9C901F0E0C900D003
-:100170000BBD83C009109D83C04CB9C84CE0C8A911
-:10018000F68540A9CA854120F2C8A9028540A9CBBD
-:10019000854120F2C82006C9C901F0E3C900D00397
-:1001A0004CB9C8A9E48540A9CA854120F2C82006F7
-:1001B000C9C901F0F6C900D027A9F08540A9CA85B0
-:1001C0004120F2C82006C9C900D015BD83C00980EE
-:1001D0009D83C0BD81C009049D81C018A00090030B
-:1001E00038A027BD83C009019D83C0A9009D82C09E
-:1001F00098605AA000B1409D80C03C81C010FBC8EF
-:10020000C00690F17A60A9FF9D80C03C81C010FBC0
-:10021000BD80C08980D0EF48A9FF9D80C068602064
-:1002200006C9485AA004A9FF9D80C03C81C010FBAC
-:10023000BD80C04888D0EFA43D6899F805689978DA
-:10024000056899F804689978047AA9FF9D80C068C8
-:1002500060DA5A8AA8A63DA5469DF805A5479D786F
-:1002600005A9009DF8049D7804A9802543F005A9FF
-:10027000019DF804A9103983C0D011A0091EF8050A
-:100280003E78053EF8043E780488D0F17AFA605A48
-:10029000A43D9D80C0B978049D80C0B9F8049D80BC
-:1002A000C0B978059D80C0B9F8059D80C0A9FF9DA3
-:1002B00080C02006C97A6048A9403C83C018F0017C
-:1002C00038686048A9203C83C018F001386860A9EC
-:1002D0000020C3C99002A92BA2FFA0FF602051C932
-:1002E000BD83C029FE9D83C0A951208FC9C900D0FC
-:1002F00050A9FF9D80C0BD80C0C9FED0F4BD81C0A3
-:1003000009109D81C0A9FF9D80C0A000BD80C09143
-:1003100044C8D0F8E645BD80C09144C8D0F8C64571
-:10032000BD80C0BD80C0BD80C0BD81C029EF9D81A2
-:10033000C018A9000848BD83C009019D83C0682872
-:100340006038A92780EE20C3C9B0672051C9BD839A
-:10035000C029FE9D83C0A958208FC9C900D04EA9CD
-:10036000FF9D80C0A9FE9D80C0A000B1449D80C0BB
-:10037000C8D0F8E645B1449D80C0C8D0F8C645A9AC
-:10038000FF9D80C09D80C09D80C0BD80C0291FC9C9
-:1003900005D01A18A9000848A9FF9D80C0BD80C0DB
-:1003A000F0F6BD83C009019D83C068286038A92785
-:1003B00080E438A92B80DF20204170706C655D5B84
-:1003C00053642076312E3020286329323031372093
-:1003D000466C6F7269616E20526569747A004000E4
-:1003E000000000954100000000F948000001AA87C4
-:1003F0005000000200FF7700000000656940000027
-:1004000000776900000000FF00000000000000000D
-:1004100000000000000000000000000000000000DC
-:1004200000000000000000000000000000000000CC
-:1004300000000000000000000000000000000000BC
+:10012000F5BD83C029FE9D83C0A9058540A9CB8567
+:10013000412016C9202AC9C901D065A9118540A945
+:10014000CB85412016C92043C9C901D056A43DB969
+:10015000F805C9AAD04AA91D8540A9CB854120161A
+:10016000C9202AC9A9298540A9CB85412016C920C3
+:100170002AC9C901F0E0C900D026A9238540A9CB2E
+:1001800085412016C92043C9C900D014A43DB978BF
+:10019000042940F048BD83C009109D83C04CEFC8BE
+:1001A0004C04C9A91D8540A9CB85412016C9A92F9A
+:1001B0008540A9CB85412016C9202AC9C901F0E391
+:1001C000C900D0034CDDC8A90B8540A9CB854120CF
+:1001D00016C9202AC9C901F0F6C900D027A9178578
+:1001E00040A9CB85412016C9202AC9C900D015BD18
+:1001F00083C009809D83C0BD81C009049D81C01852
+:10020000A000900338A027BD83C009019D83C0A929
+:10021000009D82C098605AA000B1409D80C03C8182
+:10022000C010FBC8C00690F17A60A9FF9D80C03C59
+:1002300081C010FBBD80C08980D0EF48A9FF9D80A0
+:10024000C06860202AC9485AA0044C52C9A9FF9D21
+:1002500080C03C81C010FBBD80C04888D0EFA43D69
+:100260006899F805689978056899F8046899780498
+:100270007AA9FF9D80C06860DA5A8AA8A63DA54683
+:100280009DF805A5479D7805A9009DF8049D780473
+:10029000A9802543F005A9019DF804A9103983C060
+:1002A000D011A0091EF8053E78053EF8043E7804FA
+:1002B00088D0F17AFA605AA43D9D80C0B978049D37
+:1002C00080C0B9F8049D80C0B978059D80C0B9F898
+:1002D000059D80C0A9FF9D80C0202AC97A6048A9D9
+:1002E000403C83C018F00138686048A9203C83C0B6
+:1002F00018F001386860A90020EAC99002A92BA271
+:10030000FFA0FF602078C9BD83C029FE9D83C0A9DE
+:100310005120B6C9C900D050A9FF9D80C0BD80C082
+:10032000C9FED0F4BD81C009109D81C0A9FF9D8088
+:10033000C0A000BD80C09144C8D0F8E645BD80C0D3
+:100340009144C8D0F8C645BD80C0BD80C0BD80C046
+:10035000BD81C029EF9D81C018A9000848BD83C098
+:1003600009019D83C068286038A92780EE20EAC96A
+:10037000B0672078C9BD83C029FE9D83C0A95820DD
+:10038000B6C9C900D04EA9FF9D80C0A9FE9D80C0FE
+:10039000A000B1449D80C0C8D0F8E645B1449D801E
+:1003A000C0C8D0F8C645A9FF9D80C09D80C09D8073
+:1003B000C0BD80C0291FC905D01A18A9000848A9C6
+:1003C000FF9D80C0BD80C0F0F6BD83C009019D8344
+:1003D000C068286038A92780E438A92B80DF202056
+:1003E0004170706C655D5B53642076312E3120283E
+:1003F00063293230313720466C6F7269616E20524A
+:100400006569747A0040000000009541000000001A
+:10041000F948000001AA875000000200FF770000A1
+:100420000000FF7A00000000FF69400000007769CB
+:1004300000000000FF0000000000000000000000BD
:1004400000000000000000000000000000000000AC
:10045000000000000000000000000000000000009C
:10046000000000000000000000000000000000008C
diff --git a/AppleIISd.vcxproj b/AppleIISd.vcxproj
index b3f344d..7b893e5 100644
--- a/AppleIISd.vcxproj
+++ b/AppleIISd.vcxproj
@@ -15,7 +15,10 @@
+
+
+
{9EA7EC3D-1771-420F-932F-231A35ED1200}
diff --git a/AppleIISd.vcxproj.filters b/AppleIISd.vcxproj.filters
index 2f91e44..5c8a181 100644
--- a/AppleIISd.vcxproj.filters
+++ b/AppleIISd.vcxproj.filters
@@ -10,6 +10,15 @@
+
+ src
+
+
+ src
+
+
+ src
+
diff --git a/ProFile.zip b/ProFile.zip
new file mode 100644
index 0000000..2e9d445
Binary files /dev/null and b/ProFile.zip differ
diff --git a/src/AppleIISd.inc b/src/AppleIISd.inc
new file mode 100644
index 0000000..1492ace
--- /dev/null
+++ b/src/AppleIISd.inc
@@ -0,0 +1,45 @@
+;*******************************
+;
+; Apple][Sd Firmware
+; Version 1.1
+; Defines
+;
+; (c) Florian Reitz, 2017
+;
+; X register usually contains SLOT16
+; Y register is used for counting or SLOT
+;
+;*******************************
+
+; Memory defines
+
+SLOT16 := $2B ; $s0 -> slot * 16
+SLOT := $3D ; $0s
+CMDLO := $40
+CMDHI := $41
+
+DCMD := $42 ; Command code
+BUFFER := $44 ; Buffer address
+BLOCK := $46 ; Block number
+
+R30 := $0478
+R31 := $04F8
+R32 := $0578
+R33 := $05F8
+CURSLOT := $07F8 ; $Cs
+OAPPLE := $C061 ; open apple key
+DATA := $C080
+CTRL := DATA+1
+DIV := DATA+2
+SS := DATA+3
+
+; Constants
+
+DUMMY = $FF
+FRX = $10 ; CTRL register
+ECE = $04
+SS0 = $01 ; SS register
+SDHC = $10
+WP = $20
+CD = $40
+INITED = $80
diff --git a/src/AppleIISd.s b/src/AppleIISd.s
index 28e6426..9e3c3a2 100644
--- a/src/AppleIISd.s
+++ b/src/AppleIISd.s
@@ -1,7 +1,8 @@
;*******************************
;
; Apple][Sd Firmware
-; Version 1.0
+; Version 1.1
+; Main source
;
; (c) Florian Reitz, 2017
;
@@ -10,43 +11,42 @@
;
;*******************************
-.define DEBUG 0
-
-; Memory defines
+.import GETR1
+.import GETR3
+.import SDCMD
+.import CARDDET
+.import STATUS
+.import READ
+.import WRITE
-SLOT16 := $2B ; $s0 -> slot * 16
-SLOT := $3D ; $0s
-CMDLO := $40
-CMDHI := $41
-
-DCMD := $42 ; Command code
-BUFFER := $44 ; Buffer address
-BLOCK := $46 ; Block number
-
-R30 := $0478
-R31 := $04F8
-R32 := $0578
-R33 := $05F8
-CURSLOT := $07F8 ; $Cs
-OAPPLE := $C061 ; open apple key
-DATA := $C080
-CTRL := DATA+1
-DIV := DATA+2
-SS := DATA+3
-
-; Constants
-
-DUMMY = $FF
-FRX = $10 ; CTRL register
-ECE = $04
-SS0 = $01 ; SS register
-SDHC = $10
-WP = $20
-CD = $40
-INITED = $80
+.include "AppleIISd.inc"
-; signature bytes
+;*******************************
+;
+; Signature bytes
+;
+; 65535 blocks
+; Removable media
+; Non-interruptable
+; 2 drives
+; Read, write and status allowed
+;
+;*******************************
+
+ .segment "SLOTID"
+ .dbyt $FFFF ; 65535 blocks
+ .byt $97 ; Status bits
+ .byt DRIVER
- STA $BF11,X
-@INSOUT: RTS
-
-
;*******************************
;
; Boot from SD card
;
;*******************************
- .else
+;@BOOT: CMP #0
+; BNE @NEXTSLOT ; init not successful
@BOOT: LDA #$01
STA DCMD ; load command
LDX SLOT16
@@ -188,7 +131,6 @@ INITED = $80
JSR READ ; call driver
LDX SLOT16
JMP $801 ; goto bootloader
- .endif
;*******************************
@@ -208,15 +150,6 @@ DRIVER: CLD
PHA
LDA CMDHI
PHA
-
- .if DEBUG
- LDA #$04
- STA SLOT
- LDA #$C4
- STA CURSLOT
- LDA #$40
-
- .else
PHP
SEI
LDA #$60 ; opcode for RTS
@@ -232,7 +165,6 @@ DRIVER: CLD
ASL A
ASL A
ASL A
- .endif
STA SLOT16 ; $s0
TAX ; X holds now SLOT16
@@ -252,10 +184,6 @@ DRIVER: CLD
BEQ @READ
CMP #2
BEQ @WRITE
- .if DEBUG
- CMP #$FF
- BEQ @TEST
- .endif
LDA #1 ; unknown command
SEC
BRA @RESTZP
@@ -266,10 +194,6 @@ DRIVER: CLD
BRA @RESTZP
@WRITE: JSR WRITE
BRA @RESTZP
- .if DEBUG
-@TEST: JSR TEST ; do device test
- BRA @RESTZP
- .endif
@INIT: JSR INIT
BCC @CMD ; init ok
@@ -288,13 +212,6 @@ DRIVER: CLD
RTS
-; Signature bytes
-
- .segment "SLOTID"
- .dbyt $FFFF ; 65535 blocks
- .byt $97 ; Status bits
- .byt CMD8
STA CMDHI
JSR SDCMD
- JSR GETR3
+ JSR GETR3 ; R7 is also 1+4 bytes
CMP #$01
BNE @SDV1 ; may be SD Ver. 1
-; check for $01aa match!
+ LDY SLOT ; check for $aa in R33
+ LDA R33,Y
+ CMP #$AA
+ BNE @ERROR1 ; error!
+
@SDV2: LDA #CMD55
STA CMDHI
JSR SDCMD
JSR GETR1
- LDA #ACMD4140
STA CMDHI
@@ -362,12 +283,25 @@ INIT: LDA #$03 ; set SPI mode 3
BEQ @SDV2 ; wait for ready
CMP #0
BNE @ERROR1 ; error!
-; send CMD58
+
; SD Ver. 2 initialized!
- LDA SS,X
+ LDA #CMD58
+ STA CMDHI
+ JSR SDCMD
+ JSR GETR3
+ CMP #0
+ BNE @ERROR1 ; error!
+ LDY SLOT
+ LDA R30,Y
+ AND #$40 ; check CCS
+ BEQ @BLOCKSZ
+
+ LDA SS,X ; card is SDHC
ORA #SDHC
STA SS,X
- JMP @BLOCKSZ
+ JMP @END
@ERROR1: JMP @IOERROR ; needed for far jump
@@ -431,445 +365,7 @@ INIT: LDA #$03 ; set SPI mode 3
RTS
-;*******************************
-;
-; Send SD command
-; Call with command in CMDHI and CMDLO
-;
-;*******************************
-
-SDCMD: PHY
- LDY #0
-@LOOP: LDA (CMDLO),Y
- STA DATA,X
-@WAIT: BIT CTRL,X ; TC is in N
- BPL @WAIT
- INY
- CPY #6
- BCC @LOOP
- PLY
- RTS
-
-
-;*******************************
-;
-; Get R1
-; R1 is in A
-;
-;*******************************
-
-GETR1: LDA #DUMMY
- STA DATA,X
-@WAIT: BIT CTRL,X
- BPL @WAIT
- LDA DATA,X ; get response
- BIT #$80
- BNE GETR1 ; wait for MSB=0
- PHA
- LDA #DUMMY
- STA DATA,X ; send another dummy
- PLA ; restore R1
- RTS
-
-;*******************************
-;
-; Get R3
-; R1 is in A
-; R3 is in scratchpad ram
-;
-;*******************************
-
-GETR3: JSR GETR1 ; get R1 first
- PHA ; save R1
- PHY ; save Y
- LDY #04 ; load counter
-@LOOP: LDA #DUMMY ; send dummy
- STA DATA,X
-@WAIT: BIT CTRL,X
- BPL @WAIT
- LDA DATA,X
- PHA
- DEY
- BNE @LOOP ; do 4 times
- LDY SLOT
- PLA
- STA R33,Y ; save R3
- PLA
- STA R32,Y
- PLA
- STA R31,Y
- PLA
- STA R30,Y
- PLY ; restore Y
- LDA #DUMMY
- STA DATA,X ; send another dummy
- PLA ; restore R1
- RTS
-
-
-;*******************************
-;
-; Calculate block address
-; Unit number is in $43 DSSS0000
-; Block no is in $46-47
-; Address is in R30-R33
-;
-;*******************************
-
-GETBLOCK: PHX ; save X
- PHY ; save Y
- TXA
- TAY ; SLOT16 is now in Y
- LDX SLOT
- LDA BLOCK ; store block num
- STA R33,X ; in R30-R33
- LDA BLOCK+1
- STA R32,X
- LDA #0
- STA R31,X
- STA R30,X
-
- LDA #$80 ; drive number
- AND $43
- BEQ @SDHC ; D1
- LDA #1 ; D2
- STA R31,X
-
-@SDHC: LDA #SDHC
- AND SS,Y ; if card is SDHC,
- BNE @END ; use block addressing
-
- LDY #9 ; ASL can't be used with Y
-@LOOP: ASL R33,X ; mul block num
- ROL R32,X ; by 512 to get
- ROL R31,X ; real address
- ROL R30,X
- DEY
- BNE @LOOP
-
- @END: PLY ; restore Y
- PLX ; restore X
- RTS
-
-
-;*******************************
-;
-; Send SD command
-; Cmd is in A
-;
-;*******************************
-
-COMMAND: PHY ; save Y
- LDY SLOT
- STA DATA,X ; send command
- LDA R30,Y ; get arg from R30 on
- STA DATA,X
- LDA R31,Y
- STA DATA,X
- LDA R32,Y
- STA DATA,X
- LDA R33,Y
- STA DATA,X
- LDA #DUMMY
- STA DATA,X ; dummy crc
- JSR GETR1
- PLY ; restore Y
- RTS
-
-
-;*******************************
-;
-; Check for card detect
-;
-; C Clear - card in slot
-; Set - no card in slot
-;
-;*******************************
-
-CARDDET: PHA
- LDA #CD ; 0: card in
- BIT SS,X ; 1: card out
- CLC
- BEQ @DONE ; card is in
- SEC ; card is out
-@DONE: PLA
- RTS
-
-
-;*******************************
-;
-; Check for write protect
-;
-; C Clear - card not protected
-; Set - card write protected
-;
-;*******************************
-
-WRPROT: PHA
- LDA #WP ; 0: write enabled
- BIT SS,X ; 1: write disabled
- CLC
- BEQ @DONE
- SEC
-@DONE: PLA
- RTS
-
-
-;*******************************
-;
-; Status request
-; $43 Unit number DSSS000
-; $44-45 Unused
-; $46-47 Unused
-;
-; C Clear - No error
-; Set - Error
-; A $00 - No error
-; $2B - Card write protected
-; $2F - No card inserted
-; X - Blocks avail (low byte)
-; Y - Blocks avail (high byte)
-;
-;*******************************
-
-STATUS: LDA #0 ; no error
- JSR WRPROT
- BCC @DONE
- LDA #$2B ; card write protected
-
-@DONE: LDX #$FF ; 32 MB partition
- LDY #$FF
- RTS
-
-
-;*******************************
-;
-; Read 512 byte block
-; $43 Unit number DSSS0000
-; $44-45 Address (LO/HI) of buffer
-; $46-47 Block number (LO/HI)
-;
-; C Clear - No error
-; Set - Error
-; A $00 - No error
-; $27 - Bad block number
-;
-;*******************************
-
-READ: JSR GETBLOCK ; calc block address
-
- LDA SS,X ; enable /CS
- AND #<~SS0
- STA SS,X
- LDA #$51 ; send CMD17
- JSR COMMAND ; send command
- CMP #0
- BNE @ERROR ; check for error
-
-@GETTOK: LDA #DUMMY ; get data token
- STA DATA,X
- LDA DATA,X ; get response
- CMP #$FE
- BNE @GETTOK ; wait for $FE
-
- LDA CTRL,X ; enable FRX
- ORA #FRX
- STA CTRL,X
- LDA #DUMMY
- STA DATA,X
-
- LDY #0
-@LOOP1: LDA DATA,X ; read data from card
- STA (BUFFER),Y
- INY
- BNE @LOOP1
- INC BUFFER+1 ; inc msb on page boundary
-@LOOP2: LDA DATA,X
- STA (BUFFER),Y
- INY
- BNE @LOOP2
- DEC BUFFER+1
-
-@CRC: LDA DATA,X ; read two bytes crc
- LDA DATA,X ; and ignore
- LDA DATA,X ; read a dummy byte
-
- LDA CTRL,X ; disable FRX
- AND #<~FRX
- STA CTRL,X
- CLC ; no error
- LDA #0
-
-@DONE: PHP
- PHA
- LDA SS,X
- ORA #SS0
- STA SS,X ; disable /CS
- PLA
- PLP
- RTS
-
-@ERROR: SEC ; an error occured
- LDA #$27
- BRA @DONE
-
-
-;*******************************
-;
-; Write 512 byte block
-; $43 Unit number DSSS0000
-; $44-45 Address (LO/HI) of buffer
-; $46-47 Block number (LO/HI)
-;
-; C Clear - No error
-; Set - Error
-; A $00 - No error
-; $27 - I/O error or bad block number
-; $2B - Card write protected
-;
-;*******************************
-
-WRITE: JSR WRPROT
- BCS @WPERROR ; card write protected
-
- JSR GETBLOCK ; calc block address
-
- LDA SS,X ; enable /CS
- AND #<~SS0
- STA SS,X
- LDA #$58 ; send CMD24
- JSR COMMAND ; send command
- CMP #0
- BNE @IOERROR ; check for error
-
- LDA #DUMMY
- STA DATA,X ; send dummy
- LDA #$FE
- STA DATA,X ; send data token
-
- LDY #0
-@LOOP1: LDA (BUFFER),Y
- STA DATA,X
- INY
- BNE @LOOP1
- INC BUFFER+1
-@LOOP2: LDA (BUFFER),Y
- STA DATA,X
- INY
- BNE @LOOP2
- DEC BUFFER+1
-
-@CRC: LDA #DUMMY
- STA DATA,X ; send 2 dummy crc bytes
- STA DATA,X
-
- STA DATA,X ; get data response
- LDA DATA,X
- AND #$1F
- CMP #$05
- BNE @IOERROR ; check for write error
- CLC ; no error
- LDA #0
-
-@DONE: PHP
- PHA
-@WAIT: LDA #DUMMY
- STA DATA,X ; wait for write cycle
- LDA DATA,X ; to complete
- BEQ @WAIT
-
- LDA SS,X ; disable /CS
- ORA #SS0
- STA SS,X
- PLA
- PLP
- RTS
-
-@IOERROR: SEC ; an error occured
- LDA #$27
- BRA @DONE
-
-@WPERROR: SEC
- LDA #$2B
- BRA @DONE
-
-
-
-;*******************************
-;
-; Test routine
-;
-;*******************************
-
- .if DEBUG
-TEST: LDA SLOT16
- PHA
- LDA SLOT
- PHA
-
-; get buffer
- LDA #2 ; get 512 byte buffer
- JSR $BEF5 ; call GETBUFR
- BCS @ERROR
- STA BUFFER+1
- STZ BUFFER
- PLA
- STA SLOT
- PLA
- STA SLOT16
-
-; fill buffer
- LDY #0
-@LOOP: TYA
- STA (BUFFER),Y
- INY
- BNE @LOOP
- INC BUFFER+1
-@LOOP1: TYA
- STA (BUFFER),Y
- INY
- BNE @LOOP1
- DEC BUFFER+1
-
- STZ BLOCK ; block number
- STZ BLOCK+1
- LDX SLOT16
-
-; write to card
- JSR WRITE
- BCS @ERROR
-
-; read from card
- JSR READ
- BCS @ERROR
-
-; check for errors
- LDY #0
-@LOOP2: TYA
- CMP (BUFFER),Y
- BNE @ERRCMP ; error in buffer
- INY
- BNE @LOOP2
- INC BUFFER+1
-@LOOP3: TYA
- CMP (BUFFER),Y
- BNE @ERRCMP
- INY
- BNE @LOOP3
- DEC BUFFER+1
-
-; free buffer
- JSR $BEF8 ; call FREEBUFR
- CLC
- LDA #0
- RTS
-
-@ERROR: BRK
-@ERRCMP: BRK
- .endif
-
-
-TEXT: .asciiz " Apple][Sd v1.0 (c)2017 Florian Reitz"
+TEXT: .asciiz " Apple][Sd v1.1 (c)2017 Florian Reitz"
CMD0: .byt $40, $00, $00
.byt $00, $00, $95
@@ -880,9 +376,10 @@ CMD8: .byt $48, $00, $00
CMD16: .byt $50, $00, $00
.byt $02, $00, $FF
CMD55: .byt $77, $00, $00
- .byt $00, $00, $65
+ .byt $00, $00, $FF
+CMD58: .byt $7A, $00, $00
+ .byt $00, $00, $FF
ACMD4140: .byt $69, $40, $00
.byt $00, $00, $77
ACMD410: .byt $69, $00, $00
.byt $00, $00, $FF
-
diff --git a/src/Helper.s b/src/Helper.s
new file mode 100644
index 0000000..4f7061c
--- /dev/null
+++ b/src/Helper.s
@@ -0,0 +1,208 @@
+;*******************************
+;
+; Apple][Sd Firmware
+; Version 1.1
+; Helper functions
+;
+; (c) Florian Reitz, 2017
+;
+; X register usually contains SLOT16
+; Y register is used for counting or SLOT
+;
+;*******************************
+
+.export COMMAND
+.export SDCMD
+.export GETBLOCK
+.export CARDDET
+.export WRPROT
+.export GETR1
+.export GETR3
+
+.include "AppleIISd.inc"
+.segment "EXTROM"
+
+
+;*******************************
+;
+; Send SD command
+; Call with command in CMDHI and CMDLO
+;
+;*******************************
+
+SDCMD: PHY
+ LDY #0
+@LOOP: LDA (CMDLO),Y
+ STA DATA,X
+@WAIT: BIT CTRL,X ; TC is in N
+ BPL @WAIT
+ INY
+ CPY #6
+ BCC @LOOP
+ PLY
+ RTS
+
+
+;*******************************
+;
+; Get R1
+; R1 is in A
+;
+;*******************************
+
+GETR1: LDA #DUMMY
+ STA DATA,X
+@WAIT: BIT CTRL,X
+ BPL @WAIT
+ LDA DATA,X ; get response
+ BIT #$80
+ BNE GETR1 ; wait for MSB=0
+ PHA
+ LDA #DUMMY
+ STA DATA,X ; send another dummy
+ PLA ; restore R1
+ RTS
+
+;*******************************
+;
+; Get R3 or R7
+; R1 is in A
+; R3 is in scratchpad ram
+;
+;*******************************
+
+GETR3: JSR GETR1 ; get R1 first
+ PHA ; save R1
+ PHY ; save Y
+ LDY #04 ; load counter
+ JMP @WAIT ; first byte is already there
+@LOOP: LDA #DUMMY ; send dummy
+ STA DATA,X
+@WAIT: BIT CTRL,X
+ BPL @WAIT
+ LDA DATA,X
+ PHA
+ DEY
+ BNE @LOOP ; do 4 times
+ LDY SLOT
+ PLA
+ STA R33,Y ; save R3
+ PLA
+ STA R32,Y
+ PLA
+ STA R31,Y
+ PLA
+ STA R30,Y ; R30 is MSB
+ PLY ; restore Y
+ LDA #DUMMY
+ STA DATA,X ; send another dummy
+ PLA ; restore R1
+ RTS
+
+
+;*******************************
+;
+; Calculate block address
+; Unit number is in $43 DSSS0000
+; Block no is in $46-47
+; Address is in R30-R33
+;
+;*******************************
+
+GETBLOCK: PHX ; save X
+ PHY ; save Y
+ TXA
+ TAY ; SLOT16 is now in Y
+ LDX SLOT
+ LDA BLOCK ; store block num
+ STA R33,X ; in R30-R33
+ LDA BLOCK+1
+ STA R32,X
+ LDA #0
+ STA R31,X
+ STA R30,X
+
+ LDA #$80 ; drive number
+ AND $43
+ BEQ @SDHC ; D1
+ LDA #1 ; D2
+ STA R31,X
+
+@SDHC: LDA #SDHC
+ AND SS,Y ; if card is SDHC,
+ BNE @END ; use block addressing
+
+ LDY #9 ; ASL can't be used with Y
+@LOOP: ASL R33,X ; mul block num
+ ROL R32,X ; by 512 to get
+ ROL R31,X ; real address
+ ROL R30,X
+ DEY
+ BNE @LOOP
+
+ @END: PLY ; restore Y
+ PLX ; restore X
+ RTS
+
+
+;*******************************
+;
+; Send SD command
+; Cmd is in A
+;
+;*******************************
+
+COMMAND: PHY ; save Y
+ LDY SLOT
+ STA DATA,X ; send command
+ LDA R30,Y ; get arg from R30 on
+ STA DATA,X
+ LDA R31,Y
+ STA DATA,X
+ LDA R32,Y
+ STA DATA,X
+ LDA R33,Y
+ STA DATA,X
+ LDA #DUMMY
+ STA DATA,X ; dummy crc
+ JSR GETR1
+ PLY ; restore Y
+ RTS
+
+
+;*******************************
+;
+; Check for card detect
+;
+; C Clear - card in slot
+; Set - no card in slot
+;
+;*******************************
+
+CARDDET: PHA
+ LDA #CD ; 0: card in
+ BIT SS,X ; 1: card out
+ CLC
+ BEQ @DONE ; card is in
+ SEC ; card is out
+@DONE: PLA
+ RTS
+
+
+;*******************************
+;
+; Check for write protect
+;
+; C Clear - card not protected
+; Set - card write protected
+;
+;*******************************
+
+WRPROT: PHA
+ LDA #WP ; 0: write enabled
+ BIT SS,X ; 1: write disabled
+ CLC
+ BEQ @DONE
+ SEC
+@DONE: PLA
+ RTS
diff --git a/src/ProDOS.s b/src/ProDOS.s
new file mode 100644
index 0000000..44f68ed
--- /dev/null
+++ b/src/ProDOS.s
@@ -0,0 +1,205 @@
+;*******************************
+;
+; Apple][Sd Firmware
+; Version 1.1
+; ProDOS functions
+;
+; (c) Florian Reitz, 2017
+;
+; X register usually contains SLOT16
+; Y register is used for counting or SLOT
+;
+;*******************************
+
+.export STATUS
+.export READ
+.export WRITE
+
+.import COMMAND
+.import SDCMD
+.import GETBLOCK
+.import WRPROT
+.import GETR1
+.import GETR3
+
+.include "AppleIISd.inc"
+.segment "EXTROM"
+
+
+;*******************************
+;
+; Status request
+; $43 Unit number DSSS000
+; $44-45 Unused
+; $46-47 Unused
+;
+; C Clear - No error
+; Set - Error
+; A $00 - No error
+; $2B - Card write protected
+; $2F - No card inserted
+; X - Blocks avail (low byte)
+; Y - Blocks avail (high byte)
+;
+;*******************************
+
+STATUS: LDA #0 ; no error
+ JSR WRPROT
+ BCC @DONE
+ LDA #$2B ; card write protected
+
+@DONE: LDX #$FF ; 32 MB partition
+ LDY #$FF
+ RTS
+
+
+;*******************************
+;
+; Read 512 byte block
+; $43 Unit number DSSS0000
+; $44-45 Address (LO/HI) of buffer
+; $46-47 Block number (LO/HI)
+;
+; C Clear - No error
+; Set - Error
+; A $00 - No error
+; $27 - Bad block number
+;
+;*******************************
+
+READ: JSR GETBLOCK ; calc block address
+
+ LDA SS,X ; enable /CS
+ AND #<~SS0
+ STA SS,X
+ LDA #$51 ; send CMD17
+ JSR COMMAND ; send command
+ CMP #0
+ BNE @ERROR ; check for error
+
+@GETTOK: LDA #DUMMY ; get data token
+ STA DATA,X
+ LDA DATA,X ; get response
+ CMP #$FE
+ BNE @GETTOK ; wait for $FE
+
+ LDA CTRL,X ; enable FRX
+ ORA #FRX
+ STA CTRL,X
+ LDA #DUMMY
+ STA DATA,X
+
+ LDY #0
+@LOOP1: LDA DATA,X ; read data from card
+ STA (BUFFER),Y
+ INY
+ BNE @LOOP1
+ INC BUFFER+1 ; inc msb on page boundary
+@LOOP2: LDA DATA,X
+ STA (BUFFER),Y
+ INY
+ BNE @LOOP2
+ DEC BUFFER+1
+
+@CRC: LDA DATA,X ; read two bytes crc
+ LDA DATA,X ; and ignore
+ LDA DATA,X ; read a dummy byte
+
+ LDA CTRL,X ; disable FRX
+ AND #<~FRX
+ STA CTRL,X
+ CLC ; no error
+ LDA #0
+
+@DONE: PHP
+ PHA
+ LDA SS,X
+ ORA #SS0
+ STA SS,X ; disable /CS
+ PLA
+ PLP
+ RTS
+
+@ERROR: SEC ; an error occured
+ LDA #$27
+ BRA @DONE
+
+
+;*******************************
+;
+; Write 512 byte block
+; $43 Unit number DSSS0000
+; $44-45 Address (LO/HI) of buffer
+; $46-47 Block number (LO/HI)
+;
+; C Clear - No error
+; Set - Error
+; A $00 - No error
+; $27 - I/O error or bad block number
+; $2B - Card write protected
+;
+;*******************************
+
+WRITE: JSR WRPROT
+ BCS @WPERROR ; card write protected
+
+ JSR GETBLOCK ; calc block address
+
+ LDA SS,X ; enable /CS
+ AND #<~SS0
+ STA SS,X
+ LDA #$58 ; send CMD24
+ JSR COMMAND ; send command
+ CMP #0
+ BNE @IOERROR ; check for error
+
+ LDA #DUMMY
+ STA DATA,X ; send dummy
+ LDA #$FE
+ STA DATA,X ; send data token
+
+ LDY #0
+@LOOP1: LDA (BUFFER),Y
+ STA DATA,X
+ INY
+ BNE @LOOP1
+ INC BUFFER+1
+@LOOP2: LDA (BUFFER),Y
+ STA DATA,X
+ INY
+ BNE @LOOP2
+ DEC BUFFER+1
+
+@CRC: LDA #DUMMY
+ STA DATA,X ; send 2 dummy crc bytes
+ STA DATA,X
+
+ STA DATA,X ; get data response
+ LDA DATA,X
+ AND #$1F
+ CMP #$05
+ BNE @IOERROR ; check for write error
+ CLC ; no error
+ LDA #0
+
+@DONE: PHP
+ PHA
+@WAIT: LDA #DUMMY
+ STA DATA,X ; wait for write cycle
+ LDA DATA,X ; to complete
+ BEQ @WAIT
+
+ LDA SS,X ; disable /CS
+ ORA #SS0
+ STA SS,X
+ PLA
+ PLP
+ RTS
+
+@IOERROR: SEC ; an error occured
+ LDA #$27
+ BRA @DONE
+
+@WPERROR: SEC
+ LDA #$2B
+ BRA @DONE