--- title: "SQ Notes: Terminal Program" type: "article" slug: "sq-notes-terminal-program" url: "http://localhost/article/sq-notes-terminal-program/" markdown_url: "http://localhost/article/sq-notes-terminal-program.md" published_at: "2022-10-07T12:27:00+00:00" modified_at: "2026-08-02T08:45:13+00:00" featured_image: url: "http://localhost/wp-content/uploads/2022/04/20230809-041332.jpg" excerpt: "Ever been frustrated with the type of terminal programs available for your computers? Well some years ago, the only terminal programs available for the 2068 were MTERM & MTERM II, the slow key response of either program got to me, so I sat down and wrote my own. Perhaps some of you still remember the…" category: - name: "SMUG Bytes" slug: "smug-bytes" taxonomy: "category" url: "http://localhost/category/periodicals/smug-bytes/" post_tag: - name: "Best of Timex/Sinclair 2068 Articles and Documents" slug: "ts2068best" taxonomy: "post_tag" url: "http://localhost/tag/ts2068best/" - name: "TS 2068" slug: "ts2068" taxonomy: "post_tag" url: "http://localhost/tag/ts2068/" - name: "Type-in program" slug: "type-in-program" taxonomy: "post_tag" url: "http://localhost/tag/type-in-program/" model: - name: "Timex/Sinclair 2068" slug: "ts-2068" taxonomy: "model" url: "http://localhost/model/ts-2068/" indiv: - name: "Rudy A. Hilsmann" slug: "r-a-hilsmann" taxonomy: "indiv" url: "http://localhost/indiv/r-a-hilsmann/" publication_r: id: 37935 title: "SMUG Bytes" type: "periodical" url: "http://localhost/periodical/smug-bytes/" authors: "R. A. Hilsmann" authors_r: - name: "Rudy A. Hilsmann" slug: "r-a-hilsmann" taxonomy: "indiv" url: "http://localhost/indiv/r-a-hilsmann/" volume: "6" issue: "4" issues_articles: - id: 39719 title: "SMUG Bytes v6 n4" type: "issue" url: "http://localhost/issue/smug-bytes-v6-n4/" pages: "3-5" pubdate: "April 1989" archive_link: false --- # SQ Notes: Terminal Program Ever been frustrated with the type of terminal programs available for your computers? Well some years ago, the only terminal programs available for the 2068 were MTERM & MTERM II, the slow key response of either program got to me, so I sat down and wrote my own. Perhaps some of you still remember the printout which I brought to one of the meetings. At that time I was looking for a solution to the slow screen action on the 2068 while running the 2050 modem at 1200 baud. I was loosing one or two characters at the beginning of each line after the initial screen had filled, and the scroll routine in ROM was activated. I solved the problem a few days later by telling the TNC (Terminal Node Controller) to send a few nulls after each linefeed, this took care of the problem. The program I wrote, which you can see in the next columns, was originally written for use with PACKET RADIO, a form of digital communication developed by Amateur Radio Operators, where instead digital signals are send via Radio rather than via the telephone lines. This should tell you that this program will work with an RS 232 board which I installed into the 2050 modem, but I have never checked this program with the phone modem in the 2050. In the next column is a listing of the 275 bytes of code for the main module, nothing fancy, but fast. There are some features incorporated in the code, an audible tone when a control “G” is received, and the chance to open a capture buffer, 32K in length, from basic, which you may reset and clear while in terminal mode. All this could be enhanced with the support of a basic program. You will find a few lines of basic I wrote to give you some idea. Make any additions or changes to your liking or needs. #### Assembly Listing ``` ORG $EE00 BAUD: NOP ; BAUDRATE, 4E=1200 BOPN: NOP ; FF=BUFFER OPEN, 00 CLOSED BFER: NOP ; START OF BUFFER CONSTANT NOP ; AT 6DF6H = 28150 DEC PBFR: NOP ; BUFFER POINTER (WRITE) NOP LBFR: NOP ; REMAINING SPACE IN BUFFER NOP INIT: LD HL,6DF6 ; LOAD HL - START BUFFER LD (BFER),HL ; LOAD EE02 HL LD (PBFR),HL ; LOAD EE04 HL LD HL,8000 ; LOAD HL, LENGTH BUFFER LD (LBFR),HL ; LOAD EE06 HL UART: XOR A ; CLEAR A OUT (77),A ; OUTPUT 0 THREE TIMES TO OUT (77),A ; ENSURE THAT USART IS OUT (77),A ; IN A KNOWN STATE. LD A,40 ; RESET USART=40H - 64DEC OUT (77),A ; OUTPUT TO COMMAND CHANNEL LD A,(BAUD) ; SET BAUDRATE OUT (77),A ; OUTPUT TO COMMAND CHANNEL LD A,37 ; ENABLE INPUT & OUTPUT OUT (77),A ; OUTPUT TO COMMAND CHANNEL CLBF: LD BC,8000 ; SET BC TO CLEAR BUFFER LD HL,6DF4 ; SET HL TWO AHEAD OF BUFFER LD DE,(BFER) ; SET DE TO START OF BUFFER LDIR ; CLEAR BUFFER RET ; RETURN XOR A ; CLEAR REGISTER A RLOP: LD A,(LASK) ; LOAD A, LAST KEY PRESSED CP 00 ; COMPARE WITH 00 JP NZ,STTX ; JUMP TO STTX IF > 00 IN A,(77) ; GET USART STATUS BIT 1,A ; CHECK IF USART HAS CHR$ JR Z,RLOP ; IF NO CHR$, START OVER IN A,(73) ; GET CHR$ FROM USART CP 08 ; IS IT A DELETE CHR$? JP Z,DELE ; IF YES, JUMP TO DELETE ROUT. CP 0D ; IS IT A (CR)? JR Z,BFST ; IF YES, JUMP FORWARD CP 07 ; IS IT A CTRL "G"? CALL Z,BELL ; IF YES, GOTO BELL ROUTINE CP 80 ; IS THE CHR$ > THAN 80H JR NC,RLOP ; IF NOT PRINTABLE GOTO START CP 20 ; IS THE CHR$ < THAN 20H JR C,RLOP ; IF YES GOTO START BFST: PUSH AF ; SAVE THE CHR$ LD A,(BOPN) ; LOAD A EE01 CP 00 ; CHECK IF BUFFER IS OPEN JR Z,OUCH ; IF NOT, GOTO PRINT ROUTINE PRBF: POP AF ; GET CHR$ CALL PNT1 ; GO SET HL & BC FOR BUFFER LD (HL),A ; LOAD CHR$ INTO BUFFER CPI ; UPDATE HL & BC CALL PNT2 ; GO SAVE HL & BC PUSH AF ; SAVE CHR$ AGAIN JP PE,OUCH ; IF BUFFER NOT FILLED GOTO OUCH XOR A ; CLEAR A REGISTER LD (BOPN),A ; CLOSE BUFFER CALL BELL ; RING BELL TO INDICATE JR OUCH ; NOW GO AND PRINT CHR$ PNT1: LD HL,(PBFR) ; LOAD HL CONTENTS EE04 LD BC,(LBFR) ; LOAD BC CONTENTS EE06 RET ; RETURN PNT2: LD (LBFR),BC ; LOAD EE06 BC LD (PBFR),HL ; LOAD EE04 HL RET ; RETURN OUCH: POP AF ; GET CHR$ AGAIN RST 10H ; PRINT CHR$ TO SCREEN LD A,FFH ; LOAD REG. A WITH 255 LD (SCCT),A ; SET SCROLL COUNT CONTINUDUS XOR A ; CLEAR REGISTER A RET': JR RLOP ; DONE, GOTO START DELE: LD HL,(DFCC) ; LOAD HL ADDRESS DISPLAY FILE DEC HL ; GO BACK ONE SPACE LD (DFCC),HL ; SET DISPLAY BACK ONE SPACE PUSH HL ; SAVE POINTER LD A,20H ; LOAD REG A WITH SPACE CHR$ RST 10H ; PRINT SPACE, ERASE OLD CHR$ POP HL ; GET POINTER BACK IN HL LD (DFCC),HL ; SET DISPLAY FILE POINTER LD A,(BOPN) ; LOAD REG A, EE01 CP 00 ; CHECK IF BUFFER OPEN JR Z,RLOP ; FINISHED IF NOT CALL PNT1 ; IF OPEN, SET HL & BC DEC HL ; SET BUFFER POINTER BACK ONE INC BC ; INCREMENT BUFFER LENGTH CALL PNT2 ; RESAVE EE04 & EE06 XOR A ; CLEAR REGISTER A JR RET' ; RETURN RLOP, TWO HOPS BELL: PUSH AF ; SAVE CHR$ LD DE,00FF ; SET LENGTH OF TONE LD HL,00FF ; SET PITCH OF TONE CALL 03B5 ; CALL ROM BEEP (SINCLAIR) POP AF ; GET CHR$ BACK RET ; DONE, RETURN ; THIS ROUTINE CHECKS FOR CHR$ NORMALY NOT PASSED ; SINCE THEY ARE GREATER THAN 80H OR SMALER THAN 20H. STTX: CP 80 ; UNPRINTABLE CHR$ ? (TOKEN) JR NC,RET: ; RETURN BUT CLEAR KEY FIRST CP 0E ; CS/SS PRESSED ? (CTRL KEY) JR Z,CONV ; GOTO CONVERT ROUTINE CP 0D ; IS IT THE ENTER KEY ? JR Z,OUTX ; GOTO TRANSMITT ROUTINE CP 0C ; DELETE KEY PRESSED ? JR Z,OUTX ; GOTO TRANSMITT ROUTINE CP 20 ; IS IT A SPACE ? JR Z,OUTX ; AGAIN SEND CHR$ JR TXCH ; GOTO TX ROUT. BUT CONV: LD A,(lask) ; GET 2ND KEY PRESS AFTER CS/SS CP 0E ; BUT WAIT FOR 2ND KEY PRESS JR Z,CONV ; LOOP TO WAIT SUB 40H ; SUBTRACT 40H FROM CHR$ CP 20 ; WAS IT A CAPITAL CHR$ ? CALL NC,AGAN ; IF NOT, GO DEDUCT ANOTHER 20H CP 01 ; IS IT THE CHR$ "A" ? RET Z ; IF YES, RETURN TO BASIC CP 02 ; IS IT CHR$ "B" ? CALL Z,CLBF ; IF YES, RESET & CLEAR BUFFER CP 05 ; IS IT CHR$ "E" ? CALL Z,OPEN ; IF YES, GOTO TOGLE THE BFFR. CP 02 ; CHECK FOR CHR$ <03H JR NC,OUTX ; IF NOT, SEND THEM JR RET: ; IF YES, RETURN TXCH: CP 20 ; REJECT CHR$ < THAN 20H JR C,RET: ; RETURN, BUT CLEAR LAST KEY OUTX: PUSH AF ; SAVE CHR$ TO BE SEND XLOP: IN A,(77) ; GET USART STATUS BIT 0,A ; IS USART BUSY ? JR Z,XLOP ; IF YES, LOOP AND WAIT POP AF ; GET CHR$ TO BE SEND TO REMOTE OUT (73),A ; SEND CHR$ TO REMOTE RET: XOR A ; CLEAR REGISTER A LD (lask),A ; LOAD KEY PRESSED WITH 00 LD B,FF ; LOAD REGISTER B=FF DLP1: DJNZ,DLP1 ; DELAY LOOP 255 CYCLES JP RLOP ; NOW RETURN TO START AGAN: SUB 20 ; SUBTRACT 20H AGAIN FROM CHR$ RET ; RETURN OPEN: LD A,(BOPN) ; LOAD REG. "A" BUFFER STATUS CP 00 ; BUFFER CLOSED ?? JR Z,OPN1 ; IF NOT, GO OPEN BUFFER LD A,00H ; LOAD REG "A" 00 TO CLOSE LD (BOPN),A ; CLOSE BUFFER RET ; RETURN TO CONV OPN1: LD A,FF ; LOAD REG "A" 255=FFH LD (BOPN),A ; OPEN BUFFER XOR A ; CLEAR REG "A" RET ; DONE, RETURN TO CONV ``` A bit crude in places, but it works, and if it works, don’t fix it. I probably could have done a few things different, but when I wrote this program, I wasn’t as proficient writing code. Guess we all have to learn, and one way to learn, is, to do it! Start with something simple, and have a book handy which explains the mnemonics. An assembler is a must, most full screen editors & assemblers will do fine, but are a bit complex at times, a real good assembler / disassembler is HOT Z, which one could use to enter the above code. I bought HOT Z second hand from someone who had bought a better computer, poor guy! And I love it. To bad HOT Z is not available for other computers. Reading through the code, you may have noticed, that when pressing Caps Shift & Symbol Shift together, and then pressing the “A” key, this will get you back to basic, while pressing the “B” key after CS/SS, will reset and clear the buffer, pressing the “E” key after CS/SS will togle the buffer either on or off, depending on in which state the buffer is. This will permit you to open the buffer from within the terminal program. If the buffer is togled, no reset or erase is performed, this will let you save some incoming, close the buffer, wait for some other stuffs, and reopen the buffer again to save some more without loosing text you had already saved. I just typed this feature in right now without the aid of an assembler, all I can say is, I hope it works!! Use the clear buffer function to clear the buffer if you wish to do so. Now that I took all the challenge out of adding this, I will give you another! There is no indicator that the buffer is open or closed! You could figure out to put an asterisk somewhere on the screen when the buffer is open, but you would slow the program down if you put it into the present read routine. One way to get out of the slow screen routine in ROM is to write your own routine, which, since you wont need all the checks the ROM routine normally makes, especially after the srceen has filled, will run quite a bit faster. This is a bit of a challenge for a novice to code, maybe you find such a routine somewhere, and are able to incorporate it into the above code. Here now a few lines of basic, which should go along with the code. #### BASIC Listing ``` 10 CLEAR 60927: PAPER 0: BORDER 0: INK 7: CLS 20 LOAD "TERMINAL"CODE 30 INPUT "BAUD RATE * 300/1200 >";B: IF B=300 THEN POKE 60929,79 40 IF B=1200 THEN POKE 60928,78 50 INPUT "BUFFER OPEN (Y/N) ";A$: IF A$="Y" OR A$="y" THEN POKE 60929,255: GO TO 70 60 POKE 60929,0 70 RANDOMIZE USR 60984: RANDOMIZE USR 60984 80 PRINT "DO YOU WISH TO VIEW BUFFER (Y/N)": PAUSE 0: IF INKEY$="N" OR INKEY$="n" THEN STOP 90 PRINT ''"HARDCOPY (Y/N)": PAUSE 0: IF INKEY$="N" OR INKEY$="n" THEN LET A=2: GO TO 110 100 LET A=3 110 FOR X=28150 TO 60918 120 IF PEEK X=0 THEN STOP 130 PRINT #A;CHR$ PEEK X; 140 NEXT X ``` The code has one ROM call, you would have to change the call at location EEC0 if you are planing to use this program with the 2068 in the TIMEX mode, to 03F3. The above program should work with OS64, to give you 64 columns, but you may have to decrease the buffer size !? This can be accomplished, changing the code at EE11 & EE2B from 8000 to whatever number will work. Have fun! Next month I will be in Europe, I hope to have a column ready for the May issue of SMUG BYTES before I leave (something about the QL & TURBO). If not, you will find it in the June issue. #### About this transcription This listing was transcribed from the original scan and checked line by line. The published address column, object-byte column and mnemonics each independently determine the program, so all three were cross-referenced against one another: 147 lines carried both bytes and mnemonics and were fully verified. The following could not be resolved from the available scan and are reproduced as printed: EE3Eh (`JP NZ,STTX` computes to EEC0h, not EEC5h where STTX is defined) and EE50h (`JR Z,BFST` computes to EE52h, not EE5Fh where BFST is defined). Both labels are referenced only once in the excerpt, so nothing else in the article confirms which column is at fault. If you have a cleaner copy of this issue, corrections are welcome.