Showing posts with label Programing. Show all posts
Showing posts with label Programing. Show all posts

Saturday, September 20, 2014

Developing cross platform program/game from ground up - part 4

Cross Platform development by standardization.

If your going to make program work on different operating systems, you need a lot of know how about etch of operating systems, in order to support all operating systems.

The alternative is using cross platform development libraries.

First of all I'm going to talk about SDL and Allegro this two provides every thing you need to make games, the idea is that you have standard commands you can use to make sure that your game works on all operating systems they are ported to.

SDL

* Support Graphics 2D and 3D
* Handel display window/full screen window
* There events for Mouse/Keyboard/Joystick/ Multi-touch.
* Audio 8bit and 16bit.
* Filesystem
* Threads
* Supports big and little endian cpu's

Allegro

* Support Graphics 2D and 3D
* Handel display window/full screen window
* There events for Mouse/Keyboard/Joystick/ Multi-touch.
* Audio 8bit and 16bit.
* Filesystem
* Threads
* Supports big and little endian cpu's

So they are similar and provided what you need to make a games, some even make programs in this but, that's not a good idea, there are better cross platform libraries for programs.

Linux/BSD Windows AROS AmigaOS4 MorphOS MacOSX Haiku/BeOS Score
Allegro yes yes no yes yes yes yes 6
SDL yes yes yes yes yes yes yes 7
Svgalib yes no no yes
Wrapper for Picasso96
no no no 1 (2)
Picasso96 no no yes yes yes no no 3
Cybergrephics no no yes yes yes no no 3
Haxe yes yes no no no yes no 3

The Svgalib port for AmigaOS4, was done by me, it might need some work, its not well designed, but there are NOT many games or programs that use this library, if you look at the table you see that SDL is most supported, Allegro is not so well supported.

Some information Allegro 5 and Allegro 4 are not 100% compatible, and only Allegro 4 is officially supported by AmigaOS 4, I have not looked at Allegro 4 so I can't say accurately what the difference are, anyway I have been working a bit on Allegro 5 but not a complete port, I have only implemented what was needed for a Game, so its not even based on Allegro 5 source code, so don't expect a full Allegro 5 port from me for AmigaOS 4. Developer using the nick "Hitman", ported Allegro 4 to AmigaOS 4.

As I understand it Cybergrephics is the native graphic library for MorphOS and it was addition to Graphic.library on AmigaOS3.1,  when installing a True color graphic card in your Amiga, Picasso96 is also a graphic library to enable true colors for AmigaOS3.1 / Commodore Amiga computers, on AmigaOS4.x  Picasso96 is slowly becoming obsolete if your going to make new program or game. How this implemented in AROS I do not know all I know is that its supposed to be supported.

Here are some GUI systems QT, GTK, MUI (Magic User Interface), Reaction, that we compare to see what supports the most, I have selected a few well known operating systems.
(I have excluded mobile platforms etc, or else table gets to big.)

Linux/BSD Windows AROS AmigaOS4 MorphOS MacOSX Haiku/BeOS Score
QT yes yes no yes no yes yes 5
MUI no no yes
(clone Zune)
yes yes no no 2 (or 3)
Reaction no no no yes no no no 1
GTK yes yes yes
(Zune wrapper)
no no yes yes 5
Windows Forms yes
(mono)
yes no no no yes
(mono)
no 1 (or 3)
wxWidgets yes yes no no no yes no 3
AGAR yes yes no no no yes yes 4

Best score is 7 in this table, but no GUI system support all 7, so in other words GUI's are the tricky part when creating a cross platform application, the best GUI's to support is GTK and QT, then depending on what OS you wont to support and programming language you use MUI (Magic User Interface) or Windows Forms.

While no GUI support all the 7, the build system is what solve the problem, this how you can have different GUI's for different operating systems, you really only need to support two MUI & QT or GTK & MUI and all 7 operating systems are supported.

Different Linux distributions are not listed here because they are just repackaged Libs and programs, with different install process and package managements, I know some might disagree but lets keep this about cross platform development and not about what brand you put on your Linux distribution.

Anyway GUI and how things works is what makes operating systems unique to the users, if all operating systems behave the same there is not point having a option to choose is there?

Friday, September 19, 2014

Developing cross platform program/game from ground up - part 3


Ok, now I'm going explain a bit more about Makesfiles, and also try to condense this makefile.os4 and makefile.os3 and makefile.linux into one file.

Forst of all now we description how to build 4 different .o files, but we are using gcc to generate this files in the same way.

obj/display.o:
          gcc os3/display.c -o obj/display.o -c

obj/filesystem.o:
          gcc os3/filesystem.c -o obj/filesystem.o -c

obj/joystick.o:
          gcc os3/joystick.c -o obj/joystick.o -c

obj/audio.o:
          gcc os3/audio.c -o obj/audio.o -c

however this can be written as.

obj/%.o: $(os)/%.c
          gcc $< -o $@ -c

I know this looks cryptic but what it does is when compiler is looking for obj/filesystem.o it will use label obj/%.o as it matches the filename, $(os)/%.c means that linux/filesystem.c is needed by obj/filesystem.o.

The next line gcc $< -o $@ -c work like this.

$< is replaced by whats after the label so its going to be $(os)/%.c and this translated into linux/filesystem.c

$@ is synonym with the name to compile.

So if this is the filesystem that is compiled it will be interpreted by the compiler as:.

gcc linux/filesystem.c -o obj/filesystem.o -c

so this two lines do the same as the 8 line in the first example.

And also you can easily change build target to OS4 or OS3 or Linux or what ever you like.

By setting os=linux or os=os4 or os=os3, simple do you agree?

Wednesday, September 17, 2014

Developing cross platform program/game from ground up - part 2.

Understand how build process talked about in part 1 work.

So now you type make all -f makefile.os4 you get the game.exe file for AmigaOS4.

The game.exe will contain the following files for AmigaOS4:

main.cpp 
os4/display.c 
os4/filesystem.c
os4/joystick.c
os4/audio.c

The game.exe will contain the following files for AmigaOS3:

main.cpp 
os3/display.c 
os3/filesystem.c
os3/joystick.c
os3/audio.c

The game.exe will contain the following files for Linux:

main.cpp 
linux/display.c 
linux /filesystem.c
linux /joystick.c
linux /audio.c

Etch of the files in the OS folder will contain OS specific code, for example in linux/audio.c file OSS Open Sound System is used. In the os3/audio.c code for Paula audio is used. In the os4/audio.c file the AHI sound system is used.

In the os4/filesystem.c the newest DOS.Library functions are used with full support for 64BIT offsets.

In the OS3/filesystem.c the old 32bit DOS.Library functions are used, with file limit of 2GB.

In the Linux/filesystem.c the stdio C++ lib commands are used, with full 64BIT support if compile target supports it.

So what we have done is separate the OS depended parts and we are using the best possible API that we can use for etch OS target.

This is also the case for windows target, but as it use different build system, you only need to make the folder and add the file to the project in Virtual Studio.


Developing cross platform program/game from ground up - part 1.

First of all its good to know what the differences are between the operating systems.
Do some resource and see what libs are ported and what are not ported to etch operating systems you like to support.

For AmigaOS4.1 you can check http://OS4Depot.net
For AmigaOS3.1 you can check http://Aminet.
For AROS you can check http://archives.aros-exec.org/.

Often you can to etch library and check how to configure and set it up in your development enviroment.

For example if you go to libpng web page and look you see how to configure it for windows.
http://gnuwin32.sourceforge.net/packages/libpng.htm

Note for windows visual studio uses different build system then AmigaOS/Linux/AROS/MorphsOS or what ever, so I think might be best to create the project there and copy the files to the other computers.

You should have repository to track your changes and other people changes.
You can sign up a repository at code.google.com for free.

Design your application so its easy to update your program with out messing up your code.

Try to keep the OS depended code out of your game AI and general code.

If you need to draw a line make function or macro like:

app_draw_line()

this way draw line is abstracted from the OS, and it becomes easier to keep every thing compatible.

create folder in project root directory called.

linux, os3, os4, windows, osx and so on.

you will also need a folder called inc or include, here you put .h files that declare how functions will look like.

in the inc/display.h file you should have line like:

extern void app_draw_line();

extern means that app_draw_line does not need to be in the .c/.cpp file its included in, but can be in a different .c/.cpp file, this is to make sure the compiler does not get confused, because you can only have one app_draw_line function.

Setting up the makefiles.

For AmigaOS4, you make file named it Makefile.os4
          the following line should be like:

all: obj/display.o obj/filesystem.o obj/joystick.o obj/audio.o
          gcc main.cpp obj/display.o obj/filesystem.o obj/joystick.o obj/audio.o -o game.exe

display.o:
          gcc os4/display.c -o obj/display.o -c

filesystem.o:
          gcc os4/filesystem.c -o obj/filesystem .o -c

joystick.o:
          gcc os4/joystick.c -o obj/joystick .o -c

audio.o:
          gcc os4/audio.c -o obj/audio .o -c

create a make file for AmigaOS3 and name it Makefile.os3.

all: obj/display.o obj/filesystem.o obj/joystick.o obj/audio.o
          gcc main.cpp obj/display.o obj/filesystem.o obj/joystick.o obj/audio.o -o game.exe

obj/display.o:
          gcc os3/display.c -o obj/display.o -c

obj/filesystem.o:
          gcc os3/filesystem.c -o obj/filesystem .o -c

obj/joystick.o:
          gcc os3/joystick.c -o obj/joystick .o -c

obj/audio.o:
          gcc os3/audio.c -o obj/audio .o -c

create a make file for Linux and name it Makefile.linux

all: obj/display.o obj/filesystem.o obj/joystick.o obj/audio.o
          gcc main.cpp obj/display.o obj/filesystem.o obj/joystick.o obj/audio.o -o game.exe

obj/display.o:
          gcc linux/display.c -o obj/display.o -c

obj/filesystem.o:
          gcc linux/filesystem.c -o obj/filesystem .o -c

obj/joystick.o:
          gcc linux/joystick.c -o obj/joystick .o -c

obj/audio.o:
          gcc linux/audio.c -o obj/audio .o -c


So now you see that etch target platform has its own folder, with platform dependent code, while main.cpp is on the project root folder. This is because main.cpp is shared between the different target operating systems, and should not contain any OS dependent code.

Additional support libraries most also be statically linked or dynamically linked. Its up to you how you solve that.

Note I'm not using configure scripts, well this because different operating systems do not share the same shell commands, while there is some thing called ABC shell for AmigaOS that mimics the SH shell, it does not guaranty compatibility, with 1000 of GNU commands in Linux. This simply does not work for AmigaOS.

When compiling you simply do:

make all -f makefile.os4
make all -f makefile.os3
make all -f makefile.linux
make all -f makefile.aros

you can also make soft like to from makefile.os to makefile so you can just type

make all

Sunday, September 14, 2014

Prof of concept, EPL labels on AmigaOS.

Well I felt like writing something about some working I have been doing lately.

For now I'm not going to say anything about MPlayer, all I can say is that there has been some improvements.



You might have seen my Barcode application on AmigaWorld.net, well I was nostalgic about EPL & ZPL printers, but don't have a printer my self so need a application to display labels, I know there are label design tools for PC, but what is the fun in using some thing some one else has created? Besides I was also wondering about how to generate bar-codes, I often created reports for PSI and Consafe logistics, but this was not my primary role, so I did not have time to find out how to generate bar-codes, at time I did some googling and found only barcode fonts, well they are nice in word document’s and so on, but then you need to generate a word document or excel file, its a lot easier to generate CSV files and Pictures, and its pity easy to lay out rapports in HTML.

If I did have more time to play with it back then might have done some thing, but as I was saying, I did not. as it happens now I did have the time for it, first ting I did was Google and found out how to generate code39 and then I Googled and found out how to generate code128.

Barcode39 is only numbers and uppercase alphabet.
Barcode128 is upper/lower alphabet, and also the ability to compress numbers.

 I also found some information about bar-code 2 of 5, this Barcode only supports number from 0 to 9, and also as the name imply 2 are wide and 3 as narrow lines

I know this is geeky stuff, but some times geeky stuff is useful

Almost all postal and logistic company's tag packages so they can easy lookup who the package belongs to and where it is. Also at the cash register at the local grocery store, use barcode to register what they sell. At service department in PSI and Consafe Logistics (Capbit/Captura) they used bar code to track service on defect products that has been sent for repair.

So every company small or large company's use barcodes in one way or the other.

And this is way this is interesting, if you thinking about starting your own company or if you work for some company I'm sure your in contact with barcodes.

Only basic EPL commands are supported, but program can easily to be extended to support more commands, this is just a prof of concept.

And also while I can generate the label I can't print it, find desktop printers that work with AmigaOS tricky.

If you like to buy a Label printer and use it on AmigaOS, I can inform you that they should work, as long you use ZPL or EPL program language.

You can also find documents for EPSON label printers, but they are more tricky, you see they use ESC codes, and HEX values so not so easy.

Datamax Compact 4 I don't know anything intersecting about it sorry, I know they are good quality but do not know any thing about language they support.

Some of the Intermec printers supports the EPL language this I know.

Thursday, July 10, 2014

Yesterdays problems, is todays success.


After finishing my blog yesterday, I decided  to use another technique to solve my problem.

So I know the read speed was not good, I wanted to isolate the problem, or try to exclude a problem by testing, individual components.

So I wrote a small test program for libdvdcss, by doing this I hit nail on the head, this was where speed problem was.

First run it showed about 64kb/s a bit more then when I was benchmarking from mplayer.

Corrected a few mistakes and I was at 200kb/s.

The experimented with my read ahead cache implantation, and I was soon at 800kb/s.

With bit more work I managed to get it up to 24000 kb/s, this is really close to the copy speed I got yesterday from DVD to HD.
So I think we can say the speed problem is solved.

The problem with mplayer is that it tries to read one by one block, but CD has spin up, it has to find the sector where block is located, and this for every time you read one block, this is not efficient.


sb600sata.device or sata device driver for X1000, does not try to pre buffer, this is the problem. So this is way I need to do that in mplayer/libdvdcss.

So what I try to do is, avoid any one block reads by pre fetching blocks, as mplayer mostly reads blocks in sequential order this pretty easy to do, so next reads is going to be really quick, until the read offset is outside the buffer and it has to fill the pre fetch buffer.

Also because its in memory, I do not need to foreword the IO read to the DVD read process I created, it can simply just copy the data from the buffer, so no need to wait for task switch, signals and stuff like that.

I call my pre buffering stuff "Evil" because it was quickly proto typed, as future note it should be moved into the dvdcss struct, so etch dvd device can have its own pre fetch buffer.


Anyway its not a problem for mplayer as I think there is only one process reading at any given time, from one device, I'm shore this might not be case for other operating systems.

Way I think this is not problem is because libdvdcss is not a shared library, the the pre fetch buffer is pretty mush private to mplayer as its static linked.

Wednesday, July 9, 2014

The mystery of the slow DVD speed and Mplayer for AmigaOS4.


I have been investigating the issue, for some time.

Trying to find out of problem was caused by read errors, and trying to locate the problem.

What I have done is fix cache and device io in Mplayer as it was broken, I was hoping by doing this the problem was going to go away.

But what it did was, it enabled mplayer to pre buffer 999999 bytes, but as soon as the buffer runs out mplayer is back to crawl speed.

I have tried to compile the latest version of mplayer and ffmpeg, and the problem remains. I have tried to read from the filesystem instead of depending on the IO system, by fixing that part of the code as it was broken as well, but there is no luck there, reading a DVD is not like reading a file.

I measured the read speed, at device IO in libdvdcss/device.c and found the 38KB/s read speed, so in other words, the read speed is low, it should be around 1.49MB/s, so we are not even close, to be playable.

I made some tests to see what best copy speed was, I copied a 972Mb file in 372 sec, or 2.6Mb/s, so this is not a hardware problem, the problem most be with DVD://1 DVDNAV://1 -dvd-device option.

I can play the a VOB file from a DVD disc, with some cache, but only this way I get good speed, with out cache its just as slow as the DVD://1 DVDNAV://1 options.

I have taken the time to look at the status line in mplayer, it says some thing like:

A: 13.1 B: 3.2 A-V: 9.981 ct: 0.051 77/155 39% 24% 10192.1% 153 0

So what this status line says is that A: is for audio, it represent the time played for audio, and V: for video, A-V: is the out of sync number it should be 0, 77/155 is decoded vs the not yet decoded frames in buffer, 29% is codec, 24% is the video, and 10192.1% is the audio,

the the biggest problem looks to be related to audio, but its not really, the high number comes because the audio buffer is empty and the audio cache has to be filled, so I tried to trace the it up stream, from main loop in mplayer.c, but it was not easy.

So then I remembered about debug features in AmigaOS4.1, so I decided to collect some information using stacktrace feature.

There was a problem it required the task I wanted to be halted, while using back trace, but that was lucky not a issue for me, as device io code was moved into a different task of its own, to prevent problems with treading in mplayer, and task that issues the read waits for signal for data to be ready, so I was happy about that, if not might not have tried this.

Anyway here is stack traces I made, using Exec debug interface.

Stack:
kernel : NULL
kernel : NULL
mplayer : dvdcss_seek
mplayer : css_seek
mplayer : UDFReadBlocksRaw
mplayer : DVDReadBytes
mplayer : ifoRead_PGC
mplayer : ifoRead_PGCIT_internal
mplayer : ifoRead_PGCI_UT
mplayer : ifoOpen
mplayer : open_s
mplayer : open_stream_full
mplayer : open_stream
mplayer : main
newlib.library.kmod : NULL
newlib.library.kmod : NULL
newlib.library.kmod : NULL
mplayer : _start
dos.library.kmod : NULL
kernel : NULL
kernel : NULL

Stack:
kernel : NULL
kernel : NULL
mplayer : dvdcss_seek
mplayer : css_seek
mplayer : UDFReadBlocksRaw
mplayer : fill_buffer
mplayer : stream_read_internal
mplayer : stream_fill_buffer
mplayer : cache_stream_fill_buffer
mplayer : demux_mpg_fill_buffer
mplayer : ds_fill_buffer
mplayer : ds_get_packet_pts
mplayer : decode_audio
mplayer : mp_decode_audio
mplayer : main
newlib.library.kmod : NULL
newlib.library.kmod : NULL
newlib.library.kmod : NULL
mplayer : _start
dos.library.kmod : NULL
kernel : NULL
kernel : NULL

Stack:
kernel : NULL
kernel : NULL
mplayer : dvdcss_read
mplayer : css_read
mplayer : UDFReadBlocksRaw
mplayer : fill_buffer
mplayer : stream_read_internal
mplayer : stream_fill_buffer
mplayer : cache_stream_fill_buffer
mplayer : demux_mpg_fill_buffer
mplayer : ds_fill_buffer
mplayer : ds_get_packet_pts
mplayer : decode_audio
mplayer : mp_decode_audio
mplayer : main
newlib.library.kmod : NULL
newlib.library.kmod : NULL
newlib.library.kmod : NULL
mplayer : _start
dos.library.kmod : NULL
kernel : NULL
kernel : NULL

So I hope this information is useful to find out where the problem comes from, if not it gives a good overview of where problem might be located I hope.

The problem with mplayer is to get a overview, anyway if anyone knows about free vitalization tool, to get some overview of this source code it might be rally useful.



Sunday, March 9, 2014

Things I'm working on for the mommet.

I have been busy reading about MS C#, and about classes, in order to make it interesting I wanted to make a program, that will be useful to me and maybe others, a cross platform application.

I know C# is not really portable but its more portable then VirtualBasic, at lest it has most of the C++ syntax, even if .Net Framework is different, there are a few different versions of .Net Framework you have XNA a Game API used on XBOX, and then Portable Class Library.

The Portable Class Library is more or less useless, because everything has to be recreated anyway, and its too small to be of any use.

Supporting just XNA does not make lot of senses, if AmigaOS can support some thing, there is no point in limiting it to XNA.

The full .Net Framework is too big of job to support, so what I have basically been doing to create C++ classes for what I have used in my project.

And been trying to get same program to work on AmigaOS whit small modifications, just by implementing the classes need to for the program.

So to make this clear this is not XNA, .NET or Portable Class Library this is some thing new.

Hopefully this will open some door for cross platform applications and portability between the two operating systems.

The only problem is that AmigaOS has yet to come out of the stone age.

Like File Notifications is way better on Windows, then on AmigaOS where its pretty primitive.

UTF8 encoding really sucked on AmigaOS, but works well on Windows, and I believe it has become the standard encoding for text files in windows7.

So I have spent a week trying to figure out how to do things, and ended up whit writing my own UTF8.Library it has now been uploaded to OS4Depot.net.

I'm hopeful that UTF8.Library will make more programs UTF8 friendly. 
 
More information to come on what I'm working on.

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.

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:

 LAB_0014:
     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
 LAB_0015:
     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:

LAB_0014_intuition_library:
     DC.b        "intuition.library",0
 LAB_0015_library:
     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.

Debugging

 
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.


EXECBASE EQU 4

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

ALLOCMEM    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

    SECTION MAIN,CODE

MAIN:
        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      
.NOMEM:
        move.l  #msg_nomem,d1
        moveq  #13,d2
        JSR .Write
        JMP .Out      
.Write:
        move.l DOSBASE,A6
        jsr     WriteChars(a6)
        RTS
.Out:
        move.l  DOSBASE,a1
        move.l  EXECBASE,a6
        jsr     CloseLibrary(a6)
        RTS
DOS:
        dc.b    "dos.library",0
DOSBASE:
        dc.l 0
SINDATA:
        DC.L    0
msg_start:
        dc.b   "START!!!",$A,0
msg_step
        dc.b    "STEP!!",$A,0
msg_ok:
        dc.b    "OK!!!!",$A,0
msg_nomem:
        dc.b    "AllocMem failed, no memory!",$A,0

Saturday, December 29, 2012

680x0 development enviroment on AmigaOS4.1?

Yesterday I was wondering was, is it possible to setup a 680x0 development enviroment on AmigaOS4.1, whit out depending on UAE.

And the answer is yes.

Well first I tried AsmPRO, while program seams to work, it does give me some DSI crashes some times when I start the program, it did compile my code, but when pressing “j” to run it crashed.

So AsmPRO does not work under AmigaOS4.1, I did not like the integrated text/source code editor anyway.

Next I looked at the vbcc package it has a 680x0 compiler, but it can only produce .o files, so I need vlink once found it, I wrote a tiny AmigaDOS script.


Saved it and added script flag to the file using the protect command in AmgaDOS.
Next I found a "hello world" example using google.



Compiled it, and it worked.

So what is this all about, way do I wont to write 680x0 assembler?

Well the answer to that question is, a question I have been asking my self, what if I disassembled some of old programs that don't work anymore, will I be able fix this programs up?

I have limited experience whit assembler, I did make a 3d routine in inline Assembler in BlitzBasic2 and it worked, (I did it that way because did not have the right books, when I was learning assembler.)