* 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