home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 182.lha / Ls_v2.1 / lssup.a < prev   
Text File  |  1988-04-28  |  22KB  |  835 lines

  1. * --------------------------------------------------------------------- *
  2. * LSSUP.A    - Assembly support routines for ls.c            *
  3. * Copyright © 1988 by Justin V. McCormick. All Rights Reserved.        *
  4. * --------------------------------------------------------------------- *
  5.     IDNT    "lssup.a"
  6.  
  7.     include "asm:inc/macros.i"
  8.  
  9. ; Assembler options for CAPE
  10.     BASEREG    B
  11.     SMALLOBJ
  12. ;    OPTIMON
  13. ;    ADDSYM
  14. ;    DEBUG
  15.  
  16. ; Equates
  17. fib_FileName    equ    $8
  18. fib_Size    equ    $7C
  19. fib_NumBlocks    equ    $80
  20. fib_DateStamp    equ    $84
  21.  
  22. ds_Days        equ    $0
  23. ds_Minute    equ    $4
  24. ds_Tick        equ    $8
  25.  
  26. _LVOAddPort    equ    $FFFFFE9E
  27. _LVOAllocMem    equ    $FFFFFF3A
  28. _LVOAllocSignal    equ    $FFFFFEB6
  29. _LVODebug    equ    $FFFFFF8E
  30. _LVOFindTask    equ    $FFFFFEDA
  31. _LVOFreeMem    equ    $FFFFFF2E
  32. _LVOFreeSignal    equ    $FFFFFEB0
  33. _LVOGetMsg    equ    $FFFFFE8C
  34. _LVOPutMsg    equ    $FFFFFE92
  35. _LVORawDoFmt    equ    $FFFFFDF6
  36. _LVORemPort    equ    $FFFFFE98
  37. _LVORead    equ    $FFFFFFD6
  38. _LVOWaitPort    equ    $FFFFFE80
  39. _LVOWrite    equ    $FFFFFFD0
  40.  
  41. pr_ConsoleTask        EQU    $A4 
  42. MEMF_CLEAR        EQU    $10000 
  43. MEMF_PUBLIC        EQU    $1 
  44. sp_Msg            EQU    $0 
  45. sp_Pkt            EQU    $14 
  46. sp_SIZEOF        EQU    $44 
  47. dp_Link            EQU    $0 
  48. dp_Port            EQU    $4 
  49. dp_Arg1            EQU    $14 
  50. dp_Type            EQU    $8 
  51. ACTION_SCREEN_MODE    EQU    $3E2 
  52. LN_NAME            EQU    $A 
  53. LN_PRI            EQU    $9 
  54. LN_TYPE            EQU    $8 
  55. MP_FLAGS        EQU    $E 
  56. MP_MSGLIST        EQU    $14 
  57. MP_SIGBIT        EQU    $F 
  58. MP_SIGTASK        EQU    $10 
  59. MP_SIZE            EQU    $22 
  60. NT_MSGPORT        EQU    $4 
  61. PA_SIGNAL        EQU    $0 
  62.  
  63. * External constants
  64.     XREF    _DOSBase
  65.     XREF    _Out
  66.     XREF    _In
  67. * --------------------------------------------------------------------- *
  68.     SECTION    lssup,CODE
  69.  
  70. * ------------------------------------------------------------------------- *
  71. * void asprintf(wstr, formatstring, args)
  72. *   char *wstr;
  73. *   char *formatstring;
  74. *   char **args;
  75. * Synopsis: Given formatstring and args to format, formats output to wstr.
  76. * Similar to sprintf(), except doesn't handle floats.
  77. * ------------------------------------------------------------------------- *
  78.     XDEF    _asprintf
  79. _asprintf:
  80.     link    a5,#0
  81.     movem.l    d0-d2/a0-a3,-(sp)    ;Save everything we might clobber
  82.  
  83. * Call format function to convert fmtstring and args to buffer on the stack
  84.     movea.l    12(a5),a0        ;Grab format string
  85.     lea    16(a5),a1        ;Grab EA of arguments
  86.     lea    kput1,a2        ;Grab EA of output subroutine
  87.     movea.l    8(a5),a3        ;Grab EA of dest workspace
  88.     SYS    RawDoFmt,4        ;Format it into workspace
  89.  
  90.     movem.l    (sp)+,d0-d2/a0-a3    ;Restore registers
  91.     unlk    a5            ;And stack frame
  92.     rts
  93.  
  94. * ------------------------------------------------------------------------- *
  95. * RawDoFmt() output routine for xprintf, called for each formatted char.
  96. * Takes byte in d0 and puts in buffer pointed to by a3, then increments a3.
  97. * ------------------------------------------------------------------------- *
  98.     XDEF    kput1
  99. kput1:
  100.     move.b    d0,(a3)+
  101.     rts
  102.  
  103. * --------------------------------------------------------------------- *
  104. * void GetWinBounds(width, height)
  105. *   long *width, *height;
  106. *
  107. * Find current console window, determine width and height
  108. * in terms of current font, update width and height VPARMS passed.
  109. * --------------------------------------------------------------------- *
  110. rpstr    equ    -32
  111. rpport    equ    -12
  112. packet    equ    -8
  113. conid    equ    -4
  114.  
  115. width    equ    8
  116. height    equ    12
  117.  
  118.     XDEF    _GetWinBounds
  119. _GetWinBounds:
  120.     link    a5,#-32
  121.     movem.l    d2-d4/a2,-(sp)
  122.  
  123.     suba.l    a1,a1
  124.     SYS    FindTask,4        ;d0 = FindTask(0L), our process
  125.     movea.l    d0,a0            ;Transfer to address reg
  126.     move.l    pr_ConsoleTask(a0),conid(a5) ;Save proc->pr_ConsoleTask
  127.  
  128.     moveq    #0,d4            ;Clear our success status register
  129.  
  130.     moveq    #0,d0
  131.     movea.l    d0,a0
  132.     bsr.w    CreatePort
  133.     move.l    d0,rpport(a5)        ;rpport = CreatePort(0L, 0L)
  134.      beq.w    gwbdone            ;Oops, no signals or ram available!
  135.     move.l    #MEMF_PUBLIC+MEMF_CLEAR,d1
  136.     moveq    #sp_SIZEOF,d0
  137.     SYS    AllocMem
  138.     move.l    d0,packet(a5)        ;packet = AllocMem(sizeof(*packet),MEMF_PUBLIC|MEMF_CLEAR)
  139.      beq.w    gwbfreeport        ;Oops, no ram, free up port
  140.  
  141. * Okay, we got our process id, reply port, and packet
  142. * Now toggle the console into raw mode
  143.     movea.l    rpport(a5),a2
  144.     movea.l    d0,a1
  145.     movea.l    conid(a5),a0
  146.     moveq    #1,d0
  147.     bsr.w    SetConsoleType        ;SetConsoleType(1L, conid, packet, rpport)
  148.  
  149. * Request a window bounds report
  150.     moveq    #4,d3
  151.     lea    gwbrstr(a4),a0
  152.     move.l    a0,d2
  153.     move.l    _Out(a4),d1
  154.     SYS    Write,_DOSBase(a4)    ;Write(Output(), "\2330 q", 4L);
  155.     cmpi.l    #$0004,d0        ;Did the console choke on it?
  156.      bne.w    gwbsetcook        ;hmmm, see if we can back out gracefully
  157.  
  158. * Read the report string into stack buffer
  159.     moveq    #16,d3            ;Don't let it get longer than 16 characters
  160.     lea    rpstr(a5),a0        ;Point to input string area
  161.     move.l    a0,d2
  162.     move.l    _In(a4),d1
  163.     SYS    Read            ;Read(Input(), rpstr, 16L)
  164.     move.l    d0,d4            ;Save read length while we close shop
  165.  
  166. * Turn the console back to cooked mode pronto to avoid cursor blink
  167. gwbsetcook:
  168.     movea.l    rpport(a5),a2
  169.     movea.l    packet(a5),a1
  170.     movea.l    conid(a5),a0
  171.     moveq    #0,d0
  172.     bsr.w    SetConsoleType        ;SetConsoleType(0L, conid, packet, rpport)
  173.  
  174. * Release resources we borrowed
  175. gwbfreepack:
  176.     move.l    packet(a5),d0        ;Did we allocate a packet?
  177.      beq.b    gwbfreeport        ;nay, check for port to free
  178.     movea.l    d0,a1
  179.     moveq    #sp_SIZEOF,d0
  180.     SYS    FreeMem            ;Else FreeMem(packet, sizeof(*packet))
  181.  
  182. gwbfreeport:
  183.     move.l    rpport(a5),d0        ;if (rpport)...
  184.      beq.w    gwbdone            ;nope
  185.     bsr.w    DeletePort        ;Else DeletePort(rpport)
  186.  
  187. * Finally, sanity check window bounds report string
  188. * d4 = length of report string according to Read()
  189.     cmpi.l    #9,d4            ;Less than 8 characters returned?
  190.      ble.w    gwbdone            ;hmmm, phonky bounds report from DOS?
  191.     lea    rpstr(a5),a2        ;a2 = rpstr
  192.     cmpi.b    #';',4(a2)        ;Matches a typical report template?
  193.      bne.w    gwbdone            ;nope, got some weird junk back?
  194.     cmpi.b    #'r',-1(a2,d4.w)    ;Last byte is 'r' for report?
  195.      bne.w    gwbdone            ;Nope, message fubar!
  196.  
  197. * Parse the height and width variables from the field now
  198. * Our report format looks like this in hex:
  199. *     9b 31 3b 31 3b y2 y1 3b x2 x1 20 72
  200. * Or in ascii:
  201. *    <0x9b>1;1;20;77 r
  202. * Which would indicate a width of 77 cols and a height of 20 rows for
  203. * the current console device
  204. *
  205. * REGS:    a2 points to beginning of 'r' terminated string
  206.  
  207.     lea    5(a2),a2        ;Point to first char of Y size
  208.     moveq    #0,d1            ;Clear out work reg
  209.  
  210. * Convert ascii rows value to LONG, update host data
  211.     move.b    (a2)+,d1        ;Grab a Y
  212.     subi.w    #'0',d1            ;Less ascii offset
  213.     cmpi.b    #';',(a2)        ;Any more Y digits?
  214.      beq.b    1$            ;Nope
  215.     mulu    #10,d1            ;Else shift by 10
  216.     add.b    (a2)+,d1        ;Add least significant Y digit
  217.     subi.b    #'0',d1            ;Less ascii offset
  218.     cmpi.b    #';',(a2)        ;Any more Y digits?
  219.      beq.b    1$            ;Nope
  220.     mulu    #$000a,d1        ;Else shift by 10
  221.     add.b    (a2)+,d1        ;Add least significant Y digit
  222.     subi.b    #'0',d1            ;Less ascii offset
  223.                     ;We'll assume screen height < 999 rows    
  224. 1$
  225. * Convert ascii columns value to LONG, update host data
  226.     addq.w    #1,a2            ;Move past the ';' separator
  227.     moveq    #0,d2            ;Zap work reg
  228.     move.b    (a2)+,d2        ;Grab msd of X
  229.     cmpi.b    #' ',d2            ;Premature end?
  230.      beq.w    gwbdone            ;Huh, must be garbage - don't update VPARMS
  231.     cmpi.b    #';',d2            ;Also a possible error
  232.      beq.w    gwbdone
  233.     cmpi.b    #'r',d2            ;And what about this?
  234.      beq.w    gwbdone
  235.  
  236.     subi.b    #'0',d2            ;Okay, adjust ascii offset
  237.     cmpi.b    #' ',(a2)        ;Hit end of report?
  238.      beq.b    2$            ;Yep
  239.     mulu    #$000a,d2        ;Else shift by 10
  240.     add.b    (a2)+,d2        ;Add next digit
  241.     subi.b    #'0',d2            ;Ascii adjust
  242.     cmpi.b    #' ',(a2)        ;Hit end of report?
  243.      beq.b    2$            ;Yep
  244.     mulu    #$000a,d2        ;Else shift by 10
  245.     add.b    (a2),d2            ;Add next digit
  246.     subi.b    #'0',d2            ;Ascii adjust
  247.  
  248. 2$
  249. * Finally, update parameters by reference
  250.     movea.l    height(a5),a0        ;Grab height VPARM
  251.     move.l    d1,(a0)            ;*height = d1
  252.     movea.l    width(a5),a0        ;Grab width VPARM
  253.     move.l    d2,(a0)            ;*width = d2
  254.  
  255. gwbdone:
  256.     movem.l    (sp)+,d2-d4/a2
  257.     unlk    a5
  258.     rts
  259.  
  260. * --------------------------------------------------------------------- *
  261. * void __asm SetConsoleType(flag, id, packet, port)
  262. *   register __d0 long flag;
  263. *   register __a0 struct Process *id;
  264. *   register __a1 struct StandardPacket *packet;
  265. *   register __a2 struct MsgPort *port;
  266. *
  267. * Flag = 1L -- Raw mode
  268. *      = 0L -- Cooked mode
  269. * --------------------------------------------------------------------- *
  270.     XDEF    SetConsoleType
  271. SetConsoleType:
  272.     movem.l    a3/a5,-(sp)
  273.  
  274.     movea.l    a0,a3            ;Copy process pointer
  275.     movea.l    a1,a5            ;Copy packet pointer
  276.     lea    sp_Pkt(a5),a0        ;a0 = &packet->sp_Pkt
  277.     move.l    a0,sp_Msg+LN_NAME(a5)    ;p->sp_Msg.mn_Node.ln_Name = &p->sp_Pkt
  278.     lea    sp_Msg(a5),a0        ;a0 = &packet->sp_Msg
  279.     move.l    a0,sp_Pkt+dp_Link(a5)    ;p->sp_Pkt.dp_Link = &p->sp_Msg
  280.     move.l    a2,sp_Pkt+dp_Port(a5)    ;p->sp_Pkt.dp_Port = replyport
  281.     move.l    #ACTION_SCREEN_MODE,sp_Pkt+dp_Type(a5)    ;Set function
  282.  
  283.     tst.w    d0            ;On or Off?
  284.      beq.w    1$
  285.     move.l    #-1,sp_Pkt+dp_Arg1(a5)    ;RAW ON
  286.     bra.b    2$
  287. 1$
  288.     clr.l    sp_Pkt+dp_Arg1(a5)    ;RAW OFF
  289. 2$
  290.     movea.l    a3,a0
  291.     movea.l    a5,a1
  292.     SYS    PutMsg,4        ;PutMsg(proc, packet)
  293.  
  294.     movea.l    a2,a0
  295.     SYS    WaitPort        ;WaitPort(port)
  296.     movea.l    a2,a0
  297.     SYS    GetMsg            ;(void)GetMsg(port)
  298.  
  299.     movem.l    (sp)+,a3/a5
  300.     rts
  301.  
  302. * ------------------------------------------------------------------------- *
  303. * struct MsgPort *CreatePort(name, pri) (a0/d0)
  304. * ------------------------------------------------------------------------- *
  305.     XDEF    CreatePort
  306. CreatePort:
  307.     movem.l    d5/d7/a2/a5,-(sp)
  308.  
  309.     move.l    a0,a5            ;Save Name
  310.     move.l    d0,d5            ;Save Pri
  311.  
  312. * Allocate a free signal, crap out if we can't
  313.     moveq    #-1,d0
  314.     SYS    AllocSignal,4
  315.     cmp.l    #-1,d0            ;Did we get a signal?
  316.      bne.b    cpgotsig        ;Yep
  317.     moveq    #0,d0            ;Otherwise return NULL
  318.     bra.w    cpdone
  319.  
  320. cpgotsig:
  321.     move.l    d0,d7            ;Save our signal
  322.  
  323. * Allocate memory for MsgPort
  324.     moveq.l    #MP_SIZE,d0        ;Size of MsgPort
  325.     move.l    #MEMF_PUBLIC!MEMF_CLEAR,d1    ;Type of memory
  326.     SYS    AllocMem        ;Allocate it
  327.     tst.l    d0            ;Did we get it?
  328.      bne.b    cpgotport        ;Yep
  329.  
  330.     move.l    d7,d0            ;Otherwise crap out, free signal
  331.     SYS    FreeSignal
  332.     moveq    #0,d0            ;Return NULL
  333.     bra.w    cpdone
  334.  
  335. cpgotport:
  336.     move.l    d0,a2            ;This is our new port!
  337.     move.l    a5,LN_NAME(a2)        ;port->mp_Node.ln_Name = name
  338.     move.b    d5,LN_PRI(a2)        ;port->mp_Node.ln_Pri = priority
  339.     move.b    #NT_MSGPORT,LN_TYPE(a2) ;port->mp_Node.ln_Type = NT_MSGPORT
  340.     move.b    #PA_SIGNAL,MP_FLAGS(a2) ;port->mp_Flags = PA_SIGNAL
  341.     move.b    d7,MP_SIGBIT(a2)    ;port->mp_SIGBIT = sigBit
  342.     suba.l    a1,a1
  343.     SYS    FindTask
  344.     move.l    d0,MP_SIGTASK(a2)    ;port->mp_SIGTASK = FindTask(0L)
  345.     
  346.     cmpa.l    #0,a5            ;Is this a new name?
  347.     beq.b    cpnoname        ;Nope, add it to the msg list
  348.  
  349.     movea.l    a2,a1
  350.     SYS    AddPort            ;Otherwise add this port
  351.     move.l    a2,d0            ;Return port pointer
  352.     bra.b    cpdone
  353.  
  354. cpnoname:
  355. * Initialized New List head
  356.     lea    MP_MSGLIST(a2),a0     ;a0 = &port->mp_MsgList
  357.     move.l    a0,(a0)            ;list->lh_Head = list
  358.     addq.l    #4,(a0)            ;list->lh_Head += 4L
  359.     clr.l    4(a0)            ;list->lh_Tail = 0L
  360.     move.l    a0,8(a0)        ;list->lh_TailPred = list
  361.     move.l    a2,d0            ;Return port pointer
  362.  
  363. cpdone:
  364.     movem.l    (sp)+,d5/d7/a2/a5
  365.     rts
  366.  
  367. * ------------------------------------------------------------------------- *
  368. * DeletePort(port)(d0)
  369. * ------------------------------------------------------------------------- *
  370.     XDEF    DeletePort
  371. DeletePort:
  372.     move.l    a5,-(sp)
  373.  
  374.     move.l    d0,a5
  375.     tst.l    LN_NAME(a5)        ;Is there a name?
  376.     beq.s    dpnoname
  377.     
  378.     move.l    d0,a1
  379.     SYS    RemPort,4        ;RemPort(port)
  380.     
  381. dpnoname:
  382.     move.b    #$ff,LN_TYPE(a5)     ;port->mp_Node.ln_Type = 0xff
  383.     move.l    #-1,MP_MSGLIST(a5)     ;port->mp_MsgList.lh_Head = -1L
  384.  
  385.     moveq    #0,d0
  386.     move.b    MP_SIGBIT(a5),d0    ;d0 = port->mp_SigBit
  387.     SYS    FreeSignal,4        ;FreeSignal(d0)
  388.  
  389.     moveq    #MP_SIZE,d0
  390.     move.l    a5,a1
  391.     SYS    FreeMem            ;FreeMem(port, sizeof(*port))
  392.  
  393.     move.l    (sp)+,a5
  394.     rts
  395.  
  396. * ------------------------------------------------------------------------
  397. * char *FibFileDate(fib_date)
  398. *   register struct DateStamp *fib_date;
  399. *
  400. *   Calculate date based on DateStamp structure and return a pointer
  401. * to the formatted date string.
  402. * ------------------------------------------------------------------------
  403.     XDEF    _FibFileDate
  404. _FibFileDate:
  405.     link    a5,#0
  406.     movem.l    d3-d7/a4,-(sp)
  407.  
  408.     movea.l    8(a5),a1        ;Grab datestamp pointer
  409.     moveq    #78,d7            ;Initial year = 1978
  410.  
  411.     move.l    (a1),d5            ;days = fib_date->ds_Days
  412.      blt.w    ffdbaddate        ;Hey! you can't be negative! Invalid date...
  413.  
  414. * Determine what year it is
  415.     divu    #1461,d5
  416.     move.l    d5,d0            ;Stash it
  417.     ext.l    d5
  418.     lsl.l    #2,d5
  419.     add.l    d5,d7            ;year += (days / 1461) * 4
  420.  
  421. * Count how many months into that year
  422. ffdgetmo:
  423.     swap    d0            ;days %= 1461
  424.     move.w    d0,d5
  425.  
  426. 1$    tst.w    d5            ;Out of days yet?
  427.      beq.b    3$            ;Yep, done here
  428.  
  429.     move.w    #365,d6            ;Else month_days = 365
  430.     move.w    d7,d0            ;Grab year
  431.     andi.w    #3,d0            ;if (year & 3) == 0 Leap year?
  432.      bne.b    2$            ;Nope
  433.     addq.w    #1,d6            ;Otherwise bump month_days
  434.  
  435. 2$    cmp.w    d6,d5            ;is day < month_days?
  436.      blt.b    3$            ;yep, done here
  437.     sub.w    d6,d5            ;otherwise day -= month_days
  438.  
  439.     addq.l    #1,d7            ; year++
  440.     bra.b    1$
  441. 3$
  442.  
  443. * Count how many days into that month of that year
  444. ffdgetday:
  445. ;for (i = 0, day++; i < 12; i++)
  446.     moveq    #0,d4            ;current month = 0
  447.     moveq    #0,d6            ;Zap hinybs
  448.     addq.w    #1,d5
  449.     lea    _dayspermonth(a4),a0
  450.  
  451. 1$
  452.     move.b    0(a0,d4.w),d6        ;month_days = dayspermonth[i]
  453.  
  454.     cmpi.w    #1,d4            ;if (i == 1 && (year & 3) == 0)
  455.      bne.b    2$
  456.     move.w    d7,d0
  457.     andi.w    #3,d0
  458.      bne.b    2$
  459.     addq.w    #1,d6            ;month_days++
  460.  
  461. 2$    cmp.w    d6,d5            ;if (day <= month_days)
  462.      ble.b    4$            ;Break out, found the right month
  463.  
  464.     sub.w    d6,d5            ;Else, day -= month_days
  465.  
  466.     addq.w    #1,d4            ;i++
  467. 3$    cmpi.w    #12,d4            ;Done all months yet?
  468.      blt.b    1$            ;Nope
  469.  
  470. 4$
  471. ffdprint:
  472. 1$    cmpi.l    #99,d7            ;while (year >= 100)
  473.      ble.b    2$
  474.     subi.l    #100,d7            ;year -= 100
  475.     bra.b    1$
  476. 2$
  477. ;asprintf(datestr, "%02d-%02d-%02d %02d:%02d:%02d", i + 1, day, year, hour, min, sec)
  478.     move.l    8(a1),d0        ;sec = fib_date->ds_Tick / 50;
  479.     divu    #50,d0
  480.     move.w    d0,-(sp)        ;Push secs
  481.  
  482.     moveq    #0,d0            ;Zap reg
  483.     move.w    6(a1),d0        ;min = fib_date->ds_Minute
  484.     move.w    d0,d1            ;Clone it
  485.     divu    #60,d0
  486.     move.w    d0,d3            ;hour = min / 60
  487.     mulu    #60,d0
  488.     sub.w    d0,d1            ;min -= hour * 60
  489.     move.w    d1,-(sp)        ;Push mins
  490.  
  491.     move.w    d3,-(sp)        ;Push hours
  492.     addq.w    #1,d4            ;Push day of month (offset by 1!)
  493.     move.w    d5,-(sp)        ;Push month
  494.     move.w    d4,-(sp)
  495.     move.w    d7,-(sp)        ;Push year
  496.     pea    _datepat(a4)        ;Push the format pattern
  497.     pea    _datestr(a4)        ;Push destination buffer
  498.     jsr    _asprintf    
  499.     lea    20(sp),sp
  500.     lea    _datestr(a4),a0
  501.     move.l    a0,d0            ;return((char *)&datestr[0])
  502.  
  503. ffddone:
  504.     movem.l    (sp)+,d3-d7/a4
  505.     unlk    a5
  506.     rts
  507.  
  508. ffdbaddate:
  509.     lea    _baddatestr(a4),a0    ;return (" <Invalid Date> ");
  510.     move.l    a0,d0
  511.     bra.b    ffddone
  512.  
  513. *----------------------------------------------------------------------
  514. * LONG iswild(name)
  515. *   char *name;
  516. *
  517. * Search a string for wild characters, return 1 if found
  518. *----------------------------------------------------------------------
  519.     XDEF    _iswild
  520. _iswild:
  521.     movea.l    4(sp),a0        ;Grab string pointer
  522.     moveq    #0,d0            ;Clear out our character register
  523. ischk1:
  524.     move.b    (a0)+,d0        ;Grab a char
  525.      beq.b    iwdone            ;Might be end of string?
  526.     cmpi.b    #'*',d0            ;Is it *?
  527.      beq.b    iswdone            ;yep, is wild
  528.     cmpi.b    #'?',d0            ;Is it a qmark
  529.      bne.b    ischk1            ;Nope, check next character
  530.  
  531. iswdone:
  532.     moveq    #1,d0
  533. iwdone:
  534.     rts
  535.  
  536.  
  537. * ------------------------------------------------------------------------
  538. ; Compare a wild card name with a normal name
  539. ; LONG wildmatch (name, wild)
  540. ;   char *name, *wild;
  541. * ------------------------------------------------------------------------
  542.     XDEF    _wildmatch
  543. _wildmatch:
  544.     link    a5,#-64
  545.     movem.l    d3/a2-a3,-(sp)
  546.  
  547.     movea.l    8(a5),a2        ;Grab name
  548.     movea.l    12(a5),a3        ;Grab pattern
  549.     lea    -64(a5),a0        ;back[0][0]
  550.     lea    -60(a5),a1        ;back[0][1]
  551.  
  552.     moveq    #0,d3            ;bi = 0
  553.  
  554. wmloop1:
  555.     tst.b    (a2)            ;End of name?
  556.      bne.b    wmnoteon
  557.     tst.b    (a3)            ;End of pattern?
  558.      beq.w    wmmatched        ;Yep, we matched
  559.  
  560. wmnoteon:
  561.     cmpi.b    #'*',(a3)        ;Is it a splat?
  562.      bne.b    wmnotstar        ;Nope, maybe '?'
  563.  
  564.     cmpi.w    #64,d3            ;Have we hit max expression depth?
  565.      beq.w    wmnomatch        ;Yep, ran out of room in recursion table
  566.  
  567. ;back[bi][0] = w
  568.     move.l    a3,0(a0,d3.w)        ;Stash pointer to this '*' in table
  569.  
  570. ;back[bi][1] = n
  571.     move.l    a2,0(a1,d3.w)
  572.  
  573.     addq.w    #8,d3            ;++bi
  574.     addq.w    #1,a3            ;++w
  575.     bra.b    wmloop1            ;Check next
  576.  
  577. wmgoback:
  578.     subq.w    #8,d3            ;--bi
  579.     move.l    a0,d0
  580. wmback1:
  581.     tst.w    d3            ;while (bi >= 0 && *back[bi][1] == '\x0')
  582.      blt.b    wmbacked
  583.     movea.l    0(a1,d3.l),a0
  584.     tst.b    (a0)
  585.      bne.b    wmbacked
  586.  
  587.     subq.w    #8,d3            ;--bi
  588.     bra.b    wmback1
  589.  
  590. wmbacked:
  591.     tst.w    d3            ;if (bi < 0)
  592.      blt.b    wmnomatch        ;return (0)
  593.  
  594.     movea.l    d0,a0
  595.     movea.l    0(a0,d3.w),a3        ;w = back[bi][0] + 1
  596.     addq.w    #1,a3    
  597.  
  598.     addq.l    #1,0(a1,d3.w)
  599.     movea.l    0(a1,d3.l),a2        ;n = ++back[bi][1]
  600.  
  601.     addq.w    #8,d3            ;++bi
  602.     bra.b    wmloop1
  603.  
  604. wmnotstar:
  605.     cmpi.b    #'?',(a3)        ;Is it '?'
  606.      bne.b    wmnotqmark
  607.  
  608.     tst.b    (a2)            ;Reached end of string?
  609.      bne.b    wmincpoint        ;Nope, move on to next char
  610.  
  611.     tst.w    d3            ;Are we at top level of expression?
  612.      beq.b    wmnomatch        ;Yep, expression didn't match
  613.     bra.b    wmgoback        ;Otherwise pop a level and try to match
  614.  
  615. wmnotqmark:
  616.     move.b    (a2),d0            ;Grab a char from bstr
  617.     cmpi.b    #$40,d0            ;less than @ character?
  618.      bls.b    1$            ;Yep
  619.     cmpi.b    #$5a,d0            ;Greater than Z?
  620.      bhi.b    1$            ;Yep
  621.     addi.b    #$20,d0
  622. 1$
  623.     move.b    (a3),d1            ;Grab a char from bstr
  624.     cmpi.b    #$40,d1            ;less than @ character?
  625.      bls.b    2$            ;Yep
  626.     cmpi.b    #$5a,d1            ;Greater than Z?
  627.      bhi.b    2$            ;Yep
  628.     addi.b    #$20,d1
  629. 2$
  630.     cmp.b    d0,d1            ;*n = *w?
  631.      beq.b    wmincpoint        ;Yep, move on past
  632.  
  633.     tst.w    d3            ;Are we at top expression level?
  634.      beq.b    wmnomatch        ;Yep, they didn't match
  635.     bra.b    wmgoback        ;Nope, process next part
  636.  
  637. wmincpoint:
  638.     tst.b    (a2)            ;Done with name?
  639.      beq.b    wmnamend        ;Yep
  640.     addq.w    #1,a2            ;Otherwise increment name pointer
  641.  
  642. wmnamend:
  643.     tst.b    (a3)            ;End of pattern?
  644.      beq.b    wmmatched        ;Yep, we matched
  645.     addq.w    #1,a3            ;Otherwise inc wild pointer, match next char
  646.     bra.w    wmloop1
  647.  
  648. wmmatched:
  649.     moveq    #1,d0
  650.     bra.b    wmdone
  651.  
  652. wmnomatch:
  653.     moveq    #0,d0
  654.  
  655. wmdone:
  656.     movem.l    (sp)+,d3/a2-a3
  657.     unlk    a5
  658.     rts
  659.  
  660. * --------------------------------------------------------------------- *
  661. * void SortFibs (keytype, direction, fibheadp)
  662. *           d0       d1         a0
  663. *  int keytype;
  664. *  struct FibEntry *fibheadp;
  665. *
  666. * Selection sort a linked list of FibEntrys based on a keycode         *
  667. * --------------------------------------------------------------------- *
  668.     XDEF    _SortFibs
  669. _SortFibs:
  670.     link    a5,#0
  671.     movem.l    d2-d4/a2-a3/a6,-(sp)
  672.  
  673.     movem.l    8(a5),d0-d1/a0
  674.  
  675.     move.l    d0,d2            ;Save keytype
  676.     move.l    d1,d4            ;Save direction of sort
  677.     movea.l    a0,d3            ;Save fibheadp
  678.     movea.l    a0,a2            ;a2 = a0 = i
  679.  
  680. sfILoop:
  681.     cmp.l    (a2),d3            ;i->NextFib != fibheadp?
  682.      beq.b    sfdone            ;Nope, wrapped around to start
  683.     movea.l    a2,a6            ;k = i
  684.     movea.l    (a2),a3            ;j = i->NextFib
  685.  
  686. sfJLoop:
  687.     cmp.l    a3,d3            ;j != fibheadp?
  688.      beq.b    sfJdone            ;Nope compared them all, see if swapped any
  689.     movea.l    8(a6),a0        ;a0 = k->Fibp
  690.     movea.l    8(a3),a1        ;a1 = j->Fibp
  691.     move.l    d2,d0            ;d0 = keytype
  692.     jsr    _CompFibs        ;d0 = CompFibs(keytype, k->Fibp, j->Fibp)
  693.     tst.w    d4            ;Reverse sort?
  694.      beq.b    1$            ;Nope
  695.     bchg.l    #0,d0            ;Else reverse sense of return
  696. 1$
  697.     tst.l    d0            ;Return != 0?
  698.      beq.b    sfNextJ            ;Nope, these two are in order
  699.     movea.l    a3,a6            ;else k = j, this is new swap
  700.  
  701. sfNextJ:
  702.     movea.l    (a3),a3            ;j = j->NextFib
  703.     bra.b    sfJLoop            ;Check bounds
  704.  
  705. sfJdone:
  706.     cmpa.l    a6,a2            ;k != i, did we swap?
  707.      beq.b    sfNextI            ;Nope, i was in correct position already
  708.     move.l    8(a6),d0
  709.     move.l    8(a2),8(a6)
  710.     move.l    d0,8(a2)        ;Else SwapFibs (k, i)
  711.  
  712. sfNextI:
  713.     movea.l    (a2),a2            ;i = i->NextFib
  714.     bra.b    sfILoop            ;Check bounds
  715.  
  716. sfdone:
  717.     movem.l    (sp)+,d2-d4/a2-a3/a6
  718.     unlk    a5
  719.     rts
  720.  
  721. * --------------------------------------------------------------------- *
  722. * int CompFibs (keytype, a, b)
  723. *         d0     a0 a1
  724. *   int keytype;
  725. *   struct FileInfoBlock *a, *b;
  726. *
  727. * Used by SortFibs to determine precedence of Fibs.
  728. * --------------------------------------------------------------------- *
  729.     XDEF    _CompFibs
  730. _CompFibs:
  731.     tst.w    d0            ;Alphabetize?
  732.      bne.b    cfnalpha        ;Nope
  733.  
  734. * Compare lexigraphically, ignoring case differences
  735. cfalpha:
  736.     lea    fib_FileName(a0),a0    ;a = &Fipb->fib_FileName
  737.     lea    fib_FileName(a1),a1    ;b = &Fipb->fib_FileName
  738.  
  739. ;  for(; *a && tolower(*a) == tolower(*b); a++, b++);
  740. lccstart:
  741.     tst.b    (a0)            ;Is there a char here at source?
  742.      beq.b    lcceostr        ;Nope, fell off the end
  743.  
  744.     move.b    (a1)+,d1        ;Grab a char from bstr
  745.     cmpi.b    #$40,d1            ;less than @ character?
  746.      bls.b    1$            ;Yep
  747.     cmpi.b    #$5a,d1            ;Greater than Z?
  748.      bhi.b    1$            ;Yep
  749.     addi.b    #$20,d1
  750. 1$
  751.     move.b    (a0)+,d0        ;Grab a char from astr
  752.     cmpi.b    #$40,d0            ;less than @ character?
  753.      bls.b    2$            ;Yep
  754.     cmpi.b    #$5a,d0            ;Greater than Z?
  755.      bhi.b    2$            ;Yep
  756.     addi.b    #$20,d0
  757. 2$
  758.     cmp.b    d0,d1            ;are they the same?
  759.      beq.b    lccstart        ;Yep, compare next pair of chars
  760.  
  761. lcceostr:
  762.     sub.b    d1,d0            ;return(tolower(*astr) - tolower(*bstr))
  763.      bgt.b    cftrue            ; > 0?, return TRUE
  764.     bra.b    cffalse            ;Else return FALSE
  765.  
  766. cfnalpha:
  767.     subq.w    #1,d0            ;Size?
  768.      bne.b    cfnsize            ;Nope
  769.  
  770. * Compare fib_Sizes
  771.     move.l    fib_Size(a1),d0        ;d0 = bfib->fib_Size
  772.     cmp.l    fib_Size(a0),d0        ;a->fib_Size > b->fib_Size?
  773.      blt.b    cftrue            ;Yep, return TRUE
  774.      bgt.b    cffalse            ;<, return FALSE
  775.     bra.b    cfalpha            ;Else it's a tie, alphabetize
  776.  
  777. cfnsize:
  778.     subq.w    #1,d0            ;Time?
  779.      bne.b    cffalse            ;Nope, an error!
  780.  
  781. * Compare fib_DateStamps
  782.     lea    fib_DateStamp(a0),a0    ;a = &afib->fib_DateStamp
  783.     lea    fib_DateStamp(a1),a1    ;b = &bfib->fib_DateStamp
  784.     move.l    ds_Days(a1),d0        ;d0 = bdate->ds_Days
  785.     cmp.l    ds_Days(a0),d0        ;a->ds_Days > b->ds_Days?
  786.      blt.b    cftrue            ;Yep, a is older
  787.      bgt.b    cffalse            ;Else if a < b, b is older
  788.                     ;Else they are the same day, check min/tick
  789.     move.l    ds_Minute(a0),d0
  790.     sub.l    ds_Minute(a1),d0    ;d0 = amin - bmin
  791.     muls    #3000,d0        ;     * 3000
  792.     add.l    ds_Tick(a0),d0
  793.     sub.l    ds_Tick(a1),d0        ;     + atick - btick
  794.      bgt.b    cftrue            ;Hey, a > b
  795.      blt.b    cffalse            ;a < b, return false
  796.     bra.b    cfalpha            ;Else its the same date, alphabetize
  797.  
  798. cftrue:
  799.     moveq    #1,d0
  800.     rts
  801. cffalse:
  802.     moveq    #0,d0
  803.     rts
  804.  
  805. * --------------------------------------------------------------------- *
  806.     SECTION    __MERGED,DATA
  807. * --------------------------------------------------------------------- *
  808.     XDEF    _dayspermonth
  809. _dayspermonth:
  810.     dc.b    31,28,31,30,31,30,31,31,30,31,30,31
  811.     XDEF    _datepat
  812. _datepat:
  813.     dc.b    '%02d-%02d-%02d %02d:%02d:%02d',0
  814.     CNOP    0,2
  815.     XDEF    _baddatestr
  816. _baddatestr:
  817.     dc.b    '00-00-00 00:00:00',0
  818.     CNOP    0,2
  819.  
  820.     XDEF    gwbrstr
  821. gwbrstr:
  822.     dc.b    $9b,'0 q'
  823.  
  824. * --------------------------------------------------------------------- *
  825.     SECTION    __MERGED,BSS
  826. * --------------------------------------------------------------------- *
  827.     XDEF    _datestr
  828. _datestr:
  829.     ds.b    40
  830.  
  831. * --------------------------------------------------------------------- *
  832.     END
  833. * --------------------------------------------------------------------- *
  834.