Test Program for Screen Mode switching using console_ioctl()

Other misc things
Post Reply
User avatar
RobertK
Well known member
Posts: 347
Joined: Mon Feb 26, 2018 12:58 pm

Test Program for Screen Mode switching using console_ioctl()

Post by RobertK »

I have now cleaned up my little test program for screen mode switching using console_ioctl(), so here it is. @Dom: you may publish it on a repo or wherever.

When testing a new target, you only need to define MODE_GRAPHICS and MODE_TEXT (unless the standard values can be used), and DO_NOT_USE_CLG where necessary.

The test results are as follows:

Galaksija Plus: all ok
Laser 500: broken screen after switching back to text mode
MC-1000: all ok
NEC PC-6001 Mk2: all ok
Samsung SPC-1000: broken screen after switching back to text mode
Tiki-100: all ok

Could you please check the Laser 500 and the SPC-1000?

Are there more targets that use console_ioctl() screen mode switching? Please list them here, or try them out yourself.

Code: Select all

/*
        smt.c - Screen Mode Test
        Test program for screen mode switching using console_ioctl()
        Author: RobertK, 2019-01-19

        Compile with:
        zcc +gal -subtype=galaxyp -create-app -pragma-redirect:fputc_cons=fputc_cons_generic -pragma-redirect:CRT_FONT=_font_8x8_bbc_system -o smtgalplus smt.c -D__GALPLUSHIRES__
        zcc +laser500 -pragma-redirect:CRT_FONT=_font_8x8_bbc_system smt.c -o smt -create-app -Cz--audio -Cz--fast
        zcc +mc1000 -pragma-redirect:fputc_cons=fputc_cons_generic -pragma-redirect:CRT_FONT=_font_8x8_bbc_system -create-app -Cz--audio smt.c -o smt_mc1000
        zcc +pc6001 -subtype=rom -pragma-redirect:fputc_cons=fputc_cons_generic -pragma-redirect:CRT_FONT=_font_8x8_bbc_system -create-app -o smt_pc6001Mk2 smt.c
        zcc +spc1000 -create-app -pragma-redirect:CRT_FONT=_font_8x8_bbc_system smt.c -o smt
        zcc +cpm -subtype=tiki100 -ltiki100 -create-app -pragma-redirect:fputc_cons=fputc_cons_generic -o SMT.COM smt.c

*/

#include <stdio.h>
#include <graphics.h>
#include <sys/ioctl.h>                // required for switching the screen mode

// Define graphics mode number
#if defined(__LASER500__)
        #define MODE_GRAPHICS 2
#else
        #define MODE_GRAPHICS 1        // Standard value if not defined otherwise
#endif

// Define text mode number
#if defined(__TIKI100__)  // Tiki-100 (also known as "Kontiki-100")
        #define MODE_TEXT 2
#else
        #define MODE_TEXT 0         // Standard value if not defined otherwise
#endif

// Some systems do not support clg()
#if defined(__SPC1000__) || defined(__GAL__) || defined(__LASER500__)
        #define DO_NOT_USE_CLG 1
#endif
                                                        
void myCls()        // Clear the screen (generic or VT100 console)
{
        printf("%c",12);
        printf("\x0c");  // the "\x0c" (0x0c character) resets the cursor position to the top left corner
}

void main()
{        
        int XScreenSize,YScreenSize;                // dimensions of the text screen
        int xMax,yMax;                                                // dimensions of the graphics screen
        int mode; // for screen mode switching
        int x,y;        
        char c; // for keyboard input
        int exitProgram=0;        
                
        // determine text screen size
        screensize(&XScreenSize, &YScreenSize);
        
        /* main loop */
        while(exitProgram<1)
        {
                // Text screen
                myCls();        // Clear the screen
                
                // Draw a screen border using the character "x"
                for (x = 0; x <XScreenSize; ++x)
                {
                        gotoxy(x,YScreenSize-1);
                        printf("x");
                        gotoxy(x,0);
                        printf("x");
                }
                for (y = 1; y <YScreenSize; ++y)
                {
                        gotoxy(0,y);
                        printf("x");
                        gotoxy(XScreenSize-1,y);
                        printf("x");
                }
                
                gotoxy(2,2);
                printf("text screen test");
                gotoxy(2,4);
                printf("screen size: x=%d, y=%d\n",XScreenSize,YScreenSize);
                gotoxy(2,6);
                printf("press x to exit, any");
                gotoxy(2,7);
                printf("other key to switch");
                gotoxy(2,8);
                printf("to graphics mode...");
                c = fgetc_cons();        // wait for keypress        
        
                if (c=='x' || c=='X')
                        exitProgram=1;
                else
                {
                        // Graphics Screen
                        // switch to graphics mode
                        mode = MODE_GRAPHICS;
                        console_ioctl(IOCTL_GENCON_SET_MODE, &mode);
                        #if !defined(DO_NOT_USE_CLG)
                                clg();
                        #endif
                        myCls();        // Clear the screen
                        
                    // determine the screen dimensions for this system
                    // coordinates go from 0 to this max value
                    xMax=getmaxx();
                    yMax=getmaxy();
                  
                        // Draw a screen border
                        for (x = 0; x <=xMax; ++x)
                        {
                                plot(x,yMax);
                                plot(x,0);
                        }
                        for (y = 1; y <=yMax; ++y)
                        {
                                plot(0,y);
                                plot(xMax,y);
                        }
                        
                        gotoxy(2,2);
                        printf("graphics screen test");
                        gotoxy(2,4);
                        printf("screen size: x=%d, y=%d\n",xMax+1,yMax+1);
                        gotoxy(2,6);
                        printf("press x to exit, any");
                        gotoxy(2,7);
                        printf("other key to switch");
                        gotoxy(2,8);
                        printf("to text mode...");
                        c = fgetc_cons();        // wait for keypress        
                        if (c=='x' || c=='X') exitProgram=1;                        
                
                        // switch back to text mode
                        mode = MODE_TEXT;
                        console_ioctl(IOCTL_GENCON_SET_MODE, &mode);
                }
                
        }
        myCls();        // Clear the screen        
        return;
}
User avatar
dom
Well known member
Posts: 2072
Joined: Sun Jul 15, 2007 10:01 pm

Post by dom »

Great, thanks for another test program!

The following machines supporting screen modes:

* Alphatronic
* Microbee
* CPC
* Einstein
* FP-1100
* Galaksija
* Laser 500
* MC1000
* Multi8
* MZ2500
* PC6001
* PC88
* SPC1000
* Tiki100

Some of them will be 40/80 column switches. I'm also working on the Sony SMC-70/SMC-777 which will support them as well.
User avatar
dom
Well known member
Posts: 2072
Joined: Sun Jul 15, 2007 10:01 pm

Post by dom »

Laser 500 is corrected - graphics mode wasn't being turned off.

The SPC-1000 is more interesting and I have a memory of discussing it before.

The 6847 has a concept of extended characters, whereby character codes in a certain range will be pulled out of RAM rather than the mask ROM. It looks like on the SPC-1000 the ROM copies the font into VRAM on startup. With mode 1, all 6k of the VRAM is used and this overwrites the copied font - in particular the lower case characters which is why nothing apart form dots appears on screen.
stefano
Well known member
Posts: 2137
Joined: Mon Jul 16, 2007 7:39 pm

Post by stefano »

while you're on it, have a look at the updated spritest.c demo. where bkrestore() is emulated it will flicker a lot, but the copy/paste trick is very nice, imho
User avatar
RobertK
Well known member
Posts: 347
Joined: Mon Feb 26, 2018 12:58 pm

Post by RobertK »

I will update my test program so that we will be able to test text mode switching as well.

Screen modes for the Alphatronic PC, CPC and PC-88 are not documented on the Wiki. Which modes are available under what numbers?
User avatar
RobertK
Well known member
Posts: 347
Joined: Mon Feb 26, 2018 12:58 pm

Post by RobertK »

Thanks for the wiki updates. Here is my updated test program, which now allows to test text mode switching as well. MODE_FIRSTSCREEN now defines the standard text mode, MODE_SECONDSCREEN the graphics mode or alternate text mode. Define TEXT_MODE_SWITCHING when switching between text modes only.

On the text screen, I no longer print to the bottom line because on some systems (e.g. FP-1100, MZ2500) this makes the screen scroll.

Here are the test results, most systems work ok:

- Galaksija Plus: all ok
- Laser 500: all ok
- MC-1000: all ok
- Multi-8: all ok
- NEC PC-6001 Mk2: all ok
- Samsung SPC-1000: broken screen after switching back to text mode
- Tiki-100: all ok
(For the following systems we test text mode switching)
- Casio FP-1100: all ok
- Sharp MZ2500: all ok
- Microbee: all ok
- Tatung Einstein TK02 80-Columns card: all ok, but note that you need to explicitly switch to mode 0 if you
want to output text on the 40-columns screen (even if this is DSW-set to be the default screen), otherwise
the screen will be partly broken
- Alphatronic PC: Mode 1 displays 40 columns instead of 80. Screensize() in mode 1 returns 80x24. Not sure if
maybe 80-column support needs to be activated somehow in the emulation settings.
- Amstrad CPC: all ok
- NEC PC-8801: screen switching is ok, but in mode 1 screensize() returns 37x25 instead of 40x25

Code: Select all

/*
        smt.c - Screen Mode Test
        Test program for screen mode switching using console_ioctl()
        Author: RobertK, 2019-01-22

        Compile with:
        zcc +gal -subtype=galaxyp -create-app -pragma-redirect:fputc_cons=fputc_cons_generic -pragma-redirect:CRT_FONT=_font_8x8_bbc_system -o smtgalplus smt.c -D__GALPLUSHIRES__
        zcc +laser500 -pragma-redirect:CRT_FONT=_font_8x8_bbc_system smt.c -o smt -create-app -Cz--audio -Cz--fast
        zcc +mc1000 -pragma-redirect:fputc_cons=fputc_cons_generic -pragma-redirect:CRT_FONT=_font_8x8_bbc_system -create-app -Cz--audio smt.c -o smt_mc1000
        zcc +multi8 smt.c -create-app -o smt_multi8 -pragma-redirect:CRT_FONT=_font_8x8_bbc_system
        zcc +pc6001 -subtype=rom -pragma-redirect:fputc_cons=fputc_cons_generic -pragma-redirect:CRT_FONT=_font_8x8_bbc_system -create-app -o smt_pc6001Mk2 smt.c
        zcc +spc1000 -create-app -pragma-redirect:CRT_FONT=_font_8x8_bbc_system smt.c -o smt
        zcc +cpm -subtype=tiki100 -ltiki100 -create-app -pragma-redirect:fputc_cons=fputc_cons_generic -o SMT.COM smt.c
        (For the following systems we test text mode switching)
        zcc +cpm -subtype=microbee -pragma-redirect:fputc_cons=fputc_cons_generic -create-app -o smt smt.c -D__BEE__
        zcc +cpm -subtype=einstein -pragma-redirect:fputc_cons=fputc_cons_generic -o SMT.COM smt.c -create-app -D__EINSTEIN__ -D__EINSTEIN80COLUMNS__
        zcc +mz2500 -create-app -o smt smt.c
        zcc +fp1100 -create-app -o smt_FP1100 smt.c
        zcc +pc88 -pragma-redirect:fputc_cons=fputc_cons_generic -create-app -Cz--audio -o smt_pc8001 smt.c
        zcc +cpc -lndos -subtype=dsk -pragma-redirect:fputc_cons=fputc_cons_generic -create-app -o smt smt.c
        zcc +pc88 -pragma-redirect:fputc_cons=fputc_cons_generic -create-app -Cz--audio -o smt_pc8001 smt.c                
*/

#include <stdio.h>
#include <graphics.h>
#include <sys/ioctl.h>                // required for switching the screen mode

// Define standard text mode number
#if defined(__TIKI100__)
        #define MODE_FIRSTSCREEN 2
#elif defined(__CPC__)
        #define MODE_FIRSTSCREEN 1
#else
        #define MODE_FIRSTSCREEN 0         // Standard value if not defined otherwise
#endif

// Define second screen mode number (usually graphics mode, on some systems other text mode)
#if defined(__LASER500__) || defined(__MULTI8__) || defined(__BEE__) || defined(__CPC__)
        #define MODE_SECONDSCREEN 2
#elif defined (__EINSTEIN__)
        #define MODE_SECONDSCREEN 10
#else
        #define MODE_SECONDSCREEN 1        // Standard value if not defined otherwise
#endif

// Some systems do not support clg()
#if defined(__SPC1000__) || defined(__GAL__) || defined(__LASER500__)
        #define DO_NOT_USE_CLG 1
#endif
        
// normally we switch between text mode and graphics mode, but on some 
// systems we test switching between different text modes
#if defined(__BEE__) || defined(__EINSTEIN__) || defined(__FP1100__) || defined(__MZ2500__) || defined(__SMC777__) || defined(__ALPHATRO__) || defined(__CPC__) || defined(__PC88__)
        #define TEXT_MODE_SWITCHING 1
#endif


void myCls()        // Clear the screen (generic or VT100 console)
{
        printf("%c",12);
        printf("\x0c");  // the "\x0c" (0x0c character) resets the cursor position to the top left corner
}

        
void ShowTestScreen_Text(int modeNumber)        // Displays the text mode test screen
{
        int XScreenSize,YScreenSize;        // dimensions of the text screen
        int x,y;        

        myCls();        // Clear the screen
        // determine text screen size
        screensize(&XScreenSize, &YScreenSize);
        
        // Draw a screen border using the character "x"
        // we do not print to the bottom line because on some systems this makes the screen scroll
        for (x = 0; x <XScreenSize; ++x)
        {
                gotoxy(x,YScreenSize-2);
                printf("x");
                gotoxy(x,0);
                printf("x");
        }
        for (y = 1; y <YScreenSize-1; ++y)
        {
                gotoxy(0,y);
                printf("x");
                gotoxy(XScreenSize-1,y);
                printf("x");
        }
        
        gotoxy(2,2);
        printf("text screen test (mode %d)",modeNumber);
        gotoxy(2,4);
        printf("screen size: x=%d, y=%d\n",XScreenSize,YScreenSize);
        gotoxy(2,6);
        printf("press x to exit, any");
        gotoxy(2,7);
        printf("other key to switch");
        gotoxy(2,8);
        printf("screen mode...");        
}

#if !defined(TEXT_MODE_SWITCHING)
void ShowTestScreen_Graphics(int modeNumber)        // Displays the graphics mode test screen
{
        int xMax,yMax;        // dimensions of the graphics screen
        int x,y;
        
        myCls();        // Clear the screen
        // determine the graphics screen dimensions
        // coordinates go from 0 to this max value
        xMax=getmaxx();
        yMax=getmaxy();
  
        // Draw a screen border
        for (x = 0; x <=xMax; ++x)
        {
                plot(x,yMax);
                plot(x,0);

                plot(x,yMax-4);
                plot(x,3);
        }
        for (y = 1; y <=yMax; ++y)
        {
                plot(0,y);
                plot(xMax,y);

                plot(3,y);
                plot(xMax-3,y);
        }
        
        gotoxy(2,2);
        printf("graphics screen test (mode %d)",modeNumber);
        gotoxy(2,4);
        printf("screen size: x=%d, y=%d\n",xMax+1,yMax+1);
        gotoxy(2,6);
        printf("press x to exit, any");
        gotoxy(2,7);
        printf("other key to switch");
        gotoxy(2,8);
        printf("to text mode...");
}
#endif

void main()
{        
        int mode; // for screen mode switching
        char c; // for keyboard input
        int exitProgram=0;        
                        
        /* main loop */
        while(exitProgram<1)
        {

                // First screen (standard text mode)
                ShowTestScreen_Text(MODE_FIRSTSCREEN);
                c = fgetc_cons();        // wait for keypress        
                myCls();                        // Clear the screen (done here only for multi screen systems like the Tatung Einstein)
        
                if (c=='x' || c=='X')
                        exitProgram=1;
                else
                {
                        // Second Screen (usually graphics mode)
                        // switch to the other screen mode
                        mode = MODE_SECONDSCREEN;
                        console_ioctl(IOCTL_GENCON_SET_MODE, &mode);
                        #if !(defined(TEXT_MODE_SWITCHING) || defined(DO_NOT_USE_CLG))
                                clg();
                        #endif
                        
                        #if defined(TEXT_MODE_SWITCHING)
                                ShowTestScreen_Text(MODE_SECONDSCREEN);
                        #else
                                ShowTestScreen_Graphics(MODE_SECONDSCREEN);
                        #endif
                        
                        c = fgetc_cons();        // wait for keypress        
                        if (c=='x' || c=='X') exitProgram=1;                        
                        myCls();                        // Clear the screen (done here only for multi screen systems like the Tatung Einstein)

                        // switch back to standard text mode
                        mode = MODE_FIRSTSCREEN;
                        console_ioctl(IOCTL_GENCON_SET_MODE, &mode);
                }
                
        }
        myCls();        // Clear the screen        
        return;
}
stefano
Well known member
Posts: 2137
Joined: Mon Jul 16, 2007 7:39 pm

Re: Test Program for Screen Mode switching using console_ioctl()

Post by stefano »

#elif defined (__TS2068__)
#define MODE_SECONDSCREEN 6
Post Reply