;*-------------------------------------------------------------------------*
;*                                                                         *
;*  Oberon Library Kopf                                    17-Sep-90       *
;*                                                                         *
;*               für SMALLDATA-Libraries                                   *
;*                                                                         *
;*  © 1990 by Fridtjof Siebert                                             *
;*                                                                         *
;* Diese Assemblerprogramm muß assembliert und unter dem Namen             *
;* LibraryHead.objs in eines in der Datei OBERON:Path angegebenem          *
;* Directory kopiert werden                                                *
;*                                                                         *
;*-------------------------------------------------------------------------*

; Globale Variablen:

        XDEF    LibraryHead.SegList;      unsere Segmentliste
        XDEF    LibraryHead.LibBase;      Librarybase (A6)
        XDEF    LibraryHead.OpenOk;       wurden OPEN-Teile ohne HALT ausgeführt?
        XDEF    LibraryHead.Globals       Zeiger auf globale Variablen

; Standard Library Routinen

        XDEF    LibraryHead.Open;
        XDEF    LibraryHead.Close;
        XDEF    LibraryHead.Expunge;
        XDEF    LibraryHead.Init;

        XDEF    LibraryHead.SetTrue;      intern verwendet

; Externe Oberon-Prozeduren

        XREF    LibraryHead.OpenAll;      BEGIN-Teil des Hauptmoduls
        XREF    LibraryHead.CloseAll;     CLOSE-Teil des Hauptmoduls
        XREF    LibraryHead.LibOpen;      Open-Prozedur
        XREF    LibraryHead.LibClose;     Close-Prozedur

; Memory-Größe und Requirements für SMALLDATA

        XREF    Globals_MemSize;
        XREF    Globals_MemReqs;

; ein paar Konstanten:

ln_succ  EQU 0;
ln_pred  EQU 4;
ln_type  EQU 8;
ln_pri   EQU 9;
ln_name  EQU 10;
ln_SIZE  EQU 14;

lib_flags    EQU 14;
lib_pad      EQU 15;
lib_negsize  EQU 16;
lib_possize  EQU 18;
lib_version  EQU 20;
lib_revision EQU 22;
lib_idstring EQU 24;
lib_sum      EQU 28;
lib_opencnt  EQU 32;
lib_size     EQU 34;

delexp       EQU 3;

Remove       EQU -252
FreeMem      EQU -210
AllocMem     EQU -198


; los geht's


        section "LibraryHead",code


LibraryHead.Init:

        movem.l d2-d7/a2-a6,-(a7)

        move.l  a0,LibraryHead.SegList
        move.l  d0,LibraryHead.LibBase

        move.l  #Globals_MemSize,D0;    Speicher für Globals holen
        move.l  #Globals_MemReqs,D1;

        move.l  4,A6;
        jsr     AllocMem(A6);
        tst.l   D0;
        beq.s   \ciao;                  das war nix
        move.l  D0,LibraryHead.Globals; Zeiger auf Globals retten
        move.l  D0,A5;                  und in A5

        lea     -4(A7),A0;
        jsr     LibraryHead.OpenAll;    Oberon-Openteil aufrufen

        moveq   #0,d0
        tst.b   LibraryHead.OpenOk;     alles klar?
        beq.s   \ciao;
        move.l  LibraryHead.LibBase,d0  ja, dann LibBase zurück

\ciao:  movem.l (a7)+,d2-d7/a2-a6
        rts



LibraryHead.Open:

        addq.w  #1,lib_opencnt(a6);     opencnt 1 höher
        movem.l d2-d7/a2-a6,-(sp);
        jsr     LibraryHead.LibOpen;    Library öffnen (A5 muß noch geladen werden)
        movem.l (sp)+,d2-d7/a2-a6;
        tst.b   d0;                     ok?
        bne.s   openok;
        subq.w  #1,lib_opencnt(a6);     opencnt wieder verringern, da Öffnen erfolglos
        bra.s   ciao;
openok: bclr    #delexp,lib_flags(a6);
        move.l  a6,d0;                  dann LibBase zurück
        rts;


LibraryHead.Close:

        movem.l d2-d7/a2-a6,-(sp);
        jsr     LibraryHead.LibClose;   schließen (A5 fehlt auch hier)
        movem.l (sp)+,d2-d7/a2-a6;
        subq.w  #1,lib_opencnt(a6);     opencnt 1 runter
        bne.s   ciao;                   > 0, dann bleiben wir noch da
        btst    #delexp,lib_flags(a6);  delexp gesetzt
        bne.s   LibraryHead.Expunge;    ja, dann expunge
ciao:   moveq   #0,d0;
        rts;


LibraryHead.Expunge:

        movem.l d2-d7/a2-a6,-(a7)
        tst.w   lib_opencnt(a6)
        beq.s   \l
        bset    #delexp,lib_flags(a6)
        moveq   #0,d0
        bra.s   \ciao
\l:     move.l  a6,a4;
        move.l  4,a6;
        move.l  a4,a1;
        jsr     Remove(A6);

        move.l  a4,-(a7);
        move.l  LibraryHead.Globals,a5; Globals nach A5
        jsr     LibraryHead.CloseAll;   alles schließen

        move.l  a5,a1;
        move.l  #Globals_MemSize,d0;
        move.l  4,a6;
        jsr     FreeMem(a6)

        moveq   #0,d0;
        move.l  (a7)+,a1;
        move.l  a1,a4;
        move.w  lib_negsize(a4),d0;
        sub.l   d0,a1
        add.w   lib_possize(a4),d0;
        jsr     FreeMem(a6);

        move.l  LibraryHead.SegList,d0
\ciao:  movem.l (a7)+,d2-d7/a2-a6
        rts


        section "LibData",data


id:     dc.b    "Oberon Library",0
        even


        section "LibGlobals",bss


LibraryHead.SegList dc.l    0;
LibraryHead.LibBase dc.l    0;
LibraryHead.OpenOk  dc.w    0;
LibraryHead.Globals dc.l    0;


        section "LibExtra",code

LibraryHead.SetTrue:

        st      d0;
        rts;

        END;


