DataMuseum.dk

Presents historical artifacts from the history of:

RegneCentralen RC700 "Piccolo"

This is an automatic "excavation" of a thematic subset of
artifacts from Datamuseum.dk's BitArchive.

See our Wiki for more about RegneCentralen RC700 "Piccolo"

Excavated with: AutoArchaeologist - Free & Open Source Software.


top - download

⟦2abb7a548⟧ TextFile

    Length: 13952 (0x3680)
    Types: TextFile
    Names: »DEFF2A.CSM«

Derivation

└─⟦b35f94715⟧ Bits:30003295 BDS C version 1.50 arbejdsdiskette til RC703 Piccolo
└─⟦b35f94715⟧ Bits:30005324 BDS C version 1.50 arbejdsdiskette til RC703 Piccolo
    └─ ⟦this⟧ »DEFF2A.CSM« 

TextFile

;
;	BD Software C Compiler v1.50
;	Standard Library Machine Language Functions (part A)
;	Copyright (c) 1982 by Leor Zolman
;
; This file is in "CSM" format; to convert to CRL format,
; use CASM.SUB in conjunction with CASM.COM, ASM.COM and DDT.COM.
; 
; Functions appearing in this file:
;
; 	getchar	kbhit	ungetch	putchar	putch	gets	rand	srand
;	srand1	nrand	csw	setmem	movmem	call	calla	inp
;	outp	peek	poke	sleep	pause	exit	bdos	bios
;	biosh	codend	externs	endext	topofmem 	exec	execv
;	sbrk	rsvstk	memcmp
;

	INCLUDE "bds.lib"

	FUNCTION	getchar
	lda	ungetl	;any character pushed back?
	ora	a
	mov	l,a
	jz	gch2
	xra	a	;yes. return it and clear the pushback
	sta	ungetl	;byte in C.CCC.
	mvi	h,0
	ret

gch2:	push	b
	mvi	c,conin
	call	bdos
	pop	b
	cpi	cntrlc	;control-C ?
	jz	exit	;if so, exit the program.
	cpi	1ah	;control-Z ?
	lxi	h,-1	;if so, return -1.
	rz
	mov	l,a
	cpi	cr	;carriage return?
	jnz	gch3
	push	b
	mvi	c,conout	;if so, also echo linefeed
	mvi	e,lf
	call	bdos
	pop	b
	mvi	l,newlin	;and return newline (linefeed)..

gch3:	mvi	h,0
	ret
	ENDFUNC

	FUNCTION	kbhit
	lda	ungetl	;any character ungotten?
	mvi	h,0
	mov	l,a
	ora	a
	rnz		;if so, return true

	push	b
	mvi	c,cstat	;else interrogate console status
	call	bdos
	pop	b

	ora	a	;0 returned by BDOS if no character ready
	lxi	h,0
	rz		;return 0 in HL if no character ready
	inr	l	;otherwise return 1 in HL
	ret
	ENDFUNC kbhit

	FUNCTION	ungetch
	lda	ungetl
	mov	l,a
	push	h
	call	ma2toh
	sta	ungetl
	pop	h
	mvi	h,0
	ret
	ENDFUNC ungetch

	FUNCTION	putchar
	call	ma1toh	;get character in A
	push	b
	mvi	c,conout
	cpi	newlin	;newline?
	jnz	put1	;if not, just go put out the character
	mvi	e,cr	;else...put out CR-LF
	call	bdos
	mvi	c,conout
	mvi	a,lf

put1:	mov	e,a
	call	bdos

put2:	mvi	c,cstat	;now, is input present at the console?
	call	bdos
	ora	a
	jnz	put3
	pop	b	;no...all done.
	ret

put3:	mvi	c,conin	;yes. sample it (this will always echo the
	call	bdos	;	character to the screen, alas)
	cpi	cntrlc	;is it control-C?
	jz	exit	;if so, abort and reboot
	pop	b	;else ignore it.
	ret
	ENDFUNC

	FUNCTION	putch
	call	ma1toh
	push	b
	mvi	c,conout
	mov	e,a
	cpi	newlin
	jnz	putch1	;if not newline, just put it out
	mvi	e,cr	;else put out CR-LF
	call	bdos
	mvi	c,conout
	mvi	e,lf
putch1:	call	bdos
	pop	b
	ret
	ENDFUNC

	FUNCTION	gets
	call	ma1toh	;get destination address
	push	b	;save BC
	push	h
	push	h
	lxi	h,-150	;use space below stack for reading line
	dad	sp
	push	h	;save buffer address
	mvi	m,88h	;Allow a max of about 135 characters
	mvi	c,getlin
	xchg		;put buffer addr in DE
	call	bdos	;get the input line
	mvi	c,conout
	mvi	e,lf	;put out a LF
	call	bdos
	pop	h	;get back buffer address
	inx	h	;point to returned char count
	mov	b,m	;set B equal to char count
	inx	h	;HL points to first char of line
	pop	d	;DE points to start destination area
copyl:	mov	a,b	;copy line to start of buffer
	ora	a
	jz	gets2
	mov	a,m
	stax	d
	inx	h
	inx	d
	dcr	b
	jmp	copyl
	
gets2:	xra	a	;store terminating null
	stax	d
	pop	h	;return buffer address in HL
	pop	b
	ret
	ENDFUNC


	FUNCTION	rand
	lhld	rseed
	xchg
	mvi	a,48h
	ana	e
	jz	rand1
	jpe	rand1
	stc
rand1:	lhld	rseed+2
	mov	a,h
	ral
	mov	h,a
	mov	a,l
	ral
	mov	l,a
	shld	rseed+2
	mov	a,d
	ral
	mov	h,a
	mov	a,e
	ral
	mov	l,a
	shld	rseed
	mov	a,h
	ani	7fh
	mov	h,a
	ret
	ENDFUNC

	FUNCTION	srand
	call	ma1toh
	mov	a,h
	ora	l
	jz	srand2
	shld	rseed
	shld	rseed+2
	ret

srand2:	lxi	d,stg1
	push	b
	mvi	c,9
	call	bdos
	lxi	h,0bdbdh
srand3:	push	h
	mvi	c,11
	call	bdos
	pop	h
	inx	h
	inx	h
	inx	h
	ani	1
	jz	srand3
	shld	rseed
	shld	rseed+2
	mvi	c,conout
	mvi	e,cr
	call	bdos
	mvi	c,conout
	mvi	e,lf
	call	bdos
	mvi	c,conin	;clear the character
	call	bdos
	pop	b
	ret
stg1:	db 'Wait a few seconds, and type a CR: $'
	ENDFUNC


	FUNCTION	srand1
	EXTERNAL	puts
	call	ma1toh
	push	h
	call	puts	;print prompt string
	pop	h
	push	b
	lxi	h,5678h
sr1a:	push	h
	mvi	c,cstat
	call	bdos
	pop	h
	inx	h
	inx	h
	inx	h
	ora	a
	jz	sr1a
	shld	rseed
	shld	rseed+2
	pop	b
	ret
	ENDFUNC

	FUNCTION	nrand
	EXTERNAL	puts
	call	arghak
	lhld	arg1	;get n (1st arg)
	mov	a,h
	ana	l
	cpi	255	;was it -1 (set seed) ?
	jnz	nrand1
	lhld	arg2	;copy seed
	shld	seed
	lhld	arg3
	shld	seed+2
	lhld	arg4
	shld	seed+4	
	ret		;all done

nrand1:	push	b
	mov	a,h	;look at first arg again
	ora	l
	jnz	nrand3	;is it 0 (randomize)?
	lhld	arg2
	push	h	;yes. print out string
	call	puts	;call	puts
	pop	d
	lxi	h,5a97h	;yes. start w/something odd
nrand2:	push	h
	mvi	c,cstat	;interrogate console status
	call	bdos
	pop	h
	inx	h	;and keep it odd
	inx	h	;and growing
	ora	a
	jz	nrand2	;until user types something.
	shld	seed	;then plaster the value all over the
	shld	seed+2	;seed.
	shld	seed+4
	pop	b
	ret

nrand3:	lda	seed	;now compute next random number. from this
	ori	1	; point on, the code is that of Prof. Paul Gans
	sta	seed	;lsb of SEED must be 1
	
	mvi	b,6	;clear 6 PROD bytes to 0
	lxi	h,prod
randm1:	mvi	m,0
	inx	h
	dcr	b
	jnz	randm1

	lxi	b,6	;set byte counter
randm2:	lxi	h,plier-1
	dad	b	;make addr of lsb of PLIER
	mov	a,m	;PLIER byte
	push	b	;save byte counter
	mvi	b,8	;set bit counter

randm3:	mov	d,a	;save PLIER byte
	lxi	h,prod	;shift whole PROD left one bit
	mvi	c,6
	xra	a
randm4:	mov	a,m	;get byte	
	ral		;shift left
	mov	m,a	;put byte
	inx	h
	dcr	c
	jnz	randm4

	mov	a,d	;recover PLIER byte
	ral		;look at current high bit
	jnc	randm6	;0 means no add cycle

	push	psw	;add SEED to PROD
	xra	a
	mvi	c,6
	lxi	h,prod
	lxi	d,seed
randm5:	ldax	d
	adc	m
	mov	m,a
	inx	h
	inx	d
	dcr	c
	jnz	randm5
	pop	psw

randm6:	dcr	b	;test bit counter
	jnz	randm3	;go cycle more bits
	pop	b	;recover byte counter
	dcr	c	;test it
	jnz	randm2	;go process more bytes

	mvi	b,6	;complement PROD, add 1 to it,
	lxi	h,seed	;and transfer it to SEED.
	lxi	d,prod
	xra	a
	cmc
randm7:	ldax	d
	cma
	aci	0
	mov	m,a
	inx	h
	inx	d
	dcr	b
	jnz	randm7

	dcx	h	;put the two high order bytes
	mov	a,m	;into HL for return to C, not
	ani	7fh	;neglecting to zero the high
	mov	h,a	;order bit so a positive int
	lda	seed+4	;is returned
	mov	l,a
	pop	b
	ret

plier:	db	0c5h,87h,1
	db	0eh,9ah,0e0h	

seed:	db	1,0,0,0,0,0

prod:	db	0,0,0,0,0,0
	ENDFUNC

	FUNCTION	csw
	in	255
	mov	l,a
	mvi	h,0
	ret
	ENDFUNC

	FUNCTION	setmem
	call	arghak
	push	b
	lhld	arg2
	xchg
	lhld	arg1
	lda	arg3
	mov	c,a
	inx	d
setm2:	dcx	d
	mov	a,d
	ora	e
	jnz	setm3
	pop	b
	ret

setm3:	mov	m,c
	inx	h
	jmp	setm2
	ENDFUNC

	FUNCTION	movmem
	call	arghak
	lhld	arg3	;get block length
	mov	a,h
	ora	l
	rz		;do nothing if zero length
	push	b
	mov	b,h
	mov	c,l	;set BC to length
	lhld	arg2	;get dest addr
	xchg		;put in DE
	lhld	arg1	;get source addr in HL
	call	cmphd	;if source < dest, do tail-first
	jc	tailf	;else do head-first

headf:	mvi	a,2	;test for Z-80
	inr	a
	jpe	m8080h	;Z80?
	db	0edh,0b0h	;yes. do block move.
	pop	b
	ret		;and done.

m8080h:	mov	a,m
	stax	d
	inx	h
	inx	d
	dcx	b
	mov	a,b
	ora	c
	jnz	m8080h
	pop	b
	ret

tailf:	dcx	b	;tail first. Compute new source
	dad	b	;and destination addresses
	xchg
	dad	b
	xchg
	inx	b
	mvi	a,2	;test for Z80
	inr	a
	jpe	m8080t	;Z80?
	db	0edh,0b8h	;yes. do block move.
	pop	b
	ret

m8080t:	mov	a,m
	stax	d
	dcx	h
	dcx	d
	dcx	b
	mov	a,b
	ora	c
	jnz	m8080t
	pop	b
	ret

cmphd:	mov	a,h
	cmp	d
	rnz
	mov	a,l
	cmp	e
	ret
	ENDFUNC

	FUNCTION	call
	call	arghak
	push	b
	lhld	arg5
	xchg
	lhld	arg4
	mov	b,h
	mov	c,l
	lda	arg2
	lxi	h,call2
	push	h
	lhld	arg1
	push	h
	lhld	arg3
	ret

call2:	pop	b
	ret
	ENDFUNC

	FUNCTION	calla
	call	arghak
	push	b
	lhld	arg5	;get de value
	xchg
	lhld	arg4	;get bc value
	mov	b,h
	mov	c,l
	lda	arg2	;get a value
	lxi	h,calla2  ;get return address
	push	h	;push	it
	lhld	arg1	;get address of routine
	push	h
	lhld	arg3	;get hl value	
	ret		;call	routine
	
calla2:	mov	l,a	;put A value in HL
	mvi	h,0	;clear high byte
	pop	b
	ret
	ENDFUNC

	FUNCTION	inp
	call	ma1toh
	sta	iohack+1	;store as arg to ram area input subroutine
	call	iohack		;call the subroutine to get value
	mov	l,a		;and put into HL
	mvi	h,0
	ret
	ENDFUNC

	FUNCTION	outp
	call	ma1toh		;get port number
	sta	iohack+4	;store as arg to ram area output subroutine
	call	ma2toh		;get data byte
	call	iohack+3	;output it
	ret
	ENDFUNC

	FUNCTION	peek
peek:	call	ma1toh
	mov	l,m
	mvi	h,0
	ret
	ENDFUNC peek


	FUNCTION	poke
	call	arghak
	lhld	arg1
	lda	arg2
	mov	m,a
	ret
	ENDFUNC

	FUNCTION	sleep
	call	ma1toh
	push	b
	inx	h
sl1:	dcx	h
	mov	a,h
	ora	l
	jnz	sl1a
	pop	b
	ret

sl1a:	lxi	d,10000
sl2:	dcx	d
	mov	a,d
	ora	e
	jnz	sl2
	push	h
	mvi	c,cstat
	call	bdos
	ora	a
	pop	h
	jz	sl1
	push	h
	mvi	c,conin
	call	bdos
	cpi	cntrlc
	jz	exit
	pop	h
	jmp	sl1
	ENDFUNC

	FUNCTION	pause
	push	b
paus1:	mvi	c,cstat
	call	bdos
	ora	a
	jz	paus1
	pop	b
	ret
	ENDFUNC


	FUNCTION	exit
	jmp	exit
	ENDFUNC

	FUNCTION	bdos
	call	arghak	
	push	b
	lda	arg1	;get C value
	mov	c,a
	lhld	arg2	;get DE value
	xchg		;put in DE
	call	bdos	;make the bdos call
	pop	b
	ret		;and return to caller
	ENDFUNC

	FUNCTION	bios
	call	arghak	
	push	b
	lhld	base+1	;get addr of jump table + 3
	dcx	h	;set to addr of first jump
	dcx	h
	dcx	h
	lda	arg1	;get function number (1-85)
	mov	b,a	;multiply by 3
	add	a
	add	b
	mov	e,a	;put in DE
	mvi	d,0
	dad	d	;add to base of jump table
	push	h	;and save for later
	lhld	arg2	;get value to be put in BC
	mov	b,h	;and put it there
	mov	c,l
	lxi	h,retadd	;where call to bios will return to
	xthl		;get address of vector in HL
	pchl		;and go to it...
retadd:	mov	l,a	;all done. now put return value in HL
	mvi	h,0
	pop	b
	ret		;and return to caller
	ENDFUNC

	FUNCTION	biosh
	call	arghak	
	push	b
	lhld	base+1	;get addr of jump table + 3
	dcx	h	;set to addr of first jump
	dcx	h
	dcx	h
	lda	arg1	;get function number (1-85)
	mov	b,a	;multiply by 3
	add	a
	add	b
	mov	e,a	;put in DE
	mvi	d,0
	dad	d	;add to base of jump table
	push	h	;and save for later

	lhld	arg2	;get value to be put in BC
	mov	b,h	;and put it there
	mov	c,l

	lhld	arg3	;get value to be put in DE
	mov	d,h	;adn put it there
	mov	e,l

	lxi	h,retadd	;where call to bios will return to
	xthl		;get address of vector in HL
	pchl		;and go to it...
retadd:	pop	b	;all done. Leave return value in HL
	ret		;and return to caller
	ENDFUNC

	FUNCTION	codend
	lhld	codend
	ret
	ENDFUNC

	FUNCTION	externs
	lhld	extrns
	ret
	ENDFUNC

	FUNCTION	endext
	lhld	freram
	ret
	ENDFUNC

	FUNCTION	topofmem  
	lhld	base+6
	lda	tpa	;check for "NOBOOT" hackery
	cpi	0c3h	; "jmp" at start of C.CCC (as inserted by "-n")?
	dcx	h	;if CCC doesn't begin with "lxi h," then top of
	rnz		;memory is just below the base of the bdos
	lxi	d,-2100	;else subtract CCP size (plus little more for good
	dad	d	;measure) and return that as top of memory.
	ret
	ENDFUNC

	FUNCTION	exec
	EXTERNAL	execl
	call ma1toh	;get filename
	lxi d,0		;load null parameter in DE
	push d		;push null parameter
	push h		;push filename
	call execl	;do an execl
	pop d		;clean up stack
	pop d
	ret
	ENDFUNC		


	FUNCTION	execv
	EXTERNAL	execl
	call	arghak
	push	b	;save BC
	lhld	arg2	;get -> arg list
	mvi	b,0	;clear arg count
execv1:	inr	b	;bump arg count
	mov	e,m
	inx	h
	mov	d,m
	inx	h
	mov	a,d
	ora	e	;last arg?
	jnz	execv1	;if not, keep looking for last one

	mov	a,b	;save arg count in case of error
	sta	savcnt

	dcx	h	;HL -> next to last arg
execv2:	mov	d,m	;now push args on stack
	dcx	h
	mov	e,m
	dcx	h
	dcr 	b
	push	d
	jnz	execv2

execv3:	lhld	arg1	;get program name
	push	h	;save as first arg to execl
	call	execl	;go do it; shouldn't come back.
	lda	savcnt	;woops, we're back. Must've been an error...
	inr 	a	;bump to take prog name into consideration
	add 	a
	mov	l,a	;put size of passed parameter list
	mvi	h,0	;into HL, and adjust stack
	dad	sp
	sphl
	pop	b	;restore BC
	lxi	h,-1	;return error value
	ret

savcnt:	ds 	1	;save arg count here
	ENDFUNC



	FUNCTION	sbrk
	call	ma1toh	;get # of bytes needed in HL
	xchg		;put into DE
	lhld	allocp	;get current allocation pointer
	push	h	;save it
	dad	d	;get tentative last address of new segment
	jc	brkerr	;better not allow it to go over the top!
	dcx	h
	xchg		; now last addr is in DE
	lhld	alocmx	;get safety factor
	mov	a,h	;negate
	cma
	mov	h,a
	mov	a,l
	cma 
	mov	l,a		
	inx	h
	dad	sp	;get HL = (SP - alocmx)

	call	cmpdh	;is DE less than HL?
	jnc	brkerr	;if not, can't provide the needed memory.
	xchg		;else OK.
	inx	h
	shld	allocp	;save start of next area to be allocated
	pop	h	;get pointer to this area
	ret		;and return with it.

brkerr:	pop	h	;clean up stack
	jmp	error	;and return with -1 to indicate can't allocate.

cmpdh:	mov	a,d
	cmp	h
	rc
	rnz
	mov	a,e
	cmp	l
	ret
	ENDFUNC

	FUNCTION	rsvstk
	call	ma1toh	;get the value to reserve
	shld	alocmx	;and set new safety factor
	ret
	ENDFUNC

	FUNCTION	memcmp
	call	ma3toh	;get length in HL
	push	b	;save BC
	mov	b,h
	mov	c,l	;move length to BC
	call	ma3toh	;get block2 address in HL
	xchg		;move to DE
	call	ma2toh	;get block1 address in HL
loop:	mov	a,b	;all done?
	ora	c
	jnz loop1
	lxi	h,1	;if so, return TRUE, for perfect match
	pop	b
	ret

loop1:	dcx	b	;decrement count
	ldax	d	;get block2 byte
	cmp	m	;compare to block1 byte
	inx	d	;bump pointers
	inx	h
	jz	loop	;if so far so good, go on comparing
	lxi	h,0	;else a mismatch
	pop	b
	ret

	ENDFUNC«eof»