*THIS PROGRAM TRANSFERS A FILE FROM A CP/M FORMAT DISK TO A * DEC FORMAT DISK * * *CP/M DEFINITIONS FOR PRIMITIVES * RDCON EQU 1 ;GET CHAR FROM CONSOLE WRTCON EQU 2 ;TYPE CHAR ON CONSOLE RDRDR EQU 3 ;GETCHAR FROM PAPER TAPE READER WRTPCH EQU 4 ;SEND CHAR TO PUNCH WRTLST EQU 5 ;SEND CHAR TO LIST DEVICE IOSTAT EQU 7 ;INTERROGATE I/O STATUS (NOT USED HERE) ALTIO EQU 8 ;ALTER I/O STATUS (NOT USED HERE) PCONBF EQU 9 ;PRINT CONSOLE BUFFER RCONBF EQU 10 ;READ CONSOLE BUFFER CONST EQU 11 ;CHECK CONSOLE STATUS (BIT0 SET IF READY) LIFTHD EQU 12 ;LIFT DISK HEAD (NOT USED HERE) RSTDSK EQU 13 ;DMA ADDR TO 80H,SELECT DISK A SELDSK EQU 14 ;SELECT DISK OPENF EQU 15 ;OPEN FILE CLOSEF EQU 16 ;CLOSE FILE SRCH1 EQU 17 ;SEARCH FOR FIRST FILE OCCURRENCE SCHNXT EQU 18 ;SEARCH FOR NEXT FILE OCCURRENCE DELETF EQU 19 ;DELETE FILE READF EQU 20 ;READ TO BUFFER WRITEF EQU 21 ;WRITE TO BUFFER MAKEF EQU 22 ;CREATE A FILE ENTRY RENAMF EQU 23 ;RENAME A FILE INTLOG EQU 24 ;INTERROGATE LOGIN VECTOR INTDSK EQU 25 ;INTERROGATE DISK (RETURNS SELECTED DISK #) SETDMA EQU 26 ;SET DMA ADDR INTALL EQU 27 ;INTERROGATE ALLOCATION VECTOR * BDOS EQU 0005H ;DOS ENTRY POINT FCB EQU 5CH ;DEFAULT FILE CONTROL BLOCK ADDRESS BUFF EQU 80H ;DEFAULT DMA ADDRESS * ORG 0100H * *SET UP STACK LXI SP,STKTOP JMP EXEC *STACK AREA STACK: DS 64 STKTOP EQU $ * *VARIABLES CONBUF: DS 80 * EXEC: MVI A,79 STA CONBUF ;SET FIRST BYTE TO BUFFER LENGTH JMP MAIN ;JUMP TO MAIN PROGRAM *SUBROUTINES PCHAR: ;PRINT CHAR IN REG A PUSH H! PUSH D! PUSH B ;ENVIRONMENT SAVED MVI C,WRTCON MOV E,A CALL BDOS POP B! POP D! POP H ;ENVIRONMENT RESTORED RET * CRLF: ;PRINT A CARRIAGE RETURN & LINE FEED MVI A,0DH CALL PCHAR MVI A,0AH CALL PCHAR RET * PNIB: ;PRINT NIBBLE IN REG A ANI 0FH ;LOWER 4 BITS CPI 10 JNC P10 ;LESS THAN OR EQUAL TO 9 ADI '0' JMP PRN ;GREATER THAN OR EQUAL TO 10 P10: ADI 'A'-10 PRN: CALL PCHAR RET * PHEX: ;PRINT HEX CHAR IN REG A PUSH PSW RRC RRC RRC RRC CALL PNIB ;PRINT NIBBLE POP PSW CALL PNIB RET * CHIN: ;GET A CHAR FROM CONSOLE PUSH H! PUSH D! PUSH B MVI C,RDCON CALL BDOS POP B! POP D! POP H RET * MSG: ;PRINT A MESSAGE POINTED TO BY HL (END OF MESSAGE=0FFH) MOV A,M CPI 0FFH RZ ;RETURN IF END OF MESSAGE CALL PCHAR INX H JMP MSG * SETTRK: ;SET TRACK IN C LHLD 1 LXI D,27 DAD D PCHL * SETSEC: LHLD 1 LXI D,30 DAD D PCHL * RDSEC: LHLD 1 LXI D,36 DAD D PCHL * WRTSEC: LHLD 1 LXI D,39 DAD D PCHL * RDWRT: ;READ/WRITE TO DISK B-LOG.TRACK IN "TRACK",LOG.SECTOR IN "SECTOR" PUSH B PUSH D LDA TRACK STA BTRACK LDA SECTOR STA BSECT LDA INTLEV ;GET INTERLEAVE FLAG ORA A JZ CONSEC ;0 > CONSECUTIVE SECTORS * *INTERLEAVE ALGORITHM FOR STANDARD DEC DISKS * MVI H,0 LDA BTRACK MOV L,A DCX H ;HL=TRACK-1;NOW MULTIPLY BY 6 MOV A,L ADD A MOV L,A MOV A,H RAL MOV H,A SHLD X2 ;HL*2 INTLV3: MOV A,L ADD A MOV L,A MOV A,H RAL MOV H,A XCHG LHLD X2 DAD D ;HL*6 IN HL * 6*(TRACK-1) IN HL * INTLV0: MOV A,H ORA A JNZ INTLV5 MOV A,L CPI 26 JC INTLV4 INTLV5: LXI D,0-26 DAD D JMP INTLV0 INTLV4: LDA BSECT DCR A ;SHIFT SECTOR DOWN (0-25) PUSH PSW ADD A MOV E,A ;SAVE S2 POP PSW CPI 13 MOV A,E ;GET S2 BACK TO ACC. JM INTLV2 INR A INTLV2: ADD L ;ADD BIAS INTLV1: SUI 26 JP INTLV1 ADI 27 STA BSECT ;NEW PHYSICAL SECTOR TO BSECT * *END OF INTERLEAVE ALGORITHM * CONSEC: LDA BSECT MOV C,A CALL SETSEC LDA BTRACK MOV C,A CALL SETTRK LDA OPFLAG CPI 0 JNZ CONSC1 CALL RDSEC POP D POP B RET CONSC1: CALL WRTSEC POP D POP B RET * DIRECT: ;IF READ:GET SEG.1 OF DIRECT.TO DRBUFF ;IF WRITE:WRITE SEG.1 OF DIRECT.ONTO DIRECTORY AREA OF DEC DISK ;IN BOTH CASES,ASSUME FILE WILL BE IN OR FIT IN SEG.1 MVI A,2 STA COUNT MVI A,01H STA TRACK MVI A,19H STA SECTOR LXI H,DRBUFF SHLD BUFFPT ;INIT. BUFFPT MVI C,SELDSK MVI E,1 ;B CALL BDOS LXI D,0 GTDIR1: LHLD BUFFPT DAD D SHLD BUFFPT XCHG MVI C,SETDMA CALL BDOS CALL RDWRT ;READ/WRITE SECTOR FROM/TO DISK LXI D,128 MVI A,1AH STA SECTOR LDA COUNT DCR A STA COUNT JNZ GTDIR1 ;READ IN FIRST 2 SECTORS MVI A,6 STA COUNT MVI A,02 STA TRACK DCR A STA SECTOR GTDIR2: LXI D,128 ;LENGTH OF A SECTOR LHLD BUFFPT DAD D SHLD BUFFPT XCHG ;DMA ADDR > DE MVI C,SETDMA CALL BDOS CALL RDWRT LDA SECTOR INR A STA SECTOR LDA COUNT DCR A STA COUNT JNZ GTDIR2 RET * * TRSEC: ;CALCULATES TR#,SEC# FROM # OF BLOCKS TO FILE LHLD BLOCKS ;#OF BLOCKS > HL (4 SECTORS/BLOCK) MVI B,2 TRSC1: MOV A,L ADD A MOV L,A MOV A,H RAL MOV H,A DCR B JNZ TRSC1 ;BLOCKS*4 IN HL * MVI A,1 STA TRACK ;INIT. TRACK TRSC4: LXI D,0FFE6H ;-26 DAD D MOV A,H RAL JNC TRSC2 LXI D,1BH DAD D JMP TRSC3 TRSC2: LDA TRACK INR A STA TRACK JMP TRSC4 TRSC3: MOV A,L STA SECTOR RET ;TR# IS IN TRACK,SEC# IS IN SECTOR * NAMCOM: ;COMPARES PERM. FILE NAME WITH NEW FILE NAME AND SETS FLAG ; "MATCH" IF SAME PUSH H PUSH B MVI C,6 LXI H,FILE SHLD FLNMPT LXI H,FILELO SHLD FLBFPT NMCOM1: LHLD FLNMPT MOV B,M INX H SHLD FLNMPT LHLD FLBFPT MOV A,M INX H SHLD FLBFPT CMP B JNZ NOMACH DCR C JNZ NMCOM1 MVI A,1 STA MATCH POP B! POP H RET NOMACH: XRA A STA MATCH POP B! POP H RET * * * CHR3: ;TAKES 3 ASCII CHARS FROM A,B,C (SEQ.) & CONVERTS THEM ; TO A RADIX50 WORD IN R50NUM PUSH H PUSH D CALL ASCR50 ;CONVERT TO RAD50 CHAR MOV L,A MVI H,0 CALL X50 CALL X50 ;MULTIPLY HL BY 50**2 (OCTAL) SHLD R50NUM ;C1*50**2 MOV A,B CALL ASCR50 MOV L,A MVI H,0 CALL X50 ;C2*50Q XCHG LHLD R50NUM DAD D SHLD R50NUM ;C1*50**2+C2*50 MOV A,C CALL ASCR50 MOV L,A MVI H,0 XCHG LHLD R50NUM DAD D SHLD R50NUM ;C1*50**2+C2*50+C3 POP D POP H RET * ASCR50: ;CONVERTS AN ASCII CHAR TO A BASIC RADIX50 CHAR(RET IN A) CPI 20H JNZ ASC1 XRA A RET ASC1: CPI '$' JNZ ASC2 MVI A,1BH RET ASC2: CPI '.' JNZ ASC3 MVI A,1CH RET ASC3: CPI 'A' JM ASC4 CPI 5BH JP ILLCHR SUI 40H RET ASC4: CPI '0' JM ILLCHR CPI 3AH JP ILLCHR SUI 12H RET ILLCHR: LXI H,M5 ;NON-RAD50 CHAR-TRY AGAIN CALL MSG JMP AGAIN * X50: ;MULTIPLY HL BY 50Q & RETURN IN HL PUSH B PUSH D MVI B,3 X50A: MOV A,L ADD A MOV L,A MOV A,H RAL MOV H,A DCR B JNZ X50A SHLD X8 MVI B,2 X50B: MOV A,L ADD A MOV L,A MOV A,H RAL MOV H,A DCR B JNZ X50B XCHG LHLD X8 DAD D POP D POP B RET GETNAM: JMP BEGIN * *BUFFER:* NAMBUF: DS 25 * * BEGIN: MVI A,24 STA CONBUF MVI C,RCONBF LXI D,CONBUF CALL BDOS LXI H,CONBUF+1 LDA CNTMSK MOV D,A MOV A,M STA COUNT CMP D JP SYNERR INX H LXI B,NAMBUF LDA COUNT2 MOV D,A MVI E,0 MOVCHR: MOV A,M CPI '.' JZ DOT DCR D JZ SYNERR STAX B INX B INX H INR E JMP MOVCHR DOT: DCR D JZ GETEXT MVI A,20H DOT1: STAX B INX B DCR D JNZ DOT1 GETEXT: MVI A,'.' STAX B INR E LDA COUNT SUB E CPI 4 JP SYNERR MOV D,A MVI A,3 SUB D INR A MOV E,A CPI 4 JZ GTEXT2 GTEXT1: INX H INX B MOV A,M STAX B DCR D JNZ GTEXT1 GTEXT2: DCR E JZ PUT$ MVI A,20H INX B STAX B JMP GTEXT2 PUT$ INX B MVI A,'$' STAX B RET SYNERR: CALL CRLF LXI H,M7 ;SYNTAX ERROR CALL MSG JMP AGAIN * * * MAIN: LXI H,SIGNON ;THIS PROGRAM... CALL MSG LXI H,M18 ;ZERO DEC DISK(Y/N)? CALL MSG CALL CHIN CPI 'Y' JNZ AGAIN LXI H,M19 ;ARE YOU SURE(Y/N)? CALL MSG CALL CHIN CPI 'Y' JNZ AGAIN LXI H,M0 ;PLACE DESTINATION... CALL MSG STDIR1: LXI H,M14 ;IS DEC DISK INTERLEAVED? CALL MSG CALL CHIN CPI 'Y' JNZ STDIR2 MVI A,1 STA INTLEV JMP SETDIR STDIR2: CPI 'N' JNZ STDIR1 XRA A STA INTLEV SETDIR: LXI H,4 SHLD HDWD1 ;SEGMENTS AVAILABLE=4 LXI H,0 SHLD HDWD2 ;NEXT SEGMENT=0 SHLD HDWD4 ;EXTRA WORDS/ENTRY=0 INX H SHLD HDWD3 ;HIGHEST OPEN SEG.=1 LXI H,000EH SHLD HDWD5 ;FILES START AT BLOCK 000E LXI H,0200H SHLD ENTRYS ;SET SW1 TO EMPTY FILE LXI H,479 SHLD ENTRYS+8 ;SET EMPTY LENGTH TO ENTIRE DISK (479 BL) LXI H,0800H SHLD ENTRYS+14 ;SET SW2 TO END-OF-SEGMENT MVI A,0FFH STA OPFLAG CALL DIRECT ;WRITE OUT NEW DIRECTORY JMP FINIS * * AGAIN: CALL CRLF LXI H,M10 ;CP/M FILENAME.TYP= CALL MSG MVI A,9 STA COUNT2 ;COUNT FOR CP/M'S 8 CHARS +1 MVI A,13 STA CNTMSK ;MASK FOR TOO MANY CHARS CALL GETNAM ;GET NAME FROM OPERATOR INTO NAMBUF & PAD CALL CRLF LXI H,NAMBUF ;1ST 3 CHARS LXI D,FCB+1 ;STORE FILENAME.TYP MVI C,8 LOOP1: MOV A,M STAX D INX H INX D DCR C JNZ LOOP1 INX H ;GO PAST '.' MVI C,3 LOOP2: MOV A,M STAX D INX H INX D DCR C JNZ LOOP2 ;FILENAME.TYPE STORED MVI C,4 XRA A LOOP3: STAX D ;ZERO EX,2 UNUSED BYTES,& RC INX D DCR C JNZ LOOP3 CALL CRLF LXI H,M6 ;DEC FILNAM.EXT= CALL MSG MVI A,7 STA COUNT2 ;COUNT FOR DEC'S 6 CHARS +1 MVI A,11 STA CNTMSK ;MASK FOR TOO MANY CHARS CALL GETNAM CALL CRLF LXI H,NAMBUF MOV A,M INX H MOV B,M INX H MOV C,M CALL CHR3 LHLD R50NUM SHLD FILE ;CONVERT 1ST 3 ASCII CHARS LXI H,NAMBUF+3 MOV A,M INX H MOV B,M INX H MOV C,M CALL CHR3 LHLD R50NUM SHLD NAME ;CONVERT 2ND 3 ASCII CHARS LXI H,NAMBUF+7 MOV A,M INX H MOV B,M INX H MOV C,M CALL CHR3 LHLD R50NUM SHLD EXT GOON: LXI H,M14 ;IS DEC DISK INTERLEAVED (Y/N)? CALL MSG CALL CHIN CPI 'Y' JNZ NO2 MVI A,1 STA INTLEV ;SET INTERLEAVE FLAG JMP GOON2 NO2: CPI 'N' JNZ GOON XRA A STA INTLEV * GOON2: CALL CRLF LXI H,M0 ;PLACE DESTINATION (DEC) DISK ON DRIVE B CALL MSG LXI H,M0A ;READY (Y/N)? CALL MSG CALL CHIN CPI 'Y' JNZ AGAIN *GET DIRECTORY INTO DRBUFF * XRA A STA OPFLAG ;SET FLAG FOR READ CALL DIRECT ;READ IN DIRECT. *DIRECTORY READY-SEARCH FOR END XRA A STA ENTCNT ;INIT. ENTRY COUNT LHLD HDWD5 SHLD BLKCNT ; " BLOCK COUNT LHLD ENTRYS SHLD ENTRY ; " ENTRY POINTER LXI H,ENTRYS SHLD BUFFPT ; " BUFFER PT. DRLOOP: LHLD ENTRY MVI A,08 CMP H CNZ FILBLK ;UPDATE BLKCNT,ETC. JNZ DRLOOP LDA ENTCNT CPI 70 JNZ DIROK LXI H,M9 ;?DIR FULL? CALL MSG JMP FINIS DIROK: LHLD BUFFPT LXI D,0-6 DAD D ;GO BACK TO LAST FILE LENGTH MOV E,M INX H MOV D,M XCHG SHLD LENGTH XCHG CALL NEGDE PUSH H LHLD BLKCNT DAD D SHLD BLKCNT ;SUBTRACT EMPTY FILE LENGTH FROM BLKCNT POP H LXI D,0-8 DAD D MOV A,M CPI 02 JZ DIROK2 LXI H,M9 CALL MSG JMP FINIS DIROK2: DCX H SHLD BUFFPT ;LEAVE POINT. IN POS. FOR LATER * *DEC DIRECTORY HAS BEEN SET UP-NOW OPEN CP/M FILE FOR INPUT * MVI C,SELDSK MVI E,0 CALL BDOS MVI C,OPENF LXI D,FCB CALL BDOS CPI 0FFH JNZ OPENOK LXI H,M4 ;FIL NOT FND CALL MSG JMP AGAIN OPENOK: XRA A STA FCB+32 ;ZERO NEXT RECORD LHLD BLKCNT SHLD BLOCKS CALL TRSEC ;LOAD STARTING LOG. TR & SEC TO VARIABLES CALL CRLF * MVI A,0FFH STA OPFLAG ;SET TO WRITE ON DISK B * * *CALCULATE BUFFER SIZE * LXI H,PRGEND XCHG CALL NEGDE LHLD 6 ;GET BDOS ADDR DAD D MVI C,7 DIV128: MOV A,H RAR MOV H,A MOV A,L RAR MOV L,A DCR C JNZ DIV128 MOV A,H ANI 01 MOV H,A ;DIFFERENCE/128 IN HL * * DCX H DCX H SHLD TOPCNT ;SAVE # OF BUFFERS LXI H,0 SHLD RCRDS * *BEGIN TRANSFER-SET UP BUFFER POINTER * XFER0: LXI H,PRGEND SHLD XFBFPT LXI H,0 SHLD PASSCT LHLD TOPCNT SHLD COUNT3 MVI C,SELDSK MVI E,0 CALL BDOS ;SELECT DISK A LXI D,BUFF MVI C,SETDMA CALL BDOS ;SET DMA TO DEFAULT BUFFER LXI D,0 * * XFER: LHLD XFBFPT DAD D SHLD XFBFPT MVI C,READF LXI D,FCB CALL BDOS CPI 255 JZ CPMERR CPI 1 JZ EOFFND MVI C,80H LHLD XFBFPT LXI D,BUFF XFER3: LDAX D CPI 1AH JZ EOF MOV M,A INX D INX H DCR C JNZ XFER3 LHLD PASSCT INX H SHLD PASSCT LHLD RCRDS INX H SHLD RCRDS LXI D,128 LHLD COUNT3 CALL DCR16 SHLD COUNT3 JC XFER * *OUT OF BUFFER ROOM-WRITE OUT BUFFER * LHLD TOPCNT SHLD COUNT4 ;DO ALL SECTORS IN BUFFER LXI H,PRGEND SHLD XFBFPT MVI C,SELDSK MVI E,1 CALL BDOS LXI D,0 * XFER1: LHLD XFBFPT DAD D SHLD XFBFPT XCHG MVI C,SETDMA CALL BDOS CALL RDWRT CALL REGMOD LXI D,128 LHLD COUNT4 CALL DCR16 SHLD COUNT4 JC XFER1 * JMP XFER0 * *EOF CHAR FOUND-CHANGE IT & REST OF BUFFER TO 00'S * EOF: XRA A MOV M,A INX H DCR C JNZ EOF+1 LHLD RCRDS INX H SHLD RCRDS LHLD PASSCT INX H SHLD PASSCT * *WRITE OUT BUFFER * EOFFND: LXI H,PRGEND SHLD XFBFPT LHLD PASSCT DCX H SHLD COUNT4 MVI C,SELDSK MVI E,1 CALL BDOS LXI D,0 * XFER2: LHLD XFBFPT DAD D SHLD XFBFPT XCHG MVI C,SETDMA CALL BDOS CALL RDWRT CALL REGMOD LXI D,128 LHLD COUNT4 CALL DCR16 SHLD COUNT4 JC XFER2 * *FILE WRITTEN OUT-NOW CALC. # OF BLOCKS,ETC. * * LHLD RCRDS CALL DIV4 ;DIVIDE RCRDS BY 4 TO GET BLOCKS CPI 0 JZ NOXTRA CPI 4 JM XTRA LXI H,M16 ;DIV4 ERROR CALL MSG JMP FINIS XTRA: INX H NOXTRA: SHLD BLKNUM STA EXTRA * *NOW WRITE "EXTRA" SECTORS OF 00'S (TO FILL PHYSICAL BLOCK) * MVI C,SELDSK MVI E,1 CALL BDOS LDA EXTRA CPI 0 JZ NEXTRA MOV B,A MVI A,4 SUB B MOV B,A ;#OF SECT. TO B XRA A LXI H,BUFF MVI C,80H BFLOOP: MOV M,A INX H DCR C JNZ BFLOOP ;FILL BUFFER W/00 PUSH B ;SAVE EXTRA COUNT IN B LXI D,BUFF MVI C,SETDMA CALL BDOS ;SET DMA TO BUFF POP B BFLOP1: CALL RDWRT CALL REGMOD DCR B JNZ BFLOP1 ;DO B TIMES * NEXTRA: LHLD BLKNUM XCHG CALL NEGDE LHLD LENGTH DAD D JC LNTHOK LXI H,M17 ;FILE WON'T FIT CALL MSG JMP FINIS LNTHOK: SHLD LENGTH ;SAVE NEW EMPTY LENGTH * * *CAN CLOSE DEC FILE NOW * CLOSE: LHLD BUFFPT ;HL PT. @ NEW FILE SW INX H MVI A,04 MOV M,A ;CHANGE SW TO PERM. FILE INX H LDA FILE ;PUT NEW FILNAM.EXT IN ENTRY MOV M,A INX H LDA FILE+1 MOV M,A INX H LDA NAME MOV M,A INX H LDA NAME+1 MOV M,A INX H LDA EXT MOV M,A INX H LDA EXT+1 MOV M,A INX H LDA BLKNUM ;PUT NEW FILE LENGTH IN ENTRY MOV M,A INX H LDA BLKNUM+1 MOV M,A INX H INX H INX H ;HL PT.@ DATE XRA A MOV M,A INX H MOV M,A ;ZERO DATE INX H MOV M,A ;SET UP NEXT ENTRY (EMPTY) INX H MVI A,02 MOV M,A LXI D,7 DAD D ;PT.@ NEW EMPTY FILE LENGTH LDA LENGTH MOV M,A INX H LDA LENGTH+1 MOV M,A LXI D,5 DAD D ;HL PT.@ NEW EOS SW XRA A MOV M,A INX H MVI A,08 MOV M,A ;WRITE END OF SEGMENT CODE * *DIRECTORY IS MODIFIED-NOW WRITE IT ON DEC DISK MVI A,0FFH STA OPFLAG ;TO BE SURE CALL DIRECT JMP FINIS * * * *SUBROUTINES * REGMOD: ;MODIFY DRIVE B REGISTERS AFTER SECTOR READ LDA SECTOR CPI 26 JZ RM1 INR A STA SECTOR RET RM1: MVI A,1 STA SECTOR LDA TRACK INR A STA TRACK CPI 75 RM ;RET IF LESS THAN 75 LXI H,M17 CALL MSG JMP FINIS * DCR16: ;DECREMENT HL BY 1 & SET FLAG C IF RESULT NOT ZERO ; NC IF RESULT 0 PUSH D LXI D,0FFFFH ;-1 DAD D POP D RET * DIV4: ;DIVIDES HL BY 4-RESULT IN HL W/ REM. IN A PUSH B MVI C,0 MVI B,2 DIV4A: MOV A,H RAR MOV H,A MOV A,L RAR MOV L,A MOV A,C RAR MOV C,A DCR B JNZ DIV4A MOV A,H ANI 3FH ;STRIP EXTRA BITS MOV H,A MOV A,C RAR RAR RAR RAR RAR RAR ANI 3 ;STRIP EXTRA BITS POP B RET * NEGDE: ;NEGATE (2'S COMP.) DE REGISTER PUSH PSW MOV A,D CMA MOV D,A MOV A,E CMA MOV E,A INX D POP PSW RET FILBLK: ;UPDATE BLOCK COUNT & SET UP ENTRIES ; CHANGE PERM SW TO EMPTY SW IF NAMES MATCH PUSH PSW MVI A,4 CMP H JNZ FLBLK1 LHLD BUFFPT INX H INX H MOV A,M STA FILELO INX H MOV A,M STA FILEHI INX H MOV A,M STA NAMELO INX H MOV A,M STA NAMEHI INX H MOV A,M STA EXTLO INX H MOV A,M STA EXTHI CALL NAMCOM LDA MATCH RAR JC MTCHES LXI D,0-7 DAD D SHLD BUFFPT JMP FLBLK1 MTCHES: LXI D,0-6 DAD D ;PTER @ SW LO BYTE MVI A,2 MOV M,A ;CHANGE SW TO EMPTY FILE DCX H SHLD BUFFPT FLBLK1: LHLD BUFFPT LXI D,8 DAD D ;PT.@ LENGTH BYTE1 MOV E,M INX H MOV D,M PUSH H LHLD BLKCNT DAD D SHLD BLKCNT POP H LXI D,5 DAD D ;PT.@NEXT ENTRY BYTE1 SHLD BUFFPT MOV A,M STA ENTRY INX H MOV A,M STA ENTRY+1 LDA ENTCNT INR A STA ENTCNT ;INR ENTRY COUNT POP PSW RET * CMP16: ;COMPARES HL &DE & SETS USUAL FLAGS MOV A,H CMP D RNZ MOV A,L CMP E RET * * CPMERR: LXI H,M12 ;CP/M WRITE ERROR CALL MSG JMP FINIS * * FINIS: LXI H,M15 ;ANOTHER TRANSFER? CALL MSG CALL CHIN CPI 'Y' JZ AGAIN JMP 0 ;REBOOT CP/M AND GO TO IT * * *VARIABLES INTLEV: DS 1 ;INTERLEAVE FLAG OPFLAG: DS 1 ;OPERATION FLAG- 0>READ,FF>WRITE EXTRA: DS 1 ;# OF EXTRA SECTORS TO XFER BLKNUM: DS 2 ;LENGTH OF NEW FILE ENTCNT: DS 1 ;# OF ENTRIES IN DEC DIRECTORY X2: DS 2 ;HL*2 TOPCNT: DS 2 ;# OF BUFFERS IN MEMORY SPACE XFBFPT: DS 2 ;TRANSFER BUFFER POINTER PASSCT: DS 2 ;PASS COUNT IN BUFFER COUNT3: DS 2 ;COUNTER COUNT4: DS 2 ; " RCRDS: DS 2 ;#OF FULL SECTORS TO TRANSFER BSECT: DS 1 ;NEW PHYSICAL SECTOR CNTMSK: DS 1 ;COUNT MASK (IN GETNAM) COUNT2: DS 1 ;SECOND UTILITY COUNTER R50NUM: DS 2 ;RADIX 50 CONVERSION OF 3 ASCII CHARS X8: DS 2 ;HL*8 ENTRY: DS 2 ;ENTRY STATUS WORD POINTER BLKCNT: DS 2 ;BLOCK COUNT (UPDATED EVERY ENTRY) BLOCKS: DS 2 ;# OF BLOCKS TO FILE (VALID ONLY IF FOUND) LENGTH: DS 2 ;LENGTH OF FILE FOUND (IN BLOCKS) TRACK: DS 1 ;TRACK OF FOUND FILE SECTOR: DS 1 ;SECTOR OF FOUND FILE FLBFPT: DS 2 ;FILE BUFFER POINTER FLNMPT: DS 2 ;FILE NAME POINTER MATCH: DS 1 ;MATCH FLAG FILELO: DS 1 ;PERM FILE NAME STORAGE FILEHI: DS 1 NAMELO: DS 1 NAMEHI: DS 1 EXTLO: DS 1 EXTHI: DS 1 FILE: DS 2 ;FILE NAME NAME: DS 2 ; & EXT. OF EXT: DS 2 ; REQUESTED FILE (DEC) BTRACK: DS 1 ;PHYSICAL TRACK COUNT: DS 1 ;UTILITY COUNTER LOCATION BUFFPT: DS 2 ;DIRECTORY BUFFER POINTER DRBUFF: ;DIRECTORY BUFFER HDWD1: DS 2 ;SEGMENTS AVAILABLE HDWD2: DS 2 ;NEXT SEGMENT HDWD3: DS 2 ;HIGHEST OPEN SEGMENT HDWD4: DS 2 ;EXTRA WORDS/ENTRY HDWD5: DS 2 ;FILE STARTING BLOCK ENTRYS: DS 1014 ;ENTRIES ENDBUF: DS 1 * * *MESSAGES * SIGNON: DB 0DH,0AH,'THIS PROGRAM TRANSFERS A FILE TO A DEC STANDARD (INTERLEAVED)' DB 0DH,0AH,'OR A "CONSECUTIVE" FORMATTED DISK FROM THE CP/M SYSTEM DISK',0FFH M0: DB 0DH,0AH,'PLACE DESTINATION (DEC) DISK ON DRIVE B',0DH,0AH,0FFH M0A: DB 0DH,0AH,'READY (Y/N)?',0FFH M1: DB 0DH,0AH,'SEEK ERROR-DISK B',0DH,0AH,0FFH M2: DB 0DH,0AH,'I/O ERROR ON B',0DH,0AH,0FFH M3: DB 0DH,0AH,'DIRECTORY ERROR',0DH,0AH,0FFH M4: DB 0DH,0AH,'?FIL NOT FND?',0DH,0AH,0FFH M5: DB 0DH,0AH,'NON-RAD50 CHAR-TRY AGAIN',0DH,0AH,0FFH M6: DB 0DH,0AH,'DEC:FILNAM.EXT=',0FFH M7: DB 'SYNTAX ERROR',0FFH M8: DB 0DH,0AH,'?NO EOF?',0FFH M9: DB 0DH,0AH,'?DIR FULL?',0FFH M10: DB 0DH,0AH,'CP/M:FILENAME.TYP=',0FFH M12: DB 0DH,0AH,'CP/M WRITE ERROR',0FFH M14: DB 'IS DEC DISK INTERLEAVED (Y/N)?',0FFH M15: DB 0DH,0AH,'ANOTHER TRANSFER (Y/N)?',0FFH M16: DB 0DH,0AH,'DIV4 ERROR',0FFH M17: DB 0DH,0AH,'NO ROOM FOR FILE',0FFH M18: DB 0DH,0AH,0DH,0AH,'ZERO DEC DISK (Y/N)?',0FFH M19: DB ' ARE YOU SURE (Y/N)?',0FFH * BYTBUF: DS 4 ;ISOLATE PROGRAM FROM XFER BUFFER * PRGEND EQU $ * END