;	.          _               .   _    _
;	|   _  _  / \|  _  _ |    /|  / \  / \
;	|  |_)/ \(   | / \| `|/    | ( / )( / )
;	|__|_,\_/ \_/|_\_/|_,|\    |o \_/  \_/
;
;	1993-04-27
;
;
;	Here it is, the complete OS 2.0 clock that fits in one (1) FFS
;	disk block; less than 512 bytes, that is.
;
;	If you get this any smaller, or just want to write something
;	to me, please mail me to the following addresses:
;
;	Henrik Herranen
;	Atomikatu 6 A 9
;	SF-33720 Tampere
;	Finland
;
;	e-mail: leopold@cc.tut.fi
;


	include "AInclude:Include.i"
;	include "AInclude:Macros.i"

IDCMP_CLOSEWINDOW	equ	$200
WFLG_CLOSEGADGET	equ	$8
WFLG_DEPTHGADGET	equ	$4
WFLG_DRAGBAR		equ	$2

WIDEST		equr	d4
ASC0		equr	d3
CURRWIDTH	equr	d2
WIN		equr	a3

INTUITIONBASE	equr	d5
EXECBASE	equr	d6
GRAPHICSBASE	equr	a4
MYTASK		equr	d7

				; The registers A2 and A5 are left free

main:
;	OpenLib dos

	moveq.l	#'0',ASC0
	moveq.l	#60-60,WIDEST

	move.l	$4.w,EXECBASE		; My version of A68k doesn't like the
					; .w extension. Take it away if it
					; disturbs your compiler.

	move.l	EXECBASE,a6

	sub.l	a1,a1			; MyTask = FindTask(0);
	jsr	_LVOFindTask(a6);
	move.l	d0,MYTASK

	move.l	MYTASK,a1		; InheritedPri = SetTaskPri(MyTask, 4);
	moveq.l	#4,d0
	jsr	_LVOSetTaskPri(a6)
	move.w	d0,-(sp)		; Store InheritedPri to stack

	lea	IntuitionName(pc),a1	; IntuitionBase = OpenLib("intuition.library",0);
	moveq.l	#0,d0
	lea	_LVOOpenLibrary(a6),a5
	jsr	(a5)
	move.l	d0,INTUITIONBASE

	lea	DosName(pc),a1		; DosBase = OpenLib("dos.library",0);
	moveq.l	#0,d0
	jsr	(a5)
	move.l	d0,-(sp)

	lea	GraphicsName(pc),a1	; GraphicsBase = OpenLib("graphics.library",0);
	moveq.l	#0,d0
	jsr	(a5)
	move.l	d0,GRAPHICSBASE

	move.l	INTUITIONBASE,a6	; Win = OpenWindow(&NewWin);
	lea	NewWin(pc),a0
	jsr	_LVOOpenWindow(a6)
	move.l	d0,WIN			; if (!Win) exit(0);
	beq	FailedOpeningWindow

MainLoop:
	move.l	(sp),a6			; DateStamp(&MyDate); (DosBase is on the top of stack)
	lea	MyDate(pc),a0
	move.l	a0,d1
	jsr	_LVODateStamp(a6)

	lea	LastMinute(pc),a5	; if (MyDate_Minute != LastMinute) {
	move.w	(a5),a0
	cmp.w	MyDate_Minute+2(pc),a0
	beq.s	MinuteNotChanged

	move.l	INTUITIONBASE,a6	; WindowToFront(Win);
	move.l	WIN,a0
	jsr	_LVOWindowToFront(a6)

	move.w	MyDate_Minute+2(pc),(a5); LastMinute = MyDate_Minute;
		
MinuteNotChanged:
	move.l	wd_WScreen(WIN),a5	; a5 = Win -> WScreen

	lea	TimeStr(pc),a1		; TimeStr[0] = MyDate_Minute / 600 + '0';
	move.l	MyDate_Minute(pc),d0
	divu.w	#600,d0
	bsr.s	setnum

;	swap	d0			; MyDate_Minute %= 600;
;	ext.l	d0

	divu.w	#60,d0			; TimeStr[1] = MyDate_Minute / 60 + '0';
	bsr.s	setnum

;	swap	d0			; MyDate_Minute %= 60;
;	ext.l	d0

	addq.l	#1,a1

	divu.w	#10,d0			; TimeStr[3] = MyDate_Minute / 10 + '0';
	bsr.s	setnum

;	swap	d0			; MyDate_Minute %= 10;

	bsr.s	setnum			; TimeStr[4] = MyDate_Minute + '0';

	addq.l	#1,a1

	move.l	MyDate_Tick(pc),d0	; TimeStr[6] = MyDate_Tick / 50 / 10 + '0';
	divu.w	#50,d0
	move.l	d0,-(sp)		; Store whole 32-bit division result for later use
	ext.l	d0
	divu.w	#10,d0
	bsr.s	setnum

;	swap	d0			; MyDate_Minute  %= 10;

	bsr.s	setnum			; TimeStr[7] = MyDate_Tick + '0';

	bra.s	aftersetnum
setnum:
	move.b	d0,(a1)
	add.b	ASC0,(a1)+
	swap	d0			; These was the most common commands after calling setnum!
	ext.l	d0			;   The code is not always needed, but doesn't do any harm either,
					;   and again another 8 bytes was saved!
	rts
	
aftersetnum:
	move.l	INTUITIONBASE,a6	; SetWindowTitles(Win, &TimeStr[0 (or 1)], (UBYTE *) ~0L);
	move.l	WIN,a0
;	lea	TimeStr(pc),a1
	subq.l	#8,a1
	moveq.l	#-1,d0
	move.l	d0,a2
	cmp.b	#'0',(a1)
	bne.s	11$
	addq.l	#1,a1
11$:	jsr	_LVOSetWindowTitles(a6)

	lea	sc_RastPort(a5),a1	; CurrWidth = TextLength(Win->WScreen.RastPort, TimeStr[0/1], 8/7);
	lea	TimeStr(pc),a0
	moveq.l	#8,d0

	cmp.b	#'0',(a0)		; if (TimeStr[0] == '0')
	bne.s	1$

	addq.l	#1,a0			; { TimeStr++;
	subq.l	#1,d0			;   count-- }; Actually not needed, since next char is always 0, width = 0
1$:
	move.l	GRAPHICSBASE,a6
	jsr	_LVOTextLength(a6)
	move.w	d0,CURRWIDTH

	cmp.w	WIDEST,CURRWIDTH	; if (CurrWidth > Widest) {
	bmi.s	EndUpdate
	beq.s	EndUpdate

;	Display "SizeChange:",byte,#00

	move.l	INTUITIONBASE,a6	; MoveWindow(Win, ##, 0);
	move.l	WIN,a0
	moveq.l	#-60-24,d0
	add.w	sc_Width(a5),d0
	sub.w	CURRWIDTH,d0
	move.w	d0,-(sp)
	lea	WantedLoc(pc),a2
	sub.w	(a2),d0
	move.w	(sp)+,(a2)
	moveq.l	#0,d1
	jsr	_LVOMoveWindow(a6)
	
	move.l	WIN,a0			; SizeWindow(Win, ##, ##);
	move.w	CURRWIDTH,d0
	sub.w	WIDEST,d0
	moveq.l	#1,d1
	add.b	sc_BarHeight(a5),d1	; a5 still contains the Win->WScreen ptr
	lea	NewWin+6(pc),a5		; Address of CurrWinHeight to a5
	sub.w	(a5),d1
	add.w	d1,(a5)
	jsr	_LVOSizeWindow(a6)

	move.w	CURRWIDTH,WIDEST
	
EndUpdate:				; } /* end if(CurrWidth > Widest) */
	moveq.l	#50,d1
	sub.w	(sp)+,d1		; Get former tick / 50 division % from upper word of last stack item
	move.w	(sp)+,d0		; Clear lower word of last stack item
	move.l	(sp),a6			; DosBase is stored in the stack
	jsr	_LVODelay(a6)

	move.l	EXECBASE,a6		; if (!GetMsg(Win -> UserPort)) goto MainLoop
	move.l	WIN,a0
	move.l	wd_UserPort(a0),a0
	jsr	_LVOGetMsg(a6)
	tst.l	d0
	beq	MainLoop

	move.l	d0,a1			; ReplyMsg(WinIDCMP);
	jsr	_LVOReplyMsg(a6)

	move.l	INTUITIONBASE,a6	; CloseWindow(Win);
	move.l	WIN,a0
	jsr	_LVOCloseWindow(a6)

FailedOpeningWindow:
	move.l	EXECBASE,a6

	lea	_LVOCloseLibrary(a6),a5	; CloseLib(GraphicsBase);
	move.l	GRAPHICSBASE,a1
	jsr	(a5)

	move.l	(sp)+,a1		; CloseLib(DosBase); (+ restore DosBase from stack)
	jsr	(a5)

	move.l	INTUITIONBASE,a1	; CloseLib(IntuitionBase);
	jsr	(a5)

	move.l	MYTASK,a1		; SetTaskPri(MyTask, InheritedPri);
	move.w	(sp)+,d0		; Restore InheritedPri from stack
	jsr	_LVOSetTaskPri(a6)


;	CloseLib dos

	moveq.l #0,d0
	rts



IntuitionName:
	dc.b "intuition.library",0
DosName:
	dc.b "dos.library",0
GraphicsName:
	dc.b "graphics.library"
NewWin:
        dc.w    0,0,60,20		; Left, Top, Width, Height
        dc.b    1,2			; DetailPen, BlockPen
        dc.l    IDCMP_CLOSEWINDOW	; IDCMP flags
LastMinute:
	dc.l	WFLG_CLOSEGADGET|WFLG_DEPTHGADGET|WFLG_DRAGBAR	; Flags
MyDate:
MyDate_Days:
	dc.l	0			; *FirstGadget
MyDate_Minute:
	dc.l	0			; *CheckMark
MyDate_Tick:
        dc.l    0			; *WindowTitle
TimeStr:
        dc.b    "01:11:11"		; *Screen, *BitMap
        dc.w    0			; WinWidth
        dc.w    0			; MinHeight
WantedLoc:
        dc.w    0			; MaxWidth
	dc.w	0			; MaxHeight
        dc.w    WBENCHSCREEN		; Type of mother screen (Was: WBENCHSCREEN)

	END
