@@ -55,23 +55,35 @@ http://members.casema.nl/hhaydn/howel/logic/6847_clone.htm
555564 = 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+
99114export 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