
	incdir	Includes:
	include	libraries/dosextens.i
	include	offsets/dos_lib.i
	include	offsets/exec_lib.i

TRUE		equ	1
FALSE		equ	0

DATE_MAX	equ	10
YEAR_MAX	equ	2899
MONTH_MAX	equ	12
DAY31_MAX	equ	31
DAY30_MAX	equ	30
DAY28_MAX	equ	28
DAY29_MAX	equ	29
M31_MAX		equ	7
WEEK_MAX	equ	7

YEAR_1582	equ	1582
MONTH_1582	equ	10
DAY_1582	equ	15

FEBRUARY	equ	2
FEB_MASK	equ	$00000003

STO		equ	100

	section	Date2Day,code

Begin:
	bra	Start

VerStr:
	dc.b	"$VER: Date2Day v1.0 (11.13) 05.07.96",0

Author:
	dc.b	'© 1996 Tadek Knapik. Public Domain.',0,0

Start:
	move.l	a0,a5
	move.l	a0,Date
	move.l	$4,_SysBase

	move.l	_SysBase,a6
	sub.l	a1,a1
	jsr	_LVOFindTask(a6)
	move.l	d0,a0
	tst.l	pr_CLI(a0)
	bne	CLIStuff
	lea	pr_MsgPort(a0),a0
	move.l	a0,a2
	jsr	_LVOWaitPort(a6)
	move.l	a2,a0
	jsr	_LVOGetMsg(a6)
	move.l	d0,a1
	jsr	_LVOForbid(a6)
	jsr	_LVOReplyMsg(a6)
	move.l	#10,d0
	rts

CLIStuff:
	move.l	_SysBase,a6
	bsr	OpenDOS
	beq	NoDOS

	move.l	_DOSBase,a6
	jsr	_LVOOutput(a6)
	move.l	d0,Output
	beq	NoArgs

	cmpi.b	#10,(a5)
	beq	Info

	move.l	Date,a1
	bsr	CountString
	cmpi.l	#DATE_MAX,d0
	bgt	BadArgs

	move.l	a1,a0
	bsr	ParseDate
	beq	BadArgs

	bsr	ParseTheDate
	beq	BadArgs

	cmpi.l	#WEEK_MAX,d0
	bgt	BadArgs

	moveq	#0,d3
	mulu	#4,d0

	lea	DayNames,a0
	move.l	(a0,d0.l),a0
	move.b	(a0)+,d3
	move.l	a0,d2
	move.l	Output,d1
	move.l	_DOSBase,a6
	jsr	_LVOWrite(a6)

Koniec:
	bsr	CloseDOS
	moveq	#0,d0
	rts

BadArgs:
	bsr	ShowBadArgs
NoArgs:
	bsr	CloseDOS
NoDOS:
	moveq	#10,d0
	rts

ShowBadArgs:
	move.l	_DOSBase,a6
	lea	BadArgsTxt,a0
	moveq	#0,d3
	move.b	(a0)+,d3
	move.l	a0,d2
	move.l	Output,d1
	jsr	_LVOWrite(a6)
	rts

Info:
	move.l	_DOSBase,a6
	lea	InfoTxt,a0
	moveq	#0,d3
	move.b	(a0)+,d3
	move.l	a0,d2
	move.l	Output,d1
	jsr	_LVOWrite(a6)
	bra	Koniec

ParseTheDate:

	move.l	Year,d0
	moveq	#0,d5
	moveq	#0,d6
	moveq	#0,d7
	divu	#STO,d0
	move.w	d0,d5
	swap	d0
	move.w	d0,d6

	move.l	d6,d3
	beq	TestCalendar

	andi.l	#FEB_MASK,d3
	bne	TestCalendar

	moveq	#1,d7

TestCalendar:

	cmpi.l	#YEAR_1582,Year
	bgt	OurCalendar
	blt	Julian

	cmpi.l	#MONTH_1582,Month
	bgt	OurCalendar
	blt	Julian

	cmpi.l	#DAY_1582,Day
	bge	OurCalendar

Julian:
	moveq	#0,d3
	move.l	d5,d2
	divu	#7,d2
	swap	d2
	move.w	d2,d3
	bra	TakeYear

OurCalendar:

	move.l	#0,d3

	cmpi.l	#17,d5
	beq	TakeYear
	cmpi.l	#21,d5
	beq	TakeYear
	cmpi.l	#25,d5
	beq	TakeYear

	move.l	#2,d3

	cmpi.l	#18,d5
	beq	TakeYear
	cmpi.l	#22,d5
	beq	TakeYear
	cmpi.l	#26,d5
	beq	TakeYear

	move.l	#4,d3

	cmpi.l	#15,d5
	beq	TakeYear
	cmpi.l	#19,d5
	beq	TakeYear
	cmpi.l	#23,d5
	beq	TakeYear
	cmpi.l	#27,d5
	beq	TakeYear

	move.l	#5,d3
	cmpi.l	#16,d5
	beq	TakeYear
	cmpi.l	#20,d5
	beq	TakeYear
	cmpi.l	#24,d5
	beq	TakeYear
	cmpi.l	#28,d5
	beq	TakeYear

	bra	BadData

TakeYear:

	mulu	#4,d3
	lea	YearTable,a0
	move.l	(a0,d3.l),a0

	moveq	#0,d2
	moveq	#0,d3
	move.l	d6,d1
	move.l	d1,d3
	divu	#4,d1
	move.w	d1,d2
	add.l	d2,d3
	moveq	#0,d1
	moveq	#0,d2
	divu	#7,d3
	swap	d3
	move.w	d3,d2

	moveq	#0,d0
	move.b	(a0,d2.l),d0

	cmpi.l	#1,Month
	bne	TakeFebruary

	tst.l	d7
	beq	TakeUsualJanuary

	lea	MTable5,a0
	bra	TakeAMonth

TakeUsualJanuary:
	lea	MTable6,a0
	bra	TakeAMonth

TakeFebruary:
	cmpi.l	#2,Month
	bne	TakeMarch

	tst.l	d7
	beq	TakeUsualFebruary

	lea	MTable1,a0
	bra	TakeAMonth

TakeUsualFebruary:
	lea	MTable2,a0
	bra	TakeAMonth

TakeMarch:
	cmpi.l	#3,Month
	bne	TakeApril

	lea	MTable2,a0
	bra	TakeAMonth

TakeApril:
	cmpi.l	#4,Month
	bne	TakeMay

	lea	MTable5,a0
	bra	TakeAMonth

TakeMay:
	cmpi.l	#5,Month
	bne	TakeJune

	lea	MTable0,a0
	bra	TakeAMonth

TakeJune:
	cmpi.l	#6,Month
	bne	TakeJuly

	lea	MTable3,a0
	bra	TakeAMonth

TakeJuly:
	cmpi.l	#7,Month
	bne	TakeAugust

	lea	MTable5,a0
	bra	TakeAMonth

TakeAugust:
	cmpi.l	#8,Month
	bne	TakeSeptember

	lea	MTable1,a0
	bra	TakeAMonth

TakeSeptember:
	cmpi.l	#9,Month
	bne	TakeOctober

	lea	MTable4,a0
	bra	TakeAMonth

TakeOctober:
	cmpi.l	#10,Month
	bne	TakeNovember

	lea	MTable6,a0
	bra	TakeAMonth

TakeNovember:
	cmpi.l	#11,Month
	bne	TakeDecember

	lea	MTable2,a0
	bra	TakeAMonth

TakeDecember:
	cmpi.l	#12,Month
	bne	BadData

	lea	MTable4,a0

TakeAMonth:
	moveq	#0,d1
	move.b	(a0,d0.l),d1

	moveq	#0,d0
	moveq	#0,d2
	moveq	#0,d3
	move.l	Day,d2
	divu	#7,d2
	swap	d2
	move.w	d2,d3
	tst.l	d3
	beq	DayZero
	subq.l	#1,d3
	bra	TakeADay

DayZero:
	move.l	#6,d3

TakeADay:
	mulu	#4,d3

	lea	DayTable,a0
	move.l	(a0,d3.l),a0

	move.b	(a0,d1.l),d0
	rts

BadData:
	move.l	#FALSE,d0
	rts

ParseDate:
	tst.b	(a0)
	beq	ParseBad

	lea	DayBuffer,a1
ParseDay:
	move.b	(a0)+,(a1)+
	cmpi.b	#'.',(a0)
	beq	DayParsed
	cmpi.b	#'-',(a0)
	beq	DayParsed
	tst.b	(a0)
	beq	ParseBad
	bra	ParseDay

DayParsed:
	move.b	#0,(a1)
	adda.l	#1,a0
	tst.b	(a0)
	beq	ParseBad
	lea	MonthBuffer,a1

ParseMonth:
	move.b	(a0)+,(a1)+
	cmpi.b	#'.',(a0)
	beq	MonthParsed
	cmpi.b	#'-',(a0)
	beq	MonthParsed
	tst.b	(a0)
	beq	ParseBad
	bra	ParseMonth

MonthParsed:
	move.b	#0,(a1)
	adda.l	#1,a0
	tst.b	(a0)
	beq	ParseBad
	lea	YearBuffer,a1

ParseYear:
	move.b	(a0)+,(a1)+
	cmpi.b	#'.',(a0)
	beq	YearParsed
	cmpi.b	#'-',(a0)
	beq	YearParsed
	tst.b	(a0)
	beq	YearParsed
	bra	ParseYear

YearParsed:
	move.b	#0,(a1)

	move.l	_DOSBase,a6
	lea	DayBuffer,a1
	move.l	a1,d1
	lea	Day,a2
	move.l	a2,d2
	jsr	_LVOStrToLong(a6)
	tst.l	d0
	bmi	ParseBad

	lea	MonthBuffer,a1
	move.l	a1,d1
	lea	Month,a2
	move.l	a2,d2
	jsr	_LVOStrToLong(a6)
	tst.l	d0
	bmi	ParseBad

	lea	YearBuffer,a1
	move.l	a1,d1
	lea	Year,a2
	move.l	a2,d2
	jsr	_LVOStrToLong(a6)
	tst.l	d0
	bmi	ParseBad

	cmpi.l	#YEAR_MAX,Year
	bgt	ParseBad

	cmpi.l	#MONTH_MAX,Month
	bgt	ParseBad
	tst.l	Month
	beq	ParseBad

	tst.l	Day
	beq	ParseBad

	cmpi.l	#FEBRUARY,Month
	bne	CheckDay

	move.l	Year,d0
	moveq	#0,d1
	divu	#STO,d0
	swap	d0
	move.w	d0,d1
	beq	UsualFebruary

	andi.l	#FEB_MASK,d1
	bne	UsualFebruary

	cmpi.l	#DAY29_MAX,Day
	bgt	ParseBad
	bra	ParseOver

UsualFebruary:
	cmpi.l	#DAY28_MAX,Day
	bgt	ParseBad
	bra	ParseOver

CheckDay:
	move.l	Month,d0
	cmpi.l	#M31_MAX,d0
	ble	UsualMonth
	subq.l	#1,d0

UsualMonth:
	btst	#0,d0
	beq	PMonth

	cmpi.l	#DAY31_MAX,Day
	bgt	ParseBad
	bra	ParseOver

PMonth:
	cmpi.l	#DAY30_MAX,Day
	bgt	ParseBad

ParseOver:
	move.l	#TRUE,d0
	rts

ParseBad:
	move.l	#FALSE,d0
	rts

CountString:
	move.l	a1,a0
	moveq	#0,d0
CountLoop:
	cmpi.b	#0,(a0)
	beq	Counted
	cmpi.b	#10,(a0)
	beq	Terminated
	adda.l	#1,a0
	addq.l	#1,d0
	bra	CountLoop

Terminated:
	move.b	#0,(a0)
Counted:
	rts

OpenDOS:
	lea	DosName,a1
	moveq	#0,d0
	jsr	_LVOOpenLibrary(a6)
	move.l	d0,_DOSBase
	rts

CloseDOS:
	move.l	_DOSBase,a1
	move.l	4,a6
	jsr	_LVOCloseLibrary(a6)
	rts

	section Date2Dayd,data

YearTable:
	dc.l	YTable0
	dc.l	YTable1
	dc.l	YTable2
	dc.l	YTable3
	dc.l	YTable4
	dc.l	YTable5
	dc.l	YTable6

YTable0:
	dc.b	6,0,1,2,3,4,5
YTable1:
	dc.b	5,6,0,1,2,3,4
YTable2:
	dc.b	4,5,6,0,1,2,3
YTable3:
	dc.b	3,4,5,6,0,1,2
YTable4:
	dc.b	2,3,4,5,6,0,1
YTable5:
	dc.b	1,2,3,4,5,6,0
YTable6:
	dc.b	0,1,2,3,4,5,6

MTable0:
	dc.b	1,2,3,4,5,6,0
MTable1:
	dc.b	2,3,4,5,6,0,1
MTable2:
	dc.b	3,4,5,6,0,1,2
MTable3:
	dc.b	4,5,6,0,1,2,3
MTable4:
	dc.b	5,6,0,1,2,3,4
MTable5:
	dc.b	6,0,1,2,3,4,5
MTable6:
	dc.b	0,1,2,3,4,5,6

DayTable:
	dc.l	DTable0
	dc.l	DTable1
	dc.l	DTable2
	dc.l	DTable3
	dc.l	DTable4
	dc.l	DTable5
	dc.l	DTable6

DTable0:
	dc.b	6,7,1,2,3,4,5
DTable1:
	dc.b	7,1,2,3,4,5,6
DTable2:
	dc.b	1,2,3,4,5,6,7
DTable3:
	dc.b	2,3,4,5,6,7,1
DTable4:
	dc.b	3,4,5,6,7,1,2
DTable5:
	dc.b	4,5,6,7,1,2,3
DTable6:
	dc.b	5,6,7,1,2,3,4
	dc.b	0

DayNames:
	dc.l	0
	dc.l	Monday
	dc.l	Tuesday
	dc.l	Wednesday
	dc.l	Thursday
	dc.l	Friday
	dc.l	Saturday
	dc.l	Sunday

Monday:
	dc.b	7,'Monday',10
Tuesday:
	dc.b	8,'Tuesday',10
Wednesday:
	dc.b	10,'Wednesday',10
Thursday:
	dc.b	9,'Thursday',10
Friday:
	dc.b	7,'Friday',10
Saturday:
	dc.b	9,'Saturday',10
Sunday:
	dc.b	7,'Sunday',10
	dc.b	0

BadArgsTxt:
	dc.b	14,'Date invalid!',10,0

InfoTxt:
	dc.b	55,10,'Date2Day v1.0 By Tadek Knapik.',10
	dc.b	'Usage: d2d dd.mm.year',10,10,0

DosName:
	dc.b	'dos.library',0

	section	Date2Dayb,bss

_SysBase:
	ds.l	1

_DOSBase:
	ds.l	1

Output:
	ds.l	1

Date:
	ds.l	1

Day:
	ds.l	1

Month:
	ds.l	1

Year:
	ds.l	1

DayBuffer:
	ds.b	12

MonthBuffer:
	ds.b	12

YearBuffer:
	ds.b	12

