;----------------------------------------------------------------------------
;                    printf  (formatted print to file)
;----------------------------------------------------------------------------
;
; Imbedded formatting chars:-  %s   =   string (null-terminated)
;                              %c   =   single character
;                              %ld  =   decimal number
;                              %lx  =   hexadecimal number
;
;  For numeric formats the following modifiers can be supplied immediately
;  after the "%" .These can be combined in the order shown here.
;
;    "-"           signifies that the item will be left-aligned in its field.
;    "0"           leading zeros may be attached (default is spaces).
;    "1" to "10"   number will be padded  by 1 to 10 characters('0' or space).
;    ".1" to ".10" fixed point will be inserted in number, 1 to 10 characters
;                  from the right of field.
;
;NOTE: All parameters MUST be LongWords. Numbers are passed as values.
;      Strings are passed  as addresses (Use "lea  xxxx,An" or #xxxx).
;
;Example:
;
;mystring: dc.b "abcdefghijklm",0
;
; moveq  #0,d0               ; make sure D0 is zero in upper 3 bytes
; move.b mystring+5,d0
; printf <"the %ldth char in %s,'%c', is $%03lx in hex">,6,#mystring,d0,d0
;
;Example o/p:  "the 6th char in abcdefghijklm,'f', is $066 in hex"
;
;
;NOTE: The assembler will require that the format string be enclosed in
;      "<" and ">" so that you can include spaces in the string.You can
;      also include special characters by using the numeric equivalent.
;      This includes using "<>" in the string eg. <"1",60,"2",10> will
;      be expanded to:-  dc.b "1","<","2",10
;
;
printf MACRO <"text">,parm1,parm2,parm3
    ifnc     "","\2"
    move.l  \2,_parm1
    endc
    ifnc    "","\3"
    move.l  \3,_parm2
    endc
    ifnc    "","\4"
    move.l  \4,_parm3
    endc
    pea     .Text\@(pc)
    bsr     _printf
    addq.l  #4,sp
    bra.s   .End\@
.Text\@:
    dc.b    \1,0
    even
.End\@:
    ENDM


;  _printf() ; string ptr on stack , no regs required , all regs preserved

_printf:
  movem.l d0/d1/a0-a3/a6,-(sp)
  move.l  28(sp),a0          ; get string ptr
  lea     _parm1(PC),A1
  lea     _prtchr(PC),A2
  lea     obuf(pc),a3
  add.w   olen(pc),a3
  EXEC    RawDoFmt
  movem.l (sp)+,d0/d1/a0-a3/a6
  rts

_parm1:
  dc.l 0
_parm2:
  dc.l 0
_parm3:
  dc.l 0

_prtchr:
  move.b  d0,(a3)+           ; end of string ?
  beq.s   .null
  cmp.b   #10,d0             ; linefeed ?
  bne.s   .done
  bsr     _flush             ; print line
  lea     obuf(pc),a3
  bra.s   .length            ; empty buffer
.null:
  subq.l  #1,a3              ; backup over null
.length:
  move.l  a3,d0
  lea     obuf(pc),a3
  sub.l   a3,d0
  move.w  d0,-2(a3)          ; update string length
.done:
  rts


_flush:
  movem.l d0-d3/a0-a1/a6,-(sp)
  move.l  ohandle(pc),d1
  beq.s   .nofile            ; file handle available ?
  lea     obuf(pc),a0
  move.l  a0,d2
  move.l  a3,d3
  sub.l   a0,d3
  DOS     Write              ; write line to file
.nofile:
  movem.l (sp)+,d0-d3/a0-a1/a6
  rts

; call this to force the line out

_flushf:
  lea     obuf(pc),a3
  add.w   -2(a3),a3
  bsr.s   _flush
  clr.w   olen
  rts


ohandle:
  dc.l    0    ; filehandle supplied by main program (eg. ohandle=Output() )
olen:
  dc.w    0
obuf:
  ds.b    160

