nfg.forums

NFG Forums => SIG X68000 => Topic started by: megatron-uk on July 04, 2020, 10:04:53 PM

Title: GCC programming - doscalls / ioscalls / writing to video memory
Post by: megatron-uk on July 04, 2020, 10:04:53 PM
I'm playing around with the Lydux GCC toolchain (patched with the struct alignment fix) and I've hit a function that doesn't appear to work as documented.

I'm using _dos_curdrive() and _dos_curdir(int drive, char *buffer) to save information about where I'm current at:

        /* save curdrive */
 old_drive = _dos_curdrv();
 if (old_drive < 0){
 printf("Unable to save current drive [status:%d]\n", old_drive);
 return 0;
 } else {
 printf("Saved current drive [%d]\n", old_drive);
 }
 
 /* save curdir */
 status = _dos_curdir(old_drive, old_dir_buffer);
 if (status < 0){
 printf("Unable to save current directory [status:%d]\n", status);
 return 0;
 } else {
 printf("Saved current directory [%s]\n", old_dir_buffer);
 }

After this, old_drive has the drive number I'm currently on (3 == D:, in the case of my emulated xm6-g setup). However I never get anything copied to my directory buffer:

char old_dir_buffer[DIR_BUFFER_SIZE];

Where DIR_BUFFER_SIZE is 65, from the PUNI docs. I'm working in a sub-directory of D: (lets say D:\Games), but the subdir name is never recorded. From the documentation, I should get "Games" stored in the buffer (i.e. minus the drive prefix and leading/trailing slashes) but it's always null after the call.

The prototype for the function looks like:

dos.h
extern int      _dos_curdir (int, char *);

... and looking at the definition in newlib it appears as:

curdir.S
| int _dos_curdir (int, char *);
.text
.even
.global _dos_curdir
.type _dos_curdir,@function
_dos_curdir:
        move.l  %sp@(8), %sp@-
        move.w  %sp@(10), %sp@-
        .short  0xff47
        addq.l  #6, %sp
        rts

It's some 20+ years since I did any m68k assembly (and that was only a couple of weeks on a single module for my undergraduate degree!), and I'm afraid I've lost all of that knowledge, so I don't know if the prototype matches what the assembly implementation is saying.
Title: Re: GCC programming - doscalls / dos.h help
Post by: megatron-uk on July 05, 2020, 01:35:51 AM
There's definitely something weird going on with the call to _dos_curdir().

I'm running the code from drive D: (drive number 3, as reported by _dos_curdrv()).

If I change the call to from _dos_curdir(3, buffer) to _dos_curdir(0, buffer), I get the name of the current directory on the current drive (3, in this case) in the buffer.

The documentation states that the first parameter indicates the drive to interrogate the current directory from (sensible, since Human68k, like DOS, allows you to change the current directory on any active drive). However I've found that it doesn't actually report anything unless you use drive number 0 as a parameter, and then it reports the current directory name from the current drive (regardless of you specifying drive 0).

What????

Would anyone be so kind as to try the same call from either GCC 1.x or 2.x, in case it's the particular implementation of libdos using those assembly shims in Lydux's version of newlib?
Title: Re: GCC programming - doscalls / dos.h help
Post by: megatron-uk on July 05, 2020, 02:15:11 AM
This is what I observe running the code from the following locations:

D:\
D:\Games
A:\
A:\Games

Both D:\ and A:\ should result in no 'current dir' being found, since we're at the root of the drive. But... D:\Games should result in a current directory of 'Games', the same as we see whilst on drive A:\ in the 'Games' subdir.

Oh, hold on... drive number 0 as supplied to _dos_curdrv is not the same as drive number 0 as supplied to _dos_curdir .... ARGH!!!

0 = 'current' drive when supplied to curdir, drive A: when supplied to curdrv
1 = drive A to curdir, drive B to curdrv
...
25 = drive Y to curdir, drive Z to curdrv
26 = drive Z to curdir, NA to curdrv

So, if you save the current drive selection using curdrv, increment it by +1 to get the 'real' drive number that you would have to pass in to curdir or similar (haven't been through the rest of the drv/dir functions yet to see which camp they fall into - 0 or 1-indexed).

Programmers love their 'off by one' errors, don't they?
Title: Re: GCC programming - doscalls / dos.h help
Post by: megatron-uk on July 05, 2020, 05:22:31 PM
Okay, got two fixes for functions defined in newlib for the Lydux toolchain, if anyone wants them:

_dos_files
| int _dos_files (struct _dos_filbuf *, const char *, int);
.text
.even
.global _dos_files
.type _dos_files,@function
_dos_files:
        move.w  %sp@(14), %sp@-
        move.l  %sp@(10), %sp@-
        move.l  %sp@(10), %sp@-
        .short  0xff4e
        lea    %sp@(10), %sp
        rts


_dos_nfiles
| int _dos_nfiles (struct _dos_filbuf *);
.text
.even
.global _dos_nfiles
.type _dos_nfiles,@function
_dos_nfiles:
        move.l  %sp@(4), %sp@-
        .short  0xff4f
        addq.l  #4, %sp
        rts


Both functions (files.S and nfiles.S) in the newlib source directory (newlib-1.19.0-human68k/newlib/libc/sys/human68k/libdos) are named incorrectly.

In their original implementations they both share the incorrect the .global function and label _dos_filbuf, which is actually the name of one of their parameters. I've updated their .global namespace attribute as well as their label to match the C prototype naming convention (as well as the Puni docs).

At the moment I'm just assembling the source files seperately and linking them in to overide those defined in libdos.a (which, due to the wrong names being applied, don't actually exist - so you get an undefined reference error at link-time), but at some point we'll need to merge these fixes back in to a central repository.

The new functions have been tested and work correctly (at least as far as my use-case goes: find all subdirectories in a given drive and path), matching against the filespec and attributes defined in _dos_files, and then looping through the results via _dos_nfiles.

Concrete example below:

/* list files with attribute 0x10 == directory
and wildcard name. */
struct dos_filbuf buffer;
int status;
int go;

go = 1
status = _dos_files(&buffer, "*.*", 0x10);
if (status >= 0){
printf("%s.%d\t Search for files returned [status:%d]\n", __FILE__, __LINE__, status);
while(go == 1){
status = _dos_nfiles(&buffer);
if (status == 0){
go = 1;
printf("name: %s\n", buffer.name);
} else {
go = 0;
}
}
} else {
printf("%s.%d\t Search for files returned no entries [status:%d]\n", __FILE__, __LINE__, status);
}
Title: Re: GCC programming - doscalls / dos.h help
Post by: megatron-uk on July 05, 2020, 06:29:54 PM
FYI, also looks like the same issue affects _dos_exfiles() and _dos_exnfiles(), i.e. the function is labelled as one of its parameters, rather than the actual function name.
Title: Re: GCC programming - doscalls / dos.h help
Post by: kamiboy on July 05, 2020, 11:48:26 PM
Back when I was messing around with the lydux toolchain I also found a few bugs in dos/bios call functions in C. I just circumvented the call by looking up the Japanese documentation and doing the call, reading the registers directly, or some such.

Lydux put this thing together quickly and it was never really tested extensively so it has bugs here and there. A shame, really, but I think I can count on one hand how many people in the world have ever actually done anything substantial with the toolchain.
Title: Re: GCC programming - doscalls / dos.h help
Post by: megatron-uk on July 06, 2020, 12:15:44 AM
That's a shame, as it's far closer to what most people would consider a modern development toolchain; recent C syntax support, built as a cross-compiler, not relying on an ancient assembler. etc.

Yes, there are issues, such as not being able to link to objects from period compilers, but that's something you'd expect - I've done bits and pieces of C dev for things like the Atari ST and MS-DOS and being able to link in something produced from someone else's compiler with an up to date GCC isn't really something I'd anticipate working.

So far, with the obvious gotchas (above) out of the way, it seems to be working quite nicely.
Title: Re: GCC programming - doscalls / dos.h help
Post by: megatron-uk on July 06, 2020, 02:21:24 AM
What we really need is a set of simple guides for using the graphics hardware:


I know there's various bits and pieces around, but a lot of it is still in Japanese, makes no mention of the required data formats, or is purely focused on assembly.
Title: Re: GCC programming - doscalls / dos.h help
Post by: kamiboy on July 06, 2020, 04:02:05 AM
Back in the day there were some good English language web sources with that sort of information around. Most have unfortunately vanished over time.

Best resource is google translate, Japanese documentations and an emulator with debug features, allowing you to view all graphics planes individually, plus preview memory content as well as allow manipulation of memory locations.

You'll get far using those resources. But when it comes to more advanced stuff like dma transfer and manipulation of rasterization hardware it gets a lot more complicated.

I had just gotten to that point with my projects before I stopped working on them.
Title: Re: GCC programming - doscalls / dos.h help
Post by: megatron-uk on July 06, 2020, 07:45:05 PM
Okay, so I dived in and started poking values at pixels in GVRAM (mode 8, 512x512, 16bit, single graphics page).

int gfx_init(int verbose){

 _iocs_crtmod(8);
 _iocs_vpage(0);
 _iocs_g_clr_on();

 return 0;
}

void gfx_checkerboard(){
 int x;
 int y;
 int bit;
 uint16_t super;
 bit = 1;
 
 super = _dos_super(0);
 
 gvram = GVRAM_START;
 
 for(y = 0; y < GFX_ROWS; y++){
  for(x = 0; x < GFX_COLS; x++){
   if (bit){
    *gvram = 0x0000;
   } else {
    *gvram = 0xFFFF;
   }
   // Flip b/w to w/b for next column
   bit = 1 - bit;
   gvram++;
 }
 // Flip b/w to w/b for next row
 bit = 1 - bit;
 }
 _dos_super(super);
}

And that gives me what I was expecting:
x68000_checkerboard.png

However, moving on to colour, what format are the RGB values stored in?
Title: Re: GCC programming - doscalls / dos.h help
Post by: megatron-uk on July 06, 2020, 09:10:42 PM
So looking at the Doom source (https://sourceforge.net/projects/x68000-doom/) its GRBA; 5 bits each of G, R and B, and 1 for Alpha. Is that right?
Title: Re: GCC programming - doscalls / dos.h help
Post by: kamiboy on July 06, 2020, 09:25:54 PM
I never played with that layer, but it sound logical enough. Should be easy enough to test. Just fill the screen with a gradient for each colour.
Title: Re: GCC programming - doscalls / dos.h help
Post by: neko68k on July 07, 2020, 02:21:10 PM
the last bit is a 'feature' bit. with nothing special enabled it shifts the colors up a bit so they're a little brighter. there are also bits in the video controller register 2 that let you do either semi-transparency(which is a fixed transparency %) or special priority mode which puts pixels from the top most GV or TVRAM layer on top of all other layers. you should look at the 'puni' docs and/or Inside X68000 on Internet Archive. I put some info here ages ago. vidcon registers (https://gamesx.com/wiki/doku.php?id=x68000:vidcon_registers)

(edit)
the 'puni' docs are a summary, roughly, of most of the hardware features. Inside X68000 is basically the definitive documentation.
'puni' docs (https://nfggames.com/X68000/Mirrors/x68pub/x68tools/PROGRAM/ETC/puni6_3.zip)
Inside X68000 (https://archive.org/details/InsideX680001992)
Title: Re: GCC programming - doscalls / dos.h help
Post by: megatron-uk on July 07, 2020, 05:54:42 PM
Thanks neko, so we actually have 15 bits of colourspace to work with (only 32768 colours) + brightness. That's good to know.

I was struggling yesterday to come up with a way of getting all possible colours on the screen... what I tried was looping through all pixels whilst maintaining a counter of 0-65536. Each pixel would get set to a value (from the X68_RGB macro) of 1-32 (upper 5 most bits when the current value was split into 3 bytes). That *should* have given me every combination several times over, but the output rainbow effect only seemed to have a maximum of around 700 colours.

I must have something wrong with the algorithm as it looks obviously wrong.
Title: Re: GCC programming - doscalls / dos.h help
Post by: neko68k on July 07, 2020, 06:05:28 PM
16-bit mode is swizzled. I can't remember the actual layout off the top of my head. Generally speaking I would probably suggest not using it for anything other than static images since you have to access two words per pixel. Palette modes use the normal GRBi format without anything funky and the low 8/4 bits of each 16-bits in GVRAM are used to choose the index. Also, 0x0000 is punch-through, so totally transparent, when written to the first index of each 16-color palette. I found some weird stuff you can do with the VIDCON registers to use other colors as punch-through but it was years ago and I don't remember.
Title: Re: GCC programming - doscalls / dos.h help
Post by: megatron-uk on July 07, 2020, 06:07:11 PM
This is my attempt at putting a pixel of every possible colour on screen:

void gfx_rainbow(){
int x, row;
int y, col;
uint16_t super;
uint8_t r,g,b;
unsigned r_mask, g_mask, b_mask;
uint16_t i, ii, iii;
super = _dos_super(0);
r_mask = ((1 << 5) - 1) << 11;
g_mask = ((1 << 5) - 1) << 6;
b_mask = ((1 << 5) - 1) << 1;
r=g=b=0;
ii=0;
x=0;
for(gvram = GVRAM_START; gvram < GVRAM_END; gvram++){
ii++;
if (ii >= 65536){
ii = 0;
}
// Shift each byte left 3, we only combine the 5 msb for the 15bit+alpha value
r = (uint8_t)  (((ii & r_mask) >> 11) << 3);
g = (uint8_t) (((ii & g_mask) >> 6) << 3);
b = (uint8_t) (((ii & b_mask) >> 1) << 3);
*gvram = rgb2grb(r,g,b,1);
}
_dos_super(super);
}

... and I'm using the X68_RGB macro from the Doom source:

#define rgb2grb(r, g, b, i) ( ( ((b&0xF8)>>2) | (((g)&0xF8)<<8) | (((r)&0xF8)<<3) ) | i )

I'm having a hard time figuring out where I'm losing the information that should give me 32*32*32 colours.
Title: Re: GCC programming - doscalls / dos.h help
Post by: megatron-uk on July 07, 2020, 06:10:53 PM
Quote from: neko68k on July 07, 2020, 06:05:28 PM16-bit mode is swizzled. I can't remember the actual layout off the top of my head. Generally speaking I would probably suggest not using it for anything other than static images since you have to access two words per pixel. Palette modes use the normal GRBi format without anything funky and the low 8/4 bits of each 16-bits in GVRAM are used to choose the index. Also, 0x0000 is punch-through, so totally transparent, when written to the first index of each 16-color palette. I found some weird stuff you can do with the VIDCON registers to use other colors as punch-through but it was years ago and I don't remember.

Thanks for the info - I'm in the process of trying to write a decent game browser/launcher, so the intention was to use GVRAM to hold the background frame and to load game covers into (so would be static, other than when selecting a new game and the game cover would be loaded). The game names would be loaded in to TVRAM (still to dive into that!) and selector images, buttons, etc would be in sprite ram.
Title: Re: GCC programming - doscalls / dos.h help
Post by: neko68k on July 07, 2020, 06:17:20 PM
it looks like you put the low byte of the first two pixels in the first word and the high byte of the first two pixels in the second word. so like...

$e82000 1.b -- PL = $00
$e82001 1.b -- PL = $01
$e82002 1.b PH = $00 --
$e82003 1.b PH = $01 --

it's described, briefly, near the top of _iomap.man in the 'puni' docs. so ya know, those are just shift-jis text files not man pages or word docs as the extensions suggest.
Title: Re: GCC programming - doscalls / dos.h help
Post by: megatron-uk on July 07, 2020, 07:07:04 PM
Yes, I've got those docs, as well as the Inside/Outside manual, and the Programmers Reference, and the GCC for Games... and ... and ... :D

I generally just use wxmedit to view S-JIS stuff, but google translate is only partially effective in getting any data out of them! I've found 'better' descriptions of the various system calls in the 'green' Programmers Reference manual, but it's still often just a case of trial and error to work out what the description is trying to convey!

So if I understand what you're saying about 16bit, or 15bit+bright mode ;), I'm currently trying to write a single 16bit value to a given GVRAM location, where I should be writing that same 16bit value (as low byte and high) to location x and x+2, and then next value to x+1 and x+3. So I need two pointers really; gvram_low and gvram_high. Would that layout imply that the physical video memory is two interleaved banks to improve performance?
Title: Re: GCC programming - doscalls / dos.h help
Post by: neko68k on July 07, 2020, 07:12:38 PM
I would assume that yeah its interleaved banks. I'm not sure offhand if you can do 8-bit writes to GVRAM, you'll have to try it. Otherwise you need to pack the two bytes into a word before you write them which sucks. I guess ideally you'd pre-swizzle your images on disk and just load them straight in. Inconvenient but faster at run time.
Title: Re: GCC programming - doscalls / dos.h help
Post by: megatron-uk on July 08, 2020, 08:18:19 PM
Are we sure the multiplexed, odd/even, 16bit pixel mode refers to the operation of writing to GVRAM?

In the Inside X68000 book on page 169 and 170, in the structure diagram of GVRAM, it appears to show a single pixel mapped to a single 16bit word, e.g at 0xC00000 and 0xC00001, with the next pixel in its entirety at 0xC00002- 0xC00003.

This is with a single graphics 'page' in 16bit colour mode - and the rest of the GVRAM region 'blanked off', unlike 256 and 16 colour modes, of course.

The only place I see the multiplexed 16bit rgb mode described is on page 217/218, which appears to describe the structure of the colour palette region (0xE82000 - 0xE821FF). I don't think I need to actually do anything with that myself, do I?

I could be wrong, however, as the book doesn't lend itself well to OCR translation and I'm using my phone camera to try and pick out the key words.

This all said, I'm struggling to work out how to write a pixel in a single desired colour; all my efforts end in the wrong colour.

Attempt #1
uint8_t r,g,b;
uint16_t i;
uint16_t *gvram;
r = 0x00;
g = 0x00;
b = 0xFF;
i = rgb2grb(r,g,b,1); // Flatten to 15bit + intensity in GRBI format
*gvram = i;

So for three attempts at displaying solid colours of red, green or blue, I see the following:

r=0x00, g=0x00, b=0xFF
grbi_blue.png

r=0x00, g=0xFF, b=0x00
grbi_green.png

r=0xFF, g=0x00, b=0x00
grbi_red.png

If I swap to:

i = rgb2rgb(r,g,b,1); // Flatten to 15bit + intensity in RGBI format

r=0x00, g=0x00, b=0xFF
rgbi_blue.png

r=0x00, g=0xFF, b=0x00
rgbi_green.png

r=0xFF, g=0x00, b=0x00
rgbi_red.png
Title: Re: GCC programming - doscalls / dos.h help
Post by: megatron-uk on July 08, 2020, 08:25:26 PM
Where rgb2grb and rgb2rgb are defined as:

/* Merge 3 8bit values to 15bit + intensity in GRB format */
/* Keep only the 5 msb of each value */
#define rgb2grb(r, g, b, i) ( ((b&0xF8)>>2) | ((g&0xF8)<<8) | ((r&0xF8)<<3) | i )

/* Merge 3 8bit values to 15bit + intensity in RGB format */
/* Keep only the 5 msb of each value */
#define rgb2rgb(r, g, b, i) ( ((r&0xF8)<<8) | ((g&0xF8)<<3) | ((b&0xF8)>>2) | i )
Title: Re: GCC programming - doscalls / ioscalls / writing to video memory
Post by: megatron-uk on July 08, 2020, 08:39:53 PM
Okay, I'm just going to go back and hide in my corner.

Turns out I have been trying to do 16bit colour in mode 8, rather than 12....
Title: Re: GCC programming - doscalls / ioscalls / writing to video memory
Post by: megatron-uk on July 08, 2020, 08:52:30 PM
Here's a 64k image to look at instead:

64k.png

Source code:

volatile uint16_t *gvram; // Pointer to a GVRAM location
#define CRT_MODE 12 // 512x512 65535 colour
#define GFX_ROWS 512
#define GFX_COLS 512
#define GVRAM_START 0xC00000 // Start of graphics vram
#define GVRAM_END 0xC7FFFF // End of graphics vram
#define rgb2grb(r, g, b, i) ( ((b&0xF8)>>2) | ((g&0xF8)<<8) | ((r&0xF8)<<3) | i )

int gfx_init(int verbose){
   _iocs_crtmod(CRT_MODE);
   _iocs_vpage(0);
   _iocs_g_clr_on();
   return 0;
}

void gfx_rainbow(){
int x, y;
uint16_t super;
uint8_t r,g,b, i_high, i_low;
unsigned r_mask, g_mask, b_mask;
uint16_t i, ii;
super = _dos_super(0);

// Construct masks needed to extract 5 bits each of red, green and blue from a 16bit int
r_mask = ((1 << 5) - 1) << 10;
g_mask = ((1 << 5) - 1) << 5;
b_mask = ((1 << 5) - 1) << 0;
r=g=b=0;
i=0;
ii=0;
gvram = GVRAM_START;

for(y = 0; y < GFX_ROWS; y++){
for(x = 0; x < GFX_COLS; x++){
i++; // Counter which generates our colour
if (i >= 65535){
i = 0;
}

// Shift each byte left 3, we only combine the 5 msb for the 15bit+alpha value
r = (uint8_t)  (((i & r_mask) >> 10) << 3);
g = (uint8_t) (((i & g_mask) >> 5) << 3);
b = (uint8_t) (((i & b_mask) >> 0) << 3);

// Convert r,g,b values to x68000 grbi
ii = rgb2grb(r,g,b,1);

// Write single 16bit word in grbi format
*gvram = ii;

// If writing in 16bit word mode, step by +1
gvram+=1;
}
}
_dos_super(super);
}

Some things to take away:

Title: Re: GCC programming - doscalls / ioscalls / writing to video memory
Post by: kamiboy on July 08, 2020, 09:25:11 PM
Ah, I really am a big fan of how obscure and obtuse the design of old computer/console graphics hardware is.

The X68000 is the king standing on the hill of esoteric hardware design.

It has so many graphical planes and each one somehow works different from the other ones.

You really can do some wild stuff with parallax scrolling if you use the hardware to it's full potential. But hardly anyone did. The 2nd level of Akumajo is the best attempt I can think of.

Imagine what wizard level developers could achieve if the system was more popular, especially in the west.
Title: Re: GCC programming - doscalls / ioscalls / writing to video memory
Post by: megatron-uk on July 08, 2020, 09:36:13 PM
I will say that writing to GVRAM seems slow (I am of course setting pixel-by-pixel, so that's the absolute worst-case scenario). I don't know if it can be scrolled or manipulated via the video registers like the other graphics memory so it does seem more limited than BGRAM, TVRAM or sprites.

For my purposes I just want to use GVRAM to load a nice menu frame, background image etc, so I don't need to do manipulate it much once loaded, so the speed is not a major factor.
Title: Re: GCC programming - doscalls / ioscalls / writing to video memory
Post by: megatron-uk on July 08, 2020, 11:09:10 PM
I've started documenting what I'm finding out, along with sample code (e.g. for writing pixels to GVRAM, getting that 16bit colour matrix on screen, the various dos calls, etc):

https://www.target-earth.net/wiki/doku.php?id=blog:x68_devcode

I'll be happy to transfer them to the wiki once I have time.
Title: Re: GCC programming - doscalls / ioscalls / writing to video memory
Post by: megatron-uk on July 10, 2020, 01:50:03 AM
Okay, so I can draw single pixels at points, translate x/y co-ords into GVRAM addresses, draw filled and unfilled rectangles, fill the screen with solid colours or gradients. Great.

Now moving on to the next piece of the puzzle - loading image data assets from disk. I'm using a simple BMP function (based on this (https://elcharolin.wordpress.com/2018/11/28/read-and-write-bmp-files-in-c-c/)) - it current includes math.h, which I'd really rather do without if possible, but for the moment I can live with it.

My (heavily modified) code loads the data okay, correctly seeks to attributes for bpp, height, width and the padding to the data section, then loops over loading the pixel data from the image section... but on calling fclose() at the end of reading the data the program ends with an address error:

fclose_address_error.png

Now up to this point fopen, fseek and fread implementations from newlib-1.19 as included with the Lydux toolchain all worked as expected. If I remove the reference to the end of fclose() at the end of my bmp function call, it works and passes the data back to the caller without the address error:

no_fclose.png

Just wondering if anyone else had come across it? Before I delve into the newlib implementation to see if there's anything obviously broken.
Title: Re: GCC programming - doscalls / ioscalls / writing to video memory
Post by: megatron-uk on July 10, 2020, 02:38:07 AM
Okay, so that's weird, if I move fopen() and the corresponding fclose() from inside the bmp function to outside, and simply pass in the file handle, fclose() works as expected; no address error.

So previously it was (pseudo code):

int main(){
    bitmap_struct bmp;
    loadbmp(bmp);
}

loadbmp(bitmap_struct *bmp){
    f = fopen("file");
    fseek(...);
    fread(...);
    // do other stuff with bitmap data;
    fclose(f);

}

All I've done is move the fopen and fclose calls outside, and pass in the open file handle:

int main(){
    bitmap_struct bmp;
    f = fopen("file");
    loadbmp(bmp);
    fclose(f);
}

loadbmp(FILE *f, bitmap_struct *bmp){
    fseek();
    fread();
    // do other stuff;
}

Weird???
Title: Re: GCC programming - doscalls / ioscalls / writing to video memory
Post by: megatron-uk on July 10, 2020, 06:27:36 AM
Okay, so it's not quite there yet:

  - Image still in 16bit rgb format, haven't yet put anything in place to downsample to 15bit grbi, that's why the colours are wrong - I suspect I'll put the logic for that into the bmp function, so it's always ready in native format by the time it gets back to the caller.

  - I think I'm either loading from the file wrong, or writing back to gvram in the wrong size or something like that, which is causing the offset pixels

Still... I feel a particular sense of achievement having come from just nothing, over a week ago:

bmp_to_gvram_1.png

It's the boxart to Alshark btw, if anyone is wondering.

Title: Re: GCC programming - doscalls / ioscalls / writing to video memory
Post by: megatron-uk on July 11, 2020, 02:26:20 AM
Getting closer now that I've swapped the endianness of the image data (BMP defines little-endian):

x68000_bmp_2.png

Still some things to work out - I'm clearly processing the data by-byte somewhere, whereas it should all be treated as 16bit words.. that's got to be the source of interlaced rows and offset data.

I need to review the data-reading logic where its pulling the pixels from the file and appending them to my pixel array.

Slow progress is still progress though.
Title: Re: GCC programming - doscalls / ioscalls / writing to video memory
Post by: megatron-uk on July 11, 2020, 08:41:07 AM
A bit further again; sorted out the 'interlacing' type effects, and it looks like all the colour is there, but not yet remapped to grbi:

x68000_bmp_3.png

I seem to be getting alternating scanlines in the image, and when viewing the contents of memory it's clear that I'm getting one image-width-worth-of-pixels of empty bytes in between every valid line of data (hence why the image is vertically stretched and missing the bottom half of the box-art).

It must be to do with the reverse-offset through the pixel buffer that I'm using to read the BMP data in reverse (BMP stores data bottom up, so the top row of pixels is the very last in the file). I suspect I'm jumping too far back into the pixel buffer each time I'm reading a new line from the file.

That's the next bug to track down, I think.

Also, the aspect ratio was driving me insane for a while; I was convinced that I was only getting partial content of the various boxes/rectangles I was drawing... no, it was because they are horizontally stretched in the 512x512 aspect ratio as displayed in XM6 (still wish there was a decent emulator to run in Linux, rather than having to run it via Wine...).
Title: Re: GCC programming - doscalls / ioscalls / writing to video memory
Post by: megatron-uk on July 11, 2020, 08:04:17 PM
Got the missing rows and therefore the half-height image issue sorted now. It was an alignment issue between the pixel buffer (uint16_t *) and the (uint8_t *) pointer used to index it.

I've converted both the buffer and access pointers over to (uint8_t), which solves it, but it does mean that when I come to access an indiviual pixel (2 bytes) I need to either cast back back or access pointer and pointer+1 to get both bytes, which is a bit of a chore.

Anyway:

x68000_bmp_4.png

SHould be just a case of applying the rgb565 to grb555 conversion now; you can see in the second bitmap that red and blue are still flipped.
Title: Re: GCC programming - doscalls / ioscalls / writing to video memory
Post by: megatron-uk on July 12, 2020, 04:31:12 AM
Hurrah!

x68000_bmp_5.png

That's it - 16bit BMP loaded from disk, byte-swapped from little to big-endian, colour truncated to 5 bits for each of r/g/b and then copied to an x,y screen coordinate represented in GVRAM.

The next thing is to try and work out if I can do the byteswapping or colour conversion any quicker. At the moment I'm doing this after reading all of the pixel data into memory:

for(i = 0; i < n_pixels; i++){
// Remember, each pixel is actually 2 bytes for our 16bit mode
pixel = (uint16_t) (((bmp_ptr[0] & 0xFF) << 8) | (bmp_ptr[1] & 0xFF));

// Swap from the native little-endian BMP data to big-endian
pixel = swap_int16(pixel);

r = (((pixel & r_mask565) >> 11) << 3);
g = (((pixel & g_mask565) >> 5) << 2);
b = (((pixel & b_mask565)  >> 0) << 3);
pixel = rgb888_2grb(r, g, b, 1);

bmp_ptr[0] = ((pixel & 0xFF00) >> 8);
bmp_ptr[1] = ((pixel & 0x00FF));
bmp_ptr += bmpdata->bytespp;
}

Where swap_int16() and rgb888_2grb() and the bitmasks are defined as the following macros:

#define r_mask565 ((1 << 5) - 1) << 11
#define g_mask565 ((1 << 6) - 1) << 5
#define b_mask565 ((1 << 5) - 1) << 0

#define rgb888_2grb(r, g, b, i) ( ((b&0xF8)>>2) | ((g&0xF8)<<8) | ((r&0xF8)<<3) | i )

#define swap_int16(i) ((i << 8) | ((i >> 8) & 0xFF))

And just to show that the pixelation-like distortion in the emulator is caused by the rendering/stretching by XM6, and not the image display algorithm or some deficiency in the X68000 colour format, here's the the same BMP open in an image viewer, next to the Graphic Buffer window of XM6, next to the rendered screen output:

x68000_bmp_5b.png
Title: Re: GCC programming - doscalls / ioscalls / writing to video memory
Post by: megatron-uk on July 12, 2020, 04:58:47 AM
Yeah, doing endian conversion and rgb565 to grb555 conversion on the fly isn't super fast.

I just timed a full screen, 512x512 image at around 11 seconds to display:

x68000_bmp_6.png

... almost 10 seconds of that is the conversion. Although I have to say that I'm really pleased with the output.

The smaller, 1/4 to 1/3 screen sized images (like my cover art example) load from disk in around 250-500ms, with the endian conversion and rgb conversion taking it up to say 2-3 seconds or thereabouts. I think that's reasonable for the intended use as a game browser/launcher (the main code isn't written yet!), I'll probably write a callback function that fires after a game has been selected and user input has been idle for 250-500ms, then load the bmp from disk), so normal browsing/scrolling doesn't trigger it.

Still, if I can try to speed it up at all, it's a bonus.
Title: Re: GCC programming - doscalls / ioscalls / writing to video memory
Post by: kamiboy on July 12, 2020, 06:51:09 AM
Once pre-processed you could just transfer the image to the graphics memory using DMA so as to not lose menu responsiveness.

Actually way back I wanted to do a similar graphical game launcher myself. But in the end I gave it up in favour for a simple text based one. I've set it up to start up on boot on my machine. If I had continued with the graphical version I would have prolly never finished because it was so much more work.
Title: Re: GCC programming - doscalls / ioscalls / writing to video memory
Post by: megatron-uk on July 12, 2020, 08:57:28 AM
I'll probably write some gvram to gvram bitmap copy/move functions to make life easier for copying and moving sections of screen around once loaded and then move on to looking at TVRAM and sprites next as they'll be the bulk of the stuff that will be responding to user input.
Title: Re: GCC programming - doscalls / ioscalls / writing to video memory
Post by: megatron-uk on July 12, 2020, 11:32:24 PM
In case anyone is interested, I've updated my wiki with all the functions I've written, plus examples and expected output:


https://www.target-earth.net/wiki/doku.php?id=blog:x68_devcode#screen_to_screen_copy_in_gvram

When I'm a bit further on I'll add the same content to the Gamesx wiki pages... it's better to have it in multiple locations.

If anyone has any pointers for getting started using TVRAM (loading / using custom fonts/bitmaps) or the use of PCG RAM for defining/moving sprites, I'd be really appreciative.
Title: Re: GCC programming - doscalls / ioscalls / writing to video memory
Post by: kamiboy on July 13, 2020, 01:46:25 AM
For sprites and background tiles you might want to look for my old Gankutsuou project thread on here. I believe I linked the source code for the project. Might be handy to look through.

I started it sometime in 2013 I think.
Title: Re: GCC programming - doscalls / ioscalls / writing to video memory
Post by: neko68k on July 13, 2020, 05:03:13 AM
TVRAM is 4-bit planar indexing into the first GVRAM palette (the first 16 colors). It supports a "simultaneous access mask" for writing more than one plane at a time with a single write and a "write mask" for doing easy patterning. It also supports hardware raster copy which I've seen used for fast text scrolling. There are some nice diagrams and explanation in Inside X68000.

PCG is 4-bit 1-dimensional indexing into the selected PCG palette (0-15). The nametable items reference which of the 16 palettes the item uses. IIRC sprite nametables are in their own little chunk of RAM but BG nametables are at the bottom of PCG. So BG layers eat up the bottom 1/4 to 1/2 of PCG depending on how you set things up. These are, of course, also well described in Inside and to a bit lesser extent the 'puni' docs depending on what version of them you have.

For loading custom fonts to use with stuff like _dos_print or printf you should probably just use HFONT (link (https://nfggames.com/X68000/Mirrors/x68pub/x68tools/VISUAL/FONT/hfont120.lzh)) or HIOCS from the command line. I think the font format is described at the end of the graphics chapter in Inside. There is some explanation in the HFONT documentation also.

You probably won't need it but if you intend to do wild and crazy sprite things you should look into the XSP (link (https://nfggames.com/X68000/Mirrors/x68pub/x68tools/PROGRAM/LIB/XSP200.LZH)) library. It's the sprite multiplexing code used in ChoRenSha68k and Puti'n Plin among other things.

That reminds me, Inside X68000 OCR's very well with OmniPage. Thats an expensive piece of software but maybe you can find it uh, cheap, somewhere ;)
Title: Re: GCC programming - doscalls / ioscalls / writing to video memory
Post by: megatron-uk on July 15, 2020, 05:19:33 AM
Thanks for the pointers. In relation to fonts for T-VRAM, it's more along the lines of loading some bitmap fonts and small graphics - things like widgets for a scrolling file selector, text for filenames themselves, etc. I don't think _dos_print() and printf() and friends are going to be suitable.

I've found a couple of nice, readable 8x8 bitmap font tables that I'd like to use. I can work out how to easily get these in to memory and then display them...

For simple 1bpp fonts like this:

8 Eyes (U) 1.png

... I can see that it would just be a simple case of setting 8 bytes per font, (1 byte per horizontal row, 8 rows per character), to replicate the bit pattern.

However having a plain font like that isn't the nicest option. I've got a couple of others in mind, either shaded, arcade-style, or with an eye-pleasing drop shadow (still 8x8), such as:

font1.png

... But I'm having a bit of a brain fart when it comes to working out (a), how to load it in to memory (I know I'll need 4 layers for each bit), and (b), how to represent the different shades of colour.

As I'm working primarily in 16bit colour in other areas, I haven't actually done anything to set palette entries so I assume when I'm currently doing my tests (writing various 16bit values to the first T-VRAM address in plane 0, just to see what happens), that the colours I'm seeing (cyan?) are a result of whatever did anything to the palette entries previously?
Title: Re: GCC programming - doscalls / ioscalls / writing to video memory
Post by: neko68k on July 15, 2020, 01:53:45 PM
I tossed together some stuff I wrote a while back.

TGA2SP (link (https://www.dropbox.com/s/p4yc7wah79g3rjg/tga2sp.zip?dl=1)) converts a TGA image in 8xWhatever dimensions with an 8-bit palette to PCG and palette data. There is an included TGA as an example. It should build with whatever linux just fine but there is no Makefile because I'm lazy. Just 'gcc tga.c TGA2SP.c -o tga2sp' or something like that should work. To use it './tga2sp font.tga font' where the last 'font' is what you want it to name the output. So this would create 'font.pcg' and 'font.pal'. Both files can be loaded directly into PCG or palette RAM.

In 'examples.zip' (link (https://www.dropbox.com/s/v90j7u2h5ynu5oe/examples.zip?dl=1)) there is source for 3 programs but its all written in probably not great ASM. It's also meant to be compiled with HAS060 assembler and GCC MARIKO on the X68000 itself. Hopefully it's still helpful. You can run the included X files to see what they do.

In 'msx.s' it loads a cutfile, which is a 1-bit compressed image for loading to TVRAM then draws some boxes on TVRAM planes and sets some palette entries that match the combined bits.

In 'rockman.s' it loads the PCG and PAL data then prints some text on a BG layer.

In 'original.s' it loads a cutfile and fades it in and out. IIRC it also plays a sound. I didn't write this one, it came with the ch30_omake bootloader.

You can create new cutfiles with 'TXBMC' which I don't have handy. Don't worry about it for now.

I do strongly recommend you pre-convert all your image data to a format that makes sense for loading straight into various graphics RAMs for performance reasons. Loading from an 8-bit BMP to TVRAM is going to be really funky and from 16 or 24-bit is ugh, just don't ;) Likewise, bit shifting is expensive and it'd be a lot faster if you weren't converting colors on the fly when loading from a BMP to GVRAM.
Title: Re: GCC programming - doscalls / ioscalls / writing to video memory
Post by: megatron-uk on July 15, 2020, 07:56:25 PM
Ah, that's interesting - so, if I work out what's going on from rockman.S and the tga convertor, it's using background tiles to display those text bitmaps? I wouldn't have thought of doing it that way, but that's a 'typical' console way of doing it :)

I guess, at the end of the day, there's nothing particularly special about what T-VRAM  is used for (other than it's fast to set multiple pixels simultaneously). I could just limit the use of T-VRAM to relatively simple use (to highlight the game currently selected, move a 'selection' cursor around, etc), stuff that doesn't really need any specific palette use. That would be faster, and I could use the 'set all planes' mode.

In terms of pre-converting images, that's a reasonable choice for assets for the application itself (e.g. fonts etc. I've also kept image asset data for borders etc to be only a few hundred bytes each, and memcpy multiple instances of them around [rather than storing the entire 512px window borders, for example], so it's virtually instantaneous to load and convert, once, at startup).

I don't want to get in to the state of having people pre-convert game screenshots to any particular special format - I'd hope that BMP (or GIF or whatever else) would be sufficient (and easier to obtain from MObygames or whatever). I do have an idea for storing a pickled version of the game screenshot BMP data in native byte-swapped and GRB format in some sort of 'cache' folder though, and reloaded from that cache the second time the game is selected.
Title: Re: GCC programming - doscalls / ioscalls / writing to video memory
Post by: kamiboy on July 16, 2020, 12:48:38 AM
A pickle cache is a fine idea, that is what I would do if the software is designed to be usable by other users.

Hope you finish this project. I think having a graphical frontend game launcher would be A very cool addition to the X68000.

I am sure in time new HDD images with all games populated with images will be made through community effort before long.

For my own launcher I intended a small bit of text description, genre and other small bits of info to appear for each game.

I even once went through every game on my HDD and wrote down such info for every game.

Genre and Developer would be cool text labels to consider for your launcher.
Title: Re: GCC programming - doscalls / ioscalls / writing to video memory
Post by: megatron-uk on July 18, 2020, 01:28:16 AM
I persisted with T-VRAM and wrote myself a little 1bpp font BMP loader (really a wrapper around my existing BMP routine)... it's only supporting 1bpp fonts for the moment, but all of the TVRAM routines to then load it and put symbols on the screen is already writing the multiple planes (they just set each plane to the same value when loading a 1bpp font).

x68000_font_1.png

I've got a couple of routines to place a single character and ascii strings at x/y coordinates, just like I'm using in GVRAM, so that's me just about sorted for custom text.

I'm using a 8x16 glyph at the moment (from Sonic Pinball, of all places), but I've seen some really nice aliased fonts (again 8x16) from a couple of SNES games (Breath of Fire, and Cybernator, if you're interested) that are lovely and readable on pretty much any colour background. So as soon as I wrap my head around the palette mapping, I'll try moving on to 4bpp fonts as well, as they do look so much nicer.

One question I did have was about the resolution attributes for Text VRAM - I thought that this was a fixed resolution of 1024x1024 (with 64x addressable 16bit words per row)... but it seems to alter when I change mode via crtmod. I'm obviously using 512x512@16bit in mode 12 for my main application, and the text mode seems to change to that as well at the same time. If I write something to 0xE00000 at anything more than a +31 offset in mode 12, it doesn't appear (off screen to right?). Is it fixed at 1024x1024 but a virtual/scrollable resolution if the G VRAM mode differs?
Title: Re: GCC programming - doscalls / ioscalls / writing to video memory
Post by: megatron-uk on July 18, 2020, 06:36:28 AM
Here's a quick look at the current work-in-progress version of what I've knocked together so far.

What works:


What doesn't:



Just for reference, the above video is how long it actually real-time scraping of every game installed on the V4 image... \Games, \Games2 and \Games3 ... that's something like 189 folders in total. Emulated speed is the stock 10MHz.
Title: Re: GCC programming - doscalls / ioscalls / writing to video memory
Post by: megatron-uk on July 18, 2020, 09:19:24 AM
So I'm trying to get my head around the colour mapping for the four text planes again.

I can see that the 4 layers give me 2^4 combinations and therefore point to one of the first 16 palette entries at 0xe82200... But, is plane 0 the most significant bit, or the least? As that affects what bits you write to each layer in order to get the correct colour index value (0-15).

I.e. is it

Plane 0 = 8
Plane 1 = 4
Plane 2 = 2
Plane 3 = 1

Or reverse?
Title: Re: GCC programming - doscalls / ioscalls / writing to video memory
Post by: neko68k on July 20, 2020, 07:16:33 PM
Pretty sure its in order so plane 0 is lsb. And you'll be writing to the palette at $E82200, $E82202, etc in GRBi format. I was mistaken earlier, this is actually the first BG/Sprite palette, not the first GVRAM palette.

0 = 1
1 = 2
2 = 4
3 = 8

(edit)
I can't remember if the very old versions of XM6 have this but in the Debug menu you might be able to enable a palette view and other things.

palette view.png
Title: Re: GCC programming - doscalls / ioscalls / writing to video memory
Post by: megatron-uk on July 20, 2020, 09:24:04 PM
Excellent, that's a great help - thanks! Yes, I can see the palette view in the "View" -> "Video" -> "Palette" menu. At the moment I'm just making sure everything fits together right and I don't have any stray text left on the screen when loading up the next entry.

I've redone the look of the interface a bit - it's a bit more costly in terms of memory used (there are a few more bitmaps being thrown around the place), but its still working nicely on a 2MB config.

x68000_launcher.png

Metadata is being loaded from disk now, and used to fill in the additional information for each game as it is selected. The 'metadata' file format is a basic .ini type, so you can create files such as:

[default]
name=Castlevania Chronicles
genre=Platformer
developer=Konami
publisher=Konami
year=1993
start=alt_start.bat
images=title.bmp,screen1.bmp,screen2.bmp,credits.bmp

I'll make something that takes a directory listing of all the games from the X68000 side of things and runs it against Mobygames, The GamesDB, Launchbox etc and pulls down metadata, images, resizes them and writes the metadata files and can be lha-ed back up, to be transferred and unpacked on the X68000 again. You could, of course, do it all by hand, as it's just text and 16bit (256x256 max( BMP files.

I also have an idea for an asynchronous BMP loader/byteswapper that will load a single row of pixels, byteswap, GRBI them and then screencopy the result to the required position on the screen in the gaps between user input. That way the process doesn't lock-up to user input, and the game images can still be loaded quickly as the user is scrolling through the list.
Title: Re: GCC programming - doscalls / ioscalls / writing to video memory
Post by: megatron-uk on July 20, 2020, 09:32:06 PM
BTW, I did look the information in 'Inside X68000', it's on page 179, if I recall correctly, but it doesn't appear to say which plane refers to which bit (though it does label then T0 through T3)... perhaps it just implicitly assumes you should know lowest plane == least significant bit.
Title: Re: GCC programming - doscalls / ioscalls / writing to video memory
Post by: kamiboy on July 21, 2020, 12:20:20 AM
Wow, that launcher is looking sleek. Impressive how quickly it has progressed. Kudos.
Title: Re: GCC programming - doscalls / ioscalls / writing to video memory
Post by: megatron-uk on July 21, 2020, 08:12:23 AM
I've uploaded a short clip of the new UI in action, as well as the 'asynchronous' game art loader:


Here's a still of it:

x68000_launcher_2.png

The game art loader works by first checking if there's a screenshot to load for the current game (its hardcoded to load the Castlevania title screen right now). It then sets up a structure which keeps a file position pointer and a pixel buffer of exactly one horizontal row of pixels worth of bytes.

Each loop around the while(true) user input detection loop the function gets called and reads the next line of bytes from the bitmap, byteswaps them, converts to grbi and copies that one lines worth of pixels to the screen. Every time a new game is selected, the pixel buffer is freed, the current open file handle is closed, and the bitmap header is read. So it still remains responsive to scrolling etc. (albeit not as fast scrolling as it was without the image loading!).

There's still a few things to clean up - make sure I'm not leaking memory, and move all of my quick-and-dirty sprintf message strings to snprintf to make sure the odd long-named directory or game title doesn't overflow any buffers anywhere.

I also want to implement a 'filter by genre' option, so there's some more UI functionality to implement there, as well as a simple help screen. Also need a way to allow the user to scroll through the available artwork for a game - probably some icons/text under the artwork window there to state that it's image #1 of N, or something like that.

Then there's the 'launch game' function... though that shouldn't be too hard, if I do something like the way LHES handles it: assume that the cwd will have a 'start.bat' in, and have a bat that calls the launcher like:

while true
    launcher.x
    if exists start.bat
        start.bat

Oh, and revisiting 4bpp fonts, of course. The flat blue colour of the text right now is just a side effect of whatever the initial palette entries are set to! I'm also missing a method of highlighting the currently selected row. I would like to try looking at sprites for that one, then I'll have had some experience of GVRAM, TVRAM and sprite PCG RAM.
Title: Re: GCC programming - doscalls / ioscalls / writing to video memory
Post by: megatron-uk on July 23, 2020, 01:28:13 AM
Been working on a way to get the metadata/screenshot data for the games as installed in the V4 (or any similar) disk image.

I've added an option to the config file for the launcher which saves out to disk the directories that have been found. You then copy that file out of the real/emulated X68000 an onto another box running running Python.

The directory file is then read, and queries made to Mobygames (you need a Mobygames API key to do this), and it pulls down the real game name, genre, publisher, developer etc.. and then gives you a choice of images/screenshots to download as well.

I'm working on automatically converting the images as they get downloaded, so it's an all-in-one process.

The images and metadata file for each game are saved into an output folder with the same path name(s) as on the X68000. I'll then lha it up, copy to the real/emulated machine and unpack over the existing directory structure.

Unfortunately it's a manual process (albeit a case of hitting a couple of numeric choices for each game), since the existing directory names used for the games don't generate many matches against the Mobygames metadata.
Title: Re: GCC programming - doscalls / ioscalls / writing to video memory
Post by: megatron-uk on July 23, 2020, 10:03:54 PM
Well a combination of the Mobygames API and the Launchbox metadata XML file have gotten me metadata and images for just over 100 of the ~190 games included on the V4 image. There's around 600 screenshots or covers now available for browsing, along with year, genre, publisher, developer etc. It's about 60MB so far; zipping down to about 15MB, so we'll need probably double that space on the V4 HDD image in order to unpack it all.

Both Mobygames and Launchbox are lacking for many of the other games, so it's back to doing manual lookups in Google and other places. Doujin titles are especially troublesome - finding anything on some of them is a major task.

Still, I'll package the Python scraper tool with the source code for the launcher once I've got things to a working stage and get it checked in to my Github page.
Title: Re: GCC programming - doscalls / ioscalls / writing to video memory
Post by: megatron-uk on July 24, 2020, 09:55:06 PM
New work-in-progress video of the launcher application. It can now load per-game artwork, including the ability to scroll through multiple images per game:


Slight tidy-up of the UI, including some buttons for when I get around to adding mouse and joystick support - quit/help/filter/audit; the first two being self-explanatory, with the 'filter' option (in the future) to bring up a dialogue that lets you select from all of the genre tags that have been added to the metadata of your games; show only 'action', 'rpg', 'shooter', etc. The 'audit' option to (eventually) output a summary txt document with list of games, which have metadata, which have images, totals of games per genre, etc.

But... my Aranet ATX to X68000 power adapter arrived in the mail this morning, so progress may not be as quick over the next week or so as it has been. Time to try and resurrect my new X68000 Pro...
Title: Re: GCC programming - doscalls / ioscalls / writing to video memory
Post by: kamiboy on July 25, 2020, 03:41:53 AM
Looking sharp, X68000 sharp.

I wonder how the program will run various configs of actual X68000 hardware.

I've had the problem where my programs with didn't work, or didn't work correctly on the actual hardware when they ran just fine in an emulator.

Pray that won't be something you'll encounter as figuring out what is going on is not easy in such cases.

Title: Re: GCC programming - doscalls / ioscalls / writing to video memory
Post by: megatron-uk on July 25, 2020, 05:28:47 AM
Well until I replace the PSU in my Pro (fingers crossed that's what the problem is!) I won't know for sure it will even run on actual hardware!

That's said I've been careful to stick to video modes that are on all models and I've been developing with only a 2MB memory config. The big unknown for me is how the disk IO performs - I'll be be running from a CF card on an Aztec Monster off the Sharp SCSI add-on board, rather than the internal SASI interface. Will the directory scraping process slow down dramatically I wonder...
Title: Re: GCC programming - doscalls / ioscalls / writing to video memory
Post by: megatron-uk on July 26, 2020, 05:13:33 AM
So, it's done; 187 games with metadata and images. The next problem is figuring out where to put it, as the V4 image doesn't have much in the way of free space (~60MB?). The data for all games in the V4 image is ~110MB, so we need roughly twice the amount of space available.

Is the image a 900MB disk or a 1000MB disk? I think the former, so if this was recreated on another drive of 1000MB in total, it would probably fit...
Title: Re: GCC programming - doscalls / ioscalls / writing to video memory
Post by: Jehuty on July 26, 2020, 08:04:53 PM
I added a 2nd partition on my V4 Image on a 2gb SD or 4 gb CF card.
So i have to fix some !Start.bat, but i have enough space.

Is there a newer image fpr X68k ? I heard about v8 ?
Title: Re: GCC programming - doscalls / ioscalls / writing to video memory
Post by: megatron-uk on July 27, 2020, 12:36:38 AM
I'll probably end up doing the same - possibly even move games2 or games3 from the V4 image to another drive. I have both an AztecMonster and an R-IDSC-21E SCSI/IDE bridge, so I could end up using both, for 4 partitions, 1GB on two 2GB CF cards, but if what that page above describes is true, a single 16GB CF card could potentially host a 900MB OS partition and a 15.1GB data/games partition.
Title: Re: GCC programming - doscalls / ioscalls / writing to video memory
Post by: megatron-uk on August 15, 2020, 05:50:24 AM
Just a quickie to say that whilst I haven't done much more with this (still trying to fix my faulty Pro), I did manage to get the time to check the code into Github.

There isn't a nice readme or anything like that at the moment, but if you're interested in how some of the graphics routines work, then by all means take a look:

https://github.com/megatron-uk/x68klauncher
Title: Re: GCC programming - doscalls / ioscalls / writing to video memory
Post by: megatron-uk on February 27, 2021, 10:02:48 PM
I'm picking this up again after writing (mostly complete) versions for IBM/PC DOS and PC-98 DOS, plus trying to speed things up again. In those versions I've added searching/filtering based on genre, series, publisher, developer as well as filtering games by those with specific hardware details (on the DOS version, all games supporting the Gravis Ultrasound, for example). I also managed to cut down the memory use by streaming bitmaps in from disk as well as drastically reducing the amount of dynamic memory allocation going on (always a recipe for leaks and, ultimately, hard-to-find crashes).

As part of this I'm trying to add in some performance timer functions I implemented on the other versions but have hit a stumbling block....

Problem 1

I think I've found another missing/wrongly implemented system call in the Lydux newlib implementation, specifically the _dos_time_pr() call, which if I've decoded the documentation correctly, is supposed to return the time the current thread has been running, in milliseconds.

However, in my testing on xm6g it always returns the same value (-1 if signed, 4294967295 if signed). I'm unclear if this my misunderstanding of how _time_pr() works, or if it is just not implemented.

Problem 2

Ideally, rather than the X68000 specific functions above, I'd like to use clock() which is on most platforms where you can query the system timer, and return the value of the system timer in clock ticks. This implementation seems to be missing in our newlib library. If I try to reference clock() in my code, I get this link error:

/opt/toolchains/x68k/lib/gcc/human68k/4.6.2/../../../../human68k/lib/libc.a(lib_a-timesr.o): In function `_times_r':
/usr/local/src/gcc_x68k/newlib-build/human68k/newlib/libc/reent/../../../../../newlib-1.19.0-human68k/newlib/libc/reent/timesr.c:60: undefined reference to `times'
collect2: ld returned 1 exit status
make: *** [Makefile:50: launcher.X] Error 1

The implementation of timesr.c looks like this:

clock_t
_DEFUN (_times_r, (ptr, ptms),
     struct _reent *ptr _AND
     struct tms *ptms)
{
  clock_t ret;

  ret = _times (ptms);
  return ret;
}

However, the function _times() is not defined anywhere.

Anyone got any pointers on getting system timer data? Not time (_dos_gettim2() and _dos_gettime() work quite nicely, but are wall clock based times with only a second granularity). If there's another mechanism of getting the number of clock ticks between two arbitrary sections of code I'm eager to hear of it.
Title: Re: GCC programming - doscalls / ioscalls / writing to video memory
Post by: megatron-uk on February 28, 2021, 11:36:23 PM
Latest progress:

TVRAM palette setting in place. I'm only using a 1bpp font at the moment, but at least I can now choose the colour of those mono pixels...

launcher_text_palette.png

Filtering code ported from the IBM/PC DOS version.

Hit 'F' to bring up the 'filter' menu:

launcher_filter_menu.png

The 'genre' options are automatically populated from the genre you assign to a game in the metadata file. You come up with a new genre, it automatically appears here to search by:

launcher_filter_genre.png

The 'company' options are automatically populated from both the developer and publisher fields you assign to a game in the metadata. Of course, you make a type, like having an extra space on the end of a name, and you end up with "Konami" and "Konami ", like I have below, whoops!

launcher_filter_company.png

Selecting any option then re-filters the games that were scraped and shows only the matching entries:

launcher_filter_results.png
Title: Re: GCC programming - doscalls / ioscalls / writing to video memory
Post by: ozzyOuzo on June 19, 2021, 10:46:01 PM
Nice work :)

just got a question about fixed DOS functions etc.. has it been already pushed onto the git for modification ?

Thx
Title: Re: GCC programming - doscalls / ioscalls / writing to video memory
Post by: ozzyOuzo on June 20, 2021, 03:20:28 PM
For your timer issues did you check ?https://www.chibiakumas.com/68000/x68000.php (https://www.chibiakumas.com/68000/x68000.php)
there are some getTime and others DOS timer functions available.

Alternatively you can also use vblank and a framecounter for additional granularity depending on refresh rate :  $e88001 - bit 4

Concerning newlib issues if any, maybe actual code could be easily ported to C ?
but 3-4 lines of asm is not a big deal anyway, even if it's not portable code as is.
Title: Re: GCC programming - doscalls / ioscalls / writing to video memory
Post by: megatron-uk on June 23, 2021, 01:29:41 AM
The newlib fixes haven't been pushed back, unfortunately - Lydux, the original person who did a lot of the newlib work for X68k seems to have vanished, so his github repo is stale.

The functions I've found and fixed are here: https://github.com/megatron-uk/x68klauncher/tree/master/asm

Along with a new header here: https://github.com/megatron-uk/x68klauncher/blob/master/src/newlib_fixes.h
Title: Re: GCC programming - doscalls / ioscalls / writing to video memory
Post by: incrediblehark on September 12, 2023, 07:32:17 AM
Quote from: megatron-uk on February 28, 2021, 11:36:23 PMLatest progress:

TVRAM palette setting in place. I'm only using a 1bpp font at the moment, but at least I can now choose the colour of those mono pixels...

launcher_text_palette.png

Filtering code ported from the IBM/PC DOS version.

Hit 'F' to bring up the 'filter' menu:

launcher_filter_menu.png

The 'genre' options are automatically populated from the genre you assign to a game in the metadata file. You come up with a new genre, it automatically appears here to search by:

launcher_filter_genre.png

The 'company' options are automatically populated from both the developer and publisher fields you assign to a game in the metadata. Of course, you make a type, like having an extra space on the end of a name, and you end up with "Konami" and "Konami ", like I have below, whoops!

launcher_filter_company.png

Selecting any option then re-filters the games that were scraped and shows only the matching entries:

launcher_filter_results.png

Just wondering if there has been any new progress to this project? It looks amazing and the work is really impressive! Would love to try this out in my HDD image.
Title: Re: GCC programming - doscalls / ioscalls / writing to video memory
Post by: FedericoTech on October 02, 2023, 04:36:45 AM
Hi.

I've been researching the X68000 for 2 years. I started with Lydux's toolchain but it seems that some functions are either missing or buggy.

Then I found this other toolchain: https://virtuallyfun.com it's of a guy called Jason Stevens.

It runs the Mariko toolchain on the emulated commandline run68 and it can compile original source code.

It's the one I'm primary using and it goes very well.

I have blog post on how to install it https://federicotech.wordpress.com/2022/01/15/x68000-programming-chapter-2-2-setting-up-the-ide-jason-stevens-flavour/ (https://federicotech.wordpress.com/2022/01/15/x68000-programming-chapter-2-2-setting-up-the-ide-jason-stevens-flavour/)
Title: Re: GCC programming - doscalls / ioscalls / writing to video memory
Post by: rezb1t on October 02, 2023, 05:30:52 AM
Quote from: FedericoTech on October 02, 2023, 04:36:45 AMHi.

I've been researching the X68000 for 2 years. I started with Lydux's toolchain but it seems that some functions are either missing or buggy.

Then I found this other toolchain: https://virtuallyfun.com it's of a guy called Jason Stevens.

It runs the Mariko toolchain on the emulated commandline run68 and it can compile original source code.

It's the one I'm primary using and it goes very well.

I have blog post on how to install it https://federicotech.wordpress.com/2022/01/15/x68000-programming-chapter-2-2-setting-up-the-ide-jason-stevens-flavour/ (https://federicotech.wordpress.com/2022/01/15/x68000-programming-chapter-2-2-setting-up-the-ide-jason-stevens-flavour/)
Excellent! This is really helpful, thank you