From vice-emu
Jump to: navigation, search

here i will track some things regarding rs232 emulation, and perhaps fix things while at it. It may also serve as documentation on how all those RS232 things work. Gpz (talk) 19:29, 25 July 2019 (CEST)

  • for all first tests i will use some version of CCGMS, and regular user-port rs232 emulation at 2400 baud.
  • for ACIA tests i will use novaterm or striketerm.
  • if not explicitly testing two instances of VICE, i will use cgterm as the "calling" end


I need more / better testcases. Right now i am using CCGMS, but that will hardly do for more than a few basic checks. what i am looking for is:

  • some (terminal?) program that shows the various modem control lines (dtr/dtd rts/cts CD etc) on screen in realtime
  • a minimal c*base setup that lets me reproduce c*base related bugs
    • detailed description of the supposed problems with c*base
  • other problematic programs/scenarios
  • all of the above pre-configured for a) a standard userport modem at 2400 baud and b) a swithlink at something like 38400 baud

To make this page more complete, more examples of real-world usecases would be nice.


To reproduce what is explained below, a few C64 programs and some host utilities are needed.


  • CCGMS (if you are familiar with another terminal program, that will do just as good)


  • socat (Windows binaries)
  • tcpser (use the FozzTexx fork until the changes are merged back into jim brains repo)
  • recent VICE binaries. You can find Windows nightly builds here. Sometimes we will upload experimental Windows binaries here.
  • cgterm

using a real RS232 port

This works by using the device name of your OS, VICE uses physical RS232 ports.


RsUserEnable = 1
RsUserBaud = 2400
RsUserDev = 1
RsDevice1 = /dev/ttyUSB0
RsDevice1Baud = 2400

status: working out of the box


RsUserEnable = 1
RsUserBaud = 2400
RsUserDev = 1
RsDevice1 = com6
RsDevice1Baud = 2400
  • the windows driver understands various options passed in the so called "mode string" after a colon after the ports name
  • finding out what COM port the usb adapter ended up might be tricky, you can use a tool like "Keyspan Serial Assistant"

status: working after some massaging of the code

rs232 over ip

This works by using the IP and port you are connecting to, VICE will use a TCP socket.

TODO: check if DNS lookup works ([ Domain name support in RS-232 settings})

connect two VICE instances on the same host

$ socat tcp-listen:25232 tcp-listen:25231

config instance #1

RsUserEnable = 1
RsUserBaud = 2400
RsUserDev = 2
RsDevice2 =
RsDevice2Baud = 2400

config instance #2

RsUserEnable = 1
RsUserBaud = 2400
RsUserDev = 2
RsDevice2 =
RsDevice2Baud = 2400


status: works


status: works

connect two VICE instances on different hosts

status: untested

piping to an external program

This is the unix way to talk to external programs.

Piping will be used when the first character of the device "file" name is a "|" (pipe) character.

Note: when the external program is netcat (or "nc") without further options, the result is equivalent to using "rs232 over ip" as described above.


"calling" a telnet BBS

$ tcpser -v 25232 -p 6400 -s 2400 -l 4
RsUserEnable = 1
RsUserBaud = 2400
RsUserDev = 4
RsDevice4 = |nc 25232
RsDevice4Baud = 2400



status: works


status: not implemented

TODO: a windows replacement for arch/shared/coproc.c:fork_coproc() must be implemented (this is non trivial unfortunately) and then hooked up in rs232-win32-dev.c in the same way it is on unix. once done define grep for COPROC_SUPPORT and adjust the respective places (preferably removing it)

some pointers:


  • the code is somewhat prepared
  • we should probably create another thread which monitors the launched external process, closes the pipes when the child dies, and perhaps other things


  • whether the "UP9600" (daniel dallmann) hack is being used seems to depend on the baudrate(?). this should be a seperate option

driver issues

  • handling of DTR and RTS seems to be completely missing. rs232dev_set_status, rs232dev_get_status, rs232dev_set_bps apparently are not called by the layer above
this is partially solved for IP connections

user interface

  • a couple of typical rs232 settings should probably be configurable for at least "real rs232 port at host". (behavior of DTR, RTS...)

ip232 protocol support

This is the protocol introduced by some modified WinVICE 1.19 to talk to tcpser.

tcpser->vice ip232.c:ip232_write

0xff nn ->
 nn = 0      DCD = false     
 nn = 1      DCD = true
 nn = 255    literal 0xff
other   ->   unchanged

vice->tcpser ip232.c:ip232_read

0xff nn ->
 nn = 0      DTR = false      note: the original patch sends 0 on rs232 reset
 nn = 1      DTR = true       note: the original patch sends 1 on rs232 connection established
 nn = 255    literal 0xff
other   ->   unchanged

TODO: (optionally!) support this protocol

NOTE: this is partially implemented now

  • userport handles DCD

TODO: fix userport DTR, fix ACIA, more testing


tcpser seems to be buggy too:

  • when sending 0xff, x the respective codes appear in the output. this should not happen, they should directly translate into DTR status. when using an IP connection DTR=0 should disconnect.
    • even worse, that sequence is also echoed, which causes it to be interpreted by the ip232 "user"
  • somehow using the common "+++",delay,"ATH" doesnt disconnect the "modem" when using ip232


driver stack

rsuser.c                   -> rs232drv.c              -> rs232.c              -> shared/rs232dev.c
rsuser_read_ctrl (WIP)        rs232drv_set_status (ok)   rs232_set_status (ok)   rs232dev_set_status (TODO)
rsuser_write_ctrl (WIP)       rs232drv_get_status (ok)   rs232_get_status (ok)   rs232dev_get_status (TODO)
aciacore.c                                                                       rs232net.c
acia_get_status (ok)                                                             rs232net_set_status (WIP)
acia_set_handshake_lines (ok)                                                    rs232net_get_status (WIP)