;************************************************
;*                                              *
;*                  FileSize                    *
;*                                              *
;*              von Matthias Kühn               *
;*                                              *
;*                für KICKSTART                 *
;*                                              *
;************************************************
_LVOOpenLibrary  EQU -$0228
_LVOCloseLibrary EQU -$019e
_LVOLock         EQU -$0054
_LVOUnLock       EQU -$005a
_LVOExamin       EQU -$0066
_LVOExNext       EQU -$006c
_LVOOutput       EQU -$003c
_LVOWrite        EQU -$0030
ExecBase         EQU      4
ACCES_READ       EQU     -2
CallSys        MACRO   $\Sub,$\Base
       MOVE.L  \Base,A6
       JSR     _LVO\Sub(A6)
       ENDM
Spalte MACRO   $\Zif1,$\Zif2
       MOVE.B  #$0d,(A0)+
       MOVE.B  #$9b,(A0)+
       MOVE.B  #\Zif1,(A0)+
       MOVE.B  #\Zif2,(A0)+
       MOVE.B  #$43,(A0)+
       ENDM

 MOVEM.L D0/A0/SP,Inital_D0
 BSR   OpenDos_
 BSR   Output_
 BSR   Lock_
 BSR   Directory_
 BSR   Files_
Error:
 BSR   Unlock_
 BSR   CloseDos_
 MOVE.L Inital_SP,SP
 RTS

OpenDos_:
       CLR.L   D0                      ;Version ist egal
       LEA     DosName,A1              ;Name der Library
       CallSys OpenLibrary,ExecBase    ;Library öffnen
       MOVE.L  D0,DosBase              ;Adresse retten
       BEQ     Error                   ;bei Fehler Ende
       RTS
CloseDos_:
       TST.L   DosBase                 ;ist Library geöffnet
       BEQ     \nein                   ;wenn ja
       MOVE.L  DosBase,A1
       CallSys CloseLibrary,ExecBase   ;dann schließen
\nein: RTS                             ;sonst nicht
Output_:
       CallSys Output,DosBase          ;momentanen OutputFile
       MOVE.L  D0,Output               ;holen und retten
       BEQ     Error                   ;wenn keiner da, dann Ende
       RTS
Lock_:
       MOVEM.L Inital_D0,D0/A0         ;CommandLenght und _Buffer
       ADD.L   D0,A0                   ;Pointer auf Ende
       SUB.L   #1,A0                   ;und eins weiter, dann
       MOVE.B  #0,(A0)                 ;LockInput mit 0 abschließen
       MOVE.L  ACCES_READ,D2           ;wir wollen nur lesen
       MOVE.L  Inital_A0,D1            ;Pointer auf CommandBuffer
       CallSys Lock,DosBase            ;DirZugriff holen
       MOVE.L  D0,Lock                 ;und retten
       BEQ     Error                   ;gibt es keinen, dann Ende
       RTS
Unlock_:
       MOVE.L  Lock,D1                 ;DirZugriff holen
       BEQ     \Ende                   ;gibt es keinen, dann Ende
       CallSys Unlock,DosBase          ;sonst schliesen
\Ende  RTS
Directory_:
       MOVE.L  Lock,D1                 ;DirZugriff holen
       MOVE.L  #FileInfoBlock,D2       ;Pointer auf Buffer
       CallSys Examin,DosBase          ;DirInfo holen
       TST.L   DirEntryType            ;testen ob es ein Dir ist
       BMI     Error                   ;wenn nicht dann Exit
       LEA     DirText,A1  
       LEA     WriteBuffer,A0
       MOVE.W  #4,D0                   ;5 Schleifen
\Dir   MOVE.W  (A1)+,(A0)+             ;'Directory:' in Buffer schreiben
       DBRA    D0,\Dir
       LEA     FileName,A1             ;Dir in Buffer schreiben
\next  MOVE.B  (A1)+,(A0)+
       BNE     \next
       SUB.L   #1,A0
       MOVE.B  #'/',(A0)+              ;Steuerzeichen in Buffer schreiben
       MOVE.B  #$a,(A0)+
       MOVE.B  #$d,(A0)+
       MOVE.L  A0,TextPointer
       BSR     Write_                  ;und ausgeben
       RTS
Files_:
       BSR     GetFile                 ;Fileinfo holen
       TST.L   D0                      ;war noch eins da
       BEQ     \1Ende                  ;wenn nein dann Ende
       LEA     WriteBuffer,A0          ;Pointer auf WriteBuffer
       BSR     WriteFile               ;vorderes File schreiben
       Spalte  '2','4'                 ;Steuerzeichen schreiben
       MOVE.L  Size,D0                 ;Size holen
       BNE     \1Size                  ;ist Size = 0, dann
       BSR     WriteDir                ;'Directory' schreiben
       BRA     \1                      ;sonst
\1Size BSR     WriteSize               ;Bytelänge schreiben
\1     Spalte  '3','8'                 ;Steuerzeichen
       MOVE.L  A0,TextPointer          ;TextPointer retten
       BSR     GetFile                 ;FileInfoBlock holen
       MOVE.L  TextPointer,A0          ;TextPointer holen
       MOVE.L  D0,-(SP)                ;war kein File da
       BEQ     \2                      ;dann Ende und D0 auf Stack
       BSR     WriteFile               ;sonst hinteres File schreiben
       Spalte  '6','2'                 ;wie oben ...
       MOVE.L  Size,D0
       BNE     \2Size
       BSR     WriteDir                
       BRA     \2
\2Size BSR     WriteSize               
\2     MOVE.B  #$a,(A0)+               ;CR und LF ans Ende
       MOVE.B  #$d,(A0)+
       MOVE.L  A0,TextPointer
       BSR     Write_
       TST.L   (SP)+                   ;weiteres File ?
       BNE     Files_                  ;wenn ja, dann an Anfang
\1Ende RTS                             ;sonst Ende
GetFile:
       MOVE.L  Lock,D1                 ;DirZugriff holen
       MOVE.L  #FileInfoBlock,D2       ;Pointer auf Buffer
       CallSys ExNext,DosBase          ;FileInfoBlock holen
       RTS
WriteFile:
       LEA     FileName,A1             ;FileName eintragen
\next  MOVE.B  (A1)+,(A0)+             ;solange Zeichen holen bis
       BNE     \next                   ;ein Null kommt
       SUB.L   #1,A0                   ;dann Pointer ein zurück
       RTS
WriteDir:
       LEA     DirText,A1              ;'Directory' schreiben
       MOVE.B  #' ',(A0)+              ;ein Space zur Ordnung
       MOVE.W  #8,D0                   ;9 Schleifen
\next  MOVE.B  (A1)+,(A0)+             ;Zeichen holen
       DBRA    D0,\next
       RTS
WriteSize:
       MOVE.B  #' ',D5         ;Leerzeichen in D5
       LEA     Divisor,A1       MOVE.W  #8,D4           ;9 mal Schleife durchlaufen
\10er  MOVE.L  (A1)+,D1        ;erster Divisor
       CMP.L   D1,D0           ;ist Dividend kleiner
       BLO     \Nicht          ;wenn nein
       MOVE.W  #31,D3          ;32 Schleifen durchlaufen
       CLR.L   D2
\Loop  ASL.L   #1,D0           ;D0 um 1 nach links und
       ROXL.L  #1,D2           ;in D2 schieben
       CMP.L   D1,D2           ;paßt Divisor in D2
       BLO     \ADR            ;wenn ja
       SUB.L   D1,D2           ;dann Divisor von D2 subtrahieren
       ADD.L   #1,D0           ;und 1 zu D0 addieren
\ADR   DBRA    D3,\Loop
       ADD.B   #$30,D0         ;in ASCII umwandeln
       MOVE.B  D0,(A0)+        ;ASCII schreiben
       MOVE.L  D2,D0           ;Rest -> Dividend
       MOVE.B  #'0',D5         ;D5 umschalten
       BRA     \next
\Nicht MOVE.B  D5,(A0)+        ;' ' oder '0' schreiben
\next  DBRA    D4,\10er
       ADD.B   #$30,D0         ;in ASCII umwandeln
       MOVE.B  D0,(A0)+        ;und schreiben
       RTS
Write_:
       MOVE.L  Output,D1               ;OutputHandle holen
       MOVE.L  #WriteBuffer,D2         ;Pointer auf TextAnfang
       MOVE.L  TextPointer,D3          ;TextEnde in D3
       SUB.L   #WriteBuffer,D3         ;und Länge ermitteln
       CallSys Write,DosBase           ;Text ausgeben
       RTS
;************************ ein paar Daten *************
       DATA
DosName:       DC.B    'dos.library',0
       ALIGN
DirText:       DC.B    'Directory:'
       ALIGN
Divisor:       DC.L    1000000000,100000000,10000000,1000000
               DC.L    100000,10000,1000,100,10
;************************ und etwas Platz für Infos **
       BSS
Inital_D0      DC.L    0       ;dosCmdLen
Inital_A0      DC.L    0       ;dosCmdBuf
Inital_SP      DC.L    0       ;Rücksprungadresse
DosBase        DC.L    0
Output         DC.L    0
Lock           DC.L    0
TextPointer    DC.L    0
FileInfoBlock  ;hier werden die Filedaten von Examin geschrieben
DiskKey        DS.L    1,0
DirEntryType   DS.L    1,0
FileName       DS.B    108,0
Protection     DS.L    1,0
EntryType      DS.L    1,0
Size           DS.L    1,0
NumBlocks      DS.L    1,0
Days           DS.L    1,0
Minute         DS.L    1,0
Tick           DS.L    1,0
Comment        DS.B    116,0
WriteBuffer    DS.B    200,' '
       END
