AbsExecBase	EQU $00000004
CustomChips	EQU $00dff000

	include "exec/alerts.i"
	include "exec/execbase.i"
	include "exec/resident.i"
	include "graphics/gfxbase.i"
	include "intuition/screens.i"
	include "devices/input.i"
	include "dos/dosextens.i"
	include "hardware/custom.i"
	include "hardware/dmabits.i"

	include "exec/funcdef.i"
	include "exec/exec_lib.i"

_LVOCloseScreen		EQU -66
_LVOCloseWorkBench	EQU -78
_LVODisplayBeep		EQU -96
_LVOOpenScreen		EQU -198
_LVOPrintIText		EQU -216

_LVOLoadRGB4		EQU -192
_LVOWaitTOF		EQU -270
_LVOGetRGB4		EQU -582

BufferSize		EQU 40
BLANK_TIMEOUT		EQU 100

	XDEF _PasswordCode
	XDEF _PasswordCodeEnd

*************************************************

_PasswordCode:
	movem.l a2-a5/d2,-(SP)

	lea _PasswordCode(PC),a0

	lea ResidentName(PC),a1
	move.l a1,-RT_SIZE+RT_NAME(a0)
	lea ResidentID(PC),a1
	move.l a1,-RT_SIZE+RT_IDSTRING(a0)

	move.l a0,d0
	add.l d0,Topaz8Attr+ta_Name-_PasswordCode(a0)
	add.l d0,MyNewScreen+ns_Font-_PasswordCode(a0)
	add.l d0,MyIntuiText+it_IText-_PasswordCode(a0)

	move.l AbsExecBase.w,a6
	move.l ThisTask(a6),a4
	lea MyTask(PC),a0
	move.l a4,(a0)

	lea InputName(PC),a0
	moveq #0,d0
	lea InputRequest(PC),a1
	move.l a1,a2			; a2 -> IORequest
	lea MyMsgPort+MP_MSGLIST(PC),a3
	NEWLIST a3
	lea MyMsgPort(PC),a3
	move.l a4,MP_SIGTASK(a3)
	move.b #SIGB_DOS,MP_SIGBIT(a3)
	move.l a3,MN_REPLYPORT(a1)
	moveq #0,d1
	jsr _LVOOpenDevice(a6)

	lea Interrupt(PC),a0
	move.l a0,IO_DATA(a2)
	move.w #IND_ADDHANDLER,IO_COMMAND(a2)
	lea InputHandler(PC),a1
	move.l a1,IS_CODE(a0)
	move.b #127,LN_PRI(a0)
	move.l a2,a1
	jsr _LVODoIO(a6)

	lea GfxName(PC),a1
	moveq #0,d0
	jsr _LVOOpenLibrary(a6)
	move.l d0,a4			; a4 -> GfxBase
	lea MyGfxBase(PC),a0
	move.l a4,(a0)
	lea MyNewScreen(PC),a0
	move.w gb_NormalDisplayRows(a4),d0
	sub.w #18,d0
	lsr.w #1,d0
	move.w d0,ns_TopEdge(a0)
	move.w gb_NormalDisplayColumns(a4),ns_Width(a0)

	lea IntuitionName(PC),a1
	moveq #0,d0
	jsr _LVOOpenLibrary(a6)
	move.l d0,a6

	lea MyNewScreen(PC),a0
	jsr _LVOOpenScreen(a6)
	move.l d0,a5			; a5 -> Screen
	lea MyScreen(PC),a0
	move.l a5,(a0)

	move.w #DMAF_SPRITE,CustomChips+dmacon
	move.w #0,CustomChips+spr+sd_dataa
	move.w #0,CustomChips+spr+sd_dataB

	move.l a6,a3
	move.l a4,a6
	lea sc_ViewPort(a5),a0
	move.l vp_ColorMap(a0),a0
	move.l a0,d2
	moveq #0,d0
	jsr _LVOGetRGB4(a6)
	lea StdColorTable(PC),a0
	move.w d0,(a0)
	moveq #1,d0
	move.l d2,a0
	jsr _LVOGetRGB4(a6)
	lea StdColorTable+2(PC),a0
	move.w d0,(a0)
	move.l a3,a6

	lea sc_RastPort(a5),a0
	lea MyIntuiText(PC),a1
	move.w MyNewScreen+ns_Width(PC),d0
	sub.w #23*8,d0
	lsr.w #1,d0
	moveq #0,d1
	jsr _LVOPrintIText(a6)
	bra.s AskPassword1

AskPassword:
	move.l a5,a0
	jsr _LVODisplayBeep(a6)

AskPassword1:
	lea BufferIndex(PC),a0
	clr.w (a0)
	lea MyIntuiText(PC),a1
	lea TryText(PC),a0
	move.l a0,it_IText(a1)
	move.b Tries(PC),d0
	add.b #'0',d0
	move.b d0,(a0)
	moveq #10,d1
	moveq #0,d0
	lea sc_RastPort(a5),a0
	jsr _LVOPrintIText(a6)

	move.l a6,a3
	move.l AbsExecBase.w,a6
	move.l #SIGBREAKF_CTRL_C,d0
	jsr _LVOWait(a6)
	move.l a3,a6

	lea Buffer(PC),a0
	lea Password(PC),a1
CheckPassword:
	move.b (a0),d0
	cmp.b (a1)+,d0
	bne.s WrongPassword
	cmp.b #$fe,(a0)+
	bne.s CheckPassword
	beq.s CorrectPassword

WrongPassword:
	lea Tries(PC),a0
	addq.b #1,(a0)
	cmp.b #4,(a0)
	blt.s AskPassword

	lea sc_RastPort(a5),a0
	lea MyIntuiText(PC),a1
	lea WrongText(PC),a2
	move.l a2,it_IText(a1)
	moveq #0,d0
	moveq #10,d1
	jsr _LVOPrintIText(a6)

	move.l a4,a6
WrongPasswordLoop:
	lea Red1ColorTable(PC),a1
	bsr.s SwitchColor
	lea Red2ColorTable(PC),a1
	bsr.s SwitchColor
	bra.s WrongPasswordLoop

CorrectPassword
	move.l a5,a0
	jsr _LVOCloseScreen(a6)

	jsr _LVOCloseWorkBench(a6)

	move.l a6,a1
	move.l AbsExecBase.w,a6
	jsr _LVOCloseLibrary(a6)

	move.l a4,a1
	jsr _LVOCloseLibrary(a6)

	move.w #IND_REMHANDLER,IO_COMMAND(a2)
	lea Interrupt(PC),a0
	move.l a0,IO_DATA(a2)
	move.l a2,a1
	jsr _LVODoIO(a6)

	move.l a2,a1
	jsr _LVOCloseDevice(a6)

	lea TermKey(PC),a0
	cmp.b #$44,(a0)
	beq.s AllDone

; Insert code to be executed when F1 is used instead of RETURN
	nop

AllDone:
	moveq #0,d0
	movem.l (SP)+,a2-a5/d2
	rts

SwitchColor:
	lea sc_ViewPort(a5),a0
	moveq #2,d0
	jsr _LVOLoadRGB4(a6)
	moveq #10,d2
SwitchColorLoop:
	jsr _LVOWaitTOF(a6)
	jsr _LVOWaitTOF(a6)
	jsr _LVOWaitTOF(a6)
	jsr _LVOWaitTOF(a6)
	jsr _LVOWaitTOF(a6)
	dbf d2,SwitchColorLoop
	lea BlankTimer(PC),a1
	move.w #BLANK_TIMEOUT,(a1)
	rts

*************************************************

InputHandler:
	movem.l a0/a2-a6/d2-d7,-(SP)

EventLoop:
	cmp.b #IECLASS_RAWKEY,ie_Class(a0)
	bne NotRAWKEY
	bsr UnblankScreen
	move.b ie_Code+1(a0),d0
	bmi.s NextEvent
	cmp.b #$44,d0
	beq.s PasswordDone
	cmp.b #$50,d0
	beq.s PasswordDone
	cmp.b #$60,d0
	bge.s NextEvent
	cmp.b #$41,d0
	beq.s Backspace
	move.w ie_Qualifier(a0),d1
	and.w #IEQUALIFIER_LSHIFT!IEQUALIFIER_RSHIFT,d1
	beq.s StoreCode
	or.w #$80,d0
StoreCode:
	lea BufferIndex(PC),a2
	move.w (a2),d1
	cmp.w #BufferSize-2,d1
	beq.s NextEvent
	lea Buffer(PC),a1
	move.b d0,(a1,d1.w)
	addq.w #1,(a2)

NextEvent:
	cmp.b #IECLASS_TIMER,ie_Class(a0)
	beq.s IsTimer
	clr.b ie_Class(a0)
IsTimer:
	move.l ie_NextEvent(a0),a0
	move.l a0,d0
	bne.s EventLoop

EventLoopDone:
	movem.l (SP)+,a0/a2-a6/d2-d7
	move.l a0,d0
	rts

Backspace:
	lea BufferIndex(PC),a1
	tst.w (a1)
	beq.s NextEvent
	subq.w #1,(a1)
	bra.s NextEvent

PasswordDone:
	lea BufferIndex(PC),a2
	move.w (a2),d1
	lea Buffer(PC),a1
	move.b #$fe,(a1,d1.w)

	lea TermKey(PC),a1
	move.b d0,(a1)
	move.l AbsExecBase.w,a6
	move.l #SIGBREAKF_CTRL_C,d0
	move.l MyTask(PC),a1
	jsr _LVOSignal(a6)
	bra.s EventLoopDone

NotRAWKEY:
	cmp.b #IECLASS_RAWMOUSE,ie_Class(a0)
	bne.s NotRAWMOUSE
	bsr.s UnblankScreen
	bra.s NextEvent

NotRAWMOUSE:
	cmp.b #IECLASS_TIMER,ie_Class(a0)
	bne.s NextEvent
	lea ScreenBlanked(PC),a2
	tst.b (a2)
	bne.s NextEvent
	lea BlankTimer(PC),a1
	subq.w #1,(a1)
	bne.s NextEvent
	addq.b #1,(a2)
	move.l a0,a2
	move.l MyGfxBase(PC),a6
	move.l MyScreen(PC),a0
	lea sc_ViewPort(a0),a0
	lea BlankColorTable(PC),a1
	moveq #2,d0
	jsr _LVOLoadRGB4(a6)
	move.l a2,a0
	bra NextEvent

UnblankScreen:
	lea ScreenBlanked(PC),a1
	tst.b (a1)
	beq.s NotBlanked
	clr.b (a1)
	move.l a0,a2
	move.l MyGfxBase(PC),a6
	move.l MyScreen(PC),a0
	lea sc_ViewPort(a0),a0
	lea StdColorTable(PC),a1
	moveq #2,d0
	jsr _LVOLoadRGB4(a6)
	move.l a2,a0
NotBlanked:
	lea BlankTimer(PC),a1
	move.w #BLANK_TIMEOUT,(a1)
	rts

*************************************************

MyTask		dc.l 0
MyScreen	dc.l 0
MyGfxBase	dc.l 0

Topaz8Attr	dc.l TopazName-_PasswordCode
		dc.w 8
		dc.b 0,0

MyNewScreen	dc.w 0,0
		dc.w 0,18
		dc.w 1
		dc.b 0,1
		dc.w V_HIRES
		dc.w CUSTOMSCREEN!SCREENQUIET
		dc.l Topaz8Attr-_PasswordCode
		dc.l 0
		dc.l 0
		dc.l 0

MyIntuiText	dc.b 1,0
		dc.b RP_JAM2
		dc.b 0
		dc.w 0,0
		dc.l 0
		dc.l HeaderText-_PasswordCode
		dc.l 0

BufferIndex:	dc.w 0

BlankTimer:	dc.w BLANK_TIMEOUT

StdColorTable	dc.w 0,0
BlankColorTable	dc.w $0000,$0000
Red1ColorTable	dc.w $0f00,$0000
Red2ColorTable	dc.w $0000,$0f00

InputRequest	dcb.b IOSTD_SIZE,0
Interrupt	dcb.b IS_SIZE,0
MyMsgPort	dcb.b MP_SIZE,0

Tries		dc.b 1
ScreenBlanked	dc.b 0
TermKey		dc.b 0
InputName	dc.b "input.device",0
IntuitionName	dc.b "intuition.library",0
GfxName		dc.b "graphics.library",0
TopazName	dc.b "topaz.font",0
	IFD DEUTSCH
HeaderText	dc.b "Bitte Passwort eingeben",0
TryText		dc.b "1. Versuch",0
		IFD DEUTSCH1
WrongText	dc.b "Falsches Passwort! Hacker! Spion! Mörder! Tyrann!",0
		ELSE
WrongText	dc.b "Falsches Passwort!",0
		ENDC
	ELSE
HeaderText	dc.b "Please enter password",0
TryText		dc.b "1. Try",0
WrongText	dc.b "Wrong password!",0
	ENDC

ResidentName	dc.b "Password",0
ResidentID	dc.b "Password © 23-Feb-93 Christian Stieber",0

Buffer:		dcb.b BufferSize,0

Version:	dc.b "$VER: Password 1.1 (26.04.93)",0

Password	dcb.b BufferSize,$fe

*************************************************

_PasswordCodeEnd:

		END
