16-Jul-86 14:08:30-PDT,9473;000000000001
Return-Path: <SY.FDC@CU20B.COLUMBIA.EDU>
Received: FROM CU20B.COLUMBIA.EDU BY B.ISI.EDU WITH TCP ; 16 Jul 86 14:04:53 PDT
Date: Wed 16 Jul 86 15:41:15-EDT
From: Frank da Cruz <SY.FDC@CU20B.COLUMBIA.EDU>
Subject: SCRNCOLR.ASM
To: info-ibmpc@B.ISI.EDU
Message-ID: <12223203329.166.SY.FDC@CU20B.COLUMBIA.EDU>

Here's a version of SCRNCOLR.ASM that, unlike the version in your library,
will assemble and run.

page    64,132
title   scrncolr - Change display screen from white to color attrib
.radix 10
;***************************************************************
; Adapted from "SCREEN.ASM" by H. Fischer - HFischer@eclb 12/83
; SCREEN was Typed in by Glass - gjg@cmu-cs-cad from Byte Nov. 1983
;
; NOTE: only meaningful with color card, and does not look at
;       keyboard (which makes it easywriter, etc. compatible)
;
;   To build this program:
;       1>  masm scrncolr;      /* assemble the code */
;       2>  link scrncolr;      /* link it - will get no stack seg. message */
;       3>  exe2bin scrncolr.exe scrncolr.com  /* make executable */
;       4>  del scrncolr.exe    /* don't need this anymore */
;
;  To use program:  run it or place in autoexec.bat as follows:
;
;               scrncolr nn rr
;
;                       where nn are screen attributes to replace
;                       normal white (attr=07h) video, and rr are
;                       attributes for reversed white (attr=70h)
;                       (intensity and blink are preserved).
;
;       for example, to change calls for white to white on blue
;       and to change calls for reverse white to magenta on white,
;       issue the call:  "scrncolr 17 75"
;
;  Only 80x25 screen calls are affected and only in text mode,
;       (this makes it LOGO and APL compatible)
;
;  COMMANDS:
;       none -- you reassemble to change the color assignment

;***************************************************************
;
;  Define interrupt vectors for
;       screen interrupt 10H, in segment 0.
;
;***************************************************************

scrvect segment at 0            ; define screen interrupt vector
        org     10h*4
SCRINT  label   word            ; fixed. was dword. [jrd]
scrvect ends

;***************************************************************
;
;       define constants
;
;***************************************************************

bw_val     equ  07h             ; standard b&w attibute sent to monitor

;***************************************************************
;
;       start code area
;
;***************************************************************

code    segment para
        assume  cs:code
        org     82h             ; parameters
PARM    label   word            ;    normal & rev attribs "nn rr"
        org     100h            ; start code offset 100h from starting segment
                                ; (this leaves room for DOS's work areas)

KEY     proc    far
START:
        ; Initialization code...used only once, on system startup

        jmp     init_code       ; call initialization routine
even
        validchk db 'FCP!'      ; used by INSTALL to check for valid SCREEN
                                ; program


;***************************************************************
;
;       SCR_RTNE - Replaces SCREEN interrupt so that it can intercept
;               B&W character writes and change attributes
;
;***************************************************************

SCR_RTNE:
        assume  ds:code
        sti
        push    ds              ; get cs into ds  the funny way
        push    cs
        pop     ds
        cmp     ah,0            ; Spot mode change call
        jne     NOT_MODE
        mov     savemod,al      ; Save mode input
NOT_MODE:
        cmp     ah,6            ; Spot SCROLL UP and SCROLL DOWN calls
        jl      NORMAL_SCR      ;
        push    ax              ; check if in 80x25 modes
        mov     al,savemod
        cmp     al,2
        pop     ax
        jl      NORMAL_SCR      ; no-ignore attribs (keep LOGO straight)
        push    ax              ; check if in 80x25 modes
        mov     al,savemod
        cmp     al,3
        pop     ax
        jg      NORMAL_SCR      ; no-ignore attribs (keep LOGO straight)

        cmp     ah,6
        jg      NOT_SCROLL      ;

SCROLL:
        call    GET_CH          ; for scrolling, update attribute
        jmp     NORMAL_SCR      ; now, execute scroll

NOT_SCROLL:
        cmp     ah,9            ; check for "WRITE ATTRIBUTE/CHAR" cmd
        jne     NORMAL_SCR      ; send out any other command as normal
        xchg    bh,bl           ; get attribute for command
        call    GET_CH          ; update attribute for command
        xchg    bh,bl           ; move attribute back to bh for cmd

NORMAL_SCR:
        pop     ds              ; restore ds reg

        ;
        ; NOTE: We are now ready to invoke the BIOS screen interrupt.
        ;       Since the ROM code includes an IRET interrupt return call,
        ;       all we need to do is to jump to the start of the ROM code
        ;       and all will be well.  Since the initialization code set
        ;       up the address to the screen interrupt code below, we can
        ;       set up a forced jump to that address.

JMP_SCR:                        ; Address to SCREEN interrupt
        db      0EAh            ; force a FAR JMP but do not set up dest-
        dw      0,0             ;   ination address at assembly time.
                                ;   (INIT routine will set this address)

savemod db      3               ;   default to 80x24 color mode

KEY endp                        ;done with main routine

;***************************************************************
;
;       GET_CH - subroutine replaces B&W character with current replacement
;                       attributes and allows for intensity bit setting
;
;               Inputs : bh contains attribute to be modified
;
;***************************************************************

GET_CH  proc    near
        mov     savech,bh       ; save character
        and     bh,77h          ; Remove intensity and blink bits
        cmp     bh,07h          ; see if currently defined B&W value
        jne     ISITREV         ; exit if not
        mov     bh,savech       ; otherwise, modify to current attribute
        and     bh,88h          ; get rid of B&W part
        or      bh,normvid      ; move in current attribute part
        jmp     OUT

ISITREV:
        cmp     bh,70h          ; see if currently defined W&B value
        mov     bh,savech       ; otherwise, modify to current attribute
        jne     OUT
        and     bh,88h
        or      bh,revrvid

OUT:
        ret                     ; done

savech  db      0               ; temporary character store
normvid db      05h             ; replacement for white norml video
revrvid db      50h             ; replacement for reverse white video
GET_CH  endp

LASTONE:        ; all code after this label is freed to DOS use after
                ; initialization of the program.


;***************************************************************
;
;       INIT_CODE - Code to load and initialize the SCREEN program..
;               sets up DOS to keep all code before "LASTONE" label
;               safe from overlaying during system operation.
;
;***************************************************************

INIT_CODE proc  near

        ; initialize SCREEN intercept code
        assume  es:scrvect              ;'vectors' is interrupt segment 0

        mov     ax,scrvect              ; get address to interrupt vector
        mov     es,ax                   ; save in es
        mov     ax,es:scrint            ; get address to interrupt
        mov     bx,offset jmp_scr+1     ; address to place to save vector
        mov     [bx],ax                 ; save interrupt address
        mov     ax,es:scrint[2]         ; get interrupt segment for rtne
        mov     [bx+2],ax               ; save it too
        mov     es:scrint,offset scr_rtne ; now replace with own address
        mov     ax,cs                   ; save segment in interrupt vector
        mov     es:scrint[2],ax         ;

        mov     ax,cs                   ; make parameters for color
        mov     ds,ax                   ;   addressable
        mov     dx,PARM
        test    dx,0040h                ; fix hex a-f
        jz      IT2
        sub     dx,0007h
IT2:    test    dx,4000h
        jz      IT3
        sub     dx,0700h
IT3:
        and     dx,0f0fh                ; strip and jamb nibbles
        mov     cl,4
        shl     dl,cl
        or      dh,dl
        mov     normvid,dh              ; save parameter
        mov     dx,PARM+3
        test    dx,0040h                ; fix hex a-f
        jz      IT4
        sub     dx,0007h
IT4:    test    dx,4000h
        jz      IT5
        sub     dx,0700h
IT5:
        and     dx,0f0fh
        mov     cl,4
        shl     dl,cl
        or      dh,dl
        mov     revrvid,dh


        mov     dx,offset lastone       ; save all code up to "LASTONE" label
        int     27h                     ; no return needed

INIT_CODE endp
code ends
end start
-------
