; PD8 boot-ROM code v0.5 ; adapted by VladiTX ; based on code by Alex Freed and others ; ; This is Public Domain software ; ; History: ; ; v0.1 - adapted from "boot_mmc.s" ; v0.2 - checksum, retry and I/O error ; v0.3 - second volume support ; v0.4 - defines to fix timing ; v0.5 - cleanup ; ----------------------------------------------------------------------------- ; set to fix initialization timing WAIT1 = 1 ; set to fix block-address timing WAIT2 = 1 ; set to check for buffer-transfer errors CHKBERR = 1 ; set to check for media errors on read CHKRERR = 0 ; set to check for media errors on write CHKWERR = 1 ; ----------------------------------------------------------------------------- .macro pd8wait lda STATUS,x bpl * - 3 .endmacro slot16 = $2B ; slot * 16 (boot sector relies on this) chksum = $FF ; scratch memory ; PD8 interface C_BLK = $02 ; set block address C_WBUF = $04 ; write to buffer C_MODPD = $81 ; set ProDOS mode C_READ = $82 ; read block C_WRITE = $A2 ; write block (from buffer) C_DRV = $C0 ; $C0 = drive #1, $C1 = drive #2 MTROFF = $C088 ; Disk ][ MTRON = $C089 DR0 = $C08A DR1 = $C08B Q6L = $C08C Q6H = $C08D Q7L = $C08E Q7H = $C08F STATUS = $C080 PD8CMD = Q6H PD8RDAT = Q6L PD8WDAT = Q6H ; ProDOS interface P_STAT = 0 ; commands P_READ = 1 P_WRITE = 2 P_FMT = 3 ERR_IO = $27 ; I/O error ERR_DEV = $28 ; no device connected ERR_WP = $2B ; write-protect error p_cmd = $42 ; command p_unit = $43 ; 7=drive 6-4=slot 3-0=not used p_bufl = $44 ; buffer p_bufh = $45 p_blkl = $46 ; block p_blkh = $47 ; ----------------------------------------------------------------------------- ; boot-ROM code .org $4400 ; any page rom: ; ID bytes for ProDOS and Apple Autostart ROM lda #$20 ldx #$00 ; X = 0 lda #$03 lda #$3C ; prepare block 0 to be read at $0800 ; after sector is read, will return to $0801 with X = slot * 16 stx p_blkl stx p_blkh stx p_bufl lda #$08 sta p_bufh pha ; return address - 1 (hi) txa pha ; return address - 1 (lo) inx ; P_READ stx p_cmd ; calculate (slot * 16) jsr $FF58 ; RTS tsx lda $0100,x asl asl asl asl tax ; slot * 16 sta slot16 sta p_unit ; same slot, drive #0 ; put PD8 into known state lda Q7L,x .if WAIT1 nop ; XXX .endif lda Q6L,x .if WAIT1 nop ; XXX .endif lda DR0,x .if WAIT1 nop ; XXX .endif lda MTRON,x .if WAIT1 nop ; XXX .endif lda #C_MODPD ; set ProDOS mode sta PD8CMD,x ; --- ProDOS entry point --- entry: lda p_unit and #$70 ; slot * 16 tax lda p_unit rol lda #C_DRV ; select drive adc #0 sta PD8CMD,x .if WAIT2 pha pla .endif lda #C_BLK ; set block address sta PD8CMD,x .if WAIT2 pha pla .endif lda p_blkh sta PD8WDAT,x .if WAIT2 pha pla .endif lda p_blkl sta PD8WDAT,x ; dispatch ProDOS command (with Y = 0) clc ; default return flag ldy p_cmd beq do_stat ; P_STAT dey beq do_read ; P_READ dey bne do_err ; !P_WRITE ; -- P_WRITE: WRITE request do_write: lda #C_WBUF ; write to buf sta PD8CMD,x lda chksum ; save memory pha sty chksum ; chksum = 0 wr0: lda (p_bufl),y ; transfer data sta PD8WDAT,x eor chksum sta chksum iny bne wr0 inc p_bufh wr1: lda (p_bufl),y sta PD8WDAT,x eor chksum sta chksum iny bne wr1 dec p_bufh sta PD8WDAT,x ; checksum pla ; restore memory sta chksum .if CHKBERR lda STATUS,x and #$7F ; errors? bne do_write ; retry .endif lda #C_WRITE ; write buffer sta PD8CMD,x pd8wait .if CHKWERR and #$7F ; errors? bne do_err .endif ;; clc rts ; I/O error do_errcs: pla ; restore memory sta chksum do_err: lda #ERR_IO sec rts ; -- P_STAT: STATUS request do_stat: tya ; A = 0 ldx #$FF ; XXX: blocks_lo ldy #$FF ; XXX: blocks_hi ;; clc ; device ready rts ; -- P_READ: READ request do_read: lda chksum ; save memory pha rd2: lda #C_READ ; read block sta PD8CMD,x pd8wait .if CHKRERR and #$7F ; errors? bne do_errcs .endif sty chksum ; chksum = 0 rd0: lda PD8RDAT,x ; fetch sector data sta (p_bufl),y eor chksum sta chksum iny bne rd0 inc p_bufh rd1: lda PD8RDAT,x sta (p_bufl),y eor chksum sta chksum iny bne rd1 dec p_bufh lda PD8RDAT,x .if CHKBERR eor chksum ; bus errors? bne rd2 ; retry .endif pla ; restore memory sta chksum ;; clc rts ; ProDOS frame at end of 256 byte area .res rom + $FC - * ; padding .byte $00, $00 ; 0 blocks = check status .byte $17 ; b7: medium removable ; b6: device interruptible ; b5-4: number of volumes - 1 ; b3: format supported ; b2: write supported ; b1: read supported ; b0: status supported .byte entry & $FF ; low byte of entry .end