;*************************************************************************
;
;:Program.       EdAssemSup.asm
;:Contents.      Assembler-Routines for AmokEd
;:Author.        Tobias Ruland, Hartmut Goebel
;:Language.      MC68000-Assembler
;:History.       V1.0,  3/90, Tobias Ruland, Hartmut Goebel
;:History.       V1.0c, 04 Aug 1991 [hG]: Angepasst: lst.Node ist STRUCT
;
;*************************************************************************

        XDEF FindNext
        XDEF FindNCNext
        XDEF FindPrev
        XDEF FindNCPrev
        XDEF Length
        XDEF WordLen
        XDEF LastNoSpace
        XDEF FirstNoSpace
        XDEF NCStrCmp
        XDEF bmove
        XDEF bfill
        XDEF LowFraction
        XDEF HighFraction
        XDEF Fraction020

l.next     = 0
l.prev     = 4
l.string   = 8   ; ab hier + 4, wenn RECORD!! (wg. Typeguard)
l.len      = 12

fs.find    = 0
fs.line    = 4
fs.flen    = 8
fs.pos     = 10


        SECTION FindReplace

FindNext:
        move.l  fs.find(a0),a1        ; Find-String-Pointer
        move.l  fs.line(a0),a4        ; Startline-Struktur --> a4
        move.l  l.string(a4),a2       ; Pointer auf LineBuffer --> a2
        move    fs.pos(a0),d6
        move    d6,d5                 ; Sicherheitskopie pos --> d5
        move.l  a1,a3                 ; Sicherheitskopie FindStr --> a1
        move.l  #0,d7                 ; anzahl zeilenwechsel
CompIt:
        tst.b   (a3)
        beq     foundIt
        tst.b   0(a2,d6)
        beq     getNextLine
        move.b  0(a2,d6),d4
        cmp.b   (a3)+,d4
        beq     nochGleich
        move.l  a1,a3                 ; von vorne
        addq    #1,d5
        move    d5,d6
        bra     CompIt
nochGleich:
        addq    #1,d6
        bra     CompIt
getNextLine:
        move.l  l.next(a4),a4
        cmpa.l  #0,a4
        beq     notFound
        move.l  l.string(a4),a2
        moveq   #0,d6
        moveq   #0,d5
        move.l  a1,a3
        add.l   #1,d7
        bra     CompIt
foundIt:
        sub     fs.flen(a0),d6       ; an Wortanfang
        move    d6,fs.pos(a0)
        move.l  a4,fs.line(a0)
        move.l  d7,d0
        rts

;-------------------------------------------------------------------------

FindNCNext
        move.l  fs.find(a0),a1        ; Find-String-Pointer
        move.l  fs.line(a0),a4        ; Startline-Struktur --> a4
        move.l  l.string(a4),a2       ; Pointer auf LineBuffer --> a2
        move    fs.pos(a0),d6
        move    d6,d5                 ; Sicherheitskopie pos --> d5
        move.l  a1,a3                 ; Sicherheitskopie FindStr --> a1
        move.l  #0,d7                 ; anzahl zeilenwechsel
NCCompIt
        tst.b   (a3)
        beq     NCfoundIt
        tst.b   0(a2,d6)
        beq     NCgetNextLine
        move.b  0(a2,d6),d4           ; d4 = nextes char aus text
;:::::::::::::::::::::::::
        move.b  (a3)+,d3              ; d3 = nextes char aus suchstring
        move.b  d4,d0                 ; d0 = sichercopy aus d4
        bclr    #5,d4
        cmp.b   #"A",d4               ; untere grenze
        bcs     ncdirekt              ; blo
        cmp.b   #"Z",d4
        bls     ncnocase
        cmp.b   #$c0,d4
        bcs     ncdirekt              ; blo
        cmp.b   #$d7,d4
        beq     ncdirekt
        cmp.b   #$df,d4
        beq     ncdirekt
ncnocase
        bclr    #5,d3
        cmp.b   d3,d4
        beq     NCnochGleich
        bra     nixgleich
ncdirekt
        cmp.b   d3,d0
        beq     NCnochGleich
nixgleich
        move.l  a1,a3                 ; von vorne
        addq    #1,d5
        move    d5,d6
        bra     NCCompIt
;::::::::::::::::::::::::::
NCnochGleich
        addq    #1,d6
        bra     NCCompIt
NCgetNextLine
        move.l  l.next(a4),a4
        cmpa.l  #0,a4
        beq     notFound
        move.l  l.string(a4),a2
        moveq   #0,d6
        moveq   #0,d5
        move.l  a1,a3
        add.l   #1,d7
        bra     NCCompIt
NCfoundIt
        sub     fs.flen(a0),d6       ; an Wortanfang
        move    d6,fs.pos(a0)
        move.l  a4,fs.line(a0)
        move.l  d7,d0
        rts
notFound:
        move.l  d7,d1
        move.l  #-1,d0
        rts

;-------------------------------------------------------------------------

FindPrev:
        move.l  fs.find(a0),a1        ; Find-String-Pointer
        move.l  fs.line(a0),a4        ; Startline-Struktur --> a4
        move.l  l.string(a4),a2       ; Pointer auf LineBuffer --> a2
        move    fs.pos(a0),d6         ; Cursorposition
        move    fs.flen(a0),d3        ; Länge des FindStrings
        move.l  a1,a3                 ; Sicherheitskopie FindStr --> a1
        move.l  #0,d7                 ; anzahl zeilenwechsel
        subq    #2,d6
        move    d6,d5
        tst     d6
        bmi     getPrevLine
P.CompIt:
        tst.b   (a3)
        beq     foundIt
        move.b  0(a2,d6),d4
;::::::::::::::::::
        cmp.b   (a3)+,d4
        beq     p.nochGleich
;::::::::::::::::::
        move.l  a1,a3                 ; von vorne
        subq    #1,d5
        bmi     getPrevLine
        move    d5,d6
        bra     P.CompIt
p.nochGleich:
        addq    #1,d6
        bra     P.CompIt
getPrevLine:
        move.l  l.prev(a4),a4
        cmpa.l  #0,a4
        beq     notFound
        add.l   #1,d7
        move.l  l.string(a4),a2
        move    l.len(a4),d6
        subq    #8,d6
eol.search:
        tst.b   0(a2,d6)
        beq     eol.found
        addq    #1,d6
        bra     eol.search
eol.found:
        sub     d3,d6
        bmi     getPrevLine
        move    d6,d5
        move.l  a1,a3
        bra     P.CompIt

;-------------------------------------------------------------------------

FindNCPrev:
        move.l  fs.find(a0),a1        ; Find-String-Pointer
        move.l  fs.line(a0),a4        ; Startline-Struktur --> a4
        move.l  l.string(a4),a2       ; Pointer auf LineBuffer --> a2
        move    fs.pos(a0),d6         ; Cursorposition
        move    fs.flen(a0),d3        ; Länge des FindStrings
        move.l  a1,a3                 ; Sicherheitskopie FindStr --> a1
        move.l  #0,d7                 ; anzahl zeilenwechsel
        subq    #2,d6
        move    d6,d5
        tst     d6
        bmi     ncgetPrevLine
ncP.CompIt:
        tst.b   (a3)
        beq     foundIt
        move.b  0(a2,d6),d4
;::::::::::::::::::
        move.b  (a3)+,d3              ; d3 = nextes char aus suchstring
        move.b  d4,d0                 ; d0 = sichercopy aus d4
        bclr    #5,d4
        cmp.b   #"A",d4               ; untere grenze
        bcs     p.ncdirekt            ; blo
        cmp.b   #"Z",d4
        bls     p.ncnocase
        cmp.b   #$c0,d4
        bcs     p.ncdirekt            ; blo
        cmp.b   #$d7,d4
        beq     p.ncdirekt
        cmp.b   #$df,d4
        beq     p.ncdirekt
p.ncnocase
        bclr    #5,d3
        cmp.b   d3,d4
        beq     p.NCnochGleich
        bra     p.nixgleich
p.ncdirekt
        cmp.b   d3,d0
        beq     p.NCnochGleich
p.nixgleich
        move.l  a1,a3                 ; von vorne
        addq    #1,d5
        move    d5,d6
        bra     ncP.CompIt
;::::::::::::::::::
        move.l  a1,a3                 ; von vorne
        subq    #1,d5
        bmi     ncgetPrevLine
        move    d5,d6
        bra     ncP.CompIt
p.NCnochGleich:
        addq    #1,d6
        bra     ncP.CompIt
ncgetPrevLine:
        move.l  l.prev(a4),a4
        cmpa.l  #0,a4
        beq     notFound
        add.l   #1,d7
        move.l  l.string(a4),a2
        move    l.len(a4),d6
        subq    #8,d6
nceol.search:
        tst.b   0(a2,d6)
        beq     nceol.found
        addq    #1,d6
        bra     nceol.search
nceol.found:
        sub     d3,d6
        bmi     ncgetPrevLine
        move    d6,d5
        move.l  a1,a3
        bra     ncP.CompIt

;-------------------------------------------------------------------------

        SECTION Length

Length  move.l  a0,a1
leloop  tst.b   (a0)+
        bne     leloop
        suba.l  a1,a0
        move.l  a0,d0
        subq.l  #1,d0
        cmp.l   #00010000,D0
        bcs.s   lenout
        trap    #0
lenout  rts

;-------------------------------------------------------------------------

        SECTION WordLen

WordLen move.l  #-1,d0
wlloop  addq.l  #1,d0
        move.b  (a0)+,d1
        tst.b   d1
        beq     wlcheck
        cmp.b   #' ',d1
        bne     wlloop
wlcheck cmp.l   #00010000,D0
        bcs.s   gotwl
        trap    #0
gotwl   rts

;-------------------------------------------------------------------------
; gibt Länge des String OHNE End-Spaces zurück

        SECTION LastNoSpace

LastNoSpace
        movea.l a0,a1
lnsloop tst.b   (a0)+
        bne     lnsloop
        subq.l  #1,a0      ; Null-Byte
        move.l  a0,d0
        sub.l   a1,d0
backsr  cmp.b   #' ',-(a0)
        dbne    d0,backsr
        cmp.l   #00010000,D0
        bcs.s   lnsout
        trap    #0
lnsout  rts

;-------------------------------------------------------------------------

        SECTION FirstNoSpace

FirstNoSpace
        move.l  a0,a1
fnsloop cmp.b   #' ',(a0)+
        beq     fnsloop
        suba.l  a1,a0
        move.l  a0,d0
        subq.l  #1,d0
        cmp.l   #00010000,D0
        bcs.s   fnsout
        trap    #0
fnsout  rts

;-------------------------------------------------------------------------

        SECTION NCStrCmp

; erster string in a0
; zweiter string in a1

NCStrCmp
        move.b  (a0)+,d4
        move.b  (a1)+,d3
        move.b  d4,d0                 ; d0 = sichercopy aus d4
        bclr    #5,d4
        cmp.b   #"A",d4               ; untere grenze
        bcs     ncstrdirekt           ; blo
        cmp.b   #"Z",d4
        bls     ncstrnocase
        cmp.b   #$c0,d4
        bcs     ncstrdirekt           ; blo
        cmp.b   #$d7,d4
        beq     ncstrdirekt
        cmp.b   #$df,d4
        beq     ncstrdirekt
ncstrnocase
        bclr    #5,d3
        cmp.b   d3,d4
        beq     NCStrEqual
        bra     NixStrGleich
ncstrdirekt
        cmp.b   d3,d0
        bne     NixStrGleich
NCStrEqual
        tst.b   d3
        bne     NCStrCmp
        move.l  #-1,d0                ; rückgabewert TRUE
        rts
NixStrGleich
        moveq   #0,d0                 ; rückgabewert FALSE
        rts

;-------------------------------------------------------------------------

        SECTION bmove

bmove   cmpa.l  a0,a1
        bhi     dobm
        beq     nomoremove
        subq    #1,d0
bmlloop move.b  (a0)+,(a1)+
        dbra    d0,bmlloop
        rts
dobm    adda.l  d0,a0
        adda.l  d0,a1
        subq    #1,d0
bmloop  move.b  -(a0),-(a1)
        dbra    d0,bmloop
nomoremove
        rts

;-------------------------------------------------------------------------

        SECTION bfill

; a0 Speicherzeiger
; d0 was kommt rein
; d1 wielange >=0

bfill   bra     testd1
fillloop
        move.b  d0,(a0)+
testd1  dbra    d1,fillloop
        rts

;-------------------------------------------------------------------------

       SECTION LowFraction

; Zahl1.L * $FFFF / Zahl2.L

        CODE
LowFraction
        move.l  d1,-(SP)     ; d1 retten
        clr.l   d1

        move.l  d0,d2        ; Zahl1 mit $10000 multiplizieren
        move.l  d1,d3        ;
        move.w  #15,d7
muloop  lsl.l   #1,d0
        roxl.l  #1,d1
        dbra    d7,muloop

        sub.l   d2,d0        ; und einmal abziehen --> *$FFFF
        subx.l  d3,d1        ; Zähler steht jetzt in d0/d1

        move.l  (SP)+,d6
        moveq   #0,d7        ; Nenner steht jetzt in d6/d7

        move.l  d0,d2
        move.l  d1,d3        ; Zähler nach d2/d3 kopieren

        moveq   #0,d0        ; in d0/d1 landet unser Endergebnis,
        moveq   #0,d1        ; also löschen
        moveq   #0,d4        ; Hilfszähler
        moveq   #0,d5        ; Nullkonstante (brauchen wir für addx)

wieoft  add.l   d6,d6
        addx.l  d7,d7        ; Nenner = Nenner * 2

        add.l   #1,d4        ; INC Hilfszähler

        cmp.l   d7,d3        ; Zähler > Nenner ???
        bhi     wieoft       ; JA! --> LOOP(wieoft)
        bne     divi         ; MOST_SIGNI_LONGWORD nicht gleich :-)
        cmp.l   d6,d2        ; untere 32 bit vergleichen
        bhi     wieoft       ; Zähler > Nenner! --> LOOP(wieoft)

divi    sub.l   #1,d4        ; DEC Hilfszähler
        bmi     ende         ; <Zähler am Ende?> --> ENDE
        add.l   d0,d0
        addx.l  d1,d1        ; Ergebnis = Ergebnis * 2

        lsr.l   #1,d7
        roxr.l  #1,d6        ; Nenner = Nenner / 2

        cmp.l   d3,d7        ; Nenner > Zähler ???
        bhi     divi         ; JA! --> LOOP(divi)
        bne     postcmp      ; Zähler <= Nenner --> postcmp
        cmp.l   d2,d6
        bhi     divi

postcmp add.l   #1,d0        ; Ergebnis = Ergebnis+1
        addx.l  d5,d0

        sub.l   d6,d2        ; Zähler = Zähler - Nenner
        subx.l  d7,d3
        bra     divi

ende    rts

;-------------------------------------------------------------------------

       SECTION HighFraction

* Zahl1.L * $FFFF / Zahl2.L
*
* Zahl1 wird in d0 erwartet (32 Bit >0)
* Zahl2 wird in d1 erwartet (32 Bit >0)
*
* Ergebnis steht in d0
*
* ACHTUNG: Zahl2=0 muß durch das Oberon-Programm abgefangen werden!!!
*          (div durch 0)
*
        CODE
HighFraction
        move.l  d1,-(SP)     ; d1 retten
        clr.l   d1

        move.l  d0,d2        ; Zahl1 mit $10000 multiplizieren
        move.l  d1,d3        ;
        move.w  #15,d7
hfmuloop
        lsl.l   #1,d0
        roxl.l  #1,d1
        dbra    d7,hfmuloop

        sub.l   d2,d0        ; und einmal abziehen --> *$FFFF
        subx.l  d3,d1        ; Zähler steht jetzt in d0/d1

        move.l  (SP)+,d6
        moveq   #0,d7        ; Nenner steht jetzt in d6/d7

        move.l  d0,d2
        move.l  d1,d3        ; Zähler nach d2/d3 kopieren

        moveq   #0,d0        ; in d0/d1 landet unser Endergebnis,
        moveq   #0,d1        ; also löschen
        moveq   #0,d4        ; Hilfszähler
        moveq   #0,d5        ; Nullkonstante (brauchen wir für addx)

hfwieoft
        add.l   d6,d6
        addx.l  d7,d7        ; Nenner = Nenner * 2

        add.l   #1,d4        ; INC Hilfszähler

        cmp.l   d7,d3        ; Zähler > Nenner ???
        bhi     hfwieoft     ; JA! --> LOOP(wieoft)
        bne     hfdivi       ; MOST_SIGNI_LONGWORD nicht gleich :-)
        cmp.l   d6,d2        ; untere 32 bit vergleichen
        bhi     hfwieoft     ; Zähler > Nenner! --> LOOP(wieoft)

hfdivi  sub.l   #1,d4        ; DEC Hilfszähler
        bmi     hfende       ; <Zähler am Ende?> --> ENDE
        add.l   d0,d0
        addx.l  d1,d1        ; Ergebnis = Ergebnis * 2

        lsr.l   #1,d7
        roxr.l  #1,d6        ; Nenner = Nenner / 2

        cmp.l   d3,d7        ; Nenner > Zähler ???
        bhi     hfdivi       ; JA! --> LOOP(divi)
        bne     hfpostcmp    ; Zähler <= Nenner --> postcmp
        cmp.l   d2,d6
        bhi     hfdivi

hfpostcmp
        add.l   #1,d0        ; Ergebnis = Ergebnis+1
        addx.l  d5,d0

        sub.l   d6,d2        ; Zähler = Zähler - Nenner
        subx.l  d7,d3
        bra     hfdivi

hfende  rts

;-------------------------------------------------------------------------

        SECTION Fraction020
* SPECIALDIV30.ASM
*
* Zahl1.L * $FFFF / Zahl2.L
*
* Zahl1 wird in d0 erwartet (32 Bit >0)
* Zahl2 wird in d1 erwartet (32 Bit >0)
*
* Ergebnis steht in d0
*
* ACHTUNG: Zahl2=0 muß durch das Oberon-Programm abgefangen werden!!!
*          (div durch 0)
*
;       MC68030
        CODE

Fraction020
;        clr.l   d2
;        mulu.l  #$FFFF,d2:d0
;        divu.l  d1,d2:d0
        rts
*
* Leut', kauft's euch an 30er, dann seit's manche Sorgen los  :-)
*
        END

