	opt	a+,c+,o+
	;opt	d+,x+		;comment line for stripped,
				;uncomment for unstripped

	incdir	"ainclude:"		;your asm include dir

	include	"exec/exec_lib.i"
	include	"intuition/screens.i"
	include	"intuition/intuition.i"
	include	"intuition/intuition_lib.i"
	include	"devices/console.i"
	include	"devices/console_lib.i"
	include	"libraries/amiga.lib.i"	;my asm versions of
					;amiga.lib routines
					
INTUITION_REV	equ	31		;v1.1

;Exports
	XDEF	MakeWindow
	XDEF	ClearWindow
	XDEF	GetWindowSize
	XDEF	WindowTitle
	XDEF	SetFont
	XDEF	GetC
	XDEF	CharOut
	XDEF	BackSpace
	XDEF	CStrin
	XDEF	CStrout
	XDEF	Strin
	XDEF	Strout
	XDEF	NewLine
	XDEF	Spaces
	XDEF	DecIn
	XDEF	DecIn_Long
	XDEF	DecOut
	XDEF	DecOut_Long
	XDEF	HexIn
	XDEF	HexIn_Long
	XDEF	HexOut
	XDEF	HexOut_Long
	XDEF	DivuLW
	XDEF	Rand
	XDEF	ResetRand
	XDEF	Seed
	XDEF	IOExit
	XDEF	WaitForEvent
	XDEF	AskYesNo
	XDEF	WrtIOInfo
	XDEF	_SysBase
	XDEF	RangeSeed
	XDEF	startup

;Imports
	XREF	_IntuitionBase
	XREF	IOPackWindow

startup	clr.l	_IntuitionBase
	clr.l	IOPackWindow		
	clr.l	write_req		;initialize
	clr.l	write_port
	clr.l	read_req
	clr.l	read_port
	clr.b	_ConBlock

	moveq	#INTUITION_REV,d0		;open intuition library
	lea	int_name,a1		;the only given library
	CALLEXEC	OpenLibrary		;any others must be opened
	move.l	d0,_IntuitionBase		;by the user
exit_startup	rts
 

*******************************************************************************
*
*  MakeWindow.......Make the window.
*
*  input:
*    A0: ptr to title string
*
*  output:
*    D0: 0L if error, non-zero if no error
*
*  NOTE: This routine will open a window the full size of the screen minus
*        the screens top border (so that you can drag).  The window can be
*        resized, depth arranged, and dragged.  There is no close button
*        since there is no way of handling it in the IOPack way of doing
*        things.
*
*******************************************************************************

MakeWindow	movem.l	d1-d7/a0-a6,-(sp)		;a0 = ptr to window title
	move.l	a0,-(sp)
					;***USE MY ROUTINES***
	moveq	#0,d0			;clr.l	-(sp);setup write port
	lea	iopack_write_port,a0	;pea	iopack_write_port
	jsr	CreatePort		;jsr	_CreatePort
					;addq.w	#8,sp
	move.l	d0,write_port
	beq	exit_window_CS

	move.l	d0,a0			;pea	(IOSTD_SIZE).W;setup write IO request
	moveq	#IOSTD_SIZE,d0		;move.l	d0,-(sp);block (d0 = write_port)
	jsr	CreateExtIO		;jsr	_CreateExtIO
					;addq.w	#8,sp
	move.l	d0,write_req
	beq	exit_window_CS

	moveq	#0,d0			;clr.l	-(sp);setup read port
	lea	iopack_read_port,a0		;pea	iopack_read_port
	jsr	CreatePort		;jsr	_CreatePort
					;addq.w	#8,sp
	move.l	d0,read_port
	beq	exit_window_CS

	move.l	d0,a0			,pea	(IOSTD_SIZE).W;setup read IO request
	moveq	#IOSTD_SIZE,d0		;move.l	d0,-(sp);block (d0 = read_port)
	jsr	CreateExtIO		;jsr	_CreateExtIO
					;addq.w	#8,sp
	move.l	d0,read_req
	beq	exit_window_CS

	;lea	SomeScreenDat,a0		;get wbenchscreen data
	movea.l	#SomeScreenDat,a0		;get wbenchscreen data
	moveq	#sc_WBorTop,d0
	moveq	#WBENCHSCREEN,d1
	CALLINT	GetScreenData
	beq	exit_window_CS

	;lea	MyNewWindow,a0		;fill in window info
	move.l	#MyNewWindow,a0		;fill in window info
	;lea	SomeScreenDat,a1
	move.l	#SomeScreenDat,a1
	move.w	#0,nw_LeftEdge(a0)
	move.w	sc_Width(a1),nw_Width(a0)
	moveq	#0,d1
	move.w	sc_Height(a1),d0
	move.b	sc_BarHeight(a1),d1
	addq.w	#1,d1
	sub.w	d1,d0
	move.w	d1,nw_TopEdge(a0)
	move.w	d0,nw_Height(a0)
	move.b	#0,nw_DetailPen(a0)
	move.b	#1,nw_BlockPen(a0)
	move.l	(sp)+,nw_Title(a0)
_temp	set	SMART_REFRESH|ACTIVATE|WINDOWSIZING
	move.l	#_temp|WINDOWDRAG|WINDOWDEPTH,nw_Flags(a0)
	move.l	#0,nw_IDCMPFlags(a0)
	move.w	#WBENCHSCREEN,nw_Type(a0)
	clr.l	nw_FirstGadget(a0)
	clr.l	nw_CheckMark(a0)
*	move.l	#0,nw_Screen(a0)
	clr.l	nw_BitMap(a0)
	move.w	#100,nw_MinWidth(a0)
	move.w	#25,nw_MinHeight(a0)
	move.w	#640,nw_MaxWidth(a0)
	move.w	#200,nw_MaxHeight(a0)

	;CALLINT	OpenWindow		;open window
	jsr	_LVOOpenWindow(a6)
	move.l	d0,IOPackWindow
	beq.s	exit_window

	opt	a-
	move.l	write_req,a1		;attach console
	opt	a+
	move.l	IOPackWindow,IO_DATA(a1)
	move.l	#wd_Size,IO_LENGTH(a1)
	lea	console_name,a0
	moveq	#0,d0
	move.l	d0,d1
	CALLEXEC	OpenDevice
	tst.l	d0
	seq	d0
	move.b	d0,_ConBlock
	beq.s	exit_window
	opt	a-
	move.l	write_req,a0
	move.l	read_req,a1
	opt	a+
	move.l	IO_DEVICE(a0),IO_DEVICE(a1)
	move.l	IO_UNIT(a0),IO_UNIT(a1)

	;lea	char_buf,a2
	move.l	#char_buf,a2
	jsr	QueueRead

	moveq	#-1,d0
	bra.s	exit_window

exit_window_CS	addq.l	#4,sp

exit_window	movem.l	(sp)+,d1-d7/a0-a6
	rts

*******************************************************************************
*
*  ClearWindow......Home cursor and clear window.
*
*******************************************************************************

ClearWindow	movem.l	d0/a0,-(sp)
	jsr	IsWindow
	tst.l	d0
	beq.s	end_clw
	lea	clear_buf,a0		;send codes for home and
	jsr	CStrout			;clear to end
end_clw	movem.l	(sp)+,d0/a0
	rts

*******************************************************************************
*
*  GetWindowSize....Return the size of the window.
*
*  output:
*    D0.L: upper word - width of the window
*          lower word - height of the window
*
*******************************************************************************

GetWindowSize	move.l	a0,-(sp)
	jsr	IsWindow
	tst.l	d0
	beq.s	end_gws
	move.l	IOPackWindow,a0		;reach into that window
	move.w	wd_Width(a0),d0		;struct and get out
	swap	d0			;height and width
	move.w	wd_Height(a0),d0
end_gws	move.l	(sp)+,a0
	rts

*******************************************************************************
*
*  WindowTitle......Change the title of the window.
*
*  input:
*    A0: ptr to new title string
*
*******************************************************************************

WindowTitle	movem.l	d0/d1/a0/a1/a2/a6,-(sp)
	jsr	IsWindow
	tst.l	d0
	beq.s	end_wtt
	move.l	a0,a1			;SetWindowTitles(a0,a1,-1L)
	move.l	IOPackWindow,a0
	move.l	#-1,a2
	CALLINT	SetWindowTitles
end_wtt	movem.l	(sp)+,d0/d1/a0/a1/a2/a6
	rts

*******************************************************************************
*
*  SetFont..........Change the style of the font.
*
*  input:
*    D2.W: font style (-1-Plain, 0-Bold, 1-Italic, 2-Underline)
*
*  NOTE: Mac version allows for Font and Size change.  For compatibility
*        reasons, the Amiga version does not do this.  In other words, the
*        Amiga does not have Chicago, Geneva, or Monaco for standard fonts.
*        Likewise, Mac styles 3-6 (Outline, Shadow, Condense, and Extend)
*        do nothing and are not implemented.  This routine will just ignore
*        what it cannot do.
*
*******************************************************************************

SetFont	movem.l	d0/a0,-(sp)
	jsr	IsWindow
	tst.l	d0
	beq.s	End_SetFont
	tst.w	d2			;send control codes for
	bne.s	italic			;respective actions
bold	lea	bold_buf,a0
	bra.s	End_SetFont
italic	cmpi.w	#1,d2
	bne.s	underline
	lea	italic_buf,a0
	bra.s	End_SetFont
underline	cmpi.w	#2,d2
	bne.s	plain
	lea	underline_buf,a0
	bra.s	End_SetFont
plain	cmpi.w	#-1,d2
	bne.s	End_SetFont
	lea	plain_buf,a0
End_SetFont	jsr	CStrout
	movem.l	(sp)+,d0/a0
	rts

*******************************************************************************
*
*  GetC.............Get a character from the keyboard.
*
*  output:
*    D0.B: character read in
*
*******************************************************************************

GetC	movem.l	d1/a0/a1/a2/a3/a6,-(sp)
	jsr	IsWindow
	tst.l	d0
	beq.s	end_GC
	move.l	d0,-(sp)
	;lea	char_buf,a2
	move.l	#char_buf,a2
	opt	a-
	movea.l	read_port,a3
	opt	a+
	movea.l	a3,a0
	CALLEXEC	WaitPort			;wait for a character
	movea.l	a3,a0
	jsr	_LVOGetMsg(a6)		;get the message with the char
	move.b	(a2),d1
	move.l	d0,a1
	jsr	QueueRead			;queue up next read
	move.l	(sp)+,d0
	move.b	d1,d0
end_GC	movem.l	(sp)+,d1/a0/a1/a2/a3/a6
	rts

*******************************************************************************
*
*  QueueRead........Queue up a character from the keyboard.
*
*******************************************************************************

QueueRead	movem.l	d0/d1/a0/a1/a6,-(sp)
	move.w	#CMD_READ,IO_COMMAND(a1)	;a1 = read_req
	move.l	a2,IO_DATA(a1)		;a2 = char_buf
	moveq	#1,d0
	move.l	d0,IO_LENGTH(a1)
	CALLEXEC	SendIO
	movem.l	(sp)+,d0/d1/a0/a1/a6
	rts

*******************************************************************************
*
*  CharOut..........Output a character to the window.
*
*  input:
*    D0.B: character to output
*
*******************************************************************************

CharOut	movem.l	d0/d1/a0/a1/a6,-(sp)
	movem.l	d0,-(sp)
	jsr	IsWindow
	tst.l	d0
	movem.l	(sp)+,d0
	beq.s	end_CHRO
	opt	a-
	movea.l	write_req,a1
	opt	a+
	move.w	#CMD_WRITE,IO_COMMAND(a1)	;set command write
	move.b	d0,char_buf		;put chat in buf
	;lea	char_buf,a0
	move.l	#char_buf,a0
	move.l	a0,IO_DATA(a1)		;set attributes
	moveq	#1,d0
	move.l	d0,IO_LENGTH(a1)
	CALLEXEC	DoIO			;send request
end_CHRO	movem.l	(sp)+,d0/d1/a0/a1/a6
	rts

*******************************************************************************
*
*  BackSpace........Delete the character to the left of the cursor.
*
*******************************************************************************

BackSpace	movem.l	d0/a0,-(sp)
	jsr	IsWindow
	tst.l	d0
	beq.s	end_BSP
	lea	delete_buf,a0
	jsr	CStrout			;send control codes to
end_BSP	movem.l	(sp)+,d0/a0			;delete character
	rts

*******************************************************************************
*
*  CStrin...........Input a CR delimited string.
*
*  input:
*    A0.L: address of buffer to store string
*    D0.W: size of the buffer
*
*  output:
*    A0.L: address of string (same as input)
*    D0.W: Number of characters actually read in, 0 <= D0.W.out <= D0.W.in-1
*
*  NOTE: The string will be null terminated and will not have a CR in it.
*        The Mac version uses strings where string[0] = len(string).
*
*******************************************************************************

CStrin	movem.l	d1/d2/a0,-(sp)
	movem.l	d0,-(sp)
	jsr	IsWindow
	tst.l	d0
	movem.l	(sp)+,d0
	beq.s	EndCStrin
	move.w	d0,d1
	beq.s	EndCStrin
	subq.w	#2,d1			;get 1 less than buf size
	moveq	#0,d2
Cloop	jsr	GetC			;get a char
	cmp.b	#$08,d0			;is delete?
	bne.s	notdelete
	tst.l	d2
	beq.s	Cloop
del	subq.l	#1,a0			;if so, fix vars
	subq.l	#1,d2
	addq.w	#1,d1
	jsr	BackSpace
	bra.s	Cloop			;go get another
notdelete	cmp.b	#$0d,d0			;is CR?
	beq.s	quickend			;if so, end
	jsr	CharOut			;else output that char
	addq.w	#1,d2
	move.b	d0,(a0)+
	dbra	d1,Cloop			;is buffer-1 full?
notquick	jsr	GetC			;yes, then get last char
	cmp.b	#$08,d0
	beq.s	del
	cmp.b	#$0d,d0
	bne.s	notquick
quickend	move.b	#0,(a0)
	move.w	d2,d0
EndCStrin	movem.l	(sp)+,d1/d2/a0
	rts

*******************************************************************************
*
*  CStrout..........Output a C string.
*
*  input:
*    A0: address of string to output, must be null terminated
*
*  NOTE: Mac strings in IOPack have string[0] = len(string).  Amiga
*        strings are C or Unix style null terminated strings.
*
*******************************************************************************

CStrout	movem.l	d0/d1/a0/a1/a6,-(sp)
	jsr	IsWindow
	tst.l	d0
	beq.s	end_CSTRO
	opt	a-
	movea.l	write_req,a1
	opt	a+
	move.w	#CMD_WRITE,IO_COMMAND(a1)	;send packet with length
	move.l	a0,IO_DATA(a1)		;-1 for null strings
	move.l	#-1,IO_LENGTH(a1)
	CALLEXEC	DoIO
end_CSTRO	movem.l	(sp)+,d0/d1/a0/a1/a6
	rts

*******************************************************************************
*
*  Strin............Input a counted string
*
*  input:
*    A0.L: address of buffer to store string
*    D0.W: Maximum number of characters to read in
*
*  output:
*    A0.L: address of string buffer (same as input)
*    D0.W: number of characters actually read in
*
*******************************************************************************

Strin	movem.l	d1/d2/a0,-(sp)		;see CStrin, same but no
	movem.l	d0,-(sp)
	jsr	IsWindow			;null termination
	tst.l	d0
	movem.l	(sp)+,d0
	beq.s	EndStrin
	move.w	d0,d1
	beq.s	EndStrin
	subq.w	#1,d1
	moveq	#0,d2
Sloop	jsr	GetC
	cmp.b	#$08,d0
	bne.s	notdelete2
	tst.l	d2
	beq.s	Sloop
del2	subq.l	#1,a0
	subq.l	#1,d2
	addq.w	#1,d1
	jsr	BackSpace
	bra.s	Sloop
notdelete2	jsr	CharOut
	addq.w	#1,d2
	move.b	d0,(a0)+
	cmp.b	#$0d,d0
	dbeq	d1,Sloop
	cmp.b	#$0d,d0
	bne.s	notquick2
	subq.w	#1,d2
	bra.s	quickend2
notquick2	jsr	GetC
	cmp.b	#$08,d0
	beq.s	del2
	cmp.b	#$0d,d0
	bne.s	notquick2
quickend2	move.w	d2,d0
EndStrin	movem.l	(sp)+,d1/d2/a0
	rts

*******************************************************************************
*
*  Strout...........Output a counted string.
*
*  input:
*    A0.L: address of string to output
*    D0.W: length of the string
*
*******************************************************************************

Strout	movem.l	d0/d1/a0/a1/a6,-(sp)
	movem.l	d0,-(sp)
	jsr	IsWindow
	tst.l	d0
	movem.l	(sp)+,d0
	beq.s	end_STRO
	opt	a-
	movea.l	write_req,a1
	opt	a+
	move.w	#CMD_WRITE,IO_COMMAND(a1)	;send a packet of passed
	move.l	a0,IO_DATA(a1)		;length size
	moveq	#0,d1
	move.w	d0,d1
	move.l	d1,IO_LENGTH(a1)
	CALLEXEC	DoIO
end_STRO	movem.l	(sp)+,d0/d1/a0/a1/a6
	rts

*******************************************************************************
*
*  NewLine..........Move cursor to beginning of next line.
*
*******************************************************************************

NewLine	movem.l	d0/a0,-(sp)
	jsr	IsWindow
	tst.l	d0
	beq.s	end_NL
	lea	newline_buf,a0		;send newline codes
	jsr	CStrout
end_NL	movem.l	(sp)+,d0/a0
	rts

*******************************************************************************
*
*  Spaces...........Output given number of spaces
*
*  input:
*    D0.W: number of spaces
*
*******************************************************************************

Spaces	movem.l	d0/d1/a0,-(sp)
	movem.l	d0,-(sp)
	jsr	IsWindow
	tst.l	d0
	movem.l	(sp)+,d0
	beq.s	end_spac
	move.w	d0,d1
	beq.s	end_spac			;if 0 then end
	subq.w	#1,d1			;else loop-print spaces
	moveq	#' ',d0
sploop	jsr	CharOut
	dbra	d1,sploop
end_spac	movem.l	(sp)+,d0/d1/a0
	rts

*******************************************************************************
*
*  DecIn............Input a decimal number (word size).
*
*  output:
*    D0.W: binary equivalent of decimal number
*
*******************************************************************************

DecIn	movem.l	d1/d2/d3/d4/d5/d6/a0,-(sp)
	move.l	d0,d6			;setup for ReadNum
	moveq	#6,d0			;number of ascii chars in word
	moveq	#0,d4			;d4=0 means word size
	bra.s	ReadNum

*******************************************************************************
*
*  DecIn_Long.......Input a decimal number (long size)
*
*  output:
*    D0.L: binary equivalent of decimal number
*
*******************************************************************************

DecIn_Long	movem.l	d1/d2/d3/d4/d5/d6/a0,-(sp)
	move.l	d0,d6			;setup for ReadNum
	moveq	#11,d0			;number of ascii chars in long
	moveq	#1,d4			;d4=1 means long size

ReadNum	jsr	IsWindow
	tst.l	d0
	beq.s	EndDecIn
	moveq	#0,d1
	move.l	d1,d2
	move.l	d1,d3
	;lea	DecInBuf,a0
	move.l	#DecInBuf,a0
	jsr	Strin		;this thing works by getting a char,
	bne.s	conv_num		;if there's another char then multiply
	moveq	#0,d3		;by ten and add.  loop until no more
	bra.s	clean_readnum	;chars
conv_num	subq.w	#1,d0
	cmpi.b	#'-',(a0)
	bne.s	NumCheck
	moveq	#1,d1
	addq.l	#1,a0
	subq.w	#1,d0
	bra.s	DoNum
NumCheck	cmp.b	#$30,(a0)
	bcc.s	DoNum
	addq.l	#1,a0
	subq.w	#1,d0
DoNum	move.l	d3,d5
	lsl.l	#1,d3			;multiply
	lsl.l	#3,d5			;by
	add.l	d5,d3			;10 in a weird way
	move.b	(a0)+,d2
	andi.b	#$0f,d2
	add.l	d2,d3
	dbra	d0,DoNum
clean_readnum	tst.b	d4
	bne.s	Long
Short	move.l	d6,d0
	move.w	d3,d0
	tst.b	d1
	beq.s	EndDecIn
SNeg	neg.w	d0
	bra.s	EndDecIn
Long	move.l	d3,d0
	tst.b	d1
	beq.s	EndDecIn
LNeg	neg.l	d0
EndDecIn	movem.l	(sp)+,d1/d2/d3/d4/d5/d6/a0
	rts

*******************************************************************************
*
*  DecOut...........Output a decimal number (word size).
*
*  input:
*    D0.W: binary equivalent of decimal number
*
*******************************************************************************

STKPTR	equr	a0
DIVBASE	equr	d4
BASETEN	set	10			;output base
STK_SIZE	set	5			;max number of ascii chars
					;in word size decimal number

DecOut	movem.l	d0-d4/a0,-(sp)
	movem.l	d0,-(sp)
	jsr	IsWindow
	tst.l	d0
	movem.l	(sp)+,d0
	beq.s	end_deco
	;lea	StackEnd,STKPTR
	move.l	#StackEnd,STKPTR
	move.l	STKPTR,d2
	moveq	#0,d1
	move.b	d1,StackEnd
	move.w	d0,d1
	bpl.s	CONVPOS
CONVNEG	neg.w	d1
	moveq	#'-',d0
	jsr	CharOut
CONVPOS	move.l	d1,d0
	moveq	#BASETEN,DIVBASE
	moveq	#$30,d3
DIVIT	divu	DIVBASE,d0		;loop dividing by 10 each
	swap	d0			;time
	or.b	d3,d0
	move.b	d0,-(STKPTR)
	clr.w	d0
	swap	d0
	bne.s	DIVIT
ENDDIV	jsr	CStrout
end_deco	movem.l	(sp)+,d0-d4/a0
	rts

*******************************************************************************
*
*  DecOut_Long......Output a decimal number (long size).
*
*  input:
*    D0.L: binary equivalent of decimal number
*
*******************************************************************************

BASETEN	set	10

DecOut_Long	movem.l	d0-d4/a0,-(sp)	;same as DecOut, but
	movem.l	d0,-(sp)
	jsr	IsWindow
	tst.l	d0
	movem.l	(sp)+,d0
	beq.s	end_decol
	;lea	StackEnd2,STKPTR
	move.l	#StackEnd2,STKPTR
	move.l	STKPTR,d2
	moveq	#0,d1
	move.b	d1,StackEnd2
	move.l	d0,d1
	bpl.s	CONVPOSL
CONVNEGL	neg.l	d1
	moveq	#'-',d0
	jsr	CharOut
CONVPOSL	move.l	d1,d0
	moveq	#$30,d3
DIVITL	moveq	#BASETEN,d1
	jsr	DivuLW
	or.b	d3,d1
	move.b	d1,-(STKPTR)
	tst.l	d0
	bne.s	DIVITL
ENDDIVL	jsr	CStrout
end_decol	movem.l	(sp)+,d0-d4/a0
	rts

*******************************************************************************
*
*  HexIn............Input a hex number (word size).
*
*  output:
*    D0.W: binary equivalent of hex number
*
*******************************************************************************

HexIn	movem.l	d1/d2/d4/d6/a0,-(sp)
	move.l	d0,d6		;setup vars for passing to ReadHex
	moveq	#4,d0		;size
	moveq	#0,d4		;d4=0 means word size
	move.w	d4,d2
	bra.s	ReadHex

*******************************************************************************
*
*  HexIn_Long.......Input a hex number (long size).
*
*  output:
*    D0.L: binary equivalent of hex number
*
*******************************************************************************

HexIn_Long	movem.l	d1/d2/d4/d6/a0,-(sp)
	move.l	d0,d6		;setup vars for passing to ReadHex
	moveq	#8,d0		;size
	moveq	#1,d4		;d4=1 means long size
	moveq	#0,d2

ReadHex	jsr	IsWindow
	tst.l	d0
	beq.s	end_ReadHex
	;lea	DecInBuf,a0
	move.l	#DecInBuf,a0
	jsr	Strin
	bne.s	conv_hex
	moveq	#0,d2
	bra.s	clean_readhex
conv_hex	subq.w	#1,d0
	move.w	d0,d1
readhex_loop	move.b	(a0)+,d0
	jsr	ASCIItoHex	;loop through converting ascii to
	tst.b	d4		;to hex and shifting left by 4
	bne.s	long_shift
	lsl.w	#4,d2
	bra.s	past_shift
long_shift	lsl.l	#4,d2
past_shift	or.b	d0,d2
	dbra	d1,readhex_loop
clean_readhex	move.l	d2,d0
	tst.b	d4
	bne.s	end_ReadHex
	move.l	d6,d0
	move.w	d2,d0
end_ReadHex	movem.l	(sp)+,d1/d2/d4/d6/a0
	rts

*******************************************************************************
*
*  HexOut...........Output a hex number (word size).
*
*  input:
*    D0.W: binary equivalent of number
*
*******************************************************************************

HexOut	movem.l	d0-d2/a0,-(sp)
	movem.l	d0,-(sp)
	jsr	IsWindow
	tst.l	d0
	movem.l	(sp)+,d0
	beq.s	end_hxo
	move.w	d0,d1
	moveq	#3,d2
hxloop	rol.w	#4,d1
	move.b	d1,d0
	jsr	HextoASCII	;convert to ascii and
	jsr	CharOut		;print
	dbra	d2,hxloop
end_hxo	movem.l	(sp)+,d0-d2/a0
	rts

*******************************************************************************
*
*  HexOut_Long......Output a hex number (long size).
*
*  input:
*    D0.W: binary equivalent of number
*
*******************************************************************************

HexOut_Long	movem.l	d0-d2/a0,-(sp)
	movem.l	d0,-(sp)
	jsr	IsWindow
	tst.l	d0
	movem.l	(sp)+,d0
	beq.s	end_hxol
	move.l	d0,d1
	moveq	#7,d2
hxlloop	rol.l	#4,d1
	move.b	d1,d0
	jsr	HextoASCII	;convert to ascii
	jsr	CharOut		;and print
	dbra	d2,hxlloop
end_hxol	movem.l	(sp)+,d0-d2/a0
	rts

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

HextoASCII	andi.b	#$0f,d0
	ori.b	#$30,d0
	cmpi.b	#$3a,d0
	bcs.s	end_HextoASCII
	addq.b	#7,d0
end_HextoASCII	rts

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

ASCIItoHex	cmpi.b	#$41,d0
	bcs.s	end_ASCIItoHex
	subq.b	#7,d0
end_ASCIItoHex	andi.b	#$0f,d0
	rts

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

*******************************************************************************
*
*  DivuLW...........Divide unsigned longword by word
*                   and return quotient and remainder.
*
*  input:
*    D0.L: dividend
*    D1.W: divisor
*
*  output:
*    D0.L: quotient
*    D1.W: remainder
*
*  NOTE: Mac version does not return remainder
*
*******************************************************************************

DivuLW	move.l	d2,-(sp)		;in d0.l dividend
	moveq	#0,d2		;in d1.w divisor
	swap	d0		;out d0.l quotient
	move.w	d0,d2		;out d1.w remainder
	divu	d1,d2
	move.w	d2,d0		;fancy footsteps
	swap	d0
	move.w	d0,d2
	divu	d1,d2
	move.w	d2,d0
	swap	d2
	move.w	d2,d1
	move.l	(sp)+,d2
	rts

*******************************************************************************
*
*  Rand.............Make a 16 bit random number.
*
*  output:
*    D0.W: random number
*
*******************************************************************************

Rand	move.l	d1,-(sp)
	move.l	d0,-(sp)
	move.l	RangeSeed,d0
	move.w	d0,d1
	addi.l	#5246957,d0	;just do anything
adum	add.l	d0,d0		;so that the numbers
	lsr.w	#1,d1		;aren't sequential
	bne.s	adum
	move.l	d0,RangeSeed	;make new seed
	clr.w	d0
	swap	d0
	move.l	d0,d1
	move.l	(sp)+,d0
	move.w	d1,d0
	move.l	(sp)+,d1
	rts

*******************************************************************************
*
*  ResetRand........Restart the random number generator.
*
*******************************************************************************

ResetRand	move.l	dummy2,RangeSeed
	rts

*******************************************************************************
*
*  Seed.............Randomize the random number generator.
*
*******************************************************************************

Seed	movem.l	d0/d1/a0/a1/a6,-(sp)
	lea	dummy1,a0
	lea	dummy2,a1
	CALLINT	CurrentTime	;get intuition type time for seed
	move.l	dummy2,RangeSeed
	movem.l	(sp)+,d0/d1/a0/a1/a6
	rts
dummy1	dc.l	0
dummy2	dc.l	0
RangeSeed	dc.l	0

*******************************************************************************
*
*  IOExit...........Cleanup and terminate program.
*
*  NOTE: You must JSR to this routine in order to stay compatible with the
*        Mac version.  I think it's unnecessary and is kinda weird looking.
*        It makes you think IOExit comes back!
*
*******************************************************************************

IOExit	addq.l	#4,SP			;fix stack
	tst.b	_ConBlock			;check console
	beq.s	check_read_req
	opt	a-
	move.l	read_req,a1
	opt	a+
	CALLEXEC	CheckIO			;standard request aborts
	tst.l	d0
	bne.s	wait_io
	opt	a-
	move.l	read_req,a1
	opt	a+
	jsr	_LVOAbortIO(a6)
	opt	a-
wait_io	move.l	read_req,a1
	opt	a+
	jsr	_LVOWaitIO(a6)

	opt	a-
	move.l	write_req,a1
	opt	a+
	jsr	_LVOCloseDevice(a6)

	opt	a-
check_read_req	move.l	read_req,d0		;check read request
	opt	a+
	beq.s	check_read_port
					;***USE MY OWN ROUTINES***
	move.l	d0,a0			;move.l	d0,-(sp)
	jsr	DeleteExtIO		;jsr	_DeleteExtIO
					;addq.l	#4,sp
	opt	a-
check_read_port	move.l	read_port,d0		;check read port
	opt	a+
	beq.s	check_write_req
	move.l	d0,a0			;move.l	d0,-(sp)
	jsr	DeletePort		;jsr	_DeletePort
					;addq.l	#4,sp
	opt	a-
check_write_req	move.l	write_req,d0		;check write request
	opt	a+
	beq.s	check_write_port
	move.l	d0,a0			;move.l	d0,-(sp)
	jsr	DeleteExtIO		;jsr	_DeleteExtIO
					;addq.l	#4,sp
	opt	a-
check_write_port	move.l	write_port,d0		;check write port
	opt	a+
	beq.s	check_window
	move.l	d0,a0			;move.l	d0,-(sp)
	jsr	DeletePort		;jsr	_DeletePort
					;addq.l	#4,sp
check_window	move.l	IOPackWindow,d0		;check window
	beq.s	check_intuition
	move.l	d0,a0
	CALLINT	CloseWindow

check_intuition	move.l	_IntuitionBase,d0		;check intuition
	beq.s	exit_cleanexit
	move.l	d0,a1
	CALLEXEC	CloseLibrary

exit_cleanexit	moveq	#0,d0
	rts

*******************************************************************************
*
*  WaitForEvent.....Wait for a key press.
*
*  NOTE: The Mac version also let you hit the mouse button to continue.
*        Mine does not.  I will add this later.
*
*******************************************************************************

WaitForEvent	move.l	d0,-(sp)
	jsr	GetC			;just a getc and throw away
	move.l	(sp)+,d0
	rts

*******************************************************************************
*
*  AskYesNo.........Autorequest a Yes/No question.
*
*  input:
*    A0: ptr to question string
*
*  output:
*    Z bit set if Yes, clear if No
*
*  NOTE: I never saw what the Mac version did, but I decided to make mine
*        an Amiga standard requester.
*
*******************************************************************************

AskYesNo	movem.l	d0/d1/d2/d3/a0/a1/a2/a3/a6,-(sp)
	jsr	IsWindow
	tst.l	d0
	beq.s	end_AskYesNo
	move.l	a0,Body_String
	move.l	IOPackWindow,a0		;setup AutoRequest
	lea	Body_text,a1		;stuff
	lea	Positive_text,a2
	lea	Negative_text,a3
	moveq	#0,d0
	move.l	d0,d1
	move.w	#640,d2
	move.w	#50,d3
	CALLINT	AutoRequest
	tst.l	d0
	beq.s	false_resp
true_resp	moveq	#0,d0			;set Z flag accordingly
	bra.s	end_AskYesNo
false_resp	moveq	#1,d0
end_AskYesNo	movem.l	(sp)+,d0/d1/d2/d3/a0/a1/a2/a3/a6
	rts

*******************************************************************************
*
*  WrtIOInfo........Write copyright and ordering info.
*
*******************************************************************************

WrtIOInfo	move.l	a0,-(sp)
	lea	IOInfo,a0
	jsr	CStrout
	jsr	NewLine
	move.l	(sp)+,a0
	rts

*******************************************************************************
*
*  IsWindow.........Determine if there is a window to write into.  This
*                   routine will try to open a window if one is not already
*                   open.
*
*  output:
*    D0.L: 0L if error, else -1L.
*
*******************************************************************************

IsWindow	tst.l	IOPackWindow
	bne.s	win_open
	move.l	a0,-(sp)
	lea	default_window_nm,a0
	jsr	MakeWindow
	move.l	(sp)+,a0
	rts
win_open	moveq	#-1,d0
	rts

CreatePort	CreatePortMac

DeletePort	DeletePortMac

CreateExtIO	CreateExtIOMac

DeleteExtIO	DeleteExtIOMac

* DC's

int_name		INTNAME
default_window_nm	dc.b	'Default Window',0
iopack_write_port	dc.b	'IOPack.write.port',0
iopack_read_port	dc.b	'IOPack.read.port',0
console_name	dc.b	'console.device',0
IOInfo	dc.b	'Copyright © 1991 Mark Thomas',13,10
	dc.b	'Released into the Public Domain',13,10
	dc.b	'Available at UT Austin (V1.04)',13,10
	dc.b	'from amigamat@ccwf.cc.utexas.edu',13,10,13,10
	dc.b	'Thanks to Beta-Testers:',13,10
	dc.b	'Paul Norrod and Robert Faulkner',0
clear_buf	dc.b	$1b,'[0;0H',$1b,'[J',0
delete_buf	dc.b	$08,$1b,'[P',0
newline_buf	dc.b	$0a,$0d,0
bold_buf	dc.b	$1b,'[1;30;31m',0
italic_buf	dc.b	$1b,'[3;30;31m',0
underline_buf	dc.b	$1b,'[4;30;31m',0
plain_buf		dc.b	$1b,'[0;30;31m',0
yes_str	dc.b	'YES',0
no_str	dc.b	'NO',0

	EVEN
Body_text	dc.b	0,1	;frontpen, backpen
	dc.w	RP_JAM2	;drawmode
	dc.w	10,5	;left edge, top edge
	dc.l	0	;text attr
Body_String	dc.l	0	;string
	dc.l	0	;next itext

	EVEN

Positive_text	dc.b	0,1	;frontpen, backpen
	dc.w	RP_JAM2	;drawmode
	dc.w	6,3	;left edge, top edge
	dc.l	0	;text attr
	dc.l	yes_str	;string
	dc.l	0	;next itext

	EVEN

Negative_text	dc.b	0,1	;frontpen, backpen
	dc.w	RP_JAM2	;drawmode
	dc.w	6,3	;left edge, top edge
	dc.l	0	;text attr
	dc.l	no_str	;string
	dc.l	0	;next itext

versiontag	dc.b	0,'$VER: IOPack 1.04 (13.6.91)',0

* DS's

	SECTION	"iopack.data",BSS

	EVEN

write_port	ds.l	1
read_port	ds.l	1
write_req	ds.l	1
read_req	ds.l	1
MyNewWindow	ds.b	nw_SIZE
SomeScreenDat	ds.b	sc_WBorTop
char_buf	ds.b	1
DecInBuf
DecInLongBuf
Stack	ds.b	STK_SIZE
StackEnd	ds.b	STK_SIZE
StackEnd2	ds.b	1
_ConBlock	ds.b	1
