          .globl    ad,getargs,numa,numb,binoct
          .globl    bt,sub,cp,output
          .globl    compare,higha
;
; Subroutine AD:
; Addition zweier beliebig langer Oktalzahlen und Ausgabe des Ergebnisses.
;
ad:       jsr  pc,getargs
          mov  #numa,r0
          mov  #numb,r1
          mov  (r0)+,places
          cmp  places,(r1)+   ; maximale Stellenzahl bestimmen
          bcc  noch1          ; statt "BHIS"
          mov  -2(r1),places
noch1:    mov  places,-2(r0)
          clr  carry          ; Uebertrag loeschen
adlp:     add  (r1)+,(r0)
          add  carry,(r0)+
          bpl  nocrr1         ; kein Uebertrag (MSB)
          bic  #100000,-2(r0) ; MSB loeschen
          mov  #1,carry
          br   adlpend
nocrr1:   clr  carry
adlpend:  dec  places
          bne  adlp
          mov  #numa,r1
          tst  carry          ; noch Uebertrag uebrig?
          beq  noext          ;   nein
          mov  #1,(r0)
          inc  (r1)
noext:    jsr  pc,binoct
          rts  pc
;
; Subroutine BT:
; Bildung des Betrages der Differenz zweier beliebig grožer Oktalzahlen
; und Ausgabe des Ergebnisses.
;
bt:       jsr  pc,getargs
          jsr  pc,sub
          jsr  pc,binoct
          rts  pc
;
; Subroutine SUB:
; Falls A groesser als B ist, wird A - B gebildet, sonst B - A.
; Die groessere Zahl wird durch die Differenz ersetzt. Am Ende zeigt
; R1 auf diese.
;
sub:      mov  #numa,r0
          mov  #numb,r1
          jsr  pc,compare
          bhi  higha
          mov  #numb,r0
          mov  #numa,r1
          br   startsub
higha:    mov  #numa,r0
          mov  #numb,r1
startsub: mov  (r0)+,places
          tst  (r1)+          ; zum Erhoehen von R1
          mov  r0,-(sp)       ; Zeiger auf das Ergebnis merken
          clr  carry          ; Uebertrag loeschen
sublp:    sub  (r1)+,(r0)
          sub  carry,(r0)+
          bpl  nocrr2         ; kein Uebertrag (MSB)
          bic  #100000,-2(r0) ; MSB loeschen
          mov  #1,carry
          br   sublpend
nocrr2:   clr  carry
sublpend: dec  places
          bne  sublp
          mov  (sp)+,r1
          sub  #2,r1
clzeros:  tst  -(r0)          ; fuehrende Null?
          bne  endsub         ;   nein
          dec  (r1)           ; ja, dann eine Stelle weniger
          bne  clzeros
          inc  (r1)           ; aber mindestens eine Stelle behalten
endsub:   rts  pc
;
; Datenbereich:
;
places:   .blkw     1
carry:    .blkw     1
;
; Subroutine CP:
; Zwei beliebig lange Oktalzahlen werden als Strings uebergeben und
; verglichen. Als Ergebnis wird ein entsprechender Text ausgegeben.
;
cp:       jsr  pc,getargs
          mov  #numa,r0
          mov  #numb,r1
          jsr  pc,compare
          bne  noteq
          mov  #eqtext,-(sp)
          br   mssg
noteq:    blo  lower
          mov  #gttext,-(sp)
          br   mssg
lower:    mov  #lstext,-(sp)
mssg:     jsr  pc,output
          add  #2,sp
          rts  pc
;
; Die Texte fuer CP:
;
eqtext:   .ascii    'equal                                    '
          .ascii    '                                         '
gttext:   .ascii    'greater                                  '
          .ascii    '                                         '
lstext:   .ascii    'less                                     '
          .ascii    '                                         '
          .even
;
; Subroutine COMPARE:
; Zwei beliebig lange Zahlen A und B in interner Darstellung werden
; verglichen. Nach der Rueckkehr vom COMPARE kann das aufrufende
; Programm die Condition Codes abfragen, als waere der Befehl...
;
;         CMP  A,B
;
; ...ausgefuehrt worden.
;
; Parameter: R0 - Zeiger auf A
;            R1 - Zeiger auf B
;
compare:  mov  (r0),r2        ; Stellenzahl
          cmp  (r0)+,(r1)+
          bne  compend
          asl  r2             ; * 2 (wegen Wortbreite)
          add  r2,r0          ; Zeiger auf MSW setzen
          add  r2,r1
          asr  r2             ; / 2
complp:   cmp  -(r0),-(r1)
          bne  compend
          sob  r2,complp
compend:  rts  pc
          .end

