

*-------------- IDENTIFICATION -------------------------------------------*


; Author     	: Andrew K. Pearson
; Program    	: AmigaDiary
; Version    	: 1.13
; Last Updated	: 28.6.93

; (c) Andrew K. Pearson 1992/93


*-------------- PROGRAM HISTORY -----------------------------------------*

; v1.0  : The 'original'. Finished around spring '93.

; v1.1  : Finished 20/3/93. Added some features not originally intended,
;         eg. hotkeys. This version on July '93 Amiga Computing coverdisk.

; v1.11 : Removed a few bugs present in v1.1 Thanks to all the people 
;         who pointed them out to me.

; v1.12 : Fixed the following bugs:
;         1. When the diary starts up, the whole entry for today is
;	     displayed, not just the most recently added one.
;	  2. After loading a file, the correct entries are displayed, and
;	     the day shown in the window is today's date - not the last
; 	     day loaded from the file.
;	  3. The Edit gadget in the scribblepad window no longer has the
;            E underlined. (Hotkeys only work in the main window).
;         4. (Not a bug) I never expected people to want to insert entries
;            in the past, so I made the lookup date routine add 2000 to the
;            year if it was less than 90. It would seem, however, that 
;            if you were keeping records or something then you might want
;            entries in previous years. Now, only years less than 30 are
;            21st century. Any others go to 20th century, so for example if
;            you entered 69 it would become 1969, not 2069. This means the
;            diary can be used up until 2030. If anyone is still using it
;            after that don't expect help from me!
;         5. The program now correctly sets the topaz 8 font in each window
;            that uses the graphics library text function.
;         6. Program correctly handles years. (This was a major bug - whoops!)

; v1.13 : Thanks to Peter Wesson for pointing this out. If the date given
;         in the LookUp Date window is an old date eg. in 1959, the day is
;         wrong. This was because the exec function datestamp returns the
;         date as the number of seconds since midnight, 1st Jan 1978. When
;         I changed the range of years allowed in to 1930 onwards (v1.12), I
;         forgot to take this into consideration, so any date before 1.1.78
;         would give the wrong day. This has now been fixed.


; Known Bugs
; ----------

; AmigaDiary seems to cause problems for ToolsDaemon v2.0b - I don't know
; why. The error reported is "can't find .info!" when I try to select a
; menu option. I think the problem lies in ToolsDaemon, though, because 
; I have had this error when AmigaDiary has not even been running.


*-------------- INCLUDES AND DEFINITIONS --------------------------------*


;(* LIBRARIES ...							 *)
execbase	equ	4

close		equ	-36		DOS
datestamp	equ	-192
open		equ	-30
read		equ	-42
write		equ	-48
					
allocmem	equ	-198		EXEC
closelib	equ	-414		
findtask	equ	-294
freemem		equ	-210
getmsg		equ	-372
openlib		equ	-408
replymsg	equ	-378
waitport	equ	-384
				
closefont	equ	-78		GRAPHICS
rectfill	equ	-306
move		equ	-240
openfont	equ	-72
setApen		equ	-342
setDrMd		equ	-354
setfont		equ	-66
text		equ	-60
					
activategadget	equ	-462
closewindow	equ	-72		INTUITION		
drawborder	equ	-108
drawimage	equ	-114
openwindow	equ	-204
printItext	equ	-216
refreshGlist	equ	-432


;(* DIARY STRUCTURES ...						 *)
cal_year	equ	0		CALENDAR pointer to year

yr_size		equ	54		YEAR	total size
yr_year		equ	4			eg.1992
yr_next		equ	0			pointer to next in list
yr_list		equ	6			12 pointers to 12 months			

mon_size	equ	6		MONTH	total size
mon_number	equ 	4			number of entries in month
mon_day		equ	0			pointer to 1st (used) day

day_size	equ	10		DAY	total size
day_day		equ	8			eg. 16 = 16th
day_entry	equ	4			pointer to entry list
day_next	equ	0			pointer to next day 

ent_size	equ	14		ENTRY	total size
ent_text	equ	0			pointer to text block
ent_next	equ	4			pointer to next entry 
ent_txt_size	equ	8			size of text block (bytes)
ent_stat	equ	10			control word
ent_time	equ	12			eg 0915 = 9.15 am

;					SCRIBBLEPAD ENTRY
scribent_size	equ	14			total size
scribent_next	equ	0			next entry in list
scribent_text	equ	4			pointer to text
scribent_txt_size equ	8			size of text block (bytes)
scrib_ident	equ	10			identifier

line_width	equ	15		ENTRY TEXT 	
;						max no. of chars
;						(also change line_break!!)

scrib_width	equ	35		SCRIBBLEPAD TEXT
;						max no. of chars
scrib_bottom	equ	160			pixel position of pad
;						lower margin

page_limit	equ	150		DIARY PAGE lower limit

;(* EXTERNAL FILE ...							 *)
mode_old	equ	1005
mode_new	equ	1006


;(* DATE ...								 *)
date_yr		equ	0		DATE 	year  yyyy
date_mon	equ	4			month mm
date_day1	equ	8			day1  dd (eg. 16th)
date_day2	equ	12			day2  (eg. 0=Sunday)


;(* FLAGS ...								 *)
;(* Offsets represent bits for each byte flag.				 *)
leap		equ	0		FLAG 1
quitp		equ	1
timeyn		equ	2
linebrk		equ	3
editinp		equ	4
one_entry	equ	5
firstentry	equ	6
scribover	equ	7

scribop		equ	0		FLAG 2
addentop	equ	1
shrinkop	equ	2
aboutop		equ	3
requestop	equ	4
lookop		equ	5
loadop		equ	6
saveop		equ	7

scribaeop	equ	0		FLAG 3
editop		equ	1
scribeditop	equ	2
strgad		equ	3
hrsgad		equ	4
minsgad		equ	5
topazUset	equ	6
topazset	equ	7

scribsplit	equ	0		FLAG 4
pagebottom	equ	1
splitentry	equ	2
sidetwo		equ	3
change		equ	4
scribeditinp	equ	5
defaultfile	equ	6

		;opt 	d+


*-------------- MAIN LOOP -----------------------------------------------*

;(* Initialises variables, opens libraries, opens main window and sets 	 *)
;(* the display.							 *)
Start		bsr	Workbench		icon or CLI?
		bsr	Init
		bsr	Openint
		beq	badint
		bsr	Opengfx
		beq	badgfx
		bsr	Opendos
		beq	baddos
		bsr	LoadDefault		load default AD entry file
		bsr	Topaz			open topaz 8 font
		bsr	OpenShrinkwind
		move.l	shrinkhd,d0
		tst.l	d0
		beq	badwind
		bsr	GetDate
		move.w	#45,dateXpos
		move.w	#19,dateYpos
		move.l	shrinkhd,displayhd
		bsr	DisplayDate

loop		bsr	Main
		btst	#quitp,flag1		Quit program ?	
		beq	loop

error		bsr	DFS			Free all diary memory
		bsr	ScribClear		Free all SP memory
		bsr	CloseTopaz		Close the font
		bsr	CloseAEwind
		bsr	CloseSPwind
		bsr	Closewind		main 
		bsr	CloseShrinkwind		shrink
		bsr	CloseAboutWind		about
		bsr	CloseInvInpWind		invalid inputs
		bsr	CloseLEwind		lookup entry
		bsr	CloseLFwind		load file
		bsr	CloseSFwind		save file
		bsr	CloseSAEwind		scribblepad add entry
		bsr	CloseEditwind		edit entry
		bsr	CloseSEEwind		scribblepad edit entry
badwind		bsr	Closedos
baddos		bsr	Closegfx
badgfx		bsr	Closeint
badint		rts



*-------------- ENVIRONMENT ROUTINES ------------------------------------*


;(* If the program is started by clicking an icon, instead of a CLI	 *)
;(* command, a message must be returned.				 *)
Workbench	move.l	execbase,a6
		sub.l	a1,a1
		jsr	findtask(a6)
		move.l	d0,a4
		tst.l	$ac(a4)
		bne	.out		CLI
		lea	$5c(a4),a0
		jsr	waitport(a6)
		jsr	getmsg(a6)
.out		rts


;(* Opens the intuition library.					 *)
Openint		move.l	execbase,a6
		lea	intname,a1
		jsr	openlib(a6)
		move.l	d0,intbase
		rts

;(* Opens the graphics library.						 *)
Opengfx		move.l	execbase,a6
		lea	gfxname,a1
		jsr	openlib(a6)
		move.l	d0,gfxbase
		rts

;(* Opens the dos library.						 *)
Opendos		move.l	execbase,a6
		lea	dosname,a1
		jsr	openlib(a6)
		move.l	d0,dosbase
		rts

;(* Opens the main display window.					 *)
Openwind	move.l	intbase,a6
		lea	window_defs,a0
		jsr	openwindow(a6)
		move.l	d0,windowhd
		move.l	d0,displayhd
		bsr	SetTopaz
		rts

;(* Opens the ScribblePad window.					 *)
OpenSPwind	btst	#scribop,flag2		window open?
		bne	.out			yes
		move.l	intbase,a6
		lea	spw_defs,a0
		jsr	openwindow(a6)
		move.l	d0,spwhd
		cmp.l	#0,d0			window open ok?
		beq	.out
		bset	#scribop,flag2
		move.l	d0,displayhd
		bsr	SetTopaz		
.out		rts


;(* Opens the Add Entry window.						 *)
OpenAEwind	btst	#addentop,flag2		window open?
		bne	.out			yes
		move.l	intbase,a6
		lea	ae_defs,a0
		jsr	openwindow(a6)
		move.l	d0,aehd
		cmp.l	#0,d0			window open ok?
		beq	.out
; This activates the gadget so the user does not have to click it. 
; NB may only work with some versions of intuition (because it is a high
; offset, it doesn't even appear in my System Programmer's Guide!)
		move.l	intbase,a6
		move.l	#entry_sgadget,a0	gadget
		move.l	d0,a1			window
		move.l	#0,a2			requestor (nil)
		jsr	activategadget(a6)
		bset	#addentop,flag2
		bset	#strgad,flag3
		bclr	#hrsgad,flag3
		bclr	#minsgad,flag3
.out		rts


;(* Opens the Shrink window.						 *)
OpenShrinkwind	btst	#shrinkop,flag2		window open?
		bne	.out			yes
		move.l	intbase,a6
		lea	shrink_defs,a0
		jsr	openwindow(a6)
		move.l	d0,shrinkhd
		cmp.l	#0,d0			window open ok?
		beq	.out
		bset	#shrinkop,flag2		
		move.l	d0,displayhd
		bsr	SetTopaz
.out		rts


;(* Opens the About window.						 *)
OpenAboutwind	btst	#aboutop,flag2		window open?
		bne	.out			yes
		move.l	intbase,a6
		lea	about_defs,a0
		jsr	openwindow(a6)
		move.l	d0,abouthd
		cmp.l	#0,d0			window open ok?
		beq	.out
		bset	#aboutop,flag2		
.out		rts


;(* Opens the Invalid Inputs requestor.					 *)
OpenInvInpwind	btst	#requestop,flag2	window open?
		bne	.out			yes
		move.l	intbase,a6
		lea	request_defs,a0
		jsr	openwindow(a6)
		move.l	d0,requesthd
		cmp.l	#0,d0			window open ok?
		beq	.out
		bset	#requestop,flag2		
		move.l	intbase,a6	
		move.l	requesthd,a0
		move.l	50(a0),a0
		move.l	#invinp_text,a1
		move.l	#0,d0
		move.l	#0,d1
		jsr	printItext(a6)
		move.l	intbase,a6
		move.l	requesthd,a0
		move.l	50(a0),a0		raster
		lea	stop_image,a1
		move.w	#20,d0
		move.w	#22,d1
		jsr	drawimage(a6)
.out		rts


;(* Opens the Invalid File requestor.					 *)
OpenBadFilewind	btst	#requestop,flag2	window open?
		bne	.out			yes
		move.l	intbase,a6
		lea	request_defs,a0
		jsr	openwindow(a6)
		move.l	d0,requesthd
		cmp.l	#0,d0			window open ok?
		beq	.out
		bset	#requestop,flag2		
		move.l	intbase,a6	
		move.l	requesthd,a0
		move.l	50(a0),a0
		move.l	#badfile_text,a1
		move.l	#0,d0
		move.l	#0,d1
		jsr	printItext(a6)
		move.l	intbase,a6
		move.l	requesthd,a0
		move.l	50(a0),a0		raster
		lea	stop_image,a1
		move.w	#20,d0
		move.w	#22,d1
		jsr	drawimage(a6)
.out		rts


;(* Opens the Lookup Entry window.					 *)
OpenLEwind	btst	#lookop,flag2		window open?
		bne	.out			yes
		move.l	intbase,a6
		lea	le_defs,a0
		jsr	openwindow(a6)
		move.l	d0,lehd
		cmp.l	#0,d0			window open ok?
		beq	.out
; This activates the gadget so the user does not have to click it. 
; NB may only work with some versions of intuition (because it is a high
; offset, it doesn't even appear in my System Programmer's Guide!)
		move.l	intbase,a6
		move.l	#date_sgadget,a0	gadget
		move.l	d0,a1			window
		move.l	#0,a2			requestor (nil)
		jsr	activategadget(a6)
		bset	#lookop,flag2
.out		rts


;(* Opens the Load File window.						 *)
OpenLFwind	btst	#loadop,flag2		window open?
		bne	.out			yes
		move.l	intbase,a6
		lea	lf_defs,a0
		jsr	openwindow(a6)
		move.l	d0,lfhd
		cmp.l	#0,d0			window open ok?
		beq	.out
; This activates the gadget so the user does not have to click it. 
; NB may only work with some versions of intuition (because it is a high
; offset, it doesn't even appear in my System Programmer's Guide!)
		move.l	intbase,a6
		move.l	#fileload_sgadget,a0	gadget
		move.l	d0,a1			window
		move.l	#0,a2			requestor (nil)
		jsr	activategadget(a6)
		bset	#loadop,flag2
.out		rts


;(* Opens the Save File window.						 *)
OpenSFwind	btst	#saveop,flag2		window open?
		bne	.out			yes
		move.l	intbase,a6
		lea	sf_defs,a0
		jsr	openwindow(a6)
		move.l	d0,sfhd
		cmp.l	#0,d0			window open ok?
		beq	.out
; This activates the gadget so the user does not have to click it. 
; NB may only work with some versions of intuition (because it is a high
; offset, it doesn't even appear in my System Programmer's Guide!)
		move.l	intbase,a6
		move.l	#filesave_sgadget,a0	gadget
		move.l	d0,a1			window
		move.l	#0,a2			requestor (nil)
		jsr	activategadget(a6)
		bset	#saveop,flag2
.out		rts


;(* Opens the ScribblePad Add Entry window.				 *)
OpenSAEwind	btst	#scribaeop,flag3	window open?
		bne	.out			yes
		move.l	intbase,a6
		lea	sae_defs,a0
		jsr	openwindow(a6)
		move.l	d0,saehd
		cmp.l	#0,d0			window open ok?
		beq	.out
; This activates the gadget so the user does not have to click it. 
; NB may only work with some versions of intuition (because it is a high
; offset, it doesn't even appear in my System Programmer's Guide!)
		move.l	intbase,a6
		move.l	#scribentry_sgadget,a0	gadget
		move.l	d0,a1			window
		move.l	#0,a2			requestor (nil)
		jsr	activategadget(a6)
		bset	#scribaeop,flag3
.out		rts


;(* Opens the ScribblePad Edit Entry window.			 	*)
OpenSEEwind	btst	#scribeditop,flag3	window open?
		bne	.out			yes
		move.l	intbase,a6
		lea	scribedit_defs,a0
		jsr	openwindow(a6)
		move.l	d0,scribedithd
		cmp.l	#0,d0			window open ok?
		beq	.out
; This activates the gadget so the user does not have to click it. 
; NB may only work with some versions of intuition (because it is a high
; offset, it doesn't even appear in my System Programmer's Guide!)
		move.l	intbase,a6
		move.l	#scribedit_sgadget,a0	gadget
		move.l	d0,a1			window
		move.l	#0,a2			requestor (nil)
		jsr	activategadget(a6)
		bset	#scribeditop,flag3
.out		rts


;(* Opens the Edit Entry window.				 	*)
OpenEditwind	btst	#editop,flag3		window open?
		bne	.out			yes
		move.l	intbase,a6
		lea	edit_defs,a0
		jsr	openwindow(a6)
		move.l	d0,edithd
		cmp.l	#0,d0			window open ok?
		beq	.out
		move.l	d0,displayhd
		bsr	SetTopaz
; This activates the gadget so the user does not have to click it. 
; NB may only work with some versions of intuition (because it is a high
; offset, it doesn't even appear in my System Programmer's Guide!)
		move.l	intbase,a6
		move.l	#editentry_sgadget,a0	gadget
		move.l	d0,a1			window
		move.l	#0,a2			requestor (nil)
		jsr	activategadget(a6)
		bset	#editop,flag3
		bset	#strgad,flag3
		bclr	#hrsgad,flag3
		bclr	#minsgad,flag3
.out		rts


;(* Sets up the display in the main window, displays the date.	 	*)
SetUpDisplay	bsr	BlankPages
		move.w	#120,dateXpos
		move.w	#163,dateYpos
		move.l	windowhd,displayhd
		bsr	GetDate
		bsr	DisplayDate		display today's date
		rts


;(* Sets the display in the Add Entry window.			 	*)
SetUpAEDisplay	move.l	gfxbase,a6
		move.l	aehd,a1
		move.l	#1,d0
		bsr	pencolour		set white pen	
		move.w	#330,d0
		move.w	#46,d1
		move.l	aehd,a1
		bsr	movepos			move the cursor
		move.l	#includetime,a0
		move.l	aehd,a1
		move.l	#13,d0
		bsr	displaytext
;(* Set the time option gadget to reflect the status of the time yes/no  *)
;(* flag. This way, the default yes/no value is the same as the last 	 *)
;(* entry specified.							 *)
		btst	#timeyn,flag1		time on?
		beq	.notime
		bsr	timey_disp		yes
		bra	.out
.notime		bsr	timen_disp
.out		rts


;(* Sets the display in the Edit Entry window.				 *)
SetUpEditDisplay
		move.l	gfxbase,a6
		move.l	edithd,a1
		move.l	#1,d0
		bsr	pencolour		set white pen	
		move.w	#200,d0
		move.w	#51,d1
		move.l	edithd,a1
		bsr	movepos			move the cursor
		move.l	#includetime,a0
		move.l	edithd,a1
		move.l	#13,d0
		bsr	displaytext
		rts


;(* Display the time yes/no gadget as selected.				 *)
timey_disp	move.l	intbase,a6
		btst	#addentop,flag2		which window?
		beq	.edit
;(* Change the gadget in the add entry window.				 *)
		move.l	aehd,a0
		move.w	#440,d0
		move.w	#38,d1
		bra	.out
;(* Change the gadget in the edit entry window.				 *)
.edit		move.l	edithd,a0
		move.w	#310,d0
		move.w	#43,d1
.out		move.l	50(a0),a0		raster
		lea	timeyesi_image,a1
		jsr	drawimage(a6)
		rts

;(* Display the time yes/no gadget as not selected.			 *)
timen_disp	move.l	intbase,a6
		btst	#addentop,flag2		which window?
		beq	.edit
;(* Change the gadget in the add entry window.				 *)
		move.l	aehd,a0
		move.w	#440,d0
		move.w	#38,d1
		bra	.out
;(* Change the gadget in the edit entry window.				 *)
.edit		move.l	edithd,a0
		move.w	#310,d0
		move.w	#43,d1
.out		move.l	50(a0),a0		raster
		lea	timeyes_image,a1
		jsr	drawimage(a6)
		rts


;(* Sets the flag for when the entry string gadget is seleted.		 *)
StrSel		bset	#strgad,flag3
		bclr	#hrsgad,flag3
		bclr	#minsgad,flag3
		bra	reply

;(* Sets the flag for when the entry string gadget is seleted.		 *)
HrsSel		bset	#hrsgad,flag3
		bclr	#strgad,flag3
		bclr	#minsgad,flag3
		bra	reply

;(* Sets the flag for when the entry string gadget is seleted.		 *)
MinsSel		bset	#minsgad,flag3
		bclr	#strgad,flag3
		bclr	#strgad,flag3
		bra	reply


;(* Clears the pages of the diary by drawing a white rectangle.		 *)
BlankPages	move.l	windowhd,a1
		move.l	#1,d0
		bsr	pencolour
		move.l	gfxbase,a6
		move.l	windowhd,a1
		move.l	50(a1),a1		rastport
		move.l	#8,d0
		move.l	#13,d1
		move.l	#352,d2
		move.l	#149,d3
		jsr	rectfill(a6)		fill 'pages'
		move.l	windowhd,a0
		lea	border1,a1
		move	#0,d0
		move	#0,d1
		bsr	BorderDraw
		move.l	intbase,a6
		move.l	#flip_gadget,a0
		move.l	windowhd,a1
		move.l	#0,a2
		move.l	#1,d0			number of gadgets
		jsr	refreshGlist(a6)
		rts


;(* Expects window hd in a0, border structure in a1. X,Y pos in d0,d1	 *)
BorderDraw	move.l	intbase,a6
		move.l	50(a0),a0 
		jsr	drawborder(a6)
		rts


Init		move.l	#0,calendar		pointer to years list		
		move.l	#0,start_entry
		move.l	#0,next_entry
		move.l	#0,page_start
		move.l	#1,scribmarker
		move.b	#0,flag1		clear all flags
		move.b	#0,flag2
		move.b	#0,flag3
		move.b	#0,flag4
		bset	#timeyn,flag1		time yes (AE gadgets)
		bsr	ClearEntryString
		bsr	ClearEditString
		rts
t

;(* Opens the topaz 8 font, normal and underlined.			 *)
Topaz		move.l	gfxbase,a6
		move.l	#topaz_defs,a0
		jsr	Openfont(a6)		result in d0
		tst.l	d0
		beq	.out
		move.l	d0,topazbase
		bset	#topazset,flag3
;(* Now open the underlined topaz font					 *)
		move.l	gfxbase,a6
		move.l	#topazU_defs,a0
		jsr	Openfont(a6)		result in d0
		tst.l	d0
		beq	.out
		move.l	d0,topazUbase
.out		rts


;(* Sets the topaz 8 font. Expects current window pointer in displayhd.	 *)
SetTopaz	move.l	gfxbase,a6
		move.l	topazbase,a0
		move.l	displayhd,a1
		move.l	50(a1),a1
		jsr	Setfont(a6)
		rts


;(* Sets the year, month, day to zero.					 *)
ClearDate	move.l	#date,a0
		move.l	#0,date_yr(a0)		clear date
		move.l	#0,date_mon(a0)
		move.l	#0,date_day1(a0)
		move.l	#0,date_day2(a0)
		rts

;(* Introduces blank characters into the string displayed as a 5-digit	 *)
;(* decimal number.							 *)
ClearDecString	move.l	#0,decnumber
		move.l	#decstring,a0
		move.l	"    ",(a0)+		clear decstring
		move.b	" ",(a0)
		rts


;(* Closes all open program windows, and displays the shrink window. *)
Shrink		bsr	Closewind
		bsr	CloseSPwind
		bsr	CloseAEwind
		bsr	CloseAboutwind
		bsr	CloseInvInpwind
		bsr	CloseLEwind
		bsr	CloseLFwind
		bsr	CloseSFwind
		bsr	CloseSAEwind
		bsr	CloseSEEwind
		bsr	CloseEditwind
		bsr	OpenShrinkwind
		bsr	GetDate
		move.w	#45,dateXpos
		move.w	#19,dateYpos
		move.l	shrinkhd,displayhd
		bsr	DisplayDate
		bra	finishmessage		cannot replymessage 
					       ;because main window
					       ;closed.

;(* Closes the shrink window, and restores the main window and diary	 *)
;(* pages.								 *)
Unshrink	bsr	CloseShrinkwind		
		bsr	Openwind
		bsr	SetUpDisplay
		bsr	FindEntry
		move.l	a1,start_entry
		move.l	a1,page_start
		bsr	DisplayPages	 	re-display entries
		bra	finishwait
		

;(* Opens the about window and displays author & program information	 *)
About		bsr	OpenAboutwind
		tst.l	d0
		beq	.error
		move.l	intbase,a6	
		move.l	abouthd,a0
		move.l	50(a0),a0
		move.l	#line1_text,a1
		move.l	#0,d0
		move.l	#0,d1
		jsr	printItext(a6)
.error		bra	reply


;(* Closes the invalid inputs requestor after selecting the OK gadget.	 *)
Ok		bsr	CloseInvInpwind
		bra	finishmessage
		

Main		btst	#shrinkop,flag2		shrunk?
		beq	.next			no, continue
		move.l	shrinkhd,currentwindow
		bsr	Wait
		rts
.next		btst	#requestop,flag2	Error requestor?
		beq	.next1
		move.l	requesthd,currentwindow
		bsr	Checkmsg
		rts
.next1		btst	#addentop,flag2		AE window open?
		beq	.next3
		move.l	aehd,currentwindow
		bsr	Checkmsg
		rts
.next3		btst	#aboutop,flag2		About window open?
		beq	.next4
		move.l	abouthd,currentwindow
		bsr	Checkmsg
		rts
.next4		btst	#lookop,flag2		Lookup Entry window open?
		beq	.next5
		move.l	lehd,currentwindow
		bsr	Checkmsg
		rts
.next5		btst	#loadop,flag2		Load File window open?
		beq	.next6
		move.l	lfhd,currentwindow
		bsr	Checkmsg
		rts
.next6		btst	#saveop,flag2		Save File window open?
		beq	.next7	
		move.l	sfhd,currentwindow
		bsr	Checkmsg
		rts
.next7		btst	#scribaeop,flag3	ScribblePad Add Entry?
		beq	.next8
		move.l	saehd,currentwindow
		bsr	Checkmsg
		rts
.next8		btst	#scribeditop,flag3	ScribblePad Edit Entry?
		beq	.next9
		move.l	scribedithd,currentwindow
		bsr	Checkmsg
		rts
.next9		btst	#editop,flag3		Edit Entry window open?
		beq	.next10
		move.l	edithd,currentwindow
		bsr	Checkmsg
		rts
.next10		btst	#scribop,flag2		SP window open?
		beq	.next11
		move.l	spwhd,currentwindow	
		bsr	Checkmsg
		rts
.next11		move.l	windowhd,currentwindow	Main window
		bsr	Checkmsg
.out		rts


;(* Waits for a message from the shrink window. This speeds up other	 *)
;(* programs that are multitasking.					 *)
Wait		move.l	execbase,a6
		move.l	currentwindow,a0
		move.l	86(a0),a0
		jsr	waitport(a6)
		move.l	currentwindow,a0
		move.l	86(a0),a0
		jsr	getmsg(a6)
		move.l	d0,message
		bra	CloseGadget		unshrink gadget selected 
finishwait	rts


;(* Checks for the occurence of an event, and calls the correct 	 *)
;(* routine to interpret that event.					 *)
Checkmsg	bsr	ClearPort		remove any queued messages
		move.l	execbase,a6
		move.l	currentwindow,a0
		move.l	86(a0),a0
		jsr	waitport(a6)
		move.l	execbase,a6
		move.l	currentwindow,a0
		move.l	86(a0),a0		UserPort (^MsgPort)
		jsr	getmsg(a6)
		move.l	d0,message		^IntuiMessage
		cmp.l	#0,d0			did event occur?
		beq	finishmessage		no
		move.l	d0,d6
		bsr	replymessage
		move.l	d6,a0			
		move.l	20(a0),d6		message Class
		cmp.l	#$8,d6
		beq	MouseHit
		cmp.l	#$20,d6
		beq	GadgetHit
		cmp.l	#$40,d6
		beq	GadgetHit
		cmp.l	#$200,d6
		beq	CloseGadget
		cmp.l	#$400,d6
		beq	Keypress
reply		
finishmessage	rts


;(* Clears the port of any messages that are already waiting. This 	 *)
;(* prevents messages 'queueing' on a window that is not yet ready to	 *)
;(* receive messages.							 *)
ClearPort	move.l	execbase,a6
.loop		move.l	currentwindow,a0
		move.l	86(a0),a0
		jsr	getmsg(a6)
		tst.l	d0
		beq	.out
		move.l	d0,message
		bsr	replymessage
		bra	.loop	
.out		rts


;(* Replies to a system message.					 *)
ReplyMessage	move.l	execbase,a6
		move.l	message,a1
		jsr	replymsg(a6)
		rts


;(* If in shrink mode, 'unshrink' diary, else set quitp flag true.	 *)
CloseGadget	btst	#shrinkop,flag2		Window shrunk?
		bne	Unshrink
		bset	#quitp,flag1		Quit program
		bra	finishmessage


MouseHit	btst	#aboutop,flag2		About window open?
		beq	.out
		bsr	CloseAboutwind
.out		bra	finishmessage


;(* Takes appropriate action for a keypress. Expects pointer to 	 *)
;(* IntuiMessage in a0.							 *)
Keypress	move.w	26(a0),d1		message qualifier
		btst	#3,d1			Ctrl key?
		bne	.Ctrl			yes
		move.w	24(a0),d0		message code
		cmp.w	#$c4,d0			CR within gadget?
		beq	.CR			yes
		cmp.w	#$44,d0			CR?
		bne	.out
.CR		btst	#lookop,flag2
		bne	LookUpDate		as gadget $41
		btst	#loadop,flag2
		bne	Load_File		as gadget $61
		btst	#saveop,flag2
		bne	SaveFile		as gadget $51
		btst	#addentop,flag2
		bne	AddEntryCR		
		btst	#editop,flag3
		bne	EditEntryCR
		btst	#scribaeop,flag3
		bne	AddScribEntry		as gadget $81
		btst	#scribeditop,flag3
		bne	ChangeScribEntry	as gadget $a3
		bra	.out
.Ctrl		move.w	24(a0),d0		message code
		cmp.w	#$21,d0			Ctrl + s?
		beq	Save
		cmp.w	#$28,d0			Ctrl + l?
		beq	Load
		cmp.w	#$35,d0			Ctrl + b?
		beq	About
		cmp.w	#$25,d0			Ctrl + h?
		beq	Shrink
		cmp.w	#$18,d0			Ctrl + o?
		beq	SelectLE
		cmp.w	#$20,d0			Ctrl + a?
		beq	SelectAE
		cmp.w	#$12,d0			Ctrl + e?
		beq	Edit
		cmp.w	#$33,d0			Ctrl + c?
		beq	SelectSP
.out		rts


;(* Takes appropriate action for a gadget click. Expects pointer to	 *)
;(* IntuiMessage in a0.							 *)
GadgetHit	move.l	28(a0),a1	report structure (gadget structure
;					in this instance)
		move.w	38(a1),d0	Gadget ID
		cmp.w	#$10,d0
		beq	DayForward
		cmp.w	#$11,d0
		beq	DayBackward
		cmp.w	#$12,d0
		beq	WeekBackward
		cmp.w	#$13,d0
		beq	WeekForward
		cmp.w	#$14,d0
		beq	SelectAE
		cmp.w	#$15,d0
		beq	SelectSP
		cmp.w	#$16,d0
		beq	SelectLE
		cmp.w	#$17,d0
		beq	Edit
		cmp.w	#$18,d0
		beq	Load
		cmp.w	#$19,d0
		beq	Save
		cmp.w	#$1a,d0
		beq	About
		cmp.w	#$1b,d0
		beq	Shrink
		cmp.w	#$1c,d0
		beq	FlipPage
		cmp.w	#$20,d0
		beq	InsertAnEntry
		cmp.w	#$21,d0
		beq	ClearInput
		cmp.w	#$22,d0
		beq	CloseAE
		cmp.w	#$23,d0
		beq	StrSel
		cmp.w	#$24,d0
		beq	HrsSel
		cmp.w	#$25,d0
		beq	MinsSel
		cmp.w	#$28,d0
		beq	TimeOption
		cmp.w	#$41,d0
		beq	LookupDate
		cmp.w	#$42,d0
		beq	CloseLE
		cmp.w	#$51,d0
		beq	SaveFile
		cmp.w	#$52,d0
		beq	CloseSF
		cmp.w	#$61,d0
		beq	Load_File
		cmp.w	#$62,d0
		beq	CloseLF
		cmp.w	#$70,d0
		beq	SelectSAE
		cmp.w	#$71,d0
		beq	CloseSP
		cmp.w	#$72,d0
		beq	NextSP
		cmp.w	#$73,d0
		beq	SelectSee
		cmp.w	#$81,d0
		beq	AddScribEntry
		cmp.w	#$82,d0
		beq	ClearScribInput
		cmp.w	#$83,d0
		beq	CloseSAE
		cmp.w	#$90,d0
		beq	StrSel
		cmp.w	#$91,d0
		beq	HrsSel
		cmp.w	#$92,d0
		beq	MinsSel
		cmp.w	#$93,d0
		beq	TimeOption
		cmp.w	#$94,d0
		beq	NextEntry
		cmp.w	#$95,d0
		beq	PrevEntry
		cmp.w	#$96,d0
		beq	DelEntry
		cmp.w	#$97,d0
		beq	ClearEditInput
		cmp.w	#$98,d0
		beq	ChangeEntry
		cmp.w	#$99,d0
		beq	CloseEdit
		cmp.w	#$a1,d0
		beq	DelScribEntry
		cmp.w	#$a2,d0
		beq	ClearSEditInput
		cmp.w	#$a3,d0
		beq	ChangeScribEntry
		cmp.w	#$a4,d0
		beq	CloseSEE
		cmp.w	#$a5,d0
		beq	NextScribEntry
		cmp.w	#$a6,d0
		beq	PrevScribEntry
.request	cmp.w	#$30,d0
		beq	Ok
		bra	reply


;(* moves the text cursor. Expects x,y positon in d0,d1. Also window hd  *)
;(* in a1								 *)
movepos		move.l	gfxbase,a6		x,y in d0,d1
		move.l	50(a1),a1
		jsr	move(a6)
		rts


;(* displays text in the current window. Expects text address in a0,     *)
;(* window hd in a1, text length in d0.				 	 *)  
Displaytext	move.l	gfxbase,a6	
		move.l	50(a1),a1		rastport
		jsr	text(a6)
		rts


;(* changes the pen colour. Expects colour in d0, window hd in a1	 *)
PenColour	move.l	gfxbase,a6
		move.l	50(a1),a1		get rastport
		jsr	SetApen(a6)
		rts


;(* Closes the topaz font, if open.					 *)
CloseTopaz	btst	#topazset,flag3
		beq	.out
		move.l	gfxbase,a6
		move.l	topazbase,a1
		jsr	Closefont(a6)
		bclr	#topazset,flag3
		btst	#topazUset,flag3
		beq	.out
		move.l	gfxbase,a6
		move.l	topazUbase,a1
		jsr	Closefont(a6)
		bclr	#topazUset,flag3
.out		rts


;(* Closes the Edit Entry window, if open.				 *)
CloseEditwind	btst	#editop,flag3		window open?
		beq	.out			no
		move.l	intbase,a6
		move.l	edithd,a0
		jsr	closewindow(a6)
		bclr	#editop,flag3
.out		rts


;(* Closes the ScribblePad Add Entry window, if open.			 *)
CloseSAEwind	btst	#scribaeop,flag3	window open?
		beq	.out			no
		move.l	intbase,a6
		move.l	saehd,a0
		jsr	closewindow(a6)
		bclr	#scribaeop,flag3
.out		rts


;(* Closes the ScribblePad Edit Entry window, if open.			 *)
CloseSEEwind	btst	#scribeditop,flag3	window open?
		beq	.out			no
		move.l	intbase,a6
		move.l	scribedithd,a0
		jsr	closewindow(a6)
		bclr	#scribeditop,flag3
.out		rts


;(* Closes the Save File window, if open.				 *)
CloseSFwind	btst	#saveop,flag2		window open?
		beq	.out			no
		move.l	intbase,a6
		move.l	sfhd,a0
		jsr	closewindow(a6)
		bclr	#saveop,flag2
.out		rts


;(* Closes the Load File window, if open.				 *)
CloseLFwind	btst	#loadop,flag2		window open?
		beq	.out			no
		move.l	intbase,a6
		move.l	lfhd,a0
		jsr	closewindow(a6)
		bclr	#loadop,flag2
.out		rts


;(* Closes the Lookup Entry window, if open.				 *)
CloseLEwind	btst	#lookop,flag2		window open?
		beq	.out			no
		move.l	intbase,a6
		move.l	lehd,a0
		jsr	closewindow(a6)
		bclr	#lookop,flag2
.out		rts


;(* Closes the Invalid Inputs Requestor, if open			 *)
CloseInvInpwind	btst	#requestop,flag2	window open?
		beq	.out			no
		move.l	intbase,a6
		move.l	requesthd,a0
		jsr	closewindow(a6)
		bclr	#requestop,flag2
.out		rts


;(* Closes the About window, if open					 *)
CloseAboutwind	btst	#aboutop,flag2		window open?
		beq	.out			no
		move.l	intbase,a6
		move.l	abouthd,a0
		jsr	closewindow(a6)
		bclr	#aboutop,flag2
.out		rts


;(* Closes the shrink window, if open.					 *)
CloseShrinkwind	btst	#shrinkop,flag2		window open?
		beq	.out			no
;(* First, save the position of the window by copying the position to	 *)
;(* the window structure used by openwindow.				 *)
		move.l	shrinkhd,a0		window structure
		move.l	#shrink_defs,a1		open window structure
		move.w	4(a0),(a1)		copy x pos
		move.w	6(a0),2(a1)		copy y pos
;(* Now close the window.						 *)
		move.l	intbase,a6
		move.l	shrinkhd,a0
		jsr	closewindow(a6)
		bclr	#shrinkop,flag2
.out		rts


;(* Closes the Add Entry window, if open				 *)
CloseAEwind	btst	#addentop,flag2		window open?
		beq	.out			no
		move.l	intbase,a6
		move.l	aehd,a0
		jsr	closewindow(a6)
		bclr	#addentop,flag2
.out		rts


;(* Closes the ScribblePad window, if open.				 *)
CloseSPwind	btst	#scribop,flag2		window open?
		beq	.out			no
		move.l	intbase,a6
		move.l	spwhd,a0
		jsr	closewindow(a6)
		bclr	#scribop,flag2
.out		rts


;(* Closes the main window, if open.					 *)
Closewind	btst	#shrinkop,flag2		shrunk?
		bne	.out			yes
;(* First, save the position of the window by copying the position to	 *)
;(* the window structure used by openwindow.				 *)
		move.l	windowhd,a0		window structure
		move.l	#window_defs,a1		open window structure
		move.w	4(a0),(a1)		copy x pos
		move.w	6(a0),2(a1)		copy y pos
;(* Now close the window.						 *)
		move.l	intbase,a6
		move.l	windowhd,a0
		jsr	closewindow(a6)
.out		rts


;(* Closes the dos library.						 *)
Closedos	move.l	execbase,a6
		move.l	dosbase,a1
		jsr	closelib(a6)
		rts


;(* Closes the Graphics library.					 *)
Closegfx	move.l	execbase,a6
		move.l	gfxbase,a1
		jsr	closelib(a6)
		rts


;(* Closes the Intuition library.					 *)
Closeint	move.l	execbase,a6
		move.l	intbase,a1
		jsr	closelib(a6)
		rts	



*-------------- DATE ROUTINES -------------------------------------------*


;(* Gets the internal format of date & time, and returns the date in the *)
;(* four longwords stored as 'date'. Format is day1 (eg. Sun, Mon etc)   *)
;(* year, month, day2 (eg. 16th)         				 *)

GetDate		bsr	ClearDate
		bclr	#leap,flag1		clear, because bit is used
		move.l	dosbase,a6
		move.l	#date,d1		3 reserved longwords
		jsr	datestamp(a6)
		move.l	d1,a0			address of date
		move.l	(a0),d0			number of days since... 
		move.l	d0,d5			...Jan 1st, 1978
		move.l	d0,d1			store
; Get the day (0=Sunday, 1=Monday etc) first
		divs	#7,d0
		and.l	#$ffff0000,d0		get upper half (remainder) 
		swap	d0			move to lower half
		move.l  #date,a0
		move.l	d0,date_day2(a0)	store in structure
; Get the year next
		move.l	d1,d0			restore value
		move.l	#years,a1		year lengths (days)
		move.l	#0,d2			number of years
		move.l	#0,d3			counter for list
.yearloop	cmp.w	#8,d3			end of list?
		bne	.ok			no
		move.l	#0,d3			back to start of list
.ok		move.w	(a1,d3),d4
		sub.w	d4,d0
		cmp.w	#0,d0			got right year?
		blt	.foundyear
		move.l	d0,d1			update store
		add.w	#2,d3			update counter
		addq	#1,d2			increment year
		bra	.yearloop
.foundyear	move.l	d2,d4			d4=number of years
		add.l	#1978,d2
		move.l	#date,a1
		move.l	d2,date_yr(a1)		THIS YEAR

		divs	#4,d2
		swap	d2
		cmp.w	#0,d2			is this a leap year?
		bne	.notleap
		bset	#leap,flag1		yes
.notleap
		move.l	d1,d0			number days this year
		move.l	#months,a0
		move.l	#0,d3			month (jan = 0)
.loop		move.w	(a0)+,d2
		cmp.w	#28,d2			feb?
		bne	.notfeb
		btst	#leap,flag1		leap year?
		beq	.notfeb			no
		add.w	#1,d2			add one day for 29th
.notfeb		sub.w	d2,d0
		cmp.w	#0,d0
		blt	.foundmonth
		move.l	d0,d1			update store
		add.l	#1,d3	
		bra	.loop
.foundmonth	add.l	#1,d1
		move.l	d1,date_day1(a1)	DAYS THIS MONTH
		move.l	d3,date_mon(a1)		MONTH
		rts


;(* Given a date in normal format (dd-mon-yy) workout which day of the   *)
;(* week it is. Expects date as 1st 3 longwords of date, returns weekday *)
;(* as 4th longword.							 *)
;(* Advances forward from 1st Jan 1978, to given date, or backwards if   *)
;(* the date is before 1st Jan 1978.					 *)
CorrectDay	move.l	#1,tmpday
		move.l	#1978,tmpyear
		move.l	#date,a0
		move.l	#0,date_day2(a0)	Jan 1st, 1978
		move.l	date_yr(a0),d0
		cmp.l	#1978,d0
		blt	.back
		bsr	CorrectForwards
		rts
.back		bsr	CorrectBackwards
		rts

;(* Works out the week day by moving forwards from 1st Jan 1978 until	 *)
;(* the given date is found.						 *)

CorrectForwards
		move.l	#0,tmpmon
; while year < NewYear do begin
.year		move.l	#date,a0
		move.l	date_yr(a0),d3
		cmp.l	tmpyear,d3
		ble	.month
;   if year is leap, advance day2 by 2, else advance by 1
		move.l	tmpyear,d0
		bsr	isleapyear		returns boolean result
		tst.l	d0
		beq	.notleap
		move.l	#1,d0
		bsr	AdvanceWeekday
.notleap	move.l	#1,d0
		bsr	AdvanceWeekday
		add.l	#1,tmpyear
		bra	.year			end while {year}
; while mon < NewMonth do begin
.month		move.l	#date,a0
		move.l	date_mon(a0),d2
		cmp.l	tmpmon,d2
		ble	.day
;   get month length from table
		move.l	#months,a1		table of lengths
		move.l	tmpmon,d0
		muls	#2,d0			word lengths
		add.l	d0,a1
		move.w	(a1),d5			get month length
		sub.w	#1,d5
.loop1		move.l	#1,d0
		bsr	AdvanceWeekday		move through month
		dbf	d5,.loop1
		add.l	#1,tmpmon			
		bra	.month			end while {month}
; while day < NewDay do begin
.day		move.l	#date,a0
		move.l	date_day1(a0),d1
		cmp.l	tmpday,d1
		ble	.foundday
		move.l	#1,d0
		bsr	AdvanceWeekday		move forward another day
		add.l	#1,tmpday
		bra	.day
.foundday	rts				end {day}
tmpday		dc.l	0
tmpmon		dc.l	0
tmpyear		dc.l	0


;(* If the date given is before 1st Jan 1978, must search backwards to 	 *)
;(* get correct weekday.						 *)
CorrectBackwards
		move.l	#11,tmpmon
		move.l	#months,a1		table of lengths
		move.l	tmpmon,d0
		muls	#2,d0			word lengths
		add.l	d0,a1
		move.w	(a1),d5			get month length
		;sub.l	#1,d5			month starts at 0
		move.l	d5,tmpday
; while year > NewYear do begin
.year		move.l	#date,a0
		move.l	date_yr(a0),d3
		cmp.l	tmpyear,d3
		bge	.month
;   if year is leap, retreat day2 by 2, else retreat by 1
		move.l	tmpyear,d0
		bsr	isleapyear		returns boolean result
		tst.l	d0
		beq	.notleap
		move.l	#1,d0
		bsr	RetreatWeekday
.notleap	move.l	#1,d0
		bsr	RetreatWeekday
		sub.l	#1,tmpyear
		bra	.year			end while {year}
; while mon > NewMonth do begin
.month		move.l	#date,a0
		move.l	date_mon(a0),d2
		cmp.l	tmpmon,d2
		bge	.day
;   get month length from table
		move.l	#months,a1		table of lengths
		move.l	tmpmon,d0
		muls	#2,d0			word lengths
		add.l	d0,a1
		move.w	(a1),d5			get month length
		sub.w	#1,d5
.loop1		move.l	#1,d0
		bsr	RetreatWeekday		move through month
		dbf	d5,.loop1
		sub.l	#1,tmpmon			
		bra	.month			end while {month}
; while day > NewDay do begin
.day		move.l	#date,a0
		move.l	date_day1(a0),d1
		cmp.l	tmpday,d1
		bge	.foundday
		move.l	#1,d0
		bsr	RetreatWeekday		move backward another day
		sub.l	#1,tmpday
		bra	.day
.foundday	rts				end {day}



;(* Gets the date in internal format, converts it to normal format, and  *)
;(* displays it in the window as dd-mon-yy. Expects x,y position in      *)
;(* dateXpos, dateYpos. Expects current window in displayhd		 *)

DisplayDate	bsr	ClearDecString
		move.l	gfxbase,a6
		move.l	displayhd,a1
		move.l	50(a1),a1
		move.l	#1,d0			JAM2
		jsr	setDrMd(a6)		set mode
		move.l	displayhd,a1
		move.l	#3,d0
		bsr	pencolour		set orange pen
		move.l	#date,a0
		move.l	date_day1(a0),d0	day
		bsr	Convert
		move.w	dateXpos,d0
		move.w	dateYpos,d1
		move.l	displayhd,a1
		bsr	movepos
		move.w	#2,digits
		lea	decnumber,a0
		add.l	#2,a0
		bsr	DisplayDecimal		display day 

		move.w	dateXpos,d0
		add.w	#17,d0
		move.w	dateYpos,d1
		move.l	displayhd,a1
		bsr	movepos
		move.l	#date,a0
		move.l	date_mon(a0),d0		month
		muls	#3,d0
		lea	monthnames,a0
		add.l	d0,a0
		lea	decstring,a1
		move.b	#"-",(a1)+
		move.b	(a0)+,(a1)+
		move.b	(a0)+,(a1)+
		move.b	(a0),(a1)+
		move.b	#"-",(a1)
		lea	decstring,a0
		move.l	displayhd,a1
		move.w	#5,d0
		bsr	displaytext		display month 

		move.l	#0,decnumber		clear values
		move.l	#date,a0
		move.l	date_yr(a0),d0		year
		bsr	Convert
		move.w	dateXpos,d0
		add.w	#58,d0
		move.w	dateYpos,d1
		move.l	displayhd,a1
		bsr	movepos
		move.w	#4,digits
		lea	decnumber,a0
		bsr	DisplayDecimal		display year

		move.l	#date,a0
		move.l	date_day2(a0),d0	day of week
		muls	#6,d0			length of strings
		move.l	#daynames,a1		table of names
		add.l	d0,a1			get desired day
		lea	spare_text,a2		address of text
		move.w	#5,d1			length
.loop		move.b	(a1)+,(a2)+
		dbf	d1,.loop
		lea	spare_text,a0		string
		move.l	displayhd,a1
		move.w	#6,d0
		bsr	displaytext		display day 
		rts


;(* Changes the date as a result of user selecting day forward or week   *)
;(* forward. Expects number of days moved (1 or 7) in d0		 *)

DateForward	bsr	AdvanceWeekday
		move.l	#date,a0
		move.l	date_mon(a0),d1		month
		move.l	d1,d4
		move.l	date_day1(a0),d2	day
		add.l	d0,d2			add number of days
		move.l	#months,a1		month lengths
		muls	#2,d4
		move.w	(a1,d4),d3		length of this month
		cmp.w	#28,d3
		bne	.notfeb
		move.l	date_yr(a0),d0		year
		bsr	IsLeapYear
		add.w	d0,d3			result 1 or 0 added
.notfeb		cmp.w	d2,d3			still in this month?
		bge	.ok
		sub.w	d3,d2					
		add.w	#1,d1			one month forward
		cmp.w	#12,d1			end of year?
		blt	.ok
		move.l	#0,date_mon(a0)		month = Jan	
		add.l	#1,date_yr(a0)		increment year
		move.l	d2,date_day1(a0)	new date
		rts
.ok		move.l	d2,date_day1(a0)
		move.l	d1,date_mon(a0)
		rts


;(* Changes the date forward by one day, displays change in main window	 *)
DayForward	move.l	#1,d0
		bsr	DateForward
		move.w	#120,dateXpos
		move.w	#163,dateYpos
		move.l	windowhd,displayhd
		bsr	DisplayDate
		bsr	FindEntry
		move.l	a1,start_entry
		move.l	a1,page_start
		bsr	DisplayPages
		bra	reply


;(* Changes the date forward by one week, displays change in main window *)
WeekForward	move.l	#7,d0
		bsr	DateForward
		move.w	#120,dateXpos
		move.w	#163,dateYpos
		move.l	windowhd,displayhd
		bsr	DisplayDate
		bsr	FindEntry
		move.l	a1,start_entry
		move.l	a1,page_start
		bsr	DisplayPages
		bra	reply


;(* Moves the weekday (sun=0, mon=1 etc) forward by a number of days.	 *)
;(* Expects number of days in d0 (1 or 7).				 *) 
;(* Reflects the change in date.					 *)
AdvanceWeekday	move.l	#date,a0
		move.l	date_day2(a0),d2	day (0=sun, 1=mon)
		add.l	d0,d2
		cmp.l	#6,d2
		ble	.dayfine
		sub.l	#7,d2			have gone into next week
.dayfine	move.l	d2,date_day2(a0)	reflect change in date	
		rts


;(* Moves the weekday (sun=0, mon=1 etc) backward by a number of days.	 *)
;(* Expects number of days in d0 (1 or 7).				 *) 
;(* Reflects the change in date.					 *)
RetreatWeekday	move.l	#date,a0
		move.l	date_day2(a0),d2	day (0=sun, 1=mon)
		cmp.l	#0,d2
		bne	.notsun
		move.l	#7,d2
.notsun		sub.l	d0,d2
		cmp.l	#0,d2
		bge	.dayfine
		add.l	#7,d2			have gone into next week
.dayfine	move.l	d2,date_day2(a0)	reflect change in date	
		rts


;(* Changes the date as a result of user selecting day backward or week  *)
;(* backward. Expects number of days moved (1 or 7) in d0		 *)
DateBackward	bsr	RetreatWeekday		change the weekday
		move.l	#date,a0
		move.l	date_mon(a0),d1		month
		move.l	date_day1(a0),d2	day
		sub.l	d0,d2			number of days
		cmp.w	#0,d2			still this month?
		bgt	.ok
		sub.l	#1,d1			go back one month
		move.l	d1,d4			store
		cmp.l	#0,d1			still this year?
		bge	.yearok
		move.l	#11,date_mon(a0)	December
		add.l	#31,d2			set date
		move.l	d2,date_day1(a0)
		sub.l	#1,date_yr(a0)		go back one year
		rts
.yearok		move.l	#months,a1
		muls	#2,d4
		move.w	(a1,d4),d4		month length
		cmp.w	#28,d4
		bne	.notfeb
		move.l	date_yr(a0),d0		year
		bsr	IsLeapYear
		add.w	d0,d4			result 1 or 0 added
.notfeb		add.w	d4,d2			number of days
.ok		move.l	d2,date_day1(a0)		date
		move.l	d1,date_mon(a0)		month
		rts
		

;(* Changes the date back by one day, displays change in main window	 *)
DayBackward	move.l	#1,d0
		bsr	DateBackward
		move.w	#120,dateXpos
		move.w	#163,dateYpos
		move.l	windowhd,displayhd
		bsr	DisplayDate
		bsr	FindEntry
		move.l	a1,start_entry
		move.l	a1,page_start
		bsr	DisplayPages
		bra	reply


;(* Changes the date back by one week, displays change in main window.	 *)
WeekBackward	move.l	#7,d0
		bsr	DateBackward
		move.w	#120,dateXpos
		move.w	#163,dateYpos
		move.l	windowhd,displayhd
		bsr	DisplayDate
		bsr	FindEntry
		move.l	a1,start_entry
		move.l	a1,page_start
		bsr	DisplayPages
		bra	reply


;(* Determines whether or not a year is a leap year. Expects year in d0  *)
;(* Returns boolean value in d0.					 *)
IsLeapYear	divs	#4,d0
		swap	d0
		cmp.w	#0,d0			remainder = 0?
		beq	.isleap
		move.l	#0,d0
		rts
.isleap		move.l	#1,d0
		rts


;(* Opens the Load Entry window, and returns to the main loop.		 *)
SelectLE	bsr	ClearDateString
		bsr	OpenLEwind
		tst.l	d0
		beq	.error
.error		bra	reply


;(* Closes the Lookup Entry window, and returns to the main display.	 *)
CloseLE		bsr	CloseLEwind
		bra	finishmessage


;(* Closes the Load File window, and returns to the main display.	 *)
CloseLF		bsr	CloseLFwind
		bra	finishmessage


;(* Closes the Save File window, and returns to the main display.	 *)
CloseSF		bsr	CloseSFwind
		bra	finishmessage



;(* Introduces blank characters into the string that is displayed as	 *)
;(* the date in the main and shrink windows.				 *)
ClearDateString
		move.l	#datebuffer,a0
		cmp.l	#0,a0
		beq	.error
		move.l	#0,(a0)+		clear string
		move.l	#0,(a0)+
		move.l	#0,(a0)+
		move.l	#0,(a0)+
		move.l	#0,(a0)+
		move.l	#0,(a0)+
		move.l	#0,(a0)+
		move.l	#0,(a0)+
		move.l	#0,(a0)+
		move.l	#date_sinfo,a0
		move.l	#0,28(a0)		clear numerical value
.error		rts


;(* Gets the information from the integer gadget, and sets the date	 *)
;(* to that value. Also goes to that page of the diary.			 *)

LookupDate	move.l	#date_sinfo,a0
		move.l	#datecopy,a1		
		move.l	28(a0),d0
		divs	#10000,d0		get day
		move.l	d0,d2			store
		and.l	#$ff,d0
		move.l	d0,date_day1(a1)	set day in buffer
		move.l	d2,d1
		swap 	d1
		and.l	#$ffff,d1		mask lower half
		divs	#100,d1			get month
		move.l	d1,d2			store
		and.l	#$ff,d1
		sub.l	#1,d1			jan = 0 (remember?)
		move.l	d1,date_mon(a1)		set month in buffer
		move.l	d2,d0
		swap 	d0
		and.l	#$ff,d0			get year
		cmp.l	#0,d0
		blt	.error
		cmp.l	#99,d0
		bgt	.error
		cmp.l	#30,d0
		blt	.2000
		add.l	#1900,d0		make 4 digits
		bra	.done
.2000		add.l	#2000,d0
.done		move.l	d0,date_yr(a1)		set year in buffer
		bsr	CheckDate
		cmp.l	#0,d0
		beq	.error
		move.l	#datecopy,a0		if date is valid
		move.l	#date,a1		copy from buffer
		move.l	(a0)+,(a1)+
		move.l	(a0)+,(a1)+
		move.l	(a0),(a1)
		move.w	#120,dateXpos
		move.w	#163,dateYpos
		move.l	windowhd,displayhd
		bsr	CorrectDay		set weekday
		bsr	DisplayDate
		bsr	FindEntry
		move.l	a1,start_entry
		move.l	a1,page_start
		bsr	DisplayPages
		bsr	CloseLEwind
		bra	finishmessage
.error		bsr	Openinvinpwind
		bra	finishmessage



;(* Checks the validity of the day for a given month, eg. Feb 31st is	 *)
;(* invalid. Also checks month is in range Jan...Dec. Assumes validity	 *)
;(* of year lower half (00-99) to have been checked by calling routine.  *)
;(* Expects date in datecopy (3 longwords yymmdd). Returns boolean 	 *)
;(* result in d0.	 						 *)

CheckDate	move.l	#months,a0		month lengths
		move.l	#datecopy,a1
		move.l	date_mon(a1),d1
		cmp.l	#0,d1			< Jan?
		blt	.error
		cmp.l	#11,d1			> Dec?
		bgt	.error
		move.l	d1,d3			store month
		muls	#2,d1			must be even
		move.w	(a0,d1),d1		length
		cmp.l	#1,d3			Feb?
		bne	.notleap
		move.l	date_yr(a1),d0
		bsr	IsLeapYear		
		cmp.l	#0,d0
		beq	.notleap
		add.l	#1,d1			Feb 29th
.notleap	move.l	#datecopy,a1
		move.l	date_day1(a1),d0
		cmp.w	d0,d1			check day
		bge	.fine
.error		move.l	#0,d0			false
		rts
.fine		move.l	#1,d0			true
		rts


*-------------- DIARY TEXT ROUTINES -------------------------------------*


;(* Handles the displaying of entries in the pages of the diary. Expects *)
;(* address of first entry on the page in page_start.			 *)

DisplayPages	bsr	BlankPages		clear previous entries
		bsr	SetPageFlags		
		bsr	SetPageMode
		move.w	#56,lineXpos		initial positions
		move.w	#22,lineYpos
		move.l	page_start,a1
.loop		cmp.l	#0,a1			no entry?
		beq	.noentries
		move.l	a1,a5			store
		move.w	lineXpos,d0
		sub.w	#36,d0			time is in left margin
		move.w	lineYpos,d1
		bsr	SetTimePos
		move.l	a5,a1			restore entry pointer
		bsr	DisplayEntryTime
		bsr	SetEntryPos		move cursor
		move.l	a5,a1			restore pointer
		bsr	DisplayEntry		display one entry
		btst	#pagebottom,flag4	limit reached?
		beq	.skip			no
		btst	#sidetwo,flag4		second half?
		bne	.endpage		yes
		btst	#splitentry,flag4	entry split at bottom?
		beq	.nosplit		no
		move.l	#19,leftmargin
		move.l	#180,rightmargin
		bsr 	clearoldlines
.nosplit	move.w	#221,lineXpos		move to second page
		move.w	#22,lineYpos
		bset	#sidetwo,flag4
		btst	#splitentry,flag4	entry split at bottom?
		beq	.skip  			no
		move.l	a5,a1			re-display last entry
		bra	.loop
;(* Entry has been displayed, and no flags have been set. Find next	 *)
;(* entry and continue displaying page.					 *)
.skip		move.l	ent_next(a5),a1
		cmp.l	#0,a1			end of list?
		bne	.loop	
		bra	.backtostart

;(* At this stage, bottom of the second half page has been reached.	 *)
.endpage	btst	#splitentry,flag4	split entry?
		beq	.nosplit2		no
		move.l	#186,leftmargin
		move.l	#342,rightmargin
		bsr	clearoldlines
		move.l	a5,next_entry		start of next page
		rts
.nosplit2	move.l	ent_next(a5),a1
		cmp.l	#0,a1
		beq	.backtostart
		move.l	a1,next_entry		set start of next page
		rts
;(* Here, the next entry in the list is nul, so set first entry for the	 *)
;(* day as the first entry on next page.				 *)
.backtostart	bsr	FindDay			result in a0
		move.l	day_entry(a0),next_entry first entry for day
;						 set as start of next page
.noentries	rts				no entries on that page


;(* Sets the drawing mode to JAM1, required to display the entries in 	 *)
;(* the window.								 *)
SetPageMode	move.l	gfxbase,a6
		move.l	windowhd,a1
		move.l	50(a1),a1
		move.l	#0,d0			JAM1
		jsr	setDrMd(a6)		set mode
		rts


;(* Sets/Clears the relevant flags for the state of a page initially.	 *)
SetPageFlags	bclr	#linebrk,flag1		line break
		bclr	#pagebottom,flag4
		bclr	#splitentry,flag4
		bclr	#sidetwo,flag4
		rts


;(* Moves the cursor to the start of line position, to display the entry *)
;(* time for a diary entry. Also changes the pen colour to orange.	 *)
SetTimePos	move.l	windowhd,a1
		bsr	movepos			move cursor
		move.l	windowhd,a1
		move.l	#3,d0	
		bsr	pencolour		set orange pen
		rts


;(* Moves the cursor to the start of line position, to display a diary	 *)
;(* entry. Also sets the pen colour to black.				 *)
SetEntryPos	move.w	lineXpos,d0
		move.w	lineYpos,d1
		move.l	windowhd,a1
		bsr	movepos
		move.l	windowhd,a1
		move.l	#2,d0	
		bsr	pencolour		set black pen
		rts


;(* Removes traces of a split entry from its first location.		 *)
clearoldlines	move.l	windowhd,a1
		move.l	#1,d0
		bsr	pencolour		set pen white
		move.w	entry_lines,d5		# of lines of text
		sub.w	#1,d5			because dbf
		add.w	#1,lineYpos
.blankloop	bsr	upline
		move.l	gfxbase,a6
		move.l	windowhd,a1
		move.l	50(a1),a1		rastport
		move.l	#0,d1
		move.l	leftmargin,d0		topleft x
		move.w	lineYpos,d1		topleft y
		move.w	d1,d3			bottomright y
		sub.w	#9,d1
		move.l	rightmargin,d2		bottomright x
		jsr	rectfill(a6)		fill 'pages'		
		dbf	d5,.blankloop
		move.l	intbase,a6
		move.l	#flip_gadget,a0
		move.l	windowhd,a1
		move.l	#0,a2
		move.l	#1,d0			number of gadgets
		jsr	refreshGlist(a6)
		rts


;(* Flips to the next 'page' of the diary without changing the date.	 *)
;(* Necessary when there are too many entries for one page.		 *)
FlipPage	move.l	next_entry,page_start
		bsr	DisplayPages
		bra	reply


;(* Finds the pointer to the day structure for the day shown in the 	 *)
;(* window date. Returns pointer to day in a0.				 *)
FindDay		move.l	calendar,a0		pointer to first year
		move.l	#date,a1		
		move.l	date_yr(a1),d0		get year	
.loop		cmp.l	#0,a0			end of list
		beq	.noentries
		move.w	yr_year(a0),d1		get year number eg. 1992
		cmp.w	d0,d1
		beq	.foundyear
		move.l	yr_next(a0),a0		pointer to next year
		bra	.loop
.foundyear	move.l	date_mon(a1),d0		get month
		muls	#4,d0
		add.l	#yr_list,a0		start of months
		move.l	(a0,d0),a0		pointer to month
		cmp.l	#0,a0			no month?
		beq	.noentries
		move.l	date_day1(a1),d0		get day from date
		move.w	#0,d1
		move.l	mon_day(a0),a0		pointer to day
.dayloop	cmp.l	#0,a0			
		beq	.noentries
		move.b	day_day(a0),d1		get day from day struct.
		cmp.w	d0,d1
		beq	.foundentry
		move.l	day_next(a0),a0		get next day
		bra	.dayloop
.foundentry	rts				address in a0
.noentries	move.l	#0,a0			set nul value
		rts


;(* Finds the first entry for the day shown in the window date. Returns  *)
;(* pointer to entry in a1						 *)
FindEntry	bsr	FindDay			get address in a0
		cmp.l	#0,a0			any entries?
		beq	.noentries
		move.l	day_entry(a0),a1	pointer to entry
		rts
.noentries	move.l	#0,a1			nul pointer
		rts



;(* Displays a single entry in a diary page. Expects pointer to entry 	 *)
;(* in a1.								 *)

DisplayEntry	bclr	#pagebottom,flag4	clear overflow
		bset 	#splitentry,flag4	assume split initially
		move.w	#0,entry_lines
		move.l	ent_text(a1),a0
.line		clr.w	d0
		clr.w	d1			number of chars
		move.b	(a0),d0
		cmp.w	#0,d0			end of text?
		beq	.break
		cmp.w	#" ",d0
		bne	.nospace		
		add.l	#1,a0			skip space at start
.nospace	move.l	a0,a2			store start of line
.loop		move.b	(a0)+,d0		inspect one char
		cmp.w	#0,d0			end of text?
		beq	.endtext
		addq	#1,d1
		cmp.w	#line_width,d1		line full?
		beq	.wholeline
		bra	.loop
	
.wholeline	clr.w	d2
		move.b	(a0)+,d2		complete word at EOL?
		cmp.w	#" ",d2
		beq	.okline
		cmp.w	#0,d2
		beq	.okline
		sub.l	#1,a0			go back one char
.backloop	cmp.w	#" ",d0			last char a space?
		beq	.okline
		subq	#1,d1			decrease width
		move.b	-(a0),d0
		cmp.l	a0,a2			back to start?
		bne	.backloop		search back through line
		move.l	#line_width,d1		full line
		add.l	#line_width,a0

.okline		move.l	a0,a4			start of next line
		move.l	a2,a0			start of this line
		move.l	d1,d0			number of chars
		bsr	displayline
		move.l	a4,a0
		bsr	downline		move down a line
		add.w	#1,entry_lines
		move.w	lineYpos,d1
		cmp.w	#page_limit,d1		over?
		bgt	.over
		bra	.line			do next line

.endtext	bclr	#splitentry,flag4	entry is not split
		move.l	a2,a0			start of line
		move.l	d1,d0			number of chars
		bsr	displayline
		bsr	downline
		add.w	#1,entry_lines
.break		bsr	downline
		add.w	#1,entry_lines
		move.w	lineYpos,d1
		cmp.w	#page_limit,d1
		bgt	.over
		rts
.over		bset	#pagebottom,flag4
		rts


;(* Displays the entry time in the diary page. Expects entry address in  *)
;(* a1.									 *)
DisplayEntryTime
		move.w	ent_stat(a1),d0		get entry status
		btst	#timeyn,d0		time specified?
		beq	.out			no
		move.w	ent_time(a1),d0		get time combination
		move.l	#spare_text,a0		text string
		divs	#100,d0			get HOURS
		move.l	d0,d1
		and.l	#$ffff,d0		mask out remainder
		divs	#10,d0			split digits
		add.w	#$30,d0			convert to ASCII
		move.b	d0,(a0)			copy to text string
		swap	d0			get other digit
		add.w	#$30,d0
		move.b	d0,1(a0)

		swap	d1			get MINUTES (remainder)
		and.l	#$ffff,d1		mask out upper half
		divs	#10,d1			split digits
		add.w	#$30,d1
		move.b	d1,2(a0)
		swap	d1			get other digit
		add.w	#$30,d1
		move.b	d1,3(a0)

		move.l	#4,d0			number of chars		
		bsr	DisplayLine
		rts
.out		btst	#linebrk,flag1		line break displayed?
		bne	.nobreak
		bset	#linebrk,flag1
		move.w	#line_width,d0
		add.w	#5,d0
		move.l	#line_break,a0
		bsr	displayline
		bsr	downline
.nobreak	rts


;(* Moves the text cursor down one line					 *)
downline	add.w	#10,lineYpos
		move.w	lineXpos,d0
		move.w	lineYpos,d1
		move.l	windowhd,a1
		bsr	movepos			
		rts


;(* Moves the text cursor up one line					 *)
upline		sub.w	#10,lineYpos
		move.w	lineXpos,d0
		move.w	lineYpos,d1
		move.l	windowhd,a1
		bsr	movepos			
		rts


;(* Displays a single line of text for a diary entry. Expects pointer to *)
;(* to text in a0, number of chars in d0				 *)

DisplayLine	move.l	windowhd,a1
		bsr	displaytext		
		rts


;(* Changes the time option on/off for diary entries.			 *)
TimeOption	bchg	#timeyn,flag1
		bra	reply


*-------------- ADD ENTRY ROUTINES --------------------------------------*

;(* Opens the Add Entry window, and returns to main loop.		 *)
SelectAE	bsr	ClearEntryString
		bsr	OpenAEwind
		tst.l	d0
		beq	.error
		bsr	SetUpAEDisplay
.error		bra	reply


;(* Replies to the message, closes the Add Entry window, and returns to	 *)
;(* the main loop.							 *)
CloseAE		bsr	CloseAEwind
		bra	finishmessage

;(* Takes appropriate action when CR is hit in the Add Entry window.	 *)
;(* The program moves through each of the string gadgets, then acts as	 *)
;(* if OK had been selected.						 *)
AddEntryCR	btst	#timeyn,flag1		if time OFF, do not need
		beq	InsertAnEntry		to check hrs/mins
		btst	#strgad,flag3		first gadget?
		bne	.acthrs			yes, activate hours gadget
		btst	#hrsgad,flag3		second gadget?
		bne	.actmins		yes, activate mins gadget
		bra	InsertAnEntry		as gadget $20
.acthrs		move.l	intbase,a6
		move.l	#hours_sgadget,a0	gadget
		move.l	aehd,a1			window
		move.l	#0,a2			requestor (nil)
		jsr	activategadget(a6)
		bclr	#strgad,flag3		set gadget flags ... 
		bset	#hrsgad,flag3		... appropriately
		bclr	#minsgad,flag3
		bra	.out
.actmins	move.l	intbase,a6
		move.l	#mins_sgadget,a0	gadget
		move.l	aehd,a1			window
		move.l	#0,a2			requestor (nil)
		jsr	activategadget(a6)
		bclr	#hrsgad,flag3
		bset	#minsgad,flag3
		bclr	#strgad,flag3
.out		bra	reply


;(* Introduces blank characters into the add entry string gadgets.	 *)
ClearEntryString
		move.l	#entrybuffer,a0		clear string buffer
		moveq	#71,d0
.loop		move.b	#0,(a0)+
		dbf	d0,.loop
		move.l	#hoursbuffer,a0
		move.l	#0,(a0)+		clear hours
		move.l	#0,(a0)+
		move.l	#0,(a0)
		move.l	#minsbuffer,a0
		move.l	#0,(a0)+		clear mins
		move.l	#0,(a0)+
		move.l	#0,(a0)
		move.l	#hours_sinfo,a0
		move.l	#0,28(a0)
		move.l	#mins_sinfo,a0
		move.l	#0,28(a0)
		rts


;(* Clears the current user selection from the add entry window.	 *)
ClearInput	bsr	ClearEntryString
		move.l	intbase,a6
		move.l	#entry_sgadget,a0
		move.l	AEhd,a1
		move.l	#0,a2
		move.l	#3,d0			number of gadgets
		jsr	refreshGlist(a6)
		bra	reply


;(* Deals with the whole process of creating an entry from the info 	 *)
;(* provided by the user in the Add Entry window, and inserting the 	 *)
;(* entry into the diary.						 *)

InsertAnEntry	bsr	CheckInputs
		btst	#requestop,flag2	Error requestor
		bne	.error			yes
		bsr	CloseAEwind
		move.l	#date,a0
		move.l	date_yr(a0),d0		year (today)
		move.l	date_yr(a0),d4		store
		bsr	YearExists
		cmp.l	#1,d1
		beq	.year
.noyear		move.l	d4,d0
		bsr	ReserveYear		returns address in a1
.year		move.l	a1,a4			store
		move.l	#date,a0
		move.l	date_mon(a0),d0		month (today)
		move.l	date_mon(a0),d4		store
		move.l	a1,a0			year address
		bsr	MonthExists		returns address in a1
		cmp.l	#1,d1
		beq	.month
.nomonth	move.l	a4,a0			year address
		move.l	d4,d0			month 
		bsr	ReserveMonth
.month		move.l	#date,a0
		move.l	date_day1(a0),d0	day (today)
		move.l	a1,a0			month address
		move.l	a1,a4			store
		bsr	DayExists		returns address in a1
		cmp.l	#1,d1
		bne	.noday
		move.l	a1,a4			save address 
		bra	.day
.noday		bsr	CreateDay		returns address in d0
		move.l	a4,a0			month address
		move.l	d0,a1			day address
		move.l	d0,a4			store
		bsr	InsertDay
.day		bclr	#editinp,flag1		Take inputs from AE window
		bsr	ReserveEntry		result in d0
		move.l	d0,a1			entry address
		move.l	a4,a0			day address
		move.l	a0,daystore
		bsr	InsertEntry
		bsr	DisplayPages
.error		bra	finishmessage				



;(* Checks the validity of the inputs for an entry made by the user in 	 *)
;(* the add entry window.						 *)

CheckInputs	move.l	#hours_sinfo,a0
		move.l	28(a0),d0		get hours value
		cmp.l	#23,d0
		bgt	.error
		cmp.l	#0,d0
		blt	.error
		move.l	#mins_sinfo,a0
		move.l	28(a0),d0		get mins value
		cmp.l	#59,d0
		bgt	.error
		cmp.l	#0,d0
		blt	.error
		rts				inputs fine
.error		bsr	OpenInvInpwind		invalid inputs
		rts



;(* Inserts a day into a month. Expects month in a0, day in a1      	 *)

InsertDay	clr.w	d0
		move.b	mon_number(a0),d0	number of entries
		cmp.w	#0,d0			empty?
		bne	.notempty
		move.b	#1,mon_number(a0)	trivial case
		move.l	a1,mon_day(a0)
		rts
.notempty	clr.w	d0
		move.b	day_day(a1),d0		date of new day
		move.l	a0,a3			store previous
		move.l	mon_day(a0),a2		pointer to first day
.scan		clr.w	d1
		move.b	day_day(a2),d1		date of day in list
		cmp.w	d1,d0
		blt	.found
		move.l	a2,a3			store previous
		move.l	day_next(a2),a2		next day in list
		cmp.l	#0,a2			end of list?
		bne 	.scan			no
		move.l	a1,day_next(a3)		yes
		rts
.found		move.l	day_next(a3),day_next(a1)
;						pointer to next day
		move.l	a1,day_next(a3)		insert our day
		rts


;(* Inserts an entry into the entry list for a particular day. Expects   *)
;(* address of day in a0, address of entry in a1		    	 *)

InsertEntry	move.l	day_entry(a0),d0	pointer to list of entries
		cmp.l	#0,d0			empty list?
		bne	.notempty
		move.l	a1,day_entry(a0)	trivial case
		move.l	a1,start_entry		first entry on page
		move.l	a1,next_entry
		move.l	a1,page_start
		rts
.notempty	move.w	ent_stat(a1),d1		status
		btst	#timeyn,d1		time specified?
		beq	.notime			no (add to end of list)
; if the first entry in the list has no time specified, and the new 
; entry does, then insert at the start.
.time		move.l	day_entry(a0),a2	first entry
		move.w	ent_stat(a2),d1		status
		btst	#timeyn,d1		time specified?
		bne	.findplace		yes
		move.l	a2,ent_next(a1)
		move.l	a1,day_entry(a0)	insert at start
		move.l	a1,start_entry		set first entry
		move.l	a1,next_entry		start of next page
		move.l	a1,page_start		and page start
		rts
; New entry does not go at the start or end, so scan through list 
; until a correct time slot is found, or until the next entry has no 
; time, in which case insert there.
.findplace	move.l	day_entry(a0),a2	address of entry list
		move.l	a0,a3			store previous
.scanlist	move.w	ent_stat(a2),d0		entry status
		btst	#timeyn,d0		time specified?
		beq	.found			no
		move.w	ent_time(a2),d0		time of entry
		move.w	ent_time(a1),d1		time of new entry
		cmp.w	d0,d1
		ble	.found
		move.l	a2,a3			store previous
		move.l	ent_next(a2),a2		next entry
		cmp.l	#0,a2			end of list?
		beq	.listend		yes
		bra	.scanlist
.listend	move.l	a1,ent_next(a3)		add new entry to end of 
		rts				list
.found		move.l	ent_next(a3),ent_next(a1)
		move.l	a1,ent_next(a3)		insert our new entry
		cmp.l	daystore,a3		start of list?
		bne	.endfound		no
		move.l	a1,start_entry		yes, set first entry
		move.l	a1,next_entry
		move.l	a1,page_start		and page start
.endfound	rts
.notime		move.l	day_entry(a0),a2	first entry
.loop		move.l	a2,a3			copy pointer
		move.l	ent_next(a2),a2		next entry
		cmp.l	#0,a2			end of list?
		bne	.loop			no
		bra	.listend		yes



;(* Creates a diary entry from the information supplied by the user in   *)
;(* the add entry window. Returns address of entry in d0, returns 0      *)
;(* (error) if there was no memory. 				         *)
;(* Uses Add Entry inputs if bit clear, otherwise use Edit Entry inputs  *)
ReserveEntry	btst	#editinp,flag1		which window inputs?
		bne	.edit			edit entry window
		move.l	#entrybuffer,a0		add entry window
		bra	.add
.edit		move.l	#editentrybuffer,a0
.add		clr.l	d0			number of bytes
.loop		clr.l	d1
		move.b	(a0)+,d1
		cmp.w	#0,d1			end of string?
		beq	.done			yes
		addq	#1,d0
		bra	.loop
.done		addq	#1,d0			this adds nul char at eot
		move.l	d0,d3			store size
		move.l	execbase,a6		number of bytes in d0
		move.l	#$10000,d1		clear & reserve
		jsr	allocmem(a6)	
		cmp.l	#0,d0			enough memory?
		beq	.nomem
		move.l	d0,d2			store address
		bsr	CreateEntry
		cmp.l	#0,d0			enough memory?
		beq	.nomem
		move.l	d0,a0			address of entry
		move.l	d2,ent_text(a0)		pointer to text block		
		move.w	d3,ent_txt_size(a0)	size of text block (bytes)
		btst	#editinp,flag1		which inputs?
		bne	.edit1
		move.l	#entrybuffer,a1		source
		bra	.add1
.edit1		move.l	#editentrybuffer,a1
.add1		move.l	d2,a2			destination
		sub.l	#1,d3			counter
.cloop		move.b	(a1)+,(a2)+		copy text to memory
		dbf	d3,.cloop
		btst	#timeyn,flag1		time yes/no
		beq	.out
		move.w	#%00000100,ent_stat(a0)	set time yes
		move.l	#hours_sinfo,a1
		move.l	28(a1),d0		get hours from gadget
		muls	#100,d0
		move.l	#mins_sinfo,a1		get mins from gadget
		add.l	28(a1),d0	
		move.w	d0,ent_time(a0)		put in entry
.out		move.l	a0,d0			address of entry
.nomem		rts



;(* Determines the existence of a day in the month	                 *)
;(* Expects day (date, eg. 16) as a word passed in d0, month address in  *)
;(* a0. Returns result in d1, address of day in a1            		 *)

DayExists	move.l	mon_day(a0),a0		pointer to first (used) day
		cmp.l	#0,a0			empty list?
		beq	.notpresent		yes
.scanlist	clr.l	d2
		move.b	day_day(a0),d2		date
		cmp.w	d0,d2
		beq	.present
		move.l	day_next(a0),a0		next day
		cmp.l	#0,a0			end of list?
		bne	.scanlist		no
.notpresent	move.l	#0,d1
		rts
.present 	move.l	#1,d1
		move.l	a0,a1			address of day
		rts


;(* Determines the existence of a month in a particular year.            *)
;(* Expects month in d0 (0 = jan, 1 = feb, etc.), address of year in a0  *)
;(* Returns d1 as exists yes/no, address of month in a1			 *)

MonthExists	add.l	#yr_list,a0		start of months
		muls	#4,d0
		move.l	(a0,d0),a1
		cmp.l	#0,a1
		beq	.notexists
.exists		move.l	#1,d1
		rts
.notexists	move.l	#0,d1
		rts
 

;(* Creates a new month and inserts it into month list for that year.	 *)
;(* Does not check for duplicates. 					 *)
;(* Expects month in d0, address of year in a0				 *)
;(* Returns address of month in a1					 *)

ReserveMonth	move.l	a0,a1
		add.l	#yr_list,a1		start of months
		muls	#4,d0
		add.l	d0,a1			address of our month
		move.l	a1,a2
		bsr	CreateMonth
		move.l	d0,(a2)			insert address into list
		move.l	d0,a1
		rts


;(* Determines the existence of a year in the calendar list.             *)
;(* Expects year passed in d0. 						 *)
;(* Returns result in d1, address of year in a1            		 *)

YearExists	move.l	calendar,a1		assume year in d0
		cmp.l	#0,a1
		beq	.notpresent		empty list
.scanlist	move.w	yr_year(a1),d1		year date eg. 1992
		cmp.w	d0,d1
		beq	.present
		move.l	yr_next(a1),a1		next entry
		cmp.l	#0,a1			nil pointer? (end of list)
		bne	.scanlist
.notpresent	move.l	#0,d1			year does not exist
		rts
.present	move.l	#1,d1			year does exist
		rts


;(* Creates a new year and inserts it into calendar list. Does not check *)
;(* for duplicates. Expects year in d0, returns address of year in a1    *)

ReserveYear	move.w	d0,year
		move.l	#calendar,a1
		move.l	a1,a4			store
		move.l	cal_year(a1),a2		address of year
		cmp.l	#0,a2			no years yet?
		beq	.empty			no, insert at start
		move.l	a1,yearstore
;(* Search through list of years until a place is found (new year < year) *)
;(* or the end of the list is reached - new year goes at end. 		  *)
;(* loop invariant :  {(listyear.next <> null) and (new year > year)}     *)
.yrloop		move.w	yr_year(a2),d1		year number
		cmp.w	d0,d1
		bgt	.foundplace
		move.l	yr_next(a2),a0		next year
		cmp.l	#0,a0			end of list?
		beq	.foundend
		move.l	a2,yearstore		store tmp
		move.l	a0,a2			get next year
		bra	.yrloop			continue searching
;(* At this point, the end of the years list has been reached, so insert *)
;(* our new year at the end.						 *)
.foundend	move.l	a2,a4			store year
		bsr	CreateYear
		cmp.l	#0,d0
		beq	.error
		move.l	d0,a1
		move.w	year,yr_year(a1)	set year number
		move.l	d0,yr_next(a4)		end of list points to
		rts				new year
;(* At this point, the new year has found to be less than the year at	 *)
;(* this point in the years list. Now we must insert the new year into   *)
;(* the list.								 *)
.foundplace	move.l	a2,a4			store current year
		bsr	CreateYear
		cmp.l	#0,d0
		beq	.error
		move.l	d0,a1
		move.w	year,yr_year(a1)
		move.l	yearstore,a2		tmp
		move.l	a4,yr_next(a1)
		move.l	a1,yr_next(a2)
		rts
;(* At this point, years list was empty, so insert new year as the head  *)
;(* of a previously empty list.					         *)
.empty		bsr	CreateYear		^year in d0
		cmp.l	#0,d0
		beq	.error
		move.l	d0,a1
		move.w	year,yr_year(a1)
		move.l	d0,cal_year(a4)		list is new year only
;(* Could not get memory for year, so exit.				 *)
.error		rts

				

;(* Allocs block of memory for 1 year, returns address in d0 		 *)
CreateYear	move.l	execbase,a6
		move.l	#yr_size,d0		size in bytes
		move.l	#$10000,d1		clear & reserve
		jsr	allocmem(a6)
		rts


;(* Allocs block of memory for 1 month, returns address in d0		 *)
CreateMonth	move.l	execbase,a6
		move.l	#mon_size,d0		size in bytes
		move.l	#$10000,d1		clear & reserve
		jsr	allocmem(a6)
		rts


;(* Allocs block of memory for 1 day, returns address in d0 		 *)
;(* Also set current date in day structure.				 *)
CreateDay	move.l	execbase,a6
		move.l	#day_size,d0		size in bytes
		move.l	#$10000,d1		clear & reserve
		jsr	allocmem(a6)
		cmp.l	#0,d0
		beq	.error
		move.l	d0,a0
		move.l	#date,a1
		move.l	date_day1(a1),d1		get today's date
		move.b	d1,day_day(a0)		put date in day
.error		rts



;(* Allocs block of memory for 1 entry, returns address in d0		 *)
CreateEntry	move.l	execbase,a6
		move.l	#ent_size,d0		size in bytes for entry
		move.l	#$10000,d1
		jsr	allocmem(a6)
		rts


*-------------- REMOVE STRUCTURES ROUTINES ------------------------------*


;(* Clears all calendar structures and gives back reserved memory using  *)
;(* a depth first search.						 *)

DFS		move.l	calendar,a0		start
.loop		cmp.l	#0,a0			end?
		beq	.done
		move.l	a0,yearstore		store
		bsr	FreeYear		search deeper...
		move.l	yearstore,a1
		move.l	yr_next(a1),a5		store next year
		move.l	#yr_size,d0
		bsr	freeup			de-allocate year structure
		move.l	a5,a0			get next
		bra	.loop
.done		move.l	#0,calendar
		rts


;(* Clears the scribblepad structures and gives back reserved memory.	 *)
ScribClear	move.l	scribble,a0		start
.loop		cmp.l	#0,a0			end?
		beq	.done
		move.l	a0,a5			store
		move.l	scribent_text(a0),a1
		move.l	#0,d0
		move.w	scribent_txt_size(a0),d0
		bsr	freeup			free text mem
		move.l	a5,a1
		move.l	#scribent_size,d0
		move.l	scribent_next(a5),a5	store next
		bsr	freeup			free entry mem
		move.l	a5,a0			get next
		bra	.loop
.done		move.l	#0,scribble
		rts



;(* Frees all months for a year. Expects year in a0.			 *)

FreeYear	move.l	#0,monthsoff		pointer offset
		add.l	#yr_list,a0		start of months
		move.l	a0,monthsbase		store base
		move.l	monthsoff,d0
.loop		move.l	monthsbase,a0
		move.l	(a0,d0),a0		pointer to month
		cmp.l	#0,a0
		beq	.next
		move.l	a0,monthstore		
		bsr	FreeMonth		search deeper...
		move.l	monthstore,a1
		move.l	#mon_size,d0
		bsr	freeup			free month structure
.next		move.l	monthsoff,d0
		add.l	#4,d0			next month
		move.l	d0,monthsoff		update
		cmp.l	#48,d0			end of months?
		bne	.loop
		rts



;(* Frees all days for a month. Expects month in a0.			 *)

FreeMonth	move.l	mon_day(a0),a0		pointer to first day
.loop		cmp.l	#0,a0			end?
		beq	.done
		move.l	a0,daystore		store
		bsr	FreeDay			search deeper...
		move.l	daystore,a1
		move.l	day_next(a1),a5		store next day
		move.l	#day_size,d0
		bsr	freeup			free day structure mem
		move.l	a5,a0			get next 
		bra	.loop
.done		rts



;(* Frees all entries for a day. Expects day in a0.			 *)

FreeDay		move.l	day_entry(a0),a0	pointer to first day
.loop		cmp.l	#0,a0			end?
		beq	.done
		move.l	a0,entrystore		store
		bsr	FreeEntry		search deeper...
		move.l	entrystore,a1
		move.l	ent_next(a1),a5		store next entry
		move.l	#ent_size,d0
		bsr	freeup			free entry structure mem
		move.l	a5,a0			get next
		bra	.loop
.done		rts



;(* Frees memory for an entry. Expects entry in a0.			 *)

FreeEntry	move.l	ent_text(a0),a1
		cmp.l	#0,a1			no text?
		beq	.done
		move.l	#0,d0
		move.w	ent_txt_size(a0),d0	size of reserved block
		bsr	freeup
.done		rts



;(* De-allocates a block of reserved memory. Expects memory address in 	 *)
;(* a1, size of block (bytes) in d0.					 *)

freeup		move.l	execbase,a6
		jsr	freemem(a6)
		rts



*-------------- EXTERNAL FILE ROUTINES ----------------------------------*


;(* Opens the Save File window, and returns to the main loop.		 *)
Save		bsr	OpenSFwind
		bra	reply


;(* Writes the entire diary contents, including ScribblePad, to an	 *)
;(* external file.							 *)
SaveFile	move.l	#mode_new,d2
		bsr	openfile
		tst.l	d0
		beq	.error			put requestor here
		bsr	writeheader
		move.l	calendar,a0
.yrloop		cmp.l	#0,a0
		beq	.out			
		bsr	SaveYear
		bra	.yrloop			repeat for other years
.out		bsr	SaveScribble
		move.l	#filestop_code,d2
		move.l	#1,d3
		bsr	writefile
		bsr	closefile
		bsr	CloseSFwind
		bra	finishmessage
.error		bsr	OpenBadFilewind
		bra	finishmessage
		


;(* Writes a year to a disk file. Expects year in a0. Returns next year	 *)
;(* in a0. 								 *) 
SaveYear	move.l	a0,yearstore		store
		move.l	#year_code,d2
		move.l	#1,d3
		bsr	writefile		write year identifier
		move.l	yearstore,a0
		move.w	yr_year(a0),d2
		move.w	d2,buffer
		move.l	#buffer,d2
		move.l	#2,d3
		bsr	writefile		write year number
		move.l	yearstore,a0
		move.l	#0,monthsoff		clear offset
		add.l	#yr_list,a0		start of months
		move.l	a0,monthsbase		store
		move.l	monthsoff,d0
.loop		move.l	monthsbase,a0		
		move.l	(a0,d0),a0		get month
		cmp.l	#0,a0
		beq	.next
		divs	#4,d0
		lsl	#8,d0			shift 1 byte left
		move.l	a0,monthstore
		bsr	SaveMonth
.next		move.l	monthsoff,d0
		add.l	#4,d0
		move.l	d0,monthsoff
		cmp.l	#48,d0			end of year?
		bne	.loop
		move.l	yearstore,a0
		move.l	(a0),a0
		rts


;(* Writes a month to a disk file. Expects month pointer in a0, month    *)
;(* number in d0.							 *)
SaveMonth	move.w	d0,buffer		store
		move.l	#month_code,d2
		move.l	#1,d3
		bsr	writefile		month identifier code
		move.l	#buffer,d2
		move.l	#1,d3
		bsr	writefile		month number (jan=0, etc)
		move.l	monthstore,a0
		move.l	mon_day(a0),a0
.loop		cmp.l	#0,a0
		beq	.out
		move.l	a0,daystore
		bsr	SaveDay
		move.l	daystore,a0
		move.l	day_next(a0),a0
		bra	.loop
.out		rts
			


;(* Writes a day to a disk file. Expects pointer to day in a0.		 *)
SaveDay		move.w	day_day(a0),d0
		move.w	d0,buffer		store date
		move.l	#day_code,d2
		move.l	#1,d3
		bsr	writefile		day identifier code
		move.l	#buffer,d2
		move.l	#1,d3
		bsr	writefile		write date (eg. 16th)
		move.l	daystore,a0
		move.l	day_entry(a0),a0
.loop		cmp.l	#0,a0
		beq	.out
		move.l	a0,entrystore
		bsr	SaveEntry
		move.l	entrystore,a0
		move.l	ent_next(a0),a0
		bra	.loop
.out		rts		



;(* Writes an entry to a disk file. Expects pointer to entry in a0.	 *)
SaveEntry	move.l	#entry_code,d2
		move.l	#1,d3
		bsr	writefile		entry identifier code
		move.l	entrystore,a0
		move.w	ent_stat(a0),buffer
		move.l	#buffer,d2
		move.l	#2,d3
		bsr	writefile		entry status
		move.l	entrystore,a0
		move.w	ent_time(a0),buffer
		move.l	#buffer,d2
		move.l	#2,d3
		bsr	writefile
		move.l	entrystore,a0
		move.w	ent_txt_size(a0),d0
		move.w	d0,buffer
		move.l	#buffer,d2
		move.l	#2,d3
		bsr	writefile		text size (bytes)
		move.l	entrystore,a0
		move.l	ent_text(a0),d2
		move.l	#0,d3
		move.w	buffer,d3		size
		bsr	writefile		entry text
		rts


;(* Saves the scribblepad entries to the end of a disk file.		 *)
SaveScribble	move.l	scribble,a0		start
.loop		cmp.l	#0,a0			empty list?
		beq	.out
		move.l	a0,a5			store
		move.l	#scribent_code,d2
		move.l	#1,d3
		bsr	writefile		entry identifier code
		move.w	scribent_txt_size(a5),d0
		move.w	d0,buffer
		move.l	#buffer,d2
		move.l	#2,d3
		bsr	writefile		write text size
		move.l	#0,d3
		move.w	buffer,d3
		move.l	scribent_text(a5),d2
		bsr	writefile
		move.l	scribent_next(a5),a0
		bra	.loop
.out		rts


;(* Loads a file, and returns to the main loop.				 *)
Load		bsr	OpenLFwind
		bra	reply


;(* Loads the default AmigaDiary entries file. Suppress error requestors *)
;(* if the file cannot be found.					 *)
LoadDefault	move.l	#default_file,a0	text string
		move.l	#filebuffer,a1		file name buffer
		clr.w	d0
.loop		move.b	(a0),d0
		move.b	(a0)+,(a1)+		copy 1 byte
		cmp.w	#0,d0			finished?
		bne	.loop
		bset	#defaultfile,flag4	suppress error requestor
		bsr	LoadFile
		bclr	#defaultfile,flag4
		rts


;(* Allows LoadFile to exit with an rts, and then branches to 		 *)
;(* finishmessage to allow loadfile to be called from gadgethit.	 *)
Load_File	bsr	LoadFile
		bsr	GetDate
		move.l	windowhd,displayhd
		bsr	DisplayDate
		bsr	FindEntry
		move.l	a1,start_entry
		move.l	a1,page_start
		bsr	DisplayPages
		bra	finishmessage


;(* Loads an Amiga Diary file from disk, and creates the necessary 	 *)
;(* structures. 							 *)
LoadFile	move.l	#mode_old,d2
		bsr	openfile
		tst.l	d0
		beq	.error			could not open file
		bsr	isvalidheader
		beq	.out			not an AmigaDiary file
		bsr	dfs			clear old entries
		bsr	scribclear		clear old scribblepad
		move.l	#1,scribmarker		unique identifier
.loop		move.l	#buffer,d2
		move.l	#1,d3
		bsr	readfile		read one byte
		move.w	buffer,d0
		and.l	#$ff00,d0
		cmp.w	filestop_code,d0	end of file?
		beq	.out
		cmp.w	year_code,d0	
		bne	.next
		bsr	LoadYear
		cmp.l	#0,a1
		beq	.out
		bra	.loop
.next		cmp.w	month_code,d0
		bne	.next1
		bsr	LoadMonth
		cmp.l	#0,a1
		beq	.out
		bra	.loop
.next1		cmp.w	day_code,d0
		bne	.next2
		bsr	LoadDay
		beq	.out
		bra	.loop
.next2		cmp.w	entry_code,d0
		bne	.next3
		bsr	LoadEntry
		beq	.out
		bra	.loop
.next3		cmp.w	scribent_code,d0
		bne	.out
		bsr	LoadScribEnt
		beq	.out
		bra	.loop
.out		bsr	closefile
		btst	#defaultfile,flag4
		bne	.suppress2		called from LoadDefault
		bsr	CloseLFwind		
		bra	finishmessage
.error		btst	#defaultfile,flag4	default file?
		bne	.suppress2		yes
		bsr	OpenBadFilewind		no, open requestor
.suppress	bra	finishmessage
.suppress2	rts				called from LoadDefault


;(* Determines whether a file is a valid AmigaDiary file. Returns 	 *)
;(* boolean result in d0.						 *)
isvalidheader	move.l	#buffer,d2
		move.l	#2,d3
		bsr	readfile
		move.w	buffer,d2
		cmp.w	#"AD",d2
		bne	.invalid
		move.l	#buffer,d2
		move.l	#2,d3
		bsr	readfile		skip 2 bytes (version)
		move.l	#buffer,d2
		move.l	#1,d3
		bsr	readfile		read version, start
		move.w	buffer,d0
		and.l	#$ff00,d0		isolate lower byte
		cmp.w	filestart_code,d0
		bne	.invalid
		move.l	#1,d0
		rts
.invalid	move.l	#0,d0
		rts


;(* Loads a year from a disk file, and creates a year structure.	 *)
;(* Returns year address in a1.						 *)
LoadYear	move.l	#buffer,d2
		move.l	#2,d3
		bsr	readfile		get year
		move.l	#0,d0
		move.w	buffer,d0
		bsr	ReserveYear		create year
		move.l	a1,yearstore
		rts



;(* Loads a month from a disk file, and creates a month structure. 	 *)
;(* Returns month address in a1.					 *)
LoadMonth	move.l	#buffer,d2
		move.l	#1,d3
		bsr	readfile		get month
		move.l	#0,d0
		move.w	buffer,d0
		lsr.l	#8,d0
		move.l	yearstore,a0
		bsr	ReserveMonth		create month
		move.l	a1,monthstore
		rts


;(* Loads a day from a disk file, and creates a day structure. Returns	 *)
;(* address of day in a1.						 *)
LoadDay		move.l	#buffer,d2
		move.l	#1,d3
		bsr	readfile
		move.l	#0,d0
		move.w	buffer,d0
		lsr.l	#8,d0
		move.l	#date,a0
		move.l	d0,date_day1(a0)		set date to entry
		bsr	CreateDay
		beq	.out
		move.l	monthstore,a0
		move.l	d0,daystore
		move.l	d0,a1			day address
		bsr	InsertDay
.out		rts


;(* Loads an entry from a disk file, and creates an entry structure. 	 *)
;(* Also reserves memory for text, and reads text from file.		 *)
LoadEntry	move.l	#buffer,d2
		move.l	#2,d3
		bsr	readfile		get status word
		move.l	#0,d5
		move.w	buffer,d5		store
		move.l	#buffer,d2
		move.l	#2,d3
		bsr	readfile		get time
		move.l	#0,d4
		move.w	buffer,d4		store
		bsr	CreateEntry		returns address in d0
		beq	.out
		move.l	daystore,a0
		move.l	d0,entrystore
		move.l	d0,a1
		bsr	InsertEntry		insert into day
		move.l	entrystore,a0
		move.w	d4,ent_time(a0)
		move.w	d5,ent_stat(a0)
		move.l	#buffer,d2
		move.l	#2,d3
		bsr	readfile		get text length
		move.l	execbase,a6
		move.l	#0,d0
		move.w	buffer,d0
		move.l	entrystore,a0
		move.w	d0,ent_txt_size(a0)
		move.l	#$10000,d1
		jsr	allocmem(a6)		get text mem
		beq	.out
		move.l	entrystore,a0
		move.l	d0,ent_text(a0)
		move.w	ent_txt_size(a0),d3
		move.l	d0,d2
		bsr	readfile		get text
.out		rts



;(* Loads a scribblepad entry from an external file.			 *)
LoadScribEnt	move.l	#2,d3
		move.l	#buffer,d2
		bsr	readfile		get text size
		move.l	#0,d0
		move.w	buffer,d0
		move.l	#$10000,d1
		move.l	execbase,a6
		jsr	allocmem(a6)		get text mem
		beq	.out
		move.l	d0,d5			store
		move.l	d0,d2
		move.l	#0,d3
		move.w	buffer,d3
		bsr	readfile		read text into mem
		bsr 	CreateScribEntry
		beq	.out
		move.l	d0,a0			address of entry
		move.l	d5,scribent_text(a0)	pointer to text
		move.w	buffer,scribent_txt_size(a0)	text size
		move.l	scribmarker,scrib_ident(a0)	identifier
		add.l	#1,scribmarker
		bsr	InsertScribEntry
.out		rts



;(* Writes the AmigaDiary file header.					 *)
writeheader	move.l	#header,d2
		move.l	#5,d3			size in bytes
		bsr	writefile
		rts


;(* Opens an external file. Expects mode old/new in d2.			 *)
openfile	move.l	dosbase,a6
		move.l	#filebuffer,d1
		jsr	open(a6)
		move.l	d0,filehd
		rts

;(* Closes the external file, previously opened by the program.		 *)
closefile	move.l	dosbase,a6
		move.l	filehd,d1
		jsr	close(a6)
		rts

;(* Writes data to a previously opened file. Expects pointer to data in  *)
;(* d2, and number of bytes in d3.					 *)
writefile	move.l	dosbase,a6
		move.l	filehd,d1
		jsr	write(a6)
		rts

;(* Reads data from a previously opened file. Expects area of memory in  *)
;(* d2, number of bytes in d3.						 *)
readfile	move.l	dosbase,a6
		move.l	filehd,d1
		jsr	read(a6)
		rts


*-------------- HEX TO DEC ROUTINES -------------------------------------*


;(* NB Unless otherwise stated, a digit refers to a decimal digit	 *)
;(* Decimal number is stored in the string backwards, ie.		 *)
;(* units, tens, hundreds etc.						 *)

;(* Converts a hex number to decimal, placing each decimal digit in a    *)
;(* byte. Assume hex number passed in d0, decimal result 0-9999	 	 *)
Convert		lea	decnumber,a0		address of decimal string
		move.l	#0,(a0)			clear previous values
		move.l	#1000,d1		first power of ten
		moveq	#3,d3			HEX digits-1 (dbf)
convertdigit	bsr	dodigit
		addq	#1,a0			move left to next digit
		divs	#10,d1			lower power
		dbf	d3,convertdigit		repeat for all HEX digits
		rts

;(* Sets a single digit to the correct decimal value. Used with Convert  *)
dodigit		cmp	d1,d0		Does number include this power? 
		blt	nodigit			no
		add.b	#1,(a0)			increment correct digit
		moveq	#4,d2			number of digits-1 (dbf)
		move.l	a0,a1
		bsr	checknumber		Is it 10?
		sub	d1,d0			subtract power from column
		bra	dodigit
nodigit		rts					

;(* Checks whether a digit exceeds nine. If it does, increment the next	 *)
;(* highest power, and clear this one.				   	 *)
;(* Expects address of number in a1.					 *)
checknumber	move.w	#0,d4			clear store
		move.b	(a1),d4
		cmp.w 	#$a,d4			digit = 10?
		bne	.checknext		no
		add.b	#1,1(a1)		increment next power
		clr.b	(a1)			clear this power
.checknext	addq	#1,a1
		dbf	d2,checknumber		repeat for all digits
		rts


;(* converts a decimal number to ASCII format, and displays it in the 	 *)
;(* current window. Assumes the number is at address a0			 *)

DisplayDecimal	lea	decstring,a1
		move	digits,d1
		sub.w	#1,d1
dectostring	move.b	(a0),d0
		add.b	#$30,d0
		move.b	d0,(a1)
		addq	#1,a0
		addq	#1,a1
		dbf	d1,dectostring
		lea	decstring,a0
		move.l	displayhd,a1
		move.w	digits,d0
		bsr	displaytext
		rts



*-------------- SCRIBBLEPAD ROUTINES ------------------------------------*


;(* Opens the ScribblePad window, displays a page, and returns to the 	 *)
;(* main loop.								 *)
SelectSP	bsr	OpenSPwind
		tst.l	d0
		beq	.error
		bsr	BlankPad
		bclr	#scribover,flag1		no overflow yet
		move.l	scribble,a1
		move.l	a1,scrib_curentry		first page		
		bsr	DisplaySpad
.error		bra	reply


;(* Closes the ScribblePad window, and returns to the main display.	 *)
CloseSP		bsr	CloseSPwind
		bra	finishmessage


;(* Displays the next page of the scribblepad.				 *)
NextSP		move.l	scrib_nextentry,a1		move to next
		move.l	a1,scrib_curentry		page
		bsr	BlankPad			clear pages
		bsr	DisplaySPad			display entries
		bra	reply


;(* Opens the ScribblePad Add Entry window, and returns to the main loop.*)
SelectSAE	bsr	ClearScribString
		bsr	OpenSAEwind
		bra	reply


;(* Closes the ScribblePad Add Entry window, and returns to the main 	 *)
;(* display.								 *)
CloseSAE	bsr	CloseSAEwind
		bra	finishmessage


;(* Opens the ScribblePad Edit Entry window, and returns to the main loop*)
SelectSEE	bsr	OpenSEEwind
		move.l	scribble,a0		first entry
		bsr	RecallScribEntry	display in window
		bra 	reply


;(* Closes the ScribblePad Edit Entry window, and returns to the main 	 *)
;(* loop.								 *)
CloseSEE	bsr	CloseSEEwind
		bra	finishmessage


;(* Draws a white rectangle to represent the 'pages' of the scribblepad. *)
BlankPad	move.l	spwhd,a1
		move.l	#1,d0
		bsr	pencolour
		move.l	gfxbase,a6
		move.l	spwhd,a1
		move.l	50(a1),a1		rastport
		move.l	#8,d0
		move.l	#13,d1
		move.l	#292,d2
		move.l	#160,d3
		jsr	rectfill(a6)		fill 'pages'
		rts


;(* Introduces blank characters into the scribblepad edit entry string 	 *)
;(* gadget.	 							 *)
ClearScribEdit	move.l	#scribeditbuffer,a0	clear string buffer
		moveq	#71,d0
.loop		move.b	#0,(a0)+
		dbf	d0,.loop
		rts


;(* Clears the scribblepad edit entry string gadget, refreshes the gadget*)
;(* and returns to the main loop.					 *)
ClearSEditInput	bsr	ClearScribEdit
		move.l	intbase,a6
		move.l	#scribedit_sgadget,a0
		move.l	Scribedithd,a1
		move.l	#0,a2
		move.l	#1,d0			number of gadgets
		jsr	refreshGlist(a6)
		bra	reply


;(* Clears the current user selection from the scribblepad add entry   	 *)
;(* window.	 							 *)
ClearScribInput	bsr	ClearScribString
		move.l	intbase,a6
		move.l	#scribentry_sgadget,a0
		move.l	SAEhd,a1
		move.l	#0,a2
		move.l	#1,d0			number of gadgets
		jsr	refreshGlist(a6)
		bra	reply


;(* Introduces blank characters into the scribblepad add entry string	 *)
;(* buffer.								 *)
ClearScribString
		move.l	#scribentrybuffer,a0	clear string buffer
		moveq	#71,d0
.loop		move.b	#0,(a0)+
		dbf	d0,.loop
		rts


;(* Adds a scribblepad entry.						 *)
AddScribEntry	bclr	#scribeditinp,flag4	use add entry inputs
		bsr	ReserveScribEntry
		cmp.l	#0,d0
		beq	.out
		bsr	InsertScribEntry
		bsr	DisplaySPad
.out		bsr	CloseSAEwind
		bra 	finishmessage


;(* Allocates memory for 1 scribblepad entry. Returns address in d0.	 *)
CreateScribEntry
		move.l	execbase,a6
		move.l	#scribent_size,d0
		move.l	#$10000,d1
		jsr	allocmem(a6)
		rts


;(* Inserts an entry into the scribblepad entry list. Expects pointer to *)
;(* entry in d0.							 *)
InsertScribEntry
		move.l	scribble,a1		start of list
		cmp.l	#0,a1			empty list?
		bne	.notempty
		move.l	d0,scribble		trivial case
		move.l	d0,scrib_curentry	pointer to page
		rts
.notempty	move.l	a1,a2			store previous
		move.l	scribent_next(a1),a1
		cmp.l	#0,a1			end of list?
		bne	.notempty
		move.l	d0,scribent_next(a2)	insert new entry
		rts


;(* Creates a scribblepad entry from inputs supplied in the scribblepad  *)
;(* add entry window, and gives the entry a unique identifier.		 *)
;(* Returns entry address in d0.			 		 *)
ReserveScribEntry
		btst	#scribeditinp,flag4
		bne	.edit
		move.l	#scribentrybuffer,a0
		bra	.next
.edit		move.l	#scribeditbuffer,a0
.next		clr.l	d0			counter
.loop		clr.l	d1
		move.b	(a0)+,d1
		cmp.w	#0,d1			end of text?
		beq	.done
		addq	#1,d0
		bra	.loop
.done		addq	#1,d0			add nul char at eot
		move.l	d0,d3			store size
		move.l	execbase,a6
		move.l	#$10000,d1
		jsr	allocmem(a6)
		beq	.error			no mem
		move.l	d0,d4			store text address
		bsr	CreateScribEntry
		beq	.error			no mem
		move.l	d0,a0
		move.l	d4,scribent_text(a0)
		move.w	d3,scribent_txt_size(a0)	text size
		move.l	scribmarker,scrib_ident(a0)	identifier
		add.l	#1,scribmarker		each entry is unique
		btst	#scribeditinp,flag4	which input window?
		bne	.edit1
		move.l	#scribentrybuffer,a1	add entry source
		bra	.next1
.edit1		move.l	#scribeditbuffer,a1	edit entry source
.next1		move.l	d4,a2			destination
		sub.l	#1,d3			because dbf ... 
.cloop		move.b	(a1)+,(a2)+		copy text to mem
		dbf	d3,.cloop
.out		move.l	a0,d0
.error		rts


;(* Finds the previous scribblepad entry. Expects entry address in a0. 	 *)
;(* Returns address in a0, zero if unsuccessful.			 *)
FindScribPrev	move.l	scribble,a1
		cmp.l	#0,a1	
		beq	.error			no entries
		cmp.l	scribble,a0		only one entry?
		beq	.one
		move.l	scrib_ident(a0),d0	get identifier of current
.loop		move.l	a1,a2			store previous
		move.l	scribent_next(a1),a1	get next
		move.l	scrib_ident(a1),d1
		cmp.l	d0,d1
		bne	.loop			no match, so repeat
		move.l	a2,a0			return address
		rts
.error		move.l	#0,a0			return nil
		rts
.one		move.l	scribble,a0		point to single entry
		rts


;(* Deletes an entry from the scribblepad list. Expects entry address in *)
;(* a0.									 *)
RemoveScribEntry
		move.l	scribent_next(a0),a1
		cmp.l	#0,a1			end of list?
		beq	.last			yes
		move.l	a0,a5			store
		cmp.l	scribble,a0		first entry?
		beq	.first
		bsr	findscribprev		result in a0
		move.l	a0,scribentry
		move.l	scribent_next(a5),a2	skip over entry being
		move.l	a2,scribent_next(a0)	deleted
		bra	.free
.last		move.l	a0,a5			store
		cmp.l	scribble,a0		one entry?
		beq	.one
		bsr	findscribprev		get previous
		move.l	a0,scribentry
		move.l	#0,scribent_next(a0)	
.free		move.l	a5,a1
		move.l	#scribent_size,d0
		bsr	freeup
		rts
.one		move.l	a0,a1
		move.l	#scribent_size,d0
		bsr	freeup
		move.l	#0,scribble
		rts
.first		move.l	a1,a0
		move.l	a5,a1
		move.l	a0,a5			store next entry
		move.l	#scribent_size,d0
		bsr	freeup
		move.l	a5,scribble
		rts


;(* Removes an entry from the ScribblePad list, and returns to main loop *)
DelScribEntry	move.l	scribentry,a0
		bsr	RemoveScribEntry
		bsr	BlankPad
		move.l	scribble,scrib_curentry
		bsr	DisplaySPad
		bsr	ClearScribEdit
		move.l	scribentry,a0
		bsr	RecallScribEntry
		bra	reply


;(* Changes a scribblepad entry to the new values shown in the 		 *)
;(* scribblepad edit entry window.					 *)
ChangeScribEntry
		move.l	scribentry,a0
		bsr	RemoveScribEntry	clear old version
		bset	#scribeditinp,flag4	inputs from Scr. Ed. win.
		bsr	ReserveScribEntry	create new version
		move.l	d0,scribentry		store
		bsr	InsertScribEntry	insert new version
		bsr	BlankPad
		move.l	scribble,scrib_curentry
		bsr	DisplaySPad
		bra	reply


;(* Refreshes the string gadgets in the ScribblePad Edit Entry window.	 *)
ScribEditRefresh
		move.l	intbase,a6
		move.l	#scribedit_sgadget,a0
		move.l	scribedithd,a1
		move.l	#0,a2
		move.l	#1,d0			number of gadgets
		jsr	refreshGlist(a6)
		rts


;(* Recalls scribblepad entry information and displays it in the 	 *)
;(* scribblepad edit entry window. Expects entry address in a0.		 *)
RecallScribEntry
		cmp.l	#0,a0
		beq	.out
		move.l	a0,scribentry
		move.l	#scribeditbuffer,a2
		move.l	scribent_text(a0),a1
.loop		move.w	#0,d0
		move.b	(a1),d0
		cmp.w	#0,d0
		beq	.done
		move.b	(a1)+,(a2)+
		bra	.loop
.done
.out		bsr	scribeditrefresh
		rts


;(* Finds the next scribblepad entry and displays it in the edit entry 	 *)
;(* window. Expects the current entry in scribentry.			 *)
NextScribEntry	bsr	ClearScribEdit
		bsr	ScribEditRefresh
		move.l	scribentry,a0
		cmp.l	#0,a0
		beq	.empty
		move.l	scribent_next(a0),a0
		cmp.l	#0,a0
		beq	.endlist
		bsr	RecallScribEntry
		bra	reply
.endlist	move.l	scribentry,a0
		bsr	RecallScribEntry
.empty		bra	reply



;(* Finds the previous scribblepad entry and displays it in the edit	 *)
;(* entry window. Expects the current entry in scribentry.		 *)
PrevScribEntry	bsr	ClearScribEdit
		bsr	ScribEditRefresh
		move.l	scribentry,a0
		bsr	FindScribPrev
		bsr	RecallScribEntry
		bra	reply
 

;(* Displays scribblepad entries in the window.	Expects address of first *) 
;(* entry on that page in scrib_curentry.				 *)
DisplaySPad	move.l	gfxbase,a6
		move.l	spwhd,a1
		move.l	50(a1),a1
		move.l	#0,d0			JAM1
		jsr	setDrMd(a6)		set mode
		move.l	spwhd,a1
		move.l	#2,d0	
		bsr	pencolour		set black pen
		move.w	#10,scribXpos
		move.w	scribXpos,d0
		move.w	#22,scribYpos
		move.w	scribYpos,d1
		move.l	spwhd,a1
		bsr	movepos	
		move.l	scrib_curentry,a1	start of page
.loop		cmp.l	#0,a1			end of list?
		beq	.out
		move.l	a1,a5			store
		bsr	DisplayScribEntry
		btst	#scribsplit,flag4	entry split at bottom?
		bne	.split
		btst	#scribover,flag1
		bne	.overflow
		move.l 	scribent_next(a5),a1
		bra	.loop
.overflow	move.l	scribent_next(a5),a1
		move.l	a1,scrib_nextentry	store pointer for next page
		rts
.out		move.l	scribble,a1		no overflow here, so go
		move.l	a1,scrib_nextentry	back to start
		rts
; repeat entry at start of next page of scribblepad, and blank trailing
; lines of split entry
.split		move.l	spwhd,a1
		move.l	#1,d0
		bsr	pencolour
		move.w	lines_used,d5
		sub.w	#1,d5
.blankloop	bsr	uppadline
		move.l	gfxbase,a6
		move.l	spwhd,a1
		move.l	50(a1),a1		rastport
		move.l	#0,d0
		move.l	#0,d1
		move.w	scribXpos,d0		topleft x
		move.w	scribYpos,d1		topleft y
		;sub.w	#8,d1
		move.w	d1,d3			bottomright y
		sub.w	#8,d1
		move.l	#286,d2			bottomright x
		jsr	rectfill(a6)		fill 'pages'		
		dbf	d5,.blankloop
		move.l	currententry,scrib_nextentry
		rts




;(* Displays a single scribblepad entry. Expects pointer to entry in a1. *)
DisplayScribEntry
		move.w	#0,lines_used		no lines used yet	
		bclr	#scribsplit,flag4
		move.l	scribent_text(a1),a0
		move.l	a1,currententry		store pointer
		cmp.l	#0,a0			no entries?
		beq	.break
.line		clr.w	d0
		clr.w	d1			number of chars
		move.b	(a0),d0
		cmp.w	#0,d0			end of text?
		beq	.break
		cmp.w	#" ",d0
		bne	.nospace		
		add.l	#1,a0			skip space at start
.nospace	move.l	a0,a2			store start of line
.loop		move.b	(a0)+,d0		inspect one char
		cmp.w	#0,d0			end of text?
		beq	.endtext
		addq	#1,d1
		cmp.w	#scrib_width,d1		line full?
		beq	.wholeline
		bra	.loop
	
.wholeline	clr.w	d2
		move.b	(a0)+,d2		complete word at EOL?
		cmp.w	#" ",d2
		beq	.okline
		cmp.w	#0,d2
		beq	.okline
		sub.l	#1,a0			go back one char
.backloop	cmp.w	#" ",d0			last char a space?
		beq	.okline
		subq	#1,d1			decrease width
		move.b	-(a0),d0
		cmp.l	a0,a2			back to start?
		bne	.backloop		search back through line
		move.l	#scrib_width,d1		full line
		add.l	#scrib_width,a0

.okline		move.l	a0,a4			start of next line
		move.l	a2,a0			start of this line
		move.l	d1,d0			number of chars
		bsr	displayscribline
		move.l	a4,a0
		bsr	downpadline		move down a line
		add.w	#1,lines_used		
		btst	#scribover,flag1	bottom reached?
		bne	.split			yes
		bra	.line			do next line

.endtext	move.l	a2,a0			start of line
		move.l	d1,d0			number of chars
		bsr	displayscribline
		bsr	downpadline		no need to check for
		add.w	#1,lines_used 
		bra	.break			bottom here
.split		bset	#scribsplit,flag4	entry is split
.break		rts				



;(* Displays a single line of text for a scribblepad entry. Expects 	 *)
;(* pointer to text in a0, number of chars in d0			 *)
DisplayScribLine
		move.l	spwhd,a1
		bsr	displaytext		
		rts


;(* Moves the text cursor down one line	in the scribblepad.		 *)
downpadline	bclr	#scribover,flag1	clear flag initially
		add.w	#10,scribYpos
		move.w	scribXpos,d0
		move.w	scribYpos,d1
		cmp.w	#scrib_bottom,d1	bottom of page reached?
		bgt	.error
		move.l	spwhd,a1
		bsr	movepos			
		rts
.error		bset	#scribover,flag1	overflow flag set
		rts


;(* Moves the cursor up one line in the scribblepad.			 *)
uppadline	sub.w	#9,scribYpos
		move.w	scribXpos,d0
		move.w	scribYpos,d1
		move.l	spwhd,a1
		bsr	movepos
		rts


*-------------- EDIT ENTRY ROUTINES -------------------------------------*


;(* Opens the edit window and places the first entry for that day in it. *)
Edit		bsr	OpenEditwind
		move.l	edithd,d0
		tst.l	d0
		beq	.error
		bsr	SetupEditDisplay
		bsr	FindEntry
		move.l	a1,a0
		bsr	RecallEntry		display first entry
.error		bra	reply


;(* Closes the Edit Entry window, and restores the main diary display.	 *)
CloseEdit	bsr	CloseEditwind
		bsr	FindEntry
		move.l	a1,start_entry
		move.l	a1,page_start
		bsr	DisplayPages		update display
		bra	finishmessage

;(* Takes appropriate action when CR is hit in the Add Entry window.	 *)
;(* The program moves through each of the string gadgets, then acts as	 *)
;(* if OK had been selected.						 *)
EditEntryCR	btst	#timeyn,flag1		if time OFF, do not need
		beq	ChangeEntry		to check hrs/mins
		btst	#strgad,flag3		first gadget?
		bne	.acthrs			yes, activate hours gadget
		btst	#hrsgad,flag3		second gadget?
		bne	.actmins		yes, activate mins gadget
		bra	ChangeEntry		as gadget $98
.acthrs		move.l	intbase,a6
		move.l	#edithours_sgadget,a0	gadget
		move.l	edithd,a1		window
		move.l	#0,a2			requestor (nil)
		jsr	activategadget(a6)
		bclr	#strgad,flag3		set gadget flags ... 
		bset	#hrsgad,flag3		... appropriately
		bclr	#minsgad,flag3
		bra	.out
.actmins	move.l	intbase,a6
		move.l	#editmins_sgadget,a0	gadget
		move.l	edithd,a1		window
		move.l	#0,a2			requestor (nil)
		jsr	activategadget(a6)
		bclr	#hrsgad,flag3
		bset	#minsgad,flag3
		bclr	#strgad,flag3
.out		bra	reply


;(* Clears the current user selection from the edit entry window.	 *)
ClearEditInput	bsr	ClearEditString
		bsr	EditRefresh
		bra	reply


;(* Introduces blank characters into the edit entry string gadgets.	 *)
ClearEditString
		move.l	#editentrybuffer,a0	clear string buffer
		moveq	#71,d0
.loop		move.b	#0,(a0)+
		dbf	d0,.loop
		move.l	#hoursbuffer,a0
		move.l	#0,(a0)+		clear hours
		move.l	#0,(a0)+
		move.l	#0,(a0)
		move.l	#minsbuffer,a0
		move.l	#0,(a0)+		clear mins
		move.l	#0,(a0)+
		move.l	#0,(a0)
		move.l	#hours_sinfo,a0
		move.l	#0,28(a0)
		move.l	#mins_sinfo,a0
		move.l	#0,28(a0)
		rts


;(* Refreshes the string gadgets in the Edit Entry window.		 *)
EditRefresh	move.l	intbase,a6
		move.l	#editentry_sgadget,a0
		move.l	edithd,a1
		move.l	#0,a2
		move.l	#3,d0			number of gadgets
		jsr	refreshGlist(a6)
		rts


;(* Recalls entry information and displays it in the edit entry window.  *)
;(* Expects entry address in a0.					 *)
RecallEntry	cmp.l	#0,a0
		beq	.out
		move.l	a0,currententry
		move.w	ent_stat(a0),d0		get status
; Alter the time option gadget to selected yes/no depending on whether
; or not time is specified for this entry
		btst	#timeyn,d0		time specified?
		beq	.notime			no
		bsr	timey_disp		yes, display image
		bset	#timeyn,flag1
		bra	.dotime
.notime		bsr	timen_disp		no, display other image
		bclr	#timeyn,flag1
.dotime		bsr	ClearEditString
		move.l	currententry,a0
		move.l	#editentrybuffer,a2
		move.l	ent_text(a0),a1
.loop		move.w	#0,d0
		move.b	(a1),d0
		cmp.w	#0,d0
		beq	.done
		move.b	(a1)+,(a2)+
		bra	.loop
.done		move.w	ent_time(a0),d0
		divs	#100,d0
		move.l	d0,d1				
		and.l	#$ff,d0			get hours
		move.l	#hours_sinfo,a1
		move.l	d0,28(a1)
		swap	d1
		and.l	#$ff,d1			get mins
		move.l	#mins_sinfo,a1
		move.l	d1,28(a1)
		move.l	d1,d5			store
		bsr	convert			number in d0
		move.l	#decnumber,a0
		add.l	#2,a0			only lower 2 bytes
		move.l	#hoursbuffer,a1
		bsr	copy2bytes
		move.l	d5,d0
		bsr	convert
		move.l	#decnumber,a0
		add.l	#2,a0
		move.l	#minsbuffer,a1
		bsr	copy2bytes
.out		bsr	EditRefresh
		rts


;(* Copies two bytes from address a0 to a1, and changes result to ASCII	 *)
copy2bytes	move.b	(a0)+,d0
		add.b	#$30,d0			convert to ASCII
		move.b	d0,(a1)+
		move.b	(a0),d0
		add.b	#$30,d0			convert to ASCII
		move.b	d0,(a1)
		rts



;(* Gets the next entry from the entry list.				 *)
NextEntry	bsr	ClearEditString
		bsr	EditRefresh
		move.l	currententry,a0
		cmp.l	#0,a0
		beq	.noentry
		move.l	ent_next(a0),a0
		cmp.l	#0,a0
		beq	.error
		bsr	RecallEntry
		bra	reply
.error		move.l	currententry,a0
		bsr	RecallEntry
.noentry	bra	reply


;(* Gets the previous entry from the entry list. Starts at the beginning *)
;(* and searches until it finds the entry that points to currententry. 	 *)
;(* This gets round my omission of a previous pointer in the entry 	 *)
;(* structure. Returns address in a1.					 *)
PrevEntry	bsr	ClearEditString
		bsr	EditRefresh
		move.l	currententry,a0
		cmp.l	#0,a0
		beq	.noentry
		bsr	FindPrev
		bsr	RecallEntry
.noentry	bra	reply

		
;(* Finds the entry previous to the one being considered. Expects 	 *)
;(* current entry in a0. Returns result in a0. If entry is the only one  *)
;(* for that day, or the first entry in the list, return itself.	 *)
FindPrev	bclr	#one_entry,flag1	do not know # of entries
		bclr	#firstentry,flag1
		move.l	a0,a5			store
		bsr	FindEntry		puts first entry in a1
		cmp.l	a5,a1			first entry?
		beq	.first
.loop		move.l	ent_next(a1),a0		next entry for that day
		cmp.l	a5,a0			found entry?
		beq	.out			yes
		move.l	a0,a1			get next entry
		bra	.loop
.out		move.l	a1,a0
		rts
.first		move.l	a5,a0			first entry in list, so
		bset	#firstentry,flag1	return itself
		move.l	ent_next(a0),a1		end of list?
		cmp.l	#0,a1			yes => only one entry
		beq	.one			       in list				
		rts
.one		bset	#one_entry,flag1
		rts


;(* Deletes an entry from the entry list. Expects entry address in 	 *)
;(* currententry.							 *)
DelEntry	bclr	#change,flag4
		bsr	RemoveEntry
		bra	reply	


;(* Removes an entry from the entry list. Used for deletion and also for *)
;(* editing ie. delete old version, insert new version.			 *)
;(* Expects entry address in currententry. If change flag is set [flag4] *)
;(* do not delete contents of edit buffer, because same entry must be    *)
;(* re-created with new inputs.						 *)
RemoveEntry	move.l	currententry,a0
		move.l	ent_next(a0),store	store next
		cmp.l	page_start,a0		first on page?
		bne	.notstart		no
		move.l	ent_next(a0),page_start	yes		
.notstart	bsr	FindPrev		result in a0
		btst	#one_entry,flag1	only one entry?
		bne	.one			yes
		btst	#firstentry,flag1	first entry?
		bne	.first
		move.l	a0,entrystore		store previous
		move.l	currententry,a1		needed for freeup
		move.l	#ent_size,d0
		bsr	freeup			clear structure
		move.l	entrystore,a0		get previous	
		move.l	store,ent_next(a0)	set next pointer
		btst	#change,flag4
		bne	.nochange
		bsr	ClearEditString
		bsr	EditRefresh
		move.l	entrystore,a0
		bsr	RecallEntry		update display
.nochange	rts
.one		bsr	FindDay			returns day in a0
		move.l	a0,store
		move.l	day_entry(a0),a1	needed for freeup
		move.l	#ent_size,d0
		bsr	freeup			clear structure
		move.l	store,a0
		move.l	#0,day_entry(a0)	clear pointer to first entry
		move.l	#0,currententry
		btst	#change,flag4
		bne	.nochange1
		bsr	ClearEditString
		bsr	EditRefresh
.nochange1	rts
.first		move.l	store,entrystore	store next entry
		bsr	FindDay			returns day in a0
		move.l	a0,store		store day
		move.l	day_entry(a0),a1
		move.l	#ent_size,d0
		bsr	freeup
		move.l	store,a0
		move.l	entrystore,day_entry(a0)
		btst	#change,flag4
		bne	.nochange2
		bsr	ClearEditString
		bsr	EditRefresh
		move.l	entrystore,a0
		bsr	RecallEntry		update display
.nochange2	rts


;(* Changes an entry in the entry list, to the values shown in the edit  *)
;(* entry window.							 *)
ChangeEntry	move.l	currententry,a0
		cmp.l	#0,a0
		beq	.error
		bsr	CheckInputs
		btst	#requestop,flag2	Error requestor
		bne	.error			yes
		bsr	CloseEditwind
		bset	#change,flag4		do not delete inputs
		bsr	RemoveEntry		clear old version
		bset	#editinp,flag1		inputs from Edit window
		bsr	ReserveEntry		create new version
		move.l	d0,currententry		store
		bsr	FindDay			get day address (a0)
		move.l	currententry,a1		entry address
		bsr	InsertEntry		insert new version
		bsr	FindEntry
		move.l	a1,start_entry
		move.l	a1,page_start
		bsr	DisplayPages
.error		bra	finishmessage


*-------------- WINDOW STRUCTURES ---------------------------------------*

		even				Main Window
window_defs	dc.w	100			-----------
		dc.w	20
		dc.w	360
		dc.w	210
		dc.b	0
		dc.b	1
		dc.l	$660			IDCMP flags
		dc.l	$200100e		wbenchwindow			
		dc.l	df_gadget
		dc.l	0			standard checkmark
		dc.l	windowname
		dc.l	0			screenhd
		dc.l	0			no bitmap
		dc.w	0
		dc.w	0
		dc.w	640
		dc.w	256
		dc.w	1			wbenchscreen
windowname	dc.b	" AmigaDiary v1.13 ",0
		even	
windowhd	dc.l	0	


		even				Scribble Pad
spw_defs	dc.w	50			------------
		dc.w	40
		dc.w	300
		dc.w	200
		dc.b	0
		dc.b	1
		dc.l	$260			IDCMP flags
		dc.l	$2001002		wbenchwindow			
		dc.l	sae_gadget
		dc.l	0			standard checkmark
		dc.l	spwname
		dc.l	0			screenhd
		dc.l	0			no bitmap
		dc.w	0
		dc.w	0
		dc.w	640
		dc.w	256
		dc.w	1			wbenchscreen
spwname		dc.b	" ScribblePad ",0
		even	
spwhd		dc.l	0	


		even				Add Entry
ae_defs		dc.w	40			---------
		dc.w	60
		dc.w	528
		dc.w	80
		dc.b	0
		dc.b	1
		dc.l	$660			IDCMP flags
		dc.l	$2001002		wbenchwindow			
		dc.l	entry_sgadget
		dc.l	0			standard checkmark
		dc.l	aename
		dc.l	0			screenhd
		dc.l	0			no bitmap
		dc.w	0
		dc.w	0
		dc.w	640
		dc.w	256
		dc.w	1			wbenchscreen
aename		dc.b	" Add Entry ",0
		even	
aehd		dc.l	0	


		even				Shrink Window
shrink_defs	dc.w	200			-------------
		dc.w	30
		dc.w	220
		dc.w	25
		dc.b	0
		dc.b	1
		dc.l	$260			IDCMP flags
		dc.l	$200100e		wbenchwindow			
		dc.l	0			gadgets
		dc.l	0			standard checkmark
		dc.l	shrinkname
		dc.l	0			screenhd
		dc.l	0			no bitmap
		dc.w	0
		dc.w	0
		dc.w	640
		dc.w	256
		dc.w	1			wbenchscreen
shrinkname	dc.b	" AmigaDiary v1.13 ",0
		even	
shrinkhd	dc.l	0	


		even				About Window
about_defs	dc.w	100			------------
		dc.w	60
		dc.w	360
		dc.w	100
		dc.b	0
		dc.b	1
		dc.l	$8			IDCMP flags
		dc.l	$2001002		wbenchwindow			
		dc.l	0
		dc.l	0			standard checkmark
		dc.l	aboutname
		dc.l	0			screenhd
		dc.l	0			no bitmap
		dc.w	0
		dc.w	0
		dc.w	640
		dc.w	256
		dc.w	1			wbenchscreen
aboutname	dc.b	" About AmigaDiary ",0
		even	
abouthd		dc.l	0	

		
		even
request_defs	dc.w	188			Error Requestor
		dc.w	80			---------------
		dc.w	212
		dc.w	68
		dc.b	0
		dc.b	1
		dc.l	$60			IDCMP flags
		dc.l	$2001002			
		dc.l	ok_gadget
		dc.l	0			standard checkmark
		dc.l	requestname
		dc.l	0
		dc.l	0			no bitmap
		dc.w	200
		dc.w	50
		dc.w	640
		dc.w	256
		dc.w	1			wbench screen
requestname	dc.b	"      System Message      ",0
		even	
requesthd	dc.l	0


		even				Lookup Entry Window
le_defs		dc.w	150			------------------
		dc.w	70
		dc.w	240
		dc.w	70
		dc.b	0
		dc.b	1
		dc.l	$660			IDCMP flags
		dc.l	$2001002		wbenchwindow			
		dc.l	date_sgadget
		dc.l	0			standard checkmark
		dc.l	lename
		dc.l	0			screenhd
		dc.l	0			no bitmap
		dc.w	0
		dc.w	0
		dc.w	640
		dc.w	256
		dc.w	1			wbenchscreen
lename		dc.b	" LookUp Entry ",0
		even	
lehd		dc.l	0	


		even				Load File Window
lf_defs		dc.w	110			----------------
		dc.w	70
		dc.w	340
		dc.w	70
		dc.b	0
		dc.b	1
		dc.l	$660			IDCMP flags
		dc.l	$2001002		wbenchwindow			
		dc.l	fileload_sgadget
		dc.l	0			standard checkmark
		dc.l	lfname
		dc.l	0			screenhd
		dc.l	0			no bitmap
		dc.w	0
		dc.w	0
		dc.w	640
		dc.w	256
		dc.w	1			wbenchscreen
lfname		dc.b	" Load File ",0
		even	
lfhd		dc.l	0	


		even				Save File Window
sf_defs		dc.w	110			----------------
		dc.w	70
		dc.w	340
		dc.w	70
		dc.b	0
		dc.b	1
		dc.l	$660			IDCMP flags
		dc.l	$2001002		wbenchwindow			
		dc.l	filesave_sgadget
		dc.l	0			standard checkmark
		dc.l	sfname
		dc.l	0			screenhd
		dc.l	0			no bitmap
		dc.w	0
		dc.w	0
		dc.w	640
		dc.w	256
		dc.w	1			wbenchscreen
sfname		dc.b	" Save File ",0
		even	
sfhd		dc.l	0	


		even				Add Entry (ScribblePad)
sae_defs	dc.w	40			-----------------------
		dc.w	60
		dc.w	528
		dc.w	65
		dc.b	0
		dc.b	1
		dc.l	$660			IDCMP flags
		dc.l	$2001002		wbenchwindow			
		dc.l	scribentry_sgadget
		dc.l	0			standard checkmark
		dc.l	saename
		dc.l	0			screenhd
		dc.l	0			no bitmap
		dc.w	0
		dc.w	0
		dc.w	640
		dc.w	256
		dc.w	1			wbenchscreen
saename		dc.b	" ScribblePad Add Entry ",0
		even	
saehd		dc.l	0	


		even				Edit Entry (ScribblePad)
scribedit_defs	dc.w	40			------------------------
		dc.w	60
		dc.w	550
		dc.w	65
		dc.b	0
		dc.b	1
		dc.l	$660			IDCMP flags
		dc.l	$2001002		wbenchwindow			
		dc.l	scribedit_sgadget
		dc.l	0			standard checkmark
		dc.l	scribeditname
		dc.l	0			screenhd
		dc.l	0			no bitmap
		dc.w	0
		dc.w	0
		dc.w	640
		dc.w	256
		dc.w	1			wbenchscreen
scribeditname	dc.b	" ScribblePad Edit Entry ",0
		even	
scribedithd	dc.l	0	


		even				Edit Entry Window
edit_defs	dc.w	40			-----------------
		dc.w	60
		dc.w	548
		dc.w	90
		dc.b	0
		dc.b	1
		dc.l	$660			IDCMP flags
		dc.l	$2001002		wbenchwindow			
		dc.l	editentry_sgadget
		dc.l	0			standard checkmark
		dc.l	editname
		dc.l	0			screenhd
		dc.l	0			no bitmap
		dc.w	0
		dc.w	0
		dc.w	640
		dc.w	256
		dc.w	1			wbenchscreen
editname	dc.b	" Edit Entry ",0
		even	
edithd		dc.l	0	



*-------------- BORDER STRUCTURES ---------------------------------------*


border1		dc.w	0,9			x,y distances
		dc.b	2,0			colours
		dc.b	0			JAM1
		dc.b	15			number of coord pairs
		dc.l	coord1			coords table
		dc.l	0			next border
coord1		dc.w	8,4,352,4,352,140,8,140,8,4
		dc.w	12,4,12,140,16,140,16,4
		dc.w	183,4,183,140,344,140,344,4
		dc.w	348,4,348,140


gen_border	dc.w	0,0
		dc.b	1,0
		dc.b	0
		dc.b	5
		dc.l	ae_coord
		dc.l	ae_shadow		next border
ae_coord	dc.w	0,0,77,0,77,12,0,12,0,0

ae_shadow	dc.w	0,0
		dc.b	2,0
		dc.b	0
		dc.b	8
		dc.l	ae_scoord
		dc.l	0			no more borders
ae_scoord	dc.w	78,1,78,13,2,13,2,14,79,14
		dc.w	79,1,80,1,80,13


entry_border	dc.w	0,0			no offset
		dc.b	2,0			colour
		dc.b	0			JAM1
		dc.b	5			# coord pairs
		dc.l	entry_coord
		dc.l	0			
entry_coord	dc.w	-6,-2,426,-2,426,9,-6,9,-6,-2


hours_border	dc.w	0,0			no offset
		dc.b	2,0			colour
		dc.b	0			JAM1
		dc.b	5			# coord pairs
		dc.l	hours_coord
		dc.l	0			
hours_coord	dc.w	-6,-2,25,-2,25,9,-6,9,-6,-2


am_border	dc.w	0,0			no offset
		dc.b	2,0			colour
		dc.b	0			JAM1
		dc.b	5			# coord pairs
		dc.l	am_coord
		dc.l	0			
am_coord	dc.w	0,0,31,0,31,11,0,11,0,0


date_border	dc.w	0,0			no offset
		dc.b	2,0			colour
		dc.b	0			JAM1
		dc.b	5			# coord pairs
		dc.l	date_coord
		dc.l	0			
date_coord	dc.w	-6,-2,54,-2,54,9,-6,9,-6,-2


file_border	dc.w	0,0			no offset
		dc.b	2,0			colour
		dc.b	0			JAM1
		dc.b	5			# coord pairs
		dc.l	file_coord
		dc.l	0			
file_coord	dc.w	-6,-2,264,-2,264,9,-6,9,-6,-2


*-------------- IMAGE STRUCTURES ----------------------------------------*


;(* Day Forward								 *)
df_image	dc.w	0,0			no offset
		dc.w	19,12			pixels
		dc.w	2			bit planes
		dc.l	df_data			data
		dc.b	3,0			colours
		dc.l	0
dfi_image	dc.w	0,0			no offset
		dc.w	19,12			pixels
		dc.w	2			bit planes
		dc.l	dfi_data		data
		dc.b	3,0			colours
		dc.l	0


;(* Day Backward 							 *)
db_image	dc.w	0,0			no offset
		dc.w	19,12			pixels
		dc.w	2			bit planes
		dc.l	db_data			data
		dc.b	3,0			colours
		dc.l	0
dbi_image	dc.w	0,0			no offset
		dc.w	19,12			pixels
		dc.w	2			bit planes
		dc.l	dbi_data		data
		dc.b	3,0			colours
		dc.l	0


;(* Week Backward							 *)
wb_image	dc.w	0,0			no offset
		dc.w	33,12			pixels
		dc.w	2			bit planes
		dc.l	wb_data			data
		dc.b	3,0			colours
		dc.l	0
wbi_image	dc.w	0,0			no offset
		dc.w	33,12			pixels
		dc.w	2			bit planes
		dc.l	wbi_data		data
		dc.b	3,0			colours
		dc.l	0


;(* Week Forward							 *)
wf_image	dc.w	0,0			no offset
		dc.w	33,12			pixels
		dc.w	2			bit planes
		dc.l	wf_data			data
		dc.b	3,0			colours
		dc.l	0
wfi_image	dc.w	0,0			no offset
		dc.w	33,12			pixels
		dc.w	2			bit planes
		dc.l	wfi_data		data
		dc.b	3,0			colours
		dc.l	0


;(* Time yes/no option in add entry / edit entry window.		 *)
timeyes_image	dc.w	0,0			no offset
		dc.w	31,12			pixels
		dc.w	2			bit planes
		dc.l	timeyes_data		data
		dc.b	3,0			colours
		dc.l	0
timeyesi_image	dc.w	0,0			no offset
		dc.w	31,12			pixels
		dc.w	2			bit planes
		dc.l	timeyesi_data		data
		dc.b	3,0			colours
		dc.l	0


stop_image	dc.w	0,0
		dc.w	30,15,2
		dc.l	stop_data
		dc.b	3,0
		dc.l	0


*-------------- TEXT STRUCTURES -----------------------------------------*


ds_text		dc.b	1,0			colours
		dc.b	1			mode
		even
		dc.w	6,3			x,y pos		
		dc.l	topaz_defs		font
		dc.l	ds_ttext
		dc.l	ds1_text		next text
ds_ttext	dc.b	"S",0
		even
ds1_text	dc.b	1,0			colours
		dc.b	1			mode
		even
		dc.w	15,3			x,y pos		
		dc.l	topazU_defs		font
		dc.l	ds1_ttext
		dc.l	ds2_text		next text
ds1_ttext	dc.b	"c",0
		even
ds2_text	dc.b	1,0			colours
		dc.b	1			mode
		even
		dc.w	24,3			x,y pos		
		dc.l	topaz_defs		font
		dc.l	ds2_ttext
		dc.l	0			next text
ds2_ttext	dc.b	"ribble",0
		even


le_text		dc.b	1,0			colours
		dc.b	1			mode
		even
		dc.w	16,3			x,y pos		
		dc.l	topaz_defs		font
		dc.l	le_ttext
		dc.l	le1_text		next text
le_ttext	dc.b	"L",0
		even
le1_text	dc.b	1,0			colours
		dc.b	1			mode
		even
		dc.w	25,3			x,y pos		
		dc.l	topazU_defs		font
		dc.l	le1_ttext
		dc.l	le2_text		next text
le1_ttext	dc.b	"o",0
		even
le2_text	dc.b	1,0			colours
		dc.b	1			mode
		even
		dc.w	34,3			x,y pos		
		dc.l	topaz_defs		font
		dc.l	le2_ttext
		dc.l	0			next text
le2_ttext	dc.b	"okup",0
		even


ed_text		dc.b	1,0			colours
		dc.b	1			mode
		even
		dc.w	24,3			x,y pos		
		dc.l	topazU_defs		font
		dc.l	ed_ttext
		dc.l	ed1_text		next text
ed_ttext	dc.b	"E",0
		even
ed1_text	dc.b	1,0			colours
		dc.b	1			mode
		even
		dc.w	33,3			x,y pos		
		dc.l	topaz_defs		font
		dc.l	ed1_ttext
		dc.l	0			next text
ed1_ttext	dc.b	"dit",0
		even

ed2_text	dc.b	1,0			colours
		dc.b	1			mode
		even
		dc.w	24,3			x,y pos		
		dc.l	topaz_defs		font
		dc.l	ed2_ttext
		dc.l	0			next text
ed2_ttext	dc.b	"Edit",0
		even


ld_text		dc.b	1,0			colours
		dc.b	1			mode
		even
		dc.w	24,3			x,y pos		
		dc.l	topazU_defs		font
		dc.l	ld_ttext
		dc.l	ld1_text		next text
ld_ttext	dc.b	"L",0
		even
ld1_text	dc.b	1,0			colours
		dc.b	1			mode
		even
		dc.w	33,3			x,y pos		
		dc.l	topaz_defs		font
		dc.l	ld1_ttext
		dc.l	0			next text
ld1_ttext	dc.b	"oad",0
		even


sd_text		dc.b	1,0			colours
		dc.b	1			mode
		even
		dc.w	26,3			x,y pos		
		dc.l	topazU_defs		font
		dc.l	sd_ttext
		dc.l	sd1_text		next text
sd_ttext	dc.b	"S",0
		even
sd1_text	dc.b	1,0			colours
		dc.b	1			mode
		even
		dc.w	35,3			x,y pos		
		dc.l	topaz_defs		font
		dc.l	sd1_ttext
		dc.l	0			next text
sd1_ttext	dc.b	"ave",0
		even


ab_text		dc.b	1,0			colours
		dc.b	1			mode
		even
		dc.w	21,3			x,y pos		
		dc.l	topaz_defs		font
		dc.l	ab_ttext
		dc.l	ab1_text		next text
ab_ttext	dc.b	"A",0
		even
ab1_text	dc.b	1,0			colours
		dc.b	1			mode
		even
		dc.w	30,3			x,y pos		
		dc.l	topazU_defs		font
		dc.l	ab1_ttext
		dc.l	ab2_text		next text
ab1_ttext	dc.b	"b",0
		even
ab2_text	dc.b	1,0			colours
		dc.b	1			mode
		even
		dc.w	39,3			x,y pos		
		dc.l	topaz_defs		font
		dc.l	ab2_ttext
		dc.l	0			next text
ab2_ttext	dc.b	"out",0
		even


sh_text		dc.b	1,0			colours
		dc.b	1			mode
		even
		dc.w	16,3			x,y pos		
		dc.l	topaz_defs		font
		dc.l	sh_ttext
		dc.l	sh1_text		next text
sh_ttext	dc.b	"S",0
		even
sh1_text	dc.b	1,0			colours
		dc.b	1			mode
		even
		dc.w	25,3			x,y pos		
		dc.l	topazU_defs		font
		dc.l	sh1_ttext
		dc.l	sh2_text		next text
sh1_ttext	dc.b	"h",0
		even
sh2_text	dc.b	1,0			colours
		dc.b	1			mode
		even
		dc.w	34,3			x,y pos		
		dc.l	topaz_defs		font
		dc.l	sh2_ttext
		dc.l	0			next text
sh2_ttext	dc.b	"rink",0
		even


add_text	dc.b	1,0			colours
		dc.b	1			mode
		even
		dc.w	28,3			x,y pos		
		dc.l	topazU_defs		font
		dc.l	add_ttext
		dc.l	add1_text		next text
add_ttext	dc.b	"A",0
		even
add1_text	dc.b	1,0			colours
		dc.b	1			mode
		even
		dc.w	37,3			x,y pos		
		dc.l	topaz_defs		font
		dc.l	add1_ttext
		dc.l	0			next text
add1_ttext	dc.b	"dd",0
		even


line_break	dc.b	"--------------------",0
		even


line1_text	dc.b	3,0			colours
		dc.b	1			mode
		even
		dc.w	148,20			x,y pos		
		dc.l	topaz_defs		font
		dc.l	line1_ttext
		dc.l	line2_text		next text
line1_ttext	dc.b	"AmigaDiary",0
		even


line2_text	dc.b	2,0			colours
		dc.b	1			mode
		even
		dc.w	145,40			x,y pos		
		dc.l	topaz_defs		font
		dc.l	line2_ttext
		dc.l	line3_text		next text
line2_ttext	dc.b	"version 1.13",0
		even


line3_text	dc.b	2,0			colours
		dc.b	1			mode
		even
		dc.w	75,60			x,y pos		
		dc.l	topaz_defs		font
		dc.l	line3_ttext
		dc.l	line4_text		next text
line3_ttext	dc.b	"written by Andrew K. Pearson",0
		even


line4_text	dc.b	2,0			colours
		dc.b	1			mode
		even
		dc.w	80,80			x,y pos		
		dc.l	topaz_defs		font
		dc.l	line4_ttext
		dc.l	0			next text
line4_ttext	dc.b	"(c) Andrew Pearson 1992/93",0
		even


date_text	dc.b	1,0			colours
		dc.b	1			mode
		even
		dc.w	-120,0			x,y pos		
		dc.l	topaz_defs		font
		dc.l	date_ttext
		dc.l	0			next text
date_ttext	dc.b	"Date (ddmmyy)",0
		even


next_text	dc.b	1,0			colours
		dc.b	1			mode
		even
		dc.w	24,3			x,y pos		
		dc.l	topaz_defs		font
		dc.l	next_ttext
		dc.l	0			next text
next_ttext	dc.b	"Next",0
		even


prev_text	dc.b	1,0			colours
		dc.b	1			mode
		even
		dc.w	24,3			x,y pos		
		dc.l	topaz_defs		font
		dc.l	prev_ttext
		dc.l	0			next text
prev_ttext	dc.b	"Prev",0
		even


delete_text	dc.b	1,0			colours
		dc.b	1			mode
		even
		dc.w	15,3			x,y pos		
		dc.l	topaz_defs		font
		dc.l	delete_ttext
		dc.l	0			next text
delete_ttext	dc.b	"Delete",0
		even


invinp_text	dc.b	1,0			colours
		dc.b	1			mode
		even
		dc.w	60,25			x,y pos		
		dc.l	topaz_defs		font
		dc.l	invinp_ttext
		dc.l	0			next text
invinp_ttext	dc.b	"Invalid Inputs!",0
		even


badfile_text	dc.b	1,0			colours
		dc.b	1			mode
		even
		dc.w	60,25			x,y pos		
		dc.l	topaz_defs		font
		dc.l	badfile_ttext
		dc.l	0			next text
badfile_ttext	dc.b	"Invalid File!",0
		even


done_text	dc.b	1,0			colours
		dc.b	1			mode
		even
		dc.w	26,3			x,y pos		
		dc.l	topaz_defs		font
		dc.l	done_ttext
		dc.l	0			next text
done_ttext	dc.b	"Done",0
		even


ae_text		dc.b	1,0			colours
		dc.b	1			mode
		even
		dc.w	28,3			x,y pos		
		dc.l	topaz_defs		font
		dc.l	ae_ttext
		dc.l	0			next text
ae_ttext	dc.b	"Add",0
		even


entry_text	dc.b	1,0			colours
		dc.b	1			mode
		even
		dc.w	-50,0			x,y pos		
		dc.l	topaz_defs		font
		dc.l	entry_ttext
		dc.l	0			next text
entry_ttext	dc.b	"Entry",0
		even


hours_text	dc.b	1,0			colours
		dc.b	1			mode
		even
		dc.w	-50,0			x,y pos		
		dc.l	topaz_defs		font
		dc.l	hours_ttext
		dc.l	0			next text
hours_ttext	dc.b	"Hours",0
		even


mins_text	dc.b	1,0			colours
		dc.b	1			mode
		even
		dc.w	-65,0			x,y pos		
		dc.l	topaz_defs		font
		dc.l	mins_ttext
		dc.l	0			next text
mins_ttext	dc.b	"Minutes",0
		even


yes_text	dc.b	1,0			colours
		dc.b	1			mode
		even
		dc.w	4,2			x,y pos		
		dc.l	topaz_defs		font
		dc.l	yes_ttext
		dc.l	0			next text
yes_ttext	dc.b	"Yes",0
		even


cr_text		dc.b	1,0			colours
		dc.b	1			mode
		even
		dc.w	20,3			x,y pos		
		dc.l	topaz_defs		font
		dc.l	cr_ttext
		dc.l	0			next text
cr_ttext	dc.b	"Clear",0
		even


ok_text		dc.b	1,0			colours
		dc.b	1			mode
		even
		dc.w	30,3			x,y pos		
		dc.l	topaz_defs		font
		dc.l	ok_ttext
		dc.l	0			next text
ok_ttext	dc.b	"Ok!",0
		even


cancel_text	dc.b	1,0			colours
		dc.b	1			mode
		even
		dc.w	15,3			x,y pos		
		dc.l	topaz_defs		font
		dc.l	cancel_ttext
		dc.l	0			next text
cancel_ttext	dc.b	"Cancel",0
		even


change_text	dc.b	1,0			colours
		dc.b	1			mode
		even
		dc.w	15,3			x,y pos		
		dc.l	topaz_defs		font
		dc.l	change_ttext
		dc.l	0			next text
change_ttext	dc.b	"Change",0
		even


file_text	dc.b	1,0			colours
		dc.b	1			mode
		even
		dc.w	-46,0			x,y pos		
		dc.l	topaz_defs		font
		dc.l	file_ttext
		dc.l	0			next text
file_ttext	dc.b	"File",0
		even


includetime	dc.b	"include time?",0
		even


*-------------- GADGET STRUCTURES (MAIN WINDOW) -------------------------*


;(* Day Forward 							 *)
df_gadget	dc.l	db_gadget		next gadget
		dc.w	280,155			x,y pos
		dc.w	19,12			width, height (hit box)
		dc.w	6			image, new image
		dc.w	1			flags
		dc.w	1			type : boolean
		dc.l	df_image		image
		dc.l	dfi_image		inverse data
		dc.l	0			no text
		dc.l	0			no exclude
		dc.l	0			no special info
		dc.w	$10			gadget ID	
		dc.l	0			user data


;(* Day Backward							 *)		
db_gadget	dc.l	wb_gadget		next gadget
		dc.w	65,155			x,y pos
		dc.w	19,12			width, height (hit box)
		dc.w	6			flags
		dc.w	1			flags
		dc.w	1			type : boolean
		dc.l	db_image		image
		dc.l	dbi_image		inverse data
		dc.l	0			no text
		dc.l	0			no exclude
		dc.l	0			no special info
		dc.w	$11			gadget ID	
		dc.l	0			user data


;(* Week Backward							 *)
wb_gadget	dc.l	wf_gadget		next gadget
		dc.w	23,155			x,y pos
		dc.w	33,12			width, height (hit box)
		dc.w	6			flags
		dc.w	1			flags
		dc.w	1			type : boolean
		dc.l	wb_image		image
		dc.l	wbi_image		inverse data
		dc.l	0			no text
		dc.l	0			no exclude
		dc.l	0			no special info
		dc.w	$12			gadget ID	
		dc.l	0			user data


;(* Week Forward							 *)
wf_gadget	dc.l	ae_gadget		next gadget
		dc.w	308,155			x,y pos
		dc.w	33,12			width, height (hit box)
		dc.w	6			flags
		dc.w	1			flags
		dc.w	1			type : boolean
		dc.l	wf_image		image
		dc.l	wfi_image		inverse data
		dc.l	0			no text
		dc.l	0			no exclude
		dc.l	0			no special info
		dc.w	$13			gadget ID	
		dc.l	0			user data


;(* Add Entry								 *)
ae_gadget	dc.l	ds_gadget		next gadget
		dc.w	97,170			x,y pos
		dc.w	77,12			width, height (hit box)
		dc.w	0			flags:inverse
		dc.w	1			flags
		dc.w	1			type : boolean
		dc.l	gen_border		image
		dc.l	0			inverse data
		dc.l	add_text		text
		dc.l	0			no exclude
		dc.l	0			no special info
		dc.w	$14			gadget ID	
		dc.l	0			user data


;(* Display ScribblePad							 *)
ds_gadget	dc.l	le_gadget		next gadget
		dc.w	267,170			x,y pos
		dc.w	77,12			width, height (hit box)
		dc.w	0			flags
		dc.w	1			flags
		dc.w	1			type : boolean
		dc.l	gen_border		image
		dc.l	0			inverse data
		dc.l	ds_text			text
		dc.l	0			no exclude
		dc.l	0			no special info
		dc.w	$15			gadget ID	
		dc.l	0			user data


;(* Lookup Entry							 *)
le_gadget	dc.l	ed_gadget		next gadget
		dc.w	12,170			x,y pos
		dc.w	77,12			width, height (hit box)
		dc.w	0			flags
		dc.w	1			flags
		dc.w	1			type : boolean
		dc.l	gen_border		image
		dc.l	0			inverse data
		dc.l	le_text			text
		dc.l	0			no exclude
		dc.l	0			no special info
		dc.w	$16			gadget ID	
		dc.l	0			user data


;(* Remove Entry							 *)
ed_gadget	dc.l	ld_gadget		next gadget
		dc.w	182,170			x,y pos
		dc.w	77,12			width, height (hit box)
		dc.w	0			flags
		dc.w	1			flags
		dc.w	1			type : boolean
		dc.l	gen_border		image
		dc.l	0			inverse data
		dc.l	ed_text			text
		dc.l	0			no exclude
		dc.l	0			no special info
		dc.w	$17			gadget ID	
		dc.l	0			user data


;(* Load Diary								 *)
ld_gadget	dc.l	sd_gadget		next gadget
		dc.w	12,188			x,y pos
		dc.w	77,12			width, height (hit box)
		dc.w	0			flags
		dc.w	1			flags
		dc.w	1			type : boolean
		dc.l	gen_border		image
		dc.l	0			inverse data
		dc.l	ld_text			text
		dc.l	0			no exclude
		dc.l	0			no special info
		dc.w	$18			gadget ID	
		dc.l	0			user data


;(* Save Diary								 *)
sd_gadget	dc.l	ab_gadget		next gadget
		dc.w	97,188			x,y pos
		dc.w	77,12			width, height (hit box)
		dc.w	0			flags
		dc.w	1			flags
		dc.w	1			type : boolean
		dc.l	gen_border		image
		dc.l	0			inverse data
		dc.l	sd_text			text
		dc.l	0			no exclude
		dc.l	0			no special info
		dc.w	$19			gadget ID	
		dc.l	0			user data


;(* About 								 *)
ab_gadget	dc.l	sh_gadget		next gadget
		dc.w	182,188			x,y pos
		dc.w	77,12			width, height (hit box)
		dc.w	0			flags
		dc.w	1			flags
		dc.w	1			type : boolean
		dc.l	gen_border		image
		dc.l	0			inverse data
		dc.l	ab_text			text
		dc.l	0			no exclude
		dc.l	0			no special info
		dc.w	$1a			gadget ID	
		dc.l	0			user data


;(* Shrink								 *)
sh_gadget	dc.l	flip_gadget		next gadget
		dc.w	267,188			x,y pos
		dc.w	77,12			width, height (hit box)
		dc.w	0			flags
		dc.w	1			flags
		dc.w	1			type : boolean
		dc.l	gen_border		image
		dc.l	0			inverse data
		dc.l	sh_text			text
		dc.l	0			no exclude
		dc.l	0			no special info
		dc.w	$1b			gadget ID	
		dc.l	0			user data


;(* Flip Page	 							 *)
flip_gadget	dc.l	0			next gadget
		dc.w	329,135			x,y pos
		dc.w	19,12			width, height (hit box)
		dc.w	6			image, new image
		dc.w	1			flags
		dc.w	1			type : boolean
		dc.l	df_image		image
		dc.l	dfi_image		inverse data
		dc.l	0			no text
		dc.l	0			no exclude
		dc.l	0			no special info
		dc.w	$1c			gadget ID	
		dc.l	0			user data


*-------------- GADGET STRUCTURES (ADD ENTRY WINDOW) --------------------*


entry_sgadget	dc.l	hours_sgadget		next gadget
		dc.w	69,20			x,y pos
		dc.w	425,10			width, height
		dc.w	0			flags
		dc.w	2			activation
		dc.w	4			type : string
		dc.l	entry_border		border structure
		dc.l	0			no drawing
		dc.l	entry_text		text
		dc.l	0			no exclude
		dc.l	entry_sinfo
		dc.w	$23			gadget ID
		dc.l	0			user data


hours_sgadget	dc.l	mins_sgadget		next gadget
		dc.w	69,40			x,y pos
		dc.w	30,10			width, height
		dc.w	0			flags
		dc.w	$802			integer 
		dc.w	4			type : string
		dc.l	hours_border		border structure
		dc.l	0			no drawing
		dc.l	hours_text		text
		dc.l	0			no exclude
		dc.l	hours_sinfo
		dc.w	$24			gadget ID
		dc.l	0			user data


mins_sgadget	dc.l	yes_gadget		next gadget
		dc.w	179,40			x,y pos
		dc.w	30,10			width, height
		dc.w	0			flags
		dc.w	$802			integer 
		dc.w	4			type : string
		dc.l	hours_border		border structure
		dc.l	0			no drawing
		dc.l	mins_text		text
		dc.l	0			no exclude
		dc.l	mins_sinfo
		dc.w	$25			gadget ID
		dc.l	0			user data


yes_gadget	dc.l	ae1_gadget		next gadget
		dc.w	440,38			x,y pos
		dc.w	31,11			width, height (hit box)
		dc.w	$80			flags
		dc.w	$101			flags
		dc.w	1			type : boolean
		dc.l	am_border		image
		dc.l	0			inverse data
		dc.l	yes_text		text
		dc.l	0			no exclude
		dc.l	0			no special info
		dc.w	$28			gadget ID	
		dc.l	0			user data


ae1_gadget	dc.l	cr_gadget		next gadget
		dc.w	32,55			x,y pos
		dc.w	77,12			width, height (hit box)
		dc.w	0			flags
		dc.w	1			flags
		dc.w	1			type : boolean
		dc.l	gen_border		image
		dc.l	0			inverse data
		dc.l	ae_text			text
		dc.l	0			no exclude
		dc.l	0			no special info
		dc.w	$20			gadget ID	
		dc.l	0			user data


cr_gadget	dc.l	cancel_gadget		next gadget
		dc.w	205,55			x,y pos
		dc.w	77,12			width, height (hit box)
		dc.w	0			flags
		dc.w	1			flags
		dc.w	1			type : boolean
		dc.l	gen_border		image
		dc.l	0			inverse data
		dc.l	cr_text			text
		dc.l	0			no exclude
		dc.l	0			no special info
		dc.w	$21			gadget ID	
		dc.l	0			user data


cancel_gadget	dc.l	0			next gadget
		dc.w	385,55			x,y pos
		dc.w	77,12			width, height (hit box)
		dc.w	0			flags
		dc.w	1			flags
		dc.w	1			type : boolean
		dc.l	gen_border		image
		dc.l	0			inverse data
		dc.l	cancel_text		text
		dc.l	0			no exclude
		dc.l	0			no special info
		dc.w	$22			gadget ID	
		dc.l	0			user data


*-------------- GADGET STRUCTURES (LOOKUP ENTRY) ------------------------*


date_sgadget	dc.l	ok1_gadget		next gadget
		dc.w	140,20			x,y pos
		dc.w	225,10			width, height
		dc.w	0			flags
		dc.w	$802			activation
		dc.w	4			type : string
		dc.l	date_border		border structure
		dc.l	0			no drawing
		dc.l	date_text		text
		dc.l	0			no exclude
		dc.l	date_sinfo
		dc.w	$40			gadget ID
		dc.l	0			user data


ok1_gadget	dc.l	cancel1_gadget		next gadget
		dc.w	20,40			x,y pos
		dc.w	77,12			width, height (hit box)
		dc.w	0			flags
		dc.w	1			flags
		dc.w	1			type : boolean
		dc.l	gen_border		image
		dc.l	0			inverse data
		dc.l	ok_text			text
		dc.l	0			no exclude
		dc.l	0			no special info
		dc.w	$41			gadget ID	
		dc.l	0			user data


cancel1_gadget	dc.l	0			next gadget
		dc.w	140,40			x,y pos
		dc.w	77,12			width, height (hit box)
		dc.w	0			flags
		dc.w	1			flags
		dc.w	1			type : boolean
		dc.l	gen_border		image
		dc.l	0			inverse data
		dc.l	cancel_text		text
		dc.l	0			no exclude
		dc.l	0			no special info
		dc.w	$42			gadget ID	
		dc.l	0			user data


*-------------- GADGET STRUCTURES (FILE SAVE) ---------------------------*


filesave_sgadget
		dc.l	saveok_gadget		next gadget
		dc.w	60,20			x,y pos
		dc.w	265,10			width, height
		dc.w	0			flags
		dc.w	2			activation
		dc.w	4			type : string
		dc.l	file_border		border structure
		dc.l	0			no drawing
		dc.l	file_text		text
		dc.l	0			no exclude
		dc.l	file_sinfo
		dc.w	$50			gadget ID
		dc.l	0			user data


saveok_gadget	dc.l	savecancel_gadget	next gadget
		dc.w	30,40			x,y pos
		dc.w	77,12			width, height (hit box)
		dc.w	0			flags
		dc.w	1			flags
		dc.w	1			type : boolean
		dc.l	gen_border		image
		dc.l	0			inverse data
		dc.l	ok_text			text
		dc.l	0			no exclude
		dc.l	0			no special info
		dc.w	$51			gadget ID	
		dc.l	0			user data


savecancel_gadget
		dc.l	0			next gadget
		dc.w	230,40			x,y pos
		dc.w	77,12			width, height (hit box)
		dc.w	0			flags
		dc.w	1			flags
		dc.w	1			type : boolean
		dc.l	gen_border		image
		dc.l	0			inverse data
		dc.l	cancel_text		text
		dc.l	0			no exclude
		dc.l	0			no special info
		dc.w	$52			gadget ID	
		dc.l	0			user data



*-------------- GADGET STRUCTURES (FILE LOAD) ---------------------------*


fileload_sgadget
		dc.l	loadok_gadget		next gadget
		dc.w	60,20			x,y pos
		dc.w	265,10			width, height
		dc.w	0			flags
		dc.w	2			activation
		dc.w	4			type : string
		dc.l	file_border		border structure
		dc.l	0			no drawing
		dc.l	file_text		text
		dc.l	0			no exclude
		dc.l	file_sinfo
		dc.w	$60			gadget ID
		dc.l	0			user data


loadok_gadget	dc.l	loadcancel_gadget	next gadget
		dc.w	30,40			x,y pos
		dc.w	77,12			width, height (hit box)
		dc.w	0			flags
		dc.w	1			flags
		dc.w	1			type : boolean
		dc.l	gen_border		image
		dc.l	0			inverse data
		dc.l	ok_text			text
		dc.l	0			no exclude
		dc.l	0			no special info
		dc.w	$61			gadget ID	
		dc.l	0			user data


loadcancel_gadget
		dc.l	0			next gadget
		dc.w	230,40			x,y pos
		dc.w	77,12			width, height (hit box)
		dc.w	0			flags
		dc.w	1			flags
		dc.w	1			type : boolean
		dc.l	gen_border		image
		dc.l	0			inverse data
		dc.l	cancel_text		text
		dc.l	0			no exclude
		dc.l	0			no special info
		dc.w	$62			gadget ID	
		dc.l	0			user data



*-------------- GADGET STRUCTURES (SCRIBBLEPAD) -------------------------*


;(* Add entry ...							 *)
sae_gadget	dc.l	done_gadget		next gadget
		dc.w	20,180			x,y pos
		dc.w	77,12			width, height (hit box)
		dc.w	0			flags:inverse
		dc.w	1			flags
		dc.w	1			type : boolean
		dc.l	gen_border		image
		dc.l	0			inverse data
		dc.l	ae_text			text
		dc.l	0			no exclude
		dc.l	0			no special info
		dc.w	$70			gadget ID	
		dc.l	0			user data


;(* Done entry ...							 *)
done_gadget	dc.l	scribnext_gadget	next gadget
		dc.w	200,180			x,y pos
		dc.w	77,12			width, height (hit box)
		dc.w	0			flags:inverse
		dc.w	1			flags
		dc.w	1			type : boolean
		dc.l	gen_border		image
		dc.l	0			inverse data
		dc.l	done_text		text
		dc.l	0			no exclude
		dc.l	0			no special info
		dc.w	$71			gadget ID	
		dc.l	0			user data


;(* Next Page of ScribblePad ...					 *)
scribnext_gadget
		dc.l	scribedit_gadget	next gadget
		dc.w	270,163			x,y pos
		dc.w	19,12			width, height (hit box)
		dc.w	6			image, new image
		dc.w	1			flags
		dc.w	1			type : boolean
		dc.l	df_image		image
		dc.l	dfi_image		inverse data
		dc.l	0			no text
		dc.l	0			no exclude
		dc.l	0			no special info
		dc.w	$72			gadget ID	
		dc.l	0			user data


;(* Edit entry ...							 *)
scribedit_gadget
		dc.l	0			next gadget
		dc.w	110,180			x,y pos
		dc.w	77,12			width, height (hit box)
		dc.w	0			flags:inverse
		dc.w	1			flags
		dc.w	1			type : boolean
		dc.l	gen_border		image
		dc.l	0			inverse data
		dc.l	ed2_text		text
		dc.l	0			no exclude
		dc.l	0			no special info
		dc.w	$73			gadget ID	
		dc.l	0			user data



*-------------- GADGET STRUCTURES (SCRIBBLEPAD ADD ENTRY) ---------------*


scribentry_sgadget
		dc.l	sae1_gadget		next gadget
		dc.w	69,20			x,y pos
		dc.w	425,10			width, height
		dc.w	0			flags
		dc.w	2			activation
		dc.w	4			type : string
		dc.l	entry_border		border structure
		dc.l	0			no drawing
		dc.l	entry_text		text
		dc.l	0			no exclude
		dc.l	scribentry_sinfo
		dc.w	$80			gadget ID
		dc.l	0			user data


sae1_gadget	dc.l	scr_gadget		next gadget
		dc.w	32,40			x,y pos
		dc.w	77,12			width, height (hit box)
		dc.w	0			flags
		dc.w	1			flags
		dc.w	1			type : boolean
		dc.l	gen_border		image
		dc.l	0			inverse data
		dc.l	ae_text			text
		dc.l	0			no exclude
		dc.l	0			no special info
		dc.w	$81			gadget ID	
		dc.l	0			user data


;(* Clear.								 *)
scr_gadget	dc.l	scancel_gadget		next gadget
		dc.w	215,40			x,y pos
		dc.w	77,12			width, height (hit box)
		dc.w	0			flags
		dc.w	1			flags
		dc.w	1			type : boolean
		dc.l	gen_border		image
		dc.l	0			inverse data
		dc.l	cr_text			text
		dc.l	0			no exclude
		dc.l	0			no special info
		dc.w	$82			gadget ID	
		dc.l	0			user data


scancel_gadget	dc.l	0			next gadget
		dc.w	395,40			x,y pos
		dc.w	77,12			width, height (hit box)
		dc.w	0			flags
		dc.w	1			flags
		dc.w	1			type : boolean
		dc.l	gen_border		image
		dc.l	0			inverse data
		dc.l	cancel_text		text
		dc.l	0			no exclude
		dc.l	0			no special info
		dc.w	$83			gadget ID	
		dc.l	0			user data


*-------------- GADGET STRUCTURES (SCRIBBLEPAD EDIT ENTRY) --------------*


;(* String gadget for entry text.					 *)
scribedit_sgadget
		dc.l	seditdel_gadget		next gadget
		dc.w	90,20			x,y pos
		dc.w	425,10			width, height
		dc.w	0			flags
		dc.w	2			activation
		dc.w	4			type : string
		dc.l	entry_border		border structure
		dc.l	0			no drawing
		dc.l	entry_text		text
		dc.l	0			no exclude
		dc.l	scribedit_sinfo
		dc.w	$a0			gadget ID
		dc.l	0			user data


;(* Delete entry.							 *)
seditdel_gadget	dc.l	seditcr_gadget		next gadget
		dc.w	10,40			x,y pos
		dc.w	77,12			width, height (hit box)
		dc.w	0			flags
		dc.w	1			flags
		dc.w	1			type : boolean
		dc.l	gen_border		image
		dc.l	0			inverse data
		dc.l	delete_text		text
		dc.l	0			no exclude
		dc.l	0			no special info
		dc.w	$a1			gadget ID	
		dc.l	0			user data


;(* Clear entry.							 *)
seditcr_gadget	dc.l	seditch_gadget		next gadget
		dc.w	100,40			x,y pos
		dc.w	77,12			width, height (hit box)
		dc.w	0			flags
		dc.w	1			flags
		dc.w	1			type : boolean
		dc.l	gen_border		image
		dc.l	0			inverse data
		dc.l	cr_text			text
		dc.l	0			no exclude
		dc.l	0			no special info
		dc.w	$a2			gadget ID	
		dc.l	0			user data


;(* Change Entry.							 *)
seditch_gadget	dc.l	seditdone_gadget	next gadget
		dc.w	190,40			x,y pos
		dc.w	77,12			width, height (hit box)
		dc.w	0			flags
		dc.w	1			flags
		dc.w	1			type : boolean
		dc.l	gen_border		image
		dc.l	0			inverse data
		dc.l	change_text		text
		dc.l	0			no exclude
		dc.l	0			no special info
		dc.w	$a3			gadget ID	
		dc.l	0			user data


;(* Done, ie. Confirm changes.						 *)
seditdone_gadget	
		dc.l	seditnext_gadget	next gadget
		dc.w	460,40			x,y pos
		dc.w	77,12			width, height (hit box)
		dc.w	0			flags
		dc.w	1			flags
		dc.w	1			type : boolean
		dc.l	gen_border		image
		dc.l	0			inverse data
		dc.l	done_text		text
		dc.l	0			no exclude
		dc.l	0			no special info
		dc.w	$a4			gadget ID	
		dc.l	0			user data


seditnext_gadget
		dc.l	seditprev_gadget	next gadget
		dc.w	370,40			x,y pos
		dc.w	77,12			width, height (hit box)
		dc.w	0			flags
		dc.w	1			flags
		dc.w	1			type : boolean
		dc.l	gen_border		image
		dc.l	0			inverse data
		dc.l	next_text		text
		dc.l	0			no exclude
		dc.l	0			no special info
		dc.w	$a5			gadget ID	
		dc.l	0			user data


seditprev_gadget
		dc.l	0			next gadget
		dc.w	280,40			x,y pos
		dc.w	77,12			width, height (hit box)
		dc.w	0			flags
		dc.w	1			flags
		dc.w	1			type : boolean
		dc.l	gen_border		image
		dc.l	0			inverse data
		dc.l	prev_text		text
		dc.l	0			no exclude
		dc.l	0			no special info
		dc.w	$a6			gadget ID	
		dc.l	0			user data


*-------------- GADGET STRUCTURES (EDIT ENTRY) --------------------------*
									

editentry_sgadget
		dc.l	edithours_sgadget	next gadget
		dc.w	69,20			x,y pos
		dc.w	425,10			width, height
		dc.w	0			flags
		dc.w	2			activation
		dc.w	4			type : string
		dc.l	entry_border		border structure
		dc.l	0			no drawing
		dc.l	entry_text		text
		dc.l	0			no exclude
		dc.l	editentry_sinfo
		dc.w	$90			gadget ID
		dc.l	0			user data


edithours_sgadget
		dc.l	editmins_sgadget	next gadget
		dc.w	60,45			x,y pos
		dc.w	30,10			width, height
		dc.w	0			flags
		dc.w	$802			integer 
		dc.w	4			type : string
		dc.l	hours_border		border structure
		dc.l	0			no drawing
		dc.l	hours_text		text
		dc.l	0			no exclude
		dc.l	hours_sinfo
		dc.w	$91			gadget ID
		dc.l	0			user data


editmins_sgadget
		dc.l	edityes_gadget		next gadget
		dc.w	165,45			x,y pos
		dc.w	30,10			width, height
		dc.w	0			flags
		dc.w	$802			integer 
		dc.w	4			type : string
		dc.l	hours_border		border structure
		dc.l	0			no drawing
		dc.l	mins_text		text
		dc.l	0			no exclude
		dc.l	mins_sinfo
		dc.w	$92			gadget ID
		dc.l	0			user data


edityes_gadget	dc.l	editnext_gadget		next gadget
		dc.w	310,43			x,y pos
		dc.w	31,11			width, height (hit box)
		dc.w	$80			flags
		dc.w	$101			flags
		dc.w	1			type : boolean
		dc.l	am_border		image
		dc.l	0			inverse data
		dc.l	yes_text		text
		dc.l	0			no exclude
		dc.l	0			no special info
		dc.w	$93			gadget ID	
		dc.l	0			user data


editnext_gadget	dc.l	editprev_gadget		next gadget
		dc.w	450,41			x,y pos
		dc.w	77,12			width, height (hit box)
		dc.w	0			flags
		dc.w	1			flags
		dc.w	1			type : boolean
		dc.l	gen_border		image
		dc.l	0			inverse data
		dc.l	next_text		text
		dc.l	0			no exclude
		dc.l	0			no special info
		dc.w	$94			gadget ID	
		dc.l	0			user data


editprev_gadget	dc.l	editdel_gadget		next gadget
		dc.w	360,41			x,y pos
		dc.w	77,12			width, height (hit box)
		dc.w	0			flags
		dc.w	1			flags
		dc.w	1			type : boolean
		dc.l	gen_border		image
		dc.l	0			inverse data
		dc.l	prev_text		text
		dc.l	0			no exclude
		dc.l	0			no special info
		dc.w	$95			gadget ID	
		dc.l	0			user data


editdel_gadget	dc.l	editcr_gadget		next gadget
		dc.w	40,65			x,y pos
		dc.w	77,12			width, height (hit box)
		dc.w	0			flags
		dc.w	1			flags
		dc.w	1			type : boolean
		dc.l	gen_border		image
		dc.l	0			inverse data
		dc.l	delete_text		text
		dc.l	0			no exclude
		dc.l	0			no special info
		dc.w	$96			gadget ID	
		dc.l	0			user data


;(* Clear.								 *)
editcr_gadget	dc.l	editch_gadget		next gadget
		dc.w	170,65			x,y pos
		dc.w	77,12			width, height (hit box)
		dc.w	0			flags
		dc.w	1			flags
		dc.w	1			type : boolean
		dc.l	gen_border		image
		dc.l	0			inverse data
		dc.l	cr_text			text
		dc.l	0			no exclude
		dc.l	0			no special info
		dc.w	$97			gadget ID	
		dc.l	0			user data


;(* Change.								 *)
editch_gadget	dc.l	editdone_gadget		next gadget
		dc.w	305,65			x,y pos
		dc.w	77,12			width, height (hit box)
		dc.w	0			flags
		dc.w	1			flags
		dc.w	1			type : boolean
		dc.l	gen_border		image
		dc.l	0			inverse data
		dc.l	change_text		text
		dc.l	0			no exclude
		dc.l	0			no special info
		dc.w	$98			gadget ID	
		dc.l	0			user data


editdone_gadget	
		dc.l	0			next gadget
		dc.w	430,65			x,y pos
		dc.w	77,12			width, height (hit box)
		dc.w	0			flags
		dc.w	1			flags
		dc.w	1			type : boolean
		dc.l	gen_border		image
		dc.l	0			inverse data
		dc.l	done_text		text
		dc.l	0			no exclude
		dc.l	0			no special info
		dc.w	$99			gadget ID	
		dc.l	0			user data


*-------------- GADGET STRUCTURES (INVALID INPUTS) ----------------------*


ok_gadget	dc.l	0			next gadget
		dc.w	68,47			x,y pos
		dc.w	77,12			width, height (hit box)
		dc.w	0			flags
		dc.w	1			flags
		dc.w	1			type : boolean
		dc.l	gen_border		image
		dc.l	0			inverse data
		dc.l	ok_text			text
		dc.l	0			no exclude
		dc.l	0			no special info
		dc.w	$30			gadget ID	
		dc.l	0			user data



*-------------- SPECIALINFO STRUCTURES ----------------------------------*


entry_sinfo	dc.l	entrybuffer		text buffer
		dc.l	entryundo		undo buffer
		dc.w	0			cursor position
		dc.w	60			max # of characters
		dc.w	0			output text from this char
		dc.w	0			char pos in undo buffer
		dc.w	0			# of chars in buffer
		dc.w	0			# of chars visible in box
		dc.w	0			horiz box offset
		dc.w	0			vert box offset
		dc.l	0			rastport
		dc.l	0			value of input (for int)
		dc.l	0			standard keyboard table

entrybuffer	ds.b	72
		even
entryundo	ds.b	72
		even


hours_sinfo	dc.l	hoursbuffer		text buffer
		dc.l	hoursundo		undo buffer
		dc.w	0			cursor position
		dc.w	3			max # of characters
		dc.w	0			output text from this char
		dc.w	0			char pos in undo buffer
		dc.w	0			# of chars in buffer
		dc.w	0			# of chars visible in box
		dc.w	0			horiz box offset
		dc.w	0			vert box offset
		dc.l	0			rastport
		dc.l	0			value of input (for int)
		dc.l	0			standard keyboard table

hoursbuffer	ds.l	3
		even
hoursundo	ds.l	3
		even


mins_sinfo	dc.l	minsbuffer		text buffer
		dc.l	minsundo		undo buffer
		dc.w	0			cursor position
		dc.w	3			max # of characters
		dc.w	0			output text from this char
		dc.w	0			char pos in undo buffer
		dc.w	0			# of chars in buffer
		dc.w	0			# of chars visible in box
		dc.w	0			horiz box offset
		dc.w	0			vert box offset
		dc.l	0			rastport
		dc.l	0			value of input (for int)
		dc.l	0			standard keyboard table

minsbuffer	ds.l	3
		even
minsundo	ds.l	3
		even


date_sinfo	dc.l	datebuffer		text buffer
		dc.l	dateundo		undo buffer
		dc.w	0			cursor position
		dc.w	7			max # of characters
		dc.w	0			output text from this char
		dc.w	0			char pos in undo buffer
		dc.w	0			# of chars in buffer
		dc.w	0			# of chars visible in box
		dc.w	0			horiz box offset
		dc.w	0			vert box offset
		dc.l	0			rastport
		dc.l	0			value of input (for int)
		dc.l	0			standard keyboard table
datebuffer	ds.l	7
		even
dateundo	ds.l	7
		even


file_sinfo	dc.l	filebuffer		text buffer
		dc.l	fileundo		undo buffer
		dc.w	0			cursor position
		dc.w	50			max # of characters
		dc.w	0			output text from this char
		dc.w	0			char pos in undo buffer
		dc.w	0			# of chars in buffer
		dc.w	0			# of chars visible in box
		dc.w	0			horiz box offset
		dc.w	0			vert box offset
		dc.l	0			rastport
		dc.l	0			value of input (for int)
		dc.l	0			standard keyboard table
filebuffer	ds.l	50
		even
fileundo	ds.l	50
		even


scribentry_sinfo
		dc.l	scribentrybuffer	text buffer
		dc.l	scribentryundo		undo buffer
		dc.w	0			cursor position
		dc.w	70			max # of characters
		dc.w	0			output text from this char
		dc.w	0			char pos in undo buffer
		dc.w	0			# of chars in buffer
		dc.w	0			# of chars visible in box
		dc.w	0			horiz box offset
		dc.w	0			vert box offset
		dc.l	0			rastport
		dc.l	0			value of input (for int)
		dc.l	0			standard keyboard table
		even
scribentrybuffer
		ds.b	72
		even
scribentryundo	ds.b	72
		even



scribedit_sinfo
		dc.l	scribeditbuffer		text buffer
		dc.l	scribeditundo		undo buffer
		dc.w	0			cursor position
		dc.w	70			max # of characters
		dc.w	0			output text from this char
		dc.w	0			char pos in undo buffer
		dc.w	0			# of chars in buffer
		dc.w	0			# of chars visible in box
		dc.w	0			horiz box offset
		dc.w	0			vert box offset
		dc.l	0			rastport
		dc.l	0			value of input (for int)
		dc.l	0			standard keyboard table
		even
scribeditbuffer
		ds.b	72
		even
scribeditundo	ds.b	72
		even



editentry_sinfo	dc.l	editentrybuffer		text buffer
		dc.l	editentryundo		undo buffer
		dc.w	0			cursor position
		dc.w	60			max # of characters
		dc.w	0			output text from this char
		dc.w	0			char pos in undo buffer
		dc.w	0			# of chars in buffer
		dc.w	0			# of chars visible in box
		dc.w	0			horiz box offset
		dc.w	0			vert box offset
		dc.l	0			rastport
		dc.l	0			value of input (for int)
		dc.l	0			standard keyboard table
		even
editentrybuffer	ds.b	72
		even
editentryundo	ds.b	72
		even


*-------------- GADGET IMAGE DATA ---------------------------------------*

		section images,code_c


df_data		dc.w	$FFFF,$8000,$8000,$8000,$8E00,$8000
		dc.w	$8FC0,$8000,$8FF0,$8000,$8FC0,$8000
		dc.w	$8E00,$8000,$8000,$8000,$8000,$8000
		dc.w	$FFFF,$8000,$0000,$0000,$0000,$0000
		dc.w	$0000,$0000,$0000,$6000,$0000,$6000
		dc.w	$1000,$6000,$1000,$6000,$1030,$6000
		dc.w	$11C0,$6000,$1E00,$6000,$0000,$6000
		dc.w	$0000,$6000,$3FFF,$E000,$3FFF,$E000
dfi_data	dc.w	$FFFF,$8000,$FFFF,$8000,$F1FF,$8000
		dc.w	$E03F,$8000,$E00F,$8000,$E00F,$8000
		dc.w	$E01F,$8000,$E1FF,$8000,$FFFF,$8000
		dc.w	$FFFF,$8000,$0000,$0000,$0000,$0000
		dc.w	$0000,$0000,$0000,$6000,$0000,$6000
		dc.w	$1000,$6000,$1000,$6000,$1030,$6000
		dc.w	$11E0,$6000,$1E00,$6000,$0000,$6000
		dc.w	$0000,$6000,$3FFF,$E000,$3FFF,$E000


db_data		dc.w	$FFFF,$8000,$8000,$8000,$8038,$8000
		dc.w	$81F8,$8000,$87F8,$8000,$81F8,$8000
		dc.w	$8038,$8000,$8000,$8000,$8000,$8000
		dc.w	$FFFF,$8000,$0000,$0000,$0000,$0000
		dc.w	$0000,$0000,$0000,$6000,$0000,$6000
		dc.w	$0004,$6000,$0004,$6000,$0604,$6000
		dc.w	$01C4,$6000,$003C,$6000,$0000,$6000
		dc.w	$0000,$6000,$3FFF,$E000,$3FFF,$E000
dbi_data	dc.w	$FFFF,$8000,$FFFF,$8000,$FFC7,$8000
		dc.w	$FE03,$8000,$F803,$8000,$F803,$8000
		dc.w	$FE03,$8000,$FFC3,$8000,$FFFF,$8000
		dc.w	$FFFF,$8000,$0000,$0000,$0000,$0000
		dc.w	$0000,$0000,$0000,$6000,$0000,$6000
		dc.w	$0004,$6000,$0004,$6000,$0604,$6000
		dc.w	$01C4,$6000,$003C,$6000,$0000,$6000
		dc.w	$0000,$6000,$3FFF,$E000,$3FFF,$E000


wf_data		dc.w	$FFFF,$FFFE,$0000,$8000,$0002,$0000
		dc.w	$8E00,$3802,$0000,$8FC0,$3F02,$0000
		dc.w	$8FF0,$3FC2,$0000,$8FC0,$3F02,$0000
		dc.w	$8E00,$3802,$0000,$8000,$0002,$0000
		dc.w	$8000,$0002,$0000,$FFFF,$FFFE,$0000
		dc.w	$0000,$0000,$0000,$0000,$0000,$0000
		dc.w	$0000,$0000,$0000,$0000,$0001,$8000
		dc.w	$0000,$0001,$8000,$1000,$4001,$8000
		dc.w	$1000,$4001,$8000,$1030,$40C1,$8000
		dc.w	$11C0,$4701,$8000,$1E00,$7801,$8000
		dc.w	$0000,$0001,$8000,$0000,$0001,$8000
		dc.w	$3FFF,$FFFF,$8000,$3FFF,$FFFF,$8000
wfi_data	dc.w	$FFFF,$FFFE,$0000,$FFFF,$FFFE,$0000
		dc.w	$F1FF,$C7FE,$0000,$E03F,$80FE,$0000
		dc.w	$E00F,$803E,$0000,$E00F,$803E,$0000
		dc.w	$E03F,$80FE,$0000,$E1FF,$87FE,$0000
		dc.w	$FFFF,$FFFE,$0000,$FFFF,$FFFE,$0000
		dc.w	$0000,$0000,$0000,$0000,$0000,$0000
		dc.w	$0000,$0000,$0000,$0000,$0001,$8000
		dc.w	$0000,$0001,$8000,$1000,$4001,$8000
		dc.w	$1000,$4001,$8000,$1030,$40C1,$8000
		dc.w	$11C0,$4701,$8000,$1E00,$7801,$8000
		dc.w	$0000,$0001,$8000,$0000,$0001,$8000
		dc.w	$3FFF,$FFFF,$8000,$3FFF,$FFFF,$8000


wb_data		dc.w	$FFFF,$FFFE,$0000,$8000,$0002,$0000
		dc.w	$8038,$00E2,$0000,$81F8,$07E2,$0000
		dc.w	$87F8,$1FE2,$0000,$81F8,$07E2,$0000
		dc.w	$8038,$00E2,$0000,$8000,$0002,$0000
		dc.w	$8000,$0002,$0000,$FFFF,$FFFE,$0000
		dc.w	$0000,$0000,$0000,$0000,$0000,$0000
		dc.w	$0000,$0000,$0000,$0000,$0001,$8000
		dc.w	$0000,$0001,$8000,$0004,$0011,$8000
		dc.w	$0004,$0011,$8000,$0604,$1811,$8000
		dc.w	$01C4,$0711,$8000,$003C,$00F1,$8000
		dc.w	$0000,$0001,$8000,$0000,$0001,$8000
		dc.w	$3FFF,$FFFF,$8000,$3FFF,$FFFF,$8000
wbi_data	dc.w	$FFFF,$FFFE,$0000,$FFFF,$FFFE,$0000
		dc.w	$FFC7,$FF1E,$0000,$FE03,$F80E,$0000
		dc.w	$F803,$E00E,$0000,$F803,$E00E,$0000
		dc.w	$FE03,$F80E,$0000,$FFC3,$FF0E,$0000
		dc.w	$FFFF,$FFFE,$0000,$FFFF,$FFFE,$0000
		dc.w	$0000,$0000,$0000,$0000,$0000,$0000
		dc.w	$0000,$0000,$0000,$0000,$0001,$8000
		dc.w	$0000,$0001,$8000,$0004,$0011,$8000
		dc.w	$0004,$0011,$8000,$0604,$1811,$8000
		dc.w	$01C4,$0711,$8000,$003C,$00F1,$8000
		dc.w	$0000,$0001,$8000,$0000,$0001,$8000
		dc.w	$3FFF,$FFFF,$8000,$3FFF,$FFFF,$8000

timeyes_data
	DC.W	$0000,$0000,$0000,$0000,$0C30,$0000
	DC.W	$0C30,$0000,$0663,$C3E0,$03C6,$6600
	DC.W	$0187,$E3C0,$0186,$0060,$03C3,$C7C0
	DC.W	$0000,$0000,$0000,$0000,$0000,$0000
	DC.W	$FFFF,$FFFE,$8000,$0002,$8000,$0002
	DC.W	$8000,$0002,$8000,$0002,$8000,$0002
	DC.W	$8000,$0002,$8000,$0002,$8000,$0002
	DC.W	$8000,$0002,$8000,$0002,$FFFF,$FFFE

	
timeyesi_data
	DC.W	$FFFF,$FFFE,$FFFF,$FFFC,$F3CF,$FFFC
	DC.W	$F3CF,$FFFC,$F99C,$3C1C,$FC39,$99FC
	DC.W	$FE78,$1C3C,$FE79,$FF9C,$FC3C,$383C
	DC.W	$FFFF,$FFFC,$FFFF,$FFFC,$0000,$0000
	DC.W	$0000,$0000,$7FFF,$FFFE,$7FFF,$FFFE
	DC.W	$7FFF,$FFFE,$7FFF,$FFFE,$7FFF,$FFFE
	DC.W	$7FFF,$FFFE,$7FFF,$FFFE,$7FFF,$FFFE
	DC.W	$7FFF,$FFFE,$7FFF,$FFFE,$FFFF,$FFFE
	

stop_data	dc.w	$01FF,$FE00,$07FF,$FF80,$1FFF,$FFE0
		dc.w	$7FFF,$FFF8,$FFFF,$FFFC,$F082,$083C
		dc.w	$F7EE,$EBBC,$F0EE,$E83C,$FEEE,$EBFC
		dc.w	$F0EE,$0BFC,$FFFF,$FFFC,$7FFF,$FFF8
		dc.w	$1FFF,$FFE0,$07FF,$FF80,$01FF,$FE00
		dc.w	$01FF,$FE00,$0600,$0180,$1800,$0060
		dc.w	$6000,$0018,$8000,$0004,$BFFF,$FFF4
		dc.w	$BFFF,$FFF4,$BFFF,$FFF4,$BFFF,$FFF4
		dc.w	$BFFF,$FFF4,$8000,$0004,$6000,$0018
		dc.w	$1800,$0060,$0600,$0180,$01FF,$FE00


*-------------- LIBRARIES -----------------------------------------------*
				
intname		dc.b	"intuition.library",0
		even
intbase		dc.l	0


gfxname		dc.b	"graphics.library",0
		even
gfxbase		dc.l	0


dosname		dc.b	"dos.library",0
		even
dosbase		dc.l	0


*-------------- FONTS ---------------------------------------------------*


;(* Normal 80 col topaz font						 *)
topaz_defs	dc.l	topazname
		dc.w	8			size 8
		dc.b	0			style : normal
		dc.b	1			flags : ROM font

;(* Underlined 80 col topaz font					 *) 
topazU_defs	dc.l	topazname
		dc.w	8			size 8
		dc.b	1			style : underline
		dc.b	1			flags : ROM font


topazname	dc.b	"topaz.font",0
		even
topazbase	dc.l	0
topazUbase	dc.l	0


*--------------	INDEPENDANT VARIABLES -----------------------------------*

message		dc.l	0		result of getmsg call
currentwindow	dc.l	0		window being considered

calendar	dc.l	0		pointer to calendar list
scribble	dc.l	0		pointer to scribblepad list
scrib_curentry	dc.l	0		pointer to scribble entry at start
;					of page to be displayed
scrib_nextentry	dc.l	0		pointer to first entry at start
;					of page after the one being displayed
year		dc.w	0		address of newly reserved year

lines_used	dc.w	0		number of lines occupied by a
;					scribblepad entry
entry_lines	dc.w	0		number of lines occupied by a 
;					diary entry

spare_text	ds.b	20

decnumber	ds.b	4
		even
decstring	dc.b	"     ",0
		even

date		dc.l	0			} Today's date
		dc.l	0			} yyyy-mm-dd
		dc.l	0			}
		dc.l	0			} 0=Sunday etc
datecopy	dc.l	0			Buffer used to hold
		dc.l	0			date until it has been
		dc.l	0			validated.
		dc.l	0
months		dc.w	31,28,31,30,31,30	Jan-Jun
		dc.w	31,31,30,31,30,31	Jul-Dec
monthnames	dc.b	"Jan","Feb","Mar","Apr","May","Jun"
		dc.b	"Jul","Aug","Sep","Oct","Nov","Dec"
daynames	dc.b	", Sun ",", Mon ",", Tue "
		dc.b	", Wed ",", Thur",", Fri "
		dc.b	", Sat "
years		dc.w	365,365,366,365		1978,1979,1980,1981...

dateXpos	dc.w	0		positions used by DisplayDate
dateYpos	dc.w	0
displayhd	dc.l	0		window to display text in

lineXpos	dc.w	0		position for line of entry
lineYpos	dc.w	0		being displayed
rightmargin	dc.l	0		set according to left/right side of page
leftmargin	dc.l	0		as above

scribXpos	dc.w	0		position for line of entry (scribblepad)
scribYpos	dc.w	0		being displayed

scribmarker	dc.l	0		store for next scribblepad identifier

digits		dc.w	0		number of digits in number


monthsbase	dc.l	0		base address of months (dfs)
monthsoff	dc.l	0		offset for month pointer (dfs)

monthstore	dc.l	0		month being considered 
yearstore	dc.l	0		year being considered 
daystore	dc.l	0		day being considered 
entrystore	dc.l	0		entry being considered 
store		dc.l	0		general store

currententry	dc.l	0		address of entry being edited
start_entry	dc.l	0		first entry on the page
next_entry	dc.l	0		first entry on next page
page_start	dc.l	0		first entry on page being displayed

scribentry	dc.l	0		address of scribblepad entry
;					being edited

;(* EXTERNAL FILE ...							 *)
	
filestart_code	dc.w	$0100		only upper byte is used, but
filestop_code	dc.w	$0200		these codes are words so they
year_code	dc.w	$0300		will be on even addresses
month_code	dc.w	$0400		
day_code	dc.w	$0500		
entry_code	dc.w	$0600		
text_code	dc.w	$0700
scribent_code	dc.w	$0800


;(* The default AmigaDiary entries file, loaded up on startup.		 *)
default_file	dc.b	"s:diary.def",0
		even

header		dc.b	"AD","11",$01	;AmigaDiary, version (x10), start
		even

filehd		dc.l	0		

buffer		dc.w	0


;(* FLAGS ...								 *)
flag1		dc.b	0		;0 - Leap Year
					;1 - Close gadget (main window)
					;2 - Time yes/no (AE gadgets)
					;3 - Line break has been displayed
					;4 - Use inputs from edit window
					;5 - Only one entry for that day
					;6 - Entry being deleted is first 
					;7 - Full SP page
					
			
flag2		dc.b	0		;0 - Scribblepad window open
					;1 - Add Entry window open
					;2 - Shrink window open
					;3 - About window open
					;4 - Invalid Inputs window open
					;5 - Lookup Entry window open
					;6 - Load File window open
					;7 - Save File window open


flag3		dc.b	0		;0 - Scribblepad Add Entry window
					;1 - Edit Entry window open


flag4		dc.b	0		;0 - Scrib Entry split at bottom
