1. Scrolltext
- Posted by Tor Bernhard Gausen <tor.gausen at C2I.NET> Jan 19, 1999
- 496 views
All I wanted to do was to make a txt viewer in mode 18 which would allow people to read text files and scroll up and down smoothly and with some sort of accelerating speed control. Sounds very simple, right? Well, I ran into three problems; a trivial problem, a depressing problem and a mysterious problem. The trivial problem: I don't know how the mode18 bit planes are organized (where in memory, and which bit planes are most and least significant). Could anyone please help me, and/or direct me to a place on the web where I can find such information without bothering the EU list? The depressing problem is that my routine is incredibly slow. I'm clearly doing something REALLY wrong, but what? The program is slow in mode 19, how slow would it not be in mode 18? A smoother, faster, full screen 320x200 mode scroller was programmed on the 1MHz C64 by the 1001 Crew 15 years ago... It should be possible to do something at least as good on my P233, even in an interpreted language. The mysterious problem is that at one point on the screen, it seems like the raster is skipping one line ...!?! Consequently the text seems to be 'sucked' through a narrow horizontal portion of the screen. Is there something wrong with CHARN's wait_retrace routine? Or could the problem be my cheap video card ? With my card ("expert color s3" or something) I can't use modes 261 etc, but I can use modes 256 and 257. This means it's SVGA, right? Not right ? Well, here's an example of what I'm trying to do: --------------------------------------------------------------------------------- include graphics.e include machine.e global constant wait_retrace = allocate(20) -- thanks to CHARN for this routine poke(wait_retrace, { #50, -- PUSH EAX #52, -- PUSH EDX #BA,#DA,3,0,0, -- MOV EDX, 0x03DA #EC, -- IN AL, DX #24,#08, -- AND AL, 0x08 #75,#FB, -- JNZ -5 #EC, -- IN AL, DX #24,#08, -- AND AL, 0x08 #74,#FB, -- JZ -5 #5A, -- POP EDX #58, -- POP EAX #C3 } ) -- RET integer char, key, speed, screen_mem, mem_size object junk, text screen_mem=#A0000 mem_size= 320 * 200 speed=1 char=0 text = " *** Man, this is slooowww... ***" junk=graphics_mode(19) while char < length(text) do char +=1 if char=length(text) then char=1 end if key=get_key() if key=27 then abort(1) end if if key='+' and speed < 4 then speed *= 2 end if if key='-' and speed > 1 then speed /= 2 end if if key=' ' then key=-1 while key !=' ' do key=get_key() end while end if position(25,1) puts (1,text) for m=1 to 8/speed do call (wait_retrace) mem_copy (screen_mem, screen_mem+320*speed, mem_size) end for end while ----------------------------------------------------------------------------------------- You can regulate speed with +/- and freeze with space. The text does not glide smoothly the way I wanted it to. Instead it seems to 'shake' so that it all becomes a blur. This gets worse with higher speeds, but is also visible at the slowest speed. A similar routine with a horizontal scroller is very nice and smooth, but is just as slow. Would things go faster with a virtual screen? How do I write text to a virtual screen, (not to mention drawing lines, circles etc. ?) And if the answer is: "there's no easy way, you have to copy characters to the virtual screen one by one (and code your own graphics routines (yeah, right!))" then: Where in memory can I find the standard character set? (Another trivial question I guess). Thanks, Tor Bernhard Gausen
2. Re: Scrolltext
- Posted by Lucius Hilley III <lhilley at CDC.NET> Jan 19, 1999
- 490 views
On Tue, 19 Jan 1999 03:43:33 +0000, Tor Bernhard Gausen <tor.gausen at C2I.NET> wrote: <SNIP> In short his message says he wants information about mode 18 and his routines aren't fast enough. --------------------------------------------------------------------------------- include graphics.e include machine.e global constant wait_retrace = allocate(20) -- thanks to CHARN for this routine poke(wait_retrace, { #50, -- PUSH EAX #52, -- PUSH EDX #BA,#DA,3,0,0, -- MOV EDX, 0x03DA #EC, -- IN AL, DX #24,#08, -- AND AL, 0x08 #75,#FB, -- JNZ -5 #EC, -- IN AL, DX #24,#08, -- AND AL, 0x08 #74,#FB, -- JZ -5 #5A, -- POP EDX #58, -- POP EAX #C3 } ) -- RET integer char, key, speed, screen_mem, mem_size object junk, text screen_mem=#A0000 mem_size= 320 * 200 speed=1 char=0 text = " *** Man, this is slooowww... ***" junk=graphics_mode(19) while char < length(text) do char +=1 if char=length(text) then char=1 end if key=get_key() if key=27 then abort(1) end if if key='+' and speed < 4 then speed *= 2 end if if key='-' and speed > 1 then speed /= 2 end if if key=' ' then key=-1 while key !=' ' do key=get_key() end while end if position(25,1) puts (1,text) for m=1 to 8/speed do call (wait_retrace) mem_copy (screen_mem, screen_mem+320*speed, mem_size) end for end while ----------------------------------------------------------------------------------------- > >You can regulate speed with +/- and freeze with space. > >The text does not glide smoothly the way I wanted it to. >Instead it seems to 'shake' so that it all becomes a blur. SHAKE?. Sorry I haven't tested it. >This gets worse with higher speeds, but is also visible >at the slowest speed. A similar routine with a horizontal >scroller is very nice and smooth, but is just as slow. > >Would things go faster with a virtual screen? Faster? Not really. vitual screens aren't faster. Virtual screens are smoother. The blasting of text hardly requires virtual screens. >How do I write text to a virtual screen, (not to mention >drawing lines, circles etc. ?) Graphic routines such as mode19.e and neil.e and countless others, that I don't recall, have been made for just this purpose in mind. Also the font libraries were designed for this. Someone has written some font routines that grabs the standard character set directly from memroy. >And if the answer is: "there's no easy way, you have to >copy characters to the virtual screen one by one (and >code your own graphics routines (yeah, right!))" then: Yes, code your own or use what others have built. :) >Where in memory can I find the standard character set? >(Another trivial question I guess). > > >Thanks, > >Tor Bernhard Gausen Good Luck, Lucius L. Hilley III
3. Re: Scrolltext
- Posted by The AfterBeat <afterbeat at GEOCITIES.COM> Jan 19, 1999
- 510 views
--------------685F0D9EA9FBD73982DC316C Tor Bernhard Gausen wrote: > All I wanted to do was to make a txt viewer in mode 18 which > would allow people to read text files and scroll up and down > smoothly and with some sort of accelerating speed control. > > Sounds very simple, right? > > Well, I ran into three problems; a trivial problem, > a depressing problem and a mysterious problem. > > The trivial problem: I don't know how the mode18 bit planes > are organized (where in memory, and which bit planes are > most and least significant). Could anyone please help me, > and/or direct me to a place on the web where I can find > such information without bothering the EU list? > > The depressing problem is that my routine is incredibly slow. > I'm clearly doing something REALLY wrong, but what? > The program is slow in mode 19, how slow would it not > be in mode 18? A smoother, faster, full screen 320x200 > mode scroller was programmed on the 1MHz C64 by the > 1001 Crew 15 years ago... It should be possible to do > something at least as good on my P233, even in an > interpreted language. > > The mysterious problem is that at one point on the > screen, it seems like the raster is skipping one line ...!?! > Consequently the text seems to be 'sucked' through > a narrow horizontal portion of the screen. > Is there something wrong with CHARN's wait_retrace > routine? Or could the problem be my cheap video card ? > With my card ("expert color s3" or something) I can't > use modes 261 etc, but I can use modes 256 and 257. > This means it's SVGA, right? Not right ? > Well, here's an example of what I'm trying to do: > > > --------------------------------------------------------------------------------- > include graphics.e > include machine.e > > global constant wait_retrace = allocate(20) > -- thanks to CHARN for this routine > poke(wait_retrace, { > #50, -- PUSH EAX > #52, -- PUSH EDX > #BA,#DA,3,0,0, -- MOV EDX, 0x03DA > #EC, -- IN AL, DX > #24,#08, -- AND AL, 0x08 > #75,#FB, -- JNZ -5 > #EC, -- IN AL, DX > #24,#08, -- AND AL, 0x08 > #74,#FB, -- JZ -5 > #5A, -- POP EDX > #58, -- POP EAX > #C3 } ) -- RET > > integer char, key, speed, screen_mem, mem_size > object junk, text > > screen_mem=#A0000 > mem_size= 320 * 200 > speed=1 > char=0 > text = " *** Man, this is slooowww... ***" > > junk=graphics_mode(19) > > while char < length(text) do > char +=1 if char=length(text) then char=1 end if > key=get_key() if key=27 then abort(1) end if > if key='+' and speed < 4 then speed *= 2 end if > if key='-' and speed > 1 then speed /= 2 end if > if key=' ' then > key=-1 > while key !=' ' do > key=get_key() > end while > end if > position(25,1) puts (1,text) > for m=1 to 8/speed do > call (wait_retrace) > mem_copy (screen_mem, screen_mem+320*speed, > mem_size) > end for > end while > > ----------------------------------------------------------------------------------------- > > You can regulate speed with +/- and freeze with space. > > The text does not glide smoothly the way I wanted it to. > Instead it seems to 'shake' so that it all becomes a blur. > This gets worse with higher speeds, but is also visible > at the slowest speed. A similar routine with a horizontal > scroller is very nice and smooth, but is just as slow. > > Would things go faster with a virtual screen? > How do I write text to a virtual screen, (not to mention > drawing lines, circles etc. ?) > > And if the answer is: "there's no easy way, you have to > copy characters to the virtual screen one by one (and > code your own graphics routines (yeah, right!))" then: > Where in memory can I find the standard character set? > (Another trivial question I guess). > > Thanks, > > Tor Bernhard Gausen Well, I tested out that program, and I found that it goes faster, and the text doesn't shake, when you take out the part that calls the vertical retrace routine. As far as finding the standard character set, that is located at the real-mode address F000:FA6E (hex), which in Euphoria, would be #FFA6E. The only thing that sucks, is that location only holds information for ASCII characters 0 thru 127. I know that there is information for chars 128 thru 255, but I forgot the address. I do know, however, that it is located at some real-mode interrupt vector. I just forgot which one. The format for the characters at those locations, though, goes like this... Each character, is 8 bytes long, so, to find the location of a specific character, you would use the formula #FFA6E + (character * 8). Now, each of the 8 bits for every byte contains the information for how the character is to be drawn. Bit 7 is the leftmost pixel, and bit 0 is the rightmost pixel. When a bit is set (1), that means the pixel is set for the character. When it's not, well, it's not, so, you can draw your own background color there, or not mess with it at all. Attached, I have a file containing a routine (2,604 bytes) that helps explain this. (It only works in graphics mode 19. It can be changed to make calls to pixel(), so it can work in all graphics modes.) --------------685F0D9EA9FBD73982DC316C name="abtext.e" Content-Disposition: inline; filename="abtext.e" -- -- Character displaying example -- -- Euphoria 2.1 syntax is used -- -- Created by The AfterBeat -- Email: afterbeat at hotmail.com or afterbeat at geocities.com -- ICQ #: 10166297 -- -- Constants -- constant VideoMem = #A0000, RomCharSet = #FFA6E, CharWidth = 8, CharHeight = 8, StepBackVal = 320 * CharHeight -- -- draw_text -- -- text = The text to be drawn -- fc = The foreground color -- bc = The background color (use -1 for transparent text) -- xy = A 2-element sequence for the position {x, y} -- global procedure draw_text(object text, integer fc, integer bc, sequence xy) -- Displays text on the screen (graphics mode 19 is assumed!) -- atom scrn_addr, char_addr integer bitmask -- Get the address of the starting location -- scrn_addr = VideoMem + (xy[2] * 320) + xy[1] -- Convert the text to a sequence -- if not sequence(text) then text = {text} end if -- Get the address of the character -- for count = 1 to length(text) do -- Get the address of the character -- char_addr = RomCharSet + (text[count] * 8) -- Display the character, one row at a time -- for height = 1 to CharHeight do -- Reset the bitmask (to bit 7, value = #80) -- bitmask = #80 -- Display a row of the character -- for width = 1 to CharWidth do -- See if the bit is set -- if and_bits(peek(char_addr), bitmask) then poke(scrn_addr + width, fc) -- If not, see if transparency is enabled -- elsif bc != -1 then -- Okay, that's not enabled either. Set the pixel to the background color. -- poke(scrn_addr + width, bc) end if -- Shift the bitmask 1 bit to the right -- bitmask = floor(bitmask / 2) end for -- Update the pointers -- scrn_addr += 320 -- Move to the next row of the screen -- char_addr += 1 -- Move to the next row of the character -- end for -- -- Move back to the original y position of the screen, -- and update the x position. -- -- So far, this is the fastest way to restore and -- update the position I know. Later I'll try to -- find a faster way to do this. It was written -- this way because this routine handles both strings -- of text and single characters. -- scrn_addr = (scrn_addr - StepBackVal) + CharWidth end for end procedure --------------685F0D9EA9FBD73982DC316C--
4. Re: Scrolltext
- Posted by Jiri Babor <J.Babor at GNS.CRI.NZ> Jan 20, 1999
- 487 views
Tor, I hope I am not going to enhance your depression by saying that I think there is probably not much that you can do *easily* to speed up your text scroll routines significantly... Several observations that might be of some help: In recent years I really had to use a wait_retrace routine only when I was messing around with page switching. Otherwise the 'modern' hardware does not seem to need it. I ran your scroller and it was reasonably smooth at the lowest speed setting - after I commented out the line with the wait_retrace call. Some residual 'jerkiness' is due to disproportionally long time required to actually write the text at the bottom of the screen. You can probably copy several hundred frames per second to the video screen on your P233, but the text display is so slow it will always be a problem. BTW, you should never rely on the hardware to dictate the top speed. Everybody's machine will be ten times faster in three years time. Always use a timing loop to set the maximum speed, even if you never get anywhere near it with your present gear. In a decade or so software archeologists will praise you for it... Get Pete Eberlein's fontfont.e from his site if you want to call any of the rom fonts. If I remember correctly, it can access any variation of built-in fonts. Personally I dislike 8x8 rom font (I think it's very ugly) and because the old 14x8 font is not supported on all newer machines, I use only 16x8 set in my rfont.e; I think it is still on the Recent User Contributions page and you may find it of some interest too. The above mentioned includes are pixel based. But it would be almost trivial to replace all pixel calls with memory pokes for use with virtual screens... You also mentioned drawing lines, circles, etc. on virtual screens. Have a look at my vgraph.e in the Archives. It is pretty old and neglected, but it does lines, ellipses and polygons reasonably fast. jiri
5. Re: Scrolltext
- Posted by Robert Craig <rds at EMAIL.MSN.COM> Jan 20, 1999
- 479 views
Tor Bernhard Gausen writes: > The depressing problem is that my routine is incredibly slow. > I'm clearly doing something REALLY wrong, but what? If you don't need smooth scrolling, you can use Euphoria's scroll() library routine in any graphics or text mode. It's reasonably fast. Here's a mode 18 example. include graphics.e if graphics_mode(18) then end if for i = 1 to 30 do printf(1, "%d:%s\n", {i, 'A' + rand(repeat(20, 60))}) end for for i = 1 to 100 do scroll(1,1,30) -- scroll lines 1..30 up one line position(30,1) printf(1, "%d:%s", {i, 'A' + rand(repeat(20, 60))}) end for if graphics_mode(-1) then end if As for your smooth scrolling program, it spends over 95% of it's time doing mem_copy() of 64000 bytes. Euphoria's mem_copy() calls C's memcpy(). I don't think you could run your program more than about 1% faster in C. I believe that writes to screen memory are much slower than writes to general DRAM addresses, because of the lack of caching. Regards, Rob Craig Rapid Deployment Software http://members.aol.com/FilesEu/