GCC programming - doscalls / ioscalls / writing to video memory

Started by megatron-uk, July 04, 2020, 10:04:53 PM

Previous topic - Next topic

megatron-uk

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?

neko68k

I tossed together some stuff I wrote a while back.

TGA2SP (link) 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) 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.

megatron-uk

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.

kamiboy

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.

megatron-uk

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?

megatron-uk

Here's a quick look at the current work-in-progress version of what I've knocked together so far.

What works:

  • Scraping of directory information to produce a list of game folders
  • Loading of per-game metadata (via a __launch.dat file in each folder)
  • Sorting of games based on directory name or real name from metadata file
  • A progress bar during initial load of assets and directory scraping
  • A simple 3-pane user interface from 8 teeny bitmap fragments
  • Loading of BMP screenshots (max 256x256 - for 1 to 1 screenshots) from disk

What doesn't:

  • No selectable list of game names yet
  • Launching of titles (suspect I will do something similar to LHES and write a batch file on exit)


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.

megatron-uk

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?

neko68k

#47
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

megatron-uk

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.

megatron-uk

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.

kamiboy

Wow, that launcher is looking sleek. Impressive how quickly it has progressed. Kudos.

megatron-uk

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.

megatron-uk

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.

megatron-uk

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.

megatron-uk

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...

kamiboy

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.


megatron-uk

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...

megatron-uk

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...

Jehuty

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 ?

megatron-uk

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.

megatron-uk

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

megatron-uk

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.

megatron-uk

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

ozzyOuzo

Nice work :)

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

Thx

ozzyOuzo

For your timer issues did you check ?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.

megatron-uk

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

incrediblehark

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.

FedericoTech

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/

rezb1t

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/
Excellent! This is really helpful, thank you