
;   ReadHash1.0
;   Written in 1989 by
;                        Sascha Groening
;                        Blaustrasse  13
;                        8360 Deggendorf
;                        Tel.:0991/25121
;
;   This is Public Domain !!!!
;
;   Written for the A68K Public Domain Assembler version 1.02 !!!


SysBase      equ  4
OpenLibrary  equ -552
CloseLibrary equ -414
Wait         equ -318
GetMsg       equ -372
ReplyMsg     equ -378
AllocSignal  equ -330
FreeSignal   equ -336
FindTask     equ -294
AddPort      equ -354
OpenDevice   equ -444
DoIO         equ -456
CloseDevice  equ -450
RemPort      equ -360
AllocMem     equ -198
FreeMem      equ -210
Output       equ -60     ;DOS
Write        equ -48     ;DOS
Open         equ -30     ;DOS
Close        equ -36     ;DOS
Exit         equ -144    ;DOS
DisplayBeep  equ -96     ;Int
OpenWindow   equ -204    ;Int
CloseWindow  equ -72     ;Int
RefreshGadgets equ -222  ;Int
SetWindowTitles equ -276 ;Int
Move         equ -240    ;Gfx
Text         equ -60     ;Gfx
ClearEOL     equ -42     ;Gfx
SetAPen      equ -342    ;Gfx

wd_RPort     equ $32
wd_UserPort  equ $56
MP_SIGBIT    equ $0F
wd_XOffset   equ $50
wd_YOffset   equ $51
rp_AreaInfo  equ $10
rp_cp_x      equ $24
rp_cp_y      equ $26
rp_TxHeight  equ $3A
rp_TxWidth   equ $3C
rp_TxBaseline equ $3E
rp_TxSpacing equ $40
ai_FirstX    equ $14
ai_FirstY    equ $16
im_Class     equ $14
im_Code      equ $18
im_IAddress  equ $1C
im_MouseY    equ $22
gg_GadgetID  equ $26
gg_SpecialInfo equ $22
pi_HorizPot  equ $02
pi_VertPot   equ $04
pi_HPotRes   equ $0E
pi_VPotRes   equ $10

WINDOWSIZING   equ $0001
WINDOWDRAG     equ $0002
WINDOWDEPTH    equ $0004
WINDOWCLOSE    equ $0008
SMART_REFRESH  equ $0000
ACTIVATE       equ $1000
CLOSEWINDOW    equ $00000200
WBENCHSCREEN   equ $0001
REPORTMOUSE    equ $0200
SIZEVERIFY     equ $00000004
NEWSIZE        equ $00000004
REFRESHWINDOW  equ $00000004
MOUSEBUTTONS   equ $00000008
MOUSEMOVE      equ $00000010
GADGETUP       equ $00000020
GADGETDOWN     equ $00000040
GADGHCOMP      equ $0000
RELVERIFY      equ $0001
GADGIMMEDIATE  equ $0002
FOLLOWMOUSE    equ $0008
RIGHTBORDER    equ $0010
BOOLGADGET     equ $0001
RP_JAM1        equ $0

PROPGADGET     equ $0003
AUTOKNOB       equ $0001
FREEVERT       equ $0004
KNOBHIT        equ $0100
MAXBODY        equ $ffff

MEMFCLEAR     equ $10001
ncbuffersize   equ $00003400


CALLEXEC macro
         move.l SysBase,a6
         jsr    \1(a6)
         endm
CALLINT  macro
         move.l IntBase,a6
         jsr    \1(a6)
         endm
CALLGRAF macro
         move.l GfxBase,a6
         jsr    \1(a6)
         endm
CALLDOS  macro
         move.l DOSBase,a6
         jsr    \1(a6)
         endm

    move.l  a0,comadr
    move.l  d0,comlaenge


    move.l  #dosname,a1
    moveq   #0,d0
    CALLEXEC OpenLibrary        ;Open DOSLibrary
    tst.l   d0
    beq     fini
    move.l  d0,DOSBase

    CALLDOS Output         ;LVOOutput
    move.l  d0,Handle

    move.l  comlaenge,d0   ;Commandozeilenlaenge <= 1
    cmpi.l  #1,d0          ;
    ble     helpmessage    ;

    lea     intname,a1
    moveq   #0,d0
    CALLEXEC OpenLibrary
    tst.l   d0
    beq     closedos
    move.l  d0,IntBase          ;Basis-Zeiger sichern

    lea     grafname,a1
    moveq   #0,d0
    CALLEXEC OpenLibrary
    tst.l   d0
    beq     closeint
    move.l  d0,GfxBase          ;Basis-Zeiger sichern

;
;  Signal besetzen
;
    moveq   #-1,d0
    CALLEXEC AllocSignal        ;AllocSignal
    tst.l   d0
    bmi     SignalFehler    ;D0=-1 =>Fehler
    move.b  d0,Signal
;
;   Msg-Port Struktur initialisieren
;
    move.b d0,mp_SigBit
    sub.l  a1,a1
    CALLEXEC FindTask         ;Find own Task
    move.l d0,mp_SigTask
    move.l #Speicher,a1
    CALLEXEC AddPort          ;AddPort
;
;**** Speicher belegen ***
;
    move.l #ncbuffersize,d0     ;groesse des Speichers
    move.l #MEMFCLEAR,d1      ;allokierten Speicher mit $00 fuellen
    CALLEXEC AllocMem

    move.l d0,DATA            ;nicht genug freier Speicher ?
    beq    nomem

    add.l  #$200,d0
    move.l d0,DATA2           ;Buffer fuer eingelesenen Fileheaderblock
    add.l  #$200,d0
    move.l d0,nbuffer         ;Buffer fuer Filenamen
    add.l  #$2000,d0
    move.l d0,cbuffer         ;Buffer fuer Fileheaderblocknummern
;
; TrackDiskDevice oeffnen
;

    move.l #TD_Name,a0
    move.l #IOStdReq,a1
    moveq  #0,d0
    clr.l  d1
    CALLEXEC OpenDevice         ;OpenDevice
    tst.l  d0
    bne    LeseFehler



;
; Block 880 in Buffer DATA lesen
;


    move.l  comadr,a0
    move.l  #buffer,a1
    move.l  comlaenge,d0
    subq.l  #1,d0
loop3
    move.b  (a0)+,(a1)+
    dbra    d0,loop3

    move.l  comlaenge,d0
    subq.l  #1,d0

    bsr     stringhex

;    move.l  d0,d2
;    move.l  d0,d5
;    lea.l   hbuf,a0                 ;Ziel der Konvertierung
;    move.b  #10,8(a0)               ;LineFeed anfuegen
;    bsr     hexasc
;    move.l  Handle,d1
;    move.l  #hbuf,d2
;    move.l  #9,d3
;    CALLDOS Write

;    move.l  d5,d0
    mulu    #512,d0
    move.l  d0,IO_OFFSET2         ;Offset=Block*512 (hier Block 880)

;    move.l  d0,d2
;    lea.l   hbuf,a0                 ;Ziel der Konvertierung
;    move.b  #10,8(a0)               ;LineFeed anfuegen
;    bsr     hexasc
;    move.l  Handle,d1
;    move.l  #hbuf,d2
;    move.l  #9,d3
;    CALLDOS Write


    move.l  DATA,IO_DATA2         ;in Buffer DATA lesen
    move.l  #Speicher,a1
    move.l  a1,mn_ReplyPort2
    bsr     LeseBlock             ;Lese RootBlock von Disk

;
; Hash Chain einlesen
;

        move.l  nbuffer,a5
        move.l  cbuffer,a3       ;Buffer fuer Liste
        move.l  #71,d5           ;Laenge der Hash-Chain in Bytes
        move.l  DATA,a2          ;Buffer fuer Block 880
        adda.l  #24,a2           ;Offset der Hash-Chain in Bytes

loop1   move.l  (a2)+,d2          ;n. Longword nach d2
        tst.l   d2                ;d2=$0L ?
        beq     loop2             ;dann nicht in Liste eintragen

        bsr     LeseFile
        bsr     LeseName
loop2   dbra    d5,loop1

                                  ;a3:Adr des letzten Longwords in Liste
        move.l  cbuffer,d5        ;d5;Adr des ersten   ---   "   ---
        sub.l   d5,a3             ;a3=a3-d5 ==> ListenLaenge in Bytes
        move.l  a3,d5
        asr.l   #2,d5             ;d5=d5/4  ==> ListenLaenge in Longwords
        move.w  d5,claenge

        move.w  #$0009,IO_COMMAND2  ;Motorstatus aendern
        move.l  #$0000,IO_LENGTH2   ;0==> Motor abschalten
        bsr     LeseBlock

;
;****   Window oeffnen   ****
;
   bsr      calcprop

   lea      windowdef,a0        ;zeige auf Window-Struktur
   CALLINT  OpenWindow          ;oeffne Window
   tst.l    d0                  ;ging was schief?
   beq      closegraf           ;wenn ja
   move.l   d0,windowptr        ;Window-Zeiger sichern

   move.l   d0,a1               ;brauche wieder Rastport
   move.l   wd_RPort(a1),a1
   move.l   a1,RPort

   clr.l    d2
   move.w   claenge,d2
   bsr      decl
   moveq.l  #8,d0
   move.l   #buffer1,a0
   move.l   #W_Title,a1
loop14
   move.b   (a0)+,(a1)+
   dbra     d0,loop14

   move.l   windowptr,a0
   movea.l  #W_Title,a1
   movea.l  #S_Title,a2
   CALLINT  SetWindowTitles

   movea.l  #S_Title,a2

   clr.l   d5
   move.w  claenge,d0
   move.w  lines,d5
   cmp.w   d5,d0
   bhi     cont7
   move.w  d0,d5
   tst.w   d0
   beq     event

cont7
   subq.w  #1,d5
   move.l  cbuffer,a3
   bsr     displaylist

* Auf Event warten, dann auswerten
* --------------------------------
event
        move.l  windowptr,a0         ;zeige auf Window-Struktur
        move.l  wd_UserPort(a0),a0   ;nun auf Message-Port
        move.l  a0,a5                ;rette Port-Adresse
        move.b  MP_SIGBIT(a0),d1     ;Signal Bit holen
        moveq   #0,d0                ;Nummer in
        bset    d1,d0                ;Maske wandeln
        CALLEXEC Wait                ;Schlaf gut!

        move.l   a5,a0               ;hole Port-Adresse
        CALLEXEC GetMsg              ;hole Message
        move.l   d0,a1               ;muss nach a1
        move.l   im_Class(a1),d4     ;Msg-Typ
        move.w   im_Code(a1),d5      ;Untergruppe
        move.l   im_IAddress(a1),a4  ;Adr. f. Gadgets
        CALLEXEC ReplyMsg            ;quittiere Msg in a1

        move.l   a4,ggaddress
        cmpi.l   #CLOSEWINDOW,d4     ;Window Closed?
        beq      CloseAll            ;wenn so

;        cmpi.l   #GADGETUP,d4
;        beq      propact

        cmpi.l   #GADGETDOWN,d4
        beq      do_gadget

        bra      event

do_gadget
        cmpi.w  #2,gg_GadgetID(a4)
        bne     event

;        sub.l   a0,a0
;        CALLINT DisplayBeep

        bsr     calclist

        clr.l   d5
        move.w  lines,d5

        move.w  claenge,d0
        cmp.w   d5,d0
        bhi     cont8
        move.w  d0,d5
        tst.w   d0
        beq     event
cont8
        subq.w  #1,d5
        move.w  #2,xpos
        move.w  #17,ypos
        bsr     displaylist1
        bra     event
;propact
;        move.l  gg_SpecialInfo(a4),a4
;        move.w  pi_VertPot(a4),d2
;        move.w  d2,d0
;        divu    #$1800,d0
;        addq.w  #1,d0
;        asl.w   #3,d0
;        addi.w  #9,d0
;        move.w  d0,ypos
;        bsr     displayhex2
;        bra     event


;******** Hash Chain ausgeben ******
;
;        move.w  claenge,d5
;        subq    #1,d5             ;d5=d5-1 wegen dbra
;        move.l  cbuffer,a3
;        bsr     DisplayChain      ;Liste ausgeben
;
;        bra     CloseAll

******************************************************
*******       Unterprogramme      ********************
******************************************************

movexy
   move.w   xpos,d0             ;X-Position
   move.w   ypos,d1             ;Y
   move.l   windowptr,a1        ;Via Window-Zeiger
   move.l   wd_RPort(a1),a1     ;  Rast-Port-Adresse holen
   CALLGRAF Move                ;Funtion Move to X,Y
   rts

printwin
   move.l   RPort,a1
   CALLGRAF Text
   rts

nextypos
   move.l   RPort,a1
   move.w   rp_TxHeight(a1),d0
   add.w    d0,ypos
   rts

prevypos
   move.l   RPort,a1
   move.w   rp_TxHeight(a1),d0
   sub.w    d0,ypos
   rts


;displayhex
;    move.l   #hbuf,a0
;    bsr hexasc
;
;    bsr movexy
;    move.l  #hbuf,a0
;    move.l  #8,d0
;    bsr printwin
;    bsr nextypos
;
;    clr.l   d2
;    rts

displayhex2
    move.l   #hbuf,a0
    bsr hexasc

    bsr movexy
    move.l  #hbuf,a0
    move.l  #8,d0
    bsr printwin

    clr.l   d2
    rts

displaydec2
    move.l   #buffer1,a0
    move.b   #32,9(a0)

    bsr decl

    move.l  #buffer1,a0
    move.l  #10,d0
    bsr printwin

    clr.l   d2
    rts

calcprop
    move.w  winbreite,gg2x
    sub.w    #16,gg2x
    move.w  winhoehe,gg2hoehe
    sub.w    #18,gg2hoehe

    move.w  lines,d0
    move.w  claenge,d1
    tst.w   d1
    beq     fini5

    mulu.w  #MAXBODY,d0
    divu.w  d1,d0
    move.w  d0,pi_VertBody
fini5
    rts



LeseFile
    move.l  d2,-(sp)

    mulu    #512,d2
    move.l  d2,IO_OFFSET2
    move.l  DATA2,IO_DATA2
    bsr     LeseBlock

    move.l  (sp)+,d2
    move.l  DATA2,a4

    move.l  508(a4),d0
    cmpi.l  #2,d0
    bne     cont6
    bset    #29,d2
cont6
    move.l  d2,(a3)+          ;Hash-Chain in Liste ablegen

    move.l  496(a4),d2 ;naechster eintrag in gleichen Hash
    tst.l   d2
    beq     fini1      ;wenn keiner da naechsten Hash lesen

    bset    #28,d2    ;um zu markieren dass Eintrag aus FileChain stammt

    move.l  d2,(a3)+  ;Hash in Liste eintragen: cbuffer
    subq.l  #4,a3

    bsr     LeseName  ;Name in Liste eintragen: nbuffer
    bra     LeseFile

fini1
    rts

;
; Liest einen Block von Disk
; in IO_OFFSET2 muss (AnfangsBlock*512) eingetragen sein
;
LeseBlock
    move.l  #IOStdReq,a1
    CALLEXEC DoIO           ;Kommando ausfuehren
    move.b  IO_ERROR2,d0
    tst.b   d0
    bne     LeseFehler
    rts


;
; Druckt Longwords aus Liste aus  (a3.l: ListenAnfangsadr)
; d5.l: Laenge in Longwords-1 (wegen dbra)
; * Ausgabe im CON: *

;DisplayChain
;        move.l  nbuffer,a5             ;buffer fuer namen
;DisplayChain1
;        move.l  (a3),d2
;        lea.l   hbuf,a0                 ;Ziel der Konvertierung
;        move.b  #32,8(a0)               ;LineFeed anfuegen
;        bsr     hexasc                     ;in Hex-Zahl wandeln
;
;        move.l  Handle,d1
;        move.l  #hbuf,d2
;        move.l  #9,d3                   ;Laenge
;        CALLDOS Write                   ;Eintrag in Hex ausgeben
;
;        move.l  (a3)+,d2
;        bclr    #28,d2
;        lea.l   buffer1,a0
;        move.b  #32,9(a0)
;        bsr     decl
;
;        move.l  Handle,d1
;        move.l  #buffer1,d2             ;buffer fuer dec
;        move.l  #10,d3                  ;laenge
;        CALLDOS Write                   ;Eintrag in Dec ausgeben
;
;        move.l  Handle,d1
;        move.l  a5,d2
;        move.l  a5,a0
;        move.b  (a0)+,d3                ;laenge
;        addq.b  #1,d2                   ;anfangsadr
;
;        adda.l  d3,a5
;        addq.l  #1,a5                   ;Zeiger auf naechstes LaengenByte
;
;        CALLDOS Write                   ;Name ausgeben
;
;        move.l  Handle,d1               ;Linefeed ausgeben
;        move.l  #Ret,d2                 ;weil Ende der Zeile
;        move.l  #1,d3
;        CALLDOS Write
;
;        dbra    d5,DisplayChain1
;        rts



calclist
    clr.l   d0
    clr.l   d1
    move.w  claenge,d0


    clr.l   d5
    move.w  lines,d5
    cmp.w   d5,d0
    bhi     cont9
    move.l  nbuffer,a5
    move.l  cbuffer,a3
    rts
cont9
    move.w  #$ffff,d1
    sub.w   lines,d0
    addq.w  #1,d0
    divu    d0,d1
    move.w  d1,propconst
    move.l  gg_SpecialInfo(a4),a4
    move.w  pi_VertPot(a4),d2
    divu    d1,d2
    clr.l   d0
    move.w  d2,d0
    clr.l   d2                     Anfang der auszugebenden Liste ausgeben
    move.w  d0,d2      ----------------------------------------------------
    move.w  d2,-(sp)
;    bsr     displayhex
;    clr.l   d2
;    move.w  claenge,d2
;    bsr     displayhex

    move.l  cbuffer,a0
    clr.l   d0
    move.w  (sp)+,d0
    move.w  d0,-(sp)
    tst.w   d0
    bne     loop10
    move.l  (a0),d2
    bra     outit
loop10
    subq    #1,d0
loop11
    move.l  (a0)+,d2
    dbra    d0,loop11
    suba.l  #4,a0
outit

    move.l  a0,a3
;    bsr     displayhex2
    move.l  nbuffer,a0

    clr.l   d2
    move.w  (sp)+,d2
    move.l  a3,-(sp)
    tst.w   d2
    beq     outit2
loop13
    subq    #1,d2
loop12
    clr.l   d0
    move.b  (a0)+,d0
    add.l   d0,a0
    dbra    d2,loop12
    sub.l   d0,a0
    suba.l  #1,a0
outit2
    move.l  a0,a5
    move.l  (sp)+,a3
;    bsr     prevypos
;    bsr     prevypos
    rts

;
; Druckt Longwords aus Liste aus  (a3.l: ListenAnfangsadr)
; d5.l: Laenge in Longwords-1 (wegen dbra)
;

displaylist
        move.l  nbuffer,a5             ;buffer fuer namen
displaylist1
        move.l  a5,-(sp)

        move.l  RPort,a1
        moveq.l #3,d0                   ;Farbe fuer Files:rot
        CALLGRAF SetAPen

        move.l  (a3),d2
        lea.l   hbuf,a0                 ;Ziel der Konvertierung
        move.b  #32,8(a0)               ;Leerzeichen anfuegen
        bsr     displayhex2

        move.l  (a3)+,d2
        bclr    #28,d2                  ;Eintrag stammt aus Filechain
        bclr    #29,d2                  ;Eintrag ist Dir(ectory)
        beq     cont5

        move.l  RPort,a1
        moveq.l #1,d0                   ;Farbe fuer Dirs:weiss
        CALLGRAF SetAPen
cont5
        bsr     displaydec2

        move.l  (sp)+,a5

        move.l  a5,a0
        clr.l   d0
        move.b  (a0)+,d0            ;laenge

        adda.l  d0,a5
        addq.l  #1,a5               ;Zeiger auf naechstes LaengenByte

        move.l  a5,-(sp)
        move.l  d0,-(sp)

        bsr     printwin            ;Name ausgeben

        move.l  (sp)+,d1            ;den Rest der Zeile mit
        moveq.l #41,d0              ;Leerzeichen auffuellen
        sub.l   d1,d0
        move.l  #spaces,a0
        bsr     printwin

        bsr     nextypos            ;naechste Zeile

        move.l  (sp)+,a5
        dbra    d5,displaylist1
        rts





; kopiert Name des Fileheaders in eine Liste aus der er dann ausgegeben wird
; a5: nbuffer

LeseName
        clr.l   d3
        move.l  DATA2,a4
        adda.l  #432,a4          ;position des Filenamens im Buffer
        move.b  (a4),d3          ;laengenbyte
loop4   move.b  (a4)+,(a5)+      ;laengenbyte und Name in Liste kopieren
        dbra    d3,loop4
        rts

;
; Konvertiere d2.l in ASCII-String ab (a0)
;

hexasc
    moveq   #7,d0                       ;8 Nibble (=Halbbyte) wandeln
    adda.l  #8,a0                       ;Pos der letzten Stelle im Buffer+1
loop5
    moveq   #15,d1                      ;
    and.l   d2,d1                       ;1 Nibble isolieren
    asr.l   #4,d2                       ;naechstes Nibble an 1.Pos
    addi.b  #48,d1                      ;isol. Nibble+48=Zahl in ASCII
    cmp.b   #57,d1                      ;war Zahl >9 ?
    bls     cont4
    addq.l  #7,d1                       ;wenn ja noch 7 dazu ==> A-F
cont4
    move.b  d1,-(a0)                    ;in Buffer eintragen
    dbra    d0,loop5                    ;naechstes Nibble wandeln
    rts

;
; Konvertiere d2.l -> Dec-String ab (buffer1)
;

decl
    moveq   #5,d0
    move.l  #buffer1,a0
    adda.l  #9,a0
loop6
    divu    #10,d2                      ;d2/10==>Quotient im niederwertigen
    swap    d2                          ;        Wort,Rest im hoeherwertigen
    moveq   #15,d1                      ;
    and.l   d2,d1                       ; Rest-->d1 +48-->Ziffer(0-9)
    addi.l  #48,d1                      ;
    move.b  d1,-(a0)                    ;eintragen
    swap    d2                          ;Quotient
    and.l   #$ffff,d2                   ;        \vom Rest befreien
    dbra    d0,loop6        ;(dbf=dbra nur andere Schreibweise)   \und weiter wandeln

    moveq   #5,d0            ;Nullen am Anfang durch Leerzeichen
    move.l  #buffer1,a0      ;ersetzen
    addq.l  #3,a0
loop7
    cmpi.b  #48,(a0)         ;eine 0 ?
    bne     fini3
    move.b  #32,(a0)         ;durch Leerzeichen ersetzen
    addq.l  #1,a0
    dbra    d0,loop7
fini3
    rts



buffer1 dc.b  '          '


;  d0.l Anzahl der zu konvertierenden Zeichen
;  in buffer muss der string stehen

stringhex
    MOVEM.L   D1-D7/A0-A6,-(A7)
    MOVE.L    D0,D3        ; z.B.:Eingabe $0450 (in ASCII)
    CLR.L     D0           ; 0000 0000 0000 0000      1.Durchlauf
    CLR.L     D1           ; 0000 0000 0000 0100      2.
    CLR.L     D2           ; 0000 0000 0100 0101      3.
    LEA.L     buffer,A0    ; 0000 0100 0101 0000      4.
mark1                      ; ----------------------------------------
    MOVE.B    (A0)+,D1     ;   0    4    5    0       = Inhalt von d2=$450
    bset      #5,d1
    BSR.S     aschex       ; ========================================
    ANDI.W    #15,D1       ;
    LSL.L     #4,D2        ;
    OR.W      D1,D2        ;

    CMPI.B    #10,(A0)     ;schon RET ereicht ?
    BEQ.S     mark2        ;wenn ja Ende

    DBF       D3,mark1
mark2
    MOVE.L    D2,D0
    MOVEM.L   (A7)+,D1-D7/A0-A6
    RTS

aschex
    MOVEM.L   D0/A0,-(A7)
    MOVEQ.L   #0,D0         ;Offset
    LEA.L     tabelle,A0
mark3
    CMP.B     0(A0,D0.L),D1 ;wenn gefunden
    BEQ.S     fini2         ;Ende
    ADDQ.L    #1,D0         ;Offset=Offset+1
    CMPI.L    #$00000010,D0 ;Tabelle schon zu Ende
    BCS.S     mark3         ;wenn nicht weitervergleichen
fini2
    MOVE.L    D0,D1         ;Offset nach d1 : eingegebene Zahl
    MOVEM.L   (A7)+,D0/A0
    RTS

SignalFehler
    move.l  Handle,d1
    move.l  #Fehler1,d2
    move.l  #len1,d3
    CALLDOS Write        ;LVOWrite
    bra     closegraf

LeseFehler
    move.l  d0,d2           ;d0=Fehlercode
    move.l  #hbuf,a0
    move.b  #10,8(a0)       ;LineFeed anfuegen
    bsr     hexasc

    move.l  Handle,d1
    move.l  #Fehler2,d2
    move.l  #len2,d3        ;Fehlermeldung ausgeben
    CALLDOS Write
    move.l  Handle,d1
    move.l  #hbuf,d2
    move.l  #9,d3           ;Fehlercode ausgeben
    CALLDOS Write
    bsr     memfree
    clr.l   d0              ;kein ReturnCode !
    move.l  DOSBase,a6
    jmp     Exit(a6)        ;--> CLI

nomem
    move.l  Handle,d1
    move.l  #Fehler3,d2
    move.l  #len3,d3
    CALLDOS Write     ;LVOWrite
    bra     ClosePort

helpmessage
    move.l  Handle,d1
    move.l  #Fehler4,d2
    move.l  #len4,d3
    CALLDOS Write
    bra     closedos


CloseAll
CloseWin
   move.l   windowptr,a0       ;wir sind wieder wach
   CALLINT  CloseWindow        ;Fenster zu

closedev
    move.l  #IOStdReq,a1
    CALLEXEC  CloseDevice        ;CloseDevice

memfree
    move.l  DATA,a1
    move.l  #ncbuffersize,d0
    CALLEXEC  FreeMem

ClosePort
    move.l  #Speicher,a1
    CALLEXEC RemPort        ;RemPort

FreeSig
    clr.l   d0
    move.b  Signal,d0
    CALLEXEC FreeSignal        ;FreeSignal

closegraf
   move.l   GfxBase,a1
   CALLEXEC CloseLibrary

closeint
   move.l   IntBase,a1
   CALLEXEC CloseLibrary

closedos
    move.l  DOSBase,a1
    CALLEXEC CloseLibrary        ;CloseLibrary
    clr.l   d0                   ;kein Returncode
fini    rts

            cnop 0,2
Signal      dc.b 0
            cnop 0,2
DOSBase     dc.l 0
            cnop 0,2
IntBase     dc.l 0
            cnop 0,2
GfxBase     dc.l 0
            cnop 0,2
Handle      dc.l 0
            cnop 0,2
Name        dc.b 'Lies880Port',0    ;Name des Msg-Ports
            cnop 0,2
Speicher
ln_Succ     dc.l 0  ;Message-Port Struktur
            cnop 0,2
ln_Pred     dc.l 0
ln_Type     dc.b 4
ln_Pri      dc.b 0
ln_Name     dc.l Name
mp_Flags    dc.b 0
mp_SigBit   dc.b 0
mp_SigTask  dc.l 0
lh_Head     dc.l 0
lh_Tail     dc.l 0
lh_TailPred dc.l 0
ln_Type1    dc.b 0
            dc.b 0  ;gerade Adr schaffen
            cnop 0,2
IOStdReq
ln_Succ2    dc.l 0
            cnop 0,2
ln_Pred2    dc.l 0
ln_Type2    dc.b 5
ln_Pri2     dc.b 0
ln_Name2    dc.l Name2
mn_ReplyPort2   dc.l 0
mn_Length2  dc.w $0030
IO_DEVICE2  dc.l 0
IO_UNIT2    dc.l 0
IO_COMMAND2 dc.w $0002
IO_FLAGS2   dc.b 0
IO_ERROR2   dc.b 0
IO_ACTUAL2  dc.l 0
IO_LENGTH2  dc.l $0200
IO_DATA2    dc.l 0
IO_OFFSET2  dc.l $0006e000

Name2       dc.b 'Lies880Msg',0,0
            cnop 0,2
TD_Name     dc.b 'trackdisk.device',0
            cnop 0,2
Fehler1     dc.b 'SigBitFehler'       ;der Stern (*) ist der Location
len1        equ  *-Fehler1            ;Counter des Assembler (LC)
            cnop 0,2                  ;er enthaelt im Gegensatz zum
Fehler2     dc.b 'Lesefehler:'        ;Program Counter (PC) der CPU
len2        equ  *-Fehler2            ;die relative Adr (relativ zum
            cnop 0,2                  ;Programmanfang) der aktuellen
Fehler3     dc.b 'not enough Memory  !'  ;Zeile !!!
len3        equ  *-Fehler3
            cnop 0,2
Fehler4     dc.b 'Usage "READHASH KEY/A" (Input of KEY in hex e.g. READHASH 370)',10
len4        equ  *-Fehler4
            cnop 0,2
dosname     dc.b 'dos.library',0
            cnop 0,2
intname     dc.b 'intuition.library',0
            cnop 0,2
grafname    dc.b 'graphics.library',0
            cnop 0,2

W_Gadgets equ   WINDOWDRAG!WINDOWDEPTH!WINDOWCLOSE ;!WINDOWSIZING
W_Extras  equ   SMART_REFRESH!ACTIVATE ;!REPORTMOUSE
IDCMPFlags equ  CLOSEWINDOW!GADGETUP!GADGETDOWN ;!MOUSEMOVE ;!MOUSEBUTTONS!SIZEVERIFY!NEWSIZE!REFRESHWINDOW

W_Title dc.b    'xxxxxxxxx Eintraege                                ',0
        cnop 0,2

windowdef
        dc.w    10              ;links
        dc.w    50               ;oben
winbreite        dc.w    500             ;Breite
winhoehe         dc.w    100             ;hoehe
        dc.b    -1,-1               ;Pens des Screen
        dc.l    IDCMPFlags
        dc.l    W_Gadgets!W_Extras  ;Window Flags
        dc.l    Gadget2             ;erstes User-Gadget
        dc.l    0                   ;keine User-Checkmark
        dc.l    W_Title             ;Titel des Window
        dc.l    0                   ;kein eigener Screen
        dc.l    0                   ;keine Super Bitmap
        dc.w    100,20              ;Min. Groesse
        dc.w    640,200             ;Max.
        dc.w    WBENCHSCREEN        ;Use Workbench Screen


Gadget2
        dc.l    0
gg2x        dc.w    284          ;x
            dc.w    10           ;y
            dc.w    15           ;breit
gg2hoehe         dc.w    82           ;hoch
        dc.w    GADGHCOMP       ;flags
        dc.w    RELVERIFY!FOLLOWMOUSE!GADGIMMEDIATE ;!RIGHTBORDER     ;Aktivierung
        dc.w    PROPGADGET      ;Typ
        dc.l    Border2         ;^Border-Strukt.
        dc.l    0
        dc.l    0               ;^Text-Strukt.
        dc.l    0
        dc.l    PropInfo
        dc.w    2               ;ID
        dc.l    0
Border2
        dc.w    0,0             ;x,y
        dc.b    15,0            ;Pens
        dc.b    RP_JAM1
        dc.b    5               ;Paare
        dc.l    paar2           ;^Liste
        dc.l    0               ;kein Border mehr
paar2
        dc.w    0,0             ;Koord.-Liste
        dc.w    0,19
        dc.w    49,19
        dc.w    49,0
        dc.w    0,0

PropInfo
        dc.w    FREEVERT!KNOBHIT!AUTOKNOB
        dc.w    0       ;Horiz
        dc.w    0       ;Vert
        dc.w    $ffff   ;entweder den
pi_VertBody        dc.w    $ffff   ;oder den anzeigen
        dc.w    20      ;Breite Rahmen
        dc.w    50      ;Hoehe
        dc.w    0       ;Schrittweite horiz
        dc.w    0       ;             vert
        dc.w    0       ;Rahmenlage links
        dc.w    0                   oben


windowptr  ds.l   1
           cnop 0,2
Ret        dc.b 10
           cnop 0,2
S_Title    dc.b ' ReadHash1.0  Written in 1989 by Sascha Groening',0
           dc.b '  Blaustrasse 13'
           dc.b '  8360 Deggendorf'
           dc.b '  West-Germany'
           dc.b '  Tel.:0991/25121'
           dc.b '  This is Public Domain !!'
           cnop 0,2
spaces     dc.l $20202020,$20202020,$20202020,$20202020
           dc.l $20202020,$20202020,$20202020,$20202020
           dc.l $20202020,$20202020,$20202020,$20202020
           dc.l $20202020,$20202020,$20202020,$20202020
           dc.l $20202020,$20202020,$20202020,$20202020
           dc.l $20202020,$20202020,$20202020,$20202020
           dc.l $20202020,$20202020,$20202020,$20202020
buffer     ds.w 15

tabelle
 dc.w $3031,$3233,$3435,$3637,$3839 ;0123456789
 dc.w $6162,$6364,$6566             ;ABCDEF

hbuf       ds.b  10
           cnop  0,2

xpos       dc.w  2
ypos       dc.w  17
lines       dc.w 11
claenge     dc.w 22
propconst   ds.w 1
ggaddress   ds.l 1
RPort       ds.l 1
            cnop 0,2
DATA        ds.l 1
DATA2       ds.l 1
cbuffer     ds.l 1
nbuffer     ds.l 1
comadr      ds.l 1
comlaenge   ds.l 1
            cnop 0,2
            end

