;	which.asm
;
;	this program returns size and version
;	of cp/m you are running.
;	this can be useful when running under
;	fast, despool, ddt, sid, etc.
;
;	version of 25 nov 1980
;
;	by David Fiedler
;	   InfoPro Systems
;	   Denville, NJ

;	Copyright 1980 InfoPro Systems.  This program may
;	not be used for commercial purposes without written
;	permission from InfoPro Systems.  However it may
;	be used by hackers to their heart's content as long
;	as they don't try to sell it or pass it off as their
;	own.
;
;	Please note that this has not been tried out under
;	other than CP/M 2.2, although it should work fine.
;
;	code adapted from tpa3.asm by:
;	   Ron Fowler	
;	   Westland, Mich.
;
;	   fixes and code optimizations to tpa3 by
;	   Keith Petersen
;
	org	100h
;
base:	lxi	h,0
	dad	sp	;get local stack
	shld	oldstk	;save old stack

	call	tb
msg:	db	'Welcome to $'

tb:	mvi	c,9	;print msg function
	pop	d	;get msg adrs
	call	5	;print it

	mvi	c,12	;get version number function
	call	5
	shld	retword	;hold for later
	mov	a,h	;multi-tasking?
	cpi	1
	jz	mpm	;yes.
	mvi	a,'C'	;no.
	sta	versms	;so announce properly
	jmp	getsiz
mpm:
	mvi	a,'M'
	sta	versms
		
getsiz:	lhld	6	;get the bdos address
	xchg		;into de
	lhld	retword
	mov	a,l
	cpi	0
	jnz	newone
	lxi	h,-3100h	;get 16k bdos address for cp/m 1.4
	dad	d		;subtract it, answer left in hl
	lxi	d,(16 * 1024)	;this would print 16k if addresses were equal
	dad	d		;not efficient but clear at least
	jmp	print
newone:	
	lxi	h,-3c00h	;20k bdos offset for 2.0
	dad	d
	lxi	d,(20 * 1024)
	dad	d
print:	
	mov	a,h
	rrc			;divide by 2
	rrc			;divide by 4
	ani	7fh		;mask to positive
	mov	l,a		;effectively divide by 2 ^ 8
	mvi	h,0		;for a total of 2 ^ 10 = 1K
	call	decout		;print it
	call	tb1		;print the line
sizems:	db	'K '
versms:	db	' P/M Version $'
;
;
tb1:	mvi	c,9	;print msg function
	pop	d	;get msg adrs
	call	5	;print it
;
getnum:
	lhld	retword
	mov	a,l
	cpi	0	;previous to 2.2?
	jz	oldone	;yes.
	push	psw	;save value
	ani	0f0h	;get high nibble
	rrc
	rrc
	rrc
	rrc		;into low nibble
	adi	'0'	;make ascii
	call	co	;print
	mvi	a,'.'
	call	co
	pop	psw	;retrieve lower four bits
	ani	0fh	;mask them
	adi	'0'
	call	co
	call	tb2
	db	13,10,'$'
;
oldone:
	call	tb2
	db	'1.4',13,10,'$'
;
;
tb2:	mvi	c,9	;print msg function
	pop	d	;get msg adrs
	call	5	;print it
	lhld	oldstk	;restore ccp stack
	sphl
	ret		;back to the ccp
;
;	subroutines
;
; Console output routine
;	prints character in 'a' register
;
co:	push	h
	push	d
	push	b
	mov	e,a	;character to e for CP/M
	mvi	c,2	;print console function
	call	5	;print character
	pop	b
	pop	d
	pop	h
	ret
;
; Decimal output routine
;	this routine has following
;	entry and external parameters:
;
;	   entry:    hl=binary number to print in decimal
;	   external calls: co routine
;	   ** note...this routine is recursive, and uses
;	   6 bytes of stack for each recursive call, in ad-
;	   dition to any stack space used by the co routine.
;
decout: push	b
	push	d
	push	h
	lxi	b,-10
	lxi	d,-1
;
decou2: dad	b
	inx	d
	jc	decou2
	lxi	b,10
	dad	b
	xchg
	mov	a,h
	ora	l
	cnz	decout
	mov	a,e
	adi	'0'
	call	co
	pop	h
	pop	d
	pop	b
	ret
;
stack	equ	$+80	;40 level stack
;
oldstk:	ds	2
retword:ds	2

	end	base
