; m4term/asm ; ; This is the connect command ; CONNECT EQU $ LD A,CMCFM ;Get a confirmation CALL COMND JP KERMT3 ;Abort if no pressed CALL SCRCON ;Swap in the proper screen LD A,(MAXCNT) ;Select the proper buffer size LD (SVMAX),A LD A,80 ;80 characters max are buffered LD (MAXCNT),A LD A,(FTIME) ;Is this the VERY FIRST connect? IFNZ CON_2 STROUT CLRTOP ;Clear the screen CON_1 STROUT INFMS7 ;Display the message CALL ESCPR STROUT INFMS8 LD A,1 ;Set the first time done flag LD (FTIME),A CON_2 LD A,14 CALL CONOUT ; ; While in connect mode, at most, 30 characters may be processed ; from the input port, before the keyboard is scaned. We try not ; to scan the keyboard too much, as that will kill screen I/O. This ; is especially true at higher baud rates, where the user might ; not get to type a key because the flow of characters into the ; port is continuous. ; CHRLUP LD A,30 ;Set the maximum character count LD (CHCNT),A ;Save it CALL PRTCHR ;Do input characters CALL CONCHR ;Get a keyboard character JP KERMIT ;IF we return here, then abort JR CHRLUP ;Loop on ; ; Look at the input buffer for a character, and return it, or ; return no input. ; INPORT PUSH HL ;SAVE HL LD HL,(NXTCHR) ;Get address of next input char LD A,(CURCHR) ;Get the LSB of the queue start IFA L,INOUT ;If A=L, then there is no input. DI ;Interrupts off, CRITICAL section LD A,(HL) ;Get the character back LD (SVCHAR),A ;Save the input character INC L ;Delete the character LD (NXTCHR),HL ;Set the new pointer LD HL,INCNT ;Decrement the count DEC (HL) EI ;Interrupts back on LD A,(FLOFLG) ;Is XON/XOFF in effect? IFZ INP11 ;Go if not doing flow control PUSH BC ;Save BC LD C,(HL) ;Get a copy of the count LD A,(XFFLG) ;Check if XOFF sent out IFZ INP10 ;Jump if not LD A,(MAXCNT) ;It was, so check if time for XON SRL A ;Use 1/2 of the max as the restart count IFALT C,INP10 ;If A >= count it is not time yet PUSH DE ;Save DE LD E,XON ;Get an XON character CALL OUTCHR ;Out the port it goes XOR A ;Reset the XOFF sent flag LD (XFFLG),A POP DE ;Restore E INP10 POP BC ;Restore C INP11 LD A,0 ;Get the next character SVCHAR EQU $-1 CP A ;Set Z status for normal return INOUT1 POP HL ;Restore HL RET ;Back to caller ; ; No input exit from INPORT ; INOUT EQU $ XOR A ;Reset the count LD (INCNT),A ;Zeroed INC A ;Set NZ (We know A was zero, now it is 1) POP HL ;Restore HL RET ;Back to the caller ; ; Input a character, and display it based on the current value ; of EMULATION. ; PRTCHR CALL INPORT ;Try to get an input character. RET NZ ;Return if none there LD E,A ;Get the input character CALL LOGONE ;Maybe do logging LD A,(PRTFLG) ;CHECK FOR PRINTER OUTPUT OR A ;SET THE FLAGS CALL NZ,PRTIT ;GO PRINT IT LD A,E ;GET THE CHARACTER AND DISPLAY CALL TRMOUT ;Send it to the *SO device LD B,0 ;Get the current count CHCNT EQU $-1 DJNZ PRTCHR5 ;SKIP RETURN IF NOT LIMIT RET ;RETURN AFTER LIMIT IS UP PRTCHR5 LD A,B ;GET THE NEW COUNT LD (CHCNT),A ;SAVE IT JP PRTCHR ;LOOP ON ; ; Input a character from the keyboard. ; CONCHR CALL GETKEY ;Get a keyboard character without JP NZ,RSKP ;Return if not one LD E,A ;Is it CONNECT escape character? LD A,(ESCCHR) CP E JP Z,INTCHR ;Go process the next key pressed CONCHR2 IFANOT 128,CONCHR3 ;BREAK? CALL DOBRK ;Generate real BREAK JP RSKP CONCHR3 LD A,E CONCHR4 PUSH DE ;SAVE DE CALL PRTOUT ;SEND IT TO THE PORT POP DE LD A,(ECOFLG) ;CHECK FOR LOCAL ECHO OR A LD A,E CALL NZ,TRMOUT ;Echo out terminal device JP RSKP ;RETURN TO THE CALLER SAY OK ; ; This is the code to process the escape sequences during the ; CONNECT command that do things like return to the KERMIT ; prompt, send a break, turn logging on and off, etc... ; INTCHR EQU $ CALL GETKEY ;Get a character from translator JR NZ,INTCHR ;Loop until we get one INCH00 EQU $ LD B,A ;Put the real character into B AND 137O ;Convert A to upper case IFANOT 'C',INCH01 ;Is it connect, if not try other CALL SCRCMD ;Swap KERMIT screen in LD A,(SVMAX) ;Restore the old max LD (MAXCNT),A RET ;Return to KERMIT INCH01 LD A,B ;Get the real value IFANOT '?',INTCH1 ;Is it help, if not try next LD A,15 ;Turn the cursor off CALL CONOUT LD B,4 ;Get the cursor position CALL XVDCTL PUSH HL ;Save it LD HL,2600H ;Save the screen LD B,6 ;Get screen function CALL XVDCTL ;Do the move LD HL,0C00H ;Move to middle CALL TOSCRPOS ;Move to possition on screen LD A,31 ;Clear to eos CALL CONOUT LD DE,INTHLP ;Get Help message CALL PRTSTR ;Print message INCH11 CALL GETKEY ;Get a character JR NZ,INCH11 ;Jump if no key pressed POP HL ;Reorder the stack PUSH AF PUSH HL LD HL,2600H ;Get the old screen LD B,5 ;Put it back into view CALL XVDCTL POP HL ;Restore old cursor position CALL TOSCRPOS ;Position the cursor LD A,14 ;Turn the cursor back on CALL CONOUT POP AF ;Get the character typed back JR INCH00 ;Loop back to process character ; INTCH1 AND 137O ;Convert back to uppercase IFANOT 'B',INTCH2 ;Is it BREAK, if not try next CALL DOBRK ;Send BREAK out port JP RSKP ;Return NO error INTCH2 LD A,B ;Get the real character IFANOT '0',INTCH3 ;Is it NULL, if not try next LD E,0 ;Get a NULL CALL OUTCHR ;Out the port with it JP RSKP ;Return no error INTCH3 LD E,B ;Get the real character LD A,(ESCCHR) ;Get the escape character IFA E,INTCHZ ;Is it the escape character ? LD A,B ;Get the real character AND 137O ;Upper case again IFANOT 'Q',INTCH4 ;Is it QUIT, if not try next LD A,(LOGFLG) ;Get the logging flag IFANOT 2,INTC3A ;Is logging active, jump if not DEC A ;Turn logging off LD (LOGFLG),A ;Set the value JP RSKP ;Return no error INTC3A LD A,BELL ;Get An error sound CALL CONOUT ;BEEP AT THEM JP RSKP ;Return no error INTCH4 IFANOT 'R',INTCH5 ;Resume logging? Jump if not LD A,(LOGFLG) ;Check logging status IFANOT 1,INTC3A ;If not 1, can't resume INC A ;Turn logging on LD (LOGFLG),A ;Set the value JP RSKP ;Return no error INTCH5 LD A,E ;Get the character typed CALL PRTOUT ;Send it out the port JP RSKP ;Return no error INTCHZ CALL OUTCHR ;Send it out the port LD A,BELL ;Get a bell CALL CONOUT ;Send bell to terminal JP RSKP ;Return no error ; ; Send character to printer ; PRTIT EQU $ LD A,E ;Get the character PUSH DE ;Save E for return CALL XPRT ;Dos printer routine POP DE ;Restore E RET ;Return ; ; Generate a real modem break ; DOBRK LD C,1 ;OPTION 1 OF @CTL LD DE,(CLDCB) ;Get the *CL DCB CALL XCTL ;Do @CTL to start Modem break DI ;Make the pause be exact LD BC,39000 ;Pause for 200ms BRKLOOP DEC BC ;Decrement the count LD A,B OR C JR NZ,BRKLOOP ;Loop until done EI LD E,0 ;Stop break with any character JP OUTCHR ;Null is good ; ; Output any none null character to the RS232 port ; PRTOUT OR A ;Don't send NULLS RET Z LD E,A ;Get the character JP OUTCHR ;Output it ; ; Log a character to the log file ; LOGONE PUSH AF PUSH DE LD E,A LD A,(LOGFLG) OR A LD A,E CALL NZ,LOGIT POP DE POP AF RET ; ; Output a character to *DO ; CONOUT PUSH DE ;SAVE THE REGS PUSH BC PUSH AF IFA BELL,BEEPON ;Go if bell CALL XDSP ;Use the @DSP SVC to display it CON010 POP BC ;Use BC to get A, and not destroy flags LD A,B ;Get the old A POP BC POP DE RET ;RETURN TO THE CALLER ; ; Output a character to *SO ; TRMOUT PUSH DE ;Save the regs PUSH BC PUSH AF LD E,A ;Make a copy of the character LD A,(EMULFLAG) ;Get the emulation flag IFZ TRMOUT3 ;Jump if EMULATION set to NONE ; ; Certain control characters are translated on input. In ; particular, the following mappings are in effect. ; ; 8 -> 24 non destructive backspace ; 10 -> 26 non destructive linefeed ; 13 -> 29 True carriage return ; LD A,E ;Is this a control character? IFAGE 32,TRMOUT3 ;Jump if not a control character LD HL,TRTAB ;Get the translation table LD B,0 ;Make BC an offset into TRTAB ; ; If the character in the translation table is 0, then it is ; ignored. This is handy for blocking out things like cursor ; on/off, and inverse video on/off ; LD C,A ;Get the character to use as index ADD HL,BC ;Index to the table LD A,(HL) ;Get the translated character IFZ TRMOUT5 ;Return if character is to be ignored LD E,A ;Make a copy for later IFANOT 12,TRMOUT1 ;Jump if not a formfeed CALL CMBLNK ;Clear the screen JR TRMOUT5 TRMOUT1 IFANOT 7,TRMOUT3 ;Jump if not bell CALL CONOUT ;DUMB uses BUILTIN Bell JR TRMOUT5 TRMOUT3 EQU $ LD A,E ;Get the character LD DE,(TMODCB) ;Get the Device DCB for terminal out CALL XPUT ;@PUT the character to the device TRMOUT5 POP BC ;Use BC to get A, and leave Flags alone LD A,B ;Get A POP BC ;Restore BC POP DE ;And the rest RET ; ; Input a character from *SI ; TRMIN PUSH DE PUSH BC LD DE,(TMIDCB) ;Get the terminal input DCB CALL XGET ;@GET a character POP BC ;Restore the regs POP DE RET ; ; Sound a bell ; BEEPON LD A,(BELFLG) ;IS THAT OPTION ON? IFZ CON010 ;Jump if bell option off PUSH BC ;Save counter LD C,50 ;Get the duration BEEP1 LD A,1 ;Get the value to send out port OUT (90H),A ;Toggle port high LD B,130 ;Delay DJNZ $ DEC A ;Set A to zero OUT (90H),A ;Toggle port low LD B,130 ;Delay DJNZ $ DEC C ;Decrement duration JR NZ,BEEP1 ;Loop if not done POP BC ;Restore counter JR CON010 ;Join return code ; ; Print string pointed to by DE to *DO, EOS is end of string ; NUL characters are thrown out. ; PRTSTR LD A,(DE) ;GET A CHARACTER CP EOS ;IS IT THE END? RET Z ;RETURN TO CALLER IF SO OR A ;THROW AWAY THE NULL CHARACTER CALL NZ,CONOUT ;DISPLAY ANYTHING NON-NULL INC DE ;POINT TO THE NEXT ONE JR PRTSTR ;LOOP ON ; ; Get a character from *KI ; CONIN PUSH DE ;SAVE DE CALL XKBD ;LOOK AT THE KEYBOARD WITHOUT WAITING POP DE ;RESTORE DE RET ;RETURN TO THE CALLER ; ; Output a character to *CL. The character is in E. ; OUTCHR PUSH DE ;SAVE CURRENT DE AND BC PUSH BC LD C,E ;Put the character where it should be OUTCH0 LD A,(XOFREC) ;CHECK TO SEE IF WE CAN TRANSMIT YET! IFZ OUTCH2 ; ; We allow break to force the transmittion of the character that ; is being sent. There are ways that the XON from the host can ; be lost. This allows control to be regained, without rebooting ; which would be the only other choice. ; OUTCH1 CALL CONIN ;Check the break key IFANOT 128,OUTCH0 ;Jump if not XOR A ;Reset the XOF'd flag LD (XOFREC),A OUTCH2 LD A,C ;Get the character to send OUTCH3 LD DE,(CLDCB) ;GET THE DCB OF THE DEVICE TO PUT TO CALL XPUT ;SEND THE CHARACTER JR NZ,OUTCH3 ;Transmitter may not be ready, loop if ; needed until character is transmitted OUTCH4 POP BC ;Restore the regs POP DE RET ; ; Character input routine for INPKT. We can timeout on the ; receive by allowing the timer to place a return in the code ; below, at the address RECALRM. Since TRSDOS doesn't allow ; us (neatly, without a hack) to transfer control in a task, ; to some other code, we use the self modifying code. This ; may be considered dirty, but it does work. The RET causes ; the code to behave as though the user had pressed to ; resend the latest packet. ; INCHR XOR A ;Get a NOP instruction LD (RECALRM),A ;Remove any stored RET instruction INCHR1 CALL CONIN ;Check keyboard first to make sure IFNZ INCHR3 CALL INPORT ;Get a character from the buffer JP Z,RSKP ;Return if we got one RECALRM NOP ;Modified by timeout code to be a RET JR INCHR INCHR3 IFANOT CR,INCHR4 ;Check which key was pressed LD A,(TASKSLOT) ;Get the active task OR A ;See if task aqctive RET Z ;Return if not LD C,A ;Get the task slot into c CALL XRMTSK ;Stop the task RET ;Return resend status INCHR4 CHKWKEY 'B'-64 ;Control-B for batch CHKWKEY 'F'-64 ;Control-F for file CHKWKEY 'A'-64 ;Control-A for status CHKWKEY 'E'-64 ;Control-E for send error CHKWKEY 'D'-64 ;Debug? CHKWKEY 'H'-64 ;Help? IFANOT 'C'-64,INCHR1 ;Control-C for abort completely INCHR5 ADD A,40H ;MAKE IT PRINTABLE LD (CZSEEN),A RET ; ; Timer task for receiving a packet. Called every 33.333333333 ; milliseconds. We decrement the TIMER counter, and when it ; goes to zero, we write a RET into the above code, and kill ; the task so that is does not return. ; ; Note that we must NOT leave anything on the stack when @KLTSK ; is called or else it will puke. ; RECTIMOUT EQU $ PUSH HL ;Save the registers used PUSH AF LD HL,(TIMER) ;Get the counter DEC HL ;Decrement it LD (TIMER),HL ;Store the new value LD A,H ;Check it for zero OR L JR NZ,RECT1 LD A,0C9H ;Get a RET instruction opcode LD (RECALRM),A ;Write it in POP AF ;Restore the register POP HL JP XKLTSK ;Remove this task, NO RETURN. ; RECT1 POP AF ;Restore the registers POP HL RET ;Return ; ; Move cursor to position on screen ; TOSCRPOS EQU $ LD B,3 JP XVDCTL ;end of file