freemint / m68k-atari-mint-gcc

Fork of GNU's gcc with support for the m68k-atari-mint target
https://github.com/freemint/m68k-atari-mint-gcc/wiki
Other
26 stars 7 forks source link

[question/bug?] "error opening terminal st52" when opening .tos files generated by m68k-atari-mint-gcc #33

Closed Fabrizio-Caruso closed 11 months ago

Fabrizio-Caruso commented 1 year ago

Hi!

I have compiled the C games I have written with my Cross-Lib framework (https://github.com/Fabrizio-Caruso/CROSS-LIB) by just using ncurses and nothing else.

I have installed the compiler from here: http://vincent.riviere.free.fr/soft/m68k-atari-mint/

In order to get ncurses working and avoid the error "error opening terminal st52" I have put an old st52 terminfo file in the same virtual hard disk as the .TOS files. Where can I get the correct and most up to dat st52 file to use?

Nevertheless I problem is that the keyboard is not responding at all. I remember it worked long ago when I tried with a previos version of the compiler. What am I doing wrong? The very same code can be compiled natively with GCC on a PC and it would work.

P.S.: ncurses is extremely slow (I knew it even if I don't understand why it is so sluggish). It would be nice if it could be sped up because many ASCII games and programs could be compiled straightaway without any adaptation.

th-otto commented 1 year ago

Where can I get the correct and most up to dat st52 file to use?

I dont known where you got the ncurses library from, but the one from http://tho-otto.de/crossmint.php#ncurses also contains the complete terminfo directory. There you will also find /usr/share/terminfo/s/st52 and /usr/share/terminfo/s/st52-color The source archive also contains a text file which can be compiled by tic, in case you need to make changes.

Nevertheless I problem is that the keyboard is not responding at all. I remember it worked long ago when I tried with a previos version of the compiler. What am I doing wrong? The very same code can be compiled natively with GCC on a PC and it would work.

No clue. I don't think it is a matter of the compiler, but maybe of the used libraries (ncurses and mintlib)

P.S.: ncurses is extremely slow (I knew it even if I don't understand why it is so sluggish). It would be nice if it could be sped up because many ASCII games and programs could be compiled straightaway without any adaptation.

AFAIK ncurses maintains some virtual screen, which is then updated to the physical one. I don't think that this can easily be sped up without rewriting the whole library. But maybe using Hatari and its profiler can give you a clue where the bottlenecks are.

Fabrizio-Caruso commented 1 year ago

@th-otto I am probably using the wrong compiler and the wrong ncurses. I am using the Cygwin 64 bit version done by Vincent Riviere that comes with ncurses: http://vincent.riviere.free.fr/soft/m68k-atari-mint/

Your compiler installer is not distributed with ncurses and the ncurses you linked is not supposed to be used in a cross-development environment: image

th-otto commented 1 year ago

Yes, the -bin archives have only the native atari binaries. For a cross-compiler, you have to install the devel package (https://tho-otto.de/download/mint/ncurses-6.4-mint-dev.tar.xz)

vinriviere commented 1 year ago

Hi Fabrizio. I remember we already discussed about your projects.

First, you must know that ncurses is a bad solution for plain Atari ST programs. Even if you get it to work, that will cause big (due to static linking) and slow binaries. Better solution for Atari ST text-mode programs is to use direct VT-52 escapes and system calls to output text.

ncurses exists on the Atari ST mainly to allow building UNIX/GNU/Linux software for the Atari platform, then run it in a full FreeMiNT environment (FreeMiNT is the kernel). Best emulator for that is ARAnyM (actually enhanced virtual machine). The most complete distribution was called SpareMiNT, now abandoned. Some people provide some prebuilt packages, not always usable easily. Text-mode applications can be run inside the TosWin2 terminal emulator. It can run either in tw100 mode (preferred) or tw52 (similar to plain st52).

Nowadays, there are automatic builds of the core packages. But for the UNIX stuff, I'm afraid that I don't know what's the right method to setup everything nowadays.

If you want to see how an ARAnyM/FreeMiNT environment looks like, I suggest you to have a look at that video: FreeMiNT on ARAnyM. It's quite long, but in the description you will find detailed chapters, so you can go straight to the parts you are interested. French speech, but English subtitles are available. Important: This video doesn't cover the UNIX/ncurses stuff.

By the way, if you want to persist using ncurses on plain TOS, you need to install the st52 terminal definition. Not convenient, as that's stuff designed for a POSIX system. You will find that file in ncures binary packages for MiNT. You can get either @th-otto's one, or mine from there. You can get the "68000 binary" for example. Then extract the usr/share/terminfo/s/st52 file. Rename it to unknown . Then put it on your Atari hard drive, respecting that very specific directory structure. The resulting file must be named: C:\USR\SHARE\TERMINFO\U\UNKNOWN. After that, you can run your programs. But don't expect any speed, or even accuracy.

Note: Theoretically, the right name of the file should be C:\USR\SHARE\TERMINFO\S\ST52. Unfortunately, plain TOS has no way to set the TERM environment variable, this is why I proposed to use the unknown file name instead (as default TERM when not set). Maybe, long ago, I proposed you to add putenv("TERM=st52") at the start of your program, I don't remember. By looking at your error message, that's probably the explanation.

Fabrizio-Caruso commented 1 year ago

@vinriviere Thanks for the reply. I agree with you. NCURSES is definitely not what I should use for the classic Atari ST but it should work nevertheless. Keyboard input is not working in my case. I can produce a minimal test case. NCURSES should be usable on the MINT at least. I fear that some input functions (nodelay, getch) may be broken and if they do not work on the (emulated) Atari ST, they may be broken on the MINT, as well. Or I am doing something wrong somehow.

The reason why I "insiste" with NCURSES is that my framework can compile all my games with NCURSES with zero effort from me. So it is just something to get me started on the Atari ST and Mint.

For the classic machines I need to find some time. I only need to read joystick/keyboard and draw 8x8 monochromatic tiles at 8-bit boundaries (like characters but with freely definable shapes). I need to see some examples and just do it.

th-otto commented 1 year ago

I fear that some input functions (nodelay, getch) may be broken and if they do not work on the (emulated) Atari ST, they may be broken on the MINT, as well.

If they don't work on Single-TOS, that does not mean they don't work on MiNT. Both the mintlib and the kernel try to mimic unix behaviour on tty input. For plain TOS, the situation is different. Mintlib was mainly designed to port unix tools, with quite some success. For TOS, it tries to emulate a few things, but that might be broken, or in some cases even not possible.

The reason why I "insiste" with NCURSES is that my framework can compile all my games with NCURSES with zero effort from me. So it is just something to get me started on the Atari ST and Mint.

Yes, thats understandable, and indeed it should work on mint atleast. But don't expect performance wonders from this. As Vincent suggests, it may be better to "port" those applications, even if that requires more effort. It will depend upon which curses features are used. As long as there are only calls to position the cursor, clear the screen etc. that should be rather easy. If they use more advanced features like using separate curses windows or panels, then you may better stick to ncurses.

Maybe you post a link to an examples that you are trying to compile with ncurses?

Fabrizio-Caruso commented 1 year ago

@th-otto ideally for me it would be nice if it worked (even very slowly) on the Atari ST.

Any way, below you find a minimal example that mimics what my games do and that shows the issue on an emulated classic Atari ST (I don't know how to test it on a Mint without a real Mint because I am not sure there is any emulator):

#include <ncurses.h>
#define _NCURSES_BACKGROUND_COLOR COLOR_BLACK

int main(void)
{
    volatile unsigned char ch;

    #if defined(__ATARI_ST__)
        putenv("TERM=st52");
    #endif
    initscr();   
    noecho();
    curs_set(0);
    start_color();
    cbreak();
    intrflush(stdscr, TRUE);
    init_pair(1, COLOR_YELLOW, _NCURSES_BACKGROUND_COLOR);
    init_pair(2, COLOR_CYAN, _NCURSES_BACKGROUND_COLOR);
    init_pair(3, COLOR_RED, _NCURSES_BACKGROUND_COLOR);
    init_pair(4, COLOR_GREEN, _NCURSES_BACKGROUND_COLOR);
    init_pair(5, COLOR_BLUE, _NCURSES_BACKGROUND_COLOR);
    init_pair(6, COLOR_WHITE, _NCURSES_BACKGROUND_COLOR);
    init_pair(7, COLOR_MAGENTA, _NCURSES_BACKGROUND_COLOR);
    init_pair(8, COLOR_BLACK, _NCURSES_BACKGROUND_COLOR);

    wbkgd(stdscr, COLOR_PAIR(1));   
    nodelay(stdscr,TRUE);    
    refresh();

    move(0,0);
    while(1)
    {
        ch = getch();      
        if(ch=='i' || ch=='k')
        {
            printw("%c", ch);
        }
        refresh();
    }
    return 0;
}

If compiled with gcc ./debug/ncurses_test.c -lncurses you get the correct behavior, i.e., it detects i and k key presses with auto-repeat. For example this works with gcc targeting the native machine or cygwin.

If the code above is cross-compiled with m68k-atari-mint-gcc ./debug/ncurses_test.c -lncurses -D__ATARI_ST__ then no key press is detected (tested on an emulated Atari ST with Hatari).

I wonder whether volatile is implemented. Isn't it?

vinriviere commented 1 year ago

I wonder whether volatile is implemented. Isn't it?

volatile is implemented and useless in this case.

BTW, I tested your testcase, and there's indeed a problem. For unknown reason, getch() doesn't return. It is actually implemented as wgetch(), which stays in an infinite loop. I saw that in the MonST2 debugger.

Now here is speculation. I guess that the infinite loop is that code (not exact code, as I provide ncurses 5.9 with the mint toolchain): https://github.com/mirror/ncurses/blob/87c2c84cbd2332d6d94b12a1dcaf12ad1a51a938/ncurses/base/lib_getch.c#L442-L666

I can't say more. That would require more debugging inside ncurses. But definitely, the problem is inside wgetch(). And I quickly tried ncurses 6.4 with the new mintelf toolchain, it fails equally.

Fabrizio-Caruso commented 1 year ago

@vinriviere thanks for reporting this. This is good news. At least we know it is a bug.

On a different topic: where can I find examples on how to use C (no or as little Assembly as possible) to code for the vanilla Atari ST?

For text only mode, could I just use stdio.h with escape sequences to position the cursor and clear the screen? Which escapes? VT52, VT100 or ADM3A or something else? What about reading the keyboard (with auto-repeat) and/or the joystick? Are there system calls capable to poll the keyboard with auto-repeat and/or the joystick?

For tile-based graphics (basically bitmap but with 8x8 tiles at 8-pixel boundaries), what would you suggest? For example something as simple as enabling low resolution with a 3 or 4 bit-planes and drawing a monochromatic 8x8 block somewhere on the screen.

mikrosk commented 1 year ago

Reading your post on atari-forum.com I'd say that what you want is definitely not possible with VT52 codes (it's really, really slow; to give you some idea, look at: https://youtu.be/ImtEBebXdd4?si=gSZUE5hVE0aImRgL&t=30)

For the other points, I'd definitely suggest some reading about Atari ST architecture, ST's bitplanes are nowhere near the flexibility you'd need for a game coded in C, assembly routines are a must and even those have to be cleverly coded.

Fabrizio-Caruso commented 1 year ago

@mikrosk the video you have linked is even too fast for my purposes.

My games run on ZX81 and do not require fast routines. I do not need scrolling or smooth movements.

I am doing this on 200 targets mostly 8-bit at speeds between 0.5mhz and 4mhz in C. You can take a look at the kind of games I can build with my Cross-Lib framework: https://github.com/Fabrizio-Caruso/CROSS-LIB

For the so-called tiles I just need to write the very same data on 3 bitplanes (or 4 bitplanes in the future) because my tiles are monochromatic and each tile can have just one foreground out of 8 and speed is not a concern. I am not going to use interrupts or any other kind of synchronization. My games just run on a main loop and the game code has to take care of having a speed that does not vary too much.

I am looking for C examples (inline Assembly in C is OK) that do things like: setting up low resolution with 3 bit-planes, the palette and draw an 8x8 block on the screen, reading the joystick/keyboard, producing a beep, a burp and some random noise.

th-otto commented 1 year ago

For text only mode, could I just use stdio.h with escape sequences to position the cursor and clear the screen? Which escapes? VT52, VT100 or ADM3A or something else?

You could use stdio.h, but better might be to output the esacpe sequences directly, using Bconout() or Cconout(). The VDI uses a VT52 emulation, VT100 is only used by Toswin2 on MiNT.

For the tiles, you might want to look at vrt_cpyfm(). That copies a monochrome input to the screen.

Fabrizio-Caruso commented 1 year ago

@th-otto thanks a lot! It looks like what I need, indeed. I don't need speed. I just need something faster than current ncurses. I am basically reproducing an abstract and slow 8-bit computer in Cross-Lib.

What do I need to include to have those functions? Where are they documented? Are these functions part of stilibs4cc? (https://github.com/simonsunnyboy/stlibs4gcc)

I am currently using the compiler cygwin 64-bit package by @vinriviere. Can I use his version or do I need to switch to yours?

th-otto commented 1 year ago

Bconout is documented at https://freemint.github.io/tos.hyp/en/About_the_BIOS.html#Bconout,and Cconout at https://freemint.github.io/tos.hyp/en/gemdos_chrinout.html#Cconout. Bconout(2, c) is essentially the same as Cconout(c), unless you redirect standard output (in that case, Bconout(2, c) still goes to the screen). Both functions only need an include <osbind.h> when using gcc, but no libraries since they are inlined. There is also a list of the VT52 escape sequences at https://freemint.github.io/tos.hyp/en/VT_52_terminal.html

vrt_cpyfm is documented at https://freemint.github.io/tos.hyp/en/vdi_raster.html#vrt_cpyfm. For that you need to include <gem.h>, and link with -lgem. As with all VDI functions, that also requires you to open a virtual workstation first using https://freemint.github.io/tos.hyp/en/vdi_control.html#v_opnvwk (and close it using https://freemint.github.io/tos.hyp/en/vdi_control.html#v_clsvwk when the program exits). I hope there are some simple examples on the net somewhere which explain how to do that.

You can use any compiler version you want, they should behave the same. Just make sure that all needed libraries are installed (should be only mintlib, maybe fdlibm and gemlib in this case).

Fabrizio-Caruso commented 1 year ago

@th-otto Thanks! I will see if I can get something working and integrate it into my build chain.

What can I use to poll the keyboard ? Will getch in ncurses be fixed? Cconin cannot be used for games as getch because it waits for the input.

th-otto commented 1 year ago

You can use Bconstat() prior to calling Bconin() to check whether a character is available, or Crawio(0xff)

Fixing ncurses requires a deeper analysis of the problem. Most likely, it is just something that is not supported in mintlib without mint running.

mikrosk commented 11 months ago

Closing as resolved.