I don't think there was a standard terminal with CP/M, the VT100 was widely used but was not the most popular.. it was the applications adapting to the ESC sequences.
Ok so we will probably have to do the same.. specify ESC sequences in the target configuration file. I've been trying to think of how to accommodate the different hardware on cpm machines and I think the way to do it is to set up defines in the target configuration file that are activated (in an IF..ENDIF) after selecting a specific machine.
I think I have a good way to deal with cpm and its many different targets and terminals.
For +cpm I think we stick mainly to cpm-only features maybe with some easy stuff thrown in. I am looking at the apple2 softcard as an example where the z80 address space is mapped to the 6502 address space and it has access to the machine's memory mapped io and display. For example we can easily do audio which I think is fine for the cpm target. But graphics and related I am thinking that a separate +apple2 target is in order. For any cpm-addons I think the best way is to specify an additional library on the command line:
zcc +cpm -vn -clib=new test.c -o test -lcpm/apple2
(the directory in the library name can help keep the library directory organized)
For terminals, there are two things going on. One is software emulation of tty types and the other is the actual hw tty that characters are being sent to.
The terminal drivers in the new clib have a hook that can allow software tty emulation in their 'putchar' function; the simple cpm driver is short:
cpm_01_output_dcio_oterm_msg_putc:
; enter : c = char to output
; can use: af, bc, de, hl
; char to print is coming from stdio
bit 5,(ix+6)
jr z, cooked ; if cook is disabled
; tty emulation is enabled
ld a,OTERM_MSG_TTY
call l_jpix ; carry reset if tty absorbed char
ret nc ; if tty absorbed char
ld a,c
cp CHAR_BELL
jr nz, cooked
putchar_bell:
ld a,OTERM_MSG_BELL
jp (ix)
cooked:
cpm_01_output_dcio_oterm_msg_putc_raw:
; c = ascii code
bit 4,(ix+6)
jr z, crlf_done ; if not processing crlf
ld a,c
cp CHAR_CR
ret z ; ignore cr
cp CHAR_LF
jr nz, crlf_done
; send cr+lf
ld c,13
call crlf_done ; send cr
ld c,10
crlf_done:
; c = ascii code
ld e,c
ld c,__CPM_DCIO ; bdos direct i/o
jp asm_cpm_bdos_alt
If the cook flag is set, an "OTERM_MSG_TTY" message is generated for the output char that gives the software a chance to consume it in a tty state machine. The only tty type currently available (in the new clib) is a "z88dk terminal" which is proof of concept but this method can be used to do, eg, vt100 or vt52 emulation. If a character sequence for setting cursor position is consumed, the tty emulation looks up a subroutine to call to set the cursor coordinates.
The other side is the hw tty that characters are being sent to and how the library is going to perform actions like set cursor, clear screen, scroll, etc that it is being asked to do. Unix has termcaps but that's not what we want because it's a huge database. Instead I think we can introduce subroutines for each terminal type that takes the same parameters and accomplishes some function like set cursor position. Then we link to the specific terminal type on the command line.
Eg: a vt100 terminal and a vt52 terminal might implement functions to set cursor position and clear screen. Then they would have two subroutines each in the library:
asm_term_vt100_clear_screen:
...
asm_term_vt100_set_cursor:
...
asm_term_vt52_clear_screen:
...
asm_term_vt52_set_cursor:
...
All drivers would have to supply the same means to send or return the necessary escape sequence.
All terminal functions would be in every target's library. The extra link in the compile line:
zcc +cpm -vn -SO3 -clib=sdcc_iy test.c -o test -lterm/vt100
Would connect to a library compiled solely of defines:
defc asm_term_clear_screen = asm_term_vt100_clear_screen
defc asm_term_set_cursor = asm_term_vt100_cursor
Then the library drivers would just call the generic names and, there you go, you can compile for any terminal type with only the terminal-type code included in the binary.
By having all the terminal code in the library you could still write drivers or code for more than one terminal type by using the terminal-specific names so it would still be possible to write drivers targetting specific drivers and be able to drive more than one terminal in the same program.
------------------------------------------------------------------------------