davidgiven / cpm65

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

Fix VT52 terminal driver. #138

Open ivop opened 3 months ago

ivop commented 3 months ago

Fixes the following bugs:

Bug example: vt52-backspace-bug

Bug example: vt52-bottom-border-bug

Bug example: vt52-bottom-wrap-bug

Bug example: vt52-clear-to-eos-bug

Bug example: vt52-right-border-bug

Bug example: vt52-top-left-bs-bug

There's still one issue left, and that is that ^H should not rubout the character left of the cursor, but only move the cursor. I could add a rubout flag which is set when DEL (127) is send, similar to how ADM-3A handles this. The original CP/M actually sends ^H space ^H when the backspace key is pressed, but your CCP uses DEL, which, according to the manual, VT52 terminals ignore when echoed to the screen :wink: ADM-3A calls DEL RUB and is indeed character 127. Long story short, I could make the VT52 terminal acknowledge DEL and make ^H a proper BS, i.e. cursor left with wrap to the previous line. What do you think?

davidgiven commented 3 months ago

Mm. I didn't realise that the VT52 ignore DEL. I originally used DEL to try and simplify things. I should have known better. There are three real choices:

ivop commented 3 months ago

Meh, I had written a whole essay on terminal handling here, and I pressed backspace while in preview mode by mistake. Browser goes to previous page and everything I typed is gone :disappointed:

The end conclusion was that we should at least define how our default TTYs work and make that consistent between all ports. For example, the Apple 2e and VIC-20 do a proper old-school CR (xpos=0) and LF (ypos++,scrollup when at the bottom), but the Oric, PET, and Atari treat LF as xpos=0,ypos++,scrollup. The BBC and C64 call an OS routine for which I don't know what they do, but I expect a single character for CR/LF.

IMHO The Apple 2e and VIC-20 do it right, i.e. do exactly what CR and LF actually mean from the teletype days. The others should be changed.

On Backspace (^H): there is a distinction between what the terminal emulation does (conout) and what the keyboard input does (conin). That's also the case on the Linux command line. For example, my terminal does a destructive/deleting backspace when I press ctrl-H, but echo -e 'HELxO\010\010L' prints HELLO (non-destructive BS, i.e. cursor to the left).

IMHO conout should do what most (all?) terminals did back in the day, which is move the cursor to the left.

conin should pass ^H when backspace is pressed, even if the returned code from the host keyboard routine is different. Similar to how we used stty back in the day on Unix terminals. The Atari backspace key is 126 for example, but conin translates that.

Now the question is, what to do when 127 is send to conout? We could cheat and keep current behaviour and do rubout/erase for convenience. The downside is that when a proper terminal driver is loaded that does not know about DEL/RUB, the applications depending on that (especially CCP/BDOS) won't work correctly. That basically means that every TTY driver that should not know about DEL as per the specification should also cheat and implement DEL/RUB. This is what VT52DRV currently does.

Or we don't cheat, and CCP/BDOS should act like how CP/M 2.2 works. You press character 8, it sends 8,32,8 to conout. This is what I prefer.

Having this depend on the screen driver is a no-go IMHO, because several ports don't even have a screen driver.

To summarize, if it were my decision, I'd make CR, LF and BS behaviour match the original CP/M as closely as possible. Only CCP (BDOS readline I guess?) has to be changed. After that whatever exotic TTY driver is loaded on top of that, the command line's basic functionality stays intact.

Edit: did some edits, because I wanted what I had typed to be saved :smile:

davidgiven commented 3 months ago

I think you're right. I was originally resistant to having the backspace key return 8 because it means that application's can't distinguish between backspace and ^H; but of course, native applications which really care will be using SCREEN instead and therefore won't be going through this interface. So yes, let's simplify the TTY driver. The lowest-common-denominator of CR, LF, BS and nothing else (maybe BEL?) for TTY makes sense.

Changing the BDOS should be nigh trivial.

ivop commented 3 months ago

Great!

Regarding bell, it could be part of the SCREEN drivers (perhaps even a visual bell like xterm -vb) or of a newly created SOUND driver. Or both, i.e. that SCREEN BEL checks for a SOUND driver, and if found uses that, and if not found does a visual bell. I'll open a new issue to discuss the design of a sound driver, and also something to do proper timing (waitvb, perhaps interrupts).