home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Power-Programmierung
/
CD1.mdf
/
assemblr
/
library
/
asm_kit
/
vw_to_ws.asm
< prev
next >
Wrap
Assembly Source File
|
1984-03-04
|
16KB
|
440 lines
NAME VWTOWS
PAGE 55,132
TITLE 'VWTOWS --- FILTER VW TEXT FILE FOR WORDSTAR'
;
; VWTOWS -- CONVERT VOLKSWRITER FILE TO WORDSTAR DOCUMENT FILE.
; EXTRA SEQUENTIAL SPACES ARE CONVERTED TO "SOFT SPACES".
; PARAGRAPH MARKERS ARE CONVERTED TO "HARD CARRIAGE RETURNS".
; NORMAL CR'S ARE CONVERTED TO "SOFT CARRIAGE RETURNS".
; ALL OTHER CONTROL CHARACTERS EXCEPT FOR LINE FEEDS AND FORM
; FEEDS ARE DISCARDED.
; VERSION 1.0 10 DEC 83
;
; COPYRIGHT (C) 1983 BY RAY DUNCAN
CR EQU 0DH ;ASCII CARRIAGE RETURN
LF EQU 0AH ;ASCII LINE FEED
FF EQU 0CH ;ASCII FORM FEED
EOF EQU 01AH ;END OF FILE MARKER
TAB EQU 09H ;ASCII TAB CHARACTER
COMMAND EQU 80H ;BUFFER FOR COMMAND TAIL
BLKSIZE EQU 1024 ;BLOCKING/DEBLOCKING SIZE
CSEG SEGMENT PARA PUBLIC 'CODE'
ASSUME CS:CSEG,DS:DATA,ES:DATA,SS:STACK
CLEAN PROC FAR ;ENTRY POINT FROM PC-DOS
PUSH DS ;SAVE DS:0000 FOR FINAL
XOR AX,AX ;RETURN TO PC-DOS
PUSH AX
MOV AX,DATA ;MAKE OUR DATA SEGMENT
MOV ES,AX ;ADDRESSABLE VIA ES REGISTER
CALL INFILE ;GET PATH AND FILE SPEC.
;FOR INPUT FILE
MOV AX,ES ;SET DS=ES FOR REMAINDER
MOV DS,AX ;OF PROGRAM
JNC CLEAN1 ;JUMP, GOT ACCEPTABLE NAME
MOV DX,OFFSET MSG4 ;MISSING OR ILLEGAL FILESPEC,
JMP CLEAN9 ;PRINT ERROR MESSAGE AND EXIT.
CLEAN1: CALL OUTFILE ;SET UP OUTPUT FILE NAME
CALL OPEN_INPUT ;NOW TRY TO OPEN INPUT FILE
JNC CLEAN2 ;JUMP,OPENED INPUT OK
MOV DX,OFFSET MSG1 ;OPEN OF INPUT FILE FAILED,
JMP CLEAN9 ;PRINT ERROR MSG AND EXIT.
CLEAN2:
CALL OPEN_OUTPUT ;TRY TO OPEN OUTPUT FILE.
JNC CLEAN25 ;JUMP,OPENED OK
MOV DX,OFFSET MSG2 ;OPEN OF OUTPUT FILE FAILED,
JMP CLEAN9 ;PRINT ERROR MESSAGE AND EXIT.
CLEAN25: ;ALL FILES OPENED SUCCESSFULLY,
CALL SIGN_ON ;PRINT SIGN-ON MESSAGE AND
CALL INIT_BUFFS ;SET UP BUFFERS.
CLEAN3: ;NOW FILTER THE FILE.
CALL GET_CHAR ;READ 1 CHARACTER FROM INPUT.
AND AL,07FH ;STRIP OFF THE HIGH BIT
CMP AL,20H ;IS IT A CONTROL CODE OR SPACE?
JA CLEAN4 ;NO,WRITE IT TO NEW FILE
JNE CLEAN32 ;JUMP IF NOT A SPACE CODE
MOV AH,PREV_CHAR ;CHECK IF LAST CHAR WAS A SPACE
AND AH,7FH
CMP AH,20H
JNE CLEAN4 ;NO,WRITE NORMAL SPACE
OR AL,80H ;YES, CONVERT THIS SPACE TO "SOFT"
JMP CLEAN4 ;AND WRITE IT TO THE FILE
CLEAN32: ;IT IS CONTROL CODE,
CMP AL,EOF ;IS IT END OF FILE MARKER?
JE CLEAN6 ;YES,JUMP TO CLOSE FILES.
CMP AL,14H ;IS IT VW PARAGRAPH MARKER?
JNE CLEAN33 ;NO,JUMP
CALL GET_CHAR ;DISCARD FOLLOWING CR-LF
CALL GET_CHAR
MOV AL,CR ;CONVERT IT TO "HARD" RETURN
CALL PUT_CHAR ;AND LINE FEED SEQUENCE.
MOV AL,LF
JMP CLEAN35 ;AND WRITE IT TO FILE.
CLEAN33:
CMP AL,TAB ;IS IT A TAB COMMAND?
JZ CLEAN5 ;YES,JUMP TO SPECIAL PROCESSING.
CMP AL,CR ;IF CARRIAGE RETURN AND THE LINE IS
JNE CLEAN34 ;NOT EMPTY, CONVERT IT TO "SOFT RETURN"
MOV BX,COLUMN
OR BX,BX
JZ CLEAN35
OR AL,80H ;AND WRITE IT TO FILE
JMP CLEAN35
CLEAN34:
CMP AL,LF ;IF LINE FEED WRITE IT TO FILE,
JNE CLEAN3 ;OTHERWISE DISCARD CONTROL CODE.
CLEAN35: ;IF IT IS ONE OF THOSE THREE,
MOV COLUMN,0 ;INCIDENTALLY INITIALIZE
JMP CLEAN45 ;COLUMN COUNT FOR TAB PROCESSOR.
CLEAN4: ;COUNT ALPHANUMERIC CHARS. SENT.
INC COLUMN
CLEAN45: ;WRITE THIS CHARACTER TO
CALL PUT_CHAR ;OUTPUT FILE,
JNC CLEAN3 ;IF CY NOT SET, WRITE WAS
;OK SO GO GET NEXT CHAR.
CLEAN47:
CALL CLOSE_INPUT ;IF CY SET, DISK IS FULL
CALL CLOSE_OUTPUT ;SO CLOSE FILES AND EXIT
MOV DX,OFFSET MSG5 ;WITH ERROR MESSAGE.
JMP CLEAN9
CLEAN5: ;PROCESS TAB CHARACTER
MOV AX,COLUMN ;LET DX:AX=COLUMN COUNT
CWD
MOV CX,8 ;DIVIDE IT BY EIGHT...
IDIV CX
SUB CX,DX ;REMAINDER IS IN DX.
ADD COLUMN,CX ;UPDATE COLUMN POINTER.
CLEAN55: ;8 MINUS THE REMAINDER
PUSH CX ;GIVES US THE NUMBER OF
MOV AL,20H ;SPACES TO SEND OUT TO
CALL PUT_CHAR ;MOVE TO THE NEXT TAB POSITION
POP CX ;RESTORE SPACE COUNT
JC CLEAN47 ;JUMP IF DISK IS FULL
LOOP CLEAN55
JMP CLEAN3 ;GET NEXT CHARACTER
CLEAN6: ;END OF FILE DETECTED,
CALL PUT_CHAR ;WRITE END-OF-FILE MARKER,
JC CLEAN47 ;JUMP IF DISK WAS FULL
CALL FLUSH_BUFFS ;WRITE REMAINING DATA TO DISK
JC CLEAN47 ;IF CY SET,DISK WAS FULL
;OTHERWISE FILE WAS WRITTEN OK
CALL CLOSE_INPUT ;CLOSE INPUT AND OUTPUT
CALL CLOSE_OUTPUT ;FILES.
MOV DX,OFFSET MSG3 ;ADDR OF SUCCESS MESSAGE,
CLEAN9: ;PRINT MESSAGE AND RETURN
MOV AH,9 ;CONTROL TO PC-DOS
INT 21H
RET
CLEAN ENDP
INFILE PROC NEAR ;PROCESS NAME OF INPUT FILE
;DS:SI <- ADDR COMMAND LINE
MOV SI,OFFSET COMMAND
;ES:DI <- ADDR FILESPEC BUFFER
MOV DI,OFFSET INPUT_NAME
CLD
LODSB ;ANY COMMAND LINE PRESENT?
OR AL,AL ;RETURN ERROR STATUS IF NOT.
JZ INFILE4
INFILE1: ;SCAN OVER LEADING BLANKS
LODSB ;TO FILE NAME
CMP AL,CR ;IF WE HIT CARRIAGE RETURN
JZ INFILE4 ;FILENAME IS MISSING.
CMP AL,20H ;IS THIS A BLANK?
JZ INFILE1 ;IF SO KEEP SCANNING.
INFILE2: ;FOUND FIRST CHAR OF NAME,
STOSB ;MOVE LAST CHAR. TO OUTPUT
;FILE NAME BUFFER.
LODSB ;CHECK NEXT CHARACTER, FOUND
CMP AL,CR ;CARRIAGE RETURN YET?
JE INFILE3 ;YES,EXIT WITH SUCCESS CODE
CMP AL,20H ;IS THIS A BLANK?
JNE INFILE2 ;IF NOT KEEP MOVING CHARS.
INFILE3: ;EXIT WITH CARRY =0
CLC ;FOR SUCCESS FLAG
RET
INFILE4: ;EXIT WITH CARRY =1
STC ;FOR ERROR FLAG
RET
INFILE ENDP
OUTFILE PROC NEAR ;SET UP PATH AND FILE
CLD ;NAME FOR OUTPUT FILE.
MOV CX,64 ;LENGTH TO MOVE
MOV SI,OFFSET INPUT_NAME ;SOURCE ADDR
MOV DI,OFFSET OUTPUT_NAME ;DEST ADDR
REP MOVSB ;TRANSFER THE STRING
MOV DI,OFFSET OUTPUT_NAME
OUTFILE1: ;SCAN STRING LOOKING FOR
MOV AL,[DI] ;"." MARKING START OF EXTENSION
OR AL,AL ;OR ZERO BYTE MARKING NAME END.
JZ OUTFILE2 ;IF EITHER IS FOUND,JUMP.
CMP AL,'.'
JE OUTFILE2 ;BUMP STRING POINTER, LOOP
INC DI ;IF NEITHER '.' OR ZERO FOUND.
JMP OUTFILE1
OUTFILE2: ;FOUND ZERO OR '.',FORCE THE
;EXTENSION OF OUTPUT FILE TO '.WS'
MOV SI,OFFSET OUTFILE_EXT
MOV CX,4
REP MOVSB
RET ;BACK TO CALLER
OUTFILE ENDP
OPEN_INPUT PROC NEAR ;OPEN INPUT FILE
;DS:DX=ADDR FILENAME
MOV DX,OFFSET INPUT_NAME
MOV AL,0 ;AL=0 FOR READ ONLY
MOV AH,3DH ;FUNCTION 3DH=OPEN
INT 21H ;HANDLE RETURNED IN AX,
MOV INPUT_HANDLE,AX ;SAVE IT FOR LATER.
RET ;CY IS SET IF ERROR
OPEN_INPUT ENDP
OPEN_OUTPUT PROC NEAR ;OPEN OUTPUT FILE
;DS:DX=ADDR FILENAME
MOV DX,OFFSET OUTPUT_NAME
MOV AL,1 ;AL=1 FOR WRITE ONLY
MOV AH,3CH ;FUNCTION 3CH=MAKE OR
INT 21H ;TRUNCATE EXISTING FILE
;HANDLE RETURNED IN AX
MOV OUTPUT_HANDLE,AX;SAVE IT FOR LATER.
RET ;RETURN CY=TRUE IF ERROR
OPEN_OUTPUT ENDP
CLOSE_INPUT PROC NEAR ;CLOSE INPUT FILE
MOV BX,INPUT_HANDLE ;BX=HANDLE
MOV AH,3EH
INT 21H
RET
CLOSE_INPUT ENDP
CLOSE_OUTPUT PROC NEAR ;CLOSE OUTPUT FILE
MOV BX,OUTPUT_HANDLE;BX=HANDLE
MOV AH,3EH
INT 21H
RET
CLOSE_OUTPUT ENDP
GET_CHAR PROC NEAR ;GET ONE CHARACTER FROM INPUT BUFFER
MOV BX,INPUT_PTR
CMP BX,BLKSIZE
JNE GET_CHAR1
CALL READ_BLOCK
MOV BX,0
GET_CHAR1:
MOV AL,[INPUT_BUFFER+BX]
INC BX
MOV INPUT_PTR,BX
RET
GET_CHAR ENDP
PUT_CHAR PROC NEAR ;PUT ONE CHARACTER INTO OUTPUT BUFFER
MOV PREV_CHAR,AL ;SAVE COPY OF MOST RECENT OUTPUT
MOV BX,OUTPUT_PTR
MOV [OUTPUT_BUFFER+BX],AL
INC BX
MOV OUTPUT_PTR,BX
CMP BX,BLKSIZE ;BUFFER FULL YET?
JNE PUT_CHAR1 ;NO,JUMP
CALL WRITE_BLOCK ;YES,WRITE THE BLOCK
RET ;RETURN CY AS STATUS CODE
PUT_CHAR1:
CLC ;RETURN CY CLEAR FOR OK STATUS
RET
PUT_CHAR ENDP
READ_BLOCK PROC NEAR
MOV BX,INPUT_HANDLE ;READ FIRST BLOCK OF INPUT
MOV CX,BLKSIZE
MOV DX,OFFSET INPUT_BUFFER
MOV AH,3FH
INT 21H
JNC READ_BLOCK1 ;JUMP IF NO ERROR STATUS
MOV AX,0 ;SIMULATE A ZERO LENGTH READ IF ERROR
READ_BLOCK1:
CMP AX,BLKSIZE ;WAS FULL BUFFER READ IN?
JE READ_BLOCK2 ;YES,JUMP
MOV BX,AX ;NO, STORE END-OF-FILE MARK
MOV BYTE PTR [INPUT_BUFFER+BX],EOF
READ_BLOCK2:
XOR AX,AX ;INITIALIZE INPUT BUFFER POINTER
MOV INPUT_PTR,AX
RET
READ_BLOCK ENDP
WRITE_BLOCK PROC NEAR ;WRITE BLOCKED OUTPUT (BLKSIZE BYTES)
MOV DX,OFFSET OUTPUT_BUFFER
MOV CX,BLKSIZE
MOV BX,OUTPUT_HANDLE
MOV AH,40H
INT 21H
XOR BX,BX ;INITIALIZE POINTER TO BLOCKING BUFFER
MOV OUTPUT_PTR,BX
CMP AX,BLKSIZE ;WAS CORRECT LENGTH WRITTEN?
JNE WRITE_BLOCK1 ;NO,DISK MUST BE FULL
CLC ;YES,RETURN CY=0 INDICATING ALL OK
RET
WRITE_BLOCK1: ;DISK IS FULL, RETURN CY =1
STC ;AS ERROR CODE
RET
WRITE_BLOCK ENDP
INIT_BUFFS PROC NEAR
CALL READ_BLOCK ;READ 1ST BLOCK OF INPUT
XOR AX,AX ;INITIALIZE POINTER TO OUTPUT
MOV OUTPUT_PTR,AX ;OUTPUT BLOCKING BUFFER
RET
INIT_BUFFS ENDP
FLUSH_BUFFS PROC NEAR ;WRITE ANY DATA IN OUTPUT BUFFER TO DISK
MOV CX,OUTPUT_PTR
OR CX,CX
JZ FLUSH_BUFFS1 ;JUMP,BUFFER IS EMPTY
MOV BX,OUTPUT_HANDLE
MOV DX,OFFSET OUTPUT_BUFFER
MOV AH,40H
INT 21H
CMP AX,OUTPUT_PTR ;WAS WRITE SUCCESSFUL?
JNZ FLUSH_BUFFS2 ;NO,JUMP
FLUSH_BUFFS1: ;SUCCESSFUL DISK WRITE,
CLC ;RETURN CY=0 FOR
RET ;SUCCESS FLAG
FLUSH_BUFFS2: ;DISK WAS FULL SO WRITE FAILED,
STC ;RETURN CY=1 AS ERROR FLAG
RET
FLUSH_BUFFS ENDP
SIGN_ON PROC NEAR ;PRINT SIGN-ON MESSAGE
MOV DX,OFFSET MSG6 ;TITLE...
MOV AH,9
INT 21H
MOV DX,OFFSET MSG7 ;INPUT FILE:
MOV AH,9
INT 21H
MOV DX,OFFSET INPUT_NAME
CALL PASCIIZ
MOV DX,OFFSET MSG8 ;OUTPUT FILE:
MOV AH,9
INT 21H
MOV DX,OFFSET OUTPUT_NAME
CALL PASCIIZ
MOV DX,OFFSET MSG9
MOV AH,9
INT 21H
RET
SIGN_ON ENDP
PASCIIZ PROC NEAR ;CALL DX=OFFSET OF ASCIIZ STRING
MOV BX,DX ;WHICH WILL BE PRINTED ON STANDARD OUTPUT
PASCIIZ1:
MOV DL,[BX]
OR DL,DL
JZ PASCIIZ9
CMP DL,'A'
JB PASCIIZ2
CMP DL,'Z'
JA PASCIIZ2
OR DL,20H
PASCIIZ2:
MOV AH,2
INT 21H
INC BX
JMP PASCIIZ1
PASCIIZ9:
RET
PASCIIZ ENDP
CSEG ENDS
DATA SEGMENT PARA PUBLIC 'DATA'
INPUT_NAME DB 64 DUP (0) ;BUFFER FOR INPUT FILESPEC
OUTPUT_NAME DB 64 DUP (0) ;BUFFER FOR OUTPUT FILESPEC
INPUT_HANDLE DW 0 ;TOKEN RETURNED BY PCDOS
OUTPUT_HANDLE DW 0 ;TOKEN RETURNED BY PCDOS
INPUT_PTR DW 0 ;POINTER TO INPUT BLOCKING BUFFER
OUTPUT_PTR DW 0 ;POINTER TO OUTPUT BLOCKING BUFFER
OUTFILE_EXT DB '.WS',0 ;EXTENSION FOR FILTERED FILE
COLUMN DW 0 ;COLUMN COUNT FOR TAB PROCESSING
PREV_CHAR DB 0 ;LAST CHARACTER WRITTEN TO OUTPUT
MSG1 DB CR,LF
DB 'CANNOT FIND INPUT FILE.'
DB CR,LF,'$'
MSG2 DB CR,LF
DB 'FAILED TO OPEN OUTPUT FILE.'
DB CR,LF,'$'
MSG3 DB CR,LF
DB 'FILE PROCESSING COMPLETED'
DB CR,LF,'$'
MSG4 DB CR,LF
DB 'MISSING FILE NAME.'
DB CR,LF,'$'
MSG5 DB CR,LF
DB 'DISK IS FULL.'
DB CR,LF,'$'
MSG6 DB CR,LF
DB 'CONVERT VOLKSWRITER FILE TO WORDSTAR DOCUMENT'
DB CR,LF
DB 'COPYRIGHT (C) 1983 LABORATORY MICROSYSTEMS INC.'
DB CR,LF,'$'
MSG7 DB CR,LF,'INPUT FILE: $'
MSG8 DB CR,LF,'OUTPUT FILE: $'
MSG9 DB CR,LF,'$'
INPUT_BUFFER DB BLKSIZE DUP (?) ;BUFFER FOR DEBLOCKING OF DATA
;FROM INPUT FILE
OUTPUT_BUFFER DB BLKSIZE DUP (?) ;BUFFER FOR BLOCKING OF DATA
;SENT TO OUTPUT FILE
DATA ENDS
STACK SEGMENT PARA STACK 'STACK'
DB 64 DUP (?)
STACK ENDS
END CLEAN