Metropoli BBS
VIEWER: scrl.asm MODE: TEXT (ASCII)
;=============================================================================
; scrl.asm - Simple Horizontal Scroller.
;                                                   File created: 11/21/93
; Copyright (c) 1993, Carlos Hasan                 Last modified: 11/21/93
;
; Description:
;  Just a simple scroller in VGA ModeX and an external proportional
; font file in VLA chars format. Mainly based on VLA scrollers.
;
; Dependency:
;  Requires Turbo Assembler 3.2 or later to be assembled.
;  Dependant on the IBM PC 286 or better processor.
;=============================================================================

        ideal
        model   small,pascal
        jumps
        p286

        dosseg
        stack   1024
	ends

IFDEF LinkFont
        global  FontFAR:byte            ; SCRL.FNT linked file.
ENDIF

;=========================== VLA Font Header =================================

struc   FontHeader
  Magic   db   "VGACH"                  ; Font Signature
  First   db   ?                        ; First Char
  Width   db   ?                        ; Font Width
  Height  db   ?                        ; Font Height
  Total   db   ?                        ; Number of Chars
ends    FontHeader

;=========================== Data Segment ====================================

        dataseg

SCREENWIDTH     equ  (2*320+8)          ; Logical Screen Width
                                        ; Enough Space for Double-Window
                                        ; and the working hidden area
SCROLLROW       equ  180                ; Scroller Window Start Row.

WinOffs         dw   ?                  ; Window Offset
CharOffs        dw   ?                  ; Char BitMap Offset
MesgOffs        dw   ?                  ; Ascii-Message Offset
FontHead        FontHeader ?            ; Font Header
CharColumn      db   ?                  ; Cur Char Column
FontFirst       db   ?                  ; Font First Char
FontWidth       db   ?                  ; Font Max Width
FontHeight      db   ?                  ; Font Height
FontDataOfs     dw   ?                  ; Font Data Offset
FontDataSeg     dw   ?                  ; Font Data Segment
FontWidths      db   256 dup(?)         ; Font Width Table
FontSize        dw   ?                  ; Font Char Size (Width*Height)

IFNDEF LinkFont
FontFileName    db   "SCRL.FNT",0       ; Font File Name
ENDIF

TheMessage      db   " ... Hello out there ... "
		db   "                        "
		db   " ... I am PELUSA from Chile ... "
		db   "                        "
		db   " ... Just a simple scroller... "
		db   "                        "
		db   " ... only useful to say that it's the FAKE demo ... "
		db   "                        "
		db   " ... you probably could have guessed that ... "
		db   "                        "
		db   " ... I hate scrollers because i have nothing to say..."
		db   "                        "
		db   " ... now enjoy the rest of this LAME thing ... "
		db   "                                    ",0

        codeseg

;-----------------------------------------------------------------------------
; SetModeX - Sets the VGA in Tweaked ModeX 320x400x256.
;-----------------------------------------------------------------------------

proc    SetModeX
        mov     ax,0013h                ; Sets VGA linear 320x200x256
        int     10h
        mov     dx,3C4h                 ; Disable Chain-Four
        mov     ax,0604h
        out     dx,ax
        mov     dx,3C4h                 ; Enable Write to All Four Planes
        mov     ax,0F02h
        out     dx,ax
        mov     ax,0A000h               ; Clear Display Memory
        mov     es,ax
        xor     di,di
        xor     ax,ax
        mov     cx,8000h
        cld
        rep     stosw
        mov     dx,3D4h                 ; Reprogram CRT Controller:
        mov     ax,00014h               ; turn off dword mode
        out     dx,ax
        mov     ax,0e317h               ; turn on byte mode
        out     dx,ax
        mov     ax,00009h               ; cell height
        out     dx,ax
        mov     dx,3D4h                 ; Sets Logical Screen Width
        mov     al,13h
        mov     ah,SCREENWIDTH/8
        out     dx,ax
        ret
endp    SetModeX

;-----------------------------------------------------------------------------
; WaitVR - Waits the Next VGA Vertical Retrace Ending.
;-----------------------------------------------------------------------------

proc    WaitVR
        mov     dx,3DAh
WaitStartVR:
        in      al,dx
        test    al,8
        je      WaitStartVR
WaitEndVR:
        in      al,dx
        test    al,8
        jne     WaitEndVR
        ret
endp    WaitVR

;-----------------------------------------------------------------------------
; InitScroll - Initializes the Scroller Variables.
; Out:
;  CF=1 if function was not successful.
;  CF=0 if function was successful.
;-----------------------------------------------------------------------------

proc    InitScroll
        mov     [WinOffs],0             ; Start Window Column
        mov     [CharColumn],0          ; Start with a ZeroWidth Char
        mov     [CharOffs],0            ; ZeroWidth Char BitMap Address
        lea     ax,[TheMessage]         ; Sets Message Address
        mov     [MesgOffs],ax
        call    LoadFont                ; Load Font Data
        ret
endp    InitScroll

;-----------------------------------------------------------------------------
; DoneScroll - Done Scroller Variables.
;-----------------------------------------------------------------------------

proc    DoneScroll
IFNDEF LinkFont
        mov     es,[FontDataSeg]        ; Free Font Data Segment
        mov     ah,49h
        int     21h
ENDIF
        ret
endp    DoneScroll

;-----------------------------------------------------------------------------
; LoadFont - Loads a New VGA Font.
; Out:
;  CF=1 if function was not successful.
;  CF=0 if function was successful.
;-----------------------------------------------------------------------------

proc    LoadFont

IFDEF LinkFont
        mov     ax,SEG FontFAR          ; Load Font File Address
        mov     es,ax
        mov     [FontDataSeg],ax
        mov     [FontDataOfs],Size FontHeader
        mov     al,[es:FontHeader.First] ; Get Font First Char
        mov     [FontFirst],al
        mov     al,[es:FontHeader.Width] ; Get Font Data Size
        mov     ah,[es:FontHeader.Height]
        mov     [FontWidth],al
        mov     [FontHeight],ah
        mul     ah
        mov     [FontSize],ax
        mov     dl,[es:FontHeader.Total]
        xor     dh,dh
        mul     dx
        add     ax,Size FontHeader      ; Copy Font Widths.
        mov     si,ax
        xor     di,di
        mov     cl,[es:FontHeader.Total]
        xor     ch,ch
CopyWidths:
        mov     al,[es:si]
        mov     [FontWidths+di],al
        inc     si
        inc     di
        loop    CopyWidths
ELSE
        mov     [FontDataSeg],0
        mov     ax,3D00h                ; Open Font File
        lea     dx,[FontFileName]
        int     21h
        jc      LoadFontExit
        mov     bx,ax
        mov     ah,3Fh                  ; Read Font Header
        lea     dx,[FontHead]
        mov     cx,Size FontHeader
        int     21h
        jc      LoadFontExit
        mov     al,[FontHead.First]     ; Get Font First Char
        mov     [FontFirst],al
        mov     al,[FontHead.Width]     ; Get Font Data Size
        mov     ah,[FontHead.Height]
        mov     [FontWidth],al
        mov     [FontHeight],ah
        mul     ah
        mov     [FontSize],ax
        mov     dl,[FontHead.Total]
        xor     dh,dh
        mul     dx
        push    ax
        push    bx                      ; Alloc Space for Font Data
        mov     bx,ax
        shr     bx,4
        inc     bx
        mov     ah,48h
        int     21h
        pop     bx
        pop     cx
        jc      LoadFontExit
        push    ds                      ; Read Font Data
        mov     [FontDataSeg],ax
        mov     [FontDataOfs],0
        mov     ds,ax
        xor     dx,dx
        mov     ah,3Fh
        int     21h
        pop     ds
        jc      LoadFontExit
        lea     dx,[FontWidths]         ; Read Font Widths
        mov     cl,[FontHead.Total]
        xor     ch,ch
        mov     ah,3Fh
        int     21h
        jc      LoadFontExit
        mov     ah,3Eh                  ; Close Font File
        int     21h
ENDIF
LoadFontExit:
        ret
endp    LoadFont

;-----------------------------------------------------------------------------
; DrawScroll - Polls the Horizontal Scroller.
; Out:
;  CF=1 If no more scroll message.
;  CF=0 If more scroll message.
;-----------------------------------------------------------------------------

proc    DrawScroll
        mov     bx,[WinOffs]            ; Loads Window Offset
        add     bx,2
        mov     dx,3D4h                 ; Sets VGA Start Address
        mov     al,0Dh
        mov     ah,bl
        out     dx,ax
        dec     al
        mov     ah,bh
        out     dx,ax
        sub     [CharColumn],4          ; Advance 4 pixels
        jg      NoNewChar               ; Need a New Char?
        call    GetsNewChar             ; Yes, Draw a New Char
        jc      DrawScrollExit
NoNewChar:
        mov     ax,0A000h               ; Loads Display Memory Segment
        mov     es,ax
        mov     bl,[FontWidth]          ; Loads Font Width and Height
        mov     cl,[FontHeight]
        xor     bh,bh
        xor     ch,ch
        mov     bp,SCREENWIDTH/4        ; Loads Logical Screen Width

        mov     dx,3C4h                 ; Enable Write to Plane 1
        mov     ax,0102h
        out     dx,ax
        mov     si,[CharOffs]           ; Loads Char BitMap Address
        mov     di,[WinOffs]            ; Loads VGA Window Dest Address
        add     di,SCROLLROW*SCREENWIDTH/4
        push    cx
        push    ds
        mov     ds,[FontDataSeg]
DrawCharColumn1:
        mov     al,[ds:si]
        mov     [es:di],al
        mov     [es:di+SCREENWIDTH/8],al
        add     si,bx
        add     di,bp
        loop    DrawCharColumn1
        pop     ds
        pop     cx

        mov     dx,3C4h                 ; Enable Write to Plane 2
        mov     ax,0202h
        out     dx,ax
        mov     si,[CharOffs]           ; Loads Char BitMap Address
        mov     di,[WinOffs]            ; Loads VGA Window Dest Address
        inc     si
        add     di,SCROLLROW*SCREENWIDTH/4
        push    cx
        push    ds
        mov     ds,[FontDataSeg]
DrawCharColumn2:
        mov     al,[ds:si]
        mov     [es:di],al
        mov     [es:di+SCREENWIDTH/8],al
        add     si,bx
        add     di,bp
        loop    DrawCharColumn2
        pop     ds
        pop     cx

        mov     dx,3C4h                 ; Enable Write to Plane 3
        mov     ax,0402h
        out     dx,ax
        mov     si,[CharOffs]           ; Loads Char BitMap Address
        mov     di,[WinOffs]            ; Loads VGA Window Dest Address
        add     si,2
        add     di,SCROLLROW*SCREENWIDTH/4
        push    cx
        push    ds
        mov     ds,[FontDataSeg]
DrawCharColumn3:
        mov     al,[ds:si]
        mov     [es:di],al
        mov     [es:di+SCREENWIDTH/8],al
        add     si,bx
        add     di,bp
        loop    DrawCharColumn3
        pop     ds
        pop     cx

        mov     dx,3C4h                 ; Enable Write to Plane 4
        mov     ax,0802h
        out     dx,ax
        mov     si,[CharOffs]           ; Loads Char BitMap Address
        mov     di,[WinOffs]            ; Loads VGA Window Dest Address
        add     si,3
        add     di,SCROLLROW*SCREENWIDTH/4
        push    cx
        push    ds
        mov     ds,[FontDataSeg]
DrawCharColumn4:
        mov     al,[ds:si]
        mov     [es:di],al
        mov     [es:di+SCREENWIDTH/8],al
        add     si,bx
        add     di,bp
        loop    DrawCharColumn4
        pop     ds
        pop     cx

        inc     [WinOffs]               ; Advance Window by 4 pixels
        cmp     [WinOffs],SCREENWIDTH/8
        jb      DontWrapWindow
        mov     [WinOffs],0
DontWrapWindow:
        add     [CharOffs],4            ; Advance Char Column by 4
        clc
DrawScrollExit:
        ret
endp    DrawScroll

;-----------------------------------------------------------------------------
; GetsNewChar - Gets the next message Character.
; Out:
;  CF=1 If no more characters
;  CF=0 If more characters
;-----------------------------------------------------------------------------

proc    GetsNewChar
        mov     si,[MesgOffs]           ; Loads the Message Offset
GetCharLoop:
        lodsb                           ; Gets the Character
        test    al,al                   ; if End of Message ReStart
        jne     DrawCharNow
        stc
        jmp     GetsNewCharExit
DrawCharNow:
        mov     [MesgOffs],si           ; Save Message Offset
        sub     al,[FontFirst]          ; Compute the Char BitMap Address
        xor     ah,ah
        mov     bx,ax
        mov     dx,[FontSize]
        mul     dx
        add     ax,[FontDataOfs]
        mov     [CharOffs],ax
        mov     al,[FontWidths+bx]      ; Set the Char Width
        mov     [CharColumn],al
        clc
GetsNewCharExit:
        ret
endp    GetsNewChar


;-----------------------------------------------------------------------------
; Start - Start the Demostration. Called from DOS.
;-----------------------------------------------------------------------------

proc    Start
        mov     ax,@Data                ; Sets Data Segment.
        mov     ds,ax
        mov     bx,sp                   ; Shrink Program Memory Block.
        shr     bx,4
        inc     bx
        mov     ax,ss
        mov     dx,es
        sub     ax,dx
        add     bx,ax
        mov     ah,4Ah
        int     21h
        call    SetModeX                ; Sets VGA ModeX.
        call    InitScroll              ; Init Scroller.
        jc      DemoExit
        cld
DemoLoop:
        call    WaitVR                  ; Waits Vertical Retrace.
        call    DrawScroll              ; Draw the Scroller.
        jc      DemoBreak
        mov     ah,1                    ; Any Key Pressed?
        int     16h                     ; No, Loop.
        je      DemoLoop
DemoBreak:
        call    DoneScroll              ; Done Scroller.
DemoExit:
        mov     ax,0003h                ; Set Text Mode.
        int     10h
        mov     ax,4C00h                ; Exit to DOS.
        int     21h
endp    Start

        end     Start
[ RETURN TO DIRECTORY ]