home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Columbia Kermit
/
kermit.zip
/
archives
/
trs80model4.tar.gz
/
trs80model4.tar
/
m4mit.asm
< prev
next >
Wrap
Assembly Source File
|
1986-10-22
|
13KB
|
457 lines
; M4MIT/ASM
;
ORG 6000H
;
; Model 4(p) KERMIT by Gregg Wonderly
;
; Version 5.2
;
; Version 5.2 adds wild card send capabilities as well as fixes
; to bugs. M4CHGS/ASM contains a list of the changes made between
; version 5.0, and 5.2.
;
; This version is a radically modified and rewritten version
; of the original TRS-80 KERMIT done by Stan Barber. It has
; numerous features and capabilities beyond that version due
; to differences between the Model 3 and 4.
;
; Get the macro definitions first
;
*GET M4EQU
*GET M4MAC
;
; Entry point for execution
;
START LD (OLDSP),SP ;Save the current stack pointer for later
LD SP,STACK ;Set up the stack to our area
CALL XFLAGS ;Get the flags address in IY
LD (FLAGS),IY ;Save the flags for later
LD HL,SWTBUF ;Clear initial connect screen buffer
LD DE,SWTBUF+1
LD BC,1920 ;Byte counter
LD (HL),' ' ;Clear the first character
LDIR ;Copy it to the next
LD B,1 ;Move low memory up above our code.
LD HL,0 ;Select GET option of @HIGH$
CALL XHIGH ;Get the current LOW$
JP NZ,BADMEM ;Quit on an error
LD (OLDLOW),HL ;Save for restore on exit
LD HL,TOPMEM ;Get the last address used
CALL XHIGH ;Store it as the new LOW$
JP NZ,BADMEM ;Quit on an error
LD E,'C' ;Look for the *CL DCB
LD D,'L'
CALL XGTDCB ;The address comes back in HL
LD (CLDCB),HL ;Save the address (May be wrong)
JR NZ,NOCL ;Now check for error...
LD E,'S' ;Look for the *SI DCB
LD D,'I'
CALL XGTDCB ;The address comes back in HL
LD (TMIDCB),HL ;Store the result
JR NZ,NOSI ;Skip if NOT found or other error
LD E,'S' ;Look for the *SO DCB
LD D,'O'
CALL XGTDCB ;The address comes back in HL
LD (TMODCB),HL ;Save the address
JR NZ,NOSO ;Jump if NOT found or other error
CALL SETINT ;Set up interupt receiver etc
XOR A ;ZERO A
LD (FCB),A ;SET FILE CLOSED FLAG
CALL CMBLNK ;CLEAR THE SCREEN
STROUT INTRO ;Print the intro message
CALL CHKTAK ;Check if there is a KERMIT/INI file
CALL KERMIT ;Start accepting commands.
JP EXIT1 ;If control returns, then exit
;
; Error messages printed when devices can not be found or allocated
;
NOCL LD DE,CFCL ;Error message (Can't find *CL DCB)
PRTOOPS CALL PRTSTR ;Print an OOPS message, and quit
JP EXIT2 ;Finish cleaning up
;
; No DCB for the SI device was found
;
NOSI LD DE,CFSI ;Get the message
JR PRTOOPS ;Go print it
;
; No DCB for the SO device was found
;
NOSO LD DE,CFSO ;Get the message
JR PRTOOPS ;Go print it
;
; Bad return code from @HIGH$ call
;
BADMEM CALL XERROR0 ;Print a system error message
STROUT NOMEM ;Print the message
JP XEXIT ;Exit to TRSDOS
;
; CLEAR THE SCREEN, SAVING DE
;
CMBLNK PUSH DE ;Save DE
STROUT CLRTOP ;Clear the screen
POP DE ;Restore DE
QUIT RET ;Just a simple return for QUIT
;
; KERMIT command processor
; This is where each command originates.
;
KERMIT LD SP,STACK ;Set the stack back
LD DE,FCB ;Always close an open file
LD A,(DE) ;Get the flags byte
BIT 7,A ;Is the file still open?
CALL NZ,XCLOSE ;Close it if it is
LD DE,KERM ;Get the prompt
CALL PROMPT ;Display it, and set up the parser
LD DE,COMTAB ;Get the primary command table
LD A,CMKEY ;Parse a keyword
CALL COMND ;Get a command or ERROR
JP KERMT2 ;Abort on ERROR
LD HL,KERMIT ;Put on a return address for the
PUSH HL ;FINISH, LOGOUT, and BYE commands.
PUSH HL
LD HL,KERMTB ;Get the JUMP table for these commands
LD C,A ;Make BC = A extended to 16 bits
LD B,0 ;high byte is zero, (unsigned)
ADD HL,BC ;Calculate the effective address
JP (HL) ;Jump into the jump table
;
; Jump table for primary commands
;
KERMTB JP REMOTE ;REMOTE
JP EXIT ;EXIT
JP CONNECT ;CONNECT
JP LOG ;LOG
JP READ ;RECEIVE
JP SEND ;SEND
JP SETCOM ;SET
JP SHOW ;SHOW
JP STATUS ;STATUS
JP FINISH ;FINISH
JP LOGOUT ;LOGOUT
JP BYE ;BYE
JP DIR ;DIRECTORY
JP ERA ;KILL
JP LOCCOM ;LOCAL
JP SETCL ;SETCOM
JP TAKE ;TAKE
JP INPUT ;INPUT
JP OUTPUT ;OUTPUT
JP PAUSE ;PAUSE
JP PULSE ;PULSE
JP CLEARC ;CLEAR
JP CLSFLS ;CLOSE
JP ECHO ;Type text to screen
;
; Echo text to screen
;
ECHO EQU $
LD A,CMTXT ;Get some text
LD DE,DATA ;Where to put it
PUSH DE ;Save for printing
CALL COMND ;Parse it
JP KERMT3 ;Jump on error
POP HL ;Get the start
LD C,A ;Make BC the length that is in A
LD B,0
ADD HL,BC ;Move to EOS position
LD (HL),EOS ;Put it in place
CALL NEWLIN ;Get a new line
STROUT DATA ;Print the string
JP KERMIT ;Get a new command
;
; CLEAR command. Services CLEAR INPUT-PORT, and CLEAR SCREEN
;
CLEARC LD A,CMKEY ;GET A KEYWORD
LD DE,CLRTAB ;FROM THIS TABLE
CALL COMND
JP KERMT2 ;SAY UNRECOGNIZED COMMAND ON AN ERROR
LD (TEMP1),A ;SAVE THE RETURNED VALUE
LD A,CMCFM
CALL COMND
JP KERMT3
LD A,(TEMP1)
LD C,A
IFNZ CLR010
CALL CLRPRT ;DO "CLEAR INPUT-PORT"
JP KERMIT ;GET A NEW COMMAND
CLR010 CP 3 ;IS IT CLEAR SCREEN?
JP NZ,KERMT2 ;SAY UNRECOGNIZED COMMAND IT NOT
CALL CMBLNK ;CLEAR THE SCREEN
JP KERMIT ;GET A NEW COMMAND
;
; TAKE commands from a file. This is basically a HACK that
; initializes some values so that GETSTR reads from the file,
; instead of the keyboard, until EOF is found.
;
TAKE LD DE,TFCB ;WHERE TO PUT THE FILENAME
LD A,CMIFI ;GET A FILE NAME
CALL COMND ;GET USER INPUT
JP KERMT3 ;ABORT ON AN ERROR
OR A
JP Z,KERMT3 ;Abort if no name given
LD IY,(FLAGS) ;GET THE SYSTEM FLAGS
SET 0,(IY+18) ;SET UP FOR NO FILE OPEN BIT
LD HL,TBUF ;THIS IS THE DATA BUFFER
LD DE,TFCB ;GET THE FILE FCB
LD B,0 ;256 BYTE LRL
CALL XOPEN ;TRY TO OPEN THE FILE
JR NZ,TERROR ;GO REPORT AN ERROR
LD A,1
LD (TAKFLG),A ;SET THE FLAG
JP KERMIT
TERROR CALL XERROR0 ;PRINT THE MESSAGE
XOR A ;RESET THE TAKE FLAG
LD (TAKFLG),A
JP KERMIT ;GET A NEW COMMAND
;
; SETCOM command. We use the TRSDOS SETCOM command here, as it
; saves lots of time and trouble.
;
SETCL LD A,CMTXT ;GET ARBITRARY TEXT
LD DE,CLBUF ;BUFFER TO PUT DATA INTO
CALL COMND ;GET THE INPUT
JP KERMT3 ;ABORT ON ERROR
CALL NEWLIN ;NEED A NEW LINE TO PRINT ON
LD A,CR ;Get the EOL character
LD (DE),A ;Put in the terminator
LD HL,CLBUF-7 ;Get the 'SETCOM ' prefix
CALL XCMNDR ;Let TRSDOS do it for us
JP KERMIT ;Get a new command, ignoring any errors
;
; LOCAL command. Use @CMNDR to execute a TRSDOS command
;
LOCCOM LD HL,(CMDPTR) ;GET THE ADDRESS OF THE START
SYST1 LD A,(HL) ;GET A CHARACTER
INC HL ;POINT TO THE NEXT
IFA ' ',SYST1 ;Loop if just a blank
IFA CR,SYST2 ;Do a LIB command if no text given
IFANOT '?',SYST4 ;Go if user not asking for HELP
SYST2 PUSH HL ;SAVE THE ADDRESS TO PASS
POP IY ;GET A THE ADDRESS IN AN INDEX
LD (IY-1),'L' ;HL GO INCREMENTED UP THERE
LD (IY),'I' ;SPELLING OUT LIB
LD (IY+1),'B'
LD (IY+2),CR ;ADD THE TERMINATOR
SYST4 DEC HL ;POINT TO THE ACTUAL ADDRESS
CALL NEWLIN ;NEED A NEW LINE
;
; Remove the comments below to force LOCAL to process only library
; commands
;
; LD IY,(FLAGS) ;Get the Flags pointer
; SET 4,(IY+2) ;Only library commands are allowed
CALL XCMNDR ;Do a system command
SYST5 JP KERMIT ;IGNORE ANY ERRORS
;
; Print UNRECOGNIZED COMMAND message
;
KERMT2 STROUT ERMES1 ;Issue the message
JP KERMIT
;
; Print NOT CONFIRMED message
;
KERMT3 STROUT ERMES3 ;Issue the message
JP KERMIT
;
; Exit to TRSDOS
;
EXIT LD A,CMCFM ;Get a confirmation of the EXIT
CALL COMND
JP KERMT3
EXIT1 LD DE,FCB ;Check the file FCB, and close if needed
LD A,(DE) ;Get the info byte
BIT 7,A ;Check the file open BIT
CALL NZ,XCLOSE ;Close it if needed
;
; Check the log files to make sure they are closed
;
LD DE,LFCB ;Get the file FCB
LD A,(LOGFLG) ;Check if logging active
OR A ;Check the flags
CALL NZ,XCLOSE ;Close the file if open
LD DE,DFCB ;Check debugging
LD A,(DEBLOG) ;Get the flag
OR A
CALL NZ,XCLOSE ;Close it if open
LD DE,TFCB ;Get the FCB
LD A,(TRANLOG) ;Get the flag
OR A
CALL NZ,XCLOSE ;Close it if open
;
; Now reset the interrupt vector for *CL.
;
LD C,4 ;Interrupts option of the @CTL SVC
LD IY,0 ;Reset the INTERRUPT vector of *CL
LD DE,(CLDCB) ;Get the *CL DCB address
CALL XCTL ;Use @CTL to do it
CALL CMBLNK ;Clear the screen
EXIT2 LD HL,(OLDLOW) ;Get the old low memory pointer
LD B,1 ;Set B to indicate LOW$
CALL XHIGH ;Move the value back
;
; Now fill the *FO, and *FI devices DCB's with zeros. This
; will make the devices no longer available.
;
LD HL,(FINDCB) ;Get the *FI DCB address
CALL ZERO8 ;Fill it with zeroes
LD HL,(FOTDCB) ;Do the same for *FO
CALL ZERO8 ;Fill DCB with zeroes
CALL STOPTIMER ;Stop the timer if still running
LD SP,(OLDSP) ;Restore the old STACK pointer
LD HL,0 ;Set OK exit
LD IY,(FLAGS) ;If JCL active, then just return
BIT 5,(IY+18) ;Check the BIT
RET NZ ;Return if BIT is set
JP XEXIT ;Exit via @EXIT
;
; Zero 8 bytes pointed to by HL
;
ZERO8 LD B,8 ;Get the byte count
ZERO8_1 LD (HL),0 ;Zap one byte
INC HL ;Point to next
DJNZ ZERO8_1 ;Loop until done
RET
;
; CALL ERROR Prints the DATA area on a new line, and sets
; the state to ABORT.
; CALL ERROR1 Prints the DATA area on a new line.
; CALL ERROR2 Prints the DATA area on the same line
; CALL ERROR3 Prints the string pointed to by DE on a new line
; CALL ERRORD Prints a system error message corresponding to
; A, providing A is none zero.
;
ERROR NSTATE 'A' ;Set the state to abort
;
ERROR1 CALL NEWLIN ;Get a new line
;
ERROR2 LD A,(ARGBLK+1) ;Get the length of the data
LD C,A ;Put the length into BC
LD B,0
LD HL,DATA ;Get the start of the DATA area
PUSH HL ;Save it
LD A,EOS ;Add EOS for printing
CALL PUTTRN
POP DE ;Get start back
JP PRTSTR ;Print the string, and return
;
ERROR3 PUSH DE ;Save the message
CALL NEWLIN ;Get a new line
POP DE ;Restore the message
JP PRTSTR ;Print error message
;
ERRORD OR A ;Display system error message
RET Z ;IFF an error has occured
JP XERROR0 ;Do system error
;
; Print the string in DE, followed by a new line
;
FINMES CALL PRTSTR ;Print the message
JP NEWLIN ;Get a newline and return
;
; The FINISH, BYE, and LOGOUT commands all need a return address
; on the stack. This is because the CHKTRYS routine will use it
; to abort the packet operations when MAXTRY retries are reached.
;
; This is the FINISH command.
;
FINISH LD A,CMCFM
CALL COMND ;GET A CONFIRM.
JP KERMT3
CALL NEWLIN
CALL CLRPRT ;CLEAR ANY STACKED NAKS
XOR A ;DIDN'T GET A CONFIRM.
LD (NUMTRY),A ;INITITIALIZE COUNT.
LD A,'1' ;Set block check to single char
LD (CURCHK),A ;. . .
FINSH1 CALL CHKTRYS ;Check the retry threshold
XOR A
LD (ARGBLK),A ;MAKE IT PACKET NUMBER ZERO.
LD A,1
LD (ARGBLK+1),A ;ONE PIECE OF DATA.
LD HL,DATA
LD (HL),'F' ;FINISH RUNNING KERMIT.
LD A,'G' ;GENERIC COMMAND PACKET.
CALL SPACK ;Send the packet
JP FINSH1 ;On fail, try again
CALL RPACK ;GET AN ACKNOWLEDGEMENT.
JP FINSH1 ;On fail, try again
CP 'Y' ;ACK?
JP Z,KERMIT ;YES, WE ARE DONE.
IFANOT 'E',FINSH2 ;Jump if not error packet
CALL ERROR1 ;PRINT THE ERROR MESSAGE.
JP KERMIT
FINSH2 CP 'N' ;Is this a NAK?
CALL NZ,CONOUT ;Output the packet type to term
JR FINSH1 ;Resend the packet
;
; This is the LOGOUT command.
;
LOGOUT LD A,CMCFM
CALL COMND ;GET A CONFIRM.
JP KERMT3
CALL NEWLIN
CALL LOGO ;SEND THE LOGOUT PACKET.
JP LOG111 ;GO GET ANOTHER COMMAND
JP KERMIT ;WHETHER WE SUCCEED OR NOT.
LOGO XOR A
LD (NUMTRY),A ;INITITIALIZE COUNT.
CALL CLRPRT ;CLEAR ANY STACKED NAKS
LD A,'1' ;Block check type to single
LD (CURCHK),A ;. . .
LOGO1 CALL CHKTRYS ;Check retry threshold
XOR A
LD (ARGBLK),A ;MAKE IT PACKET NUMBER ZERO.
LD A,1
LD (ARGBLK+1),A ;ONE PIECE OF DATA.
LD HL,DATA
LD (HL),'L' ;LOGOUT THE REMOTE HOST.
LD A,'G' ;GENERIC COMMAND PACKET.
CALL SPACK
JP LOGO3
CALL RPACK ;GET AN ACKNOWLEDGEMENT
JP LOGO1
CP 'Y' ;ACK?
JP Z,RSKP ;YES, WE ARE DONE.
CP 'E' ;IS IT AN ERROR PACKET?
JP Z,ERROR1 ;Print the error message
LOGO2 CP 'N'
CALL NZ,CONOUT
JR LOGO1
;
LOGO3 LD DE,ERMS19 ;Get the message
JP PRTSTR ;Print it
;
; This is the BYE command
;
BYE EQU $
LD A,CMCFM
CALL COMND ;GET A CONFIRM.
JP KERMT3
CALL NEWLIN
CALL LOGO ;TELL THE MAIN FRAME TO LOGOUT.
JP LOG111 ;IF IT FAILS, DON'T EXIT.
JP EXIT1 ;EXIT KERMIT.
LOG111 CALL NEWLIN ;GET A NEW LINE
JP KERMIT
;
; Get the rest of the modules
;
*GET M4FILE/ASM ;Log file code
*GET M4CMD/ASM ;Command parser
*GET M4SET/ASM ;Set command processing
*GET M4TERM/ASM ;Terminal emulation
*GET M4SHOW/ASM ;Show command processing
*GET M4PKT/ASM ;Additional packet stuff
*GET M4GET/ASM ;Receive protocol
*GET M4SEND/ASM ;Send protocol
*GET M4XFER/ASM ;Protocol common code
*GET M4ADD/ASM ;TRSDOS SVC's and other system dependent stuff
*GET M4RMT/ASM ;Remote commands
*GET M4KEY/ASM ;Set key code
*GET M4LOG/ASM ;Input, Output, Pause, Pulse commands
*GET M4WILD/ASM ;Wild carding
*GET M4STR/ASM ;Strings and storage
TOPMEM EQU $+10 ;A little padding
END START
;end of file