Writing low level stuff on all ATARI

From AtariForumWiki
Jump to: navigation, search

Original text by Leonard / Oxygene

Wikified by Simon Sunnyboy / Paradize

back to Programming

Writing low level stuff on all ATARI

(STf,STe,MegaSTE,TT,Falcon,CT60)

I've been writing demo stuff on the ATARI for 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've appended 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 this document is not ?

Before all, this 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 on how to use the 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 completely). 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 host 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 monitor type (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 powerful machine.

The TT, FALCON and CT60 have great processors using memory caching for both instructions and data. 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 behaviour. In the case of the TT or FALCON, simply do this:

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

This just switches off the 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" extras :-)

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, which 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 controlled by YM register 14 (remember, the same register used for selecting the floppy side). Remember to turn that poor internal speaker off. Example, 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 sound 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 the 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--- Useful 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

back to Programming