<< Previous Message Main Index Next Message >>
<< Previous Message in Thread This Month Next Message in Thread >>
Date   : Sun, 10 Feb 2002 22:19:20 -0000
From   : "Rich Talbot-Watkins" <rich_tw@...>
Subject: Sample Firetrack-type-scrolling proggy

After all the recent discussion, this may be of interest to anyone
developing emulators and trying to get to the bottom of the Firetrack
scrolling... here's a little demo which should be small enough to type-in
(wow, a type-in listing... keeping the nostalgia alive!).  It splits the
screen in two: the top 16 displayed character rows are a pixel-by-pixel
vertical scroll, the bottom 16 displayed character rows remain stationary:-

[typed in by hand, 'tis the only way I've got unfortunately, so sorry for
any typos that creep in]

   10 MODE2
   20 PROCdraw
   30 PROCassemble
   40 !addr=&B00:CALL&900
   50 :

\\ just a crap demo screen so you can see what's going on....

   60 DEF PROCdraw
   70 VDU28,0,15,19,0,17,132,12,26,17,128
   80 FOR N%=0 TO 15
   90 COLOUR N%MOD7+1
  100 COLOUR 128:PRINTTAB(N%,16+N%);N%;"_";
  110 COLOUR 132:PRINTTAB(2,N%);N%+16;
  120 NEXT
  130 MOVE0,1023:DRAW1279,1023:DRAW1279,512:DRAW0,512:DRAW0,1023
  140 ENDPROC
  150 :

\\ wait for vsync

  160 DEF FNvsync
  170 [OPTN%:LDA&FE4D:AND#2:BEQP%-5:STA&FE4D:]
  180 =N%
  190 :

\\ set our timer to timeout in L% microseconds

  200 DEF FNsetwait(L%)
  210 [OPTN%:LDA#L%AND255:STA&FE44:LDA#L%DIV256:STA&FE45:]
  220 =N%
  230 :

\\ wait for our timer to timeout

  240 DEF FNwait
  250 [OPTN%:LDA&FE4D:AND#&40:BEQP%-5:STA&FE4D:]
  260 =N%
  270 :

\\ this macro either enables or disables display by
\\ changing all palette colours

  280 DEF FNcols(B%)
  290 FORC%=0TO7:IFB% D%=C%EOR7 ELSE D%=7
  300 [OPTN%:LDA#C%*16+D%:STA&FE21:]
  310 NEXT
  320 =N%
  330 :
  340 DEF PROCassemble
  350 addr=&70:line=&72
  355 linetime%=64:REM 1 scanline rasterises in 64 microsecs
  360 FOR N%=0 TO 2 STEP 2:P%=&900:[OPT N%
  370 SEI

\\ set bits 4/5 of addressable latch for 10k screen

  380 LDA#15:STA&FE42
  390 LDX#12:STX&FE40:INX:STX&FE40

\\ initialise a few constant CRTC registers

  400 LDA#3:STA&FE00:LDA#&88:STA&FE01
  410 LDA#10:STA&FE00:LDA#32:STA&FE01
  420 .loop

\\ wait until vsync, then blank all colours and set timer
\\ for four character rows time (top of visible screen)

  430 OPT FNvsync                      \wait for vsync
  440 OPT FNsetwait(linetime%*32-50)   \-50 for fine tuning
  450 OPT FNcols(0)                    \all colours off
  460 OPT FNwait

\\ after four character rows, turn all colours back on
\\ (we deem this point to be the top of the visible screen),
\\ set timer to stop us sometime in the bottom half of scrn,
\\ setup R4/5/6/7 for this top half of the screen, and
\\ setup R12/13 for the bottom half of screen when recached

  470 OPT FNsetwait(linetime%*138)     \reasonably arbitrary
  480 OPT FNcols(1)                    \colours back on
  490 LDA#4:STA&FE00:LDA#15:STA&FE01   \crtc cycle=16 rows
  500 LDA#5:STA&FE00:LDAline:STA&FE01  \plus these scanlines
  510 LDA#6:STA&FE00:LDA#255:STA&FE01  \display always
  520 LDA#7:STA&FE00:LDA#255:STA&FE01  \inhibit vsync this half
  530 LDA#12:STA&FE00:LDA#6:STA&FE01   \bottom screen start
  540 LDA#13:STA&FE00:LDA#0:STA&FE01   \  address is &3000
  550 OPT FNwait

\\ now prepare to jiggle the addr and line variables to
\\ scroll the screen up by a line (this is effectively
\\ the bottom of the loop)

  560 LDAline:CLC:ADC#1:CMP#8:BCCskip
  570 LDAaddr:CLC:ADC#80:STAaddr
  580 LDAaddr+1:ADC#0:CMP#&10:BCCP%+4
  590 LDA#&B:STAaddr+1:LDA#0
  600 .skip STAline

\\ we are currently rasterising the bottom half of screen,
\\ setup R4/5/6/7 for this bottom half, and R12/13 for
\\ the top half (next frame).
\\ NB As the VSync occurs midway through this CRTC update,
\\ the effects of changing R5 are effectively seen in the
\\ positioning of the 'top' screen next update.

  610 LDA#4:STA&FE00:LDA#21:STA&FE01
  620 LDA#5:STA&FE00
  630 SEC:LDA#8:SBCline:STA&FE01
  640 LDA#6:STA&FE00:LDA#16:STA&FE01  \16 lines in bottom screen
  650 LDA#7:STA&FE00:LDA#18:STA&FE01
  660 LDA#12:STA&FE00:LDAaddr+1:STA&FE01
  670 LDA#13:STA&FE00:LDAaddr:STA&FE01

\\ that's it!  vsync set to occur sometime this crtc
\\ update, which will be picked up next time round this loop

  680 JMPloop
  690 ]:NEXT
  700 ENDPROC


This works perfectly on my BBC Master at home, I've not had a chance to try
it on any emulators.  It's quite timing critical; the black palette fringe
inhibiting display at the top of the screen is set to occur in the side
border just before the appropriate screen line, so the visible number of
lines in the 'top' screen should be exactly 128.  It is important that R3 is
set to &88 (line 400); changing the top 4 bits will move this fringe up and
down by scanline amounts - probably crucial in an emulator too.

The following changes might make the demo more useful for getting the timing
right:

  290 FORC%=0TO7:IFB% D%=C%EOR7 ELSE D%=0
  455 LDA#3:STA&FE21
  485 LDA#7:STA&FE21
  555 LDA#7:JMPskip

This stops the scrolling, and should display the 'masked' area at the very
top of the screen as white text on blue.  The very top digit zero should
appear wholly in white on blue, whereas the underline next to it should be
in the first 'visible' scanline of the screen and should hence appear red.
As we are effectively displaying a 33-row screen here (but always masking up
to the first 8 scanlines), we see 7 lines of the digit zero repeated in row
16 too, just before the 'bottom' screen half begins.

Probably worth trying on a real Beeb first of all anyway in order to get a
feel for what should be going on....

All this to get blimmin' Firetrack working...!

cheers,
Rich
<< Previous Message Main Index Next Message >>
<< Previous Message in Thread This Month Next Message in Thread >>