1 /*
2  *	z88dk RS232 Function
3  *
4  *	ZX Spectrum plus version
5  *	Reference: zfst terminal emulator by Russell Marks
6  *
7  *	unsigned char rs232_put(char)
8  *
9  *	No error checking, for now.
10  *
11  *      $Id: rs232_put.c,v 1.8 2015-01-21 08:27:13 stefano Exp $
12  */
13 
14 
15 #include <rs232.h>
16 
17 
18 uint8_t rs232_put(uint8_t char)
19 {	/* Fastcall so implicit push */
20 #asm
21 
22 ;	EXTERN   zx_break
23 
24 	PUBLIC rs232_patch2
25 
26 ;;	defc	BAUD  = $5B71
27 	EXTERN BAUD
28 
29 
30 	ld	a,l	;get byte
31 
32 	push	af
33 
34 	ld	c,$fd
35 	ld	d,$ff
36 	ld	e,$bf
37 	ld	b,d
38 	ld	a,14
39 	out	(c),a	; AY reg. to control the RS232 port.
40 
41 .brkcheck
42 ;	call  zx_break
43 ;	jr    c,nobreak
44 ;
45 ;	ld	hl,RS_ERR_BREAK
46 ;	ret
47 ;
48 ;.nobreak
49 
50         IN   A,(C)        ; Read status of data register.
51         AND  $40          ; %01000000. Test the DTR line.
52         JR   NZ,brkcheck     ; Jump back until device is ready for data.
53 
54         LD   HL,(BAUD)    ; $5B5F. HL=Baud rate timing constant.
55 .rs232_patch2
56         LD   DE,$0002     ;
57         OR   A            ;
58         SBC  HL,DE        ;
59         EX   DE,HL        ; DE=(BAUD)-2.
60 
61         POP  AF           ; Retrieve the byte to send.
62         CPL               ; Invert the bits of the byte (RS232 logic is inverted).
63         SCF               ; Carry is used to send START BIT.
64         LD   B,$0B        ; B=Number of bits to send (1 start + 8 data + 2 stop).
65 
66         DI                ; Disable interrupts to ensure accurate timing.
67 
68 ;Transmit each bit
69 
70 L08E7:  PUSH BC           ; Save the number of bits to send.
71         PUSH AF           ; Save the data bits.
72 
73         LD   A,$FE        ;
74         LD   H,D          ;
75         LD   L,E          ; HL=(BAUD)-2.
76         LD   BC,$BFFD     ; AY-3-8912 data register.
77 
78         JP   NC,L08F9     ; Branch to transmit a 1 or a 0 (initially sending a 0 for the start bit).
79 
80 ;Transmit a 0
81 
82         AND  $F7          ; Clear the RXD (out) line.
83         OUT  (C),A        ; Send out a 0 (high level).
84         JR   L08FF        ; Jump ahead to continue with next bit.
85 
86 ;Transmit a 1
87 
88 L08F9:  OR   8            ; Set the RXD (out) line.
89         OUT  (C),A        ; Send out a 1 (low level).
90         JR   L08FF        ; Jump ahead to continue with next bit.
91 
92 ;Delay the length of a bit
93 
94 L08FF:  DEC  HL           ; (6) Delay 26*BAUD cycles.
95         LD   A,H          ; (4)
96         OR   L            ; (4)
97         JR   NZ,L08FF     ; (12) Jump back until delay is completed.
98 
99         NOP               ; (4) Fine tune the timing.
100         NOP               ; (4)
101         NOP               ; (4)
102 
103         POP  AF           ; Retrieve the data bits to send.
104         POP  BC           ; Retrieve the number of bits left to send.
105         OR   A            ; Clear carry flag.
106         RRA               ; Shift the next bit to send into the carry flag.
107         DJNZ L08E7        ; Jump back to send next bit until all bits sent.
108 
109         EI                ; Re-enable interrupts.
110 ;        RET               ; Return with carry and zero flags reset.
111 
112 
113 
114 	ld	hl,RS_ERR_OK
115 ;	pop	bc	;remove implicit push
116 
117 
118 #endasm
119 }
120