home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
kermit.columbia.edu
/
kermit.columbia.edu.tar
/
kermit.columbia.edu
/
archives
/
trs80model4.zip
/
m4pkt.asm
< prev
next >
Wrap
Assembly Source File
|
1986-10-22
|
11KB
|
405 lines
; m4pkt/asm
;
; Most of the code in this file was derived directly from
; the C-KERMIT program. The code here represents a line by
; line translation of the C-KERMIT code.
;
MEMSTR DW 0
MAXSIZE DB 0
;
; Encode a packet from memory contents instead of from a file
;
ENCSTR EQU $
PUSH HL ;Save the registers
PUSH BC
PUSH DE
LD (MEMSTR),HL ;Store the passed pointer
CALL RSETPKT ;Reinitiaize GETPKT() parameters
CALL GETPKT ;Get a packet
LD HL,0 ;Reset the memory pointer
LD (MEMSTR),HL
POP DE ;Restore the registers
POP BC
POP HL
RET ;Return to the caller
;
; Get a packet worth of data from the FILE indicated by the global
; FCB. Eighth bit quoting, and Repeat count prefixing are done
; as indicated by the status of EBQFLAG, and RPTFLG respectively.
;
GETPKT EQU $
PUSH BC ;Save the registers
PUSH DE
PUSH HL
LD A,(CURCHK) ;Calculate the size of a packet
SUB '1'
LD B,A
LD A,(SPSIZ) ;Get the user specified size
SUB 5 ;Minus the overhead
SUB B
LD (MAXSIZE),A ;Save it for later use
LD HL,(NEXT) ;Get the next character, 16 bits
LD BC,0 ;Subtract zero to set flags
OR A ;Reset the carry flag
SBC HL,BC ;Set the flags
JP P,GETPKT1
CALL GETCH ;Get a character if no previous exists
LD (CH),HL ;Save it
GETPKT1 EQU $
LD BC,0 ;Copy leftovers from previous call
GETPKT2 EQU $
LD HL,LEFTOVER ;Get the start
ADD HL,BC ;Index by BC
LD A,(HL) ;Get a byte
LD HL,FILBUF ;Get the destination
ADD HL,BC ;Index by BC
LD (HL),A ;Put a byte
IFZ GETPKT3 ;Exit loop if zero byte found
INC C ;Point to next
JR GETPKT2 ;Loop on
GETPKT3 EQU $
LD A,C ;Save the initial size of leftovers
LD (SIZE),A
XOR A ;Nullify the string for next time
LD (LEFTOVER),A
GETPKT4 EQU $
LD HL,(CH) ;Get the character
LD BC,0 ;Subtract zero to set the flags
OR A
SBC HL,BC
JP M,GETPKT20 ;Jump at end of file
CALL GETCH ;Get the next character
LD (NEXT),HL ;Save it
LD A,(SIZE) ;Get the current size
LD (OSIZE),A ;Save it in case we overflow the packet
LD C,A ;Make BC a 16 bit value of C
LD B,0
LD HL,FILBUF ;Get the desination buffer
ADD HL,BC ;Index by BC
LD (CBFPTR),HL ;Save the buffer pointer
LD HL,(CH) ;Get the character
LD A,L ;Keep only 8 bits
CALL ENCODE ;Encode it and store the result
LD HL,(CBFPTR) ;Compute the new size
LD BC,FILBUF ;Get the start
OR A ;Reset carry
SBC HL,BC ;Compute lenght
LD A,L ;Keep only 8 bits
LD (SIZE),A ;Store the result
LD HL,(NEXT) ;Get the next character
LD (CH),HL ;Store it as the current character
LD A,(SIZE) ;Get the size and check the size
LD C,A
LD A,(MAXSIZE) ;Get the maximum length
CP C ;Are they equal?
JP Z,GETPKT20 ;Go return SIZE if equal
JP P,GETPKT13 ;Jump if maxsize still bigger
LD BC,0 ;Start from the beginning
GETPKT11 EQU $
LD A,(OSIZE) ;Get the oldsize index
PUSH BC ;Save the value of i
ADD A,C ;Compute osize+i
LD C,A ;Save the result
LD HL,FILBUF ;Get the start of the buffer
ADD HL,BC ;Compute &filbuf[osize+i]
LD A,(HL) ;Get the character stored there
POP BC ;Restore i
LD HL,LEFTOVER ;Get the address of the leftover buffer
ADD HL,BC ;Compute the absolute address
LD (HL),A ;Store the byte
OR A ;Check the value for zero
JR Z,GETPKT12 ;Jump if end of string
INC C ;Compute i++
JR GETPKT11 ;Go to the top of the loop
GETPKT12 EQU $
LD A,(OSIZE) ;Store the new pointer
LD (SIZE),A
LD C,A ;Terminate the string with a NULL
LD B,0 ;Get a 16 bit offset
LD HL,FILBUF ;Get the starting address
ADD HL,BC ;Compute the address
LD (HL),0 ;Put in the NULL
JP GETPKT20 ;Go to the return code
GETPKT13 EQU $
JP GETPKT4
GETPKT20 EQU $
LD A,(SIZE) ;Get the size to return
POP HL ;Restore the registers
POP DE
POP BC
RET
;
; Encode the character in the Accumlator and put it into
; the packet buffer at CBFPTR.
;
ENCODE EQU $
PUSH BC ;Save the regs
PUSH DE
PUSH HL
LD C,A ;Save the character to encode
LD A,(RPTFLG) ;Is repeat quoting in effect?
OR A
JP Z,ENCODE30
LD HL,(NEXT) ;Get the last character
LD A,L
IFANOT C,ENCODE3
LD A,(RPTCNT) ;Get the current repeat count
INC A ;Add one to it
LD (RPTCNT),A ;Store it back
CP 94 ;Too many characters?
JP M,ENCODE50
LD A,(RPTQ)
CALL PUTCBF
LD A,(RPTCNT)
TOCHAR
CALL PUTCBF
XOR A
LD (RPTCNT),A
JP ENCODE30
ENCODE3 EQU $
LD A,(RPTCNT)
IFANOT 1,ENCODE7
XOR A
LD (RPTCNT),A
LD A,C ;Get the character back
CALL ENCODE ;Encode it again
LD HL,(CBFPTR) ;Get the buffer pointer
LD DE,FILBUF ;Get the start of the buffer
OR A ;Reset the carry
SBC HL,DE ;Compute the difference in L
LD A,(MAXSIZE) ;Get MAXSIZE
CP L ;Is L <= A?
JP M,ENCODE6
LD A,L ;Get SIZE
LD (OSIZE),A ;Store it in the old size
ENCODE6 EQU $
XOR A
LD (RPTCNT),A
LD A,C ;Get the character back
CALL ENCODE ;Encode it
JP ENCODE50
ENCODE7 EQU $
LD A,(RPTCNT)
CP 2
JP M,ENCODE10
LD A,(RPTQ)
CALL PUTCBF
LD A,(RPTCNT) ;Get the count
ADD A,' '+1 ;Uncontrolify it
CALL PUTCBF
XOR A
LD (RPTCNT),A
ENCODE10 EQU $
ENCODE30 EQU $
LD A,C ;Get the character
AND 127 ;Turn off high bit
LD B,A ;Save it
LD A,C ;Get the character
AND 128 ;Leave only high bit
LD D,A ;Save it
IFZ ENCODE32
LD A,(EBQFLG)
IFZ ENCODE32
LD A,(EBQ)
CALL PUTCBF
LD C,B ;Save only 7 bit version
ENCODE32 EQU $
LD A,C ;Get all bits for check
IFA 127,ENCODE33
IFAGE ' ',ENCODE34
ENCODE33 EQU $
LD A,(MYCTLQ)
CALL PUTCBF
LD A,C ;Get the character
ADD A,64 ;Uncontrolify it
AND 127 ;Keep only 7 bits
LD C,A ;Save the new value
ENCODE34 EQU $
LD HL,(CBFPTR) ;Do this ahead to save overhead
LD A,(MYCTLQ)
IFANOT B,ENCODE35
PUTHL A ;Store the byte
ENCODE35 EQU $
LD A,(RPTFLG)
IFZ ENCODE36
LD A,(RPTQ)
IFANOT B,ENCODE36
LD A,(MYCTLQ)
PUTHL A
ENCODE36 EQU $
LD A,(EBQFLG)
IFZ ENCODE37
LD A,(EBQ)
IFANOT B,ENCODE37
LD A,(MYCTLQ)
PUTHL A
ENCODE37 EQU $
PUTHL C
LD (CBFPTR),HL
LD (HL),0
ENCODE50 EQU $
POP HL ;Restore the stack
POP DE
POP BC
RET
;
; Decode the contents of the packet, and output them using
; the function whose address is passed in HL
;
DECODE LD (OUTADDR),HL ;Save the output function
PUSH BC ;Save the registers that we use
PUSH DE
PUSH HL
LD HL,DATA ;Get the buffer address
LD (DATPTR),HL ;Set the address
LD C,A ;Get the length
LD B,0 ;Make it 16 bits
PUSH HL ;Save DATPTR
ADD HL,BC ;Compute the end of the packet
LD (HL),0 ;Put in the NULL byte
POP HL ;Get DATPTR back
DECODE0 LD A,1 ;Set the repeat count
LD (RPTCNT),A
LD A,(HL) ;Get a character
INC HL ;Point to the next
LD C,A ;Store the value
OR A ;Is it NULL?
JP Z,DECODE40 ;Quit the loop if it is
LD A,(RPTFLG) ;Is repeat prefixing on?
IFZ DECODE1
LD A,(RPTQ) ;Get the quote character
IFANOT C,DECODE1
LD A,(HL) ;Get the count + 32
SUB ' ' ;Make it the real count
INC HL ;Point to next character
LD (RPTCNT),A ;Save the repeat count
LD A,(HL) ;Get a character
INC HL ;Point to the next
LD C,A ;Save the character
DECODE1 XOR A ;Set the initial eighth bit as ZERO
LD D,A
LD A,(EBQFLG) ;Is eighth bit quoting on?
IFZ DECODE2
LD A,(EBQ) ;Get the eighth bit quote character
IFANOT C,DECODE2
LD D,128 ;Get an eighth bit
LD A,(HL) ;Get a character
INC HL ;Point to the next
LD C,A ;Save the character
DECODE2 LD A,(MYCTLQ) ;Get the control character quote
IFANOT C,DECODE5
LD A,(HL) ;Get a character
INC HL ;Point to the next
LD C,A ;Save the character
AND 127 ;Keep 7 bits
LD E,A ;Save only 7 bits worth
LD A,E ;Check lower bound of controls
CP '@'
JP M,DECODE3 ;Jump if less than
CP 96 ;Check upper bound of controls
JP M,DECODE4
DECODE3 IFANOT '?',DECODE5
DECODE4 LD A,C ;Get the character
SUB 64 ;Subtract 64 to uncontrolify it
AND 127
LD C,A ;Save the new value
DECODE5 LD A,D ;Get the eighth bit
OR C ;Or in the character
LD C,A ;Save the new value
LD A,(RPTCNT) ;Get the repeat count
LD B,A ;Get it into the counter
DECODE8 LD IX,RTRANS ;Get the pointer
CALL INCKTRANS ;Increment character counts
LD A,C ;Get the character
CALL PUTCH
JR NZ,DECODE50
DJNZ DECODE8 ;Loop until done
JP DECODE0
DECODE40 EQU $
POP HL ;Restore the stack
POP DE
POP BC
RET
DECODE50 EQU $
CALL XERROR0 ;Print a system error message
LD A,1 ;Set NZ status for return
OR A
JR DECODE40 ;Join the exit code
;
; Get the next character from the input file. We translate CR to
; CRLF, for ASCII files. Returns with (EOFLAG) set to 0FFH at end
; of file. The character retrieved is in HL. HL will be 16bits
; of -1 and EOF, but will otherwise only be 8bits wide. H in this
; case will always be 0, and L will hold the character.
;
GETCH LD A,(FILTYPE) ;Check for binary mode
OR A ;Set the flags
JR NZ,GETCH1 ;Jump if it is binary
LD A,(PREVCH) ;Get the previous character
IFANOT CR,GETCH1
LD A,10 ;Get a LF character
LD (PREVCH),A ;Reset the previous character
LD L,A ;Put it into HL
LD H,0
RET ;Return to the caller
GETCH1 EQU $
LD HL,(MEMSTR)
LD A,H
OR L
JR Z,GETCH2
LD A,(HL)
INC HL
LD (MEMSTR),HL
IFZ GETCH4
JR GETCH3
GETCH2 EQU $
LD DE,FCB ;Get the File Control Block
CALL XGET ;Get a character into A
JR NZ,GETCH4 ;Jump to EOF on error
LD IX,STRANS ;Get the pointer
CALL INCKTRANS ;Increment the character count
GETCH3 EQU $
LD (PREVCH),A ;Set the previous character
LD L,A ;Put it into HL
LD H,0
RET ;Return
GETCH4 EQU $
LD A,0FFH ;Set the EOF flag
LD (EOFLAG),A
LD (PREVCH),A ;Reset the previous character flag
LD L,A ;Make HL 16bits wide -1
LD H,A
RET ;Return to caller
;
; Put the next character to the output file. We convert CRLF to CR
; IFF X packets are not active, and binary mode is not active
;
PUTCH PUSH HL
PUSH BC ;Save the register
LD C,A ;Save the character to output
LD A,(PREVCH) ;Get the previous character
IFANOT CR,PUTCH1
LD A,(DISFLG) ;Check if we are doing X packets
IFZ PUTCH1
LD A,(FILTYPE) ;Doing D packets, so check file mode
OR A
JR NZ,PUTCH1
LD A,C
IFA 10,PUTCH2
PUTCH1 LD A,C ;Get the character to output
LD (PREVCH),A ;Make it the new previous
LD HL,(OUTADDR) ;Get the output routines address
CALL CALLHL ;Call the output routine
PUTCH2 POP BC ;Restore the stack
POP HL
RET ;Return to caller
;
; Put A into the location pointed to by CBFPTR, and increment the
; pointer to point to the next location
;
PUTCBF LD HL,(CBFPTR) ;Get the pointer
PUTHL A
LD (CBFPTR),HL ;Store the new pointer value
RET ;Return
;end of file