Skip to content

Commit f81baf0

Browse files
CoderCoder
authored andcommitted
the border does not change colour per line or char, it changes per frame
Also made the character background dark green or dark orange like suggested.
1 parent 5e1f037 commit f81baf0

File tree

1 file changed

+81
-40
lines changed

1 file changed

+81
-40
lines changed

6847.js

Lines changed: 81 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -55,23 +55,35 @@ http://members.casema.nl/hhaydn/howel/logic/6847_clone.htm
5555
64 = 64/8 = 8 8x2bpp = reg1:16 (xscale*2) 0x10
5656
5757
58+
# Data on PORTA used to set the screen mode; 0x10 means graphics mode, and then 0x20, 0x40, 0x80 are used to set the graphics mode.
59+
# Data on PORTC used to set the colour select bit, which is used in conjunction with the graphics mode bits to select the colour of the screen.
60+
# css = 0 means Black/Green
61+
# css = 1 means Black/Orange
62+
63+
# PORTA is #b000 and PORTC is #b002
64+
# bits 4-7 on #b000 are used to set the graphics mode, )
65+
# and bit 3 on #b002 is used to set the colour select bit. (CSS connected to PC3 on 8255 via)
66+
# eight bits 0-7
67+
68+
5869
// video mode constants
59-
//ppai PORTA
60-
MODE_AG = 0x10; // alpha or graphics
61-
MODE_GM2 = 0x80; // only used if AG is 1
62-
MODE_GM1 = 0x40; // only used if AG is 1
63-
MODE_GM0 = 0x20; // only used if AG is 1
70+
//ppia PORTA
71+
MODE_GM2 = 0x80; // only used if AG is 1 (bit 7)
72+
MODE_GM1 = 0x40; // only used if AG is 1 (bit 6)
73+
MODE_GM0 = 0x20; // only used if AG is 1 (bit 5)
74+
MODE_AG = 0x10; // alpha or graphics (bit 4)
6475
65-
//ppai PORTC
66-
MODE_CSS = 0x08; // colour select
76+
//ppia PORTC
77+
MODE_CSS = 0x08; // colour select (bit 3)
6778
79+
when reading a byte from the VDG, looking at
6880
// WITHIN THE VIDEO MEMORY (bit 6, 6, 7) (AS, INTEXT, INV resp.)
69-
// A/S, INT/EXT, CSS and INV can be changed character by character
70-
// these not used if AG is 1, GM not used if AG is 0
71-
MODE_AS = 0x04;
72-
MODE_INTEXT = 0x02;
73-
MODE_INV = 0x01;
81+
(INT/EXT & A/S connected to D6, and INV connected to D7 from CPU
7482
83+
This means D6 switches between internal alphanumeric, and semigraphics 6 (SG6)
84+
85+
// A/S-INT/EXT, INV can be changed character by character, and CSS on interrupt from CPU
86+
// these not used if AG is 1, GM not used if AG is 0
7587
7688
for bits
7789
@@ -96,6 +108,9 @@ only 1 bit is used of SG6 - to get yellow/red, cyan/orange
96108
// MODE_GM1 = 0x20,
97109
// MODE_GM0 = 0x10;
98110

111+
// constant for the graphics mode
112+
const MODE_AG = 0x10; // graphics mode
113+
99114
export function Video6847(video) {
100115
this.video = video;
101116
this.levelDEW = false;
@@ -105,9 +120,21 @@ export function Video6847(video) {
105120
//
106121
this.collook = utils.makeFast32(
107122
new Uint32Array([
108-
0xff000000, 0xff00ff00, 0xff00ffff, 0xffff0000, 0xff0000ff, 0xffffffff, 0xffffff00, 0xffff00ff, 0xff0080ff,
123+
0xff000000, // #00000000, // black
124+
0xff03b91e, // #00ff00, // green
125+
0xff00ffff, // #ffff00, // yellow
126+
0xffff083b, // #3b08ff, // blue
127+
0xff0516b9, // #b91605, // red
128+
0xff018eb4, // #b48e01, // buff
129+
0xffeb9200, // #0092eb, // cyan
130+
0xffff1cff, // #ff1cff, // magenta
131+
0xff005bbd, // #bd5b00, // orange
132+
133+
0xff000600, // dark green (char background) #000600
134+
0xff000d1c, // dark orange (char background) #1c0d00
109135
])
110136
);
137+
111138
// { 0, 0, 0 }, /*Black 0*/
112139
// { 0, 63, 0 }, /*Green 1*/
113140
// { 63, 63, 0 }, /*Yellow 2*/
@@ -116,7 +143,10 @@ export function Video6847(video) {
116143
// { 63, 63, 63 }, /*Buff 5*/
117144
// { 0, 63, 63 }, /*Cyan 6*/
118145
// { 63, 0, 63 }, /*Magenta 7*/
119-
// { 63, 32, 0 }, /*Orange 8 - actually red on the Atom*/
146+
// { 63, 32, 0 }, /*Orange 8 - can be red on the Atom*/
147+
148+
// /* dark green 9 */
149+
// /* dark orange 10 */
120150

121151
this.regs = new Uint8Array(32);
122152
this.bitmapX = 0;
@@ -272,11 +302,16 @@ export function Video6847(video) {
272302
this.vdg_cycles = 0;
273303
this.charTime = 0;
274304

305+
this.bordercolour = 0x00; // 0x00 black 0x01 // green or orange depending on CSS
306+
275307
// ATOM uses 6847 chip
276308
this.polltime = function (clocks) {
277309
var mode = this.ppia.portapins & 0xf0;
278310
var css = (this.ppia.portcpins & 0x08) >>> 2;
279311
this.setValuesFromMode(mode);
312+
// Note: Polltime is called from the CPU many times during a frame. Once the VDG has drawn a bit of a frame
313+
// it returns, and then comes back here later to continue the same frame. That's how the snow is able to work
314+
// it doesn't draw the whole frame. It regularly gives control back to the CPU.
280315

281316
var vdgcharclock = this.pixelsPerChar / 2; // 4 or 8
282317
var vdgclock = 3.638004; // This ought to be 3.579545, but this looks better with the INTs being used.
@@ -399,6 +434,13 @@ export function Video6847(video) {
399434
// );
400435
// this.lastseconds = seconds ?? 0;
401436
// }
437+
438+
// fix the border colour at the end/start of a frame
439+
// it won't change within a frame
440+
let AGM = (mode & MODE_AG) === 0;
441+
442+
if (AGM) this.bordercolour = 0x00; // black
443+
else this.bordercolour = 0x01; // green orange
402444
}
403445

404446
if (nextChar) {
@@ -415,26 +457,17 @@ export function Video6847(video) {
415457
{
416458
// TODO: Add in the INTEXT modifiers to mode (if necessary)
417459
// blit into the fb32 buffer which is painted by VIDEO
418-
if ((mode & 0x10) === 0)
460+
if ((mode & MODE_AG) === 0)
419461
// MODE_AG - bit 4; 0x10 is the AG bit
420462
this.blitChar(this.video.fb32, dat, offset, this.pixelsPerChar, css);
421463
else this.blitPixels(this.video.fb32, dat, offset, css);
422464
}
423465
}
424466
} else {
425-
let dat = 0xff;
426-
// var insideTopBottomBorder = (this.dispEnabled & (HDISPENABLE | VDISPENABLE)) === (VDISPENABLE);
427-
// dat = 0x2f;
428-
// if (insideTopBottomBorder)
429-
// dat = 0x11;
430-
431467
// draw BLACK in the border
432468
let offset = this.bitmapY;
433469
offset = offset * 1024 + this.bitmapX;
434-
if ((mode & 0x10) === 0)
435-
// MODE_AG - bit 4; 0x10 is the AG bit
436-
this.blitChar(this.video.fb32, 0x20, offset, this.pixelsPerChar, css);
437-
else this.blitPixels(this.video.fb32, dat, offset, css);
470+
this.blitBorder(this.video.fb32, this.bordercolour, offset, css);
438471
}
439472

440473
this.addr = (this.addr + 1) & 0x1fff;
@@ -489,6 +522,24 @@ export function Video6847(video) {
489522
} // matches while
490523
};
491524

525+
this.blitBorder = function (buf, data, destOffset, css) {
526+
var bpp = this.bpp;
527+
var pixelsPerBit = this.pixelsPerBit / bpp;
528+
var numPixels = 8 * pixelsPerBit; //per char
529+
var fb32 = buf;
530+
var i = 0;
531+
for (i = 0; i < numPixels; ++i) {
532+
var n = numPixels - 1 - i; // pixels in reverse order
533+
534+
var colour = this.collook[css ? 5 : 1]; // buff or green
535+
if (data === 0x00) {
536+
colour = this.collook[0]; // black
537+
}
538+
fb32[destOffset + n] = fb32[destOffset + n + 1024] = // two lines
539+
colour;
540+
}
541+
};
542+
492543
this.blitPixels = function (buf, data, destOffset, css) {
493544
// var scanline = this.scanlineCounterT;
494545
// bitpattern from data is either 4 or 8 pixels in raw graphics
@@ -519,16 +570,6 @@ export function Video6847(video) {
519570
// get bits in pairs or singles
520571
var j = Math.floor(i / pixelsPerBit);
521572

522-
// { 0, 0, 0 }, /*Black 0*/
523-
// { 0, 63, 0 }, /*Green 1*/
524-
// { 63, 63, 0 }, /*Yellow 2*/
525-
// { 0, 0, 63 }, /*Blue 3 */
526-
// { 63, 0, 0 }, /*Red 4 */
527-
// { 63, 63, 63 }, /*Buff 5*/
528-
// { 0, 63, 63 }, /*Cyan 6*/
529-
// { 63, 0, 63 }, /*Magenta 7*/
530-
// { 63, 32, 0 }, /*Orange 8 - actually red on the Atom*/
531-
532573
// get just one bit
533574
// RG modes
534575
if (bpp === 1) {
@@ -560,10 +601,10 @@ export function Video6847(video) {
560601

561602
// character set is just the pixel data
562603
// 0 - 63 is alphachars green (0x00-0x3f) bits 0-5 for character
563-
// 64-127 is alphagraphics green/yellow/blue/red (0x40-0x7f) bit 6,7 (0xC0)
604+
// 64-127 is 16 alphagraphics in 4 colours green/yellow/blue/red (0x40-0x7f) bit 6,7 (0xC0)
564605
// bit 7 set is inverted and the alphagraphics again
565606
// 128 - 191 is alphachars inverted green (0x80-0xbf)
566-
// 192-255 is alphagraphics again buff/cyan/magenta/orange (0xc0-0xff) bit 6,7 set (0xC0)
607+
// 192-255 is alphagraphics in different colours buff/cyan/magenta/orange (0xc0-0xff) bit 6,7 set (0xC0)
567608

568609
// in the data; bits 0-5 are the pixels
569610
// bit 7 and CSS give the colour
@@ -598,9 +639,9 @@ export function Video6847(video) {
598639
for (i = 0; i < numPixels; ++i) {
599640
var n = numPixels - 1 - i; // pixels in reverse order
600641
var j = i / pixelsPerBit;
601-
// text is either green/black or orange/black - nothing else
642+
// text is either green/black or buff/black - nothing else
602643
// css is 2 or 0 on input
603-
var fgcol = this.collook[css ? 8 : 1];
644+
var fgcol = this.collook[css ? 5 : 1];
604645

605646
if (agmode) {
606647
// alphagraphics 6
@@ -614,7 +655,7 @@ export function Video6847(video) {
614655
}
615656

616657
var luminance = (chardef >>> j) & 0x1;
617-
var colour = luminance ? fgcol : this.collook[0];
658+
var colour = luminance ? fgcol : this.collook[css ? 10 : 9]; //dark orange or green
618659
fb32[destOffset + n] = fb32[destOffset + n + 1024] = // two lines
619660
colour;
620661
}

0 commit comments

Comments
 (0)