davidgiven / cpm65

CP/M for the 6502
BSD 2-Clause "Simplified" License
264 stars 24 forks source link

Terminal emulator with VT52 support and Xmodem send/receive + vt52driver #103

Closed venomix666 closed 7 months ago

venomix666 commented 7 months ago

I wrote a small terminal emulator CP/M-65 with VT52 emulation and Xmodem file send and receive functionality. It works well enough to login to a linux machine and run vim (when the shell is properly setup for VT52 and the correct numbers of lines and columns), and it is possible to do in-session file transfer to and from the linux machine to the CP/M-65 machine using sx/rx on the linux side.

It would be handy with defined constants for arrow keys in the screen driver to allow sending arrow-keys over VT52 instead of manually punching ESC-A to get the previous command ;)

I made a small wrapper function for serial_inp in order to allow checking if there is available data, and still accepting 0x00 as valid data, from C. Otherwise I just made a straight mapping to all functions in the serial driver.

A known issue is that files are sometimes corrupted in both directions if several Xmodem transfers are made sequentially, I am currently looking into that.

I added a vt52driver (+ a tester application) as suggested by @ivop so that other applications also can use the vt52 capability.

ivop commented 7 months ago

Nice work! If you turn the VT52 code into a TTY driver that sits on top of the BIOS TTY and SCREEN drivers, it'll open up VT52 capabilities for other programs, too. I think that's how David intended the driver model to be used. Similar to how the Atari 80 columns driver works.

Kind regards, Ivo

venomix666 commented 7 months ago

Nice work! If you turn the VT52 code into a TTY driver that sits on top of the BIOS TTY and SCREEN drivers, it'll open up VT52 capabilities for other programs, too. I think that's how David intended the driver model to be used. Similar to how the Atari 80 columns driver works.

Kind regards, Ivo

Hi Ivo,

That is an interesting idea, thanks. I will look into how the loadable drivers are written. I think it should be enough to do something similar to the caps-driver which only replaces TTY_CONOUT.

Best regards, Henrik

iss000 commented 7 months ago

Well done and congrats, @venomix666! Q: what would be more "cmp-ish" to implement a serial setup functionality (i.e. set baud, bits, parity etc.):

venomix666 commented 7 months ago

Well done and congrats, @venomix666! Q: what would be more "cmp-ish" to implement a serial setup functionality (i.e. set baud, bits, parity etc.):

  • put it in BIOS and extend the jump table with one more function or
  • create standalone utility which will be run before the actual communication program (for instance vt52term)? I'm playing with Oric and I have already working code for MOS6551 and MC6850 serial chips but just want to follow as much as possible the "standard" way if any. Happy and prosperous 2024! iss

Thanks!

That's a good question. I am not very familiar with how things are usually done in CP/M, but in drivers.inc it is noted that SERIAL_OPEN takes flags as arguments in XA - I assumed that the idea here is to define a set of flags for baudrates, start/stop bits etc, so that the port settings are configured when you open the port. This way, it would be portable between different machines and UART-chips. I think David may have better input here?

A happy 2024 to you too! /Henrik

davidgiven commented 7 months ago

Thank you --- that's really useful.

My vague thought regarding drivers was that you could install the VT52 terminal driver, then programs could use VT52 escape sequences and they'd Just Work. So the terminal app wouldn't need to know anything about the terminal; it'd just pass stuff back and forth to the TTY driver. The downside is that changing the terminal emulation would require rebooting the system, as there's no way to unload a driver.

However, given that there's no actual software for CP/M-65, I don't know if that's actually useful --- there's nothing which needs VT52 escape sequences. Maybe a better option would be for the VT52 driver to install a specific VT52 TTY-like device. I'm open to suggestions here.

Regarding SERIAL: yes, the flags for the open opcode are supposed to set format and baud rate, but I hadn't specified those yet. One issue is that it'd be good to have a way to distinguish between multiple SERIAL drivers. Maybe reserving a range of driver IDs, one per port?

venomix666 commented 7 months ago

Thank you --- that's really useful.

My vague thought regarding drivers was that you could install the VT52 terminal driver, then programs could use VT52 escape sequences and they'd Just Work. So the terminal app wouldn't need to know anything about the terminal; it'd just pass stuff back and forth to the TTY driver. The downside is that changing the terminal emulation would require rebooting the system, as there's no way to unload a driver.

However, given that there's no actual software for CP/M-65, I don't know if that's actually useful --- there's nothing which needs VT52 escape sequences. Maybe a better option would be for the VT52 driver to install a specific VT52 TTY-like device. I'm open to suggestions here.

That is the way the driver is written now, i.e. taking over the TTY driver's conout. I also have VT52-parsing code in the terminal application as I wrote this before making the driver, but that is simple to remove (and rename the terminal application) if a separate driver is the preferred approach. The main benefit I see with having at VT52 driver is that you could use the SCREEN driver from BASIC by printing VT52 escape sequences (if it is possible to print the escape key from Altirra BASIC?). The drawback as you mention is that you would have to reboot to unload it.

One use case that I see is logging in to a linux machine, editing some C-code, cross compiling and downloading the binary with Xmodem to run it. In this case you will have 4 pages less TPA available after using the terminal emulator as the VT52 driver is still resident in memory, so just having the VT52 being part of the terminal application makes more sense in this case.

How hard would it be to make it possible to unload loadable drivers?

Regarding SERIAL: yes, the flags for the open opcode are supposed to set format and baud rate, but I hadn't specified those yet. One issue is that it'd be good to have a way to distinguish between multiple SERIAL drivers. Maybe reserving a range of driver IDs, one per port?

I think reserving a range of driver IDs would work fine. Then you could either scan through these when you start an application using serial ports, or have the user specify the port as a command line argument. I think supporting 4 serial ports (like the fixed IO addresses of COM-ports in IBM PCs) would cover most hardware configurations, but there is no shortage of driver IDs so you could as well support a much larger number of ports if you think that it is useful.

davidgiven commented 7 months ago

The issue with unloading drivers is that they have to be unloaded in reverse order. (Also, there'd need to be functionality to tell them to unload themselves, which currently there isn't.)

I've wondered whether it might be feasible or desirable to extend the device driver model into something like CP/M 3's RSX files, where you'd bind a driver to an application and then load them both together, GSX-like, but that feels like it's getting a bit too shared-library like and while something like that would be cool I think it belongs in the application layer.