1 REM Ins{nd av Kristoffer Eriksson <5357> 1987-12-11 19.50.09 (KERMIT) ; Fil: HFMMAIN.ASM ; Av : Kristoffer Eriksson, "SKE" <5357>, 1987. ; F|r: ABC800-serien. ; ;-Ver--/-Datum----/-Sign-/-Kommentar---------------------------------- ; / 87-07-16 / SKE / HFMMAIN ; 1.00 / 87-11-13 / SKE / Klart. ; ; Huvudrutinen till HFM.ASM. Kommandotolkning, fil|ppning, huvudstruktur, ; texter, utskrifter. SkipSp: = 24 IO: = 90 ErrPtr: = 65452 Iocm.Opn: = 0 Iocm.Prp: = 1 Iocm.Clo: = 2 Iocm.Del: = 9 Err.NoExist:= 21 Lu.RndRC: = +17 Lu.RndO: = +19 Y.Int: = +35 ; CTRL-C-flagga. Int.Ctrc: = 0 SavSP: DEFW 0 ; SP vid start sparas h{r. Uppgift: DEFB 0 ; 1=Komprimera, 2=Dekomprimera, Upp.Comp: = 1 ; 4=Frekvenstabell. Upp.DeComp: = 2 Upp.Freq: = 4 SvarLen: = 80 Svar: DEFS SvarLen ; Buffert f|r svar p} vissa fr}gor. EXTERN Start, ConsWriteS, FelSlut, ConsCR Start: EXX PUSH HL PUSH DE PUSH BC LD (SavSP),SP LD (TopMem),HL ; N{sta adress i relokeringskoden enligt ; RELOCATE.ASM. CALL ConsInit JP C Exit ; Hittar inte fil 0. LD HL,TStart CALL ConsWriteS ; H{lsa anv{ndaren. CALL GIOInit LD (GIO+1),HL LD (GIOClose+1),DE LD HL,TGIOFel JP C FelSlut ; Hittar inte GIO-rutinen. CommandLine:CALL Chain.Clr ; F|rbered Chain-data. CALL Clinepar ; Hitta kommandoraden. JP C IaktCommand ; Inga parametrar - fr}ga. CP ";" JP Z IaktCommandC LD B,0 ; BC <- C. CALL Caps ; Omvandla hela raden till versaler. LD E,0 ; Samla optioner i E. LD A,(HL) CL.OLoop: CP 13 JP Z SyntaxFel ; Bara optioner {r ocks} fel. CALL Option JP C SyntaxFel INC HL LD A,(HL) ; N{sta tecken. CP " " JP NZ CL.OLoop CALL OptCheck ; Lagra och kolla optioner. JR NC CL.Pars LD HL,TOptComb JP FelSlut CL.Pars: CALL SkipSp ; Forts{tt in i filnamnsparametrarna. CP 13 ; ([ven IaktCommand g}r in h{r.) JP Z SyntaxFel CL.Files: CP ";" JP Z SyntaxFel CL.NextFile: LD BC,0 LD (FNamA.Ut),BC ; Inget utfilnamn angivet f.n. CALL WordSplit ; Avgr{nsa filnamn p} kommandoraden. LD A,C ; Tomt ord? OR B JP Z SyntaxFel LD (FNamA.In),HL ; Spara filnamnsparametern. LD (FNamL.In),BC ; FNamL.In f}r max vara 255, men det {r PUSH DE ; ingen risk att den blir mer. LD A,(DE) ; F|rsta tkn i n{sta ord. CP "=" ; Efter "=" kan utfilens namn spec'as. JR NZ CL.DoFile POP HL ; HL <- Aktuell pos. CALL SkipSP CP 13 JP Z SyntaxFel CALL WordSplit LD A,C ; Utnamnet tomt ord? OR B JP Z SyntaxFel LD (FNamA.Ut),HL ; Spara utfilens namn. LD (FNamL.Ut),BC PUSH DE CL.DoFile: CALL ProcessFile POP HL ; N{sta position i kommandoraden. LD A,(HL) CP 13 JR Z Exit CP ";" JR NZ CL.NextFile CALL Chain.Load ; Chain-fil sist p} raden. JP C SyntaxFel Exit: LD SP,(SavSP) CALL CloseFiles ; Ifall felstopp l{mnat filer |ppna. RES Int.Ctrc,(IY+Y.Int); Nolla CTRL-C-flagga. POP BC ; ]terst{ll relokeringsregistren. POP DE POP HL EXX RET ; IaktCommand - Interaktiv inmatning av uppgift och filnamn om inget angivet. IaktCommandC:CALL Chain.Load JP C SyntaxFel IaktCommand:LD HL,TUppgift ; Fr}ga vad som ska g|ras. K/D/F. CALL ConsWriteS LD HL,Svar LD BC,3 ; Max svar {r "KF" + CR. CALL ConsRead CALL ConsCR LD E,0 ; Samla optioner i E. LD HL,Svar-1 IC.OptL: CALL SkipSP CP 13 JR Z IC.OChk CALL Option JR C IaktCommand ; Felaktigt svar - fr}ga igen. JR IC.OptL IC.OChk: CALL OptCheck ; Lagra och kolla optioner. JR C IC.OFel LD A,E AND A JP Z Exit ; Tomt svar - sluta. LD HL,TInfil ; Fr}ga efter infil(er). CALL ConsWriteS LD HL,Svar LD BC,SvarLen CALL ConsRead CALL ConsCR LD HL,Svar LD BC,SvarLen CALL Caps ; Omvandla svaret till versaler. DEC HL CALL SkipSP CP 13 JP Z Exit ; Tomt svar - sluta. JP CL.Files ; Forts{tt med behandling av filnamnen. IC.OFel: LD HL,TOptComb CALL ConsWrites JR IaktCommand ; In: A=Tecken, E=Tidigare optionsbittar, Ut: E=E OR optionsbitt f|r A. ; Carry vid otill}tet optionstecken. D och A p}verkas. Option: CP "-" ; Dummyoption. RET Z AND 223 ; G|r till versal. LD D,Upp.Comp CP "K" JR Z OptKlar CP "C" JR Z OptKlar INC D ; Upp.DeComp CP "D" JR Z OptKlar LD D,Upp.Freq CP "F" SCF RET NZ OptKlar: LD A,D OR E ; L{gg ihop optioner. LD E,A RET ; Lagra optionsbittarna i Uppgift, samt kolla att de inte strider mot ; varandra. In: E=Optionsbittar. Ut: Sann Carry vid otill}tna kombinationer. ; Endats A p}verkas. OptCheck: LD A,E LD (Uppgift),A ; Lagra optioner. AND Upp.Freq+Upp.DeComp CP Upp.Freq+Upp.DeComp SCF RET Z ; Optionerna F och D kan ej kombineras. LD A,E AND Upp.Comp+Upp.DeComp CP Upp.Comp+Upp.DeComp SCF RET Z ; Inte D och K heller. AND A RET ; Genomf|r de optionsbest{mda behandlingen av en fil. ; In: (FNamA.In) och (FNamL.In) = Infilens namns adress och l{ngd. ; (FNamA.Ut) och (FNamL.Ut) = Utfilens namn om n}got angivet, annars 0. ; Denna rutin mixtrar med filnamnen, men garanterar inte att in-variablerna ; efter}t pekar p} de {ndrade filnamnen, eller p} n}got alls. Och de nya ; filnamnsstr{ngarna {r utsatta f|r |verskrivning i DefExt:s lokala buffert. ProcessFile:LD HL,(FNamA.In) LD BC,(FNamL.In) LD DE,HFMExt LD A,(Uppgift) CP Upp.DeComp ; L{gg till default extension p} infil CALL Z DefExt ; vid dekomprimering. PUSH HL PUSH BC CALL ConsWrite ; Visa filnamnet som ska behandlas, POP BC ; OBS: inget radbyte, utskriften fort- POP HL ; s{tter senare. LD IX,LU.In LD A,Iocm.Opn ; OPEN. CALL OpenUnForm ; \ppna filen. JP C FilFelCR LD A,(Uppgift) AND Upp.DeComp JP NZ PF.DeComp ; Komprimera och/eller frekvensr{kna filen. LD A,(Uppgift) AND Upp.Comp PUSH AF CALL Z ConsCR POP AF JR Z PFC.Freq LD HL,TLika CALL ConsWriteS ; Skriv " = ". LD DE,HFMExt ; Om utfilens namn har angivits, s} LD HL,(FNamA.Ut) ; l{gg bara till ev saknad enhet och, LD A,L ; extension. Skapa annars ett default OR H ; utfilnamn utifr}n infilens namn. JR Z PFC.DefNam CALL CpDev ; OBS b}de DefExt o DefDev ger samma LD DE,HFMExt ; buffert, s} DefExt m}ste anropas sist. CALL DefExt ; .HFM default extension. JR PFC.Prep PFC.DefNam: LD HL,(FNamA.In) LD BC,(FNamL.In) CALL NewExt ; L{gg till extension f|r att f} utfil. PFC.Prep: PUSH HL PUSH BC CALL ConsWrite ; Visa utfilnamnet. CALL ConsCR POP BC POP HL LD IX,LU.Ut CALL IaktPrep ; Skapa utfilen. JP C IPFel PFC.Freq: LD HL,BinFileSize CALL ZeroTriB ; Nollst{ll filstorleken. LD IX,LU.In CALL Freq.Byte ; Frekvensr{kning. CALL NC RewindFile JP C AvbrytsFel LD A,(Uppgift) AND Upp.Freq CALL NZ DispFreq CALL DispBinSize LD A,(Uppgift) AND Upp.Comp JR Z PF.End CALL RemoveUnused CALL ConstructTree ; Konstruera kodningstr{det. CALL StartBitOut LD IX,LU.Ut CALL PutHead ; Lagra filhuvudet. CALL NC PutTree ; Lagra kodningstr{det i filen. CALL NC Cmprs.Byte ; Genomf|r komprimeringen av infilen. LD IX,LU.Ut CALL NC BitFlush ; Skriv ut sista bit-bufferten. JR C AvbrytsFel CALL DispCmpSize JR PF.End ; Dekomprimera fil. PF.DeComp: LD IX,LU.In CALL GetHead ; L{s in filhuvud och utfilens namn. JR C GHFel LD IX,LU.In CALL StartBitIn CALL GetTree JP C FilFelCR LD HL,TLika CALL ConsWriteS ; Skriv " = ". CALL CpDev ; Kopiera enhetsnamn fr}n infil t utfil. LD (FNamA.Ut),HL LD (FNamL.Ut),BC PUSH HL PUSH BC CALL ConsWrite ; Visa utfilnamn. CALL ConsCR CALL DispBinSize POP BC POP HL LD IX,LU.Ut CALL IaktPrep ; Skapa utfilen. JR C IPFel CALL DeCom.Byte ; Genomf|r dekomprimeringen. JR C AvbrytsFel CALL DispCmpSize PF.End: CALL CloseFiles RET IPFel: AND A ; Filen ej skapad. JP NZ FilFelSlut ; [kta fel - rapportera och avsluta. LD HL,TAvbryt ; Avbrutet av anv{ndaren. CALL ConsWriteS JR PF.End ; Forts{tt med ev n{sta fil. AvbrytsFel: AND A ; Avbrutet. JP NZ FilFelSlut ; [kta fel - rapportera och avsluta. LD HL,TAvbryt ; Avbrutet av anv{ndaren. CALL ConsWriteS JP Exit ; Avsluta programmet. GHFel: AND A ; D}ligt filhuvud. JP NZ FilFelCR ; IO-fel - rapportera. PUSH HL CALL ConsCR POP HL CALL ConsWriteS ; D}ligt inneh}ll. JR PF.End ; St{ng in- och utfiler om de {r |ppna. Kan anropas {ven om filerna inte {r ; |ppna. (Hanteras av GIOClose) Det {r inte risk f|r loopning av att ; CloseFiles kan anropa FilFel som anropar Exit som anropar CloseFiles igen, ; eftersom Close p} fil med fel inte ger fel p}nytt. CloseFiles: LD IX,LU.In ; St{ng filerna. CALL GIOClose LD IX,LU.Ut CALL NC GIOClose JP C FilFelSlut RET ; Visa filstorlekar. DispBinSize:LD HL,TBSDig LD DE,BinFileSize LD BC,8 << 8 + 10 ; F{ltvidd 8 tkn, Bas 10. XOR A ; Undertryck nollor. CALL TriBAsc LD HL,TBinSize CALL ConsWriteS RET DispCmpSize:LD HL,TCSDig LD DE,CmpFileSize LD BC,8 << 8 + 10 ; F{ltvidd 8 tkn, Bas 10. XOR A ; Undertryck nollor. CALL TriBAsc LD HL,TCmpSize JP ConsWriteS TBinSize: DEFM "Ej komprimerad storlek = " TBSDig: DEFM " " DEFM " tokens." DEFB 13,10,0 TCmpSize: DEFM "Komprimerad storlek = " TCSDig: DEFM " " DEFM " bytes." DEFB 13,10,0 ;* Fel-stopp. SyntaxFel: LD HL,TSyntax FelSlut: CALL ConsWriteS ; Skriv felmeddelandet. JP Exit FilFelCR: PUSH AF CALL ConsCR POP AF FilFelSlut: CALL FilFel JP Exit FilFel: LD HL,TFilFel CP Err.NoExist JR NZ BasicFel LD HL,TFinnsEj JP ConsWriteS BasicFel: PUSH AF CALL ConsWriteS POP AF LD HL,-80 ADD HL,SP LD SP,HL EX DE,HL PUSH DE LD HL,(ErrPtr) DEC H INC H SCF CALL NZ JPHL EX DE,HL JR NC BFX1 PUSH HL PUSH AF LD HL,TFelkod CALL ConsWriteS POP AF POP HL LD E,A LD D,0 XOR A CALL I2ASC BFX1: POP DE AND A SBC HL,DE LD C,L LD B,H EX DE,HL CALL ConsWrite CALL ConsCR LD HL,80 ADD HL,SP LD SP,HL RET BasicFelSlut:CALL BasicFel JP Exit JPHL: JP (HL) ;* Ta reda p} l{ngden av en str{ng, vars slut markeras av ett NUL-tecken. ;* In: HL = Str{ngens start, Ut: BC = Str{ngens l{ngd exkl NUL. ;* Inga register utom BC {ndras. ;* StrLen: PUSH AF PUSH HL LD BC,65535 XOR A CPIR LD HL,65534 SBC HL,BC LD C,L LD B,H POP HL POP AF RET ;* Skriv ut str{ng avslutad med NUL-tecken. HL=Str{ngens start. ;* ConsWriteS: CALL StrLen JP ConsWrite ;* Skriv ut radskifte. ;* ConsCR: LD HL,CR LD BC,2 JP ConsWrite ;* Interaktiv prepare. Skapa fil. Om filen redan finns, fr}ga f|rst om ;* den f}r skrivas |ver. HL=Filnamn, BC=Namnets l{ngd, IX=LU-block. ;* Fel fr}n OPEN ger carry och A=felkod, avbrutet arbete ger carry och A=0. IaktPrep: PUSH HL PUSH BC LD A,Iocm.Opn CALL OpenUnForm POP BC POP HL JR NC IP.Exist CP Err.NoExist JR Z IP.Prep SCF RET ; Annat fel - avbryt. IP.Fr}ga: POP BC POP HL IP.Exist: PUSH HL PUSH BC PUSH IX CALL ConsWrite ; Filnamnet. LD HL,TFinns CALL ConsWriteS ; " finns redan. Skriva |ver?" LD HL,IP.Svar LD BC,2 CALL ConsRead CALL ConsCR POP IX LD A,(IP.Svar) AND 95 CP "J" ; Ja - skapa filen. JR Z IP.Del CP "N" JR NZ IP.Fr}ga ; Fel - fr}ga igen. CALL GIOClose POP BC POP HL XOR A SCF ; Nej - retur med A=0, Carry. RET IP.Del: LD A,Iocm.Del ; Ta bort filen. Beh|ver den st{ngas CALL IO ; ocks} sen? POP BC POP HL IP.Prep: LD A,Iocm.Prp ; Prepare. CALL OpenUnForm ; \ppna filen. RET IP.Svar: DEFS 2,0 ;* G|r POSIT till filens (IX) b|rjan. Uppenbarligen fungerar detta bara p} ;* blockorienterade filenheter. Markerar inte textfilslut f|r PRINT:ade ;* filer. GIO ser till att r{tt block blir inl{st vid n{sta l{sning, och ;* ev uppdaterad buffert blir utskriven. RewindFile: LD (IX+Lu.RndO),3 ; Offset i buffert. XOR A LD (IX+Lu.RndRC),A ; Logisk sektor. LD (IX+Lu.RndRC+1),A RET ;* Om infilen har enhetsnamn angivet, och utfilen inte har det, s} kopiera ;* enhetsnamnet fr}n infilen till utfilen. Adress och l{ngd till det nya ;* filnamnet returneras i HL och BC. Filnamnet hamnar i DefDev:s lokala ;* buffert. DE {ndras. CpDev: LD HL,(FNamA.In) LD BC,(FNamL.In) LD A,":" CPIR ; Kolla om det finns kolon i infilen. LD DE,(FNamA.In) LD HL,(FNamA.Ut) LD BC,(FNamL.Ut) ; Ta d} infilens enhet som default enhet JP Z DefDev ; f|r utfilens namn. RET ;* Omvandla till enbart versaler i str{ng. HL=Adress, BC=L{ngd. ;* HL och BC {ndras ej. Caps: PUSH HL PUSH BC DEC HL C.L: INC HL LD A,C ; Slut? OR B JR NZ C.X POP BC POP HL RET C.X: DEC BC LD A,(HL) CP "`" JR C C.L CP 127 JR NC C.L ; Omvandla bara tecken fr}n "`" - "~". SUB "a"-"A" LD (HL),A JR C.L ;* Texter. TStart: DEFM "HFM Ver 1.00, Av Kristoffer Eriksson 1987." DEFB 13,10,10,0 TGIOFel: DEFM "Hittar inte GIO. Ok{nd Basic-version. Rapportera!" DEFB 13,10,0 TSyntax: DEFM "Syntax: RUN HFM,(-)Optioner Filnamn (= Utfilnamn) ..." DEFM " (;CHAIN-fil)" DEFB 13,10 DEFM "Optioner: K=Komprimera, D=Dekomprimera, F=Frekvenstabell." DEFB 13,10 DEFM "HFM huffmannkodar filer s} de blir mindre." CR: DEFB 13,10,0 TOptComb: DEFM "Otill}ten kombination av optioner." DEFB 13,10,0 TUppgift: DEFM "Komprimering, Dekomprimering eller Frekvenstabell" DEFM " (K/D/F) ? " DEFB 0 TInfil: DEFM "Infil: " DEFB 0 TFinns: DEFM " finns redan. Skriva |ver (J/N) ? " DEFB 0 TAvbryt: DEFM "Behandlingen avbruten." DEFB 13,10,0 TLika: DEFM " = " DEFB 0 TFilFel: DEFM "Fel i filhantering: " DEFB 0 TFinnsEj: DEFM "Kan inte hitta filen." DEFB 13,10,0 TFelkod: DEFM "Basic-felkod " DEFB 0 HFMExt: DEFB 4 ; L{ngd av ".HFM" DEFM ".HFM"