; :Program.       SPrintf.s
; :Author.        Volker Rudolph
; :Address.       Lettow-Vorbeck-Str. 11 / 6750 Kaiserslautern 26
; :Phone.         06301/8566
; :Version.       1.0
; :Date.          28.11.1989
; :Copyright.     PD
; :Language.      Assembler / Oberon
; :Translator.    A68k(Freeware) / Amiga-Oberon V1.17.1
; :Contents.      Allzweck-Textausgabe in Form der C-Funktion Printf
; :Usage.         Aufruf und Parameter wie in C
;
; Angepasst an 2.20 (Offene Feld-Parameter jetzt .l)

_LVORawDoFmt  EQU -522            ; Exec.RawDoFmt

  XREF OberonLib.StackChk
  XDEF Printf.SPrintf0,Printf.SPrintf1,Printf.SPrintf2,Printf.SPrintf3,
  XDEF Printf.SPrintf4,Printf.SPrintf5,Printf.SPrintf6,Printf_SPrintf

  SECTION Module,CODE

Printf.SPrintf0:
  moveq   #0,d7
  bra.s   Printf_SPrintf
Printf.SPrintf1:
  moveq   #1,d7
  bra.s   Printf_SPrintf
Printf.SPrintf2:
  moveq   #2,d7
  bra.s   Printf_SPrintf
Printf.SPrintf3:
  moveq   #3,d7
  bra.s   Printf_SPrintf
Printf.SPrintf4:
  moveq   #4,d7
  bra.s   Printf_SPrintf
Printf.SPrintf5:
  moveq   #5,d7
  bra.s   Printf_SPrintf
Printf.SPrintf6:
  moveq   #6,d7
;  bra.s   Printf_SPrintf

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

; Register-Belegungen

OFFS      EQUR d6                   ; Gesamtlänge der val-Parameter
HIGHS     EQUR d4                   ; HIGH(str)
INDEX     EQUR d3                   ; INDEX für diverse dbra-Schleifen

HELP      EQUR a4                   ; Hilfs-Pointer

; Register-Parameter (werden vom Rufer übergeben)
ARGC      EQUR d7                   ; Anzahl val-Parameter

HIGHB     EQUR d5                   ; Größe des Ausgabe-Puffers
PUTCHDATA EQUR a3                   ; Daten für PutChar-Prozedur

; Parameter für RawDoFmt
;PUTCHDATA  EQUR a3 ;               ; Puffer (schon mal definiert)
PROC      EQUR a2                   ; Ausgabe-Prozedur für Zeichen
ARGV      EQUR a1                   ; Argument-Vektor
STR       EQUR a0                   ; Format-String

  ; d7 = Anzahl val-Parameter
  ; d5 = HIGH(Buffer)
  ; a3 = ADR(Buffer)

Printf_SPrintf:
  movem.l a5/a6,-(sp)               ; a5/a6 retten
  lea     12(sp),HELP               ; Anfang val-Parameter

  move.l  ARGC,OFFS                 ; Offset über val-Parameter berechnen
  lsl.l   #2,OFFS

  moveq.l   #0,HIGHS
  moveq.l   #0,HIGHB

  move.l  12(sp,OFFS),HIGHS         ; HIGH(str)
  move.l  16(sp,OFFS),STR           ; str (Format-String)
  move.l  20(sp,OFFS),HIGHB         ; HIGH(buf)
  subq.l  #8,sp
  move.l  sp,PUTCHDATA
  move.l  32(sp,OFFS),(PUTCHDATA)   ; buffer (24+8)

stackCheck:
  move.l  OFFS,d0                   ; Stackbedarf berechnen
  addq.l  #8,d0
  addq.l  #8,d0
  jsr     OberonLib.StackChk
  tst.l   ARGC
  beq.s   print

copyArgs:                           ; val-Argumente auf Stack kopieren
  subq.l  #1,ARGC                   ; Sie liegen für die RawDoFmt-Routine
1$:                                 ; in der falschen Reihenfolge auf dem
  move.l  (HELP)+,-(sp)             ; Stack.
  dbra    ARGC,1$

  move.l  sp,ARGV                   ; Neuer Argument-Vektor

print:
  move.l  (PUTCHDATA),4(PUTCHDATA)  ; Endadresse des Puffers berechnen
  add.l   HIGHB,4(PUTCHDATA)

  lea     PutChProc(pc),PROC        ; Ausgabe-Prozedur für Zeichen

  move.l  4,a6                      ; Exec.RawDoFmt aufrufen
  jsr     _LVORawDoFmt(a6)

  add.l   #8,sp
  add.l   OFFS,sp
  movem.l (sp)+,a5/a6               ; a5/a6 holen
  move.l  (sp),a0
  lea     20(sp),sp                 ; 4+2*(4+4)
  add.l   OFFS,sp
  jmp     (a0)

; Diese Prozedur wird von RawDoFmt Aufgerufen.
; Das Zeichen das ausgegeben werden soll, ist in d0
PutChProc:
  move.l  (PUTCHDATA),a0
  cmp.l   4(PUTCHDATA),a0           ; Ist Ausgabe-Puffer voll ?
  bgt.s   1$
  move.b  d0,(a0)+                  ; Nein: Zeichen in Puffer schreiben
  move.l  a0,(PUTCHDATA)
1$:
  rts

  END
