Discussion:
using rep movsw instruction to move text mode screen
(too old to reply)
bilsch01
2019-12-05 00:50:33 UTC
Permalink
My program uses 4000 bytes at segment 0xb800 for text mode display. The
bottom 3 lines of the screen (160 bytes of memory per line) are static
display and are not to be moved. Bytes 0 thru 3519 contain part of a
text document and are the area to be moved up/down.

1. The code below moves the displayed document text up one line. It
works fine:

mov ax,0xb800
mov ds,ax
mov es,ax
mov cx,1680
mov si,160
mov di,0
rep movsw

2. I tried the code below to move the displayed document text down one line:

mov ax,0xb800
mov ds,ax
mov es,ax
mov cx,1680
mov si,3200
mov di,3360
rep movsw

It moves the line beginning at b800:3200 down one line on the screen but
the lines above it are not moved down. It is unfortunate that the static
display gets overwritten, I can handle that later. I tried some
variations of the code but I wasn't able to get the entire document area
to move down one line. Can someone here tell me how to move the document
area down one line.
TIA. Bill S.
Terje Mathisen
2019-12-05 07:02:32 UTC
Permalink
Post by bilsch01
My program uses 4000 bytes at segment 0xb800 for text mode display. The
bottom 3 lines of the screen (160 bytes of memory per line) are static
display and are not to be moved. Bytes 0 thru 3519 contain part of a
text document and are the area to be moved up/down.
1. The code below moves the displayed document text up one line. It
mov ax,0xb800
mov ds,ax
mov es,ax
mov cx,1680
mov si,160
mov di,0
rep movsw
mov ax,0xb800
mov ds,ax
mov es,ax
mov cx,1680
mov si,3200
mov di,3360
rep movsw
It moves the line beginning at b800:3200 down one line on the screen but
the lines above it are not moved down. It is unfortunate that the static
display gets overwritten, I can handle that later. I tried some
variations of the code but I wasn't able to get the entire document area
to move down one line. Can someone here tell me how to move the document
area down one line.
TIA.   Bill S.
This is the classic overlapping move problem. :-)

You have recognized it partially, in that you are pointing at hte end of
the buffer areas instead of the beginning, but you have failed to issue
a STD (Set Direction bit, vs CLD which is the default).

However, the real issue here is the fact that you should NOT move text
around on a classic PC screen at all! Instead you maintain an off-screen
buffer and then you use REP MOVSW to copy the relevant parts into the
screen memory.

This is because the screen buffer is/was 3-10 times slower than normal
RAM, so it was far faster to do all updates off-screen and then copy in
the finished screen.

In my own code I used a list of line buffers for that off-screen
display, so that I could do partial scrolling with just a few pointer
updates, before using REP MOVSW on individual lines to copy them to the
correct screen location.

If you have the original CGA screen then you also need to worry about
screen flicker if you write to the CGA memory while the screen is being
refreshed! You can copy at least 1-4 lines (afair) of data in the
vertical retrace interval and a few characters in each horizontal
retrace if you need to.

Terje
--
- <Terje.Mathisen at tmsw.no>
"almost all programming can be viewed as an exercise in caching"
bilsch01
2019-12-13 23:39:01 UTC
Permalink
Post by Terje Mathisen
Post by bilsch01
My program uses 4000 bytes at segment 0xb800 for text mode display.
The bottom 3 lines of the screen (160 bytes of memory per line) are
static display and are not to be moved. Bytes 0 thru 3519 contain part
of a text document and are the area to be moved up/down.
1. The code below moves the displayed document text up one line. It
mov ax,0xb800
mov ds,ax
mov es,ax
mov cx,1680
mov si,160
mov di,0
rep movsw
mov ax,0xb800
mov ds,ax
mov es,ax
mov cx,1680
mov si,3200
mov di,3360
rep movsw
It moves the line beginning at b800:3200 down one line on the screen
but the lines above it are not moved down. It is unfortunate that the
static display gets overwritten, I can handle that later. I tried some
variations of the code but I wasn't able to get the entire document
area to move down one line. Can someone here tell me how to move the
document area down one line.
TIA.   Bill S.
This is the classic overlapping move problem. :-)
You have recognized it partially, in that you are pointing at hte end of
the buffer areas instead of the beginning, but you have failed to issue
a STD (Set Direction bit, vs CLD which is the default).
However, the real issue here is the fact that you should NOT move text
around on a classic PC screen at all! Instead you maintain an off-screen
buffer and then you use REP MOVSW to copy the relevant parts into the
screen memory.
This is because the screen buffer is/was 3-10 times slower than normal
RAM, so it was far faster to do all updates off-screen and then copy in
the finished screen.
In my own code I used a list of line buffers for that off-screen
display, so that I could do partial scrolling with just a few pointer
updates, before using REP MOVSW on individual lines to copy them to the
correct screen location.
If you have the original CGA screen then you also need to worry about
screen flicker if you write to the CGA memory while the screen is being
refreshed! You can copy at least 1-4 lines (afair) of data in the
vertical retrace interval and a few characters in each horizontal
retrace if you need to.
Terje
Thanks.

s***@nospicedham.yahoo.com
2019-12-05 16:05:29 UTC
Permalink
Post by bilsch01
My program uses 4000 bytes at segment 0xb800 for text mode display. The
bottom 3 lines of the screen (160 bytes of memory per line) are static
display and are not to be moved. Bytes 0 thru 3519 contain part of a
text document and are the area to be moved up/down.
0..3519 is 3520 bytes
3520/160 = 22 lines?, or 21?
Post by bilsch01
1. The code below moves the displayed document text up one line. It
mov ax,0xb800
mov ds,ax
mov es,ax
mov cx,1680
mov si,160
mov di,0
rep movsw
mov ax,0xb800 ;; begins screen offset
mov ds,ax ;; prep ds for source segment, assumed ds value was saved,
;; and CLD was done for increment block moves.
Post by bilsch01
mov es,ax ;; destination segment, same as src segm
mov cx,1680 ;; count is 1680/80 words per line = 21 lines
mov si,3200 ;; starting source offset ?? --I think you mean from line zero
;; whose offset is 0000h
Post by bilsch01
mov di,3360 ;; destination offset is ?? 3360/80 words is line 42 ???
;; one line is 80 words, to scroll one line down, add 80 to
;; the starting offset to put into the destination offset.
;; Scrolling from line zero down, then the DI value is line 0 plus
;; 80 words, mov di, 80
Post by bilsch01
rep movsw ;; means DS:SI++ -> ES:DI++ by word size
It moves the line beginning at b800:3200 down one line on the screen but
the lines above it are not moved down. It is unfortunate that the static
display gets overwritten, I can handle that later. I tried some
variations of the code but I wasn't able to get the entire document area
I guess this means from line 0 toward line 21.
I think your perception might be that scrolling is done from the bottom of the screen toward the top of the screen.. but with CLD, the scrolling is from bottom of memory (top of the screen) toward the top of memory (bottom of the screen).
A little counter intuitive.

You could develop using STD, block moves (scrolling) toward lower memory (from bottom of screen toward the top of the screen) just watch your indexing SI, DI and think of CX as a form of line count: mov cx, line_cnt*80

There are also the int 10h functions:
o Fn 6, scroll window up
o Fn 7, scroll window down

-as options, see RBIL

hth,

Steve
Post by bilsch01
to move down one line. Can someone here tell me how to move the document
area down one line.
TIA. Bill S.
Loading...