;This code is listed here for entertainment value only, it should ;not be used for anything important. Do not use this for a saleable product. ;Feel free to pass this on to others in it's entirety. along with this message. ;No Guarantees implicit or otherwise are implied, your mileage may vary. $RB(0) $RB(1) $NOMOD51 INCLUDE(87C752.pdf) $INCLUDE(common.inc) ; Put Character routine CLIBC SEGMENT CODE RSEG CLIBC PUBLIC PUTCHAR PUBLIC IPUTCHAR PUTCHAR: ; char is put in *R1 CLR EA ; Turn off interrupts, a critical section. SETB RS0 ; Use register bank 1. MOV @R1,A ; put character into output buffer. INC R1 ; move output buffer head, wrap around if end. CJNE R1,#OBUFEND,RETPUTC MOV R1,#OBUFSTART RETPUTC: CLR RS0 ; get back to register bank 0 SETB EA ; reenable interrupts and leave. RET ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; IPUTCHAR ; Takes character in ACC and puts it out SWR 9600,N,8,1 ; uses R6 and R7 but these are free for other usage since this code ; doesn't get interrupted. ; ; CPB cycles per bit. ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; IPUTCHAR: CLR EA ; Disable all interrupts until character is out SETB RS0 ; Register bank 1 contains output buffer data MOV A,R0 CLR C SUBB A,R1 JZ BAILOUT MOV A,@R0 WRITEBUFOK: CLR RS0 ; Register bank 0 needs to be reset. CPL A ; RS 232 is expecting inverted output. ; 1 cycle MOV R6,#9 ; 9 Bits out(1start plust 8 bits), plus stop ; bit.. ; 1 cycle ;write first (one) bit. SETB C ; 1 cycle ; loop=( base cycles - 7 for bit setup overhead ) / 2 ; R7 will contain the time necessary to match 9600 baud. PNEXTBIT: MOV SWR,C ; 2 cycles MOV R7,#(CPB-7)/2 ; 1 cycle ;sleep DJNZ R7,$ ; 2 cycles IF ((CPB-7) MOD 2) > 0 NOP ; Waste time to get to CPB cycles. ENDIF CLR C ; 1 cycles RRC A ; 1 cycles DJNZ R6,PNEXTBIT ; 2 cycles ;write two stop (zero) bits. CLR SWR ; 1 cycle ; loop=(base cycles - 1 ) * 2 / 2 MOV R7,#(CPB-1) ; 1 cycle ; sleep DJNZ R7,$ ; 2 cycles JB CTS,BAILOUT ; Character didn't make it, try again later. ; What happened was the master moved on ; after telling us it was ok to transmit. SETB RS0 ; Register bank 1 contains output buffer data INC R0 ; Update output buffer, since we actually ; got the character out. CJNE R0,#OBUFEND,BAILOUT MOV R0,#OBUFSTART ; and wrap if necessary. BAILOUT: CLR RS0 ; get back to register bank 0 SETB EA ; Reenable all interrupts now. RET ; and leave. $EJECT END