; CDIR - A program to compare directories of two disks. ; ;Written by: Robert Wilcox ; 920 N. Washington St. ; Owosso, MI 48867 ; ;Date: 15 Sept. 82 ; ;------- Revisions -------- ; ; v1.2 Added equates for Kaypro computers and made a Kaypro-only ; 04/02/86 version (CDIR-K84.COM) with even more video equates used. ; ; Steve Sanders, TBKUG/DataCOM Super Systems ; (813) 791-1454 or 791-1455 modem 300/1200/2400 ; ;----- ; ; v1.1 Fixes and mods by Mark Pulver ; ;-------------------------------------------------------------------- ; ;Operation: CDIR prints a directory of files of the disk in drive ; A, with files that are also on drive B indicated by the ; file name being in reverse video if the terminal supports ; it, or by "*" if it does not. ; ; Wild cards (CDIR *.ASM, CDIR test?.as?, etc. are supported. ; ; CDIR ? gives a help message. ; ; Any key pressed while the directory is being printed aborts ; the program. ; ;software system used: CP/M 2.2 ;terminals supported: ADDS Viewpoint/3A Plus ; Heath H-19 ; Imsai VIO ; Televideo series ; Wyse50 ; ADM3A/Kaypro ; ;----------------------------------------------------------------------------- ; terminal codes (hex) ; ;----------------------------------------------------------------------------- ; clear cursor erase to address set/reset set attribute: ; screen up end of pg cursor attribute flag reverse video ; ------ ------ --------- --------- -------------- -------------- ;ADDS 3A 1A 0B 1B,59 1B,3D,r,c 1B,29/1B,28 1B,30,50 ;Heath H-19 1B,45 1B,41 1B,4A 1B,59,r,c 1B,70/1B,71 n/a ;Imsai VIO 1A 0B 15 1B,3D,r,c 1B,56/1B,56 n/a ;Televideo 1A 0B 1B,59 1B,3D,r,c 1B,29/1B,28 n/a ;Wyse50 (same as Televideo) ;Kaypro 1A 0B 17 1B,3D,r,c 1B,42,30/1B,43,30 n/a ; FALSE EQU 0 TRUE EQU NOT FALSE ; ;One and only one of the following conditionals should be true ;to select the visual attributes and cursor addressing for the ;terminal used. ; ADDS EQU FALSE HEATH EQU FALSE IMSAI EQU FALSE TVI EQU FALSE ;also Wyse50 ; KAYPRO EQU TRUE ; ; OTHER EQU FALSE ;used if the terminal used does not support ;cursor addressing or reverse video ; ;CP/M FUNCTION CODES - PASS IN REGISTER C TO BDOS RCCFC EQU 01 ;READ CONSOLE CHARACTER WCCFC EQU 02 ;WRITE CONSOLE CHARACTER WCBFC EQU 09 ;WRITE CONSOLE BUFFER GCSFC EQU 11 ;GET CONSOLE STATUS RESET EQU 13 ;DISK RESET SRFFC EQU 17 ;SEARCH FIRST SRNFC EQU 18 ;SEARCH NEXT ; ;CP/M ADDRESS EQUATES ; BDOS EQU 0005H ;BDOS ENTRY POINT SFCB EQU 005CH ;SYSTEM FILE CONTROL BLOCK DBUF EQU 0080H ;SYSTEM DISK BUFFER ; ;ASCII EQUATES ; BEL EQU 07H ;BELL LF EQU 0AH ;LINE FEED VT EQU 0BH ;VERTICAL TAB (CTRL-K) CR EQU 0DH ;CARRIAGE RETURN NAK EQU 15H ;CTRL-U CLR EQU 1AH ;CTRL-Z/CLEAR SCREEN ESC EQU 1BH ;ESCAPE EOS EQU '$' ;END OF STRING ; PRTN: EQU 4 ;number of file names on a line ; ORG 0100H ;program originate address ; START: LXI H,0 ;begin by saving system DAD SP ;stack pointer and setting SHLD OLDSP ;program stack LXI SP,STACK+64 ; LXI D,MSG0 CALL WASC ;print program title ; ; print a help message if '?' was ; typed after the program name. ; lda dbuf ;look at dbuf ana a ;see if anything typed after "CDIR" jz makefcb ;if not, make like "CDIR *.*" cpi 2 ;2 characters (" ?") typed? jnz nohelp ;no - lda dbuf+2 ;if yes, was it '?' cpi '?' jnz nohelp lxi d,helpmsg ;if '?' type help message and call wasc ;return to cp/m jmp exit ; makefcb: lxi h,fcba ;if no file specifications typed, lxi d,sfcb ;make it as if "*.*" was typed. mvi b,16 call move ; nohelp:; ;program continues - - LXI D,MSG2 CALL WASC ;give instructions WAIT: CALL RACC ;wait for CPI ' ' ;space returns JZ DONE ;to CP/M CPI CR JNZ WAIT MVI C,RESET CALL BDOS LXI D,MSG1 CALL WASC ;print header LXI D,SFCB CALL GETFL ;get file list LDA FLCNT ORA A JZ NONE ;no matching files on drive A MVI A,PRTN STA PCOUNT ; LOOP: CALL CKABRT ;check if any key pressed ;abort if so. LHLD FLPTR ;HL = ptr to next name LXI D,SFCB ;DE = destination addr MVI B,16 ;# bytes to move CALL MOVE SHLD FLPTR ;update file list ptr MVI A,2 ;set drive specification for B STA SFCB LXI D,SFCB ;search for file CALL SRCHF ;on drive B. INR A PUSH PSW ; IF NOT OTHER JZ LOOP1 LXI D,MSG6 ;set attribute tag CALL WASC ENDIF ; LOOP1: MVI A,' ' CALL WACC ;print a space LXI H,SFCB+1 ;point to file name MVI B,8 CALL PMSG ;print file name MVI A,' ' CALL WACC ;print a space MVI B,3 CALL PMSG ;print file type MVI A,' ' CALL WACC ;print a space POP PSW JZ LOOP2 LXI D,MSG7 ;reset attribute tag ;or "*" CALL WASC ; IF OTHER JMP LOOP3 ; LOOP2: MVI A,' ' CALL WACC ENDIF ; IF NOT OTHER LOOP2: ENDIF ; LOOP3: LXI H,FLCNT ;decrement filelist count DCR M ;and quit if no files left, JZ DONE ;otherwise continue. LXI H,PCOUNT DCR M ;if this line is full skip the JZ LOOP4 ;spaces and start a new line. LXI D,SPACES CALL WASC ;print " | " JMP LOOP ;and get next file name ; LOOP4: CALL WEOLC ;start a new line MVI A,PRTN STA PCOUNT JMP LOOP ;and get next file name. ; CKABRT: MVI C,GCSFC ;get console status function code CALL BDOS ANA A ;set flags..A=0 if no key pressed RZ CALL RACC ; DONE: CALL WEOLC LXI D,MSG4 CALL WASC CALL RACC MVI C,RESET CALL BDOS ; IF NOT OTHER LXI D,MSG5 CALL WASC ENDIF ; JMP EXIT ;back to CP/M NONE: LXI D,MSG3 CALL WASC ; ;EXIT ROUTINE RESETS SYSTEM STACK AND RETURNS TO CP/M ; EXIT: LHLD OLDSP SPHL RET ; GETFL: LXI H,FLIST ;FLPTR = FWA OF FILELIST SHLD FLPTR XRA A ;FLCNT = 0 STA FLCNT PUSH D GETFL1: CALL SRCHF ;SEARCH FOR FIRST OCCURRENCE CPI 255 ;JUMP IF NONE FOUND JZ GETFL3 GETFL2: ANI 03H ;DE = DBUF + 32 * (A AND 3) ADD A ADD A ADD A ADD A ADD A MOV L,A MVI H,0 LXI D,DBUF DAD D XCHG LHLD FLPTR ;HL = FILE LIST PTR XCHG MVI B,16 ;B = # OF BYTES TO MOVE CALL MOVE XCHG SHLD FLPTR ;UPDATE FILELIST POINTER LXI H,FLCNT ;INCREMENT FILELIST COUNT INR M POP D PUSH D CALL SRCHN ;SEARCH FOR NEXT OCCURRENCE CPI 255 ;LOOP IF ANOTHER FOUND JNZ GETFL2 GETFL3: POP D LXI H,FLIST ;RESET FILELIST POINTER SHLD FLPTR RET ; MOVE: MOV A,M ;move B bytes from HL to DE INX H STAX D INX D DCR B JNZ MOVE RET ; ;SEARCH FOR FIRST OCCURRENCE OF FILE ;ON ENTRY DE POINTS TO FCB ;RETURNS 0, 1, 2 OR 3 IF FOUND, 255 IF NOT FOUND ; SRCHF: PUSH H PUSH D PUSH B MVI C,SRFFC CALL BDOS POP B POP D POP H RET ;SEARCH FOR NEXT OCCURRENCE OF FILE ; SRCHN: PUSH H PUSH D PUSH B MVI C,SRNFC CALL BDOS POP B POP D POP H RET ; ;READ CONSOLE CHARACTER ;EXIT: CHARACTER IN ACCUM. ; RACC: PUSH H PUSH D PUSH B MOV E,A MVI C,RCCFC CALL BDOS POP B POP D POP H RET ; ;WASC - WRITE BUFFER TO CONSOLE ;ENTRY - DE POINTS TO MESSAGE BUFFER ;MSG MUST END IN '$' ; WASC: PUSH H PUSH D PUSH B MVI C,WCBFC CALL BDOS POP B POP D POP H RET ; ;WEOLC - WRITE END OF LINE (CR,LF) ; WEOLC: MVI A,CR CALL WACC MVI A,LF ; ;WRITE CONSOLE CHARACTER ;ENTRY: CHARACTER IN ACCUM. ; WACC: PUSH H PUSH D PUSH B MOV E,A MVI C,WCCFC CALL BDOS POP B POP D POP H RET ; PMSG: MOV A,M ;prints B characters CALL WACC ;pointed at by HL INX H DCR B JNZ PMSG RET ; ; ; ;MESSAGE AND STORAGE AREA ; MSG0: IF (ADDS OR IMSAI OR TVI OR KAYPRO) DB CLR ENDIF ; IF HEATH DB ESC,'E' ENDIF ; IF KAYPRO ;fancy underlining DB ESC,'B3',' Compare DIRectories - Ver 1.2kp ' DB ESC,'C3',CR,LF,EOS ENDIF ; DB 'CDIR - Ver 1.2',CR,LF,EOS MSG1: IF (ADDS OR TVI) DB ESC,'=! ',ESC,'Y' ENDIF ; IF KAYPRO DB ESC,'=! ',17H ENDIF ; IF HEATH DB ESC,'Y! ',ESC,'J' ENDIF ; IF IMSAI DB ESC,'=! ',NAK ENDIF ; DB CR,LF,'DIR of drive A:, Files also found on B: are ' ; IF OTHER DB 'indicated by "*".' ENDIF ; IF ADDS DB ESC,')','Reversed.' DB ESC,'(',ESC,'0P' ENDIF ; IF KAYPRO DB ESC,'B0','Reversed.' DB ESC,'C0' ENDIF ; IF HEATH DB ESC,'p','Reversed.' DB ESC,'q' ENDIF ; IF IMSAI DB ESC,'V','Reversed.' DB ESC,'V' ENDIF ; IF TVI DB ESC,')','Lo-Intensity.' DB ESC,'(' ENDIF ; DB CR,LF,LF,EOS ; MSG2: DB CR,LF DB 'Place one disk in drive A and the other in drive B',CR,LF,LF DB ' Press: to start',cr,lf DB ' to quit > ',EOS MSG3: DB 'there are no files on drive A:',EOS MSG4: DB cr,lf,'Replace system disk in A: then press : ',EOS ; IF (ADDS OR TVI) MSG5: DB VT,ESC,'Y',EOS ENDIF ; IF KAYPRO MSG5: DB VT,17H,EOS ENDIF ; IF IMSAI MSG5: DB VT,NAK ENDIF ; IF HEATH MSG5: DB ESC,'A',ESC,'J' ENDIF ; IF (ADDS OR TVI) MSG6: DB ESC,')',EOS MSG7: DB ESC,'(',EOS ENDIF ; IF KAYPRO MSG6: DB ESC,'B0',EOS MSG7: DB ESC,'C0',EOS ENDIF ; IF HEATH MSG6: DB ESC,'p',EOS MSG7: DB ESC,'q',EOS ENDIF ; IF IMSAI MSG6: EQU ESC,'V',EOS MSG7: DB ESC,'V',EOS ENDIF ; IF OTHER MSG7: DB '*',EOS ENDIF ; HELPMSG: DB CR,LF DB 'CDIR - Displays the directory of disk A:, files which',cr,lf DB ' also exist on disk B: are shown in ' ; IF ADDS DB ESC,')','Reverse' DB ESC,'(',ESC,'0P' ENDIF ; IF KAYPRO DB ESC,'B0','Reverse' DB ESC,'C0' ENDIF ; IF HEATH DB ESC,'p','Reverse' DB ESC,'q' ENDIF ; IF IMSAI DB ESC,'V','Reverse' DB ESC,'V' ENDIF ; IF TVI DB ESC,')','Lo-Intensity' DB ESC,'(' ENDIF ; IF OTHER DB '"*".' ENDIF ; IF NOT OTHER DB ' video.' ENDIF ; DB cr,lf,lf,lf DB 'Usage: CDIR',CR,LF DB ' CDIR *.*',CR,LF DB ' CDIR *.COM',CR,LF DB ' CDIR AB??.??Z',CR,LF DB ' etc.',CR,LF,LF,LF DB EOS SPACES: DB ' | ',EOS FCBA: DB 1,'???????????',0,0,0,0 ;ambig file name OLDSP: DS 2 ;SYSTEM SP STACK: DS 64 ;LOCAL STACK ; FLCNT: DS 1 ;file list count FLPTR: DS 2 ;file list pointer PCOUNT: DS 1 ;print counter FLIST: EQU $ ;file list starts here ; END START