diff --git a/firmware/HDD/HDDRVR.BIN b/firmware/HDD/HDDRVR.BIN index 21f68edb..6dba7143 100644 Binary files a/firmware/HDD/HDDRVR.BIN and b/firmware/HDD/HDDRVR.BIN differ diff --git a/firmware/HDD/hddrvr.a65 b/firmware/HDD/hddrvr.a65 index 13c205eb..a55320e7 100644 --- a/firmware/HDD/hddrvr.a65 +++ b/firmware/HDD/hddrvr.a65 @@ -55,8 +55,6 @@ hd_unitnum = $c083 hd_memblock = $c084 hd_diskblock = $c086 ;hd_nextbyte = $c088 ; legacy read-only port (still supported by AppleWin) -hd_imgsizelo = $c089 -hd_imgsizehi = $c08a ; Notes on accesses to I/O registers: ; . ROR ABS16,X and ROL ABS16,X - only used for $C081+s*$10 STATUS register: @@ -282,12 +280,7 @@ GetSlotInX ; Post: ; C = hd_status.b0 ; A = result of hd_execute -; Read or write command ; X = Slot# << 4 -; Y = command -; Status command -; X = low byte of disk size -; Y = high byte of disk size cmdproc php @@ -316,21 +309,11 @@ cmdproc done ror hd_status,x ; Post: C=0 or 1 - ldy command ; Was it status - beq size ; yes, fill in the values - rts ; no, go home - -size - pha ; Save result - ldy hd_imgsizehi,x ; Get high byte of size - lda hd_imgsizelo,x ; Get low byte of size - tax ; Transfer into X - pla ; Get back status call result rts ;====================================== -; 18 unused bytes +; 33 unused bytes !zone data @@ -347,12 +330,12 @@ size ; $D7 = Removable, Interruptable, #Volumes=2, Supports write/read/status ; $BF = Removable, Interruptable, #Volumes=4, Supports format/write/read/status (KEGS / IIGS) -; datablock. This starts near the end of the firmware (at offset $FB) +; datablock. This starts near the end of the firmware (at offset $FC) ;; data -@checkCsFB -*= $00FB ; org $00FB -!warn "CsFB padding = ", * - @checkCsFB - !byte $00 ; Smart port ID Type byte - !word $0000 ; how many blocks are on the device. Zero means use status call +@checkCsFC +*= $00FC ; org $00FC +!warn "CsFC padding = ", * - @checkCsFC + + !word $7fff ; how many blocks are on the device. !byte $D7 ; specifics about the device (number of drives, read/write/format capability, etc) !byte cmdproc + + ; C=0: fall through to SmartPort... + +;====================================== + +; TODO: Is it OK to trash Y and $42,..,$47 ? +; Pre: C=0, X = Slot# << 4 +SmartPort ; SmartPort -> GetSlotInX -> cmdproc + pla + sta $46 + adc #3 ; Pre: C=0, Post: C=0 or 1 + tay + pla + sta $47 ; ($46) = &cmd_hdr + adc #0 + pha + tya + pha ; (sp).w += 3 + + ldy #1 + lda ($46),y ; cmd + sta $42 + iny + + lda ($46),y ; param_l + sta $45 + iny + lda ($46),y ; param_h + sta $46 + + ldy #1 ; skip paramLength (assume it's #$03) + lda ($45),y ; unit + sta $43 + iny + + lda ($45),y ; memblock_l + sta $44 + iny + lda ($45),y ; memblock_h + pha + iny + + lda ($45),y ; diskblock_l + pha + iny + + bne SmartPort2 + +;====================================== +; 2 unused bytes + +@checkCs46 +*= $0046 ; org $0046 +!warn "Cs46 padding = ", * - @checkCs46 + +Entrypoint_Cs46 ; Old f/w 'cmdproc' entrypoint + ; Keep this for any DOSMaster HDD images created with old AppleWin HDD f/w. + ; DOSMaster hardcodes the entrypoint addr into its bootstrapping code: + ; - So DOSMaster images are tied to the HDD's controller's f/w + sec + bcs Entrypoint ; or directly to GetSlotInX + +;====================================== + +Bootstrap +; Lets check to see if there's an image ready +; Slot n, disk 1 + clc + bcc GetSlotInX ; Post: X = Slot# << 4 +Bootstrap2 + lda #$00 + sta hd_unitnum,x ; b7=0 => disk 1 + sta hd_command,x + lda hd_execute,x + ror hd_status,x ; Post: C=0 or 1 + bcc hdboot + +; no image ready, boot diskette image instead +BootSlot6 + jmp slot6 + +;====================================== +; 2 unused bytes + +@checkCs61 +*= $0061 ; org $0061 +!warn "Cs61 padding = ", * - @checkCs61 + +Entrypoint_Cs61 ; Apple Oasis HDD controller entrypoint + ; Keep this for any DOSMaster HDD images created with Apple Oasis HDD f/w. + ; DOSMaster hardcodes the entrypoint addr into its bootstrapping code: + ; - So DOSMaster images are tied to the HDD's controller's f/w + sec + bcs Entrypoint ; or directly to GetSlotInX + +;====================================== + +; image ready. Lets boot from it. +; we want to load block 1 from disk 1 to $800 then jump there +; Pre: X = Slot# << 4 +; C = 0 +hdboot + lda #$0 + sta unitnum ; b7=0 => disk 1 + sta memblock + sta diskblock + sta diskblock+1 + lda #$8 + sta memblock+1 + lda #$1 + sta command + bne cmdproc +hdboot2 + bcs BootSlot6 + + bit BUTTON0 ; button 0 pressed? + bmi BootSlot6 + +; Pre: X = Slot# << 4 + jmp OS + +;====================================== + +SmartPort2 + lda ($45),y ; diskblock_h + sta $47 + + pla + sta $46 + pla + sta $45 + + sec + ; fall through... + +;====================================== + +; Pre: +; C=0 => via Bootstrap +; C=1 => via Entrypoint / SmartPort2 +; Post: +; X = Slot# << 4 +GetSlotInX + php + sei ; disable ints, in case an int handler races our $0000/RTS and stack accesses! + + ; NB. need RAM that's guaranteed to be both read & writeable: + ; . can't use $0200-$BFFF, due to eg. RAMRD=0/RAMWRT=1 combination + ; . can't use LC as ROM might be enabled. + ; So use ZP (specifically $0000) as whatever the state of ALTZP, both read & write will be to the same physical memory location. + lda $00 ; save $00 + ldx #$60 ; opcode RTS + stx $00 + jsr $0000 ; RTS immediately (NB. can't use $FF58, since LC RAM may be switched in) + sta $00 ; restore $00 + tsx + lda $0100,x ; $Cn + asl + asl + asl + asl + tax ; X=$n0 + + plp ; + restore int status + bcc Bootstrap2 + ; otherwise fall through for Entrypoint / SmartPort... + +;-------------------------------------- + +; entry point for ProDOS' block driver +; simple really. Copy the command from $42..$47 +; to our I/O ports then execute command + +; Pre: +; C=0 => via Bootstrap (hdboot) +; C=1 => via GetSlotInX (eg. Entrypoint / SmartPort2) +; X = Slot# << 4 +; Post: +; C = hd_status.b0 +; A = result of hd_execute +; Read or write command +; X = Slot# << 4 +; Y = command +; Status command +; X = low byte of disk size +; Y = high byte of disk size +cmdproc + php + + lda command + sta hd_command,x + lda unitnum + sta hd_unitnum,x + lda memblock + sta hd_memblock,x + lda memblock+1 + sta hd_memblock+1,x + lda diskblock + sta hd_diskblock,x + lda diskblock+1 + sta hd_diskblock+1,x + lda hd_execute,x ; A = result of hd_execute (NB. instantaneous 512 byte r/w!) + +- rol hd_status,x ; b7=busy doing DMA? + bcs - + + plp ; restore C from start of cmdproc + bcs done + ror hd_status,x ; Post: C=0 or 1 + lda #0 + beq hdboot2 + +done + ror hd_status,x ; Post: C=0 or 1 + ldy command ; Was it status + beq size ; yes, fill in the values + rts ; no, go home + +size + pha ; Save result + ldy hd_imgsizehi,x ; Get high byte of size + lda hd_imgsizelo,x ; Get low byte of size + tax ; Transfer into X + pla ; Get back status call result + rts + +;====================================== + +; 18 unused bytes + +!zone data + +; $CsFE = status bits (BAP p7-14) +; 7 = medium is removable +; 6 = device is interruptable +; 5-4 = number of volumes (0..3 means 1..4) +; 3 = device supports Format call +; 2 = device can be written to +; 1 = device can be read from (must be 1) +; 0 = device status can be read (must be 1) + +; $C7 = Removable, Interruptable, #Volumes=1, Supports write/read/status +; $D7 = Removable, Interruptable, #Volumes=2, Supports write/read/status +; $BF = Removable, Interruptable, #Volumes=4, Supports format/write/read/status (KEGS / IIGS) + +; datablock. This starts near the end of the firmware (at offset $FB) +;; data +@checkCsFB +*= $00FB ; org $00FB +!warn "CsFB padding = ", * - @checkCsFB + !byte $00 ; Smart port ID Type byte + !word $0000 ; how many blocks are on the device. Zero means use status call + !byte $D7 ; specifics about the device (number of drives, read/write/format capability, etc) + !byte