home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
CP/M
/
CPM_CDROM.iso
/
simtel
/
sigm
/
vols000
/
vol096
/
print.a86
< prev
next >
Wrap
Text File
|
1984-04-29
|
12KB
|
579 lines
;************************************************
;* *
;* FILE PRINT UTILITY *
;* *
;************************************************
;
; By Bill Bolton
; Software Tools
; P.O. Box 80
; Newport Beach
; NSW, 2016
; AUSTRALIA
;
; CP/M-86 History (most recent version at top)
;
; Version 1.0 Adapted from PAGE utility
; 4/Mar/82
;
TITLE 'PRINT utility for CP/M-86'
PAGEWIDTH 132
EJECT
;************************************************
;* *
;* MISCELLANEOUS EQUATES *
;* *
;************************************************
TFCB EQU 005CH ;TRANSIENT PROGRAM FCB
TBUF EQU 0080H ;TRANSIENT PROGRAM BUFFER
OPEN EQU 15 ;OPEN FUNCTION CODE
READ EQU 20 ;READ FUNCTION CODE
BS EQU 08H ;ASCII Back Space
TAB EQU 09H ;ASCII TAB
LF EQU 0AH ;ASCII Line Feed
FORMF EQU 0CH ;ASCII Form Feed
CR EQU 0DH ;ASCII Carriage Return
SPACE EQU 20H ;ASCII Blank
FILLER EQU 00H ;USED AS FF NULL
PAGSZ EQU 66 ;LINES/PAGE
MAXLN EQU 58 ;USABLE LINES/PAGE
NULLS EQU 1 ;NULLS AFTER A FORM FEED
ODEV EQU 5 ;CON:=2 LST:=5
M EQU Byte Ptr 0[BX] ;Handy for ASM86
EJECT
CSEG
;************************************************
;* *
;* GET PARAMETERS FROM COMMAND LINE *
;* *
;************************************************
PRINT:
MOV BX,TBUF ;POINT TO BUFFER
MOV CH,M ;GET COUNT OF CHARACTERS IN CMD
MOV AL,M ;GET COUNT AGAIN
OR AL,AL ;TEST FOR ZERO
JNZ L_1
JMP PERR ;YES, NO ARGUMENTS
L_1:
INC BX ;SKIP COUNT
SKP1:
MOV AL,M ;GET BYTE
CMP AL,' ' ;SPACE?
JNZ SKP2 ;NO
INC BX ;BUMP POINTER
DEC CH ;DECRMENT COUNT
JNZ SKP1 ;SKIP TO FIRST NON-SPACE
JMPS PERR ;NO, NON SPACE AFTER FILE ID
SKP2:
MOV AL,M ;GET CHAR
CMP AL,' ' ;SPACE?
JZ SKP3 ;YES
INC BX ;BUMP POINTER
DEC CH ;DECREMENT COUNT
JNZ SKP2 ;SKIP TO SPACE
JMP PEND ;NO SPACE AFTER FILE ID
SKP3:
MOV AL,M ;GET CHAR
CMP AL,' ' ;TEST FOR NON,SPACE
JNZ SKP4 ;FOUND ARGUMENTS
INC BX ;BUMP POINTER
DEC CH ;DECREMENT COUNT
JNZ SKP3
JMP PEND
SKP4:
MOV DX,(Offset PARMS)
SKP4A:
MOV AL,M
MOV SI,DX
MOV [SI],AL
INC BX
INC DX
DEC CH
JNZ SKP4A
MOV AL,' '
MOV SI,DX ;INDICATE END OF PARMS
MOV [SI],AL
;************************************************
;* *
;* PROCESS PARAMETERS *
;* *
;************************************************
PPARM:
MOV DX,(Offset PARMS) ;POINT TO PARMS AREA
PLP0:
MOV BX,(Offset PTAB) ;POINT TO PARM TABLE
MOV CH,(Offset PTABS) ;SIZE OF PARM TABLE
PLP1:
MOV SI,DX ;GET PARM BYTE
MOV AL,[SI]
CMP AL,' ' ;END OF PARMS?
JZ PEND ;YES, DONE
CMP AL,00 ;END OF PARMS?
JZ PEND ;YES, DONE
CMP AL,M ;COMPARE TO TABLE ENTRY
JZ PFND ;FOUND IT
INC BX ;BUMP PARM TABLE PTR
INC BX
INC BX
DEC CH ;DECREMENT COUNT
JNZ PLP1 ;KEEP LOOKING
PERR:
MOV DX,(Offset PERMSG) ;POINT TO PARM ERROR MSG
MOV CL,09 ;WRITE MSG
INT 224
MOV CL,0 ;EXIT
MOV DL,0
INT 224
PFND:
INC BX ;POINT TO ROUTINE ADDR
PUSH DX ;SAVE PARM POINTER
MOV DL,M
INC BX
MOV DH,M ;GET ROUTINE ADDR
MOV BX,(Offset PRET) ;RETURN ADDRESS
PUSH BX ;SIMULATE CALL
XCHG BX,DX ;GET ROUTINE ADDR
JMP BX ;EXIT TO PARM PROC. ROUTINE
PRET:
POP DX ;GET PARM POINTER AGAIN
INC DX ;POINT TO NEXT ONE
JMPS PLP0 ;CONTINUE
;
;************************************************
;* *
;* PARAMETER PROCESSING ROUTINES *
;* *
;************************************************
NPARM:
MOV AL,0FFH ;SET 'NO HEADING' SWITCH
MOV Byte Ptr NSWT,AL
RET
;
CPARM:
MOV AL,0FFH ;SET 'NO PAGINATION' SWITCH
MOV Byte Ptr CSWT,AL
RET
;************************************************
;* *
;* OPEN FILE FOR INPUT *
;* *
;************************************************
PEND:
MOV DX,TFCB ;POINT TO FCB
CALL FOPEN ;OPEN FILE
JNB L_2
JMP ERR ;IF ERROR, EXIT
L_2:
CALL HEAD ;PRINT HEADING
;****************************************
;* *
;* MAIN PROCESSING LOOP *
;* *
;****************************************
LOOP:
CALL GETBT ;GET A BYTE
JNB L_3
JMP ERR ;ERROR
L_3:
CMP AL,1AH ;EOF?
JZ DONE ;YES
CMP AL,CR ;CR?
JZ CRET ;YES
CMP AL,LF ;LF?
JZ LFEED ;YES
CMP AL,TAB ;TAB?
JZ TABMOV ;YES
CMP AL,FORMF ;FORM FEED?
JZ FFEED ;YES
CMP AL,BS ;BACKSPACE
JZ BSPACE ;YES
CMP AL,SPACE ;ODD CONTROL CHR?
JB LOOP ;YES, IGNORE IT
CALL PBYT ;OTHERWISE PRINT IT
JMPS LOOP ;CONTINUE
;************************************************
;* *
;* FINAL PROCESSING *
;* *
;************************************************
DONE:
CALL TPAGE ;MOVE TO TOP OF PAGE
MOV CL,0 ;EXIT TO BDOS
MOV DL,0
INT 224
;************************************************
;* *
;* PROCESS TABS *
;* *
;************************************************
TABMOV:
MOV BX,(Offset COL) ;POINT TO COLUMN
TBLP:
MOV AL,SPACE ;PRINT ONE SPACE
CALL PBYT
MOV AL,M ;GET COLUMN
AND AL,07H ;MODULO 8
JNZ TBLP ;IF NOT AT TAB STOP, KEEP TYPING
JMPS LOOP
CALL PBYT ;PRINT BYTE
JMPS LOOP
;************************************************
;* *
;* PROCESS <CR> *
;* *
;************************************************
CRET:
XOR AL,AL
MOV Byte Ptr COL,AL
MOV AL,CR
CALL PBYT ;PRINT <CR>
JMPS LOOP ;CONTINUE IN MAIN LOOP
;************************************************
;* *
;* PROCESS <LF> *
;* *
;************************************************
LFEED:
MOV AL,Byte Ptr CSWT ;GET PAGINATION SWITCH
OR AL,AL ;SEE IF 'NO PAGINATION'
JNZ LFEED2 ;TRUE, SKIP PAGINATION TEST
MOV AL,Byte Ptr LINE ;GET LINE COUNT
CMP AL,MAXLN ;PAGE OVERFLOW?
JZ FFEED ;YES
LFEED2:
MOV AL,Byte Ptr LINE ;GET LINE COUNT
INC AL ;BUMP LINE COUNT
MOV Byte Ptr LINE,AL
MOV AL,LF
CALL PBYT
JMP LOOP
;****************************************
;* *
;* PROCESS <BS> *
;* *
;****************************************
BSPACE:
MOV AL,BS
CALL PBYT
MOV AL,Byte Ptr COL ;GET COLUMN COUNTER
OR AL,AL ;IF ZERO, DONT DECREMENT IT
JNZ L_4
JMP LOOP
L_4:
DEC AL
MOV Byte Ptr COL,AL ;DECREMENT COLUMN COUNT
JMP LOOP
;************************************************
;* *
;* PROCESS FORM FEED *
;* *
;************************************************
FFEED:
MOV AL,CR
CALL PBYT ;PRINT CR
CALL TPAGE ;POSITION AT TOP OF PAGE
CALL HEAD ;PRINT HEADING
JMP LOOP ;CONTINUE IN MAIN LOOP
;************************************************
;* *
;* HEADING PRINT ROUTINE *
;* *
;************************************************
HEAD:
MOV AL,Byte Ptr NSWT ;NO HEADING SWITCH
OR AL,AL ;IF SET, NO HEADING
JNZ HEADA
MOV BX,(Offset FMSG) ;POINT TO MESSAGE
CALL PSTRNG ;PRINT STRING
MOV BX,TFCB+1 ;POINT TO NAME
MOV CH,8 ;SIZE OF NAME
CALL PCNT ;PRINT COUNT
MOV AL,SPACE ;PRINT A SPACE
CALL PBYT
MOV BX,TFCB+9 ;POINT TO TYPE
MOV CH,03 ;SIZE OF TYPE
CALL PCNT ;PRINT COUNT
MOV BX,(Offset PMSG) ;POINT TO MESSAGE
CALL PSTRNG ;PRINT STRING
MOV AL,Byte Ptr PAGEN ;GET PAGE NUMBER
INC AL ;BUMP IT
MOV Byte Ptr PAGEN,AL ;SAVE IT
CALL DEC ;CONVERT TO DECIMAL
MOV BX,(Offset DECWRK) ;POINT TO DEC STRING
MOV CH,3
CALL PCNT ;PRINT PAGE NUMBER
MOV AL,CR ;PRINT CR
CALL PBYT
MOV AL,LF
CALL PBYT ;PRINT LF
MOV AL,LF
CALL PBYT ;AND SECOND
MOV AL,LF
CALL PBYT ;AND A THIRD
MOV AL,3 ;SET NUMBER OF LINES PRINTED
JMPS HEADB
HEADA:
XOR AL,AL
HEADB:
MOV Byte Ptr LINE,AL ;RESET LINE COUNT
XOR AL,AL ;RESET COLUMN
MOV Byte Ptr COL,AL ;RESET COLUMN
RET
;************************************************
;* *
;* CHARACTER PRINT ROUTINE *
;* *
;************************************************
PBYT:
PUSH BX
PUSH CX
PUSH AX
MOV DL,AL
MOV CL,ODEV
INT 224 ;PRINT
POP AX
CMP AL,SPACE ;NON-PRINTING?
JB PBY2 ;YES, DONT BUMP COL
MOV BX,(Offset COL) ;INCREMENT COLUMN
INC M
PBY2:
MOV CL,11 ;GET CONSOLE STATUS
INT 224
CMP AL,00 ;BREAK?
JZ L_5
MOV CL,0 ;YES, DONE
MOV DL,0
INT 224
L_5:
POP CX
POP BX
RET
;************************************************
;* *
;* STRING PRINT ROUTINE *
;* *
;************************************************
PSTRNG:
MOV AL,M ;GET BYTE
CMP AL,'$' ;STRING END?
JNZ L_6
RET ;YES, DONE
L_6:
CALL PBYT ;PRINT BYTE
INC BX ;BUMP POINTER
JMPS PSTRNG ;LOOP
;************************************************
;* *
;* STRING PRINT ROUTINE (COUNT IN B) *
;* *
;************************************************
PCNT:
MOV AL,M ;GET BYTE
CALL PBYT ;PRINT IT
INC BX ;BUMP POINTER
DEC CH ;DECREMENT COUNT
JNZ PCNT
RET
;************************************************
;* *
;* DECIMAL OUTPUT ROUTINE *
;* *
;************************************************
DEC:
MOV BX,(Offset DECWRK)
MOV CL,100
CALL DIGIT
MOV CL,10
CALL DIGIT
MOV CL,1
CALL DIGIT
RET
DIGIT:
MOV M,'0'
DI0:
SUB AL,CL
JS DI1
INC M
JMPS DI0
DI1:
ADD AL,CL
LAHF
INC BX
SAHF
RET
;************************************************
;* *
;* TOP OF PAGE ROUTINE *
;* *
;************************************************
TPAGE:
MOV AL,FORMF ;ISSUE FORM FEED
CALL PBYT
MOV CH,NULLS ;NUMBER OF NULLS
TPAGE2:
MOV AL,FILLER
CALL PBYT
DEC CH ;PRINT N FILLERS
JNZ TPAGE2
RET
;************************************************
;* *
;* I/O ERROR MESSAGE ROUTINE *
;* *
;************************************************
ERR:
MOV DX,(Offset ERMSG)
MOV CL,09H ;WRITE MSG
INT 224
MOV CL,0
MOV DL,0
INT 224
;************************************************
;* *
;* F O P E N *
;* ROUTINE TO OPEN A DISK FILE *
;* *
;* INPUT: DX= pointer to FCB *
;* OUTPUT: CARRY=ERROR *
;* *
;************************************************
FOPEN:
MOV CL,OPEN ;OPEN CODE
INT 224 ;ISSUE OPEN
CMP AL,0FFH ;ERROR?
JZ FOERR ;YES
XOR AL,AL ;CLEAR CARRY
RET
FOERR:
STC
RET
;********************************************************
;* *
;* G E T B T *
;* ROUTINE TO READ A BYTE *
;* *
;* OUTPUTS: AL = BYTE *
;* CARRY = ERROR *
;* *
;********************************************************
GETBT:
MOV BX,TBUF+128
XCHG BX,DX ;BUFFER END ADDR. IN DE
MOV BX,Word Ptr INPTR ;CURRENT POINTER IN HL
CMP BX,DX ;TEST FOR END OF BUFFER
JZ GETB2 ;YES, READ
GETB1:
MOV AL,M ;GET BYTE
INC BX ;BUMP POINTER
INC Word Ptr INPTR ;BUMP POINTER
OR AL,AL ;RESET CARRY
RET
GETB2:
MOV CL,READ ;READ CODE
MOV DX,TFCB ;FCB ADDRESS
INT 224 ;ISSUE READ
CMP AL,00 ;ERROR?
JNZ IERR ;YES
MOV BX,TBUF ;RESET BUFFER POINTER
MOV Word Ptr INPTR,BX
JMPS GETB1 ;CONTINUE
IERR:
STC
RET
EJECT
;************************************************
;* *
;* D A T A *
;* *
;************************************************
L_8 EQU $
DSEG
ORG Offset L_8
DB 'PRINT.CMD - File PRINT Utility, CP/M-86 Version 1.0, '
DB '(C) Copyright March 1982, '
DB 'By Bill Bolton, Software Tools, Sydney, Australia'
NSWT DB 0 ;NO HEADING SWITCH
CSWT DB 0 ;NO PAGINATION SWITCH
INPTR DW TBUF+128 ;INPUT POINTER
DECWRK DB '000' ;DECIMAL WORK AREA
COL DB 0 ;COLUMN COUNTER
LINE DB 0 ;LINE COUNTER
PAGEN DB 0 ;PAGE COUNTER
FMSG DB CR,'FILE: $'
PMSG DB ' PAGE $'
PERMSG DB 'PARAMETER ERROR',CR,LF,'$'
ERMSG DB 'ERROR',CR,LF,'$'
PARMS RS 16 ;PARAMETER STORAGE AREA
;************************************************
;* *
;* PARAMETER PROCESSING TABLE *
;* *
;* ENTRIES ARE 3 BYTES WIDE *
;* *
;* BYTE 1 = PARAMETER BYTE *
;* *
;* BYTES 2,3 = ROUTINE ADDRESS *
;* *
;************************************************
PTAB DB 'N'
DW (Offset NPARM)
DB 'C'
DW (Offset CPARM)
PTABS EQU ((Offset $)-(Offset PTAB))/3
END