1
0
mirror of synced 2026-01-13 15:27:51 +00:00
Matthieu Bucchianeri 422a4306f2
Improvements to the SD Card and EMS drivers. (#31)
* Refactor SD driver the IO to XTMax.

* Refactor the EMS driver to support 8MB.
2025-01-19 19:04:05 -08:00

3575 lines
89 KiB
NASM
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

PAGE 90,132
NAME LTEMM
include LTEMM.MAC ; macros
include LTEMM.INC ; structures
;
;************************************************************************
;* *
;* EMS 4.0 Driver XTMax *
;* Copyright (C) 2024, Ted Fried, Matthieu Bucchianeri *
;* *
;* Based on EMS 4.0 Driver for Lo-tech 2MB EMS Board, rev.01, Mar-14 *
;* *
;* http://www.lo-tech.co.uk/wiki/2MB-EMS-Board *
;* http://www.lo-tech.co.uk/wiki/LTEMM.EXE *
;* *
;* This code is TASM source. *
;* *
;* Based on modifications by Michael Karcher *
;* *
;* Based on original works Copyright (c) 1988, Alex Tsourikov. *
;* All rights reserved. *
;* *
;* Original source kindly provided subject to the BSD 3-Clause *
;* License: http://opensource.org/licenses/BSD-3-Clause *
;* *
;* This software, as modified, is provided subject to the terms *
;* of use at: *
;* *
;* http://www.lo-tech.co.uk/wiki/lo-tech.co.uk:General_disclaimer *
;* *
;* No charge has been made for this software. *
;* *
;************************************************************************
code SEGMENT
ASSUME CS:code
ORG 0000H
; DEVICE header block
emmdrv DW -1,-1 ;Link to next device (none)
DW 8000H
DW OFFSET emmstat
DW OFFSET emmint
DB 'EMMXXXX0' ; required - this is how apps
; detect EMS driver is present
ptrsav LABEL DWORD
parofs DW 0
parseg DW 0
;--------------------------------------------------------------------
; EMM driver work data area
;--------------------------------------------------------------------
emsio LABEL WORD
ems_io DW 260h ;Default EMS i/o port address
backup_count DB 0 ;mapping data backup count
OSE_flag DW 0 ;OS/E function enable flag
OSE_fast DW 0 ;OS/E fast access flag
access_key_h DW 0 ;OS/E access key high
access_key_l DW 0 ;OS/E access key low
alter_map LABEL DWORD
alter_map_off DW 0
alter_map_seg DW 0
page_ptr DW alloc_page ;allocate page buffer pointer.
page_frame_seg DW 0D000h ;Default physical page frame address
total_pages DW PAGE_MAX ;total logical page count
un_alloc_pages DW PAGE_MAX ;unallocate logical page count
handle_count DW 0 ;EMM handle used count
jump_addr DW 0 ;EMM function jump address data area
;
; physical page status data area
;
map_table LABEL phys_page_struct
DB SIZE phys_page_struct * PHYS_PAGES DUP (-1)
;
; handle status flag buffer pointers (handle)
;
alloc_page_count LABEL WORD
;
; allocate page count buffer pointers (handle)
;
handle_flag equ $+2
dw HANDLE_CNT DUP(0)
;
; mapping data backup buffer pointers (handle)
;
back_address LABEL WORD
dw HANDLE_CNT DUP(0)
;
; allocate pages buffer pointers (handle)
;
page_address LABEL WORD
dw HANDLE_CNT DUP(0)
;
; mapping data backup area
;
backup_map LABEL WORD
db SIZE phys_page_struct * PHYS_PAGES * BACK_MAX DUP(-1)
;
; backup area status flags
;
backup_flags LABEL BYTE
db BACK_MAX DUP(0)
;
; allocate data area
;
alloc_page LABEL WORD
dw PAGE_MAX DUP(-1)
;
; logical page kanri data
; 55AAH:not used , 0 - 254:used , FFFFH:bad or non
;
log_page LABEL WORD
dw PAGE_MAX DUP(-1)
;
;====================================================================
;
; Define offsets for io data packet
;
iodat STRUC
cmdlen DB ? ;LENGTH OF THIS COMMAND
unit DB ? ;SUB UNIT SPECIFIER
cmd DB ? ;COMMAND CODE
status DW ? ;STATUS
DB 8 DUP (?)
media DB ? ;MEDIA DESCRIPTOR
trans DD ? ;TRANSFER ADDRESS
count DW ? ;COUNT OF BLOCKS OR CHARACTERS
start DW ? ;FIRST BLOCK TO TRANSFER
iodat ENDS
;
; Define offsets for io data packet 2
;
iodat2 STRUC
DB 13 DUP (?)
DB ?
brkoff DW ? ;BREAK ADDRESS (OFFSET)
brkseg DW ? ;BREAK ADDRESS (SEGMENT)
iodat2 ENDS
;
; Simplistic Strategy routine for non-multi-Tasking system.
;
; Currently just saves I/O packet pointers in PTRSAV for
; later processing by the individual interrupt routines.
;
emmstat PROC FAR
MOV CS:parofs,BX ;
MOV CS:parseg,ES ;
RET
emmstat ENDP
;
; Common program for handling the simplistic I/O packet
; processing scheme in MSDOS
;
emmint PROC FAR
PUSH AX BX DS
LDS BX,CS:ptrsav ;Retrieve pointer to I/O Packet.
MOV AL,[BX].cmd ;Retrieve Command type. (1 => 16)
CMP AL,10h ;Verify that not more than 16 commands.
JA cmderr ;Ah, well, error out.
OR AL,AL ;init. command?
JNZ exit ;just "OK"
JMP emminit ;EMS Driver initial.
cmderr:
MOV AL,3 ;Set unknown command error #.
err_exit: ;
MOV AH,10000001B ;Set error and done bits.
JMP short exit1 ;Quick way out.
exit:
MOV AH,00000001B ;Set done bit for MSDOS.
exit1:
LDS BX,CS:ptrsav ;Retrieve pointer to I/O Packet.
MOV [BX].status,AX ;Save operation compete and status.
POP DS BX AX
RET
emmint ENDP
;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
;--------------------------------------------------------------------
; int 67H EMM driver main routine
;--------------------------------------------------------------------
int67 PROC FAR
CLI
SUB SP,EMMWORK
PUSH DS ES BP DI SI DX CX BX
MOV BP,SP
CLD
PUSH CS
POP DS
ASSUME DS:code
CMP AH,40H ; function code check
JC err84 ; FUNCTION 1 - 30 ?
f_max equ $+2
CMP AH,5EH
JNC err84
PUSH BX
MOV jump_addr,AX
XCHG AH,AL
AND AL,0BFH
CBW
SHL AX,1
MOV BX,AX
MOV AX,func_table[BX]
XCHG AX,jump_addr
POP BX
JMP jump_addr ;---- jump to functions -----
noerr: ;normal return point.
XOR AH,AH
err_ret: ;error return point.
POP BX CX DX SI DI BP ES DS
ADD SP,EMMWORK
IRET
int67 ENDP
;--------------------------------------------------------------------
; error status set routine
;--------------------------------------------------------------------
;The manager detected a malfunction in the EMM software.
err80:
MOV AH,80H
JMP err_ret
;The manager detected a malfunction in the expanded memory hardware.
;err81:
; MOV AH,81H
; JMP err_ret
;The EMM couldn't find the EMM handle your program specified.
err83:
MOV AH,83H
JMP err_ret
;The function code passed to the EMM is not defined.
err84:
MOV AH,84H
JMP err_ret
;All EMM handles are being used.
err85:
MOV AH,85H
JMP err_ret
;The EMM detected a "save" or "restore" page mapping context error.
err86:
MOV AH,86H
JMP err_ret
;There aren't enough expanded memory pages to satisfy your program's request.
err87:
MOV AH,87H
JMP err_ret
;There aren't enough unallocated pages to satisfy your program's request.
err88:
MOV AH,88H
JMP err_ret
;Can't allocate zero (0) pages.
err89:
MOV AH,89H
JMP err_ret
;The logical page is out of the range of logical pages which are allocated to
;the EMM handle.
err8a:
MOV AH,8AH
JMP err_ret
;The physical page to which the logical page is mapped is out of the range of
;physical pages.
err8b:
MOV AH,8BH
JMP err_ret
;The page mapping hardware state save area is full.
err8c:
MOV AH,8CH
JMP err_ret
;The page mapping hardware state save area already has a state associated with
;the EMM handle.
err8d:
MOV AH,8DH
JMP err_ret
;The page mapping hardware state save area doesn't have a state associated with
;the EMM handle.
err8e:
MOV AH,8EH
JMP err_ret
;The subfunction parameter passed to the function isn't defined.
err8f:
MOV AH,8FH
JMP err_ret
;The attrbute type is undefined.
err90:
MOV AH,90H
JMP err_ret
;The system configuration does not support non_volatility.
err91:
MOV AH,91H
JMP err_ret
;The source and destination expanded memory region have the same handle and
;overlap. (move)
err92:
MOV AH,92H
JMP err_ret
;The length of the specified source or destination expanded memory region
;exceeds the length of the expanded memory region allocated to the specified
;source or destination handle.
err93:
MOV AH,93H
JMP err_ret
;The conventional memory region and expanded memory region overlap.
err94:
MOV AH,94H
JMP err_ret
;The offset within the logical page exceeds the length of the logical page.
err95:
MOV AH,95H
JMP err_ret
;Region length exceeds 1M_byte limit.
err96:
MOV AH,96H
JMP err_ret
;The source and destination expanded memory region have the same handle and
;overlap. (exchanged)
err97:
MOV AH,97H
JMP err_ret
;The memory source and destination type are undefined/not supported.
err98:
MOV AH,98H
JMP err_ret
;Alternate map register serts are supported, but the alternate map register set
;specified is not support.
err9a:
MOV AH,9AH
JMP err_ret
;Alternate map/DMA register sets are supported. However, all alternate map/DMA
;register sets are currently allocated.
err9b:
MOV AH,9BH
JMP err_ret
;Alternate map/DMA register sets are not supported, and the alternate map/DMA
;register set specified is not zero.
err9c:
MOV AH,9CH
JMP err_ret
;Alternate map register serts are supported, but the alternate map register set
;specified is not defined, not allocated, or is the currently allocated map
;register set.
err9d:
MOV AH,9DH
JMP err_ret
;Dedicated DMA channels are not supported.
err9e:
MOV AH,9EH
JMP err_ret
;Dedicated DMA channels are not supported. But the DMA channel specified is not
;supported.
err9f:
MOV AH,9FH
JMP err_ret
;No corresponding handle value could be found for the handle name specified.
erra0:
MOV AH,0A0H
JMP err_ret
;A handle with this name already exists.
erra1:
MOV AH,0A1H
JMP err_ret
;An attempt was made to "wrap around" the 1M_byte address space during the
;move/exchange.
erra2:
MOV AH,0A2H
JMP err_ret
;The contents of the data structure passed to the function have either been
;corrupted or are meaningless.
erra3:
MOV AH,0A3H
JMP err_ret
;The operating system has denied access to the this function.
erra4:
MOV AH,0A4H
JMP err_ret
;--------------------------------------------------------------------
; EMM driver function jump table
; (40H - 5DH)
;--------------------------------------------------------------------
func_table LABEL WORD
DW OFFSET noerr
DW OFFSET func2
DW OFFSET func3
DW OFFSET func4
DW OFFSET func5
DW OFFSET func6
DW OFFSET func7
DW OFFSET func8
DW OFFSET func9
DW OFFSET err84
DW OFFSET err84
DW OFFSET func12
DW OFFSET func13
DW OFFSET func14
DW OFFSET func15
DW OFFSET func16
DW OFFSET func17
DW OFFSET func18
DW OFFSET func19
DW OFFSET func20
DW OFFSET func21
DW OFFSET func22
DW OFFSET func23
DW OFFSET func24
DW OFFSET func25
DW OFFSET func26
DW OFFSET func27
DW OFFSET func28
DW OFFSET func29
DW OFFSET func30
;========================================================================
;--------------------------------------------------------------------
; Set physical page map.
; output
; CF = 0 : OK
; CF = 1 : NG
;--------------------------------------------------------------------
set_pages_map PROC NEAR
PUSH AX CX DX DI
MOV DI,OFFSET map_table
MOV CX,PHYS_PAGES
set_pages_map2:
MOV DX,CS:[DI].phys_page_port
MOV AX,CS:[DI].log_page_data
OUT DX,AX ;mapping physical pages...
ADD DI,SIZE phys_page_struct
LOOP set_pages_map2
POP DI DX CX AX
RET
set_pages_map ENDP
;--------------------------------------------------------------------
; Reset physical page.
; input
; AL : physical page no.
;--------------------------------------------------------------------
reset_phys_page PROC NEAR
PUSH AX CX DX DI
cbw
MOV DI,OFFSET map_table
MOV CL,SIZE phys_page_struct
MUL CL
ADD DI,AX
MOV DX,CS:[DI].phys_page_port
MOV AX,DIS_EMS
OUT DX,AX
MOV CS:[DI].emm_handle2,UNMAP
MOV CS:[DI].log_page_data,AX;logical page no.
POP DI DX CX AX
RET
reset_phys_page ENDP
;--------------------------------------------------------------------
; Check mapping data.
; input
; ES:DI : pointer to mapping data
; output
; CF = 0 : OK
; CF = 1 : NG
;--------------------------------------------------------------------
check_map_data PROC NEAR
PUSH AX CX SI DI
MOV SI,OFFSET map_table
MOV CX,PHYS_PAGES
check_map_data3:
MOV AX,ES:[DI].phys_page_port
CMP AX,CS:[SI].phys_page_port
jne check_map_data1
MOV AX,ES:[DI].phys_seg_addr
CMP AX,CS:[SI].phys_seg_addr
jne check_map_data1
ADD SI,SIZE phys_page_struct
ADD DI,SIZE phys_page_struct
LOOP check_map_data3
CLC
check_map_data2:
POP DI SI CX AX
RET
check_map_data1:
STC
JMP check_map_data2
check_map_data ENDP
;------ function 1 --------------------------------------------------
; Get status
; output
; AH : status
;--------------------------------------------------------------------
; Same as noerr
;------ function 2 --------------------------------------------------
; Get page frame address
; output
; AH : status
; BX : page segment address
;--------------------------------------------------------------------
func2:
STI
MOV BX,page_frame_seg ;get EMM physical page segment
f21: ; address.
MOV [BP].bx_save,BX
JMP noerr ;exit
;------ function 3 --------------------------------------------------
; Get unallocated page count
; output
; AH : status
; BX : unallocate page
; DX : all page
;--------------------------------------------------------------------
func3: ;v0.5....
MOV DX,total_pages ;Get total page count
MOV BX,un_alloc_pages ;Get unallocated page count
MOV [BP].dx_save,DX ;Save all page count
JMP f21
;------ function 4 --------------------------------------------------
; Allocate pages
; input
; BX : request allocate page
; output
; AH : status
; DX : EMM handle
;--------------------------------------------------------------------
func4: ;v0.6....
OR BX,BX ;request page size 0 ?
JZ f49 ;yes
;------ function 27 -------------------------------------------------
; Allocate raw pages
; input
; BX : num_of_raw_pages_to_alloc
; output
; AH : status
; DX : raw handle
;--------------------------------------------------------------------
func27:
f41:
CMP total_pages,BX ;request total size over ?
jb f42 ;yes
CMP un_alloc_pages,BX ;request unallocate size over ?
jb f43 ;yes
XOR SI,SI
MOV CX,HANDLE_CNT
f45:
CMP byte ptr [SI].handle_flag,0;not used EMM handle ?
je f44
ADD SI,FLAG_SIZE ;add handle flag size
LOOP f45
JMP err85 ;error exit
f44:
MOV DX,SI
SHR DX,1
MOV byte ptr [SI].handle_flag,1;handle active flag set
INC handle_count ;used EMM handle count up
SUB un_alloc_pages,BX ;unallocated page - BX
MOV [SI].alloc_page_count,bx;EMM handle used page count set
MOV [SI].back_address,0 ;backup address clear
MOV DI,page_ptr
MOV [SI].page_address,DI ;set page buffer pointer
push cs
pop es
MOV SI,OFFSET log_page
XOR AX,AX
MOV CX,BX
jcxz f48
jmp short f47
f4a:
ADD SI,LOG_SIZE
INC AX
f47:
CMP WORD PTR [SI],NOT_USE ;unallocated page ?
JNZ f4a
MOV [SI],DX ;EMM handle set
STOSW ;logical page no. set
LOOP f4a
f48:
MOV [BP].dx_save,DX ;return EMM handle
MOV page_ptr,DI
JMP noerr ;exit
f49:
JMP err89 ;error exit
f42:
JMP err87 ;error exit
f43:
JMP err88 ;error exit
;------ function 5 --------------------------------------------------
; Map handle pages
; input
; AL : physical page no.
; BX : logical page no. (if BX=FFFFH then unmap)
; DX : EMM handle
; output
; AH : status
;--------------------------------------------------------------------
func5: ;v0.6....
CMP AL,PHYS_PAGES ;physical page no. ok ?
jnb f51 ;no
CMP DX,HANDLE_CNT ;check handle data...
jnb f5a
MOV SI,DX
SHL SI,1
CMP byte ptr [SI].handle_flag,0;active handle ?
je f5a
MOV DI,OFFSET map_table ;get phys_page_struct pointer..
mov cl,al
MOV AX,SIZE phys_page_struct
MUL CL
ADD DI,AX
CMP BX,UNMAP ;unmap ?
JZ f57
CMP bx,[SI].alloc_page_count;logical page no. OK ?
jnb f53
SHL BX,1
ADD BX,[SI].page_address
MOV AX,[BX]
f58:
CMP DX,[DI] ;same handle ?
JNZ f54
CMP AX,[DI].log_page_data ;same page no. ?
JZ f56
f54:
MOV [DI],DX ;set handle
MOV [DI].log_page_data,AX ;set logical page no. data
MOV DX,[DI].phys_page_port
OUT DX,AX
f56:
JMP noerr ;exit
f57:
xor al,al
MOV DX,bx
JMP f58
f51:
JMP err8b ;error exit
f53:
JMP err8a ;error exit
f5a:
JMP err83 ;error exit
;------ function 6 --------------------------------------------------
; Deallocate pages
; input
; DX : EMM handle
; output
; AH : status
;--------------------------------------------------------------------
f63:
JMP err86 ;error exit
func6:
push CS
pop ES
CMP DX,HANDLE_CNT ;check handle data...
JNC f5a
MOV BX,DX
SHL BX,1
CMP byte ptr [BX].handle_flag,0;handle OK ?
JZ f5a
CMP [BX].back_address,0 ;backup used?
JNZ f63
MOV cx,[BX].alloc_page_count
JCXZ f6c ;page = 0 ?
add un_alloc_pages,cx ;add unallocated pages
MOV DI,[BX].page_address ;deallocate logical page...
mov si,di
PUSH BX
f65:
MOV BX,[si]
SHL BX,1
MOV [BX].log_page,NOT_USE
add si,2
LOOP f65
POP BX
MOV CX,page_ptr
SUB CX,SI
SHR CX,1
JCXZ f62
REPZ MOVSW
f62:
MOV cx,[BX].alloc_page_count
JCXZ f68
MOV AX,UNALLOC
REPZ STOSW
f68:
XOR DI,DI ;change page address....
MOV SI,[BX].page_address ;get page address.
MOV ax,[BX].alloc_page_count;get allocated page count.
SHL AX,1
MOV CX,handle_count
JMP short f66
f6b:
ADD DI,FLAG_SIZE
f66:
CMP byte ptr [DI].handle_flag,0;active handle ?
JZ f6b
CMP [DI].page_address,SI ;page_address > SI ?
JNG f64
SUB [DI].page_address,AX ;page address - AX
f64:
LOOP f6b
SUB page_ptr,AX ;SUB page pointer
MOV CX,PHYS_PAGES ;deallocate physical page...
XOR AL,AL
MOV SI,OFFSET map_table
f6a:
CMP [SI],DX ;same handle no.?
JNZ f67
CALL reset_phys_page ;reset physical page.
f67:
INC AL
ADD SI,SIZE phys_page_struct
LOOP f6a
f6c:
MOV word ptr [BX].alloc_page_count,0
MOV [BX].page_address,0 ;clear handle page pointer
MOV [BX].back_address,0 ;clear handle back pointer
cmp byte ptr f7_ver,32h
je f6e
MOV DI,OFFSET handle_name ;clear handle name data...
MOV AX,DX
MOV CL,3
SHL AX,CL
ADD DI,AX
xor ax,ax
MOV CX,HANDLE_NAME_SIZE/2
REPZ stosw
f6e:
OR DX,DX ;system handle?
JZ f6d
DEC handle_count ;not use handle count up
JMP noerr ;exit
f6d:
MOV byte ptr [BX].handle_flag,1
JMP noerr ;exit
;------ function 7 --------------------------------------------------
; Get EMS version
; output
; AH : status
; AL : EMS version number
;--------------------------------------------------------------------
func7:
STI
f7_ver equ $+1
MOV AL,40h ;get version no.
JMP noerr
;------ function 8 --------------------------------------------------
; Save page map
; input
; DX : EMM handle
; output
; AH : status
;--------------------------------------------------------------------
func8: ;v0.6....
push CS
pop ES
CMP DX,HANDLE_CNT ;check handle data
JNC f81
MOV SI,DX
SHL SI,1
CMP byte ptr [SI].handle_flag,1;handle OK ?
JNZ f81
CMP [SI].back_address,0 ;backup ?
JNZ f82
MOV AL,backup_count
CMP AL,BACK_MAX
jb f83
f84:
JMP err8c ;error exit
f83:
MOV DI,offset backup_flags ;copy mapping data -> [DI]
mov cx,BACK_MAX ;v1.01
xor al,al
repnz scasb ;Search for free region
jnz f84
dec di
mov byte ptr [di],1 ;Set busy flag
sub di,offset backup_flags
mov ax,di
mov cl,CONTEXT_SIZE
mul cl
add ax,offset backup_map
mov di,ax
MOV [SI].back_address,DI
MOV SI,OFFSET map_table
MOV CX,CONTEXT_SIZE/2
REPZ MOVSW
INC backup_count
JMP noerr
f81:
JMP err83
f82:
JMP err8d
;------ function 9 --------------------------------------------------
; Restore page map
; input
; DX : EMM handle
; output
; AH : status
;--------------------------------------------------------------------
func9:
push CS
pop ES
CMP DX,HANDLE_CNT ;check handle data
JNC f81
MOV BX,DX
SHL BX,1
CMP byte ptr [BX].handle_flag,1;handle OK ?
JNZ f81
CMP [BX].back_address,0 ;backup ?
JZ f92
MOV CX,CONTEXT_SIZE/2 ;move mapping data...
MOV SI,[BX].back_address
MOV DI,OFFSET map_table
PUSH DI
REPZ MOVSW
POP DI
CALL set_pages_map ;enable physical pages...
DEC backup_count ;backup mapping count DEC
MOV ax,[BX].back_address ;v1.01
sub ax,offset backup_map
mov cl,CONTEXT_SIZE
div cl
add ax,offset backup_flags
mov di,ax
mov byte ptr [di],0 ;Set free flag
MOV [BX].back_address,0
JMP noerr ;exit
f92:
JMP err8e
;------ function 10 -------------------------------------------------
; Get page mapping register I/O port array
; input
; ES:DI : buffer address point
; output
; AH : status
; AL : board count
;--------------------------------------------------------------------
; Not supported on 4.0 : err84
;------ function 11 -------------------------------------------------
; Get logical-to-physical page translation array
; input
; DX : EMM handle
; ES:DI : buffer address point
; output
; AH : status code
; BX : number of pages allocated EMM handle.
;--------------------------------------------------------------------
; Not supported on 4.0 : err84
;------ function 12 -------------------------------------------------
; Get EMM handle count
; output
; AH : status
; BX : active EMM handles
;--------------------------------------------------------------------
func12:
STI
MOV BX,handle_count
f121:
MOV [BP].bx_save,BX
JMP noerr ;exit
;------ function 13 -------------------------------------------------
; Get EMM handle pages
; input
; DX : EMM handle
; output
; AH : status
; BX : pages EMM handle
;--------------------------------------------------------------------
func13: ;v0.6....
STI
CMP DX,HANDLE_CNT ;check handle data
jnb f131
MOV SI,DX
SHL SI,1
CMP byte ptr [SI].handle_flag,1;handle OK ?
jne f131
MOV bx,[SI].alloc_page_count
jmp f121 ;exit
f131:
JMP err83 ;error exit
;------ function 14 -------------------------------------------------
; Get all EMM handle pages
; input
; ES:DI : buffer address point
; output
; AH : status
; BX : number of active EMM handles
;--------------------------------------------------------------------
func14:
STI
XOR SI,SI
MOV CX,HANDLE_CNT
XOR BX,BX
XOR DX,DX
f142:
CMP byte ptr [SI].handle_flag,0
JZ f141
MOV AX,DX
STOSW
MOV ax,[SI].alloc_page_count;v0.5
STOSW
INC BX
f141:
INC DX
ADD SI,FLAG_SIZE
LOOP f142
JMP f121
;------ function 15 -------------------------------------------------
; Get/set page map
; input
; AL : request subfunction no.
; ES:DI : mapping registers buffer address point
; output
; AH : status
;--------------------------------------------------------------------
func15:
cbw
dec ax
js get_page_map ; 0
jz set_page_map ; 1
dec ax
jz get_set_page_map ; 2
dec ax
jz get_size_page_map ; 3
jmp err84 ;error exit
;--------------------------------------------------------------------
; Get page map.
; input
; ES:DI : dest_page_map
; output
; AH : status
;--------------------------------------------------------------------
get_page_map:
MOV SI,OFFSET map_table
MOV CX,CONTEXT_SIZE/2
REPZ MOVSW
JMP noerr ;exit
;--------------------------------------------------------------------
; Set page map.
; input
; DS:SI : source_page_map
; output
; AH : status
;--------------------------------------------------------------------
set_page_map:
MOV AX,[BP].ds_save
MOV DS,AX
MOV CX,CONTEXT_SIZE/2
MOV AX,SS
MOV ES,AX
LEA DI,[BP].f15_map_data ;save map data.
REPZ MOVSW
set_page_map3:
LEA DI,[BP].f15_map_data
CALL check_map_data ;check map data (ES:DI)
JC set_page_map2
MOV AX,ES
MOV DS,AX
MOV SI,DI
push cs
pop es
MOV DI,OFFSET map_table
MOV CX,CONTEXT_SIZE/2
REPZ MOVSW
CALL set_pages_map ;mapping physical pages.
JMP noerr ;exit
set_page_map2:
JMP erra3 ;error exit
;--------------------------------------------------------------------
; Get & set page map.
; input
; DS:SI : source_page_map
; ES:DI : dest_page_map
; output
; AH : status
;--------------------------------------------------------------------
get_set_page_map:
PUSH DI DS ES
MOV AX,[BP].ds_save
MOV DS,AX
MOV AX,SS
MOV ES,AX
LEA DI,[BP].f15_map_data
MOV CX,CONTEXT_SIZE/2
REPZ MOVSW
POP ES DS DI
MOV SI,OFFSET map_table ;move current map data...
MOV CX,CONTEXT_SIZE/2
REPZ MOVSW
MOV AX,SS
MOV ES,AX
JMP set_page_map3
;--------------------------------------------------------------------
; Get size of page map save array.
; output
; AH : status
; AL : size_of_array
;--------------------------------------------------------------------
get_size_page_map:
MOV AL,CONTEXT_SIZE ;map data size set.
JMP noerr
;
; This is end of EMS 3 function set
;
;------ function 16 -------------------------------------------------
; Get/set partial page map
;--------------------------------------------------------------------
func16:
cbw
dec ax
js get_partial_map ; 0
jz set_partial_map ; 1
dec ax
jz get_size_partial_map ; 2
jmp err84 ;error exit
;--------------------------------------------------------------------
; Get size of partial page map save array
; input
; BX : number of pages in the partial array
; output
; AH : status
; AL : size_of_partial_save_array
;--------------------------------------------------------------------
get_size_partial_map:
OR BX,BX ;BX = 0?
JZ get_size_partial_map1
CMP BX,PHYS_PAGES ;BX > physical page count?
JG get_size_partial_map2
MOV AX,SIZE phys_page_struct;get size of partial map array.
MUL BL
ADD AX,2
JMP noerr ;exit
get_size_partial_map1:
JMP err8f ;error exit
get_size_partial_map2:
JMP err8b ;error exit
;--------------------------------------------------------------------
; Get partial page map
; input
; DS:SI : partial_page_map
; ES:DI : dest_array
; output
; AH : status
;--------------------------------------------------------------------
get_partial_map:
MOV AX,[BP].ds_save
MOV DS,AX
LODSW
CMP AX,PHYS_PAGES
JG get_partial_map1 ;rel. 0.2
MOV CX,AX
JCXZ get_partial_map5 ;page count = 0?
STOSW
get_partial_map4:
LODSW
PUSH CX
MOV BX,OFFSET map_table
MOV CX,PHYS_PAGES
get_partial_map3:
CMP AX,CS:[BX].phys_seg_addr
JZ get_partial_map2
ADD BX,SIZE phys_page_struct
LOOP get_partial_map3
POP CX
JMP err8b ;error exit
get_partial_map2:
PUSH SI DS
PUSH CS
POP DS
MOV SI,BX
MOV CX,SIZE phys_page_struct
REPZ MOVSB
POP DS SI CX
LOOP get_partial_map4
get_partial_map5:
JMP noerr ;exit
get_partial_map1:
JMP erra4 ;error exit
;--------------------------------------------------------------------
; Set partial page map
; input
; DS:SI : source_array
; output
; AH : status
;--------------------------------------------------------------------
set_partial_map:
MOV AX,[BP].ds_save
MOV DS,AX
LODSW
MOV [BP].f16_map_len,AX ;save page map data length.
MOV CX,SIZE phys_page_struct
MUL CL
MOV CX,AX
JCXZ set_partial_map1
MOV AX,SS ;save page map data...
MOV ES,AX
LEA DI,[BP].f16_map_data
REPZ MOVSB
LEA SI,[BP].f16_map_data ;set page map data...
MOV AX,ES
MOV DS,AX
MOV AX,CS
MOV ES,AX
MOV CX,[BP].f16_map_len ;get page map data length.
set_partial_map4:
MOV AX,[SI].phys_seg_addr
CALL change_seg_page ;change segment -> phys_page_no
JC set_partial_map3
MOV DI,OFFSET map_table
PUSH CX
MOV CX,SIZE phys_page_struct
MUL CL
ADD DI,AX
REPZ MOVSB
POP CX
LOOP set_partial_map4
CALL set_pages_map ;mapping physical pages.
set_partial_map1:
JMP noerr ;exit
set_partial_map3:
JMP err8b ;error exit
;------ function 17 -------------------------------------------------
; Map/unmap multiple handle pages
;--------------------------------------------------------------------
func17:
STI
OR AL,AL
JZ log_phys_map
CMP AL,1
JZ log_phys_map
JMP err84 ;error exit
;--------------------------------------------------------------------
; Logical page/physical page/segment method
; input
; AL : physical page/segment selector
; DX : EMM handle
; CX : logical to physical map length
; DS:SI : pointer to logical to physical/segment map array
; output
; AH : status
;--------------------------------------------------------------------
log_phys_map:
MOV [BP].f17_ax_save,AX
MOV AX,[BP].ds_save
MOV DS,AX
CALL check_handle ;check handle data.
JC log_phys_map2
CMP CX,PHYS_PAGES
ja log_phys_map1
JCXZ log_phys_map9
MOV [BP].f17_map_len,CX ;save page map data length.
MOV AX,SS
MOV ES,AX
LEA DI,[BP].f17_map_data ;save page map data.
SHL CX,1
REPZ MOVSW
MOV AX,SS
MOV DS,AX
LEA SI,[BP].f17_map_data ;set page map data pointer.
MOV CX,[BP].f17_map_len ;get page map data length.
log_phys_map7:
mov bx,[si].log_page_number1;get logical page no.
cmp bx,UNMAP ;unmapping?
je log_phys_map6
call check_log_page ;check logical page no.
jc log_phys_map3 ;error?
mov bx,ax ;set EMM logical page no.
log_phys_map6:
mov ax,[bp].f17_ax_save
or al,al ;subfunction 0?
jnz log_phys_map8
mov ax,[si].phys_page_number1;get physical page no.
cmp ax,PHYS_PAGES ;check physical page no.
jb log_phys_map4
log_phys_map1:
jmp err8b
log_phys_map8:
mov ax,[si].mappable_seg_addr;get mappable seg_address.
call change_seg_page ;change segment -> phys_page_no
jc log_phys_map1
log_phys_map4:
cmp bx,UNMAP ;unmapping?
jz log_phys_mapa
call set_phys_page ;set physical page
jmp short log_phys_map5
log_phys_mapa:
call reset_phys_page ;reset physical page
log_phys_map5:
add si,SIZE log_to_phys_map_struct;
loop log_phys_map7
log_phys_map9:
jmp noerr ;exit
log_phys_map2:
jmp err83
log_phys_map3:
jmp err8a
;------ function 18 ------------------------------------------------------
; Reallocate pages
; input
; DX : EMM handle
; BX : reallocation count
; output
; AH : status
; BX : number of pages allocated to handle after reallocation
;-------------------------------------------------------------------------
f182:
JMP err87
f181:
MOV word ptr [BP].bx_save,0
JMP err83
func18:
push CS
pop ES
CMP DX,HANDLE_CNT ;check handle data...
jnb f181
MOV SI,DX
SHL SI,1
CMP byte ptr [SI].handle_flag,0
je f181
CMP total_pages,BX ;request total size over ?
JC f182 ;yes
MOV ax,[SI].alloc_page_count;get page size to handle
OR BX,BX ;reallocate count = 0?
JNZ f184
MOV CX,AX
JCXZ f18a ;CX = 0 case?
MOV DI,[SI].page_address ;BX = 0 case...
add un_alloc_pages,ax ;add unallocated pages
PUSH BX
f185:
MOV BX,[DI]
SHL BX,1
MOV [BX].log_page,NOT_USE ;unallocate logical page
add di,2
LOOP f185
POP BX
JMP short f18l
f184:
CMP AX,BX ;check reallocation/allocated
JNZ f18c ;pages.
f18a:
JMP noerr ;same size case.
f18c:
JNC f183 ;BX < allocated count?
JMP f186
f183:
MOV CX,AX ;BX < allocated pages case...
SUB CX,BX
MOV DI,[SI].page_address ;BX = 0 case...
MOV AX,BX
SHL AX,1
ADD DI,AX
add un_alloc_pages,cx ;add unallocated pages
PUSH BX
f18b:
MOV BX,[DI]
SHL BX,1
MOV [BX].log_page,NOT_USE ;unallocate logical page
add di,2
LOOP f18b
POP BX
f18l:
MOV CX,page_ptr ;clear & sort page buffer...
MOV AX,BX
SHL AX,1
ADD AX,[SI].page_address
SUB CX,AX
PUSH SI
MOV DI,[SI].page_address
MOV AX,BX
SHL AX,1
ADD DI,AX
MOV ax,[SI].alloc_page_count
MOV SI,[SI].page_address
SHL AX,1
ADD SI,AX
SHR CX,1
JCXZ f18e
REPZ MOVSW
f18e:
MOV CX,page_ptr
SUB CX,DI
SHR CX,1
JCXZ f18f
MOV AX,UNALLOC
REPZ STOSW
f18f:
POP SI
MOV ax,[SI].alloc_page_count
MOV [SI].alloc_page_count,bx;set EMM handle used page count
XOR DI,DI ;change other handle page add-
SUB AX,BX ;ress....
SHL AX,1
MOV BX,[SI].page_address
MOV CX,handle_count
JMP short f18j
f18k:
ADD DI,FLAG_SIZE
f18j:
CMP byte ptr [DI].handle_flag,0;active handle ?
JZ f18k
CMP [DI].page_address,BX ;page_address > BX ?
JNG f18m
SUB [DI].page_address,AX ;page_address - AX
f18m:
LOOP f18k
SUB page_ptr,AX ;page_ptr - AX
CMP [SI].alloc_page_count,0 ;allocate page count = 0 ?
JNZ f18o
MOV [SI].page_address,0 ;clear page buffer pointer
f18o:
JMP noerr ;exit.
f187:
MOV ax,[SI].alloc_page_count
MOV [BP].bx_save,AX
JMP err88 ;error exit
f186:
MOV CX,BX ;BX > allocated pages case...
SUB CX,AX
cmp un_alloc_pages,cx ;request unallocate size over ?
jb f187 ;no
PUSH SI ;move page buffer...
MOV DI,page_ptr
CMP [SI].page_address,0 ;not poniter address?
JNZ f18p
MOV [SI].page_address,DI ;set page pointer
JMP short f18q
f18p:
DEC DI
MOV AX,CX
SHL AX,1
ADD DI,AX
MOV ax,[SI].alloc_page_count
SHL AX,1
ADD AX,[SI].page_address
PUSH CX
MOV CX,page_ptr
SUB CX,AX
MOV SI,page_ptr
DEC SI
STD
JCXZ f18g
REPZ MOVSB
f18g:
POP CX
f18q:
SHL CX,1
ADD page_ptr,CX ;pointer add
POP SI
CLD
MOV DI,[SI].page_address ;allocate add pages...
MOV ax,[SI].alloc_page_count
MOV CX,BX
SUB CX,AX
SHL AX,1
ADD DI,AX
PUSH SI
MOV SI,OFFSET log_page
XOR AX,AX
sub un_alloc_pages,cx
JMP short f188
f189:
ADD SI,LOG_SIZE
INC AX
f188:
CMP WORD PTR [SI],UNMAP ;logical page end?
JZ f18d
CMP WORD PTR [SI],NOT_USE ;unallocated page ?
JNZ f189
MOV WORD PTR [SI],DX
STOSW
LOOP f189
POP SI
MOV ax,[SI].alloc_page_count
MOV [SI].alloc_page_count,bx;set EMM handle used page count
XOR DI,DI ;change other handle page add-
XCHG AX,BX ;ress....
SUB AX,BX
SHL AX,1
MOV BX,[SI].page_address
MOV CX,handle_count
JMP short f18h
f18i:
ADD DI,FLAG_SIZE
f18h:
CMP byte ptr [DI].handle_flag,0
JZ f18i
CMP [DI].page_address,BX
JNG f18n
ADD [DI].page_address,AX
f18n:
LOOP f18i
JMP noerr ;exit
f18d:
POP SI
JMP err80 ;error exit
;------ function 19 -------------------------------------------------
; Get/set handle attribute
;--------------------------------------------------------------------
func19:
sti
cbw
dec ax
js get_handle_attr ; 0
jz set_handle_attr ; 1
dec ax
jz get_attr_cap ; 2
jmp err84 ;error exit
;--------------------------------------------------------------------
; Get handle attribute
; input
; DX : EMM handle
; output
; AH : status
; AL : handle attribute
;--------------------------------------------------------------------
get_handle_attr:
CALL check_handle ;check handle data
JC get_handle_attr1
MOV AL,VOLATILE ;handle attribute set
JMP noerr ;exit
get_handle_attr1:
JMP err83 ;error exit
;--------------------------------------------------------------------
; Set handle attribute
; input
; DX : EMM handle
; BL : new handle attribute
; output
; AH : status
;--------------------------------------------------------------------
set_handle_attr:
JMP err91 ;error exit
;--------------------------------------------------------------------
; Get attribute capability
; output
; AH : status
; AL : attribute capability
;--------------------------------------------------------------------
get_attr_cap:
mov al,VOLATILE ;set attribute capability
jmp noerr ;exit
;------ function 20 -------------------------------------------------
; Get/set handle name
;--------------------------------------------------------------------
func20:
dec al
js get_handle_name ; 0
jz set_handle_name ; 1
jmp err84 ;error exit
;--------------------------------------------------------------------
; Get handle name
; input
; DX : EMM handle
; ES:DI : pointer to handle name array
; output
; AH : status
;--------------------------------------------------------------------
get_handle_name:
CALL check_handle ;check handle data
JC get_handle_name1
MOV SI,OFFSET handle_name
MOV AX,DX
MOV CL,3
SHL AX,CL
ADD SI,AX
MOV CX,HANDLE_NAME_SIZE/2
REPZ MOVSW
JMP noerr ;exit
get_handle_name1:
JMP err83 ;error exit
;--------------------------------------------------------------------
; Set handle name
; input
; DX : EMM handle
; DS:SI : pointer to handle name
; output
; AH : status
;--------------------------------------------------------------------
set_handle_name:
call check_handle ;check handle data
jc get_handle_name1
push cs
pop es
mov ax,[bp].ds_save
mov ds,ax
mov cx,HANDLE_CNT ;check handle name...
mov di,offset handle_name
mov bx,offset handle_flag
set_handle_name2:
cmp byte ptr [bx],0 ;active handle ?
je set_handle_name3
push cx si
mov cx,HANDLE_NAME_SIZE/2
repz cmpsw ;compare handle name...
pop si cx
je set_handle_name4 ;found same handle name ?
set_handle_name3:
add bx,2
loop set_handle_name2
mov di,offset handle_name ;set handle name...
mov cl,3
shl dx,cl
add di,dx
mov cx,HANDLE_NAME_SIZE/2
rep movsw
jmp noerr ;exit
set_handle_name4:
jmp erra1 ;error exit
;------ function 21 -------------------------------------------------
; Get handle directory
;--------------------------------------------------------------------
func21:
dec al
js get_handle_dir ; 0
JZ search_for_name ; 1
dec al
JZ get_total_handle ; 2
JMP err84 ;error exit
;--------------------------------------------------------------------
; Get handle directory
; input
; ES:DI : pointer to handle_dir
; output
; AH : status
; AL : number of entries in the handle_dir array
;--------------------------------------------------------------------
get_handle_dir:
MOV CX,HANDLE_CNT
MOV SI,OFFSET handle_name
XOR DX,DX
XOR BL,BL
get_handle_dir1:
CALL check_handle ;check handle data
JC get_handle_dir2
MOV AX,DX ;set EMM handle.
STOSW
PUSH CX SI ;set handle name...
MOV CX,HANDLE_NAME_SIZE/2
REPZ MOVSW
POP SI CX
INC BL ;inc handle count.
get_handle_dir2:
ADD SI,HANDLE_NAME_SIZE
INC DX
LOOP get_handle_dir1
MOV AL,BL
JMP noerr ;exit
;--------------------------------------------------------------------
; Search for named handle
; input
; DS:SI : search handle_name pointer
; output
; AH : status
; DX : EMM handle
;--------------------------------------------------------------------
search_for_name:
push CS
pop ES
MOV CX,HANDLE_CNT
MOV DI,OFFSET handle_name
MOV AX,[BP].ds_save
MOV DS,AX
XOR DX,DX
search_for_name1:
PUSH CX SI di
MOV CX,HANDLE_NAME_SIZE/2
repz cmpsw
POP di SI CX
JZ search_for_name2
add di,HANDLE_NAME_SIZE
inc dx
loop search_for_name1
jmp erra0
search_for_name2:
mov cx,HANDLE_NAME_SIZE/2
xor ax,ax
repz scasw
jnz search_for_name3
jmp erra1 ;error exit
search_for_name3:
push cx
pop ds
mov [bp].dx_save,dx
jmp noerr ;exit
;--------------------------------------------------------------------
; Get total handle
; output
; AH : status
; BX : total_handles
;--------------------------------------------------------------------
get_total_handle:
MOV BX,HANDLE_CNT ;set max handle count.
MOV [BP].bx_save,BX
JMP noerr ;exit
;------ function 22 -------------------------------------------------
; Alter page map & jump.
; input
; AL : physical page number/segment selector
; DX : EMM handle
; DS:SI : pointer to map_and_jump structure
; output
; AH : status
;--------------------------------------------------------------------
f224:
JMP err8a
func22:
STI
cmp AL,0
je f220
cmp AL,1
je f220
JMP err8f
f220:
MOV [BP].f22_ax_save,AX
CALL check_handle ;check handle data.
JC f221
MOV AX,[BP].ds_save ;copy calling parameters...
MOV DS,AX
LES BX,[SI].target_address1
MOV AX,ES
MOV [BP].f22_target_off,BX ;offset
MOV [BP].f22_target_seg,AX ;segment
MOV CL,[SI].log_phys_map_len;get mapping data length.
XOR CH,CH
MOV [BP].f22_map_len,CX ;length
JCXZ f22a
LES BX,[SI].log_phys_map_ptr;get log_phys_map_ptr.
LEA DI,[BP].f22_map_data ;copy log_phys_map data...
SHL CX,1
f228:
MOV AX,ES:[BX]
MOV SS:[DI],AX
add DI,2
add BX,2
LOOP f228
f22a:
MOV AX,SS
MOV DS,AX
MOV CX,[BP].f22_map_len ;length
JCXZ f222
LEA DI,[BP].f22_map_data ;get mapping data pointer.
f223:
MOV BX,[DI].log_page_number1;get logical page no.
CMP BX,UNMAP ;unmapping?
JZ f22b
CALL check_log_page ;check logical page no.
JC f224
MOV BX,AX ;set EMM logical page no.
f22b:
MOV AX,[BP].f22_ax_save ;get phys_page_no/seg_selector.
OR AL,AL ;sub_function 0?
JNZ f229
MOV AX,[DI].phys_page_number1;get physical page no.
CMP AX,PHYS_PAGES
jb f225
f22c:
jmp err8b
f229:
MOV AX,[DI].mappable_seg_addr;get mappable segment.
CALL change_seg_page ;change segment -> phys_page_no.
JC f22c
f225:
CMP BX,UNMAP ;unmapping?
JZ f227
CALL set_phys_page ;set physical page
jmp short f226
f221:
JMP err83
f227:
CALL reset_phys_page ;reset physical page
f226:
ADD DI,SIZE log_to_phys_map_struct;
LOOP f223
f222:
MOV AX,[BP].f22_target_seg ;get target address.
MOV [BP].ret_segment,AX ;set FAR:JUMP segment.
MOV AX,[BP].f22_target_off ;get target address.
MOV [BP].ret_offset,AX ;set FAR:JUMP offset.
JMP noerr ;exit
;------ function 23 -------------------------------------------------
; Alter page map & call
;--------------------------------------------------------------------
func23:
STI
or al,al
je f2300
cmp al,1
je f2300
cmp al,2
je get_page_map_stack
jmp err84
;--------------------------------------------------------------------
; Get page map stack space size
; output
; AH : status
; BX : stack space required
;--------------------------------------------------------------------
get_page_map_stack:
MOV BX,RET_SP ;set stack space...
MOV [BP].bx_save,BX
JMP noerr ;exit
;--------------------------------------------------------------------
; Alter page map & call
; input
; AL : physical page number/segment selector
; DX : EMM handle
; DS:SI : pointer to map_and_call structure
; output
; AH : status
; AL : number of entries in the handle_dir array
;--------------------------------------------------------------------
f2300:
MOV [BP].f23_ax_save,AX
CALL check_handle ;check handle data
JC f221
MOV AX,[BP].ds_save
MOV DS,AX
LES BX,[SI].target_address2 ;get FAR:CALL target_addr.
MOV [BP].f23_target_off,BX ;set offset.
MOV AX,ES ;get segment
MOV [BP].f23_target_seg,AX ;set segment.
MOV CL,[SI].new_page_map_len;get new_page_map_len.
XOR CH,CH
MOV [BP].f23_new_map_len,CX
LES BX,[SI].new_page_map_ptr;get new_page_map_ptr.
JCXZ f2303
LEA DI,[BP].f23_new_map_data;
SHL CX,1
f2302:
MOV AX,ES:[BX]
MOV SS:[DI],AX
add DI,2
add BX,2
LOOP f2302
f2303:
MOV CL,[SI].old_page_map_len;get old_page_map_len.
XOR CH,CH
MOV [BP].f23_old_map_len,CX
LES BX,[SI].old_page_map_ptr;get old_page_map_ptr.
JCXZ f2305
LEA DI,[BP].f23_old_map_data;
SHL CX,1
f2304:
MOV AX,ES:[BX]
MOV SS:[DI],AX
add DI,2
add BX,2
LOOP f2304
f2305:
MOV CX,[BP].f23_new_map_len ;get new_page_map_len.
JCXZ f2307 ;mapping page length = 0?
MOV AX,SS
MOV DS,AX
LEA SI,[BP].f23_new_map_data;get new_page_map_ptr.
f2306:
MOV BX,[SI].log_page_number2;get logical page no.
CMP BX,UNMAP ;unmapping?
JZ f2313
CALL check_log_page
JC f2309
MOV BX,AX
f2313:
MOV AX,[BP].f23_ax_save
OR AL,AL ;sub_function 0?
JZ f2310
MOV AX,[SI].mappable_seg_addr;
CALL change_seg_page ;change segment -> phys_page_no.
JC f2314
f2310:
MOV AX,[SI].phys_page_number1;get physical page no.
CMP AX,PHYS_PAGES
jnb f2314
f2311:
CMP BX,UNMAP ;unmapping?
JZ f2312
CALL set_phys_page ;set physical page
jmp short f2308
f2309:
JMP err8a
f2314:
JMP err8b
f2312:
CALL reset_phys_page ;reset physical page
f2308:
ADD SI,SIZE log_to_seg_map_struct;
LOOP f2306
f2307:
MOV BX,OFFSET f2350 ;get FAR:CALL return_addr
MOV [BP].f23_retoff,BX ;set offset.
MOV AX,CS
MOV [BP].f23_retseg,AX ;set segment.
MOV AX,[BP].ret_flag ;get flags.
MOV [BP].f23_flag,AX ;set flags.
MOV AH,0
POP BX CX DX SI DI BP ES DS
IRET ;FAR:CALL to target
;
; far call return point
;
f2350:
PUSHF ;push flags.
POP AX ;pop flags.
CLI
SUB SP,F23_RETSP
PUSH DS ES BP DI SI DX CX BX
MOV BP,SP
MOV [BP].ret_flag,AX ;set return_flags.
MOV CX,[BP].f23_old_map_len ;get old_page_map_len.
JCXZ f2351 ;mapping page length = 0?
MOV AX,SS
MOV DS,AX
LEA SI,[BP].f23_old_map_data;get old_page_map_ptr.
f2352:
MOV BX,[SI].log_page_number2;get logical page no.
CMP BX,UNMAP ;unmapping?
JZ f2359
CALL check_log_page
JC f2309
MOV BX,AX
f2359:
MOV AX,[BP].f23_ax_save
OR AL,AL
JZ f2354
MOV AX,[SI].mappable_seg_addr
CALL change_seg_page ;change segment -> phys_page_no.
jc f2314
f2354:
MOV AX,[SI].phys_page_number1;get physical page no.
CMP AX,PHYS_PAGES
jnb f2314
CMP BX,UNMAP ;unmapping?
JZ f2357
CALL set_phys_page ;set physical page
jmp short f2353
f2357:
CALL reset_phys_page ;reset physical page
f2353:
ADD SI,SIZE log_to_seg_map_struct
LOOP f2352
f2351:
JMP noerr
;------ Function 24 (57h) -------------------------------------------
; Move Memory Region
; This subfunction copies a region of memory in the following memory
; source/destination combinations:
;
; o conventional memory to conventional memory
; o conventional memory to expanded memory
; o expanded memory to conventional memory
; o expanded memory to expanded memory
;
; AL : Operation (0)
; DS:SI : pointer to move_info
; AH : Return code
;--------------------------------------------------------------------
func24:
or al,al
je f2400
cmp al,1
je f2400
jmp err84 ;
f2400:
mov [bp].f24_al_save,al
mov ax,[bp].ds_save
mov ds,ax
mov ax,[si].source_offset ;
mov [bp].source_off,ax
mov al,[si].source_type
mov [bp].source_type1,al
or al,al
je f2401
mov ax,[si].source_seg_page ; = EMS
mov [bp].source_page,ax
mov ax,cs:Page_Frame_Seg
mov [bp].source_seg,ax
mov ax,[si].source_handle1
mov [bp].source_handle2,ax
jmp short f2402
f2401:
mov ax,[si].source_seg_page ; = RAM
mov [bp].source_seg,ax
f2402:
mov ax,[si].dest_offset ;
mov [bp].dest_off,ax
mov al,[si].dest_type
mov [bp].dest_type1,al
or al,al
je f2403
mov ax,[si].dest_seg_page ; = EMS
mov [bp].dest_page,ax
mov ax,cs:Page_Frame_Seg
add ax,400H
mov [bp].dest_seg,ax
mov ax,[si].dest_handle1
mov [bp].dest_handle2,ax
jmp short f2404
f2403:
mov ax,[si].dest_seg_page ; = RAM
mov [bp].dest_seg,ax
f2404:
les di,[si].region_lenght ;
mov [bp].region_low,di
mov ax,es
mov [bp].region_high,ax
cmp ax,10h ;
jb f2405
jne f2407
or di,di
jnz f2407
f2405:
cmp [si].source_type,0
jne f2408 ; = RAM
FarPtrAddress [bp].source_seg,[bp].source_off
cmp dx,10h ;...
jnb f2411
f2409:
Save32 [bp].source_ea_high,[bp].source_ea_low;
Add32 [bp].region_high,[bp].region_low
Sub32 0,1 ;
cmp dx,10h ;
jb f2410
jg f2411
or ax,ax
jz f2410
f2411:
jmp errA2
f2413:
jmp err8A
f2414:
jmp err95
f2410a:
jmp err93
f2412:
jmp err83
f2407:
jmp err96
f2418:
jmp errA2
f2408:
mov dx,[bp].source_handle2 ; = EMS
call check_handle ;
jc f2412
mov bx,[bp].source_page
call check_log_page ;
jc f2413
mov di,dx
mov ax,[bp].source_off
cmp ax,4000h
jnb f2414
xor dx,dx
Add32 [bp].region_high,[bp].region_low
Sub32 0,1
Shl32 2
add bx,dx
mov dx,di
call check_log_page ;
jc f2410a
f2410:
cmp [si].dest_type,0
jne f2415 ; = RAM
FarPtrAddress [bp].dest_seg,[bp].dest_off
cmp dx,10h ;.
jnb f2418
Save32 [bp].dest_ea_high, [bp].dest_ea_low
Add32 [bp].region_high,[bp].region_low
Sub32 0,1 ;
cmp dx,10h ;
jb f2417
jmp short f2418
f2419:
jmp err83
f2420:
jmp err8A
f2421:
jmp err95 ;
f2417a:
jmp err93 ;
f2415:
mov dx,[bp].dest_handle2 ; = EMS
call check_handle ;
jc f2419
mov bx,[bp].dest_page
call check_log_page ;
jc f2420
mov di,dx
mov ax,[bp].dest_off
cmp ax,4000h
jnb f2421
xor dx,dx
Add32 [bp].region_high, [bp].region_low
Sub32 0,1
Shl32 2
add bx,dx
mov dx,di
call check_log_page ;
jc f2417a
f2417:
mov [bp].direct_move,0
mov al,[si].source_type
cmp al,[si].dest_type ;
jne f2423
f2422:
cmp al,1
je f2424
FLoad32 [bp].source_ea_low
mov bx,[bp].dest_ea_low ; = RAM
mov cx,[bp].dest_ea_high
jmp short f2430
f2424:
mov ax,[bp].source_handle2 ; = EMS
cmp ax,[bp].dest_handle2
jne f2423
mov dx,[bp].dest_page
xor ax,ax
Shr32 2
Add32 0,[bp].dest_off
mov bx,ax
mov cx,dx
mov dx,[bp].source_page
xor ax,ax
Shr32 2
Add32 0,[bp].source_off
f2430:
cmp dx,cx ;DX:AX = , CX:BX =
jne f2425
cmp ax,bx
f2425:
jae f2426
xchg bx,ax
xchg cx,dx
cmp [bp].f24_al_save,1
je f2426
or [bp].direct_move,1 ;
f2426:
sub ax,bx
sbb dx,cx
cmp dx,[bp].region_high
jne f2427
cmp ax,[bp].region_low
f2427:
jae f2423
cmp [bp].f24_al_save,1
je f2428 ;
or [bp].direct_move,2 ;
f2423:
mov [bp].zero_low,0
test [bp].direct_move,1
jnz f2429
cld
jmp f2435
f2428:
jmp err97
f2429:
std
cmp [si].dest_type,1 ; = EMS ?
je f2432
FLoad32 [bp].dest_ea_low
Add32 [bp].region_high,[bp].region_low
Sub32 0,1
mov bx,ax
and bx,000Fh
mov [bp].dest_off,bx
Shr32 4
mov [bp].dest_seg,ax
jmp short f2433
f2432: ; EMS...
FLoad32 [bp].region_low
Add32 0,[bp].dest_off
Sub32 0,1
mov bx,ax
and bx,3FFFh
mov [bp].dest_off,bx
Shl32 2
mov bx,[bp].dest_page
add bx,dx
mov [bp].dest_page,bx
mov dx,[bp].dest_handle2
call check_log_page
mov bx,ax
mov al,1
call set_phys_page
f2433:
cmp [si].source_type,1 ; = EMS ?
je f2434
;...
FLoad32 [bp].source_ea_low
Add32 [bp].region_high,[bp].region_low
Sub32 0,1
mov bx,ax
and bx,000Fh
mov [bp].source_off,bx
Shr32 4
mov [bp].source_seg,ax
jmp short f2435
f2434: ; EMS...
FLoad32 [bp].region_low
Add32 0,[bp].source_off
Sub32 0,1
mov bx,ax
and bx,3FFFh
mov [bp].source_off,bx
Shl32 2
add [bp].source_page,dx
mov dx,[bp].source_handle2
call check_log_page
mov bx,ax
xor al,al
call set_phys_page
f2435:
mov al,[si].source_type ;
or al,[si].dest_type ;
jz f2436
mov cx,SIZE phys_page_struct
mov si,offset map_table
mov di,offset f24_data
mov ax,cs
mov ds,ax
mov es,ax
rep movsw
or [bp].direct_move,4
f2436:
mov ax,[bp].region_low
or ax,[bp].region_high
jnz f2438
test [bp].direct_move,4 ;
jz f2439
mov cx,SIZE phys_page_struct
mov si,offset f24_data
mov di,offset map_table
f2440:
mov ax,cs
mov ds,ax
mov es,ax
rep movsw
call set_pages_map
f2439:
test [bp].direct_move,2 ; F24 !!!
jnz f2441
jmp noerr
f2441:
jmp err92
f2438:
cmp [bp].source_type1,1
je f2442
FarPtrAddress [bp].source_seg,[bp].source_off
test [bp].direct_move,1
jnz f2443
Add32 [bp].zero_low,0 ;
mov bx,ax
and bx,000Fh
mov [bp].source_off,bx
Shr32 4
mov [bp].source_seg,ax
jmp short f2444
f2443:
Sub32 0,[bp].zero_low ;
mov bx,ax
or bx,0FFF0h
mov [bp].source_off,bx
Sub32 0,bx
Shr32 4
mov [bp].source_seg,ax
jmp short f2444
f2442:
mov ax,[bp].source_off ; EMS...
test [bp].direct_move,1
jnz f2445
add ax,[bp].zero_low ;...
cmp ax,4000h
jb f2446
inc [bp].source_page
mov [bp].source_off,0
jmp short f2446
f2445:
sub ax,[bp].zero_low ;...
jnc f2446
dec [bp].source_page
mov [bp].source_off,3FFFh
f2446:
mov dx,[bp].source_handle2
mov bx,[bp].source_page
call check_log_page
mov bx,ax
xor al,al
call set_phys_page
f2444:
test [bp].dest_type1,1
jnz f2447
FarPtrAddress [bp].dest_seg,[bp].dest_off
test [bp].direct_move,1
jnz f2448
Add32 0,[bp].zero_low ;
mov bx,ax
and bx,000Fh
mov [bp].dest_off,bx
Shr32 4
mov [bp].dest_seg,ax
jmp short f2449
f2448:
Sub32 0,[bp].zero_low ;...
mov bx,ax
or bx,0FFF0h
mov [bp].dest_off,bx
Sub32 0,bx
Shr32 4
mov [bp].dest_seg,ax
jmp short f2449
f2447:
mov ax,[bp].dest_off ; EMS...
test [bp].direct_move,1
jnz f2450
add ax,[bp].zero_low ;...
cmp ax,4000h
jb f2451
inc [bp].dest_page
mov [bp].dest_off,0
jmp short f2451
f2450:
sub ax,[bp].zero_low ;...
jnc f2451
dec [bp].dest_page
mov [bp].dest_off,3FFFh
f2451:
mov dx,[bp].dest_handle2
mov bx,[bp].dest_page
call check_log_page
mov bx,ax
mov al,1
call set_phys_page
f2449:
mov bl,[bp].dest_type1 ;MAXLEN (dest)...
mov ax,[bp].dest_off
call maxlen
push ax
mov bl,[bp].source_type1 ;MAXLEN (source)...
mov ax,[bp].source_off
call maxlen
pop bx
mov cx,ax
FLoad32 [bp].region_low
cmp cx,bx ;
jb f2452
mov cx,bx
f2452:
or dx,dx
jnz f2453
cmp cx,ax
jb f2453
mov cx,ax
f2453:
mov [bp].zero_low,cx
mov ax,[bp].source_seg
mov ds,ax
mov ax,[bp].dest_seg
mov es,ax
mov si,[bp].source_off
mov di,[bp].dest_off
cmp [bp].f24_al_save,1
je f2454
rep movsb ;
f2455:
FLoad32 [bp].region_low
Sub32 0,[bp].zero_low
Save32 [bp].region_high,[bp].region_low
jmp f2436
f2454:
Exbyte ;...
loop f2454
jmp f2455
;------ function 25 -------------------------------------------------
; Get mappable physical address array
;--------------------------------------------------------------------
func25:
STI
DEC AL
js get_map_phys_addr ; 0
JZ get_map_phys_ent ; 1
JMP err84 ;error exit
;--------------------------------------------------------------------
; Get mappable physical address array
; input
; ES:DI : mappable_phys_page
; output
; AH : status
; CX : number of entries in the mappable_phys_page
;--------------------------------------------------------------------
get_map_phys_addr:
MOV AX,[BP].es_save
MOV ES,AX
MOV CX,PHYS_PAGES
MOV SI,OFFSET map_table
XOR DX,DX
get_map_phys_addr1:
MOV AX,[SI].phys_seg_addr
STOSW
MOV AX,DX
STOSW
INC DX
ADD SI,SIZE phys_page_struct
LOOP get_map_phys_addr1
;--------------------------------------------------------------------
; Get mappable physcal address array entries
; output
; AH : status
; CX : number of entries in the mappable_phys_page
;--------------------------------------------------------------------
get_map_phys_ent:
get_map_phys_addr2:
MOV CX,PHYS_PAGES
MOV [BP].cx_save,CX ;set segment addr entrie
JMP noerr ;exit
;------ function 26 -------------------------------------------------
; Get expanded memory hardware infomation
;--------------------------------------------------------------------
func26:
STI
DEC AL
js get_hardware_config ; 0
JZ get_unalloc_raw_page ; 1
JMP err84 ;error exit
;--------------------------------------------------------------------
; Get hardware configration array
; input
; ES:DI : hardware_info
; output
; AH : status
;--------------------------------------------------------------------
get_hardware_config:
CMP OSE_flag,0 ;OS/E flag enable?
jne get_hardware_config1
MOV AX,[BP].es_save
MOV ES,AX
MOV AX,RAW_PAGES
STOSW
MOV AX,ALTER_REGS
STOSW
MOV AX,CONTEXT_SIZE
STOSW
MOV AX,DMA_REGS
STOSW
MOV AX,DMA_CHANNEL
STOSW
JMP noerr ;exit
get_hardware_config1:
JMP erra4 ;error exit
;--------------------------------------------------------------------
; Get unallocated raw page count
; output
; AH : status
; BX : unallocated raw pages
; DX : total raw pages
;--------------------------------------------------------------------
get_unalloc_raw_page:
JMP func3 ;goto function 3
;------ function 28 -------------------------------------------------
; Alternate map register set
;--------------------------------------------------------------------
f280:
JMP erra4 ;error exit
func28:
STI
CMP OSE_flag,0 ;OS/E flag enable?
jne f280
cbw
dec ax
js get_alter_map_reg ; 0
JZ set_alter_map_reg ; 1
dec ax
jz get_alter_map_size ; 2
dec ax
jz alloc_alter_map_reg ; 3
dec ax
jz dealloc_alter_map_reg ; 4
dec ax
jz alloc_DMA_reg ; 5
dec ax
jz enable_DMA_alter_reg ; 6
dec ax
jz disable_DMA_alter_reg ; 7
dec ax
jz dealloc_DMA_reg ; 8
jmp err84 ;error exit
;--------------------------------------------------------------------
; Get alternate map save array size
; output
; AH : status
; DX : size_of_array
;--------------------------------------------------------------------
get_alter_map_size:
MOV DX,CONTEXT_SIZE
MOV [BP].dx_save,DX
JMP noerr ;exit
;--------------------------------------------------------------------
; Allocate alternate map register set
; output
; AH : status
; BL : alternate map register set number
;--------------------------------------------------------------------
alloc_alter_map_reg:
;--------------------------------------------------------------------
; Allocate DMA register set
; output
; AH : status
; BL : DMA register set number
;--------------------------------------------------------------------
alloc_DMA_reg:
xor bx,bx
MOV [BP].bx_save,BX
JMP noerr ;exit
;--------------------------------------------------------------------
; Deallocate alternate map register set
; input
; BL : alternate map register set number
; output
; AH : status
;--------------------------------------------------------------------
dealloc_alter_map_reg:
;--------------------------------------------------------------------
; Enable DMA on alternate map register set
; input
; BL : DMA register set number
; DL : DMA channel number
; output
; AH : status
;--------------------------------------------------------------------
enable_DMA_alter_reg:
;--------------------------------------------------------------------
; Disable DMA on alternate map register set
; input
; BL : alternate register set number
; output
; AH : status
;--------------------------------------------------------------------
disable_DMA_alter_reg:
;--------------------------------------------------------------------
; Deallocate DMA register set
; input
; BL : DMA register set number
; output
; AH : status
;--------------------------------------------------------------------
dealloc_DMA_reg:
OR BL,BL
jnz dealloc_alter_map_reg1
JMP noerr
dealloc_alter_map_reg1:
JMP err9c
;--------------------------------------------------------------------
; Get alternate map register set
; output
; AH : status
; BL : current active alternate map register set number
; ES:DI : pointer to a map register context save area
;--------------------------------------------------------------------
get_alter_map_reg:
MOV DI,alter_map_off
MOV AX,alter_map_seg
MOV ES,AX
OR AX,DI
JZ get_alter_map_reg1
MOV SI,OFFSET map_table
PUSH CS
POP DS
MOV CX,CONTEXT_SIZE/2
REPZ MOVSW
get_alter_map_reg1:
MOV DI,CS:alter_map_off
MOV AX,CS:alter_map_seg
MOV [BP].di_save,DI
MOV [BP].es_save,AX
MOV BX,[BP].bx_save
xor bl,bl
MOV [BP].bx_save,BX
JMP noerr
;--------------------------------------------------------------------
; Set alternate map register set
; input
; BL : new alternate map register set number
; ES:DI : pointer to a map register context restore area
; output
; AH : status
;--------------------------------------------------------------------
set_alter_map_reg:
cli
or bl,bl
jnz set_alter_map_reg1
mov alter_map_off,di
mov ax,es
mov alter_map_seg,ax
or ax,di
jz set_alter_map_reg2
push es
pop ds
mov si,di
mov cx,CONTEXT_SIZE/2
mov ax,ss
mov es,ax
lea di,[bp].f28_map_data
rep movsw
lea di,[bp].f28_map_data
call check_map_data
jc set_alter_map_reg3
mov si,di
push es
pop ds
mov cx,CONTEXT_SIZE/2
mov di,offset map_table
push cs
pop es
rep movsw
call set_pages_map
set_alter_map_reg2:
jmp noerr
set_alter_map_reg1:
jmp err9c
set_alter_map_reg3:
jmp erra3
;------ function 29 -------------------------------------------------
; Prepare expanded memory hardware for warm boot
;--------------------------------------------------------------------
func29:
MOV AX,CS
MOV ES,AX
MOV DS,AX
MOV DI,OFFSET map_table ;disable physical pages...
MOV CX,PHYS_PAGES
f291:
MOV [DI].emm_handle2,UNMAP
MOV [DI].log_page_data,0
ADD DI,SIZE phys_page_struct
loop f291
call set_pages_map
MOV DI,OFFSET alloc_page_count;clear all...
mov cx,HANDLE_CNT*3
xor ax,ax
rep stosw
MOV DI,OFFSET handle_name ;clear handles...
MOV CX,HANDLE_CNT*4
REPZ STOSW
MOV di,OFFSET backup_flags ;v1.01
mov cx,CONTEXT_SIZE/2
rep stosw
MOV DI,OFFSET alloc_page ;clear logical page buffer...
MOV CX,PAGE_MAX*2
dec ax ; set to -1
REPZ STOSW
MOV byte ptr handle_flag,1 ;set system handle flag...
MOV handle_count,1 ;set active handle count
MOV backup_count,0 ;set backup map count
MOV AX,total_pages
MOV un_alloc_pages,AX ;set unallocate page count
MOV AX,OFFSET alloc_page ;set page buffer pointer
MOV page_ptr,AX
JMP noerr ;exit
;------ function 30 -------------------------------------------------
; Enable/disable OS/E function set functions
; input
; BX,CX : alternate register set number
; output
; AH : status
; BX,CX : alternate register set number
;--------------------------------------------------------------------
func30:
sti
dec al
js enable_OSE_func ; 0
jz disable_OSE_func ; 1
dec al
jz return_access_key ; 2
jmp err84 ;error exit
;--------------------------------------------------------------------
; Enable OS/E function set
; input
; BX,CX : access_key
; output
; AH : status
; BX,CX : access_key
;--------------------------------------------------------------------
enable_OSE_func:
CMP OSE_fast,0 ;OS/E fast access flag enable?
JZ enable_OSE_func1
CMP access_key_h,BX ;compare access key high
JNZ enable_OSE_func2
CMP access_key_l,CX ;compare access key low
jnz enable_OSE_func2
enable_OSE_func1:
MOV OSE_flag,0 ;enable OS/E function
MOV OSE_fast,0FFFFH ;set OS/E fast access flag
MOV BX,access_key_h
MOV [BP].bx_save,BX
MOV CX,access_key_l
MOV [BP].cx_save,CX
JMP noerr
enable_OSE_func2:
JMP erra4
;--------------------------------------------------------------------
; Disable OS/E function set
; input
; BX,CX : access_key
; output
; AH : status
; BX,CX : access_key
;--------------------------------------------------------------------
disable_OSE_func:
CMP OSE_fast,0 ;OS/E fast access flag enable?
JZ disable_OSE_func1
CMP access_key_h,BX ;compare access key high
JNZ enable_OSE_func2
CMP access_key_l,CX ;compare access key low
jnz enable_OSE_func2
disable_OSE_func1:
MOV OSE_flag,0FFFFH ;disable OS/E function
MOV OSE_fast,0FFFFH ;set OS/E fast access flag
MOV BX,access_key_h
MOV [BP].bx_save,BX
MOV CX,access_key_l
MOV [BP].cx_save,CX
JMP noerr
;--------------------------------------------------------------------
; Return access key
; input
; BX,CX : access_key
; output
; AH : status
;--------------------------------------------------------------------
return_access_key:
CMP OSE_flag,0 ;OS/E flag enable?
jnz enable_OSE_func2
CMP access_key_h,BX ;compare access key high
jnz enable_OSE_func2
CMP access_key_l,CX ;compare access key low
jnz enable_OSE_func2
MOV OSE_flag,0 ;enable OS/E function
MOV OSE_fast,0 ;reset OS/E fast access flag
XOR AX,AX
MOV ES,AX
MOV AX,ES:[46CH]
ADD BX,AX ;make access key...
MOV access_key_h,BX
ADC AX,ES:[46EH]
ADD CX,AX
MOV access_key_l,CX
JMP noerr
;.........................................................................
;--------------------------------------------------------------------
; \82\EB\E7\A8᫥\AD\A8\A5 \AC\A0\AAᨬ\A0\AB쭮 \A2\AE\A7\AC\AE\A6\AD\AE\A9 \A4\AB\A8\AD\EB \A1\AB\AE筮\A9 \AF\A5\E0\A5\E1뫪\A8
; \A2室
; BL : \AF\A0\AC\EF\E2\A8 (0=RAM,1=EMS)
; AX : ᬥ饭\A8e \A1\AB\AE\AA\A0
; \A2\EB室
; AX : \A4\AB\A8\AD\A0 \AF\A5\E0\A5\E1뫪\A8
;--------------------------------------------------------------------
maxlen PROC NEAR
or bl,bl
jnz max1
test [bp].direct_move,1 ;\A4\AB\EF ᮢ\AC\A5\E1⨬\AE\A9 \AF\A0\AC\EF\E2\A8...
jnz max2
neg ax
jmp short max3
max2:
inc ax
max3:
or ax,ax
jnz max4
dec ax
ret
max1:
test [bp].direct_move,1 ;\A4\AB\EF EMS...
jnz max5
sub ax,4000h
neg ax
ret
max5:
inc ax
max4:
ret
maxlen ENDP
;--------------------------------------------------------------------
; Check logical page no.
; input
; BX : logical page number in handle
; DX : EMM handle
; output
; AX : logical page number in EMM
; CF = 0 : OK
; CF = 1 : NG
;--------------------------------------------------------------------
check_log_page PROC NEAR
PUSH CX SI
MOV SI,DX
SHL SI,1
CMP bx,CS:[SI].alloc_page_count
jnb check_log_page2
MOV SI,CS:[SI].page_address
MOV AX,BX
SHL AX,1
ADD SI,AX
MOV AX,CS:[SI] ;get logical no. in EMM
CLC
check_log_page1:
POP SI CX
RET
check_log_page2:
STC
JMP short check_log_page1
check_log_page ENDP
;--------------------------------------------------------------------
; Check EMM handle no.
; input
; DX : EMM handle
; output
; CF = 0 : OK
; CF = 1 : NG
;--------------------------------------------------------------------
check_handle PROC NEAR
PUSH DI
CMP DX,HANDLE_CNT
jnb check_handle1
MOV DI,DX
SHL DI,1
cmp byte ptr CS:[DI].handle_flag,0 ;active handle ?
JZ check_handle1
CLC
check_handle2:
POP DI
RET
check_handle1:
STC
jmp check_handle2
check_handle ENDP
;--------------------------------------------------------------------
; Set physical page.
; input
; AL : physical page no.
; BX : logical page no. in EMM (if BX=FFFFH then unmap)
; DX : EMM handle
;--------------------------------------------------------------------
set_phys_page PROC NEAR
PUSH AX CX DX DI
cbw
MOV DI,OFFSET map_table
MOV CL,SIZE phys_page_struct
MUL CL
ADD DI,AX
PUSH DX
MOV DX,CS:[DI].phys_page_port
MOV AX,BX
OUT DX,AX
POP DX
MOV CS:[DI].emm_handle2,DX ;handle
MOV CS:[DI].log_page_data,AX;logical page no.
POP DI DX CX AX
RET
set_phys_page ENDP
;--------------------------------------------------------------------
; Change mappable segment address to physical page number.
; input
; AX : mappable segment address
; output
; AX : physical page number
;--------------------------------------------------------------------
change_seg_page PROC NEAR
PUSH BX CX DI
XOR BX,BX
MOV DI,OFFSET map_table
MOV CX,PHYS_PAGES
CLC ;reset CF
change_seg_page2:
CMP AX,CS:[DI].phys_seg_addr
JZ change_seg_page1
ADD DI,SIZE phys_page_struct
INC BX
LOOP change_seg_page2
STC ;set CF
change_seg_page1:
MOV AX,BX
POP DI CX BX
RET
change_seg_page ENDP
;
; EMS 4.0 Data
;
ALIGN 2
;
; handle name buffer
;
handle_name LABEL BYTE
DB HANDLE_NAME_SIZE * HANDLE_CNT DUP (0)
;
; f24 Save area
;
f24_data DB SIZE phys_page_struct * 2 dup (0)
;
;--------------------------------------------------------------------
; EMM driver initilize program
;--------------------------------------------------------------------
emminit:
PUSH CX DX SI DI ES BP ;Store registers...
PUSH CS
POP DS
CALL getprm ;get parameters
test sysflg,1
jz emminit1
call set32
emminit1:
MOV SI,OFFSET start_msg ;display start messege.
CALL strdsp
CALL ckemsio ;check EMS i/o port
jc errems ;error ?
CALL ramchk ;check EMS memory
jc errems ;error ?
CALL instmsg ;display install message.
XOR AX,AX
MOV ES,AX
MOV AX,ES:[46CH]
ADD BX,AX ;make access key...
MOV access_key_h,BX
ADC AX,ES:[46EH]
ADD BX,AX
MOV access_key_l,BX
XOR DI,DI ;set system handle...
PUSH CS
POP ES
MOV byte ptr es:[DI].handle_flag,1;set system handle active.
INC es:handle_count ;handle count up
MOV AX,OFFSET emminit ;make 4.0 break address...
test sysflg,1
jz emminit2
MOV AX,OFFSET func16 ;make 3.2 break address...
emminit2:
ADD AX,0FH
MOV CL,4
SHR AX,CL
MOV CX,AX
MOV AX,CS
ADD AX,CX
LDS BX,ptrsav
MOV [BX].brkoff,0 ;break address offset set.
MOV [BX].brkseg,AX ;break address segment set.
XOR AX,AX
MOV ES,AX
MOV SI,19CH
MOV WORD PTR ES:[SI],OFFSET int67;set int67 offset.
MOV ES:[SI+2],CS ;set int67 segment.
JMP short emmint1
errems:
MOV SI,OFFSET notinst ;display error message
CALL strdsp
LDS BX,ptrsav
MOV [BX].brkoff,0 ;unload driver
MOV [BX].brkseg,CS
emmint1:
POP BP ES DI SI DX CX ;Restore registers...
JMP exit ;exit initial program.
;--------------------------------------------------------------------
; Get CONFIG.SYS parameters.
;--------------------------------------------------------------------
getprm PROC NEAR
PUSH DS
LES BX,ptrsav
MOV DI,ES:[BX].count
MOV AX,ES:[BX].start
MOV ES,AX
XOR CL,CL
getpr2:
MOV AL,ES:[DI]
CMP AL,CR
JZ getpr4
CMP AL,'/' ;set page frame address?
jne getpr5
inc di
MOV AL,ES:[DI]
OR AL,20h ;tolower
CMP AL,'p' ;set page frame address?
JNZ getpr3
INC DI
MOV AL,ES:[DI]
CMP AL,':'
JNZ getpr5
INC DI
CALL ascbin2 ;change data ascii -> binary.
JNC getpr8 ;error ?
JMP getpr5
getpr8:
MOV page_frame_seg,AX
JMP getpr5
getpr3:
CMP AL,'i' ;set EMS i/o port address?
JNZ getpr6
INC DI
MOV AL,ES:[DI]
CMP AL,':'
JNZ getpr5
INC DI
CALL ascbin2 ;change data ascii -> binary.
MOV emsio,AX
JMP getpr5
getpr6:
CMP AL,'q' ;set quiet mode
JNZ getpr1
OR CL,4
JMP getpr5
getpr1:
CMP AL,'n' ;set notest mode
JNZ getpr10
OR CL,8
JMP getpr5
getpr10:
CMP AL,'x' ;set extended memory test
JNZ getpr9
OR CL,2
JMP getpr5
getpr9:
CMP AL,'3' ;set 3.2 mode
JNZ getpr5
OR CL,1
getpr5:
INC DI
JMP getpr2
getpr4:
MOV sysflg,CL ;set system option flag.
POP DS
RET
getprm ENDP
;--------------------------------------------------------------------
; Display EMM install opening message.
;--------------------------------------------------------------------
instmsg PROC NEAR
PUSH AX BX CX DI
PUSH CS
POP ES
MOV AX,page_frame_seg
MOV DI,OFFSET segadr
CALL hbinasc
MOV AX,total_pages
MOV DI,OFFSET total_pg
CALL dbinasc
MOV AX,emsio
MOV DI,OFFSET pioadr
CALL hbinasc
MOV AX,total_pages
mov cl,4
shl ax,cl ; Multiply to 16
MOV DI,OFFSET totmem
CALL dbinasc5
MOV SI,OFFSET install_msg
CALL strdsp
POP DI CX BX AX
RET
instmsg ENDP
;--------------------------------------------------------------------
; Check EMS i/o port.
; output
; for lo-tech EMS board, we cannot read from the page registers
; hence we just return OK anyway.
; cf = 0 : OK
; cf = 1 : NG
;--------------------------------------------------------------------
ckemsio PROC NEAR
MOV DX,CS:EMSIO
; JJP IN AL,DX
; JJP CMP AL,255 ;check TRS flag
; JJP JE ckems3
ckems4:
CLC ;reset CF
RET
ckems3:
MOV SI,OFFSET hard_w_err ;display hardware error messege.
CALL strdsp
STC ;set CF
RET
ckemsio ENDP
;--------------------------------------------------------------------
; Check expanded memory.
; output
; cf = 0 : OK
; cf = 1 : NG
;--------------------------------------------------------------------
ramchk PROC NEAR
PUSH AX BX CX DX BP
PUSH CS
POP DS
MOV DI,OFFSET map_table
MOV CX,PHYS_PAGES
MOV BX,emsio
MOV SI,page_frame_seg
ramch14:
MOV [DI].phys_page_port,BX
MOV [DI].log_page_data,0
MOV [DI].phys_seg_addr,SI
ADD DI,SIZE phys_page_struct
ADD SI,0400H
MOV DX,BX ;disable physical pages ---
MOV AX,DIS_EMS
OUT DX,AX
ADD BX,2 ;each port is a word
LOOP ramch14
MOV SI,OFFSET pagemsg ;display page test msg..
CALL strdsp
IN AL,I8042+1 ;logical page test...
OR AL,4 ;system memory parity disable
and al,0feh
OUT I8042+1,AL
MOV DI,OFFSET log_page
XOR AX,AX
MOV CX,PAGE_MAX
XOR BX,BX
ramch9:
PUSH CX
MOV DX,emsio
OUT DX,AX
MOV DX,AX
CALL imgchk ; checks the page is RAM
jc ramch17
test byte ptr sysflg,8 ;supress memory test
jne ramch2
call testkb ; check if user press ESC
jnc ramch6
or byte ptr sysflg,8 ;supress memory test
jmp short ramch2
ramch6:
test byte ptr sysflg,2 ;long memory test
jne ramch3
CALL pagetst
jmp short ramch4
ramch3:
CALL spagetst
ramch4:
jc ramch8
ramch2:
MOV [DI],NOT_USE
INC BX
ramch17:
ADD DI,LOG_SIZE
ramch8:
POP CX
INC AX
LOOP ramch9
ramch16:
MOV total_pages,BX
MOV un_alloc_pages,BX
MOV AX,DIS_EMS
OUT DX,AX
IN AL,I8042+1 ;enable system memory parity..
AND AL,0FBH
or AL,1
OUT I8042+1,AL
CMP total_pages,0 ;total page zero?
JNZ ramch7
MOV SI,OFFSET nopage_err ;error message display
CALL strdsp
STC ;set CF
JMP ramch5
ramch7:
CLC
ramch5:
POP BP DX CX BX AX
RET
ramchk ENDP
;--------------------------------------------------------------------
; check memory size (1024 KByte)
;--------------------------------------------------------------------
imgchk PROC NEAR
CLD
PUSH AX CX SI DI DS
PUSH CS ;set ES <- CS..
POP ES
test dx,3
jnz imgchk2
IN AL,I8042+1
or AL,2
OUT I8042+1,AL
imgchk2:
MOV AX,DX
MOV DI,OFFSET tstpage
CALL dbinasc ;change binary -> ascii.
MOV SI,OFFSET tstpage ;display message..
CALL strdsp
IN AL,I8042+1
and AL,0fdh
OUT I8042+1,AL
MOV AX,page_frame_seg
MOV ES,AX
MOV ax,chkchr
mov es:[0],ax
cmp es:[0],ax
jne imgch1
xor ax,ax
mov es:[0],ax
CLC
jmp imgch3
imgch1:
STC
imgch3:
POP DS DI SI CX AX
RET
imgchk ENDP
;--------------------------------------------------------------------
; check logical page memory.
; input
; AX : logical page no.
;--------------------------------------------------------------------
pagetst PROC NEAR
CLD ;reset DF
PUSH AX BX CX DX DI
MOV AX,page_frame_seg ;set page frame address -> ES...
MOV ES,AX
MOV AX,chkchr
XOR DI,DI
MOV CX,2000h
REP STOSW
XOR DI,DI
MOV CX,2000h ;check pattan data...
REPZ SCASW
JZ pagets1
pagets2:
STC
JMP pagets5
pagets1:
XOR AX,AX ;clear expand memory...
XOR DI,DI
MOV CX,2000h
REP STOSW
CLC
pagets5:
POP DI DX CX BX AX
RET
pagetst ENDP
;--------------------------------------------------------------------
spagetst proc near
cld ;reset DF
push ax bx cx di ds
mov ax,page_frame_seg ;set page frame address -> ES...
mov es,ax
mov ds,ax
xor ax,ax
xor di,di
mov cx,2000h
rep stosw ;Fill area with zeros
mov bx,00ffh
; Pass 1
xor di,di
mov cx,4000h
spagets3:
mov al,[di]
cmp al,bh
jne spagets2
mov [di],bl
inc di
loop spagets3
; Pass 2
xor di,di
mov cx,4000h
xchg bl,bh
spagets4:
mov al,[di]
cmp al,bh
jne spagets2
mov [di],bl
inc di
loop spagets4
; Pass 3
mov di,4000h
dec di
xchg bl,bh
spagets6:
mov al,[di]
cmp al,bh
jne spagets2
mov [di],bl
dec di
jns spagets6
; Pass 4
mov di,4000h
dec di
xchg bl,bh
spagets7:
mov al,[di]
cmp al,bh
jne spagets2
mov [di],bl
dec di
jns spagets7
clc
spagets5:
pop ds di cx bx ax
ret
spagets2:
stc
jmp spagets5
spagetst endp
;--------------------------------------------------------------------
; Change data BYNARY -> ASCII (DEC) 5 digits
; input
; AX : binary data
; output
; ES:DI : ascii data (DEC)
;--------------------------------------------------------------------
dbinasc5:
PUSH AX BX CX DX SI
MOV SI,DI
MOV CX,5
MOV BX,10000
JMP SHORT dbinas0
;--------------------------------------------------------------------
; Change data BYNARY -> ASCII (DEC)
; input
; AX : binary data
; output
; ES:DI : ascii data (DEC)
;--------------------------------------------------------------------
dbinasc:
PUSH AX BX CX DX SI
MOV SI,DI
MOV CX,4
MOV BX,1000
dbinas0:
XOR DX,DX
dbinas1:
DIV BX
OR AL,AL
JNZ dbinas2
CMP SI,DI
JZ dbinas4
CMP BYTE PTR [SI],' '
JNZ dbinas2
dbinas4:
MOV AL,' '
CMP CL,1
JNZ dbinas3
XOR AL,AL
dbinas2:
ADD AL,'0'
dbinas3:
MOV SI,DI
STOSB
PUSH DX
XOR DX,DX
MOV AX,BX
MOV BX,10
DIV BX
MOV BX,AX
POP AX
LOOP dbinas1
POP SI DX CX BX AX
DEC DI
RET
;--------------------------------------------------------------------
; Change data BYNARY -> ASCII (HEX)
; input
; AX : binary data
; output
; ES:DI : ascii data (HEX)
;--------------------------------------------------------------------
hbinasc:
PUSH AX BX CX DX SI
MOV SI,DI
MOV CX,4
MOV BX,1000H
XOR DX,DX
hbinas1:
DIV BX
CMP AL,10
JC hbinas2
ADD AL,7
hbinas2:
ADD AL,'0'
hbinas3:
MOV SI,DI
STOSB
PUSH DX
XOR DX,DX
MOV AX,BX
MOV BX,10H
DIV BX
MOV BX,AX
POP AX
LOOP hbinas1
POP SI DX CX BX AX
DEC DI
RET
;--------------------------------------------------------------------
; Change data ASCII (DEC) -> BINARY
; input
; ES:DI = ascii data address (DEC)
; output
; AX = binary data
;--------------------------------------------------------------------
ascbin1:
PUSH BX CX DX
XOR DL,DL
MOV CX,4
XOR BX,BX
ascbin11:
MOV AL,ES:[DI]
CMP AL,' '
JZ ascbin13
CMP AL,TAB
JNZ ascbin14
ascbin13:
OR DL,DL
JNZ ascbin12
INC DI
JMP ascbin11
ascbin12:
OR DL,DL
JNZ ascbin16
STC
JMP ascbin15
ascbin14:
CMP AL,'0'
JC ascbin12
CMP AL,':'
JNC ascbin12
MOV DL,1
SUB AL,'0'
XOR AH,AH
XCHG BX,AX
PUSH DX
MOV DX,10
MUL DX
ADD BX,AX
POP DX
INC DI
LOOP ascbin11
ascbin16:
MOV AX,BX
CLC
ascbin15:
POP DX CX BX
RET
;--------------------------------------------------------------------
; Change data ASCII (HEX) -> BINARY
; input
; ES:DI = ascii data address (HEX)
; output
; AX = binary data
;--------------------------------------------------------------------
ascbin2:
PUSH BX CX DX
XOR DL,DL
MOV CX,4
XOR BX,BX
ascbin21:
MOV AL,ES:[DI]
CMP AL,' '
JZ ascbin23
CMP AL,TAB
JNZ ascbin24
ascbin23:
OR DL,DL
JNZ ascbin22
INC DI
JMP ascbin21
ascbin22:
OR DL,DL
JNZ ascbin27
STC
JMP ascbin25
ascbin24:
CMP AL,'0'
JC ascbin22
CMP AL,':'
JC ascbin26
CMP AL,'A'
JC ascbin22
CMP AL,'G'
JNC ascbin22
SUB AL,7
ascbin26:
MOV DL,1
SUB AL,'0'
XOR AH,AH
XCHG BX,AX
PUSH DX
MOV DX,10H
MUL DX
ADD BX,AX
POP DX
INC DI
LOOP ascbin21
ascbin27:
MOV AX,BX
CLC
ascbin25:
POP DX CX BX
RET
;--------------------------------------------------------------------
; STRINGS DISPLAY SUB
; input
; DS:SI : strings datas
;--------------------------------------------------------------------
strdsp:
test byte ptr cs:sysflg,4 ;supress output
jnz strdsp1 ;when in quet mode
PUSH AX DX ES
PUSH CS
POP ES
MOV DX,SI
MOV AH,9
INT 21H ;bdos call
POP ES DX AX
strdsp1:
RET
;
; Set EMS 3 mode
;
set32:
mov byte ptr msg_ver,'3'
mov byte ptr msg_ver+2,'2'
mov byte ptr f7_ver,32h
mov byte ptr f_max,4fh
ret
;
; Test ESC from keyboard
;
testkb:
push ax
mov ah,1
int 16h
jz testkb1
xor ah,ah
int 16h
cmp al,27
jne testkb1
stc
jmp short testkb2
testkb1:
clc
testkb2:
pop ax
ret
;____________________________________________________________________
;
; This is "EXE" part of this driver
;
;____________________________________________________________________
info:
push cs
pop ds
mov si, offset start_msg ; Display title & version
call strdsp
mov si, offset info_msg ; Display switches
call strdsp
mov ax,4c00h ;Exit to DOS
int 21h
;____________________________________________________________________
;--------------------------------------------------------------------
; EMM driver initial routine work data area
;--------------------------------------------------------------------
start_msg db CR,LF
DB 'XTEMM: EMM Driver for XTMax r02',CR,LF
db ' Based on Lo-tech EMM Driver for the Lo-tech 2MB EMS board.',CR,LF
db ' Based on modifications by Michael Karcher.',CR,LF
db ' Based on original works Copyright (c) 1988, Alex Tsourikov.',CR,LF
db ' All rights reserved.',CR,LF
db 'Using EMS '
msg_ver db '4.0',CR,LF,'$'
install_msg label byte
page_msg DB 'Page frame specification: Frame Segment at '
segadr DB '0000',CR,LF
total_pg DB '0000 pages found on EMS board at '
pioadr DB '0000',CR,LF
db 'Installation completed - '
totmem db '00000K RAM Available.',CR,LF,LF,'$'
hard_w_err DB 'No EMS board found.',CR,LF,'$'
nopage_err DB 'No EMS memory found.',CR,LF,'$'
notinst DB 'Installation failed - No EMS available.',CR,LF,LF,'$'
pagemsg DB '0000 Pages testing, Esc bypass test',CR,'$'
tstpage DB '0000',CR,'$'
info_msg db CR,LF
db 'Expanded Memory Manager for the XTMax expansion board.',CR,LF
db CR,LF
db 'Based on Lo-tech EMM Driver for the Lo-tech 2MB EMS board.',CR,LF
db 'Based on modifications by Michael Karcher.',CR,LF
db 'Based on original works Copyright (c) 1988, Alex Tsourikov.',CR,LF
db 'All rights reserved.',CR,LF
db CR,LF
db 'http://www.lo-tech.co.uk/wiki/2MB-EMS-Board',CR,LF
db 'Syntax: DEVICE=LTEMM.EXE [/switches]',CR,LF
db CR,LF
db ' /p:nnnn - Page frame address(D000)',CR,LF
db ' /i:nnn - EMS i/o port base address(260)',CR,LF
db ' /h:nnn - Maximal number of handles(64)',CR,LF
db ' /d:nn - Depth of contest saves(5)',CR,LF
db ' /n - Bypass memory test',CR,LF
db ' /x - Perform long memory test',CR,LF
db ' /3 - Use only EMS 3.2 functions',CR,LF
db ' /q - Quiet mode',CR,LF
db CR,LF
db 'Defaults in parentheses.',CR,LF,'$'
sysflg DB 0 ;system option flag
chkchr DW 55AAH
code ENDS
END INFO