;******************************************************** ;* * ;* Disassembly of T.COM from CBBS disks * ;* * ;******************************************************** ; ; Originally written by ; Ward Christensen ; and supplied with the CBBS package ; ; Disassembly ; By Bill Bolton ; "Software Tools" RCPM ; SYSOP ; ;VERSION LIST - most recent version first ; ;11/Aug/82 Fixed Control S "pause" to release on any char ; following, including another Control S. Bill Bolton ; ;02/Aug/82 Entering TYPE *.* would eventually yield a list of ; all the files on the disk, including tagged and SYS ; files. File type testing was rearranged to prevent ; this and COM and OBJ messages were deleted. Fixed bug ; due to error in disassembly concerning buffer size. ; Changed console input check to direct console I/O ; (BDOS 6) and added CP/M version trap. Added messages ; explaning how to look at some files that can't be ; "type"d. Bill Bolton ; ;15/Jul/82 Diassembled and file type testing routines from ; MLIST50 merged in. Bill Bolton ; ; BDOS EQU 00005H ;CP/M BDOS entry point FCB EQU 0005CH ;CP/M file control block SECTOR EQU 80H ;Length of a CP/M sector BUF$SIZE EQU 30H ;Size of buffer in pages ; CNTRLC EQU 3 TAB EQU 9 ALF EQU 0AH ACR EQU 0DH CNTRLS EQU 13H CNTRLX EQU 18H CNTRLZ EQU 1AH ; CONOUT EQU 2 DIRECT EQU 6 STRING EQU 9 VERSION EQU 12 OPEN EQU 15 SEARCH$1ST EQU 17 SEARCH$NXT EQU 18 READ EQU 20 SET$DMA EQU 26 ; ORG 100H ; START: CALL BEGIN ; DB 'TYPE Ver 5.3 - Multiple file lister',ACR,ALF,'$' ; BEGIN: POP D LXI H,0 DAD SP SHLD OLD$STACK ;Save entry stack LXI SP,STACK$TOP ;Set up local stack MVI C,STRING CALL BDOS MVI C,VERSION CALL BDOS CPI 20H JNC VERSION$OK CALL PRN$EXIT ; DB 'Sorry, you need CP/M Version 2.0 or later to run TYP' DB ACR,ALF,ACR,ALF,'$' ; VERSION$OK: LDA FCB+1 CPI ' ' ;File name specified? JNZ HEADER ;Yes CALL PRN$EXIT ;No, show usage ; DB 'TYPE command usage:',ACR,ALF,ACR,ALF DB ' TYPE name',ACR,ALF DB ' TYPE name nn',ACR,ALF DB ' TYPE name #',ACR,ALF DB ' TYPE name label',ACR,ALF,ACR,ALF DB 'Where:',ACR,ALF,ACR,ALF DB ' name Any file name. * and ? allowed',ACR,ALF DB ' nn A starting line # (1 = first)',ACR,ALF DB ' # Means to count # of lines',ACR,ALF DB ' label Skip to label before printing',ACR,ALF DB ' Must match exactly and completely',ACR,ALF DB ' To match leading chars, end the string with *:' DB ACR,ALF DB ' TYPE b:foo.asm tr*',ACR,ALF,'$' ; HEADER: CALL PRN$MSG ; DB ACR,ALF DB 'CTL-S pauses, CTL-X skips to next file, CTL-C aborts' DB ACR,ALF,ACR,ALF,0 ; LDA FCB+17 CPI ' ' ;More command line? JZ NEXT ;No CPI '0' ;Yes,line number? JC A02AE ;No CPI ':' JC A02BD ;Yes A02AE: LXI H,FCB+17 ;Point to secondary FCB LXI D,D0707 ;Internal buffer LXI B,11 ;Length to move CALL MOVER ;Do it JMP NEXT ; A02BD: LXI D,FCB+17 LXI H,0 A02C3: LDAX D INX D CPI ' ' JZ A0302 CPI '0' JC A02E5 CPI ':' JNC A02E5 SUI '0' MOV B,H MOV C,L DAD H DAD H DAD B DAD H ADD L MOV L,A JNC A02C3 INR H JMP A02C3 ; A02E5: CALL PRN$EXIT ; DB '++INVALID STARTING LINE #$' ; A0302: MOV A,H ORA L JZ A0308 DCX H A0308: SHLD D0705 NEXT: LXI SP,STACK$TOP ;Reset stack CALL A062D JC EXIT CALL A031C ; DB ' ' ; A031C: POP H LXI B,5 ;Length to move LXI D,T043D CALL MOVER CALL A032F ; DB ' ' ; A032F: POP H LXI B,6 ;Length to move LXI D,T044B CALL MOVER LXI H,0 SHLD D0700 MVI C,OPEN ;Open file LXI D,FCB CALL BDOS INR A ;Good open? JZ EXIT ;No ; ;Check for file protected by CP/M 2.x f2' attribute ; CKFIL: LDA FCB+10 ;POINT TO SYS FILE ATTR ANI 80H ;IS IT SYS? JNZ NEXT ;SYS file, can't print it ; ;Check for .COM file, which can't be printed ; LDA FCB+11 CPI 'M' ;WAS LAST CHAR AN 'M'? JNZ OBJCHK ;IF NOT, CHK FOR '.OBJ' TYPE LDA FCB+10 ANI 7FH ;STRIP CP/M 2.x ATTR CPI 'O' ;AN 'O'? JNZ OBJCHK ;IF NOT IT'S OK TO PRINT LDA FCB+9 ANI 7FH ;STRIP CP/M 2.x ATTR CPI 'C' ;'C' AS IN '.COM'? JNZ OBJCHK ;IF NOT, IT'S OK TO PRINT JMP NEXT ;MORE TO PRINT? ; ;Check for .OBJ file, which can't be printed ; OBJCHK: CPI 'J' ;WAS LAST CHAR AN 'J' ? JNZ SHOW$NAME ;IF NOT, OK TO LIST LDA FCB+10 ;MIGHT BE '.OBJ', CHK NEXT CHR ANI 7FH ;STRIP CP/M 2.x ATTR CPI 'B' ;IS IT A 'B'? JNZ SHOW$NAME ;IF NOT, LIST LDA FCB+9 ;WAS, CHK FIRST CHAR ANI 7FH ;STRIP CP/M 2.x ATTR CPI 'O' ;'O' AS IN '.OBJ'? JNZ SHOW$NAME ;IF NOT, PRINT THE FILE, IF SO JMP NEXT ;MORE TO PRINT? ; SHOW$NAME: LXI H,FCB+1 ;Point to primary file name LXI D,PRIMARY LXI B,8 ;Length CALL MOVER LXI H,FCB+9 ;Point to secondary file name LXI D,SECNDRY LXI B,3 ;Length CALL MOVER CALL PRN$MSG ; DB ACR,ALF,ACR,ALF DB '===> LISTING FILE: ' PRIMARY: DB 'XXXXXXXX.' SECNDRY: DB 'XXX',ACR,ALF,ACR,ALF DB 0 ; LDA FCB+2 ;POINT TO TAG FILE ATTR ANI 80H ;IS IT TAGGED? JZ SQCHK ;NO, CHECK IF SQUEEZED CALL PRN$MSG ;PRINT: ; DB '++FILE NOT FOR DISTRIBUTION, SORRY++',ACR,ALF,0 ; LDA FCB+11 CPI 'L' ;WAS LAST CHAR AN 'L' ? JNZ HLPCHK ;IF NOT, OK TO LIST LDA FCB+10 ;MIGHT BE '.ALL', CHK NEXT CHR ANI 7FH ;STRIP CP/M 2.x ATTR CPI 'L' ;IS IT A 'L'? JNZ HLPCHK ;IF NOT, LIST LDA FCB+9 ;WAS, CHK FIRST CHAR ANI 7FH ;STRIP CP/M 2.x ATTR CPI 'A' ;'A' AS IN '.ALL'? JNZ HLPCHK ;NO, NEXT CHECK CALL PRN$MSG ; DB ACR,ALF DB '++Use DISPLAY to look at this Catalogue++' DB ACR,ALF,0 JMP NEXT ;MORE TO PRINT? ; HLPCHK: LDA FCB+11 ;POINT TO LAST CHAR OF FTYPE CPI 'P' JNZ NXTCHK ;IF NOT, OK TO LIST LDA FCB+10 ;MIGHT BE '.HLP', CHK NEXT CHR ANI 7FH ;STRIP CP/M 2.x ATTR CPI 'L' ;IS IT A 'L'? JNZ NXTCHK ;IF NOT, LIST LDA FCB+9 ;WAS, CHK FIRST CHAR ANI 7FH ;STRIP CP/M 2.x ATTR CPI 'H' ;'H' AS IN '.HLP'? JNZ NXTCHK ;NO, NEXT CHECK CALL PRN$MSG ; DB ACR,ALF DB '++Use HELP to look this "HLP" file++' DB ACR,ALF,0 JMP NEXT ;MORE TO PRINT? ; NXTCHK: JMP NEXT ; ;Check for possible 'squeezed' file, which will not print ; SQCHK: LDA FCB+10 ;GET SECOND CHAR OF FILETYPE ANI 7FH ;STRIP ATTRIBUTE CPI 'Q' ;THIS MAY BE SQUEEZED FILE JNZ A038A ;NOT SQUEEZED CALL PRN$MSG ;PRINT: ; DB 'NOTE: If this file doesn''t ' DB 'print correctly, try TYPE in XYAM.',ACR,ALF DB 'Most files with "Q" as 2nd char. ' DB 'of filetype are squeezed.',ACR,ALF,ACR,ALF,0 ; A038A: LXI H,BUF$END MVI B,1 A038F: PUSH B PUSH D PUSH H LXI H,T06FE CALL A057C POP H POP D POP B CPI CNTRLZ ;End of file? JZ A03ED ANI 07FH ;Strip of MSB (WordStar?) CPI ACR JZ A03C0 CPI TAB JNZ A03BA TABER: MVI M,' ' INX H INR B MOV A,B DCR A ANI 007H ;Reached next TAB stop? JNZ TABER ;No JMP A038F ;Yes ; A03BA: MOV M,A INX H INR B JMP A038F ; A03C0: MVI M,' ' INX H MOV M,A PUSH B PUSH D PUSH H LXI H,T06FE CALL A057C POP H POP D POP B CALL CONSOLE$CHK JC NEXT LDA D0707 CPI '#' JZ A038A LHLD D0705 MOV A,H ORA L JZ A045E DCX H SHLD D0705 JMP A038A ; A03ED: LHLD D0705 MOV A,H ORA L JZ A0415 CALL PRN$EXIT ; DB '++STARTING LINE # TOO HIGH++$' ; A0415: LDA D0707 CPI ' ' JZ NEXT CPI '#' JZ A043A CALL PRN$EXIT ; DB '++STRING NOT FOUND++$' ; A043A: CALL PRN$MSG ; T043D: DB ' ' T0442: DB ' LINES, ' T044B: DB ' ' T0451: DB ' BYTES',ACR,ALF,0 ; JMP NEXT ; A045E: LDA D0707 CPI ' ' JZ A048F LXI H,D0707 LXI D,BUF$END A046C: LDAX D CPI ' ' JZ A0489 CPI ':' JZ A0489 CMP M JNZ A0480 INX D INX H JMP A046C ; A0480: MOV A,M CPI '?' JZ A048F JMP A038A ; A0489: MOV A,M CPI ' ' JNZ A038A A048F: MVI A,' ' STA D0707 MVI C,0 LXI H,BUF$END A0499: MOV A,M CPI ' ' JNZ A04A9 CPI ACR JZ A04A9 INX H INR C JMP A0499 ; A04A9: LXI H,BUF$END MVI B,1 A04AE: PUSH B PUSH H A04B0: MOV A,M INX H INR B CPI ACR JZ A04E6 CPI ' ' JNZ A04B0 MOV A,B POP H POP B CPI 'P' JC A04EA JZ A04EA CALL PRN$MSG DCR C LDAX B NOP PUSH B A04CF: XRA A ORA C JZ A04E7 PUSH B PUSH D PUSH H MVI C,DIRECT ;Console out LXI D,' ' CALL BDOS POP H POP D POP B DCR C JMP A04CF ; A04E6: POP H A04E7: POP B MVI B,1 A04EA: MOV E,M INR B MOV A,M CPI ' ' JNZ A04F8 MOV A,B CPI 'P' JZ A0503 A04F8: PUSH B PUSH D PUSH H MVI C,DIRECT ;Console out CALL BDOS POP H POP D POP B A0503: CALL CONSOLE$CHK JC NEXT MOV A,M INX H CPI ACR JZ SEND$LF CPI ' ' JNZ A04EA JMP A04AE ; DIR$CON: PUSH B PUSH D PUSH H LXI D,0FFH MVI C,DIRECT ;Direct Console input CALL BDOS POP H POP D POP B ORA A RET ; CONSOLE$CHK: CALL DIR$CON RZ CONTROL$CHK: CPI CNTRLC ;Abort ? JZ ABORT ;Yes CPI CNTRLX ;Skip to next file? JZ SKIP ;Yes CPI CNTRLS ;Pause for a while? JNZ NO$ACTION ;No PAUSE$LOOP: CALL DIR$CON ;Another key pressed JZ PAUSE$LOOP ;No CPI CNTRLS ;Yes, go again? JZ NO$ACTION ;Yes JMP CONTROL$CHK ;No, check it ; NO$ACTION: ORA A ;Reset flags RET ; SKIP: CALL PRN$MSG ; DB ACR,ALF,ACR,ALF,'++SKIPPING TO NEXT FILE++',0 ; STC RET ; SEND$LF: PUSH B PUSH D PUSH H MVI C,DIRECT ;Console out LXI D,ALF CALL BDOS POP H POP D POP B JMP A038A ; PRN$MSG: XTHL MSG$LOOP: MOV E,M PUSH B PUSH D PUSH H MVI C,DIRECT ;Console out CALL BDOS POP H POP D POP B INX H MOV A,M ORA A JNZ MSG$LOOP XTHL RET ; MOVER: MOV A,M ;Get a byte from source STAX D ;Put into destination INX H ;Adjust pointers INX D DCX B ;Adjust counter MOV A,B ORA C ;Done? JNZ MOVER ;No RET ; A057C: MOV E,M INX H MOV D,M INX H MOV C,M INX H MOV B,M MOV A,B ORA C JNZ A05D1 INX H MOV A,M ADD A MOV B,A INX H PUSH H MOV A,M INX H MOV H,M MOV L,A A0592: CALL CONSOLE$CHK JC NEXT MVI A,CNTRLZ STAX D PUSH D PUSH H PUSH B PUSH D PUSH H MVI C,SET$DMA ;Set DMA address CALL BDOS POP H POP D POP B POP D PUSH B PUSH D PUSH H MVI C,READ ;Read sequential CALL BDOS POP H POP D POP B ORA A POP H JNZ A05C6 MOV A,L ADI 080H MOV L,A MOV A,H ACI 0 MOV H,A XCHG DCR B JNZ A0592 A05C6: POP H DCX H MOV A,M DCX H MOV M,A DCX H DCX H DCX H JMP A057C ; A05D1: INX H MOV A,M XCHG ADD H MOV H,A MOV A,L SUB C MOV L,A MOV A,H SBB B MOV H,A MOV A,M XCHG CALL A05EF CPI ALF CZ A05FA CPI CNTRLZ RZ DCX B DCX H MOV M,B DCX H MOV M,C RET ; A05EF: PUSH H LXI H,T0451 A05F3: PUSH PSW CALL A0601 POP PSW POP H RET ; A05FA: PUSH H LXI H,T0442 JMP A05F3 ; A0601: MOV A,M ORI '0' INR A MOV M,A CPI ':' RNZ MVI M,'0' DCX H JMP A0601 ; ; >> NO EXECUTION PATH TO HERE << PUSH PSW RAR RAR RAR RAR CALL A0618 POP PSW A0618: ANI 00FH ADI 090H DAA ACI 040H DAA MOV E,A PUSH B PUSH D PUSH H MVI C,DIRECT CALL BDOS POP H POP D POP B RET ; A062D: PUSH B PUSH D PUSH H MVI C,SET$DMA ;Set DMA address LXI D,00080H CALL BDOS POP H POP D POP B XRA A STA FCB+12 STA FCB+32 LDA D06DA ORA A JNZ A067D MVI A,1 STA D06DA LXI H,FCB LXI D,T06DB LXI B,12 CALL MOVER LDA FCB STA CDISK LXI H,T06DB LXI D,FCB LXI B,12 CALL MOVER PUSH B PUSH D PUSH H MVI C,SEARCH$1st ;Search for first LXI D,FCB CALL BDOS POP H POP D POP B JMP A06B1 ; A067D: LXI H,CDISK LXI D,FCB LXI B,12 CALL MOVER PUSH B PUSH D PUSH H MVI C,SEARCH$1st ;Search for first LXI D,FCB CALL BDOS POP H POP D POP B LXI H,T06DB LXI D,FCB LXI B,12 CALL MOVER PUSH B PUSH D PUSH H MVI C,SEARCH$NXT ;Search for next LXI D,FCB CALL BDOS POP H POP D POP B A06B1: INR A STC RZ DCR A ANI 3 ADD A ADD A ADD A ADD A ADD A ADI 081H MOV L,A MVI H,0 PUSH H LXI D,T06E8 LXI B,11 CALL MOVER POP H LXI D,FCB+1 LXI B,11 CALL MOVER XRA A STA FCB+12 RET ; D06DA: DB 0 T06DB: DB 0,0,0,0,0,0,0,0,0,0 DB 0,0 CDISK: DB 0 T06E8: DB 0,0,0,0,0,0,0,0,0,0 DB 0 ; ABORT: CALL PRN$EXIT ; DB ACR,ALF,ACR,ALF,'++ABORTED++',ACR,ALF,'$' ; PRN$EXIT: POP D MVI C,STRING ;Print string CALL BDOS EXIT: LHLD OLD$STACK SPHL RET ; T06FE: DW BUFFER D0700: DB 0,0 DB BUF$SIZE DW FCB D0705: DW 0 D0707: DB 020H ; DB 0,0,0,0,0,0,0,0,0,0 DB 0,0,0,0,0,0,0,0,0,0 DB 0,0,0,0,0,0,0,0,0,0 DB 0,0,0,0,0,0,0,0,0,0 DB 0,0,0,0,0,0,0,0,0,0 DB 0,0,0,0,0,0,0,0,0,0 DB 0,0,0,0,0,0,0,0,0,0 DB 0,0,0,0,0,0,0,0,0,0 DB 0,0,0,0,0,0,0,0,0,0 DB 0,0,0,0,0,0,0,0,0,0 DB 0,0,0,0,0,0,0,0,0,0 STACK$TOP: ; OLD$STACK: DW 0 ; BUFFER EQU $ BUF$END EQU $ + ((2 * BUF$SIZE) * SECTOR) ;Length of buffer ; END