;SCDATE.ASM v1.0 06/18/85
; Carl Efird
;
; This program reads the CP/M+ system date,
; sets the SuperCalc (tm) date and chains SC2.COM 
; with the command line if provided. It will work
; the same way with SC.COM if you change the name
; below.
;
; The SuperCalc (tm) date is stored in BCD starting 
; at 10h in month, day, year order.
;
	org	100h
reset	equ	0
bdos	equ	5
prtstr	equ	9
versn	equ	12
setdma	equ	26
chain	equ	47
getdat	equ	105
;
dcfld	equ	10h
month	equ	10h
day	equ	11h
year	equ	12h
;
	jmp	start
;
	db	'SCDATE v1.0 -  SuperCalc (tm) date set for CP/M+ - '
	db	'Carl Efird 06/85',1ah
	ds	40
;
start:	lhld	start-1
	sphl			; set up stack
	mvi	c,versn
	call	bdos		; get CP/M version number
	mov	a,l
	ani	0f0h		; strip off lower 4 bits
	cpi	30h
	jz	cpm30
;
; Must be CP/M 3.0 or higher
;
	lxi	d,not30
	mvi	c,prtstr
	call	bdos
	mvi	c,reset
	call	bdos
;
not30:	db	'Must be CP/M 3.0 or higher$'
;
; OK - proceed to get the system date
;
cpm30:	lxi	d,date	
	mvi	c,getdat
	call	bdos		; get the system date
	lhld	date
	call	dcvrt		; convert date
;
; insert command at begining of command tail in default dma
;
	lxi	h,80h		; load default dma address
	mvi	a,' '
	mov	m,a		; replace length with a blank
	lxi	d,cmd		; load end of command address
insert:	lxi	h,80h		; start at begining of dma
	dcx	d		; back up 1 character in command
	ldax	d		; load character
	cpi	0
	jz	scalc		; done if 0
move:	mov	b,m		; get character from dma
	mov	m,a		; replace with preceeding character
	inx	h		; point to next character
	mov	a,b		; new preceeding character
	cpi	0
	jnz	move		; continue if not 0
	mov	m,a		; save the 0
	jmp	insert
;
scalc:	mvi	e,0
	mvi	c,chain
	call	bdos		; chain to SC2.COM
;
date:	db	0,0,0,0,0
	db	'SC2.COM'	; name of command to chain
cmd:	db	0
;
;------------------------------------------------------
;DATE.ASM v1.10 10/26/83
; S. Kluger El Paso RCPM
;
; This module will take the date in Digital Research
; format and change it into human-readable form.
;
;Input: The number of days since 01/01/78. DCFLD
;	must be defined in the main module and be
;	3 bytes.
;Output:The structure at DCFLD will contain the
;	date in BCD.
;
; The routine works, don't ask me why. If you think it's
; too kludgy or too big, feel free to change it. Just
; don't leave my name off the ASM file, ok?
;
; Enter with the number of days since 1-1-78 in HL
;
; Modified 06/18/85 - cre
;   returns decoded date as BCD rather than ASCII
;   for compatability with SuperCalc (tm)
;
dcvrt:	shld	drtime		;save it for now
	mvi	b,78		;set years counter
loop:	call	ckleap
	lxi	d,-365		;set up for subtract
	jnz	nolpy		;skip if no leap year
	dcx	d		;set for leap year
nolpy:	dad	d		;subtract
	jnc	ydone		;continue if years done
	mov	a,h
	ora	l
	jz	ydone
	shld	drtime		;else save days count
	inr	b		;increment years count
	jmp	loop		;and do again
;
; The years are now finished, the years count is in B
; and drtime holds the days (HL is invalid)
;
ydone:	call	ckleap		;check if leap year
	mvi	a,-28
	jnz	febno		;february not 29 days
	mvi	a,-29		;leap year
febno:	sta	feb		;set february
	mov	a,b		;get years count
	lxi	h,dcfld+2	;point to years field
	call	stasha		;stash A into years field
	lhld	drtime		;get days count
	lxi	d,mtable	;point to months table
	mvi	b,0ffh		;set up b for subtract
	mvi	a,0		;set a for # of months
mloop:	push	psw
	ldax	d		;get month
	mov	c,a		;put in C for subtract
	pop	psw
	shld	drtime		;save days count
	dad	b		;subtract
	inx	d		;increment months counter
	inr	a
	jc	mloop		;and loop for next month
;
; The months are finished, days count is on stack.
; First, calculate month.
;
mdone:	mov	b,a		;save months
	lhld	drtime
	mov	a,h
	ora	l
	jnz	nzd
	dcx	d
	dcx	d
	ldax	d
	cma
	inr	a
	mov	l,a
	shld	drtime
	dcr	b
nzd:	mov	a,b
	push	h
	lxi	h,dcfld		;point to months field
	call	stasha		;put a into months field
	pop	h		;get days count back
	mov	a,l		;into a
	lxi	h,dcfld+1	;point to day field
;
; Plug the accumulator into <HL> as decimal
;
stasha:	push	b		;save bc as counter
	mvi	b,0		;initialize tens
stl:	cpi	10		; > 10?
	jc	got10		;no, done
	sui	10		;subtract 10 from A
	inr	b		;increment tens
	jmp	stl		;and loop
;
; B has the tens, A has the units.
;
got10:	mov	c,a		;save units
	mov	a,b		;get tens
	rlc
	rlc
	rlc
	rlc			;move tens to upper nibble
	add	c		;combine tens and units
	mov	m,a		;store value
	pop	b		;restore bc
	ret
;
; This routine checks for leap years.
;
ckleap:	mov	a,b
	ani	0fch
	cmp	b
	ret
;
; This is the months table
;
mtable:	db	-31		;January
feb:	db	-28		;February
	db	-31,-30,-31,-30	;Mar-Jun
	db	-31,-31,-30	;Jul-Sep
	db	-31,-30,-31	;Oct-Dec
;
drtime:	dw	0		;temporary storage
;
	end
db	-31,-30,-31,-30	;Mar-Jun
	db	