• Updated 2023-07-12: Hello, Guest! Welcome back, and be sure to check out this follow-up post about our outage a week or so ago.

vpRowBytes in video card declaration ROM

ymk

Well-known member
I'm trying to understand the video parameter record structure.

From Designing Cards and Drivers for the Macintosh Family 3rd Edition 1992:

1697645735730.png

Does vpRowBytes describe the width of each visible line, or can it be greater?

For example, in a 640x480x256 mode, must vpRowBytes be 640?

If I set it to 1024, will the pixel at 0,2 have a 2048 byte offset from the start of the framebuffer?

In other words, would the framebuffer operate as a virtual 1024-wide buffer, with only the left-most 640 columns visible?
 

cheesestraws

Well-known member
Does vpRowBytes describe the width of each visible line, or can it be greater?

It can be greater - that field is purely about the memory layout, not the visual layout at all.

For example, in a 640x480x256 mode, must vpRowBytes be 640?

Nope, it can be arbitrarily (ish) big.

If I set it to 1024, will the pixel at 0,2 have a 2048 byte offset from the start of the framebuffer?

That sounds right to me, yes.

In other words, would the framebuffer operate as a virtual 1024-wide buffer, with only the left-most 640 columns visible?

Yes, precisely this, if you were in an 8-bit mode. If you were in a 4-bit mode, it would be a 2048-pixel wide (1024-byte wide) buffer with only the leftmost 640 columns visible.

Some code that might help here is the framebuffer wrangling code in my A/UX VNC server, around here: https://github.com/cheesestraws/aux...1fa12b72181f7655d2ada/app/frame_buffer.c#L169. Here I am copying out of the (mapped) video framebuffer into an application buffer the same as the visible size of the screen. (I get the size of the visible area of the screen from the A/UX video struct, but you could equally well get it from the vpBounds field of the video parameters struct that you cited above)
 

Melkhior

Well-known member
Does vpRowBytes describe the width of each visible line, or can it be greater?
It can be greater (or lower! at low depth), it's the number of bytes a row occupies - including potential padding if the hardware has some specific requirements.
For example, in a 640x480x256 mode, must vpRowBytes be 640?
No, but at least 640. For 640x480x1, minimum would be 80 - each byte contains 8 pixels.

If I set it to 1024, will the pixel at 0,2 have a 2048 byte offset from the start of the framebuffer?
Yes, that's the idea.

While pure 'dumb' framebuffer may not need such feature, it's quite useful when you accelerate if e.g. computing rectangle doesn't need complicated arithmetic, in particular multipliers. So in your example, you can find the offset via (row << 10), which is a lot easier to compute (and if fixed to a single value, doesn't even need to be computed per se) than (row * 640), as you need at least an adder (e.g. row << 512 + row << 128).

My 'Goblin' framebuffer doesn't use such tricks because the FPGA has plenty of hardwired DSP blocks with multipliers, might as well do something with them :)
 

Crutch

Well-known member
One of the things I love about this forum is that I can find a 2-hour old pretty obscure question about ‘90s Mac tech, and think “oh I know the answer, I will reply” and then realize that 2 people have already answered it. OK cool, nothing further to say here!

(If you run an Xceed Grayscale adapter on an SE/30 in 8-bit/pixel mode you will see that rowBytes is 1024 for the built-in 512x342 display, for example … not the 512 bytes you would expect.)
 

joevt

Well-known member
Some GPUs may use the extra bytes of a row for some purpose such as a hardware cursor (e.g. /chaos/control on Power Mac 8600).

I remember on a Macintosh LC with 12 inch RGB monitor and max VRAM, I could simulate a 1024x768 mode by using 512x384 mode and messing with the rowBytes, rects, pixelSize, and cmpSize of MainDevice, WMgrCPort, WMgrPort, DeskPort, CrsrPin, GrayRgn, etc. It didn't look great (the colors were wrong) but it was interesting.

This code is from 30 years ago. It creates 6 FKEYs (Command-Shift-4 to Command-Shift-9) that transform the display in different ways (zoom in, zoom out, etc). Some of the ways work on the Macintosh LC because of the way it sets up the real rowBytes (doubling the virtual height requires the real rowBytes to have space for two virtual rows of pixels while only displaying the even virtual rows). I don't remember all the details.
 

Attachments

  • ScreenDoubleMag.zip
    6.7 KB · Views: 1

ymk

Well-known member
Excellent. That's what I was hoping for. Thanks for the responses.

Here I am copying out of the (mapped) video framebuffer into an application buffer the same as the visible size of the screen.

That brings me to other questions:

Outside of screencap/VNC applications, how common is it for QuickDraw to read from the framebuffer?

What could break if a video card returned null reads?

Obviously, write performance is important for video hardware. How important are fast reads?
 

Phipli

Well-known member
Some GPUs may use the extra bytes of a row for some purpose such as a hardware cursor (e.g. /chaos/control on Power Mac 8600).

I remember on a Macintosh LC with 12 inch RGB monitor and max VRAM, I could simulate a 1024x768 mode by using 512x384 mode and messing with the rowBytes, rects, pixelSize, and cmpSize of MainDevice, WMgrCPort, WMgrPort, DeskPort, CrsrPin, GrayRgn, etc. It didn't look great (the colors were wrong) but it was interesting.

This code is from 30 years ago. It creates 6 FKEYs (Command-Shift-4 to Command-Shift-9) that transform the display in different ways (zoom in, zoom out, etc). Some of the ways work on the Macintosh LC because of the way it sets up the real rowBytes (doubling the virtual height requires the real rowBytes to have space for two virtual rows of pixels while only displaying the even virtual rows). I don't remember all the details.
Joevt, have you ever looked at the Toby style cards? Some of the documentation basically says the (paraphrasing from memory) "the card output is programmable, with defaults (i.e. the 13" Apple monitor) stored in ROM".

The implication is that through software you can tell the cards to output other resolutions, although you'd have to replace the pixel clock.

An interesting thing with this is that some of those early cards have... Two? Possibly even three clock footprints, with only one used.

Any thoughts? I'd love to add a 1024*768, 16 colour mode to my Macintosh II Video or "High Resolution" video card.

Tagging @bigmessowires for his interest
 

Arbee

Well-known member
You can freely reprogram the CRTC on the JMFB (4*8, 8*24 unaccelerated) cards, within the bounds of the pixel clock (which is also programmable) and how fast the framebuffer chip, VRAM, and RAMDAC can operate (1024x768 is likely pushing it).

MAME's emulation of the 4*8 style cards uses the parameters programmed by the firmware to set the mode.
 

cheesestraws

Well-known member
What could break if a video card returned null reads?

I'm not sure, but I think (and this is from memory, so verify it if it really matters!) qemu's quadra 800 emulation does not support reading back the framebuffer (which broke my VNC server). But that didn't seem to break anything else, so you might be in luck here. Though you are, strictly speaking, supposed to support reading.
 

Phipli

Well-known member
You can freely reprogram the CRTC on the JMFB (4*8, 8*24 unaccelerated) cards, within the bounds of the pixel clock (which is also programmable) and how fast the framebuffer chip, VRAM, and RAMDAC can operate (1024x768 is likely pushing it).
The 8•24 supports 1024x768 stock doesn't it? At a lower bit depth. I think 256 colours?

I'll check...
 

Phipli

Well-known member
You can freely reprogram the CRTC on the JMFB (4*8, 8*24 unaccelerated) cards, within the bounds of the pixel clock (which is also programmable) and how fast the framebuffer chip, VRAM, and RAMDAC can operate (1024x768 is likely pushing it).

MAME's emulation of the 4*8 style cards uses the parameters programmed by the firmware to set the mode.
If this pamphlet is right, it supports 1152*870, but not 1024*768. 1152*870 needs a 100Mhz pixel clock for the Mac timings, so that means it should be capable of doing 1024*768. Sounds like a good thing to do.
 

Attachments

  • macintosh-display-card-4-8-8-24-9003.pdf
    2.4 MB · Views: 3

Melkhior

Well-known member
Outside of screencap/VNC applications, how common is it for QuickDraw to read from the framebuffer?

Quite. Starting with scrolling, which are simply fb-to-fb copies if not double-buffered (I'm talking 7/8 here, likely older as well, dunno 9 but I'd expect similar). That's where acceleration is the most useful, as it avoid doing slow read-then-write over the bus (twice), the acceleration egine talks directly to the VRAM.

Modern systems can afford the memory and computations needed to double-buffer everything and do some compositions to the screen, but QD is a lot more frugal.

I'm not sure, but I think (and this is from memory, so verify it if it really matters!) qemu's quadra 800 emulation does not support reading back the framebuffer

The Qemu I have, which is from a while ago, did as far as I can remember when I did a virtual version of Goblin. Hardware registers have custom functions for read & write, but the memory is just a big buffer mapped by the I/O subsystem with no restriction that I can remember.

I don't think QuickDraw can really work without the ability to read back data from the FB.
 

cheesestraws

Well-known member
The Qemu I have, which is from a while ago, did as far as I can remember when I did a virtual version of Goblin. Hardware registers have custom functions for read & write, but the memory is just a big buffer mapped by the I/O subsystem with no restriction that I can remember.

Hm, I may be conflating this with something else, then. I'd believe your memory over mine. Thanks :)
 

Crutch

Well-known member
How does CopyBits from video memory to an arbitrary pointer work if you can’t read back the framebuffer?
 

joevt

Well-known member
Joevt, have you ever looked at the Toby style cards? Some of the documentation basically says the (paraphrasing from memory) "the card output is programmable, with defaults (i.e. the 13" Apple monitor) stored in ROM".

The implication is that through software you can tell the cards to output other resolutions, although you'd have to replace the pixel clock.

An interesting thing with this is that some of those early cards have... Two? Possibly even three clock footprints, with only one used.

Any thoughts? I'd love to add a 1024*768, 16 colour mode to my Macintosh II Video or "High Resolution" video card.

Tagging @bigmessowires for his interest
I remember creating code to dump Slot Manager resources but I didn't look into the display drivers and hardware registers until the Power Mac 8600. The Slot Manager includes old style 68K display drivers DRVR. The Power Mac 8600 uses PowerPC display drivers ndrv. I don't remember seeing sample code for old style 68K display drivers?

68K Mac display controllers have only a few pixel clock options so the resolutions you can choose would be limited by the refresh rates that a CRT will accept. Higher resolutions would require lower refresh rates if you can't increase the pixel clock. Lower resolutions would require higher refresh rates if you can't decrease the pixel clock.

How does CopyBits from video memory to an arbitrary pointer work if you can’t read back the framebuffer?
Normal Mac video framebuffer is readable so Copybits can do this in software.

For something like the Voodoo framebuffer that you can't normally read from, I suppose you would need to use some API that asks the hardware to transmit the framebuffer to host memory using DMA?
 

Phipli

Well-known member
Higher resolutions would require lower refresh rates if you can't increase the pixel clock. Lower resolutions would require higher refresh rates if you can't decrease the pixel clock.
You can likely add multiple, presumably selectable pixel clocks to the board, this shouldn't be an issue.selectable
I don't remember seeing sample code for old style 68K display drivers?
This contains example code I think?

https://vintageapple.org/inside_o/p...for_the_Macintosh_Family_2nd_Edition_1990.pdf

There are three editions in that website.
 

mcayland

Member
I'm not sure, but I think (and this is from memory, so verify it if it really matters!) qemu's quadra 800 emulation does not support reading back the framebuffer (which broke my VNC server). But that didn't seem to break anything else, so you might be in luck here. Though you are, strictly speaking, supposed to support reading.

The framebuffer is simply memory mapped, but I have a feeling we discussed this before - wasn't it one of the palette indexing registers? Should be quite trivial to implement, especially now the MacOS q800 changes are upstream :)
 

Arbee

Well-known member
If this pamphlet is right, it supports 1152*870, but not 1024*768. 1152*870 needs a 100Mhz pixel clock for the Mac timings, so that means it should be capable of doing 1024*768. Sounds like a good thing to do.
You're right, of course - it supports the Two Page Display, which I forgot about. So a custom declaration ROM should do it.
 

Arbee

Well-known member
The framebuffer is simply memory mapped, but I have a feeling we discussed this before - wasn't it one of the palette indexing registers? Should be quite trivial to implement, especially now the MacOS q800 changes are upstream :)
Congrats on getting that upstreamed! Is there some limitation to QEMU's internals that the framebuffer isn't just readable? And does QEMU handle the Turbo SCSI halting the processor on pseudo-DMA, or does the 53C9X cheat and just always accept data? That took me over a month to work out for MAME because we enforce real SCSI bus delays :)

DAFB isn't bad if you only target one generation and use Apple's built-in declaration ROM. It does get more interesting when you have to handle all 3 Quadra generations that used it (and eventually HPV).
 
Top