
;====================================== Init Serial Port at 9600,8,n,1,noHandShake
Init_Serial:                           ; (Assuming XTAL 11.0592MHz, 12cycles)
          clr  TCON_TR1                ; Stop Timer1
          mov  A, TMOD                 ; TMOD = (TMOD & 0x0F)|0x20
          anl  A, #0x0F                ; TMOD = 0000dddd (clear Timer1 bits)
          orl  A, #0x20                ; TMOD = 0010dddd (set M1=1 M0=0)
          mov  TMOD, A                 ; Timer1 at mode2 8bit autoreload
          mov  A, PCON                 ; PCON &= 0x7F 
          anl  A, #0x7F                ; clear PCON.7 = SMOD double rate
          mov  PCON, A                 ; 0=x1 baud rate, 1=x2 baud rate
          mov  SCON, #0x52             ; REN=1 (ready to receive)
                                       ; TI=1 (ready to transmit next char)
          mov  TH1, #0xFD              ; Reload value TH1 
          mov  TL1, #0xFD              ; Reload value TL1
          setb TCON_TR1                ; Start Timer1 as Baud Rate Generator
          ret      

;====================================== getchar Returns received character in A
getchar:                               ; 
gtchr1:   jbc  SCON_RI, gtchr2         ; if  RI=1 (char received) clear RI
          sjmp gtchr1                  ; polled wait for RI=1
gtchr2:   mov  A, SBUF                 ; then return the char in A
          ret


;====================================== putchar Transmit a character in A =====
putchar:
ptchr1:   jbc  SCON_TI, ptchr2         ; if TI=1 (ready for next) clear TI
          sjmp ptchr1                  ; polled wait for TI=1
ptchr2:   mov  SBUF, A                 ; then send the next char to TX
          ret


;====================================== prints DPTR points to a string ========
prints:                                ; in Code memory
prnts1:   clr  A                       ; print string Null terminated 
          movc A, @A+DPTR              ; 
          jz   prnts2                  ; Check for NULL  #0x00
          acall putchar                ; print character
          inc  DPTR                    ; get next
          sjmp prnts1                  ;
prnts2:   ret



;====================================== print_hex or print_byte ===============
print_byte:                           ;
print_hex:                            ; Print a hex value in A to stdio (ANSI)
                                      ; eg. A has 11010111  ==> D7
prh_a:                                ; uses A, B
           push B                     ; save B
           mov  B, A                  ; save A in B
           anl  A, #0xF0              ; mask upper nibble 
           swap A                     ; now A has 0000xxxx
           cjne A, #0x0A, prh_c       ; check A <> 10
prh_b:     add  A, #0x37              ; if A = 0x0A then add 0x37 ('A'-10)
           sjmp prh_d                 ; goto print
prh_c:     jnc  prh_b                 ; if A > 0x0A same a s A=0x0A
           add  A, #0x30              ; if A < 0x0A then add 0x30 ('0')
prh_d:     acall putchar              ; print high nibble

           mov  A, B                  ; get the value from B
           anl  A, #0x0F              ; mask the low nibble
           cjne A, #0x0A, prh_f       ; check A <> 10
prh_e:     add  A, #0x37              ; if A = 0x0A then add 0x37 ('A'-10)
           sjmp prh_g                 ; goto print
prh_f:     jnc  prh_e                 ; if A > 0x0A 
           add  A, #0x30              ; if A < 0x0A then add 0x30 ('0')
prh_g:     acall putchar              ; print high nibble
           pop  B                     ; restore B
           mov  A, B                  ; restore A
           ret



;====================================== print_bin99 prints a byte 00h-63h ASCII
print_bin99:                      
           push A                      ; A holds the byte to be printed
           push B                      ;
           push PSW                    ;
           
prb99_a:                               ; while (A>=100) A-=100
           cjne A, #100, prb99_b       ;
             sjmp prb99_c              ; A=100
prb99_b:   jc prb99_d                  ; if A<100 then exit
prb99_c:      clr C                    ; A>=100
              subb A, #100             ; A-=100
           sjmp prb99_a                ;
prb99_d:

           mov  B, #10                 ; divider by decimal 10
           div  AB                     ; quotiend=piliko in A (dekades)
                                       ; remainder-ypoloipo in B (monades)
           add  A,#'0'                 ; make quotiend 0h-9h ASCII 30h-39h
           acall putchar               ; dekades first
           mov  A, B                   ;
           add  A, #'0'                ; make remainder ASCII 30h-39h
           acall putchar
           
           pop PSW
           pop B
           pop A
           ret

;====================================== PART of MAIN =======================
          ...
          acall Init_Serial
          ...

  
          mov  DPTR, #string1          ; Send String1
          acall prints                 ;
          mov  DPTR, #CRLF             ; Send CRLF
          acall prints                 ; 
          mov  DPTR, #prompt           ; Prompt "0>"
          acall prints                 ;
         
          ...
          sjmp $
   
;===========================================================================


CRLF:     DB 0x0D, 0x0A, 0x00          ; Carriage Return, Line Feed, Null term.
FF:       DB 0x0C                      ; FormFeed
string1:  DB "String 1 to print"       ; Double quotes = NULL terminated string
prompt:   DB "0>"                      ; Prompt
