[comp.sys.atari.st] Extend you ST's screen into the border...

unpowell@csvax.liv.ac.uk (03/09/88)

		EXTENDING THE ST SCREEN INTO THE BORDER

   You may have seen programs on the C64 that "removed" the border,
at the top and the bottom of screen. This is possible on the ST. It's
not really a new discovery as I worked out how to do it during Easter
1987, but recently I've seen a few programs by other people using it,
so I thought I'd tell the rest of the world about it. 
   It is quite a simple procedure to produce this effect. While the
last raster line of the normal display area is being displayed set
the ST in 60Hz mode. Then wait until the next raster line and put
it back into 50Hz mode, simple! The border at the bottom of the screen
will "disappear" and the memory following the normal display area will
be displayed down there. This really works best on a TV as there is a
lot more space below the picture on a TV. I hear all you people in the
States saying "but we're already in 60Hz mode", well I know that. I
have never used this on a 60Hz display, but maybe doing the opposite
will work, ie. into 50Hz on last screen raster line and back to 60Hz
on first "border" raster line.
   Anyway the two source listings following will demonstrate this. The
first is the proper way to do it, as it creates a perfect display into
the border. The second uses a bit less processor time, but as you will
notice the last 16 pixels of the normal screen are missing from the
display. The second is given for people writing programs with not much
time to spare (their programs haven't much time to spare that is),
where the first method which takes up a whole raster line, will get
in the way of other interrupts they have going.
   They both use timerb to count the raster lines down the screen.
Although they could just interrupt at the last raster line on the
normal screen, by setting timer B data register to 199, they interrupt
on every raster line to put the colours up, which show that the extra
display lines just work like any others and that the HBL on these lines
is just like on any other.
   Although I only describe how to remove the border at the bottom of
the screen, it can also be done at the top of the screen, but the method
doesn't work with some televisions that can't handle a 60Hz display.
Other "strange" effects can be produced with the display. Changing
screen resolution while the raster scan is in the physical display area
can expand the screen's width, but more on this at a later date.

Method 1

   This program interrupts on the last raster line inside the normal
display, and then waits until the next HBL. When the next HBL comes it
puts the ST into 60HZ mode and then delays for a short time until the
raster scan is just into the next raster line. Then it puts the ST
back into 50Hz mode. This waiting means that the interrupt routine
takes up two raster lines, which can be a problem in some programs,
although this method produces the best display.

raster_line	equ	$40
global_colour	equ	$44
local_colour	equ	$48

	clr.l	-(sp)
	move	#32,-(sp)	* Into super mode
	trap	#1		* very messily (who cares?)
	lea	$70000,sp

	move.l	a7,a0		
	lea	$fc0000,a1
	moveq	#-1,d0		* put ROM
	move	#40000/4-1,d1	* on screen
filllp	move.l	(a1)+,(a0)+	* for something to look at (?)
	dbra	d1,filllp

	move.b	#7,$8201.w	* screen to $70000
	clr.b	$8203.w

	move	#$2700,sr	* take over the system (My favourite!)
	clr.b	$fa07.w		* disable
	clr.b	$fa09.w		* all interrupts
	clr.b	$fa0b.w		* clear all
	clr.b	$fa0d.w		* "pending"
	clr.b	$fa0f.w		* clear all
	clr.b	$fa11.w		* "in service"
	move.b	#1,$fa13.w	* mask timerb
	clr.b	$fa15.w		* mask none
	move.b	#8,$fa1b.w	* timerb into event count mode
	move.b	#1,$fa21.w	* want interrupt on every raster line
	move.l	#timerb,$120.w	* set up timerb handler
	move.l	#vbl,$70.w	* set up vbl handler
	stop	#$2300		* wait for vbl
	clr.b	$8260.w		* low res (works just as well in medium)

	move.b	#1,$fa07.w	* enable timerb

loop	bra.s	loop		* hang about

vbl	clr	$8240.w		* pallette 0 to black
	clr	(raster_line).w			* reset raster_line
	move	(global_colour).w,(local_colour).w	* this gives
*							  the scrolling
*							  effect in the
*							  border
	add	#$89,(global_colour).w		* increment
	and	#$777,(global_colour).w		* global_colour
	rte

timerb	move	(local_colour).w,$8240.w	* set pallette 0
	cmp	#198,(raster_line).w	* right raster line?
	bne.s	not
	clr.b	$fa1b.w		* TBCR must be clear to allow next
*				  instruction to work
	clr.b	$fa21.w		* TBDR=0 ie interrupt on next hbl
	move.b	#8,$fa1b.w	* timerb back into event count mode
wtlp	tst.b	$fa21.w		* wait for next hbl
	beq.s	wtlp
	clr.b	$820a.w		* into 60Hz mode
	move.l	$40,$40		* Delay 76 clock periods
	move.l	$40,$40		* until scan is in border on next
	nop			* raster line
	move.b	#2,$820a.w	* back to 50Hz mode
	clr.b	$fa1b.w		* TBCR=0 for same reson as last time
	move.b	#1,$fa21.w	* back to counting single lines
	move.b	#8,$fa1b.w	* back to event count mode
not	addq	#1,(raster_line).w	* increment raster_line
	add	#$89,(local_colour).w	* increment
	and	#$777,(local_colour).w	* local_colour
	clr.b	$fa0f.w		* clear interrupt in service bit/byte?
	rte			* exit

Method 2

   The second listing, which follows, interrupts on the last raster
line of the normal display and immediately puts the ST into 60Hz mode.
It then waits a short while until the raster scan has moved from the
border into the screen display area and then goes back to 50Hz mode.
For some reason (probably due to part of the display line being in
60Hz and part being in 50) the last 16 pixels of the last normal screen
display line are completely left off from the display, which leaves the
border colour showing through here. If you need the extra speed and can
cope with this missing "word" then this is the version for you.

raster_line	equ	$40
global_colour	equ	$44
local_colour	equ	$48

	clr.l	-(sp)
	move	#32,-(sp)	* Into super mode
	trap	#1		* very messily (who cares?)
	lea	$70000,sp

	move.l	a7,a0
	moveq	#-1,d0		
	move	#40000/4-1,d1	* fill screen so 
filllp	move.l	d0,(a0)+	* missing word shows up
	dbra	d1,filllp

	move.b	#7,$8201.w	* screen to $70000
	clr.b	$8203.w

	move	#$2700,sr	* take over the system (My favourite!)
	clr.b	$fa07.w		* disable
	clr.b	$fa09.w		* all interrupts
	clr.b	$fa0b.w		* clear all
	clr.b	$fa0d.w		* "pending"
	clr.b	$fa0f.w		* clear all
	clr.b	$fa11.w		* "in service"
	move.b	#1,$fa13.w	* mask timerb
	clr.b	$fa15.w		* mask none
	move.b	#8,$fa1b.w	* timerb into event count mode
	move.b	#1,$fa21.w	* want interrupt on every raster line
	move.l	#timerb,$120.w	* set up timerb handler
	move.l	#vbl,$70.w	* set up vbl handler
	stop	#$2300		* wait for vbl
	clr.b	$8260.w		* low res (works just as well in medium)

	move.b	#1,$fa07.w	* enable timerb

loop	bra.s	loop		* hang about

vbl	clr	$8240.w		* pallette 0 to black
	clr	(raster_line).w			* reset raster_line
	move	(global_colour).w,(local_colour).w	* this gives
*							  the scrolling
*							  effect in the
*							  border
	add	#$89,(global_colour).w		* increment
	and	#$777,(global_colour).w		* global_colour
	rte

timerb	move	(local_colour).w,$8240.w	* set pallette 0
	cmp	#198,(raster_line).w	* last (on screen) raster line?
	bne.s	not198
	move.l	$40.w,$40.w		* short delay, until
	move.l	$40.w,$40.w		* scan is in screen display area
	clr.b	$820a.w			* 60Hz mode
	bra.s	not199
not198	cmp	#199,(raster_line).w	* first border raster line?
	bne.s	not199
	move.b	#2,$820a.w		* back to 50Hz
not199	addq	#1,(raster_line).w	* increment raster_line
	add	#$89,(local_colour).w	* increment
	and	#$777,(local_colour).w	* local_colour
	clr.b	$fa0f.w		* clear interrupt in service bit (byte?)
	rte			* exit

**************************************************************************

 "...there's no success  JANET unpowell@uk.ac.liv.csvax
  like failure and 	 UUCP  {backbone}!mcvax!ukc!mupsy!liv-cs!unpowell
  failure's no		 ARPA  unpowell%csvax.liv.ac.uk@nss.cs.ucl.ac.uk
  success at all..."			

**************************************************************************