[net.sources] MORERAM - IBMPC program to set memory size.

dob@ihuxj.UUCP (Daniel M. O'Brien) (07/19/84)

Someone in net.micro.pc wanted a program to set memory size correctly
when the switches have been set to 64k for quick boots. I also have
a version that takes the form of a DOS 2.0 device driver. This one,
MORERAM.ASM, should be invoked in your AUTOEXEC.BAT. 


		
			Daniel M. O'Brien
			AT&T Bell Laboratories
			IH 4A-258
			Naperville, IL 60566
		
			....!ihuxj!dob
		
----- cut here --- and don't forget to remove my signature at the end ----

title	moreram 12-16-83	[12-16-83]
;-------------------------------------------------------------------------------
; MORERAM.COM - by Daniel M. O'Brien (v 1.0) 21 Dec 1983
;
;	      - freely adapted from a PC-WORLD User-to-User column program
;		of the same name (object disassembled using ASMGEN) and from
;		a program shown in a DR. DOBBS Journal article
;		(Socha's 16 bit Toolkit) called MEMSIZE.
;
; This program has two (or three) purposes.
;
;	1) Allow a PC to use more memory than is allowed via the motherboard
;	memory switches (544 K bytes for the 64K motherboard and 640 K bytes
;	for the newer 256K motherboard). And because of 1)...
;
;	2) Allow faster power-up sequence by setting the motherboard memory
;	switch settings to 64 K bytes installed.
;
;	And as long as we are in the neighborhood...
;
;	3) Patch the ROM BIOS data area to indicate that this PC has four
;	floppy diskettes installed (instead of the normal two). This is for
;	ram disk emulation programs that require the motherboard equipment
;	options switch to be set to include the number of ram disks.
;	This is most notably required by the AST RESEARCH ramdisk program
;	called SUPERDRV. This code is commented out. To use it you must
;	uncomment out the code and reassemble. Search for the string:
;
;			;stub***
;
; Using MORERAM.
;
;	First, copy MORERAM.COM to your boot device (floppy or fixed).
;	Next, create or edit your AUTOEXEC.BAT file found on your
;	boot device to include MORERAM as the **FIRST** program that
;	will be executed. This is important as results are not guaranteed
;	if MORERAM is not the first command executed at boot time.
;	Next, open the covers of your PC and set the memory switches
;	to indicate that your PC only has 64K.
;
;	Now try rebooting your PC using the Alt-Ctrl-Del sequence.
;
;	MORERAM will first display a hello banner and the amount of
;	memory DOS thinks your PC has (should be 64K). Next, MORERAM
;	will pause a second or two while it determines how much memory
;	your PC really has. (It also clears this memory in the process
;	to eliminate PARITY 2 errors later).
;	Once the physical memory limit is determined, MORERAM will display
;	that amount and then automatically re-boot. (Don't get excited,
;	this won't loop indefinitely, because...) The next time MORERAM
;	is again executed from your AUTOEXEC.BAT it will find that the amount
;	of memory DOS thinks you have will be the same as that installed, and
;	a reboot will be avoided!
;
; I use this program on my PC that has 576K (64K + 512K) worth of memory.
; Also, I have successfully tested it with 704K (64K + 512K + 128K) of memory,
; but this requires placing memory into the semi-forbidden zone (segment A000)
; designated by IBM as "reserved". But that's ok, as long as you don't install
; memory beyond this into the B000 segment where monochrome and graphics display
; memory live!
;
; Questions or comments should be left for me (DAN OBRIEN) on Gene Plantz'
; BBS in Chicago, IL (312-882-4227). I will attempt to fix bugs that may
; crop up, but I make no guarantees. You use this at your own risk (just like
; I do!). If you break something valuable, it's your own fault.
;
;-------------------------------------------------------------------------------


lf	equ	0ah
cr	equ	0dh
;
;initial values :	cs:ip	0000:0100
;			ss:sp	0000:ffff

s0000	segment
	assume ds:s0000, ss:s0000 ,cs:s0000 ,es:s0000
	org	$+0100h

start:	jmp	begin

hello	db	"MORE RAM than switches (v 1.0) "
	db	"by Daniel M. O'Brien (21 Dec 1983)",cr,lf,'$'
inmem	db	" Current memory is $"
kbytes	db	" K bytes. $"
findmem db	cr,lf," Physical memory is $"
analyze db	" Analyzing & Clearing...$"
reboot	db	" Re-Booting...",cr,lf,'$'
done	db	cr,lf," Memory size is set correctly.",cr,lf,'$'

begin:
	mov	dx,offset hello 	; say hello
	mov	ah,9
	int	21h

	mov	dx,offset inmem 	; how much memory?
	mov	ah,9
	int	21h

	mov	ax,ds:2 	; get top segment number from program prefix

	push	ds		; save ds for later

	push	ax		; save top segment number for later
	mov	cl,6		; convert to K bytes
	shr	ax,cl
	call	decout		; and display

	mov	dx,offset kbytes	; display "K bytes"
	mov	ah,9
	int	21h

	mov	dx,offset analyze	; display analyzing message
	mov	ah,9
	int	21h

	xor	ax,ax		; stop parity errors while we poke around
	out	0a0h,al

	pop	ax		; recover top segment number

loop:	mov	bx,0		; look into this 16 byte "segment"
;	cmp	ax,0a000h	; is ax = beginning of "reserved" addrs?
				; stop at display memory instead!
	cmp	ax,0b000h	; is ax = beginning of "reserved" addrs?
	je	ramend		; yes, so end of ram
	mov	ds,ax		; no, so use this as segment
	mov	[bx],ax 	; write contents of ax to ds:bx...
	mov	cx,[bx] 	;... and read it back to cx
	cmp	ax,cx		; does data read = data written?
	jne	ramend		; if it not, then ran out of ram!

	mov	cx,8		;    else - reset this 16 byte area
	mov	es,ax
	xor	ax,ax		;      reset means 0000h
	xor	di,di
	rep	stosw		;    to prevent parity errors when used

	mov	ax,ds		; copy ds to ax...
	inc	ax		;... increment it...
	jmp	loop		;... and loop

ramend:
	mov	bx,ax		; found real end of ram - save it

	mov	al,80h		; enable parity errors for the future
	out	0a0h,al

	mov	ax,bx		; convert segments to K bytes
	mov	cl,6
	shr	ax,cl

	mov	bx,40h		; point to bios data area
	mov	ds,bx
	mov	bx,13h		; and to memory size word in particular

	cmp	[bx],ax 	; same size?
	je	exit		; yes-then we must have done this before

	mov	[bx],ax 	; else - update and
	push	ax

; remove comments to patch equipment flag to indicate 4 floppies attached.
; especially useful for AST RESEARCH's SUPERDRV.

;stub** mov	bx,10h		; point to equipment flag
;stub** mov	ax,[bx] 	; get equipment flag
;stub** or	ax,00c0h	; set installed floppy count to 4
;stub** mov	[bx],ax 	; and restore to proper spot

	mov	bx,10h		; point to equipment flag
	mov	ax,[bx] 	; get equipment flag
	or	ax,00c0h	; set installed floppy count to 4
	mov	[bx],ax 	; and restore to proper spot

	pop	ax		; get ds back but save ax on stack
	pop	ds
	push	ax

	mov	dx,offset findmem	; tell how much memory we found
	mov	ah,9
	int	21h

	pop	ax		; get K byte count
	call	decout

	mov	dx,offset kbytes
	mov	ah,9
	int	21h

	mov	dx,offset reboot	; tell them about reboot
	mov	ah,9
	int	21h

	int	19h		; re-boot

exit:
	pop	ds
	mov	dx,offset done
	mov	ah,9
	int	21h

	int	20h		; exit to dos


; quick and probably dirty - display decimal in ax routine

decout:
	push	ax
	push	bx
	push	cx
	push	dx

	xor	cx,cx		;counter of digits
	mov	bx,10		;divide by 10 for conversion

decimal$loop:
	xor	dx,dx		;clear for divide
	div	bx		;get remainder and quotient
	add	dx,'00'         ;make remainder ascii
	push	dx		;save it
	inc	cx		;and count it
	or	ax,ax		;out of digits?
	jnz	decimal$loop	;no-loop on the decimal

decimal$out:
	pop	dx		;get digit
	mov	ah,2		;print digit
	int	21h
	loop	decimal$out	;and loop

	pop	dx
	pop	cx
	pop	bx
	pop	ax
	ret

s0000	ends

	end	start
------------------------------------------------
-- 
		
			Daniel M. O'Brien
			AT&T Bell Laboratories
			IH 4A-258
			Naperville, IL 60566
		
			....!ihuxj!dob