;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
;       AMOSQ.SBR - quiet version of AMOS.SBR
;
;       Copyright (C) 1986 by UltraSoft.  All Rights Reserved.
;       Written by: David Pallmann
;
;       Desc:   executes an AMOS command, with output supressed
;
;       Call:   XCALL AMOSQ, {cmd$}
;
;       Where:  {cmd$} is a string variable or constant containing an AMOS cmd
;
;       Edit History:
;       1.0 09-Aug-86 created from AMOS.M68. /DFP

       VMAJOR=1
       VMINOR=0

       OBJNAM  .SBR

       SEARCH  SYS
       SEARCH  SYSSYM
       SEARCH  TRM

       .OFINI                          ; XCALL argument block:
       .OFDEF  COUNT,2                 ;   number of arguments
       .OFDEF  TYPE1,2                 ;   type code, arg 1
       .OFDEF  ADDR1,4                 ;   address, arg 1
       .OFDEF  SIZE1,4                 ;   size, arg 1
       .OFSIZ  XCSIZ

       STRING=2                        ; type code for a string variable

       LF=12                           ; line feed
       CR=15                           ; carriage return

       .OFINI
       .OFDEF  CMDLIN,512.             ; command line buffer
       .OFDEF  SAVBAS,4                ; saved job memory base
       .OFDEF  SAVSIZ,4                ; saved job memory size
       .OFDEF  SAVIDV,4                ; saved IDV name in RAD50
       .OFDEF  SAVTDV,4                ; saved TDV name in RAD50
       .OFSIZ  MEMSIZ

       PHDR    -1,PV$RSM!PV$WSM,PH$REE!PH$REU  ; program header

;check for validity of XCALL parameters

ENTRY:  CMPW    COUNT(A3),#1            ; one arg in XCALL?
       JNE     ERROR0                  ;  no - error
       CMPW    TYPE1(A3),#STRING       ; is arg a string?
       JNE     ERROR1                  ;  no - error

;copy command line from user variable to internal buffer

CPYLIN: MOV     ADDR1(A3),A0            ; point to variable
       LEA     A1,CMDLIN(A4)           ; point to buffer
       MOV     SIZE1(A3),D0            ; load variable size
10$:    MOVB    (A0)+,(A1)+             ; copy character
       BEQ     20$                     ; branch if null encountered
       SOB     D0,10$                  ; loop till entire string copied
       CLRB    (A1)+                   ; terminate buffer
20$:    MOVB    #CR,-1(A1)              ; store CR
       MOVB    #LF,(A1)+               ; store LF
       CLRB    @A1                     ; terminate buffer

;save job control information, include partition base and size, and interface
;and terminal driver names

SAVMEM: JOBIDX  A0                      ; point to Job Control Block
       MOV     JOBBAS(A0),SAVBAS(A4)   ; save partition base
       MOV     JOBSIZ(A0),SAVSIZ(A4)   ; save partition size
       MOV     JOBTRM(A0),A1           ; point to Terminal Control Block
10$:    TSTB    T.STS(A1)               ; wait for output in progress
       BMI     10$                     ;  to expire
       MOV     T.IDV(A1),A2            ; get interface driver address
       MOV     -(A2),SAVIDV(A4)        ; save IDV name
       MOV     T.TDV(A1),A2            ; get terminal driver address
       MOV     -(A2),SAVTDV(A4)        ; save TDV name

;set interface/terminal drivers to PSEUDO/NULL, to supress command output

SETDVR: LEA     A2,PSEUDO               ; set interface driver
       CALL    SETIDV                  ;  to PSEUDO
       LEA     A2,NULL                 ; set terminal driver
       CALL    SETTDV                  ;  to NULL

;create a fake partition within BASIC's free memory area

SETMEM: LEA     A1,MEMSIZ(A4)           ; point to free memory
       ADD     #4,A1                   ; add 4 for good measure
       MOV     A1,JOBBAS(A0)           ; set new partition base in JCB
       CLR     @A1                     ; clear partition
       MOV     A5,D0                   ; point to end of free memory
       SUB     A1,D0                   ; calculate amount of free memory
       SUB     #10,D0                  ; subtract 8 for good measure
       MOV     D0,JOBSIZ(A0)           ; set new partition size
       PUSH    A4                      ; save impure area address on stack

;execute the command

EXEC:   LEA     A2,CMDLIN(A4)           ; index command line
       AMOS                            ; execute it

;restore memory partition
;we must assume that all registers are corrupted at this point

RESMEM: POP     A4                      ; get impure area address off of stack
       JOBIDX  A0                      ; point to JCB again
       MOV     SAVBAS(A4),JOBBAS(A0)   ; put back partition base
       MOV     SAVSIZ(A4),JOBSIZ(A0)   ; put back partition size

;put back original interface/terminal drivers

RESDVR: MOV     JOBTRM(A0),A1           ; point to TCB
10$:    TSTB    T.STS(A1)               ; wait for output in progress
       BMI     10$                     ;  to expire
       LEA     A2,SAVIDV(A4)           ; attach original
       CALL    SETIDV                  ;  interface driver
       LEA     A2,SAVTDV(A4)           ; attach original
       CALL    SETTDV                  ;  terminal driver
       RTN                             ; return to BASIC program

ERROR0: TYPESP  ?Argument count error
       BR      ERROR

ERROR1: TYPESP  ?Argument type error

ERROR:  TYPECR  in AMOS.SBR
       RTN

;set interface driver routine
;A2 must point to the RAD50-packed name of the driver

SETIDV: MOV     TRMIDC,A3               ; point to IDV table
10$:    CMM     4(A3),@A2               ; is this the driver we want?
       BEQ     20$                     ;  yes - branch
       MOV     @A3,A3                  ; point to next driver in table
       BR      10$                     ; loop
20$:    ADD     #10,A3                  ; bypass link and driver name
       JOBIDX                          ; index JCB
       MOV     JOBTRM(A6),A6           ; index TCB
       MOV     A3,T.IDV(A6)            ; set IDV address
       RTN                             ; return

;set terminal driver routine
;A2 must point to the RAD50-packed name of the driver

SETTDV: MOV     TRMTDC,A3               ; point to TDV table
10$:    CMM     4(A3),@A2               ; is this the driver we want?
       BEQ     20$                     ;  yes - branch
       MOV     @A3,A3                  ; point to next driver in table
       BR      10$                     ; loop
20$:    ADD     #10,A3                  ; bypass link and driver name
       JOBIDX                          ; index JCB
       MOV     JOBTRM(A6),A6           ; index TCB
       MOV     A3,T.TDV(A6)            ; set TDV address
       RTN                             ; return

PSEUDO: RAD50   /PSEUDO/
NULL:   RAD50   /NULL  /

       END