scrolling up help
Re:scrolling up help
Hi,
can i use the asm source in Protected Mode ?
What must i do to use this asm source inline ?
I want use this function inline in my c source.
thanks,bye
Matze
can i use the asm source in Protected Mode ?
What must i do to use this asm source inline ?
I want use this function inline in my c source.
thanks,bye
Matze
Re:scrolling up help
All you have to do is convert it to gcc inline style asm, you could compile it as is with nasm, and then just link it in to your kernel. It is PMode code and it is ready to be called from C, you just have to change 'RET 4' to 'RET' in both of the functions. This code assumes a zero based data segment, if you use a segment just for video (ie you have a segment with a base of 0xb8000) then just subtract 0xb8000 from all absolute address within the functions.
Re:scrolling up help
OK, to make it inline you will need to remove some code from the start and end of each function, just the stuff to do with the stack and the argument. I am no good with gcc inline asm so I cannot help you with the conversion, sorry.
Re:scrolling up help
Glancing through this thread, it occured to me that an alternative approach simply cries out for consideration: block-move the contents of the current text page below the point to be scrolled to to one of the other three text pages, then page-flip. It would be both faster and smoother than the code I see above. I should have realized that there was a reason no one had mentioned this idea...
In researching this, I found that there seemed to be little if any information on swapping text pages without using a BIOS call. Still, the idea had some merit - if nothing else, the unsed text pages could still be used as temporary space. So I came up with this code and got it to work well enough to post:
While it is not quite perfected, it appears to be rather simpler than most of the alternatives, if nothing else. Note that it does not reset the hardware cursor; this is a Feature, not a bug, as many times you will want to scroll text relative to a stationary cursor. Adding a gotoxy call is no big problem, I hope. Also, while I tested it in real mode, it should work in p-mode without any modifications; if any has the chance to test it out, please let me know.
Scrolling backwards (moving the text down the page) is a fairly trivial modification. Scrolling a text window (that is, moving text in a rectangular area of the screen without moving the text around it) is a fairly serious one (you'd have to first move the whole text page to the swap page, then scroll the changed part line by line between the edges of the window, then copy the modified screen back to the current page).
If anyone has a good reason why this might cause problems - or knows what values to tickle which I/O port with to swap text pages - please let me know.
(EDIT: I have added a bit of code to clear the swap page first, in case there was an material left over from a previous swap. While it makes the code a bit harder to follow, it should be fairly straightforward.)
Assuming Mode 3, then the values should be
ScrWidth == 80,
CurrPageTop == 0xb8000,
CurrPageSize == 0x1000, and
SwapPageTop == 0xb9000 (the beginning of the second text page in mode 3).
C&CW.
In researching this, I found that there seemed to be little if any information on swapping text pages without using a BIOS call. Still, the idea had some merit - if nothing else, the unsed text pages could still be used as temporary space. So I came up with this code and got it to work well enough to post:
Code: Select all
;; scrollfwd - moves text n lines up.
;; arguments -
;; ah = number of rows to scroll
scrollfwd:
pushad ; save the registers to be used
cld ; make sure direction flag is set to increment
mov cx, CurrPageSize ; get the size of the text pages in bytes
mov di, SwapPageTop ; set the destination to the new text screen
push cx ; CX, and DI need to have same values
push di ; used and modified in two different places
mov al, 0 ; clear the swap page of any garbage
rep stosb ; copy zero into every byte of the swap text page
pop di
pop cx
mov al, ah ; put parameter into al, where it can be used
mov bl, ScrWidth
shl bl, 1 ; multiply by two to get size of line in bytes
mul bl ; multiply total columns by rows to scroll
mov si, ax
add si, CurrPageTop ; get the new top of the screen
sub cx, ax ; and subtract by the removed section to get
; the size of the block to be moved
rep movsb ; copy scrolled block to new text screen
mov cx, CurrPageSize ; reset the size of the buffer for swapping back
mov si, SwapPageTop
mov di, CurrPageTop
rep movsb ; move the data back to the current page, shifted up n lines
popad ; restore used registers
ret
While it is not quite perfected, it appears to be rather simpler than most of the alternatives, if nothing else. Note that it does not reset the hardware cursor; this is a Feature, not a bug, as many times you will want to scroll text relative to a stationary cursor. Adding a gotoxy call is no big problem, I hope. Also, while I tested it in real mode, it should work in p-mode without any modifications; if any has the chance to test it out, please let me know.
Scrolling backwards (moving the text down the page) is a fairly trivial modification. Scrolling a text window (that is, moving text in a rectangular area of the screen without moving the text around it) is a fairly serious one (you'd have to first move the whole text page to the swap page, then scroll the changed part line by line between the edges of the window, then copy the modified screen back to the current page).
If anyone has a good reason why this might cause problems - or knows what values to tickle which I/O port with to swap text pages - please let me know.
(EDIT: I have added a bit of code to clear the swap page first, in case there was an material left over from a previous swap. While it makes the code a bit harder to follow, it should be fairly straightforward.)
Assuming Mode 3, then the values should be
ScrWidth == 80,
CurrPageTop == 0xb8000,
CurrPageSize == 0x1000, and
SwapPageTop == 0xb9000 (the beginning of the second text page in mode 3).
C&CW.
Re:scrolling up help
RE: my last posting: C programmers will probably have noticed by now that this is roughly equivalent to:
where
void* memcpy(void* to, const void* from, size_t count) and void* memset(void* buf, int ch, size_t cont)
can be more or less implemented in NASM as:
Code: Select all
/* assumes page size and other related constants defined elsewhere */
void scrollfwd(int lines)
{
char* scroll_region;
long scroll_size;
memset((void *) SwapPageTop, 0, (size_t) CurrPageSize);
scroll_size = (lines * ScrWidth) << 1;
scroll_region = CurrPageTop - scroll_size;
memcpy((void *) SwapPageTop, (const void *) scroll_region, (size_t) scroll_size);
memcpy((void *) CurrPageTop, (const void*) SwapPageTop, (size_t) CurrPageSize);
}
void* memcpy(void* to, const void* from, size_t count) and void* memset(void* buf, int ch, size_t cont)
can be more or less implemented in NASM as:
Code: Select all
_memcpy:
push ebp
mov ebp, esp
mov esi, [ebp + 8] ; first arg - src pointer
mov edi, [ebp +12] ; 2nd arg - dest pointer
mov ecx, [ebp + 16] ; 3rd arg - string size in bytes
mov eax, edi ; return value - save now, before EDI gets trashed
cdl ; make sure direction flag set correctly
rep movsb ; block-copy from src to dest
pop ebp ; restore caller's stack frame
ret
_memset:
push ebp
mov ebp, esp
mov edi, [ebp + 8] ; first arg - buffer pointer
mov edi, [ebp +12] ; 2nd arg - value to write
mov eax, [ebp + 16] ; 3rd arg - string size in bytes
push edi ; return value - save now, before EDI gets trashed
cdl ; make sure direction flag set correctly
rep stosb
pop eax ; recover return value
pop ebp ; restore caller's stack frame
ret
Re:scrolling up help
After browsing your code, I am not sure but are copying the visible screen to the second text page, scrolling in the process by not copying the lines that are to be scrolled. Then at the end you copy the second page back to the visible page, now the data is scrolled up. But my question is how is this faster or smoother?
You are copying the data two times, and you are copying the data byte by byte, surley this isn't as fast as copying the data once, dword by dword?
Also, to make things look smoother in my code you could just clear each dword after copying it, this only has to be done on the lines that are be exposed after the scroll. There are some optimizations that could be done in the code I posted, however.
Also, even though it is more limited, the ultimate way for speed and smoothness is to do a hardware scroll....
Anyway, the code you have posted should work (as far as I can tell at a glance). But I would divide all of your values by 4 and do a 'rep movsd' instead of 'rep movsb' this of course would be 4 times as fast as your current implementation.
You are copying the data two times, and you are copying the data byte by byte, surley this isn't as fast as copying the data once, dword by dword?
Also, to make things look smoother in my code you could just clear each dword after copying it, this only has to be done on the lines that are be exposed after the scroll. There are some optimizations that could be done in the code I posted, however.
Also, even though it is more limited, the ultimate way for speed and smoothness is to do a hardware scroll....
Anyway, the code you have posted should work (as far as I can tell at a glance). But I would divide all of your values by 4 and do a 'rep movsd' instead of 'rep movsb' this of course would be 4 times as fast as your current implementation.
- Pype.Clicker
- Member
- Posts: 5964
- Joined: Wed Oct 18, 2006 2:31 am
- Location: In a galaxy, far, far away
- Contact:
Re:scrolling up help
want it smoother ? well then just use the VGA registers to move around the video memory or the fine-pitching (pixel-per-pixel scrolling in text mode, hehe
Re:scrolling up help
I'm not sure it is, to be honest. If I had been able to use page-flipping, then I'm sure that it would be, as the rep functions are very highly optimized, running much faster than the equivalent loops. The fact that I do it twice probably negates the value, though. You are correct that it should go faster if I moved the data by doubleword increments, and there are certainly other ways I could optimize it, too. I was mostly interested in getting it working, and in seeing if anyone could help with the text-page switching issue.PlayOS wrote: After browsing your code, I am not sure but are copying the visible screen to the second text page, scrolling in the process by not copying the lines that are to be scrolled. Then at the end you copy the second page back to the visible page, now the data is scrolled up. But my question is how is this faster or smoother?
- Pype.Clicker
- Member
- Posts: 5964
- Joined: Wed Oct 18, 2006 2:31 am
- Location: In a galaxy, far, far away
- Contact:
Re:scrolling up help
your video memory is larger than a screen (actually, it is about 4 screens large!) thus you can do a scrolling by
where screen1 is 0xb8000 and screen2 is, say 0xb9000
Code: Select all
if (even) {
memcpy(screen1+1*LINE,screen2,24*LINE);
show(screen2);
} else {
memcpy(screen2+1*LINE,screen1,24*LINE);
show(screen1);
}
even++;