
Small Mcode.

When even the smallest Ataris have al least 500 kb of memory there is
normally no reason to save memory by making programs small, there is
hovever one thing were space is cramped and you have be economical
about your code, it's when you want to make a complete program that
fits into a 512 bytes bootsektor!
There are two ways of looking at the lenght of a program, dynamic or
static. The dynamic lenght is how many instructions are executed when
the program is executed, the smaller dynamic lenght, the faster
program. Static lenght is how much memory the code occupies.
There are several ways of reducing codesize, either reprogram using
fewer instructions, or make instructions themselves smaller.
Instructions can be of three different sizes 2, 4 and 6 bytes.

First a list on the size of different instructions, all these have
the same effect and only differs in size!


Machine Code    Mnemonics                Comment

DFFC00000002    add.l     #2,sp          This adjust the stackpointer
4FEF0002        lea       2(sp),sp       Only works upto 32k.
548F            addq.l    #2,sp          Only works upto 8.


203C00000013    move.l    #19,d0         Inits a dbra loop.
303C0013        move.w    #19,d0         only word is needed.
7013            moveq.l   #19,d0         only upto 128.


227C0000044E    move.l    #$44e,a1       Move from an adress
2278044E        move.l    $44e.w,a1      Only works in low memory

227900000074    move.l    hej,a1         move from fixed adress.
227A004A        move.l    hej(pc),a1     relative is smaller


4EF900000074    jmp       hej            Jumps.
60000038        bra       hej            Branch is always smaller.
6034            bra.s     hej            only short distance.


There are also some more tricks to make code smaller, Below are two
examples that sets medium resolution.

3F3C0000        move.w    #0,-(sp)            setscreen 28 bytes
2F3CFFFFFFFF    move.l    #-1,-(sp)
2F3CFFFFFFFF    move.l    #-1,-(sp)
3F3C0005        move.w    #5,-(sp)
4E4E            trap      #14
DFFC0000000C    add.l     #12,sp

2F3CFFFF0000    move.l    #$ffff0000,-(sp)    setscreen 24 bytes.
2F3CFFFFFFFF    move.l    #-1,-(sp)
2F3C0005FFFF    move.l    #$0005ffff,-(sp)
4E4E            trap      #14
4FEF000C        lea       12(sp),sp

By moveing more data at a time to the stack, code can be reduced in
size.

Here is a source list of this disks bootcode. The original program was
176 bytes long, after considering the above info I got it down to 100
bytes.


start
        lea     tend+30(pc),a5
        move.l  a5,a6

* These two lines are the only initialization needed, where to find
* the scrolltext, as you can see I set end of text marker and text-
* pointer to the same value, starting scrolling at the end of the text
* tend+30 means 30 spaces added after the scrolltext.
* (It's 30 ascii 0 really but they both look the same so it doesn't 
* matter)

key     moveq.l #3,d7
shut_up bsr.s   shift
        bsr.s   shift
        move.l  #$25000b,-(sp)
        trap    #14
        addq.l  #2,sp
        dbra    d7,shut_up

* When I move #$25000b to the stack and later adjust SP with 2 I
* will exit the loop with four words of 000b on the stack, I need
* these later on.

        cmp.l   a5,a6
        bne.s   cont
        lea     text(pc),a6
* I check and see if I've reached the end of the scrolltext!
* This will be true when starting the code so I reset a6 to start
* of text.

cont    dc.w    $a000           fontbase
        move.l  4(a1),a1
        move.l  76(a1),a1
* The original did this at the beginning and stored the result in a
* data register, moveing it here saved a few bytes.

        move.b  (a6)+,d6
        add.l   d6,a1
        moveq.l #7,d0
new_char
        move.b  (a1),(a4)
        addq.l  #2,a4
        lea     256(a1),a1
        dbra    d0,new_char
* nothing very fancy here, only a4 that got it's value in the 
* shift subroutine.

vsync   trap    #1
        addq.l  #8,sp
        tst.b   d0
        beq.s   key
* When I get here, the stack will contain 4 word of $000b, so I use
* those and adjust SP accordingly.


shift   move.l  $44e.w,a1               find screen
        lea     3354(a1),a1     2-red,4-green,8-blue!
* gets screenbase and adds a number so I can scroll bottom to top.


        move.l  a5,a4
        moveq.w #7,d0
rows    lsl.w   -(a4)
        moveq.w #19,d1
left    roxl.w  (a1)
        subq.l  #8,a1
        dbra    d1,left
        dbra    d0,rows
* This is where I get the a4 value I use later on.

        rts     Return with RTS!

text    dc.b    "This is the bootscroller in this mag. "
        dc.b    "This code is now 100 bytes long "
        dc.b    "and I don't think I can make it any smaller.   "
        dc.b    "Bootscrollers are nice, you don't have to write "
        dc.b    "long scrolltexts!!!  Only 383 bytes of chars!! "
        dc.b    "Greetings to Bluestar.  Thats all folks!     "
        even
tend    dc.b    ""

If you know how to make this smaller or If you already have a smaller
scroller, please let me know. I think this is the smallest possible
all char scroller on the ST.

Hints and tips:

Use the info above, if you only need to add a number between 1 and 8
use addq, between 1 and 32000 use lea.

Using PC offset is double effective when compiling to PRG files, it's
smaller in itself and it doesn't require an entry in the relocate
table.

You can, when having several traps after each other, adjust the
stackpointer only after the last one.

Try not to use any memory locations to store data if possible, moving
between two register takes only 2 bytes of memory and diskspace.

Remember that speed is not that important, if you need the physbase DO
NOT find it before the program starts and store it somewhere, but get
it only when you need it. That goes for all initialization, if you can
get it within the code, do so. It will save you the instructions to
store it first and recall it later.

Search for instructions that appear two times or more where you put
values in data or adress registers, perhaps you can alter the code so
that only the first initialisation is needed.

Most important, admit defeat, when you've tweaked and fiddled with 
your code so it's only half the original size it might be impossible 
to compress it further.

