main:		bra	main1

civer:		dc.b	'NGC Ver: 00162  02-Aug-89 05:33:18',$0a
		dc.b	'Copyright (C) 1989, Ulf Nordquist.',$0a,0
civerend:

;	Nordquist Generic Checker
;	complete program

;	This source code is released into the public domain for
;	non-profit use only.
;	Copyright (C) 1989, Ulf Nordquist. All Rights Reserved !
;	Ulf Nordquist
;	Brunnehagen 36
;	417 47 Gothenburg
;	Sweden

;	History
;	890725 : first (open & closedev from me)
;		 read block 0 & 1
;		 check against a normal bootblock
;	890726 : check all attached floppy drives
;		 handle drive with no disk
;		 report only disks of boot type
;	890727 : check disks as they are inserted
;		 open control window when error is found
;		 save boot blocks as ordinary file
;	890728 : write standard boot blocks on disk
;		 chkcnt & instcnt & vircnt
;	890729 : menu button opens control window
;		   special gadgets only then
;		     force check of boot blocks
;		     change current drive +/-
;	890731 : compare with saved bootblocks
;		 run from workbench
;	890801 : check resident library jump table
;	890802 : check resident device jump table

;	amiga system routine offsets

_LVOActivateGadget equ	-462
_LVOAddPort	equ	-354
_LVOAllocMem	equ	-198
_LVOAllocSignal equ	-330
_LVOAutoRequest equ	-348
_LVOClose	equ	-36
_LVOCloseDevice equ	-450
_LVOCloseLibrary equ	-414
_LVOCloseWindow equ	-72
_LVOCurrentDir	equ	-126
_LVODisplayBeep equ	-96
_LVODoIO	equ	-456
_LVODrawBorder	equ	-108
_LVOExamine	equ	-102
_LVOExNext	equ	-108
_LVOFindName	equ	-276
_LVOFindResident equ	-96
_LVOFindTask	equ	-294
_LVOForbid	equ	-132
_LVOFreeMem	equ	-210
_LVOFreeSignal	equ	-336
_LVOGetMsg	equ	-372
_LVOLock	equ	-84
_LVOModifyIDCMP equ	-150
_LVOOpen	equ	-30
_LVOOpenDevice	equ	-444
_LVOOpenLibrary equ	-552
_LVOOpenWindow	equ	-204
_LVOOutput	equ	-60
_LVOPrintIText	equ	-216
_LVORead	equ	-42
_LVORemPort	equ	-360
_LVOReplyMsg	equ	-378
_LVOUnLock	equ	-90
_LVOWait	equ	-318
_LVOWaitPort	equ	-384
_LVOWrite	equ	-48

;	amiga sytem structs offsets and sizes

DeviceList	equ	350	;struct, LH
IOSTD_SIZE	equ	48	;total IOStdReq size
IO_ACTUAL	equ	32	;long, actual bytes
IO_COMMAND	equ	28	;word, device command
IO_DATA 	equ	40	;ptr, data
IO_LENGTH	equ	36	;long, req bytes
IO_OFFSET	equ	44	;long, for seek devs
LIB_NEGSIZE	equ	16	;word, bytes before lib
LIB_POSSIZE	equ	18	;word, bytes after lib
LIB_SIZE	equ	34	;total size
LibList 	equ	378	;struct, LH
LN_NAME 	equ	10	;ptr
LN_TYPE 	equ	8	;byte
MN_LENGTH	equ	18	;word, size of nxt block
MN_REPLYPORT	equ	14	;ptr
MN_SIZE 	equ	20	;total message size
MP_FLAGS	equ	14	;byte
MP_SIGBIT	equ	15	;byte
MP_SIGTASK	equ	16	;ptr
MP_SIZE 	equ	34	;total MsgPort size
NT_MSGPORT	equ	4
RT_INIT 	equ	22	;ptr,  to init code
fib_SIZEOF	equ	260	;total FileInfoBlock size
fib_DirEntryType equ	4	;long
fib_FileName	equ	8	;108 bytes, null term string
fib_Size	equ	124	;long
gg_GadgetID	equ	38	;word
im_IAddress	equ	28	;ptr
im_Class	equ	20	;long
im_Code 	equ	24	;word
nw_LeftEdge	equ	0	;word, initial Window dim
nw_TopEdge	equ	2	;word, initial Window dim
pr_CLI		equ	172	;bptr, to ConsoleLineInterpreter
pr_MsgPort	equ	92	;struct, this is BPTR addr from DOS
wd_LeftEdge	equ	4	;word
wd_RPort	equ	50	;ptr
wd_TopEdge	equ	6	;word
wd_UserPort	equ	86	;ptr

;	amiga system constants

ACCESS_READ	equ	-2
ACTIVATE	equ	$1000		;when Window opens, it's the Active one
BOOLGADGET	equ	$0001
CLOSEWINDOW	equ	$00000200
CMD_NONSTD	equ	9		;first individual cmd
CMD_READ	equ	2		;standard read
CMD_UPDATE	equ	4		;write all buffers
CMD_WRITE	equ	3		;standard write
DISKINSERTED	equ	$00008000
FALSE		equ	0
GADGDISABLED	equ	$0100
GADGETUP	equ	$00000040
GADGHCOMP	equ	$0000
MEMF_ANY	equ	$0
MEMF_CHIP	equ	$2
MEMF_CLEAR	equ	$10000
MEMF_PUBLIC	equ	$1
MENUDOWN	equ	$69		;empirically deduced
MODE_NEWFILE	equ	1006
MODE_OLDFILE	equ	1005
MOUSEBUTTONS	equ	$00000008
NOCAREREFRESH	equ	$00020000	; not to be bothered with REFRESH
NUMSECS 	equ	11
PA_SIGNAL	equ	0
RELVERIFY	equ	$0001
RMBTRAP 	equ	$00010000	;Catch RMB events for your own
RP_JAM2 	equ	1
SELECTED	equ	$0080
STRGADGET	equ	$0004
TD_CHANGENUM	equ	CMD_NONSTD+4
TD_CHANGESTATE	equ	CMD_NONSTD+5
TD_MOTOR	equ	CMD_NONSTD+0
TD_PROTSTATUS	equ	CMD_NONSTD+6
TD_SECTOR	equ	512
TRUE		equ	~FALSE
WBENCHSCREEN	equ	$0001
WINDOWCLOSE	equ	$0008
WINDOWDEPTH	equ	$0004
WINDOWDRAG	equ	$0002
_AbsExecBase	equ	4

;	equates
;	ascii control

lf		equ	$0a

;	parameters for all windows

chrh		equ	7		;character height
chrw		equ	8		;character width
strbufsiz	equ	30		;no of chrs in string gadget buffers
windp		equ	0		;detail pen
winbp		equ	1		;block pen

;	startup window parameters

winx		equ	253-3*chrw	;top x
winy		equ	0		;top y
winw		equ	85+3*chrw	;width
winh		equ	chrh+3		;height
winidcmp	equ	CLOSEWINDOW+DISKINSERTED+MOUSEBUTTONS ;idcmp flags

;	control window parameters

ctlwinx 	equ	0		;init top x
ctlwiny 	equ	0		;init top y
ctlwinw 	equ	308		;width
ctlwinh 	equ	75		;height

;	control window text

ctlmsgx 	equ	chrw		;status message
ctlmsgy 	equ	13
ctlcdx		equ	ctlmsgx 	;current drive msg
ctlcdy		equ	ctlmsgy+chrh+5
ctlcddx 	equ	ctlcdx+19*chrw	;current drive digit
ctlcddy 	equ	ctlcdy

;	control window gadgets
;	id # (do not change values)

coid		equ	0
fnid		equ	1
said		equ	2
inid		equ	3
chid		equ	4
plid		equ	5
miid		equ	6
cpid		equ	7

;	continue

ctlcox		equ	10		;box top x
ctlcoy		equ	40		;box top y
ctlcow		equ	8*chrw+4	;width
ctlcoh		equ	chrh+4		;height
ctlcotx 	equ	ctlcox+2	;text top x
ctlcoty 	equ	ctlcoy+2	;text top y

;	save

ctlsax		equ	ctlcox+ctlcow+5 ;box top x
ctlsay		equ	ctlcoy		;box top y
ctlsaw		equ	4*chrw+4	;width
ctlsah		equ	chrh+4		;height
ctlsatx 	equ	ctlsax+2	;text top x
ctlsaty 	equ	ctlsay+2	;text top y

;	install

ctlinx		equ	ctlsax+ctlsaw+5 ;box top x
ctliny		equ	ctlcoy		;box top y
ctlinw		equ	7*chrw+4	;width
ctlinh		equ	chrh+4		;height
ctlintx 	equ	ctlinx+2	;text top x
ctlinty 	equ	ctliny+2	;text top y

;	check

ctlchx		equ	ctlinx+ctlinw+5 ;box top x
ctlchy		equ	ctlcoy		;box top y
ctlchw		equ	5*chrw+4	;width
ctlchh		equ	chrh+4		;height
ctlchtx 	equ	ctlchx+2	;text top x
ctlchty 	equ	ctlchy+2	;text top y

;	compare

ctlcpx		equ	ctlchx+ctlchw+5 ;box top x
ctlcpy		equ	ctlcoy		;box top y
ctlcpw		equ	7*chrw+4	;width
ctlcph		equ	chrh+4		;height
ctlcptx 	equ	ctlcpx+2	;text top x
ctlcpty 	equ	ctlcpy+2	;text top y

;	plus

ctlplx		equ	ctlcddx+3*chrw	;box top x
ctlply		equ	ctlcddy-2	;box top y
ctlplw		equ	3*chrw+4	;width
ctlplh		equ	chrh+4		;height
ctlpltx 	equ	ctlplx+2	;text top x
ctlplty 	equ	ctlply+2	;text top y

;	minus

ctlmix		equ	ctlplx+ctlplw+20 ;box top x
ctlmiy		equ	ctlply		;box top y
ctlmiw		equ	3*chrw+4	;width
ctlmih		equ	chrh+4		;height
ctlmitx 	equ	ctlmix+2	;text top x
ctlmity 	equ	ctlmiy+2	;text top y

;	file name

ctlfnx		equ	16*chrw 	;top x
ctlfny		equ	60		;top y
ctlfnw		equ	20*chrw+2	;width
ctlfnh		equ	chrh+3		;height
ctlfntx 	equ	ctlmsgx 	;text top x
ctlfnty 	equ	ctlfny		;text top y

;	memory error requester

memreqw 	equ	250		;width
memreqh 	equ	70		;height

;	chkone error codes (do not change values)

nodev		equ	1
nomem		equ	2
nodsk		equ	3
nochg		equ	4
nobot		equ	5
nocod		equ	6
noclr		equ	7

;	startup errors

nodos		equ	25
noint		equ	20
nowin		equ	15

;	various

bootsize	equ	2*TD_SECTOR	;size of bootblock
brainst 	equ	%0110000000000000 ;long
jmpinst 	equ	%0100111011111001 ;jmp abs.l
libver		equ	33		;1.2 and later
moveqinst	equ	%0111000000000000 ;with reg & data = 0
moveqmask	equ	%1111000100000000 ;mask reg & data
nopinst 	equ	%0100111001110001
numdrv		equ	4		;maximum number of drives
romend		equ	$ffffff 	;last byte in rom
romstart	equ	$fc0000 	;1:st byte in rom
trkbufsiz	equ	bootsize	;size of disk read buffer

;	the program continues here

		ds.w	0		;alignment

main1:		move.l	a7,spsave
		move.l	_AbsExecBase,a6
		move.l	a6,d7

;	open DOS

		lea	dosname(pc),a1          ;ptr name string
		moveq.l #libver,d0		;ver #
		jsr	_LVOOpenLibrary(a6)
		moveq.l #nodos,d5		;error code
		move.l	d0,dosbase
		beq	exit1			;if no DOS

;	determine who started us

		suba.l	a1,a1
		jsr	_LVOFindTask(a6)
		clr.l	-(a7)                   ;flg no wbmsg
		move.l	d0,a0
		tst.l	pr_CLI(A0)
		bne.s	main2			;if started by CLI

;	started by workbench
;	get message from workbench

		lea	pr_MsgPort(a0),a2       ;msg port ptr
		move.l	a2,a0
		jsr	_LVOWaitPort(a6)
		move.l	a2,a0			;msg port ptr
		jsr	_LVOGetMsg(a6)
		move.l	d0,(a7)                 ;use msg later
		bra.s	main3

;	get stdout handle

main2:		move.l	dosbase(pc),a6
		jsr	_LVOOutput(a6)
		move.l	d0,d1			;output handle

;	output copyright message

		moveq.l #civerend-civer,d3	;len
		move.l	#civer,d2		;txt ptr
		jsr	_LVOWrite(a6)           ;write

;	open intuition

main3:		move.l	d7,a6			;_AbsExecBase
		lea	intname(pc),a1          ;ptr name string
		moveq.l #libver,d0		;ver #
		jsr	_LVOOpenLibrary(a6)
		moveq.l #noint,d5		;flg no intuition
		move.l	d0,intbase
		beq	exit2			;if no intuition

;	open window

		move.l	d0,a6
		lea	window(pc),a0           ;window ptr
		jsr	_LVOOpenWindow(a6)
		moveq.l #nowin,d5		;flg no window
		move.l	d0,-(a7)                ;window ptr
		beq	exit3			;if no window

;	perform initial checks

		move.l	d7,a6			;_AbsExecBase
		bsr	chkall
		move.l	(a7),a3                 ;window ptr
		bsr	memchk

;	wait for somethimg to happen

event:		move.l	(a7),a0                 ;window ptr
		move.l	wd_UserPort(a0),a2      ;IDCMP ptr
		move.b	MP_SIGBIT(a2),d1        ;sigbit #
		moveq.l #1,d0
		asl.l	d1,d0			;sigbit mask
		jsr	_LVOWait(a6)
		move.l	a2,a0			;IDCMP ptr
		jsr	_LVOGetMsg(a6)
		tst.l	d0
		beq.s	event			;if no msg

;	IDCMP received

		move.l	d0,a1			;ptr msg
		move.l	im_Class(a1),d3         ;IDCMP class
		move.w	im_Code(a1),d4
		jsr	_LVOReplyMsg(a6)
		cmp.l	#CLOSEWINDOW,d3
		beq	exit			;if close window
		cmp.l	#MOUSEBUTTONS,d3
		beq.s	event1			;if a mouse button
		cmp.l	#DISKINSERTED,d3
		bne.s	event			;if not a new disk

;	a disk is inserted

		bsr	chkall
		bra.s	event			;wait for nxt

;	a mouse button is pressed

event1: 	cmp.w	#MENUDOWN,d4
		bne.s	event			;if no menu button

;	menu button is pressed

		moveq.l #0,d4
		move.b	lastdrv(pc),d4          ;last drive used
		bsr	reschgcnt		;force chg
		bsr	chkone
		tst.l	d5
		beq.s	event11 		;if no error
		subq.l	#nomem+1,d5
		bmi.s	event			;if nodev/mem

;	turn off IDCMP

event11:	move.l	intbase(pc),a6
		move.l	(a7),a0                 ;window ptr
		moveq.l #0,d0
		jsr	_LVOModifyIDCMP(a6)

;	enable special gadgets

		lea	ctlch(pc),a0
		move.l	a0,ctlfn		;link in special gadgets
		lea	ctltxtch(pc),a0
		move.b	#ctlchtx,(a0)           ;special texts
		lea	ctlbrdch(pc),a0
		move.w	#ctlchx,(a0)            ;special borders
		bsr.s	reqstr

;	turn on IDCMP

		move.l	(a7),a0                 ;window ptr
		move.l	#winidcmp,d0
		jsr	_LVOModifyIDCMP(a6)
		move.b	d4,lastdrv		;last drive used
		move.l	d7,a6			;_AbsExecBase
		bsr	chkoneend

;	disable special gadgets

		moveq.l #0,d0
		move.l	d0,ctlfn		;remove special gadgets
		lea	ctltxtch(pc),a0
		move.b	d0,(a0)                 ;special texts
		lea	ctlbrdch(pc),a0
		move.w	d0,(a0)                 ;special borders
		bra	event

;	normal end cleanup

exit:		moveq.l #0,d5			;exit code

;	close startup window

		move.l	intbase(pc),a6
		move.l	(a7)+,a0                ;window ptr
		jsr	_LVOCloseWindow(a6)

;	if no startup window

exit3:		move.l	d7,a6			;_AbsExecBase
		move.l	intbase(pc),a1
		jsr	_LVOCloseLibrary(a6)    ;close intuition

;	if no intuition.library

exit2:		move.l	dosbase(pc),a1
		jsr	_LVOCloseLibrary(a6)    ;close dos

;	if no dos.library

exit1:		move.l	(a7)+,d2                ;wbmsg ptr
		beq.s	exit4			;if started from workbench

;	reply workbench message

		jsr	_LVOForbid(a6)
		move.l	d2,a1
		jsr	_LVOReplyMsg(a6)
exit4:		move.l	spsave(pc),a7           ;defensive programming
		move.l	d5,d0			;exit code
		rts

;	reqstr
;	open control window and handle user response
;	entry : d4=trackdisk unit number
;		a3=trackdisk ioreq ptr, a4=track buf ptr, a5=status str ptr
;	exit  : d4=trackdisk unit (possibly updated), a6=intbase
;	chg   : d0,d1,d2,d3,d4,d5,d6
;		a0,a1,a2,a5,a6
;	4,6-9,12,14->

reqstr: 	move.l	intbase(pc),a6
		lea	ctlwin(pc),a0           ;window ptr
		jsr	_LVOOpenWindow(a6)
		tst.l	d0
		bne.s	reqstr11
		rts				;exit if no window
reqstr11:	move.l	a4,d6			;track buf ptr
		move.l	d0,a4			;win ptr

;	display fixed text

		lea	ctltxt(pc),a2           ;fixed text ptr
reqstr1:	moveq.l #0,d0
		move.l	d0,d1
		move.b	(a2)+,d0                ;x coord
		beq.s	reqstr3 		;if no more
		move.b	(a2)+,d1                ;y coord
		move.l	a2,genitptr		;txt ptr
reqstr2:	tst.b	(a2)+
		bne.s	reqstr2 		;loop until end of str
		bsr	prttxt
		bra.s	reqstr1 		;print text

;	display fixed border boxes

reqstr3:	lea	ctlbrd(pc),a2           ;fixed border ptr
reqstr13:	moveq.l #0,d0
		move.l	d0,d1
		move.w	(a2),d2
		beq.s	reqstr5 		;if no more
		move.l	a2,genbdptr		;coord ptr
		add.w	#5*2*2,a2		;next box coords
		move.l	wd_RPort(a4),a0         ;rast port ptr
		lea	genbd(pc),a1            ;ptr to border struct
		jsr	_LVODrawBorder(a6)
		bra.s	reqstr13		;loop

;	event loop
;	display drive digit

reqstr5:	move.l	intbase(pc),a6
		lea	bbdigit(pc),a0
		move.b	d4,(a0)
		add.b	#'0',(a0)               ;make ascii
		move.l	a0,genitptr		;intuitext string ptr
		moveq.l #ctlcddx/2,d0
		add.l	d0,d0			;x coord
		moveq.l #ctlcddy,d1		;y coord
		bsr	prttxt

;	display status message

		move.l	a5,genitptr		;intuitext string ptr
		beq.s	reqstr10		;if no msg
		moveq.l #ctlmsgx,d0		;x coord
		moveq.l #ctlmsgy,d1		;y coord
		bsr	prttxt
		sub.l	a5,a5			;flg no msg

;	wait for event

reqstr10:	move.l	d7,a6			;_AbsExecBase
		move.l	wd_UserPort(a4),a2      ;IDCMP ptr
		move.b	MP_SIGBIT(a2),d1        ;sigbit #
		moveq.l #1,d0
		asl.l	d1,d0			;sigbit mask
		jsr	_LVOWait(a6)
		move.l	a2,a0			;IDCMP ptr
		jsr	_LVOGetMsg(a6)
		tst.l	d0
		beq.s	reqstr5 		;if no msg
		move.l	d0,a1			;ptr msg
		move.l	im_Class(a1),d2         ;IDCMP class
		move.l	im_IAddress(a1),a2      ;gadget ptr
		jsr	_LVOReplyMsg(a6)
		cmp.l	#DISKINSERTED,d2
		beq	reqch			;if a new disk, chk it
		cmp.l	#GADGETUP,d2
		bne.s	reqstr5 		;if not gadget
		moveq.l #0,d1
		move.w	gg_GadgetID(a2),d1

;	do the requested routine
;	routines must not destroy d4,d6,a3,a4

		beq	reqco			;if continue
		subq.l	#2,d1
		beq.s	reqsa			;if save
		subq.l	#1,d1
		beq.s	reqin			;if install
		subq.l	#1,d1
		beq	reqfch			;if forced check
		subq.l	#1,d1
		beq	reqpl			;if plus
		subq.l	#1,d1
		beq	reqmi			;if minus
		subq.l	#1,d1
		beq	reqcp			;if compare
		bra	reqstr5 		;if unkown

;	save bootblock

reqsa:		move.l	dosbase(pc),a6
		move.l	#strbuf,d1		;name ptr
		move.l	#MODE_NEWFILE,d2	;mode
		jsr	_LVOOpen(a6)
		move.l	d0,d1			;handle
		move.l	d0,d5
		beq	reqerr			;if no handle
		move.l	d6,d2			;data ptr
		move.l	#trkbufsiz,d3		;data size
		jsr	_LVOWrite(a6)
		move.l	d0,d2			;if open error
		move.l	d5,d1			;handle
		jsr	_LVOClose(a6)
		addq.l	#1,d2
		bne	reqstr5 		;cont event loop

;	save, install error

reqerr: 	move.l	intbase(pc),a6
		sub.l	a0,a0			;all screens
		jsr	_LVODisplayBeep(a6)
		bra	reqstr5 		;cont event loop

;	install disk
;	check if there is a disk in the drive

reqin:		bsr	tdstate
		bne	reqstr5 		;if no disk

;	get a new trackbuffer

		move.l	#TD_SECTOR,d0
		move.l	#MEMF_CHIP+MEMF_CLEAR,d1
		jsr	_LVOAllocMem(a6)        ;get mem ptr
		tst.l	d0
		beq.s	reqerr			;if no mem
		move.l	d0,a2			;buf ptr

;	check if disk is write protected

		move.w	#TD_PROTSTATUS,IO_COMMAND(a3)
		bsr	doiotst
		lea	bbwpmsg(pc),a5
		bne.s	reqin3			;if write prot

;	write block 1 & 0

		moveq.l #1,d2			;write 2 blocks
		move.l	#TD_SECTOR,IO_OFFSET(a3) ;block 1
reqin2: 	move.l	a2,IO_DATA(a3)          ;data ptr
		move.l	#TD_SECTOR,IO_LENGTH(a3) ;data size
		move.w	#CMD_WRITE,IO_COMMAND(a3) ;write
		bsr	doiotst
		moveq.l #(bootend-bootstart)/4-1,d0 ;normal boot code size
		move.l	a2,a1			;buf ptr
		lea	bootstart(pc),a0        ;normal code ptr
reqin1: 	move.l	(a0)+,(a1)+
		dbra	d0,reqin1		;move norm code to buffer
		clr.l	IO_OFFSET(a3)           ;block 0
		dbra	d2,reqin2		;write block 0

;	put it on the disk

		move.w	#CMD_UPDATE,IO_COMMAND(a3)
		bsr	doiotst
		bsr	motoroff
		lea	bb0msg(pc),a5
		add.w	#1,instcnt		;one more installed

;	free this track buffer

reqin3: 	move.l	a2,a1			;ptr
		move.l	#TD_SECTOR,d0		;size
		jsr	_LVOFreeMem(a6)
		bra	reqstr5 		;cont event loop

;	close window

reqco:		move.l	a4,a0			;win ptr
		move.l	d6,a4			;track buf ptr
		move.l	intbase(pc),a6
		lea	ctlwin(pc),a1           ;NewWindow ptr
		move.w	wd_LeftEdge(a0),nw_LeftEdge(a1)
		move.w	wd_TopEdge(a0),nw_TopEdge(a1) ;update init pos
		jmp	_LVOCloseWindow(a6)

;	forced check of drive

reqfch: 	bsr	reschgcnt

;	normal check of drive

reqch:		exg	a4,d6			;d6=ctl ptr a4=trkbuf
		move.l	a3,d0
		beq.s	reqch1			;if no io req
		bsr	chkoneend
reqch1: 	bsr	reschgcnt		;force chk
		bsr	chkone
		exg	a4,d6			;a4=ctl ptr d6=trkbuf
		tst.l	d5
		beq	reqstr5 		;if no error
		subq.l	#nomem+1,d5
		bpl	reqstr5 		;if successful open
		sub.l	a3,a3			;no io req

;	decrease drive number

reqmi:		subq.l	#1,d4			;prev drive #
		bpl.s	reqch			;if valid, go chk it
		addq.l	#1,d4
		bra	reqstr5

;	increase drive number

reqpl:		addq.l	#1,d4			;nxt drive #
		cmp.b	#numdrv-1,d4
		ble.s	reqch			;if valid, go chk it
		subq.l	#1,d4
		bra	reqstr5

;	compare with saved
;	allocate memory for FileInfoBlock and read buffer

reqcp:		move.l	#fib_SIZEOF+trkbufsiz,d0
		move.l	#MEMF_ANY,d1
		jsr	_LVOAllocMem(a6)        ;get mem ptr
		move.l	d0,a2			;ptr
		tst.l	d0
		beq	reqerr			;if no mem

;	get lock to compare directory

		move.l	dosbase(pc),a6
		move.l	#cpdev,d1		;dir name
		move.l	ACCESS_READ,d2
		jsr	_LVOLock(a6)
		move.l	d0,d5			;dir lock
		beq	reqcp2			;if no lock
		move.l	d0,d1			;dir lock
		jsr	_LVOCurrentDir(a6)

;	get FileInfoBlock for compare directory

		move.l	a2,d2			;fib ptr
		move.l	d5,d1			;dir lock
		jsr	_LVOExamine(a6)
		tst.l	d0
		beq	reqcp3			;if error

;	get FileInfoBlock for next file

reqcp5: 	move.l	d5,d1			;dir lock
		move.l	a2,d2			;fib ptr
		jsr	_LVOExNext(a6)
		tst.l	d0
		beq.s	reqcp3			;if no more entries
		tst.l	fib_DirEntryType(a2)
		bgt.s	reqcp5			;if a directory, try next

;	a file is found

		cmp.l	#trkbufsiz,fib_Size(a2)
		bne.s	reqcp5			;if not right size, try next
		lea	fib_FileName(a2),a0
		move.l	a0,d1			;ptr name
		move.l	#MODE_OLDFILE,d2
		jsr	_LVOOpen(a6)
		move.l	d0,a5			;handle
		tst.l	d0
		beq.s	reqcp5			;if error, try next
		move.l	d0,d1			;handle
		lea	fib_SIZEOF(a2),a0
		move.l	a0,d2			;read buffer ptr
		move.l	#trkbufsiz,d3		;size
		jsr	_LVORead(a6)
		move.l	d0,d2			;ret code
		move.l	a5,d1			;handle
		jsr	_LVOClose(a6)
		moveq.l #-1,d0
		cmp.l	d0,d2
		beq.s	reqcp5			;ir read err, try next

;	a file of correct size is read, compare it

		move.w	#trkbufsiz/4-1,d0	;loop count
		move.l	d6,a0			;current bootblock ptr
		lea	fib_SIZEOF(a2),a1       ;read file ptr
reqcp6: 	cmp.l	(a0)+,(a1)+
		bne.s	reqcp5			;if not same, try next
		dbra	d0,reqcp6		;loop

;	an identical file is found
;	move name to status buffer

		lea	bbfbmsg(pc),a5          ;status msg
		lea	fib_FileName(a2),a0     ;name ptr
		lea	bbfbmsgname(pc),a1      ;status name buffer ptr
		moveq.l #bbfbmsgend-bbfbmsgname-1,d0 ;buffer cnt
reqcp8: 	move.b	(a0)+,(a1)+             ;name to buf
		beq.s	reqcp7			;if end of name
		dbra	d0,reqcp8		;loop
		bra.s	reqcp4
reqcp7: 	subq.l	#1,a1			;write over end mark
reqcp9: 	move.b	#' ',(a1)+
		dbra	d0,reqcp9		;fill with ' '
		bra.s	reqcp4

;	entry from : no lock or dir exhausted

reqcp3: 	lea	bbnfmsg(pc),a5          ;no file msg
reqcp4: 	move.l	d5,d1			;ptr to dir lock
		jsr	_LVOUnLock(a6)          ;unlock dir

;	free memory
;	entry from : no lock to compare directory

reqcp2: 	move.l	d7,a6			;_AbsExecBase
		move.l	a2,a1			;ptr
		move.l	#fib_SIZEOF+trkbufsiz,d0 ;size
		jsr	_LVOFreeMem(a6)
		bra	reqstr5

;	subroutines

;	chkall
;	check the boot blocks in all floppy disk drives
;	if error is found : call reqstr
;	entry : a6=exec.library ptr
;	chg   : d0,d1,d2,d3,d4,d5
;		a0,a1,a2,a3,a4

chkall: 	moveq.l #numdrv-1,d4		;drive count
chkall4:	bsr.s	chkone
		tst.l	d5
		beq.s	chkall3 		;if no error
		subq.l	#nomem+1,d5
		bmi.s	chkall1 		;if nodev/mem
		subq.l	#3,d5
		bmi.s	chkall3 		;if nodsk/chg/bot

;	error found in boot block

		bsr	reqstr			;handle response
		move.l	d7,a6			;_AbsExecBase
chkall3:	bsr	chkoneend		;chkone cleanup
chkall1:	dbra	d4,chkall4		;drive loop
		rts

;	chkone
;	check the boot blocks in one floppy disk drive
;	  if the drive
;	    is attached
;	    has changed since last check
;	    has a disk inserted
;	entry : d4=drive number, a6=exec.library ptr
;	exit  : d5=error code (see equates in beginning of file)
;		a3=io request ptr, a4=track buffer ptr, a5=msg string ptr
;	chg   : d0,d1,d2,d3,d5
;		a0,a1,a2,a3,a4,a5

;	open trackdisk device

chkone: 	moveq.l #nodev,d5		;flg no device
		move.l	#trkname,d2
		move.l	#trknodename,d3
		bsr	opendev
		bne.s	chkone1 		;if open
chkone4:	rts				;exit if not possible to open

;	allocate trackdisk buffer memory

chkone1:	move.l	IO_ACTUAL(a3),0(a0,d1)  ;update cnt
		moveq.l #nomem,d5		;flg no memory
		move.l	#trkbufsiz,d0
		move.l	#MEMF_CHIP,d1
		jsr	_LVOAllocMem(a6)        ;get mem ptr
		tst.l	d0
		beq	closedev		;if no mem
		move.l	d0,a4			;ptr

;	check if the drive has a disk inserted

		bsr	tdstate
		bne	chkone4 		;if no disk

;	check if the drive has changed since last check

		move.w	#TD_CHANGENUM,IO_COMMAND(a3)
		bsr	doiotst
		lea	chgcnt(pc),a0
		move.l	d4,d1
		asl.l	#2,d1			;long ptr
		move.l	0(a0,d1),d0             ;last cnt
		moveq.l #nochg,d5		;flg no change
		cmp.l	IO_ACTUAL(a3),d0
		beq	chkone4 		;if no change
		move.l	IO_ACTUAL(a3),0(a0,d1)  ;update cnt

;	read block 0 and 1

		move.l	a4,IO_DATA(a3)          ;data ptr
		move.l	#trkbufsiz,IO_LENGTH(a3) ;data size
		move.w	#CMD_READ,IO_COMMAND(a3) ;read
		clr.l	IO_OFFSET(a3)           ;start at block 0
		bsr.s	doiotst
		bsr	motoroff

;	check code part of bootblock

		add.w	#1,chkcnt		;one more checked
		lea	bootstart(pc),a1        ;ptr to std data
		move.l	a4,a0			;ptr to read data
		lea	bb5msg(pc),a5
		moveq.l #nobot,d5		;flg no bootdisk
		cmp.l	(a0)+,(a1)+             ;chk type
		bne.s	chkone7 		;if not a boot disk
		moveq.l #((bootend-bootstart)/4)-2,d0 ;long size-2
		moveq.l #nocod,d5		;flg no boot code
		lea	bb6msg(pc),a5
chkone3:	cmp.l	(a0)+,(a1)+
		bne.s	chkone5 		;if not std code
		dbra	d0,chkone3		;loop

;	check cleared part of bootblock

		move.w	#bootsize/4-((bootend-bootstart)/4)-1,d0 ;long size of clr area
		moveq.l #noclr,d5		;flg error in clear area
		lea	bb7msg(pc),a5
chkone2:	tst.l	(a0)+
		bne.s	chkone5 		;if not cleared
		dbra	d0,chkone2		;loop
		lea	bb0msg(pc),a5
		moveq.l #0,d5			;flg no error
chkone7:	rts

;	if error

chkone5:	add.w	#1,vircnt		;one more non std found
		rts

;	chkoneend
;	close device and free trackdisk buffer memory
;	entry : a3=io req ptr, a4=track buffer ptr, a6=_AbsExecBase
;	chg   : d0,d1
;		a0,a1,a2

chkoneend:	bsr	closedev
		move.l	a4,a1			;ptr
		move.l	#trkbufsiz,d0		;size
		jmp	_LVOFreeMem(a6)

;	doiotst
;	make a DoIO and tst IO_ACTUAL
;	entry : a3=io request, a6=_AbsExecBase
;	exit  : flags
;	chg   : d0,d1,a0,a1

doiotst:	move.l	a3,a1			;ioreq ptr
		jsr	_LVODoIO(a6)
		tst.l	IO_ACTUAL(a3)
		rts

;	memchk
;	check jump tables of all resident libraries and all resident devices
;	jump address must be in rom or in private area of a resident library
;	entry : a3=startup window pointer, a6=_AbsExecBase
;	chg   : d0,d1,d2,d3,d5
;		a0,a1,a2,a5

;	13->
;	allocate memory for lib & dev private begin & end ptrs

memchk: 	move.l	#numlibs*2*4,d0 	;size
		move.l	#MEMF_ANY+MEMF_CLEAR,d1
		jsr	_LVOAllocMem(a6)        ;get mem ptr
		move.l	d0,d5			;mem ptr
		bne.s	memchk1 		;if mem
		rts
memchk1:	move.l	d5,a5			;size array ptr
		lea	firstlib(pc),a2         ;1:st lib name ptr

;	set up array with library & device private begin & end

		lea	LibList(a6),a0          ;library header
memchk13:	move.l	a0,d3			;header ptr
memchk3:	move.l	a2,a1			;name
		move.l	d3,a0			;header
		jsr	_LVOFindName(a6)
		tst.l	d0
		beq	memchk2 		;should not happen, get nxt
		move.l	d0,a0			;lib or dev ptr
		lea	LIB_SIZE(a0),a1
		move.l	a1,(a5)+                ;1:st private
		move.w	LIB_POSSIZE(a0),d0
		add.w	d0,a0			;1:st after private
		move.l	a0,(a5)+
memchk2:	tst.b	(a2)+
		bne.s	memchk2 		;find nxt name
		tst.b	(a2)
		bne	memchk3 		;if more names
		addq	#1,a2			;skip end mark
		lea	LibList(a6),a0
		cmp.l	a0,d3
		lea	DeviceList(a6),a0       ;device header
		beq.s	memchk13		;do device list

;	library & device check loop

		lea	firstlib(pc),a2         ;1:st lib name ptr
		lea	LibList(a6),a0          ;library header
memchk14:	move.l	a0,d3			;header ptr
memchk6:	move.l	a2,a1			;name
		move.l	d3,a0			;header
		jsr	_LVOFindName(a6)
		move.l	d0,d2
		move.l	d0,a0
		beq	memchk5 		;should not happen, chk nxt
		moveq.l #0,d0
		move.w	LIB_NEGSIZE(a0),d0      ;jump tab size
		beq.s	memchk5 		;should not happen, chk nxt
		divu	#6,d0			;# of entries
		subq.l	#1,d0			;use as loop cnt

;	jump table check loop

memchk4:	subq.l	#6,a0			;entry ptr

;	check instruction

		move.w	(a0),d1                 ;instr
		move.l	2(a0),a1                ;jmp addr
		cmp.w	#jmpinst,d1
		beq.s	memchk7 		;if jmp
		cmp.w	#nopinst,d1
		beq.s	memchk8 		;if nop
		and.w	#moveqmask,d1
		cmp.w	#moveqinst,d1
		bne.s	memerr			;if unknown instr

;	moveq or nop instruction

memchk8:	move.l	2(a0),d1                ;get nxt instr
		swap	d1			;instr to lo
		cmp.w	#brainst,d1
		bne.s	memerr			;if unknown instr

;	bra instruction

		swap	d1			;offset to lo
		lea	2(a0),a1                ;instr addr
		add.w	d1,a1			;jump target addr

;	check jmp address against rom

memchk7:	cmp.l	#romstart,a1
		blt.s	memchk9 		;if addr before start
		cmp.l	#romend+1,a1
		blt.s	memchk10		;if addr before end

;	check jmp address against resident lib or dev private area

memchk9:	move.l	d5,a5			;start of start/stop array
		moveq.l #numlibs-1,d1		;loop cnt
memchk12:	cmp.l	(a5),a1
		blt.s	memchk11		;if addr before start
		cmp.l	4(a5),a1
		blt.s	memchk10		;if addr before end
memchk11:	addq.l	#8,a5			;nxt start/stop pair
		dbra	d1,memchk12		;loop

;	suspicious jump address found

		bra.s	memerr

;	one library or device is checked

memchk10:	dbra	d0,memchk4		;tab loop
memchk5:	tst.b	(a2)+
		bne.s	memchk5 		;find nxt name
		tst.b	(a2)
		bne	memchk6 		;if more names
		addq	#1,a2			;skip end mark
		lea	LibList(a6),a0
		cmp.l	a0,d3
		lea	DeviceList(a6),a0       ;device header
		beq	memchk14		;do device list

;	all libraries and devices are checked

		move.l	#numlibs*2*4,d0 	;size
		move.l	d5,a1
		jsr	_LVOFreeMem(a6)         ;get mem ptr
		rts

;	errors

memerr: 	movem.l d0/d2/d3/a0/a2/a3/a6,-(a7)
		move.l	intbase(pc),a6

;	calculate offset into table and covert to decimal

		sub.l	a0,d2			;offset into tab
		moveq.l #100,d1
		lea	memmsgnum(pc),a0
memerr1:	divu	d1,d2
		add.b	#'0',d2
		move.b	d2,(a0)+
		clr.b	d2
		swap	d2			;rem to lo
		divu	#10,d1
		bne.s	memerr1 		;if more digits

;	set up requester

		move.l	a3,a0			;window ptr
		lea	membt1(pc),a1           ;boty text intuitext
		move.l	a2,membt2ptr
		sub.l	a2,a2			;no positive text
		lea	memnt(pc),a3            ;negative text intuitext
		moveq.l #memreqw/4,d2		;width
		asl.l	#2,d2
		moveq.l #memreqh,d3		;height
		moveq.l #0,d0
		move.l	d0,d1			;no IDCMP
		jsr	_LVOAutoRequest(a6)
		movem.l (a7)+,d0/d2/d3/a0/a2/a3/a6 ;restore
		bra.s	memchk10

;	motoroff
;	turn the motor off in a drive
;	entry : a3=ptr to iorequest
;	chg   : d0,d1
;		a0,a1

motoroff:	moveq.l #0,d0
		move.l	d0,IO_LENGTH(a3)        ;motor state
		move.w	#TD_MOTOR,IO_COMMAND(a3)
		bra	doiotst

;	opendev
;	open the device, allocate a message port and allocate a StdIOReq
;	entry : d2=ptr device name string, d3=ptr msgport node name string
;		d4=unit #
;		a6=exec.library ptr
;	exit  : a3=ptr StdIOReq, z=failure
;	chg   : d0,d1
;		a0,a1,a2,a3

;	get memory for port and iorequest

opendev:	moveq.l #MP_SIZE+IOSTD_SIZE,d0
		move.l	#MEMF_ANY+MEMF_PUBLIC+MEMF_CLEAR,d1
		jsr	_LVOAllocMem(a6)        ;get mem ptr
		tst.l	d0
		bne.s	opendev1
		rts				;exit if no mem
opendev1:	move.l	d0,a2			;msg port ptr

;	allocate a signal

		moveq.l #-1,d0
		jsr	_LVOAllocSignal(a6)
		move.b	d0,MP_SIGBIT(a2)        ;signal #
		addq.l	#1,d0
		beq.s	opendev3		;if failure

;	add a MsgPort

		move.b	#NT_MSGPORT,LN_TYPE(a2) ;node type
		move.l	d3,LN_NAME(a2)          ;node name
		move.b	#PA_SIGNAL,MP_FLAGS(a2) ;action type
		sub.l	a1,a1
		jsr	_LVOFindTask(a6)
		move.l	d0,MP_SIGTASK(a2)       ;task ptr
		move.l	a2,a1
		jsr	_LVOAddPort(a6)

;	open the device

		lea	MP_SIZE(a2),a3          ;IOStdReq ptr
		move.l	a2,MN_REPLYPORT(a3)     ;ptr port
		move.w	#IOSTD_SIZE-MN_SIZE,MN_LENGTH(a3) ;msg size
		move.l	d2,a0			;dev name
		move.l	d4,d0			;unit #
		move.l	a3,a1			;ptr StdIOReq
		moveq.l #0,d1			;flgs
		jsr	_LVOOpenDevice(a6)
		or.l	d0,d0
		bne.s	opendev2		;if error
		moveq.l #1,d0			;flg no error
		rts

;	back out safely and don't destroy anything
;	remove signal and port

opendev2:	moveq.l #0,d0
		move.b	MP_SIGBIT(a2),d0        ;signal #
		jsr	_LVOFreeSignal(a6)
		move.l	a2,a1
		jsr	_LVORemPort(a6)
		moveq.l #0,d0			;flg error

;	free message port and io request memory

opendev3:	move.l	a2,a1			;msgport ptr
		move.l	#MP_SIZE+IOSTD_SIZE,d0	;size
		jsr	_LVOFreeMem(a6)
		moveq.l #0,d0			;flg failure
		rts				;exit if no alloc

;	closedev
;	remove the message port and close the device
;	entry : a3=ptr to a associated IoReq
;		a6=exec.library ptr
;	chg   : d0,d1
;		a0,a1,a2

closedev:	move.l	MN_REPLYPORT(a3),a2     ;msgport ptr
		move.l	a3,a1			;io request ptr
		jsr	_LVOCloseDevice(a6)
		bra.s	opendev2

;	prttxt
;	print intui text in a window, using genit struct
;	entry : d0=x coord, d1=y coord
;		a4=ptr to window, a6=intbase
;	chg   : d0,d1
;		a0,a1

prttxt: 	move.l	wd_RPort(a4),a0         ;rast port ptr
		lea	genit(pc),a1            ;ptr to intuitext struct
		jmp	_LVOPrintIText(a6)

;	reschgcnt
;	reset change counter for a drive
;	entry : d4=drive #
;	chg   : d0,d1,d0

reschgcnt:	lea	chgcnt(pc),a0
		move.l	d4,d1
		asl.l	#2,d1			;long ptr
		moveq.l #0,d0
		move.l	d0,0(a0,d1)             ;force change
		rts

;	tdstate
;	check if drive has disk inserted
;	entry : a3=io request, a6=_AbsExecBase
;	exit  : z=disk in drive
;	chg   : d0,d1,d5
;		a0,a1,a5

tdstate:	lea	bb3msg(pc),a5
		moveq.l #nodsk,d5		;flg no disk
		move.w	#TD_CHANGESTATE,IO_COMMAND(a3)
		bra	doiotst

;	normal boot code, to check bootblock against
;	bootcode
;	execution starts 12 bytes into block 0
;	entry : a6=exec lib ptr
;	exit  : d0=failure code, 0=ok
;		a0=ptr to boot routine

;	data area

bootstart:	dc.b	"DOS",0                 ;4 byte id
		dc.l	$c0200f19		;chksum
		dc.l	$00000370		;dos patch

;	start execution here

bootentry:	lea	bootname(pc),a1         ;ptr lib name
		jsr	_LVOFindResident(a6)
		tst.l	d0
		beq.s	booterror		;if lib ptr = 0

;	dos library found

		movea.l d0,a0			;lib ptr
		movea.l RT_INIT(a0),a0          ;ptr to resident init code
		moveq.l #0,d0			;flg no error
bootexit:	rts
booterror:	moveq.l #-1,d0			;flg error
		bra.s	bootexit

;	data area

bootname:	dc.b	"dos.library",0
		dc.w	0			;align to long size
bootend:

;	the rest is cleared

;		 dcb.b	  bootsize-(bootend-bootstart),0

;	end of normal bootblock

;	data area
;	initialized data area
;	name strings of resident libraries and devices

numlibs 	equ	16			;number of libs & devs

firstlib:
dosname:	dc.b	'dos.library',0
		dc.b	'exec.library',0
		dc.b	'expansion.library',0
		dc.b	'graphics.library',0
intname:	dc.b	'intuition.library',0
		dc.b	'layers.library',0
		dc.b	'mathffp.library',0
		dc.b	'romboot.library',0
		dc.b	'ramlib.library',0
		dc.b	0			;end of libraries
		dc.b	'keyboard.device',0
		dc.b	'gameport.device',0
		dc.b	'timer.device',0
		dc.b	'audio.device',0
		dc.b	'input.device',0
		dc.b	'console.device',0
		dc.b	'trackdisk.device',0
		dc.b	0			;end of devices

;	error messages from memchk

memmsg: 	dc.b	'Suspicious entry at -'
memmsgnum:	dc.b	'    ',0

;	various strings

cpdev:		dc.b	'ngcbb:',0
trkname:	dc.b	'trackdisk.device',0
trknodename:	dc.b	'NGC trk',0

;	startup window data area
;	title

wintitle:	dc.b	'NGC',0

;	NewWindow struct

window: 	dc.w	winx,winy		;top x,y
		dc.w	winw,winh		;width, height
		dc.b	windp,winbp		;detail, block pen
		dc.l	winidcmp		;idcmp flags
		dc.l	WINDOWDRAG+WINDOWDEPTH+WINDOWCLOSE+NOCAREREFRESH+RMBTRAP ;window flags
		dc.l	0			;ptr 1st gadget
		dc.l	0			;ptr checkmark
		dc.l	wintitle		;ptr title
		dc.l	0			;ptr screen
		dc.l	0			;ptr bit map
		dc.w	0,0			;min width height
		dc.w	0,0			;max width height
		dc.w	WBENCHSCREEN		;screen type

;	control window data area
;	status messages

bb0msg: 	dc.b	"Standard bootcode    ",0
bb3msg: 	dc.b	"No disk inserted     ",0
bb5msg: 	dc.b	"Not a bootable disk  ",0
bb6msg: 	dc.b	"Not standard bootcode",0
bb7msg: 	dc.b	"Data in clear part   ",0
bbnfmsg:	dc.b	"No identical file    ",0
bbwpmsg:	dc.b	"Write protected disk ",0
bbfbmsg:	dc.b	"Found: ",
bbfbmsgname:	dc.b	"              "
bbfbmsgend:	dc.b	0
bbdigit:	dc.b	" ",0

;	fixed text
;	x,y coords
;	string
;	end with x coord = zero

ctltxt: 	dc.b	ctlcotx,ctlcoty
		dc.b	'Continue',0
		dc.b	ctlsatx,ctlsaty
		dc.b	'Save',0
		dc.b	ctlintx,ctlinty
		dc.b	'Install',0
		dc.b	ctlfntx,ctlfnty
		dc.b	'Save as file :',0
		dc.b	ctlcdx,ctlcdy
		dc.b	'Current drive is df',0
ctltxtch:	dc.b	0,ctlchty		;temp end
		dc.b	'Check',0
		dc.b	ctlpltx,ctlplty
		dc.b	' + ',0
		dc.b	ctlmitx,ctlmity
		dc.b	' - ',0
		dc.b	ctlcptx,ctlcpty
		dc.b	'Compare',0
		dc.b	0			;end

;	fixed borders
;	5 x,y coord pairs per box
;	end with x coord = 0

ctlbrd: 	dc.w	ctlcox,ctlcoy		;continue   0  2
		dc.w	ctlcox,ctlcoy+ctlcoh-1		   ;4  6
		dc.w	ctlcox+ctlcow-1,ctlcoy+ctlcoh-1    ;8  10
		dc.w	ctlcox+ctlcow-1,ctlcoy		   ;12 14
		dc.w	ctlcox,ctlcoy			   ;16 18
		dc.w	ctlsax,ctlsay		;save
		dc.w	ctlsax,ctlsay+ctlsah-1
		dc.w	ctlsax+ctlsaw-1,ctlsay+ctlsah-1
		dc.w	ctlsax+ctlsaw-1,ctlsay
		dc.w	ctlsax,ctlsay
		dc.w	ctlinx,ctliny		;install
		dc.w	ctlinx,ctliny+ctlinh-1
		dc.w	ctlinx+ctlinw-1,ctliny+ctlinh-1
		dc.w	ctlinx+ctlinw-1,ctliny
		dc.w	ctlinx,ctliny
		dc.w	ctlfnx-3,ctlfny-2	    ;file name
		dc.w	ctlfnx-3,ctlfny+ctlfnh-1
		dc.w	ctlfnx+ctlfnw,ctlfny+ctlfnh-1
		dc.w	ctlfnx+ctlfnw,ctlfny-2
		dc.w	ctlfnx-3,ctlfny-2
ctlbrdch:	dc.w	0,ctlchy	    ;check (temp end)
		dc.w	ctlchx,ctlchy+ctlchh-1
		dc.w	ctlchx+ctlchw-1,ctlchy+ctlchh-1
		dc.w	ctlchx+ctlchw-1,ctlchy
		dc.w	ctlchx,ctlchy
		dc.w	ctlplx,ctlply		;plus
		dc.w	ctlplx,ctlply+ctlplh-1
		dc.w	ctlplx+ctlplw-1,ctlply+ctlplh-1
		dc.w	ctlplx+ctlplw-1,ctlply
		dc.w	ctlplx,ctlply
		dc.w	ctlmix,ctlmiy		;minus
		dc.w	ctlmix,ctlmiy+ctlmih-1
		dc.w	ctlmix+ctlmiw-1,ctlmiy+ctlmih-1
		dc.w	ctlmix+ctlmiw-1,ctlmiy
		dc.w	ctlmix,ctlmiy
		dc.w	ctlcpx,ctlcpy		;compare
		dc.w	ctlcpx,ctlcpy+ctlcph-1
		dc.w	ctlcpx+ctlcpw-1,ctlcpy+ctlcph-1
		dc.w	ctlcpx+ctlcpw-1,ctlcpy
		dc.w	ctlcpx,ctlcpy
		dc.w	0			;end

;	control window NewWindow struct

ctlwin: 	dc.w	0,0			;top x,y (to be set)
		dc.w	ctlwinw,ctlwinh 	;width, height
		dc.b	windp,winbp		;detail, block pen
		dc.l	GADGETUP+DISKINSERTED	;idcmp flags
		dc.l	WINDOWDRAG+WINDOWDEPTH+NOCAREREFRESH ;window flags
		dc.l	ctlco			;ptr 1st gadget
		dc.l	0			;ptr checkmark
		dc.l	civer			;ptr title
		dc.l	0			;ptr screen
		dc.l	0			;ptr bit map
		dc.w	0,0			;min width height
		dc.w	0,0			;max width height
		dc.w	WBENCHSCREEN		;screen type

;	input window gadget structs
;	continue

ctlco:		dc.l	ctlsa			;ptr nxt gadget
		dc.w	ctlcox,ctlcoy		;top x,y
		dc.w	ctlcow,ctlcoh		;width, height
		dc.w	GADGHCOMP		;flags
		dc.w	RELVERIFY		;activation
		dc.w	BOOLGADGET		;gadget type
		dc.l	0			;ptr gadget render
		dc.l	0			;ptr select render
		dc.l	0			;ptr gadget txt
		dc.l	0			;mutual exclude
		dc.l	0			;ptr spec info
		dc.w	coid			;id#
		dc.l	0			;ptr user data

;	save

ctlsa:		dc.l	ctlin			;ptr nxt gadget
		dc.w	ctlsax,ctlsay		;top x,y
		dc.w	ctlsaw,ctlsah		;width, height
		dc.w	GADGHCOMP		;flags
		dc.w	RELVERIFY		;activation
		dc.w	BOOLGADGET		;gadget type
		dc.l	0			;ptr gadget render
		dc.l	0			;ptr select render
		dc.l	0			;ptr gadget txt
		dc.l	0			;mutual exclude
		dc.l	0			;ptr spec info
		dc.w	said			;id#
		dc.l	0			;ptr user data

;	install

ctlin:		dc.l	ctlfn			;ptr nxt gadget
		dc.w	ctlinx,ctliny		;top x,y
		dc.w	ctlinw,ctlinh		;width, height
		dc.w	GADGHCOMP		;flags
		dc.w	RELVERIFY		;activation
		dc.w	BOOLGADGET		;gadget type
		dc.l	0			;ptr gadget render
		dc.l	0			;ptr select render
		dc.l	0			;ptr gadget txt
		dc.l	0			;mutual exclude
		dc.l	0			;ptr spec info
		dc.w	inid			;id#
		dc.l	0			;ptr user data

;	filename

ctlfn:		dc.l	0			;ptr nxt gadget
		dc.w	ctlfnx,ctlfny		;top x,y
		dc.w	ctlfnw,ctlfnh		;width, height
		dc.w	SELECTED+GADGHCOMP	;flags
		dc.w	RELVERIFY		;activation
		dc.w	STRGADGET		;gadget type
		dc.l	0			;ptr gadget render
		dc.l	0			;ptr select render
		dc.l	0			;ptr gadget txt
		dc.l	0			;mutual exclude
		dc.l	ctlfninfo		;ptr spec info
		dc.w	fnid			;id#
		dc.l	0			;ptr user data

;	special info for filename gadget

ctlfninfo:	dc.l	strbuf			;ptr buffer
		dc.l	undobuf 		;ptr undo buffer
		dc.w	0			;init buf pos
		dc.w	strbufsiz+1		;buf size
		dc.w	0			;pos of 1:st disp chr
		dc.w	0			;pos in undo buf
		dc.w	0			;# chr in buf
		dc.w	0			;# chr disp
		dc.w	0,0			;top x,y
		dc.l	0			;ptr layer
		dc.l	0			;result if int gadget
		dc.l	0			;ptr alt key map

;	check

ctlch:		dc.l	ctlpl			;ptr nxt gadget
		dc.w	ctlchx,ctlchy		;top x,y
		dc.w	ctlchw,ctlchh		;width, height
		dc.w	GADGHCOMP		;flags
		dc.w	RELVERIFY		;activation
		dc.w	BOOLGADGET		;gadget type
		dc.l	0			;ptr gadget render
		dc.l	0			;ptr select render
		dc.l	0			;ptr gadget txt
		dc.l	0			;mutual exclude
		dc.l	0			;ptr spec info
		dc.w	chid			;id#
		dc.l	0			;ptr user data

;	plus

ctlpl:		dc.l	ctlmi			;ptr nxt gadget
		dc.w	ctlplx,ctlply		;top x,y
		dc.w	ctlplw,ctlplh		;width, height
		dc.w	GADGHCOMP		;flags
		dc.w	RELVERIFY		;activation
		dc.w	BOOLGADGET		;gadget type
		dc.l	0			;ptr gadget render
		dc.l	0			;ptr select render
		dc.l	0			;ptr gadget txt
		dc.l	0			;mutual exclude
		dc.l	0			;ptr spec info
		dc.w	plid			;id#
		dc.l	0			;ptr user data

;	minus

ctlmi:		dc.l	ctlcp			;ptr nxt gadget
		dc.w	ctlmix,ctlmiy		;top x,y
		dc.w	ctlmiw,ctlmih		;width, height
		dc.w	GADGHCOMP		;flags
		dc.w	RELVERIFY		;activation
		dc.w	BOOLGADGET		;gadget type
		dc.l	0			;ptr gadget render
		dc.l	0			;ptr select render
		dc.l	0			;ptr gadget txt
		dc.l	0			;mutual exclude
		dc.l	0			;ptr spec info
		dc.w	miid			;id#
		dc.l	0			;ptr user data

;	compare

ctlcp:		dc.l	0			;ptr nxt gadget
		dc.w	ctlcpx,ctlcpy		;top x,y
		dc.w	ctlcpw,ctlcph		;width, height
		dc.w	GADGHCOMP		;flags
		dc.w	RELVERIFY		;activation
		dc.w	BOOLGADGET		;gadget type
		dc.l	0			;ptr gadget render
		dc.l	0			;ptr select render
		dc.l	0			;ptr gadget txt
		dc.l	0			;mutual exclude
		dc.l	0			;ptr spec info
		dc.w	cpid			;id#
		dc.l	0			;ptr user data

;	generic intuitext struct

genit:		dc.b	winbp,windp		;front, back pen
		dc.b	RP_JAM2 		;draw mode
		dc.b	0			;word align fill
		dc.w	0,0			;top x,y
		dc.l	0			;ptr font
genitptr:	dc.l	0			;ptr text, (to be set)
		dc.l	0			;ptr next intui text

;	requester first bodytext intuitext struct

membt1: 	dc.b	windp,winbp		;front, back pen
		dc.b	RP_JAM2 		;draw mode
		dc.b	0			;word align fill
		dc.w	2*chrw,chrh		;top x,y
		dc.l	0			;ptr font
		dc.l	memmsg			;ptr text
		dc.l	membt2			;ptr next intui text

;	requester second bodytext intuitext struct

membt2: 	dc.b	windp,winbp		;front, back pen
		dc.b	RP_JAM2 		;draw mode
		dc.b	0			;word align fill
		dc.w	2*chrw,3*chrh		;top x,y
		dc.l	0			;ptr font
membt2ptr:	dc.l	0			;ptr text, (to be set)
		dc.l	0			;ptr next intui text

;	requester negative intuitext struct

memnt:		dc.b	windp,winbp		;front, back pen
		dc.b	RP_JAM2 		;draw mode
		dc.b	0			;word align fill
		dc.w	7,3			;top x,y
		dc.l	0			;ptr font
		dc.l	1$			;ptr text
		dc.l	0			;ptr next intui text

1$:		dc.b	'Continue',0

;	generic border struct, for boxes (5 pairs)

genbd:		dc.w	0,0			;top x,y
		dc.b	winbp,windp		;front, back pen
		dc.b	RP_JAM2 		;draw mode
		dc.b	5			;# coord pairs
genbdptr:	dc.l	0			;ptr coord pairs, (to be set)
		dc.l	0			;nxt border

;	library pointers

libstart:
dosbase:	dc.l	0
intbase:	dc.l	0
		dc.l	-1			;last

;	various initialized data
;	long

chgcnt: 	dcb.l	4,0			;change count for each drive

;	word

chkcnt: 	dc.w	0			;no of checked disks
instcnt:	dc.w	0			;no of installed disks
vircnt: 	dc.w	0			;no of nonstd bootblocks

;	byte
;	for file name string gadget

strbuf: 	dc.b	'ngcbb:',0              ;initial value
strbuf1:
		ds.b	strbufsiz-(strbuf1-strbuf-1) ;remaining
undobuf:	dc.b	0			;empty a start
		ds.b	strbufsiz
lastdrv:	dc.b	0			;last drive # used

;	various uninitialized data
;	long

spsave: 	ds.l	1			;init sp

		end

