NETWORK - PKTD11B.ZIP - OCCUPIED.ASM

 
Output of file : OCCUPIED.ASM contained in archive : PKTD11B.ZIP

; Subroutine to check if an address range is available for allocation
; as shared memory.
; Input: bx = segment start address
; di = # of bytes / 16
; Returns with carry set if range is occupied
; All registers saved and restored
;
public occupied_chk
occupied_chk:
push ax ; save registers
push bx
push cx
push dx
push si
push di
push ds
;
; first check if there is any ROM in our range
;
add di,bx ; end of range to check
mov dx,0c000h-(2048 shr 4) ; start of possible ROM area
occ_next2k:
add dx,2048 shr 4 ; next 2k segment
occ_nextROM:
cmp dx,di ; ROM addr above our range?
jae occ_chk_RAM ; -yes, go check for RAM
mov ds,dx ; -no, check for ROM
xor si,si
mov cx,0aa55h ; ROM signature
mov ax,[si]
cmp ax,cx ; any signature?
jne occ_next2k
mov ch,[si+2] ; ROM length in 512 byte blocks
xor cl,cl
push cx
shl cx,1 ; # of bytes to checksum
xor ah,ah ; clear accumulated checksum
occ_chksum:
lodsb ; get a byte
add ah,al ; add modulo 100h
loop occ_chksum ; repeat for all bytes
pop cx
or ah,ah ; is checksum zero?
jnz occ_next2k ; -no, check next 2k addr
shr cx,1 ; -yes, valid ROM found
shr cx,1
shr cx,1
add dx,cx ; end of ROM
cmp dx,bx ; does it reach into our area?
ja occ_is_ROM
jmp occ_nextROM
;
; no ROM found in our range, check for RAM
;
occ_chk_RAM:
mov ds,bx ; point segment at start of range
sub di,bx ; compute # of bytes
mov cl,4
shl di,cl
xor bx,bx ; clear word pointer
mov ax,0a5a5h ; test pattern
mov si,05a5ah ; and its complement
occ_nextword:
pushf
cli ; disable interrupts
mov cx,[bx] ; save original contents
mov dx,[bx+2] ; save original contents
mov [bx],si ; put our pattern
mov [bx+2],ax ; drain any capacitive memory
cmp [bx],si ; is our pattern still there?
mov [bx],cx ; restore original contents
mov [bx+2],dx ; restore original contents
jne occ_no_RAM
mov [bx],ax ; put the complement pattern
mov [bx+2],si ; drain capacitive memory
cmp [bx],ax ; our pattern still there?
mov [bx],cx ; restore original contents
mov [bx+2],dx ; restore original contents
je occ_is_RAM ; -yes, range is occupied
occ_no_RAM:
popf ; enable interrupt
add bx,2 ; check next word
cmp bx,di ; at end of range?
jb occ_nextword
clc ; clear carry - range is available
jmp short occ_return
occ_is_RAM:
popf ; enable interrupts
occ_is_ROM:
stc ; set carry - range is occupied
occ_return:
pop ds ; restore registers
pop di
pop si
pop dx
pop cx
pop bx
pop ax
ret