        NOLIST
        INCLUDE "exec/execbase.i"
        INCLUDE "exec/memory.i"
        INCLUDE "libraries/dosextens.i"
        INCLUDE "devices/input.i"
        INCLUDE "intuition/intuition.i"
        INCLUDE "libraries/dos.i"
        INCLUDE "libraries/dosextens.i"
        INCLUDE "workbench/startup.i"
        INCLUDE "workbench/workbench.i"
        LIST

_LVOOpen                                    EQU  -030
_LVOCurrentDir                              EQU  -126
_LVOGADS                                    EQU  -252
_LVOAtol                                    EQU  -258
_LVOFileRequest                             EQU  -294
_LVOCreatePort                              EQU  -306
_LVODeletePort                              EQU  -312
_LVOASyncRun                                EQU  -546
_LVOTackOn                                  EQU  -624
_LVOArpOpenLibrary                          EQU  -654

_LVOWBenchToBack                            EQU  -336
_LVOWBenchToFront                           EQU  -342

_LVOGetDiskObject                           EQU  -078
_LVOFreeDiskObject                          EQU  -090
_LVOFindToolType                            EQU  -096

_LVOForbid                                  EQU  -132
_LVOWait                                    EQU  -318
_LVOSignal                                  EQU  -324
_LVOAllocSignal                             EQU  -330
_LVOFreeSignal                              EQU  -336
_LVOGetMsg                                  EQU  -372
_LVOReplyMsg                                EQU  -378
_LVOWaitPort                                EQU  -384
_LVOCloseLibrary                            EQU  -414
_LVOOpenDevice                              EQU  -444
_LVOCloseDevice                             EQU  -450
_LVODoIO                                    EQU  -456
_LVOOpenLibrary                             EQU  -552

FCHARS          EQU     32
DSIZE           EQU     33
STDIO_Val       EQU     32

CTRL_CFlag      EQU     $01000  ;
NULL            EQU     0
AbsExecBase     EQU     $4
LVersion        EQU     31
AVersion        EQU     39

ArpBase         EQUR    D7
IntuitBase      EQUR    D6
IconBase        EQUR    D5
GlobData        EQUR    A5
FileRData       EQUR    A4


        STRUCTURE FileRequester,0
        CPTR    fr_Hail                 ; Hailing text
        CPTR    fr_File                 ; *Filename array (FCHARS+1)
        CPTR    fr_Dir                  ; *Directory array (DSIZE+1)
        CPTR    fr_Window               ; Window requesting or NULL
        UBYTE   fr_FuncFlags            ; Set bitdef's below
        UBYTE   fr_reserved1            ; Set to NULL
        APTR    fr_Function             ; Func to call for wildcards
        LONG    fr_reserved2            ; RESERVED
        LABEL   fr_SIZEOF

        STRUCTURE ProcessControlBlock,0
                ULONG   pcb_StackSize   ; Stacksize for new process
                BYTE    pcb_Pri         ; Priority of new process
                BYTE    pcb_Control     ; Control bits, see BITDEF's below.
                APTR    pcb_TrapCode    ; Optional trapcode vector
                ULONG   pcb_Input       ; Optional default input
                ULONG   pcb_Output      ; Optional default output
                    LABEL pcb_SplatFile ; file to use for Open("*")
                    LABEL pcb_ConName   ; CON: filename
                STRUCT  pcb_Console,4
                ULONG   pcb_LoadedCode  ; If not null, use this code
                CPTR    pcb_LastGasp    ; ReplyMsg to be filled in by exit code
                CPTR    pcb_WBProcess   ; Valid only when PRB_NOCLI.
                LABEL   pcb_SIZEOF

        STRUCTURE WorkSpace,0                ; Data stored on stack
        ULONG   WakeUpSig
        UBYTE   WakeUpSigNum
        UBYTE   HotKey_RAW
        APTR    HostTask
        STRUCT  ArgList,0
        APTR    Command
        APTR    Title
        APTR    HotKeyPtr
        APTR    WBMsg
        STRUCT  FR,fr_SIZEOF
        STRUCT  inputReqBlk,IOSTD_SIZE
        STRUCT  handlerStuff,IS_SIZE
        STRUCT  FormattedArgLine,128
        STRUCT  Directory,DSIZE+1
        STRUCT  FullPath,DSIZE+FCHARS+2
        STRUCT  FileName,FCHARS+1
        STRUCT  TitleCopy,128
        STRUCT  ComCopy,128
        STRUCT  PCB,pcb_SIZEOF
        LABEL   WorkSize                ; Size of Stack Data

LINKEXE MACRO
        jsr     _LVO\1(a6)
        ENDM

LINKARP MACRO
        exg.l   A6,ArpBase
        jsr     _LVO\1(A6)
        exg.l   A6,ArpBase
        ENDM

LINKINT MACRO
        exg.l   A6,IntuitBase
        jsr     _LVO\1(A6)
        exg.l   A6,IntuitBase
        ENDM

LINKICN MACRO
        exg.l   A6,IconBase
        jsr     _LVO\1(A6)
        exg.l   A6,IconBase
        ENDM

MiniBrowser:
        move.l  AbsExecBase,a6
        move.l  #(WorkSize-1)/4,D1
ClearLoop:
        clr.l   -(A7)
        dbra    D1,ClearLoop
        move.l  A7,GlobData
        move.l  ThisTask(A6),HostTask(GlobData)
        lea     FR(GlobData),FileRData
        lea     Directory(GlobData),A1
        move.l  A1,fr_Dir(FileRData)
        lea     FileName(GlobData),A1
        move.l  A1,fr_File(FileRData)
        move.l  A0,A2
        move.l  D0,D2
        lea     arpName(pc),A1
        moveq.l  #AVersion,D0
        LINKEXE OpenLibrary
        move.l  D0,ArpBase
        beq     NoArp
        lea     intuitName(pc),A1
        moveq.l  #LVersion,D0
        LINKARP ArpOpenLibrary
        move.l  D0,IntuitBase
        lea     DefTitle(PC),A0
        move.l  A0,Title(GlobData)
        move.l  A2,A0
        move.l  D2,D0
        bsr     Parse
        move.l  Title(GlobData),fr_Hail(FileRData)
        tst.b   HotKey_RAW(GlobData)
        beq     DoOnce
        bsr     InstallHandler
WaitLoop:
        move.l  WakeUpSig(GlobData),D0
        or.l    #CTRL_CFlag,D0
        LINKEXE Wait
        move.l  D0,D1
        and.l   #CTRL_CFlag,D0
        bne     CleanUp
        and.l   WakeUpSig(GlobData),D1
        beq     WaitLoop
DoOnce:
        bsr     GetFile
        tst.b   HotKey_RAW(GlobData)
        bne     WaitLoop
CleanUp:
        tst.l   WBMsg(GlobData)
        beq     NotWBLaunch
        LINKEXE Forbid
        move.l  WBMsg(GlobData),A1
        LINKEXE ReplyMsg
NotWBLaunch:
        bsr     RemHandler
        move.l  ArpBase,A1
        move.l  A1,D0
        beq     NoArp
        LINKEXE CloseLibrary
NoArp:
        move.l  GlobData,A7
        add.l   #((WorkSize+3)/4)*4,A7
        rts
;****************************************
GetFile:
        tst.l   IntuitBase
        beq.s   NoSwap
        move.l  IntuitBase,A1
        move.l  ib_FirstScreen(a1),D3
        LINKINT WBenchToFront
NoSwap:
        lea     FR(GlobData),A0
        LINKARP FileRequest
        move.l  D0,D4
        tst.l   IntuitBase
        beq.s   NoSwapBack
        move.l  IntuitBase,A1
        cmp.l   ib_FirstScreen(a1),D3
        beq.s   NoSwapBack
        LINKINT WBenchToBack
NoSwapBack:
        tst.l   D4
        beq     NoCommand
        lea     Directory(GlobData),A0
        lea     FullPath(GlobData),A1
DirMove:
        move.b  (A0)+,(A1)+
        bne     DirMove
        lea     FullPath(GlobData),A0
        lea     FileName(GlobData),A1
        LINKARP TackOn
        move.l  Command(GlobData),A0
        move.l  A0,D1
        beq     NoCommand
        lea     FormattedArgLine(GlobData),A1
        lea     FullPath(GlobData),A2
CommandMove:
        cmp.b   #'%',(A0)
        bne     NotCommand
        bsr     MoveFile
NotCommand:
        move.b  (A0)+,(A1)+
        bne     CommandMove
        subq    #1,A1
        move.l  A2,D0
        beq     GetFileDone
        move.b  #' ',(A1)+
        bsr     MoveFile
GetFileDone:
        lea     PCB(GlobData),A2
        tst.l   WBMsg(GlobData)
        beq     DoDefault
        lea     DefCon(PC),A0
        move.l  A0,pcb_Console(A2)
        move.b  #STDIO_Val,pcb_Control(A2)
DoDefault:
        lea     PCB(GlobData),A2
        lea     FormattedArgLine(GlobData),A0
        move.l  A0,A1
ArgLoop:
        tst.b   (A1)
        beq     NoArg
        cmp.b   #' ',(A1)+
        bne     ArgLoop
        clr.b   -1(A1)
ArgLoop2:
        tst.b   (A1)
        beq     NoArg
        cmp.b   #' ',(A1)+
        beq     ArgLoop2
        subq.l  #1,A1
        tst.b   (A1)
        bne     GotArg
NoArg:
        lea     NoArgLine(PC),A1
GotArg:
        move.l  #4000,pcb_StackSize(A2)
        LINKARP ASyncRun
        tst.l   D0
        beq     CleanUp
NoCommand:
        rts
;
MoveFile:
        move.b  (A2)+,(A1)+
        bne     MoveFile
        addq    #1,A0
        sub.l   A2,A2
        subq    #1,A1
        rts
;****************************************
Parse:
        move.l  HostTask(GlobData),A2
        tst.l   pr_CLI(A2)
        beq     WBParse
        lea     Help(PC),A1
        lea     ArgList(GlobData),A2
        lea     Templ(PC),A3
        LINKARP GADS
        move.l  HotKeyPtr(GlobData),A0
        bsr     SetKey
NoHotKey:
        tst.l   Title(GlobData)
        bne     GotTitle
        lea     DefTitle(PC),A0
        move.l  A0,Title(GlobData)
GotTitle:
        rts
;****************************************
WBParse:
        lea     pr_MsgPort(A2),A0
        LINKEXE WaitPort
        lea     pr_MsgPort(A2),A0
        LINKEXE GetMsg
        move.l  D0,WBMsg(GlobData)
        move.l  D0,A3
        move.l  sm_ArgList(A3),D0
        beq     CleanUp
        move.l  D0,A0
        move.l  wa_Lock(a0),D1
        move.l  wa_Name(A0),D3
        LINKARP CurrentDir
GetIcon:
        lea     iconName(pc),A1
        moveq.l  #LVersion,D0
        LINKEXE OpenLibrary
        move.l  D0,IconBase
        beq     \NoIconLib
        move.l  D3,A0
        LINKICN GetDiskObject
        move.l  D0,D3
        beq     \NoObject
        move.l  D3,A0
        move.l  do_ToolTypes(A0),D2
        move.l  D2,A0
        lea     COMTYPE(PC),A1
        LINKICN FindToolType
        tst.l   D0
        beq     \NoCom
        move.l  D0,A0
        lea     ComCopy(GlobData),A1
        move.l  A1,Command(GlobData)
\ComMove
        move.b  (A0)+,(A1)+
        bne     \ComMove
\NoCom
        lea     DefTitle(PC),A0
        move.l  A0,Title(GlobData)
        move.l  D2,A0
        lea     TITLETYPE(PC),A1
        LINKICN FindToolType
        tst.l   D0
        beq     \NoTitle
        move.l  D0,A0
        lea     TitleCopy(GlobData),A1
        move.l  A1,Title(GlobData)
\TitleMove
        move.b  (A0)+,(A1)+
        bne     \TitleMove
\NoTitle
        move.l  D2,A0
        lea     KEYTYPE(PC),A1
        LINKICN FindToolType
        tst.l   D0
        beq     \NoKey
        move.l  D0,A0
        bsr     SetKey
\NoKey
        move.l  D3,A0
        LINKICN FreeDiskObject
\NoObject
        move.l  IconBase,A1
        LINKEXE CloseLibrary
\NoIconLib
        rts
;****************************************
SetKey:
        move.l  A0,D0
        beq     \NoHotKey
        cmp.b   #'f',(A0)
        beq     \FnKey
        cmp.b   #'F',(A0)
        beq     \FnKey
        LINKARP Atol
        bra     \GotHotKey
\FnKey
        addq.l  #1,A0
        LINKARP Atol
        tst.l   D0
        ble     \NoHotKey
        cmp.b   #11,D0
        bpl     \NoHotKey
        add.b   #79,D0
\GotHotKey
        move.b  D0,HotKey_RAW(GlobData)
\NoHotKey
        rts
;****************************************
InstallHandler:
        moveq   #-1,d0
        LINKEXE AllocSignal
        move.b  d0,WakeUpSigNum(a5)
        cmp.b   #-1,d0
        beq     IHAbort
        moveq   #1,d1
        rol.l   d0,d1
        move.l  d1,WakeUpSig(a5)
        clr.l   D0
        move.l  D0,A0
        LINKARP CreatePort
        tst.l   d0
        beq     IHAbort

        lea     inputReqBlk(a5),a1      ; create I/O request block for
        move.b  #NT_MESSAGE,LN_TYPE(a1) ; communicating with input.device
        move.w  #IOSTD_SIZE,MN_LENGTH(a1)
        move.l  d0,MN_REPLYPORT(a1)

        lea     inputName(pc),a0        ; open input.device
        moveq   #0,d0
        moveq   #0,d1
        LINKEXE OpenDevice
        tst.l   d0
        bne     IHAbort

        lea     handlerStuff(a5),a0
        move.b  #61,LN_PRI(a0)          ; before Intuition !!
        lea     InputHandler(pc),a1
        move.l  a1,IS_CODE(a0)
        move.l  a5,IS_DATA(a0)

        lea     inputReqBlk(a5),a1      ; install ScrapBook's input handler
        move.l  a0,IO_DATA(a1)
        move.w  #IND_ADDHANDLER,IO_COMMAND(a1)
        LINKEXE DoIO
        rts
IHAbort:
        clr.b   HotKey_RAW(GlobData)
        rts
;****************************************
RemHandler:
        tst.b   HotKey_RAW(GlobData)
        beq     RHDone
        lea     inputReqBlk(a5),a1      ; remove our input handler
        lea     handlerStuff(a5),a0
        move.l  a0,IO_DATA(a1)
        move.w  #IND_REMHANDLER,IO_COMMAND(a1)
        move.l  MN_REPLYPORT(a1),d3
        LINKEXE DoIO

        lea     inputReqBlk(a5),a1      ; terminate access to input.device
        LINKEXE CloseDevice

        move.l  d3,A1
        LINKARP DeletePort
        clr.l   d0
        move.b  WakeUpSigNum(a5),d0
        LINKEXE FreeSignal
RHDone:
        rts
;****************************************
InputHandler:
        movem.l a0/a4/a5/a6,-(sp)
        move.l  AbsExecBase,a6
        move.l  a0,a4
        move.l  a1,a5                   ; work area pointer always in a5!
IHLoop:
        cmpi.b  #IECLASS_RAWKEY,ie_Class(a4)
        bne     IHNextEvent
        move.w  ie_Qualifier(a4),d0 ; get the qualifiers into D0
        and.w   #IEQUALIFIER_LCOMMAND,d0 ; keep only the ones we care about
        beq     IHNextEvent
        sub.l   d1,d1
        move.b  HotKey_RAW(a5),d1
        cmp.w   ie_Code(a0),d1
        bne     IHNextEvent
        move.l  WakeUpSig(a5),d0
        move.l  HostTask(a5),a1
        LINKEXE Signal
        move.b  #IECLASS_NULL,ie_Class(a4)
IHNextEvent:
        move.l  ie_NextEvent(a4),d0
        move.l  d0,a4
        bne     IHLoop
IHEnd:
        movem.l (sp)+,d0/a4/a5/a6
        rts
;****************************************

DefTitle        dc.b    'MicroBrowser 1.2',0
arpName         dc.b    'arp.library',0
intuitName      dc.b    'intuition.library',0
iconName        dc.b    'icon.library',0
inputName       dc.b    'input.device',0
Templ           dc.b    'COM/K,TITLE/K,KEY/K',0
NoArgLine       dc.b    10,0
Help            dc.b    'Please read the documentation!',00
COMTYPE         dc.b    'COM',0
TITLETYPE       dc.b    'TITLE',0
KEYTYPE         dc.b    'KEY',0
DefCon          dc.b    'con:0/10/640/90/MicroBrowser',0
    END












