Querying Capabilities

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

Querying Capabilities

Post by RobertK »

I did some testing with this new functionality - it's very useful for cross development, thanks.

A little test program with a batch file for five targets that I have tried it with:

Code: Select all

// CapsTest.c

// #pragma define CLIB_EXIT_STACK_SIZE=0

#include <conio.h>
#include <sys/ioctl.h>                // required for querying system capabilites and for switching screen modes

#if defined(__MC1000__) || defined(__PC6001__)
        #define SCREEN_MODE 1
// #elif defined(__TIKI100__)
//        #define SCREEN_MODE 3
// #elif defined(__VZ200__) || defined(__SV8000__)
//        #define SCREEN_MODE 1
#endif

void main()
{
        int caps;
        int result;
        int x;
        
        #if defined(SCREEN_MODE)
                int mode;
                mode = SCREEN_MODE;
                console_ioctl(IOCTL_GENCON_SET_MODE, &mode);        
        #endif
        
        // On the ZX Spectrum, we switch to 32 column mode
        #if defined(__SPECTRUM__)
                printf("%c%c",1,32);
        #endif
        
        // Clear the screen
        printf("%c",12);
        printf("\x0c");  // the "\x0c" (0x0c character) resets the cursor position to the top left corner
        
        printf("*** Capabilities Test ***\n\n");
        
        console_ioctl(IOCTL_GENCON_GET_CAPS, &caps);

        printf("IOCTL Result: %d\n", caps);
        
        if (caps>255)
        {
                caps = (caps >> 8) & 0xFF;
                printf(">255, right-shifted: %d\n", caps);
        }
        
        printf("\n");
        
// CAP_GENCON_CUSTOM_FONT  1
// CAP_GENCON_UDGS         2
// CAP_GENCON_FG_COLOUR    4
// CAP_GENCON_BG_COLOUR    8
// CAP_GENCON_INVERSE      16
// CAP_GENCON_BOLD         32
// CAP_GENCON_UNDERLINE    64

                
        result = caps & CAP_GENCON_CUSTOM_FONT;
        printf("Custom Font: ");
        if (result==0) printf("no\n"); else printf("yes\n");

        result = caps & CAP_GENCON_UDGS;
        printf("UDG: ");
        if (result==0) printf("no\n"); else printf("yes\n");

        result = caps & CAP_GENCON_INVERSE;        
        if (result==0)
                printf("Inverse: no\n"); 
        else
                printf("Inverse: yes %cpInverse%cq\n",27,27);

        result = caps & CAP_GENCON_BOLD;        
        if (result==0)
                printf("Bold: no\n"); 
        else
                printf("Bold: yes %c2Bold%c3\n",27,27);

        result = caps & CAP_GENCON_UNDERLINE;        
        if (result==0)
                printf("Underline: no\n"); 
        else
                printf("Underline: yes %c0Underline%c1\n",27,27);
                
        result = caps & CAP_GENCON_FG_COLOUR;        
        if (result==0)
                printf("Fore Colour: no\n"); 
        else
        {
                printf("Fore Colour: yes "); 
                for (x = 0; x < 8 ; x++ )
                        printf("%cb%c%u", 27, x + 32,x);
                printf("\n"); 
        }

        result = caps & CAP_GENCON_BG_COLOUR;        
        if (result==0)
                printf("Back Colour: no\n"); 
        else
        {
                printf("Back Colour: yes "); 
                for (x = 0; x < 8 ; x++ )
                        printf("%cc%c%u", 27, x + 32,x);
                printf("\n"); 
        }
        
        #if defined(__PV1000__) || defined(__COLECO__) || defined(__PACMAN__) || defined(__Z80TVGAME__) || defined(__GAMEBOY__) || defined(__MYVISION__) || defined(__SV8000__)
                // On systems without keyboard, wait five seconds
                msleep(5000);
        #else
                fgetc_cons();        // wait for keypress          
        #endif
}

Code: Select all

setlocal
rem Set your z88dk root path here
set z88root=C:\Misc\z88dk\

set path=%PATH%;%z88root%bin\
set zcccfg=%z88root%lib\config\
set z80_ozfiles=%z88root%lib\

zcc +coleco -pragma-redirect:fputc_cons=fputc_cons_generic -o CapsTest_coleco -create-app CapsTest.c
zcc +hgmc -pragma-redirect:fputc_cons=fputc_cons_generic -o CapsTest_HueblerGrafikMC -create-app CapsTest.c
zcc +pv2000 -create-app -pragma-redirect:fputc_cons=fputc_cons_generic -o CapsTest_PV2000 CapsTest.c
zcc +rx78 -pragma-redirect:fputc_cons=fputc_cons_generic -o CapsTest_rx78 -create-app CapsTest.c
zcc +zx -pragma-redirect:fputc_cons=fputc_cons_generic -lndos -create-app -o CapsTest_ZXSpectrum CapsTest.c

endlocal

rem pause
A few questions and issues (?):

1. PV2000: the result was 6144 and therefore greater than 255, so I had to right-shift it by 8 bits to get the desired 8-bit result.
Is this normal behaviour? If so, what's the reason for such a great result value?

2. PV2000: FG Colour result is "no" while this system definitively supports FG colour.

3. RX78: I couldn't get the underlining sample text to work (this is so far the only system I encountered that supports underlining).

4. Spectrum and H?bler Grafik MC: the result is always 0.
User avatar
dom
Well known member
Posts: 2072
Joined: Sun Jul 15, 2007 10:01 pm

Post by dom »

Er yeah, I messed up! I forgot that on targets that actually implement mode switching etc the ioctl() function that is called swaps registers around. I'm hoping you should get sensible values now!
User avatar
RobertK
Well known member
Posts: 347
Joined: Mon Feb 26, 2018 12:58 pm

Post by RobertK »

All five systems work fine now, thanks.

Off-topic: The bold letters are very effective, but on many systems we have a problem with the small m and w letters:

Image

Image

I am not sure what we could do about it. Suggestions:

- Not printing these two letters in bold?
Image

- Leaving it as it is and hoping the user will still know what letter this is supposed to be?

- Avoiding these two letters in our programs...?

Here is one more test program.

Code: Select all

// BoldTest.c

// #pragma define CLIB_EXIT_STACK_SIZE=0

#include <conio.h>
#include <sys/ioctl.h>                // required for querying system capabilites and for switching screen modes

#if defined(__MC1000__) || defined(__PC6001__)
        #define SCREEN_MODE 1
// #elif defined(__TIKI100__)
//        #define SCREEN_MODE 3
// #elif defined(__VZ200__) || defined(__SV8000__)
//        #define SCREEN_MODE 1
#endif

        
void main()
{
        int caps;
        int result;
        int x;
        
        #if defined(SCREEN_MODE)
                int mode;
                mode = SCREEN_MODE;
                console_ioctl(IOCTL_GENCON_SET_MODE, &mode);        
        #endif
        
        // On the ZX Spectrum, we switch to 32 column mode
        #if defined(__SPECTRUM__)
                printf("%c%c",1,32);
        #endif
        
        // Clear the screen
        printf("%c",12);
        printf("\x0c");  // the "\x0c" (0x0c character) resets the cursor position to the top left corner
        
        printf("*** Bold Test ***\n\n");
        
        console_ioctl(IOCTL_GENCON_GET_CAPS, &caps);
        printf("IOCTL Result: %d\n\n", caps);
        
        result = caps & CAP_GENCON_BOLD;        
        if (result==0)
        {
                printf("Bold is not available!\n");
        }
        else
        {
                printf("%c2ABCDEFGHIJKLMNOPQRSTUVWXYZ%c3\n",27,27);
                printf("%c2abcdefghijklmnopqrstuvwxyz%c3\n",27,27);
                printf("%c20123456789%c3\n",27,27);
                printf("%c2()<>,;-/?%c3\n",27,27);
                printf("\n\n");
                // We try to print the letters m and w not in bold to see what it would look like.
                printf("%c2abcdefghijkl%c3m%c2nopqrstuv%c3w%c2xyz%c3\n",27,27,27,27,27,27);
        }
        #if defined(__PV1000__) || defined(__COLECO__) || defined(__PACMAN__) || defined(__Z80TVGAME__) || defined(__GAMEBOY__) || defined(__MYVISION__) || defined(__SV8000__)
                // On systems without keyboard, wait five seconds
                msleep(5000);
        #else
                fgetc_cons();        // wait for keypress          
        #endif
}

Code: Select all

setlocal
rem Set your z88dk root path here
set z88root=C:\Misc\z88dk\

set path=%PATH%;%z88root%bin\
set zcccfg=%z88root%lib\config\
set z80_ozfiles=%z88root%lib\

zcc +coleco -pragma-redirect:fputc_cons=fputc_cons_generic -o BoldTest_coleco -create-app BoldTest.c
zcc +hgmc -pragma-redirect:fputc_cons=fputc_cons_generic -o BoldTest_HueblerGrafikMC -create-app BoldTest.c
zcc +pv2000 -create-app -pragma-redirect:fputc_cons=fputc_cons_generic -o BoldTest_PV2000 BoldTest.c
zcc +rx78 -pragma-redirect:fputc_cons=fputc_cons_generic -o BoldTest_rx78 -create-app BoldTest.c
zcc +zx -pragma-redirect:fputc_cons=fputc_cons_generic -lndos -create-app -o BoldTest_ZXSpectrum BoldTest.c

endlocal

rem pause
User avatar
RobertK
Well known member
Posts: 347
Joined: Mon Feb 26, 2018 12:58 pm

Post by RobertK »

On-topic again: when compiling for the BIC or SMC777 I get a "symbol 'CLIB_GENCON_CAPS' not defined" compiler error.

Code: Select all

zcc +cpm -subtype=smc777 -pragma-redirect:fputc_cons=fputc_cons_generic -o CTSMC.COM CapsTest.c -create-app -D__SMC777__

zcc +cpm -subtype=bic -pragma-redirect:fputc_cons=fputc_cons_generic -o CTBIC.COM CapsTest.c -create-app -D__BIC__
User avatar
dom
Well known member
Posts: 2072
Joined: Sun Jul 15, 2007 10:01 pm

Post by dom »

I've added in the value for bic and smc777 - a quick find/grep doesn't show anymore missing so hopefully that's correct.

Regarding the font - this comes out of the way the bold is performed - the byte is rotated one bit to the right and then or'd with the original value - it's a simple naive technique that works surprisingly well for a lot of fonts/characters. I remember the Outlet disczine in the 90s had specific overrides for those two characters to make them more legible. In order to that we'd have to stop treating fonts as blobs of binary which happen to represent 8x8 characters and define an actual format.

I was really envisaging that bold was just used for emphasis and that if it was wanted permanently then a custom font should be used which works around these issues.
User avatar
RobertK
Well known member
Posts: 347
Joined: Mon Feb 26, 2018 12:58 pm

Post by RobertK »

Ok, we will use this "simple" bold font where it makes sense, for example for a game score line that does not contain any m or w characters.

Two more IOCTL_GENCON_GET_CAPS issues:

- On the VG5000, it reports BG colour to be available, but textbackground() has no effect on that target. Unless BG colour is currently broken, it should return BG = 0.

- On the SMC-777 in text mode, BG colour does not seem to be "freely available" for individual characters, so the BG result should be rather 0 than 1.

I've tried IOCTL_GENCON_GET_CAPS on many more platforms, and it seems to be working fine.
User avatar
RobertK
Well known member
Posts: 347
Joined: Mon Feb 26, 2018 12:58 pm

Post by RobertK »

The Galaksija Plus Hires mode 1 could also be considered in the #1360 enhancements issue. Currently IOCTL_GENCON_GET_CAPS returns 0.

Compilation for the standard and hires Galaksija models:

Code: Select all

zcc +gal -create-app -pragma-redirect:fputc_cons=fputc_cons_generic -o ctgal CapsTest.c

zcc +gal -subtype=galaxyp -create-app -pragma-redirect:fputc_cons=fputc_cons_generic -pragma-redirect:CRT_FONT=_font_8x8_bbc_system -o ctgalhi CapsTest.c -D__GALPLUSHIRES__
Add this condition to make the Galaksija Hires Test switch to mode 1:

#if defined(__MC1000__) || defined(__PC6001__) || defined(__GALPLUSHIRES__)
#define SCREEN_MODE 1
...
User avatar
dom
Well known member
Posts: 2072
Joined: Sun Jul 15, 2007 10:01 pm

Post by dom »

Thanks for the corrections, I've fixed the SMC777 and implemented bold/underlined for Mode1 on the Galaksija.

The VG5k is interesting. Background colour is supported if you choose a custom font. If you don't then it's not. To be pedantic I could change the flags when the font is changed.
User avatar
RobertK
Well known member
Posts: 347
Joined: Mon Feb 26, 2018 12:58 pm

Post by RobertK »

SMC777: fixed, the BG bit is 0 now.

VG5000: a note on the Wiki page (that BG colour only works with a custom font) would be sufficient, but your proposed behaviour would of course be perfect.

For some reason I couldn't get BG colour working even with a custom font. Do I need to do more than this?
zcc +vg5k -pragma-redirect:fputc_cons=fputc_cons_generic -pragma-redirect:CRT_FONT=_font_8x8_bbc_system -o CapsTest_vg5000 -create-app CapsTest.c

Galaksija Plus Hires: great, thanks! However, underlining does not work yet, I've tried both _font_8x8_bbc_system and _font_8x8_zx_system. Is this feature restricted to fonts that do not use the full character height?
User avatar
dom
Well known member
Posts: 2072
Joined: Sun Jul 15, 2007 10:01 pm

Post by dom »

So, the vg5k, I misread the attribute table, paper colour is only available when plotting graphics so I've removed that capability.

For Galaksija Plus, underline is now fixed - I was blanking out the line rather than drawing it!

I see you've put the feature to good use with Mastermind - if there's anything else that would make creating these massively portable programs easier let me know.
User avatar
RobertK
Well known member
Posts: 347
Joined: Mon Feb 26, 2018 12:58 pm

Post by RobertK »

dom wrote:if there's anything else that would make creating these massively portable programs easier let me know.
Yes, there a few more capability constants that I have defined in my code, these could be defined in the target libraries. Currently I would never notice that e.g. games.h support has been added to such a target.

1. Is games.h supported?

Code: Select all

#if defined(__ABC80__) || defined(__CPC__) || defined(__SORCERER__) || defined(__KC__) || defined(__MULTI8__) || defined(__NASCOM__) || defined(__PC6001__) || defined(__OSBORNE1__) || defined(__SPC1000__) || defined(__EINSTEIN__) || defined(__TIKI100__) || defined(__Z1013__) || defined(__MZ2500__) || defined(__FP1100__) || defined(__ACE__) || defined(__P2000__) || defined(__X1__) || defined(__KAYPRO83__) || defined(__ATTACHE__) || defined(__QC10__) || defined(__PC88__) || defined(__DMV__) || defined(__LASER500__) || defined(__ZX80__) || defined(__SMC777__) || defined(__PASOPIA7__) || defined(__EXCALIBUR64__) || defined(__BIC__) || defined(__HEMC__) || defined(__HGMC__) || defined(__KRAMERMC__)
        #define GAMES_H_NOT_AVAILABLE 1
#else
        #include <games.h>        // for virtual joystick control
#endif
2. System has no keyboard? On these, fgetc_cons() may not be called (usually gaming consoles).

Code: Select all

#if defined(__PV1000__) || (defined(__COLECO__) && !defined(__BIT90__)) || defined(__PACMAN__) || defined(__Z80TVGAME__) || defined(__GAMEBOY__) || defined(__MYVISION__)        // Casio PV-1000, ColecoVision, PacMan-Hardware, etc.
        #define JOYSTICK_ONLY 1
#endif
Here it would also help to know whether only one joystick is available, so that two-player mode can be disabled:

Code: Select all

// But some have only one joystick
#if defined(__Z80TVGAME__) || defined(__GAMEBOY__)
        #define TWO_PLAYER_MODE_NOT_AVAILABLE 1
#endif
3. System is upper-case only, meaning that only lower-case letters should be used for text output (normally using upper-case letters makes no difference, but on the ZX80 and ZX81 this would output inverse characters):

Code: Select all

#if defined(__ZX81__) || defined(__ZX80__) || defined(__PACMAN__) || (defined(__GAL__) && !defined(__GALPLUSHIRES__))
        #define SMALL_LETTERS_ONLY 1
#endif
Note that some of these constants - namely those that are used to identify sub-types - are defined in my compile parameters, for example __BIT90__, __BIC__ or __GALPLUSHIRES__.

I would prefer a #if..#else...#endif pre-processor solution rather than querying at runtime in order to keep memory demand down.
User avatar
dom
Well known member
Posts: 2072
Joined: Sun Jul 15, 2007 10:01 pm

Post by dom »

I'm starting to see some of your pain.

The intention is that games.h should always be supported, that is you should always have at least one joystick available: it may well be a keyboard emulated one, but it should be there. So when I'm finished with the pmd85 I'll sort that out.

Knowing whether there's a keyboard available is a useful thing to know. Whatever is done will have to take account of the virtual keyboard on the Gameboy and in my mind should also take account of firmware/non-firmware keyboard so it should be a function call.

The number of joysticks should come form GAME_DEVICES in <games.h>.

Upper case: This depends on the screen mode on the MC6847 machines so should go in the existing capabilities number.
User avatar
RobertK
Well known member
Posts: 347
Joined: Mon Feb 26, 2018 12:58 pm

Post by RobertK »

dom wrote:The intention is that games.h should always be supported, that is you should always have at least one joystick available: it may well be a keyboard emulated one, but it should be there. So when I'm finished with the pmd85 I'll sort that out.
That would be very useful. BTW, if possible, all targets with keyboard should IMHO have a joystick option for the "quasi-standard" QAOP-NM input.
dom wrote:The number of joysticks should come form GAME_DEVICES in <games.h>.
Good point, that should solve my problem, I only need that for consoles without keyboard.
dom wrote:Upper case: This depends on the screen mode on the MC6847 machines so should go in the existing capabilities number.
I agree, the Galaksija Plus is another such example. Although for this I think I would stick to my current method because the text constants eat so much RAM that I prefer to define them at pre-processor time.
User avatar
dom
Well known member
Posts: 2072
Joined: Sun Jul 15, 2007 10:01 pm

Post by dom »

dom wrote:Upper case: This depends on the screen mode on the MC6847 machines so should go in the existing capabilities number.
I agree, the Galaksija Plus is another such example. Although for this I think I would stick to my current method because the text constants eat so much RAM that I prefer to define them at pre-processor time.
Interesting. So with the console there?s this concept of raw mode (print this character without interpretation) and the the default non-raw mode. This is used to handle mapping of the ZX81 character set.

I think there?s a good argument that in non-raw mode the lower case characters are converted to upper case. That way you don?t need to maintain two copies of the strings.

I think this affects mc6847, ZX8. and gal targets. I?ll check the various pc6001 machines though - I have a hunch that the mk2 does support lower case.
User avatar
RobertK
Well known member
Posts: 347
Joined: Mon Feb 26, 2018 12:58 pm

Post by RobertK »

dom wrote:I think there?s a good argument that in non-raw mode the lower case characters are converted to upper case.
Yes, that would make sense to drop this extra treamtent for the ZX81/ZX80. But then it should support inverse via Generic/ANSI console, which accoding to my tests it currently doesn't.

Another topic: it would be good to know whether a target supports in_KeyPressed(). As usual, I would prefer a pre-processor solution.

Currently I am doing this in H-Tron - are these all, or did I miss any recently added target?

Code: Select all

#if defined(__ZX81__) || defined(__ZX80__) || defined(__ACE__) || defined(__VZ200__) || defined(__SORCERER__) || defined(__VG5000__) || defined(__TRS80__) || defined(__AQUARIUS__) || defined(__SPECTRUM__) || defined(__PMD85__)
        #define USE_INKEYPRESSED 1                // allows simultaneously checking the status of more than just one key
#endif
User avatar
RobertK
Well known member
Posts: 347
Joined: Mon Feb 26, 2018 12:58 pm

Post by RobertK »

A few more GET_CAPS issues (it works fine on all other systems I have tested it so far):

Code: Select all

zcc +ace -pragma-redirect:fputc_cons=fputc_cons_generic -vn -create-app -o acect.bin CapsTest.c
zcc +mz -pragma-redirect:fputc_cons=fputc_cons_generic -create-app CapsTest.c -o ctmz700
zcc +pc88 -pragma-redirect:fputc_cons=fputc_cons_generic -create-app -Cz--audio -o ct_pc8001 CapsTest.c
zcc +super80 -create-app -o CapsTest_super80em CapsTest.c
zcc +super80 -create-app -clib=vduem -o CapsTest_super80rv CapsTest.c
Jupiter Ace: GET_CAPS result is correct (no inverse), but - off-topic here - I think this system should be able to support inverse?

Sharp MZ-700: GET_CAPS reports Inverse to be available, but it does not work.

NEC PC 800x: GET_CAPS reports Fore Colour, Back Colour and Inverse to be available, but none of them work. I've tested with the M88 emulator on the three N88 models.

Super 80 E/M: same ase NEC PC 800x. Inverse should be working on the m and v colour models, but it doesn't.
In addition, compiling with the -clib=vduem option for the r or v model currently gives the following errors:

Errors in source file C:\Misc\z88dk\lib\config\\..\..\\lib\target\super80\classic\super80_crt0.asm:
Error at file 'target/super80/stdio/generic_console_vduem_ioctl.asm' line 27: symbol '__super80_custom_font' not defined
Error at file 'target/super80/stdio/generic_console_vduem_ioctl.asm' line 45: symbol '__super80_custom_font' not defined
User avatar
dom
Well known member
Posts: 2072
Joined: Sun Jul 15, 2007 10:01 pm

Post by dom »

Cool, thank you, hopefully fixe dup now. Some comments:

Jupiter Ace: There's 128 slots available in the PCG, the font will take up 96 of those and the screen is defined by a 24x32 character code grid so to get inverse you'd have to sacrifice fonts. You could do this yourself with a custom font and then, for example, use lower case as inverse.

pc88: There was some missing documentation on the wiki! Screen modes 0 and 1 don't support any attributes, but mode 2 is a bitmapped (640x200) mode and supports colours/inverse and I've just added bold and inverse to complete the set.

Super80: Did you go to the machine configuration menu in mame and switch to composite? The inverse on this machine is achieved by swapping paper/ink colours.
User avatar
RobertK
Well known member
Posts: 347
Joined: Mon Feb 26, 2018 12:58 pm

Post by RobertK »

All fixed now, thanks!

Jupiter Ace: no problem, thanks for the explanation.

PC88: Screen Mode 2 works fine, and the named colours are correctly mapped. On the platform list, the VT100 / GenCon / Graphics columns still need to be filled.

Super 80: ah, beautiful! :-) I'll make four versions of my game (em, em colour, rv, rv colour). I'll compile the colour versions with -D__SUPER80COLOUR__ and I will disable the capabilities in my code when this is not defined.
Post Reply