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