                opt     l+,o+,ow-
*
*   extdos.s vesion 7.6 - © Copyright 1990 Jaba Development
*
*   Author    : Jan van den Baard
*   Assembler : Devpac version 2.14
*
*

                incdir  'sys:devpac_inc/'
                include 'mymacros.i'
                include 'libraries/dos_lib.i'
                include 'exec/exec_lib.i'
                include 'tool.i'

                xref    _DOSBase

                xref    StrCpy
                xref    InitMemoryChain
                xref    AllocItem
                xref    FreeMemoryChain

                xdef    IoErrToStr
                xdef    OpenDir
                xdef    GetEntry
                xdef    CloseDir
                xdef    FreeDir

OpenDir:        movem.l d2-d3/a2-a3/a6,-(sp)
                move.l  a0,a2
                move.l  a1,a3
                NEWLIST a2
                lea.l   dr_DirMem(a2),a0
                move.l  #DIRBLOCK,d0
                bsr     InitMemoryChain
                lea.l   dr_DirMem(a2),a0
                move.l  #fib_SIZEOF,d0
                moveq   #MEMF_PUBLIC,d1
                bsr     AllocItem
                move.l  d0,d3
                move.l  d0,dr_InfoBlock(a2)
                beq.s   OpenErr
                move.l  _DOSBase,a6
                move.l  a3,d1
                move.l  #ACCESS_READ,d2
                libcall Lock
                move.l  d0,dr_Lock(a2)
                beq.s   OpenErr
                move.l  d0,d1
                move.l  d3,d2
                libcall Examine
                tst.l   d0
                beq.s   OpenErr
                move.l  d3,a0
                tst.l   fib_DirEntryType(a0)
                blt.s   OpenErr
                clr.l   dr_NumEntries(a2)
                moveq   #1,d0
                bra.s   EndOD
OpenErr:        lea.l   dr_DirMem(a2),a0
                bsr     FreeMemoryChain
                move.l  dr_Lock(a2),d1
                beq.s   NoLck
                libcall UnLock
NoLck:          clr.l   dr_Lock(a2)
                moveq   #0,d0
EndOD:          movem.l (sp)+,d2-d3/a2-a3/a6
                rts

GetEntry:       movem.l d2-d3/a2-a3/a6,-(sp)
                move.l  a0,a2
                move.l  dr_InfoBlock(a2),d3
                move.l  _DOSBase,a6
                move.l  dr_Lock(a2),d1
                move.l  d3,d2
                libcall ExNext
                beq.s   NoNext
                lea.l   dr_DirMem(a2),a0
                move.l  #ei_SIZEOF,d0
                moveq   #MEMF_PUBLIC,d1
                bsr     AllocItem
                move.l  d0,a3
                beq     NextErr
                move.l  d3,a0
                tst.l   fib_DirEntryType(a0)
                blt.s   IsFile
                move.w  #ENTRY_DIR,ei_Type(a3)
                bra.s   HaveType
IsFile:         move.w  #ENTRY_FILE,ei_Type(a3)
HaveType:       move.l  fib_Size(a0),ei_SizeBytes(a3)
                move.l  fib_NumBlocks(a0),ei_SizeBlocks(a3)
                move.l  fib_Protection(a0),ei_ProtectionBits(a3)
                lea.l   fib_FileName(a0),a1
                lea.l   ei_Name(a3),a0
                bsr     StrCpy
                move.l  d3,a0
                lea.l   fib_DateStamp(a0),a0
                move.l  ds_Days(a0),ei_Date+ds_Days(a3)
                move.l  ds_Minute(a0),ei_Date+ds_Minute(a3)
                move.l  ds_Tick(a0),ei_Date+ds_Tick(a3)
                inc.l   dr_NumEntries(a2)
                move.l  a2,a0
                move.l  a3,a1
                ADDTAIL
                move.l  a3,d0
                bra.s   EndGN
NoNext:         libcall IoErr
                cmp.l   #ERROR_NO_MORE_ENTRIES,d0
                bne.s   NextErr
                move.l  dr_Lock(a2),d1
                libcall UnLock
                clr.l   dr_Lock(a2)
                cldat   d0
                bra.s   EndGN
NextErr:        move.l  dr_Lock(a2),d1
                libcall UnLock
                clr.l   dr_Lock(a2)
                lea.l   dr_DirMem(a2),a0
                bsr     FreeMemoryChain
                cldat   d0
EndGN:          movem.l (sp)+,d2-d3/a2-a3/a6
                rts

CloseDir:       movem.l a2/a6,-(sp)
                move.l  a0,a2
                move.l  _DOSBase,a6
                move.l  dr_Lock(a2),d1
                beq.s   NoClose
                libcall UnLock
                clr.l   dr_Lock(a2)
NoClose:        movem.l (sp)+,a2/a6
                rts

FreeDir:        move.l  a2,-(sp)
                move.l  a0,a2
                bsr     CloseDir
                lea.l   dr_DirMem(a0),a0
                bsr     FreeMemoryChain
                NEWLIST a2
                clr.l   dr_NumEntries(a2)
                move.l  (sp)+,a2
                rts



*
* makes a call to "IoErr" and returns a pointer to a string
* which explains the occured error. If IoErr didn't return
* one of the error codes listed below NULL is returned!
*
IoErrToStr:     move.l  a6,-(sp)
                move.l  _DOSBase,a6
                libcall IoErr           ; what seem's to be the trouble ?
                lea.l   ErrTab,a0       ; get the ErrorTable in a0
GetStr:         move.l  (a0)+,d1        ; scan the table for the error
                blt.s   GotIT           ; end of the table ?
                cmp.l   d0,d1           ; found the error code ?
                beq.s   GotIT
                addq.w  #4,a0           ; increase table pointer
                bra.s   GetStr          ; loop
GotIT:          move.l  (a0),d0         ; return a pointer to the error string
EndIOE:         move.l  (sp)+,a6
                rts

*
* ASCII versions of the "IoErr" return codes
*
err1:           dc.b    '103: Insufficient free store.',0
err2:           dc.b    '105: Task table full.',0
err3:           dc.b    '120: Argument line invalid or too long.',0
err4:           dc.b    '121: File is not an object module.',0
err5:           dc.b    '122: Invalid resident library during load.',0
err6:           dc.b    '202: Object in use.',0
err7:           dc.b    '203: Object already exists.',0
err8:           dc.b    '204: Directory not found.',0
err9:           dc.b    '205: Object not found.',0
err10:          dc.b    '206: Invalid window.',0
err11:          dc.b    '209: Packet request type unknown.',0
err12:          dc.b    '210: Invalid stream component name.',0
err13:          dc.b    '211: Invalid object lock.',0
err14:          dc.b    '212: Object not of required type.',0
err15:          dc.b    '213: Disk not validated.',0
err16:          dc.b    '214: Disk write protected.',0
err17:          dc.b    '215: Rename across devices attempted.',0
err18:          dc.b    '216: Directory not empty.',0
err19:          dc.b    '218: Device not mounted.',0
err20:          dc.b    '219: Seek error.',0
err21:          dc.b    '220: Comment too big.',0
err22:          dc.b    '221: Disk full.',0
err23:          dc.b    '222: File is protected from deletion.',0
err24:          dc.b    '223: File is protected from writing.',0
err25:          dc.b    '224: File is protected from reading.',0
err26:          dc.b    '225: Not a DOS disk.',0
err27:          dc.b    '226: No disk in drive.',0
err28:          dc.b    '232: No more entries in directory.',0

                even
*
* A table in the form "error_code,pointer_to_error_string,...."
*
ErrTab:         dc.l    103,err1,105,err2,120,err3,121,err4,122,err5
                dc.l    202,err6,203,err7,204,err8,205,err9,206,err10
                dc.l    209,err11,210,err12,211,err13,212,err14,213,err15
                dc.l    214,err16,215,err17,216,err18,218,err19,219,err20
                dc.l    220,err21,221,err22,222,err23,223,err24,224,err25
                dc.l    225,err26,226,err27,232,err28,-1,0


