TITL Diskcopy command"Version November 27,1978 DDR * * * * * * DISKCOPY COMMAND * * VERSION 2.0 MOD 0 * * * * ASSEMBLER DIRECTIVES * * ASCF 0 IFLS . LIST ALL "IF" CONDITIONALS COPY NPTDEFS GET 1.4 DEFINITIONS ORG 100H XEQ CSTRT DO THE PART THAT GETS EATEN FIRST * * * A FEW EQUATES * SECTSZ EQU 256 ONE SECTOR FULSZ EQU 320 EACH ADDITIONAL SECTOR CR EQU 10 A CARRIAGE RETURN LF EQU 13 * * * * * * START UP ROUTINE AND BRANCH TO SELECTED OPTION * * * TEST OPTIONS IN A V,F,E,W SEQUENCE * COPY1 CALL DDRI INITIALIZE THE DRIVES * LXI H,MXUNT CHECK IF IN-UNIT OR OUT-UNIT MOV A,M DCR A ...IS >= MAX UNIT DCX H POINT TO INUNT CMP M CC ER1 IF SO THEN ERROR DCX H POINT TO OTUNT CMP M CC ER1 * LDA VEONL VERIFY ONLY? ORA A JNZ VERIFY NO NEED TO TEST OTHER FLAGS * * * TEST LOCK, UNIT ZERO AND OUTPUT UNITS HERE * LDA DTUNT GET DEFAULT UNIT CMP M HL SET FROM ABOVE CZ ER4 ERROR OUT-UNIT SAME AS DEFAULT * MOV A,M GET OUT-UNIT ORA A CZ ER5 ERROR OUT-UNIT CAN'T BE ZERO * LHLD SYSGLO NOW POINT TO SYSTEM LOCK LXI D,GLLOK POINT TO LOCK DAD D MOV A,M DCR A TEST CZ ER9 SYSTEM LOCKED * * BRANCH IF FORMAT * LDA FMONL FORMAT? ORA A JNZ FORMT YUP * * BRANCH IF ERASE * LDA ERFLG ERASE? ORA A JNZ DERAS YUP THIS TIME * PAGE * * ******************************************* * * * CODE FOR DISK TO DISK COPY * * * GIVE MESSAGE AND WAIT FOR A CR OR ESC * * CALL OUST DB CR,LF ASC 'Copy unit ' DB 0 LDA INUNT CALL UNOUT OUTPUT THE UNIT NUMBER CALL OUST ASC ' to unit ' DB 0 LDA OTUNT CALL UNOUT CALL MWAIT WAIT FOR KEY * * * * NOW DO THE ACTUAL COPY * * COPY XRA A STA TETRK AND TRACK 0 * RTRACK LXI H,TKBUF GET CURRENT TRACK TO THE TRACK BUFFER LXI SP,STACK RESET THE STACK IN CASE OF ERROR RETURNS LDA INUNT BE SURE THE INPUT UNIT IS SELECTED STA TUNIT CALL CTRED READ IN THE TRACK * RTRK1 EQU $ LEAVE THIS HERE....THE RETURN ADDRESS OF THE CALL * * ENTIRE TRACK HAS BEEN READ...NOW DO THE WRITES * LDA OTUNT STA TUNIT CHANGE TO THE OUTPUT UNIT CALL SUNIT CALL SECHK SEEK TO PROPER TRACK IN CASE OF DIFFERENT DRIVE LDA TETRK GET WHICH TRACK CPI DITRK THE DIRECTORY? CZ FMTRK IF SO ERASE AND PRE FORMAT THE TRACK * * TKOVR LXI H,TKBUF RESET THE BUFFER SHLD TBUFP * * START AT SECTOR ZERO * XRA A STA TTSEC LDA OTUNT GET OUTPUT UNIT STA TUNIT CALL SUNIT * WRCOP LHLD TBUFP GET THE LOCATION POINTER MOV A,M ORA A JNZ WRCO1 USE TBUF HEADER IF IND=1 LXI H,STDHD-1 CHANGE TO STANDARD HEADER * WRCO1 INX H BUMP THE POINTER XCHG LXI H,TRBUF MVI C,HELEN MOVE PROPER HEADER INTO TRBUF CALL HDSE1 MOVE IT OVER * ********************* * * NOW WRITE THE HEADER * CALL XDSKH WRITE THE HEADER JMP WDERR WRITE HEADER ERROR LHLD TBUFP INX H LXI D,HELEN DAD D POINT TO DATA CALL WDNOP AND WRITE IT JC WDERR * * DATA WAS WRITTEN...PROCESS THE BUFFER * LHLD TBUFP MOV A,M ORA A INX H MOVE PAST INDICATOR MVI B,1 IN CASE OF BRANCH WE WROTE ONLY ONE SECTOR JZ WDNO2 NO REAL DATA, JUST SPACE OVER INDICATOR * LXI D,HELEN DAD D SKIP OVER HEADER XCHG LHLD TBCNT DAD D NOW SKIP THE DATA LDA OHPRO BLKLN HAS SET IT ANI 15 MASK THE UPPER BITS MOV B,A NUMBER OF SECTORS IS IN B * * THIS SECTOR IS WRITTEN STORE THE NEW POINTER * WDNO2 SHLD TBUFP LDA TTSEC THE BLOCK JUST WRITTEN ADD B ADD IN THE SECTOR COUNT STA TTSEC EQUALS THE NEW SECTOR CPI 16 JC WRCOP LOOP UNTIL ALL 16 * * * THE TRACK IS WRITTEN, LOOP TO READ IF COPY NOT FINISHED * NETRK XRA A RESET THE SECTOR STA TTSEC LDA TETRK INR A POINT TO THE NEXT TRACK STA TETRK CPI 77 JC RTRACK NOW DO THE NEXT TRACK JMP COPDN WAY UP ON TOP SO WE CAN EAT THIS CODE * PAGE * * ******************************************* * * * THIS CODE VERIFYS TWO DISKS FOR ABSOLUTE EQUALITY * * VERIFY LDA INUNT LXI H,OTUNT CMP M JNZ VERF1 CALL OUST DB CR,LF ASC 'Verify unit ' DB 0 JMP VERF2 * VERF1 CALL OUST DB CR,LF ASC 'Compare units ' DB 0 LDA INUNT CALL UNOUT CALL OUST ASC " and " DB 0 VERF2 LDA OTUNT CALL UNOUT CALL MWAIT * XRA A STA TETRK * * MAIN LOOP FOR VERIFY * VERFM LXI H,TKBUF FIRST READ THE IN UNIT LDA INUNT STA TUNIT CALL CTRED READ IN THE TRACK SHLD IBEND THE END OF THE INPUT BUFFER (HL SET FROM CTRED) * LXI H,INUNT LDA OTUNT CMP M SEE IF THEY ARE THE SAME JZ VTKDON IF SO THEN SKIP ALL THE TESTS STA TUNIT LXI H,VEBUF NOW THE OUT UNIT CALL CTRED SHLD OBEND OUTPUT BUFFER END LXI D,VEBUF AND THE START CALL DSUB HL = HL - DE MOV B,H MOV C,L BC HAS LENGTH OF OUTBUF LHLD IBEND LXI D,TKBUF CALL DSUB HL GETS LENGTH OF INBUF MOV A,B CMP H JNZ NVERF MUST BE THE SAME!! MOV A,C CMP L JNZ NVERF * * * NOW COMPARE THE CONTENT OF BOTH BUFFERS * * BC = COUNT * LXI H,TKBUF LXI D,VEBUF * VLOOP DCX B MOV A,B ORA C JZ VTKDON THIS TRACK IS DONE LDAX D CMP M INX H INX D JZ VLOOP * NVERF CALL OUST DB CR,LF ASC 'Difference found on track ' DB 0 LDA TETRK CALL DEC99 JMP DRRET AND FINISH UP THE OPERATION * * VTKDON LDA TETRK GET TRACK INR A STA TETRK CPI 77 JNZ VERFM JMP VEDON * PAGE * * ************************************ * * * READ A FULL TRACK INTO BUFFER POINTED TO BY TKBUF * CTRED SHLD CBUFP * * ERROR RETURNS ETC CAN COME HERE * CTTVR LHLD CBUFP GET POINTER SHLD TBUFP SET THE POINTER XRA A STA TTSEC CALL SUNIT SELECT UNIT IN TUNIT CALL SECHK STEP TO PROPER TRACK * ********************* * * * LOOP POINT FOR EACH SECTOR ON EACH TRACK * CTOVR LDA TUNIT GET CURRENT UNIT CALL SUNIT CALL ESCST SEE IF ESCAPE IS WANTED * THEAD CALL DATNS TOVER CALL HDVER * * INIT THE HEADER * MVI A,HELEN LXI H,IHEAD CLRHE MVI M,0FFH INX H DCR A JNZ CLRHE * * READ AND CHECK HEADER * TDAOP CALL HDATOP READ THE NEXT HEADER TDAO1 IN STAPT ANI ABERR+CCERR JNZ HERRA ERROR READING HEADER * IN STAPT LOOP FOR READY OR ERROR ANI TRCOM+SREDY LOOP FOR FLAG JZ TDAO1 * ANI TRCOM JZ HERRA ERROR IF NO TC...CAME OUT WITH SREADY * * HEADER SEEMS OK...TEST PARAMETERS * LDA IHTRK ORA A JM TNSEC ????? <----<<<<< CMP C TEST FOR TRACK ERROR JNZ TTKER LDA IHSEC CMP B JNZ TNSEC FIND PROPER SECTOR * * WE'VE READ A PROPER HEADER NOW FIND * OUT IF THERE'S ANY DATA. * LHLD IHFID MOV A,H ORA L JZ HERR1 NO DATA SET UP FOR STANDARD HEADER ON WRITE * * * HEADER SHOWS VALID FILE - SO READ INDICATED DATA * TO THE TRACK BUFFER IF VALID READ OCCURS. * SHLD TFID SET ID INTO TRANSFER DESCRIPTOR LHLD TBUFP GET CURRENT POINTER LXI D,HELEN+1 POINT PAST HEADER DAD D WE DON'T MOVE THE POINTER UNTIL AFTER READ SHLD TBUF WE'LL READ THE DATA TO HERE LHLD IHSIZ SHLD TBCNT THE SIZE TOO SHLD DRLEN NEEDED ALL OVER LDA IHPRO STA OHPRO * ********************* * * NOW DO THE READ OPERATION * MVI A,RDATA STA DOPER SET READ OPERATION CALL GOPER JUST READ THE DATA JMP RDERR ERROR RETURN * * VALID DATA WAS READ...PROCESS THE BUFFER * MVI A,1 SET INDICATOR LXI D,IHEAD CALL HDSET MOVE IHEAD INTO THE BUFFER XCHG . TBUFP TO DE LHLD IHSIZ GET THE SIZE OF DATA BLOCK THAT WAS READ IN DAD D SHLD TBUFP NEW POINTER FOR NEXT SECTOR LDA IHPRO ANI 15 MOV B,A NUMBER OF SECTORS USED BY THIS BLOCK * * COME HERE TO MOVE PAST SECTORS * NODAT LDA TTSEC CURRENT SECTOR+REG "B" ADD B CPI 16 HAVE WE DONE THE LAST SECTOR STA TTSEC JC CTOVR KEEP DOING THE READS RET * PAGE * * ******************************************* * * * * * ROUTINE TO WRITE THE DATA FROM THE BUFFER TO DISK * WDNOP SHLD TBUF SET UP THE DESCRIPTOR,WRITE DATA FROM HERE LHLD TRSIZ SHLD TBCNT LHLD TRFID SHLD TFID CALL WDSK WRITE OUT THE DATA STC . SET ERROR!! RET DB 0 SPACE FILLER ORA A RET . WITH CARRY CLEAR FOR NORMAL RETURN * PAGE * * * * ERROR ROUTINES * HERRA MVI A,-1 OUT TRAPT CANCEL LAST COMMAND CALL ERRPR JMP HERR1 JMP TOVER * * COULDN'T READ THE HEADER SO USE STANDARD * HERR1 XRA A CALL HDSET SET THE TRACK BUFFER RIGHT MVI B,1 JMP NODAT DATS RIGHT SKIP THE SECTOR * * * TRACK ERROR * TTKER CALL TERRP JMP TTKE1 SKIP THIS TRACK JMP TOVER TRY MORE * TTKE1 POP H GET RETURN ADDRESS MOV A,H CPI RTRK1 JNZ COABT CALL FMTRK ERASE THE OUT-UNIT * * ERASE MUST CHANGE TO THE OUTPUT UNIT!!! * JMP NETRK AND SKIP TRACK * * * HAVEN'T FOUND SECTOR YET * TNSEC CALL WAITS WAIT FOR SREADY LDA DSECN INR A STA DSECN CPI 25 JC TDAOP LDA VEONL IF CALLED FROM VERIFY THEN THIS IS ORA A REALLY AN ERROR JZ HERR1 * * * ERROR TRYING TO READ DATA FIELD * RDERR CALL ESCST CALL OUST DW 0A0DH ASC 'Unable to read ' DB 0 * CALL TSMES LDA WAFLG SEE IF WAIT FLAG IS SET ORA A JNZ HERR1 CALL OUST ASC 'Retry? ' DB 0 CALL CONIN ANI 7FH PUSH PSW CALL CONOUT CALL OUST DW 0A0DH DB 0 POP PSW ORI ' ' CPI 'n' JZ HERR1 SKIP OVER IF NO * RDER1 XRA A STA TTSEC JMP CTTVR TRY...TRY AGAIN * TSMES CALL OUST ASC 'sector- ' DB 0 LDA TTSEC CALL DEC99 OUTPUT IN DECIMAL CALL OUST ASC ' track- ' DB 0 LDA TETRK CALL DEC99 CALL OUST DW 0A0DH DB 0 RET * * WDERR LXI SP,STACK CALL OUST DW 0A0DH ASC 'Write retry... ' DB 0 CALL TSMES CALL FMTRK ERASE AND FORMAT JMP TKOVR AND DO AGAIN * PAGE * * ************************************ * * * * THIS ROUTINE MOVES THE HEADER POINTED TO BY "DE" * INTO THE CURRENT LOCATION OF THE TRACK BUFFER. REG * 'A' IF ZERO ONLY SETS THE INDICATOR TO SHOW NO VALID * DATA FOLLOWS. * * ON RETURN THE POINTER IS UPDATED ONE BEYOND THE HEADER * HDSET LHLD TBUFP GET CURRENT BUFFER LOCATION MOV M,A SAVE THE INDICATOR MVI C,HELEN HEADER LENGTH INX H ORA A CNZ HDSE1 MOVE IN HEADER IF NON ZERO SHLD TBUFP UPDATE THE BUFFER POINTER RET * * * GENERAL PURPOSE MOVE ROUTINE * HDSE1 LDAX D MOV M,A INX H INX D DCR C JNZ HDSE1 RET * * * SUBTRACT DE FROM HL AND RETURN RESULT IN HL * DSUB MOV A,L SUB E MOV L,A MOV A,H SBB D MOV H,A HL HAS LENGTH OF BUFFER INX H RET * * DEC99 MVI B,'0' PUSH PSW XRA A STA FIRS1 POP PSW DEC2 SUI 10 JC DEC3 INR B JMP DEC2 * * DEC3 ADI 10 ADJUST BACK PUSH PSW CALL WRITB POP PSW ADI '0' MOV B,A * WRITB LDA FIRS1 ORA A MOV A,B JNZ CONOUT STA FIRS1 CPI '0' RZ JMP CONOUT * FIRS1 DB 0 * * * * GIVE MESSAGE AND WAIT FOR CR TO CONTINUE * * SKIP MESSAGE IF -W WAS GIVEN * MWAIT LDA WAFLG NO WAIT? ORA A RNZ * CALL OUST DB CR,LF ASC 'Press RETURN to begin; MODE to abort: ' DB 0 * MESIN CALL CONIN ANI 7FH JZ DRRET COPY ABORT CPI 0DH CARRIAGE RETURN JNZ MWAIT RETYPE MESSAGE IF ANYTHING ELSE CALL CONOUT MVI B,10 LINE FEED CALL CONOUT RET * * * MESSAGE OUTPUT ROUTINE * OUST POP H OUST5 MOV A,M INX H ORA A JNZ OUST9 PCHL * OUST9 CALL CONOUT JMP OUST5 * * UNOUT ADI '0' JMP CONOUT OUTPUT IT AND RETURN * * ********* COPY DCOP:2S/1 * COPY DCOP:3S/1 * * END *