;**************************************************************** ;* * ;* S-D-COPY, Kopierprogramm fuer nur ein Laufwerk * ;* * ;**************************************************************** ; CNTRC EQU 3 ;^C LF EQU 0AH ;Linefeed FF EQU 0CH ;Formfeed CR EQU 0DH ;Wagenruecklauf BDOS EQU 5 WBOOT EQU 0 FCB EQU 005CH ;standard-FCB ; .Z80 .PHASE 2100h LD HL,TX+3 LD DE,100H LD BC,660H 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!$' 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 ; ; Textausgabe ; TAUS: LD C,9 JP BDOS ; ; 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 JP Z,WBOOT ;Warmstart, wenn ^C RET ; ; gibt Text aus und wartet auf ; Bestaetigung. In DE muss Adresse fuer Text stehen! ; TAUSB: CALL TAUS ;Textausgabe JR ZECCT ;Tastenbetaetigung ; ; fordert zu Diskettenwechsel auf und wartet auf ; Bestaetigung. In DE muss Adresse fuer Text stehen! ; DISKW: PUSH DE LD C,13 CALL BDOS POP DE CALL TAUSB JR DISKW2 DISKW1: LD C,13 ;Diskettensystem ruecksetzen CALL BDOS DISKW2: POP HL POP DE ;waehlen aktuelles Laufwerk PUSH HL 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 JP 0 ; ; 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 JR TAUS ; ; 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 ; ; holt Bitmap des aktuellen Laufwerkes und testet auf Fehler ; BM: PUSH DE CALL SDMA POP DE PUSH DE LD C,27 CALL BDOS INC HL LD A,H OR L JR Z,DISKERR DEC HL POP DE RET ; ; speichert Bitmap im TPA, Adersse in DE ; SBITMAP: CALL BM LD BC,2 LDIR RET ; ; testet, ob Bitmap mit dem unter Adr(DE) uebereinstimmt ; wenn ja, ist Z-Flag gesetzt ; TBITMAP: CALL BM LD A,(DE) CPI RET NZ INC DE LD A,(DE) CPI 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 JR Z,FERTIG RET 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 OPEN1 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 ; ; 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 ; ; Sichern der letzten Position beim Dateieinlesen ; LPOS: PUSH DE CALL SDMA LD DE,FCB LD C,36 CALL BDOS LD HL,FCB+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 INC DE LD (MINADR),DE ;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,STACK ;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 LD DE,BITMQ CALL SBITMAP ;Bitmap Quelldiskette speichern JR EING1 EINLESEN: LD DE,DISKWQ LD HL,(USER) PUSH HL LD HL,(QDR) PUSH HL CALL DISKW ;Aufforderung Einlegen Qdisk LD DE,BITMQ CALL TBITMAP ;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 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 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,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,BITMZ ;Kontrolle, ob Zieldiskette CALL TBITMAP ;vorliegt anhand des Bitmap des JR Z,AUS2 ;Directory 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 OPEN2 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 POP DE ;Anfadr erhoehen 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 AUS5: CALL MADR ;maximaladresse erreicht? JR NC,AUS7 ;nein 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,BITMZ ;Bitmap Zieldiskette retten CALL SBITMAP 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 ; ; Stackbereich ; DW 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00 STACK: DW 00 ; ; Platz fuer Programmvariable ; BITMQ: DW 00,00 BITMZ: DW 00,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