Rocksolid Light

Welcome to novaBBS (click a section below)

mail  files  register  nodelist  faq  login

"Besides, I think [Slackware] sounds better than 'Microsoft,' don't you?" (By Patrick Volkerding)


programming / alt.lang.asm / A20 device driver

SubjectAuthor
o A20 device driverT. Ment

1
Subject: A20 device driver
From: T. Ment
Newsgroups: comp.os.msdos.programmer, alt.lang.asm
Organization: A noiseless patient Spider
Date: Mon, 24 Feb 2020 06:12 UTC
Path: i2pn2.org!i2pn.org!eternal-september.org!feeder.eternal-september.org!reader01.eternal-september.org!.POSTED!not-for-mail
From: t.m...@protocol.invalid (T. Ment)
Newsgroups: comp.os.msdos.programmer,alt.lang.asm
Subject: A20 device driver
Date: Mon, 24 Feb 2020 06:12:23 +0000
Organization: A noiseless patient Spider
Lines: 204
Message-ID: <1eo65fl7caqtivvluh3058hfdhbai7i0qi@4ax.com>
Mime-Version: 1.0
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit
Injection-Info: reader02.eternal-september.org; posting-host="56f5c5d49f1c9db523add63a595ea2e4";
logging-data="7984"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX19lVeImza01CZwIPoIZaw+g1SVFfMXyFhQ="
Cancel-Lock: sha1:F8Lbmke0cOXOsYMxBcWs3YJSrJE=
X-Newsreader: Forte Agent 1.93/32.576 English (American)
View all headers
I have a computer where BIOS enables A20 by default, with no option to
disable it. It's not a recent CPU without an A20 pin, it's an older one
and I want to disable A20. It affects Jack's XMGR.SYS, which won't take
control of A20 if it's already on.

So I wrote a device driver to disable A20. It does its work, prints a
message, and vanishes from memory and the driver chain.

The method for detecting the state of A20 is taken from Frank Gilluwe's
Undocumented PC 1st edition, page 270. I like his method, but his code
is incomplete. You must compare the 0:0 word vs. the ffff:10 word twice,
both before and after the NOT, to make sure the two words are not equal
by random chance when the A20 line is on.

I built the driver with MASM 5.10B. Maybe 4.0 works too.



page 255, 132
title A20 device driver

DATA equ 60h
COMMAND equ 64h
STATUS equ 64h

cseg segment para public 'code'
assume cs:cseg, ds:cseg, es:nothing, ss:nothing
begin:
dd -1 ; simple link
attribute db 80h ; character device
db 0
dw strategy ; address of 1st DOS call
dw interrupt ; address of 2nd DOS call
db 'A20$' ; driver name
db 4 dup (' ') ; filler

rh_off dw ? ; request header offset
rh_seg dw ? ; request header segment

bits db ?

mget db 'get ', '$'
mput db 'put ', '$'
m8042 db '8042 ', '$'

ma20 db 'A20 disable ', '$'

mwork db 'worked', '$'
mfail db 'failed', '$'
mhalt db ', reset or power cycle computer', '$'

mline db 0dh, 0ah, '$' ; newline

look proc near ; deduce A20 status
push ds
cli
xor ax, ax
mov ds, ax
dec ax
mov es, ax
mov ax, ds:0
mov bx, es:10h
cmp ax, bx
jne look1
not word ptr ds:0
mov ax, ds:0
mov bx, es:10h
not word ptr ds:0
cmp ax, bx
jne look1
clc ; A20 off
look0: sti
pop ds
ret
look1: stc ; A20 on
jmp look0
look endp

print proc near
mov ah, 9
int 21h
ret
print endp

get proc near ; 8042 keyboard controller
xor cx, cx
get0: in al, STATUS
test al, 1
jnz get1
loop get0
lea dx, mget
call print
jmp short e8042
get1: in al, DATA
ret
get endp

put proc near ; 8042 keyboard controller
xor cx, cx
put0: in al, STATUS
test al, 2
jz put1
loop put0
lea dx, mput
call print
jmp short e8042
put1: mov al, bl
out dx, al
ret
put endp

disable proc near ; A20
cli
mov bl, 0adh ; disable keyboard
mov dx, COMMAND
call put
mov bl, 0a7h ; disable mouse
mov dx, COMMAND
call put
in al, DATA ; flush kc output buffer
mov bl, 0d0h ; read port 2 control bits
mov dx, COMMAND
call put
call get ; clear A20 bit
and al, 0fdh
mov bits, al
mov bl, 0d1h ; write port 2 control bits
mov dx, COMMAND
call put
mov bl, bits
mov dx, DATA
call put
mov bl, 0AEh ; enable keyboard
mov dx, COMMAND
call put
mov bl, 0A8h ; enable mouse
mov dx, COMMAND
call put
sti
ret
disable endp

e8042: lea dx, m8042 ; 8042 error, report and freeze
call print
lea dx, mfail
call print
lea dx, mhalt
call print
lea dx, mline
call print
cli
hlt

interrupt proc far ; second call from DOS
pushf
push ax
push bx
push cx
push dx
push ds
push es
push cs
pop ds
call look ; A20 state cf 0=off 1=on
jnc exit ; A20 off, no need to disable
call disable
lea dx, ma20
call print
call look
jc fail ; A20 disable failed
lea dx, mwork
jmp short mtail
fail: lea dx, mfail
mtail: call print ; message tail
lea dx, mline
call print
inc dx
call print
exit: mov attribute, 0 ; device type (become block)
mov bx, rh_off ; load request header address
mov ds, rh_seg ; use ds to avoid es: overrides
mov word ptr 3[bx], 100h ; status (done)
mov byte ptr 0dh[bx], 0 ; number of units
mov word ptr 0eh[bx], 0 ; self offset
mov 10h[bx], cs ; self segment
pop es
pop ds
pop dx
pop cx
pop bx
pop ax
popf
ret
interrupt endp

strategy proc far ; first call from DOS
mov cs: rh_off, bx ; save request header address
mov cs: rh_seg, es
ret
strategy endp

cseg ends
end begin



1
rocksolid light 0.7.2
clearneti2ptor