home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Frozen Fish 1: Amiga
/
FrozenFish-Apr94.iso
/
bbs
/
alib
/
d1xx
/
d178
/
ls.lha
/
Ls
/
lssup.a
< prev
next >
Wrap
Text File
|
1989-02-04
|
22KB
|
833 lines
* --------------------------------------------------------------------- *
* LSSUP.A - Assembly support routines for ls.c *
* Copyright (c) 1988 by Justin V. McCormick. All Rights Reserved. *
* --------------------------------------------------------------------- *
IDNT "lssup.a"
include "asm:inc/macros.i"
; Assembler options for CAPE
BASEREG B
SMALLOBJ
OPTIMON
ADDSYM
DEBUG
; Equates
fib_FileName equ $8
fib_Size equ $7C
fib_NumBlocks equ $80
fib_DateStamp equ $84
ds_Days equ $0
ds_Minute equ $4
ds_Tick equ $8
_LVOAddPort equ $FFFFFE9E
_LVOAllocMem equ $FFFFFF3A
_LVOAllocSignal equ $FFFFFEB6
_LVODebug equ $FFFFFF8E
_LVOFindTask equ $FFFFFEDA
_LVOFreeMem equ $FFFFFF2E
_LVOFreeSignal equ $FFFFFEB0
_LVOGetMsg equ $FFFFFE8C
_LVOPutMsg equ $FFFFFE92
_LVORawDoFmt equ $FFFFFDF6
_LVORemPort equ $FFFFFE98
_LVORead equ $FFFFFFD6
_LVOWaitPort equ $FFFFFE80
_LVOWrite equ $FFFFFFD0
pr_ConsoleTask EQU $A4
MEMF_CLEAR EQU $10000
MEMF_PUBLIC EQU $1
sp_Msg EQU $0
sp_Pkt EQU $14
sp_SIZEOF EQU $44
dp_Link EQU $0
dp_Port EQU $4
dp_Arg1 EQU $14
dp_Type EQU $8
ACTION_SCREEN_MODE EQU $3E2
LN_NAME EQU $A
LN_PRI EQU $9
LN_TYPE EQU $8
MP_FLAGS EQU $E
MP_MSGLIST EQU $14
MP_SIGBIT EQU $F
MP_SIGTASK EQU $10
MP_SIZE EQU $22
NT_MSGPORT EQU $4
PA_SIGNAL EQU $0
* External constants
XREF _DOSBase
XREF _Out
XREF _In
* --------------------------------------------------------------------- *
SECTION lssup,CODE
* ------------------------------------------------------------------------- *
* void asprintf(wstr, formatstring, args)
* char *wstr;
* char *formatstring;
* char **args;
*
* Synopsis: Given formatstring and args to format, formats output to wstr.
* Similar to sprintf(), except doesn't handle floats.
* ------------------------------------------------------------------------- *
XDEF _asprintf
_asprintf:
link a5,#0
movem.l d0-d2/a0-a3,-(sp) ;Save everything we might clobber
* Call format function to convert fmtstring and args to buffer on the stack
movea.l 12(a5),a0 ;Grab format string
lea 16(a5),a1 ;Grab EA of arguments
lea kput1,a2 ;Grab EA of output subroutine
movea.l 8(a5),a3 ;Grab EA of dest workspace
SYS RawDoFmt,4 ;Format it into workspace
movem.l (sp)+,d0-d2/a0-a3 ;Restore registers
unlk a5 ;And stack frame
rts
* ------------------------------------------------------------------------- *
* RawDoFmt() output routine for xprintf, called for each formatted char.
* Takes byte in d0 and puts in buffer pointed to by a3, then increments a3.
* ------------------------------------------------------------------------- *
XDEF kput1
kput1:
move.b d0,(a3)+
rts
* --------------------------------------------------------------------- *
* void GetWinBounds(width, height)
* long *width, *height;
*
* Find current console window, determine width and height
* in terms of current font, update width and height VPARMS passed.
* --------------------------------------------------------------------- *
rpstr equ -32
rpport equ -12
packet equ -8
conid equ -4
width equ 8
height equ 12
XDEF _GetWinBounds
_GetWinBounds:
link a5,#-32
movem.l d2-d4/a2,-(sp)
suba.l a1,a1
SYS FindTask,4 ;d0 = FindTask(0L), our process
movea.l d0,a0 ;Transfer to address reg
move.l pr_ConsoleTask(a0),conid(a5) ;Save proc->pr_ConsoleTask
moveq #0,d4 ;Clear our success status register
moveq #0,d0
movea.l d0,a0
bsr.w CreatePort
move.l d0,rpport(a5) ;rpport = CreatePort(0L, 0L)
beq.w gwbdone ;Oops, no signals or ram available!
move.l #MEMF_PUBLIC+MEMF_CLEAR,d1
moveq #sp_SIZEOF,d0
SYS AllocMem
move.l d0,packet(a5) ;packet = AllocMem(sizeof(*packet),MEMF_PUBLIC|MEMF_CLEAR)
beq.w gwbfreeport ;Oops, no ram, free up port
* Okay, we got our process id, reply port, and packet
* Now toggle the console into raw mode
movea.l rpport(a5),a2
movea.l d0,a1
movea.l conid(a5),a0
moveq #1,d0
bsr.w SetConsoleType ;SetConsoleType(1L, conid, packet, rpport)
* Request a window bounds report
moveq #4,d3
lea gwbrstr(a4),a0
move.l a0,d2
move.l _Out(a4),d1
SYS Write,_DOSBase(a4) ;Write(Output(), "\2330 q", 4L);
cmpi.l #$0004,d0 ;Did the console choke on it?
bne.w gwbsetcook ;hmmm, see if we can back out gracefully
* Read the report string into stack buffer
moveq #16,d3 ;Don't let it get longer than 16 characters
lea rpstr(a5),a0 ;Point to input string area
move.l a0,d2
move.l _In(a4),d1
SYS Read ;Read(Input(), rpstr, 16L)
move.l d0,d4 ;Save read length while we close shop
* Turn the console back to cooked mode pronto to avoid cursor blink
gwbsetcook:
movea.l rpport(a5),a2
movea.l packet(a5),a1
movea.l conid(a5),a0
moveq #0,d0
bsr.w SetConsoleType ;SetConsoleType(0L, conid, packet, rpport)
* Release resources we borrowed
gwbfreepack:
move.l packet(a5),d0 ;Did we allocate a packet?
beq.b gwbfreeport ;nay, check for port to free
movea.l d0,a1
moveq #sp_SIZEOF,d0
SYS FreeMem ;Else FreeMem(packet, sizeof(*packet))
gwbfreeport:
move.l rpport(a5),d0 ;if (rpport)...
beq.w gwbdone ;nope
bsr.w DeletePort ;Else DeletePort(rpport)
* Finally, sanity check window bounds report string
* d4 = length of report string according to Read()
cmpi.l #9,d4 ;Less than 8 characters returned?
ble.w gwbdone ;hmmm, phonky bounds report from DOS?
lea rpstr(a5),a2 ;a2 = rpstr
cmpi.b #';',4(a2) ;Matches a typical report template?
bne.w gwbdone ;nope, got some weird junk back?
cmpi.b #'r',-1(a2,d4.w) ;Last byte is 'r' for report?
bne.w gwbdone ;Nope, message fubar!
* Parse the height and width variables from the field now
* Our report format looks like this in hex:
* 9b 31 3b 31 3b y2 y1 3b x2 x1 20 72
* Or in ascii:
* <0x9b>1;1;20;77 r
* Which would indicate a width of 77 cols and a height of 20 rows for
* the current console device
*
* REGS: a2 points to beginning of 'r' terminated string
lea 5(a2),a2 ;Point to first char of Y size
moveq #0,d1 ;Clear out work reg
* Convert ascii rows value to LONG, update host data
move.b (a2)+,d1 ;Grab a Y
subi.w #'0',d1 ;Less ascii offset
cmpi.b #';',(a2) ;Any more Y digits?
beq.b 1$ ;Nope
mulu #10,d1 ;Else shift by 10
add.b (a2)+,d1 ;Add least significant Y digit
subi.b #'0',d1 ;Less ascii offset
cmpi.b #';',(a2) ;Any more Y digits?
beq.b 1$ ;Nope
mulu #$000a,d1 ;Else shift by 10
add.b (a2)+,d1 ;Add least significant Y digit
subi.b #'0',d1 ;Less ascii offset
;We'll assume screen height < 999 rows
1$
* Convert ascii columns value to LONG, update host data
addq.w #1,a2 ;Move past the ';' separator
moveq #0,d2 ;Zap work reg
move.b (a2)+,d2 ;Grab msd of X
cmpi.b #' ',d2 ;Premature end?
beq.w gwbdone ;Huh, must be garbage - don't update VPARMS
cmpi.b #';',d2 ;Also a possible error
beq.w gwbdone
cmpi.b #'r',d2 ;And what about this?
beq.w gwbdone
subi.b #'0',d2 ;Okay, adjust ascii offset
cmpi.b #' ',(a2) ;Hit end of report?
beq.b 2$ ;Yep
mulu #$000a,d2 ;Else shift by 10
add.b (a2)+,d2 ;Add next digit
subi.b #'0',d2 ;Ascii adjust
cmpi.b #' ',(a2) ;Hit end of report?
beq.b 2$ ;Yep
mulu #$000a,d2 ;Else shift by 10
add.b (a2),d2 ;Add next digit
subi.b #'0',d2 ;Ascii adjust
2$
* Finally, update parameters by reference
movea.l height(a5),a0 ;Grab height VPARM
move.l d1,(a0) ;*height = d1
movea.l width(a5),a0 ;Grab width VPARM
move.l d2,(a0) ;*width = d2
gwbdone:
movem.l (sp)+,d2-d4/a2
unlk a5
rts
* --------------------------------------------------------------------- *
* __asm void SetConsoleType(flag, id, packet, port)
* register __d0 long flag;
* register __a0 struct Process *id;
* register __a1 struct StandardPacket *packet;
* register __a2 struct MsgPort *port;
*
* Flag = 1L -- Raw mode
* = 0L -- Cooked mode
* --------------------------------------------------------------------- *
XDEF SetConsoleType
SetConsoleType:
movem.l a3/a5,-(sp)
movea.l a0,a3 ;Copy process pointer
movea.l a1,a5 ;Copy packet pointer
lea sp_Pkt(a5),a0 ;a0 = &packet->sp_Pkt
move.l a0,sp_Msg+LN_NAME(a5) ;p->sp_Msg.mn_Node.ln_Name = &p->sp_Pkt
lea sp_Msg(a5),a0 ;a0 = &packet->sp_Msg
move.l a0,sp_Pkt+dp_Link(a5) ;p->sp_Pkt.dp_Link = &p->sp_Msg
move.l a2,sp_Pkt+dp_Port(a5) ;p->sp_Pkt.dp_Port = replyport
move.l #ACTION_SCREEN_MODE,sp_Pkt+dp_Type(a5) ;Set function
tst.w d0 ;On or Off?
beq.w 1$
move.l #-1,sp_Pkt+dp_Arg1(a5) ;RAW ON
bra.b 2$
1$
clr.l sp_Pkt+dp_Arg1(a5) ;RAW OFF
2$
movea.l a3,a0
movea.l a5,a1
SYS PutMsg,4 ;PutMsg(proc, packet)
movea.l a2,a0
SYS WaitPort ;WaitPort(port)
movea.l a2,a0
SYS GetMsg ;(void)GetMsg(port)
movem.l (sp)+,a3/a5
rts
* ------------------------------------------------------------------------- *
* struct MsgPort *CreatePort(name, pri) (a0/d0)
* ------------------------------------------------------------------------- *
XDEF CreatePort
CreatePort:
movem.l d5/d7/a2/a5,-(sp)
move.l a0,a5 ;Save Name
move.l d0,d5 ;Save Pri
* Allocate a free signal, crap out if we can't
moveq #-1,d0
SYS AllocSignal,4
cmp.l #-1,d0 ;Did we get a signal?
bne.b cpgotsig ;Yep
moveq #0,d0 ;Otherwise return NULL
bra.w cpdone
cpgotsig:
move.l d0,d7 ;Save our signal
* Allocate memory for MsgPort
moveq.l #MP_SIZE,d0 ;Size of MsgPort
move.l #MEMF_PUBLIC!MEMF_CLEAR,d1 ;Type of memory
SYS AllocMem ;Allocate it
tst.l d0 ;Did we get it?
bne.b cpgotport ;Yep
move.l d7,d0 ;Otherwise crap out, free signal
SYS FreeSignal
moveq #0,d0 ;Return NULL
bra.w cpdone
cpgotport:
move.l d0,a2 ;This is our new port!
move.l a5,LN_NAME(a2) ;port->mp_Node.ln_Name = name
move.b d5,LN_PRI(a2) ;port->mp_Node.ln_Pri = priority
move.b #NT_MSGPORT,LN_TYPE(a2) ;port->mp_Node.ln_Type = NT_MSGPORT
move.b #PA_SIGNAL,MP_FLAGS(a2) ;port->mp_Flags = PA_SIGNAL
move.b d7,MP_SIGBIT(a2) ;port->mp_SIGBIT = sigBit
suba.l a1,a1
SYS FindTask
move.l d0,MP_SIGTASK(a2) ;port->mp_SIGTASK = FindTask(0L)
cmpa.l #0,a5 ;Is this a new name?
beq.b cpnoname ;Nope, add it to the msg list
movea.l a2,a1
SYS AddPort ;Otherwise add this port
move.l a2,d0 ;Return port pointer
bra.b cpdone
cpnoname:
* Initialized New List head
lea MP_MSGLIST(a2),a0 ;a0 = &port->mp_MsgList
move.l a0,(a0) ;list->lh_Head = list
addq.l #4,(a0) ;list->lh_Head += 4L
clr.l 4(a0) ;list->lh_Tail = 0L
move.l a0,8(a0) ;list->lh_TailPred = list
move.l a2,d0 ;Return port pointer
cpdone:
movem.l (sp)+,d5/d7/a2/a5
rts
* ------------------------------------------------------------------------- *
* DeletePort(port)(d0)
* ------------------------------------------------------------------------- *
XDEF DeletePort
DeletePort:
move.l a5,-(sp)
move.l d0,a5
tst.l LN_NAME(a5) ;Is there a name?
beq.s dpnoname
move.l d0,a1
SYS RemPort,4 ;RemPort(port)
dpnoname:
move.b #$ff,LN_TYPE(a5) ;port->mp_Node.ln_Type = 0xff
move.l #-1,MP_MSGLIST(a5) ;port->mp_MsgList.lh_Head = -1L
moveq #0,d0
move.b MP_SIGBIT(a5),d0 ;d0 = port->mp_SigBit
SYS FreeSignal,4 ;FreeSignal(d0)
moveq #MP_SIZE,d0
move.l a5,a1
SYS FreeMem ;FreeMem(port, sizeof(*port))
move.l (sp)+,a5
rts
* ------------------------------------------------------------------------
* char *FibFileDate(fib_date)
* register struct DateStamp *fib_date;
*
* Calculate date based on DateStamp structure and return a pointer
* to the formatted date string.
* ------------------------------------------------------------------------
XDEF _FibFileDate
_FibFileDate:
link a5,#0
movem.l d3-d7/a4,-(sp)
movea.l 8(a5),a1 ;Grab datestamp pointer
moveq #78,d7 ;Initial year = 1978
move.l (a1),d5 ;days = fib_date->ds_Days
blt ffdbaddate ;Hey! you can't be negative! Invalid date...
* Determine what year it is
divu #1461,d5
move.l d5,d0 ;Stash it
ext.l d5
lsl.l #2,d5
add.l d5,d7 ;year += (days / 1461) * 4
* Count how many months into that year
ffdgetmo:
swap d0 ;days %= 1461
move.w d0,d5
1$ tst.w d5 ;Out of days yet?
beq 3$ ;Yep, done here
move.w #365,d6 ;Else month_days = 365
move.w d7,d0 ;Grab year
andi.w #3,d0 ;if (year & 3) == 0 Leap year?
bne 2$ ;Nope
addq.w #1,d6 ;Otherwise bump month_days
2$ cmp.w d6,d5 ;is day < month_days?
blt 3$ ;yep, done here
sub.w d6,d5 ;otherwise day -= month_days
addq.l #1,d7 ; year++
bra 1$
3$
* Count how many days into that month of that year
ffdgetday:
;for (i = 0, day++; i < 12; i++)
moveq #0,d4 ;current month = 0
moveq #0,d6 ;Zap hinybs
addq.w #1,d5
lea _dayspermonth(a4),a0
1$
move.b 0(a0,d4.w),d6 ;month_days = dayspermonth[i]
cmpi.w #1,d4 ;if (i == 1 && (year & 3) == 0)
bne 2$
move.w d7,d0
andi.w #3,d0
bne 2$
addq.w #1,d6 ;month_days++
2$ cmp.w d6,d5 ;if (day <= month_days)
ble 4$ ;Break out, found the right month
sub.w d6,d5 ;Else, day -= month_days
addq.w #1,d4 ;i++
3$ cmpi.w #12,d4 ;Done all months yet?
blt 1$ ;Nope
4$
ffdprint:
1$ cmpi.l #99,d7 ;while (year >= 100)
ble 2$
subi.l #100,d7 ;year -= 100
bra 1$
2$
;asprintf(datestr, "%02d-%02d-%02d %02d:%02d:%02d", i + 1, day, year, hour, min, sec)
move.l 8(a1),d0 ;sec = fib_date->ds_Tick / 50;
divu #50,d0
move.w d0,-(sp) ;Push secs
moveq #0,d0 ;Zap reg
move.w 6(a1),d0 ;min = fib_date->ds_Minute
move.w d0,d1 ;Clone it
divu #60,d0
move.w d0,d3 ;hour = min / 60
mulu #60,d0
sub.w d0,d1 ;min -= hour * 60
move.w d1,-(sp) ;Push mins
move.w d3,-(sp) ;Push hours
addq.w #1,d4 ;Push day of month (offset by 1!)
move.w d5,-(sp) ;Push month
move.w d4,-(sp)
move.w d7,-(sp) ;Push year
pea _datepat(a4) ;Push the format pattern
pea _datestr(a4) ;Push destination buffer
jsr _asprintf
lea 20(sp),sp
lea _datestr(a4),a0
move.l a0,d0 ;return((char *)&datestr[0])
ffddone:
movem.l (sp)+,d3-d7/a4
unlk a5
rts
ffdbaddate:
lea _baddatestr(a4),a0 ;return (" <Invalid Date> ");
move.l a0,d0
bra ffddone
*----------------------------------------------------------------------
* LONG iswild(name)
* char *name;
*
* Search a string for wild characters, return 1 if found
*----------------------------------------------------------------------
XDEF _iswild
_iswild:
movea.l 4(sp),a0 ;Grab string pointer
moveq #0,d0 ;Clear out our character register
ischk1:
move.b (a0)+,d0 ;Grab a char
beq iwdone ;Might be end of string?
cmpi.b #'*',d0 ;Is it *?
beq iswdone ;yep, is wild
cmpi.b #'?',d0 ;Is it a qmark
bne ischk1 ;Nope, check next character
iswdone:
moveq #1,d0
iwdone:
rts
* ------------------------------------------------------------------------
; Compare a wild card name with a normal name
; LONG wildmatch (name, wild)
; char *name, *wild;
* ------------------------------------------------------------------------
XDEF _wildmatch
_wildmatch:
link a5,#-64
movem.l d3/a2-a3,-(sp)
movea.l 8(a5),a2 ;Grab name
movea.l 12(a5),a3 ;Grab pattern
lea -64(a5),a0 ;back[0][0]
lea -60(a5),a1 ;back[0][1]
moveq #0,d3 ;bi = 0
wmloop1:
tst.b (a2) ;End of name?
bne wmnoteon
tst.b (a3) ;End of pattern?
beq wmmatched ;Yep, we matched
wmnoteon:
cmpi.b #'*',(a3) ;Is it a splat?
bne wmnotstar ;Nope, maybe '?'
cmpi.w #64,d3 ;Have we hit max expression depth?
beq wmnomatch ;Yep, ran out of room in recursion table
;back[bi][0] = w
move.l a3,0(a0,d3.w) ;Stash pointer to this '*' in table
;back[bi][1] = n
move.l a2,0(a1,d3.w)
addq.w #8,d3 ;++bi
addq.w #1,a3 ;++w
bra wmloop1 ;Check next
wmgoback:
subq.w #8,d3 ;--bi
move.l a0,d0
wmback1:
tst.w d3 ;while (bi >= 0 && *back[bi][1] == '\x0')
blt wmbacked
movea.l 0(a1,d3.l),a0
tst.b (a0)
bne wmbacked
subq.w #8,d3 ;--bi
bra wmback1
wmbacked:
tst.w d3 ;if (bi < 0)
blt wmnomatch ;return (0)
movea.l d0,a0
movea.l 0(a0,d3.w),a3 ;w = back[bi][0] + 1
addq.w #1,a3
addq.l #1,0(a1,d3.w)
movea.l 0(a1,d3.l),a2 ;n = ++back[bi][1]
addq.w #8,d3 ;++bi
bra wmloop1
wmnotstar:
cmpi.b #'?',(a3) ;Is it '?'
bne wmnotqmark
tst.b (a2) ;Reached end of string?
bne wmincpoint ;Nope, move on to next char
tst.w d3 ;Are we at top level of expression?
beq wmnomatch ;Yep, expression didn't match
bra wmgoback ;Otherwise pop a level and try to match
wmnotqmark:
move.b (a2),d0 ;Grab a char from bstr
cmpi.b #$40,d0 ;less than @ character?
bls 1$ ;Yep
cmpi.b #$5a,d0 ;Greater than Z?
bhi 1$ ;Yep
addi.b #$20,d0
1$
move.b (a3),d1 ;Grab a char from bstr
cmpi.b #$40,d1 ;less than @ character?
bls 2$ ;Yep
cmpi.b #$5a,d1 ;Greater than Z?
bhi 2$ ;Yep
addi.b #$20,d1
2$
cmp.b d0,d1 ;*n = *w?
beq wmincpoint ;Yep, move on past
tst.w d3 ;Are we at top expression level?
beq wmnomatch ;Yep, they didn't match
bra wmgoback ;Nope, process next part
wmincpoint:
tst.b (a2) ;Done with name?
beq wmnamend ;Yep
addq.w #1,a2 ;Otherwise increment name pointer
wmnamend:
tst.b (a3) ;End of pattern?
beq wmmatched ;Yep, we matched
addq.w #1,a3 ;Otherwise inc wild pointer, match next char
bra wmloop1
wmmatched:
moveq #1,d0
bra wmdone
wmnomatch:
moveq #0,d0
wmdone:
movem.l (sp)+,d3/a2-a3
unlk a5
rts
* --------------------------------------------------------------------- *
* void SortFibs (keytype, direction, fibheadp)
* d0 d1 a0
* int keytype;
* struct FibEntry *fibheadp;
*
* Selection sort a linked list of FibEntrys based on a keycode *
* --------------------------------------------------------------------- *
XDEF _SortFibs
_SortFibs:
link a5,#0
movem.l d2-d4/a2-a3/a6,-(sp)
move.l d0,d2 ;Save keytype
move.l d1,d4 ;Save direction of sort
movea.l a0,d3 ;Save fibheadp
movea.l a0,a2 ;a2 = a0 = i
sfILoop:
cmp.l (a2),d3 ;i->NextFib != fibheadp?
beq sfdone ;Nope, wrapped around to start
movea.l a2,a6 ;k = i
movea.l (a2),a3 ;j = i->NextFib
sfJLoop:
cmp.l a3,d3 ;j != fibheadp?
beq sfJdone ;Nope compared them all, see if swapped any
movea.l 8(a6),a0 ;a0 = k->Fibp
movea.l 8(a3),a1 ;a1 = j->Fibp
move.l d2,d0 ;d0 = keytype
jsr _CompFibs ;d0 = CompFibs(keytype, k->Fibp, j->Fibp)
tst.w d4 ;Reverse sort?
beq 1$ ;Nope
bchg.l #0,d0 ;Else reverse sense of return
1$
tst.l d0 ;Return != 0?
beq sfNextJ ;Nope, these two are in order
movea.l a3,a6 ;else k = j, this is new swap
sfNextJ:
movea.l (a3),a3 ;j = j->NextFib
bra sfJLoop ;Check bounds
sfJdone:
cmpa.l a6,a2 ;k != i, did we swap?
beq sfNextI ;Nope, i was in correct position already
move.l 8(a6),d0
move.l 8(a2),8(a6)
move.l d0,8(a2) ;Else SwapFibs (k, i)
sfNextI:
movea.l (a2),a2 ;i = i->NextFib
bra sfILoop ;Check bounds
sfdone:
movem.l (sp)+,d2-d4/a2-a3/a6
unlk a5
rts
* --------------------------------------------------------------------- *
* int CompFibs (keytype, a, b)
* d0 a0 a1
* int keytype;
* struct FileInfoBlock *a, *b;
*
* Used by SortFibs to determine precedence of Fibs.
* --------------------------------------------------------------------- *
XDEF _CompFibs
_CompFibs:
tst.w d0 ;Alphabetize?
bne cfnalpha ;Nope
* Compare lexigraphically, ignoring case differences
cfalpha:
lea fib_FileName(a0),a0 ;a = &Fipb->fib_FileName
lea fib_FileName(a1),a1 ;b = &Fipb->fib_FileName
; for(; *a && tolower(*a) == tolower(*b); a++, b++);
lccstart:
tst.b (a0) ;Is there a char here at source?
beq lcceostr ;Nope, fell off the end
move.b (a1)+,d1 ;Grab a char from bstr
cmpi.b #$40,d1 ;less than @ character?
bls 1$ ;Yep
cmpi.b #$5a,d1 ;Greater than Z?
bhi 1$ ;Yep
addi.b #$20,d1
1$
move.b (a0)+,d0 ;Grab a char from astr
cmpi.b #$40,d0 ;less than @ character?
bls 2$ ;Yep
cmpi.b #$5a,d0 ;Greater than Z?
bhi 2$ ;Yep
addi.b #$20,d0
2$
cmp.b d0,d1 ;are they the same?
beq lccstart ;Yep, compare next pair of chars
lcceostr:
sub.b d1,d0 ;return(tolower(*astr) - tolower(*bstr))
bgt cftrue ; > 0?, return TRUE
bra cffalse ;Else return FALSE
cfnalpha:
subq.w #1,d0 ;Size?
bne cfnsize ;Nope
* Compare fib_Sizes
move.l fib_Size(a1),d0 ;d0 = bfib->fib_Size
cmp.l fib_Size(a0),d0 ;a->fib_Size > b->fib_Size?
blt cftrue ;Yep, return TRUE
bgt cffalse ;<, return FALSE
bra cfalpha ;Else it's a tie, alphabetize
cfnsize:
subq.w #1,d0 ;Time?
bne cffalse ;Nope, an error!
* Compare fib_DateStamps
lea fib_DateStamp(a0),a0 ;a = &afib->fib_DateStamp
lea fib_DateStamp(a1),a1 ;b = &bfib->fib_DateStamp
move.l ds_Days(a1),d0 ;d0 = bdate->ds_Days
cmp.l ds_Days(a0),d0 ;a->ds_Days > b->ds_Days?
blt cftrue ;Yep, a is older
bgt cffalse ;Else if a < b, b is older
;Else they are the same day, check min/tick
move.l ds_Minute(a0),d0
sub.l ds_Minute(a1),d0 ;d0 = amin - bmin
muls #3000,d0 ; * 3000
add.l ds_Tick(a0),d0
sub.l ds_Tick(a1),d0 ; + atick - btick
bgt cftrue ;Hey, a > b
blt cffalse ;a < b, return false
bra cfalpha ;Else its the same date, alphabetize
cftrue:
moveq #1,d0
rts
cffalse:
moveq #0,d0
rts
* --------------------------------------------------------------------- *
SECTION __MERGED,DATA
* --------------------------------------------------------------------- *
XDEF _dayspermonth
_dayspermonth:
dc.b 31,28,31,30,31,30,31,31,30,31,30,31
XDEF _datepat
_datepat:
dc.b '%02d-%02d-%02d %02d:%02d:%02d',0
CNOP 0,2
XDEF _baddatestr
_baddatestr:
dc.b '00-00-00 00:00:00',0
CNOP 0,2
XDEF gwbrstr
gwbrstr:
dc.b $9b,'0 q'
* --------------------------------------------------------------------- *
SECTION __MERGED,BSS
* --------------------------------------------------------------------- *
XDEF _datestr
_datestr:
ds.b 40
* --------------------------------------------------------------------- *
END
* --------------------------------------------------------------------- *