[Back to SCROLL SWAG index] [Back to Main SWAG index] [Original]
{
> Does anybody know if it is possible to accomplish a smooth-text scroller
> (like in the old c64 dayz) in text mode? If so, please let me know and
> Well, it's impossible, you'll have to switch to a graphic mode.
No, it's possible in text mode... it's just a pain in the
arse. I know of two ways. The first is to use an alternate
character set (the EGA can have 2 on screen at once, the VGA can
have 4). You use one character set as normal text, and use the
other as a pseudo-graphics window. Put the text you need to
scroll in the window and move (copy) it a pixel at a time. The
second way is to use the 8253 timer to time the scanline. When
the scanline gets to the portion of the screen you want, turn off
v-retrace, set v-retrace on the next scan line, and set the
horizontal pel pan to the value you need for your smooth pan.
When the card gets to the line that the v-retrace would occur, it
resets the pan but doesn't retrace because you turned it off.
After this, reset the registers you changed back to their default
values so the card builds the screen correctly. This is done on
EVERY screen build. Needless to say, the pseudo-graphics window
version is easier so that's the one I used to program the example
that follows.
}
Program SmoothTextScrollExample1;
{==============================================
Smooth Scroll In Text Mode Example
Programmed by David Dahl
12/21/93
This program and source are PUBLIC DOMAIN
----------------------------------------------
This example uses a second font to scroll
the text. The font definition is changed
to make the text scroll. This program
requires VGA.
==============================================}
Uses CRT;
Type FontDefType = Array[0..255, 0..31] of Byte;
Var ScrollText : String;
FontDef : FontDefType;
Procedure SetCharWidthTo8; Assembler;
Asm
{ Change To 640 Horz Res }
MOV DX, $3CC
IN AL, DX
AND AL, Not(4 OR 8)
MOV DX, $3C2
OUT DX, AL
{ Turn Off Sequence Controller }
MOV DX, $3C4
MOV AL, 0
OUT DX, AL
MOV DX, $3C5
MOV AL, 0
OUT DX, AL
{ Reset Sequence Controller }
MOV DX, $3C4
MOV AL, 0
OUT DX, AL
MOV DX, $3C5
MOV AL, 3
OUT DX, AL
{ Switch To 8 Pixel Wide Fonts }
MOV DX, $3C4
MOV AL, 1
OUT DX, AL
MOV DX, $3C5
IN AL, DX
OR AL, 1
OUT DX, AL
{ Turn Off Sequence Controller }
MOV DX, $3C4
MOV AL, 0
OUT DX, AL
MOV DX, $3C5
MOV AL, 0
OUT DX, AL
{ Reset Sequence Controller }
MOV DX, $3C4
MOV AL, 0
OUT DX, AL
MOV DX, $3C5
MOV AL, 3
OUT DX, AL
{ Center Screen }
MOV DX, $3DA
IN AL, DX
MOV DX, $3C0
MOV AL, $13 OR 32
OUT DX, AL
MOV AL, 0
OUT DX, AL
End;
Procedure WriteScrollTextCharacters(Row : Byte);
Var Counter : Word;
Begin
{ Set Fonts 0 & 1 }
ASM
MOV BL, 4
MOV AX, $1103
INT $10
END;
{ Write Characters }
For Counter := 0 to 79 do
Begin
{ Set Characters }
MEM[$B800:(80*2)*Row+(Counter*2)] := Counter;
{ Set Attribute To Secondary Font }
MEM[$B800:(80*2)*Row+(Counter*2)+1] :=
MEM[$B800:(80*2)*Row+(Counter*2)+1] OR 8;
End;
End;
Procedure FlushKeyBoardBuffer;
Var Key : Char;
Begin
While KeyPressed do
Key := ReadKey;
End;
Procedure SetAccessToFontMemory; Assembler;
ASM
{ Turn Off Sequence Controller }
MOV DX, $3C4
MOV AL, 0
OUT DX, AL
MOV DX, $3C5
MOV AL, 1
OUT DX, AL
{ Reset Sequence Controller }
MOV DX, $3C4
MOV AL, 0
OUT DX, AL
MOV DX, $3C5
MOV AL, 3
OUT DX, AL
{ Change From Odd/Even Addressing to Linear }
MOV DX, $3C4
MOV AL, 4
OUT DX, AL
MOV DX, $3C5
MOV AL, 7
OUT DX, AL
{ Switch Write Access To Plane 2 }
MOV DX, $3C4
MOV AL, 2
OUT DX, AL
MOV DX, $3C5
MOV AL, 4
OUT DX, AL
{ Set Read Map Reg To Plane 2 }
MOV DX, $3CE
MOV AL, 4
OUT DX, AL
MOV DX, $3CF
MOV AL, 2
OUT DX, AL
{ Set Graphics Mode Reg }
MOV DX, $3CE
MOV AL, 5
OUT DX, AL
MOV DX, $3CF
MOV AL, 0
OUT DX, AL
{ Set Misc. Reg }
MOV DX, $3CE
MOV AL, 6
OUT DX, AL
MOV DX, $3CF
MOV AL, 12
OUT DX, AL
End;
Procedure SetAccessToTextMemory; Assembler;
ASM
{ Turn Off Sequence Controller }
MOV DX, $3C4
MOV AL, 0
OUT DX, AL
MOV DX, $3C5
MOV AL, 1
OUT DX, AL
{ Reset Sequence Controller }
MOV DX, $3C4
MOV AL, 0
OUT DX, AL
MOV DX, $3C5
MOV AL, 3
OUT DX, AL
{ Change To Odd/Even Addressing }
MOV DX, $3C4
MOV AL, 4
OUT DX, AL
MOV DX, $3C5
MOV AL, 3
OUT DX, AL
{ Switch Write Access }
MOV DX, $3C4
MOV AL, 2
OUT DX, AL
MOV DX, $3C5
MOV AL, 3 {?}
OUT DX, AL
{ Set Read Map Reg }
MOV DX, $3CE
MOV AL, 4
OUT DX, AL
MOV DX, $3CF
MOV AL, 0
OUT DX, AL
{ Set Graphics Mode Reg }
MOV DX, $3CE
MOV AL, 5
OUT DX, AL
MOV DX, $3CF
MOV AL, $10
OUT DX, AL
{ Set Misc. Reg }
MOV DX, $3CE
MOV AL, 6
OUT DX, AL
MOV DX, $3CF
MOV AL, 14
OUT DX, AL
End;
Procedure MakeFontDefTable;
Var CounterX,
CounterY : Word;
Begin
SetAccessToFontMemory;
For CounterY := 0 to 255 do
For CounterX := 0 to 31 do
FontDef[CounterY, CounterX] :=
MEM[$B800:(CounterY * 32)+CounterX];
SetAccessToTextMemory;
End;
Procedure ClearSecondFontMemory;
Var Counter : Word;
Begin
SetAccessToFontMemory;
For Counter := 0 to 32 * 256 do
MEM[$B800:$4000 + Counter] := 0;
SetAccessToTextMemory;
End;
Procedure ScrollMessage;
Const CharCol : Integer = 8;
Counter : Byte = 1;
COUNTERY : Byte = 0;
PWRTbl : Array [0..7] of Byte = (1,2,4,8,16,32,64,128);
Begin
SetAccessToFontMemory;
ASM
{ Wait For Retrace }
MOV DX, $3DA
@RT:
IN AL, DX
TEST AL, 8
JZ @RT
{ Scroll Text One Pixel To The Left }
MOV AX, $B800 + ($4000 / 16)
MOV ES, AX
MOV CX, 32
@Row:
MOV DI, (79 * 32) - 1
ADD DI, CX
SHL byte ptr ES:[DI], 1
PUSHF
SUB DI, 32
POPF
PUSH CX
MOV CX, 79
@Chrs:
RCL byte ptr ES:[DI], 1
PUSHF
SUB DI, 32
POPF
Loop @Chrs
POP CX
Loop @Row
END;
If CharCol < 0
Then
Begin
CharCol := 7;
Inc(Counter);
End
Else
Dec(CharCol);
If Counter > Length(ScrollText)
Then
Counter := 1;
{ Write New Column Of Pixels }
For CounterY := 0 to 31 do
MEM[$B800:$4000 + (79 * 32) + CounterY] :=
MEM[$B800:$4000 + (79 * 32) + CounterY] OR
((FontDef[Ord(ScrollText[Counter]), CounterY] AND PwrTbl[CharCol])
SHR CharCol);
SetAccessToTextMemory;
End;
Procedure TurnCursorOff; Assembler;
ASM
MOV DX, $3D4
MOV AL, $0A
OUT DX, AL
MOV DX, $3D5
IN AL, DX
OR AL, 32
OUT DX, AL
End;
Procedure TurnCursorOn; Assembler;
ASM
MOV DX, $3D4
MOV AL, $0A
OUT DX, AL
MOV DX, $3D5
IN AL, DX
AND AL, Not(32)
OUT DX, AL
End;
Begin
TextMode (C80);
TurnCursorOff;
SetCharWidthTo8;
MakeFontDefTable;
ClearSecondFontMemory;
TextColor(Red);
ClrScr;
ScrollText := 'This program is one example of how a smooth '+
'scroll can be done in text mode. ';
WriteScrollTextCharacters(10);
TextColor(Blue);
GoToXY (26,10);
Write ('Text Mode Smooth Scroll Example');
GoToXY (34,11);
Write ('By David Dahl');
FlushKeyBoardBuffer;
Repeat
ScrollMessage;
Until Keypressed;
FlushKeyboardBuffer;
TextMode (C80);
TurnCursorOn;
End.
[Back to SCROLL SWAG index] [Back to Main SWAG index] [Original]