;*************************
;*       PROJEKT e       *
;*         von           *
;*      G.Steffens       *
;*************************

ExecBase:         equ   4
RawDoFmt:         equ   -522
OldOpenLib:       equ   -408
CloseLib:         equ   -414
Open:             equ   -30
Close:            equ   -36
Write:            equ   -48
Output:           equ   -60
langworte:        equ   105   ; mindestens 2
laenge:           equ   4*langworte

;***********************************************
   move.l   ExecBase,a6       ;
   lea      dosname(pc),a1    ; doslibrary
   jsr      OldOpenLib(a6)    ; öffnen
   move.l   d0,dosbase        ; Zeiger sichern
   move.l   d0,a6             ; dosbase holen
   jsr      Output(a6)        ; handle holen
   move.l   d0,handle         ; und sichern

;*********** Speicherbereiche löschen **********
   lea      dividend(pc),a0   ;
   lea      summe(pc),a3      ;
   move.l   #langworte-1,d0   ; Umläufe
clrloop:
   clr.l    (a0)+             ; löschen
   clr.l    (a3)+             ; löschen
   dbra     d0,clrloop        ; usw. ->

;************* Division durchführen ************
   lea      summe(pc),a3      ;
   lea      dividend(pc),a2   ;
   moveq    #1,d2             ; Zähler i=1
   move.l   #langworte,d4     ; langworte
   move.l   d2,(a2)           ; dividend=1
   move.l   d2,(a3)           ; summe=1
loop:
   move.l   a2,a0             ; 1.Position<>0
   move.l   d4,d7             ; langworte in 
   add      d7,d7             ; worte wandeln
   subq     #1,d7             ; d7=Umläufe
   moveq    #0,d0             ; Rest=0
divloop:
   move     (a0),d0           ; [Rest][Wort]=d0
   divu     d2,d0             ; Langwort/i=
   move     d0,(a0)+          ; Quotient ->(a0)
   dbra     d7,divloop        ; Rest übernehmen

;*************** Summe bilden ******************
   lea      dividend(pc),a0   ;
   lea      summe(pc),a3      ;
   lea      laenge(a0),a0     ; dividendende
   lea      laenge(a3),a3     ; summeende
   move.l   #langworte-1,d0   ; Umläufe
   sub      d7,d7             ; X-flag löschen
sumloop:
   addx.l   -(a0),-(a3)       ; den Quotienten
   dbra     d0,sumloop        ; zur Summe
                              ; addieren
;***********************************************
   addq.l   #1,d2             ; i=i+1
   tst.l    (a2)              ; Position<>0?
   bne      loop              ; nein: weiter ->
   addq.l   #4,a2             ; Position erhöhen
   subq.l   #1,d4             ; Umläufe-1
   bne      loop              ; nächste Runde->
;******** eigentliche Rechnung beendet *********

;************ Ausgabe der Ziffern **************
alles0:
   subq.l   #1,d2             ; d2 korrigieren
   moveq    #0,d6             ; Gesamtlänge=0
   lea      formatstr2(pc),a0 ; Anzahl der
   bsr      print             ; Umläufe ausgeben
   move.l   #laenge*3/5-2,d5  ; Ausgabelänge
drucken:
   lea      summe(pc),a3      ; da unsere Zahl
   lea      laenge(a3),a3     ; im Binärsystem
   move.l   #laenge/2-1,d7    ; vorliegt,
   moveq    #0,d1             ; muß noch eine
loop10:                       ; Umwandlung
   move     -(a3),d0          ; in das
   mulu     #10000,d0         ; Dezimalsystem
   add.l    d1,d0             ; erfolgen.
   move     d0,(a3)           ; Statt mit 10
   clr      d0                ; multiplizieren
   swap     d0                ; wir sogar
   move.l   d0,d1             ; mit 10000, daß
   dbra     d7,loop10         ; ist 4*schneller

   lea      summe(pc),a3      ; die nächsten
   move.l   (a3),d2           ; 4 Stellen
   lea      formatstr1(pc),a0 ; der Zahl
   bsr      print             ; ausgeben und
   clr.l    (a3)              ; dann löschen
   addq.l   #4,d6             ; Gesamtlänge
   dbra     d5,drucken        ; weiter im Text

   move.l   d6,d2             ; Anzahl der
   lea      formatstr3(pc),a0 ; ausgegebenen
   bsr      print             ; Ziffern

;************* Rückzug einleiten **************
ende2:
   move.l   ExecBase,a6       ;
   move.l   dosbase(pc),a1    ; Dos-Library
   jsr      CloseLib(a6)      ; schließen
   moveq    #0,d0             ; Returncode 0
   rts                        ; und Tschüß!

;********** Unterroutine Textausgabe **********
print:
   movem.l  d0-a6,-(a7)       ; alles sichern
   move.l   #-1,length        ; Zähler löschen
   lea      datas(pc),a1      ; Datenspeicher
   move.l   d2,(a1)           ; Wert einladen
   lea      routine(pc),a2    ; Hilfsroutine
   lea      buffer,a3         ; Zeichenpuffer
   move.l   ExecBase,a6       ; und nun
   jsr      RawDoFmt(a6)      ; formatieren

   move.l   handle(pc),d1     ; filehandle
   move.l   #buffer,d2        ; Pufferadresse
   move.l   length,d3         ; Textlänge
   move.l   dosbase(pc),a6    ;
   jsr      Write(a6)         ; Text ausgeben
   movem.l  (a7)+,d0-a6       ; restaurieren
   rts                        ; und zurück

;********* Hilfsroutine für RawDoFmt **********
routine:                      ; ein Zeichen in
   move.b   d0,(a3)+          ; Ausgabepuffer
   clr.b    (a3)              ; Endekode
   addq.l   #1,length         ; Textlänge
   rts                        ; und zurück

;*************** diverse Daten ****************
length:     dc.l  0
dosbase:    dc.l  0
handle:     dc.l  0
datas:      dc.l  0

dosname:    dc.b  "dos.library",0
formatstr1: dc.b  "%04ld",0
formatstr2: dc.b  "Umläufe : %-ld",10,0
formatstr3: dc.b  10,"Anzahl der Nachkommastellen: %-ld",10,0
   even
buffer:     ds.b  256
dividend:   ds.b  laenge
summe:      ds.b  laenge

   end

