* == force.asm =========================================================
*
* Copyright (c) 1987 by William S. Hawes (All Rights Reserved)
*
* ======================================================================
* Command utility to force data into the ConMan line buffer.
* USAGE: force command-line

         SECTION  Force,CODE

         INCLUDE  "exec/types.i"
         INCLUDE  "exec/tasks.i"

         INCLUDE  "libraries/dos.i"
         INCLUDE  "libraries/dosextens.i"

         IFND     EXEC_EXECBASE_I
ThisTask EQU      276
         ENDC

         ; A couple of macro definitions

XLIB     MACRO    * FunctionName
         XREF     _LVO\1
         ENDM

CALLSYS  MACRO    * FunctionName
         jsr      _LVO\1(a6)
         ENDM

         ; Private packet code definitions supported by ConMan

ACTION_FORCE   EQU   2001              ; "force" packet code

         XREF     _AbsExecBase

         ; DOS library functions

         XLIB     Read
         XLIB     Write

         ; Exec library functions

         XLIB     CloseLibrary
         XLIB     FindTask
         XLIB     GetMsg
         XLIB     OpenLibrary
         XLIB     PutMsg
         XLIB     WaitPort

STACKBF  SET      4+sp_SIZEOF
start:   movea.l  _AbsExecBase,a6
         lea      -STACKBF(sp),sp      ; message packet/read buffer
         movea.l  ThisTask(a6),a4

         moveq    #RETURN_FAIL,d6      ; default error
         moveq    #pr_MsgPort,d7       ; processid offset
         add.l    a4,d7

         ; Trim any trailing "white space"

         movea.l  a0,a3
         move.l   d0,d3
         adda.l   d0,a0                ; end of string
         subq.w   #1,d3                ; loop count

1$:      cmpi.b   #' ',-(a0)           ; > blank?
         dbhi     d3,1$                ; loop back
         addq.w   #1,d3                ; restore length

         ; Get the input stream and validate the filehandle.

         move.l   pr_CIS(a4),d0        ; an input stream?
         beq.s    Exit                 ; no ...
         lsl.l    #2,d0                ; real address
         movea.l  d0,a5
         tst.l    fh_Interactive(a5)   ; interactive?
         beq.s    Exit                 ; no
         move.l   fh_Type(a5),d2       ; a handler?
         beq.s    Exit                 ; no

         ; Initialize a message packet on the stack

         move.l   sp,d0
         addq.l   #3,d0
         andi.b   #$FC,d0              ; longword address
         movea.l  d0,a2                ; message packet

         ; Initialize the DOS packet by linking the two parts.

         lea      (sp_Pkt)(a2),a1      ; start of DOS packet
         move.l   a2,(a1)              ; dp_Link (back pointer)
         move.l   a1,LN_NAME(a2)       ; forward pointer
         move.l   d7,MN_REPLYPORT(a2)
         move.l   d7,(sp_Pkt+dp_Port)(a2)

         move.l   #ACTION_FORCE,(sp_Pkt+dp_Type)(a2)
         move.l   fh_Arg1(a5),(sp_Pkt+dp_Arg1)(a2)
         move.l   a3,(sp_Pkt+dp_Arg2)(a2)
         move.l   d3,(sp_Pkt+dp_Arg3)(a2)

         ; Send the message to the input handler

         movea.l  d2,a0                ; handler message port
         movea.l  a2,a1                ; message packet
         CALLSYS  PutMsg

         ; Wait (at our processid message port) for the reply

         movea.l  d7,a0                ; our processid
         CALLSYS  WaitPort
         movea.l  d7,a0
         CALLSYS  GetMsg               ; return: D0=message

         ; Check the actual count to see if everything was forced

         move.l   (sp_Pkt+dp_Res2)(a2),pr_Result2(a4)
         move.l   (sp_Pkt+dp_Res1)(a2),d0
         beq.s    Exit
         moveq    #0,d6

Exit     move.l   d6,d0                ; error code
         lea      STACKBF(sp),sp
         rts

         END
