Mercurial > hg > Members > kono > nitros9-code
view level1/cmds/dir_cb.asm @ 1912:37fd74e6fad8
Now assembles with rma, uses os9defs.d in c3
author | boisy |
---|---|
date | Fri, 11 Nov 2005 12:41:12 +0000 |
parents | 3beb3d140cb5 |
children |
line wrap: on
line source
* DIR Edition #8 - Released Mar. 12/2000 * Added the '-c' option, which stands for case insensitive. This means that * wildcard filename matches do not care as to whether the filenames are * upper or lowercase, when compared to the wildcard filename search you * specified. There still are some quirks to using the '*' wildcard in some * cases... I am still tracking down why that is happening. * * DIR Edition #7 - Released Jan. 16/2000 * * This is a new version of the DIR command, based on the version Alan Dekok * did with wildcarding. It fixes the year to work with modern clock drivers, * allowing from 1900-2155. It also fixes the help message, and changes the * edition # to 7. It should work with all version of OS9/NitrOS9/PowerBoost. * * -Curtis- * * Edition #7: (L. Curtis Boyle) * 2000/01/15: Fixed help message bug. * 2000/01/16: Fixed year output to handle 1900-2155 * * Edition #8 (Curtis) * 2000/03/11 Fixed Bad Filename error * 2000/03/12 Added -c option (case insensitive filematching) * Need to do 1 things: * Fix '*' wildcards (ex. DIR *.lzh returns completely different than * DIR *lzh - 1st only does files with ONE '.' char, 2nd does mix of ONE * and >1, but not all the same as first example???) nam dir ttl program module * Disassembled 94/11/18 12:51:39 by Alan DeKok ifp1 use defsfile endc tylg set Prgrm+Objct atrv set ReEnt+rev rev set $01 mod eom,name,tylg,atrv,start,size u0000 rmb 1 Path to current Directory u0001 rmb 1 Path to RAW drive (current data or exec dir's drive) u0002 rmb 2 Pointer to directory we are DIRing u0004 rmb 2 Ptr to end of current sub-parm (if more than 1) u0006 rmb 2 Pointer to filename match string we are DIRing u0008 rmb 1 Case insensitive flag (0=NO) u0009 rmb 1 Wildcard matched flag (0=NO) u000A rmb 1 0=Filename not written yet, <>0 means is written out u000B rmb 1 Merge of directories/non-directories/ext. info flags u000C rmb 1 Wildcards in effect flag u000D rmb 1 Extended info flag (0=No) u000E rmb 1 Directories ONLY (0=No) u000F rmb 1 Non-directories ONLY (0=NO) u0010 rmb 1 One entry/line flag (0=Yes, else no) u0011 rmb 1 Screen width u0012 rmb 1 # chars left on current output line u0013 rmb 2 Length of current filename u0015 rmb 1 char from current directory entry u0016 rmb 1 char from wild card string u0017 rmb 1 Attributes for DIR open (Ex. EXEC) * File descriptor info - 1st 13 bytes - only used if certain options and/or * extended directory listings are requested. u0018 rmb 1 File attributes u0019 rmb 2 File owner ID u001B rmb 5 Date last modified u0020 rmb 1 DIR path # (link count on FD read, but not used) u0021 rmb 4 File size (in bytes) * Start of WritLn buffer for each directory entry starts here u0025 rmb 1 * Information to be printed out goes here * user-number, 4 bytes of hex, space space u0026 rmb 6 * YY/MM/DD HHMM u002C rmb 17 * file attributes u003B rmb 10 * starting sector number u0045 rmb 8 * file size u004D rmb 8 * a space u0055 rmb 1 * file name u0056 rmb 25 u006F rmb 1 u0070 rmb 4 * starting sector of the file (3 bytes) u0074 rmb 2 u0076 rmb 1 u0077 rmb 1 always 0 AllFlag rmb 1 $2E=don't print out .foo, $00=print out .foo rmb 256 leave room for the stack size equ . name fcs /dir/ fcb $08 start ldd #$0150 Default to multiple entries/line, 80 column width std <u0010 lda #'. default to NOT printing files with this first char sta <AllFlag clra clrb std <u000E directories only/non-directories only flags std <u000C Clear wildcard & extended info flags sta <u0008 Set case sensitivity to ON leay >L0449,pc point to '.' sty <u0002 Default to current data directory as DIR path ldb #READ. directory attribute=READ. clr <u0077 Always 0 * Process parameter line L003F lda ,x get character cmpa #$0D End of parms? beq L0071 yup, time to dir! cmpa #$20 space? beq L006D yup, skip it pshs x save ptr to start of current sub-parm L004B lda ,x+ get char, bump up ptr cmpa #$20 if a space, skip it beq L0057 cmpa #$0D if not a CR, skip bne L004B leax -1,x save address of the CR L0057 stx <u0004 Save ptr to end of current sub-parm puls x Restore start of current sub-parm lda ,x Get 1st char of sub-parm cmpa #'- option flag? bne L0066 no, must be dir/filename, go process lbsr L023A Update flags based on hyphen options bra L0069 Continue from end of current sub-parm block L0066 lbsr L0286 Process dir and/or filenames L0069 ldx <u0004 Continue from end of current sub-parm block bra L003F Start working on next sub-parm L006D leax 1,x skip this character bra L003F and get another one * Done processing parameter line - start doing actual DIR * Entry: A=13 (which looks to be width if SS.ScSiz fails). L0071 stb <u0017 Save directory attributes byte ldb <u000D Get extended info flag orb <u000E Merge setting with Directories flag orb <u000F Merge with non-directories flag stb <u000B Save merged flag tst <u0010 one line/entry? beq L00B3 if so, continue pshs x,a * Calculate dir table width lda #1 ldb #SS.ScSiz return screen size os9 I$GetStt bcs L00A6 Check for unknown service error tfr x,d Move screen width to D cmpb #80 >=80 characters/line? bhs L00AF Yes, continue lda #60 go to 64 cmpb #60 64 to 79 chars? bhs L00AD Yes, set width to 64 lda #48 48 to 63 chars? cmpb #48 Yes, set width to 48 bhs L00AD lda #32 32 to 47 chars? cmpb #32 Yes, set to 32 chars bhs L00AD clr <u0010 if <32, do 1 file/line bra L00AD L00A6 cmpb #E$UnkSvc Unknown service code? beq L00AF Yes, skip ahead lbra L0430 Check for EOF, or exit with error L00AD sta <u0011 Save screen width we will use L00AF andcc #$FE Clear error flag puls x,a Restore regs L00B3 lda <u0017 Get current attributes flag ora #$80 Add DIR attribute ldx <u0002 Get ptr to DIR directory path os9 I$Open Open directory lbcs L0430 Error, exit with it sta <u0000 Save DIR path ldx <u0002 Get ptr to DIR pathname lda <u0017 Get DIR attributes we used to OPEN os9 I$ChgDir Change directory to DIR path tst <u000B Get dir vs. nondir, extended info flags beq L00ED None set, skip ahead lda <u0017 Get DIR attributes leax >L044B,pc point to '@' os9 I$Open Open current drive RAW (to get file descriptors) lbcs L0430 Error, check for EOF, or exit with it sta <u0001 Save path to raw drive L00ED lda <u0011 Get screen width sta <u0012 Save it as # chars left on current output line lda <u000D Get extended info requested flag ora <u0010 Merge with 1 line/entry flag beq L0145 All clear, skip 'Directory of' leax >L044D,pc Print ' Directory of ' to screen ldy #$000F lda #$01 os9 I$Write lbcs L0430 leay <u0025,u Point to directory entries buffer area ldx <u0002 Get pathname to directory L010D lda ,x+ Copy pathname up until CR sta ,y+ cmpa #$0D bne L010D tst <u000C Separate filename? beq L0127 No, skip ahead lda #'/ Yes, Add slash to end of buffer sta -1,y ldx <u0006 Get pointer to user filename request * Copy User filename to end of 'dir of' line L011F lda ,x+ Copy it over until CR * Force to uppercase if case insensitive flag set AND char is lowercase * Will make for faster compares later. lbsr ForcUppr Do uppercase change if needed sta -1,x Save over original char (in case changed) sta ,y+ cmpa #$0D bne L011F L0127 leax <u0025,u Point to full directory path/file requested ldy #$00FF Max of 255 chars to print lda #$01 Print directory name out (with 'directory of') os9 I$WritLn tst <u000D Extended info requested? beq L0145 No, skip extended info header ldd #$0102 std out for output, 2 lines to print leax >L045C,pc Write out extended info header lines lbsr L0627 lbcs L0430 * Main dir entry reading loop L0145 lda <u0000 get path number to current directory ldy #$001D get the filename leax <u0056,u where to put it os9 I$Read read it lbcs L0430 ldy #$0003 and the starting sector leax <u0074,u os9 I$Read lbcs L0430 lda <u0056 get the first character of filename beq L0145 if zero (deleted), skip it cmpa #$80 hi bit (deleted), ignore it beq AllCont continue * Now A<>0, and AllFlag may be zero (=print out all files) anda #$7F cmpa <AllFlag do all files? beq L0145 if the first character is '.', don't print it * Non '.' leading char filenames go here AllCont clrb Filename size set to 0 leax <u0056,u Point to filename L016D lda ,x+ Check char incb Bump up filename size cmpa #$80 End of filename marker? blo L016D No, keep getting size anda #$7F make it a real character sta -1,x save it back lda #$0D Add carriage return to filename sta ,x stb <u0013 Save filename size tst <u000C filename to match specified? beq L0191 No, skip ahead leax <u0056,u Point to filename part of write buffer ldy <u0006 Get ptr to filename match string lbsr L0324 Do wildcard compare tst <u0009 Did we have a match? beq L0145 No, skip to next filename L0191 tst <u000B Any files we have to weed out? beq L01CA No, just print * we only want certain types of files - check ldx <u0074 Get FD sector # - hi word pshs u Preserve U ldu <u0076 Get FD sector # - low word lda <u0001 Get path to raw drive os9 I$Seek seek to the file descriptor lbcs L0430 puls u Restore U leax <u0018,u Point to place to store FD info ldy #13 We only need 1st 13 bytes os9 I$Read Read it in lbcs L0430 lda <u0018 Get file attributes anda #$80 Ignore all but DIR attribute tst <u000E Directories ONLY? beq L01C1 No, skip ahead tsta This file a directory? lbeq L0145 No, skip to next filename bra L01CA Yes, print dir name out L01C1 tst <u000F Non-directories ONLY? beq L01CA No, print filename out tsta This file a non-directory? lbne L0145 It is a DIR, skip to next filename * Print current dir entry out L01CA tst <u0010 do one entry/line? beq L0221 yes, print it out clr <u000A Flag we have NOT printed filename yet. ldb <u0013 Get filename size cmpb <u0012 enough chars left in current output line to fit? bge L0205 No, Print CR inc <u000A Flag that we will have printed filename L01D8 clra D=Current filename size tfr d,y Y=size of filename inca Std Out leax <u0056,u Point to filename in output buffer os9 I$Write Write out filename lbcs L0430 lda <u0012 Get # chars left on current output line * Add spaces between filenames - they are 'tabbed' at 16 or 32 chars, * depending on filename size L01E8 suba #16 Subtract 16 from # chars left on output line ble L0205 Done line, print CR subb #16 Not done, subtract 16 chars from filename size bge L01E8 filename was >16 chars, bump to next 'tab' stop negb # spaces we have to print to pad to next 'tab' sta <u0012 Save # chars left on output line clra Y=# spaces to print to finish current tab field tfr d,y inca Std out leax >L04F2,pc Write spaces out os9 I$Write lbcs L0430 lbra L0145 On to next filename entry * Flush out current output line to screen, reset # chars left on output line * to screen width. L0205 lda #$01 Print CR by itself ldy #$0001 leax >L044A,pc os9 I$WritLn lbcs L0430 lda <u0011 Get screen width sta <u0012 Save as size available on current line tst <u000A Did we print filename out yet? beq L01D8 No, do it now lbra L0145 Already printed, skip to next filename L0221 tst <u000D lbne L036A if not zero, print out all the information lda #$01 leax <u0056,u ldy #$001E length of the filename os9 I$WritLn dump out the filename lbcs L0430 lbra L0145 * parse the path options * Entry: X=ptr to current char being checked in parameter line L023A leax 1,x Point to next char lda ,x Get it cmpa #$20 Space? beq L025E Yes, done current parm, return cmpa #$0D CR? beq L025E Yes, done parm line, return anda #$DF make it uppercase cmpa #'E extended directory? beq L0274 cmpa #'S Single entry/line beq L0270 cmpa #'D Directories only beq L027A cmpa #'F Non-Dirs only beq L0280 cmpa #'X Execution directory beq L026C * Curt's additions here cmpa #'C Case insensitve? beq CaseIns *--- my additions here cmpa #'L Extended dir beq L0274 cmpa #'A do _all_ files (includes '.' and '..') beq DoAll bra L025F L025E rts CaseIns inc <u0008 Set case insensitivity ON bra L023A L025F ldd #$010c 12 lines of text in help leax >L0505,pc Point to help message lbsr L0627 Print it out lbra L0430 L026C addb #EXEC. add in exec attribute bra L023A and get another character L0270 clr <u0010 one line/entry bra L023A L0274 inc <u000D print out all info clr <u0010 one line/entry bra L023A L027A inc <u000E Set directories only flag clr <u000F Clear non-directories only flag bra L023A L0280 inc <u000F Set non-directories only flag clr <u000E Clear directories only flag bra L023A DoAll clr <AllFlag do all files bra L023A and get another character * Process requested dir/file name from user * Entry: X=ptr to start of wildcard matching filename * Exit: u0002=ptr to start of dir name * u0006=ptr to start of filename to match (if any) * L0286 stx <u0002 save ptr to start of file/dir name L0288 lda ,x+ Get char from file/dir name cmpa #'_ underscore? beq L0288 skip it cmpa #'. period or under? blo L02A6 special checks, skip ahead cmpa #'9 9? bls L0288 Below, skip to next char cmpa #'A Between ':' and '@', skip ahead blo L02A6 cmpa #'Z Uppercase letter, skip to next char bls L0288 cmpa #'a Between '[' and "'", skip ahead blo L02A6 cmpa #'z lowercase, skip to next char bls L0288 L02A6 cmpa #$0D cr? beq L02B2 exit if so cmpa #$20 space? bne L02B3 no, go do more checks lda #$0D replace space with CR (only 1 file/dirname allowed) sta ,-x save in the parameter area L02B2 rts * Special char check L02B3 cmpa #'* any sequence match wildcard? beq L02C1 yes, process it cmpa #'? one-character wildcard? beq L02C1 yes, process it ldb #E$BNam Exit with Bad filename error orcc #1 lbra L0430 L02C1 stx <u0006 Save pointer to filename match string L02C3 lda ,x+ grab another byte cmpa #$0D CR? beq L02D1 yup, exit cmpa #$20 space? bne L02C3 no, skip it lda #$0D dump a CR at the end of the filename sta ,-x L02D1 ldx <u0006 Get ptr to start of filename again L02D3 lda ,-x get the previous character to filename cmpx <u0002 was dirname ptr? bne L02E3 no, check for user specified dir separator stx <u0006 save start of filename leax >L0449,pc point to a '.' (current dir) stx <u0002 save dir pathname bra L02ED L02E3 cmpa #'/ slash (wildcard is start of filename after dir)? bne L02D3 no, keep searching back until '/' or start of entry lda #$0D Found '/', Put CR over slash sta ,x+ (separate dir name from filename) stx <u0006 Save new wildcard start L02ED inc <u000C Set wildcards used flag ldx <u0006 Get wildcard start L02F1 lda #$0D Is current char of wildcard CR? cmpa ,x beq L0323 Yes, skip ahead lda #'* wildcard? cmpa ,x beq L0301 yes, do it leax 1,x otherwise skip the character bra L02F1 L0301 leay 1,x cmpa ,y beq L0311 lda #'? one-character wildcard? cmpa ,y beq L031B leax $01,x bra L02F1 L0311 lda ,y+ sta -$02,y cmpa #$0D bne L0311 bra L02F1 L031B sta ,x+ lda #'* save a wildcard sta ,x bra L02F1 L0323 rts * Compare current dir entry filename to user specified match filename * Entry: X=ptr to current filename from dir * Y=ptr to wildcard match filename * Exit: <u0009=0, no match * <>1, match L0324 lda ,x Get char from current dir entry filename bsr ForcUppr Change case if needed ldb ,y Get char from user match filename std <u0015 Save both 1st chars cmpb #$0D CR of wildcard? bne L0334 No, skip ahead cmpa #$0D CR of current DIR entry filename? beq L0362 Yes, matched bra L0367 No match L0334 cmpb #'* any char match wildcard? beq L034A yes, do it cmpa #$0D End of filename from current dir entry? beq L0367 Yes, flag that filename did NOT match cmpb #'? one-character wildcard? beq L0344 yes, simply skip over 1 char in both strings cmpb <u0015 non-wildcard char from user match dir entry? bne L0367 No, flag no match & return L0344 leax 1,x next up in current dir entry leay 1,y next up in wildcard bra L0324 Continue comparing L034A leay 1,y Bump up user filename char ptr ldb ,y Get that char from user filename string cmpb #$0D End of wildcard match string? beq L0362 Yes, set flag & return L0352 cmpb <u0015 Same as current char from current filename? beq L0344 Yes, bump both string pointers up and do next chars leax 1,x Bump up dir entry char ptr lda ,x Get char cmpa #$0D End of filename? beq L0367 Yes, clear flag and return sta <u0015 Save char from current dir entry bra L0352 Try next * Flag that wildcard compare has a match (so far) L0362 lda #$01 sta <u0009 rts * Flag that wildcard compare did NOT match L0367 clr <u0009 rts * Change current char in A to uppercase, if <u0008 <>0 ForcUppr tst <u0008 Case insensitive? beq NoChange No, check char as is cmpa #'a blo NoChange Non-lowercase, check as is cmpa #'z Lowercase? bhi NoChange No, check as is anda #$DF Force uppercase NoChange rts * Copy default output line information to output line buffer L036A leax >L04D4,pc Point to default date/attributes string leay <u0025,u Point to output line buffer L0371 lda ,x+ Copy until we hit LF cmpa #$0A beq L037B sta ,y+ bra L0371 L037B leay <u0026,u Point to start of output line buffer leax <u0019,u Point to file creator's user # ldb #$02 print out user number, in hex (2 bytes) L0383 lda ,x+ lbsr L0409 dump hex ASCII number into 2 bytes @ y decb Do 2nd byte bne L0383 leax <u0026,u Point to start of user # in output buffer lbsr L0420 replace leading zeros with spaces leay <u002C,u Where ASCII date/time info goes in write buffer leax <u001B,u Point to date/time last modified binary data * Y2k - Treat century as separate # ldb ,x Get year clra Century offset starts @ 0 LoopCent cmpb #100 Calculate century offset (0-2) into A blo DoCent inca subb #100 bra LoopCent DoCent tfr a,b Save century offset adda #19 actual century offset bsr L03F8 Convert A to 2 digit century lda #100 mul Calculate # of years already accounted for pshs b Save it lda ,x+ Get original year back suba ,s+ Calculate years left bsr L03F8 Dump rest of year out leay 1,y Skip slash ldb #2 We are converting 3 #'s into 2 digit ASCII L0399 lda ,x+ Get binary value bsr L03F8 dump it out in ASCII leay 1,y Skip over when '/' decb bne L0399 lda ,x+ bsr L03F8 HH lda ,x bsr L03F8 MM * Attributes leay <u003B,u leax <u0018,u ldd #$2D08 hyphen, 8-times L03B3 lsl ,x bcs L03B9 sta ,y save hyphen if bit is not set L03B9 leay $01,y go to the next byte decb bne L03B3 Do all 8 attribute bits leay <u0045,u Point to part of output buffer for start sector # leax <u0074,u Point to start sector # data ldb #$03 3 bytes of data to do L03C6 lda ,x+ Convert to hex bsr L0409 decb bne L03C6 leax <u0045,u bsr L0420 replace leading 0's with spaces leay <u004D,u Point to file size in output buffer leax <u0021,u Point to file size data ldb #$04 4 bytes of data to do L03DB lda ,x+ Convert to hex bsr L0409 decb bne L03DB leax <u004D,u bsr L0420 replace leading 0's with spaces leax <u0025,u Point to output buffer ldy #$0050 Print line (filename done earlier) lda #$01 os9 I$WritLn bcs L0430 lbra L0145 Onto next dir entry * Dump decimal ASCII out for contents of A (2 digit max) * ,y must contain a '0' for this to work. L03F8 cmpa #10 <10? blo L0402 Yes, just do one digit inc ,y Bump up 10's counter suba #10 Subtract 10 from byte bra L03F8 Do until 10's digit is done. L0402 leay 1,y Skip to 2nd byte adda #'0 add in a zero (for bin to ASCII) sta ,y+ Save it & return rts * Convert binary to hex * Entry: A=byte to convert to 2 digit hex * Y=ptr to 2 byte buffer to hold ASCII HEX chars L0409 pshs a Save byte lsra A=high nibble (shifted down) lsra lsra lsra bsr L0415 Make digit puls a Restore original anda #$0F Mask out high nibble L0415 adda #'0 Convert to ASCII char cmpa #'9 bls L041D adda #$07 L041D sta ,y+ rts * replace leading zeros with spaces from ASCII sequence, stopping at non-zero * Entry: X=ptr to string L0420 ldd #$3020 Zero & space chars L0423 cmpa ,x is the first character a zero? bne L042F if not, return cmpb 1,x is the 2nd character a space? beq L042F if '0 ', return without any changes stb ,x+ otherwise save space over '0', go onto next char bra L0423 L042F rts L0430 cmpb #E$EOF bne L0435 clrb ignore EOF errors L0435 tst <u0010 one file/line? beq L0446 if so, exit leax >L044A,pcr output a CR lda #$01 ldy #$0001 os9 I$WritLn and then exit L0446 os9 F$Exit L0449 fcc /./ L044A fcb $0d L044B fcc /@/ fcb $0d L044D fcb $0a fcc / Directory of / L045C fcb $0a fcc /User # Last Modified Attributes Sector File Size File Name/ fcb $0d fcc /------ --------------- ---------- ------ --------- ----------/ fcb $0d L04D4 fcc ' 0000/00/00 0000 dsewrewr' L04F2 fcc / / L0505 fcb $0a fcc 'dir [-opts] [path/patt] [-opts]' fcb $0d fcc /opts: x - use current exec dir/ fcb $0d fcc ' s - one entry/line' fcb $0d fcc ' e/l - extended directory' fcb $0d fcc / a - show '.files', too/ fcb $0d fcc / d - only directory files/ fcb $0d fcc / f - only non-dir files/ fcb $0d fcc / c - case insensitive filename match (BUT NOT DIR NAME)/ fcb $0d fcc / ? - help message/ fcb $0d fcc /pattern: may include wild cards/ fcb $0d fcc / * - multiple character/ fcb $0d fcc / ? - single character/ fcb $0d * Print several lines of text up to 80 chars each * Entry: X=Ptr to multi-line text string (CR terminates lines) * B=# of lines to write. L0627 decb Dec line counter ldy #80 os9 I$WritLn bcs L0642 Error writing, return with it pshs d preserve path/line count tfr y,d Move size actually written to D leax d,x Bump source buffer ptr to next line puls d Restore path/line count tstb Any lines left to print? beq L0642 No, exit bra L0627 Yes, print next line L0642 rts emod eom equ *