Skip to content

[libc, paint] Add fmemcpy and fdstmemcpy, port drawscanline to C86#2287

Merged
ghaerr merged 5 commits intomasterfrom
fmemcpy
Apr 7, 2025
Merged

[libc, paint] Add fmemcpy and fdstmemcpy, port drawscanline to C86#2287
ghaerr merged 5 commits intomasterfrom
fmemcpy

Conversation

@ghaerr
Copy link
Copy Markdown
Owner

@ghaerr ghaerr commented Apr 7, 2025

Adds libc fmemcpy for OWC only.
Adds fdstmemcpy for GCC and C86 to paint.

Ports vga_scanline to C86.

@Vutshi: I just noticed, are you aware that the single pixel brush "button" is now showing two horizontal pixels (instead of a single pixel) after your last commit or so? Drawing is still down with a single pixel. This PR doesn't change any render.c code.

@Vutshi
Copy link
Copy Markdown
Contributor

Vutshi commented Apr 7, 2025

are you aware that the single pixel brush "button" is now showing two horizontal pixels (instead of a single pixel) after your last commit or so? Drawing is still down with a single pixel. This PR doesn't change any render.c code.

Yes, I also noticed it but I don’t understand how it happens. It draws three pixel which is what DrawDisk does for radius=1, but it should not do it due to if(r<=1) drawpixel…

@Vutshi
Copy link
Copy Markdown
Contributor

Vutshi commented Apr 7, 2025

Oh, I see, it is if (bushSize <= 1){ instead of if (r <= 1){ in DrawDisk

@ghaerr
Copy link
Copy Markdown
Owner Author

ghaerr commented Apr 7, 2025

Oh, I see, it is if (bushSize <= 1){ instead of if (r <= 1){ in DrawDisk

Ok, I'll fix it in this PR.

@ghaerr ghaerr merged commit 13435da into master Apr 7, 2025
1 check passed
@ghaerr ghaerr deleted the fmemcpy branch April 7, 2025 22:42
@rafael2k
Copy link
Copy Markdown
Contributor

rafael2k commented Apr 8, 2025

Wow, this scanline drawing is amazing. I need to get this to elks-viewer!

One question - how should I use this code - will it make its way to the libc, or I should just copy over the files?

@rafael2k
Copy link
Copy Markdown
Contributor

rafael2k commented Apr 8, 2025

btw, should I pursue a bmp to jpg converter (or vice-versa, which is basically done), in order we can have a more complete image editing ecosystem in ELKS?

Also - we need to improve "file" command to identify at least bmp, jpg, ppm and pgm format, as now they are fully supported on ELKS viewer, and can be easily supported by a "elks-imagemagic" I could derive from elks-viewer. Should I add this "file" improvement to a TODO somewhere?

@ghaerr
Copy link
Copy Markdown
Owner Author

ghaerr commented Apr 8, 2025

this scanline drawing is amazing. I need to get this to elks-viewer!

Are you talking about the API, which allows an array of 4-bit colors to be drawn, or the speed with which Paint now draws its icons/buttons? The big speedup with with Paint bmp's came as a result of caching the palette color conversion, not drawscanline. In fact, I've been unable to see any actual speed difference between drawscanline and calling drawpixel for each pixel, when using the ASM drawpixel routines we now have. I haven't tested on real hardware though. (The difference could be tested on real hardware using USE_DRAWSCANLINE=1 or not in drawbmp.c).

I'm not sold on drawscanline yet (as it is kind of big with no visible speed increase), which came from SVGALib, but I've included it in Paint because it's helped to get the macros built for a general C routine to manipulate VGA registers for all three compilers, which is now done.

how should I use this code - will it make its way to the libc, or I should just copy over the files?

I hope to get this stuff added to libc, but we're not quite there yet. We now have toolchain/examples, Paint, and your code, all with slight variations. I'm thinking we'll probably use this Paint code as a start, then add your 256-color pal_ routines and palette management stuff after this settles down a bit.

If you could test Paint on real hardware with and without USE_DRAWSCANLINE that would help determine which direction to go.

What will help the process of moving to libc would be ensuring that elks-viewer encoders/decoders, etc routines are already in separate files/headers and and callable like library routines, if they're not already. Each module should be as independent as possible, and depend on graphics.h and their own (possibly shared) header, if possible.

should I pursue a bmp to jpg converter (or vice-versa, which is basically done)

Our work in Paint is showing that the BMP format is well suited for ELKS since the files can be 4- or 8-bit RLE encoded for small size and rapidly decoded, we have a definite need for "any image format" to BMP format image conversion. In particular, handling some of the problems there seem to be no host tools for would be great.

These features would include taking an image (including a BMP image), and converting it to BMP using:

  • Conversion input colors to standard 16-color VGA (CGA) palette
  • Storing the palette in standard order and only using 16 BMP palette entries in the output file
  • Marking the BMP (nonstandard) that the palette is VGA standard and stored in standard order (this would eliminate the very slow palette conversion code which prohibits fast image display now without caching)
  • 4bpp or 8bpp RLE encoding
  • 4bpp color output (or 8bpp for 256-color images for palette graphics, also using a standardized palette)
  • Testing drawbmp.c (or your decoders) with the above.

we need to improve "file" command to identify at least bmp, jpg, ppm and pgm format

This can probably be easiest done by finding the Linux file source and taking a look at it. Our version only uses a 4-byte identifier table but this should be able to work for the image formats. I will look into this.

@Vutshi
Copy link
Copy Markdown
Contributor

Vutshi commented Apr 8, 2025

Hi @ghaerr ,

Something strange is going on with BMP drawing. I converted icons to what is called "Standard palette for 16 color systems" in drawbmp.c. And got wrong rendering:
Screenshot 2025-04-08 at 23 19 31

Gray became LightGray.

UPDATE: here are new icon examples
icons_new.zip

@ghaerr
Copy link
Copy Markdown
Owner Author

ghaerr commented Apr 8, 2025

Gray became LightGray.

Try adding the following diff to drawbmp.c:

diff --git a/elkscmd/gui/drawbmp.c b/elkscmd/gui/drawbmp.c
index 2470eec6..186e23ce 100644
--- a/elkscmd/gui/drawbmp.c
+++ b/elkscmd/gui/drawbmp.c
@@ -214,8 +214,8 @@ draw_bmp(char *path, int x, int y)
         if (palsize > 256) palsize = 0;
         else if (palsize == 0 && bpp <= 8) palsize = 1 << bpp;
     }
-    /*__dprintf("'%s' bpp %d comp %d pal %d %dx%d\n",
-        path, bpp, compression, palsize, width, height);*/
+    __dprintf("'%s' bpp %d comp %d pal %d %dx%d\n",
+        path, bpp, compression, palsize, width, height);
 
     if (width > 640)        /* bounds check for later array overflow */
         goto out;
@@ -302,6 +302,7 @@ draw_bmp(char *path, int x, int y)
                     pal = &bmppal[image[w]];
                     c = find_nearest_color(pal->r, pal->g, pal->b);
                     cache[image[w]] = c;
+                    __dprintf("cache %d\n", c);
                 }
 #if USE_DRAWSCANLINE
                 image[w] = c;

That will display the actual VGA pixel color (once) for each bmp. I'm wondering if perhaps find_nearest_color isn't working correctly or maybe returning light gray rather than gray.

@ghaerr
Copy link
Copy Markdown
Owner Author

ghaerr commented Apr 8, 2025

Just tried the above over here with your new paint.bmp:

'/lib/paint.bmp' bpp 8 comp 1 pal 16 128x128
cache 7
cache 7
cache 0

So, yes, that's what's happening, the original shows cache 8 as the first color, so find_nearest_color seems not to be working. Can you check that the actual palette values produced in the BMP file in fact match the VGA standard palette in drawbmp.c?

(BTW, you're using the "CGA" palette with #if 1, right? If not, then recompile with #if 0 in drawbmp for the time being.)

@ghaerr
Copy link
Copy Markdown
Owner Author

ghaerr commented Apr 8, 2025

(BTW, you're using the "CGA" palette with #if 1, right? If not, then recompile with #if 0 in drawbmp for the time being.)

Ok - that's the problem confirmed. Selecting the "CGA" palette in drawbmp.c and the images are correct.

Long story short, there is some debate as to what is the actual palette used on VGA. In Nano-X, we are using the "older" version:

/*
 * Standard palette for 16 color systems.
 */
struct palette palette[16] = {
    /* 16 EGA colors, arranged in VGA standard palette order*/
    RGBDEF( 0  , 0  , 0   ),    /* black*/
    RGBDEF( 0  , 0  , 128 ),    /* blue*/
    RGBDEF( 0  , 128, 0   ),    /* green*/
    RGBDEF( 0  , 128, 128 ),    /* cyan*/
    RGBDEF( 128, 0  , 0   ),    /* red*/
    RGBDEF( 128, 0  , 128 ),    /* magenta*/
    RGBDEF( 128, 64 , 0   ),    /* adjusted brown*/
    RGBDEF( 192, 192, 192 ),    /* ltgray*/
    RGBDEF( 128, 128, 128 ),    /* gray*/
    RGBDEF( 0  , 0  , 255 ),    /* ltblue*/
    RGBDEF( 0  , 255, 0   ),    /* ltgreen*/
    RGBDEF( 0  , 255, 255 ),    /* ltcyan*/
    RGBDEF( 255, 0  , 0   ),    /* ltred*/
    RGBDEF( 255, 0  , 255 ),    /* ltmagenta*/
    RGBDEF( 255, 255, 0   ),    /* yellow*/
    RGBDEF( 255, 255, 255 ),    /* white*/
};

but in drawbmp.c (and thus this project), we are using the "CGA" palette, which, according to some a bunch of online documentation, is "more correct":

/*
 * CGA palette for 16 color systems.
 */
struct palette palette[16] = {
    RGBDEF( 0   , 0   , 0    ), /* black*/
    RGBDEF( 0   , 0   , 0xAA ), /* blue*/
    RGBDEF( 0   , 0xAA, 0    ), /* green*/
    RGBDEF( 0   , 0xAA, 0xAA ), /* cyan*/
    RGBDEF( 0xAA, 0   , 0    ), /* red*/
    RGBDEF( 0xAA, 0   , 0xAA ), /* magenta*/
    RGBDEF( 0xAA, 0x55, 0    ), /* brown*/
    RGBDEF( 0xAA, 0xAA, 0xAA ), /* ltgray*/
    RGBDEF( 0x55, 0x55, 0x55 ), /* gray*/
    RGBDEF( 0x55, 0x55, 0xFF ), /* ltblue*/
    RGBDEF( 0x55, 0xFF, 0x55 ), /* ltgreen*/
    RGBDEF( 0x55, 0xFF, 0xFF ), /* ltcyan*/
    RGBDEF( 0xFF, 0x55, 0x55 ), /* ltred*/
    RGBDEF( 0xFF, 0x55, 0xFF ), /* ltmagenta*/
    RGBDEF( 0xFF, 0xFF, 0x55 ), /* yellow*/
    RGBDEF( 0xFF, 0xFF, 0xFF ), /* white*/
};

Let me try to find that link. So that begs the question, which is "correct" and which should we be using?

@ghaerr
Copy link
Copy Markdown
Owner Author

ghaerr commented Apr 8, 2025

Here's the article. Let me know what you think.

@ghaerr
Copy link
Copy Markdown
Owner Author

ghaerr commented Apr 8, 2025

One way we could get around this mess would be to assume a "standard" palette when a BMP is seen that has exactly 16 palette entries. If there are 16 entries, we could just skip the palette match lookup entirely, and assume that the palette index is in fact the VGA or CGA color, and just use that index unmodified. We would also assume that the palette is in "standard" order when its 16 entries. That will then work regardless of our palette.

If the BMP has 256 entries (as produced normally by other tools, etc), then we'd use the process we're using now.

What do you think? If your BMPs now have only 16 entries, I can write some code that will make this all work, for both your new and old bmp files.

@ghaerr
Copy link
Copy Markdown
Owner Author

ghaerr commented Apr 8, 2025

One way we could get around this mess would be to assume a "standard" palette when a BMP is seen that has exactly 16 palette entries.

I just tried this and it doesn't work: some of the existing .bmp files have exactly 16 entries, but they're not a standard palette:

'/lib/save.bmp' bpp 8 comp 1 pal 16 32x32
'/lib/fill.bmp' bpp 8 comp 1 pal 4 32x32
cache 8
cache 7
cache 0
cache 15
'/lib/brush.bmp' bpp 8 comp 1 pal 3 32x32
cache 8
cache 7
cache 0
'/lib/circle.bmp' bpp 8 comp 1 pal 5 32x32
cache 8
cache 7
cache 7
cache 8
cache 0
'/lib/quit.bmp' bpp 8 comp 1 pal 16 32x32
'/lib/cls.bmp' bpp 8 comp 1 pal 16 32x32
'/lib/paint.bmp' bpp 8 comp 1 pal 16 128x128
Screen Shot 2025-04-08 at 2 54 09 PM

@ghaerr
Copy link
Copy Markdown
Owner Author

ghaerr commented Apr 8, 2025

A second idea of how to deal with this would be to keep the palette which we are using now (CGA), as it has seemed to work well with your existing tools and seems to display those BMPs correctly using our find_nearest_color() against it. Instead, just modify your conversion tool to output a CGA palette rather than VGA palette. Thoughts?

@ghaerr
Copy link
Copy Markdown
Owner Author

ghaerr commented Apr 8, 2025

Another note, it seems circle.bmp is not matching the 3rd and 4th indices encountered properly, resulting in incorrect output. I hadn't noticed this visually, but see it with the new debug output:

'/lib/circle.bmp' bpp 8 comp 1 pal 5 32x32
cache 8
cache 7
cache 7 <--- dup, means source image using different palette index
cache 8 <--- dup ""
cache 0

@Vutshi
Copy link
Copy Markdown
Contributor

Vutshi commented Apr 8, 2025

then recompile with #if 0 in drawbmp for the time being.

#if 0 solved the problem.
if0

So which palette should we use, VGA (#if 0) or CGA (#if 1)?

@ghaerr
Copy link
Copy Markdown
Owner Author

ghaerr commented Apr 8, 2025

So which palette should we use, VGA (#if 0) or CGA (#if 1)?

From the above discussion, I suggest staying with the palette we're already using, the CGA palette (#if 1), since that palette apparently (from the article) more closely matches the actual IBM screen and emulator output.

Then when your conversion tool changes RGB values to palette values, it will convert to the palette that is used in most emulators and apparently real hardware screens in use today.

@Vutshi
Copy link
Copy Markdown
Contributor

Vutshi commented Apr 8, 2025

I just tried this and it doesn't work: some of the existing .bmp files have exactly 16 entries, but they're not a standard palette:

This is because they were created by optimizing the palette. In fact they contain only 3 or 4 colors because icons don’t use more. Only the new icons I’ve send above contain “standard” VGA palette with all 16 colors. So I think you can read number of colors in bmp and assume the palette is standard if there are exactly 16 of them.

@Vutshi
Copy link
Copy Markdown
Contributor

Vutshi commented Apr 8, 2025

Then when your conversion tool changes RGB values to palette values, it will convert to the palette that is used in most emulators and apparently real hardware screens in use today.

Ok. I switch to the CGA palette in icons and #if 1.

@Vutshi
Copy link
Copy Markdown
Contributor

Vutshi commented Apr 8, 2025

We can also introduce our own .ico files for icons which are bmp without palette included to save 4*16=64 bytes per icon.

@ghaerr
Copy link
Copy Markdown
Owner Author

ghaerr commented Apr 8, 2025

In fact they contain only 3 or 4 colors because icons don’t use more.

I see. So we don't really need a full palette.

Ok. I switch to the CGA palette in icons and #if 1.

Yes, lets do that.

We can also introduce our own .ico files for icons which are bmp without palette included to save 4*16=64 bytes per icon.

Actually, as a result of this testing I am now realizing that I was incorrect in thinking that there is a "standard" palette that will work for everything. Instead, we're going to have to continue to use the CGA palette which maps closest to current reality, it seems. That's ok though.

However, I am now thinking that it would be better to just include the actual palette entries, but only for the indices actually used. In this way, the .bmp files stay very small, but also remain completely .bmp compatible. IMO, it would be better to stay with a standard .bmp format (and keep them as small as possible), than to introduce our own .ico format which is different.
In the standard .bmp file format, a zero in the palette entry field means the same thing as using the maximum palette size, so we can't use zero-length palettes without becoming incompatible with other tools. Having a minimal 3-4 palette also allows the .bmp files to be re-edited later by standard tools, which will likely come in handy.

So what we're probably talking about is doing almost what you've done - having a post processor on the .bmp files that make them small, and then write just the number of entries required, which for our purposes will always match the CGA palette. So we're not using the CGA palette to speed up display, as I had first imagined, but instead using it to match colors better with emulators and real screens.

@ghaerr
Copy link
Copy Markdown
Owner Author

ghaerr commented Apr 9, 2025

save 4*16=64 bytes per icon.

That may help, but the bigger issue is how a bmp aligns with a disk sector or block: on MINIX, all file access is read two sectors at a time (=1K blocks) so what really matters is when an icon is very close to a 1K boundary; e.g. a 1025-byte bmp file will actually cause 2k disk to be read. I would think the amount of time spent reading ~64 bytes of palette internally using fread to be insignificant, especially since it's only done once per image.

Here are the current (non-converted) bmp file sizes:

-rw-r--r--  1 greg  staff   380 Apr  6 15:02 images/brush.bmp
-rw-r--r--  1 greg  staff   660 Apr  7 09:18 images/circle.bmp
-rw-r--r--  1 greg  staff   454 Mar 31 15:14 images/cls.bmp
-rw-r--r--  1 greg  staff   484 Apr  6 15:02 images/fill.bmp
-rw-r--r--  1 greg  staff  2116 Apr  8 15:00 images/paint.bmp
-rw-r--r--  1 greg  staff   528 Mar 31 15:14 images/quit.bmp
-rw-r--r--  1 greg  staff   568 Mar 31 15:14 images/save.bmp

The only problem image is paint, which is just over 2K, so 3K will be read from disk. Is that image compressed using RLE?

@Vutshi
Copy link
Copy Markdown
Contributor

Vutshi commented Apr 9, 2025

The only problem image is paint, which is just over 2K, so 3K will be read from disk. Is that image compressed using RLE?

Yes, it is RLE compressed. My encoding is not the most optimal but it is better than what image magick does. I’ll just cut off a few pixel rows on top and bottom to fit into 2048.

@Vutshi
Copy link
Copy Markdown
Contributor

Vutshi commented Apr 9, 2025

Also, did you have to do something magic in a config file to get the mouse to connect?

In martypc.toml I add this to get EGA and mouse.

config_overlays = [ "ibm_ega",
                    "pcxt_2_serial_ports",
                    "microsoft_serial_mouse"]

Next, one needs to switch to COM1 (port 0) in config_overlays.toml

[[overlay]]
name = "microsoft_serial_mouse"
    [overlay.serial_mouse]
    type = "Microsoft"
    # Port 0 - COM1
    # Port 1 - COM2
    port = 0

However, when I run paint, the screen blanks and it just sits there with the cursor in the upper left, blinking. Hitting 'q' exits, but the screen isn't painting. How do you setup MartyPC to emulate a VGA?

To get EGA running (VGA is semi broken) one needs to put ibm ega bios to media/roms folder inside Install folder
ibm_6277356_ega_card_u44_27128.bin.zip

@Vutshi
Copy link
Copy Markdown
Contributor

Vutshi commented Apr 9, 2025

You can also try VGA by setting ibm_vga in martypc.toml and put the vga bios in the roms folder
ibm_vga.bin.zip

@ghaerr
Copy link
Copy Markdown
Owner Author

ghaerr commented Apr 9, 2025

Then how do I turn on/off the mouse, since it doesn't work automatically like QEMU with a mouse down in the window?

You can also try VGA by setting ibm_vga i

You mean with 'config_overlays = ["ibm_vga"]' ? Do I need an additional config_overlays = section for VGA? I don't want to mess with VGA if it doesn't work, I'm having enough trouble getting EGA to work.

Next, one needs to switch to COM1 (port 0)

Ok. Is there a way to get ELKS kernel serial output on COM1 for debug statements? On QEMU I normally set serial console to COM1 to get debug statements and then have the mouse set to COM2, for just that reason.

@ghaerr
Copy link
Copy Markdown
Owner Author

ghaerr commented Apr 9, 2025

And then how do you get it to remember the floppy image that you selected? It doesn't remember the last setting, I have to manually select the floppy from elks/image/fd.img each time?

@ghaerr
Copy link
Copy Markdown
Owner Author

ghaerr commented Apr 9, 2025

Ok I have EGA working and Paint paints (interestingly enough for its cycle-accuracy, it seems the display aspect is not the same, the circles are now slight ovals), and the mouse cursor shows, but haven't figured out how to attach/disattach the mouse nor how to remember the floppy image. Thank you!

Tried below but didn't work:

[emulator.media]
filename = "../image/fd2880.img"

@Vutshi
Copy link
Copy Markdown
Contributor

Vutshi commented Apr 9, 2025

Then how do I turn on/off the mouse, since it doesn't work automatically like QEMU with a mouse down in the window?

You can double click on the emulated screen to attach mouse and middle click to release it. The latter doesn't work on my MacBook because there is no middle click on a trackpad. That is why there is ctrl+F10 to turn on/off the mouse. One con also change the keys in a config file

@Vutshi
Copy link
Copy Markdown
Contributor

Vutshi commented Apr 9, 2025

Ok. Is there a way to get ELKS kernel serial output on COM1 for debug statements?

I don't know. There is a lot of debug information in the drop-down menu. Also MartyPC has a discord channel where you can ask @dbalsom directly.

@Vutshi
Copy link
Copy Markdown
Contributor

Vutshi commented Apr 9, 2025

And then how do you get it to remember the floppy image that you selected? It doesn't remember the last setting, I have to manually select the floppy from elks/image/fd.img each time?

I never figured that out. I click every time on a required floppy manually :)))

@ghaerr
Copy link
Copy Markdown
Owner Author

ghaerr commented Apr 9, 2025

That is why there is ctrl+F10 to turn on/off the mouse. One con also change the keys in a config file

Got that working, thanks. But after double-clicking on screen and capturing mouse, mouse still doesn't show any events.
I suppose I have config file setup incorrect, but still not working with:

[[overlay]]
name = "microsoft_serial_mouse"

[overlay.serial_mouse]
type = "Microsoft"
# Port 0 - COM1
# Port 1 - COM2
port = 0 

The MartyPC error message scroll horizontally at the bottom of the screen too fast to read.

I never figured that out. I click every time on a required floppy manually :)))

Yeah, for all the work that went into MartyPC, it's not very user friendly.

@Vutshi
Copy link
Copy Markdown
Contributor

Vutshi commented Apr 9, 2025

it seems the display aspect is not the same, the circles are now slight ovals

Well, 640x350 image is stretched to 4:3 aspect ratio...

@Vutshi
Copy link
Copy Markdown
Contributor

Vutshi commented Apr 9, 2025

Yeah, for all the work that went into MartyPC, it's not very user friendly.

It is still a very early version. There are many things to do. It got mouse only recently as far as I understand, fancy floppy drive support which can deal with copy protection, no real VGA still...

@Vutshi
Copy link
Copy Markdown
Contributor

Vutshi commented Apr 9, 2025

The MartyPC error message scroll horizontally at the bottom of the screen too fast to read.

Agree

@Vutshi
Copy link
Copy Markdown
Contributor

Vutshi commented Apr 9, 2025

[[overlay]]
name = "microsoft_serial_mouse"

[overlay.serial_mouse]
type = "Microsoft"
#Port 0 - COM1
#Port 1 - COM2
port = 0

which file did you edit?

@ghaerr
Copy link
Copy Markdown
Owner Author

ghaerr commented Apr 9, 2025

which file did you edit?

martypc.toml, the same one I've been editing

@ghaerr
Copy link
Copy Markdown
Owner Author

ghaerr commented Apr 9, 2025

What's the double [[ for in [[overlays]] ? Why not just single [overlays] ? I find that confusing.

@Vutshi
Copy link
Copy Markdown
Contributor

Vutshi commented Apr 9, 2025

which file did you edit?

martypc.toml, the same one I've been editing

Not this. Go to /configs/machines/config_overlays.toml and Microsoft mouse overlay is already defined there. You just need to change port

@Vutshi
Copy link
Copy Markdown
Contributor

Vutshi commented Apr 9, 2025

What's the double [[ for in [[overlays]] ? Why not just single [overlays] ? I find that confusing.

I find many Rust-related things confusing. As well as C-related things. The only non confusing things are Fortran, Python, and Mathematica :)

@dbalsom
Copy link
Copy Markdown

dbalsom commented Apr 9, 2025

And then how do you get it to remember the floppy image that you selected? It doesn't remember the last setting, I have to manually select the floppy from elks/image/fd.img each time?

I never figured that out. I click every time on a required floppy manually :)))

If I interpreted this correctly, you want the last used disk image that was mounted to be remembered and re-mounted the next time the emulator is started?

@Vutshi
Copy link
Copy Markdown
Contributor

Vutshi commented Apr 9, 2025

If I interpreted this correctly, you want the last used disk image that was mounted to be remembered and re-mounted the next time the emulator is started?

That would be very useful!

@dbalsom
Copy link
Copy Markdown

dbalsom commented Apr 9, 2025

What's the double [[ for in [[overlays]] ? Why not just single [overlays] ? I find that confusing.

double brackets in TOML represent arrays. The file defines an array of overlays.

@dbalsom
Copy link
Copy Markdown

dbalsom commented Apr 9, 2025

The MartyPC error message scroll horizontally at the bottom of the screen too fast to read.

Agree

Are you talking about the notification widget in the bottom right that pops up, or the console log scroll?

@ghaerr
Copy link
Copy Markdown
Owner Author

ghaerr commented Apr 9, 2025

Are you talking about the notification widget in the bottom right that pops up

The bottom right stuff that shows for a few seconds then disappears. This happens when selecting a drive manually, and by the time you get to try to read the messages, they are gone. IMO they would be better either not displayed, or be able to be scrolled back, if there's something important to read.

When the emulator starts up, there's so much debug info, but the important thing for the user is which image is mounted, which isn't displayed anywhere, or at least I don't see it. Can that be passed as an argument?

I suppose all this is related to what an emulator would be used for. For ELKS, I use it to test new images, and it is nice to be able to change images (i.e. floppy sizes, etc) without editing a configuration file, and certainly without having to run a GUI.

Also what would be nice is not having to wait through the boot process every startup, but I suppose that's not easily possible given the emulator is bare CPU and interprets the BIOS startup code as well. Again, I suppose differing requirements for different uses.

@dbalsom
Copy link
Copy Markdown

dbalsom commented Apr 9, 2025

Yeah, for all the work that went into MartyPC, it's not very user friendly.

I am sorry you are frustrated. I am doing the best I can, and continually trying to make things easier to use. It is a lot of work for one person, and sometimes I feel overwhelmed.

@Vutshi
Copy link
Copy Markdown
Contributor

Vutshi commented Apr 9, 2025

The MartyPC error message scroll horizontally at the bottom of the screen too fast to read.

Agree

Are you talking about the notification widget in the bottom right that pops up, or the console log scroll?

Yes, that blue pesky message in the bottom right sometimes is too quick to read

@dbalsom
Copy link
Copy Markdown

dbalsom commented Apr 9, 2025

Yes, that blue pesky message in the bottom right sometimes is too quick to read

Okay, I can make them stay on the screen longer.

@ghaerr
Copy link
Copy Markdown
Owner Author

ghaerr commented Apr 9, 2025

Another very useful something (which MartyPC may already have) is the ability to support displaying serial output from the guest somewhere. With QEMU, this can be set to just scroll onto the terminal which started the emulator. This allows displaying debug output to say, COM1 or COM2, while the mouse is operating on another port.

I am sorry you are frustrated. I am doing the best I can, and continually trying to make things easier to use. It is a lot of work for one person, and sometimes I feel overwhelmed.

I'm not really, it is always hard for me to learn something new. You've done a fantastic job, I saw @Vutshi's screenshot of the emulator running an instruction trace, very cool! Can't wait to figure how to turn that on.

I would suggest that most all options (e.g. EGA, VGA etc) be preset somewhere, even if turned off, so that one can quickly learn by scanning the config file. It is very hard to learn when there is a directory hierarchy and multiple configuration files, initially one has no idea where to look.

And I'm using a macOS artifact build, so I'm not sure everything is included as in a normal installation, since I can't build directly on my laptop.

These are only my very first thoughts, please don't take them personally, the actual look and feel of the emulator on-screen looks very very nice and the multi-window output seems pretty neat also. I understand what a huge effort it is to get something like this even built, let alone working. I am excited to learn more about MartyPC.

@dbalsom
Copy link
Copy Markdown

dbalsom commented Apr 9, 2025

Are you talking about the notification widget in the bottom right that pops up
The bottom right stuff that shows for a few seconds then disappears. This happens when selecting a drive manually, and by the time you get to try to read the messages, they are gone. IMO they would be better either not displayed, or be able to be scrolled back, if there's something important to read.

I can slow down the notification expiry, and I can add an notification history where you can view notifications you may have missed. I don't want to get rid of them as I find them personally useful.
If anything, I could put it behind a flag so you can disable them if you don't like them.

Before they were implemented, there was no indication in the UI that anything worked or failed, you'd have had to check the log, so I found the notification system to be a big improvement.

When the emulator starts up, there's so much debug info, but the important thing for the user is which image is mounted, which isn't displayed anywhere, or at least I don't see it. Can that be passed as an argument?

the currently mounted image should be in the floppy drive menu, by the eject button:
image

This shows us that "Outrun.img" is mounted

As far as a command line argument, there isn't one, but one can be specified in the config like so:

[[emulator.media.floppy]]
# Floppy image to mount into drive 0 (Typically A:)
drive = 0
filename = "./media/floppies/Demos/Area 5150 (Compo Version).img"

I can add the command line option too if it would be useful.

I suppose all this is related to what an emulator would be used for. For ELKS, I use it to test new images, and it is nice to be able to change images (i.e. floppy sizes, etc) without editing a configuration file, and certainly without having to run a GUI.

I am a bit confused on this point. one MartyPC is running you can change images all day long; from the quick access menu, or by browsing for a file. But you don't want to have to run a GUI? You want to specify everything on the command line and just get a plain window with the video?

Also what would be nice is not having to wait through the boot process every startup, but I suppose that's not easily possible given the emulator is bare CPU and interprets the BIOS startup code as well. Again, I suppose differing requirements for different uses.

There are some potential features I have thought about for such problems, such as running the emulation at 250% speed until it hits the system bootstrap address.

@ghaerr
Copy link
Copy Markdown
Owner Author

ghaerr commented Apr 9, 2025

there isn't one, but one can be specified in the config like so:

Oh great, that will work well :)

I can add the command line option too if it would be useful.

Since the boot image itself is likely different for every use or MartyPC, I would say that having a command line option would be extremely useful!

the currently mounted image should be in the floppy drive menu, by the eject button:

Good to know. My suggest was that, since there's so much being displayed on the console by MartyPC anyways, why not also show the boot image, since that confirms to the user what is actually being booted. I would assume that a command line option would override the config file filename=, for instance, so a confirmation would be good.

one MartyPC is running you can change images all day long; from the quick access menu, or by browsing for a file.

Well, I'm an old UNIX programmer and use the command line all day long. Changing image locations by scrolling through a file open dialog is... well, very slow. Especially since I'm starting martypc from the command line anyways.

You want to specify everything on the command line and just get a plain window with the video?

I would definitely like to specify the most oft-changed option(s) on the command line, since I'm running from a command line. This would be the boot image, as described above. The window can remain as it is with menu drop downs, that's no big deal.
For users that don't run from the command line, I can understand they're used to slowly selecting through GUIs to setup everything, although in this case it appears that there is no "save configuration" so GUI users have to re-setup the emulator every time? (That's usually why I don't run GUIs, but I may be an old outlier :)

such as running the emulation at 250% speed until it hits the system bootstrap address.

That would be a GREAT command line or config option! :)

There is a community need for a cycle-accurate emulator: in fact this is the reason I'm setting up MartyPC, because @Vutshi and I are trying to speed up Paint (BTW, its 10x faster than before when you tried it!). I'm making small adjustments in 8088 ASM code and am trying to be able to discern some draw-speed differences without using real hardware. QEMU just doesn't work well for that, and many of the other emulators are way too hard to setup. Yes, MartyPC has been relatively easy to setup, it just needs a little fine-tuning and presets in config files and you're there :)

Back to the community use case: having a cycle-accurate emulator that can be run on the command line out of the box with a few options would be fantastic, as there just isn't anything out there that does that. The kinds of things I'm suggesting would be typical very basic options like the following command line suggests, with no config edits required:

martypc -fda=image/fd1440.img -boot=fast -video=ega -mouse=com1 -stdio=com2

or something like that.

Thank you for your comments!

@dbalsom
Copy link
Copy Markdown

dbalsom commented Apr 10, 2025

although in this case it appears that there is no "save configuration" so GUI users have to re-setup the emulator every time? (That's usually why I don't run GUIs, but I may be an old outlier :)

This is sort of a result of the TOML parser library i'm using not having the ability to write back to the TOML file without destroying all the comments and ordering in it. I have been experimenting with a different TOML parser that can, but using it is a bit more laborious as it constructs a large dictionary.

Plus it's surprisingly difficult to ascertain what options should change. For example, maybe you always want to play Frog Fractions, so you specify Frog Fractions Disk 1 in the configuration. MartyPC loads up and starts the game - great, but at some point while playing you have to put in Frog Fractions Disk 2. Now if I save that to the config, the next time will load Disk 2 and won't boot. Is that a problem itself? I could add yet another option to the config, like "save_last_loaded_image" if that's what you want.

I have also been dabbling with the idea of defining "workspace" configurations, which save any customizations you've made from the main configuration, like window positions, breakpoints, images loaded, etc.

I have also thought about adding a "recent images" menu for quick access to the last N images you loaded, and that could be saved in the config.

Making a good user interface is not easy!

martypc -fda=image/fd1440.img -boot=fast -video=ega -mouse=com1 -stdio=com2

I'm unlikely to copy linux device names exactly. The IBM PC can actually support up to 8 floppy drives which is crazy but I want to be able to support esoteric things like that. I think using numbers 0-7 is more clear to people with no linux experience

martypc --floppy0="path/to/your/image"

We could also make a generic mount directive, and specify the device as sort of a uri

martypc --mount="floppy0:/path/to/your/image"

We have lots of things we could want to "mount", PCjr cartridges, floppy disks, VHD images, even cassettes, (someday) CD-ROMS, etc?

You can currently select the video mode on the command line, via my config overlay system, so
martypc --machine-config-overlays=ibm_ega will start the system in EGA mode. It's a bit wordy so maybe I could make 'overlays' an alias to that.

Overlays can add a lot of hardware with associated options quite easily, assuming they are defined. I have overlays now for a mouse on com1 or com2, so,
martypc --overlays=ibm_ega,microsoft_serial_mouse_com1 is already possible.

I think the overlay system is very powerful but I need to document it better and expand on it. It is not clear what your options even are for adding overlays unless you go poking around in the overlay definitions.

Anyway, this making this issue thread wildly off-topic. I have a discord here https://discord.gg/8Gv7mVz4CC where I'd be happy to have you, you could give me direct feedback there and watch development progress.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants