English Amiga Board

English Amiga Board (https://eab.abime.net/index.php)
-   Coders. Asm / Hardware (https://eab.abime.net/forumdisplay.php?f=112)
-   -   Best practices for direct hardware programming ? (https://eab.abime.net/showthread.php?t=61225)

weiju 29 September 2011 03:34

Best practices for direct hardware programming ?
 
Hi,

when I programmed the Amiga the first time around, I always had been using it with the operating system turned on. I was now interested into poking into the hardware registers directly. Since I often read about that you have to deactivate the operating system, I was wondering what would be the best approach to do that so I can still do something like starting the program from DOS, work directly on the hardware and after exiting, I can continue using the system again. Do I really have to deactivate everything (e.g. Exec and DOS) or only parts ?

Thanks,

Wei-ju

pmc 29 September 2011 08:59

I tend to forbid multitasking (ie. take over the whole system) and save the state of the essential bits of the system so that I can restore them before permitting multitasking again. This seems to work fine for me - my code works on most systems I've ever tried it on.

You'll need to save things like, the system copper list addresses, the state of the any dma and interrupt registers etc. etc. If you want startup code I can give you some, or there are others out there who can too (Hi Stinger :))

There are cleaner ways to take over the system than I use though which, as someone who normally does their code with the OS enabled, you might find more to your taste.

See here: http://www.mways.co.uk/amiga/howtoco...tupandexit.php
and here: http://www.mways.co.uk/amiga/howtoco...ce/startup.asm

freehand 29 September 2011 16:43

I used to go in with all guns blazing and just save a handful of states copper list e.t.c but just recently i wish to show some peeps my uridum soft-scroll routine so i have cleaned it up a little, all so i have taken a snippet of code from some guy called stingray so people can few on the 1200.

pmc 29 September 2011 17:08

Quote:

Originally Posted by freehand
from some guy called stingray

LOL :D

Geijer 29 September 2011 20:34

The problem with taking over the system totally is that you can not load data from hard drive, the days of trackdisk loading routines are unfortunantely over :(
I need a good way to bang the hardware and still load data from the hard drive or is it best practice to use "loading scenes" where the system is temporarily enabled.
(let me know if you think I am stealing your thread)

pmc 29 September 2011 21:58

@ Geijer - check the first link I posted above: quoting directly from the page it links to:

Quote:

Instead of using Forbid() and Permit() to prevent the OS stealing time from your code, you could put your demo or game at a high task priority.

Now, only essential system activity will dare to steal time from your code. This means you can now carry on using dos.library to load files from hard drives, CD-ROM, etc, while your code is running.
:)

weiju 30 September 2011 02:32

Thanks for the advice and pointers, I'll probably try both the Forbid()/Permit() and the high-priority approach. Another interesting thing to know would be memory allocation. Do you allocate all your mem at the beginning (before Forbid()) and use that for the entire runtime of the program or rather allocate on the fly ?

pmc 30 September 2011 08:05

Personally, I don't really allocate memory at all. Instead, I just ask the assembler to reserve memory in my code for my use.

For example, if I wanted to have space for a standard 320*256 bitplane I would usually do something like:

Code:

bitplane:          dcb.b              10240,0
Then, at run time, I can just use this space as bitplane data.

Photon 01 October 2011 03:26

With regards to the original question, it's really a decision whether you want/need to have the system on [all the time in the background] or not.

If you're doing a system-friendly utility or game, the answer is obviously yes. If you're doing a regular demo or game and need full CPU time to make sure it runs as smooth as possible, the answer's as obviously no.

If yes, then you're already there, nothing special needs to be done, just write the library code from scratch.

If no, then there are plenty of simple Startup Routines that you could use. You can use libraries while the system is on, and some parts even when the system is off.

System off really only means disabling some interrupts, not shutting it down completely and removing it from memory.

You can turn the system on and off for portions of your program, such as 'in-game' (off) and 'loading files' (on). You need to switch the system on and off wisely (ie. not while the OS finishes a write of file to disk) and correctly, but there's nothing stopping you from doing it anytime you like. If you catch my drift. ;)

There's no real need for Forbid/Permit on original HW/OS [in order to manage system on/off], I never use it. But you WILL need to lock/alloc/own resources shared by the system, even if the system is off, if you plan to return to the OS that is. Ie. alloc memory, OwnBlit etc.

Minuous 01 October 2011 04:54

Quote:

Originally Posted by pmc (Post 779071)
Personally, I don't really allocate memory at all. Instead, I just ask the assembler to reserve memory in my code for my use.

For example, if I wanted to have space for a standard 320*256 bitplane I would usually do something like:

Code:

bitplane:          dcb.b              10240,0
Then, at run time, I can just use this space as bitplane data.

Wouldn't this be better as ds.b? Won't dcb.b bloat the size of the executable?

pmc 01 October 2011 06:50

Minuous: Same difference. Using ds.b still makes 10240 bytes of space available.

To test, assemble just dcb.b 10240,0 or ds.b 10240 - either way, size of assembled code: 10240 bytes

Also remember that, for this example, any cruncher is going to squeeze 10240 contiguous bytes of 0's down to virtually nothing.

StingRay 01 October 2011 08:59

Quote:

Originally Posted by Minuous (Post 779169)
Wouldn't this be better as ds.b? Won't dcb.b bloat the size of the executable?

Depends where you use it. Outside of a BBS section, ds.b and dcb.b is exactly the same, the size of the allocated memory will be added to the executable. In a BSS section (where you can only use ds.b) only the size of the allocated memory will be stored (hunk header), i.e. size of the executable won't change except for the entries in the hunk header.

Quote:

Originally Posted by weiju (Post 779058)
Thanks for the advice and pointers, I'll probably try both the Forbid()/Permit() and the high-priority approach.

The high priority approach is rather pointless IMHO. Either you want to kill the system or you don't. That's just my opinion anyway, I never liked that approach. And you can load files even with disabled system, you just need to make sure that you re-enable the ports/timers interrupt before loading a file. I can post the code of my file loader that uses exactly this approach if you want. But try to do it yourself first. :)

pmc 01 October 2011 11:00

Nice one for that explanation Stinger - I learned something new today :)

Photon 01 October 2011 17:12

I type too much, Stingray summarizes my post nicely: just decide if and when you want the system off. This can be tricky to know if you're new or unfamiliar with such practices of course, but I hope my longer post gives some tips on how to know when turning off the system is useful. Either way, turn it off by disabling ints like all the proven startup sources do.

Leffmann 01 October 2011 17:46

I would disable multitasking, suppress all requesters and add an input handler with highest priority that just returns 0. This way your code runs almost exclusively on the system, you've full control over the screen and you've got file I/O, and any mouse clicks, keyboard presses and other user input will not reach the Workbench to possibly glitch something up.

This sort of game and demo programming is a bit like a realtime system where you want to control exactly what code runs and when, so from here you can also prevent the system interrupts from running by just disabling them or removing them from the interrupt chain, and temporarily enable them again whenever you need file I/O.

Quote:

Originally Posted by StingRay (Post 779175)
Depends where you use it. Outside of a BBS section, ds.b and dcb.b is exactly the same, the size of the allocated memory will be added to the executable. In a BSS section (where you can only use ds.b) only the size of the allocated memory will be stored (hunk header), i.e. size of the executable won't change except for the entries in the hunk header.

Actually that's not entirely correct, the allocate size of a hunk can be different from the size of its contents in the file. It's possible to f.ex have a 10K executable load into 20K of allocated space.

pmc 01 October 2011 18:25

I have a question. As a test, I did this:

Code:

                    section            data,bss
bitplane:          dcb.b              10240,0

Which assembled with no errors and a code size of 10240 bytes.

I also did this:

Code:

                    section            data,bss
bitplane:          ds.b                10240

Which again assembled with no errors but again with a code size of 10240 bytes.

Now, bearing in mind this:

Quote:

Originally Posted by StingRay
Outside of a BBS section, ds.b and dcb.b is exactly the same, the size of the allocated memory will be added to the executable. In a BSS section (where you can only use ds.b) only the size of the allocated memory will be stored (hunk header), i.e. size of the executable won't change except for the entries in the hunk header.

I would've expected to get an error for using dcb.b on the first test and a code size of 0 on the second test. Or have I missed something or done something wrong...?

Lonewolf10 01 October 2011 23:26

Quote:

Originally Posted by pmc (Post 779225)
I would've expected to get an error for using dcb.b on the first test and a code size of 0 on the second test. Or have I missed something or done something wrong...?

Did you turn off optomisations and such-like? Theres a good chance that Devpac (or whatever you are using) has corrected it without telling you.


Regards,
Lonewolf10

pmc 02 October 2011 05:59

No, no optimisations enabled.

StingRay 02 October 2011 15:36

Quote:

Originally Posted by Leffmann (Post 779221)
Actually that's not entirely correct, the allocate size of a hunk can be different from the size of its contents in the file. It's possible to f.ex have a 10K executable load into 20K of allocated space.

What I wrote is completely correct. The question was about ds.b vs. dcb.b and what happens to the executable size. That there are lots of other ways to deal with hunks is irrevelant here.

Quote:

Originally Posted by pmc (Post 779225)
I would've expected to get an error for using dcb.b on the first test and a code size of 0 on the second test. Or have I missed something or done something wrong...?

My guess is that Devpac silently removed the BSS section (maybe because there wasn't any code?), check the executable in a disassembler. dcb.b doesn't make sense in a BSS section because BSS data is uninitialised, i.e. dcb.b 10240,$ff won't work in a BSS section. BSS = B.lock S.torage S.ection and ds.b = d.efine s.torage. dcb = d.efine c.onstant b.lock which, as said, won't make sense in a BSS section.

pmc 02 October 2011 17:35

You're right Stinger - Devpac was silently substituting dcb.b for ds.b on assembly.

Assembled size as reported by Devpac is 10240 bytes but the size on disk is 108 bytes.

I *hate* it when it does things like that. It should at least warn about the fact it's making a substitution!


All times are GMT +2. The time now is 15:00.

Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2024, vBulletin Solutions Inc.

Page generated in 0.09463 seconds with 11 queries