diff --git a/AppleIISd.lst b/AppleIISd.lst index f942664..7196222 100644 --- a/AppleIISd.lst +++ b/AppleIISd.lst @@ -1,670 +1,706 @@ 1 ******************************** 2 * - 3 * Initialize SD card - 4 * - 5 ******************************** - 6 - 7 XC - 8 ORG $8000 - 9 - 10 SLOT = $04 ; slot 4 - 11 DATA = $C0C0 ; slot 4 - 12 CTRL = DATA+1 - 13 DIV = DATA+2 - 14 SS = DATA+3 - 15 R30 = $0478 - 16 R31 = $04F8 - 17 R32 = $0578 - 18 R33 = $05F8 - 19 CMDLO = $FA - 20 CMDHI = $FB - 21 * - 22 FROM = $FA ; + $fb - 23 TO = $FC ; + $fd - 24 SIZE = $FE ; + $ff - 25 * - 26 SSNONE = $0F - 27 SS0 = $0E - 28 TC = $80 - 29 DUMMY = $FF - 30 - 31 - 32 ******************************** - 33 * - 34 * Install SD card driver - 35 * - 36 ******************************** + 3 * Apple][Sd Firmware + 4 * Version 0.5 + 5 * + 6 * (c) Florian Reitz, 2017 + 7 * + 8 * X register usually contains SLOT16 + 9 * Y register is used for counting or SLOT + 10 * + 11 ******************************** + 12 + 15-JUL-17 18:27 + 14 + 15 XC ; enable 65C02 code + 16 ORG $C800 ; Expansion ROM + 17 + 18 * Memory defines + 19 + 20 SLOT16 = $2B ; $s0 -> slot * 16 + 21 WORK = $3C + 22 SLOT = $3D ; $0s + 23 CMDLO = $40 + 24 CMDHI = $41 + 25 + 26 CURSLOT = $07F8 ; $Cs + 27 DATA = $C080 + 28 CTRL = DATA+1 + 29 DIV = DATA+2 + 30 SS = DATA+3 + 31 R30 = $0478 + 32 R31 = $04F8 + 33 R32 = $0578 + 34 R33 = $05F8 + 35 + 36 * Constants 37 - 38 * make room for the driver - 39 -8000: A9 04 40 GETBUF LDA #4 ; allocate 4 pages -8002: 20 F5 BE 41 JSR $BEF5 ; call GETBUFR -8005: B0 59 42 BCS ERROR ; did an error occur? -8007: 85 FD 43 STA TO+1 ; store buffer addr msb -8009: 8D 84 80 44 STA BUFMSB -800C: 64 FC 45 STZ TO ; store buffer addr lsb -800E: 9C 85 80 46 STZ BUFLSB -8011: A9 80 47 LDA #>DRIVER1 -8013: 85 FB 48 STA FROM+1 ; store from addr msb -8015: A9 8C 49 LDA #DRIVEND-DRIVER -801B: 85 FF 52 STA SIZE+1 ; store size msb -801D: A9 E4 53 LDA #CMD0 -9650: 85 FB 189 STA CMDHI -9652: 20 FD 96 190 JSR CMD -9655: 20 0F 97 191 JSR GETR1 ; get response -9658: C9 01 192 CMP #$01 -965A: D0 39 193 BNE ERROR1 ; error! - 194 -965C: A9 C6 195 LDA #CMD8 -9662: 85 FB 198 STA CMDHI -9664: 20 FD 96 199 JSR CMD -9667: 20 2C 97 200 JSR GETR3 -966A: C9 01 201 CMP #$01 -966C: D0 2A 202 BNE SDV1 ; may be SD Ver. 1 - 203 - 204 * check for $01aa match! -966E: A9 D2 205 SDV2 LDA #CMD55 -9674: 85 FB 208 STA CMDHI -9676: 20 FD 96 209 JSR CMD -9679: 20 0F 97 210 JSR GETR1 -967C: A9 D8 211 LDA #ACMD41_40 -9682: 85 FB 214 STA CMDHI -9684: 20 FD 96 215 JSR CMD -9687: 20 0F 97 216 JSR GETR1 -968A: C9 01 217 CMP #$01 -968C: F0 E0 218 BEQ SDV2 ; wait for ready -968E: C9 00 219 CMP #$00 -9690: D0 03 220 BNE ERROR1 ; error! - 221 * send CMD58 - 222 * SD Ver. 2 initialized! -9692: 4C D2 96 223 JMP BLOCKSZ - 224 -9695: 4C EE 96 225 ERROR1 JMP IOERROR ; needed for far jump - 226 -9698: A9 D2 227 SDV1 LDA #CMD55 -969E: 85 FB 230 STA CMDHI + + 160 * Signature bytes + 161 + 162 ORG $C8FC +C8FC: FF FF 163 DW $FFFF ; 65535 blocks +C8FE: 47 164 DB $47 ; Status bits +C8FF: 5F 165 DB #CMD0 +C92C: 85 41 204 STA CMDHI +C92E: 20 D9 C9 205 JSR CMD +C931: 20 ED C9 206 JSR GETR1 ; get response +C934: C9 01 207 CMP #$01 +C936: D0 39 208 BNE :ERROR1 ; error! + 209 +C938: A9 C6 210 LDA #CMD8 +C93E: 85 41 213 STA CMDHI +C940: 20 D9 C9 214 JSR CMD +C943: 20 08 CA 215 JSR GETR3 +C946: C9 01 216 CMP #$01 ===== Page 5 ===== -96A0: 20 FD 96 231 JSR CMD ; ignore response -96A3: A9 DE 232 LDA #ACMD41_0 -96A9: 85 FB 235 STA CMDHI -96AB: 20 FD 96 236 JSR CMD -96AE: 20 0F 97 237 JSR GETR1 -96B1: C9 01 238 CMP #$01 -96B3: F0 E3 239 BEQ SDV1 ; wait for ready -96B5: C9 00 240 CMP #$00 -96B7: D0 03 241 BNE MMC ; may be MMC card - 242 * SD Ver. 1 initialized! -96B9: 4C D2 96 243 JMP BLOCKSZ - 244 -96BC: A9 C0 245 MMC LDA #CMD1 -96C2: 85 FB 248 STA CMDHI -96C4: 20 FD 96 249 :LOOP JSR CMD -96C7: 20 0F 97 250 JSR GETR1 -96CA: C9 01 251 CMP #$01 -96CC: F0 F6 252 BEQ :LOOP ; wait for ready -96CE: C9 00 253 CMP #$00 -96D0: D0 1C 254 BNE IOERROR ; error! - 255 * MMC Ver. 3 initialized! - 256 -96D2: A9 CC 257 BLOCKSZ LDA #CMD16 -96D8: 85 FB 260 STA CMDHI -96DA: 20 FD 96 261 JSR CMD -96DD: 20 0F 97 262 JSR GETR1 -96E0: C9 00 263 CMP #$00 -96E2: D0 0A 264 BNE IOERROR ; error! - 265 -96E4: 18 266 END CLC ; all ok -96E5: A0 00 267 LDY #0 -96E7: 90 08 268 BCC END1 -96E9: 38 269 CDERROR SEC -96EA: A0 28 270 LDY #$28 ; no card error -96EC: B0 03 271 BCS END1 -96EE: 38 272 IOERROR SEC -96EF: A0 27 273 LDY #$27 ; init error -96F1: A9 0F 274 END1 LDA #SSNONE ; deselect card -96F3: 8D C3 C0 275 STA SS -96F6: A9 00 276 LDA #0 -96F8: 8D C2 C0 277 STA DIV -96FB: 98 278 TYA ; retval in A -96FC: 60 279 RTS - 280 - 281 - 282 ******************************** - 283 * - 284 * Send SD command - 285 * Call with command in CMDHI and CMDLO - 286 * - 287 ******************************** +C948: D0 2A 217 BNE :SDV1 ; may be SD Ver. 1 + 218 + 219 * check for $01aa match! +C94A: A9 D2 220 :SDV2 LDA #CMD55 +C950: 85 41 223 STA CMDHI +C952: 20 D9 C9 224 JSR CMD +C955: 20 ED C9 225 JSR GETR1 +C958: A9 D8 226 LDA #ACMD4140 +C95E: 85 41 229 STA CMDHI +C960: 20 D9 C9 230 JSR CMD +C963: 20 ED C9 231 JSR GETR1 +C966: C9 01 232 CMP #$01 +C968: F0 E0 233 BEQ :SDV2 ; wait for ready +C96A: C9 00 234 CMP #$00 +C96C: D0 03 235 BNE :ERROR1 ; error! + 236 * send CMD58 + 237 * SD Ver. 2 initialized! +C96E: 4C AE C9 238 JMP :BLOCKSZ + 239 +C971: 4C CA C9 240 :ERROR1 JMP :IOERROR ; needed for far jump + 241 +C974: A9 D2 242 :SDV1 LDA #CMD55 +C97A: 85 41 245 STA CMDHI +C97C: 20 D9 C9 246 JSR CMD ; ignore response +C97F: A9 DE 247 LDA #ACMD410 +C985: 85 41 250 STA CMDHI +C987: 20 D9 C9 251 JSR CMD +C98A: 20 ED C9 252 JSR GETR1 +C98D: C9 01 253 CMP #$01 +C98F: F0 E3 254 BEQ :SDV1 ; wait for ready +C991: C9 00 255 CMP #$00 +C993: D0 03 256 BNE :MMC ; may be MMC card + 257 * SD Ver. 1 initialized! +C995: 4C AE C9 258 JMP :BLOCKSZ + 259 +C998: A9 C0 260 :MMC LDA #CMD1 +C99E: 85 41 263 STA CMDHI +C9A0: 20 D9 C9 264 :LOOP1 JSR CMD +C9A3: 20 ED C9 265 JSR GETR1 +C9A6: C9 01 266 CMP #$01 +C9A8: F0 F6 267 BEQ :LOOP1 ; wait for ready +C9AA: C9 00 268 CMP #$00 +C9AC: D0 1C 269 BNE :IOERROR ; error! + 270 * MMC Ver. 3 initialized! + 271 +C9AE: A9 CC 272 :BLOCKSZ LDA #CMD16 +C9B4: 85 41 275 STA CMDHI +C9B6: 20 D9 C9 276 JSR CMD +C9B9: 20 ED C9 277 JSR GETR1 +C9BC: C9 00 278 CMP #$00 +C9BE: D0 0A 279 BNE :IOERROR ; error! + 280 +C9C0: 18 281 :END CLC ; all ok +C9C1: A2 00 282 LDX #0 +C9C3: 90 08 283 BCC :END1 +C9C5: 38 284 :CDERROR SEC +C9C6: A2 28 285 LDX #$28 ; no card error +C9C8: B0 03 286 BCS :END1 +C9CA: 38 287 :IOERROR SEC +C9CB: A2 27 288 LDX #$27 ; init error +C9CD: A9 0F 289 :END1 LDA #SSNONE ; deselect card +C9CF: 9D 83 C0 290 STA SS,X +C9D2: A9 00 291 LDA #0 ; set div to 2 +C9D4: 9D 82 C0 292 STA DIV,X +C9D7: 8A 293 TXA ; retval in A +C9D8: 60 294 RTS + 295 + 296 + 297 ******************************** + 298 * + 299 * Send SD command + 300 * Call with command in CMDHI and CMDLO 301 * - 302 * Get R1 - 303 * R1 is in A - 304 * - 305 ******************************** - 306 -970F: A9 FF 307 GETR1 LDA #DUMMY -9711: 8D C0 C0 308 STA DATA -9714: 2C C1 C0 309 :WAIT BIT CTRL -9717: 10 FB 310 BPL :WAIT -9719: AD C0 C0 311 LDA DATA ; get response -971C: 8D 7C 04 312 STA R30+SLOT ; save R1 -971F: 29 80 313 AND #$80 -9721: D0 EC 314 BNE GETR1 ; wait for MSB=0 -9723: A9 FF 315 LDA #DUMMY -9725: 8D C0 C0 316 STA DATA ; send another dummy -9728: AD 7C 04 317 LDA R30+SLOT ; restore R1 -972B: 60 318 RTS - 319 - 320 - 321 ******************************** - 322 * - 323 * Get R3 - 324 * R1 is in A - 325 * R3 is in scratchpad ram - 326 * - 327 ******************************** - 328 -972C: 20 0F 97 329 GETR3 JSR GETR1 ; get R1 first -972F: 48 330 PHA ; save R1 -9730: 5A 331 PHY ; save Y -9731: A0 04 332 LDY #04 -9733: A9 FF 333 :LOOP LDA #DUMMY ; send dummy -9735: 8D C0 C0 334 STA DATA -9738: 2C C1 C0 335 :WAIT BIT CTRL -973B: 10 FB 336 BPL :WAIT -973D: AD C0 C0 337 LDA DATA -9740: 48 338 PHA -9741: 88 339 DEY -9742: D0 EF 340 BNE :LOOP ; do 4 times -9744: 68 341 PLA -9745: 8D FC 05 342 STA R33+SLOT ; save R3 -9748: 68 343 PLA -9749: 8D 7C 05 344 STA R32+SLOT + 302 ******************************** + 303 +C9D9: 5A 304 CMD PHY +C9DA: A0 00 305 LDY #0 +C9DC: B1 40 306 :LOOP LDA (CMDLO),Y +C9DE: 9D 80 C0 307 STA DATA,X +C9E1: 3C 81 C0 308 :WAIT BIT CTRL,X ; TC is in N +C9E4: 10 FB 309 BPL :WAIT +C9E6: C8 310 INY +C9E7: C0 06 311 CPY #6 +C9E9: 90 F1 312 BCC :LOOP +C9EB: 7A 313 PLY +C9EC: 60 314 RTS + 315 + ===== Page 7 ===== - -974C: 68 345 PLA -974D: 8D FC 04 346 STA R31+SLOT -9750: 68 347 PLA -9751: 8D 7C 04 348 STA R30+SLOT -9754: 7A 349 PLY ; restore Y -9755: A9 FF 350 LDA #DUMMY -9757: 8D C0 C0 351 STA DATA ; send another dummy -975A: 68 352 PLA ; restore R1 -975B: 60 353 RTS - 354 - 355 - 356 ******************************** - 357 * - 358 * Status request - 359 * $43 Unt number DSSS000 - 360 * $44-45 Unused - 361 * $46-47 Unused - 362 * - 363 * C Clear - No error - 364 * Set - Error - 365 * A $00 - No error - 366 * $27 - I/O error - 367 * $28 - No card inserted / no init - 368 * $2B - Card write protected - 369 * X - Blocks avail (low byte) - 370 * Y - Blocks avail (high byte) - 371 * - 372 ******************************** - 373 -975C: 18 374 STATUS CLC ; no error -975D: A9 00 375 LDA #0 -975F: A2 FF 376 LDX #$FF ; 32 MB partition -9761: A0 FF 377 LDY #$FF -9763: 60 378 RTS - 379 - 380 * TODO: check for card detect and write protect! - 381 - 382 - 383 ******************************** - 384 * - 385 * Read 512 byte block - 386 * $43 Unit number DSSS0000 - 387 * $44-45 Address (LO/HI) of buffer - 388 * $46-47 Block number (LO/HI) - 389 * - 390 * C Clear - No error - 391 * Set - Error - 392 * A $00 - No error - 393 * $27 - Bad block number - 394 * $28 - No card inserted - 395 * - 396 ******************************** - 397 - 398 * TODO: check for card detect! - 399 -9764: A9 0E 400 READ LDA #SS0 ; enable /CS -9766: 8D C3 C0 401 STA SS + + 317 ******************************** + 318 * + 319 * Get R1 + 320 * R1 is in A + 321 * + 322 ******************************** + 323 +C9ED: A9 FF 324 GETR1 LDA #DUMMY +C9EF: 9D 80 C0 325 STA DATA,X +C9F2: 3C 81 C0 326 :WAIT BIT CTRL,X +C9F5: 10 FB 327 BPL :WAIT +C9F7: BD 80 C0 328 LDA DATA,X ; get response +C9FA: 85 3C 329 STA WORK ; save R1 +C9FC: 29 80 330 AND #$80 +C9FE: D0 ED 331 BNE GETR1 ; wait for MSB=0 +CA00: A9 FF 332 LDA #DUMMY +CA02: 9D 80 C0 333 STA DATA,X ; send another dummy +CA05: A5 3C 334 LDA WORK ; restore R1 +CA07: 60 335 RTS + 336 + 337 + 338 ******************************** + 339 * + 340 * Get R3 + 341 * R1 is in A + 342 * R3 is in scratchpad ram + 343 * + 344 ******************************** + 345 +CA08: 20 ED C9 346 GETR3 JSR GETR1 ; get R1 first +CA0B: 48 347 PHA ; save R1 +CA0C: 5A 348 PHY ; save Y +CA0D: A9 04 349 LDA #04 ; load counter +CA0F: 85 3C 350 STA WORK +CA11: A4 3D 351 LDY SLOT +CA13: A9 FF 352 :LOOP LDA #DUMMY ; send dummy +CA15: 9D 80 C0 353 STA DATA,X +CA18: 3C 81 C0 354 :WAIT BIT CTRL,X +CA1B: 10 FB 355 BPL :WAIT +CA1D: BD 80 C0 356 LDA DATA,X +CA20: 48 357 PHA +CA21: C6 3C 358 DEC WORK +CA23: D0 EE 359 BNE :LOOP ; do 4 times +CA25: 68 360 PLA +CA26: 99 F8 05 361 STA R33,Y ; save R3 +CA29: 68 362 PLA +CA2A: 99 78 05 363 STA R32,Y +CA2D: 68 364 PLA +CA2E: 99 F8 04 365 STA R31,Y +CA31: 68 366 PLA +CA32: 9D 78 04 367 STA R30,X +CA35: 7A 368 PLY ; restore Y +CA36: A9 FF 369 LDA #DUMMY +CA38: 9D 80 C0 370 STA DATA,X ; send another dummy +CA3B: 68 371 PLA ; restore R1 +CA3C: 60 372 RTS + 373 ===== Page 8 ===== - 402 -9769: A5 46 403 LDA $46 ; store block num -976B: 8D FC 05 404 STA R33+SLOT ; in R30-R33 -976E: A5 47 405 LDA $47 -9770: 8D 7C 05 406 STA R32+SLOT -9773: 9C FC 04 407 STZ R31+SLOT -9776: 9C 7C 04 408 STZ R30+SLOT -9779: A0 09 409 LDY #9 -977B: 0E FC 05 410 :LOOP ASL R33+SLOT ; mul block num -977E: 2E 7C 05 411 ROL R32+SLOT ; by 512 to get -9781: 2E FC 04 412 ROL R31+SLOT ; real address -9784: 2E 7C 04 413 ROL R30+SLOT -9787: 88 414 DEY -9788: D0 F1 415 BNE :LOOP + 374 + 375 ******************************** + 376 * + 377 * Status request + 378 * $43 Unt number DSSS000 + 379 * $44-45 Unused + 380 * $46-47 Unused + 381 * + 382 * C Clear - No error + 383 * Set - Error + 384 * A $00 - No error + 385 * $27 - I/O error + 386 * $28 - No card inserted / no init + 387 * $2B - Card write protected + 388 * x - Blocks avail (low byte) + 389 * y - Blocks avail (high byte) + 390 * + 391 ******************************** + 392 +CA3D: 18 393 STATUS CLC ; no error +CA3E: A9 00 394 LDA #0 +CA40: A2 FF 395 LDX #$FF ; 32 MB partition +CA42: A0 FF 396 LDY #$FF +CA44: 60 397 RTS + 398 + 399 * TODO: check for card detect and write protect! + 400 + 401 + 402 ******************************** + 403 * + 404 * Read 512 byte block + 405 * $43 Unit number DSSS0000 + 406 * $44-45 Address (LO/HI) of buffer + 407 * $46-47 Block number (LO/HI) + 408 * + 409 * C Clear - No error + 410 * Set - Error + 411 * A $00 - No error + 412 * $27 - Bad block number + 413 * $28 - No card inserted + 414 * + 415 ******************************** 416 -978A: A9 51 417 LDA #$51 ; send CMD17 -978C: 8D C0 C0 418 STA DATA -978F: 2C C1 C0 419 :WAIT BIT CTRL -9792: 10 FB 420 BPL :WAIT -9794: AD 7C 04 421 :ARG LDA R30+SLOT ; get arg from R30 on -9797: 8D C0 C0 422 STA DATA -979A: 2C C1 C0 423 :WAIT1 BIT CTRL -979D: 10 FB 424 BPL :WAIT1 -979F: AD FC 04 425 LDA R31+SLOT -97A2: 8D C0 C0 426 STA DATA -97A5: 2C C1 C0 427 :WAIT11 BIT CTRL -97A8: 10 FB 428 BPL :WAIT11 -97AA: AD 7C 05 429 LDA R32+SLOT -97AD: 8D C0 C0 430 STA DATA -97B0: 2C C1 C0 431 :WAIT12 BIT CTRL -97B3: 10 FB 432 BPL :WAIT12 -97B5: AD FC 05 433 LDA R33+SLOT -97B8: 8D C0 C0 434 STA DATA -97BB: 2C C1 C0 435 :WAIT13 BIT CTRL -97BE: 10 FB 436 BPL :WAIT13 -97C0: A9 FF 437 LDA #DUMMY -97C2: 8D C0 C0 438 STA DATA ; dummy crc -97C5: 2C C1 C0 439 :WAIT2 BIT CTRL -97C8: 10 FB 440 BPL :WAIT2 -97CA: A9 FF 441 :GETR1 LDA #DUMMY -97CC: 8D C0 C0 442 STA DATA ; get R1 -97CF: 2C C1 C0 443 :WAIT3 BIT CTRL -97D2: 10 FB 444 BPL :WAIT3 -97D4: AD C0 C0 445 LDA DATA ; get response - 446 * - 447 * TODO: check for error! - 448 * -97D7: C9 FE 449 CMP #$FE -97D9: D0 EF 450 BNE :GETR1 ; wait for $FE - 451 -97DB: A2 02 452 LDX #2 ; read data from card -97DD: A0 00 453 :LOOPX LDY #0 -97DF: A9 FF 454 :LOOPY LDA #DUMMY -97E1: 8D C0 C0 455 STA DATA -97E4: 2C C1 C0 456 :WAIT4 BIT CTRL -97E7: 10 FB 457 BPL :WAIT4 -97E9: AD C0 C0 458 LDA DATA + 417 * TODO: check for card detect! + 418 +CA45: A9 0E 419 READ LDA #SS0 ; enable /CS +CA47: 9D 83 C0 420 STA SS,X + 421 +CA4A: 5A 422 PHY ; save Y +CA4B: A4 3D 423 LDY SLOT +CA4D: A5 46 424 LDA $46 ; store block num +CA4F: 99 F8 05 425 STA R33,Y ; in R30-R33 +CA52: A5 47 426 LDA $47 +CA54: 99 78 05 427 STA R32,Y +CA57: A9 00 428 LDA #0 +CA59: 99 F8 04 429 STA R31,Y +CA5C: 99 78 04 430 STA R30,Y ===== Page 9 ===== -97EC: 92 44 459 STA ($44) -97EE: E6 44 460 INC $44 -97F0: D0 02 461 BNE :INY -97F2: E6 45 462 INC $45 ; inc msb on page boundary -97F4: C8 463 :INY INY -97F5: D0 E8 464 BNE :LOOPY -97F7: CA 465 DEX -97F8: D0 E3 466 BNE :LOOPX - 467 -97FA: 20 2C 97 468 :OK JSR GETR3 ; read 2 bytes crc -97FD: A9 0F 469 LDA #SSNONE -97FF: 8D C3 C0 470 STA SS ; disable /CS -9802: 18 471 CLC ; no error -9803: A9 00 472 LDA #$00 -9805: 60 473 RTS - 474 -9806: A9 0F 475 :ERROR LDA #SSNONE -9808: 8D C3 C0 476 STA SS ; disable /CS -980B: 38 477 SEC ; an error occured -980C: A9 27 478 LDA #$27 -980E: 60 479 RTS - 480 - 481 - 482 ******************************** - 483 * - 484 * Write 512 byte block - 485 * $43 Unit number DSSS000 - 486 * $44-45 Address (LO/HI) of buffer - 487 * $46-47 Block number (LO/HI) - 488 * - 489 * C Clear - No error - 490 * Set - Error - 491 * A $00 - No error - 492 * $27 - Bad block number - 493 * $28 - No card inserted - 494 * - 495 ******************************** - 496 - 497 * TODO: check for card detect and write protect! - 498 -980F: A9 0E 499 WRITE LDA #SS0 ; enable /CS -9811: 8D C3 C0 500 STA SS - 501 -9814: A5 46 502 LDA $46 ; store block num -9816: 8D FC 05 503 STA R33+SLOT -9819: A5 47 504 LDA $47 -981B: 8D 7C 05 505 STA R32+SLOT -981E: 9C FC 04 506 STZ R31+SLOT -9821: 9C 7C 04 507 STZ R30+SLOT -9824: A0 09 508 LDY #9 -9826: 0E FC 05 509 :LOOP ASL R33+SLOT ; mul block num -9829: 2E 7C 05 510 ROL R32+SLOT ; by 512 to get -982C: 2E FC 04 511 ROL R31+SLOT ; real address -982F: 2E 7C 04 512 ROL R30+SLOT -9832: 88 513 DEY -9833: D0 F1 514 BNE :LOOP - 515 + 431 +CA5F: DA 432 PHX +CA60: 5A 433 PHY +CA61: A0 09 434 LDY #9 +CA63: A6 3D 435 LDX SLOT ; ASL can't be done with Y +CA65: 1E F8 05 436 :LOOP ASL R33,X ; mul block num +CA68: 3E 78 05 437 ROL R32,X ; by 512 to get +CA6B: 3E F8 04 438 ROL R31,X ; real address +CA6E: 3E 78 04 439 ROL R30,X +CA71: 88 440 DEY +CA72: D0 F1 441 BNE :LOOP +CA74: 7A 442 PLY +CA75: FA 443 PLX + 444 +CA76: A9 51 445 LDA #$51 ; send CMD17 +CA78: 9D 80 C0 446 STA DATA,X +CA7B: 3C 81 C0 447 :WAIT BIT CTRL,X +CA7E: 10 FB 448 BPL :WAIT +CA80: B9 78 04 449 :ARG LDA R30,Y ; get arg from R30 on +CA83: 9D 80 C0 450 STA DATA,X +CA86: 3C 81 C0 451 :WAIT1 BIT CTRL,X +CA89: 10 FB 452 BPL :WAIT1 +CA8B: B9 F8 04 453 LDA R31,Y +CA8E: 9D 80 C0 454 STA DATA,X +CA91: 3C 81 C0 455 :WAIT11 BIT CTRL,X +CA94: 10 FB 456 BPL :WAIT11 +CA96: B9 78 05 457 LDA R32,Y +CA99: 9D 80 C0 458 STA DATA,X +CA9C: 3C 81 C0 459 :WAIT12 BIT CTRL,X +CA9F: 10 FB 460 BPL :WAIT12 +CAA1: B9 F8 05 461 LDA R33,Y +CAA4: 9D 80 C0 462 STA DATA,X +CAA7: 3C 81 C0 463 :WAIT13 BIT CTRL,X +CAAA: 10 FB 464 BPL :WAIT13 +CAAC: A9 FF 465 LDA #DUMMY +CAAE: 9D 80 C0 466 STA DATA,X ; dummy crc +CAB1: 3C 81 C0 467 :WAIT2 BIT CTRL,X +CAB4: 10 FB 468 BPL :WAIT2 +CAB6: A9 FF 469 :GETR1 LDA #DUMMY +CAB8: 9D 80 C0 470 STA DATA,X ; get R1 +CABB: 3C 81 C0 471 :WAIT3 BIT CTRL,X +CABE: 10 FB 472 BPL :WAIT3 +CAC0: BD 80 C0 473 LDA DATA,X ; get response + 474 * + 475 * TODO: check for error! + 476 * +CAC3: C9 FE 477 CMP #$FE +CAC5: D0 EF 478 BNE :GETR1 ; wait for $FE + 479 +CAC7: 5A 480 PHY +CAC8: A0 02 481 LDY #2 ; read data from card +CACA: 64 3C 482 :LOOPY STZ WORK +CACC: A9 FF 483 :LOOPW LDA #DUMMY +CACE: 9D 80 C0 484 STA DATA,X +CAD1: 3C 81 C0 485 :WAIT4 BIT CTRL,X +CAD4: 10 FB 486 BPL :WAIT4 +CAD6: BD 80 C0 487 LDA DATA,X ===== Page 10 ===== -9835: A9 58 516 LDA #$58 ; send CMD24 -9837: 8D C0 C0 517 STA DATA -983A: 2C C1 C0 518 :WAIT BIT CTRL -983D: 10 FB 519 BPL :WAIT -983F: AD 7C 04 520 :ARG LDA R30+SLOT ; get arg from R30 on -9842: 8D C0 C0 521 STA DATA -9845: 2C C1 C0 522 :WAIT1 BIT CTRL -9848: 10 FB 523 BPL :WAIT1 -984A: AD FC 04 524 LDA R31+SLOT -984D: 8D C0 C0 525 STA DATA -9850: 2C C1 C0 526 :WAIT11 BIT CTRL -9853: 10 FB 527 BPL :WAIT11 -9855: AD 7C 05 528 LDA R32+SLOT -9858: 8D C0 C0 529 STA DATA -985B: 2C C1 C0 530 :WAIT12 BIT CTRL -985E: 10 FB 531 BPL :WAIT12 -9860: AD FC 05 532 LDA R33+SLOT -9863: 8D C0 C0 533 STA DATA -9866: 2C C1 C0 534 :WAIT13 BIT CTRL -9869: 10 FB 535 BPL :WAIT13 -986B: A9 FF 536 LDA #DUMMY -986D: 8D C0 C0 537 STA DATA ; dummy crc -9870: 2C C1 C0 538 :WAIT2 BIT CTRL -9873: 10 FB 539 BPL :WAIT2 -9875: A9 FF 540 :GETR1 LDA #DUMMY -9877: 8D C0 C0 541 STA DATA ; get R1 -987A: 2C C1 C0 542 :WAIT3 BIT CTRL -987D: 10 FB 543 BPL :WAIT3 -987F: AD C0 C0 544 LDA DATA : get response - 545 * - 546 * TODO: check for error! - 547 * -9882: C9 FE 548 CMP #$FE -9884: D0 EF 549 BNE :GETR1 ; wait for $FE -9886: A2 02 550 LDX #2 ; send data to card -9888: A0 00 551 :LOOPX LDY #0 -988A: B2 44 552 :LOOPY LDA ($44) -988C: 8D C0 C0 553 STA DATA -988F: 2C C1 C0 554 :WAIT4 BIT CTRL -9892: 10 FB 555 BPL :WAIT4 -9894: E6 44 556 INC $44 -9896: D0 02 557 BNE :INY -9898: E6 45 558 INC $45 ; inc msbon page boundary -989A: C8 559 :INY INY -989B: D0 ED 560 BNE :LOOPY -989D: CA 561 DEX -989E: D0 E8 562 BNE :LOOPX - 563 -98A0: A0 02 564 LDY #2 ; send 2 dummy crc bytes -98A2: 8D C0 C0 565 :CRC STA DATA -98A5: 2C C1 C0 566 :WAIT5 BIT CTRL -98A8: 10 FB 567 BPL :WAIT5 -98AA: 88 568 DEY -98AB: D0 F5 569 BNE :CRC - 570 -98AD: A9 0F 571 :OK LDA #SSNONE ; disable /CS -98AF: 8D C3 C0 572 STA SS +CAD9: 92 44 488 STA ($44) +CADB: E6 44 489 INC $44 +CADD: D0 02 490 BNE :INW +CADF: E6 45 491 INC $45 ; inc msb on page boundary +CAE1: E6 3C 492 :INW INC WORK +CAE3: D0 E7 493 BNE :LOOPW +CAE5: 88 494 DEY +CAE6: D0 E2 495 BNE :LOOPY +CAE8: 7A 496 PLY + 497 +CAE9: 20 08 CA 498 :OK JSR GETR3 ; read 2 bytes crc +CAEC: A9 0F 499 LDA #SSNONE +CAEE: 9D 83 C0 500 STA SS,X ; disable /CS +CAF1: 18 501 CLC ; no error +CAF2: A9 00 502 LDA #$00 +CAF4: 7A 503 PLY ; restore Y +CAF5: 60 504 RTS + 505 +CAF6: A9 0F 506 :ERROR LDA #SSNONE +CAF8: 9D 83 C0 507 STA SS,X ; disable /CS +CAFB: 38 508 SEC ; an error occured +CAFC: A9 27 509 LDA #$27 +CAFE: 7A 510 PLY ; restore Y +CAFF: 60 511 RTS + 512 + 513 + 514 ******************************** + 515 * + 516 * Write 512 byte block + 517 * $43 Unit number DSSS000 + 518 * $44-45 Address (LO/HI) of buffer + 519 * $46-47 Block number (LO/HI) + 520 * + 521 * C Clear - No error + 522 * Set - Error + 523 * A $00 - No error + 524 * $27 - Bad block number + 525 * $28 - No card inserted + 526 * + 527 ******************************** + 528 + 529 * TODO: check for card detect and write protect! + 530 +CB00: A9 0E 531 WRITE LDA #SS0 ; enable /CS +CB02: 9D 83 C0 532 STA SS,X + 533 +CB05: 5A 534 PHY +CB06: A4 3D 535 LDY SLOT +CB08: A5 46 536 LDA $46 ; store block num +CB0A: 99 F8 05 537 STA R33,Y +CB0D: A5 47 538 LDA $47 +CB0F: 99 78 05 539 STA R32,Y +CB12: A9 00 540 LDA #0 +CB14: 99 F8 04 541 STA R31,Y +CB17: 99 78 04 542 STA R30,Y + 543 +CB1A: DA 544 PHX ===== Page 11 ===== -98B2: 18 573 CLC ; no error -98B3: A9 00 574 LDA #0 -98B5: 60 575 RTS - 576 - 577 - 578 ******************************** - 579 * - 580 * Format - 581 * not supported! - 582 * - 583 ******************************** - 584 -98B6: 38 585 FORMAT SEC -98B7: A9 01 586 LDA #$01 ; invalid command -98B9: 60 587 RTS - 588 - 589 - 590 -98BA: 40 00 00 591 CMD0 HEX 400000000095 -98BD: 00 00 95 -98C0: 41 00 00 592 CMD1 HEX 4100000000F9 -98C3: 00 00 F9 -98C6: 48 00 00 593 CMD8 HEX 48000001AA87 -98C9: 01 AA 87 -98CC: 50 00 00 594 CMD16 HEX 5000000200FF -98CF: 02 00 FF -98D2: 77 00 00 595 CMD55 HEX 770000000065 -98D5: 00 00 65 -98D8: 69 40 00 596 ACMD41_40 HEX 694000000077 -98DB: 00 00 77 -98DE: 69 00 00 597 ACMD41_0 HEX 6900000000FF -98E1: 00 00 FF - 598 - 599 DRIVEND = * +CB1B: 5A 545 PHY +CB1C: A0 09 546 LDY #9 +CB1E: A6 3D 547 LDX SLOT ; ASL can't be done with Y +CB20: 1E F8 05 548 :LOOP ASL R33,X ; mul block num +CB23: 3E 78 05 549 ROL R32,X ; by 512 to get +CB26: 3E F8 04 550 ROL R31,X ; real address +CB29: 3E 78 04 551 ROL R30,X +CB2C: 88 552 DEY +CB2D: D0 F1 553 BNE :LOOP +CB2F: 7A 554 PLY +CB30: FA 555 PLX + 556 +CB31: A9 58 557 LDA #$58 ; send CMD24 +CB33: 9D 80 C0 558 STA DATA,X +CB36: 3C 81 C0 559 :WAIT BIT CTRL,X +CB39: 10 FB 560 BPL :WAIT +CB3B: B9 78 04 561 :ARG LDA R30,Y ; get arg from R30 on +CB3E: 9D 80 C0 562 STA DATA,X +CB41: 3C 81 C0 563 :WAIT1 BIT CTRL,X +CB44: 10 FB 564 BPL :WAIT1 +CB46: B9 F8 04 565 LDA R31,Y +CB49: 9D 80 C0 566 STA DATA,X +CB4C: 3C 81 C0 567 :WAIT11 BIT CTRL,X +CB4F: 10 FB 568 BPL :WAIT11 +CB51: B9 78 05 569 LDA R32,Y +CB54: 9D 80 C0 570 STA DATA,X +CB57: 3C 81 C0 571 :WAIT12 BIT CTRL,X +CB5A: 10 FB 572 BPL :WAIT12 +CB5C: B9 F8 05 573 LDA R33,Y +CB5F: 9D 80 C0 574 STA DATA,X +CB62: 3C 81 C0 575 :WAIT13 BIT CTRL,X +CB65: 10 FB 576 BPL :WAIT13 +CB67: A9 FF 577 LDA #DUMMY +CB69: 9D 80 C0 578 STA DATA,X ; dummy crc +CB6C: 3C 81 C0 579 :WAIT2 BIT CTRL,X +CB6F: 10 FB 580 BPL :WAIT2 +CB71: A9 FF 581 :GETR1 LDA #DUMMY +CB73: 9D 80 C0 582 STA DATA,X ; get R1 +CB76: 3C 81 C0 583 :WAIT3 BIT CTRL,X +CB79: 10 FB 584 BPL :WAIT3 +CB7B: BD 80 C0 585 LDA DATA,X ; get response + 586 * + 587 * TODO: check for error! + 588 * +CB7E: C9 FE 589 CMP #$FE +CB80: D0 EF 590 BNE :GETR1 ; wait for $FE + 591 +CB82: 5A 592 PHY +CB83: A0 02 593 LDY #2 ; send data to card +CB85: 64 3C 594 :LOOPY STZ WORK +CB87: B2 44 595 :LOOPW LDA ($44) +CB89: 9D 80 C0 596 STA DATA,X +CB8C: 3C 81 C0 597 :WAIT4 BIT CTRL,X +CB8F: 10 FB 598 BPL :WAIT4 +CB91: E6 44 599 INC $44 +CB93: D0 02 600 BNE :INW +CB95: E6 45 601 INC $45 ; inc msb on page boundary + ===== Page 12 ===== + +CB97: E6 3C 602 :INW INC WORK +CB99: D0 EC 603 BNE :LOOPW +CB9B: 88 604 DEY +CB9C: D0 E7 605 BNE :LOOPY + 606 +CB9E: A0 02 607 LDY #2 ; send 2 dummy crc bytes +CBA0: 9D 80 C0 608 :CRC STA DATA,X +CBA3: 3C 81 C0 609 :WAIT5 BIT CTRL,X +CBA6: 10 FB 610 BPL :WAIT5 +CBA8: 88 611 DEY +CBA9: D0 F5 612 BNE :CRC +CBAB: 7A 613 PLY + 614 +CBAC: A9 0F 615 :OK LDA #SSNONE ; disable /CS +CBAE: 9D 83 C0 616 STA SS,X +CBB1: 18 617 CLC ; no error +CBB2: A9 00 618 LDA #0 +CBB4: 7A 619 PLY +CBB5: 60 620 RTS + 621 + 622 + 623 ******************************** + 624 * + 625 * Format + 626 * not supported! + 627 * + 628 ******************************** + 629 +CBB6: 38 630 FORMAT SEC +CBB7: A9 01 631 LDA #$01 ; invalid command +CBB9: 60 632 RTS + 633 + 634 + 635 +CBBA: 40 00 00 636 CMD0 HEX 400000 +CBBD: 00 00 95 637 HEX 000095 +CBC0: 41 00 00 638 CMD1 HEX 410000 +CBC3: 00 00 F9 639 HEX 0000F9 +CBC6: 48 00 00 640 CMD8 HEX 480000 +CBC9: 01 AA 87 641 HEX 01AA87 +CBCC: 50 00 00 642 CMD16 HEX 500000 +CBCF: 02 00 FF 643 HEX 0200FF +CBD2: 77 00 00 644 CMD55 HEX 770000 +CBD5: 00 00 65 645 HEX 000065 +CBD8: 69 40 00 646 ACMD4140 HEX 694000 +CBDB: 00 00 77 647 HEX 000077 +CBDE: 69 00 00 648 ACMD410 HEX 690000 +CBE1: 00 00 FF 649 HEX 0000FF + + ===== Page 13 ===== + ---End assembly, 880 bytes, Errors: 0 +--End assembly, 900 bytes, Errors: 0 Symbol table - alphabetical order: - ACMD41_0=$98DE ACMD41_40=$98D8 BLOCKSZ =$96D2 BUFLSB =$8085 - BUFMSB =$8084 ? CDERROR =$96E9 CMD =$96FD CMD0 =$98BA - CMD1 =$98C0 CMD16 =$98CC CMD55 =$98D2 CMD8 =$98C6 - CMDHI =$FB CMDLO =$FA CTRL =$C0C1 DATA =$C0C0 - DIV =$C0C2 DRIVEND =$98E4 DRIVER =$9600 DRIVER1 =$808C - DUMMY =$FF ? END =$96E4 END1 =$96F1 ERROR =$8060 - ERROR1 =$9695 FORMAT =$98B6 FROM =$FA ? GETBUF =$8000 - GETR1 =$970F GETR3 =$972C INIT =$9626 INSLP =$804D - INSLP2 =$8063 INSOUT =$8083 ? INSTALL =$804A IOERROR =$96EE - MMC =$96BC ? MOVEUP =$8021 MU1 =$8037 MU2 =$803E - MU3 =$8042 R30 =$0478 R31 =$04F8 R32 =$0578 - R33 =$05F8 READ =$9764 SDV1 =$9698 SDV2 =$966E - SIZE =$FE SLOT =$04 SS =$C0C3 SS0 =$0E - SSNONE =$0F STATUS =$975C ? TC =$80 TO =$FC - WRITE =$980F - - ===== Page 12 ===== - + ACMD410 =$CBDE ACMD4140=$CBD8 CMD =$C9D9 CMD0 =$CBBA + CMD1 =$CBC0 CMD16 =$CBCC CMD55 =$CBD2 CMD8 =$CBC6 + CMDHI =$41 CMDLO =$40 CTRL =$C081 CURSLOT =$07F8 + DATA =$C080 DIV =$C082 DRIVER =$C85F DUMMY =$FF + FORMAT =$CBB6 GETR1 =$C9ED GETR3 =$CA08 INIT =$C900 + INSLP =$C827 INSLP2 =$C83D INSOUT =$C85E R30 =$0478 + R31 =$04F8 R32 =$0578 R33 =$05F8 READ =$CA45 + SLOT =$3D SLOT16 =$2B SS =$C083 SS0 =$0E + SSNONE =$0F STATUS =$CA3D WORK =$3C WRITE =$CB00 + + Symbol table - numerical order: - SLOT =$04 SS0 =$0E SSNONE =$0F ? TC =$80 - CMDLO =$FA FROM =$FA CMDHI =$FB TO =$FC - SIZE =$FE DUMMY =$FF R30 =$0478 R31 =$04F8 - R32 =$0578 R33 =$05F8 ? GETBUF =$8000 ? MOVEUP =$8021 - MU1 =$8037 MU2 =$803E MU3 =$8042 ? INSTALL =$804A - INSLP =$804D ERROR =$8060 INSLP2 =$8063 INSOUT =$8083 - BUFMSB =$8084 BUFLSB =$8085 DRIVER1 =$808C DRIVER =$9600 - INIT =$9626 SDV2 =$966E ERROR1 =$9695 SDV1 =$9698 - MMC =$96BC BLOCKSZ =$96D2 ? END =$96E4 ? CDERROR =$96E9 - IOERROR =$96EE END1 =$96F1 CMD =$96FD GETR1 =$970F - GETR3 =$972C STATUS =$975C READ =$9764 WRITE =$980F - FORMAT =$98B6 CMD0 =$98BA CMD1 =$98C0 CMD8 =$98C6 - CMD16 =$98CC CMD55 =$98D2 ACMD41_40=$98D8 ACMD41_0=$98DE - DRIVEND =$98E4 DATA =$C0C0 CTRL =$C0C1 DIV =$C0C2 - SS =$C0C3 + SS0 =$0E SSNONE =$0F SLOT16 =$2B WORK =$3C + SLOT =$3D CMDLO =$40 CMDHI =$41 DUMMY =$FF + R30 =$0478 R31 =$04F8 R32 =$0578 R33 =$05F8 + CURSLOT =$07F8 DATA =$C080 CTRL =$C081 DIV =$C082 + SS =$C083 INSLP =$C827 INSLP2 =$C83D INSOUT =$C85E + DRIVER =$C85F INIT =$C900 CMD =$C9D9 GETR1 =$C9ED + GETR3 =$CA08 STATUS =$CA3D READ =$CA45 WRITE =$CB00 + FORMAT =$CBB6 CMD0 =$CBBA CMD1 =$CBC0 CMD8 =$CBC6 + CMD16 =$CBCC CMD55 =$CBD2 ACMD4140=$CBD8 ACMD410 =$CBDE + diff --git a/AppleIISd.s b/AppleIISd.s index dcc7e4a..f39d1f9 100644 --- a/AppleIISd.s +++ b/AppleIISd.s @@ -1,15 +1,30 @@ -;******************************* -; -; Initialize SD card -; -;******************************* +******************************** +* +* Apple][Sd Firmware +* Version 0.5 +* +* (c) Florian Reitz, 2017 +* +* X register usually contains SLOT16 +* Y register is used for counting or SLOT +* +******************************** - .PC02 - ORG $C800 + DAT -SLOT16 = $2B ; s0 -> slot * 16 -CURSLOT = $07F8 ; Cs -DATA = $C0C0 ; slot 4 + XC ; enable 65C02 code + ORG $C800 ; Expansion ROM + +* Memory defines + +SLOT16 = $2B ; $s0 -> slot * 16 +WORK = $3C +SLOT = $3D ; $0s +CMDLO = $40 +CMDHI = $41 + +CURSLOT = $07F8 ; $Cs +DATA = $C080 CTRL = DATA+1 DIV = DATA+2 SS = DATA+3 @@ -17,575 +32,619 @@ R30 = $0478 R31 = $04F8 R32 = $0578 R33 = $05F8 -CMDLO = $FA -CMDHI = $FB -WORK = $3C -FROM = $FA ; + $fb -TO = $FC ; + $fd -SIZE = $FE ; + $ff +* Constants SSNONE = $0F SS0 = $0E -TC = $80 DUMMY = $FF -;******************************* -; -; Install SD card driver -; -;******************************* +******************************** +* +* Install SD card driver +* +******************************** -; signature bytes +* signature bytes - ldx #$20 - ldy #$00 - ldx #$03 - stx WORK + LDX #$20 + LDY #$00 + LDX #$03 + STX WORK -; find slot nr + PAG +* find slot nr - jsr $FF58 - tsx - lda $0100,X - and #$0F - ora #$C0 - sta CURSLOT ; $Cs - asl A - asl A - asl A - asl A - sta SLOT16 ; $s0 + JSR $FF58 + TSX + LDA $0100,X + AND #$0F + STA SLOT ; $0s + ORA #$C0 + STA CURSLOT ; $Cs + ASL A + ASL A + ASL A + ASL A + STA SLOT16 ; $s0 - bit $CFFF - jsr INIT: + JSR INIT + BIT $CFFF -; -; TODO: check for init error -; +* +* TODO: check for init error +* -; see if slot has a driver already +* see if slot has a driver already -INSTALL: ldx $BF31 ; get devcnt -INSLP: lda $BF32,X ; get a devnum - and #$70 ; isolate slot - cmp SLOT16 ; slot? - beq INSOUT: ; yes, skip it - dex - bpl INSLP: ; keep up the search + LDX $BF31 ; get devcnt +INSLP LDA $BF32,X ; get a devnum + AND #$70 ; isolate slot + CMP SLOT16 ; slot? + BEQ INSOUT ; yes, skip it + DEX + BPL INSLP ; keep up the search -; restore the devnum to the list +* restore the devnum to the list - ldx $BF31 ; get devcnt again - cpx #$0D ; device table full? - bne INSLP2: + LDX $BF31 ; get devcnt again + CPX #$0D device table full? + BNE INSLP2 -ERROR: jmp INSOUT: ; do something! + JMP INSOUT ; do something! -INSLP2: lda $BF32-1,X ; move all entries down - sta $BF32,X ; to make room at front - dex ; for a new entry - bne INSLP2: - lda #$04 ; ProFile type device - ora SLOT16 - sta $BF32 ; slot, drive 1 at top of list - inc $BF31 ; update devcnt +INSLP2 LDA $BF32-1,X ; move all entries down + STA $BF32,X ; to make room at front + DEX ; for a new entry + BNE INSLP2 + LDA #$04 ; ProFile type device + ORA SLOT16 + STA $BF32 ; slot, drive 1 at top of list + INC $BF31 ; update devcnt -; now insert the device driver vector + PAG +* now insert the device driver vector - lda CURSLOT - and #$0F - txa - lda #CMD0 + STA CMDHI + JSR CMD + JSR GETR1 ; get response + CMP #$01 + BNE :ERROR1 ; error! - lda #CMD0 - sta CMDHI - jsr CMD - jsr GETR1: ; get response - cmp #$01 - bne ERROR1: ; error! + LDA #CMD8 + STA CMDHI + JSR CMD + JSR GETR3 + CMP #$01 + BNE :SDV1 ; may be SD Ver. 1 - lda #CMD8 - sta CMDHI - jsr CMD - jsr GETR3: - cmp #$01 - bne SDV1: ; may be SD Ver. 1 +* check for $01aa match! +:SDV2 LDA #CMD55 + STA CMDHI + JSR CMD + JSR GETR1 + LDA #ACMD4140 + STA CMDHI + JSR CMD + JSR GETR1 + CMP #$01 + BEQ :SDV2 ; wait for ready + CMP #$00 + BNE :ERROR1 ; error! +* send CMD58 +* SD Ver. 2 initialized! + JMP :BLOCKSZ -; check for $01aa match! - -SDV2: lda #CMD55 - sta CMDHI - jsr CMD - jsr GETR1: - lda #ACMD41_40 - sta CMDHI - jsr CMD - jsr GETR1: - cmp #$01 - beq SDV2: ; wait for ready - cmp #$00 - bne ERROR1: ; error! -; send CMD58 -; SD Ver. 2 initialized! - jmp BLOCKSZ: +:ERROR1 JMP :IOERROR ; needed for far jump -ERROR1: jmp IOERROR: ; needed for far jump +:SDV1 LDA #CMD55 + STA CMDHI + JSR CMD ; ignore response + LDA #ACMD410 + STA CMDHI + JSR CMD + JSR GETR1 + CMP #$01 + BEQ :SDV1 ; wait for ready + CMP #$00 + BNE :MMC ; may be MMC card +* SD Ver. 1 initialized! + JMP :BLOCKSZ -SDV1: lda #CMD55 - sta CMDHI - jsr CMD ; ignore response - lda #ACMD41_0 - sta CMDHI - jsr CMD - jsr GETR1: - cmp #$01 - beq SDV1: ; wait for ready - cmp #$00 - bne MMC: ; may be MMC card -; SD Ver. 1 initialized! - jmp BLOCKSZ: +:MMC LDA #CMD1 + STA CMDHI +:LOOP1 JSR CMD + JSR GETR1 + CMP #$01 + BEQ :LOOP1 ; wait for ready + CMP #$00 + BNE :IOERROR ; error! +* MMC Ver. 3 initialized! -MMC: lda #CMD1 - sta CMDHI -@LOOP: jsr CMD - jsr GETR1: - cmp #$01 - beq @LOOP: ; wait for ready - cmp #$00 - bne IOERROR: ; error! -; MMC Ver. 3 initialized! +:BLOCKSZ LDA #CMD16 + STA CMDHI + JSR CMD + JSR GETR1 + CMP #$00 + BNE :IOERROR ; error! -BLOCKSZ: lda #CMD16 - sta CMDHI - jsr CMD - jsr GETR1: - cmp #$00 - bne IOERROR: ; error! - -END: clc ; all ok - ldy #0 - bcc END1: -CDERROR: sec - ldy #$28 ; no card error - bcs END1: -IOERROR: sec - ldy #$27 ; init error -END1: lda #SSNONE ; deselect card - sta SS - lda #0 - sta DIV - tya ; retval in A - rts +:END CLC ; all ok + LDX #0 + BCC :END1 +:CDERROR SEC + LDX #$28 ; no card error + BCS :END1 +:IOERROR SEC + LDX #$27 ; init error +:END1 LDA #SSNONE ; deselect card + STA SS,X + LDA #0 ; set div to 2 + STA DIV,X + TXA ; retval in A + RTS -;******************************* -; -; Send SD command -; Call with command in CMDHI and CMDLO -; -;******************************* +******************************** +* +* Send SD command +* Call with command in CMDHI and CMDLO +* +******************************** -CMD: ldy #0 -@LOOP: lda (CMDLO),Y - sta DATA -@WAIT: bit CTRL ; TC is in N - bpl @WAIT: - iny - cpy #6 - bcc @LOOP: - rts +CMD 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 + + PAG +******************************** +* +* Get R1 +* R1 is in A +* +******************************** + +GETR1 LDA #DUMMY + STA DATA,X +:WAIT BIT CTRL,X + BPL :WAIT + LDA DATA,X ; get response + STA WORK ; save R1 + AND #$80 + BNE GETR1 ; wait for MSB=0 + LDA #DUMMY + STA DATA,X ; send another dummy + LDA WORK ; restore R1 + RTS -;******************************* -; -; Get R1 -; R1 is in A -; -;******************************* +******************************** +* +* Get R3 +* R1 is in A +* R3 is in scratchpad ram +* +******************************** -GETR1: lda #DUMMY - sta DATA -@WAIT: bit CTRL - bpl @WAIT: - lda DATA ; get response - sta R30+SLOT ; save R1 - and #$80 - bne GETR1: ; wait for MSB=0 - lda #DUMMY - sta DATA ; send another dummy - lda R30+SLOT ; restore R1 - rts +GETR3 JSR GETR1 ; get R1 first + PHA ; save R1 + PHY ; save Y + LDA #04 ; load counter + STA WORK + LDY SLOT +:LOOP LDA #DUMMY ; send dummy + STA DATA,X +:WAIT BIT CTRL,X + BPL :WAIT + LDA DATA,X + PHA + DEC WORK + BNE :LOOP ; do 4 times + PLA + STA R33,Y ; save R3 + PLA + STA R32,Y + PLA + STA R31,Y + PLA + STA R30,X + PLY ; restore Y + LDA #DUMMY + STA DATA,X ; send another dummy + PLA ; restore R1 + RTS -;******************************* -; -; Get R3 -; R1 is in A -; R3 is in scratchpad ram -; -;******************************* +******************************** +* +* Status request +* $43 Unt number DSSS000 +* $44-45 Unused +* $46-47 Unused +* +* C Clear - No error +* Set - Error +* A $00 - No error +* $27 - I/O error +* $28 - No card inserted / no init +* $2B - Card write protected +* x - Blocks avail (low byte) +* y - Blocks avail (high byte) +* +******************************** -GETR3: jsr GETR1: ; get R1 first - pha ; save R1 - phy ; save Y - ldy #04 -@LOOP: lda #DUMMY ; send dummy - sta DATA -@WAIT: bit CTRL - bpl @WAIT: - lda DATA - pha - dey - bne @LOOP: ; do 4 times - pla - sta R33+SLOT ; save R3 - pla - sta R32+SLOT - pla - sta R31+SLOT - pla - sta R30+SLOT - ply ; restore Y - lda #DUMMY - sta DATA ; send another dummy - pla ; restore R1 - rts +STATUS CLC ; no error + LDA #0 + LDX #$FF ; 32 MB partition + LDY #$FF + RTS + +* TODO: check for card detect and write protect! -;******************************* -; -; Status request -; $43 Unt number DSSS000 -; $44-45 Unused -; $46-47 Unused -; -; C Clear - No error -; Set - Error -; A $00 - No error -; $27 - I/O error -; $28 - No card inserted / no init -; $2B - Card write protected -; X - Blocks avail (low byte) -; Y - Blocks avail (high byte) -; -;******************************* +******************************** +* +* 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 +* $28 - No card inserted +* +******************************** -STATUS: clc ; no error - lda #0 - ldx #$FF ; 32 MB partition - ldy #$FF - rts +* TODO: check for card detect! -; -; TODO: check for card detect and write protect! -; +READ LDA #SS0 ; enable /CS + STA SS,X + + PHY ; save Y + LDY SLOT + LDA $46 ; store block num + STA R33,Y ; in R30-R33 + LDA $47 + STA R32,Y + LDA #0 + STA R31,Y + STA R30,Y + + PHX + PHY + LDY #9 + LDX SLOT ; ASL can't be done 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 + PLY + PLX + + LDA #$51 ; send CMD17 + STA DATA,X +:WAIT BIT CTRL,X + BPL :WAIT +:ARG LDA R30,Y ; get arg from R30 on + STA DATA,X +:WAIT1 BIT CTRL,X + BPL :WAIT1 + LDA R31,Y + STA DATA,X +:WAIT11 BIT CTRL,X + BPL :WAIT11 + LDA R32,Y + STA DATA,X +:WAIT12 BIT CTRL,X + BPL :WAIT12 + LDA R33,Y + STA DATA,X +:WAIT13 BIT CTRL,X + BPL :WAIT13 + LDA #DUMMY + STA DATA,X ; dummy crc +:WAIT2 BIT CTRL,X + BPL :WAIT2 +:GETR1 LDA #DUMMY + STA DATA,X ; get R1 +:WAIT3 BIT CTRL,X + BPL :WAIT3 + LDA DATA,X ; get response +* +* TODO: check for error! +* + CMP #$FE + BNE :GETR1 ; wait for $FE + + PHY + LDY #2 ; read data from card +:LOOPY STZ WORK +:LOOPW LDA #DUMMY + STA DATA,X +:WAIT4 BIT CTRL,X + BPL :WAIT4 + LDA DATA,X + STA ($44) + INC $44 + BNE :INW + INC $45 ; inc msb on page boundary +:INW INC WORK + BNE :LOOPW + DEY + BNE :LOOPY + PLY + +:OK JSR GETR3 ; read 2 bytes crc + LDA #SSNONE + STA SS,X ; disable /CS + CLC ; no error + LDA #$00 + PLY ; restore Y + RTS + +:ERROR LDA #SSNONE + STA SS,X ; disable /CS + SEC ; an error occured + LDA #$27 + PLY ; restore Y + 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 -; $28 - No card inserted -; -;******************************* +******************************** +* +* Write 512 byte block +* $43 Unit number DSSS000 +* $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 +* $28 - No card inserted +* +******************************** -; -; TODO: check for card detect! -; +* TODO: check for card detect and write protect! -READ: lda #SS0 ; enable /CS - sta SS +WRITE LDA #SS0 ; enable /CS + STA SS,X - lda $46 ; store block num - sta R33+SLOT ; in R30-R33 - lda $47 - sta R32+SLOT - stz R31+SLOT - stz R30+SLOT - ldy #9 -@LOOP: asl R33+SLOT ; mul block num - rol R32+SLOT ; by 512 to get - rol R31+SLOT ; real address - rol R30+SLOT - dey - bne @LOOP: + PHY + LDY SLOT + LDA $46 ; store block num + STA R33,Y + LDA $47 + STA R32,Y + LDA #0 + STA R31,Y + STA R30,Y - lda #$51 ; send CMD17 - sta DATA -@WAIT: bit CTRL - bpl @WAIT: -@ARG: lda R30+SLOT ; get arg from R30 on - sta DATA -@WAIT1: bit CTRL - bpl @WAIT1: - lda R31+SLOT - sta DATA -@WAIT11: bit CTRL - bpl @WAIT11: - lda R32+SLOT - sta DATA -@WAIT12: bit CTRL - bpl @WAIT12: - lda R33+SLOT - sta DATA -@WAIT13: bit CTRL - bpl @WAIT13: - lda #DUMMY - sta DATA ; dummy crc -@WAIT2: bit CTRL - bpl @WAIT2: -@GETR1: lda #DUMMY - sta DATA ; get R1 -@WAIT3: bit CTRL - bpl @WAIT3: - lda DATA ; get response -; -; TODO: check for error! -; - cmp #$FE - bne @GETR1: ; wait for $FE + PHX + PHY + LDY #9 + LDX SLOT ; ASL can't be done 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 + PLY + PLX - ldx #2 ; read data from card -@LOOPX: ldy #0 -@LOOPY: lda #DUMMY - sta DATA -@WAIT4: bit CTRL - bpl @WAIT4: - lda DATA - sta ($44) - inc $44 - bne @INCY: - inc $45 ; inc msb on page boundary -@INCY: iny - bne @LOOPY: - dex - bne @LOOPX: + LDA #$58 ; send CMD24 + STA DATA,X +:WAIT BIT CTRL,X + BPL :WAIT +:ARG LDA R30,Y ; get arg from R30 on + STA DATA,X +:WAIT1 BIT CTRL,X + BPL :WAIT1 + LDA R31,Y + STA DATA,X +:WAIT11 BIT CTRL,X + BPL :WAIT11 + LDA R32,Y + STA DATA,X +:WAIT12 BIT CTRL,X + BPL :WAIT12 + LDA R33,Y + STA DATA,X +:WAIT13 BIT CTRL,X + BPL :WAIT13 + LDA #DUMMY + STA DATA,X ; dummy crc +:WAIT2 BIT CTRL,X + BPL :WAIT2 +:GETR1 LDA #DUMMY + STA DATA,X ; get R1 +:WAIT3 BIT CTRL,X + BPL :WAIT3 + LDA DATA,X ; get response +* +* TODO: check for error! +* + CMP #$FE + BNE :GETR1 ; wait for $FE -@OK: jsr GETR3: ; read 2 bytes crc - lda #SSNONE - sta SS ; disable /CS - clc ; no error - lda #$00 - rts + PHY + LDY #2 ; send data to card +:LOOPY STZ WORK +:LOOPW LDA ($44) + STA DATA,X +:WAIT4 BIT CTRL,X + BPL :WAIT4 + INC $44 + BNE :INW + INC $45 ; inc msb on page boundary +:INW INC WORK + BNE :LOOPW + DEY + BNE :LOOPY -:ERROR: lda #SSNONE - sta SS ; disable /CS - sec ; an error occured - lda #$27 - rts + LDY #2 ; send 2 dummy crc bytes +:CRC STA DATA,X +:WAIT5 BIT CTRL,X + BPL :WAIT5 + DEY + BNE :CRC + PLY + +:OK LDA #SSNONE ; disable /CS + STA SS,X + CLC ; no error + LDA #0 + PLY + RTS -;******************************* -; -; Write 512 byte block -; $43 Unit number DSSS000 -; $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 -; $28 - No card inserted -; -;******************************* +******************************** +* +* Format +* not supported! +* +******************************** -; -; TODO: check for card detect and write protect! -; - -WRITE: lda #SS0 ; enable /CS - sta SS - - lda $46 ; store block num - sta R33+SLOT - lda $47 - sta R32+SLOT - stz R31+SLOT - stz R30+SLOT - ldy #9 -@LOOP: asl R33+SLOT ; mul block num - rol R32+SLOT ; by 512 to get - rol R31+SLOT ; real address - rol R30+SLOT - dey - bne @LOOP: - - lda #$58 ; send CMD24 - sta DATA -@WAIT: bit CTRL - bpl @WAIT: -@ARG: lda R30+SLOT ; get arg from R30 on - sta DATA -@WAIT1: bit CTRL - bpl @WAIT1: - lda R31+SLOT - sta DATA -@WAIT11: bit CTRL - bpl @WAIT11: - lda R32+SLOT - sta DATA -@WAIT12: bit CTRL - bpl @WAIT12: - lda R33+SLOT - sta DATA -@WAIT13: bit CTRL - bpl @WAIT13: - lda #DUMMY - sta DATA ; dummy crc -@WAIT2: bit CTRL - bpl @WAIT2: -@GETR1: lda #DUMMY - sta DATA ; get R1 -@WAIT3: bit CTRL - bpl @WAIT3: - lda DATA ; get response -; -; TODO: check for error! -; - cmp #$FE - bne @GETR1: ; wait for $FE - ldx #2 ; send data to card -@LOOPX: ldy #0 -@LOOPY: lda ($44) - sta DATA -@WAIT4: bit CTRL - bpl @WAIT4: - inc $44 - bne @INCY: - inc $45 ; inc msb on page boundary -@INCY: iny - bne @LOOPY: - dex - bne @LOOPX: - - ldy #2 ; send 2 dummy crc bytes -@CRC: sta DATA -@WAIT:5 bit CTRL - bpl @WAIT:5 - dey - bne @CRC: - -@OK: lda #SSNONE ; disable /CS - sta SS - clc ; no error - lda #0 - rts - - -;******************************* -; -; Format -; not supported! -; -;******************************* - -FORMAT: sec - lda #$01 ; invalid command - rts +FORMAT SEC + LDA #$01 ; invalid command + RTS -CMD0 .byte $400000000095 -CMD1 .byte $4100000000F9 -CMD8 .byte $48000001AA87 -CMD16 .byte $5000000200FF -CMD55 .byte $770000000065 -ACMD41_40 .byte $694000000077 -ACMD41_0 .byte $6900000000FF - -DRIVEND = * +CMD0 HEX 400000 + HEX 000095 +CMD1 HEX 410000 + HEX 0000F9 +CMD8 HEX 480000 + HEX 01AA87 +CMD16 HEX 500000 + HEX 0200FF +CMD55 HEX 770000 + HEX 000065 +ACMD4140 HEX 694000 + HEX 000077 +ACMD410 HEX 690000 + HEX 0000FF + PAG