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	dword
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
sted;  FORMAT does all kinds of things.  I understand
that this problem also affects DISKCOPY.