;**************************************************************** ;* * ;* S-D-COPY, Kopierprogramm fuer nur ein Laufwerk * ;* * ;**************************************************************** ; CNTRC EQU 3 ;^C LF EQU 0AH ;Linefeed FF EQU 0CH ;Formfeed CR EQU 0DH ;Wagenruecklauf WBOOT EQU 0 BDOS EQU 5 FCB EQU 005CH ;standard-FCB ; .Z80 .PHASE 2100h LD HL,TX+3 LD DE,100H LD BC,67FH LDIR TX: JP EINGANG .DEPHASE .PHASE 100H ; ; einige Texte ; PROMPT1: DB LF,CR,20H,20H,20H,20H,20H,'$' PROMPT2: DB LF,CR,20H,20H,20H,20H,20H,20H,20H,20H,20H,20H,'$' DATEI: DB 00,00,00,00,00,00,00,00,'.',00,00,00,'$' EF: DB LF,CR,'Eingabefehler!$' DEXT: DB LF,CR,'Datei ' DEXT1: DB 00,00,00,00,00,00,00,00,'.',00,00,00 DB ' existiert bereits!$' TFRO: DB ' Datei ist schreibgeschuetzt!$' TAUFF: DB LF,CR,'Druecken Sie eine Taste!$' OBS: DB LF,CR,'(B)ackup, (O)verwrite, (S)kip$' CC: DB LF,CR,'Bei ^C erfolgt Programmabbruch!$' FDSK: DB LF,CR,'Das ist die falsche Diskette!$' IV: DB LF,CR,'Directory ist voll!$' DV: DB LF,CR,'Diskette ist voll!$' DISKWQ: DB FF,'Legen Sie die Quelldiskette ein!$' DISKWZ: DB FF,'Legen Sie die Zieldiskette ein!$' DSKERRM: DB LF,CR,'Diskettenfehler!$' FERTIGM: DB LF,CR,'Fertig!$' ; ; einige Unterprogramme ; ; Promptzeichen und dateinamen ausgeben ; ZMELD: LD DE,PROMPT2 CALL TAUS LD HL,(FPOSS) LD DE,DATEI LD BC,8 LDIR INC DE LD BC,3 LDIR LD DE,DATEI ; ; Textausgabe ; TAUS: LD C,9 JP BDOS ; ; gibt Text aus und wartet auf ; Bestaetigung. In DE muss Adresse fuer Text stehen! ; TAUSB: CALL TAUS ;Textausgabe ; ; fordert zu Tastatureingabe auf, Rueckkehr nach erfolgter ; Tastenbetaetigung, bei ^C - Warmstart ; ZECCT: LD DE,TAUFF CALL TAUS ;Ausgabe der Aufforderung ; ; Tastatureingabe, bei ^C Programmabbruch ; CCT: LD DE,CC ;Ausgabe Text CC CALL TAUS LD C,1 CALL BDOS ;Tastatureingabe CP CNTRC JR Z,WBO ;Warmstart, wenn ^C RET ; ; fordert zu Diskettenwechsel auf und wartet auf ; Bestaetigung. In DE muss Adresse fuer Text stehen! ; DISKW: CALL TAUSB DISKW1: POP HL POP DE PUSH HL PUSH DE ;setzt Laufwerk zuruek ; LD B,E ;LWNR wird b-tes Bit in DE ; XOR A ; LD D,A ; LD E,A ; INC B ; SCF ;MDW: RL E ; RL D ; DJNZ MDW ; LD C,37 LD C,13 CALL BDOS POP DE ;waehlt aktuelles Laufwerk LD C,14 CALL BDOS POP HL POP DE ;User setzen PUSH HL LD C,32 JP BDOS ; ; Fehlermeldung ausgeben, Warmstart ; DISKERR: LD DE,DSKERRM FERTIG1: CALL TAUS LD DE,TAUFF CALL TAUS LD C,1 CALL BDOS WBO: JP WBOOT ; ; setzt DMA-Bereich auf 80h ; SDMA: LD DE,80H LD C,26 JP BDOS ; ; prueft, ob Datei schreibgeschuetzt. wenn ja ZERO rueckgesetzt ; gegeben: AKTUELLER FCB ; FRO: LD HL,FCB+9 BIT 7,(HL) RET NZ INC HL BIT 7,(HL) RET ; ; ruft BIOS-Funktion SELDSK auf ; SELDISK: LD HL,(1) LD DE,24 ADD HL,DE JP (HL) ; ; holt Chksum des aktuellen Laufwerkes und testet auf Fehler ; erhaelt LWNR in C, giebt Adresse von CHKSUM in HL zurueck ; CHKSUM: PUSH DE CALL SELDISK LD A,H OR L CALL Z,DISKERR LD DE,12 ADD HL,DE LD E,(HL) INC HL LD D,(HL) EX DE,HL POP DE RET ; ; speichert Cksum im TPA, Adersse in DE ; SCHKSUM: CALL CHKSUM LDI LDI RET ; ; testet, ob CHKSUM mit dem unter Adr(DE) uebereinstimmt ; wenn ja, ist Z-Flag gesetzt ; TCHKSUM: CALL CHKSUM LD A,(DE) CP (hl) RET NZ INC DE INC HL LD A,(DE) CP (HL) RET ; ; erhoeht FPOS und testet auf Ende, wenn ja, NC ; EFPOS: LD HL,(FPOS) ;Dateiende LD BC,16 ;naechste Pos im Fileverz ADD HL,BC LD (FPOS),HL LD A,0FFH ;Setze Neufile LD (NEUFILE),A LD DE,(FENDP) ;Kontrolle ob FPOS INC DE AND A ;nicht zu gross SBC HL,DE RET ; ; erhoeht FPOSS und testet auf Ende, wenn ja, Warmstart ; EFPOSS: LD HL,(FPOSS) PUSH HL LD BC,16 ADD HL,BC LD (FPOSS),HL POP HL LD A,(FERT) AND A RET Z LD DE,(FENDP) SBC HL,DE RET NZ FERTIG: LD DE,FERTIGM JP FERTIG1 ; ; Test ob beim Kopieren maximale Adresse erreict wurde ; MADR: LD HL,(FPOS) LD DE,(FPOSS) INC DE AND A SBC HL,DE RET ; ; traegt im FCB Nullen an allen Pos. ausser Namen ein ; FCBCL: XOR A LD (DE),A LD HL,FCB+12 LD (HL),0 LD DE,FCB+13 LD BC,19 LDIR LD DE,FCB RET ; ; stellt AnfangsFCB aus Dateinamen her ; FCBCR: PUSH DE LD HL,FCB LD DE,FCB+1 PUSH DE LD BC,80H-FCB LD (HL),0 LDIR POP DE POP HL LD BC,11 LDIR CALL SDMA LD DE,FCB RET ; ; stellt FCB mit Namenserw. '$$$' her ; FCBCRS: LD DE,(FPOSS) CALL FCBCR LD HL,FCB+9 LD (HL),'$' INC HL LD (HL),'$' INC HL LD (HL),'$' RET ; ; loeschen eines files, wenn es schon existiert ; LOEEV: PUSH DE CALL PRUEF1 POP DE INC A RET Z CALL FCBCL PUSH DE LD C,19 CALL BDOS POP DE CALL FCBCL RET ; ; Eroeffnen eines Files ; OPEN: LD DE,(FPOS) OPEN2: CALL FCBCR JR OPEN1 ; ; Eroeffnen eines files mit Erw '$$$' ; OPENS: CALL FCBCRS OPEN1: LD C,15 JP BDOS ; ; Pruefen, ob ein File bereits existiert ; PRUEF2: CALL FCBCR PRUEF1: LD C,17 JP BDOS ; ; Erzeugen eines Files mit der Erw. '$$$' ; CREATE: CALL FCBCRS CALL LOEEV LD C,22 JP BDOS ; ; Loeschen eines Files fuer overwrite ; OVER: CALL SDMA LD DE,(FPOSS) CALL FCBCR LD C,19 CALL BDOS JP AUS1 ; ; Umbenennen eines Files zu Erw 'BAK' ; BACKUP: LD DE,(FPOSS) ;nachschauen, ob File mit Erw. 'BAK' CALL FCBCR ;schon existiert. wenn ja, loeschen LD HL,FCB+9 LD (HL),'B' INC HL LD (HL),'A' INC HL LD (HL),'K' CALL LOEEV LD DE,(FPOSS) ;Umbenennen CALL FCBCR LD HL,(FPOSS) LD DE,FCB+17 LD BC,8 LDIR EX DE,HL LD (HL),'B' INC HL LD (HL),'A' INC HL LD (HL),'K' LD DE,FCB LD C,23 CALL BDOS JP AUS1 ; ; Ersetzen von '$$$' durch norm. Erw. ; REN: CALL CLOSE CALL FCBCRS LD HL,(FPOSS) LD DE,FCB+17 LD BC,11 LDIR LD DE,FCB LD C,23 JP BDOS ; ; Schliessen einer Datei ; CLOSE: CALL SDMA LD DE,FCB LD C,16 JP BDOS ווווווווווווווווווווווווווווווווווווווווווווווווווווווווווווווווווווווווווווווווווווווווווווווווווווווווווווווווווווווווווווווווB+32 POP DE LD BC,3 LDIR RET ; ; Eroeffnen und positionieren auf letzten Zugriff ; POS: LD DE,FCB+32 LD BC,3 LDIR LD DE,FCB LD C,33 JP BDOS ; ; Hauptprogramm ; EINGANG: LD DE,MINADR+2 POP HL ;Returnadr ins PASCAL, nicht benoetigt POP HL ;Anfangsadr Stringfeld POP BC ;Laenge Stringfeld (Parameter MAX) LD B,C ;immer <128 , in BReg fuer DJNZ M1: PUSH BC INC HL ;der erste Wert jedes Feldelementes ist LD (FENDP),DE ;die Stringlaenge , kopieren ab LD BC,11 ;zweitem Element LDIR INC DE ;das im vorl. Progr. verw. Feld soll INC DE ;ausser den Stringnamen noch Anf.- und INC DE ;Endadr. aufnehmen (Anf auf 12,13 und INC DE ;End auf 14 15) INC DE POP BC djnz m1 LD HL,32 ADD HL,DE LD (MINADR),HL ;hier Feld zu Ende, freier TPA Bereich POP HL LD (ZDR),HL ;Ziellaufwerk aus PASCAL-Programm POP HL LD (QDR),HL ;Quellaufwerk POP HL LD (XUSER),HL POP HL LD (USER),HL POP BC ;Laenge einer Zeichenkette 2.Promptzeichen LD HL,PROMPT2+2 LD (HL),B INC HL ;uebernehmen des 2. und anschliessend LD B,C ;des 1. Promptzeichens aus dem Stack DEC B M3: POP DE LD (HL),E INC HL DJNZ M4 LD B,D LD HL,PROMPT1+2 JR M5 M4: LD (HL),D INC HL DJNZ M3 POP BC LD HL,PROMPT1+2 LD (HL),B INC HL LD B,C DEC B M5: POP DE LD (HL),E INC HL DJNZ M6 JR M7 M6: LD (HL),D INC HL DJNZ M5 M7: LD HL,(MINADR) ;Stack wird nach unten verlegt LD SP,HL ;damit ist der ges. restl. TPA frei LD DE,(USER) PUSH DE LD DE,(QDR) PUSH DE CALL DISKW1 JR EING1 EINLESEN: LD DE,DISKWQ LD HL,(USER) PUSH HL LD HL,(QDR) PUSH HL CALL DISKW ;Aufforderung Einlegen Qdisk LD DE,CHKSMQ LD BC,(QDR) CALL TCHKSUM ;Test ob Quelldiskette JR Z,EINL1 LD DE,FDSK CALL TAUSB ;Ausgabe Fehlermeldung JP EINLESEN ; ; Abpeichern einiger Werte fuer nachfolgendes Saven ; ;EINL2: LD BC,16 ; ADD HL,BC ; JR EINL3 EINL1: LD A,(NEUFILE) LD (NEUFILES),A LD HL,(FPOS) ; AND A ; JR NZ,EINL2 EINL3: LD (FPOSS),HL DEC HL LD DE,(MINADR) LD (HL),D DEC HL LD (HL),E ; ; Einlesen eines Files in den Hauptspeicher ; EING1: LD DE,PROMPT1 CALL TAUS LD HL,(FPOS) LD DE,DATEI LD BC,8 LDIR INC DE LD BC,3 LDIR LD DE,DATEI CALL TAUS LD DE,(FPOS) CALL OPEN INC A CALL Z,DISKERR LD IX,(FPOS) ;setzt Anfadr. auf LD H,(IX-1) ;letzte Endadr LD L,(IX-2) LD (IX+13),H LD (IX+12),L LD A,(NEUFILE) AND A JR NZ,EING2 ;Anfangen eines neuen Files LD HL,FCBM ;oder Setzen des aktuellen CALL POS ;FCB auf letzten Stand EING2: LD IX,(FPOS) LD H,(IX+13) ;setze Endadr auf Anfadr LD L,(IX+12) LD (IX+15),H LD (IX+14),L EING3: LD D,(IX+15) ;setze DMA auf Endadr LD E,(IX+14) LD C,26 CALL BDOS LD DE,FCB LD C,20 ;seq lesen CALL BDOS AND A JR Z,EING5 ;Lesen erfolgte fehlerfrei DEC A JP NZ,DISKERR ;Diskettenfehler CALL EFPOS JP C,EING1 LD A,0FFH LD (FERT),A JR AUSGABE ;fertig mit allen Files EING5: LD IX,(FPOS) LD H,(IX+15) ;Endadr erhoehen LD L,(IX+14) LD BC,80H ADD HL,BC LD (IX+15),H LD (IX+14),L ADD HL,BC ;maximal moegliche Adr-128 erreicht? LD DE,(6) AND A SBC HL,DE JR C,EING3 ;nein LD DE,FCBM CALL LPOS ;Retten des aktuellen FCB ld de,fcb LD C,20 ;seq lesen CALL BDOS AND A JR Z,EING6 ;Lesen erfolgte fehlerfrei DEC A JP NZ,DISKERR ;Diskettenfehler LD A,0FFH ;Dateiende, setzen Neufile LD (NEUFILE),A JR AUSGABE EING6: XOR A ;Ruecksetzen Neufile LD (NEUFILE),A AUSGABE: LD DE,CHKSMQ LD BC,(QDR) CALL SCHKSUM ;CHKSUM Quelldiskette speichern LD DE,DISKWZ ;Diskettenwechsel LD HL,(XUSER) PUSH HL LD HL,(ZDR) PUSH HL CALL DISKW ;zur Zieldiskette LD A,(ERST) AND A JR NZ,AUS0 LD DE,CHKSMZ ;Kontrolle, ob Zieldiskette LD BC,(ZDR) CALL TCHKSUM ;vorliegt anhand der CHKSUM JR Z,AUS2 LD DE,FDSK ;falsche Diskette geladen CALL TAUSB JR AUSGABE ;neuer Versuch AUS2: LD A,(NEUFILES) ;Test ob unvollst kopiertes AND A ;File weiterkopiert werden soll JR NZ,AUS1 CALL ZMELD LD DE,(FPOSS) CALL OPENS LD HL,FCBMS CALL POS ;gehe zu Dateiende LD DE,FCB LD C,20 CALL BDOS JR AUS3 AUS0: XOR A LD (ERST),A AUS1: CALL ZMELD CALL SDMA LD DE,(FPOSS) ;Test ob file vorhanden CALL PRUEF2 INC A JR Z,AUS4 ;nein LD DE,DEXT1 ;Eintragen des Dateinamen LD HL,(FPOSS) ;in auszugebenden Text LD BC,8 LDIR INC DE LD BC,3 LDIR CALL FRO PUSH AF LD DE,DEXT ;Ausgabe des Textes Datei schon da CALL TAUS POP AF JR NZ,AU AX: LD DE,OBS CALL TAUSB ;Menuausg, Einl.Taste Test auf ^C CP 'O' ;overwrite JP Z,OVER CP 'o' JP Z,OVER CP 'B' ;backup JP Z,BACKUP CP 'b' JP Z,BACKUP CP 'S' ;skip JR Z,AUS5 CP 's' JR Z,AUS5 LD DE,EF CALL TAUS JR AX ;kein erlaubtes Zeichen, nochmal! AU: LD DE,TFRO CALL TAUS JR AUS5 AUS4: CALL CREATE AUS3: LD IX,(FPOSS) ;Anfadr>Endadr? LD H,(IX+15) LD L,(IX+14) LD D,(IX+13) LD E,(IX+12) DEC HL AND A SBC HL,DE JR C,AUS6 ;ja PUSH DE LD C,26 ;DMA auf Anfadr setzen CALL BDOS LD DE,FCB LD C,21 ;seq schreiben CALL BDOS INC A ;wenn A=FF, Diskettenfehler CALL Z,DISKERR POP DE DEC A DEC A ;wenn A=1, Directory voll JR Z,MIV DEC A ;wenn A=2, Disk voll JR Z,MDV LD HL,80H ADD HL,DE LD IX,(FPOSS) LD (IX+13),H LD (IX+12),L LD DE,FCBMS CALL LPOS ;Retten des aktuellen FCB JR AUS3 MDV: LD DE,DV JR MV MIV: LD DE,IV MV: CALL TAUSB LD DE,FCB CALL FCBCL LD DE,FCB CALL LOEEV AUS5: CALL MADR ;maximaladresse erreicht? JR NC,AUS7 ;nein LD A,(FERT) AND A CALL NZ,FERTIG LD A,(NEUFILE) AND A SCF CALL Z,EFPOS CALL NC,FERTIG LD A,0FFH ;Einlesen von Quelldiskette soll LD (NEUFILE),A ;mit neuem File erfolgen AUS8: CALL EFPOSS ;erhoeht FPOSS und testet auf fertig LD DE,CHKSMZ ;CHKSUM Zieldiskette retten LD BC,(ZDR) CALL SCHKSUM JP EINLESEN ;Diskettenwechsel AUS7: CALL EFPOSS ;erhoeht FPOSS und testet auf fertig JP AUS1 AUS6: CALL MADR ;Maximaladresse erreicht? JR C,AUS9 ;ja CALL REN ;originale Dateierweiterung setzen CALL EFPOSS ;erhoeht FPOSS und testet auf fertig JP AUS1 AUS9: LD A,(NEUFILE) ;ist File vollst. auf Zieldisk? AND A JR Z,AUS10 ;nein CALL REN ;originale Dateierweiterung setzen JR AUS8 AUS10: CALL CLOSE ;Datei schliessen JR AUS8 ; ; Platz fuer Programmvariable ; CHKSMQ: DW 00 CHKSMZ: DW 00 NEUFILE: DB 0FFH NEUFILES: DB 0FFH ERST: DB 0FFH FERT: DB 00 FCBM: DB 0,0,0 FCBMS: DB 0,0,0 FPOS: DW MINADR+2 FPOSS: DW MINADR+2 FENDP: DW 00 USER: DW 00 XUSER: DW 00 QDR: DW 00 ZDR: DW 00 MINADR: DW 00 END