 ORG 103H
 XEQ 103H
SIN EQU 0C01FH    SOL INPUT
SOU EQU 0C019H    SOL OUTPUT
STAK EQU 0CBFFH   STACK IN SCRATCHPAD RAM
 LXI SP,STAK
 COPY NPTDEFS     PTDOS SYSTEM CALLS
 CALL 0C0D5H      CLEAR SCREEN
 CALL MSGI        ASK FOR INPUT FILENAME
 LXI H,IBUFI
IMF CALL SIN      PUT IT IN BUFFER FOR PSCAN
 JZ IMF
 MOV M,A
 CPI 0DH
 PUSH PSW
 MOV B,A
 CNZ OUTR       ECHO TO SCREEN IF NOT C/R
 POP PSW
 INX H
 JNZ IMF
 CALL MSGO     ASK FOR OUTPUT FILENAME
 LXI H,IBUFO
OMF CALL SIN   TO BUFFER
 JZ OMF
 MOV M,A
 CPI 0DH
 PUSH PSW
 MOV B,A
 CNZ OUTR
 POP PSW
 INX H
 JNZ OMF
PI MVI A,PSOP+40H  OPEN INPUT FILE
 LXI H,IBUFI       NAME IS IN IBUFI
 LXI D,OBUFI       OUTPUT BUFFER FOR PSCAN
 CALL PSCAN
 JC ERR            CARRY IS ERROR, ALWAYS
 JZ ERR            HERE, SO IS ZERO
 MOV A,E
 CPI 0FFH          0FFH IN E IS ERROR
 JZ ERR
 STA IFN           GOT FILE NUMBER, STORE IT
PO MVI A,PSCO+40H  DO SAME FOR OUTPUT FILE
 LXI H,IBUFO       CREATE IF IT DOESN'T EXIST
 LXI D,OBUFO
 CALL PSCAN
 JC ERR
 JZ ERR
 MOV A,E
 CPI 0FFH
 JZ ERR
 STA OFN
 LXI H,0
 SHLD TEMP1    COUNTER FOR INPUT FILE BUFFER
 LXI H,04C0H
 SHLD TEMP2    COUNTER FOR OUTPUT FILE BUFFER
 LXI H,OFB
 SHLD TEMP5    START OF OUTPUT FILE BUFFER
 LXI H,40H     LINE LENGTH COUNTER
 SHLD TEMP7
 LXI H,1
 SHLD TEMP6    EOF FLAG
START LHLD  TEMP1
 XRA A         SEE IF COUNTER IS ZERO
 CMP H
 JNZ STAR2
 CMP L
 JZ  BEGIN         EMPTY?, READ IN MORE & RESET COUNTER
STAR2 LHLD  TEMP4  TEMP4 IS INPUT BUFFER POINTER
 MOV A,M
 STA TEMP3
 CPI 0AH      REMOVE LF
 JZ CONT
 CPI 1AH      REMOVE CTRL/Z
 JZ FINISH
 CPI 9        REMOVE HORIZONTAL TAB
 JZ CONT
 CPI 0DH      CR? RESET LINE LENGTH COUNTER
 CZ CRRES
 CALL WOBUF   PUT CHARACTER IN OUTPUT FILE BUFFER
CONT  LHLD  TEMP4  INCREMENT INPUT FILE BUFFER POINTER
 INX H
 SHLD TEMP4
 LHLD  TEMP1  DECREMENT INPUT BUFFER COUNTER
 DCX H
 SHLD TEMP1
 LHLD TEMP7
 DCR L     INSERT CR IF 64 CHARACTERS WITHOUT ONE
 SHLD TEMP7
 CZ CRINS
 JMP START
CRRES LXI H,40H   RESET CHARACTER COUNTER TO 64
 SHLD TEMP7
 RET
CRINS MVI A,0DH   CR IN A
 CALL WOBU2       PUT IT IN OUTPUT BUFFER
 JMP CRRES    RESET CHARACTER COUNTER
BEGIN LDA TEMP6  EOF?
 CPI 0
 JZ FINISH  IF SO,ENDFILE OF, CLOSE FILES, RETURN TO SYS
 PUSH H    READ INPUT FILE INTO BUFFER
 PUSH B         RESET COUNTER
 PUSH D
 PUSH PSW
 LXI B,04C0H
 LXI D,IFB
 MVI L,1
 LDA IFN
 CALL SYS
 DB DRDOP
 JMP RERR    ERROR RETURN
NRET PUSH B  B HAS # BYTES NOT READ
 POP H       NOW H HAS IT
 SHLD TEMP1  IN TEMP1 FOR THE MOMENT
 LXI H,TEMP1    HL POINTS TO IT
 MVI A,0C0H     DOUBLE PRECISION SUBTRACTION OF BYTES
 SUB M          NOT READ FROM SIZE OF BUFFER (4C0H)
 MOV C,A
 INX H
 MVI A,04
 SBB M
 MOV B,A
 PUSH B
 POP H
 SHLD TEMP1     TEMP1 NOW HAS BYTES READ
 LXI H,IFB
 SHLD TEMP4
 POP PSW
 POP D
 POP B
 POP H
 JMP START
RERR CPI 18H  IN CASE THERE IS NO EOF MARK
 JZ EFSET
 JMP ERR1
EFSET XRA A   RESET EOF FLAG
 STA TEMP6
 JMP NRET
WOBUF LDA TEMP3     GET CHARACTER
WOBU2 LHLD  TEMP5   H POINTS TO OUTPUT FILE BUFFER
 MOV M,A            PUT IT THERE
 LHLD  TEMP2        TEMP2 IS COUNTER
 DCX H              BUFFER FULL?
 SHLD TEMP2
 XRA A
 CMP H
 JNZ RES
 CMP L
 JZ WRT             IF SO, WRITE TO DISK
RES   LHLD TEMP5
 INX H
 SHLD TEMP5
 RET                OTHERWISE GET ANOTHER CHARACTER
WRT1 XRA A          RESET EOF FLAG
 STA TEMP6
WRT LDA OFN         DELIMITED WRITE TO DISK
 LXI B,04C0H
 LXI D,OFB
 MVI L,1
 CALL SYS
 DB DWROP
 JMP ERR1
W2 LXI H,04C0H  RESET COUNTER
 SHLD TEMP2
 LXI H,OFB    RESET POINTER
 SHLD TEMP5
 RET
FINISH MVI A,1  PUT 1 AT END FOR DELIMITED WRITE
 CALL WOBU2
 CALL WRT       WRITE REST OF BUFFER TO DISK
 LDA OFN      MOVE FILE CURSOR BACK ONE SPACE
 LXI B,1
 MVI D,128
 CALL SYS
 DB SPAOP
 JMP ERR
 LDA OFN  EOF MARK TO OUTPUT FILE
 CALL SYS
 DB EOFOP
 JMP ERR
EN MVI A,255  CLOSE ALL OPEN FILES
 CALL SYS
 DB CAOP
 JMP ERR
 CALL SYS  RETURN TO PTDOS
 DB RESOP
MSGI LXI H,MSI
MSGI1 MOV A,M
 CPI 0FFH
 RZ
 MOV B,A
 CALL OUTR
 INX H
 JMP MSGI1
MSGO LXI H,MSO
 JMP MSGI1
MSI ASC 'ENTER INPUT FILE NAME - C/R'
 DB 0DH
 DB 0AH
 DB 0FFH
MSO DB 0DH
 DB 0AH
 ASC 'ENTER OUTPUT FILE NAME - C/R'
 DB 0DH
 DB 0AH
 DB 0FFH
OUTR PUSH H
 PUSH D
 PUSH B
 PUSH PSW
 CALL SOU
 POP PSW
 POP B
 POP D
 POP H
 RET
ERR1 MOV E,A
ERR LXI H,EM
 MOV M,E
 MVI A,84H
 CALL UTIL
 DB UXOP
 JMP EN
 DB -1
EM DS 1
 JMP EN
TEMP1 DS 2
TEMP2 DS 2
TEMP3 DS 1
TEMP4 DS 2
TEMP5 DS 2
TEMP6 DS 2
TEMP7 DS 2
IFN DS 1
OFN DS 1
IBUFI DS 10
IBUFO DS 10
OBUFI DS 20
 DB 0AEH
 DW 04C0H
 DB 0
OBUFO DS 20
IFB DS 04C0H
OFB DS 04C0H
 END
