Tuesday, October 15, 2013

Its time to talk about optimizing code, so I was looking at Basilisk II code.

Its time to talk about optimizing code, so I was looking at Basilisk II code.

One think I noticed was was I did have his platform depended read and write functions.
So I found where they where used, this where used whit UAE CPU memory header by read and write functions for CPU core, and some where else, this where yet agin used some where else, by some other function.

As it happens my education was electronics and programing on microprocessors, it was impotent back then to reduce code due to slow CPU & MCU, micro controllers and micro processor units.

We used to use inline assembler and macros. So now I'm going to show you the magic power of macros, and how it can make big difference.

So this code show what was happening in Basilisk II, you have two loops typical when you filling or doing some graphic operation, so you have a main routine calling do_sum and do_sum calling sum, but this can be changed, this is how it works, so what do you do macros.

Now lets see what difference it made.

So we have 4096 ms (4 sec) before the change.
after the change we have 1091 ms (1 sec) 

so what we find is that 4096/1091 = 3.754. so the unoptimized code is 3.7 times slower or 375% slower.

so what is going on?

functions generate a lot of code, and they forces program to make jumps, jumps are considered expensive, often result in cache misses, next functions are designed to be isolated, variables from the previous code put on the stack to be later restored when you exit the function, function parameters are filled, to be letter read, by code inside the function, and when its all done it old variables are restored and the program exits the function.

So as you can understand its a lot of stuff that goes on when calling functions.

now when we rewrote it to use macros, the the macro is just replaced in the code before its compiled, the result is that that we only need to increment a variable by a value, and this in the main function.

Wednesday, September 25, 2013

So you have been waiting for Basilisk II 1.0

I'm going to tell you about latest changes for AmigaOS4.1

When we talk about Basilisk its emulator for MacOS7/MacOS8, the different versions the Basilisk II 1.0 was created more or less in 2001 to 2006, after this it was almost no changes to Amiga specific stuff.

jlachmann added video switching in 2001.
cebix did some work on SCSI support.
gbeauche added copy-paste of 'TEXT' from 2004

Basilisk 0.9 comes from Ilkka "itix" Lehtoranta it was ported to MorphOS back in 2005 form a older source code, later it was upgraded with a newer UAE CPU core (from 1.0), AmigaOS4 version was heavily based on 0.9 version for MorphOS, there where few problems whit difference between AmigaOS4 and MorphOS, but the main thing the MorphOS version made easier for me to know where changes things, because CPU emulated, unlike on a Classic Amiga, I also rewrote the MUI based GUI to Reaction, it was simple to do whit few macro changes, the difference between this two GUI systems are not that big they fundamentally work the same way.

The biggest difference is that 1.0 support screen modes, and so you switch resolution whit out quieting the emulator, there are some other thins too, it was much easier to quit 0.9 then 1.0, because 1.0 does some thing strange in the interpreter, recursive callbacks makes it hard to understand what is going on, so this version does not have a quit button.

I have put copied over platform specific code from 0.9 and replaced the incompatible source code whit 1.0 and updated it, some of the changes jlachmann, cebix and gbeauche did might have been lost in the process, as for core of Basilisk 1.0 has been updated to recently a lot of work has done on SDL stuff, we only use the audio part of SDL, because AHI stuff did not work.

So now there is compliantly new video code for AmigaOS4, based on AmigaOS3 code, I have also added the scroll wheel support form 0.9 video drivers, the rest is new code.

Video modes supported are 2 and 256 colors and 32bit, I have dropped the 16bit video mode for now because it has to be converted to 32bit in window mode (slow), maybe add it later.

I have also experimented whit composition because its hardware accelerated, and enables fast scaling, its nice to be able to make where large window smaller, or small window whit low resolution bigger, if your playing a old game.

Disk images has been upgraded, whit support for read only disk images,
you can now also create disk images from the GUI, I have also done few more improvements to the GUI.

Virtual Amiga volume thing, is kind of buggy if you delete .finf and .rsrc directory before start emulator it work perfect or else you can get DSI error you can ignore, the best thing to point it to RAM disk, I think.

Sunday, September 15, 2013

Network, file shearing, on AmigaOS is hopeless or is it?

So other platforms have DropBox and Google Drive, Samba / Mirosoft network, NFS, and so on.
We have where old version of Samba, and we are having problems whit ever dated Socket API, it put a lot of restrictions on what we can port over to AmigaOS, I think it's time we work around this problems.
We need our own file sharing system, I think this the only way we can control compatibility whit other systems we use.

We are stuck whit FTP based file shearing, and it's not horrible simple to manage.
The conclusion is that we need our own Windows/Linux/AmigaOS Client/Server software.
I have thinking the simplest form of file shearing might be some kind of file sync system.

Wednesday, August 28, 2013

Summer time, holyday and software development.

So what has happened sines last time, I wrote some thing here.

Excalibur 1.4.0 was released, this should have great release whit context menus, and some cool stuff like being able to hide and unhide Excalibur by Clicking the border, it was bit of horror really, last secund changes screwed up the build process, resulting half rebuilt executable, also people started reporting problems whit install and uninstall scripts.

Rebuilding Excalibur was easy, but all the changes that resulted in meny Skins/theams being out date, and was needed a work over, the result was Excalibur 1.4.1, I was not able fix problems as fast as expected because it was lot of work.

So what do I need to fix, I need to fix build horror issue, what it is.

What I have done is that I have decided the program into modules (objects), that are compiled separately and then linked into the executable. This all nice, as I don't need to see warning from modules I don't need to recompile and recompile gets quicker, less text on the screen and so on, and it organized, but his modules include some header files, that I some times need to changes, due to some structs,

but the makefile lacks the dependency and so even if I modify the header file the modules does not recompile. I'm thinking of some kind of auto clean, where if header files are changed all the objects should be deleted, forcing a make clean, make all.

Well thats the idea.

So what else, updated RunADF, well I use it a lot, I don't really have the need to mount adf's, more often I just want start a old game. The old version needed you to install UAE manually, changes stuff in user-startup, and modify DefIcons, this this are not needed in AmigaOS4.1, it was only needed in AmigaOS4.0.

DefIocns has entry for ADF files, I think its because of RunInUAE provided whit AmigaOS4.1, so all I need to do is replace sys icon, UAE is provided whit AmigaOS4.1 and so I don't need to look for it else where, so no need for UAE: Assign.

Then I was outside Norway for a week, enjoyed a week in Prague, walked around the city, I'm bit restless, I can't really sit down for too long, I need to do something, we did see a lot, I did not really dig into history of Prague or anything like that.

A bought a Samsung Galaxy, on airport, it came in heady to check on Amiga news, and look for restaurants and other useful travel information at hotel, it was also possible for me check up on work, but I tried to avoid that, unless it was needed.

Coming back after the holyday, there is some work that needs to be done on my apparent, first off this has been raining for most part this summer or I have been working, and in the weekend has been some what busy too, I have have not really have time for anything, but now, I need to get things done, only started on this, so it want be any major updates in any software until this taken care off.

One small thing I did also was release a new version in Whdload-to-UAE, that I did whit this was simular to what I did for RunADF, every thing is now provided, so made the install process easier, RunInUAE should be able to start whdload I belive but does not work here, I don't care way, all I care is that that it works, and it does after installing whdload-to-UAE, so I'm happy, hope you are.

Wednesday, May 29, 2013

So what to say? I think its about time to upload a new version soon.

So what to say? I think its about time to upload a new version soon, take a look at picture be under what do you think?

I don't know if notice some thing new....
but look closely, did you see it :-)

Yes the logo can now be on top, but there is some thing else....
We now how icons on About and Quit, maybe not big improvements.

But I have done allot of fixes and I hope every can notice that product is better when they use it, some of the fixes might not be easy to spot, I notice I changed the prefs, so its easier to find what your looking for.

Some of most impotent changes are fixes, found an memory leak, some problems because changing setting on the fly, lots settings did not reload as they should.

Fixed some rendering bugs.

I can say I'm really happy whit what I have done in this version, more impotent I think most of bugs is gone,  if you find a bug now its likely I do not know about it, so please rapport bugs.

So whats next, now that I bugs fixed, its time to look at things that might be nice to have.

* Context menus are on the top of that list.
* I'm also thinking about ways to hide Excalibur, I'm NOT a big fan of iconification.

I believe whit this two on the roadmap, its going to be lots of work, to one implement all the menu items. I think hiding Excalibur should be relatively easy, considering all the work being put into reloading settings, and switching resolution while program is running, it probably going to be lots of bugs during development its always is, I can't give any time estimates.

Her is a list of the changes in this version:

Version 1.3.5

* Changed: Grouping of prefs options, so its easier to find what your looking for.
* Added: A command line argument to reload to ExcaliburPrefs, this forces Excalibur to reload prefs
* Fixed:  Positioning and calculation of app icons coordinates, when prefs was reloaded.
* Added: Support for logos on top of the menu.
* Added: Loading and saving of logo placement (left,top).
* Fixed: Default settings was not set before reloading prefs
* Updated: Use presets scripts, now forces reload of settings in Excalibur
* Fixed: Crashes when changing screenmode due to changes in the way Excalibur open and close the toolbar.
* Fixed: Text length in menu,  bug was only visible when you where using a large font.
* Fixed: Menu editor so when you move a menu item up or down, the selected item stays the same.
* Fixed: Color for clock and screen did not change when config was reloaded.
* Updated: presets for Black, DjNick, 3d and Bloody
* Fixed: min_window height now its height left top+bottom or right top+bottom or center top+bottom border height.
* Fixed: Datatype support, JPG/IFF/TIFF is now converted into ARGB format, (ALPHA is assumed to be 0xFF)
* Fixed: toolbar border size for 3d and XEN, they where default 0.
* Fixed: icons in toolbar is also now reloaded.
* Added: wb96 preset for classic look.
* Fixed: fixed one pixel croping bug on icon rendering
* Changed: Max Icon size now defines height of toolbar icon not the width, (menu rendering unchanged).
* Fixed: Menu selector was misplaced on first menu, but not on sub menus.
* Changed: Logo can now be higher then the menu.
* Added: RGB and BG RGB for memory bars.
* Added: Support for icons on About and Quit menu item.
* Changed: ENVARC:Excalibur/toolbar.csv so the Excalibur menu points to SYS:Prefs/Presets/Excalibur/icons/current/Excalibur.info
* Changed: Theams to copy icons into to SYS:Prefs/Presets/Excalibur/icons/current/

Friday, May 24, 2013

So we are moving forward whit Excalibur 1.3.5.

Some really nice new features in this version, is that you do not need to quit Excalibur to reload settings. When I made the changes I discovered lots small bugs, that I have been addressing, mostly rendering related.

I most say it has been lots of bugs found I'm a bit surprised, mostly not critical, they just need to be fixed, it really does not help having lots of new features if the program is not work as expected, so this has to be fixed first.

And the second new feature is you now can have the logo on top of menus, this was not possible before, some themes might looks better whit logo on top, this was a lot of work to get right.

I also by playing a lot whit the settings I might found a lot more rendering bugs in this version, some of this bugs where not so easy to spot, I don't know if your going to see the difference.

Using datatypes (JPG,TIF,IFF images) is now working again, previously the images became transparent and was not rendered, (this going to need some more work I think, as the images loaded whit datatypes does not scale).

There is also a rendering bug in the menu that need to be fixed, when this done I will upload a new version.

I hope whit this version to have removed all known bugs, so I can start working on new features, and improvements.

I have also regrouped some prefs items so its easier to find the correct settings.

Saturday, May 11, 2013

So its that time again, Excalibur is ready for new release candidate V1.3.0

So what its going on well the last version was V1.2.5 I head to do things twice because some source code was lost, in the end, the product was not as tested as it might have been if orignal was released, so this version fixed a lot the bugs and issues that where overseen in last release.

* Fixed: menu editor used wrong type id for divider.
* Fixed: rendering of 3D and XEN screens
* Fixed: Transparency was not the same for menu as toolbar.
* Disable_clock() crashed on exit, added a check if mutex is allocated.
* Fixed: menu editor, when you delete a menu, no text is printed anymore.

And then I added some new features and found a few bugs in the process, most important is the ability to test if your configuration is what you wont whit out quiting excalibur, I also added a few up and down arrows to the menu editor, so now, its not totally useless anymore, it might need some more work, but at lest I have it, in addition Exchange support was improved by not having to click the toolbar to get Excalibur to respond to Exchange, then I added a few tests to make shore Excalibur can't get 100% transparent, I know people should know better, but some go looking for bugs it seams to me.

* Added: improved icons support for only icons / all files in menus and toolbars.
* Added: move up and down to menu editor.
* Added: stupidity check for transparency, toolbar can not be less then 25 of 255.
* BB emu API MakeCommodity(), changed to return MsgPort, so I can do handel signals.
* Fixed: Excalibur should now notice when Exchange event has happened, whit out clicking on the window.
* Added: code to prevent Excalibur to be started more then once.
* Added: test button to prefs
* Added: code to unload/reload graphics, fonts and prefs.
* Fixed: Toolbar height calculation when prefs was reloaded
* Fixed: Fixed a memory leek, background bitmap not freed.

So hopefully all this changes should translate in to better user experience, I know Excalibur has long way to go, there are lots of improvements on the table, or ideas that has not yet been implemented, so don't worry this is not the last version yet.

Sunday, April 14, 2013

AGA/OCS (planar) vs 8BIT CLUT (chunky)

Friday after work, and yester day I did some experimentation, people keep on saying how great AGA and OCS are for demos, is this really true? Does planar really have a advantage over 8bit CLUT chunky graphics. I think it does not, its just that planar modes, makes easier to do layering, and graphic card does the rest, so my experiment was simple implement some sort of layering in 8bit CLUT, should not be too hard.

So here is my main code, not so complicated.

#include <stdlib.h>
#include <stdio.h>

#include <proto/exec.h>
#include <proto/dos.h>
#include <proto/intuition.h>
#include <proto/graphics.h>
#include <proto/Picasso96API.h>
#include "chunky_plains.h"

int main()
    struct chunky_plains *cp;
    struct Screen *src = NULL;
    struct Window *win;
    struct RenderInfo ri;
    int err;
    void *tmp;
    PLANEPTR ptr;
    BPTR bmlock;
    int x,y;
    int n,anim;
    ULONG bpr;

    src = p96OpenScreenTags(
        P96SA_DisplayID, 0x50051000,
        P96SA_Title, (ULONG) "666",
        P96SA_Quiet, TRUE,
        P96SA_NoMemory, TRUE,
        P96SA_NoSprite, TRUE,
        P96SA_Exclusive, TRUE,
        TAG_END    );

    if ( src )
        win = OpenWindowTags(NULL,
            WA_Left, 0, WA_Top, 0,
            WA_Width, 640, WA_Height, 480,
            WA_NoCareRefresh, TRUE,
            WA_Borderless, TRUE,
            WA_Activate, TRUE,
            WA_RMBTrap, TRUE,
            WA_ReportMouse, TRUE,
            WA_CustomScreen, (ULONG) src,

        if (src)
            SetRGB32( &src -> ViewPort ,0,0xFFFFFFFF,0,0);

            for (y=0;y<255;y++)
                SetRGB32( &src -> ViewPort ,1,y * 0x01010101, (255-y)* 0x01010101,y*0x01010101);

            printf("Bitmap %x\n",src -> BitMap);
            printf("BytesPerRow %d\n", src -> BitMap.BytesPerRow);
            printf("Rows %d\n", src -> BitMap.Rows);


        if (err = alloc_cunky_plains(win -> RPort -> BitMap, 4,4,0,0,0,0,0,0, 320,200,&cp))
            printf("error code: %d\n",err);

            for (y=0;y<255;y++)
                for (x=0;x<255;x++)
                    set_color(cp,0, (y^x) & 8 ? (x & 3) : (y & 3) , x ,y );
            for (anim = 0; anim < 5; anim++)
            for (n=0;n<32;n++)
                for (y=0;y<255;y++)
                    for (x=0;x<255;x++)
                        set_color(cp,1, (y^(x+n)) & 16 ? 2 : 0 , x ,y );

            for (anim = 0; anim < 100; anim++)



As it turns out its easy to do, I think Intel/AMD PC moved to 16bit/32bit so quickly they forgot about 8Bit/6bit graphics, there are lots of cool things you can do whit 8bit graphics like layering, fadein between layers, scroll texts that go top of some image, or having some kind of vector cube in background and some logo on top of it.

People love this tricks and there are people that do make demos whit this effects even today.

Does it make sens today? Retro is in, but it probably look a lot better in OpenGL, using the Z axes, the things you don't have so great control over in OpenGL is things you can do whit the color palette.

To test you need your own "chunky_plains.h" file, so here is the rest of the code.

struct chunky_plains {
    char bits[8];                    // bits on plain
    char index[8];                    // index bit for color
    char mask[8];                    // mask for color value
    char palette[3][8][256];            // hemm...
    int bytes_per_row;                // copy of bitmap bytes per row
    char *data;                    // ptr to the Bitmap memory
    char *f_buffer;                    // buffer so we can do filtering.
    char *n_buffer;                    // buffer so we can do filtering.

enum {
    cp_error_no_mem = 0,

void free_chunky_plains(struct chunky_plains *p)
    if (p)
        if (p -> f_buffer) FreeVec(p -> f_buffer);
        if (p -> n_buffer) FreeVec(p -> n_buffer);

int alloc_cunky_plains(struct BitMap *bm, char n0,char n1,char n2,char n3,char n4,char n5, char n6,char n7, int w,int h,struct chunky_plains **new_cp)
    struct chunky_plains *p;
    int n;
    int cnt;
    int bpr;
    int error_code = 0;

    p = (struct chunky_plains *) AllocVec( sizeof(struct chunky_plains) , MEMF_ANY );

    if (p)
        bpr = p96GetBitMapAttr(  bm, P96BMA_BYTESPERROW);   

        p -> data =  (char *) p96GetBitMapAttr( bm , P96BMA_MEMORY);
        p -> f_buffer = (char *)  AllocVec( bpr * h , MEMF_ANY | MEMF_CLEAR);
        p -> n_buffer = (char *)  AllocVec( bpr * h , MEMF_ANY | MEMF_CLEAR);
        p -> bytes_per_row = bpr;

        p -> bits[0]=n0;
        p -> bits[1]=n1;
        p -> bits[2]=n2;
        p -> bits[3]=n3;
        p -> bits[4]=n4;
        p -> bits[5]=n5;
        p -> bits[6]=n6;
        p -> bits[7]=n7;

        p -> index[0] = 0;

        cnt = 0;
        for (n=1;n<8;n++)
            p -> index[n] = p -> index[n-1] + p -> bits[n-1];

            cnt += p -> bits[n];

        for (n=0;n<8;n++)
            p -> mask[n] = ((1 << p -> bits[n]) -1) << p -> index[n];

            printf("bits %02x mask %02x index %d\n",p -> bits[n] ,p->mask[n], p -> index[n]);

        if (cnt > 8) error_code = cp_error_too_many_bits;
        if (!p -> data)    error_code = cp_error_no_mem;
        if (!p -> f_buffer) error_code = cp_error_no_mem;
        if (!p -> n_buffer) error_code = cp_error_no_mem;

    } else {
        error_code = cp_error_no_mem;

    if (error_code)
        p = NULL;

    *new_cp = p;

    return error_code;

void set_color(struct chunky_plains *cp, char number, char color, int x,int y)
    char *pixel = &cp -> data[ x + (cp -> bytes_per_row * y)];
    *pixel = (~cp -> mask[number]) &  *pixel | (color << cp -> index[number] );

int get_color(struct chunky_plains *cp, char number, char color, int x,int y)
    return (cp -> mask[number] &  cp -> data[ x + (cp -> bytes_per_row * y)]) >> cp -> index[number] ;

void scroll(struct chunky_plains *cp, int number, int x1,int y1,int x2,int y2, int offset_x, int offset_y )
    int fmask = ~ cp -> mask[number];
    int mask = cp -> mask[number];
    int bytes_per_row = cp -> bytes_per_row;
    register int x = 0;
    register int y;
    register int line_offset;
    register int offset;
    register int doffset;

    // we filter out the other plains into the buffer, so we can put it back in.

    for (y =y1;y<=y2;y++)
        line_offset = y *  bytes_per_row;
        for (x=x1;x<=x2;x++)
            offset = line_offset +x;
            cp -> f_buffer[offset] = cp -> data[ offset ] & fmask;
            cp ->n_buffer[offset] = cp -> data[ offset ] & mask;

    for (y =y1;y<=y2;y++)
        line_offset = y * bytes_per_row;
        for (x=x1;x<=x2;x++)
            offset = line_offset +x;

            doffset = (y + offset_y) * bytes_per_row + (x + offset_x);

            cp -> data[ offset ] = cp -> f_buffer[offset] | cp ->n_buffer[ doffset ] ;

Friday, April 5, 2013

The release of excalibur is eminent

The release of Excalibur is eminent

There are only a few features, that I can think of that want, but they going to break some thing maybe, it's time think about uploading a new version, there is 30 changes in this update, so this big update compared to few of the older updates, I lost a lot changes, and head to do most of this twice, nothing makes me more annoyed, well its done.


* Alpha blended Logo
* Menu divider texture is tiled and scaled up or down to fit.
* Added border to toolbar
* save and load of font settings
* save and load of RGB color options for clock and screens
* some settings has changed name
* toolbar icons, screens and clock is now relative to border
* smarter positioning of toolbar icons
* prefs: added fonts to save routine and gui.
* prefs: added border textures for toolbar.
* prefs: RGB color option for clock and screens.
* Fixed black border texture in GIMP.
* Bjornar made a new logo for me.
* Svenn Ove Hansen, created some experimental textures.
* Fixed bug: droping icons resulted in menu being saved to env, menu divider lost bug.
* Fixed best_height calculation in menu, assumed toolbar to be 60 pixels, that was wrong.
* logo is now sacled down if menu is too small.
* ASync memory bar redraw bug when drooping icons fixed.
* Clip background from window instead of background bitmap bug, fixed.
* Background texture in menu is now aligned whit border top texture, to support DjNick theme.
* DjNick designed a theme
* Fixed DjNick theme, created a icon from textures, and left menu texture, cut of some transparent empty space of right and bottom side of theme,
cropped down menu border textures so it worked on toolbar.
* Fixed up black theme, and bloody theme.
* Fixed check_ext() function checked .info instead of .ext (no major problem unless I like to use it for some thing else)
* disk.info is now ignored.
* font shadow option changed to menu and toolbar instead of global
* max icon size option changed to menu and toolbar instead of global
* prefs program: default setings are now set, before config is loaded.
* GFXMEM can't be 64bit int, due to only 32bit api for memory in OS4, changed to unsigned int32, max 4Gbytes.
* Membar drawen too often, due to refresh bug, added draw_gfx option to membar::Memory() function.

DJNick theme, what happened, well some of changes you see in Mokup are implemented, for example the different size of fonts in menu and toolbar, different icon sizes in menu and toolbar, this things might have not been there if was not for the mockup, what is not implemented is logo on border, and the shadow effect.

What you might not know, is that Excalibur allows for more then one menu, so you can have your music menu, and your games menu, and what ever, just drop your volume or folder on the app/toolbar.

So lets hope I have some time to upload it tomorrow, so you all can enjoy it.

This is Kjetil signing out.

Wednesday, March 20, 2013

So how close are we?

So how close are we?

I done lots of work on fine tuning and improving the code, many small visual improvements that I hope will make it easier to make nice looking themes for Excalibur, what we have her is a improved black theme, whit a logo made by Bjørnar, it show some of new features that is important for DjNick mockup.

There are some complaints that is coming from some of you that DjNick mockup is too windows like, but its just a theme, Excalibur is not one form factor, you decide how its going to look how many buttons, what is going to be shown, the idea is that is customizable in looks, so you make look as just as you want (whit in limits of the program).

So what is new, as you can see fonts can be changed in style and size, the menu selector is a transparent bitmap, the menu divider is bitmap tiled or scaled to fit the menu perfect, the program tries to be smart about it, a number of graphic glitches has been fixed, due small disk crash I head to do it twice, so it was almost ready a month ago, but did take me a extra month, due the crash, what is left is going over etch theme and fix and compatibility issues new prefs, some of settings has changed names, so this has to be fixed.

I have long list of ideas in my head, and there are a lot of things that is on the TODO list, but most of graphical stuff is done, might might be effected by changes in other parts of the code, its always a on going processes, where you changes some thing and it effects an other parts, and every thing has be tested.

I also include DjNicks mockup so you can compare.

Saturday, January 26, 2013

Reverse engineering and other stuff.

IRA the dissembler again

Wow, it has started to piss me off, well not rally, what i considered as relative easy thing to do is not as easy as first thought.

The dissembler does good job at generating Assembly code, but does poor job as knowing the different between strings and assembly code, the challenge was not Assembly but cleaning up after a tornado.

What the dissembler generated:

     BVS.S    LAB_001C
     MOVEQ    #117,D2
     BVS.S    LAB_001F
     DC.W    $696f
     BGT.S    LAB_0018
     DC.W    $6c69
     BHI.S    LAB_0020
     BSR.S    LAB_0021
     DC.W    $7900
     BEQ.S    LAB_0022
     BSR.S    LAB_0022
     DC.W    $6869
     DC.W    $6373
     MOVEA.L    26978(A4),A7
     MOVEQ    #97,D1
     MOVEQ    #121,D1

This should be:

     DC.b        "intuition.library",0
     DC.b        "graphics.library",0

You can see that some thing went wrong when you see DC.w and DC.b mixed whit assembly its not common, maybe if it was a undocumented machine code instruction.

Just to repeat my self, I know some you who read this might not have written assembly so explain it again, DC.b is for arrays of byte and string (array of bytes that has ascii values), DC.w is for 16bit Integer (WORD) of arrays.

“DS” is for size of data and reserves chunk inside your code.

What you really need to use to clean it up a good hex editor, so you can look inside the exe file, and see what text strings should be.

I write a few commands to help me find hex values.

hex_to_string and string_to_hex, it's nice to have if you wonder if some thing really is ASCII and not numbers.


When debugging code one of my favorite tools is PrintF, simply because debuggers don't work so well under AmigaOS, we have grim repaper that displays power pc registers and 680x0 emulated registers, and where it crashed, but 680x0 code its translated as program runs so its hard to know where it crashed, and also grim only displays crash location as powerpc assembly.

Under UAE there are probably better tools, but I need to find the crashes under AmigaOS4, not under UAE, so not that useful,


C vs Assembly language

 Sorry I just don't get it, way are people (Franko) telling me that Assembly is easy language?

This window display C code that does the Dos.library / PrintF command just as Assembly code above.

Well the code lies, I should have opened the DOS.library but its no longer necessary under AmigaOS4, whit -lauto option, so not a big lie, it works as its written.

but as you can see Assembly version of printf takes up to 7 lines to do the same as C does in just ONE single line, and it does the same thing.

And also you can see that strings has to be put some where else, and then you need to move the values in to ARGS array (D2), before command is executed, it just allot of more work.

Well maybe Assembly is not that complicated, but does require a lot more work, in the old days it made sense to do it in Assembly because you needed to optimize for speed as CPU's back then was slow, and you need to optimize for size as storage space was critical, but today it makes no sense to do it unless your optimizing something critical.

Wednesday, January 16, 2013

Reverse engendering of 680x0 assembly code.

Trying to make sense of it all, IRA the disassembler has been really help full to gives some clues; by providing EQU constants for hardware registers, and some other stuff I don't know what is.

It is worth to point out that any access to hardware registers are illegal under AmigaOS4.1, unless your running on old hardware, so we need to replace it whit system friendly code, so we need to look for any references to this constants, that I have marked, and replace the code.

Next thing that is a issue is to understand what the code does, there are some clues, see the lines that starts whit JSR, JSR is short for Jump To Sub Routine. In front of A6 (address register 6), you have a negative value, this is a offset value we call LVO, A6 is loaded whit library base address, we just need to find what library and compare the LVO values to that library offsets, LVO number are not unique to one library they can be the same for number of libraries, so we can't just auto replace the values whit constants.

Another thing that will help making it possible to understand some thing is to look at bottom of the code, this where you find data, like strings.

DC and DS is defines data space, DC is for values you enter, while DS just reserves chunk of space, it is the DC that we are most interested, in front of DC there is label it represent a reference to the data, the label has been generated by IRA disassembler and not human understandable, we need to replace the label name whit some thing we understand, so we replace LAB_0F71 whit LAB_STERO_LEVEL, and LAB_0F6B whit LAB_VOLUME_BOOST, we do that for all readable strings, we most be careful to replace every reference of LAB_0F6B and LAB_0F71.

Saturday, January 12, 2013

Paula sound, so where does that 14bit audio come from?

So where does that 14bit stereo sound come from? You might have wondered, well after reading the hardware reference manual, it explains that 4 audio channels can be combined in to two.

In this mode, one of channels controls the volume (a value from 0 to 63) 6bits, and wave from is (127 to -127) 8bit, so if you add that up 6+8 = 14bit.

This not a hack, that's a urban myth, it was designed to be like this. Its properly more complicated to calculate wave form and volume, and also it does not take advantage of all bits in the audio channels, plus it does need a bit more CPU if I'm not mistaken.

Its a shame they did not provided a proper 16bit D/A converter instead, anyway the sound was not that bad compared some early sound blaster sound cards that sounded a bit sour.

I think this graph illustrates the dilemma, where audio quality is better at lower amplitude, then on higher, as as the amplitude increases, because the 8bits are more compressed at lower volume. So you do not get popper 14bit, where the bits are evenly spread out, what you get if you made a sinus or a sawtooth, you see that top and bottom of sinus are more pixelated then in the center of sinus.

I have also played whit Paula whit some help, few small errors, and this codes players a beep. I have not really found out about interrupts, the DMA is supposed to trigger a interrupt when sound was played, so you fill the buffer whit new sound, but I can't find any interrupt vector to configure in the hardware reference manual.


OldOpenLibrary EQU -$0198
WriteChars EQU -$03AE
CloseLibrary EQU -$019E
Delay EQU -198

FREEMEM        EQU    -210

CUSTOM        EQU    $DFF000
AUD0LCH        EQU    $0A0
AUD0LCL        EQU $0A2
AUD0LEN        EQU $0A4
AUD0VOL        EQU    $0A8
AUD0PER        EQU    $0A6
DMACON        EQU $096


        LEA DOS(pc),A1
        MOVE.l #0,D0
        MOVE.l EXECBASE,a6
        jsr     OldOpenLibrary(a6)
        move.l  d0,DOSBASE
        beq.s   .Out

        move.l  #msg_start,d1
        moveq  #9,d2
        JSR .Write

        ; Alloc Sound wave
        MOVE.l #100,D0    ; size
        MOVE.l #2,D1        ; chip mem
        MOVE.l EXECBASE,a6
        JSR ALLOCMEM(a6)
        MOVE.l d0,SINDATA
        BEQ.s    .NOMEM
        ; Setup sound wave
        MOVE.L SINDATA,a1
        MOVE.b 0,0(a1)
        MOVE.b 90,1(a1)
        MOVE.b 127,2(a1)
        MOVE.b 90,3(a1)
        MOVE.b 0,4(a1)
        MOVE.b -90,5(a1)
        MOVE.b -127,6(a1)
        MOVE.b -90,7(a1)

        ; Play sound
        LEA.l CUSTOM,a0
        MOVE.l SINDATA,AUD0LCH(a0)  ; sound wave to play
        MOVE.W #4,AUD0LEN(a0) ; length of sound wave
        MOVE.W #64,AUD0VOL(a0) ; sound volume
        MOVE.W #447,AUD0PER(a0) ; set audio period
        ; enable (bit 15) dma (bit 9), audio channel 0 (bit 0)
        MOVE.W #$8201,DMACON(a0)

        ; Wait for sound to be played
        move.l DOSBASE,A6
        move.l #40,D1
        JSR Delay(A6)

        LEA.l CUSTOM,a0
        MOVE.W #1,AUD0VOL(a0) ; sound volume
        MOVE.W #0,AUD0LEN(a0) ; length of sound wave
        MOVE.W #220,AUD0PER(a0) ; set audio period
        MOVE.W #$0001,DMACON(a0)

        move.l  #msg_step,d1
        moveq  #7,d2
        JSR .Write

        ; Wait for sound to be played
        move.l DOSBASE,A6
        move.l #20,D1
        JSR Delay(A6)

        ; Free sound wave
        MOVE.l #100,D0
        MOVE.l SINDATA,a1
        MOVE.l EXECBASE,a6
        JSR FREEMEM(a6)

        move.l  #msg_ok,d1
        moveq  #7,d2
        JSR .Write
        JMP .Out      
        move.l  #msg_nomem,d1
        moveq  #13,d2
        JSR .Write
        JMP .Out      
        move.l DOSBASE,A6
        jsr     WriteChars(a6)
        move.l  DOSBASE,a1
        move.l  EXECBASE,a6
        jsr     CloseLibrary(a6)
        dc.b    "dos.library",0
        dc.l 0
        DC.L    0
        dc.b   "START!!!",$A,0
        dc.b    "STEP!!",$A,0
        dc.b    "OK!!!!",$A,0
        dc.b    "AllocMem failed, no memory!",$A,0