Green spots when scrolling?

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
earlz
Member
Member
Posts: 1546
Joined: Thu Jul 07, 2005 11:00 pm
Contact:

Green spots when scrolling?

Post by earlz »

Ok, I have this very strange problem..

Whenever my OS scrolls, there are a few blocks where there attribute byte(I'm in text mode) change from 0x07 to 0x27, seemingly random.

It also happens sometimes with one or two blocks when I cls.
my scrolling and cls code:

Code: Select all

volatile uint8_t *vram=(uint8_t *)0xB8000;
volatile uint8_t kd_color=0x07;
void kd_scroll_down(){
	memcpy(vram,vram+(80*2),80*2*25);
	uint32_t i;
	for(i=0;i<=((80*2));i+=2){
		vram[i+(80*24*2)]=0;
		vram[i+1+(80*24*2)]=kd_color; //set color
	}
}

void kd_cls(){
	uint32_t i;
	for(i=0;i<=((80*25*2));i+=2){
		vram[i]=0;
		vram[i+1]=kd_color; //set color
	}
}
Note, nothing ever changes except for the attribute byte, and it always makes the background green and never changes the foreground..

Also, my video does not work by video-repost interrupt. I do not think it's relevant, as all modern video adapters have fixes for the snow problem.


This only happens on real computers. Certain computers don't do it, but the 3 I have at my house do. They include a new netbook, a older hp computer and a really old gateway computer..
User avatar
kmtdk
Member
Member
Posts: 263
Joined: Sat May 17, 2008 4:05 am
Location: Cyperspace, Denmark
Contact:

Re: Green spots when scrolling?

Post by kmtdk »

have you thought about the vga registers ( bitoperations on input) ?
it it the only one i see now ( or something in that way)

can you give a scrennshot

since i can not tell fully from the c code, ( im a noob at c, but understand some of it)[and also what way scrolling ??, becuase as i see it now, the memcpy goes from line 2 , to line 1, and then you clear line 2, and it use the color like the last one(the one to scrool) ???? ..]

KMT dk
well, what to say, to much to do in too little space.
when it goes up hill, increase work, when it goes straight, test yourself but when going down, slow down.
User avatar
Combuster
Member
Member
Posts: 9301
Joined: Wed Oct 18, 2006 3:45 am
Libera.chat IRC: [com]buster
Location: On the balcony, where I can actually keep 1½m distance
Contact:

Re: Green spots when scrolling?

Post by Combuster »

Two things:
libc documentation wrote:memcpy() - Copies n bytes from s2 to s1, where s1 and s2 do not overlap
You are also reading beyond the screen
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
earlz
Member
Member
Posts: 1546
Joined: Thu Jul 07, 2005 11:00 pm
Contact:

Re: Green spots when scrolling?

Post by earlz »

Combuster wrote:Two things:
libc documentation wrote:memcpy() - Copies n bytes from s2 to s1, where s1 and s2 do not overlap
You are also reading beyond the screen
ok.. I'm not sure if my implementation of memcpy is "safe" for that kinda thing.. so that does make sense..

so are you saying the best way to implement a scrolling function is to copy to a buffer and back to the screen shifted?
User avatar
kmtdk
Member
Member
Posts: 263
Joined: Sat May 17, 2008 4:05 am
Location: Cyperspace, Denmark
Contact:

Re: Green spots when scrolling?

Post by kmtdk »

you shuld be able to do without (since it is slower... )
I can write one in asm (if you like)
but remeber

scroll up =
copy secound line, put into 1 line, copy 3 ...
until you reach button, and then you may clear it, or might use a "buffer" for the text outside the screen..

down is like this:
copy secound las line, put into third last line, .. and so on . ( until you reach the top.. and then the same as above)

this might make it more clear to you: :P



KMT dk

ill just write one in asm ( up and down)


scroll up ( forgetting buffer, and sutch things, but clears last line):

Code: Select all

; no input, just call
; this is not mean to return to a running code, it is just a "on the fly" example: ( assumtions: a line has 80 char, and that there is 24 lines)
mov esi,0xb8000+80
mov edi,0xb8000
cld ; ensure that the move is incresming.
mov cx,((80*23)/4); depends on the next instruction.
rep stosd ; move.
cli
hlt



scroll down ( forgetting buffer, and sutch things, but clears first line):

Code: Select all

; no input, just call
; this is not mean to return to a running code, it is just a "on the fly" example: ( assumtions: a line has 80 char, and that there is 24 lines)
mov esi,0xb8000+(80*23)
mov edi,0xb8000+(80*24)
std ; ensure that the move is decreasing.
mov cx,((80*23)/4); depends on the next instruction.
rep stosd ; move.
cli
hlt
i have NOT tested this ( cause im sitting with math(homework :P) and when the clock is 01:10 (24 hour system) ...)
well, what to say, to much to do in too little space.
when it goes up hill, increase work, when it goes straight, test yourself but when going down, slow down.
earlz
Member
Member
Posts: 1546
Joined: Thu Jul 07, 2005 11:00 pm
Contact:

Re: Green spots when scrolling?

Post by earlz »

Ok, I implemented memmove using the copy to buffer method.. but I still am plagued by the random green squares..

Is it possible that this is caused by a locking problem with the video memory? cause I am not using a buffer, I am copying straight to and from memory.
User avatar
Combuster
Member
Member
Posts: 9301
Joined: Wed Oct 18, 2006 3:45 am
Libera.chat IRC: [com]buster
Location: On the balcony, where I can actually keep 1½m distance
Contact:

Re: Green spots when scrolling?

Post by Combuster »

To fix your problem, and make your code faster, I'd keep a text buffer in memory. While writing to a vga is comparatively slow, reading is even slower.

Also, when you read or write to VGA memory, there are a lot of processing steps before the data actually gets across. In many of these steps, the result can be modified by the internal logic (read modes, write modes), so a read may not be an exact copy of video memory. Also, the VGA is 8-bit, and I have never tried doing 32-bit reads through the GC unit. While this normally shouldn't be a problem, if your register setup is off then you might get artefacts (although I have no solid explanation for this "randomness", so my gut says its something else).

Could you post the graphics chipsets that break? If I have a computer with a matching video card then I can try reproducing everything from here.
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
earlz
Member
Member
Posts: 1546
Joined: Thu Jul 07, 2005 11:00 pm
Contact:

Re: Green spots when scrolling?

Post by earlz »

I get this error with just about every chipset I've yet to try(but this only happens on real hardware, not emulation)

I think the error comes from VGA cards aren't exactly intended to have their memory read from, only written to..
jal
Member
Member
Posts: 1385
Joined: Wed Oct 31, 2007 9:09 am

Re: Green spots when scrolling?

Post by jal »

earlz wrote:I think the error comes from VGA cards aren't exactly intended to have their memory read from, only written to..
That's of course bullocks. The VGA has a whole load of registers just for reading the memory. You're green square problem is no doubt some weird coding bug triggered by something circumstancial.


JAL
jal
Member
Member
Posts: 1385
Joined: Wed Oct 31, 2007 9:09 am

Re: Green spots when scrolling?

Post by jal »

earlz wrote:Ok, I have this very strange problem..
Well let's look at your code first.

Code: Select all

volatile uint8_t *vram=(uint8_t *)0xB8000;
I doubt whether it is needed to make it volatile, as I hope your screen routines/driver are the only ones accessing the screen, and you have proper mutual exclusion in place.

Code: Select all

volatile uint8_t kd_color=0x07;
Having a volatile here is really weird. Who is changing it from under your nose?? See also remark above.

Code: Select all

void kd_scroll_down(){
	memcpy(vram,vram+(80*2),80*2*25);
}
As was already mentioned by a few others, this is unsafe to do. I'd propose changing it to a copy per line. Also, it is very ugly to have '80' and '25' pop-up anywhere - what if you decide to have, say, a 90x60 text screen? I'd advise something like this:

Code: Select all

uint8_t* p = vram;

for (i = 0; i < scr_num_lines - 1; i++)
{
    memcpy(p, p + scr_width_bytes, scr_width_bytes);
    p += scr_width_bytes;
}

Code: Select all

	uint32_t i;
I would never use a type other than 'int' for a simple loop counter, even if you (think you) know the int size of your platform.

Code: Select all

	for(i=0;i<=((80*2));i+=2){
		vram[i+(80*24*2)]=0;
		vram[i+1+(80*24*2)]=kd_color; //set color
	}
It's probably (hopefully) rough code, but having all these calculations in there is ugly. Also, as someone else already pointed out, you need < not <=, as you are writing two bytes outside the screen. I'd do something like:

Code: Select all

p = &vram[(scr_num_lines-1) * scr_width_bytes];
for (i = 0; i < scr_width_bytes; i++, p += 2)
{
    p[0] = ' ';
    p[1] = kd_color;
}
Whether to increase p in the for-line or more explicitly below the assignments is a matter of taste, I guess.

Code: Select all

void kd_cls(){
	uint32_t i;
	for(i=0;i<=((80*25*2));i+=2){
		vram[i]=0;
		vram[i+1]=kd_color; //set color
	}
}
Again, there's writing outside the screen (<= instead of <). Also, I'd investigate whether it isn't faster to disable plane 1, then do a memset, then disable plane 0 (and enable plane 1), then do another memset. But since that takes a few outw's, it could be slower, actually.
Note, nothing ever changes except for the attribute byte, and it always makes the background green and never changes the foreground..
Did you actually do a memory dump of the screen memory, or are you just assuming that? A green square can be created in various ways.
Also, my video does not work by video-repost interrupt.
I'm not sure I even know what you're talking about here.
I do not think it's relevant, as all modern video adapters have fixes for the snow problem.
Errr... I have an umbrella in case it rains. Also totally irrelevant to the discussion. But then again, you are probably too young to have ever actually witnessed an original IBM CGA with snow.


JAL
earlz
Member
Member
Posts: 1546
Joined: Thu Jul 07, 2005 11:00 pm
Contact:

Re: Green spots when scrolling?

Post by earlz »

for all the volatiles.. I have yet to have a video driver.. well.. speaking of.. I should just make it a driver and not part of some crappy shell.

When I rewrite it to be a driver, I'll use variables instead of 80 and 25..

My OS can't run on anything but 32bit pmode.. so how could int be any different?

Well.. maybe I should go back to learning to code properly before posting here.. lol

the video repost thing.. the interrupt that happens when the video stops redrawing itself or something.. think its IRQ 2...

and no, I've never witnessed snow
jal
Member
Member
Posts: 1385
Joined: Wed Oct 31, 2007 9:09 am

Re: Green spots when scrolling?

Post by jal »

earlz wrote:for all the volatiles.. I have yet to have a video driver.. well.. speaking of.. I should just make it a driver and not part of some crappy shell.
You should not define something volatile unless it can be changed by something else.
When I rewrite it to be a driver, I'll use variables instead of 80 and 25..
It's never a bad idea to do it from the start, unless it's just a q&d proof of concept or something.
My OS can't run on anything but 32bit pmode.. so how could int be any different?
That's not the point. You just should never use fixed size variables unless there's a good reason to do so.
Well.. maybe I should go back to learning to code properly before posting here..
Perhaps you should learn to code properly before attempting to create an OS.
the video repost thing.. the interrupt that happens when the video stops redrawing itself or something.. think its IRQ 2...
"or something". I guess you mean the vertical retrace interrupt. Google vertical retrace for more info.
and no, I've never witnessed snow
It's like many white horizontal bars (resembling blinking cursors) flickering on the screen, usually only in some area. It was present only in the original CGA and some clones, before they used dual port memory.

However, what's more important, I gave you a lot of hints about what you could change to get rid of your green blocks problem. Did you try anything? E.g. line by line copy?


JAL
Post Reply