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

_LVOExecute                                 EQU  -222
_LVOGADS                                    EQU  -252
_LVOAtol                                    EQU  -258
_LVOFileRequest                             EQU  -294
_LVOCreatePort                              EQU  -306
_LVODeletePort                              EQU  -312
_LVOTackOn                                  EQU  -624
_LVOWBenchToBack                            EQU  -336
_LVOWBenchToFront                           EQU  -342
_LVOWait                                    EQU  -318
_LVOSignal                                  EQU  -324
_LVOAllocSignal                             EQU  -330
_LVOFreeSignal                              EQU  -336
_LVOCloseLibrary                            EQU  -414
_LVOOpenLibrary                             EQU  -552
_LVOOpenDevice                              EQU  -444
_LVOCloseDevice                             EQU  -450
_LVODoIO                                    EQU  -456

FCHARS          EQU     32
DSIZE           EQU     33

CTRL_CFlag      EQU     $01000  ;
NULL            EQU     0
HotKey          EQU     $059
AbsExecBase     EQU     $4
LVersion        EQU     31
AVersion        EQU     34

        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 WorkSpace,0                ; Data stored on stack
        ULONG   WakeUpSig
        UBYTE   WakeUpSigNum
        UBYTE   HotKey_RAW
        APTR    HostTask
        STRUCT  ArgList,0
        APTR    Command
        APTR    Title
        APTR    HotKeyPtr
        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
        LABEL   WorkSize                ; Size of Stack Data

LINKDOS MACRO
        jsr     _LVO\1(a6)
        ENDM

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

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

MiniBrowser:
        move.l  AbsExecBase,a6
        move.l  #(WorkSize-1)/4,D1
ClearLoop:
        clr.l   -(A7)
        dbra    D1,ClearLoop
        move.l  A7,A5
        move.l  ThisTask(A6),HostTask(A5)
        lea     FR(A5),A4
        lea     Directory(A5),A1
        move.l  A1,fr_Dir(A4)
        lea     FileName(A5),A1
        move.l  A1,fr_File(A4)
        move.l  A0,A2
        move.l  D0,D2
        lea     arpName(pc),A1
        moveq.l  #AVersion,D0
        LINKDOS OpenLibrary
        beq     NoArp
        move.l  D0,D7
        lea     intuitName(pc),A1
        moveq.l  #LVersion,D0
        LINKDOS OpenLibrary
        move.l  D0,D6
        move.l  A2,A0
        move.l  D2,D0
        bsr     Parse
        move.l  Title(A5),fr_Hail(A4)
        tst.b   HotKey_RAW(A5)
        beq     DoOnce
        bsr     InstallHandler
WaitLoop:
        move.l  WakeUpSig(A5),D0
        or.l    #CTRL_CFlag,D0
        LINKDOS Wait
        move.l  D0,D1
        and.l   #CTRL_CFlag,D0
        bne     CleanUp
        and.l   WakeUpSig(A5),D1
        beq     WaitLoop
        bsr     GetFile
        beq     WaitLoop
        lea     FormattedArgLine(A5),A0
        move.l  A0,D1
        clr.l   D2
        clr.l   D3
        LINKARP Execute
        bra     WaitLoop
DoOnce:
        bsr     GetFile
        beq     CleanUp
        lea     FormattedArgLine(A5),A0
        move.l  A0,D1
        clr.l   D2
        clr.l   D3
        LINKARP Execute
CleanUp:
        bsr     RemHandler
        move.l  D6,A1
        move.l  A1,D0
        beq     Nointuit
        LINKDOS CloseLibrary
Nointuit:
        move.l  D7,A1
        move.l  A1,D0
        beq     NoArp
        LINKDOS CloseLibrary
NoArp:
        move.l  A5,A7
        add.l   #((WorkSize+3)/4)*4,A7
        rts
;****************************************
GetFile:
        tst.l   D6
        beq.s   NoSwap
        move.l  D6,A1
        move.l  ib_FirstScreen(a1),D4
        LINKINT WBenchToFront
NoSwap:
        lea     FR(A5),A0
        LINKARP FileRequest
        move.l  D0,D5
        tst.l   D6
        beq.s   NoSwapBack
        move.l  D6,A1
        cmp.l   ib_FirstScreen(a1),D4
        beq.s   NoSwapBack
        LINKINT WBenchToBack
NoSwapBack:
        tst.l   D5
        beq     NoCommand
        lea     Directory(A5),A0
        lea     FullPath(A5),A1
DirMove:
        move.b  (A0)+,(A1)+
        bne     DirMove
        lea     FullPath(A5),A0
        lea     FileName(A5),A1
        LINKARP TackOn
        move.l  Command(A5),A0
        move.l  A0,D1
        beq     NoCommand
        lea     FormattedArgLine(A5),A1
        lea     FullPath(A5),A2
        lea     RunBack(PC),A3
        tst.b   HotKey_RAW(A5)
        beq     CommandMove
RBMove:
        move.b  (A3)+,(A1)+
        bne     RBMove
        subq    #1,A1
CommandMove:
        cmp.b   #'%',(A0)
        bne     NotCommand
        bsr     MoveFile
NotCommand:
        move.b  (A0)+,(A1)+
        bne     CommandMove
        move.l  A2,D0
        beq     GetFileDone
        bsr     MoveFile
GetFileDone:
        move.b  #0,(A1)
        moveq   #1,D1
NoCommand:
        rts
;
MoveFile:
        move.b  #' ',-1(A1)
FileMoveLoop:
        move.b  (A2)+,(A1)+
        bne     FileMoveLoop
        addq    #1,A0
        sub.l   A2,A2
        move.b  #' ',(A1)+
        rts
;****************************************
Parse:
        lea     DefTitle(PC),A1
        move.l  A1,Title(A5)
        lea     Help(PC),A1
        lea     ArgList(A5),A2
        lea     Templ(PC),A3
        LINKARP GADS
        move.l  HotKeyPtr(A5),A0
        move.l  A0,D0
        beq     NoHotKey
        LINKARP Atol
        beq     NoHotKey
        move.b  D0,HotKey_RAW(A5)
NoHotKey:
        tst.l   Title(A5)
        bne     NoTitle
        lea     DefTitle(PC),A0
        move.l  A0,Title(A5)
NoTitle:
        rts
;****************************************
InstallHandler:
        moveq   #-1,d0
        LINKDOS 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
        LINKDOS 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)
        LINKDOS DoIO
        rts
IHAbort:
        clr.b   HotKey_RAW(A5)
        rts
;****************************************
RemHandler:
        tst.b   HotKey_RAW(A5)
        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
        LINKDOS DoIO

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

        move.l  d3,A1
        LINKARP DeletePort
        clr.l   d0
        move.b  WakeUpSigNum(a5),d0
        LINKDOS 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
        LINKDOS 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.1',0
arpName         dc.b    'arp.library',0
inputName       dc.b    'input.device',0
intuitName      dc.b    'intuition.library',0
Templ           dc.b    'COM,TITLE/K,KEY/K',0
RunBack         dc.b    'run <nil: >nil: ',0
Help            dc.b    'Read the documentation!',00
                END


