├── 115200-timing.xlsx ├── LICENSE ├── PSG15.bin ├── README.md ├── rs232-115200.asm ├── rs232-2400-19200.asm ├── rs232-57600.asm ├── rs232-86400.asm └── rs232.asm /115200-timing.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rolandvans/msx_softserial/86c7bb5788714e3482f180d5941896c9b947e481/115200-timing.xlsx -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 rolandvans 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /PSG15.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rolandvans/msx_softserial/86c7bb5788714e3482f180d5941896c9b947e481/PSG15.bin -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # msx_softserial 2 | rs232 serial ttl interface via joystick port at 57600 bps for MSX 3 | Only works on 3.58MHz Z80 MSX computers. 4 | Thanks to Grauw for his work on fast loops and the correct timing table for the Z80 instructions: http://map.grauw.nl/resources/z80instr.php 5 | -------------------------------------------------------------------------------- /rs232-115200.asm: -------------------------------------------------------------------------------- 1 | ;READ DATA VIA JYSTICK AT 115200 BITS/SECOND 2 | ;REQUIRES 2 STOPBITS (!!) 3 | ;STARTS WRITING DATA AT HL, STOPS AT TIMEOUT 4 | ;MODIFIES HL,BC,AF, PSG REG #15 5 | CPU Z80 6 | FNAME "RS232RD.BIN" 7 | 8 | VOICEAQ: EQU $F975 ;BUFFER TO OCCUPY IN SYSTEM AREA: DO NOT USE PLAY... 9 | 10 | ;MSX .BIN HEADER 11 | DB $FE 12 | DW START, END, START 13 | 14 | ORG VOICEAQ 15 | START: 16 | 17 | RECBYTES: 18 | ;INITIAL SETUP 19 | DI ;NO INTERRUPTS, TIME CRITICAL ROUTINE 20 | LD A,$0F ;PSG REGISTER 15, SELECT JOYSTICK PORT 2 21 | OUT ($A0),A 22 | IN A,($A2) 23 | SET 6,A ;SELECT JOY2 24 | OUT ($A1),A 25 | LD B,$00 ;NICE FOR DEBUGGING, NOT STRICTLY NEEDED 26 | 27 | LD A,$0E ;SET PSG #14 WE READ BIT 0 (JOY-UP) 28 | OUT ($A0),A 29 | LD C,$A2 ;PSG READ REGISTER 30 | .WAITFORFIRSTSTARTBIT: 31 | IN A,(C) ;STARTBIT 32 | JP PE,.WAITFORFIRSTSTARTBIT 33 | NOP ;10 CYCLE DUMMY DELAY 34 | NOP 35 | ;START READING DATA BITS 36 | IN A,($A2) ;BIT0 37 | RRCA 38 | RR B 39 | NOP 40 | IN A,($A2) ;BIT1 41 | RRCA 42 | RR B 43 | IN A,(C) ;BIT2 44 | RRCA 45 | RR B 46 | NOP 47 | IN A,($A2) ;BIT3 48 | RRCA 49 | RR B 50 | NOP 51 | IN A,($A2) ;BIT4 52 | RRCA 53 | RR B 54 | IN A,(C) ;BIT5 55 | RRCA 56 | RR B 57 | NOP 58 | IN A,($A2) ;BIT6 59 | RRCA 60 | RR B 61 | ;NOP 62 | IN A,(C) ;BIT7 63 | RRCA 64 | RR B 65 | LD (HL),B 66 | INC HL 67 | .WAITFORSTARTBIT: 68 | IN A,(C) 69 | JP PO,.READDATABITS 70 | IN A,(C) 71 | JP PO,.READDATABITS 72 | IN A,(C) 73 | JP PO,.READDATABITS 74 | EI 75 | RET 76 | .READDATABITS: 77 | NOP ;10 CYCLE DUMMY 78 | NOP 79 | ;START READING DATA BITS 80 | IN A,($A2) ;BIT0 81 | RRCA 82 | RR B 83 | NOP 84 | IN A,($A2) ;BIT1 85 | RRCA 86 | RR B 87 | IN A,(C) ;BIT2 88 | RRCA 89 | RR B 90 | NOP 91 | IN A,($A2) ;BIT3 92 | RRCA 93 | RR B 94 | NOP 95 | IN A,($A2) ;BIT4 96 | RRCA 97 | RR B 98 | IN A,(C) ;BIT5 99 | RRCA 100 | RR B 101 | NOP 102 | IN A,($A2) ;BIT6 103 | RRCA 104 | RR B 105 | ;NOP 106 | IN A,(C) ;BIT7 107 | RRCA 108 | RR B 109 | LD (HL),B 110 | INC HL 111 | JP .WAITFORSTARTBIT 112 | 113 | ;SEND 'BC' BYTES FROM [HL] TO PIN6, JOY2 114 | ;MSX, Z80 3.58MHz 115200bps 115 | SENDBYTES: 116 | DI ;NO INTERRUPTS 117 | LD A,$0F ;SELECT PSG REG #15 118 | OUT ($A0),A 119 | IN A,($A2) ;SAVE VALUE 120 | ;PUSH AF 121 | SET 6,A ;JOY2 122 | RES 2,A ;TRIG1 LOW 123 | LD E,A ;0V VALUE (0) IN E 124 | SET 2,A ;TRIG1 HIGH 125 | LD D,A ;5V VALUE (1) IN D 126 | 127 | .BYTELOOP: 128 | LD A,(HL) 129 | PUSH BC 130 | LD C,$A1 131 | .STARTBIT: 132 | OUT (C),E ;STARTBIT=LOW 133 | .BYTE: 134 | RRCA 135 | JP C,.BIT0H 136 | ;BIT LOW 137 | .BIT0L: 138 | OUT (C),E 139 | RRCA 140 | JP C,.BIT1H 141 | .BIT1L: 142 | OUT (C),E 143 | RRCA 144 | JP C,.BIT2H 145 | .BIT2L: 146 | OUT (C),E 147 | RRCA 148 | JP C,.BIT3H 149 | .BIT3L: 150 | OUT (C),E 151 | RRCA 152 | JP C,.BIT4H 153 | .BIT4L: 154 | OUT (C),E 155 | RRCA 156 | JP C,.BIT5H 157 | .BIT5L: 158 | OUT (C),E 159 | RRCA 160 | JP C,.BIT6H 161 | .BIT6L: 162 | OUT (C),E 163 | RRCA 164 | JP C,.BIT7H 165 | .BIT7L: 166 | OUT (C),E 167 | LD A,D ;NOP 168 | POP BC ;JP .STOPBIT 169 | OUT ($A1),A 170 | .STOPBIT: 171 | ; INCREASE HL AND CHECK BC COUNTER 172 | INC HL 173 | DEC BC 174 | LD A,B 175 | OR C 176 | JP NZ,.BYTELOOP 177 | .EXIT: 178 | EI ;EXIT 179 | RET 180 | ;BIT HIGH 181 | .BIT0H: 182 | OUT (C),D 183 | RRCA 184 | JP NC,.BIT1L 185 | .BIT1H: 186 | OUT (C),D 187 | RRCA 188 | JP NC,.BIT2L 189 | .BIT2H: 190 | OUT (C),D 191 | RRCA 192 | JP NC,.BIT3L 193 | .BIT3H: 194 | OUT (C),D 195 | RRCA 196 | JP NC,.BIT4L 197 | .BIT4H: 198 | OUT (C),D 199 | RRCA 200 | JP NC,.BIT5L 201 | .BIT5H: 202 | OUT (C),D 203 | RRCA 204 | JP NC,.BIT6L 205 | .BIT6H: 206 | OUT (C),D 207 | RRCA 208 | JP NC,.BIT7L 209 | .BIT7H: 210 | OUT (C),D 211 | POP BC ;NOP 212 | JP .STOPBIT 213 | -------------------------------------------------------------------------------- /rs232-2400-19200.asm: -------------------------------------------------------------------------------- 1 | ;RECEIVING AND SENDING RS232 DATA @9600 BITS/S ON A STANDARD MSX 3.57MHz 2 | CPU Z80 3 | FNAME "RS232.BIN" 4 | 5 | VOICEAQ: EQU $D000 ;BUFFER TO OCCUPY IN SYSTEM AREA: DO NOT USE PLAY... 6 | 7 | ;MSX .BIN HEADER 8 | DB $FE 9 | DW START, END, START 10 | 11 | ORG VOICEAQ 12 | START: 13 | ;TRANSFER 'BC' BYTES FROM JOY2, 'UP', PIN1 TO (HL) 14 | ;MSX, Z80 3.58MHz 15 | ;SETS CARRY BIT ON ERROR. A HOLDS ERROR CODE: 16 | ;A=1 RS232 LINE NOT HIGH,A=2 STARTBIT TIMEOUT 17 | RECBYTES: 18 | LD D,B ;USE DE AS BYTE COUNTER, B AS BIT COUNTER AND C AS VDP STATUS REGISTER 19 | LD E,C 20 | LD BC,$0099 ;B=0 -> ~4 SECONDS TIME-OUT 21 | 22 | DI ;NO INTERRUPTS, TIME CRITICAL ROUTINE 23 | 24 | LD A,$0F ;PSG REGISTER 15, SELECT JOYSTICK PORT 2 25 | OUT ($A0),A 26 | IN A,($A2) 27 | SET 6,A ;SELECT JOY2 28 | OUT ($A1),A 29 | 30 | LD A,$0E ;SET PSG #14 31 | OUT ($A0),A 32 | IN A,($A2) 33 | AND $01 34 | JR NZ,.STARTBIT ;RS232 LINE SHOULD BE HIGH, OTHERWISE STOP 35 | LD A,$01 ;ERROR, RS232 LINE NOT READY 36 | SCF 37 | EI 38 | RET 39 | .STARTBIT: 40 | IN A,($A2) 41 | AND $01 42 | JP Z,.STARTREAD ;YES, WE HAVE A START BIT 43 | 44 | IN F,(C) ;VDP INTERRUPT? 45 | JP P,.STARTBIT ;NO INTERRUPT 46 | 47 | IN A,($A2) 48 | AND $01 49 | JP Z,.STARTREAD ;YES, WE HAVE A START BIT 50 | 51 | DJNZ .STARTBIT 52 | LD A,$02 ;ERROR START BIT TIME-OUT ~4-5S 53 | SCF 54 | EI 55 | RET 56 | .STARTREAD: 57 | LD A,(DELAY_START) ;DELAY FROM START BIT -> BIT 0 58 | CALL DELAY ;WAIT FOR BIT0 59 | LD B,7 ;WE NEED 8 BITS, READ AS 7+1 60 | .READBITS: 61 | IN A,($A2) 62 | RRCA ;SHIFT DATA BIT (0) -> CARRY 63 | RR (HL) ;SHIFT CARRY -> [HL] 64 | LD A,(DELAY_BITS) ;DELAY FROM BIT N -> BIT N+1 65 | CALL DELAY 66 | DJNZ .READBITS 67 | IN A,($A2) ;LAST BIT, OTHER DELAY (STOPBIT) 68 | RRCA ;SHIFT DATA BIT (0) -> CARRY 69 | RR (HL) ;SHIFT CARRY -> [HL] 70 | .NEXTBYTE: 71 | LD A,(DELAY_STOP) ;DELAY BIT 7 TO ENSURE WE ARE AT STOPBIT 72 | CALL DELAY 73 | LD B,A ;LD B,0 BUT A=0 74 | INC HL 75 | DEC DE 76 | LD A,D 77 | OR E 78 | JP Z,.FINISH ;WE ARE FINISHED 79 | IN A,($A2) ;READ ACTUAL STOPBIT VALUE 80 | AND $01 81 | JR NZ,.STARTBIT ;NEXT BYTE OR STOPBIT ERROR 82 | .STOPBITERROR: 83 | LD A,3 84 | SCF 85 | EI 86 | RET 87 | .FINISH: 88 | OR A ;RESET CARRY FLAG 89 | EI 90 | RET 91 | 92 | ;SEND 'BC' BYTES FROM [HL] TO PIN6, JOY2 93 | ;MSX, Z80 3.58MHz 94 | SENDBYTES: 95 | DI ;NO INTERRUPTS 96 | LD A,$0F ;SELECT PSG REG #15 97 | OUT ($A0),A 98 | IN A,($A2) 99 | PUSH AF ;SAVE VALUE OF REG #15 100 | SET 6,A ;JOY2 101 | RES 2,A ;TRIG1 LOW 102 | LD E,A ;0V VALUE (0) IN E 103 | SET 2,A ;TRIG1 HIGH 104 | LD D,A ;5V VALUE (1) IN D 105 | .BYTELOOP: 106 | PUSH BC 107 | LD A,E ;START BIT (=0) 108 | .STARTBIT: 109 | LD C,(HL) 110 | LD B,$08 111 | OUT ($A1),A 112 | ADD A,$00 ;DUMMY 8 CYCLES 113 | LD A,(DELAY_BITS) 114 | CALL DELAY 115 | .BITLOOP: 116 | RRC C 117 | LD A,D ;ASSUME BIT=1 118 | JR C,.SETBIT 119 | LD A,E ;NO, BIT=0 120 | .SETBIT: 121 | OUT ($A1),A 122 | LD A,(DELAY_BITS) 123 | CALL DELAY 124 | DJNZ .BITLOOP 125 | .STOPBIT: 126 | LD A,D 127 | OUT ($A1),A ;STOP BIT (=1) 128 | LD A,(DELAY_STOP) 129 | CALL DELAY 130 | POP BC 131 | DEC BC 132 | INC HL 133 | LD A,B 134 | OR C 135 | JP NZ,.BYTELOOP 136 | .EXIT: 137 | POP AF 138 | OUT ($A1),A ;RESTORE REG #15 OF PSG 139 | EI 140 | RET 141 | 142 | DELAY: 143 | DEC A 144 | JP NZ,DELAY 145 | RET 146 | 147 | ;SET SPEED FRO SERIAL COMMUNICATION: A=0 2400 BPS, A=1 4800 BPS, A=2 9600 BPS, A=3 19200 BPS 148 | SETSPEED: 149 | AND 3 150 | LD HL,SERIALSPEEDDATA 151 | LD E,A 152 | SLA A 153 | ADD A,E 154 | LD E,A 155 | LD D,0 156 | ADD HL,DE 157 | LD DE,DELAY_START 158 | LD BC,3 159 | LDIR 160 | RET 161 | 162 | ;DEFAULT SETTING 9600 BPS 163 | DELAY_START: 164 | DB 28 165 | DELAY_BITS: 166 | DB 18 167 | DELAY_STOP: 168 | DB 16 169 | 170 | SERIALSPEEDDATA: 171 | ;2400 BPS (0) 172 | DB 133,88,85 173 | ;4800 BPS (1) 174 | DB 63,41,38 175 | ;9600 BPS (2) 176 | DB 28,18,16 177 | ;19200 BPS (3) 178 | DB 11,6,4 179 | 180 | END: 181 | 182 | -------------------------------------------------------------------------------- /rs232-57600.asm: -------------------------------------------------------------------------------- 1 | ;RECEIVING AND SENDING RS232 DATA @57600 BITS/S ON A STANDARD MSX 3.57MHz 2 | CPU Z80 3 | FNAME "57600.BIN" 4 | 5 | VOICEAQ: EQU $D000 ;BUFFER TO OCCUPY IN SYSTEM AREA: DO NOT USE PLAY... 6 | 7 | ;MSX .BIN HEADER 8 | DB $FE 9 | DW START, END, START 10 | 11 | ORG VOICEAQ 12 | START: 13 | ;TRANSFER 'BC' BYTES FROM JOY2, 'UP', PIN1 TO (HL) 14 | ;MSX, Z80 3.58MHz 57600bps 15 | ;SETS CARRY BIT ON ERROR. A HOLDS ERROR CODE: 16 | ;A=1 RS232 LINE NOT HIGH,A=2 STARTBIT TIMEOUT 17 | RXBYTES: 18 | DI ;NO INTERRUPTS, TIME CRITICAL ROUTINE 19 | LD A,$0F ;PSG REGISTER 15, SELECT JOYSTICK PORT 2 20 | OUT ($A0),A 21 | IN A,($A2) 22 | SET 6,A ;SELECT JOY2 23 | OUT ($A1),A 24 | 25 | INC BC ; COMPENSATION FOR THE CHECK UPFRONT ISO AFTER WRITING BYTE (CPI) 26 | DEC HL 27 | LD A,$0E ;SET PSG #14 28 | OUT ($A0),A 29 | LD E,$01 ;FOR FASTER 'AND' OPERATION 'AND r'(5) VS. 'AND n'(8) 30 | IN A,($A2) 31 | AND E 32 | JR NZ,.FIRSTSTARTBIT ;RS232 LINE SHOULD BE HIGH, OTHERWISE STOP 33 | LD A,$01 ;ERROR, RS232 LINE NOT READY 34 | SCF 35 | EI 36 | RET 37 | .FIRSTSTARTBIT: 38 | IN A,($A2) 39 | AND E 40 | JP NZ,FIRSTSTARTBIT 41 | .DELAY: 42 | CPI 43 | EX AF,AF' 44 | LD D,B 45 | LD B,$08 46 | .BITLOOP: 47 | INC HL ;DUMMY 48 | DEC HL ;DUMMY 49 | IN A,($A2) 50 | RRCA ;SHIFT DATA BIT (0) -> CARRY 51 | RR (HL) ;SHIFT CARRY -> [HL] 52 | DJNZ .BITLOOP 53 | .NEXTBYTE: 54 | LD B,D 55 | EX AF,AF' 56 | JP PE,.FIRSTSTARTBIT 57 | OR A ;RESET CARRY 58 | EI 59 | RET 60 | 61 | RXBYTES: 62 | DI ;NO INTERRUPTS, TIME CRITICAL ROUTINE 63 | LD A,$0F ;PSG REGISTER 15, SELECT JOYSTICK PORT 2 64 | OUT ($A0),A 65 | IN A,($A2) 66 | SET 6,A ;SELECT JOY2 67 | OUT ($A1),A 68 | 69 | INC BC ; COMPENSATION FOR THE CHECK UPFRONT ISO AFTER WRITING BYTE (CPI) 70 | DEC HL 71 | LD A,$0E ;SET PSG #14 72 | OUT ($A0),A 73 | LD E,$01 ;FOR FASTER 'AND' OPERATION 'AND r'(5) VS. 'AND n'(8) 74 | IN A,($A2) 75 | AND E 76 | JR NZ,.FIRSTSTARTBIT ;RS232 LINE SHOULD BE HIGH, OTHERWISE STOP 77 | LD A,$01 ;ERROR, RS232 LINE NOT READY 78 | SCF 79 | EI 80 | RET 81 | .FIRSTSTARTBIT: 82 | IN A,($A2) 83 | AND E 84 | JP NZ,FIRSTSTARTBIT 85 | .DELAY: 86 | INC HL ; UPDATE COUNTERS (OFFSET BY ONE) 87 | DEC BC 88 | NOP ; DUMMY 89 | NOP ; DUMMY 90 | LD D,B ; STORE B 91 | LD B,$08 92 | .BITLOOP: 93 | INC HL ;DUMMY 94 | DEC HL ;DUMMY 95 | IN A,($A2) 96 | RRCA ;SHIFT DATA BIT (0) -> CARRY 97 | RR (HL) ;SHIFT CARRY -> [HL] 98 | DJNZ .BITLOOP 99 | .NEXTBYTE: 100 | LD B,D ; RESTORE B 101 | LD A,B 102 | OR C 103 | JR Z,.EXIT 104 | .STARTBIT 105 | IN A,($A2) 106 | AND E 107 | JP Z,.DELAY 108 | IN A,($A2) 109 | AND E 110 | JP Z,.DELAY 111 | IN A,($A2) 112 | AND E 113 | JP Z,.DELAY 114 | IN A,($A2) 115 | AND E 116 | JP Z,.DELAY 117 | .TIMEOUT: 118 | LD A,$02 119 | SCF 120 | EI 121 | RET 122 | .EXIT 123 | OR A ;RESET CARRY 124 | EI 125 | RET 126 | 127 | 128 | ;SEND 'BC' BYTES FROM (HL) TO PIN6, JOY2 129 | ;MSX, Z80 3.58MHz 57600bps 130 | TXBYTES: 131 | DI ;NO INTERRUPTS 132 | LD A,$0F ;SELECT PSG REG #15 133 | OUT ($A0),A 134 | IN A,($A2) ;SAVE VALUE 135 | PUSH AF 136 | SET 6,A ;JOY2 137 | RES 2,A ;TRIG1 LOW 138 | LD E,A ;0V VALUE (0) IN E 139 | SET 2,A ;TRIG1 HIGH 140 | LD D,A ;5V VALUE (1) IN D 141 | .BYTELOOP: 142 | PUSH BC 143 | LD A,E 144 | .STARTBIT: 145 | OUT ($A1),A 146 | LD C,(HL) 147 | LD B,$08 148 | .BITLOOP: 149 | RRC C 150 | ;ASSUME BIT=1 151 | LD A,D 152 | JR C,.SETBIT 153 | ;NO, BIT=0 154 | LD A,E 155 | .SETBIT: 156 | ADD A,$00 ;DUMMY 157 | OUT ($A1),A 158 | DJNZ .BITLOOP 159 | LD A,E 160 | POP BC 161 | DEC BC 162 | NOP ;DUMMY 163 | ADD A,$00 ;DUMMY 164 | .STOPBIT: 165 | LD A,D 166 | OUT ($A1),A 167 | INC HL 168 | LD A,B 169 | OR C 170 | NOP ;DUMMY 171 | JP NZ,.BYTELOOP 172 | .EXIT: 173 | NOP ;DUMMY 174 | POP AF 175 | OUT ($A1),A 176 | EI 177 | RET 178 | END: 179 | -------------------------------------------------------------------------------- /rs232-86400.asm: -------------------------------------------------------------------------------- 1 | ;RECEIVING AND SENDING RS232 DATA @84600 BITS/S ON A STANDARD MSX 3.57MHz 2 | CPU Z80 3 | FNAME "86400.BIN" 4 | 5 | ;VOICEAQ: EQU $D000 6 | 7 | ;MSX .BIN HEADER 8 | DB $FE 9 | DW START, END, START 10 | 11 | ORG $D000 12 | START: 13 | 14 | ; READ BC BYTES FROM PORT TO (HL) 15 | RX: 16 | DI ; NO INTERRUPTS, TIME CRITICAL ROUTINE 17 | INC BC ; COMPENSATE LOOP (CHECK IS BEFORE ISO AFTER WRITING BYTE) 18 | LD D,B ; USE DE AS COUNTER, WE NEED C FOR IN A,(C) 19 | LD E,C 20 | LD A,$0F ; PSG REGISTER 15, SELECT JOYSTICK PORT 2 21 | OUT ($A0),A 22 | IN A,($A2) 23 | SET 6,A ; SELECT JOY2 24 | OUT ($A1),A 25 | LD A,$0E ; SET PSG #14 WE READ BIT 0 (JOY-UP) AS INPUT (RX) 0V='0',5V='1' 26 | OUT ($A0),A 27 | LD C,$A2 ; PSG READ REGISTER 28 | .FIRSTSTARTBIT: 29 | IN A,(C) ; WAIT FOR STARTBIT 30 | JP PE,.FIRSTSTARTBIT 31 | .DELAY: ; 27 CYCLES DELAY TO NEXT READ 32 | DEC DE 33 | LD A,D 34 | OR E 35 | JR Z,.EXIT 36 | .READBYTE: 37 | IN A,(C) ; BIT0 38 | RRCA 39 | RR B 40 | IN A,(C) ; 14 DUMMY CYCLES 41 | IN A,($A2) ; BIT1 42 | RRCA 43 | RR B 44 | NOP ; 15 DUMMY CYCLES 45 | NOP 46 | NOP 47 | IN A,($A2) ; BIT2 48 | RRCA 49 | RR B 50 | IN A,(C) ; 14 DUMMY CYCLES 51 | IN A,($A2) ; BIT3 52 | RRCA 53 | RR B 54 | IN A,(C) ; 14 DUMMY CYCLES 55 | IN A,($A2) ; BIT4 56 | RRCA 57 | RR B 58 | NOP ; 15 DUMMY CYCLES 59 | NOP 60 | NOP 61 | IN A,($A2) ; BIT5 62 | RRCA 63 | RR B 64 | IN A,(C) ; 14 DUMMY CYCLES 65 | IN A,($A2) ; BIT6 66 | RRCA 67 | RR B 68 | NOP ; 15 DUMMY CYCLES 69 | NOP 70 | NOP 71 | IN A,($A2) ; BIT7 72 | RRCA 73 | RR B 74 | LD (HL),B ; STORE RESULT, IGNORE STOPBIT 75 | INC HL 76 | .WAITFORSTARTBIT: 77 | IN A,(C) ;TIME OUT IF STARTBIT IS TOO LATE 78 | JP PO,.DELAY 79 | IN A,(C) 80 | JP PO,.DELAY 81 | IN A,(C) 82 | JP PO,.DELAY 83 | .EXIT: 84 | EI ; TIME-OUT, RETURN (END OR TIME-OUT, CHECK HL VALUE TO BE SURE) 85 | RET ; IF ZERO FLAG IS SET: OK, OTHERWISE TIME-OUT ERROR. 86 | 87 | ;SEND 'BC' BYTES FROM [HL] TO PIN6, JOY2 88 | ;MSX, Z80 3.58MHz 86400bps 89 | TX: 90 | DI ;NO INTERRUPTS 91 | LD A,$0F ;SELECT PSG REG #15 92 | OUT ($A0),A 93 | IN A,($A2) ;SAVE VALUE OF PSG REGISTER 94 | PUSH AF 95 | SET 6,A ;JOY2 96 | RES 2,A ;TRIG1 LOW 97 | LD E,A ;0V VALUE (0) IN E 98 | SET 2,A ;TRIG1 HIGH 99 | LD D,A ;5V VALUE (1) IN D 100 | LD C,$A1 ;WRITE REGISTER 101 | PUSH BC 102 | EXX 103 | POP BC ;MOVE BC -> BC' 104 | EXX 105 | .BYTELOOP: 106 | LD B,(HL) 107 | .STARTBIT: 108 | OUT (C),E ;STARTBIT=LOW | 109 | .BYTE: ;| 110 | RRC B ;| 111 | LD A,D ;|(42) 112 | JR C,.SETBIT0 ;| 113 | LD A,E ;| 114 | .SETBIT0: ;| 115 | OUT (C),A 116 | RRC B 117 | LD A,D 118 | JR C,.SETBIT1 119 | LD A,E 120 | .SETBIT1: 121 | OUT (C),A 122 | RRC B 123 | LD A,D 124 | JR C,.SETBIT2 125 | LD A,E 126 | .SETBIT2: 127 | OUT (C),A 128 | RRC B 129 | LD A,D 130 | JR C,.SETBIT3 131 | LD A,E 132 | .SETBIT3: 133 | OUT (C),A 134 | RRC B 135 | LD A,D 136 | JR C,.SETBIT4 137 | LD A,E 138 | .SETBIT4: 139 | OUT (C),A 140 | RRC B 141 | LD A,D 142 | JR C,.SETBIT5 143 | LD A,E 144 | .SETBIT5: 145 | OUT (C),A 146 | RRC B 147 | LD A,D 148 | JR C,.SETBIT6 149 | LD A,E 150 | .SETBIT6: 151 | OUT (C),A 152 | RRC B 153 | LD A,D 154 | JR C,.SETBIT7 155 | LD A,E 156 | .SETBIT7: 157 | OUT (C),A ;(41) TO STOPBIT 158 | EXX ;COUNTER IN BC' 159 | DEC BC 160 | LD A,B 161 | OR C ;Z-FLAG 162 | EXX 163 | .STOPBIT: 164 | OUT (C),D ;(42) TO STARTBIT 165 | INC HL 166 | JR NZ,.BYTELOOP 167 | .EXIT: 168 | LD A,$0F ;SELECT PSG REG #15 169 | OUT ($A0),A 170 | POP AF 171 | OUT ($A1),A ;RESTORE VALUE 172 | EI ;EXIT 173 | RET 174 | END: 175 | -------------------------------------------------------------------------------- /rs232.asm: -------------------------------------------------------------------------------- 1 | ;RECEIVING AND SENDING RS232 DATA @57600 BITS/S ON A STANDARD MSX 3.58MHz 2 | CPU Z80 3 | FNAME "RS232.BIN" 4 | 5 | VOICEAQ: EQU $F975 ;BUFFER TO OCCUPY IN SYSTEM AREA: DO NOT USE PLAY... 6 | 7 | ;MSX .BIN HEADER 8 | DB $FE 9 | DW START, END, START 10 | 11 | ORG VOICEAQ 12 | START: 13 | ;TRANSFER 'BC' BYTES FROM JOY2, 'UP', PIN1 TO (HL) 14 | ;MSX, Z80 3.58MHz 57600bps 15 | ;SETS CARRY BIT ON ERROR. A HOLDS ERROR CODE: 16 | ;A=1 RS232 LINE NOT HIGH,A=2 STARTBIT TIMEOUT 17 | RECBYTES: 18 | DI ;NO INTERRUPTS, TIME CRITICAL ROUTINE 19 | LD A,$0F ;PSG REGISTER 15, SELECT JOYSTICK PORT 2 20 | OUT ($A0),A 21 | IN A,($A2) 22 | SET 6,A ;SELECT JOY2 23 | OUT ($A1),A 24 | 25 | LD A,C ; FAST LOOP WITH BC (GRAUW, FAST LOOPS) 26 | DEC BC ; COMPENSATION FOR THE CASE C=0 27 | INC B 28 | LD C,B ; SWAP B AND C FOR LOOP STRUCTURE 29 | LD B,A 30 | 31 | LD A,$0E ;SET PSG #14 32 | OUT ($A0),A 33 | LD E,$01 ;FOR FASTER 'AND' OPERATION 'AND r'(5) VS. 'AND n'(8) 34 | IN A,($A2) 35 | AND E 36 | JR NZ,.FIRSTSTARTBIT ;RS232 LINE SHOULD BE HIGH, OTHERWISE STOP 37 | LD A,$01 ;ERROR, RS232 LINE NOT READY 38 | SCF 39 | EI 40 | RET 41 | ;THE NEXT PART IS TIME CRITICAL. EVERY CYCLE COUNTS 42 | .FIRSTSTARTBIT: ;WAIT FOR FIRST STARTBIT 43 | IN A,($A2) 44 | AND E 45 | JP NZ,.FIRSTSTARTBIT 46 | JP .READFIRSTBIT ;START READING BIT0, COMPENSATED FOR 12 CYCLES, 1 JP 47 | .STARTBIT: 48 | IN A,($A2) ;WAIT FOR THE HIGH->LOW TRANSITION (STARTBIT) 49 | AND E 50 | JP Z,.READBITS 51 | IN A,($A2) ;WAIT FOR THE HIGH->LOW TRANSITION (STARTBIT) 52 | AND E 53 | JP Z,.READBITS 54 | IN A,($A2) ;WAIT FOR THE HIGH->LOW TRANSITION (STARTBIT) 55 | AND E 56 | JP Z,.READBITS 57 | IN A,($A2) ;WAIT FOR THE HIGH->LOW TRANSITION (STARTBIT) 58 | AND E 59 | JP Z,.READBITS 60 | LD A,$02 ;ERROR, STARTBIT TIMEOUT 61 | SCF 62 | EI 63 | RET 64 | .READBITSNEXTBLOCK: 65 | INC HL 66 | DEC C 67 | JR NZ,.INITBITLOOP ;NEXT BLOCK UNLESS WE ARE DONE (C=0) 68 | JR .EXIT 69 | .READBITSNEXTBYTE: 70 | INC HL 71 | NOP ;DUMMY 72 | JR .INITBITLOOP 73 | .READBITS: 74 | IN A,($A2) ;DUMMY 75 | .READFIRSTBIT: ;ALT TIMING TO COMPENSATE FOR 1 JP 76 | ADD A,$00 ;DUMMY 77 | NOP ;DUMMY 78 | .INITBITLOOP: 79 | LD D,B 80 | LD B,$08 81 | .BITLOOP: 82 | INC HL ;DUMMY 83 | DEC HL ;DUMMY 84 | IN A,($A2) 85 | RRCA ;SHIFT DATA BIT (0) -> CARRY 86 | RR (HL) ;SHIFT CARRY -> [HL] 87 | DJNZ .BITLOOP 88 | LD B,D 89 | DJNZ .STARTBITNEXTBYTE ;NEXT BYTE, SKIP STOPBIT AND WAIT FOR STARTBIT 90 | NOP ;DUMMY 91 | .STARTBITNEXTBLOCK: 92 | IN A,($A2) ;WAIT FOR THE HIGH->LOW TRANSITION (STARTBIT) 93 | AND E 94 | JP Z,.READBITSNEXTBLOCK 95 | IN A,($A2) ;WAIT FOR THE HIGH->LOW TRANSITION (STARTBIT) 96 | AND E 97 | JP Z,.READBITSNEXTBLOCK 98 | IN A,($A2) ;WAIT FOR THE HIGH->LOW TRANSITION (STARTBIT) 99 | AND E 100 | JP Z,.READBITSNEXTBLOCK 101 | IN A,($A2) ;WAIT FOR THE HIGH->LOW TRANSITION (STARTBIT) 102 | AND E 103 | JP Z,.READBITSNEXTBLOCK 104 | DEC C ;POSTPONED CHECK 105 | JR Z,.EXIT ;IF C=0, WE ARE DONE SO EXIT OTHERWISE ERROR 106 | LD A,$02; ERROR STARTBIT TIMEOUT 107 | SCF 108 | EI 109 | RET 110 | .STARTBITNEXTBYTE: 111 | IN A,($A2) ;WAIT FOR THE HIGH->LOW TRANSITION (STARTBIT) 112 | AND E 113 | JP Z,.READBITSNEXTBYTE 114 | IN A,($A2) ;WAIT FOR THE HIGH->LOW TRANSITION (STARTBIT) 115 | AND E 116 | JP Z,.READBITSNEXTBYTE 117 | IN A,($A2) ;WAIT FOR THE HIGH->LOW TRANSITION (STARTBIT) 118 | AND E 119 | JP Z,.READBITSNEXTBYTE 120 | IN A,($A2) ;WAIT FOR THE HIGH->LOW TRANSITION (STARTBIT) 121 | AND E 122 | JP Z,.READBITSNEXTBYTE 123 | LD A,$02 124 | SCF 125 | EI 126 | RET 127 | .EXIT: 128 | OR A ;RESET CARRY 129 | EI 130 | RET 131 | 132 | ;SEND 'BC' BYTES FROM [HL] TO PIN6, JOY2 133 | ;MSX, Z80 3.58MHz 57600bps 134 | SENDBYTES: 135 | DI ;NO INTERRUPTS 136 | LD A,$0F ;SELECT PSG REG #15 137 | OUT ($A0),A 138 | IN A,($A2) ;SAVE VALUE 139 | PUSH AF 140 | SET 6,A ;JOY2 141 | RES 2,A ;TRIG1 LOW 142 | LD E,A ;0V VALUE (0) IN E 143 | SET 2,A ;TRIG1 HIGH 144 | LD D,A ;5V VALUE (1) IN D 145 | .BYTELOOP: 146 | PUSH BC 147 | LD A,E 148 | .STARTBIT: 149 | OUT ($A1),A 150 | LD C,(HL) 151 | LD B,$08 152 | .BITLOOP: 153 | RRC C 154 | ;ASSUME BIT=1 155 | LD A,D 156 | JR C,.SETBIT 157 | ;NO, BIT=0 158 | LD A,E 159 | .SETBIT: 160 | ADD A,$00 ;DUMMY 161 | OUT ($A1),A 162 | DJNZ .BITLOOP 163 | LD A,E 164 | POP BC 165 | DEC BC 166 | NOP ;DUMMY 167 | ADD A,$00 ;DUMMY 168 | .STOPBIT: 169 | LD A,D 170 | OUT ($A1),A 171 | INC HL 172 | LD A,B 173 | OR C 174 | NOP ;DUMMY 175 | JP NZ,.BYTELOOP 176 | .EXIT: 177 | NOP ;DUMMY 178 | POP AF 179 | OUT ($A1),A 180 | EI 181 | RET 182 | END: 183 | --------------------------------------------------------------------------------