Scrolling text in 80 column text mode

Page 1/3
| 2 | 3

By Aslak3

Supporter (5)

Aslak3's picture

13-09-2016, 13:10

Hi MSX gods!

I've never actually owned an MSX, sadly. But I'm in love with a critical part of it, the VDC, and am using one in my 6809 based home-brew machine. Specifically I'm using a V9958. So far I have only really played with the text (pattern) modes. Everything is working well: my little micro has a little OS which presents a text based "DOS". The one thing I am struggling with (performance wise) is scrolling text up the screen when the "cursor" reaches the bottom of the bottom of the display.

Currently I'm reading the screen data, and writing it back, offset one line up the screen. This is followed by blanking the bottom most line. It works quite well, the problem is it is rather slow. I see that the V9938 and V9958 has hardware for copying graphical blocks about, drawing lines etc. I've not played with these yet (nor any graphics mode in fact), but is it possible to use some of this hardware for arbitrary VRAM manipulation? Or is there some other technique I can use for scrolling text?

Sorry for posting here - my question is not MSX specific. But you guys seem EXTREMELY knowledgeable on these amazing VDCs. Smile

Lawrence

PS. If you are interested, you can read about my little micro here: http://aslak3.blogspot.co.uk/

Login or register to post comments

By tvalenca

Paladin (747)

tvalenca's picture

13-09-2016, 17:59

Welcome to the MSX (V9958) world, Aslak3!

Just for clarification and not for nitpicking, We call the V9958 and its predecessors (V9938 and TMS9918) VDP (Video Display Processor) because they have some processing power likewise we have on modern GPUs. VDC (Video Display Controller) is a nice description for CoCo's 6847.

Well, I've just discussed this with a friend a few days ago. Even if reading/writting the text on screen isn't (performance wise) a good way to do things, it would have a decent speed. Since you don't look satisfied and you're using V9958, you could use the VDP command engine, I think the command YMMM would be exactly what you're looking for.

But I have to ask: how are you doing the scroll? by rewritting the pattern data or the name table? And you are using the autoincrement VRAM address pointer during VRAM Writes?

By AxelF

Champion (389)

AxelF's picture

13-09-2016, 18:21

I thought you could only use the VDP command engine in screen5 and above ???

By tvalenca

Paladin (747)

tvalenca's picture

13-09-2016, 18:33

AxelF wrote:

I thought you could only use the VDP command engine in screen5 and above ???

This is true only for V9938; V9958 can run commands on any screen mode.

By ARTRAG

Enlighted (6567)

ARTRAG's picture

13-09-2016, 18:57

And during vblank also v9938 can use the copy engine.
Just go to any graphic mode at vblank, cast the command and return to text mode once after its completion

By AxelF

Champion (389)

AxelF's picture

13-09-2016, 20:30

AHA thank you guys, very interesting...

By PingPong

Prophet (3793)

PingPong's picture

13-09-2016, 20:41

@Aslak3:
on vdp you do the scroll by scrolling the so called nametable. you have to move 80x24 bytes for an entire screen at once that can be more if you choose also to use blink/charater cursors and inverted colors in hw.
We, on the msx world, use the z80 to perform the same thing. those old and beloved cpu can move about 900 bytes each on each vblank (4ms) so we can scroll an entire screen at 60fps only in 40 column text mode or in 32 column mode.
our z80 run @3.57mhz with a m1 wait state. Do not be fooled by the apparently high clock. the z80 is designed to accept and require an high clock rate. Approx it's like a 6809 @2-.2.5 mhz.
so i think you should be able to move the same amount of data without difficulties.
Also take in account that if start the move operation on VBLANK time, the raster beam hardly can catch you and you can move the entire screen in 18ms rather than 4ms of vblank interval retrace.
however, take into account that the vdp, when displaying data in active area cannot keep up with cpu sending data to fast. in active area you can not push bytes at a rate greater than 1 byte every 8us to keep on safe condition.

By NYYRIKKI

Enlighted (5889)

NYYRIKKI's picture

13-09-2016, 20:54

In V9958 you can indeed enable VDP command engine to work in text modes as well... how ever this is pretty useless. When command mode is enabled it handles the screen as in SCREEN 8 (256 color mode, 1byte = 1pixel). So logically VDP sees the 128KB VRAM as one 256x512 resolution picture. Because 80-column mode is practically 80x24 picture, it is very hard to do anything useful with the engine as it does not have any linear copy... It can only copy rectangular areas... At this moment you may still think that it is a good idea, but the problems don't stop there, because the addressing of VRAM is "interlaced" in modes where over 32KB is needed for drawing a screen. This means that when VDP is reading or writing the address is divided by 2 and bit 0 becomes bit 16. This means that even if you manage to use the command engine for scrolling, it will actually scroll two screens 64KB from each other. ie. If you in SCREEN 8 write address range #10000-#1FFFF in SCREEN 0 this means you wrote address ranges #8000-#FFFF and #18000-#1FFFF (This kind of things happen when you try to keep downwards compatibility with TMS99x8 series)

Other possibility to use the engine is like ARTRAG suggested. When VDP is not drawing the display area of screen, you can ie. switch in to SCREEN 5 (16 colors, 1 nibble = 1 pixel) where 128KB of VRAM means virtual 256x1024 screen. In this mode the VRAM addressing works in same way as in text modes, but you have to make sure that your copies are finished before it is time to switch back to text & draw the visible screen again.

Practically both methods cause huge headache and I don't even know if anyone has ever used these methods. I would say that if you just have some spare RAM you can use, just keep the copy of screen in RAM and when scrolling, just dump the whole RAM buffer to VRAM... As PingPong explained, this will be fast enough to update whole screen in a screen draw.

By Marq

Champion (387)

Marq's picture

13-09-2016, 21:29

900 bytes in vblank? I guess yes, if the sloppy BIOS VBI handler is running. If not, more like 1.5 k in the blank and 1.5 k more during the screen refresh.

By Aslak3

Supporter (5)

Aslak3's picture

13-09-2016, 22:52

Thanks everyone for your replies! I love this place already. Smile

tvalenca wrote:

Welcome to the MSX (V9958) world, Aslak3!

Just for clarification and not for nitpicking, We call the V9958 and its predecessors (V9938 and TMS9918) VDP (Video Display Processor) because they have some processing power likewise we have on modern GPUs. VDC (Video Display Controller) is a nice description for CoCo's 6847.

Righty ho. Smile I wasn't aware of the distinction - I've heard of VDP but just assumed it was the same thing. Useful to know it is not!

Quote:

Well, I've just discussed this with a friend a few days ago. Even if reading/writting the text on screen isn't (performance wise) a good way to do things, it would have a decent speed. Since you don't look satisfied and you're using V9958, you could use the VDP command engine, I think the command YMMM would be exactly what you're looking for.

As others have said, and I was able to very roughly determine myself reading the manual, this would be hard I think. I'm still unsure if it is totally unsuitable, but from the sounds of it, it is. It's a real shame because the VDP should be lightning fast at moving around 80x24 bytes.

Quote:

But I have to ask: how are you doing the scroll? by rewritting the pattern data or the name table? And you are using the autoincrement VRAM address pointer during VRAM Writes?

Yes, I'm using auto-increment. So I actually have 6 console in VRAM, at 0x8000, 0x9000, 0xa000 etc. I'm doing the following actions:

1. "Seek", in read mode to 0x8000 + 80
2. Read in 80x23 bytes
3. "Seek", in write mode to 0x8000
4. Write out 80x23 bytes
5. "Seek", in write mode to 0x8000 + 80x23
6. Zero 80 bytes

In the 6809 I'm doing standard looping with a 16bit index register counting down. I have found that when writing I need 3 nops (2Mhz machine cycle in the 6809) after the store to the VDP port. Otherwise I get the odd missed byte when doing consecutive (unrolled) writes. I have no nops on the read loop.

Looking at the 6809 datasheet I've calculated that my read loop is 18 cycles long. The write loop, with the nops, comes in at 25 cycles. Doing clears only shaves 6 cycles from the write loop.

So the total cycles to do a scroll, ignoring setting up the VRAM pointer registers, is:

18 x (80 x 23) + 25 x (80 x 23) + 19 x 80 = 33120 + 46000 + 1520 = 80640

With a 0.5uS machine cycle, this is 0.04032 seconds, or just about 1/25th second. I really need to try shaving those nops. I should not need them inside the loop, only when doing "inline" writes. Anyway, does this sound roughly as good as I'll ever get, or am I missing some "tricks"?

For most uses, eg. if I wanted to run a BASIC in my little computer, or run a DOS shell that I intend to write, the scrolling would probably be fast enough. The problem is that I have another use in mind for my little micro - as a serial terminal. Right now I'm loosing data, a lot of data, at the start of each line, if the screen has to scroll. Even with a FIFO in the UART, the data cannot be pulled off fast enough since the 6809 is busy scrolling the text buffer.

One thing that might help a bit is chunking up the scrolling and scroll at every 2nd or 4th line or similar. This ould be nasty. Nastier still would be to not scroll at all and just wrap the cursor to the top of the screen, blanking out the current line. But... Yuck.

Boy, I wish the pattern name base was settable to a specific byte (or even modulo 80) RAM address.

Thanks everyone. Smile

By NYYRIKKI

Enlighted (5889)

NYYRIKKI's picture

13-09-2016, 23:33

Indeed... this is a bit painful... In 32-column mode you can use scroll register, but unfortunately even that does not work in 80-column mode.

I still suggest that you draw the screen to RAM instead. This way you can handle all the data coming from UART. You can then output the screen buffer to VRAM as parts between checking if there is data in FIFO. If scrolling happens, you just set the "current screen update position" back to start of screen, so that the screen will be updated only when there is time to do it... If you are worried that the whole screen stays without any updates when there is big data chunk coming in then update the last line in real time and update rest of the screen only when there is time to do it.

Page 1/3
| 2 | 3