.Z80 ; COPY BETWEEN OPERATING SYSTEMS ; LAST UPDATED 12-01-83 EXT MSGADD,AINP,BIOS,SENDM BDOS EQU 5 CR EQU 0DH ;CARRAGE RETURN LF EQU 0AH ;LINE FEED COPY:: LD A,(MSGADD+2) ;GET ID CODE CP 1 ;FILE NAME? JR Z,FNAM ;BIF YES CP 2 ;DATA TRANSFER? JP Z,FDATA ;BIF YES CP 3 ;SEND EOF? JP Z,FEOF ;BIF YES JP AINP ;GO GET NEXT MESSAGE FNAM: LD HL,BUFFER ;SET UP BLOCKING XOR A LD (ADDRESS),HL LD (COUNT),A LD (EOFF),A LD A,020H ;FILL NAME IN WITH SPACES LD HL,FCB+1 LD B,11 FNAM1: LD (HL),A INC HL DJNZ FNAM1 XOR A ;CLEAR REST LD B,24 FNAM2: LD (HL),A INC HL DJNZ FNAM2 LD HL,MSGADD+3 ;GET READ OR WRITE LD A,(HL) LD (MODE),A INC HL INC HL ;GET FILE NAME LD BC,11 ;TRANSFER FILE NAME LD DE,FCB+1 LDIR LD C,1 ;DRIVE B LD E,0 ;DRIVE SELECT FORCED CALL BIOS+01BH ;SELECT DISK LD A,H ;CHECK FOR ERROR OR L JP Z,FNCPM ;BIF NO CPM DISK CALL FIXCONT ;FIX CONTROLLER LD A,(MSGADD+4) ;GET SEARCH MODE OR A ;IS THIS A SEARCH FOR FILE? JR Z,FOPEN ;BIF NO CP 1 ;IS THIS A SEARCH FOR 1ST? JR NZ,SFN ;BIF NO, DO SEARCH FOR NEXT LD C,26 ;SET DMA ADDRESS TO SAVE SECTOR LD DE,080H CALL BDOS LD C,17 ;SEARCH FOR 1ST LD DE,FCB CALL BDOS CP 0FFH ;FILE FOUND? JP Z,FNERR ;BIF NOT LD HL,080H ;MAKE FCB WITH CORRECT FILE NAME ADD A,A ;A*32 ADD A,A ADD A,A ADD A,A ADD A,A ADD A,L LD L,A INC HL PUSH HL LD DE,FCB+1 LD BC,11 LDIR ;MOVE NAME POP HL LD DE,MSGADD+5 LD BC,11 LDIR LD C,15 ;OPEN FILE FOR READ LD DE,FCB CALL BDOS CP 0FFH ;ERROR? JR Z,FNERR ;BIF YES LD A,15 ;SEND OPERATION COMPLETE LD (MSGADD+1),A JR OPOK1 FOPEN: LD A,(MODE) OR A ;READ OR WRITE JR Z,FREAD ;BIF READ LD C,19 ;DELETE FILE IF PRESENT LD DE,FCB CALL BDOS LD C,22 ;DO MAKE FILE LD DE,FCB CALL BDOS OPOK: LD A,1 ;SEND OPERATION COMPLETE LD (MSGADD+1),A OPOK1: XOR A LD (MSGADD+2),A CALL SENDM JP AINP ;GO GET NEXT MESSAGE SFN: LD C,26 ;SET DMA ADDRESS LD DE,080H CALL BDOS LD C,18 ;SEARCH FOR NEXT LD DE,FCB CALL BDOS CP 0FFH ;FILE FOUND? JR Z,FNERR2 ;BIF NOT LD HL,080H ;MAKE FCB WITH CORRECT FILE NAME ADD A,A ;A*32 ADD A,A ADD A,A ADD A,A ADD A,A ADD A,L LD L,A INC HL PUSH HL LD DE,FCB+1 LD BC,11 LDIR ;MOVE NAME POP HL LD DE,MSGADD+5 LD BC,11 LDIR LD C,15 ;OPEN FILE FOR READ LD DE,FCB CALL BDOS CP 0FFH ;ERROR? JR Z,FNERR ;BIF YES LD A,15 ;SEND OPERATION COMPLETE LD (MSGADD+1),A JR OPOK1 FREAD: LD C,15 ;OPEN FILE FOR READ LD DE,FCB CALL BDOS CP 0FFH ;ERROR? JR NZ,OPOK ;BIF IF YES FNERR: LD C,9 ;PRINT ERROR MESSAGE LD DE,FNERRM FNERR1: CALL BDOS FNERR2: LD A,1 ;SEND ERROR MESSAGE LD (MSGADD+1),A LD (MSGADD+2),A CALL SENDM JP AINP FNCPM: LD C,9 LD DE,FERR1M ;NO CPM DISK JR FNERR1 FDATA: LD A,(MODE) ;READ OR WRITE? OR A JR Z,READ ;BIF READ LD DE,(ADDRESS) ;DO TRANSFER LD HL,MSGADD+3 LD BC,128 LDIR LD (ADDRESS),DE ;SAVE CURRENT ADDRESS LD A,(COUNT) ;INCREMENT COUNT INC A LD (COUNT),A CP 4*8 ;SAVE AT MOST 1 TRACK JP NZ,OPOK ;BIF IF BUFFER NOT FULL LD C,1 ;DRIVE B LD E,0 ;DRIVE SELECT FORCED CALL BIOS+01BH ;SELECT DISK CALL FIXCONT ;FIX CONTROLLER CALL WRTDSK ;WRITE BUFFER TO DISK JP Z,OPOK ;BIF ALL OK WRTERR: LD C,9 ;WRITE ERROR LD DE,FERR2M ;DISK FULL JP FNERR1 ;SEND MESSAGE WRTDSK: LD DE,BUFFER WFIL: LD C,26 ;SET DMA PUSH DE CALL BDOS LD C,21 ;WRITE SEQUENTIAL LD DE,FCB CALL BDOS POP DE CP 0 ;ERROR? JR NZ,WRTDERR ;BIF IF NOT OK EX DE,HL LD DE,128 ;ADVANCE DMA ADD HL,DE EX DE,HL LD HL,COUNT DEC (HL) JR NZ,WFIL ;THRU? LD HL,BUFFER ;RESET BUFFER ADDRESS LD (ADDRESS),HL XOR A ;SET ZERO FLAG WRTDERR: RET READ: LD A,(COUNT) ;READ FROM BUFFER OR FROM DISK? OR A JR NZ,BREAD ;BIF BUFFER READ LD A,(EOFF) ;CHECK FOR EOF OR A JR NZ,RDEOF ;BIF FOUND LD HL,BUFFER LD (ADDRESS),HL LD C,1 ;DRIVE B LD E,0 ;DRIVE SELECT FORCED CALL BIOS+01BH ;SELECT DISK CALL FIXCONT ;FIX CONTROLLER LD DE,(ADDRESS) RFIL: LD C,26 ;SET DMA PUSH DE CALL BDOS LD C,20 ;READ SEQUENTIAL LD DE,FCB CALL BDOS POP DE CP 0 ;END OF FILE? JR NZ,READEOF ;BIF IF OK EX DE,HL LD DE,128 ADD HL,DE EX DE,HL LD A,(COUNT) ;IS BUFFER FULL? INC A LD (COUNT),A CP 4*8 JR NZ,RFIL ;BIF NOT BREAD2: LD HL,BUFFER ;SET UP FOR TRANSFER JR BREAD1 FNCPMR: JP FNCPM BREAD: LD HL,(ADDRESS) BREAD1: LD DE,MSGADD+3 LD BC,128 LDIR LD (ADDRESS),HL LD A,129 ;SET MESSAGE LENGTH LD (MSGADD+1),A RSM: CALL SENDM LD HL,COUNT DEC (HL) JP AINP ;GO GET NEXT MESSAGE READEOF: LD A,1 ;SET EOF FLAG LD (EOFF),A JR BREAD2 RDEOF: LD A,1 ;SEND END OF FILE LD (MSGADD+1),A LD A,3 LD (MSGADD+2),A JP RSM OPOKR: JP OPOK FEOF: LD C,1 ;DRIVE B LD E,0 ;DRIVE SELECT FORCED CALL BIOS+01BH ;SELECT DISK CALL FIXCONT ;FIX CONTROLLER LD A,(COUNT) ;ANY DATA LEFT IN BUFFER? OR A JR Z,FEOF2 ;BIF IF NOT CALL WRTDSK ;WRITE BUFFER TO DISK JP NZ,WRTERR ;BIF ALL OK FEOF2: LD C,16 ;CLOSE FILE LD DE,FCB CALL BDOS CP 0FFH ;ERROR? JR NZ,OPOKR LD C,16 ;CLOSE FILE LD DE,FCB CALL BDOS CP 0FFH ;ERROR? JR NZ,OPOKR LD C,9 LD DE,FERR3M ;CLOSE CPM FILE ERROR JP FNERR1 ;SEND MESSAGE FIXCONT: ;FIX CONTROLLER ; LD C,1 ;DRIVE B ; LD E,0 ;DRIVE SELECT FORCED ; CALL BIOS+01BH ;SELECT DISK LD BC,1 ;SELECT TRACK 1 CALL BIOS+1EH LD BC,1 ;SECTOR 1 CALL BIOS+21H LD BC,080H ;DUMMY BUFFER CALL BIOS+24H CALL BIOS+27H ;DO READ TO GET CONTROLER RIGHT RET GETCH: LD A,(HL) ;GET CHARACTER CP '9' JR NC,GETCH1 CP '*' JR Z,GETCHE ;BIF ERROR CP '.' JR Z,GETP ;BIF PERIOD CP ' ' JR Z,GETP ;BIF SPACE GETCHO: XOR A ;CLEAR FLAGS LD A,(HL) INC HL RET GETCH1: CP '?' JR C,GETCHE ;BIF ERROR CP '[' JR Z,GETCHE CP ']' JR NZ,GETCHO GETCHE: OR A ;SET NOT ZERO INC HL RET GETP: SCF ;SET CARRY FLAG INC HL RET FNERRM: DB CR,LF,LF,'CPM FILE NAME ERROR',CR,LF,LF,'$' FERR1M: DB CR,LF,LF,'NO CPM DISK IN DRIVE B',CR,LF,LF,'$' FERR2M: DB CR,LF,LF,'CPM DISK IS FULL',CR,LF,LF,'$' FERR3M: DB CR,LF,LF,'COULD NOT CLOSE CPM FILE',CR,LF,LF,'$' MODE: DB 0 ;READ OR WRITE MODE EOFF: DB 0 ;END OF FILE FLAG COUNT: DB 0 ;BLOCKING COUNT ADDRESS:DW 0 ;BLOCKING ADDRESS FCB: DB 2 ;ALWAYS SELECT DRIVE B: DB 0,0,0,0,0,0,0,0 ;FILE NAME DB 0,0,0 ;FILE TYPE DB 0 ;EX DB 0 ;S1 DB 0 ;S2 DB 0 ;RC DS 16 DB 0 ;CR DB 0,0,0 ;R0,R1,R2 BUFFER: DS 128*4*8 ;BUFFER EOP: DB 0 END