; Attribute Controller register operations
;
; int char ACread_reg(int register_number);
; void ACset_reg(int register_number, int value);
; void ACset_regm(int reg_num, int value,
; int mask);
; reg(reg_num)= (!mask & reg(reg_num)) | (mask & value);
;
BMASK EQU [BP+0ah]
VALUE EQU [BP+8]
REGNO EQU [BP+6]
;
AC_TEXT SEGMENT word public 'CODE'
ASSUME cs:AC_TEXT, ds:NOTHING
PUBLIC _ACread_reg
PUBLIC _ACset_reg
PUBLIC _ACset_regm
_ACread_reg PROC far
push bp
mov bp,sp
mov ax,40h
mov es,ax
mov dx,es:[63h]
add dl,6 ; get register address
cli
in al,dx ;reset 3c0 flip/flop
push dx
mov dl,0c0h
mov al,REGNO ; palette register number
or al,20h ; don't disable display, we're just looking
out dx,al
xor ax,ax
inc dx
jmp $+2 ; waste a little more time
in al,dx
mov bl,al ; save return in bl for a moment
pop dx
in al,dx ;reset 3c0 flip/flop
mov dl,0c0h
mov al,20h
out dx,al ; return 3c0 to the way we left it
sti
xor ah,ah
mov al,bl ; place return value in al
pop bp
ret ; return to C
_ACread_reg ENDP
_ACset_reg PROC far
push bp
mov bp,sp
mov ax,40h
mov es,ax
mov dx,es:[63h]
add dl,6 ;dx=0x03da (color) 0x03ba (mono)
mov bl,VALUE ; save value in a register
push dx ; save flip/flop reset location
cli
in al,dx ;reset 3c0 flip/flop
mov dl,0c0h ; dx=0x03c0
mov al,REGNO
cmp al,10h
jb outind ; if a palette register,
; disable display
or al,20h ; else don't disable display
outind: out dx,al ; output index to 0x3c0
mov al,bl
jmp $+2 ; waste a little more time
out dx,al ; out(0x3c0,VALUE)
pop dx
in al,dx ;reset 3c0 flip/flop
mov dl,0c0h
mov al,20h
out dx,al ; reenable screen
sti
xor ax,ax
pop bp
ret ; return to C
_ACset_reg ENDP
_ACset_regm PROC far
push bp
mov bp,sp
mov dl,REGNO
push dx
call _ACread_reg ; returns al=reg(reg_num);
add sp,2
mov bl,BMASK
not bl ; !mask
and al,bl ; al=(!mask®(reg_num));
mov cl,al ; save for a microsecond
mov al,VALUE
mov bl,BMASK
and al,bl
or al,cl
push ax
mov al,REGNO
push ax
call _ACset_reg
add sp,4
xor ax,ax
pop bp
ret
_ACset_regm ENDP
AC_TEXT ENDS
END