I have started to squeeze the hook code. This can be done by merging the start, stop and data bits into a 16 bit register and use the same loop to transmit all the bits from the RS232 character (i.e. 10 bits). It also has a positive side effect that now all the bits will last exactly the same time (the stop bit may linger but it doesn't really matter as long as it takes at least 1 bit time.
Then the bitbang code turns into:
SND232: ; Inputs: ; L: Byte to be sent ; ; Changes: AF, BC, HL ; Select PSG Register 15 LD A,15 OUT [PSGAD],A ; Prepare stream of bits LD H,255; Add stop bits AND A ; clear carry flag RL L ; Add start bit and send 7th bit to carry RL H ; Send 7th bit to H register ; HL register is now ; ------------ H ----------- ----------- L --------- ; 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 ; 1 1 1 1 1 1 1 stp b7 b6 b5 b4 b3 b2 b1 b0 start ; Now loop through 10 bits [1 extra to compensate time at the end of the loop] LD B,10+1 ; poke here with 12 to send two stop bits instead of only one SEND_BITS: ; prepare mask ; Cycles Accumul IN A,[PSGRD] ; 14 24 save the present state of the bits from PSG register 15 RES 0,A ; 10 clear bit 0 ; 16 bit rotate RR H ; 10 20 H.0->Cy (bit 0 from H goes to carry) RR L ; 10 Cy->L.7, L.0->Cy ; set TXD line state ADC A,0 ; 8 20 A.0 now equals Cy OUT [PSGWR],A ; 12 write bit to output. Here starts the cycle counting ; delay 1 bit time LD C,_DLY ; 8 8 poke here to change the cycle count DELAY_C: DEC C ; ( 5) JP NZ DELAY_C ; (11) ; 16*_DLY DJNZ SEND_BITS ; 14(/9) send next bit ;Total: 8 + 16*_DLY + 24 + 20 + 20 from Start bit to beginning of stop bit ; 72 +16*_DLY cycles ; ; after the last bit we have: 8 + 16*_DLY + 9 ; 17 + 16*_DLY ; ; we're missing 72-17 = 55 cycles that's why we added 1 to ensure that ; at least 1 stop bit time has passed before we return RET
Discussions
Become a Hackaday.io Member
Create an account to leave a comment. Already have an account? Log In.