Does b-em support mode 7 screen at &3C00 on a model B?
Closed this issue · 11 comments
This is definitely pushing my comfort zone, but I've been playing around with it. I couldn't find any sample code, but by experimentation I've come up with this:
MODE 7
PRINT "Hello"
$&3C00="Top"
A%=&3C00+24*40+34
$A%="Bottom"
FOR I%=&3C03 TO A%-1
?I%=32+(I% MOD 95)
NEXT
VDU 23,0,12,32,0,0,0,0,0,0
VDU 23,0,13,0 ,0,0,0,0,0,0
REPEAT UNTIL FALSE
On b-em this leave "Hello" on the screen, if I run it on jsbeeb I get a screen full of text with "Top" at the top left and "Bottom" at the bottom right. I haven't tried this on real hardware; I understand it will only work on a model B anyway.
I've attached a bootable zipped .ssd of the above program for convenience:
m7-3c00.zip
If this is a bug in b-em, I suspect the problem is somewhere around the else branch of 'if (ma & 0x2000)' in video_poll(), but I really don't understand the hardware situation here well enough to actually propose a fix.
Thanks very much for trying this out on real hardware, it's good to know this works there!
So here is an excerpt from the circuit diagram:
So looking at the MA pins of the 6845 the mask 0x2000 in:
if (ma & 0x2000)
dat = ram[0x7C00 | (ma & 0x3FF) | vidbank];
else {
if ((crtc[8] & 3) == 3)
addr = (ma << 3) | ((sc & 3) << 1) | interlline;
else
addr = (ma << 3) | (sc & 7);
if (addr & 0x8000)
addr -= screenlen[scrsize];
dat = ram[(addr & 0x7FFF) | vidbank];
}
corresponds to the TTXVDU line. I'll have to trace where that goes.
FWIW there is some information (which goes a bit over my head) here: http://beebwiki.mdfs.net/Address_translation You've probably already seen that or it doesn't help here, but I thought I'd mention it.
Actually I had not see that so I am reading it now. In the meantime the TTXVDU seems to determine if a latch grabs the data from memory to feed to the SAA5050.
Here's a patch to get the Model B behaviour:
diff --git a/src/video.c b/src/video.c
index 910623e..1c2c9b5 100644
--- a/src/video.c
+++ b/src/video.c
@@ -898,7 +898,7 @@ void video_poll(int clocks, int timer_enable)
cdraw = cdrawlook[crtc[8] >> 6];
if (ma & 0x2000)
- dat = ram[0x7C00 | (ma & 0x3FF) | vidbank];
+ dat = ram[0x3C00 | ((ma & 0x800) << 3) | (ma & 0x3FF) | vidbank];
else {
if ((crtc[8] & 3) == 3)
addr = (ma << 3) | ((sc & 3) << 1) | interlline;
That was quick! That works, thanks! Sorry to state the obvious, but just in case you have overlooked it: I assume this actually needs to be done only if we're in model B mode, because at the moment it makes the test program "work" on a Master as well and based on what I've picked up from stardot that's not how real hardware behaves.
I don't actually know if the B+ should support this or not...
I don't know about the B+. I didn't want to test the MASTER boolean for every character to here's a patch that takes account of whether it's a master or not but only does the test when the CRTC register is set.
diff --git a/src/video.c b/src/video.c
index 910623e..374e0da 100644
--- a/src/video.c
+++ b/src/video.c
@@ -32,7 +32,7 @@ int crtc_i;
int hc, vc, sc;
static int vadj;
-uint16_t ma;
+uint16_t ma, ttxbank;
static uint16_t maback;
static int vdispen, dispen;
static int crtc_mode;
@@ -64,6 +64,8 @@ void crtc_write(uint16_t addr, uint8_t val)
vdispen = 0;
if (crtc_i == 8)
set_intern_dtype(vid_dtype_user);
+ else if (crtc_i == 12)
+ ttxbank = MASTER ? 0x4000 : (val & 0x8) << 11;
}
}
@@ -898,7 +900,7 @@ void video_poll(int clocks, int timer_enable)
cdraw = cdrawlook[crtc[8] >> 6];
if (ma & 0x2000)
- dat = ram[0x7C00 | (ma & 0x3FF) | vidbank];
+ dat = ram[0x3C00 | ttxbank | (ma & 0x3FF) | vidbank];
else {
if ((crtc[8] & 3) == 3)
addr = (ma << 3) | ((sc & 3) << 1) | interlline;
Thanks, that works! There's not much difference from a hardware perspective, but I've been testing this with the tidied up variant of the code I posted on stardot here as well as the code in the first post in this thread.
The patch to get this working on a B+ is merged to master. I am just waiting to hear from someone with a B+ whether this Mode 7 at 3C00 works on a B+ or not.
Thanks to Richard B (rmbrowngr) from stardot.org.uk forums for testing this on a B+. The trick for Mode 7 at 3C00 does not work on a B+. Commit 0b708a6 implements this.