cseg	segment para public 'code'
org	100h
getmem	proc far

intaddr equ 60h*4		; interrupt address - int 60 hex

; Memory-resident program to get and hold a block of memory.
; To reserve a block of memory, enter 'GETMEM nn', where nn is the
; number of KB to be allocated. For example, 'GETMEM 32' reserves 32KB.
; NN can be from 1 to 63. The address of the block is saved at interrupt
; 60h (0:180h - 0:183h), with the length in the  first word, and the segment
; in the second word.
; A '/x' option can be used to keep the program from allocating memory if
; a block of memory is already allocated.

	assume cs:cseg,ds:cseg,ss:nothing,es:nothing

p000:				; read command line
	mov dx,offset copyr
	call p100		; print copyright
	mov si,80h		; point to start of command line
	mov ch,0
	mov cl,[si]		; get length
	mov ax,0
	mov bx,0
p010:	inc si			; point to next character
	mov bl,[si]		; get the character
	cmp bl,'/'              ; is it a slash?
	jnz p015		; no
	mov bh,[si+1]		; get next character
	cmp bh,'x'              ; is it 'x'?
	jz p012 		; yes
	cmp bh,'X'              ; is it 'X'?
	jz p012 		; yes
	mov bh,0
	jmp p015

p012:	mov norerun,bh		; set rerun flag
	mov bh,0

p015:	cmp bl,'0'              ; is it less than zero?
	jb p020 		; yes
	cmp bl,'9'              ; is it greater than nine?
	ja p020 		; yes
	sub bl,'0'              ; convert to binary
	push cx 		; save cx
	mov cx,10
	mul cx			; multiply current ax by 10
	pop cx
	add ax,bx		; add latest digit
p020:	loop p010		; all done?

	cmp ax,1		; is memory less than 1?
	jb p090 		; yes
	cmp ax,63		; is memory greater than 63?
	ja p090 		; yes
	push ax 		; save ax

	aam			; set up message
	xchg ah,al
	add ax,3030h		; make it ascii
	cmp al,30h		; leading zero?
	jnz p030		; no
	mov al,20h		; make it a space

p030:	mov msg1mem,ax		; move to message area

	pop ax			; restore ax
	mov cl,10
	sal ax,cl		; convert to KB
	mov memsize,ax		; save memory size

	push es 		; set interrupt 60h
	mov ax,0
	mov es,ax
	mov di,intaddr		; interrupt address
	mov al,norerun		; is /x option present?
	cmp al,0
	jz p050 		; no

	mov ax,es:[di]
	cmp ax,0		; any memory reserved?
	jz p050 		; no
	pop es
	int 20h 		; yes - terminate

p050:	mov ax,memsize		; length of block
	push cs
	pop bx			; code segment
	mov es:[di],ax		; modify interrupt
	mov es:[di+2],bx
	pop es
	mov dx,offset msg1	; print message
	call p100
	mov dx,memsize		; set block size
	int 27h 		; terminate and stay resident

p090:				; print error message
	mov dx,offset msg2
	call p100
	int 20h 		; terminate

p100	proc near		; print message
	push ax
	mov ah,9
	int 21h
	pop ax
	ret
p100	endp

memsize dw 0			; requested memory size
norerun db 0			; rerun flag - non-zero if /x option
copyr	db 'GETMEM - Copyright 1983 Data Base Decisions',10,13,'$'
msg1	db 'Reserving '
msg1mem dw '..'
	db ' KB of memory.',10,13,'$'
msg2	db 'Missing/invalid memory specification',7,10,13,'$'

getmem	endp
cseg	ends
end	getmem
of memory.