	include	bds.lib
	include	z80.lib
	page	55
;
;********************************************************
;*							*
;*		BDS-C Supplementary Library		*
;*			release 3			*
;*							*
;*		Steve de Plater, May. 1982		*
;*		      66 Priam St.			*
;*		      Chester Hill,			*
;*		      NSW, 2162 			*
;*		      Australia 			*
;*		Phone: (02) 644 4009			*
;*							*
;********************************************************
;
;  THE (IN)FAMOUS BDS-C SUPPLEMENTARY LIBRARY
;    FOR THE EXIDY SORCERER COMPUTER SYSTEM
;
; int supp();
;
;   Returns the release number of the SUPP.CRL file
;   as a 16 bit number (heaven forbid)!

	function	supp

release equ	3	;DATE INSTALLED: 28 May 82
			;-------------------------

	lxi	h,release
	ret

	endfunc
;
;=============================================================
;
; int fillb(a1,a2,c,mode)
;  char c;
;  int a1, a2, mode;
;
;   if (mode==0)
;     Fills memory from address a1 to address a2 (inclusive)
;     with the byte c.
;   else
;     Fills memory from address a1 for a2 bytes with byte c.
;
	function	fillb

	call	arghak
	push	b

	lda	arg4		;"from/to" or "from/count"
	ora	a		;"from/to" - jump
	jz	fillb2
	lhld	arg2		;"COUNT" value
	push	h		;move it to
	pop	b		;BC
	jmp	fillb4		;and jump

fillb2: lhld	arg1		;"FROM" address
	mov	a,l		;turn it
	cma			;round
	mov	e,a		;into the DE pair
	mov	a,h
	cma
	mov	d,a		;to form"1's comp"
	inx	d		;and now"2's comp"
	lhld	arg2		;and now get"TO" addr
	dad	d		;ie"TO" - "FROM" = range
	push	h		;move it to
	pop	b		;BC (bytes to fill)
	inx	b		;include the end address too!

fillb4: lhld	arg1		;"FROM" address
	lda	arg3		;byte to fill with
	mov	e,a		;just somewhere to put it!

fillb6: mov	m,a		;and fill it in there!
	inx	h		;point to next fill address
	dcx	b		;one less to go!
	mov	a,b
	ora	c		;finished ?
	jz	fillb8		;yes - jump
	mov	a,e		;get fill byte again
	jmp	fillb6		;and fill with it

fillb8: pop	b		;all over
	ret

	endfunc
;
;=============================================================
;
; char *fill(saddr,eaddr,string,opt)
;   char *string;
;
;   If (opt==0)
;     Fills a contiguous block of RAM starting at saddr and
;     ending at eaddr with the string pointed to by"string".
;   else
;     Fills a contiguous block of RAM starting at saddr of
;     length eaddr bytes with the string pointed to.
;
;   The string is reused until the fill is complete.
;   Returns the address of the fill string.
;
	function	fill

	call	arghak
	push	b

	lda	arg4		;"from/to" or "from/count"
	ora	a
	jz	fill02		;"from/to" - jump
	lhld	arg2		;get"COUNT"
	push	h		;and move to
	pop	b		;BC
	jmp	fill04		;then jump

fill02: lhld	arg1		;"FROM" address
	mov	a,l		;turn it
	cma			;round
	mov	e,a		;into the DE pair
	mov	a,h
	cma
	mov	d,a		;to form"1's comp"
	inx	d		;and now"2's comp"
	lhld	arg2		;and now get"TO" addr
	dad	d		;ie"TO" - "FROM" = range
	push	h		;move it to
	pop	b		;BC (bytes to fill)
	inx	b		;include the end address too!

fill04: lhld	arg1		;"FROM" address
	xchg			;to DE
	lhld	arg3		;pointer to the "fill string"
	mov	a,m		;get first char to fill with
	ora	a		;null string ?
	jz	fill08		;if so then quit

fill06: stax	d		;and fill it in there!
	inx	d		;point to next fill address
	inx	h		;and next"fill string" char
	dcx	b		;one less to go!
	mov	a,b
	ora	c		;finished ?
	jz	fill08		;yes - jump
	mov	a,m		;get the next char to fill with
	ora	a		;is it a 0 (end of string)
	jnz	fill06		;no - fill with it then
	lhld	arg3		;back to the start of string
	mov	a,m		;get the first char
	jmp	fill06		;and fill with it

fill08: lhld	arg3		;return addr of the fill str
	pop	b		;all over
	ret

	endfunc
;
;==============================================================
;
; char *strrot(mode,s)
;   char *s;
;
;    Rotates the string (end around) pointed to by"s".
;    If mode==0 then rotate LEFT, and
;    if mode<>0 then rotate RIGHT.
;    Returns the address of the string.
;
	function	strrot

	call	arghak
	push	b

	lhld	arg2		;point to string
	push	h
	pop	d		;in DE as well
	inx	d		;and point ahead one
	mvi	c,0		;a counter to zero!
	lda	arg1		;get MODE switch
	ora	a		;rotate left ?
	jnz	strr06		;no - jump

	mov	a,m		;get char to rotate
	mov	b,a		;and save it
strr02: ldax	d		;get char
	ora	a		;have we reached end of str
	jz	strr04		;yes - jump
	mov	m,a		;rotate the char
	inx	h		;next please
	inx	d
	jmp	strr02		;and back for more
strr04: mov	a,b		;"the first shall be last.."
	mov	m,a
	jmp	strr14

strr06: mov	a,m		;first scan for end
	inx	h
	inr	c		;chars in string
	ora	a		;there yet ?
	jnz	strr06		;no - back we go
	dcx	h		;point back to the null
	dcx	h		;and then to last char
	dcr	c		;we don't count the null
	push	h		;and copy
	pop	d		;to DE
	dcx	d		;back one more
	mov	a,m		;the end char to save
	mov	b,a		;in B
strr10: dcr	c		;have we rotated enough ?
	jz	strr12		;yes - jump
	ldax	d		;get char to rotate
	mov	m,a		;and rotate it!
	dcx	h		;back one more
	dcx	d
	jmp	strr10		;next please
strr12: mov	a,b		;".and the last shall be first"
	mov	m,a
strr14: lhld	arg2		;return string address
	pop	b
	ret

	endfunc
;
;
;=============================================================
;
; int hi(i)
;  int i;
;
;   Returns the high byte of i.
;
	function	hi

	call	ma1toh
	mov	l,h
	mvi	h,0
	ret

	endfunc
;
;=============================================================
;
; int lo(i)
;  int i;
;
;   Returns the low byte of i.
;
	function	lo

	call	ma1toh
	mvi	h,0
	ret

	endfunc
;
;============================================================
;
; int cursor(x,y);
;
;   moves the cursor to position x (line), y (column) of
;   the Sorcerer screen. (if possible)!
;   Returns the offset from the beginning of the screen RAM
;   of the new cursor position.

	function	cursor

	call	arghak		;get the arguements
	push	b		;we need it!

getiy	equ	0e1a2h		;Exidy Monitor entry points
wcur	equ	0e9cch		;write cursor
rec	equ	0e9e8h		;remove the old one
ptrset	equ	0e9d6h		;find the cursor address

	lda	arg2		;get the column
	ora	a
	jm	curses		;you can't have a -ve column!
	cpi	64
	jnc	curses		;or one > 63
	lda	arg1		;get the line
	ora	a
	jm	curses		;you can't have a -ve line!
	cpi	30
	jnc	curses		;or one > 29

	lda	arg1+1
	ora	a
	jnz	curses
	lda	arg2+1
	ora	a
	jnz	curses

	call	getiy
	call	rec
	lda	arg1
	mov	e,a		;and multiply it be 64
	mvi	d,0
	mvi	b,6
cur04:	sla	e
	rl	d
	dcr	b
	jnz	cur04
	stiy	e,68h		;and save it in the MWA
	stiy	d,69h		;(both bytes)
	lda	arg2		;now get the column
	stiy	a,6ah		;and save it too
	stiyi	0,6bh		;high byte is zero
	call	wcur		;and put the cursor there!

curses: call	ptrset		;just in case we hadn't
	pop	b		;told you we'd need it
	ret			;home we go

	endfunc

pushix	equ	0e5ddh
pushiy	equ	0e5fdh
inxix	equ	023ddh
scan	equ	0e225h
;
;==============================================================
;
; int remcur()
;
;   Removes the cursor from the screen.
;   Returns the cursor address.
;
	function	remcur

	push	b
	call	getiy
	call	rec
	pop	b
	ret

	endfunc
;
;==============================================================
;
; int mwa();
;
;   Returns the MWA address.
;
	function	mwa

	call	getiy
	dw	pushiy
	pop	h
	ret

	endfunc
;
;=============================================================
;
; int exycall();
;
;   Calls the Exidy Standard Monitor
;   using the monitor command found at MWA.
;   Returns 0 if illegal command (or no command)
;     or    1 if command successfully executed.
;
;   WARNING: This function may not return AT ALL if you
;   crash it in the Monitor itself! ;BE WARNED!
;
	function	exycall

	push	b		;just in case!
	dw	pushiy		;move IY
	pop	h		;  to HL
	call	scan		;get delims
	jz	exyc5 		;NONE!
	db	0ddh,021h,012h,0e3h
exyc1:	push	h
	dw	pushix
	mvi	b,2
exyc2:	db	0ddh,07eh,00h
	cmp	m
	jnz	exyc4
	inx	h
	dw	inxix
	dcr	b
	jnz	exyc2
	pop	d
	pop	d
	lxi	b,exyc6
	push	b
exyc3:	db	0ddh,06eh,00h
	db	0ddh,066h,01h
	pchl
exyc4:	db	0ddh,0e1h
	pop	h
	dw	inxix
	dw	inxix
	dw	inxix
	dw	inxix
	db	0ddh,07eh,00h
	ora	a
	jnz	exyc1
exyc5:	lxi	h,0
	pop	b
	ret
exyc6:	lxi	h,1
	pop	b
	ret

	endfunc
;
;=============================================================
;
; int hidecur(c)
;   char c;
;
;	Hides the character passed under the cursor (so that
;	when the cursor is moved then"all secrets will be
;       made known" (or at least displayed on the screen))!
;
;	Returns the cursor address.
;
	function	hidecur

	call	arghak
	push	b

	call	getiy			;we may not have it
	lda	arg1			;the char to hide
	stiy	a,067h			;and hide it there!
	call	ptrset			;get cursor address

	pop	b
	ret				;and return

	endfunc
