* VT52/T4010 EMULATOR PROGRAM FOR THE SINCLAIR QL Version 3.53g * (C) S.R.Usher MCMLXXXIX (1st December) * Many thanks to Rob Newson for the code tidying. * Modifications:- * 4/ 1/89 : New version of T4010 produced + other major changes. * a - 7/ 1/89 : Correct T4010 section after checking with BBC micro * and check for errors in graphics cursor positioning. * b - 9/ 1/89 : Fix *FX4 bug and soft key/cursor addressing bug. * c - 11/ 1/89 : Make Alpha only work if graph mode set. * d - 14/ 1/89 : Fix XON turning off bug. * e - 2/ 5/89 : Fix BUFFER FULL redisplay bug. * f - 5/ 9/89 : Add ESC M (delete line) and ESC E (clr/home) VT52 * codes. Also tidy code slightly. Correct the ESC I * code so that it reverse scrolls at top of screen. * g - 1/12/89 : Correct terminal identification code. * * DATA SPACE NEEDED = 27000 Bytes BLOCK EQU TMP_BUF+256 WKSPAC EQU BLOCK+8 B1BAS EQU WKSPAC+134 B1TOP EQU B1BAS+10240 ALT_SCR EQU B1TOP+2 BRA.S START DC.L 0 DC.L $4AFB0029 DC.B 'Term Emulator Vers 3.53g © S.R.Usher 1989' ALIGN START MOVEQ #0,D0 TRAP #1 MOVE.W #$E2,$92(A0) ;Change CTRL-C to CTRL-Capslock MOVEQ #0,D2 ;Set mode to 4 & Monitor MOVEQ #0,D1 MOVEQ #$10,D0 TRAP #1 MOVEQ #11,D0 MOVEQ #-1,D1 MOVEQ #100,D2 TRAP #1 ;Set job priority to 100 SCR_OP LEA SCR1,A0 ;Open main window MOVEQ #1,D0 TRAP #2 MOVE.L A0,D5 ;Put window ID in D5 BSR SCR_CLR LEA SCR2,A0 ;Open Baud window MOVEQ #1,D0 TRAP #2 MOVEQ #-1,D1 MOVE.L #1,D3 LEA WKSPAC,A6 MOVE.L A6,A4 MOVE.L A0,(A4)+ ;Put ID in WKSPAC LEA SCR3,A0 ;Open Duplex window MOVEQ #1,D0 TRAP #2 MOVE.L A0,(A4)+ ;Put ID in WKSPAC+4 MOVEQ #-1,D1 MOVE.L #1,D3 LEA SCR4,A0 ;Open buffer status window MOVEQ #1,D0 TRAP #2 MOVE.L A0,(A4)+ ;Put ID in WKSPAC+8 MOVEQ #-1,D1 MOVE.L #1,D3 CLR.B 117(A6) ;Set Caps variable to 0 LEA SCR6,A0 ;Open Caps window MOVEQ #1,D0 TRAP #2 MOVE.L A0,(A4)+ ;Put ID in WKSPAC+12 MOVEQ #-1,D1 MOVE.L #1,D3 LEA SCR8,A0 ;Open DEL window MOVEQ #1,D0 TRAP #2 MOVE.L A0,(A4)+ ;Put ID in WKSPAC+16 MOVEQ #-1,D1 MOVE.L #1,D3 LEA SCR7,A0 ;Open TAB window MOVEQ #1,D0 TRAP #2 MOVE.L A0,(A4)+ ;Put ID in WKSPAC+20 MOVEQ #-1,D1 MOVE.L #1,D3 LEA SCR9,A0 ;Open HELP window MOVEQ #1,D0 TRAP #2 MOVE.L A0,(A4)+ ;Put ID in WKSPAC+24 MOVEQ #-1,D1 MOVE.L #1,D3 LEA SCR10,A0 ;Open CURS window MOVEQ #1,D0 TRAP #2 MOVE.L A0,(A4)+ ;Put ID in WKSPAC+28 MOVEQ #-1,D1 MOVE.L #1,D3 LEA SCR11,A0 ;Open XON window MOVEQ #1,D0 TRAP #2 MOVE.L A0,(A4)+ ;Put ID in WKSPAC+32 * Set up default values * --------------------- SET_DEF LEA WKSPAC,A6 MOVE.W #5,100(A6) ;Set Baud display to 2400 MOVE.W #2400,110(A6) ;BAUD rate to 2400 MOVE.W #0,114(A6) ;HDX ESC Off MOVE.B #1,116(A6) ;Buffer status Ok MOVE.B #1,118(A6) ;DEL flag On MOVE.B #1,119(A6) ;XON flag On MOVE.B #0,120(A6) ;CURS Off MOVE.B #1,121(A6) ;TAB On CLR.B 133(A6) ;HDX Off BSR LOAD_DEF MOVEQ #-1,D1 MOVE.L #1,D3 BSR REFRSH SER_OP BSR SEROP TST.B D0 BNE ST_PROG MOVE.W 110(A6),D1 MOVEQ #$12,D0 TRAP #1 ;Set Baud rate MOVE.L D5,A0 ;Load screen ID into A0 MOVEQ #0,D3 MOVEQ #$20,D0 TRAP #3 ;Clear Screen CUR_POS MOVEQ #0,D1 MOVEQ #0,D2 MOVEQ #0,D3 MOVE.L D5,A0 MOVEQ #16,D0 TRAP #3 ;Put cursor at top left of screen MOVEQ #0,D2 MOVEQ #0,D3 MOVE.L D5,A0 MOVEQ #45,D0 TRAP #3 ;Set character size to 1 CPY_RIT BSR RIT_MSG ;Write start up msg to screen CUR_ON MOVEQ #0,D3 MOVE.L D5,A0 MOVEQ #14,D0 TRAP #3 ;Turn on cursor BUF_SET BSR KEY_RED BSR BUF_INI TST.W D1 BEQ BUF_SET LEA B1BAS,A4 MAIN_LP BSR GET_BYT CMP.B #' ',D6 ;Test if control character BLT CTR_DEC ;if so then branch to decoding CMP.B #127,D6 ;subroutine BEQ CTR_DEC ETC_TST BSR KEY_RED ;Read keyboard again BSR RD_SER ;Read Serial port MOVEQ #0,D1 MOVE.B D6,D1 MOVEQ #0,D3 MOVE.L D5,A0 ;Put main screen ID in A0 MOVEQ #5,D0 TRAP #3 ;Send character to screen CMP.L #-1,D0 ;Test if not complete error BNE RETURN1 ;if not then branch to RETURN1 BSR CTRL_F5 ;else branch to CTRL_F5 subroutine RETURN1 TST.B 60(A6) BNE RETURN2 BRA MAIN_LP ;Branch to start of main loop $INCLUDE FLP2_T4010_ASM CTRL_F5 BSR RD_SER ;Read serial port MOVE.B D6,D1 MOVE.L D5,A0 MOVEQ #5,D0 TRAP #3 ;Try to send character to screen CMP.L #-1,D0 BEQ CTRL_F5 ;If not complete error, then goto start RTS ;else return BUF_INI CMP.B #1,116(A6) ;Test if addr of buf var set BEQ SK_INWR ;If not then skip routine INWR BSR S_XON ;Send X-ON character to host MOVE.L 8(A6),A0 ;Chan ID of buffer status window in A0 BSR CLS ;Clear the window LEA BUF_OK,A1 MOVE.W #19,D2 BSR WRITE ;Write OK message to it MOVE.B #1,(A5) ;Reset buffer variable SK_INWR MOVEQ #0,D1 ;Reset buffer MOVE.W #10240,D2 MOVE.L #10240,A5 MOVEQ #0,D3 MOVE.L D4,A0 LEA B1BAS,A1 MOVEQ #2,D0 TRAP #3 ;Read serial port MOVE.L A1,A2 RTS ;Return S_XON TST.B 119(A6) ;Test if XON variable set ON LEA 116(A6),A5 ;Put address of buffer variable in A5 BEQ END_XON ;If XON variable set OFF then goto end MOVE.B #1,(A5) ;Reset buffer variable MOVEQ #17,D1 MOVE.L D4,A0 MOVEQ #5,D0 TRAP #3 ;Send X-ON character to serial port END_XON RTS ;Return RD_SER CMP.L #1024,A5 ;Test if buffer has less than 1k free BLT NO_SER ;if so then goto NO_SER CMP.L #4096,A5 ;Test if buffer has more than 4k free BGT SK_XOFF ;if not then call S(end)_XOFF routine BSR S_XOFF SK_XOFF LEA B1TOP,A3 ;Calculate space left in buffer MOVE.L A2,A1 SUB.L A1,A3 MOVE.L A3,A5 MOVE.L A3,D2 MOVEQ #0,D3 MOVE.L D4,A0 MOVE.L A2,A1 MOVEQ #2,D0 ;Read serial port TRAP #3 MOVE.L A1,A2 ;Put updated base of buffer into A2 END_SER RTS ;Return NO_SER CMP.B #3,116(A6) ;Test if buffer full set to FULL BEQ END_SER ;if so then jump to end of routine MOVE.B #3,116(A6) ;Set buffer variable to FULL MOVE.L 8(A6),A0 ;Load channel ID of window into A0 BSR CLS ;Clear the window MOVE.W #19,D2 LEA BUF_FUL,A1 BSR WRITE ;Write buffer full message to it BRA END_SER ;branch to end of serial port read rout S_XOFF TST.B 119(A6) ;Test if XON not set then return BEQ EN_XOFF CMP.B #1,116(A6) ;Test if buffer var set then return BGT EN_XOFF MOVE.B #2,116(A6) ;Set buffer variable to 2/3 MOVE.L 8(A6),A0 ;Load chan ID of buffer window into A0 BSR CLS ;Clear window MOVE.W #19,D2 LEA BUF_NER,A1 BSR WRITE ;Write buffer 2/3 message to it MOVE.L D4,A0 ;Load serial port ID into A0 MOVEQ #19,D1 MOVEQ #5,D0 ;Send X-OFF character to serial port TRAP #3 EN_XOFF RTS ;Return CTR_DEC BSR CTR_ROU ;Call control code decode subroutine CLR.B 114(A6) ;Unset HDX ESCape code variable BRA RETURN1 ;Return to main loop CTR_ROU BSR RD_SER ;Read serial port CMP.B #27,D6 ;Test if ESCape code BEQ ESC_DEC ;and branch to decode routine MOVE.B D6,D1 ;Make copy of character in D1 CMP.B #10,D1 ;Test if linefeed BNE CTR_1 ;if not then jump routine LINEFED MOVE.L D5,A0 ;Load main screen ID into A0 MOVEQ #0,D3 MOVEQ #22,D0 ;Move cursor down a line TRAP #3 CMP.B #-4,D0 ;Test if off screen BNE CTR_RET ;if not then return BSR SCROLL ;else scroll up a line RTS ;return SCROLL MOVE.L D1,D7 ;Save D1 in D7 MOVEQ #-10,D1 ;Scroll screen up 10 pixels MOVEQ #24,D0 TRAP #3 MOVE.L D7,D1 ;Put value back into D1 RTS ;Return CTR_1 CMP.B #13,D1 ;Test if CR if so then branch to BEQ CR ;routine CMP.B #7,D1 ;Test if BELL character BEQ BELL CMP.B #8,D1 ;Test if BACKSPACE character BEQ BACK_SP CMP.B #9,D1 ;Test if TAB character BEQ TAB CMP.B #12,D1 ;Test if → character BEQ FWD CMP.B #11,D1 ;Test if Reverse LF character BEQ UP_ROW CMP.B #127,D1 ;Test if DEL character BEQ DEL CMP.B #$1D,D1 ;GS BEQ DK_VECT CMP.B #$1F,D1 ;US BEQ ALPHA CMP.B #$1C,D1 ;FS BEQ ALPHA CMP.B #$1E,D1 ;RS BEQ ALPHA CTR_RET RTS ;Return GET_BYT MOVEQ #0,D3 CMPI.L A4,A2 ;Test buffer to see if empty BGT GET_JP1 ;if not then jump to ESC_DCO GET_JP0 BSR KEY_RED ;Read keyboard BSR BUF_INI ;Initialise buffer TST.W D1 ;if no characters in buffer then BEQ GET_JP0 ;repeat from ESC_DE0 LEA B1BAS,A4 ;Put buffer base into A4 SUB.L A3,A3 ;Clear A3 GET_JP1 BSR KEY_RED MOVE.B (A4)+,D6 ;Put a byte from the buffer into D6 BCLR #7,D6 ;Clear bit 7 RTS ESC_DEC CMP.B #-1,114(A6) ;Test HDX, Branch to spec code if set BEQ HDX_ESC BSR GET_BYT TST.B D6 ;Test if character is zero, DEL or ESC BEQ ESC_DEC ;if so then get another byte CMP.B #127,D6 BEQ ESC_DEC CMP.B #27,D6 BEQ ESC_DEC HDX_ENT SUB.L A3,A3 ;Clear A3 CMP.B #'A',D6 ;Test if character is A & branch if BEQ UP_ROW ;so CMP.B #'I',D6 ;Test if character is I & branch if so BEQ REV_LF CMP.B #'B',D6 ;Test if character is B BEQ LINEFED CMP.B #'C',D6 ;Test if character is C BEQ FWD CMP.B #'D',D6 ;Test if character is D BEQ BACK_SP CMP.B #'E',D6 ;Test if character is E BEQ CLS_HOM CMP.B #12,D6 ;Test if character is FF BEQ CLS_HOM CMP.B #'H',D6 ;Test if character is H BEQ HOME CMP.B #'J',D6 ;Test if character is J BEQ CLS_EOS CMP.B #'K',D6 ;Test if character is K BEQ EOL CMP.B #'L',D6 ;Test if character is L BEQ SFT_SER CMP.B #'M',D6 ;Test if character is M BEQ DEL_LIN CMP.B #'Y',D6 ;Test if character is Y BEQ CUR_ADR CMP.B #'Z',D6 ;Test if character is Z BEQ TERM_ID CMP.B #$1D,D6 ;Test if character is GS BEQ DK_VECT CMP.B #$1F,D6 ;Test if character is US BEQ ALPHA CMP.B #$18,D6 ;Test if character is CAN BEQ BYPASS CMPI.L A4,A2 ;Test if buffer empty BNE ESC_BAC ;if not then return BSR BUF_INI ;else initialise it LEA B1BAS,A4 ESC_BAC RTS ;return SFT_SER MOVE.L D5,A0 ;Load screen ID into A0 MOVEQ #0,D3 MOVEQ #0,D1 MOVEQ #$2C,D0 TRAP #3 MOVEQ #7,D1 ;Set default ink to white CMP.B 62(A6),D1 ;Test if ink should be white BEQ WHT_TXT MOVEQ #4,D1 ;if not set ink to green WHT_TXT MOVEQ #$28,D0 ;Change strip to colour TRAP #3 MOVEQ #0,D1 MOVEQ #$29,D0 ;Change ink to black TRAP #3 LEA TMP_BUF,A3 MOVE.L #255,D7 SFT_LP1 BSR CHK_BUF ;Check SER buffer and read it MOVE.L D5,A0 ;Load screen ID into A0 MOVE.B (A4)+,D6 ;Load character into D6 BCLR #7,D6 ;Clear bit 7 MOVE.B D6,(A3)+ ;Put it into TMP_BUFfer CMP.B #$0D,D6 ;Test if CR BEQ ESFTLP1 ;if so then exit loop MOVE.B D6,D1 ;Put copy into D1 MOVEQ #5,D0 ;Print it on the screen TRAP #3 DBRA D7,SFT_LP1 ;Go back round the loop ESFTLP1 MOVEQ #0,D1 MOVEQ #17,D0 ;Do a Carriage Return TRAP #3 MOVEQ #0,D1 ;Reset all the colours MOVEQ #$28,D0 TRAP #3 MOVEQ #4,D1 CMP.B #7,62(A6) BNE CH_KEY MOVEQ #1,D1 MOVEQ #$2C,D0 TRAP #3 MOVEQ #7,D1 CH_KEY MOVEQ #$29,D0 TRAP #3 LEA TMP_BUF,A3 ;Load TMP_BUF address into A3 MOVE.B (A3)+,D6 ;Load first character into D6 CMP.B #'*',D6 ;Test if * BNE ESC_BAC ;if not then return MOVE.B (A3)+,D6 ;Load second character into D6 CMP.B #'F',D6 ;Test if F BEQ FX_CMD ;if so then goto FX_CMD CMP.B #'K',D6 ;Test if K BNE ESC_BAC ;if not then return MOVEQ #0,D6 ;Clear D6 KEY_LP1 MOVE.B (A3)+,D6 ;Load next character into D6 CMP.B #$0D,D6 ;Test if CR BEQ ESC_BAC ;if so then return CMP.B #' ',D6 ;Test if space BEQ KEY_LP1 ;if so then goto start of loop CMP.B #'E',D6 ;Test if E BEQ KEY_LP1 ;if so then go round loop again CMP.B #'Y',D6 ;Test if Y BEQ KEY_LP1 ;if so then go round loop again BSR VAL_DEC ;Decode ASCII to value in D0 CMP.L #15,D0 ;Test if GT 15 BGT ESC_BAC ;if so then return TST.L D0 ;Test if negative BLT ESC_BAC ;if so then return KEY_LP2 CMP.B #' ',D6 ;Test if next character Space BNE EKY_LP2 ;if not then exit loop MOVE.B (A3)+,D6 ;Next character into D6 BRA KEY_LP2 ;go back round loop EKY_LP2 LEA KEY_DEF,A0 ;Calculate Key definition address MULU #256,D0 ADD.L D0,A0 MOVE.L A0,122(A6) ;and place it in WKSPAC+122 LEA TMP_BUF,A0 ;Rewrite rest of input string into MOVEQ #0,D1 ;TMP_BUF starting at TMP_BUF MOVEQ #0,D7 KEY_LP3 MOVE.B D6,(A0)+ ;Counting the number of characters ADD.W #1,D1 ;until CR code found MOVE.B D6,D7 MOVE.B (A3)+,D6 CMP.B #$0D,D7 BNE KEY_LP3 SUB.W #1,D1 ;Subtract one from number of charaters LEA TMP_BUF,A1 BSR STR_DEC ;Decode string ( |- CTRL char ) MOVE.L 122(A6),A0 ;Load Key definition address into A0 MOVE.B D1,(A0) ;Save D1 in (A0) MOVEQ #0,D1 ;Clear D1, just in case MOVE.B (A0)+,D1 ;Reload it and increment A0 LEA TMP_BUF,A1 KEB_LP MOVE.B 0(A1,D1),0(A0,D1);Move string from TMP_BUF to key def DBLT D1,KEB_LP MOVE.L D5,A0 ;Clear registers MOVEQ #0,D0 MOVEQ #0,D1 MOVEQ #0,D2 MOVEQ #0,D3 MOVEQ #0,D6 MOVE.L D0,A1 MOVE.L A1,A3 RTS ;Return FX_CMD MOVEQ #0,D6 ;Clear D6 MOVE.B (A3)+,D6 ;Load character into D6 CMP.B #'X',D6 ;Test if X BEQ FX_CMD ;if so then go back around loop CMP.B #' ',D6 ;Test if Space BEQ FX_CMD ;if so then go back round loop BSR VAL_DEC ;Decode ASCII into value in D0 CMP.B #4,D0 ;Test if returned value is 4 BEQ FX4_LP ;if so then goto FX4_LP CMP.B #153,D0 ;Test if returned value is 153 BEQ FX53_LP ;if so then goto FX53_LP CMP.B #138,D0 BEQ FX53_LP RTS ;Else return FX4_LP MOVE.B (A3)+,D6 ;Load next character into D6 CMP.B #' ',D6 ;Test if Space BEQ FX4_LP ;if so then go back round loop CMP.B #',',D6 ;Test if , BEQ FX4_LP ;if so then go back round loop CMP.B #'0',D6 ;Test if not number BLT ESC_BAC CMP.B #'9',D6 BGT ESC_BAC ;if not then return MOVE.B D6,D1 ;Copy character into D1 BSR VAL_DEC ;Decode ASCII into value in D0 CMP.B #2,D0 ;Test if GT 2 BGT ESC_BAC ;if so then return TST.B D0 ;Test if negative BLT ESC_BAC ;if so then return MOVE.B D0,120(A6) ;Change CURS variable to value BSR S_RFSH ;Refresh status line RTS ;return FX53_LP MOVE.B (A3)+,D6 ;Load next character into D6 CMP.B #' ',D6 ;Test if Space BEQ FX53_LP ;if so then go back round loop CMP.B #',',D6 ;Test if , BEQ FX53_LP ;if so then go back round loop CMP.B #'0',D6 ;Test if not number BLT ESC_BAC CMP.B #'9',D6 BGT ESC_BAC ;if not then return MOVE.B D6,D1 ;Copy character into D1 BSR VAL_DEC ;Decode ASCII into value in D0 TST.B D0 ;Test if returned value zero BNE ESC_BAC ;if not then return FX53_L2 MOVE.B (A3)+,D6 ;Load next character into D6 CMP.B #' ',D6 ;Test if Space BEQ FX53_L2 ;if so then go back round loop CMP.B #',',D6 ;Test if , BEQ FX53_L2 ;if so then go back round loop CMP.B #'0',D6 ;Test if not number BLT ESC_BAC CMP.B #'9',D6 BGT ESC_BAC ;if not then return MOVE.B D6,D1 ;Copy character into D1 BSR VAL_DEC ;Decode ASCII into value in D0 LEA TMP_BUF,A0 MOVEQ #0,D2 TST.B D0 ;Test if returned number >128 BPL JMP_DEC ;if not then jump over routine CMP.B #143,D0 ;Test if returned number >143 BGT ESC_BAC ;if so then return MOVE.B #255,(A0)+ SUB.B #80,D0 ADDQ.W #1,D2 JMP_DEC MOVE.B D0,(A0) ADDQ.W #1,D2 LEA TMP_BUF,A1 BSR SFT_OUT RTS VAL_DEC MOVEQ #0,D0 ;Clear D0 VAL_LP CMP.B #'0',D6 ;Test if D6 is a number BLT EVAL CMP.B #'9',D6 BGT EVAL ;if not then return SUB.B #'0',D6 ;Subtract $30 (change into value) MULU.W #10,D0 ;Multiply D0 by 10 ADD.W D6,D0 ;Add value to D0 MOVE.B (A3)+,D6 ;Load next char into D6 BRA VAL_LP ;goto start of loop EVAL RTS ;Return CHK_BUF CMP.L A4,A2 ;Test if any more chars in buffer BNE END_CHK ;if so then return CHK_LP BSR KEY_RED ;read keyboard BSR BUF_INI ;initiate buffer TST.W D1 ;test if any chars read in BEQ CHK_LP ;if not then goto start of loop LEA B1BAS,A4 ;reset buffer position counter END_CHK RTS ;return KEY_RED BSR KEY_RD ;Read keyboard TST.B D1 ;Test if byte read BNE CONT ;If so then continue RTS ;else return CONT CMP.B #194,D1 ;Test if CTRL Left BEQ DELETE ;if so branch to delete CMP.B #10,D1 ;Test if ENTER BEQ CARET ;if so then branch to CARET CMP.B #255,D1 ;Test if ALT BEQ ALT_TRAP ;if so then branch to ALT_TRAP CMP.B #232,D1 ;Test if F1 BEQ F1_TRAP ;if so then branch to F1_TRAP CMP.B #244,D1 ;Test if F4 BEQ REFRSH ;if so then branch to REFRSH CMP.B #236,D1 ;Test if F2 BEQ SFT_KBD ;if so then branch to SFT_KeyBoard Def CMP.B #240,D1 ;Test if F3 BEQ SAV_DEF ;if so then branch to SAVe DEFaults CMP.B #248,D1 ;Test if F5 BEQ OVER_0 ;if so then goto set OVER_0 CMP.B #200,D1 ;Test if Right BEQ RIGHT CMP.B #192,D1 ;Test if Left BEQ LEFT CMP.B #208,D1 ;Test if Up BEQ UP CMP.B #216,D1 ;Test if Down BEQ DOWN CMP.B #220,D1 ;Test if SHIFT Down BEQ LF CMP.B #217,D1 ;Test if ALT Down BEQ ALT_DOW OUT_CH MOVE.L D4,A0 ;Put serial port ID in A0 MOVEQ #0,D3 MOVEQ #5,D0 TRAP #3 ;Send byte to serial port ESC_HDX TST.B 133(A6) ;Test if HDX flag set BNE.S HDX ;If so then branch to HDX routine KEY_END RTS ;Return HDX MOVE.B #-1,114(A0) ;Set HDX ESCape variable MOVE.L D5,A0 ;Put main screen ID in A0 MOVE.B D1,D6 ;Save character in D6 CMP.B #' ',D1 ;Test if control character BLT HDX_CTR ;and branch to decode routine if so CMP.B #127,D1 BEQ HDX_CTR BSR PRINT ;Print character on screen RTS ;Return HDX_CTR CMP.B #27,D1 ;Test if character is ESC BEQ HDX_ESC ;if so then branch to decode routine BSR CTR_ROU ;Call control code decode routine RTS ;Return HDX_ESC MOVEQ #1,D0 ;Read byte from keyboard TRAP #3 CMP.B #-1,D0 ;If none then read keyboard again BEQ HDX_ESC ;until character found MOVE.B D1,D6 ;move character to D6 TST.B D6 ;Test if character is Zero, DEL or ESC BEQ HDX_ESC ;if so then read another character from CMP.B #127,D6 ;keyboard BEQ HDX_ESC CMP.B #27,D6 BEQ HDX_ESC CMP.B #'L',D6 BEQ ESC_BAC BRA HDX_ENT ;Branch to ESCape code decode routine CUR_HDX MOVEQ #1,D0 ;Fetch byte from keyboard TRAP #3 CMP.B #-1,D0 ;If none fetched, then retry BEQ CUR_HDX MOVE.B D1,D6 ;Save character in D6 TST.B D6 ;Test if it is Zero, DEL or ESC BEQ CUR_HDX ;if so then fetch another character CMP.B #127,D6 BEQ CUR_HDX CMP.B #' ',D6 ;Test if control character BLT CTR_RET ;if so then return CLR.W D7 ;Clear D7 MOVE.B D6,D7 ;Move character to D7 and subtract 32 SUB.B #' ',D7 BUG_HDX MOVEQ #1,D0 ;Fetch another byte from keyboard TRAP #3 CMP.B #-1,D0 BEQ BUG_HDX TST.B D6 BEQ BUG_HDX CMP.B #' ',D6 ;Check if it is a control character BLT CTR_RET ;if so then return CLR.W D2 ;Clear D2 and put character in it MOVE.W D6,D2 SUB.B #' ',D2 ;Subtract 32 MOVE.W D2,D1 ;Move answer to D1 MOVE.W D7,D2 ;Move D7 (first byte-32) to D2 MOVEQ #0,D3 MOVE.L D5,A0 ;Put screen channel ID in A0 MOVEQ #$10,D0 TRAP #3 ;Position cursor at D2,D1 MOVEQ #0,D1 ;Clear D1 MOVE.L D1,D0 ;Clear D0 RTS ;Return KEY_RD MOVEQ #0,D0 ;Read system info so as to get pointer TRAP #1 ;to system variables LEA $88(A0),A1 ;Load address of SV.CAPS in A1 MOVE.L 12(A6),A0 ;Put Caps window ID in A0 TST.B (A1) ;Test SV.CAPS BNE CAP_ON ;if on then jump to CAP_ON TST.B 117(A6) ;if Caps set off then goto RD_CONT BEQ RD_CONT CLR.B 117(A6) ;Set Caps variable off BSR CLS ;Clear window LEA CAP_OFF,A1 MOVE.W #9,D2 BSR WRITE ;Write Caps off message to window BRA RD_CONT ;Goto RD_CONT CAP_ON CMP.B #1,117(A6) ;if Caps set on then goto RD_CONT BEQ RD_CONT MOVE.B #1,117(A6) ;Set caps variable on BSR CLS ;Clear window LEA CAPS_ON,A1 MOVE.W #9,D2 BSR WRITE ;Write Caps on message to window RD_CONT MOVE.L D5,A0 ;Load screen channel ID into A0 MOVEQ #0,D3 ;Clear D3 MOVEQ #1,D0 MOVEQ #0,D1 TRAP #3 ;Read a byte from the keyboard RTS ;Return CR MOVE.L D1,D7 ;Save D1 in D7 MOVE.L D5,A0 ;Load screen channel ID into A0 MOVEQ #0,D3 MOVEQ #0,D1 MOVEQ #17,D0 TRAP #3 ;Put cursor at beginning of line MOVE.L D7,D1 ;put value back into D1 BRA NORM BACK_SP MOVEQ #0,D3 MOVE.L D5,A0 MOVEQ #19,D0 TRAP #3 ;Move cursor back one character RTS ;Return FWD MOVEQ #0,D3 MOVE.L D5,A0 ;Load screen ID into A0 MOVEQ #$14,D0 TRAP #3 ;Move cursor one character forward CMP.B #-4,D0 ;Test if off screen BEQ NEWLINE ;if so then do a newline RTS ;Return TAB LEA 120(A6),A1 ;Test Curs variable TST.B (A1)+ BEQ FWD ;if unset then goto FWD TST.B (A1) ;Test Tab variable BEQ FWD ;if unset then goto FWD MOVE.L D5,A0 ;Load screen ID into A0 LEA BLOCK,A1 ;Load address of enquiry block into A1 MOVEQ #$B,D0 TRAP #3 ;Get cursor position into enquiry block LEA BLOCK+4,A1 ;Put X position into D1 and divide by 8 MOVE.W (A1),D1 DIVU #8,D1 ADD.W #1,D1 ;Add one to the answer and times by 8 MULU #8,D1 MOVEQ #$11,D0 TRAP #3 ;Move cursor to this column CMPI #-4,D0 ;Test if off screen BNE EN_TAB ;if not then return BSR NEWLINE ;Call NEWLINE subroutine EN_TAB RTS ;Return NEWLINE MOVEQ #18,D0 ;Force a NEWLINE TRAP #3 CMP.B #-4,D0 ;Test if off screen BEQ S_NL ;if so then goto S_NL RTS ;Return S_NL BSR SCROLL ;Scroll the screen 10 pixels up MOVEQ #0,D1 MOVEQ #$11,D0 TRAP #3 ;Move cursor to left side of screen RTS ;Return UP_ROW MOVE.L D5,A0 ;Move screen ID in A0 MOVEQ #0,D3 MOVEQ #21,D0 TRAP #3 ;Move cursor up a row RTS ;Return REV_LF MOVE.L D5,A0 ;Move screen ID in A0 MOVEQ #0,D3 MOVEQ #21,D0 TRAP #3 ;Move cursor up a row TST.W D0 ;Test if error BEQ END_LF MOVEQ #10,D1 ;if so then scroll window down by one MOVEQ #$18,D0 ;line. TRAP #3 END_LF RTS ;Return DEL CMP.B #-1,118(A6) ;Test DEL variable BEQ CTR_RET ;If unset then return BSR BACK_SP ;Backspace MOVEQ #' ',D1 MOVEQ #0,D3 BSR PRINT ;Print a SPACE BSR BACK_SP ;Backspace RTS CUR_ADR CMP.B #-1,114(A6) ;Test HDX ESCape variable BEQ CUR_HDX ;if set then goto CUR_HDX routine CMPI.L A4,A2 ;Check if buffer empty BNE CUR_ACO ;if not then jump to CUR_ACO CUR_AD0 BSR KEY_RED ;Read keyboard BSR BUF_INI ;Initialise buffer TST.W D1 ;Test if any characters read in BEQ CUR_AD0 ;if not then repeat from CUR_AD0 LEA B1BAS,A4 ;Put buffer base in A4 SUBA.L A3,A3 CUR_ACO MOVE.B (A4)+,D6 ;Read character into D6 BCLR #7,D6 ;Clear bit 7 TST.B D6 ;Test if Zero, DEL or ESC BEQ CUR_ADR ;if so then get new character CMP.B #127,D6 BEQ CUR_ADR CMP.B #' ',D6 ;If character less than 32 then return BLT CTR_RET CLR.W D7 ;Clear D7 MOVE.B D6,D7 ;Save character in D7 and subtract 32 SUB.B #' ',D7 BUG CMPI.L A4,A2 ;Test if buffer empty BNE CUR_AC1 ;if not then jump to CUR_AC1 CUR_AD1 BSR KEY_RED ;Read keyboard BSR BUF_INI ;Initialise buffer TST.W D1 ;Check if any characters read in BEQ CUR_AD1 ;if not then repeat from CUR_AD1 LEA B1BAS,A4 ;Load buffer base into A4 SUB.L A3,A3 CUR_AC1 MOVE.B (A4)+,D6 ;Read byte from buffer BCLR #7,D6 ;Clear bit 7 TST.B D6 ;Test if Zero, DEL or ESC BEQ BUG ;if so then read another byte CMP.B #' ',D6 ;Test if byte less than 32 BLT CTR_RET ;if so then return CLR.W D2 ;Clear D2 MOVE.W D6,D2 ;Move byte to D2 and subtract 32 SUB.B #' ',D2 MOVE.W D2,D1 ;Move byte to D1 MOVE.W D7,D2 ;Move first byte to D2 MOVEQ #0,D3 MOVE.L D5,A0 ;Load screen ID into A0 MOVEQ #$10,D0 TRAP #3 ;Move cursor to D2,D1 MOVEQ #0,D1 ;Clear D1 MOVEQ #0,D0 ;Clear D0 RTS ;Return OVER_0 MOVE.B #4,62(A6) MOVE.L D5,A0 MOVEQ #0,D1 MOVEQ #0,D3 MOVEQ #$2C,D0 TRAP #3 MOVEQ #4,D1 MOVEQ #$29,D0 TRAP #3 RTS ALPHA TST.B 60(A6) BGE EALPHA BSR NORM LEA GCUR1,A1 MOVE.W (A1)+,D1 MOVE.W (A1),D2 MULU #100,D1 MULU #100,D2 DIVU #234,D1 DIVU #308,D2 SUB.L #240,D2 NEG.L D2 SUB.W #13,D2 TST.W D2 BGE ALPHSK MOVEQ #0,D2 ALPHSK ADD.W #19,D1 MOVEQ #0,D3 MOVE.L D5,A0 MOVEQ #$17,D0 TRAP #3 CMP.B #-4,D0 BNE EALPHA MOVEQ #0,D1 MOVEQ #0,D2 MOVEQ #$10,D0 TRAP #3 EALPHA RTS BYPASS MOVE.W #1,60(A6) RTS DK_VECT TST.B 114(A6) BNE CTR_RET MOVE.L D5,A0 MOVEQ #0,D3 MOVEQ #1,D1 MOVEQ #$2C,D0 TRAP #3 MOVEQ #7,D1 MOVEQ #$29,D0 TRAP #3 LEA 60(A6),A1 MOVE.W #-1,(A1)+ MOVE.B #7,(A1) BSR CORD_DE LEA GCUR1,A1 LEA GCUR2,A3 MOVE.L (A3),(A1) RTS NORM CLR.W 60(A6) RTS TERM_ID MOVEQ #27,D1 ;Send ESC to serial port BSR OUT_CH MOVEQ #'/',D1 ;Send / to serial port BSR OUT_CH MOVEQ #'K',D1 ;Send K to serial port BSR OUT_CH RTS ;Return CLS_HOM MOVEQ #0,D3 MOVE.L D5,A0 ;Load screen ID into A0 BSR CLS ;Clear screen MOVEQ #14,D0 TRAP #3 ;Turn Cursor on RTS ;Return CLS MOVEQ #15,D0 ;Turn Cursor off TRAP #3 MOVEQ #0,D1 MOVEQ #0,D2 MOVEQ #16,D0 TRAP #3 ;Set cursor to top left of window MOVEQ #32,D0 TRAP #3 ;Clear window CMP.L D5,A0 BNE.S EX_CLS LEA GCUR1,A0 ;Load A0 with the address of the MOVE.L #$000002FF,(A0)+;Graphics Cursor and clear it MOVE.L #$000002FF,(A0) MOVE.L D5,A0 ;Restore ID in A0 EX_CLS RTS ;Return HOME MOVEQ #0,D3 MOVEQ #0,D1 MOVEQ #0,D2 MOVE.L D5,A0 ;Load screen ID into A0 MOVEQ #16,D0 TRAP #3 ;Move cursor to top left of screen RTS ;Return CLS_EOS BSR EOL ;Clear to end of line MOVEQ #34,D0 TRAP #3 ;Clear from cursor line down RTS ;Return EOL MOVE.L D5,A0 ;Load screen ID into A0 MOVEQ #0,D3 MOVEQ #36,D0 TRAP #3 ;Clear to end of line RTS ;Return DEL_LIN MOVEQ #0,D3 ;Move cursor to beginning of line MOVEQ #0,D1 MOVEQ #$11,D0 TRAP #3 MOVEQ #$15,D0 ;Move cursor to line above TRAP #3 MOVEQ #-10,D1 ;Scroll bottom part of screen up one MOVEQ #$1A,D0 ;line (10 pixels) TRAP #3 MOVEQ #$16,D0 ;Move cursor back to the original line TRAP #3 RTS ;Return BORDER BSR CLS ;Clear window MOVEQ #2,D1 MOVE.W #1,D2 MOVEQ #$C,D0 TRAP #3 ;Put border around it MOVEQ #-1,D1 MOVE.L #1,D3 RTS ;Return PRINT MOVEQ #5,D0 ;Send byte to channel TRAP #3 CMP.B #-4,D0 ;If off screen then BEQ NL ;Do a NEWLINE RTS ;Return NL BSR NEWLINE ;Call NEWLINE routine BRA PRINT ;Go back to PRINT BELL MOVEQ #$11,D0 LEA SOUND_E,A3 MOVE.L D5,A5 ;Save Screen ID in A5 temporarily TRAP #1 ;Stop any pending sound LEA SOUND_P,A3 MOVEQ #$11,D0 TRAP #1 ;Tell IPC to start sound MOVE.L A5,D5 ;Replace Screen ID in D5 CLR.L D7 ;Clear D7 RTS ;Return DELETE MOVEQ #127,D1 ;Change character to DEL BRA OUT_CH ;Return RIGHT CMP.B #1,120(A6) ;if CURS set then branch to ERIGHT BEQ ERIGHT CMP.B #2,120(A6) BEQ SRIGHT MOVEQ #9,D1 ;Change character to chr$(9) BRA OUT_CH ;Return ERIGHT MOVE.L D4,A0 ;load serial port ID into A0 LEA RIGH_ES,A1 MOVE.W #2,D2 BSR WRITE ;Write ESC C to serial port MOVEQ #12,D1 ;Change character to chr$(12) BRA ESC_HDX ;Branch to ESC_HDX SRIGHT MOVE.L D4,A0 MOVEQ #0,D2 LEA KEY_DEF+3328,A1 ;PF 13 MOVE.B (A1)+,D2 BSR WRITE RTS LEFT CMP.B #1,120(A6) ;As above except BEQ ELEFT CMP.B #2,120(A6) BEQ SLEFT MOVEQ #8,D1 ;Change character to chr$(8) BRA OUT_CH ELEFT MOVE.L D4,A0 LEA LEFT_ES,A1 MOVE.W #2,D2 BSR WRITE ;Write ESC D to serial port MOVEQ #8,D1 BRA ESC_HDX SLEFT MOVE.L D4,A0 MOVEQ #0,D2 LEA KEY_DEF+3072,A1 ;PF 12 MOVE.B (A1)+,D2 BSR WRITE RTS UP CMP.B #1,120(A6) BEQ EUP CMP.B #2,120(A6) BEQ SUP MOVEQ #$0B,D1 ;Change character to chr$(11) BRA OUT_CH EUP MOVE.L D4,A0 LEA UP_ES,A1 MOVE.W #2,D2 BSR WRITE ;Write ESC A to serial port MOVEQ #$0B,D1 BRA ESC_HDX SUP MOVE.L D4,A0 MOVEQ #0,D2 LEA KEY_DEF+3840,A1 ;PF 15 MOVE.B (A1)+,D2 BSR WRITE RTS DOWN CMP.B #1,120(A6) BEQ EDOWN CMP.B #2,120(A6) BEQ SDOWN MOVEQ #$0A,D1 ;Change character to chr$(10) BRA OUT_CH EDOWN MOVE.L D4,A0 LEA DOWN_ES,A1 MOVE.W #2,D2 BSR WRITE ;Write ESC B to serial port MOVEQ #$0A,D1 BRA ESC_HDX SDOWN MOVE.L D4,A0 MOVEQ #0,D2 LEA KEY_DEF+3584,A1 ;PF 14 MOVE.B (A1)+,D2 BSR WRITE RTS ALT_DOW MOVE.L D4,A0 MOVEQ #0,D2 LEA KEY_DEF+2816,A1 ;PF 11 (ALT+DOWN) MOVE.B (A1)+,D2 BSR WRITE RTS CARET MOVEQ #13,D1 ;Change Character to chr$(13) BRA OUT_CH ;Return LF MOVEQ #10,D1 ;Change character to chr$(10) BRA OUT_CH ;Return $INCLUDE FLP2_SAV_DEF $INCLUDE FLP2_LOAD_DEF ALT_TRAP BSR KEY_RD ;Read keyboard TST.B D1 ;Test if byte read BEQ ALT_TRAP ;if not then repeat until one found CMP.B #248,D1 ;Test if F5 BEQ ST_PROG ;if so then branch to stop progam rout BCLR #5,D1 ;Clear bit 5 (ie CASE independent) CMP.B #$42,D1 ;Test if B BNE EN_BAUD ;if not then jump to EN_BAUD CH_BAUD MOVE.W 100(A6),D1 ADD.W #1,D1 CMP.W #7,D1 BLE BAUD_OK MOVEQ #1,D1 BAUD_OK MOVE.W D1,D7 MOVE.W D1,100(A6) LSL.W #01,D1 MOVE.W LOOK_TA(D1.W),D1 MOVE.W D1,110(A6) ;Save Baud rate in WKSPAC+110 MOVE.L D1,A5 BSR BAUD_CH ;Change Baud rate MOVE.L (A6),A0 ;Load Baud window ID into A0 MOVEQ #0,D3 BSR CLS ;Clear window MULU #5,D7 LEA NAME_TA,A1 ADD D7,A1 MOVE.W #5,D2 BSR WRITE ;Write baud rate to window BRA EN_BAUD ;jump to end of routine LOOK_TA DC.W 0,75,300,600,1200,2400,4800,9600 ALIGN EN_BAUD CMP.B #'L',D1 ;Test if character is L BNE EN_HDXT ;if not the jump to end of routine TST.B 133(A6) ;Test if HDX flag set BNE HDXT_1 ;if so then goto HDXT_1 ST 133(A6) ;Set HDX flag MOVE.L 4(A6),A0 ;Load HDX window ID into A0 BSR CLS ;Clear it LEA HDX_ON,A1 MOVE.W #4,D2 BSR WRITE ;Write HDX message to it BRA EN_HDXT ;Jump to end of routine HDXT_1 CLR.B 133(A6) ;Unset HDX flag MOVE.L 4(A6),A0 ;Load HDX window ID into A0 BSR CLS ;Clear it LEA HDX_OF,A1 MOVE.W #4,D2 BSR WRITE ;Write FDX message to it EN_HDXT CMP.B #'D',D1 ;Test if character is D BNE DE_END ;if not the jump to end of routine MOVE.L 16(A6),A0 ;Load DEL window ID into A0 CMP.B #1,118(A6) ;Test DEL variable BEQ DEL_OFF ;if set then goto DEL_OFF routine MOVE.B #1,118(A6) ;Set variable BSR CLS ;Clear window LEA DEL_ON,A1 MOVE.W #4,D2 BSR WRITE ;Write DEL message to it BRA DE_END ;jump to end of routine DEL_OFF MOVE.B #-1,118(A6) ;Unset DEL variable BSR CLS ;Clear window DE_END CMP.B #'X',D1 ;Test if character is X BNE EN_XON ;if not then jump to end of routine CMP.B #1,119(A6) ;Test XON variable BEQ XON_OFF ;if set then jump to XON_OFF routine MOVE.B #1,119(A6) ;Set XON variable MOVE.L 32(A6),A0 ;Load XON window ID into A0 LEA XON_SCR,A1 MOVE.W #5,D2 BSR WRITE ;Write X-ON message to it BRA EN_XON ;Jump to end of routine XON_OFF MOVE.B #0,119(A6) ;Unset XON variable MOVE.L 32(A6),A0 BSR CLS ;Clear XON window EN_XON CMP.B #67,D1 ;Test if character was C BNE EN_CTRL ;if not then jump to end of routine LEA 120(A6),A1 TST.B (A1) ;Test CURS variable BGT CTRL_ON ;if set then goto CTRL_ON routine MOVE.B #1,(A1) ;Set CURS variable MOVE.L 28(A6),A0 ;Load CURS window ID into A0 BSR CLS ;Clear it LEA ESCC_ON,A1 MOVE.W #5,D2 BSR WRITE ;Write ESC message to window TST.B 121(A6) ;if not TAB then jump to end of routine BEQ EN_CTRL MOVE.L 20(A6),A0 ;Load TAB window ID into A0 BSR CLS ;Clear it LEA TAB_SCR,A1 MOVE.W #4,D2 BSR WRITE ;Write TAB message to it BRA EN_CTRL ;Jump to end of routine CTRL_ON CLR.B (A1) ;Unset CURS variable MOVE.L 28(A6),A0 ;Load CURS window ID into A0 BSR CLS ;Clear it LEA CUR_SCR,A1 MOVE.W #5,D2 BSR WRITE ;Write CTRL message to it LEA 121(A6),A1 TST.B (A1) ;Test TAB variable BEQ EN_CTRL ;if not set then jump to end of routine MOVE.L 20(A6),A0 ;Load TAB window ID into A0 BSR CLS ;Clear it EN_CTRL CMP.B #'T',D1 ;Test if character was T BNE TAB_END ;If not then jump to end of routine LEA 120(A6),A1 ;Test CURS variable TST.B (A1)+ ;if unset then jump to end of routine BEQ TAB_END CMP.B #1,(A1) ;Test TAB variable BEQ TAB_OFF ;if set then goto TAB_OFF routine MOVE.B #1,(A1) ;Set TAB variable MOVE.L 20(A6),A0 ;Load TAB window ID into A0 BSR CLS ;Clear it LEA TAB_SCR,A1 MOVE.W #4,D2 BSR WRITE ;Write TAB message to it BRA TAB_END ;Jump to end of routine TAB_OFF CLR.B (A1) ;Unset TAB variable MOVE.L 20(A6),A0 ;Load TAB window ID into A0 BSR CLS ;Clear it TAB_END CMP.B #27,D1 ;Test if ESC BNE END_BRK ;If not then skip code MOVE.W #75,D1 BSR BAUD_CH ;Change Baud rate to 75 MOVE.L D4,A0 MOVEQ #0,D3 MOVEQ #6,D2 LEA BRK_BYT,A1 MOVEQ #7,D0 TRAP #3 ;Send 64 NULs (set line high for time) MOVE.L #$FFFF,D0 ;Go around LOOP 65535 times so as to LOOP DBLT D0,LOOP ;allow the NULs to be sent before Baud MOVE.W 110(A6),D1 ;rate set back to original BSR BAUD_CH ;Set Baud rate back again MOVE.L D5,A0 END_BRK CMP.B #$10,D1 BLT END_PF CMP.B #$1A,D1 BGT END_PF MOVEM.L D0-D7/A0-A6,-(A7) MOVE.L D1,D6 SUB.B #$10,D6 LSL.L #8,D6 LEA KEY_DEF,A3 ADD.L D6,A3 MOVEQ #0,D2 MOVE.B (A3)+,D2 MOVE.L D4,A0 MOVE.L A3,A1 BSR SFT_OUT MOVEM.L (A7)+,D0-D7/A0-A6 END_PF NOP ALT_END BRA KEY_END ;Return SFT_OUT MOVE.L A2,A5 MOVEM.L D1/D2/A0/A1,-(A7) MOVEQ #0,D0 TRAP #1 MOVE.L $4C(A0),A2 MOVEM.L (A7)+,D1/D2/A0/A1 SUBQ.W #1,D2 OUT_LP MOVE.B (A1)+,D1 CMP.B #10,D1 BNE JUMP MOVE.B #$DC,D1 JUMP MOVE.W $E0,A0 JSR (A0) DBLT D2,OUT_LP MOVE.L D5,A0 MOVE.L A5,A2 RTS F1_TRAP MOVE.L D5,A0 ;Load screen ID into A0 MOVEQ #7,D1 MOVEQ #0,D3 MOVEQ #$29,D0 TRAP #3 ;Set ink to white BSR CLS ;Clear screen LEA HELP,A1 MOVE.W (A1)+,D2 MOVEQ #7,D0 TRAP #3 ;Write first help page to screen LEA HELP_MS,A1 MOVE.W #26,D2 BSR WRITE ;Write 'press any key' message WAIT1 MOVEQ #1,D0 TRAP #3 ;Test for key press, if none then CMP.B #-1,D0 ;repeat from WAIT1 BEQ WAIT1 BSR CLS ;Clear screen MOVEQ #$0E,D0 TRAP #3 ;Enable the cursor BSR RIT_MSG BRA KEY_END WRITE MOVE.W 0,D3 MOVEQ #7,D0 TRAP #3 ;Write message to channel RTS ;Return BAUD_CH MOVEQ #$12,D0 TRAP #1 ;Change Baud rate RTS ;Return ST_PROG MOVE.L A0,A1 MOVEQ #0,D0 TRAP #1 MOVE.W #3,$92(A0) ;Change CTRL-Capslock back to CTRL-C MOVE.L D4,A0 MOVEQ #0,D3 MOVEQ #$F,D0 TRAP #3 ;Turn off cursor MOVEQ #2,D0 TRAP #2 ;Close main screen channel MOVE.L D5,A0 MOVEQ #2,D0 TRAP #2 ;Close serial port channel MOVE.L A6,A5 MOVE.L (A5)+,A0 MOVEQ #2,D0 ;Close rest of channels TRAP #2 MOVE.L (A5)+,A0 MOVEQ #2,D0 TRAP #2 MOVE.L (A5)+,A0 MOVEQ #2,D0 TRAP #2 BSR SCR_CLR MOVEQ #-1,D1 MOVEQ #0,D3 MOVEQ #5,D0 TRAP #1 ;Kill Job SEROP MOVEQ #-1,D1 MOVEQ #1,D3 LEA SER,A0 ;Open SER for I/O MOVEQ #1,D0 TRAP #2 MOVE.L A0,D4 ;Put ID in D4 RTS RIT_MSG MOVEQ #7,D1 MOVEQ #$29,D0 TRAP #3 ;Change ink colour to white MOVEQ #0,D2 LEA CPY_MSG,A1 MOVE.W (A1)+,D2 BSR WRITE ;Write start-up message to screen CMP.B #7,62(A6) BEQ CH_HLP MOVEQ #4,D1 MOVEQ #$29,D0 TRAP #3 ;Set ink to green CH_HLP RTS STA_WIN MOVEQ #-1,D1 MOVEQ #1,D3 LEA SCR5,A0 MOVEQ #1,D0 TRAP #2 BSR BORDER MOVEQ #2,D0 TRAP #2 RTS REFRSH BSR SCR_CLR MOVE.L D5,A0 BSR CLS MOVEQ #$0E,D0 TRAP #3 S_RFSH BSR STA_WIN MOVE.L A6,A5 MOVE.L #8,D7 RLOOP MOVE.L (A5)+,A0 BSR BORDER DBLT D7,RLOOP MOVEQ #0,D7 MOVE.W 100(A6),D7 MOVE.L (A6),A0 MOVEQ #0,D3 MULU #5,D7 LEA NAME_TA,A1 ADD D7,A1 MOVE.W #5,D2 BSR WRITE MOVE.L 4(A6),A0 TST.B 133(A6) BNE HD_MSG LEA HDX_OF,A1 MOVE.W #4,D2 BRA E_HMSG HD_MSG LEA HDX_ON,A1 MOVE.W #4,D2 E_HMSG BSR WRITE MOVE.B 116(A6),D2 MULU #19,D2 LEA BUF_OK-19,A1 ADD.L D2,A1 MOVE.L 8(A6),A0 MOVE.W #19,D2 BSR WRITE MOVE.B 117(A6),D2 MULU #9,D2 LEA CAP_OFF,A1 ADD.L D2,A1 MOVE.W #9,D2 MOVE.L 12(A6),A0 BSR WRITE LEA 118(A6),A1 CMP.B #1,(A1) BNE E_DEL MOVE.L 16(A6),A0 LEA DEL_ON,A1 MOVE.W #4,D2 BSR WRITE E_DEL LEA 120(A6),A1 TST.B (A1)+ BEQ E_TAB TST.B (A1) BEQ E_TAB MOVE.L 20(A6),A0 LEA TAB_SCR,A1 MOVE.W #4,D2 BSR WRITE E_TAB MOVE.L 24(A6),A0 LEA HLP_SCR,A1 MOVE.W #11,D2 BSR WRITE MOVE.B 120(A6),D2 MULU #5,D2 LEA CUR_SCR,A1 ADD.L D2,A1 MOVE.W #5,D2 MOVE.L 28(A6),A0 BSR WRITE TST.B 119(A6) BEQ E_XON MOVE.L 32(A6),A0 LEA XON_SCR,A1 MOVE.W #5,D2 BSR WRITE E_XON BRA KEY_END SCR_CLR MOVEQ #-1,D1 MOVEQ #1,D3 LEA SCR20,A0 MOVEQ #1,D0 TRAP #2 BSR CLS MOVEQ #2,D0 TRAP #2 RTS SFT_KBD MOVEQ #$0F,D0 ;Turn cursor off TRAP #3 CMP.B #1,119(A0) ;Test if XON variable set BNE NO_XON1 MOVE.L D4,A0 MOVEQ #$13,D1 MOVEQ #0,D3 MOVEQ #5,D0 TRAP #3 ;if so then send X-OFF NO_XON1 BSR RD_SER ;Read serial port MOVE.L #133888,A1 ;Load start of part of screen to be LEA ALT_SCR,A3 ;saved into A1 and the destnation in A3 MOVE.L #16*1024/4-1,D0 ;Length into D0 SAV_LP MOVE.L (A1)+,(A3)+ DBRA D0,SAV_LP MOVEQ #0,D1 ;Open PF window LEA KEY_CON,A0 MOVEQ #1,D0 TRAP #2 MOVE.L A0,36(A6) ;Save ID in WKSPAC+36 MOVEQ #2,D1 MOVE.W #2,D2 MOVEQ #$C,D0 ;Set border to red width 2 TRAP #3 MOVEQ #7,D1 MOVEQ #$27,D0 ;Set paper white TRAP #3 MOVEQ #7,D1 MOVEQ #$28,D0 ;Set strip white TRAP #3 MOVEQ #2,D1 MOVEQ #$29,D0 ;Set ink red TRAP #3 BSR CLS ;clear window MOVEQ #0,D1 MOVEQ #1,D2 MOVEQ #$10,D0 ;Position cursor at 0,1 TRAP #3 MOVE.W #18,D2 ;MESSAGE LENGTH LEA KEY_NO,A1 BSR WRITE ;write message MOVE.W #6,D2 LEA NUM_BUF,A1 MOVEQ #2,D0 ;Call IO.FLINE MOVE.W #-1,D3 ;Timeout=INFINITY TRAP #3 MOVEQ #0,D3 ;Reset timeout to 0 BSR RD_SER ;Read serial port LEA NUM_BUF,A0 MOVEQ #0,D6 MOVE.B (A0),D6 ;Load value returned into D6 SUB.B #'0',D6 ;Change from ASCII to value BMI RES_SCR ;if so then exit routine CMP.B #9,D6 ;Test if GT 9 BGT RES_SCR ;if so then exit routine LSL.L #8,D6 ;Multiply by 256 LEA KEY_DEF,A0 ADD.L D6,A0 ;Add it to start of pfkey Definitions MOVE.L A0,122(A6) ;and save the address in WKSPAC+122 MOVE.L 36(A6),A0 ;Load pf screen ID into A0 MOVEQ #0,D3 MOVEQ #0,D1 MOVEQ #2,D2 MOVEQ #$10,D0 ;Position cursor at 0,2 TRAP #3 LEA KEY_WR,A1 MOVE.W #12,D2 ;MESSAGE LENGTH BSR WRITE ;Write message MOVEQ #-1,D3 ;Timeout = INFINITY MOVE.W #$FF,D2 ;Buffer length 255 LEA TMP_BUF,A1 MOVEQ #2,D0 ;Call IO.FLINE TRAP #3 LEA TMP_BUF,A1 ;Load address of buffer into A1 BSR STR_DEC ;Call STRing DECode routine MOVE.L 122(A6),A0 ;Load address of FKey definition in A0 MOVE.B D1,(A0) ;Save length in (A0) MOVEQ #0,D1 ;Clear D1 (JUST TO BE SAFE) MOVE.B (A0)+,D1 ;Put it back LEA TMP_BUF,A1 BUF_LP MOVE.B (A1)+,(A0)+ DBRA D1,BUF_LP ;Copy decoded string into FKey def RES_SCR MOVE.L 36(A6),A0 ;Load pf screen ID into A0 MOVEQ #0,D1 ;Change paper to black MOVEQ #$27,D0 TRAP #3 MOVEQ #0,D1 ;Border to black and 0 width MOVEQ #0,D2 MOVEQ #$0C,D0 TRAP #3 MOVEQ #$20,D0 ;Cls window TRAP #3 MOVEQ #2,D0 ;and close it TRAP #2 LD_SCR MOVE.L #133888,A1 ;Copy screen portion back again LEA ALT_SCR,A3 MOVE.L #16*1024/4-1,D0 LD_LP MOVE.L (A3)+,(A1)+ DBRA D0,LD_LP CMP.B #1,119(A6) ;Test if XON variable set BNE NO_XON2 CMP.B #1,116(A6) ;and BUFFER not full or 2/3 BGT NO_XON2 MOVE.L D4,A0 MOVEQ #$11,D1 MOVEQ #0,D3 MOVEQ #5,D0 TRAP #3 ;send X-ON NO_XON2 MOVE.L D5,A0 MOVEQ #0,D3 MOVEQ #$0E,D0 ;Turn on cursor TRAP #3 BRA KEY_END ;Return STR_DEC MOVEQ #0,D2 ;Clear D2 MOVEQ #0,D0 ;Clear D0 STR_LP MOVE.B 0(A1,D0),D6 ;Load character into D6 CMP.B #'|',D6 ;Test if | BEQ CT_CHAR ;if so then goto ConTrol CHAR decode CMP.B #' ',D6 ;Test if CTRL char BLT SKIP_CH ;if so then skip it CT_BAC MOVE.B D6,0(A1,D2) ;Put character back ADDQ.W #1,D2 ;Add 1 to replace counter SKIP_CH ADDQ.W #1,D0 ;Add 1 to original counter CMP.B #10,D6 BEQ END_STR TST.W D1 DBLT D1,STR_LP ;goto STR_LP if not at end of string END_STR MOVE.L D2,D1 ;Put length of decoded string into D1 MOVEQ #0,D0 ;Clear registers MOVEQ #0,D6 MOVEQ #0,D2 RTS ;return CT_CHAR ADDQ.W #1,D0 ;Add 1 to original counter SUBQ.W #1,D1 ;Decrement loop counter MOVE.B 0(A1,D0),D6 ;Load character into D6 CMP.B #'@',D6 ;Test if less than @ BLT CT_BAC ;if so then return via dump routine CMP.B #'|',D6 ;Test if | BEQ CT_BAC ;if so then return BCLR #5,D6 ;Make case independent SUB.W #'@',D6 ;Decode into CTRL char BRA CT_BAC ;Return SCR1 DC.W @2-@1 @1 DC.B 'CON_486X243A22X0_512' @2 ALIGN SCR2 DC.W @2-@1 @1 DC.B 'SCR_40X12A438X243' @2 ALIGN SCR3 DC.W @2-@1 @1 DC.B 'SCR_40X12A400X243' @2 ALIGN SCR4 DC.W @2-@1 @1 DC.B 'SCR_118X12A38X243' @2 ALIGN SCR5 DC.W @2-@1 @1 DC.B 'SCR_512X12A0X243' @2 ALIGN SCR6 DC.W @2-@1 @1 DC.B 'SCR_58X12A154X243' @2 ALIGN SCR7 DC.W @2-@1 @1 DC.B 'SCR_28X12A284X243' @2 ALIGN SCR8 DC.W @2-@1 @1 DC.B 'SCR_28X12A310X243' @2 ALIGN SCR9 DC.W @2-@1 @1 DC.B 'SCR_76X12A210X243' @2 ALIGN SCR10 DC.W @2-@1 @1 DC.B 'SCR_34X12A336X243' @2 ALIGN SCR11 DC.W @2-@1 @1 DC.B 'SCR_34X12A368X243' @2 ALIGN SCR20 DC.W @2-@1 @1 DC.B 'SCR_512X255A0X0' @2 ALIGN KEY_CON DC.W @2-@1 @1 DC.B 'CON_400X100A50X50_255' @2 ALIGN FILE1 DC.W @2-@1 @1 DC.B 'TERM_DEF' @2 ALIGN FILE2 DC.W @2-@1 @1 DC.B 'FLP1_TERM_DEF' @2 ALIGN FILE3 DC.W @2-@1 @1 DC.B 'MDV1_TERM_DEF' @2 ALIGN BAU_SCR DC.B ' 2400' HDX_SCR DC.B ' FDX' DEL_SCR DC.B 'DEL ' TAB_SCR DC.B 'TAB ' CUR_SCR DC.B 'CTRL ' ESCC_ON DC.B 'ESC ' SFT_SCR DC.B 'SOFT ' XON_SCR DC.B 'X-ON ' HLP_SCR DC.B ' F1 Help ' BUF_OK DC.B 'Buffer Status: OK ' BUF_NER DC.B 'Buffer Status: 2/3 ' BUF_FUL DC.B 'Buffer Status: Full' KEY_NO DC.B 'Function key no. >' KEY_WR DC.B 'Definition >' ALIGN SER DC.W @2-@1 @1 DC.B 'SER2IR' @2 ALIGN CPY_MSG DC.W @2-@1 @1 DC.B ' QL Terminal Emulator',10 DC.B ' Version 3.53',10,10 DC.B '(press f1 for command key functions)',10,10 @2 ALIGN CAP_OFF DC.B 'Caps: ' CAPS_ON DC.B 'Caps: ↑↑ ' HDX_ON DC.B ' HDX' HDX_OF DC.B ' FDX' DEL_ON DC.B 'DEL ' ALIGN SOUND_E DC.B $0B,$00,$FF,$FF,$FF,$FF,$FF ALIGN SOUND_P DC.B $0A,$08,$FF,$FF,$AA,$AA,$02,$00,0,0,0,$08,$70,0,$FF,0 ALIGN RIGH_ES DC.B 27,'C' LEFT_ES DC.B 27,'D' UP_ES DC.B 27,'A' DOWN_ES DC.B 27,'B' ALIGN NAME_TA DC.B ' 75 300 600 1200 2400 4800 9600' ALIGN HELP DC.W @2-@1 @1 DC.B ' QL Terminal Emulator Help Page' DC.B 10,' © S.R.Usher 1989',10,10 DC.B 10,' ' DC.B 'The commands available are accessed with the followin' DC.B 'g key presses:-',10,10 DC.B ' ' DC.B ' ALT-B Set baud rate. Pressing the keys together' DC.B ' cycles',10,' ' DC.B ' through the available baud rates. The' DC.B ' current',10,' ' DC.B ' one is displayed in the right-' DC.B 'most window.',10 DC.B ' ' DC.B ' ALT-C ConTRol/ESCape toggle.',10,' ' DC.B ' ALT-D DEL toggle.',10,' ' DC.B ' ALT-L Local echo of characters toggle (HDX/FDX).' DC.B 10,' ' DC.B ' ALT-T TAB toggle (only when in ESCape mode).' DC.B 10,' ' DC.B ' ALT-X X-ON/X-OFF enable toggle.' DC.B 10,' ' DC.B ' ALT-ESC Send BREAK to host.',10,' ' DC.B ' ALT-0→9 Programable Function key 0→9' DC.B 10,' ' DC.B ' F2 Program Programable Function keys.' DC.B 10,' ' DC.B ' F3 Save Default Settings to FLP or MDV.' DC.B 10,' ' DC.B ' F4 Refresh screen (after other programs have ' DC.B 'run).',10,' ' DC.B ' F5 Turn off over-printing (After graphics hav' DC.B 'e been drawn).',10,' ' DC.B ' ALT-F5 Exit emulator - to RERUN you must RELOAD' DC.B ' program.',10,10,10,' ' @2 ALIGN HELP_MS DC.B 'Press any key to continue.' ALIGN GCUR1 DCB.W 2,0 GCUR2 DCB.W 2,0 KEY_DEF DCB.B 4096,0 ALIGN BRK_BYT DCB.B 64,0 ALIGN NUM_BUF DCB.B 6,0 TMP_BUF DCB.B 255,0 ALIGN