; This program is to control Cyrix's Cx486SLC/DLC internal cache.
; This program should be used for chip evaluation use only.
; If you want to use this program with '-e' option, be sure that
; all required hardware modification had been done.
; This program could not run on the DOS running under MS-Windows,
; for it accesses CR0 to cause previlage violation.
; For more information about Cx486SLC/DLC internal cache control,
; see Cyrix's Cx486SLC/DLC data book and application note volume 1.
;
; Contents of makefile is shown below.
;
; cx486cc.com : cx486cc.obj
; tlink /t /x cx486cc.obj
;
; cx486cc.obj : cx486cc.asm
; tasm /m10 /z /zi /l cx486cc.asm
;
TRUE equ 1
FALSE equ 0
CR equ 0dh
LF equ 0ah
BEL equ 07h
TAB equ 09h
SPC equ 20h
MSEOF equ 1ah
I86 equ 00h
I186 equ 01h
I286 equ 02h
I386 equ 03h
I486 equ 04h
X486 equ 05h
V30 equ 06h
V33 equ 07h
BARB equ 20h
NEC98 equ FALSE
DEBUG equ FALSE
DUMPA equ FALSE
DISABLE_CACHE macro
mov eax, cr0
or eax, 40000000h
mov cr0, eax
INVD ;flash cache
endm
ENABLE_CACHE macro
mov ebx, cr0
and ebx, 9fffffffh
mov cr0, ebx
endm
EXIT macro
mov ah, 04ch
mov al, byte ptr cpu_type
int 21h
endm
;input dx:offset to message
PUTSTR macro
mov ah, 09h
int 21h
endm
;dx --- offset to message
PUTS macro msg
mov ah, 09h
mov dx, offset msg
int 21h
endm
.486P
CODE SEGMENT USE16
ASSUME CS:CODE,DS:CODE
ORG 0100H
start:
db "-Cx486CC-",MSEOF,'$'
mov ax, cs
mov ds, ax
mov es, ax
cld
call check_cpu
mov byte ptr cpu_type, al
call disp_cpu
mov al, byte ptr cpu_type
cmp al, X486
je get_argc
jmp not_cyrix
get_argc:
mov si, 80h
lodsb
cmp al, 0
je help
check_option:
lodsb
cmp al,'/' ; option flag
je check_option_parameter
cmp al,'-' ; option flag
je check_option_parameter
cmp al, SPC
je check_option
cmp al, TAB
je check_option
jmp help
check_option_parameter:
mov al, byte ptr ds:[si]
call tolower
cmp al, 'f'
je enable_f
cmp al, 'e'
je enable
cmp al, 'd'
je disable
cmp al, 'v'
je dump
jmp help
not_cyrix:
PUTS helpmsg
EXIT
help:
PUTS helpmsg
PUTS usage
EXIT
enable_f:
mov ax, word ptr ccregs
or ah, BARB ;set BARB bit
mov word ptr ccregs, ax
enable:
mov cx, 14
mov si, offset ccregs
mov dx, 23h
cli ;mask off external interrupts
DISABLE_CACHE
enable_loop:
lodsb
out 22h, al
outsb
loop enable_loop
ENABLE_CACHE
sti
PUTS enable_msg
EXIT
disable:
cli
DISABLE_CACHE
sti
PUTS disable_msg
EXIT
dump:
mov di, offset work
mov si, offset ccregs
call get_ccr
mov si, offset work
call dmp_ccr
if DEBUG
cli
mov ebx, cr0
sti
call dump_32
endif
EXIT
;input si:buffer
dmp_ccr proc
if DUMPA
mov di, offset ccrdmp
mov cx, 14
dump_loop:
lodsb
call b2hexasc
stosw
loop dump_loop
PUTS ccrdmpr
PUTS ccrdmp
else
PUTS ccr0_bit
mov bl, [si]
inc si
push si
mov cx, 8
mov si, offset ccr0_bit_table
ccr_loop0:
mov al, bl
and al, 01h
add al, '0'
mov dx, [si]
mov di, dx
mov byte ptr [di + 5], al
PUTSTR
inc si
inc si
shr bl, 1
loop ccr_loop0
pop si
;ccr1
PUTS ccr1_bit
lodsb
and al, 01h
add al, '0'
mov di, offset ccr1_bits
mov byte ptr [di + 5], al
PUTS ccr1_bits
mov cx, 4
ncr_reg_dmp_loop:
push cx
PUTS ccr_reg_dmp
mov cx, 3
mov di, offset ncr_address
ncr_reg_loop:
lodsb
call b2hexasc
stosw
loop ncr_reg_loop
mov byte ptr [di - 1], '0'
PUTS ncr_address
dec si
xor ax, ax
lodsb
and al, 0fh
push si
mov si, offset size_table
xor ah, ah
mov bx, ax
mov al, [si + bx]
add ax, si
mov dx, ax
PUTSTR
PUTS size_byte
pop si
pop cx
inc byte ptr ccr_reg_num
loop ncr_reg_dmp_loop
endif
ret
ccrdmpr db "c0c1c4c5c6c7c8c9cAcBcCcDcEcF",CR,LF,'$'
ccrdmp db " ",CR,LF,'$'
ccr_reg_dmp db "Non-cacheable region "
ccr_reg_num db "0 starting address :$"
ncr_address db "xxxxxx00 Size:$"
size_table db size0 - size_table, size1 - size_table
db size2 - size_table, size3 - size_table
db size4 - size_table, size5 - size_table
db size6 - size_table, size7 - size_table
db size8 - size_table, size9 - size_table
db sizeA - size_table, sizeB - size_table
db sizeC - size_table, sizeD - size_table
db sizeE - size_table, sizeF - size_table
size0 db "0$"
size1 db "4K$"
size2 db "8K$"
size3 db "16K$"
size4 db "32K$"
size5 db "64K$"
size6 db "128K$"
size7 db "256K$"
size8 db "512K$"
size9 db "1M$"
sizeA db "2M$"
sizeB db "4M$"
sizeC db "8M$"
sizeD db "16M$"
sizeE db "32M$"
sizeF db "4G$"
size_byte db "byte",CR,LF,'$'
ccr0_bit db "Cache Configuration Register 0 (C0h)",CR,LF,'$'
ccr1_bit db "Cache Configuration Register 1 (C1h)",CR,LF,'$'
ccr1_bits db "bit0= : RPL 1:enables RPLSET, /RPLVAL output "
db "pins",CR,LF
db "bit[1..7] reserved.",CR,LF,'$'
ccr0_bit_table dw ccr_bit0, ccr_bit1, ccr_bit2, ccr_bit3
dw ccr_bit4, ccr_bit5, ccr_bit6, ccr_bit7
ccr_bit0 db "bit0= : NC0 1:sets the first 64KB at each 1MB "
db "boundary as non-cacheable",CR,LF,'$'
ccr_bit1 db "bit1= : NC1 1:sets 640KB to 1MB region as "
db "non-cacheable",CR,LF,'$'
ccr_bit2 db "bit2= : A20M 1:enables /A20M input pin",CR,LF,'$'
ccr_bit3 db "bit3= : KEN 1:enables /KEN input pin",CR,LF,'$'
ccr_bit4 db "bit4= : FLUSH 1:enables /FLUSH input pin",CR,LF,'$'
ccr_bit5 db "bit5= : BARB 1:enables flushing of internal cache "
db "when hold state is entered",CR,LF,'$'
ccr_bit6 db "bit6= : CO Selects cache organization. "
db "0:2 way set associative 1:direct mapped",CR,LF,'$'
ccr_bit7 db "bit7= : SUSPEND 1:enables /SUSP input and "
db "/SUSPA output pins",CR,LF,'$'
endp
;input di:buffer
get_ccr proc
mov dx, 23h
mov cx, 14
cli
ccrread_loop:
lodsw
out 22h, al
insb
loop ccrread_loop
sti
ret
endp
if DEBUG
;input ebx
dump_32 proc
cld
mov di, offset dump_buffer + 4
mov cx, 4
dump_32_loop:
rol ebx, 8
mov eax, ebx
call b2hexasc
stosw
loop dump_32_loop
PUTS dump_buffer
ret
dump_buffer db "cr0: h",CR,LF,'$'
endp
endif
;input al
;outpu ax
b2hexasc proc near
mov ah, al
shr al, 4
and al, 0fh
cmp al, 09
ja b2hexasc_1
add al, 30h
jmp b2hexasc_2
b2hexasc_1:
add al, 37h
b2hexasc_2:
and ah, 0fh
cmp ah, 09
ja b2hexasc_3
add ah, 30h
jmp b2hexasc_4
b2hexasc_3:
add ah, 37h
b2hexasc_4:
ret
endp
tolower proc
cmp al,'A'
jb exit_tolower
cmp al,'Z'
ja exit_tolower
add al,' '
exit_tolower:
ret
endp
check_cpu proc
test_8086:
mov cl, 33
mov al, 1
shl al, cl
or al, al
jnz test_186
test_v30:
mov ax, sp
pusha ;pusha valid?
nop
nop
nop
nop
nop
cmp ax, sp
je i8086
popa
test_v33:
mov ax, 0100h
aad 0h
jz nec_v33
jmp nec_v3020
test_186:
pushf
pop ax
test ax, 08000h
jnz i80186
test_286:
or ax, 04000h
push ax
popf
pushf
pop ax
test ax, 04000h
jz i80286
test_386:
pushfd
pop eax
bts eax, 18
push eax
popfd
pushfd
pop eax
bt eax, 18
jnc i80386
test_Cx486:
mov al, 08h
add al, 08h
and al, 00h
daa
cmp al, 06h
je Cx486
; jmp i80486 ;otherwise i486
i80486:
mov al, I486
ret
i80386:
mov al, I386
ret
i80286:
mov al, I286
ret
i80186:
mov al, I186
ret
i8086:
mov al, I86
ret
nec_v3020:
mov al, V30
ret
nec_v33:
mov al, V33
ret
Cx486:
mov al, X486
ret
endp
;input al:cpu type
;output dx:offset to string
disp_cpu proc
mov si, offset cpu_table
xor ah, ah
mov bx, ax
mov al, [si + bx]
add ax, si
mov dx, ax
PUTSTR
PUTS cpu_det
ret
cpu_table db cpu86 - cpu_table
db cpu186 - cpu_table
db cpu286 - cpu_table
db cpu386 - cpu_table
db cpu486 - cpu_table
db cpx486 - cpu_table
db cpv30 - cpu_table
cpu86 db "i8086$"
cpu186 db "i186$"
cpu286 db "i286$"
cpu386 db "i386$"
cpu486 db "i486$"
cpx486 db "Cx486$"
cpv30 db "V30$"
cpv33 db "V33$"
cpu_det db " microprocessor detected.",CR,LF,'$'
endp
cpu_type db 0
work db " $"
ccregs dw 010c0h,000c1h
if NEC98
dw 000c4h,00ac5h,006c6h ;a0000-c0000, 128kb VRAM
dw 000c7h,00cc8h,006c9h ;c0000-e0000, 128kb ROM/EMS
dw 000cah,00ecbh,004cch ;e0000-e8000, 32kb VRAM
dw 000cdh,00eceh,084cfh ;e8000-f0000, 32kb ROM/EMS
else
dw 000c4h,00ac5h,006c6h ;a0000-c0000, 128kb Video
dw 000c7h,00cc8h,004c9h ;c0000-c8000, 32kb
dw 000cah,00ccbh,083cch ;c8000-cc000, 16kb
dw 000cdh,00eceh,005cfh ;e0000-f0000, 64kb
endif
helpmsg db "Cx486SLC/DLC cache control program ver. 1.51 for "
if NEC98
db "NEC-98"
else
db "IBM-PC/AT"
endif
db " programed by HOS",CR,LF,'$'
usage db "Usage:Cx486CC -option",CR,LF
db "options: e:enable cache.",CR,LF
db " f:enable cache.(flush on hold)",CR,LF
db " d:disable cache.",CR,LF
db " v:view internal cache control registers."
db CR,LF,'$'
disable_msg db "Internal cache disabled.",CR,LF,'$'
enable_msg db "Internal cache enabled.",CR,LF,'$'
CODE ENDS
END START
;Technical note
;
;CCR0 (C0h)
;bit0 : NC0 1:sets the first 64KB at each 1MB boundary as non-cacheable
;bit1 : NC1 1:sets 640KB to 1MB region as non-cacheable
;bit2 : A20M 1:enables /A20M input pin
;bit3 : KEN 1:enables /KEN input pin
;bit4 : FLUSH 1:enables /FLUSH input pin
;bit5 : BARB 1:enables flushing of internal cache when hold state is entered
;bit6 : CO Selects cache organization. 0:2 way set associative 1:direct mapped
;bit7 : SUSPEND 1:enables /SUSP input and /SUSPA output pins
;
;CCR1 (C1h)
;bit0 : RPL 1:enables RPLSET, /RPLVAL output pins.
;bit1..7 : reserved.
;
;Size (bit[0..3] of c6,c9,cc,cf)
; 0:disabled 8:512KB
; 1:4KB 9:1MB
; 2:8KB A:2MB
; 3:16KB B:4MB
; 4:32KB C:8MB
; 5:64KB D:16MB
; 6:128KB E:32MB
; 7:256KB F:4GB