;* $Revision Header built automatically *************** (do not edit) ************
;*
;* © Copyright by (none)
;*
;* File             : AskFile.asm
;* Created on       : Monday, 14.02.94 10:01:32
;* Created by       : Arnold Schommer
;* Current revision : V1.3
;*
;*
;* Purpose
;* -------
;*   - Opens an ASL-FileRequester and asks for a filename.
;*     The result is stored in a variable (local or ENV:).
;*
;* Revision V1.3
;* --------------
;* created on Sunday, 20.02.94 20:36:56  by  Arnold Schommer.   LogMessage :
;*   - returns quickly if started from WB (does not even open
;*     dos.library etc.)
;*
;* Revision V1.2
;* --------------
;* created on Tuesday, 15.02.94 10:30:46  by  Arnold Schommer.   LogMessage :
;*   - now fully resident (uses about 1K of vars on stack)
;*
;* Revision V1.1
;* --------------
;* created on Tuesday, 15.02.94 09:34:34  by  Arnold Schommer.   LogMessage :
;*   - now reentrant
;*
;* Revision V1.0
;* --------------
;* created on Monday, 14.02.94 10:01:32  by  Arnold Schommer.   LogMessage :
;*     --- Initial release ---
;*
;*********************************************************************************
REVISION  MACRO
          dc.b "1.3"
          ENDM
REVDATE   MACRO
          dc.b "20.02.94"
          ENDM
REVTIME   MACRO
          dc.b "20:36:56"
          ENDM
AUTHOR    MACRO
          dc.b "Arnold Schommer"
          ENDM
VERNUM    EQU  1
REVNUM    EQU  3
NAME      MACRO
          dc.b "AskFile"
          ENDM
****************************************************************************
TEMPLATE: macro
        dc.b    "VAR=VARNAME/A,LOCAL/S,QUESTION=TITLE/A,CONFIRM/K,CANCEL/K,"
        dc.b    "NO_OLD=BLANK/S,FILE/K,DIR/K,NOFILES/S,SAVE/S,PATTERN/K,"
        dc.b    "PATTERN_GADGET=PATGG/S",0
        endm
****************************************************************************
        NOLIST
        INCLUDE "exec/LVO.i"
        INCLUDE "exec/libraries.i"
        INCLUDE "dos/LVO.i"
        INCLUDE "dos/dos.i"
        INCLUDE "dos/dosextens.i"
        INCLUDE "dos/rdargs.i"
        INCLUDE "dos/var.i"
        INCLUDE "libraries/asl.i"
        INCLUDE "libraries/asl_LVO.i"
        INCLUDE "utility/tagitem.i"

DOS:    MACRO
        move.l  _DosBase(a4),a6
        CALL    \1
        ENDM
XASL:   MACRO
        move.l  _AslBase(a4),a6
        CALL    \1
        ENDM
        LIST
****************************************************************************
;Rahmen-Programm, welches die Libraries öffnet und eine ordnungsgemäße
;Rückkehr gewährleistet:

        CODE
; eigene Variablen auf dem Stack anlegen
; (es sind nur etwa 1K, also durchaus akzeptabel)
        lea     -SIZE_data(sp),sp
        move.l  sp,a4
        move.l  sp,FrameSP(a4)
        moveq   #0,d0
        move.l  d0,_DosBase(a4)
        move.l  d0,_AslBase(a4)
        move.l  d0,RetCode(a4)
        move.l  d0,readargs(a4)
        move.l  d0,FRQ(a4)
        sub.l   a1,a1           ;a1=0->eigener Task
        CALLEXEC FindTask       ;Wo darf man denn nachschauen ?
        move.l  d0,a3
        tst.l   pr_CLI(a3)      ;von CLI oder WB aus gestartet ?
        bne     fromCLI
;von WB aus: ist nicht vorgesehen (keine Parameterübergabe), also Abbruch
        lea     pr_MsgPort(a3),a0
        CALL    WaitPort        ;auf Start-Message warten
        lea     pr_MsgPort(a3),a0
        CALL    GetMsg
        move.l  d0,-(sp)        ;Startup-Message sichern
;Message zur WB zurück
        CALLEXEC Forbid
        move.l  (sp)+,a1
        CALL    ReplyMsg
        lea     SIZE_data(a4),sp
        moveq   #RETURN_FAIL,d0
        rts
;Libraries öffnen:
fromCLI: OPENLIB DosName(pc)
        move.l  d0,_DosBase(a4)
        bne     1$
;Fehler: KEINE dos.library !?!
        moveq   #RETURN_FAIL,d0
        bra     _exit
1$:     move.l  d0,a0
        cmp.w   #37,LIB_VERSION(a0)
        bge     2$
;Fehler: alte Dos-Library
        move.l  d0,a6
        CALL    Output
        move.l  d0,d1
        lea     error_olddos(pc),a0
        move.l  a0,d2
        moveq   #SIZE_error_olddos,d3
        CALL    Write
        moveq   #RETURN_ERROR,d0
        bra     _exit
2$:     OPENLIB AslName(pc),36
        move.l  d0,_AslBase(a4)
        bne     4$
;Fehler: keine Asl-Library
        lea     error_noasl(pc),a0
        bra     _error
;Das Hauptprogramm aufrufen:
4$:     bsr     main
        moveq   #RETURN_OK,d0
_exit:  move.l  d0,RetCode(a4)
        move.l  FrameSP(a4),sp
;Freigabe der RDArgs-Struktur
        move.l  readargs(a4),d1
        beq     1$
        DOS     FreeArgs
;Freigabe des FileRequesters
1$:     move.l  FRQ(a4),d0
        beq     2$
        move.l  d0,a0
        XASL    FreeAslRequest
;die Libraries schließen
2$:     move.l  _AslBase(a4),d0
        beq     CloseDos
        CLOSELIB d0
CloseDos: move.l _DosBase(a4),d0
        beq     ende
        CLOSELIB d0
;und wieder zurück
ende:   move.l  RetCode(a4),d0
        lea     SIZE_data(a4),sp
        rts
****************************************************************************
;Versions-String
        dc.b    "$VER: "
        NAME
        dc.b    " "
        REVISION
        dc.b    " ("
        REVDATE
        dc.b    ")",0
        even
****************************************************************************
;Fehler-Ausstieg speziell für Dos-Fehler, die über IoErr() identifiziert
;werden.
_io_error:
        DOS     IoErr
        move.l  d0,d1
        moveq   #0,d2
        move.l  #Var,d3
        add.l   a4,d3
        move.l  #514,d4
        CALL    Fault
        lea     Var(a4),a0
;        bra     _error
****************************************************************************
;Fehler-Ausstieg:
_error: move.l  a0,-(sp)
        move.l  sp,d2
        lea     error_any(pc),a0
        move.l  a0,d1
        DOS     VPrintf
        moveq   #RETURN_ERROR,d0
        bra     _exit
****************************************************************************
main:
;Argumenten-Array löschen
        moveq   #0,d0
        moveq   #NARGS-1,d1
        lea     rargs(a4),a0
1$:     move.l  d0,(a0)+
        dbra    d1,1$
;Parsen lassen
        lea     Template(pc),a0
        move.l  a0,d1
        move.l  #rargs,d2
        add.l   a4,d2
        moveq   #0,d3
        DOS     ReadArgs
        move.l  d0,readargs(a4)
        beq     _io_error
        moveq   #0,d0
        move.b  d0,FileName(a4)
        move.b  d0,DirName(a4)
        tst.l   ARG_DONT_READ(a4)
        bne     dont_read
;genannte Variable auslesen
        move.l  ARG_VARNAME(a4),d1
        move.l  #Var,d2
        add.l   a4,d2
        move.l  #514,d3
        moveq   #LV_VAR,d4
        tst.l   ARG_VARTYPE(a4)
        bne     2$
        move.l  #GVF_GLOBAL_ONLY|LV_VAR,d4
2$:     DOS     GetVar
        cmp.l   #513,d0
        ble     3$
        lea     error_big_var(pc),a0
        bra     _error
3$:     move.l  #Var,d1
        add.l   a4,d1
        CALL    FilePart
        move.l  d0,a0
        bsr     SetFilePreset
        move.l  #Var,d1
        add.l   a4,d1
        CALL    PathPart
        move.l  d0,a0
        move.b  #0,(a0)
        lea     Var(a4),a0
        bsr     SetDirPreset
dont_read:
        lea     ARG_FILE_PRESET(a4),a0
        bsr     SetFilePreset
        lea     ARG_DIR_PRESET(a4),a0
        bsr     SetDirPreset
;Tag-Liste für FRQ aufbauen:
        lea     FRQ_Tags(a4),a2
        move.l  #ASL_Hail,(a2)+
        move.l  ARG_QUESTION(a4),(a2)+
        lea     FileName(a4),a0
        tst.b   (a0)
        beq     4$
        move.l  #ASL_File,(a2)+
        move.l  a0,(a2)+
4$:     lea     DirName(a4),a0
        tst.b   (a0)
        beq     5$
        move.l  #ASL_Dir,(a2)+
        move.l  a0,(a2)+
5$:     move.l  ARG_OK_TEXT(a4),d0
        beq     6$
        move.l  #ASL_OKText,(a2)+
        move.l  d0,(a2)+
6$:     move.l  ARG_CANCEL_TEXT(a4),d0
        beq     7$
        move.l  #ASL_CancelText,(a2)+
        move.l  d0,(a2)+
7$:     tst.l   ARG_SELECT_DIR(a4)
        beq     8$
        move.l  #ASL_ExtFlags1,(a2)+
        move.l  #FIL1F_NOFILES,(a2)+
8$:     tst.l   ARG_SAVEFLAG(a4)
        beq     9$
        move.l  #ASL_FuncFlags,(a2)+
        move.l  #FILF_SAVE,(a2)+
9$:     tst.l   ARG_PATGAD(a4)
        beq     10$
;das neue Flag ggf. über das gerade geschriebene hinüber-odern:
        move.l  #ASL_FuncFlags,d0
        move.l  #FILF_PATGAD,d1
        cmp.l   -8(a2),d0
        beq     12$
        move.l  d0,(a2)+        ;neu schreiben
        move.l  d1,(a2)+
        bra     10$
12$:    or.l    d1,-4(a2)       ;odern
10$:    move.l  ARG_PATTERN(a4),d0
        beq     11$
        move.l  #ASL_Pattern,(a2)+
        move.l  d0,(a2)+
11$:    move.l  #TAG_END,(a2)

;FileRequester allozieren
        move.l  #ASL_FileRequest,d0
        lea     FRQ_Tags(a4),a0
        XASL    AllocAslRequest
        move.l  d0,FRQ(a4)
        bne     do_frq
;Fehler: kein Filerequester
        lea     error_nofrq(pc),a0
        bra     _error

;FileRequester aufrufen:
do_frq: move.l  d0,a0
        CALL    RequestFile
        tst.l   d0
        beq     ret_warn
;File/Pfad ausgewählt: zusammensetzen
        lea     Var(a4),a1
        move.b  #0,(a1)
        move.l  FRQ(a4),a0
        move.l  rf_Dir(a0),d0
        beq     nodir
;Pfadnamen kopieren
        move.l  d0,a0
1$:     move.b  (a0)+,(a1)+
        bne     1$
;Dateinamen anhängen ?
nodir:  tst.l   ARG_SELECT_DIR(a4)
        bne     setvar                  ;es sollte keine Datei gewählt werden
        move.l  FRQ(a4),a0
        move.l  rf_File(a0),d2
        beq     setvar
        move.l  d2,a0
        tst.b   (a0)
        beq     setvar
        move.l  #Var,d1
        add.l   a4,d1
        move.l  #513,d3
        DOS     AddPart
        tst.l   d0
        beq     longfname
;Dateinamen in Variable schreiben
setvar: move.l  ARG_VARNAME(a4),d1
        move.l  #Var,d2
        add.l   a4,d2
        moveq   #-1,d3
        moveq   #LV_VAR,d4
        tst.l   ARG_VARTYPE(a4)
        bne     1$
        move.l  #GVF_GLOBAL_ONLY|LV_VAR,d4
1$:     CALL    SetVar
        tst.l   d0
        beq     _io_error
        rts
;Dateiname war zu lang -> Text & exit(RETURN_WARN);
longfname:
        lea     warning_longfname(pc),a0
        move.l  a0,d1
        DOS     PutStr
ret_warn:
        moveq   #RETURN_WARN,d0
        bra     _exit
****************************************************************************
SetFilePreset:
        lea     WarningFNPreset(pc),a1
        move.l  a1,d1
        lea     FileName(a4),a1
        bra     SetAnyPreset
****************************************************************************
SetDirPreset:
        lea     WarningDNPreset(pc),a1
        move.l  a1,d1
        lea     DirName(a4),a1
SetAnyPreset:
        move.l  a0,d0
        beq     1$
        tst.b   (a0)
        beq     1$              ;leer-Strings werden NICHT kopiert !
        moveq   #0,d0
2$:     tst.b   0(a0,d0.l)
        beq     strcpy          ;String-Ende ?
        addq.b  #1,d0
        bvc     2$              ;Länge >255 -> Überlauf ?
        DOS     PutStr
1$:     rts
strcpy: move.b  (a0)+,(a1)+
        bne     strcpy
        rts
****************************************************************************
AslName: ASLNAME
DosName: DOSNAME

;verschiedene Fehler-Texte:
error_olddos:
        NAME
        dc.b ": dos.library v37+ required",10
SIZE_error_olddos: equ *-error_olddos
error_any:
        NAME
        dc.b ": %s",10,0
error_noasl:    dc.b "asl.library v36+ required",0
error_big_var:  dc.b "variable too big",0
error_nofrq:    dc.b "Filerequester not available !",0

WarningDNPreset:
        NAME
        dc.b ": preset for filename too long",10,0
WarningFNPreset:
        NAME
        dc.b ": preset for dirname too long",10,0
warning_longfname:
        NAME
        dc.b ": new filename too long",10,0

Template:       TEMPLATE
****************************************************************************
;Definition der eigenen Variablen:

FrameSP:        equ 0
RetCode:        equ FrameSP+4
_AslBase:       equ RetCode+4
_DosBase:       equ _AslBase+4
readargs:       equ _DosBase+4
FRQ:            equ readargs+4
rargs:          equ FRQ+4
ARG_VARNAME:    equ rargs
ARG_VARTYPE:    equ ARG_VARNAME+4
ARG_QUESTION:   equ ARG_VARTYPE+4
ARG_OK_TEXT:    equ ARG_QUESTION+4
ARG_CANCEL_TEXT: equ ARG_OK_TEXT+4
ARG_DONT_READ:  equ ARG_CANCEL_TEXT+4
ARG_FILE_PRESET: equ ARG_DONT_READ+4
ARG_DIR_PRESET: equ ARG_FILE_PRESET+4
ARG_SELECT_DIR: equ ARG_DIR_PRESET+4
ARG_SAVEFLAG:   equ ARG_SELECT_DIR+4
ARG_PATTERN:    equ ARG_SAVEFLAG+4
ARG_PATGAD:     equ ARG_PATTERN+4
FRQ_Tags:       equ ARG_PATGAD+4
NARGS:          equ (FRQ_Tags-rargs)/4
Var:            equ FRQ_Tags+(NARGS*8)
FileName:       equ Var+514
DirName:        equ FileName+256
SIZE_data:      equ DirName+256

        END
