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