OBJNAM TINPCH.LIT ; Created 27-Nov-85, Last modified 27-Dec-85
; by Irv Bromberg, Medic/OS Consultants, 78 Wildginger Way, Toronto,
; CANADA  M3H 5X1
RADIX 10
VEDIT=4
VMINOR=2
VMAJOR=1
VSUB=0

IF EQ,1

Under AMOS/L 1.2 or 1.3 TINPCH.LIT version 1.2(4) size=322 bytes
(only 20 bytes are actually consumed in memory), hash=145-562-136-156.

Syntax: TINPCH

Patches TIN monitor call (and hence anything that calls directly or
indirectly for terminal input) so that the EchoWait loop time wasting is
drastically reduced. TINPCH must be invoked before any SYSTEM commands
are used in AMOSL.INI file (preferably after the first TRMDEF).  Does
not install itself it beyond addressing range (message issued). With
this patch installed the TIN EchoWait loop pauses 50ms each time around
the loop (using a SLEEP instruction) instead of consuming all CPU time
waiting for input to echo.

TINPCH can be used after system bootup to check if it has already installed
the TIN patch.  The message will either be "%TIN patch already installed"
or "?TIN patch must be installed before any SYSTEM commands".

Installation tip:  Use early in the bootup INI file to prevent "out of
addressing range" condition.  Typically it may be necessary to put TINPCH
after the first TRMDEF (occasionally before the first TRMDEF) and to move
the JOBALC statements to a position following the TRMDEFs.

Tested under AMOS/L 1.2A and 1.3, operates correctly.

Essentially all AMOS/L installations will gain more CPU processing time
by installing this patch, but the benefit will be much more noticeable
when terminals are at a low baud rate and/or if multiplexor emulation is
being used on the CPU.  This patch to the operating system when used
together with the EXIPCH command eliminates the CPU time wasting problem
that is experienced with heavy use of multiplexor emulation (see
AMUS.LOG Nov/85 report on Multiplexor Emulation using Alpha Micro Computers).

ENDC

SEARCH SYS
SEARCH SYSSYM
SEARCH TRM

JCB     =A0
Block   =A1
Table   =A2
Buffer  =A2
Patch   =A3
Target  =A4
TCB     =A5
Atemp   =A6

Number  =D1
Size    =D2

       PHDR    -1,0,PH$REE!PH$REU

       MOV     ^O50,Table              ; get address of EM1010 routine
Search: CMPW    (Table)+,#^O47165       ; search for RTN instruction, leaving
       BNE     Search                  ; Table register -->base of SVCA table
       ADD     #2*^O2,Table            ; add offset to TIN SVCA
       SUB     Target,Target           ; search for target address
       ADDW    @Table,Target           ; =address of TIN routine
10$:    CMPW    (Target)+,#^H0A072      ; search for TTYIN instruction
       BNE     10$
       SUB     #8,Target               ; back up to CMP instruction
       MOVW    @Target,D7              ; check that patch not already done
       ANDW    #^B1111000111000000,D7  ; select bits we care about
       CMPW    D7,#^B1011000010000000  ; is it CMP longword?
       BEQ     ChkUp                   ; yes, check if system has booted
       TYPECR  <%TIN patch already installed>
       EXIT

ChkUp:  MOV     SYSTEM,D7               ; has final SYSTEM command been given?
       AND     #SY$UP,D7
       BEQ     ChkSYS                  ; if so abort with error message
Before: TYPECR  <?TIN patch must be installed before any SYSTEM commands>
       EXIT
ChkSYS: TST     SYSBAS                  ; any SYSTEM commands executed?
       BNE     Before                  ; yes, abort with error message

ChkRng: ; Check if within addressing range (if not TINPCH must be moved to
       ; earlier position in AMOSL.INI file)
       ; calculate value of displacement that will be needed
       MOV     MEMBAS,Block            ; index available memory
       MOV     Block,Number
       SUB     Target,Number
       SUB     #2,Number               ; slight adjustment
       CMP     Number,#^H7FFF          ; cannot exceed +32K distance
       BLO     Proceed                 ; all OK, proceed with patch
       TYPECR  <?Too late to install TIN patch - out of addressing range>
       EXIT

Proceed:LEA     Patch,PRGBAS            ; index TIN patch routine
       MOVW    #<PRGEND-PRGBAS-2>,Size ; get size of block (-2/2 for DBF loop)
       LSRW    Size                    ; /2 for 16-bit word block move

BlkMov: MOVW    (Patch)+,(Block)+       ; copy patch onto end of monitor
       DBF     Size,BlkMov
       MOV     Block,MEMBAS            ; update MEMBAS
       MOVW    #^H4EBA,(Target)+       ; change CMP to CALL
       MOVW    Number,(Target)+        ; follow with displacement
       MOVW    #^H4E71,(Target)        ; and clean up with a NOP
       TYPECR  <TIN echo-wait patched> ; successfull!
       EXIT

; TINPCH.LIT substitutes this EchoWait loop for the time-wasting
; one originally in the TIN routine:

PRGBAS:
EchoWait:MOV    T.ICC(TCB),D7           ; Is echo done yet for at least
       CMP     D7,T.ECC(TCB)           ; one character?
       BHI     10$                     ; yes
       SLEEP   #500                    ; sleep 50ms
       BR      EchoWait                ; then try again
10$:    RTN                             ; return and allow TTYIN

PRGEND: NOP

       END