Hi Steve,
Ok, the problem is this:
The Beeb video hardware imposes certain limits with regard to hardware scrolling, namely that there are only 4 hard-coded screen sizes which can be used - 8k, 10k, 16k or 20k. These 4 possibilities are represented by 2 bits in the addressable latch. The reason this is needed is that the video hardware needs to 'know' which address to loop back to when the screen address reaches &8000.
If you turn to page 419 of the AUG, you can see how the addressable latch works. It is accessed via the bottom 4 bits of &FE40. Bits 0-2 hold the number of the addressable latch bit you want to write (0-7), and bit 3 contains the value to be written (0 or 1).
So, to turn the Caps Lock light off, we need to write a 1 to addressable latch bit 6 (the AUG doesn't mention it, but writing a zero turns the LEDs on, and vice versa), which would go something like this:
Code:
SEI
LDA #15:STA &FE42 ; allow write access to bits 0-3 of &FE40
LDA #6+8:STA &FE40 ; write 1 to addressable latch bit 6
CLI
Interrupts are disabled to ensure the OS doesn't get to change any register values midway through the process.
As you can see, addressable latch bits 4 and 5 control the screen size. The values they represent are totally hardcoded just to be able to accommodate all the standard Beeb modes - the problem with this is that even if you wanted to have a 12k hardware scrolled screen, you'd have to specify a screen size of at least 16k in the addressable latch, and hence allocate this much screen memory, even if you didn't display it all at once.
The other problem is that the AUG is wrong regarding the meaning of the bits! The correct table should look like this:
Code:
Mode Size Start of screen B5 B4
0,1,2 20k &3000 1 0
3 16k &4000 0 0
4,5 10k &5800 1 1
6 8k &6000 0 1
All this addressable latch business is doing is defining the screen size for the video hardware, so that it knows where to wrap-around to. The start of screen address is still set using CRTC R12/R13, as you've seen.
Anyway, here's the bad news: you'll have to rethink the screen size of your playing area so that it's either a 10k or a 16k screen. Assuming you want to keep the screen at full width (20 characters), a 10k screen would be 16 lines high, but actually you could only display 15 at once due to the way the technique works (this is the 'hidden' line that is scrolled on from the top of the screen that you alluded to - there's no equivalent at the bottom though). Or alternatively, a 16k screen would be 25 lines high (but again, only able to display 24 at once).
In my demo, I have exactly a 10k scrolling area (16 Mode 2 characters wide * 20 lines), and then an additional 2 line window underneath which isn't scrolled. As before, only 19 lines of the playing area are actually displayed in total. This seemed to be the best compromise between size of play area and memory usage.
Hope this hasn't shafted your plans too much
Give me a shout if there's anything else I can give you a hand with.