home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Power-Programmierung
/
CD1.mdf
/
assemblr
/
library
/
sampler0
/
list.asm
< prev
next >
Wrap
Assembly Source File
|
1986-03-01
|
14KB
|
399 lines
PAGE 60,132
TITLE LIST --- Replace TYPE and MORE commands
;==============================================================================
; Name: LIST, display contents of an ASCII file.
; Syntax:
; LIST <[d:][path]filename[.ext]>
; Input:
; An ASCII file of any size may be listed, however only the
; first 80 bytes of each record is displayed.
;
; After the 'More?' prompt, enter a CR to continue, or
; any other character to terminate.
; Output:
; Logical records (ending in LF and/or CR) are placed into
; the screen buffer.
; Notes:
; Written for the IBM PC by Vernon Buerg, November 1983,
; and is supplied for public domain use.
;
; Revised: Robert S. Russell, Bootstrap Creations, Walnut Creek, Calif.
; December 3, 1983 to allow enough space in buffer for filename
; so that a path may also be specified. Also removed a bug which
; caused the system to lock if a carriage return is entered in
; response to the filename prompt.
;
;==============================================================================
;
STACK SEGMENT PARA STACK 'STACK'
DB 128 DUP (0)
STACK ENDS
;
DATA SEGMENT PUBLIC PARA 'DATA'
ASKFILE DB 13,10,'Enter [d:][path]filename[.ext]:$' ;RSR
CLEAR DB 27,'[2J$'
PROMPT DB 27,'[25;1H','More?$'
EOFMSG DB 27,'[25;1HEnd-of-file$'
CODE2 DB 13,10,'File not found$' ;RSR
CODE4 DB 13,10,'Too many open files$' ;RSR
KEYIN DB 0 ;keyboard buffer size
KEYOUT DB 0 ;keyboard length read
FILENAME DB 45 DUP (0) ;drive:\path\filename.ext ;RSR
HANDLE DW 0 ;file handle from open
COL DW 1 ;current display column
ROW DW 2 ;current display row
INDEX DW 0 ;offset in buffer to record
;
OPENMSG DB 13,10,'Open code: ' ;RSR
OPENCODE DW '00'
DB ' $'
RECLEN DW 0 ;length of current record
RECADDR DW 0 ;addr of i/o buffer
;
SWITCH1 DB 0
EOR EQU 1 ;end-of-record
SWITCH2 DB 0
NODATA EQU 2 ;null record
NUMLF DB 0 ;line feed count
NUMCR DB 0 ;C/R count
WORK DB 256 DUP (?) ;current logical record
DATA ENDS
;
ZBUFFER SEGMENT PARA PUBLIC 'BUFFER'
RECORDS DB 65535 DUP (?)
ZBUFFER ENDS
;
BIOS SEGMENT AT 40H ;set up labels to determine
ORG 10H ;color or monochrome card
EQFLAG LABEL WORD
ORG 4AH ;40 or 80 column display
NCLMS LABEL WORD
ORG 63H
A6845 LABEL WORD ;points to video card ports
BIOS ENDS
;
PAGE
CSEG SEGMENT PARA PUBLIC 'CODE'
ASSUME CS:CSEG,DS:DATA,SS:STACK,ES:ZBUFFER
LIST PROC FAR
PUSH DS ;save for linkage
XOR AX,AX ;clear for return
PUSH AX ;put in stack
;
MOV AX,DATA ;Addr of work areas
MOV DS,AX ;Set data segment reg
;
PUSH DS ;Save DS
XOR CX,CX ;clear hi-byte
MOV CL,BYTE PTR ES:[80H] ;Length of command parm
DEC CL ;For ending CR
CMP CL,0 ;Any parm string?
JLE GETNAME ;No, ask for it
;
MOV SI,82H ;Offset to command parm string
MOV DI,OFFSET FILENAME
MOV AX,DS ;Swap DS/ES
MOV BX,ES
MOV DS,BX ;Copy command string
MOV ES,AX
REP MOVSB
POP DS ;Restore DS
JMP OPEN
PAGE
; No filename supplied with command
;
GETNAME: POP DS
RETRYNAME: ;RSR
MOV DX,OFFSET ASKFILE ;Prompt for file name
MOV AH,9
INT 21H
MOV AH,0AH ;Buffered kybd input DOS req
MOV DX,OFFSET KEYIN
MOV KEYIN,44 ;Size of buffer ;RSR
INT 21H
;
XOR BX,BX
MOV BL,KEYOUT ;Number of chars read
CMP BL,0
JE RETRYNAME ;RSR
MOV FILENAME[BX],0 ;overlay CR
PAGE
;
OPEN: MOV DX,OFFSET FILENAME ;file to open
MOV AX,0 ;for read only ;RSR
MOV AH,3DH ;open a file
INT 21H
MOV HANDLE,AX ;save file handle
;
JNC INIT ;if OPEN okay
MOV DX,OFFSET CODE2
CMP AL,2 ;is it 'file not found'?
JE ERROR
MOV DX,OFFSET CODE4 ;RSR
CMP AL,4 ;is it 'too many open files'? ;RSR
JE ERROR
;
AAM
XCHG AL,AH
OR OPENCODE,AX
MOV DX,OFFSET OPENMSG
ERROR: MOV AH,9
INT 21H ;say OPEN FAILED
RET
PAGE
;
; Initialize buffer to EOF stoppers
;
INIT: MOV BX,ZBUFFER ;addr of I/O area
MOV RECADDR,BX ;save it
MOV DX,OFFSET CLEAR
MOV AH,9
INT 21H ;to clear screen
;
READAGN: MOV CX,65535 ;number of bytes to clear
MOV ES,RECADDR
;
STOPPER: MOV DI,CX
MOV ES:BYTE PTR[DI],1AH ;fill with stoppers
LOOP STOPPER
PAGE
;
; Read a block (64K)
;
MOV BX,HANDLE ;get file handle from open
MOV DX,RECADDR ;offset to record buffer
PUSH DS
MOV DS,DX ;set data segment ptr
SUB DX,DX ; with zero offset
MOV CX,65534 ;number of bytes to read
MOV AH,3FH ;read from a file
INT 21H
;
POP DS
; MOV BX,AX ;Save length read
MOV SWITCH1,0 ;reset EOR flag
MOV INDEX,0 ;offset into buffer
CMP AX,0 ;Any bytes read?
JNE READ ;Yes, list the buffer
JMP CLOSE ;No, all done
;
; Set next row and column for next display line
;
READ: MOV CX,RECLEN ;set column and row
INC CX ; for next record
MOV AX,ROW
DEC AX
CMP NUMLF,0 ;record ended in LF?
JE SET ;no, have col/row
INC AX ;yes, row stays where it is
MOV CX,1 ; and in column 1
;
SET: MOV ROW,AX ;set row
MOV COL,CX ;set column
;
; Extract next logical record from display
;
GETNEXT: CALL SCAN_BUF ;Scan for logical record
MOV CX,RECLEN ;Record size
SUB CL,NUMLF ;for LF
SUB CL,NUMCR ;for CR
MOV RECLEN,CX
CMP CX,0 ;blank line?
JE GETROW ;yes, increment row only
;
LEA SI,WORK ;addr of record
MOV AX,ROW ;destination row
CALL PRINT ;put into screen buffer
;
GETROW: MOV AX,ROW ;get row again
INC AX ;bump to next row
MOV ROW,AX ;save row number
CMP AL,25 ;exceeded screen?
JNE TESTEOR ;no, read next record
;
MOV DX,OFFSET PROMPT
MOV AH,9
INT 21h ;say 'More?'
;
; Wait for keyboard input
;
MOV AH,12 ;clear console
MOV AL,7 ;and get a char
INT 21H ;pause for enter
CMP AL,0DH ;want to quit?
JNE CLOSE ;yes, clean up
;
MOV ROW,2 ;no, reset to first row
MOV AX,ROW
;
MOV DX,OFFSET CLEAR
MOV AH,9
INT 21H ;to clear screen
;
LEA SI,WORK ;addr of record
MOV AX,1 ;put last line on top
MOV CX,RECLEN
CALL PRINT ;put into screen buffer
;
TESTEOR: TEST SWITCH1,EOR ;end-of-records?
JZ READ
JMP READAGN ;yes, read next block
;
CLOSE: MOV BX,HANDLE ;file handle from open
MOV AH,3EH ;close a file handle
INT 21H
;
MOV DX,OFFSET EOFMSG
MOV AH,9
INT 21H ;to say done
;
RET
PAGE
SCAN_BUF PROC NEAR
;
; Function: Scan the buffer for special characters and copy wanted
; data to field WORK. A logical record ends in an LF and/or CR.
;
; Input: ZBUFFER (RECORDS) contains a block of data from the file
; INDEX is the current offset to a logical record
; Output:
; WORK contains a logical record
; NUMLF contains number of line feeds (ignored)
; NUMCR contains number of carriage returns (ignored)
; RECLEN contains length of logical record
; Notes: Tabs are replaced by blanks;
; lines beginning with hex-F are ignored
;
PUSH ES
PUSH CX
PUSH SI
PUSH DI
TEST SWITCH1,EOR
JZ SCAN1
JMP SCAN_END
;
SCAN1: XOR CX,CX
XOR DI,DI
AND SWITCH2,0FFH-NODATA
MOV NUMLF,0 ;reset LF indicator
MOV NUMCR,0 ;zero CR counter
MOV AX,ZBUFFER
MOV ES,AX ;set addr of I/O buffer segment
;
SCAN2: MOV SI,INDEX
MOV AL,RECORDS[SI] ;Get a byte
CMP AL,1AH ;End of buffer?
JNE SCAN3
MOV RECLEN,CX
OR SWITCH1,EOR ;Indicate end-of-records
JMP SCAN_END
;
SCAN3: CMP AL,9H ;Is it TAB?
JNE SCAN4
MOV AL,' ' ;Yes, replace with blank
;
SCAN4: MOV WORK[DI],AL ;Store character
INC DI ;Increment pointer
INC CX ;Increment counter
INC INDEX ;Increment counter
;
CMP AL,0DH ;Is it a CR?
JNE SCAN5
INC NUMCR ;Yes, increment counter
SCAN5: CMP AL,' '
JE SCAN7
CMP AL,0AH ;Is it line feed?
JNE SCAN6
INC NUMLF
JMP SCAN8
SCAN6: OR SWITCH2,NODATA ;Non-space found
;
SCAN7: CMP CX,255 ;Record too big?
JE SCAN8 ;Chop record at 255 bytes
JMP SCAN2
;
SCAN8: MOV RECLEN,CX
CMP WORK,0FH ;If record begins with "sun"
JNE SCAN9 ; symbol, skip it
JMP SCAN1
;
SCAN9: TEST SWITCH2,NODATA ;If nothing but spaces found,
JNZ SCAN_END ; read another record
JMP SCAN1
;
SCAN_END:
POP DI
POP SI
POP CX
POP ES
RET
;
SCAN_BUF ENDP
;
PAGE
ASSUME CS:CSEG,DS:DATA,ES:NOTHING
PRINT PROC NEAR
PUSH ES
PUSH DI
PUSH DX
PUSH SI
;
MOV DI,COL ;set column
DEC DI ;adjust for zero offset
DEC AX ;adjust row too
CMP CL,0 ;null string?
JE EXIT ;if so,do nothing, Else,
;
MOV BX,BIOS ;get ready to determine card type
MOV ES,BX ;and number of columns
MUL ES:NCLMS ;AX = column * words per line
ADD DI,AX ;DI = words from start of screen
SHL DI,1 ;adjust for attribute bytes
;
MOV DX,ES:A6845 ;point to 6845 base port
ADD DX,6 ;point to status port
;
;CX has the count of characters to write,
;SI points to the string data,
;DI points to a screen position
;
MOV AX,0B800H ;default to color card
MOV BX,ES:EQFLAG
AND BX,30H
CMP BX,30H ;is it monochrome?
JNE CARDOK ;no, go
MOV AX,0B000H ;yes, set for monochrome
CARDOK: MOV ES,AX ;points ES to video
;
; DS:SI => first character of string
; ES:DI => screen memory to display it
; CX => number of characters to display
; DX => status port of video card
;
;-------- Wait for horzontal retrace
TESTLO: IN AL,DX ;get status
TEST AL,1 ;is it low?
JNZ TESTLO ;no, keep checking
CLI ;turn off interrupts
TESTHI: IN AL,DX ;get status
TEST AL,1 ;is it high?
JZ TESTHI ;no, keep checking
;-------- Okay to write to screen now (no 'hash')
MOVSB ;[DS:DI]->[ES:DI],DI++,SI++,CX--
INC DI ;skip the attribute byte
LOOP TESTLO ;do till end of string
STI ;turn interrupts back on
;
EXIT: POP SI
POP DX
POP DI
POP ES
RET
;
PRINT ENDP
;
LIST ENDP
CSEG ENDS
;
END LIST