Writing low level stuff on all ATARI
(STf,STe,MegaSTE,TT,Falcon,CT60)


I write demo stuff on ATARI since a long time now. Believe me or not but I enjoy writing ATARI demos even today. ( shame on me :-) ). I always targeted my demos for ATARI-STf. Actually I don't know what kind of ATARI people had at home: emulator, ST, TT, FALCON ? So I don't know if people can see my demos or not. That's a big problem because demos are made to be seen :-).

Now I decided to make my new stuff working on all these ATARI machines: STf,STe,MegaST,TT,Falcon and even CT60. For people who want to write demo working on all these machines, here are some rules you have to follow in order to make your demo "compatible".

Before the show I would like to thanks Heinz Rudolf aka Cyclone / X-Troll for precious help on debugging all my low level stuff on FALCON,TT and CT60 ( As I don't have any of these machines, it's funny to do FALCON remote debugging between France and Germany using ICQ :-) ).

NOTE: I happend my boot-sector compatible source code at the end of the document. It uses all stuff described here, so you can use it to initialize your demo.

1) What that document is not ?

Before all, that document just explains rules you have to follow in order to run your STf demo on every machine listed above. This document is not a document to use TT, Falcon or CT60 at best. It does not contains any optimisation tips, etc. Worst, it generally explain how to slow-down your machine to run your code as an ST should.

Ok let's start...

2) Low and high level stuff

In introduction I speak about "low level" stuff. Actually you often find demos in "file" format (PRG). These demos can be launched from hard-disk and generally use some hardware settings the operating system has already initialized. As an "oldskool" fanatic, I prefer "trackload" demo. That is, the demo uses its own file system and boot from floppy. You can't rely on operating system for hardware initialization (not completly). For those who prefer "high level" stuff, you can skip some parts of the document.

3) What kind of machine is it ?

In the very beginning of your demo ( bootsector is a nice place !), you have to detect the machine. We can do that using classic ATARI Cookie-JAR. ( Warning: Cookie-JAR does not exist on every ATARI-ST, take it into account !). If there is no cookie support, you can guess you're on an old ATARI STF. If there is cookie support, then here is how to know the machine:

Cookie Signature
Value
Description
_MCH
$0000xxxx
STf
_MCH
$00010000
STe
_MCH
$00010010
Mega-STe ( only bit 4 of the 32bits value tells it's a Mega-STE )
_MCH
$0002xxxx
TT
_MCH
$0003xxxx
Falcon
CT60
$xxxxxxxx
CT60

 

4) Video

Once you know what kind of machine is it, you can initialize video. Remember you do an ATARI-ST demo, so you want to select a mode very close to 320*200, 50Hz. On ST, STE or MegaSTE, set the video by a classic

clr.b $ffff8260.w
move.b #2,$ffff820a.w

For TT machine, better use the rom code with XBios function:

clr.w -(a7) ;set stlow (st/tt)
moveq #-1,d0
move.l d0,-(a7)
move.l d0,-(a7)
move.w #5,-(a7)
trap #14
lea 12(a7),a7

Things are a bit more tricky for FALCON and CT60, because you don't know anything about the monitor. ( RGB or VGA ). so first, use XBios to know about the monitor:

move.w #$59,-(a7) ;check monitortype (falcon)
trap #14
addq.l #2,a7

(remember to execute that XBios call on Falcon ONLY !). If the func returns 1 or 3, you are on RGB monitor, otherwhise you are in VGA. Here is the code I use to setup video registers in both RGB and VGA case:

lea vga50(pc),a0 or
lea rgb50(pc),a0

move.l (a0)+,$ffff8282.w
move.l (a0)+,$ffff8286.w
move.l (a0)+,$ffff828a.w
move.l (a0)+,$ffff82a2.w
move.l (a0)+,$ffff82a6.w
move.l (a0)+,$ffff82aa.w
move.w (a0)+,$ffff820a.w
move.w (a0)+,$ffff82c0.w
move.w (a0)+,$ffff8266.w
clr.b $ffff8260.w
move.w (a0)+,$ffff82c2.w
move.w (a0)+,$ffff8210.w

vga50:
dc.l $170011
dc.l $2020E
dc.l $D0012
dc.l $4EB04D1
dc.l $3F00F5
dc.l $41504E7
dc.w $0200
dc.w $186
dc.w $0
dc.w $5
dc.w $50

rgb50:
dc.l $300027
dc.l $70229
dc.l $1e002a
dc.l $2710265
dc.l $2f0081
dc.l $211026b
dc.w $0200
dc.w $185
dc.w $0
dc.w $0
dc.w $50

5) Cache, CPU speed and memory

The main goal is to run your ST demo on powerfull machine. TT, FALCON and CT60 has great processors using memory caching for both instructions and datas. If you don't read the Microsoft "Writing solid code" book and you continue to do self-modifying code ( good boy :-) ), you may have trouble on these CPUs. In that case, the best you have to do is to switch off all memory caching, to be very close to the ST memory bahavior. In case of TT or FALCON, simply to this:

moveq #0,d0
dc.l $4e7b0002 ; movec d0,cacr ; switch off cache

This simply swith off caches. The "MOVEC" instruction is binary coded just because my 68000 assembler doesn't know that mnemonic. If you are on CT60, better use an official XBios call to switch off all these "new skool" stuff :-)

clr.w -(a7) ; param = 0 ( switch off all caches )
move.w #5,-(a7) ; opcode
move.w #160,-(a7)
trap #14
addq.w #6,a7

Now you can do self-modifying code, you can load data using DMA with no problem. Hem, not exactly. On FALCON, the CPU needs some virtual memory tables, wich are located in low memory space. In other words, don't use anything below $1000 address. If you really need every bytes of memory, simply use two code paths in your demo. In my latest "sprite record", all the demo code is loaded at $200 to work on 520-ST. On FALCON, I load all demo code at $1000 ( I'm sure there is more than 512Kb on FALCON ! ( if not, a bastard has surely fucked you on eBay :-) )

For the oldskool guys, just know you can use memory from $100 to $2ff safely. I'm not sure about it, but I guess you can use $100 to $6ff.

Last but not least, you can setup MegaSTE to 8Mhz if you want perfect ST speed using:

clr.b $ffff8e21.w ; 8Mhz MegaSTE

6) Trackload and FDC routs

What ? you want to do a demo running on hard-drive ? are you crazy or what ? If you really want to continue the oldskool trip you have to make a track-loaded disk. Take your old rout and simply make it a bit "slower". If you had some "nops" in your old rout between FDC commands, simply call a Wait subroutine instead:

Wait:
move.w d0,-(a7)
move.w #16-1,d0
.wait:
dbf d0,.wait
move.w (a7)+,d0
rts

Another nice trick to know: on FALCON, internal speaker is controled by YM register 14 ( remember, the same register used for selecting the floppy side ). Remember to turn that poor internal speaker off. Exemple, to select side 0:

SPEAKER = $6060
move.l #$0e0e0505 | SPEAKER,$ffff8800.w

7) Video sync and music

If you are doing an ST demo, you surely have a great 50hz oldskool music. The music may sounds bad if replayed with another frequency ( on TT, FALCON or CT60 ). Remember the VBlank interrupt is not at 50hz on these machines. Please use timer routine for music playing. Here is the code to launch a timer interrupt at 50hz using TimerA.

clr.b $fffffa19.w
bset #5,$fffffa07.w
bset #5,$fffffa13.w
move.b #245,$fffffa1f.w
move.l #timerA,$134.w
move.b #7,$fffffa19.w ; prediv 200, -> 50Hz timer

If your ST demo is optimized to the death and the music routine is done in the mainloop ( no interrupt ), just modify the code using "nops" and launch music interrupt in case of TT, FALCON or CT60. You keep the maximum speed on ST, and the demo still works on stronger machine.

Another important thing to know on TT or FALCON is sound shadowing registers. In these machines, you can't use MOVEM anymore to access sound-chip registers, as many routines do. Just use $ff8800 and $ff8802. If you have a music player using these shadowing capabilities, simply patch the original code for TT and Falcon compatibility.

8) Last hints

Usefull tips on CT60: The 68060 does not implement the MOVEP instruction !! ( what a lame idea from motorola ?). The instruction is software emulated on 68060 based machine, but not on FALCON CT60 from bootsector. So, simple, DON'T use MOVEP at all on CT60 ! ( Thanks Cyclone ! ). If MOVEP was a great optimisation for your ST demo, simply use another code path on CT60. Even if second code is slower, the CT60 will run it faster than your MOVEP code, so don't care !

The end...

I hope I don't forget anything here. If you have comments, corrections or new ideas, write me !

 

Leonard / OXYGENE
15/08/2004
http://leonard.oxg.free.fr

 

Appendix ( bootsector code to initialize hardware )

; Multi Atari Boot code.
; If you have done an ST demo, use that boot to run it on these machines:
;
; ST, STe, Mega-ST,TT,Falcon,CT60
;
; More info:
; http://leonard.oxg.free.fr/articles/multi_atari/multi_atari.html



start sf $1fe.w
move.l $5a0.w,d0
beq noCookie
move.l d0,a0
.loop: move.l (a0)+,d0
beq noCookie
cmp.l #'_MCH',d0
beq.s .find
cmp.l #'CT60',d0
bne.s .skip

; CT60, switch off the cache
pea (a0)

lea bCT60(pc),a0
st (a0)

clr.w -(a7) ; param = 0 ( switch off all caches )
move.w #5,-(a7) ; opcode
move.w #160,-(a7)
trap #14
addq.w #6,a7
move.l (a7)+,a0
.skip:
addq.w #4,a0
bra.s .loop

.find: move.w (a0)+,d7
beq noCookie ; STF
move.b d7,$1fe.w

cmpi.w #1,d7
bne.s .noSTE
btst.b #4,1(a0)
beq.s .noMegaSTE
clr.b $ffff8e21.w ; 8Mhz MegaSTE

.noMegaSTE:
bra noCookie

.noSTE:
; here TT or FALCON

; Always switch off the cache on these machines.
move.b bCT60(pc),d0
bne.s .noMovec

moveq #0,d0
dc.l $4e7b0002 ; movec d0,cacr ; switch off cache
.noMovec:

cmpi.w #3,d7
bne.s noCookie

; Here FALCON
move.w #$59,-(a7) ;check monitortype (falcon)
trap #14
addq.l #2,a7
lea rgb50(pc),a0
subq.w #1,d0
beq.s .setRegs
subq.w #2,d0
beq.s .setRegs
lea vga50(pc),a0

.setRegs:
move.l (a0)+,$ffff8282.w
move.l (a0)+,$ffff8286.w
move.l (a0)+,$ffff828a.w
move.l (a0)+,$ffff82a2.w
move.l (a0)+,$ffff82a6.w
move.l (a0)+,$ffff82aa.w
move.w (a0)+,$ffff820a.w
move.w (a0)+,$ffff82c0.w
move.w (a0)+,$ffff8266.w
clr.b $ffff8260.w
move.w (a0)+,$ffff82c2.w
move.w (a0)+,$ffff8210.w

noCookie:

; Set res for all machines exept falcon or ct60
cmpi.b #3,$1fe.w
beq letsGo

clr.w -(a7) ;set stlow (st/tt)
moveq #-1,d0
move.l d0,-(a7)
move.l d0,-(a7)
move.w #5,-(a7)
trap #14
lea 12(a7),a7

cmpi.b #2,$1fe.w ; enough in case of TT
beq.s letsGo

move.w $468.w,d0
.vsync: cmp.w $468.w,d0
beq.s .vsync

move.b #2,$ffff820a.w
clr.b $ffff8260.w

;---------------------------------------------------------------------
letsGo:

; load your kernel, or whatever you want here !


;---------------------------------------------------------------------

vga50: dc.l $170011
dc.l $2020E
dc.l $D0012
dc.l $4EB04D1
dc.l $3F00F5
dc.l $41504E7
dc.w $0200
dc.w $186
dc.w $0
dc.w $5
dc.w $50

rgb50: dc.l $300027
dc.l $70229
dc.l $1e002a
dc.l $2710265
dc.l $2f0081
dc.l $211026b
dc.w $0200
dc.w $185
dc.w $0
dc.w $0
dc.w $50

bCT60: dc.b 0
even