📄 winsrch.asm
字号:
GPFexit:
ret
GetPageFrame endp
;===============================================================================
;==
;== SetPageFrame: Given a page frame address, it sets up the EMS_window[],
;== EMS_window_location[], and EMSsegLoc[].
;==
;==
;== Enter:
;== [PF_Base] page frame base address assigned.
;== Page4K[] array completely filled out.
;==
;== Exit:
;== EMS_window_location[]
;== EMSsegLoc[]
;== Page4K[] array completely filled out.
;==
;===============================================================================
SetPageFrame proc near
mov [number_EMS_windows],0 ; save number of EMS windows
;
; Check to see if the base address of the page frame needs to be set
;
cmp gs:[NoEMSset],TRUE ;Q: Has NoEMS switch been used?
je SPFexit ; Y: don't select one.
cmp gs:[NoPFset],TRUE ;Q: Has FRAME=NONE switch been used?
je SPFexit ; Y: don't select one.
cmp gs:[PF_Base],FREE ;Q: Has page frame been selected?
je SPFexit ; N: don't set one.
test cs:[PnSet],P0+P1+P2+P3 ;Q: XMA2EMS mode selected?
jnz short SPFinvParm ; Y: don't select page frame
mov ax,gs:[PF_Base] ; get page frame address
;
; Make sure page frame was not set in base memory
;
mov bx,[end_of_base_memory_PTE] ; get lowest PTE candidate
shl bx,8 ; paragraph address
cmp ax,bx ;Q: Valid page frame address?
jae short SPFcont ; Y: continue
mov gs:[PF_Base],FREE ; N: can not load
jmp short SPFexit
SPFcont:
;
; Exclude range from Page4K[] array and check for conflicts
;
mov bx,ax
shr bx,8 ; paragraph to 4K page
mov cx,16
SPFConflictLoop:
test cs:[Page4K][bx],not (EMS or RAM);Q: Marked for usage other than EMS?
jz short SPFnoConflict ; N: no conflict
or gs:[msg_flag],PF_WARN_MSG ; Y: warn user of conflict
SPFnoConflict:
or cs:[Page4K][bx],EXCLUDE ; exclude from usage
inc bx
loop SPFConflictLoop ; continue excluding
;
; Initialize EMS_window_location[], EMSsegLoc[], and EMS_window[] with information
;
mov bx,ax
add bx,0C00h ; EMS window number 3
shr bx,8
mov ecx,4 ; number of windows in page frame
SPFloop:
mov [EMS_window_location][ecx*2-2],bx ; address of window
;QEMS mov [EMS_window][ecx*2+ecx-3].handle,FREE ; window is free
mov [EMSsegLoc][bx],cl ; window index
dec [EMSsegLoc][bx] ; window index
sub bx,4 ; next window
loop SPFloop
mov [number_EMS_windows],4 ; save number of EMS windows
SPFexit:
ret
SPFinvParm:
or gs:[msg_flag],INV_PARM_MSG
jmp short SPFexit
SetPageFrame endp
;===============================================================================
;==
;== EMSwindows:
;==
;==
;==
;== Enter:
;== Page4K[] array completely filled out.
;==
;== Exit:
;== EMS_window_location[]
;== Page4K[] array completely filled out.
;==
;===============================================================================
EMSwindows proc near
;
; Check to see if EMS windows are needed
;
cmp gs:[NoEMSset],TRUE ;Q: Has NoEMS switch been used?
je EwExit ; Y: don't create EMS windows
cmp gs:[NoPFset],TRUE ;Q: Has FRAME=NONE switch been used?
je EwExit ; Y: don't create EMS windows
test cs:[PnSet],P0+P1+P2+P3+P254+P255 ;Q: XMA2EMS mode selected?
jnz short EwXMA2EMS ; Y: set XMA2EMS mode
;
; Create as many EMS windows as possible in the 640K to 1MB region.
;
mov ax,[end_of_base_memory_PTE] ; get lowest PTE candidate
add ax,3
shr ax,2 ; round to next 16K boundary
mov cx,100h shr 2 ; 1MB index in 16K blocks
sub cx,ax ; number of PTE entries to 1MB
shl ax,10 ; paragraph address
movzx esi,[number_EMS_windows]; get number of EMS windows so far
EwLoop:
mov bx,EMS ; erase EMS flag
call CheckEMSWindow
test bx,not EMS ;Q: Conflict?
jnz short EwNext ; Y: try next 16K window
test bx,EMS ;Q: Is this page specified as EMS?
jnz short Ewfound ; Y: use for EMS
cmp cs:[UMBset],TRUE ;Q: Has RAM switch been used?
je EwNext ; Y: use RAM as default
; N: use EMS as default
EwFound:
mov bx,ax ; N: exclude range
add bx,3FFh
call ExcludeRange
;
; Set up EMS_window_location[] and EMS_Window[]
;
mov bx,ax
shr bx,8
mov [EMS_window_location][esi*2],bx
;QEMS mov [EMS_window][esi*2+esi].handle,FREE
xchg ax,si
mov [EMSsegLoc][bx],al ; window index
xchg ax,si
inc si
EwNext:
add ax,400h ; next window
loop EwLoop
mov [number_EMS_windows],si ; save number of EMS windows
jmp EwExit
;
; Need to place CEMM in XMA2EMS mode.
;
EwXMA2EMS:
mov [XMA2EMS],TRUE ; configure in XMA2EMS mode
cmp gs:[PF_Base],FREE ;Q: Has a page frame been set?
je short EwXPn ; N: just look at Pn set
mov ax,gs:[PF_Base] ; Y: get base address
shr ax,8 ; get PTE index
mov cx,4 ;
xor bx,bx
EwXloop:
mov Pn[bx],al ; save starting address
bts [PnSet],bx ; set Pn value
inc bx ; next Pn value
add al,4 ; next window base address
loop EwXloop
;
; Check conflicts with P0-P3 & P254-P255
;
EwXPn:
xor esi,esi ; index into Pn
xor dx,dx ; number of EMS windows
mov cx,6 ; check P0-3 & P254-255
EwXPnLoop:
bt [PnSet],si ;Q: Is this P set?
jnc short EwXnextPn ; N: skip it
mov al,Pn[si] ; Y: get address
xor bx,bx
shl ax,8 ; change to paragraph
cmp gs:[PF_Base],FREE ;Q: Has a page frame been set?
je short EwXcont1 ; N: check for conflicts
cmp si,3 ;Q: PF has already been tested?
jbe short EwXcont ; Y: don't check
EwXcont1: ; N: check if valid EMS page
call CheckEMSWindow ; check for conflict
;
;QLEO: Need a message if this conflicts with a page marked as RAM
;
test bx,EXCLUDE ;Q: Is this window excluded?
jnz short EwNoWay ; Y: can't do it
test bx,INUSE ;Q: Is there a ROM in the window?
jz short EwXcont ; N: continue
mov cs:[PFB_warning],TRUE ; Y: warn user
EwXcont:
;
; Set up EMS_window_location[] and EMS_Window[]
;
mov bx,ax
shr bx,8
mov [EMS_window_location][esi*2],bx
;QEMS mov [EMS_window][esi*2+esi].handle,FREE
xchg ax,si
mov [EMSsegLoc][bx],al ; window index
xchg ax,si
;
; Exclude window range from available area
;
mov bx,ax
add bx,3FFh
call ExcludeRange
inc dx ;@PIW
EwXnextPn:
inc si
loop EwXPnLoop
mov [number_EMS_windows],dx ; number of EMS windows
;
; Now that all Pn's are set, can a page frame be formed?
;
EwXPF:
mov cx,3
mov esi,3
mov ax,[EMS_window_location][esi*2]
EwXPFset:
dec si
mov bx,[EMS_window_location][esi*2]
sub ax,bx
cmp ax,4 ;Q: Are they next to each other?
jne short EwXnoPF ; N: page frame is not available
mov ax,bx ; Y: get last address
loop EwXPFset
shl ax,8
mov gs:[PF_Base],ax ; save page frame address
jmp short EwExit
EwExit:
ret
EwXnoPF:
or gs:[msg_flag],NO_LIM_PF_MSG ; no page frame warning
jmp short EwExit
EwNoWay:
mov gs:[PF_Base],FREE
jmp short EwExit
EMSwindows endp
;===============================================================================
;==
;== UMBwindows:
;==
;==
;== Enter:
;== Page4K[] array completely filled out.
;==
;== Exit:
;== EMS_window_location[]
;== Page4K[] array completely filled out.
;==
;===============================================================================
UMBwindows proc near
mov bx,[end_of_base_memory_PTE] ; get lowest PTE candidate
mov cx,100h ; 1MB PTE entry
sub cx,bx ; number of PTE entries to 1MB
xor si,si
UMBloop:
test cs:[Page4K][bx],not (RAM+ROM);Q: Is this page used?
jnz short UMBnotFound ; Y: no UMB here
test cs:[Page4K][bx],RAM+ROM ;Q: Is this page specified as RAM or ROM?
jnz short UMBfound ; Y: use as a UMB
cmp gs:[NoEMSset],TRUE ;Q: Has NoEMS switch been used?
je UMBfound ; Y: UMBs implied
cmp gs:[NoPFset],TRUE ;Q: Has FRAME=NONE switch been used?
je UMBfound ; Y: UMBs implied
cmp cs:[UMBset],TRUE ;Q: Has RAM switch been used?
jne UMBnotFound ; N: no RAM by default
UMBfound:
test cs:[Page4K][bx],ROM ;Q: Is this page specified as ROM?
jnz short UMBcont ; Y: don't add to base memory
cmp [end_of_base_memory_PTE],bx;Q: Is this adjacent to base memory?
jne short UMBcont ; N: don't add to base memory
inc [end_of_base_memory_PTE] ; Y: Add to base memory?
UMBcont:
;QLEO or cs:[Page4K][bx],EXCLUDE
mov cs:[UMBtable][si],bl
inc si
UMBnotFound:
inc bx
loop UMBloop
UMBend:
mov bx,si
mov cs:[NumOfUMBwindows],bl
ret
UMBwindows endp
;===============================================================================
;==
;== BaseEMSwindows:
;==
;==
;==
;== Enter:
;== Page4K[] array completely filled out.
;==
;== Exit:
;== EMS_window_location[]
;== Page4K[] array completely filled out.
;==
;===============================================================================
BaseEMSwindows proc near
;
; Check to see if base EMS windows are needed
;
ifdef NoEMS
cmp gs:[NoEMSset],TRUE ;Q: [NoEMS] mode?
je short BEwExit ; Y: no base EMS windows
endif
cmp [XMA2EMS],TRUE ;Q: XMA2EMS mode?
je short BEwExit ; Y: no base EMS windows
movzx esi,[number_EMS_windows]; get number of EMS windows so far
mov cx,[end_of_base_memory_PTE] ; beyond base window
add cx,3
shr cx,2
xor ax,ax
BEwLoop:
xor bx,bx
call CheckEMSWindow
test bx,not (EMS+RAM)
jnz short BEwNext
mov bx,ax
shr bx,8
mov [EMS_window_location][esi*2],bx
;QEMS mov [EMS_window][esi*2+esi].handle,FREE
xchg ax,si
mov [EMSsegLoc][bx],al ; window index
xchg ax,si
mov bx,ax
add bx,3FFh
call ExcludeRange
inc si
BEwNext:
add ax,400h
loop BEwLoop
mov [number_EMS_windows],si
BEwExit:
ret
BaseEMSwindows endp
;===============================================================================
;==
;== CheckEMSWindow: Given a starting paragraph address, this routine will
;== return a composite of all the flags encountered in the
;== 16K range.
;==
;== Enter:
;== AX = Starting paragraph
;== BX = flag to clear from range: EMS, RAM, EXCLUDE, INUSE
;==
;== Exit:
;== AX = same
;== BX = 0 No conflict. No carry.
;== EXCLUDE Conflict with an excluded 4K page
;== RAM Conflict with a RAM 4K page
;== INUSE Conflict with a default excluded area
;==
;===============================================================================
CheckEMSWindow proc near
push ax
push cx
push dx
not bx ; complement flag
mov dx,bx ; flag to clear
mov bx,ax ; starting paragraph address
xor ax,ax ; clear flags
shr bx,8
mov cx,4
CEWloop:
or al,cs:[Page4K][bx]
and cs:[Page4K][bx],dl
inc bx
loop CEWloop
mov bx,ax
and bx,not EMS
pop dx
pop cx
pop ax
ret
CheckEMSWindow endp
;===============================================================================
;==
;== CheckPageFrame: Given a starting paragraph address, this routine will
;== return a composite of all the flags encountered in the
;== 64K range.
;==
;== Enter:
;== AX = Starting paragraph
;==
;== Exit:
;== AX = same
;== BX = 0 No conflict. No carry.
;== EXCLUDE Conflict with an excluded 4K page
;== RAM Conflict with a RAM 4K page
;== INUSE Conflict with a default excluded area
;==
;===============================================================================
CheckPageFrame proc near
push ax
push cx
push dx
xor dx,dx
mov cx,4
CPFloop:
xor bx,bx
call CheckEMSWindow
or dx,bx
add ax,400h
loop CPFloop
mov bx,dx
pop dx
pop cx
pop ax
ret
CheckPageFrame endp
;===============================================================================
;==
;== UpdatePageArray: Updates page array (Page4K[]) with detected ROM/RAM.
;==
;== Enter:
;== AX = Paragraph address of next ROM/RAM position.
;== DX = Length of ROM/RAM in paragraphs
;==
;== Exit:
;== [Page4K] updated
;==
;==
;===============================================================================
UpdatePageArray proc near
push bx
mov bx,ax
sub bx,dx ; start of ROM/RAM
UPAloop:
shr bx,8 ; index into 4K page
or cs:[Page4K][bx],INUSE ; mark it used
inc bx ; next page
shl bx,8 ; paragraph address
cmp bx,ax ;Q: Still in the ROM/RAM area?
jb short UPAloop ; Y: mark this page as used
pop bx
ret
UpdatePageArray endp
ifndef MSFLAG
;===============================================================================
;==
;== CheckPrechargeBus: Detects a ROM which did not include a ROM header.
;== The routine expects a floating bus to be precharged
;== to either 00 or FF. Thus, if any other pattern is read,
;== a non-standard ROM will be reported.
;==
;== Enter:
;== AX = Paragraph address of next ROM/RAM position.
;==
;== Exit:
;== CY = A non-standard ROM was found at this location.
;== NC = Did not find a valid ROM at this location.
;== AX = Paragraph address of next ROM location.
;== DX = Length of this ROM in paragraphs
;==
;==
;===============================================================================
CheckPrechargeBus proc near
push ds
;
; Assume no ROM will be found: Floating Bus
;
mov ds,ax
mov dx,NEXT_ROM_SEG
add ax,dx
;
; Check for precharge of low
;
cmp dword ptr ds:[4],0
jne short CPBcheckFF
cmp dword ptr ds:[8],0
jne short CPBROMdetected
cmp dword ptr ds:[12],0
jne short CPBROMdetected
jmp short CPBFloatingBus
;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -