; Some routines to make Input and Output more easy
; you MUST include this AFTER MACS.ASM

         BRA      _IO_end
; ------------------------------------
; Write one hex digit in D0 to buffer
; ------------------------------------
HEXO4:  MOVE.W  D0,-(A7)
        AND.B   #$F,D0
        ADD.B   #'0',D0
        CMP.B   #'9',D0
        BLE.S   IOHX41
        ADD.B   #7,D0
IOHX41: BSR     OUTCH
        MOVE.W  (A7)+,D0
        RTS
; ----------------------------------------
; Write a BYTE Hex number in D0 to buffer
; ----------------------------------------
HEXO8:  MOVE.W  D0,-(A7)
        LSR.B   #4,D0
        BSR.S   HEXO4
        MOVE.W  (A7)+,D0
        BRA.S   HEXO4
; ---------------------------------------
; Write a WORD Hex number in D0 to buffer
; ---------------------------------------
HEXO16: MOVE.W  D0,-(A7)
        LSR.W   #8,D0
        BSR.S   HEXO8
        MOVE.W  (A7)+,D0
        BRA.S   HEXO8
; --------------------------------------------
; write a LONGWORD Hex number in D0 to buffer
; --------------------------------------------
HEXO32: SWAP    D0
        BSR.S   HEXO16
        SWAP    D0
        BRA.S   HEXO16
; ---------------------------------------
; write a decimal number in D0 to buffer
; ---------------------------------------
DECOUT: MOVEM.L D0-D3,-(A7)
        TST.L   D0                      ; first check negative value
        BPL.S   IODEC1
        MOVE.L  D0,-(A7)
        MOVE.B  #'-',D0
        BSR     OUTCH
        MOVE.L  (A7)+,D0
        NEG.L   D0
IODEC1: MOVE.L  D0,D1
        MOVE.L  #100000,D2
IODEC2: CMP.L   D2,D1                   ; number should be less than D1
        BGE.S   IODEC3
        DIVU    #10,D2
        TST.W   D2
        BEQ.S   IODEC4
        BRA.S   IODEC2
IODEC4: MOVEQ   #48,D0                 ; Trap D0='0'
        BSR     OUTCH
        BRA.S   IODEC5
IODEC3: DIVU    D2,D0
        ADD.B   #'0',D0
        BSR     OUTCH
        SUB.B   #'0',D0
        MULU    D2,D0
        SUB.L   D0,D1
        MOVE.L  D1,D0
        DIVU    #10,D2
        TST.W   D2
        BNE.S   IODEC3
IODEC5: MOVEM.L (A7)+,D0-D3
        RTS
; -----------------------------------------
;     write one byte in D0 to buffer
; -----------------------------------------
OUTCH:
        MOVEM.L D1/A0,-(A7)
        LEA     DATSPC,A0
        MOVE.W  (A0),D1
        MOVE.B  D0,2(A0,D1.W)
        ADDQ.W  #1,D1
        MOVE.W  D1,(A0)
        MOVEM.L (A7)+,D1/A0
        RTS
; ------------------------------------------
;     Print out string in DATSPC without LF
; ------------------------------------------
PRINTBUF:
         MOVEM.L  D0-D3/A0,-(A7)
         LEA      DATSPC,A0
         RCL      StdOut,D1   ; get output handle
         CLR.L    D3
         MOVE.W   (A0)+,D3    ; lenth of text
         MOVE.L   A0,D2       ; address of buffer
         LINKSYS  Write,dos
         LEA      DATSPC,A0
         MOVE.W   #0,(A0)     ; and clear counter
         MOVEM.L  (A7)+,D0-D3/A0
         RTS

; --------------------------------------------------------------
;      put text after BSR instruction up to 0 to buffer
; --------------------------------------------------------------
TXTOUT: ; Call like : BSR TXTOUT / DC.B 'Dies ist ein Text',0
      MOVEM.L  D0/A0,-(A7)
      MOVE.L   8(A7),A0 ; get start of text
TXTOUT_1:
      MOVE.B   (A0)+,D0
      BEQ.S    TXTOUT_2
      BSR      OUTCH
      BRA.S    TXTOUT_1
TXTOUT_2:
      MOVE.L   A0,D0
      BTST     #0,D0     ; even or odd address ?
      BEQ.S    TXTOUT_3
      ADDQ.L   #1,A0     ; align to even address
TXTOUT_3:
      MOVE.L   A0,8(A7) ; store return address
      MOVEM.L  (A7)+,D0/A0
      RTS

DATSPC:  DS.B  256

_IO_end:
      NOP
