home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Simtel MSDOS 1992 June
/
SIMTEL_0692.cdr
/
msdos
/
sysutl
/
addram10.arc
/
ADDRAM.ASM
next >
Wrap
Assembly Source File
|
1989-02-14
|
15KB
|
404 lines
; Copyright (c) 1989 by Marty Del Vecchio for personal use only.
; May not be sold under any circumstances. For questions call me
; at (508) 820-1544, or the Channel 1 BBS at (617) 354-8873).
;
; To create ADDRAM.COM, you must assemble this file:
;
; MASM addram;
;
; then link it to an executable:
;
; LINK addram;
;
; then turn it into a .COM file:
;
; EXE2BIN addram.exe addram.com
;
; then delete the .EXE file:
;
; DEL addram.exe
;
get_vector equ 35h
emm_int equ 67h
EMM_name_length equ 8
code_seg_a segment
assume cs:code_seg_a, ds:code_seg_a
org 100h
addram proc far
start: jmp begin
copyrt db 0Dh, 0Ah
db 'ADDRAM 1.00 Copyright (C) 1989 by Marty Del Vecchio', 0Dh, 0Ah, 00h
no_EMM_msg db 'Expanded Memory Manager not found--no EMS installed.', 0Dh, 0Ah, 00h
EMM_error_msg db 'Expanded Memory Manager reports an error.', 0Dh, 0Ah, 00h
bad_ver_msg db 'This program requires version 4.0 expanded memory.', 0Dh, 0Ah, 00h
need_640_msg db 'This program requires exactly 640K of installed DOS memory.', 0Dh, 0Ah, 00h
not_last_msg db 'This program''s memory allocation block is not the last', 0Dh, 0Ah
db 'in DOS''s chain. Cannot change memory if not at end.', 0Dh, 0Ah, 00h
no_A000_msg db 'Expanded Memory Manager cannot map memory at segment A000.', 0Dh, 0Ah, 00h
no_alloc_msg db 'Not enough expanded memory available.', 0Dh, 0Ah, 00h
no_map_msg db 'Error while mapping expanded memory at A000.', 0Dh, 0Ah, 00h
bad_name_msg db 'Error assigning name to expanded memory handle.', 0Dh, 0Ah, 00h
name_used_msg db 'ADDRAM''s name already in use by another handle.', 0Dh, 0Ah, 00h
added_msg db ' KB memory succesfully added to DOS.', 0Dh, 0Ah, 00h
usage_msg db 'Usage: ADDRAM [/#]', 0Dh, 0Ah
db ' /# = add # 16KB pages to DOS (1-6 pages, 16-96KB)', 0Dh, 0Ah, 00h
EMM_name db 'EMMXXXX0'
handle_name db 'ADDRAM00' ; 8 characters, pad with 0
handle dw 0
mappable_buf dd 64 dup (0) ; Buffer for mappable address array
mappable_count dw 0 ; # of consec. mappable addresses
pages_asked db 6 ; Assume they want 96K for now
pages_used db 0
map_array label byte ; 6 map entries for map function
dw 00h, 0A000h
dw 01h, 0A400h
dw 02h, 0A800h
dw 03h, 0AC00h
dw 04h, 0B000h
dw 05h, 0B400h
; Program entry point
begin: call say_hello ; Print messages, check command line
jc error_exit
call check_DOS ; Can we add memory to DOS?
jc error_exit
call check_EMM ; Is EMM around and acceptable?
jc error_exit
call check_A000 ; Are pages mappable and available?
jc error_exit
call map_pages ; Allocate memory and map at A000
jc error_exit
call tell_DOS ; Tell DOS about new memory
jc error_exit
call tell_user ; Tell user about new memory
success_exit: mov ax, 4C00h ; Terminate, signal success
int 21h
error_exit: mov ax, 4C01h ; Terminate, signal failure
int 21h
addram endp
say_hello PROC near
mov si, offset copyrt ; Say hello first
call printf_si
check_params: mov byte ptr pages_asked, 6 ; Assume they want 6 pages
mov si, 81h
call skip_white ; Skip white space
cmp al, 0Dh ; All done?
je hello_exit ; Yes, exit
cmp al, '/' ; Specifying parameter?
jne usage ; No, invalid command line
found_param: lodsb ; Get character specified
cmp al, '1' ; Is it 1?
jb usage ; Below, error!
cmp al, '6' ; Is it 6?
ja usage ; Above, error!
found_num: sub al, '0' ; Convert to number
mov byte ptr pages_asked, al ; Store as requested # of pages
clc
jmp hello_exit
usage: mov si, offset usage_msg
call printf_si
stc
jmp hello_exit
hello_exit: ret
say_hello ENDP
skip_white PROC near
next_ch: lodsb ; Load next character
cmp al, 20h ; Is it space?
je next_ch ; Yes, get next
cmp al, 09h ; Is it tab?
je next_ch ; Yes, get next
ret
skip_white ENDP
check_DOS PROC near
mov ax, ds:0002 ; Get end of mem allocation block (PSP)
cmp ax, 0A000h ; Is it A000?
jne need_640 ; No, signal error
have_640: push ds
mov ax, cs ; Point ds to our MCB
dec ax
mov ds, ax
mov al, ds:0000 ; 4Dh if not last, 5Ah if last
pop ds
cmp al, 5Ah ; Is this the last block:
jne not_last ; No, signal error
is_last: clc ; Everything OK, signal
jmp DOS_exit ; Get out
need_640: mov si, offset need_640_msg
jmp DOS_print
not_last: mov si, offset not_last_msg
DOS_print: call printf_si
stc
jmp DOS_exit
DOS_exit: ret
check_DOS endp
check_EMM PROC near
mov ah, get_vector
mov al, emm_int
int 21h
mov di, 0Ah
lea si, EMM_name
mov cx, EMM_name_length
cld
repe cmpsb
jne not_installed
check_version: mov ah, 46h ; Get EMM version #
int 67h ; Major number hi nibble of al
or ah, ah ; Status OK?
jnz EMM_error ; No, signal error.
mov cl, 4
shr al, cl ; al = major version number
cmp al, 4 ; Is it 4 or above?
jb bad_version ; No, signal error
check_name: mov ax, 5401h ; Check if handle name exists
mov si, offset handle_name
int 67h
or ah, ah ; Return 0?
jz name_used ; No, some type of error
EMM_is_ok: clc
jmp check_exit
not_installed: mov si, offset no_EMM_msg
call printf_si
stc
jmp check_exit
EMM_error: mov si, offset EMM_error_msg
jmp EMM_print
bad_version: mov si, offset bad_ver_msg
jmp EMM_print
name_used: mov si, offset name_used_msg
EMM_print: call printf_si
stc
check_exit: ret
check_EMM ENDP
check_A000 PROC near
mov ax, ds
mov es, ax
mov ax, 5800h ; Get mappable physical address array
mov di, offset mappable_buf
int 67h
inc cx ; cx = # of entries + 1 now
find_A000: mov si, offset mappable_buf
next_entry: dec cx ; One more looked at
or cx, cx ; Are we finished?
jz no_A000 ; Yes, didn't find A000 in table
lodsw ; DS:SI into ax
cmp ax, 0A000h ; Do we have A000?
je A000_ok ; Yes, proceed
inc si
inc si ; Point to next entry
jmp next_entry
A000_ok: add si, 2
mov bl, 01h ; BL = number of mappables found
lodsw ; Get next segment address
cmp ax, 0A400h ; Is it A400?
jne can_map ; No, only one page mappable, OK
add si, 2
inc bl ; Found two now
cmp bl, byte ptr pages_asked
je can_map ; This is all they want, proceed
lodsw ; Get next segment address
cmp ax, 0A800h ; Is it A800?
jne can_map ; No, only two pages mappable, OK
add si, 2
inc bl ; Found three now
cmp bl, byte ptr pages_asked
je can_map ; This is all they want, proceed
lodsw ; Get next segment address
cmp ax, 0AC00h ; Is it AC00?
jne can_map ; No, only three pages mappable, OK
add si, 2
inc bl ; Found four now
cmp bl, byte ptr pages_asked
je can_map ; This is all they want, proceed
lodsw ; Get next segment address
cmp ax, 0B000h ; Is it B000?
jne can_map ; No, only four pages mappable, OK
add si, 2
inc bl ; Found five now
cmp bl, byte ptr pages_asked
je can_map ; This is all they want, proceed
lodsw ; Get next segment address
cmp ax, 0B400h ; Is it B400?
jne can_map ; No, only five pages mappable, OK
add si, 2
inc bl ; Found six now
can_map: mov byte ptr pages_used, bl
clc
jmp A000_exit
no_A000: mov si, offset no_A000_msg
call printf_si
stc
jmp A000_exit
A000_exit: ret
check_A000 ENDP
map_pages PROC near
mov ah, 43h ; Function 43h--allocate pages
xor bh, bh
mov bl, byte ptr pages_used
int 67h
or ah, ah ; EMM status OK?
jnz alloc_error ; No, signal error
mov word ptr handle, dx ; Yes, store handle
name_handle: mov si, offset handle_name ; Give handle a name
mov ax, 5301h
int 67h
or ah, ah ; Error naming?
jnz name_error ; Yes
alloc_OK: mov ax, 5001h ; Function 50h, map multiple pages
xor ch, ch
mov cl, byte ptr pages_used ; CX=count of pages
mov si, offset map_array ; DS:SI = map array
int 67h ; Map memory
or ah, ah ; Error mapping?
jnz map_error ; Yes, signal error
map_OK: clc ; Signal success
jmp map_exit ; And exit
alloc_error: mov si, offset no_alloc_msg
call printf_si
stc
jmp map_exit
name_error: mov si, offset bad_name_msg
jmp map_print
map_error: mov si, offset no_map_msg
map_print: call printf_si
mov ah, 45h ; Deallocate pages first
mov dx, word ptr handle
int 67h
stc
map_exit: ret
map_pages ENDP
tell_DOS PROC near
mov ax, ds ; es = ds, make sure
mov es, ax
xor ah, ah
mov al, byte ptr pages_used ; retrieve # of pages to add
mov cl, 0Ah
shl ax, cl ; ax = paragraphs adding
mov dx, cs
dec dx
mov ds, dx ; ds = our Memory Control Block
add word ptr ds:[0003], ax ; MCB: paragraphs allocated
add word ptr es:[0002], ax ; PSP: end of memory allocation
mov cl, 6
shr ax, cl ; ax = KB adding now
mov dx, 40h
mov ds, dx ; ds-> BIOS data area
add word ptr ds:[0013h], ax ; Add to BIOS mem size
mov ax, cs
mov ds, ax ; Restore ds
ret
tell_DOS ENDP
tell_user PROC near
xor ah, ah
mov al, byte ptr pages_used
mov cl, 4
shl al, cl ; al = KB added
mov bl, 10
div bl ; al = (al div 10), ah = remainder
mov bx, ax ; Save in bx
mov ah, 06h ; DOS function 6, character output
mov dl, bl
add dl, '0'
int 21h ; Print out tens digit
mov ah, 06h
mov dl, bh
add dl, '0'
int 21h ; Print out ones digit
mov si, offset added_msg
call printf_si
ret
tell_user ENDP
printf_si PROC near
mov ah, 06h ; DOS function 06h, console output
next_char: lodsb ; Next char into al
or al, al ; Is it zero?
jz printf_done ; Yes, exit
mov dl, al ; Put char into dl
int 21h ; Output character
jmp next_char ; Loop to next character
printf_done: ret
printf_si ENDP
code_seg_a ends
end start