* === handler.asm ==========================================================
*
* Copyright (c) 1987 by William S. Hawes
*
* Distribute freely (but please leave the notice intact ...)
*
* ======================================================================
*
* This program functions as a "bootstrap loader" for DOS handler processes.
* It begins life as an ersatz-BCPL process, loaded automatically by DOS
* when your handler is opened.  It opens your handler, created as
* a standard shared library, and then transfers to its main entry point.
*
* The main idea here is to allow handlers to be developed without going
* through the nonsense of creating BCPL-style modules.  It is difficult
* even in assembler to get the module to look right -- it took numerous
* tries to get even this short program working.  The basic problem is that
* every "hunk" created by your program must look like the BCPL model:
* preceded by a long-word count, and followed by the global vector table.
* The long-word count requires that you assemble the whole program at once
* to get the total size, which makes for some very long assembles.
*
* Even after your program looks right, the trouble is only beginning.
* Your code may look like BCPL, but the program libraries used in
* linking the handler may contribute hunks that aren't BCPL-ish.
* I got around this by including the EXEC library offset definitions in
* the include file "fix.i", so I don't even need Amiga.lib in my link.
*
* By developing the handler as standard shared library, you can work in
* a less ascetic development environment and still use DOS's automatic
* loading capabilites.
*
* One nice side-effect of building handlers this way is that the
* handler library can be unloaded by the system if memory gets tight.
* Each invocation of the handler opens and eventually closes the library,
* so the library can be swapped out if the handler isn't open at the time.
* This is partial compensation for the lack of proper DOS mechanisms to
* unload device handlers when they are no longer being used ...

* After assembling and linking this program, install it as a handler in the
* usual way (either by the MOUNT command or by patching the device node).
* Note that if a simple entry-point convention were adopted, this program
* could work for any handler, requiring only the name of the specific
* library to be opened.  Why, there could even be a function called
* "OpenHandler" ... but then, no one get to use BCPL anymore.
*
*                                      -- WSH  (617) 568-8695


         INCLUDE  "chlib.i"            ; definitions for your handler
         INCLUDE  "fix.i"              ; offsets derived from "exec_lib.i"

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

_AbsExecBase   EQU   4

         CNOP     0,4
StartModule:
         dc.l     (EndModule-StartModule)/4

start:   movea.l  _AbsExecBase,a6
         move.l   d1,d4                ; save packet (BPTR)

         lea      CHLib(pc),a1         ; library name
         moveq    #CHLVERS,d0          ; version number
         CALLSYS  OpenLibrary
         tst.l    d0                   ; opened?
         beq.s    CleanUp              ; no??
         movea.l  d0,a5

         ; Call the console handler entry point

         move.l   d4,d1                ; startup packet
         exg      a5,a6
         CALLSYS  CHEntry
         exg      a5,a6

         movea.l  a5,a1
         CALLSYS  CloseLibrary
         bra.s    Exit

         ; Groan ... if we can't open the library, I can't even use the
         ; "ReturnPkt" function defined there ... must repeat it here.

CleanUp:
         lsl.l    #2,d4
         movea.l  d4,a0                ; DOS packet
         clr.l    dp_Res1(a0)          ; FALSE return
         clr.l    dp_Res2(a0)          ; use an error code, maybe?
         movea.l  dp_Link(a0),a1       ; EXEC message
         movea.l  dp_Port(a0),a0       ; replyport (??#@!)
         CALLSYS  PutMsg

Exit:    rts

CHLib    CHLNAME                       ; library name

         CNOP     0,4
         dc.l     0                    ; end marker
         dc.l     1                    ; global defined
         dc.l     4                    ; offset
         dc.l     1                    ; maximum global
EndModule:

         END
