;AppleWin : An Apple //e emulator for Windows ; ;Copyright (C) 1994-1996, Michael O'Brien ;Copyright (C) 1999-2001, Oliver Schmidt ;Copyright (C) 2002-2005, Tom Charlesworth ;Copyright (C) 2006-2012, Tom Charlesworth, Michael Pohoreski ; ;AppleWin is free software; you can redistribute it and/or modify ;it under the terms of the GNU General Public License as published by ;the Free Software Foundation; either version 2 of the License, or ;(at your option) any later version. ; ;AppleWin is distributed in the hope that it will be useful, ;but WITHOUT ANY WARRANTY; without even the implied warranty of ;MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ;GNU General Public License for more details. ; ;You should have received a copy of the GNU General Public License ;along with AppleWin; if not, write to the Free Software ;Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ; ; Description: Firmware for harddisk card ; ; Author: Copyright (c) 2005, Robert Hoem ; ; Modified by Tom Charlesworth: ; . Fixed so it can be assembled by a65 v1.06 ; . Fixed so that ProDOS entrypoint is $c70a (26 Dev 2007) (Bug #12723) ; . Modified to support Apple Oasis' entrypoint: $c761 (8 Sept 2012) (Feature #5557) ; . Added support for SmartPort entrypoint (20 Oct 2012) ; - EG. "Prince of Persia (Original 3.5 floppy for IIc+).2mg" ; TODO: ; . Make code relocatable (so HDD controller card can go into any slot) ; . Remove support for Entrypoint_C746 (old AppleWin) & Entrypoint_C761 (Apple Oasis) ; - provide a utility to convert these to use Entrypoint_ProDOS ; . Check SmartPort: Is it OK to trash Y and $42,..,$47 ? ; ; constants hd_execute = $c0f0 hd_error = $c0f1 hd_command = $c0f2 hd_unitnum = $c0f3 hd_memblock = $c0f4 hd_diskblock = $c0f6 hd_nextbyte = $c0f8 command = $42 unitnum = $43 memblock = $44 diskblock = $46 slot6 = $c600 OS = $0801 ; The Autoboot rom will call this. ; This is also the entry point for such things as IN#7 and PR#7 ;; code *= $c700 ; org $c700 start ; Autoboot and ProDOS look at the following few opcodes to detect block devices ; NB. $Cn07 should be $00 for a SmartPort Interface, but changing this means that it won't autoboot on ][, ][+ and unenhanced IIe. ; . ref: http://www.1000bit.it/support/manuali/apple/technotes/udsk/tn.udsk.2.html lda #$20 lda #$00 lda #$03 lda #$3C bne Bootstrap Entrypoint_ProDOS ; $c70a - ProDOS entrypoint sec bcs Entrypoint Entrypoint_SmartPort ; $c70d - SmartPort entrypoint clc Entrypoint ; $c70e - entrypoint? bcs cmdproc bcc SmartPort ;; Bootstrap ; Lets check to see if there's an image ready lda #$00 sta hd_command ; Slot 7, disk 1 lda #$70 ; Slot# << 4 sta hd_unitnum lda hd_execute ; error capturing code. Applewin is picky ; about code assigning data to registers and ; memory. The safest method is via I/O port pha lda hd_error clc cmp #1 bne noerr0 sec noerr0 pla bcc hdboot ; no image ready, boot diskette image instead jmp slot6 ;====================================== ; TODO: Is it OK to trash Y and $42,..,$47 ? ; Pre: C=0 SmartPort pla sta $46 pla sta $47 ; ($47) = &cmd_hdr pha lda $46 adc #3 ; Pre: C=0, Post: assume C=0 pha ; (sp).w += 3 ldy #1 lda ($46),y ; cmd sta $42 iny bne SmartPort2 ;====================================== ; 2 unused bytes *= $c746 ; org $c746 Entrypoint_C746 ; 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 ;====================================== ; Pre: Y=2 SmartPort2 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 bne SmartPort3 ;====================================== ; 1 unused byte *= $c761 ; org $c761 Entrypoint_C761 ; 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 ;====================================== ; image ready. Lets boot from it. ; we want to load block 1 from s7,d1 to $800 then jump there hdboot lda #$70 ; Slot# << 4 sta unitnum lda #$0 sta memblock sta diskblock sta diskblock+1 lda #$8 sta memblock+1 lda #$1 sta command jsr cmdproc bcc goload jmp slot6 goload ; X=device ldx #$70 ; Slot# << 4 jmp OS ; entry point for ProDOS' block driver ; simple really. Copy the command from $42..$47 ; to our I/O ports then execute command cmdproc clc lda $42 sta hd_command lda $43 sta hd_unitnum lda $44 sta hd_memblock lda $45 sta hd_memblock+1 lda $46 sta hd_diskblock lda $47 sta hd_diskblock+1 lda hd_execute ; check for error pha lda command cmp #1 bne skipSread jsr sread skipSread lda hd_error clc cmp #1 bne noerr2 sec noerr2 pla rts ; if there's no error, then lets read the block into memory ; because Applewin is picky about memory management, here's what I did: ; on read, hd_nextbyte = buffer[0], therefore we'll read that byte 256 times (in which ; the emulated code increments the buffer by 1 on each read) to (memblock),y ; increment memblock+1 and read the second 256 bytes via hd_nextbyte. ; ; if I could figure out how to consistantly get applewin to update it's memory regions all ; this code can be moved into the emulation code (although, this is how I'd build the hardware ; anyway...) sread tya pha ldy #0 loop1 lda hd_nextbyte sta (memblock),y iny bne loop1 inc memblock+1 ldy #0 loop2 lda hd_nextbyte sta (memblock),y iny bne loop2 dec memblock+1 ; restore memblock+1 ($45) to original value (for Epyx's California Games) pla tay rts ;====================================== SmartPort3 lda ($45),y ; memblock_h pha iny lda ($45),y ; diskblock_l pha iny lda ($45),y ; diskblock_h sta $47 pla sta $46 pla sta $45 iny bne cmdproc ;====================================== ; 15 unused bytes ; $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 $FC) ;; data *= $c7fc ; org $c7fc .word $7fff ; how many blocks are on the device. .byte $D7 ; specifics about the device (number of drives, read/write/format capability, etc) .byte