Amiga.org

Amiga News and Community Announcements => Amiga News and Community Announcements => Amiga Programming and Development => Topic started by: ssolie on September 30, 2015, 05:50:17 PM

Title: AmigaOS and the Console Development - Part 1
Post by: ssolie on September 30, 2015, 05:50:17 PM
There is a new blog on how the Amiga's console evolved from 68K assembly to PowerPC.

See http://blog.hyperion-entertainment.biz/
Title: Re: AmigaOS and the Console Development - Part 1
Post by: eliyahu on September 30, 2015, 06:22:47 PM
@ssolie

since i spend so much time in the shell, i'm looking forward to reading the next installment. the new console in final edition is so much nicer than kingcon (which i had used before). tony did a really nice job. :)

-- eliyahu
Title: Re: AmigaOS and the Console Development - Part 1
Post by: Pyromania on September 30, 2015, 07:20:02 PM
Nice read.
Title: Re: AmigaOS and the Console Development - Part 1
Post by: matthey on September 30, 2015, 08:06:16 PM
Code: [Select]
   //    lea    cd_RastPort(a6),a1
    //    move.b    cu_Mask(a2),rp_Mask(a1)
    IGraphics->SetWriteMask(rastPtr, unit->cu_Mask);

    //    moveq    #0,d0
    //    move.b    d6,d0
    //    LINKGFX    SetDrMd
    IGraphics->SetDrMd(rastPtr, oldMode);

Progress! The replacement code is probably 1/3 of the speed of the original. Calling functions has lots of overhead. The macros in includes/graphics/gfxmacros.h could be used from C as well.

Quote
The original 68K assembler version of the console occupied 16,212 bytes. Compare that with the last 68K C version (V50.26) which was 42,564 bytes! It just shows how squashed the assembler version was (but that C version did have some debug code as well).

... Also, the assembler version had been written to minimise code size, rather than to optimise speed or code legibility.

The 68k assembler code was optimized for size instead of speed yet the example shown is much faster and much smaller in assembler. Why don't they just write the code in C++ (for better maintainability) also and see if they can make a semi-modern $2000 PPC computer slower than a 25 year old 68060?

Edit: Also, the 5 lines of assembler code, if properly optimized, should be 4 lines on an existing 68k CPU and could be 3 lines on an enhanced 68k CPU.

Code: [Select]
   //    move.b    cu_Mask(a2),rp_Mask+cd_RastPort(a6) ; this works on existing 68k
    IGraphics->SetWriteMask(rastPtr, unit->cu_Mask);

    //    mvz.b    d6,d0  ; ColdFire instruction
    //    LINKGFX    SetDrMd
    IGraphics->SetDrMd(rastPtr, oldMode);
Title: Re: AmigaOS and the Console Development - Part 1
Post by: kamelito on September 30, 2015, 08:19:55 PM
Nice read can we see episode 2? :)

Kamelito
Title: Re: AmigaOS and the Console Development - Part 1
Post by: ssolie on September 30, 2015, 08:35:53 PM
Quote from: kamelito;796655
Nice read can we see episode 2? :)

We are working on it now. It shouldn't be too long.
Title: Re: AmigaOS and the Console Development - Part 1
Post by: amigakit on September 30, 2015, 08:38:20 PM
A very interesting read.  Thanks!
Title: Re: AmigaOS and the Console Development - Part 1
Post by: guest11527 on October 01, 2015, 01:23:44 AM
Quote from: matthey;796652
Progress! The replacement code is probably 1/3 of the speed of the original.
And why do you bother? Is this in a speed-critical part of the device? Even worse, the assembler function does not go through an interface, hence anything that probably sits on top of SetWriteMask() is ignored.

Despite all that, the best optimization *here* would have been to simply drop the SetWriteMask() alltogether. The reason why the console.device uses this trick is to speed up scrolling in case the current color selection only requires a single plane to be modified, but everything on the PPC does not use planar graphics in first place, so any attempt to modify the write mask will make the code slower.

So yes, the translation to C code is probably well-intended, the 1/3 speed of a C function call is surely not relevant here. What is relevant is that this function is - for any sane graphics organization - useless and the whole code part that depends on this should have better been moved to trash in first place.

The speed critical part was not the function call, but the problem it solved in first place, a problem absent at the target platform.

Again, this rather shows that such a low-level view on optimizations is highly misleading.

Quote from: matthey;796652
Calling functions has lots of overhead. The macros in includes/graphics/gfxmacros.h could be used from C as well.
But would not have isolated the interface as well. Anyhow, neither the macro nor the function call is the right solution. The right solution here is to learn what the purpose of the write mask was in first place, and that it serves no purpose on the target platform.

Quote from: matthey;796652
The 68k assembler code was optimized for size instead of speed yet the example shown is much faster and much smaller in assembler. Why don't they just write the code in C++ (for better maintainability) also and see if they can make a semi-modern $2000 PPC computer slower than a 25 year old 68060?
With C++ code, the code would have been better, and probably faster than the C code, but as always, "faster" does not come with the language automatically, it comes with "understanding the problem" that is to be solved. Neither C, C++ or assembler do that by themselves. C++ helps because it allows you to get a cleaner view on the problem. Here, however, the actual problem was not understood correctly, and the code was "blindly" translated to C.


Quote from: matthey;796652
Edit: Also, the 5 lines of assembler code, if properly optimized, should be 4 lines on an existing 68k CPU and could be 3 lines on an enhanced 68k CPU.
That's just a useless micro-optimization. It wouldn't have created any noticable difference. Setting the mask on a planar graphics system - *that* makes a noticable difference. Instead, setting a mask on a chunky graphics system is a notable pessimisation because the graphics emulation has much more work to emulate the mask in first place. It is not "how to set the mask" that makes the console faster or slower.

It is "why do I need this code" that makes the difference. The analysis here should have showed "No, I do not need this code". In fact, this would probably have been more obvious if the code would have been in a high-level language in first place - instead the author got lost in details.
Title: Re: AmigaOS and the Console Development - Part 1
Post by: kolla on October 01, 2015, 05:21:54 AM
I just want a console-handler with a wee bit of scroll back buffer and tab competition that can be put in kickstart even on a 68000, for those occations when I boot without startup-sequence. Or rather, tab-expansion in shell and only scroll back buffer in console-handler. For what it is worth, AROS has something like this already, "real" AmigaOS is lacking behind these days.
Title: Re: AmigaOS and the Console Development - Part 1
Post by: matthey on October 01, 2015, 06:32:20 AM
Quote from: Thomas Richter;796669
And why do you bother? Is this in a speed-critical part of the device? Even worse, the assembler function does not go through an interface, hence anything that probably sits on top of SetWriteMask() is ignored.


The macros are perfectly legal and they are a lot faster. Is it better coding practice to use slower code for little if any benefit? It is true that the macros don't go through the LVO so a setpatch couldn't replace the code but this is true of much of the AmigaOS. It didn't stop P96/CGFX from patching everything. Your newest layers.library still uses the Forbid/Permit macros in most places instead of the function calls. Also, some of your layers.library function calls go through the LVO and some use a regular BSR instruction. It looks pretty inconsistent to me.

Quote from: Thomas Richter;796669

Despite all that, the best optimization *here* would have been to simply drop the SetWriteMask() alltogether. The reason why the console.device uses this trick is to speed up scrolling in case the current color selection only requires a single plane to be modified, but everything on the PPC does not use planar graphics in first place, so any attempt to modify the write mask will make the code slower.


AmigaOS 4.x can be used on a CSPPC with AGA graphics so maybe it is not completely useless. There is sometimes a cost to backward compatibility.

Quote from: Thomas Richter;796669

So yes, the translation to C code is probably well-intended, the 1/3 speed of a C function call is surely not relevant here. What is relevant is that this function is - for any sane graphics organization - useless and the whole code part that depends on this should have better been moved to trash in first place.


A couple of functions aren't going to make much of a difference. I just found it funny that the example wasn't consistent with the article comments. It is also funny that the 68k AmigaOS with all its optimizing for space really wasn't so well optimized from their example either.

Quote from: Thomas Richter;796669

The speed critical part was not the function call, but the problem it solved in first place, a problem absent at the target platform.

Again, this rather shows that such a low-level view on optimizations is highly misleading.


Yea, but you wouldn't have removed the call because the code is working. I know you too well. Making the safe optimizations to gain what I could while leaving planar support intact sounds pretty good to me. It would be better if the code was in C with the programmer using the macros and the compiler doing the optimizations though. This is not speed critical code after all ;).

Quote from: Thomas Richter;796669

With C++ code, the code would have been better, and probably faster than the C code, ...


Not likely faster. Not likely at all. Better is debatable.
Title: Re: AmigaOS and the Console Development - Part 1
Post by: olsen on October 01, 2015, 11:10:37 AM
Quote from: matthey;796682
AmigaOS 4.x can be used on a CSPPC with AGA graphics so maybe it is not completely useless.

Wait -- the operating system allocates chip memory bitmaps in a particular manner. The bitplanes are interleaved, which means that a single line of the bitmap is stored consecutively in memory. See the Leo Schwab article on page 10 for an explanation of how interleaving works: https://archive.org/details/AmigaWorld_Tech_Journal_Volume_2_Number_1_1992-02_IDG_Communications_US

This is an optimization to allow for blitter operations to move bigger chunks of data in a single operation, rather than breaking them up into several separate operations. For example, if the bitmap is non-interleaved, the blitter is reinitialized and restarted for each single bit plane. In interneaved form the blitter is initialized and started only once. As a side-effect, the update minimizes flickering. The update can also use more bandwidth (one big chunk vs. up to 8 smaller chunks).

Now, what exactly will SetWriteMask() do in this situation? It has the effect of making display updates more costly if an interleaved bitmap is used (which is the standard case). Instead of moving one consecutive chunk of bitmap data, the blitter operations have to be broken up into individual planes again. Available bandwidth is used less effectively. This can be noticeably slower.
Title: Re: AmigaOS and the Console Development - Part 1
Post by: guest11527 on October 01, 2015, 03:51:52 PM
Quote from: kolla;796680
I just want a console-handler with a wee bit of scroll back buffer and tab competition that can be put in kickstart even on a 68000, for those occations when I boot without startup-sequence. Or rather, tab-expansion in shell and only scroll back buffer in console-handler. For what it is worth, AROS has something like this already, "real" AmigaOS is lacking behind these days.

What's the problem with ViNCEd?
Title: Re: AmigaOS and the Console Development - Part 1
Post by: guest11527 on October 01, 2015, 04:13:29 PM
Quote from: matthey;796682
The macros are perfectly legal and they are a lot faster.  
Please define "a lot". Or rather, take your time and benchmark console with the macro and without it, measure the difference and tell me. I haven't done that, admittedly, but just from your gut, what would you expect? 10% speed improvement? Not seriously. My gut feeling is: Below the statistical error. Way below. Don't waste your time in details.  
Quote from: matthey;796682
Is it better coding practice to use slower code for little if any benefit?  
Compatibility? Readability? Maintainability? Actually, that's quite worth something. What I do not like about macros is that they require knowledge of the implementation details to work. In other words, they expose the internal structure you are manipulating to the compiler, making it impossible to change that without recompiling the code. Again, admittedly, it's already too late for graphics to fix that, graphics is all over with code that exposes internal interfaces where it should not, but please! can we avoid this problem in future code somehow? There are interface functions, and here we have a perfectly fine "setter" function for an internal property. It's good practice to use that.  
Quote from: matthey;796682
Your newest layers.library still uses the Forbid/Permit macros in most places instead of the function calls.  
No. Actually, in one single place, and that was replaced by a semaphore in Os 4 anyhow (by Olsen). Again, you're looking at the details and not at the problem. The problem that is solved here (in the function using the Forbid()-locking) is creating a layer-info global stack of cliprects, thus avoiding a wasteful memory allocation, and hence avoiding memory fragmentation whenever possible. That makes a difference, though probably not for layers directly. Ideally, this could be a semaphore, but given that only a single pointer linkage requires protection, this might arguably an overshoot. The real reason why there is no semaphore is that back then I didn't know where to put that semaphore. It should be a layerinfo-relative semaphore (since that's where the cliprects belong to), but there is no room in the layerinfo anymore. It could be a global semaphore, but that means that one layer info can lock out another layer info, same as with forbid-locking. So there is not really a clear advantage of semaphores here either.  
Quote from: matthey;796682
Also, some of your layers.library function calls go through the LVO and some use a regular BSR instruction. It looks pretty inconsistent to me.
That depends on the function, and is pretty much a choice the original designers of layers took (mostly). Given that layers is patched over by many places, it's not a good idea to mess with that overly. If you have a patch on top of a layer function, you'd probably better make sure to know when precisely that is called, and the patch - in some cases - should not be called for internal functioning of layers. Again, I outright admit that I do not understand the logic by which layers does or does not call through its external interface, but given that patches and programs may depend on exactly the choices that have been taken by our ancestors (ehem), it should probably stay that way.    
Quote from: matthey;796682
A couple of functions aren't going to make much of a difference. I just found it funny that the example wasn't consistent with the article comments. It is also funny that the 68k AmigaOS with all its optimizing for space really wasn't so well optimized from their example either.
No, it's not a particularly good example. Or rather, it wasn't made quite clear by the article why that choice was a good choice and helped making console better. From a software design perspective, it *might* have been a good example, but it would have been an even better example to explain why that function call should be removed in first place.  
Quote from: matthey;796682
Yea, but you wouldn't have removed the call because the code is working. I know you too well. Making the safe optimizations to gain what I could while leaving planar support intact sounds pretty good to me. It would be better if the code was in C with the programmer using the macros and the compiler doing the optimizations though.  
Maybe I've done too much C++, but I wouldn't pick macros if there is a call interface. Macros are fine for internal interfaces, really. But for something you expose to the global world, they are a particularly bad choice. Again, too late for poor gfx anyhow.    
Quote from: matthey;796682
Not likely faster. Not likely at all. Better is debatable.

"Better" requires a metric you measure quality with (oh boy, I'm again talking as if in a JPEG meeting again, same problem all over!). "Running speed" and "code size" are two of them, but not necessarily the most important ones. Something I did not understand back then either, again admittedly. But if you want to maintain code over a longer period of time, and want to update it if you need to, you'd better make sure that you have robust interfaces and a well-documented code, and code that speaks for itself. Assembler doesn't quite fit into this picture, and macros neither.
Title: Re: AmigaOS and the Console Development - Part 1
Post by: Georg on October 01, 2015, 05:05:58 PM
Quote from: Thomas Richter;796700
What's the problem with ViNCEd?


The name!!! The worst one you could possibly come up with. Really!
Title: Re: AmigaOS and the Console Development - Part 1
Post by: guest11527 on October 01, 2015, 05:21:43 PM
Quote from: Georg;796704
The name!!! The worst one you could possibly come up with. Really!

Would "VeryNewCon"  be better? That's the initial name it was.
Title: Re: AmigaOS and the Console Development - Part 1
Post by: kolla on October 01, 2015, 09:17:25 PM
Quote from: Thomas Richter;796700
What's the problem with ViNCEd?


Can I put it in kickstart?

Really, the problem with ViNCEd is that it is "too much". I am sure it has brilliant terminal emulation, but what is the point when there is no good ssh implementation?
Title: Re: AmigaOS and the Console Development - Part 1
Post by: kolla on October 01, 2015, 09:25:43 PM
Apropos - Thank you Olsen for Term! I've been using it a lot lately, on MIST and Minimig, zmodem ftw :)
Title: Re: AmigaOS and the Console Development - Part 1
Post by: kolla on October 01, 2015, 09:28:19 PM
Quote from: Thomas Richter;796700
What's the problem with ViNCEd?


Quote from: Thomas Richter;796706
Would "VeryNewCon"  be better? That's the initial name it was.


Just VCON? ViNCEd, it is neither vi nor ced, who knows what the "acronym" is supposed to mean? And the casing? Crazy.
Title: Re: AmigaOS and the Console Development - Part 1
Post by: matthey on October 01, 2015, 09:39:10 PM
Quote from: olsen;796689
Now, what exactly will SetWriteMask() do in this situation? It has the effect of making display updates more costly if an interleaved bitmap is used (which is the standard case). Instead of moving one consecutive chunk of bitmap data, the blitter operations have to be broken up into individual planes again. Available bandwidth is used less effectively. This can be noticeably slower.

Good explanation. So the SetWriteMask() is only an optimization for non-interleaved planar bitmaps? It now sounds like SetWriteMask() should be removed in all cases this "optimization" is used for AmigaOS 3+.

Quote from: Thomas Richter;796702
Please define "a lot". Or rather, take your time and benchmark console with the macro and without it, measure the difference and tell me. I haven't done that, admittedly, but just from your gut, what would you expect? 10% speed improvement? Not seriously. My gut feeling is: Below the statistical error. Way below. Don't waste your time in details.

I was talking about the macros vs the functions not the overall code speed which would be difficult to measure (it waits most of the time but should be fast when it doesn't wait). If you look at the macro vs function code on say the 68060, the overhead of a function through the LVO is at least 14 cycles (ignoring cache misses where inlined code like the macro has an advantage) for the JSR+JMP+RTS. For short functions like SetWriteMask() where the code is only a couple of cycles, this is significant. There is more overhead in setting up for a function call than using the macro also. The newer PPC processors are likely to have a link stack which might cut the function overhead in half but the macro is still significantly faster.

Quote from: Thomas Richter;796702
Compatibility? Readability? Maintainability? Actually, that's quite worth something. What I do not like about macros is that they require knowledge of the implementation details to work. In other words, they expose the internal structure you are manipulating to the compiler, making it impossible to change that without recompiling the code. Again, admittedly, it's already too late for graphics to fix that, graphics is all over with code that exposes internal interfaces where it should not, but please! can we avoid this problem in future code somehow? There are interface functions, and here we have a perfectly fine "setter" function for an internal property. It's good practice to use that.

Compatibility is a false claim if the code works fine with the macros (the original did). Readability is arguable. I agree that the library functions have maintenance advantages which is valuable. IMO, it comes down to maintenance vs speed. Maintenance may be the better choice on powerful processors but then some of the speed and responsiveness advantage the AmigaOS gives is lost so now a faster CPU is needed to make up for it. Maybe that would be ok if people weren't comparing a PPC Amiga with 20 year old embedded PPC CPU design to a modern PC with modern x86_64 CPU costing a fraction of the price.

Quote from: Thomas Richter;796706
Would "VeryNewCon"  be better? That's the initial name it was.

Why not ECON for Enhanced CON or Editor CON?
Title: Re: AmigaOS and the Console Development - Part 1
Post by: candyman on October 01, 2015, 09:39:39 PM
Too many technicalities... After two posts I have ceased to understand what you were talking about... :(

Anyway, may I suggest Miami ViNCEd? :)
Title: Re: AmigaOS and the Console Development - Part 1
Post by: Hans_ on October 01, 2015, 10:23:52 PM
@matthey
Quote
Good explanation. So the SetWriteMask() is only an optimization for non-interleaved planar bitmaps? It now sounds like SetWriteMask() should be removed in all cases for AmigaOS 3+.

Uh, no. We want to move away from people peeking and poking about in internal OS structures.

Hans
Title: Re: AmigaOS and the Console Development - Part 1
Post by: kolla on October 02, 2015, 12:26:50 AM
Why must it have a new name anyways, just want something that replaces CON: and RAW: and that is more capable - call it console.handler with an appropriate version string.
Title: Re: AmigaOS and the Console Development - Part 1
Post by: Duce on October 02, 2015, 07:48:33 AM
Good read, thanks for posting the link.
Title: Re: AmigaOS and the Console Development - Part 1
Post by: olsen on October 02, 2015, 09:36:41 AM
Quote from: matthey;796714
Good explanation. So the SetWriteMask() is only an optimization for non-interleaved planar bitmaps? It now sounds like SetWriteMask() should be removed in all cases this "optimization" is used for AmigaOS 3+.


It's not that terrible, really. The blitter works exactly like it always did regardless of whether you restart it several times over for each individual plane, or let it rip for a single consecutive chunk of memory which comprises all planes. Noticeable gains are only possible on an AGA machine (higher bandwidth). On an ECS machine the effects will be less pronounced. In Super72 mode at four colours, ECS already has so much trouble at hand that it cannot always detect if the blitter is still running :-(

Where the write mask makes a big difference, however, is with RTG screens. Instead of jush pushing chunky pixels around, CyberGraphX/Picasso96/etc. now have to treat the screen as if it were a real planar bitmap, so that only the relevant data is affected when text is rendered or scrolled. This requires significant extra effort.

Ironically, the "optimization" of restricting rendering operations to a single plane now cause exactly the opposite of the intended goal.
Title: Re: AmigaOS and the Console Development - Part 1
Post by: guest11527 on October 02, 2015, 12:07:15 PM
Quote from: matthey;796714
If you look at the macro vs function code on say the 68060, the overhead of a function through the LVO is at least 14 cycles (ignoring cache misses where inlined code like the macro has an advantage) for the JSR+JMP+RTS. For short functions like SetWriteMask() where the code is only a couple of cycles, this is significant. There is more overhead in setting up for a function call than using the macro also. The newer PPC processors are likely to have a link stack which might cut the function overhead in half but the macro is still significantly faster.

Excuse me, no, it's not. You seem to assume a program that does nothing except calling SetWriteMask() in a tight loop without doing anything else, so the program speed is dominated by function call vs. macro.

However, that's certainly not the case here. If the program would make such tight function calls, the argument would be all different and I would agree that this is possibly something to consider in worst case.  However, we're talking about probably 20 cycles vs. probably 5 cycles somewhere in the middle of a large program where the 20/5 difference is only relevant in a small percentage of the overall code coverage.

So, in other words, the whole argument is mood. Don't worry about problems you don't have in first place. The dominant problem here is coding style, and that outweights the hand full of cycles nobody is able to measure or notice.
Title: Re: AmigaOS and the Console Development - Part 1
Post by: QuikSanz on October 03, 2015, 02:51:08 AM
Looks like your saying macros are a disaster in the waiting, Virus entry point!
Title: Re: AmigaOS and the Console Development - Part 1
Post by: matthey on October 03, 2015, 05:28:27 AM
Quote from: kolla;796719
Why must it have a new name anyways, just want something that replaces CON: and RAW: and that is more capable - call it console.handler with an appropriate version string.


If the new handlers can be enhanced while maintaining full backward compatibility, then keeping the same name and bumping the version is appropriate. Otherwise, a new name is required so that programs needing compatibility can use the old handler.

Quote from: QuikSanz;796756
Looks like your saying macros are a disaster in the waiting, Virus entry point!


Actually, the macros would reduce the chances of a virus as there are less functions to hook into, not that this is a concern in this case. The concern about macros is that the program accesses the elements of structures instead of calling a function to do it. The OS developers may decide to change the structures and the functions with it. This is more object oriented and easier to maintain but also significantly slower. Most Amiga programs already access some OS structures directly, with or without macros, so changing the structures will break compatibility. The macros are no more a disaster than the majority of AmigaOS programs which use macros and access the structures directly. It may be unfortunate that so many OS structures were documented and modified directly but it was fast and easy. To go away from this would be to break direct compatibility and instead provide compatibility through a sandbox. This may be necessary if moving to a completely alien CPU architecture after PPC finishes dying off.
Title: Re: AmigaOS and the Console Development - Part 1
Post by: QuikSanz on October 03, 2015, 06:09:03 AM
No way to separate Internal and external macros will eventually kill arex?
Title: Re: AmigaOS and the Console Development - Part 1
Post by: guest11527 on October 03, 2015, 09:25:52 AM
Quote from: QuikSanz;796761
No way to separate Internal and external macros will eventually kill arex?

ARexx has nothing to do with the problem, completely unrelated.
Title: Re: AmigaOS and the Console Development - Part 1
Post by: kolla on October 03, 2015, 11:47:24 AM
I suppose the idea is "convinced".
Title: Re: AmigaOS and the Console Development - Part 1
Post by: wawrzon on October 03, 2015, 12:20:37 PM
Quote from: kolla;796768
I suppose the idea is "convinced".

kool!
Title: Re: AmigaOS and the Console Development - Part 1
Post by: psxphill on October 03, 2015, 12:25:43 PM
Quote from: olsen;796689
Now, what exactly will SetWriteMask() do in this situation? It has the effect of making display updates more costly if an interleaved bitmap is used (which is the standard case). Instead of moving one consecutive chunk of bitmap data, the blitter operations have to be broken up into individual planes again. Available bandwidth is used less effectively. This can be noticeably slower.

It won't be more costly in the standard case when only one bitplane is scrolled, if more than one is scrolled then the overhead is just waking the CPU up and getting it to kick off the next blit and in some cases you can do it with one blit anyway.

In fact not calling SetWriteMask() would make "the display updates more costly" in the "standard case" as "available bandwidth is used less effectively" (for the simple reason that you are copying up to 8 times the data with the blitter).

The way the autodoc is written I would only expect the call to only have an effect on planar screens, so there isn't a clear benefit to removing the call.
Title: Re: AmigaOS and the Console Development - Part 1
Post by: guest11527 on October 03, 2015, 01:15:41 PM
Quote from: psxphill;796770
The way the autodoc is written I would only expect the call to only have an effect on planar screens, so there isn't a clear benefit to removing the call.

Unfortuntely, this "non-standard case" you mention in this last sentence *is* the standard case for PPC, namely "chunky graphics". And that's exactly what the conversion to C was made for: The PPC "chunky graphics case". Believe me, you don't want your graphics software to emulate planar scrolling on chunky graphics, that is much more overhead than to scroll eight planes on a planar bitplane.
Title: Re: AmigaOS and the Console Development - Part 1
Post by: itix on October 03, 2015, 03:01:42 PM
Quote from: Hans_;796716
Quote

Good explanation. So the SetWriteMask() is only an optimization for non-interleaved planar bitmaps? It now sounds like SetWriteMask() should be removed in all cases for AmigaOS 3+.

Uh, no. We want to move away from people peeking and poking about in internal OS structures.


RastPort structure is not really an internal OS structure. For most purposes it is a parameter structure defining additional parameters to gfx operations. Drawing mode, write mask and so on could be just nth parameter to gfx operations and storing those parameters to rastport is a mere convenience to developers. From clean API design POV those parameters dont need separate getter and setter functions.

Introducing SetWriteMask() in Kickstart 3.0 was never necessary but just an example how CBM developers were lost in details.
Title: Re: AmigaOS and the Console Development - Part 1
Post by: guest11527 on October 03, 2015, 03:58:36 PM
Quote from: itix;796774
RastPort structure is not really an internal OS structure.  
Says who? Look, the problem with gfx all over is that it never documented which structures are internal, and which are not. Is a struct ViewPort an internal structure?

Hard to say. It is documented. Should it be documented? Probably not.
Quote from: itix;796774
For most purposes it is a parameter structure defining additional parameters to gfx operations. Drawing mode, write mask and so on could be just nth parameter to gfx operations and storing those parameters to rastport is a mere convenience to developers.
Really? So for example, what is the difference between the APen, which must be set with SetAPen() or it does not function correctly, and the WriteMask, which is poked into the structure but still works? Does it work by accident? By intention?

The difference between the APen and the WriteMask is an implementation detail: The APen forces a recomputation of the MinTerms, the WriteMask does not. But that's simply "how gfx works internally", and it's really not spelled out that explicitly. Somehow, "you have to know".

It really boils down to that: Gfx is a big piece of junk, it is exactly "how not to write software", namely not defining proper interfaces. Gfx leaves it pretty much unclear which part of it is an interface, and what is internal, and where which part stops.


Quote from: itix;796774
From clean API design POV those parameters dont need separate getter and setter functions.
From a clean API design POV, this structure should be undocumented, and you should use getters and setters. But gfx does not have an "API design". It is quickly hacked together, and it shows.


Quote from: itix;796774
Introducing SetWriteMask() in Kickstart 3.0 was never necessary but just an example how CBM developers were lost in details.

It is a necessary extension to create a somewhat clean interface for gfx, on a "best attempt" basis.

So for example, why would graphics card hardware have to read the write mask from the rastport? It could also store it somewhere else, in some other form. SetWriteMask() could very well be patched over, performing internal adjustments of whatever the graphics card software has to do.

Remember, SetAPen() also adjusts some internal graphics structures in "some way" you're not supposed to depend upon.

The difference between the APen and the WriteMask is really just an implementation artefact and not a "design choice".
Title: Re: AmigaOS and the Console Development - Part 1
Post by: itix on October 03, 2015, 04:43:12 PM
Quote from: Thomas Richter;796778
Says who? Look, the problem with gfx all over is that it never documented which structures are internal, and which are not. Is a struct ViewPort an internal structure?

Hard to say. It is documented. Should it be documented? Probably not.

From developer point of view ViewPort is not an internal structure. You just fill some data and pass pointer to MakeVPort(). Internally the OS could convert data to its own private, internal format. We know that the OS dont do that but it could have been designed to work like that...

Some parts work like this. For example to open window you can create NewWindow structure. Internally Intuition is not linking this structure to its private data but new structure, Window, is created instead. Unfortunately this structure is returned to the caller... but you get the idea. The struct NewWindow describes what you want and Intuition does its best to satisfy your request.

Quote
Really? So for example, what is the difference between the APen, which must be set with SetAPen() or it does not function correctly, and the WriteMask, which is poked into the structure but still works? Does it work by accident? By intention?

The difference between the APen and the WriteMask is an implementation detail: The APen forces a recomputation of the MinTerms, the WriteMask does not. But that's simply "how gfx works internally", and it's really not spelled out that explicitly. Somehow, "you have to know".

I know that SetAPen() calculates those silly minterms. But from implementation point of view there is no need to calculate this data in SetAPen(). Minterms could be calculated in drawing operations and results could be cached to some other private data structure.

In RTG systems SetAPen() is even less useful because there private minterms are not used anymore. However, at the time when SetAPen() is called it can't know this and it has to recalculate minterms just in case. If minterms were checked in RectFill()/Text()/whatever you could skip this minterm calculation when it is not needed by target bitmap.

Quote
It really boils down to that: Gfx is a big piece of junk, it is exactly "how not to write software", namely not defining proper interfaces. Gfx leaves it pretty much unclear which part of it is an interface, and what is internal, and where which part stops.

I agree.

Quote
From a clean API design POV, this structure should be undocumented, and you should use getters and setters. But gfx does not have an "API design". It is quickly hacked together, and it shows.

It depends. In Windows API you are passing loads of parameters through structures. They are just parameter containers, not internal OS structures that would be passed through to OS. RastPort should be just like this: a paremeter container.

Quote
So for example, why would graphics card hardware have to read the write mask from the rastport? It could also store it somewhere else, in some other form. SetWriteMask() could very well be patched over, performing internal adjustments of whatever the graphics card software has to do.

It can do that, even when setting write mask directly to rastport. For example when Text() is called the system could collect relevant parameters from RastPort to its own internal private structure and execute render function asynchronously on the target hardware.
Title: Re: AmigaOS and the Console Development - Part 1
Post by: psxphill on October 03, 2015, 05:19:14 PM
Quote from: Thomas Richter;796771
Believe me, you don't want your graphics software to emulate planar scrolling on chunky graphics

The autodoc for SetWriteMask says that the device can ignore you, but if for compatibility they emulate it then technically you do want it to be called as someone might have done something funky like draw a background in the console they don't want scrolled.

However using SetMaxPen instead is probably the better option.