;*****  File-Tracer;  6/87  S.D.  *****

ExecBase  =  4      ;EXEC base address
FindTask  = -294    ;Search for Task-Structure
AddPort   = -354    ;Add port
RemPort   = -360    ;Remove port
OpenLib   = -408    ;Open library
CloseLib  = -414    ;Close library
OpenDev   = -444    ;Open Device
CloseDev  = -450    ;Close Device
DoIo      = -456    ;Start I/O and wait

output    = -60     ;Set standard output
write     = -48     ;Display data

; If  > 512K RAM assemble to Chip RAM or disable Fast Ram

run:
     move.l  a0,commpnt
     move.l  d0,commlen
     move.l  execbase,a6
     lea     dosname,a1       ;Name: dos.library
     clr.l   d0
     jsr     openlib(a6)      ;Open DOS.library
     move.l  d0,dosbase
     beq     nodos

     move.l  dosbase,a6
     jsr     output(a6)       ;Standard output channel
     move.l  d0,outbase

     sub.l   #1,commlen       ;Correct name length
     move.l  commpnt,a0       ;* Compute hash value *
     move.l  commlen,d0       ;Hash=Length
     clr.l   d2
     move.l  d0,d1
     subq    #1,d1            ;Counter=Length-1

hashloop:
     mulu    #13,d0           ;Hash=Hash*13
     move.b  (a0)+,d2
     bsr     upper            ;Convert to uppercase
     add     d2,d0            ;Hash=Hash+Character
     and     #$7ff,d0         ;AND $7FF
     dbra    d1,hashloop      ;Loop

     divu    #72,d0
     swap    d0               ;Hash modulo 72
     addq    #6,d0            ;+6
     move    d0,hash          ;Compute Hash

     move.l  #hashtxt,d2
     bsr     prtxt            ;Display "Hash:"
     move    hash,d0
     bsr     phex             ;Display Hash number

     move.l  execbase,a6      ;Pointer to EXEC library
     sub.l   a1,a1            ;Own task
     jsr     FindTask(a6)     ;Search for task
     move.l  d0,readreply+$10 ;set SigTask

     lea     readreply,a1
     jsr     AddPort(a6)      ;Add Reply-Port

     lea     diskio,a1
     clr.l   d0
     clr.l   d1
     lea     trddevice,a0
     jsr     OpenDev(a6)      ;Open trackdisk.device
     tst.l   d0
     bne     error

     move.l  #880,d0          ;Load sector 880 (root sector)
     bsr     loadsec          ;into disk buffer

     move.l  #voltxt,d2
     bsr     prtxt            ;Display "Volume:"
     move.l  dosbase,a6
     move.l  outbase,d1
     move.l  #diskbuff+433,d2 ;Name address
     clr.l   d3
     move.b  diskbuff+432,d3  ;Name length
     jsr     write(a6)        ;Display disk names

     lea     diskbuff,a0
     clr.l   d0
     move    hash,d0
     lsl     #2,d0            ;Hash*4=Sector-Pointer
     move.l  0(a0,d0),d0      ;Get sector number
     tst.l   d0               ;Pointer there?
     beq     none             ;NO: Hash entry not configured
loadloop:
     move.l  d0,sector
     bsr     loadsec          ;Load next sector

     move.l  commpnt,a0
     lea     diskbuff+432,a1  ;Get name length from header
     move.l  commlen,d0
     cmp.b   (a1)+,d0         ;Length set?
     bne     nextsec          ;NO

     subq    #1,d0
namelop:
     move.b  (a1)+,d2
     bsr     upper            ;Character in uppercase
     move    d2,d1
     move.b  (a0)+,d2
     bsr     upper            ;Character in uppercase
     cmp.b   d1,d2            ;Compare two characters
     bne     nextsec          ;false
     dbra    d0,namelop
     bra     sectorok         ;Name set

nextsec:
     move.l  diskbuff+496,d0  ;Pointer to next sector
     tst.l   d0               ;Is there one available?
     bne     loadloop         ;YES:Continue
none:                         ;else
     move.l  #unknown,d2
     bsr     prtxt            ;Display "-unknown"
     bra     ende             ;and end

sectorok:
     move.l  #header,d2
     bsr     prtxt            ;Display "Header:"
     move.l  sector,d0        ;Display sector's
     bsr     phex             ;header number

     cmp.l   #2,diskbuff+508  ;Dir-Header?
     bne     nodir            ;NO
     move.l  #dirtxt,d2
     bsr     prtxt            ;Display "Directory"
     bra     ende             ;and end

nodir:
     move.l  diskbuff+504,d0  ;Extension
     tst.l   d0               ;exists?
     beq     noextens         ;NO
     move.l  d0,-(sp)         ;Reserve D0
     move.l  #extxt,d2
     bsr     prtxt            ;Display "Extension"
     move.l  (sp)+,d0         ;Get sector number
     bsr     phex             ;and display it

noextens:
     move.l  #crtxt,d2
     bsr     prtxt            ;Display CR
     move.l  diskbuff+8,d0
     bsr     phex             ;Display number of sectors
     move.l  #sectxt,d2
     bsr     prtxt            ;Display "Sectors"
     clr     counter          ;Column counter=0
     bra     seclop1          ;Display sectors

secloop:
     move.l  sector,d0
     bsr     phex             ;Display sector number
     add     #1,counter       ;Counter+1
     cmp     #8,counter       ;8 numbers displayed?
     bne     seclop1          ;NO
     clr     counter          ;else clear counter
     move.l  #crtxt,d2
     bsr     prtxt            ;and display CR
seclop1:
     move.l  diskbuff+16,d0   ;Next sector
     tst.l   d0               ;available?
     beq     ende             ;NO: ready
     move.l  d0,sector
     bsr     loadsec          ;Load next sector
     bra     secloop          ;etc...

ende:
     move.l  #crtxt,d2
     bsr     prtxt            ;Display CR

     move.l  execbase,a6
     lea     readreply,a1
     jsr     RemPort(a6)      ;Remove Port
     lea     diskio,a1
     jsr     closedev(a6)     ;Close Trackdisk-Device
error:
     move.l  dosbase,a1
     jsr     closelib(a6)     ;Close DOS
nodos:
     rts                      ;End

loadsec:                      ;Load sector D0
     lea     diskio,a1
     move.l  #readreply,14(a1) ;set Reply-Port
     move    #2,28(a1)        ;Command: READ
     move.l  #diskbuff,40(a1) ;Buffer
     move.l  #512,36(a1)      ;Length: 1 sector
     mulu    #512,d0
     move.l  d0,44(a1)        ;Offset: Sector number+512
     move.l  execbase,a6
     jsr     DoIo(a6)         ;Read sector

     lea     diskio,a1
     move    #9,28(a1)        ;TD_MOTOR
     move.l  #0,36(a1)        ;Motor off
     jsr     DoIo(a6)
     rts

phex:                         ;Display D0 hex
     lea     outbuff,a0
     move    d0,d2
     move    #3,d3            ;4 numbers
niblop:
     rol     #4,d2            ;Move left nibble down
     move    d2,d1
     and     #$f,d1           ;Mask it off
     add     #$30,d1          ;Change to ASCII
     cmp     #'9',d1          ;Is it a number?
     bls     nibok            ;YES
     add     #7,d1            ;else correct it
nibok:
     move.b  d1,(a0)+         ;Character in output buffer
     dbra    d3,niblop        ;Continue loop
     move.b  #$20,(a0)        ;Space at the end

     move.l  dosbase,a6
     move.l  outbase,d1
     move.l  #outbuff,d2      ;Output buffer
     move.l  #5,d3            ;Display 5
     jmp     Write(a6)        ;characters

prtxt:                        ;Display text at (D2)
     move.l  dosbase,a6
     move.l  outbase,d1
     move.l  #12,d3           ;12 characters in length
     jmp     Write(a6)        ;Display 12 character text

upper:                        ;Convert D2 into uppercase
     cmp.b   #'a',d2          ;Character <'a'?
     blo     upperx           ;YES:Exit
     cmp.b   #'z',d2          ;Character >'z'?
     bhi     upperx           ;YES:Exit
     sub     #$20,d2          ;else correct it
upperx:
     rts                      ;Ready


trddevice:   dc.b "trackdisk.device",0
dosname:     dc.b 'dos.library',0

hashtxt:     dc.b $a,'Hashnum:   '
voltxt:      dc.b $a,'Volume:    '
unknown:     dc.b $a,'-unknown-  '
header:      dc.b $a,'Header:    '
extxt:       dc.b $a,'Extension: '
dirtxt:      dc.b $a,'Directory ',$a
sectxt:      dc.b 'Sectors:   ',$a
crtxt:       dc.b '           ',$a

 data
 align                   ;some assemblers use even
outbuff:     blk.b 6     ;Buffer for hex number output
sector:      blk.l 1     ;Sector buffer
counter:     blk.w 1     ;Output format counter
dosbase:     blk.l 1     ;DOS base address
outbase:     blk.l 1     ;Standard output handle
hash:        blk.w 1     ;Hash number
commpnt:     blk.l 1     ;Pointer to input line
commlen:     blk.l 1     ;Length of input line

diskio:                  ;Disk-I/O structure
message:     blk.b 20,0
io:          blk.b 12,0
ioreq:       blk.b 16,0

readreply:   blk.l 8,0
diskbuff:    blk.b 512,0
 end
