|
DataMuseum.dkPresents historical artifacts from the history of: CP/M |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about CP/M Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - download
Length: 11776 (0x2e00) Types: TextFile Names: »PRINT.MAC«
└─⟦8aac91c70⟧ Bits:30003307 SuperCalc v. 1.12 & RcKalk 1.0 til RC700 └─ ⟦this⟧ »PRINT.MAC«
TITLE PRINT Version 2, Maj 1984 .COMMENT * Programmet udskriver en tekstfil til den lokale printer. Man starter fra CP/M som ved andre transiente kommandoer: A>PRINT FILNAVN <cr> Filnavnet skal overholde standard CP/M formatet d:nnnnnnnn.ttt, hvor d er drive, nnnnnnnn er filnavnet og ttt er filtype. Programmet kan kun skrive en enkelt fil ud, men er man i tvivl om filnavnet kan man bruge spørgsmålstegn og stjerner (wildcards) som normalt for CP/M. Findes der flere filer, der matcher navnet, skrives de allesammen på skærmen (som ved DIR), og der udskrives en fejlmeddelelse. Finder programmet kun en fil starter udskrivningen med det samme. Hvis filen ikke findes på det valgte drive tester programmet om der er valgt default drive (dvs. der er ikke angivet drive i filnavnet). Hvis ikke returnerer programmet til CP/M med en fejlmeddelelse, ellers søger det filen på det andet drive (den findes jo nok et eller andet sted). Tekstfilen udskrives med printerens mindste bogstaver (16,5 CPI). Det betyder at kompileringslister kan udskrives på A4 høj, fordi man får 132 tegn pr. linie (mod normalt 80). Der er 72 linier på en A4-side, men for at skippe perforeringen foretager programmet sideskift efter 67 linier. Bemærk dog, at listefiler fra M80-assembleren kun har 50 linier pr. side, medmindre andet er specificeret med PAGE-kommandoen. * .Z80 BDOS EQU 0005H ;BDOS ENTRYPOINT FCB EQU 5CH ;CP/M DEFAULT FCB DEFDRV EQU 0004H ;DEFAULTDRIVE BELL EQU 07H ; HT EQU 09H ;TABULATOR (HORIZONTAL TAB) CR EQU 0DH ;CARRIAGE RETURN LF EQU 0AH ;LINEFEED FF EQU 0CH ;FORMFEED EOF EQU 1AH ;END OF FILE SUBTTL HOVEDPROGRAM: SØG FILNAVN I DIRECTORY PAGE 67 PRINT: LD DE,OPSTARTTEKST LD C,9 CALL BDOS ;Hvis fcb'ens andet tegn (filnavnets første tegn) er en blank ;er der ikke blevet indtastet et filnavn i kommandolinien, og ;programmet returnerer til CP/M med en fejlmeddelelse. LD A,(FCB+1) CP " " LD DE,INTETFILNAVNTEKST JP Z,FEJLRETUR ;Find første forekomst af det indtastede filnavn. CALL FINDFOERSTEFIL JR NC,FUNDET ;Filen findes ikke på det valgte drive. Test om der er valgt defaultdrive, og ;søg det andet drive igennem hvis det er tilfældet. Programmet kommer typisk ;hertil, når brugeren glemmer at angive drive i filnavnet, og drive A er ;default mens tekstfilen ligger på drive B. LD A,(FCB) ;ER DER VALGT DEFAULTDRIVE? OR A LD DE,INGENFILTEKST JP NZ,FEJLRETUR ;NEJ => GLEM DET OG GIV EN FEJLMEDDELELSE LD HL,FCB ;JA: FIND UD AF HVILKET DRIVE DER ER DEFAULT LD (HL),2 ;OG SÆT FCB'EN TIL DET ANDET DRIVE. LD A,(DEFDRV) OR A JR Z,SKIP LD (HL),1 LD A,"A" LD (DRIVETEGN),A SKIP: CALL FINDFOERSTEFIL ;SØG FILEN PÅ DET ANDET DRIVE LD DE,INGENFILTEKST JP C,FEJLRETUR ;STADIG IKKE FUNDET => UD TIL CP/M MED FEJL LD DE,FUNDETPAAANDETTEKST LD C,9 ;MEDDEL AT FILEN ER FUNDET PÅ DET ANDET DRIVE PUSH HL CALL BDOS POP HL LD A,1 ;FILEN BLEV FUNDET, MEN IKKE PÅ DET VALGTE LD (ACCEPTFLAG),A ;DRIVE, DERFOR AFVENT ACCEPT FØR UDSKRIVNING. PAGE ;Første forekomst er fundet. Skriv filnavnet på skærmen og søg videre i ;directoryet. Findes der flere er det galt, for programmet kan kun ;udskrive en enkelt fil til printeren. FUNDET: CALL SKRIVFILNAVN CALL FINDNAESTEFIL JR C,IKKEFLEREFILER ;KUN EN MATCH I DIRECTORY => SKRIV FILEN ;For mange filer matcher med det indtastede filnavn. Alle fundne ;filer skrives derfor på skærmen, og der returneres til CP/M med ;en fejlmeddelelse. Brugeren må herefter starte forfra med en mere ;præcis angivelse af filnavnet. FLEREFILER: ;SKRIV RESTERENDE FILNAVNE LD DE,SKILLETEGN ;ADSKIL FILNAVNE MED " : " LD C,9 PUSH HL CALL BDOS POP HL CALL SKRIVFILNAVN ;SKRIV NAVNET PÅ NÆSTE FOREKOMST CALL FINDNAESTEFIL JR NC,FLEREFILER ;LOOP SÅ LÆNGE DER FINDES FILER DER MATCHER LD DE,FORMANGEFILERTEKST JP FEJLRETUR ;UD TIL CP/M MED EN FEJLMEDDELELSE IKKEFLEREFILER: ;Kun een fil fundet der matcher det indtastede filnavn. ;Hvis acceptflaget ikke er sat (=0) udskrives filen med det samme. ;Er flag = 1 afventes accept før udskrivning (J/N), fordi filen ;blev fundet på det andet drive. LD A,(ACCEPTFLAG) ;FLAG = 0 ? OR A JP Z,SKRIVFILTILPRINTER ;JA => UDSKRIV FILEN MED DET SAMME ;Skriv navnet på filen og afvent accept før udskrivningen (J/N) LD HL,FCBBUFFER ;SKRIV FILNAVNET PÅ SKÆRMEN CALL SKRIVFILNAVN LD DE,ACCEPTTEKST ;SKRIV LEDETEKST LD C,9 CALL BDOS VENTPAAACCEPT: ;VENT PÅ J ELLER N LD C,1 CALL BDOS AND 5FH ;LAV EVT. LILLE BOGSTAV STORT CP "J" ;HVIS J => SKRIV FILEN JR Z,SKRIVFILTILPRINTER CP "N" ;HVIS N => UD TIL CP/M JR NZ,VENTPAAACCEPT ;ELLERS => VENT IGEN LD DE,CRLFTEKST FEJLRETUR: LD C,9 ;BDOS RUTINE 10: PRINT MESSAGE CALL BDOS ; RET ;RETURNER TIL CP/M. CCP ER IKKE BLEVET ØDELAGT, ;SÅ DET ER IKKE NØDVENDIGT AT VARMSTARTE. SUBTTL HOVEDPROGRAM: SKRIV FUNDEN FIL TIL PRINTER PAGE SKRIVFILTILPRINTER: LD SP,PRINTSTAK ;INITIER EGEN STAK LD E,29 ;SÆT PRINTER TIL LILLE SKRIFT (16,5 CPI) LD C,5 CALL BDOS ;Indlæs fil fra diskette til lager. ;Indlæsning af tekstfilen sker først til lageret. Når hele filen er indlæst, ;eller når lagerbufferen er fuld, udskrives bufferens indhold til printeren. ;Programmet bruger den maksimale bufferplads, som memory tillader. Bufferen ;starter i lageret umiddelbart efter print-programmet og slutter ved toppen ;af memory (normalt =CC06H, dvs. start af BDOS). Adressen for toppen af memory ;kan hentes fra adresse 0006H, da adresse 0005H indeholder kommandoen ;JP TOPOFMEMORY (normalt JP CC06H). LD DE,FCB ;KALD BDOS OPEN-RUTINE. LD C,15 ;DET GÅR ALTID GODT, FORDI FILEN LIGE ER CALL BDOS ;FUNDET I DIRECTORYET UNDER SØGNINGEN. LD DE,FILBUFFER ;SÆT DMA-ADRESSEN TIL AT STARTE UMIDDELBART ;EFTER PROGRAMMET (FØRSTE LEDIGE PLADS I LAGER) LAES: PUSH DE ;SÆT DMA-ADRESSE LD C,26 ; CALL BDOS LD DE,FCB ;LÆS NÆSTE SEKTOR FRA FILEN LD C,20 CALL BDOS POP DE ;RETABLER DMA-ADRESSE OR A ;VAR DER END OF FILE? JR NZ,AFSLUT ;JA => AFSLUT PROGRAMMET LD HL,128 ;TÆL DMA-ADRESSEN OP MED +128, SÅ NÆSTE SEKTOR ADD HL,DE ;BLIVER INDLÆST UMIDDELBART EFTER DEN EX DE,HL ;FOREGÅENDE OR A ;TEST OM BUFFEREN ER FULD, DVS. OM DMA-ADRESSEN LD HL,(0006H) ;ER HØJERE END MAKSIMUM-ADRESSEN FOR TPA LD BC,128+1 ; SBC HL,BC SBC HL,DE JR NC,LAES ;PLADS I BUFFER => FORTSÆT INDLÆSNING LD A,EOF ;BUFFER FULD: SKRIV BUFFERINDHOLD TIL PRINTER LD (DE),A CALL SKRIVFRABUFFER LD DE,FILBUFFER ;FORTSÆT INDLÆSNING FRA START AF LAGERBUFFER JR LAES AFSLUT: LD A,EOF ;MARKER FILEN MED EOF, UANSET OM DEN ER LD (DE),A ;EOF-MÆRKET I FORVEJEN CALL SKRIVFRABUFFER ;SKRIV BUFFERENS INDHOLD LD E,30 ;SÆT PRINTEREN TIL "NORMAL" SKRIFT (10 CPI) LD C,5 CALL BDOS LD E,FF ;AFSLUT MED ET SIDESKIFT PÅ PRINTEREN LD C,5 CALL BDOS JP 0000H ;VARMSTART CP/M, FORDI CCP MÅSKE ER BLEVET ;ØDELAGT (VED STORE FILER). SUBTTL UNDERRUTINER BENYTTET VED FILSØGNING PAGE ;Find næste forekomst af filnavnet i default-fcb'en (adresse 5CH). ;Første gang kaldes SEARCHFIRST, alle efterfølgende gange kaldes SEARCHNEXT. ;Hvis rutinerne finder en forekomst i directoriet returneres der med NC og ;HL peger på første byte i det pågældende directoryentry. Hvis der ikke ;findes en match returneres der med C-flaget sat. FINDFOERSTEFIL: LD DE,FCB ; LD C,17 ;BDOS RUTINE 17: SEARCH FIRST JR FIND ; FINDNAESTEFIL: LD C,18 ;BDOS RUTINE 18: SEARCH NEXT FIND: CALL BDOS ; RRCA ;A * 32 + 80H RRCA ; SCF ; RRA ; LD H,0 ;SÆT HL TIL AT PEGE PÅ ENTRY LD L,A ; RET ;RETURNER MED STATUS I C-FLAG ;Skriv et filnavn til skærm i formatet NNNNNNNNbTTT (12 bytes). ;Ved kald skal HL pege på starten af den fcb der indeholder filnavnet. SKRIVFILNAVN: LD B,8 ;8 TEGN I FILNAVN INC HL CALL SKRIVTEGN PUSH HL ;ADSKIL NAVN OG TYPE MED ET BLANKTEGN LD E," " LD C,2 CALL BDOS POP HL LD B,3 ;3 TEGN I FILTYPE SKRIVTEGN: LD E,(HL) RES 7,E LD C,2 ;BDOS RUTINE 2: CONSOLE OUTPUT PUSH BC PUSH HL CALL BDOS POP HL POP BC INC HL DJNZ SKRIVTEGN RET SUBTTL UNDERRUTINE BENYTTET VED UDSKRIVNING TIL PRINTER PAGE ;Udskriv lagerbufferens indhold til printer SKRIVFRABUFFER: LD HL,FILBUFFER ;START AF FILBUFFER I LAGERET PRINTTEGN: LD A,(HL) ;HENT NÆSTE TEGN FRA FILEN CP EOF ;STOP VED END OF FILE RET Z PUSH HL CALL PRINTA ;SKRIV TEGNET TIL PRINTEREN POP HL INC HL JR PRINTTEGN ;Udskriv A-registret til printeren. Rutinen udvider tabulatortegn ;til et antal blanktegn frem til næste kolonne a' 8 tegn. ;Derfor vedligeholdes en tæller for, hvilken kolonne printhovedet ;i øjeblikket befinder sig i (PRINTKOLONNE). ;Der er 72 linier på en A4-side, men for at skippe perforeringen foretager ;rutinen et sideskift når der er skrevet mere end 67 linier på en side. PRINTA: CP " " ;KONTROLTEGN? JR NC,PRA1 ;NEJ => SKRIV TEGNET CP HT ;TABULATOR? JR Z,TABULATOR;JA => SKRIV BLANKE FREM TIL NÆSTE KOLONNE A' 8 TEGN LD HL,PRINTKOLONNE LD (HL),0 ;ANDRE KONTROLTEGN BEVIRKER, AT DER STARTES FORFRA PÅ ;PRINTLINIEN, SELVOM DET IKKE ALTID BEHØVER AT VÆRE ;TILFÆLDET, SPECIELT IKKE VED STYREKARAKTERER TIL ;PRINTEREN. DET ER IKKE MULIGT AT TAGE HØJDE FOR ALLE ;SPECIALTILFÆLDE. CP FF ;SKIFT SIDE VED FORMFEED JR Z,NYSIDE CP LF ;SKIFT LINIE VED LINEFEED, JR NZ,PRA2 ;ELLERS BARE SKRIV KONTROLTEGNET LD HL,LINIETAELLER INC (HL) LD A,(HL) ;HVIS LINIETAELLEREN BLIVER STØRRE END 67 SKIFTES CP 68 ;SIDE, FOR AT SKIPPE PERFORERINGEN LD A,LF JR C,PRA2 NYSIDE: XOR A ;SIDESKIFT: NULSTIL LINIETÆLLER LD (LINIETAELLER),A LD A,FF JR PRA2 PRA1: LD HL,PRINTKOLONNE ;HVIS DET ER FØRSTE TEGN PÅ LINIEN UDFØRES EN INC (HL) ;TABULERING. DET GIVER EN VENSTREMARGIN PÅ 8 TEGN LD B,(HL) DEC B JR NZ,PRA2 PUSH AF CALL TABULATOR POP AF JR PRA1 PRA2: LD E,A ;SKRIV TEGNET TIL PRINTEREN LD C,5 ;BDOS RUTINE LIST (SKRIVER E-REGISTER TIL PRINTER) CALL BDOS RET TABULATOR: LD A," " ;SKRIV BLANKTEGN FREM TIL NÆSTE KOLONNE A' 8 TEGN CALL PRA1 LD A,(PRINTKOLONNE) AND 111B ;KOLONNE A' 8 TEGN? JR NZ,TABULATOR ;NEJ => SKRIV ET BLANKTEGN MERE RET SUBTTL DATAAREALER PAGE DS 32 ;PROGRAMSTAK: 16 NIVEAUER PRINTSTAK EQU $ PRINTKOLONNE: DB 0 LINIETAELLER: DB 0 OPSTARTTEKST: DB "PRINT version 2.0 EDB-skolen i HERLEV Maj 1984.",CR,LF,LF,"$" FUNDETPAAANDETTEKST: DB BELL,128+4,"Fundet på " DRIVETEGN: DB "B : ",128,"$" ACCEPTTEKST: DB CR,LF,"Skal filen udskrives til printer (J/N)? $" SKILLETEGN: DB " : $" ; FEJLTEKSTER: INTETFILNAVNTEKST: DB "Du skal indtaste et filnavn i kommandolinien:",CR,LF DB "A>PRINT FILNAVN",CR,LF,"$" INGENFILTEKST: DB "Kan ikke finde filen!",CR,LF,"$" FORMANGEFILERTEKST: DB CR,LF,"Der er for mange filer med det navn!",CR,"$" CRLFTEKST: DB CR,LF,"$" ACCEPTFLAG: ;FLAGET VISER OM DER SKAL AFVENTES ACCEPT AF DE FUNDNE DB 0 ;FILER FØR UDSKRIVNING: ;0: KUN EN FIL PÅ DET VALGTE DRIVE, UDSKRIV MED DET SAMME ;1: FILEN FUNDET PÅ IKKE DEFAULT DRIVE, AFVENT ACCEPT (J/N) ;I denne buffer gemmes fcb'en for først fundne fil. FCBBUFFER: DS 33,0 FILBUFFER EQU $ ;RESTEN AF LAGERET BRUGES SOM BUFFER VED INDLÆSNING ;AF FILEN FRA DISKETTEN SUBTTL END PRINT «eof»