| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415 | ;;	CP/M Time-of-day Program;;	v1.08	12/22/82 WGW	Changed name of program to TIME.COM;	v1.07	11/12/82 WGW	Correct values for get/settime;	v1.06	11/10/82 WGW	Changed help message to fit on EC8800;	v1.05	 9/20/82 WGW	Get number of days via gettime;	v1.04	 7/01/82 WGW	Correct noon time (12 PM);	v1.03	 6/07/82 WGW	Correct get character routine;	v1.02	 5/27/82 WGW	Check validity of time, regular/military time;	v1.01	 5/21/82 WGW	Set time of day;	v1.00	 5/20/82 WGW	Read time of day (original version);version		equ	1revision	equ	8month		equ	12day		equ	22year		equ	82cpm		equ	0bdos		equ	5fcb1		equ	5ch		; location of first fcb parsed by ccpfcb2		equ	6ch		; location of second fcbfilename	equ	1		; offset into fcbfileextension	equ	filename+8	; offset into fcbparameter1a	equ	fcb1+filenameparameter1b	equ	fcb1+fileextensionparameter2a	equ	fcb2+filenameparameter2b	equ	fcb2+fileextensiontpa		equ	100hbeep		equ	7cr		equ	13lf		equ	10endmsg		equ	'$'regulartime	equ	0militarytime	equ	0ffhuppercase	equ	5fhdisplaychar	equ	' '		; character indicating display todrepeatchar	equ	'P'		; character indicating repeat modemilitarychar	equ	'M'		; character indicating military todmaxhours	equ	24h		; 24 hoursmorning		equ	maxhours/2noon		equ	12hmidnight	equ	0maxminutes	equ	60h		; 60 minutesreadconsole	equ	1		; bdos function callsgetconsole	equ	6printstring	equ	9consolestatus	equ	11settime		equ	104readtime	equ	105readclock	equ	155	org	tpa	jmp	startsignon:	db	cr,lf	db	'Time-of-day Program  WGW  V'	db	(version/10)+'0'	db	(version mod 10)+'0'	db	'.'	db	(revision/10)+'0'	db	(revision mod 10)+'0'	db	'  '	db	(month/10)+'0'	db	(month mod 10)+'0'	db	'/'	db	(day/10)+'0'	db	(day mod 10)+'0'	db	'/'	db	(year/10)+'0'	db	(year mod 10)+'0'	db	endmsgdisplaytype:	db	regulartime		; default display type;;  ---  Main part of program  -----------;start:	lxi	sp,stack		; use internal stack	call	main			; perform main program	lxi	d,crlfmsg	call	print1	jmp	cpm			; exitmain:	lda	parameter1a		; a  := first char of first parameter	call	isdigit			; see if a digit is entered	jz	settod			; see if the time is to be set	cpi	militarychar		; check for military time	jnz	checkdisplaytype	mvi	a,militarytime		; set display type to military time	sta	displaytype	lda	parameter2a		; a  := first char of second parametercheckdisplaytype:	cpi	displaychar		; check for print one time display	jz	printtime	cpi	repeatchar		; check for repeat time display	jz	repeatprinttime	lxi	d,signon		; otherwise print signon	call	print	lxi	d,helpmsg		; and print format messageprint:	call	print1			; print stringprintcrlf:	lxi	d,crlfmsg		; begin a new lineprint1:	mvi	c,printstring	jmp	bdoshelpmsg:	db	'The following display the time-of-day:',cr,lf	db	cr,lf	db	'TIME           Prints normal time',cr,lf	db	'TIME M         Prints military time',cr,lf	db	cr,lf	db	'The following display the time-of-day',cr,lf	db	'    until a key is pressed:',cr,lf	db	cr,lf	db	'TIME P         Prints normal time',cr,lf	db	'TIME M P       Prints military time',cr,lf	db	cr,lf	db	'The following set the time-of-day:',cr,lf	db	cr,lf	db	'TIME hh.mm     Set military time',cr,lf	db	'TIME hh.mm AM  Set normal time (morning)',cr,lf	db	'TIME hh.mm PM  Set normal time (evening)',cr,lf	db	'                 when a key is pressed.',cr,lf	db	endmsgprinttime:				; print time-of-day	lxi	d,timeismsg		; print 'time is'	call	print1	lxi	d,tod			; read the tod clock	mvi	c,readclock	call	bdos	call	converttime	lxi	d,timemsg		; print the time	call	print1	call	ismilitary		; see if military time display	cnz	printampm	lxi	d,crmsg			; print trailing cr	jmp	print1printampm:	call	getampm			; get right letter	mov	a,l			; a  := am/pm character	sta	ampm			; update message	lxi	d,ampmmsg		; print am/pm message	jmp	print1getampm:	mvi	l,'P'			; l  := possible result	lda	todhours		; a  := hours	cpi	morning			; see if it is the morning	rnc				; exit if in the evening	mvi	l,'A'	ret	converttime:	lda	todhours		; convert to ascii and display	call	converthourscheck	; check the hours	call	makeascii	shld	msghours	lda	todminutes	call	makeascii	shld	msgminutes	lda	todseconds	call	makeascii	shld	msgseconds	retconverthourscheck:	mov	b,a			; b  := hours (BCD)	call	ismilitary		; see if it is military time	mov	a,b			; a  := hours (BCD)	rz				; exit if military time	ora	a			; check for midnight	mvi	a,12h			; return 12 if midnight	rz				; exit if midnight	mov	a,b			; a  := hours (BCD)	cpi	morning+1		; check if evening	rc				; exit if in morning	adi	88h			; subtract 12 hours	daa				; make BCD	retismilitary:	lda	displaytype		; a  := displaytype	cpi	militarytime		; return zero if military time	retrepeatprinttime:			; print tod until character entered	call	printtime	mvi	c,consolestatus		; get console status	call	bdos	ora	a	jz	repeatprinttime		; loop until done if no character typedgetchr: mvi	c,consolestatus		; get console status	call	bdos	ora	a	jz	getchr			; wait until character entered	mvi	e,0ffh			; e  := get character	mvi	c,getconsole		; get the character	jmp	bdos			; and exitsettod:					; set time-of-day	lxi	d,tod			; get time-of-day to set days	mvi	c,readtime	call	bdos	lhld	parameter1a		; get hours	xchg				; de := parameter	call	makebcdblank		; convert to bcd, possible leading ' '	cpi	0ffh			; check for entry errors	jz	seterror	call	checkhours		; check for range error	jnc	seterror		; jump if greater or equal to limit	sta	todhours	lhld	parameter1b		; get minutes	xchg				; de := parameter	call	makebcd			; convert to bcd	cpi	0ffh			; check for entry errors	jz	seterror	cpi	maxminutes		; check for range error	jnc	seterror		; jump if greater or equal to limit	sta	todminutes	lxi	d,startmsg		; print waiting to set time message	call	print1	call	getchr			; get a character	call	printcrlf	lxi	d,tod			; set time-of-day	mvi	c,settime	call	bdos	jmp	printtime		; print the time just setcheckhours:	mov	b,a			; b  := hours (BCD)	lda	parameter2a		; a  := first char of second parameter	cpi	'P'			; see if it is PM	jz	checkhourspm	cpi	'A'			; see if it is AM	jz	checkhoursam	cpi	' '			; see if it is military time (default)	jz	checkhoursmilitary	ora	a			; no carry indicates an error	retcheckhoursmilitary:	mov	a,b			; a  := hours (BCD)	cpi	maxhours		; check max hours	retcheckhourspm:	mov	a,b			; a  := hours (BCD)	ora	a			; see if it is zero	rz				; return with no carry if zero	adi	morning			; convert to PM hours	daa				; make BCD	cpi	maxhours		; check max hours	rnz				; return in not midnight	mvi	a,noon			; return a := 12h if noon	stc				; set carry to indicate it is ok	retcheckhoursam:	mov	a,b			; a  := hours (BCD)	ora	a			; see if it is zero	rz				; return with no carry if zero	cpi	morning			; check max hours	rnc				; exit if ok (1 to 11 am)	cpi	12h			; see if it is 12 am	rnc				; exit if not 12 am (error)	sub	a			; a  := 0 (12 midnight)	stc				; set carry to indicate it is ok	retstartmsg:	db	cr,lf	db	'Enter any key to set time of day',endmsgseterrormsg:	db	'Invalid time-of-day format',endmsgseterror:	lxi	d,seterrormsg		; print error message	call	error	lxi	d,helpmemsg		; print how-to-get-help message	jmp	printhelpmemsg:	db	cr,lf	db	'Enter the following to get more information:',cr,lf	db	cr,lf	db	'TIME ?',endmsgerror:	push	d			; save error message index	 lxi	d,errorprefix		; print error prefix	 call	print1	pop	d	call	print1			; print error message	lxi	d,errorsuffix		; print error suffix	jmp	printerrorprefix:	db	cr,lf	db	'*** ',endmsgerrorsuffix:	db	' ***',beep,endmsgisdigit:			; returns zero if A is an ascii digit	mov	c,a		; c  := character	push	b		; save it	 call	isdigit1	; check digit	pop	b		; restore character, return zero flag	mov	a,c	retisdigit1:	cpi	'0'		; is is less than a '0'	jc	returnff	cpi	'9'+1	jnc	returnff	; is it greater than a '9'return0:	sub	a		; a  := 0, zero = true	retreturnff:	mvi	a,0ffh		; a  := 0ffh, zero = false	ora	a	retmakebcdblank:			; a  := bcd value of de (ls, ms), ls can = ' '	mov	a,d		; a  := ls ascii digit	cpi	' '		; see if it is a blank	jnz	makebcd		; convert if already a digit	mov	d,e		; shift right one digit	mvi	e,'0'		; set in a leading zeromakebcd:			; a  := bcd value of de (ls, ms)	mov	a,e		; a  := ms ascii digit	call	isdigit		; see if it is a digit	rnz			; exit if it is not	mov	a,e		; restore ms ascii digit	ral			; shift into upper nibble	ral	ral	ral	ani	0f0h		; a (ms nibble) := bcd part of ms ascii digit	mov	e,a		; save it	mov	a,d		; a  := ls ascii digit	call	isdigit		; see if this is a digit too	rnz	mov	a,d		; restore ls ascii digit	ani	0fh		; a (ls nibble) := bcd part of ls ascii digit	ora	e		; a  := result	retmakeascii:	push	psw	 call	makedigit	 mov	h,a		; h  := ls digit (remember, msb stored last)	pop	psw	rrc	rrc	rrc	rrc			; a (ls nibble) := ms nibble	call	makedigit	mov	l,a		; hl := two ascii digits	retmakedigit:	ani	0fh		; a  := ls nibble	adi	'0'		; convert to a digit	rettod:		dw	0todhours:	db	0todminutes:	db	0todseconds:	db	0timeismsg:	db	'The time is ',endmsgtimemsg:			; displays timemsghours:	db	'00.'msgminutes:	db	'00.'msgseconds:	db	'00',endmsgampmmsg:	db	' 'ampm:		db	' M',endmsgcrmsg:		db	cr,endmsgcrlfmsg:	db	cr,lf,endmsg	ds	256		; internal stackstack:	end
 |