AN INQUIRING MIND WANTS TO KNOW....
At some point in a man's live he realizes that the place reserved
for him in this world is totally unimportant. Reality impacts his
soul like a fly hitting a windshield of a brand new Alfa Romeo
33S going 100Mph. Money has become irrelevant, women are
uninteresting and sex is a triviality. The modern society spoils
his mind with cheap deals, the fast food is still raw, the coke
is lukewarm, the pizza is cold and the computers are dead
machines. There is no place for him, his feet are cold and his
digital watch runs backward. He trancends a region of space and
time totally new to him and he will develop into a new being. His
mind expands to insane proportions and his feet get even colder.
After being in a total state of nothingness, he decides to break
out of the endless vortex of nihilism and relives his early
youth, his First Time and the day he beheld the opening of
borders on his ST.
No more bullshit.
OBLITERATING SCREEN BORDERS
-or-
GIVING YOUR MMU A HARD TIME
by Stefan Posthuma
This article plus the source belonging to it are based upon an
original source written by Gunter of The Exceptions.
Ok, get your assembler, your clockcyclesheet, your ST Internals
and your intelligence together and listen to this:
If you take a look at the color demo in this issue of ST NEWS,
you will notice that the 'Digital Insanity' letters and the
little stars totally ignore the screen borders and happily fly
around the whole screen area. Officially, this is impossible,
since there simply is no screen there.
But we all know that it is perfectly easy to open the lower
border of the screen and display graphics there. It is an ancient
technique first used by TEX, in their Neochrome Slideshow. After
that, a lot of people have used it. After this, they found out
how to open the right border (Amiga Demo), the upper border and
finally the left border. The highlights of this technique can be
witnessed in the fullscreen demo from the Union demo, and the
Fullscreen demo from the Cuddly Demos. Both demos obliterate all
screen borders, and the Cuddly one even does full-screen
scrolling, using the breathtaking new hardware scrolling.
I am going to tell you how to open the left and right borders at
the same time, creating a very wide screen. The real secret
behind it is synchronized interrupts, which is a quite complex
technique. Since the opening of borders is a VERY delicate thing,
it has to be timed clockcycle-wise to get it right. Every
conventional interrupt will cause a small flicker on the screen,
which is fatal for border-obliterating routines. So we have to
find a way to make an interrupt fully stable.
So how do we achieve this?
There is a very interesting address in the I/O regions, called
'Video address counter low byte'. It is $FFFFFA09 for data-
freaks. The ST keeps track of which byte of screen memory it is
displaying, which is very useful for our little trick.
We read the low byte of the screen address and subtract a certain
value to make it a small value (<10). Then we synchronize using
this value. The 8th scanline of the screen looks like this
(assuming the screen starts at $F8000)
byte byte byte
------+------+------+
| | |
$F8500 $F8501 $F8502
Let's suppose we time an interrupt to occur at the beginning of
scanline 8, we can never get it to occur exactly at $F8500, so
exactly at the beginning of the scanline. No matter how hard we
try, the value will differ from $F8500 to $F850A (or something).
So let's say the maximum will be $F8510. The thing we have to to
is to take the value of $FFFFFA09, which will vary from $0 to $10
and subtract it from $10, leaving a number that indicates how far
we are from $F8510. So if $FFFFFA09=1, our value will be $10-
$1=$0E.
Now displaying 1 byte of screen memory takes approximately 2
clockcycles. So all we have to do is wait a number of
clockcycles (the number we just determined) and we will have a
stabilized interrupt.
If you take a look at the shift instructions, you will notice
that shifting a register x bits will take 6+x*2 clockcycles,
solving our problem! So if you use the following code, you will
get a stabilized interrupt:
MOVE.B $FFFFFA09.W,D0 ; GET SCREEN BYTE
MOVE.B #$10,D1 ; MAX. VALUE
SUB.B D0,D1 ; SUBTRACT SCREEN BYTE
LSL.W D1,D0 ; WAIT 6+D1*2 CYCLES
In practise, the value $10 will depend on the scanline you're on.
You also might want to subtract something from D0 first, to make
it approximately 0. Anyway, that's the trick, what rests us now
is the opening of borders! (But I'm gonna get a drink first...)
The old man slowly turned around and watched Therior so intensely
that a feeling of guilt slowly crept up his spine. His eyes
seemed to be on fire, spitting curses in Theriors direction.
Suddenly, the man drew a scimitar from his robe and emitted a
shrill cry, attacking Therior. But Therior was a trained
fighter. Immediately, his reflexes took over and as soon as he
gripped the handle of his broadsword, he turned and parried the
man's stroke with a swift flick of his blade. A splitsecond
later, his broadsword hit the man's skull, completely......
Oops, wrong story...
Ok, once you're in sync, you wait a while to reach the beginning
of the left border and the obliterating can start.
After 4 cycles, you change to monochrome resolution (70Hz) and
back again, opening the left border. This will take 16 cycles.
Then we wait a long time (356 cycles) to (almost) reach the right
border. Here we change to 60Hz and back, to open the right
border. Again 16 cycles. Then we wait another 52 cycles to reach
the end of the right border. Here, we change to 60Hz wait 4
cycles and switch to 50Hz back to smooth things out (20 cycles),
wait 48 cycles and we have had excactly 4+16+356+16+52+20+48 =
512 cycles = 1 scanline!
Programming this, we first have to set up some addresses in
registers:
LEA $FFFF820A.W,A0 ; SYNC MODE (50/60 HZ)
LEA $FFFF8260.W,A1 ; RESOLUTION
MOVEQ #2,D3
MOVEQ #0,D4
Then we synchronize and get the following loop:
; NUMBER OF LINES IN WHICH TO OPEN BORDERS
MOVE #99,D0
LINELOOP: NOP ; 4
; SWITCH TO MONO -> OBLITERATE LINKER BORDER (MMU: OUCH!!)
MOVE.B D3,(A1) ; 8 TO MONOCHROME
MOVE.B D4,(A1) ; 8 TO LO-RES
DCB.W 89,$4E71 ; 356
; 50/60 HZ FOR RIGHT BORDER (NURSE!!!)
MOVE.B D4,(A0) ; 8
MOVE.B D3,(A0) ; 8
DCB.W 13,$4E71 ; 52
; MONO AGAIN SO IT WILL WORK ON ALL MACHINES
MOVE.B D3,(A1) ; 8
NOP ; 4
MOVE.B D4,(A1) ; 8
DCB.W 9,$4E71 ; 36
DBRA D0,LINELOOP ; 12
Note that the directive DCB.W x,y will result in a block of x
words with the value y. Now the value of a NOP is $4E71, so
DCB.W 9,$4E71 will result in 9 NOP's, thus a wait of 4*9 = 36
clockcycles. This is a DevPack-only directive.
Note that since there is more data to display, the scanlines will
no longer be 160 bytes, but 230 bytes. This also means that the
effective screen size will no longer be 32000 bytes, but more,
depending on how many scanlines you open!
A problem
As you can see, if you want to open 20 scanlines, you have to
wait 20 scanlines, to open the borders. This will effectively
waste a lot of processor time, thus reducing the number of things
you can do on the screen in your demo. If you open all borders,
it will take all processor time, it's as simple as that.
So how does Level 16 play music, do a scrolltext, rasters and a
sprite while he has all borders opened? (Union Demo)
Well, you will have notices the NOP's in the loop, especially the
one block of 89 NOP's. If you fill in code here and count the
number of clockcycles it takes and add NOP's to get 356 cycles,
you will be OK. Now this takes a lot of puzzling and figuring out
since if you miss one clockcycle, the whole thing will mess up
totally.
In the ST NEWS demo, while I am opening borders, I also mirror
the scrolline in the 'water', reducing the waste of time.
Well, that's the story. Take a look at the 'BORDERS.S' source in
the PROGRAMS folder on this disk. Assemble it using DevPack and
witness the borders being blasted to nothingness.
One final note about hardware scrolling:
If you have experienced the Cuddly Demos by the CareBears, you
will witness hardware scrolling. They do it in the main menu, the
megaballs demo and in the fullscreen demo.
Hardware scrolling was invented by Nick and depends on the
ability of being able to change the screen address by a number of
bytes that can be as low as 8, thus bypassing the official limit
of 256 bytes.
If you fiddle enough with borders in the upper border, at some
point you will be able to change the screen address. If you
change it 160 bytes, the whole screen will scroll 1 scanline,
smoothly, reducing the time needed to redraw the whole area.
Also, if you change it 8 bytes, the whole screen will scroll 16
pixels to the left or the right.
Now this is extremely complex for it is not the same for all
machines. So the first thing you have to do is to find out which
version of the MMU there is in the ST and use different sync
routines accordingly. I have a source that does it, but I am
still totally mystified by the enormous complexity of it all. If
I do figure it out before February, a feature article will follow
in ST NEWS for sure.....
Disclaimer
The text of the articles is identical to the originals like they appeared
in old ST NEWS issues. Please take into consideration that the author(s)
was (were) a lot younger and less responsible back then. So bad jokes,
bad English, youthful arrogance, insults, bravura, over-crediting and
tastelessness should be taken with at least a grain of salt. Any contact
and/or payment information, as well as deadlines/release dates of any
kind should be regarded as outdated. Due to the fact that these pages are
not actually contained in an Atari executable here, references to scroll
texts, featured demo screens and hidden articles may also be irrelevant.