home *** CD-ROM | disk | FTP | other *** search
- ; 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
-
-
-
-