NEW AUTO 3,1 *-------------------------------------- dcmd .EQ $42 disk command (=1 for read) unit .EQ $43 (16*slot)+(128*(drive-1)) buff .EQ $44 ram address blok .EQ $46 disk address dent .EQ $48 device call entry address idxl .EQ $4a pointer to low page of index block idxh .EQ $4c pointer to high page of index block idxp .EQ $4e index byte pointer iobuff .EQ $60 * the following are for disk ii only dbuf .EQ $26 BB.Slotn0 .EQ $2b oddbits .EQ $3c sector .EQ $3d BB.RetryCnt .EQ $40 BB.TargetTrk .EQ $41 BB.CurrentQTrack .EQ $50 BB.TargetQTrack .EQ $51 BB.HdrPtr .EQ $52 BB.Hdr .EQ $54 BB.HdrTrk .EQ $55 BB.HdrVol .EQ $56 BB.Hdr96 .EQ $57 nbuf1 .EQ $300 dnib .EQ $2d6 clrscrn .EQ $fc58 scrn .EQ $5b6 sosid .EQ $c00 entlen .EQ sosid+$23 kernel .EQ $2000 *-------------------------------------- .PH $800 xboot .DA #1 sec apple iii enters xboot 'ora $38' * bcs BB.AppleII branch if not apple iii native mode bcc * *-------------------------------------- *BB.AppleIII lda #$9f make apple iii boot using block 1 * pha the return address is $a000 * lda #$ff * pha * inc * tax ldx #0 * inc lda #1 (read block 1) * jmp $f479 *-------------------------------------- BB.AppleII stx unit save unit number cmp #$03 for disk ii php save result, it may be irrelevant txa find out if disk ii and #$70 strip drive # if any lsr lsr get slot address lsr lsr ora #$c0 sta dent+1 ldy #$ff look at last byte sty dent plp restore carry (if disk ii & sect 0&2 read) iny make y=0 lda (dent),y get device entry addr bne ndsk2 branch if not disk ii (16 sector) bcs isdsk2 branch if it is disk ii, but block 0 read lda #3 make rom read only sector 2 sta xboot to complete block 0 inc sector was = 1 lda dent+1 do rts to re-enter rom pha lda #$5b pha rts go read sector 2 into $900 *-------------------------------------- isdsk2 sta BB.HdrTrk A=0, make sure previous track =0 sta dent and dent points at beginning of slot ldy #$63 move code from card to ram mvboot lda (dent),y sta zzstart-$5e,y iny cpy #$eb have we moved enough? bne mvboot ldx #mods.cnt now modify code to handle errors. modboot ldy mods-1,x lda chgs-1,x sta zzstart,y cpx #8 bcs .1 lda endcode-1,x sta zzzend-1,x .1 dex bne modboot lda #BB.Hdr sta BB.HdrPtr stx BB.HdrPtr+1 X=0 lda /BB.ReadBlock reset device entry sta dent+1 to point at disk ii routines. lda #BB.ReadBlock get low addr (must be <$80) *-------------------------------------- ndsk2 sta dent save low adr of device call entry. ldy #0 sty iobuff y=0 sty idxl sty idxh sty idxp sty blok+1 iny y=1 sty dcmd set read command. iny y=2 sty blok to read directory blocks lda #$c 2-5 at $c00 sta iobuff+1 sta idxl+1 rddir jsr goread call read block routine. bcs bterr2 give up on error. inc iobuff+1 inc iobuff+1 inc blok lda blok have all directory blocks been read? cmp #6 bcc rddir loop if not. *-------------------------------------- lda #4 begin look-up with first entry past header. .HS 2C BIT ABS nxdent lda idxl nxdent1 clc adc entlen bump to next directory entry. tay save in y for now. bcc nxdent2 branch if not a page cross. inc idxl+1 lda idxl+1 check for new block. lsr if even then new block. bcs nxdent2 cmp #$a have all file names been compared? beq booterr branch if no pro.kernel. ldy #4 else, begin at block beginning. nxdent2 sty idxl ldy #6 lookpro lda (idxl),y look for matching name. cmp BB.ProDOS,y bne nxdent branch if no match. dey bpl lookpro * ldy #$10 get file type & index block addr. * lda (idxl),y * cmp #S.FI.T.SYS is it a system file? * bne booterr * iny ldy #$11 lda (idxl),y sta blok iny lda (idxl),y sta blok+1 lda #0 now set up to read kernel. sta idxl ldy #$1e read index block at $1e00 and sty idxl+1 kernel at $2000 sty iobuff+1 iny sty idxh+1 *-------------------------------------- rdkernl jsr goread read index block. bterr2 bcs booterr inc iobuff+1 inc iobuff+1 ldy idxp get index pointer inc idxp bump for next time. lda (idxl),y sta blok lda (idxh),y high disk addr. sta blok+1 ora (idxl),y if both=0 then done. bne rdkernl branch if more to read. jmp kernel go execute kernel code. *-------------------------------------- booterr jsr clrscrn clear video ldy #BB.MSG.ERR.Len-1 .1 lda BB.MSG.ERR,y sta scrn,y dey bpl .1 jmp $ff69 *-------------------------------------- goread lda iobuff sta buff lda iobuff+1 sta buff+1 jmp (dent) *-------------------------------------- mods .DA #mod1,#mod2,#mod3,#mod4,#mod5,#mod6,#mod7,#mod8,#mod8+1,#mod9 mods.cnt .EQ *-mods chgs .DA #chg1,#chg2,#chg3,#chg4,#chg5,#chg6,#chg7,#$91,#BB.HdrPtr,#BB.HdrTrk endcode ldx BB.Slotn0 clc rts jmp BB.Seek *-------------------------------------- BB.MSG.ERR .AS -"BOOT ERROR" BB.MSG.ERR.Len .EQ *-BB.MSG.ERR BB.ProDOS .DA #$26 $20 = storage type + 6 = "PRODOS" len .AS "PRODOS" *-------------------------------------- BB.ReadBlock lda blok figure out track & sector. and #7 strip track for now. cmp #4 and #3 php asl plp rol now we have the first sector of block. sta sector lda blok+1 get high block # lsr shift hi addr to carry. lda blok now figure track # ror lsr lsr sta BB.TargetTrk *-------------------------------------- lda buff+1 sta dbuf+1 ldx BB.Slotn0 lda IO.D2.DrvOn,x jsr BB.Seek go read sector. inc dbuf+1 bump address inc sector inc sector and sector # bcs .9 branch if error. jsr BB.Seek .9 ldy IO.D2.DrvOff,x rts return error status in carry. *-------------------------------------- BB.Wait100usecA phx (3) .1 ldx #20 (2) .2 dex (2) bne .2 (3) dec (2) bne .1 (3) plx (4) rts (6) *-------------------------------------- BB.Trk2Qtrk asl x2 sta .1+1 bit BB.HdrVol bpl .1 x4 bvs .1 > $C0 ? (VOL=254) lsr x3 .1 adc #$ff SELF MODIFIED BB.Trk2Qtrk.RTS rts *-------------------------------------- BB.Seek lda BB.HdrTrk get track we're on jsr BB.Trk2Qtrk sta BB.CurrentQTrack lda BB.TargetTrk jsr BB.Trk2Qtrk sta BB.TargetQTrack lda BB.CurrentQTrack cmp BB.TargetQTrack beq BB.Read bit #1 bne .1 jsr .10 we are on 0/4 or 2/4 track bra .9 no wait, next operation will be phy/plx/Ph0On,y .1 cmp BB.TargetQTrack we are on 1/4 or 3/4 bcs .2 if CS, C > T, must move out inc CC: C < T, ON next PH .HS B0 BCS .2 dec CS: C > T, ON prev PH sta BB.CurrentQTrack bra .6 Ph ON to go to 0/4 or 2/4, then wait *-------------------------------------- .10 and #6 ora BB.Slotn0 tay lda IO.D2.Ph0On,y rts *-------------------------------------- .3 bcs .4 if CS, C > T, must move out inc CC: C < T, ON next PH .HS B0 BCS .4 dec CS: C > T, ON prev PH sta BB.CurrentQTrack bit #1 bne .5 we must go to 1/4 or 3/4 lda IO.D2.Ph0Off,x we must go to 0/4 or 2/4 : Off Prev Ph bra .8 go wait.... .5 phy we must go on 1/4 or 3/4 plx Y already ON, -> X for Ph0Off,x bcs .6 if CS, C > T, must move out inc CC: C < T, ON next PH .6 jsr .10 now X and Y on .8 lda #IO.D2.SeekTimeB jsr BB.Wait100usecA ...wait... .9 lda BB.CurrentQTrack cmp BB.TargetQTrack bne .3 lda #0 jsr BB.Wait100usecA lda IO.D2.Ph0Off,x nop nop lda IO.D2.Ph0Off,y *-------------------------------------- BB.Read ldx BB.Slotn0 stz BB.RetryCnt php tryread plp fix stack. rdhead sec anticipate error. inc BB.RetryCnt if = 0 then give up! beq BB.Trk2Qtrk.RTS branch if can't fine/read sector. clc indicate reading header. ldy #0 Retry cnt waiting D5 rddata php carry set if reading sector. rd0 iny beq tryread *-------------------------------------- * from zzstart to zzend code is moved from rom and modified to match this code... *-------------------------------------- zzstart .EQ * rd1 lda IO.D2.RData,x read a byte from the state machine. bpl rd1 loop until ready. .DUMMY rd1a eor #$d5 mark 1? mod1 .EQ *-zzstart+1 bne rd0 branch if not. chg1 .EQ rd0-* rd2 lda IO.D2.RData,x bpl rd2 cmp #$aa mark 2? bne rd1a nop waste a little time. rd3 lda IO.D2.RData,x bpl rd3 cmp #$96 header mark 3? beq rdhd1 branch if it is. plp were we looking for data mark 3? mod2 .EQ *-zzstart+1 bcc rdhead branch if not. chg2 .EQ rdhead-* eor #$ad data mark 3? beq rddt1 go read data field if true... mod3 .EQ *-zzstart+1 rdhd0 bne rdhead otherwise, start over. chg3 .EQ rdhead-* rdhd1 ldy #3 read in trk,sect,&volume #. mod8 .EQ *-zzstart rdhd2 sta (BB.HdrPtr),y save last result in .. , BB.HdrTrk , BB.HdrVol , .. rdhd3 lda IO.D2.RData,x bpl rdhd3 rol sta oddbits save odd bits (7,5,3,1) rdhd4 lda IO.D2.RData,x bpl rdhd4 and oddbits combine even and odd to form value. dey bne rdhd2 read in next pair. plp cmp sector last byte formed is sector# mod4 .EQ *-zzstart+1 bne rdhead branch if target sector not found. chg4 .EQ rdhead-* mod9 .EQ *-zzstart+1 lda BB.HdrTrk previous result is track # cmp BB.TargetTrk is desired track found? mod5 .EQ *-zzstart+1 bne goseek re-seek if mismatch. chg5a .EQ * mod6 .EQ *-zzstart+1 bcs rddata branch if proper track always. chg6 .EQ rddata-* *-------------------------------------- rddt1 ldy #$56 read 2 bit groupings first. rddt1a sty oddbits rddt2 ldy IO.D2.RData,x bpl rddt2 eor dnib,y denibblize using table left from boot rom. ldy oddbits save in nbuf1 dey sta nbuf1,y bne rddt1a loop until all 86 groups are read. rddt3 sty oddbits now count up for 6-bit groups. rddt4 ldy IO.D2.RData,x bpl rddt4 eor dnib,y ldy oddbits save result to specified buffer. sta (dbuf),y iny bne rddt3 loop for 256 bytes. rdchk ldy IO.D2.RData,x now verify checksum... bpl rdchk eor dnib,y must be equal... mod7 .EQ *-zzstart+1 bne rdhd0 branch if error. chg7 .EQ rdhd0-* ldy #0 make y=0 nxttwo ldx #$56 now combine 2-bit group with 6 bit group twobit dex all done with this group? bmi nxttwo branch if so. lda (dbuf),y lsr nbuf1,x rol lsr nbuf1,x rol sta (dbuf),y iny bne twobit *-------------------------------------- zzzend ldx BB.Slotn0 clc indicate good read. rts chg5 .EQ *-chg5a goseek jmp BB.Seek .ED *-------------------------------------- .LIST ON BB.End .EQ * BB.Free .EQ $a00-* .BS BB.Free .LIST OFF .EP *-------------------------------------- MAN SAVE usr/src/lib/libblkdev.s.bb LOAD usr/src/lib/libblkdev.s ASM