Loading Files Dynamically

This article is intended as an overview of the ways in which you can manage memory and load files from floppy disk or harddisk.


Unexpanded Amigas have a limited amount of memory. To target those models, you must sometimes manage memory to know that you can fit all that you want in your demo, and sometimes this means you have to keep some things, and discard others to make room for files loaded into the freed memory later.
There are many methods, and learning them gives you a good set of tools to apply for the right release type:
  • One-file executable (from floppy or harddisk)
  • Track-loaded (run from floppy only)
  • Multi-file demo (floppy or harddisk)

Planning memory usage

Often you have grand plans for your demo! In a multi-part demo, you often have to think of screen buffer sizes and how much memory they will require, while simultaneously keeping a song in chip memory and loading more resources. Planning will make you avoid downgrading your demo by selecting smaller screen buffers or sacrificing parts that didn't fit. That's bad mojo!
Users are expected to boot without startup-sequence (hold both mousebuttons at boot) and (for accelerated Amigas only) to run SetPatch before starting a demo. This maximizes the memory that you can use for your demo. Type "Avail" at the prompt to see how much that is on f.ex. A500 Kickstart 2.0, which is the worst case for A500. External floppy drives and harddisk buffers take 0.5K per sector, which is a point to consider when testing. If the demo fits on a floppy, harddisk buffers can be ignored by requiring the user to simply put the exe on a floppy.

Normally, you don't have to allocate memory yourself, but can create one big BSS Section with DS statements that do this for you when the executable is loaded by the OS, and use it freely. For screen buffers, they will have to be in Chipmem, so that usually, you create two big BSS sections: one BSS_C for stuff that has to be in Chipmem, like screen buffers, and one BSS (no prefix!) for all other stuff.
You can also disallow exit from the demo, and use all memory down to about address $100 as buffers. This can add up to 100-120K of usable Chipmem, but think twice if you really need it. One case where you shouldn't hesitate is if you have a tune that sounds great but really can't be made smaller. Surely everyone would prefer a great sounding demo without exit to a demo with grating samples!

One-file executable

The simplest case is the one-file executable: You include all files into the source of your demo, and write an object file. This file is a binary file, organized into hunks with extra information added to help the OS relocate absolute addresses to whatever memory address your demo is available to load it to. The Assembler software does this for you, so you can build and build, testing that it still fits in the normal amount of memory left after booting your target Amiga setup.
The order of operations is normally that the executable is loaded into memory, started, you turn off the OS, run the demo, and on mouse-click turn the OS on and exit.
One example of a one-file executable is Dreamscape by Aurora. There are of course too many examples to list, but if your demo doesn't push the limits or require fast multiload (for example: an intro), you should definitely release it as a one-file executable. It will be easy to run, distribute on packdisks, and they're easy to integrate in one's demo collection. :)


Here, the order of operations is that the OS loads the boot block (sectors 0 and 1) to anywhere in memory, executes it, you turn off the OS and use all of the memory to load further sector sequences into and execute them. If you keep the boot block in memory, i.e. use it for loading more parts, you must first copy it to a location you will not use.
Technically, you can keep the OS in memory and use it to relocate code (the bit that is taken care of for you in the case of one-file executables), but you will not be able to control where parts are loaded, and you will have to waste some memory by keeping the OS in memory.
It's far easier to not involve relocation at all, but to use ORG instead of SECTION to assemble your binary to start at a known address.
It's not necessary to know about the physical layout of a floppy disk in order to use this method. The disk is treated as a sequence of numbered sectors, and you've already used sectors 0 and 1 for the boot block, so the next load will be written (WS command) to sector 2 and up. Each load represents a contiguous chunk of memory matching a contiguous chunk of sectors, and you simply specify those parameters and call the trackloader.

You have two main choices for managing the loading sequence: you can script parts as separate loads from a common loader part or menu (as in Megademos, where all parts can use memory from a certain address and up, so that there is no memory area overlap between parts.
You can also chain each part to load the next part, as is the case in trackmos. If there are few parts, you can load each part to ever increasing addresses. You can also insert a picture or a text between each real part, which will break the flow and make it look and behave similar to a Megademo. But if you want it to appear an unbroken sequence of real parts, a useful tip is to load parts alternately into low and high memory areas, so that the next part can be loaded without overwriting the currently running part.
A track-loaded demo allows maximum memory usage and loads the quickest, and is the best choice for unaccelerated Amiga models such as the standard A500 Kick 1.3 with 512k Slowmem platform.
Remember the stacks! Don't use the top 4K of Chipmem, unless you know enough to assign your own stack pointers. You do not normally have to set the Supervisor stack pointer on stock machines if you follow this advice, but it's always good advice to point your system stack pointer (A7 register) to a memory area that you know is sufficient and won't be overwritten.

One example of a megademo is Red Sector Megademo, where the full-screen picture is the loaderpart. An example of a trackmo is Mental Hangover by Scoopex.
Note that with track-loaded demos, you can't run any DOS commands before starting the demo. This means your accelerator will not be configured as your commands do it in the startup-sequence. The only thing you can do is turn caches on/off. If you have code that depends on exact CPU speed, you will have to make it compatible (or add code to handle all accelerator types yourself).

Multi-file demo

This type of demo, in its simplest form, is a number of one-file executables scripted to run in sequence. There are some examples where a song is started first of all, and then the soundless executables are loaded one by one, the OS screen hidden most simply by a system-configuration with all colors set to the same RGB value. Each part can of course have its own music. Examples include PD demos and Trip To Mars by Tomas Landspurg.
But that's not usually how multi-part demos are made, even if there's nothing wrong with that.
More commonly, the demo is kept running, and resources are loaded into memory when needed. This is often the case with demos for accelerated Amigas, where the OS consumes much less CPU time. This makes it convenient for the coder to have a development folder where he can add resource files as he develops the demo, and at any point he can push out an executable and it will run the same as in his development environment. He has only to strip any source and build files and zip the folder in order to release the prod as an archive.
To load files while the demo is running, the OS can't be completely turned off. In other words, nowhere in your code must you disable the INTEN, DSKSYN, VERTB, PORTS, or DSKBLK bits in INTENA.
For unaccelerated Amigas, this means that the OS will use a chunk of CPU time - up to 17% or 50 scanlines, if you move the mouse. When 100% CPU time is required, you can temporarily disable the above bits, only to restore them when loading. If your demo is using the vertical blank interrupt as well, you must use a hook as described in f.ex. The System Programmer's Guide found under Downloads.
To just load a file to memory:
	moveq #0,d6			;filesize or 0 if not ok
	move.l #Filename,d1
	move.l #_1005,d2		;mode_old - file must exist
	jsr -30(a6)			;DOS Open()
	move.l d0,d5			;copy file handle
	move.l d5,d1			;filehdl
	move.l #Destination,d2		;addr
	move.l #FileLength,d3		;maxlen cap
	jsr -42(a6)			;DOS Read()
	cmp.l d7,d0
	bne.s .notok
	move.l d7,d6			;loading ok! (set to size!)
.notok:	move.l d5,d1			;file handle
	jsr -36(a6)			;DOS Close()

This can be used in other productions than demos too, f.ex. for loading pictures in a slideshow or tunes in a musicdisk.