Scrolling text in 80 column text mode

Pagina 2/3
1 | | 3

Van Aslak3

Supporter (5)

afbeelding van Aslak3

14-09-2016, 00:10

NYYRIKKI wrote:

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.

Interesting. I'm using the 32 column mode in my Snake game. I wasn't aware of a scrolling register; I'll look it up. I can't wait to have a go at writing a Pac Man game. (Another use for my little micro is writing games!)

Quote:

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.

I hadn't considered this approach and it is intriguing. I could then "scroll" the screen by adjusting the offset into the 6809 RAM that is copied from. Multiple consoles will drive up memory usage though. My head is already starting to hurt at this - it is significantly more complex then simply calculating VRAM address from the cursor position. But I like, very much, what you are saying - especially about only updating the VRAM when the machine does not have more important things to do. I need to go away and think about how to do this. Smile

Thanks!

Van NYYRIKKI

Enlighted (5889)

afbeelding van NYYRIKKI

14-09-2016, 00:51

Aslak3 wrote:

Interesting. I'm using the 32 column mode in my Snake game. I wasn't aware of a scrolling register; I'll look it up.

Yes, with V9958 you can scroll the whole screen to both X & Y direction in 1 pixel accuracy in all screen modes except 40 and 80 column text modes.

Aslak3 wrote:

it is significantly more complex then simply calculating VRAM address from the cursor position.

If you can reserve a little bit more RAM the calculations become very easy... ie. if you create 128x24 virtual screen from where you only output 80x24 the location calculations can be done with pretty simple bit shifts & boolean math instead of trying to calculate x80 type of complex math... ie start of next line = (+128)AND $FF80 ... I think you get the point.

Van tvalenca

Paladin (747)

afbeelding van tvalenca

14-09-2016, 00:47

Aslak3 wrote:
NYYRIKKI wrote:

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.

I hadn't considered this approach and it is intriguing. I could then "scroll" the screen by adjusting the offset into the 6809 RAM that is copied from. Multiple consoles will drive up memory usage though. My head is already starting to hurt at this - it is significantly more complex then simply calculating VRAM address from the cursor position. But I like, very much, what you are saying - especially about only updating the VRAM when the machine does not have more important things to do. I need to go away and think about how to do this. Smile

NYYRIKKI solution is better. I know there's a lot of unused memory hooked to the VDP, but since you're using UARTs the cost of using it may be too high - you may lose incoming when "scrolling". You could use it to store less time-critical data, unload anything that you stored there to any location at RAM and then upload it back whenever you need. Since you're talking about multiple consoles, maybe there's some info that won't be received through serial connection... If you have only one active session per time, you could have inactive sessions data (apart from the data received through the UART) stored on VDP RAM... it may be a good trade off.

Van PingPong

Prophet (3793)

afbeelding van PingPong

14-09-2016, 00:59

[quote=Aslak3 wrote:
NYYRIKKI wrote:

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.

Interesting. I'm using the 32 column mode in my Snake game. I wasn't aware of a scrolling register; I'll look it up. I can't wait to have a go at writing a Pac Man game. (Another use for my little micro is writing games!)

v9958 provide you scroll support in both horizontal & vertical directions, with the nice feature of having circular mode. so you need to fill only the part that is disappearing during scroll. most systems by contrast have a limited support, the scroll register does not wrap-around. Also you can have limited hw sprite support.
As said in 80 column mode you can have more that two color for each charater on screen. you can have 4 colors.
every charater on screen can be displayed with the standard color or with alternate color taken from another register (does not remember which) and the alternate color can be flipped via hw at specified intervals.

Van NYYRIKKI

Enlighted (5889)

afbeelding van NYYRIKKI

14-09-2016, 01:07

tvalenca wrote:

Since you're talking about multiple consoles, maybe there's some info that won't be received through serial connection... If you have only one active session per time, you could have inactive sessions data (apart from the data received through the UART) stored on VDP RAM... it may be a good trade off.

Yes... I'm sure VRAM can hold more than enough copies of different consoles. If you set up the display base address according to console number and make sure you have flushed/drawn the screen to VRAM before changing console, you automatically have up to date copy of the screen when you next time need it... When you switch back you only need to copy the VRAM content once back to your RAM buffer and you are ready to rock. How ever if you are receiving data to all consoles at a same time, there is no fast way other than having all of the buffers in RAM... Even if you need to swap the consoles the way I explained, it is not really any slower than you current method of scrolling one line. Smile

Van Aslak3

Supporter (5)

afbeelding van Aslak3

14-09-2016, 13:55

NYYRIKKI wrote:

Yes... I'm sure VRAM can hold more than enough copies of different consoles. If you set up the display base address according to console number and make sure you have flushed/drawn the screen to VRAM before changing console, you automatically have up to date copy of the screen when you next time need it... When you switch back you only need to copy the VRAM content once back to your RAM buffer and you are ready to rock. How ever if you are receiving data to all consoles at a same time, there is no fast way other than having all of the buffers in RAM... Even if you need to swap the consoles the way I explained, it is not really any slower than you current method of scrolling one line. Smile

I should have explained: I've implemented a relatively simple multitasking "kernel" underneath the consoles. So each one, foreground and background, can received input from arbitrary serial ports, or the keyboard, or tasks running which want to display something. With the current implementation, switching consoles is achieved simply by updating the pattern address - which is beautiful and fast and can be done in the keyboard (attached to another UART port)'s ISR. Writing a character (the only output primitive) "seeks" to the current cursor position for the console in question (which not be currently active) and pokes the byte in, followed by a cursor byte. It also deals with carriage returns, backspace, and decides if a scroll is required. This all "feels" nice because it is very close to the serial port driver, the exception being the "seeking" and dealing with a scrolling display.

I need to go away and think about the RAM-backed display and how it might work within my current driver model, what the (CPU) memory requirements might be etc. Is it going to be possible to write in a circular (lines) screen buffer and scroll by moving the starting position for the VRAM update? Lots of thinking ahead for me.

Van Louthrax

Prophet (2406)

afbeelding van Louthrax

14-09-2016, 15:10

Maybe trying to have your console in graphics mode? Scroll would be super fast but outputing a character to the screen requires updating coordinates and send a VDP copy command, which can be processed independently by the VDP, but you'll have to wait for command completion before launching the next command, so that's still a bottlneck... And of course switching consoles implies redrawing the whole screen...

Ah, forgot that you'll also need to clean the bottom line when scrolling, so the character output rate on the screen will even not be constant...

Van hit9918

Prophet (2911)

afbeelding van hit9918

15-09-2016, 10:52

is there an UART interrupt handler?
an interrupt handler plus RAM buffer can eat huge hiccups happening in the main program.
having an interrupt buffer overflow versus having corruption in a polling loop are two very different stories.

how many bytes per second UART transfer are we talking?
the ballpark is needed to estimate how much graphics action can go on. and whether one needs stunts.
and what is the application.
"to have a nice console in an OS" is different to "I want the maximum ZDMODEM download on that tiny cpu".

6xxx fastopy

	lda x,0
	sta vdp
	lda x,1
	sta vdp
	lda x,2
	sta vdp
	...

the offsets in the instructions slide, no instructions to change the IX register.

Van Aslak3

Supporter (5)

afbeelding van Aslak3

15-09-2016, 13:35

hit9918 wrote:

is there an UART interrupt handler?

Yeap. There's also a FIFO in the UART which I'm utilising the lower the IRQ rate as well. The ISR fills a circular buffer from the FIFO, and when the FIFO is empty the task that owns the port is scheduled, which subsequently pulls off characters from the circular buffer, returning them to the "read a char" user routine.

Quote:

an interrupt handler plus RAM buffer can eat huge hiccups happening in the main program.
having an interrupt buffer overflow versus having corruption in a polling loop are two very different stories.

I think that is basically the only valid approach. Updating the screen VRAM from received characters is never going to work because it will always take (at best case) a 50th of a second to scroll the VRAM. But at the worst case....

Quote:

how many bytes per second UART transfer are we talking?

... there could be 240 scroll events a second (back to back CR LFs). So I've given up with the idea of NOT using CPU memory. This does suck mightily though: each console will consume 1920 bytes. Sad

I'm not keen on going below 9600 if I can help it. I should be able to go significantly faster, but right now my interrupt routine has a lot of overhead due to figuring out which device generated the interrupt, etc. What I don't want is for that overhead to include scrolling the display.

An alternative to all this cleverness would be... hardware flow control. I'm not so keen on that idea though.

Quote:

the ballpark is needed to estimate how much graphics action can go on. and whether one needs stunts.
and what is the application.
"to have a nice console in an OS" is different to "I want the maximum ZDMODEM download on that tiny cpu".

Yes indeed.

Quote:

6xxx fastopy

	lda x,0
	sta vdp
	lda x,1
	sta vdp
	lda x,2
	sta vdp
	...

the offsets in the instructions slide, no instructions to change the IX register.

That's a nice trick. When updating the VRAM I'll use that, but probably only to bunch up 8 updates in a inline chunk, with every 8th write bumping the index register and doing the bne after adjusting the countdown index.

Van hit9918

Prophet (2911)

afbeelding van hit9918

15-09-2016, 14:47

in bitmap mode (screen 7).
every char needs to copy 32 bytes. but scroll is faster.
the scroll goes with a register.
then the command engine needs to clear 2048 bytes to clear the bitmap.
while the charset mode needed cpu read 1920 bytes and write 1920 bytes.

the best fun would be to let the command engine clear halve of it while the cpu clears the other halve.
parallel processing Smile
sta port sta port, hammer hammer, the 9958 may hiccup and need some NOPs.

in bitmap mode rendering chars is much slower.
but when the text has all CR LF then comes the worst case and it is all a scroll show.

another idea. you could just blindly restart the command engine.
when it didnt finish the previous clear, random garbage from previous times appears onscreen.
but no chars are missing from the UART transfer. the currently incoming text is correct.
like "the zmodem tool still keeps usable". not for general application but for faster downloads.

as a goodie. the bitmap mode can print images. could print buttons of a nice gui.
I don't know, are there common escape sequences for image printing?

Pagina 2/3
1 | | 3