1 REM Ins{nd av Kristoffer Eriksson SYSOP <5357> 1986-09-28 05.20.08 (DUMP) ; Fil: CDK.ASM - Kernal ; Av: Kristoffer Eriksson, "SKE" <5357>, 1986. ; ;-Ver--/-Datum----/-Sign-/-Kommentar---------------------------------- ; 1.00 / 86-08-12 / SKE / CD ; 1.01 / 86-08-20 / SKE / Hoppar |ver biblioteksl|senord efter "!". ; Bryr sig inte om enhetsangivelser inne i path. ; Ger inte felstopp p} blanka filnamn. ; Tar hand om DOS:ets specialfel OnErrDef. ; 1.20 / 86-08-24 / SKE / FILESTAT - CDK utbruten till egen fil. ; Omflyttningar och andra bytebasparingar. ; Tolkar namnet ".." som h{nvisning till fader-UFD. ; ; Exekverar instruktionen CD, med vilken man l{tt kan byta UFD. ; LUX-NET-kompatibelt. ; Endast f|r vanligt stand-alone UFD-DOS. Ej ABC/CAT/LUX-NET. ; H|r till ett huvudprogram, och avl{ser en laddningsflagga p} stacken. Om ; den (AF) {r n}got annat {n noll l{nkas rutinen f|r byte till faderbibliotek ; in i huvudrutinen f|r CD. ; Anv{nder FINDDEV.ASM som inneh}ller rutinen FindDev. ; ; En tanke kunde vara att anv{nda vanlig USEUTLU-filhantering i st{llet f|r ; DOS-anrop, f|r att slippa dess specialbehandling av vissa fel. Men d} g}r ; det }t en av de ordinarie dosbuffertarna. EXTERN Exek.CD, CD.Exek.Len, DotDOt.Len Rst.Err: = 16 SoftNoCo: = 18 Evalu: = 32 Unpfd: = 99 ; Filnamnskontroll och formatering. Open.: = 24600 Close.: = 24609 Read.: = 24621 DR.0: = 24678 UFDent: = 24685 ; Pekare till UFD-pekaren. DiscSelect: = 64769 DosFilRIB: = 64776 DosBuffers: = 64786 DiscErr: = 64789 OnErrDef: = 64819 UFDptr: = 65527 ; Normal adress till UFD-pekaren. DevUFD: = 30 ; Enhetsnumret f|r UFD. ;* Fullst{ndig exekveringsrutin f|r CD. ;* Exek.CD: RST Evalu ; $ LD (IPsav),DE POP IX ; Slaskutrymme p} stacken, POP DE ; Textpekare, POP BC ; Textl{ngd. ADD IX,SP ; Returposition f|r stacken. LD HL,-14 ADD HL,SP ; Flytta upp stacken s} vi f}r en LD SP,HL ; buffer p} 14 bytes. LD (BufPtr),HL PUSH IX LD A,B OR C LD A,0 ; A=0 Anv{nds b}de om villkoret {r JR NZ,CDpath ; sannt eller falskt. LD L,A ; Tom str{ng => nollst{llt UFD. LD H,A ; (C {r redan noll, enligt testet.) CALL UFDset ; (Anv{nder HL, C och A.) CDret: POP HL LD SP,HL ; ]terst{ll SP. LD DE,(IPsav) ; ]terst{ll Basic-instruktionspekaren. RET ; H{r utf|rs ett varv f|r varje biblioteksniv} i angiven path. CDloop: $$OnErr1: LD HL,0 ; H{r l{ggs gammalt OnErrDef-v{rde in. LD (OnErrDef),HL LD A,C ; Om kvarvarande l{ngd p} instr{ngen OR B ; nu {r noll, s} {r det klart. JR Z,CDret LD A,DevUFD ; N{sta niv} s|ks endast i UFD:. CDpath: LD (Drive),A ; (Hit g|rs inhoppet i loopen.) LD HL,UFDerr ; (OnErrSet) LD (OnErrDef),HL PUSH DE ;--, EX DE,HL ; ! HL <- DE = Filnamnsstr{ngen. LD DE,-1 ; ! DE f}r r{kna antal passerade tecken. CDsplitL1: INC DE ; ! S|k snedstreck eller utropstecken, CALL ScanPath ; ! och r{kna antalet tecken f|re. JR Z,CDFchk ; ! CP '!' ; ! JR NZ,CDsplitL1 ; ! CDsplitL2: CALL ScanPath ; ! H{r efter "!" s|ker vi vidare efter JR NZ,CDsplitL2 ; ! "/", men r{knar inte tecknen. CDFchk: EX (SP),HL ;===+ HL <- Start av filnamnet, Stacka rest. PUSH BC ;--,! L{gg kvarvarande l{ngd p} stacken. LD C,E ; !! BC <- Dell{ngd. LD B,D ; !! LD DE,(BufPtr) ; !! DE <- M}ladr f|r filnamnet (bufferten) PUSH DE ;--,!! $$DotDot: CALL Unpfd ; !!! Formattera och kontrollera filnamnet JR C,UFDerr21 ; !!! till v}r nya buffert. POP HL ;--'!! PUSH HL ;--,!! (HL=Adr till bufferten) LD A,(Drive) ; !!! Om vi redan ligger n}gon niv} ned i AND A ; !!! denna path, ska filen endast s|kas JR NZ,CDchkDev ; !!! i UFD:. Skippa enhetsangivelsen. LD BC,11 ; !!! ADD HL,BC ; !!! HL <- Adress till enhetsnamnet. EX DE,HL ; !!! CALL FindDev ; !!! HL <- Adr i DevTba, BC <- Entry-adr. JR C,UFDerr21 ; !!! LD A,B ; !!! CP 96 ; !!! Acceptera inte enheter ur BASIC- JR C,UFDerr21 ; !!! prommet. Knappast diskenhet. LD BC,7 ; !!! ADD HL,BC ; !!! LD A,(HL) ; !!! F|rmodat diskenhetsnummer. CDchkDev: LD C,A ; !!! INC A ; !!! 255 {r godk{nt (s|k p} alla enheter). JR Z,UFDext ; !!! CP 33 ; !!! (33 = 32 + 1 pga INC A ovan) JR C,UFDext ; !!! Rimligt nummer, chansa och acceptera ; !!! det. Ganska ofarligt... ; (Ett felanrop h{r, s} det kan n}s fr}n alla platser med enbart JR.) UFDerr21: LD A,21 JP UFDerr RST Rst.Err DEFB 21 ; Error 21 - Hittar ej filen. ; !!! UFDext: POP HL ;-'!! EX DE,HL ; !! DE <- filnamnets adress, till OPEN. LD HL,8 ; !! ADD HL,DE ; !! HL <- Adress till filnamnsextension. LD A,(HL) ; !! CP ' ' ; !! JR NZ,UFDopen ; !! LD A,(DE) ; !! L}t helt blanka filnamn passera utan CP ' ' ; !! effekt f|r att slippa f} okompatibla JR Z,CDnext ; !! errors. LD (HL),'U' ; !! INC HL ; !! L{gg p} default '.Ufd', om inget annat LD (HL),'f' ; !! angivits. INC HL ; !! LD (HL),'d' ; !! UFDopen: LD A,C ; !! LD (DiscSelect),A ; !! V{lj drive. LD B,0 ; !! V{lj dosbuffer 0. PUSH BC ;-,!! CALL Open. ; !!! \ppna UFD-filen. JR C,UFDerr21 ; !!! LD DE,0 ; !!! CALL Read. ; !!! L{s in f|rsta sektorn f|r koll. JR C,UFDerr48 ; !!! LD HL,(DosBuffers); !!! LD L,0 ; !!! LD E,(HL) ; !!! INC HL ; !!! Kontrollera filen f|rst... LD A,(HL) ; !!! DEC A ; !!! JR NZ,UFDerr48 ; !!! INC HL ; !!! CP (HL) ; !!! JR NZ,UFDerr48 ; !!! LD L,5 ; !!! LD A,E ; !!! CP (HL) ; !!! JR NZ,UFDerr48 ; !!! LD DE,(DosFilRIB) ; !!! INC DE ; !!! INC DE ; !!! DE <- Start av sj{lva biblioteket. PUSH DE ;-,!!! CALL Close. ; !!!! POP HL ;-'!!! POP BC ;--'!! LD A,(DiscSelect) ; !! CP 255 ; !! JR NZ,CDx1 ; !! LD A,C ; !! A <- Drive. CDx1: AND 31 ; !! ([ven inhopp fr}n DotDot-rutinen.) LD C,165 ; !! C <- Permanent-flagga. CALL UFDset ; !! (Anv{nder HL, C, A) CDnext POP BC ;-'! Kvarvarande l{ngd p} namnet. POP DE ;--' Namnpekare. JP CDloop ;* St{ll/Nollst{ll UFDpekaren. ;* HL = Biblioteks-offset, A = Drive ({ven 30=UFD), C = Permanent-flagga. ;* Att adressera UFD-pekaren direkt tar en byte mindre {n att ladda in ;* adressen i HL och anv{nda den, samt d} ha sektorn i DE. Observera {ven ;* tricket att anv{nda BC, n{r det inte finns en instruktion f|r bara C. ;* UFDset: $$UFDptr1: LD (UFDptr-1),BC ; St{ll UFD-pekaren till $$UFDptr2: LD (UFDptr),HL ; sektor HL, drive A, flagga C. CP DevUFD ; Om Drive=UFD, f|rblir MFD-drive RET Z ; of|r{ndrad. $$UFDptr3: LD (UFDptr+2),A RET ;* Del av rutinen som delar upp biblioteks-"path" i filnamn och l|senord. ;* BC = Antal tecken kvar av hela str{ngen. Minskas med ett. ;* HL = Pekare till n{sta tecken. \kas med ett. ;* Resultatet blir sann Z-flagga om str{ngen {r slut eller n{sta tkn = "/". ;* ScanPath: LD A,C OR B RET Z LD A,(HL) INC HL DEC BC CP '/' RET ;* St{llning och }terst{llning av DOS:ets felhanteringsadresser. Dessa ;* anv{nds f|r t ex error 46 och 35. F|r att spara bytes avl{ses inte den ;* gamla adressen av OnErrDef varje g}ng den {ndras, utan en g}ng f|r alla ;* i INIT-rutinen. ;* Rutinerna har placerats in direkt i CD-koden. ;* ;OnErrSet: LD HL,UFDerr ; LD (OnErrDef),HL ; RET ;OnErrReset:LD HL,... ; LD (OnErrDef),HL ; RET ;* Rutin f|r att leta igenom enhetslistan efter en viss enhet. ;* In: DE = Pekare till s|kt enhetsnamn ;* Ut: HL <- Adress till funnen l{nk i listan ;* BC <- Enhetens drivrutinadress ;* NC/C <- Funnen / Ej funnen ;* FindDev: INCLUDE FINDDEV ;* Felkod 48. Placerad h{r, kan den n}s fr}n alla st{llen de beh|vs med JR. ;* UFDerr48: LD A,48 ; Error 48 - Fel i (UFD-)biblioteket. UFDerr: $$OnErr2: LD HL,0 ; H{r l{ggs gammalt OnErrDef-v{rde in. LD (OnErrDef),HL JP SoftNoCo ;* Lokala variabler. ;* IPsav: DEFW 0 BufPtr: DEFW 0 Drive: DEFB 0 CD.Exek.Len:= * - Exek.CD ;* Specialrutin som tar hand om och identifierar biblioteketsnamnet "..", ;* vilket betecknar faderbiblioteket. L{nkas bara in p} beg{ran. ;* Inl{nkningen g|rs d{r anropet till Unpfd sitter i huvudrutinen, och ;* ers{tter det med ett anrop hit. Det ligger n}gra saker p} stacken. ;* ;--,!!! DotDot?: EXX ; !!!! Om man med ".." har hamnat i MFD, {r $$UFDptr4: LD DE,(UFDptr) ; !!!! det inte s} bra om n{sta namn s|ks LD A,E ; !!!! i UFD:. D{rf|r st{lls d} Drive om. OR D ; !!!! N}gra olika alt finns. 0 g|r det JR NZ,DD.X1 ; !!!! m|jl ange drive och annars defs|kn, LD (Drive),A ; !!!! 255 ger bara defs|kn, UFDptr+2 ger DD.X1: EXX ;-,!!!! aktuell drive. LD A,C ; !!!!! SUB 2 ; ! (Om C verkl. {r 2 blir A noll nu.) JR NZ,NoDotDot ; ! OR B ; ! H{r kollas att namnets l{ngd {r 2. JR NZ,NoDotDot ; ! LD A,'.' ; ! Och h{r att det best}r av just tv} CP (HL) ; ! punkter. JR NZ,NoDotDot ; ! INC HL ; ! CP (HL) ; ! JR NZ,NoDotDotD ; ! EXX ;-' LD A,E ; DE = UFD-pekaren. OR D ; Det {r ett fel att f|rs|ka detta utan SCF ; att vara i ett UFD (err 21). RET Z DEC DE $$UFDptr5: LD A,(UFDptr+2) ; UFD-drive. LD (DiscSelect),A CALL DR.0 ; H{r skulle det vara en JR C,UFDerr48, LD HL,(DosBuffers) ; om vi inte litade s} p} UFD-pekaren. LD L,3 LD E,(HL) ; Sektor i faderbiblioteket d{r filens INC HL ; namn finns. LD D,(HL) INC HL LD A,E OR D ; Direkt klart om fadern {r MFD. JR Z,DotDotSet LD A,(HL) ; Filnummer (PFN). AND 15 ; Maska ut relativa sektornumret. cf<-0. LD L,A LD H,0 EX DE,HL SBC HL,DE PUSH HL ;-, DEC HL ; ! Ber{kna faderns info-sektor. EX DE,HL ; ! CALL DR.0 ; ! L{s in sektorn och kontrollera lite. POP DE ;-' JR C,UFDerr48 LD HL,(DosBuffers) LD L,1 LD A,(HL) DEC A JR NZ,UFDerr48 INC HL ; !!!! CP (HL) ; !!!! JR NZ,UFDerr48 ; !!!! DotDotSet: POP HL ;-'!!! Eliminera returadressen och adressen POP HL ;--'!! till bufferten fr}n stacken. EX DE,HL ; !! HL <- Startsektor f|r UFD. LD A,DevUFD ; !! A=DevUFD g|r drivenr of|r{ndrat. JP CDx1 ; !! ]terintr{de i huvudrutinen. ; - - - - - - - NoDotDotD: DEC HL ; !!!! H{r utf|rs det av inl{nkningen NoDotDot: JP Unpfd ;-'!!! utflyttade anropet. DotDot.Len: = * - DotDot? ;_ Initiering _ CDInit: LD HL,(OnErrDef) ; Tidig avl{sning av detta v{rde. LD ($$OnErr1+1),HL LD ($$OnErr2+1),HL LD HL,(UFDent) ; Se till att UFDent anv{nds som pekare DEC HL ; till UFD-datat. LD ($$UFDptr1+2),HL ; +2 eftersom LD (),BC tar 4 byte. INC HL LD ($$UFDptr2+1),HL LD ($$UFDptr4+2),HL ; +2 eftersom LD DE,() tar 4 byte. INC HL INC HL LD ($$UFDptr3+1),HL LD ($$UFDptr5+1),HL POP HL POP AF ; Flagga f|r DotDot-rutinen. PUSH HL AND A RET Z LD HL,DotDot? ; Byt ut Unpfd-anropet mot ett anrop LD ($$DotDot+1),HL ; till DotDot?. RET REL PUSH CDInit REL CALL ORG CDInit