Mode 7 with screen RAM at &3C00 on the model B

bbc micro/electron/atom/risc os coding queries and routines
Post Reply
SteveF
Posts: 720
Joined: Fri Aug 28, 2015 9:34 pm
Contact:

Mode 7 with screen RAM at &3C00 on the model B

Post by SteveF » Wed Aug 05, 2020 11:50 pm

I'm working on an application where I'd like to be able to page in a bank of sideways RAM and have as large a block of contiguous free RAM as possible. This is easy with shadow RAM on a B+ or Master, but on the B the screen RAM gets in the way.

I've been playing around and I think I've managed to persuade the OS character output routines to work in mode 7 with the screen RAM at &3C00, so I should be able to have &4000-&C000 (32K) of contiguous free RAM. Here's the code I've come up with (attached as a zipped .ssd too):

Code: Select all

MODE 7
HIMEM=&3C00
IF INKEY-256<>-1 THEN PRINT "Sorry, BBC B only!":END
vdu_status=&D0
wrchv=&20E
keyv=&228
rts_opcode=&60
crtc_screen_start_high=12
crtc_cursor_start_high=14
crtc_register=&FE00
crtc_data=&FE01
FOR opt%=0 TO 2 STEP 2
P%=&900
[OPT opt%
.start
.nop_to_patch
nop
LDA #rts_opcode:STA nop_to_patch
\ We install a wrapper around OSWRCH which adjusts the CRTC cursor position
\ after every character output, otherwise the cursor is invisible.
LDA wrchv:STA call_old_wrchv+1
LDA wrchv+1:STA call_old_wrchv+2
LDA #our_oswrch MOD 256:STA wrchv
LDA #our_oswrch DIV 256:STA wrchv+1
\ In order to make cursor editing work, we need to adjust the CRTC cursor
\ position during that too. Hooking the keyboard timer interrupt is the best
\ way I've thought of to get a chance to do this.
LDA keyv:STA call_old_keyv+1
LDA keyv+1:STA call_old_keyv+2
LDA #our_keyv MOD 256:STA keyv
LDA #our_keyv DIV 256:STA keyv+1
RTS
\
.our_oswrch
.call_old_wrchv
JSR &FFFF \ patched
PHA
OPT FNadjust_cursor(opt%)
PLA
RTS
\
.our_keyv
BCC call_old_keyv
BVC call_old_keyv
\ keyboard timer interrupt entry
JSR call_old_keyv
PHP
PHA
BIT vdu_status
BVC not_cursor_editing
OPT FNadjust_cursor(opt%)
.not_cursor_editing
PLA
PLP
RTS
.call_old_keyv
JMP &FFFF \ patched
]
NEXT
CALL &900
:
VDU 28,0,24,39,0
PROCcrtc(crtc_screen_start_high, &20)
?&34E=&3C:REM high byte of bottom of screen memory
?&351=&3C:REM high byte display start address for 6845
PRINT CHR$(12);:REM force OS to pick up new settings
$&7C00="Hello, world!":REM note this doesn't appear on screen
PRINT "We're now in mode 7 with the screen RAM"'"at &3C00. The OS is happy, as long as wedon't do VDU 26. Cursor editing works"'"too."
END
:
DEF PROCcrtc(R%,V%)
VDU 23,0,R%,V%,0,0,0,0,0,0
ENDPROC
:
DEF FNadjust_cursor(opt%)
[OPT opt%
LDA #crtc_cursor_start_high:STA crtc_register
LDA &34B:SEC:SBC #&1C:STA crtc_data
]
=opt%
The biggest problem was getting the cursor to work; I've had to resort to adjusting the value the OS is programming the CRTC with at judiciously chosen times. Hooking WRCHV to do this after OSWRCH completes does most of the job, but to make cursor editing (split cursors) work, I need to get a chance to do this adjustment without a character being output. I haven't been able to think of a better way than hooking the keyboard timer event.

So I have a few questions:
  • Have I missed something which would let me get the OS to position the cursor correctly without needing to hook those vectors?
  • Is there a better alternative to the keyboard timer event to make cursor editing work?
  • I've only been able to test this on jsbeeb. Is it likely to work on real hardware? Obviously it will only work on a model B, but that's fine, because on anything else I'll just use a shadow mode instead.
  • Are there any other flaws in this plan which I've overlooked?
Cheers.

Steve
Attachments
mode7-3c00.zip
(1.36 KiB) Downloaded 19 times

User avatar
lurkio
Posts: 2892
Joined: Wed Apr 10, 2013 12:30 am
Location: Doomawangara
Contact:

Re: Mode 7 with screen RAM at &3C00 on the model B

Post by lurkio » Thu Aug 06, 2020 12:37 pm

I don't know enough to comment about the technical details of this MODE7 hack except to say it's very impressive! It doesn't work in BeebEm, though -- but I guess that's not too big a problem because BeebEm users will always be able to use the copro version of Ozmoo instead..?

But would it be too fiddly to just use SWRAM in a more conventional way? Is there a minimum amount of contiguous memory that Ozmoo needs? Is the size of the contiguous memory block available in a Model B without your hack just not big enough?

(I know that fuzzel's recent text game LAND uses seven banks of SWRAM, and switches between them, but I think the SWRAM is used mainly, if not exclusively, for data rather than game code.)

:?:

User avatar
BigEd
Posts: 3420
Joined: Sun Jan 24, 2010 10:24 am
Location: West
Contact:

Re: Mode 7 with screen RAM at &3C00 on the model B

Post by BigEd » Thu Aug 06, 2020 1:37 pm

Nice!

But... is it possible to convince the model B that it's actually a model A, with 16k RAM? Maybe that would put the screen down below &4000 and everything should work?

SteveF
Posts: 720
Joined: Fri Aug 28, 2015 9:34 pm
Contact:

Re: Mode 7 with screen RAM at &3C00 on the model B

Post by SteveF » Thu Aug 06, 2020 2:02 pm

lurkio wrote:
Thu Aug 06, 2020 12:37 pm
I don't know enough to comment about the technical details of this MODE7 hack except to say it's very impressive! It doesn't work in BeebEm, though -- but I guess that's not too big a problem because BeebEm users will always be able to use the copro version of Ozmoo instead..?
Yes, that's right - anyone using an emulator could just use Master 128 mode or any model with a 6502 second processor, and they'd get a "better" experience anyway, except for any specific nostalgic attraction they have to the model B. Those people would have to use a different emulator which supports this hack - jsbeeb does, and Coeus has a patch to make this work in b-em.
lurkio wrote:
Thu Aug 06, 2020 12:37 pm
But would it be too fiddly to just use SWRAM in a more conventional way? Is there a minimum amount of contiguous memory that Ozmoo needs? Is the size of the contiguous memory block available in a Model B without your hack just not big enough?
Good questions! The short answer to all of them is "maybe". :-) I started writing a long response and then realised it was really very long, so I'll post it over in the Ozmoo thread instead to avoid derailing this one.
Last edited by SteveF on Thu Aug 06, 2020 2:31 pm, edited 1 time in total.

SteveF
Posts: 720
Joined: Fri Aug 28, 2015 9:34 pm
Contact:

Re: Mode 7 with screen RAM at &3C00 on the model B

Post by SteveF » Thu Aug 06, 2020 2:04 pm

BigEd wrote:
Thu Aug 06, 2020 1:37 pm
But... is it possible to convince the model B that it's actually a model A, with 16k RAM? Maybe that would put the screen down below &4000 and everything should work?
I haven't tried it yet, but that might be genius! I know there's a *FX command you can run that makes the startup banner say 16K. Unless the hardware somehow disables one of the address lines I guess there'd be nothing to stop the running application using the memory at &4000 which it just happens to know is there.

Edit: I actually need my code to be loaded into RAM above &4000 (there'd be a "hole" in the code around the screen at &3C00), so the filing system would have to not mind doing that. But then again, the filing system probably doesn't check to see if it's loading past the notional top of main RAM anyway.

Edit: Thinking about this, I was poking with vague comprehension at the OS 1.2 disassembly while trying to get this hack to work, and I have a horrible feeling the OS will just write to &7C00 and rely on the fact b14 of the address bus is ignored if you really only have 16K of RAM. But I really don't know, I'll wait and hope someone who understands this stuff properly is reading...

User avatar
tricky
Posts: 4665
Joined: Tue Jun 21, 2011 9:25 am
Contact:

Re: Mode 7 with screen RAM at &3C00 on the model B

Post by tricky » Thu Aug 06, 2020 3:26 pm

Looks like the 6845 sets &2800 for both, but I might not have set Model A mode correctly.

User avatar
BigEd
Posts: 3420
Joined: Sun Jan 24, 2010 10:24 am
Location: West
Contact:

Re: Mode 7 with screen RAM at &3C00 on the model B

Post by BigEd » Thu Aug 06, 2020 4:11 pm

SteveF wrote:
Thu Aug 06, 2020 2:04 pm
BigEd wrote:
Thu Aug 06, 2020 1:37 pm
But... is it possible to convince the model B that it's actually a model A, with 16k RAM? Maybe that would put the screen down below &4000 and everything should work?
... I have a horrible feeling the OS will just write to &7C00 and rely on the fact b14 of the address bus is ignored if you really only have 16K of RAM...
Aaah, of course: simple, cheap and fast. The OS doesn't have to do anything. Which doesn't help this case one bit.

Coeus
Posts: 1814
Joined: Mon Jul 25, 2016 12:05 pm
Contact:

Re: Mode 7 with screen RAM at &3C00 on the model B

Post by Coeus » Thu Aug 06, 2020 5:17 pm

Can anyone confirm if this trick works on a B+? If we don't know can someone try it on a real one, please?

Post Reply

Return to “programming”