VolksForth/8086/msdos/serial.fb
2021-04-11 13:43:39 +02:00

1 line
22 KiB
Plaintext

\ Serial interface for IBM-PC using 8250 chip cas 11nov05 INCLUDE SERIAL.FB will load code for COM1, 2 LOADFROM SERIAL.FB for COM2 Bytes recieved will be buffered in a 128 Byte deep Queue by an interrupt Routine. The DTR Line will be used to signal that new bytes can be recieved. The Sender will recognize CTS, a full Handshake is implemented Xon/Xoff Protocoll using ^S/^Q is _not_ implemented. Sender: TX? ( -- f ) TX ( -- char ) Empf„nger: RX? ( -- f ) RX ( char -- ) \ Driver for IBM-PC Serial card using 8250 cas 11nov05 Onlyforth \needs Assembler 2 loadfrom asm.fb cr .( COM1: ) | $C 4 * Constant SINT@ \ absolute loc. of serial interrupt $3F8 >label Portadr | $10 Constant I_level \ 8259 priority 2 7 +thru \ Driver for IBM-PC Serial card using 8250 cas 11nov05 Onlyforth \needs Assembler 2 loadfrom asm.fb cr .( COM2: ) | $B 4 * Constant SINT@ \ absolute loc. of serial interrupt $2F8 >label Portadr | 8 Constant I_level \ 8259 priority 1 6 +thru \ Driver for IBM-PC Serial card using 8250 ks 11 mai 88 \ 3 .( 38.4 kbaud ) \ &6 .( 19.2 kbaud ) &12 .( 9.6 kbaud ) \ &24 .( 4.8 kbaud ) \ &96 .( 1200 baud ) >label baud $20 >label I_ctrl $21 >label I_mask \ 8259 addresses Create Queue 0 , $80 allot \ 0 1 2 130 byte address \ | len | out |<-- 128 byte Queue -->| \ len ::= number of characters queued \ out ::= relativ address of next output character \ (len+out)mod(128) ::= relative address of first empty byte \ transmit to 8250 ks 11 dez 87 Code tx? ( -- f ) D push Portadr 5 + # D mov D in D D xor $1020 # A and $1020 # A cmp 0= ?[ D dec ]? Next end-code Code tx ( c -- ) D- A- xchg Portadr # D mov D byte out D pop Next end-code Code -dtr D push Portadr 4 + # D mov D byte in $1E # A- and D byte out D pop Next end-code Code +dtr D push Portadr 4 + # D mov D byte in 1 # A- or D byte out D pop Next end-code \ receive queue and interrupt service routine ks 11 dez 87 Label S_INT D push I push A push Portadr # D mov D byte in A- D+ mov Queue # I mov C: seg I ) A mov A- D- mov D- inc C: seg D- I ) mov A+ A- add $7F # A and A I add C: seg D+ 2 I D) mov $68 # D- cmp CS not ?[ Portadr 4 + # D mov D byte in $1E # A- and D byte out ]? \ -DTR $20 # A- mov I_ctrl #) byte out \ EOI for 8259 A pop I pop D pop iret end-code \ rx? rx ks 30 dez 87 Code rx? ( -- f ) D push D D xor Queue #) D- mov D- D- or 0= ?[ [[ D push Portadr 4 + # D mov \ +DTR D byte in 9 # A- or D byte out D pop swap ]? Next end-code Code rx ( -- 8b ) I W mov Queue # I mov D push D D xor cli lods A- A- or 0= not ?[ A+ C- mov A- dec A+ inc $7F # A+ and A -2 I D) mov D- C+ mov C I add I ) D- mov ]? sti W I mov $18 # A- cmp CS not ?] Next end-code \ Serial initialization ks 25 apr 86 | Code S_init D push D: push A A xor A D: mov C: A mov SINT@ # W mov S_INT # W ) mov A 2 W D) mov D: pop Portadr 3 + # D mov $80 # A- mov D byte out \ DLAB = 1 2 # D sub baud # A mov A- A+ xchg D byte out D dec A- A+ xchg D byte out \ baudrate 3 # D add $A07 # A mov D out \ 8bit, noP, +RTS +OUT 2 # D sub 1 # A- mov D byte out \ +rxINT I_mask #) byte in I_level Forth not Assembler # A- and I_mask #) byte out D pop Next end-code \ init bye ks 11 dez 87 \needs init : init ; : init init Queue off S_init ; init : bye 0 [ Portadr 1+ ] Literal pc! \ -rxINT 0 [ Portadr 4 + ] Literal pc! \ -dtr/-rts/-out2 I_mask pc@ I_level or I_mask pc! bye ; \ dumb terminal via 8250 ks 11 dez 87 Variable Fkeys Fkeys on | : ?rx ( -- ) pause rx? 0=exit rx Fkeys @ 0= IF emit ?cr exit THEN #LF case? IF cr exit THEN #CR case? IF Row 0 at exit THEN #BS case? IF del exit THEN emit ; | : ?tx ( c -- ) BEGIN ?rx tx? UNTIL tx ; : dumb BEGIN BEGIN ?rx key? UNTIL key $1B case? IF -dtr exit THEN ?tx REPEAT ;