 nam   Dir 
 ttl   program module        
 
* Edition 10 rewrite 10/27/88 - RML
 
 ifp1
 use     defsfile
 endc
 
tylg     set   Prgrm+Objct 
atrv     set   ReEnt+rev 
rev      set   $01 
 
 mod   eom,name,tylg,atrv,start,size 
 
dirnam   rmb   2 
dirpath  rmb   1 
expflag  rmb   1 
execbit  rmb   1 
devpath  rmb   1 
lead0flg rmb   1 
colcnt   rmb   1 
maxchars rmb   1 
col32    rmb   1 
lnptr    rmb   2 
datehold rmb   3 
timehold rmb   3 
filename rmb   29 
sector1  rmb   1 
sector2  rmb   1 
sector3  rmb   1 
attr     rmb   1 
owner    rmb   2 
lstdate  rmb   6 
fsize1   rmb   2 
fsize2   rmb   2 
outline  rmb   530 
size     equ   . 
 
name     equ   * 
 fcs   /Dir/ 
edition  fcb   10  
 
msg1
 fcb   $0A 
 fcs   / Directory of / 
 
msg2
 fcb   $0a
 fcc   /Owner Last modified Attributes Sector Bytecount Name/ 
 fcb   $0a
msg2sz   equ   *-msg2 
 
 
msg3
 fcb   $0a
 fcc   /Modified on  Owner   Name/ 
 fcb   $0a
 fcc   /  Attr     Sector     Size/ 
 fcb   $0a
msg3sz   equ   *-msg3 
 
start    equ   * 
 leay  <outline,u point to start of output buffer
 sty   <lnptr   and save as line pointer
 clr   <execbit clear exec bit
 clr   <expflag clear expanded dir flag
 clr   <col32   clear 32 col flag
 ldd   #$1030   16 chars per column,48 chars per line
 std   <colcnt   save limits
 pshs  y,x,b,a  save registers
 lda   #1       std output path
 ldb   #SS.Scsiz get size of screen
 os9   I$GetStt 
 bcc   chksize  no error..go check screen size
 cmpb  #E$UnkSvc was it unknown svc request
 beq   chkopts  yes...set up as 80 col output
 puls  y,x,b,a  retore registers
 lbra  exit     exit error
 
dirdot
 fcc   /./ 
 fcb   $0D 
 
chksize
 cmpx  #60      check screen size
 bge   chkopts  if greater than or equal..do 80 col
 inc   <col32   else set flag for 32 col
 ldd   #$0A14   10 chars per column,20 chars per line
 std   <colcnt   save limits
 
chkopts
 puls  y,x,b,a  restore registers
 lbsr  chkparm  check for E/X flags
 lda   ,-x      point to first char of path name
 cmpa  #$0D     was it end of line
 bne   savename nope....use path name given
 leax  <dirdot,pcr else point to '.' mnemonic for current dir
 
savename
 stx   <dirnam  save path name start address
 lda   #DIR.+READ. open attributes
 ora   <execbit add in exec bit if x option specified
 pshs  x,a      save registers
 os9   I$Open   attempt file open
 sta   <dirpath save path number
 puls  x,a      restore registers
 lbcs  exit     exit on error
 os9   I$ChgDir change to that dir
 lbcs  exit     exit on error
 pshs  x        save reg
 leay  msg1,pcr get 'dir of' msg
 lbsr  mvfname  merge the msg into line
 ldx   <dirnam  get addr of dir path name
 
movename
 lda   ,x+      get a char
 lbsr  movechar move it in
 cmpx  ,s       are we at end of path name?
 blo   movename nope..loop back for next
 leas  $02,s    drop local off stack
 lbsr  chkparm  check for E/X options
 lbsr  moveblnk move a space into line
 lbsr  moveblnk move a space into line
 leax  datehold,u buffer for date/time
 os9   F$Time   get current date/time
 leax  timehold,u point to hours
 lbsr  datim030 convert time
 lbsr  lineprnt send line
 tst   <expflag do we want expanded dir
 beq   skipdots nope..skip this stuff
 lda   #READ.   set read attribute
 ora   <execbit add exec bit if needed
 leax  <devfile,pcr point to '@'
 os9   I$Open   open the device as a file
 lbcs  exit     exit on error
 sta   <devpath save path number
 tst   <col32   are we doing 32 col screen
 bne   dohdr030 yes...print that header
 leax  msg2,pcr else point to 80 col header
 ldy   #msg2sz  chars to send
 bsr   sndline  send it
 leay  hdrdata,pcr point to '-' data
 
dohdr010
 lda   #'-      get fill character
 ldb   ,y+      get fill count
 beq   dohdr040 done..go send line
 bsr   dohdr020 else merge in fill char 
 lda   #$20     get a blank
 sta   ,x+      and move it in 
 bra   dohdr010 loop back for next set
 
devfile
 fcc   /@/ 
 fcb   $0D 
 
dohdr020
 sta   ,x+      move the char in
 decb           bump counter down
 bne   dohdr020 if more..loop back
 rts
 
hdrdata
 fcb   5,13,10,6,9,10,0 
 
sndline
 lda   #1       std out
 os9   I$WritLn 
 leax  <outline,u point to output buffer
 rts
 
dohdr030
 leax  msg3,pcr point to 32 col header
 ldy   #msg3sz  chars to send
 bsr   sndline  send the line
 lda   #'=      char to move
 ldb   #31      chars to send
 bsr   dohdr020 merge them in
 
dohdr040
 stx   <lnptr   save line pointer
 lbsr  lineprnt write the line out
 
skipdots
 lda   <dirpath get dir path
 ldx   #$0000   clear msb for seek
 pshs  u        save u
 ldu   #$0040   skip first two dir entries
 os9   I$Seek   seek to that position
 puls  u        restore u register
 lbra  readnext go to read in a dir entry
 
chkactiv
 tst   <filename is it an active entry ???
 beq   readnext nope...read next one
 tst   <expflag do we want expanded dir
 bne   doline   yup...go do it
 leay  <filename,u else point to dir name
 lbsr  mvfname  merge the name in
 
chklnsz
 lbsr  moveblnk merge a blank in
 ldb   <lnptr+1 get lsb of line pos
 subb  #outline get chars in line
 cmpb  <maxchars   is it > max ?
 bhi   prntline yes..send the line & read next dir entry
 
spacepad
 subb  <colcnt   else subtract chars per column
 bhi   spacepad loop back if not done
 bne   chklnsz  go back & move another blank
 bra   readnext get next dir entry
 
* do expanded dir line
 
doline
 pshs  u        save u reg
 lda   <sector3 get lsb of sector number
 clrb           and make least byte 0
 tfr   d,u      move to u for seek
 ldx   <sector1 get 2 msb's of file sector address
 lda   <devpath get path number of device
 os9   I$Seek   seek to file fd sector
 puls  u        restore u register
 bcs   exit     exit on error
 leax  <attr,u  point to buffer
 ldy   #$000D   bytes to read from FD entry
 os9   I$Read   read it
 bcs   exit     exit on error
 tst   <col32   80 col screen ?
 bne   prnt32   nope..do 32 col processing
 bsr   moveown  move in the owner
 lbsr  datim010 move in last modified
 lbsr  moveblnk move in a space
 lbsr  attr010  move in attributes
 bsr   movesz   move in file size & start sector
 leay  <filename,u point to file name
 lbsr  mvfname  merge the name in
 
prntline
 lbsr  lineprnt send the line
 bra   readnext go read next dir entry
 
moveown
 ldd   <owner   get owner number
 clr   <lead0flg clear lead zero flag
 bsr   cvrthex  convert to decimal & move it in
 bsr   moveblnk move in a blank
 rts
movesz
 bsr   moveblnk move in a blank
 bsr   moveblnk move in a blank
 bsr   prntsect move in start sector
 bsr   prntfsiz move in byte count
 rts
 
 
* Send line for 32 column
 
prnt32
 lbsr  datim010 move in date last modified
 bsr   moveown  move in owner
 leay  <filename,u point to file name
 lbsr  mvfname  move it in
 lbsr  lineprnt send the line
 bsr   attr010  move in attributes
 bsr   movesz   move in file size & start sector
 lbsr  lineprnt send the line
 
readnext
 leax  <filename,u 
 ldy   #32      chars to read
 lda   <dirpath dir path
 os9   I$Read   read a dir entry
 lbcc  chkactiv if read o.k...go back & process
 cmpb  #E$EOF   was it end of file
 bne   exit     no..error exit 
 clrb           else clear error code
 
exit
 bsr   lineprnt send the current line
 os9   F$Exit   and exit
 
prntfsiz
 ldd   <fsize1  get 2 high bytes file size
 bsr   binhex   convert first byte to hex & merge in
 tfr   b,a      xfer for second byte
 bsr   binhex10 convert second byte & move in
 bsr   moveblnk move in a space
 ldd   <fsize2  get 2 low order bytes
 bra   cvrthex  and conver & move them in
 
prnthi
 pshs  a        save byte
 lsra           shift off 4 low bits 
 lsra
 lsra
 lsra
 bsr   binhex30 print the low order bits
 puls  pc,a     restore byte & return
 
* Convert byte in 'A' to hex digits & move them in
 
binhex
 clr   <lead0flg set flag to strip lead zeros
 
binhex10
 bsr   prnthi   convert & move first hex char
 
binhex20
 anda  #$0F     strip off high 4 bits
 
binhex30
 tsta           anything left
 beq   binhex40 nope...go print 0 or blank
 sta   <lead0flg else set falg for no more zeros
 
binhex40
 tst   <lead0flg check the number
 beq   moveblnk it was a zero...move a space in
 adda  #'0      add ascii bias
 cmpa  #'9      is it a number
 bls   movechar yes..go move it in
 adda  #$07     else its a letter so add on bias
 bra   movechar and move it in
 
prntsect
 lda   <sector1 get high order byte of sector number
 bsr   binhex   convert to hex & move it in
 ldd   <sector2 get 2 low order bytes of sector number
 
cvrthex
 bsr   binhex10 convert first byte to hex & move in
 tfr   b,a      xfer bytes
 bsr   prnthi   print first char of second byte
 inc   <lead0flg set flag so we print at least a 0
 bsr   binhex20 convert & move the least significant character
 
* merge a blank into the output line
 
moveblnk
 lda   #$20     get a blank
 
* Merge one char into the outut line
 
movechar
 pshs  x        save x
 ldx   <lnptr   get current line pointer
 sta   ,x+      move the character in
 stx   <lnptr   save new line counter
 puls  pc,x     restore x & return
 
* Merge the file attributes into the output line
 
attrs
 fcc   /dsewrewr/ 
 fcb   $ff 
 
attr010
 ldb   <attr    get attributes
 leax  <attrs,pcr point to attributes
 lda   ,x+      get first attribute char ('d')
 
attr020
 lslb           shift off 1 bit
 bcs   attr030  move atribute char in if bit set
 lda   #'-      get a dash
 
attr030
 bsr   movechar merge it in
 lda   ,x+      get next char from attributes
 bpl   attr020  loop back if not done
 rts            else return
 
* Merge the file name into the output line
 
mvfname
 lda   ,y       get a char from dir
 anda  #%01111111 strip off high order bit
 bsr   movechar merge the character into the line
 lda   ,y+      check bit again & bump up pointer
 bpl   mvfname  if not done,loop back
 
mvfn010
 rts
 
* send the line
 
lineprnt
 pshs  y,x,a    save registers
 lda   #$0D     get a <cr>
 bsr   movechar merge it in
 leax  <outline,u point to start of line 
 stx   <lnptr   save line pointer
 ldy   #80      max chars to send
 lda   #$01     std out
 os9   I$WritLn write it
 puls  pc,y,x,a restore regs & return
 
* Convert & move the last modified date/time
 
datim010
 leax  <lstdate,u get the date last updated
 bsr   datim060 move first two chars
 bsr   datim020 move '/' and next two
 bsr   datim020 move '/' and next two
 bsr   moveblnk move a space
 bsr   datim060 move hours
 bsr   datim060 move minutes
 bra   moveblnk go move a space & exit
 
datim020
 lda   #'/      get the separator
 bra   datim050 go move it in & convert next two
 
datim030
 bsr   datim060 move the hours
 bsr   datim040 move the ':' and minutes,fall thru to move sec
 
datim040
 lda   #':      get the separator
 
datim050
 bsr   movechar move the chracter in  
 
datim060
 ldb   ,x+      get a char from the buffer
 lda   #$2f     ('0'-1)
 cmpb  #100     is < 100 ?
 blo   datim070 yes..dont do 100's processing
 clrb           else make it a zero
 
datim070
 inca           increment 100's counter
 subb  #100     decrement by 100
 bcc   datim070 if more..loop back
 cmpa  #$30     did we have one ?
 beq   datim080 nope...dont print it
 bsr   movechar else print the char
 
datim080
 lda   #$3A     ('9'+1)
 
datim090
 deca           bump down counter
 addb  #10      subtract 10
 bcc   datim090 if more...loop back
 lbsr  movechar print the char
 tfr   b,a      xfer remainder
 adda  #'0      add ascii bias
 lbra  movechar and move it in  
 
* Check the param line for 'E' or 'X' options
 
chkparm
 ldd   ,x+      get a char
 cmpa  #$20     was it a blank
 beq   chkparm  yes..skip it
 cmpa  #$2C     was it a comma
 beq   chkparm  yes skip it
 anda  #$DF     make it upper case
 cmpa  #'E      do we want expanded directory
 bne   chkp010  no..check if we want exec dir
 cmpb  #'0      was it number or letter
 bhs   mvfn010  yes..just exit out
 inc   <expflag else set flag for expanded dir
 bra   chkparm  and check rest
 
chkp010
 cmpa  #'X      do we want exec dir
 bne   mvfn010  nope...just exit out (pointing to path name)
 cmpb  #'0      is next char number or alpha?
 bhs   mvfn010  yes..start of name so exit
 lda   #EXEC.   else set exec bit
 sta   <execbit and check next 
 bra   chkparm  and check next char
 
 emod
eom      equ   * 
 
 
 
