
;            *********************************************
;            *                                           *
;            *         M A X's door starter pac          *
;            *                                           *
;            *   Created by Anthony Barrett, 11-Aug-91   *
;            *                                           *
;            *                Version 1.0                *
;            *                                           *
;            *********************************************


			opt o+, a+
			include	"DH0:Asm/Include/Misc/OffSets.i"


;This is an assembler starter pac for programming with the door
;on  M A X's BBS.  All the useful door commands are available
;as subroutines.  If you wish to get the full list of commands
;then grab the file "ParaProg.lzh" from the "M A X's BBS support
;files" section on my BBS (02) 412-3280.  Yes it is downward
;compatable with Paragon but there are  M A X's BBS exclusive
;door commands shown in this source.  Have fun.


;** The start! **:

Start:			move.l	sp,StackPrt


;Get line number from cmd string:

			subq.l	#1,d0
			beq	Exit
			move.b	(a0),MsgPortName+11
			move.b	(a0),MsgPortName2+9


;Open DOS library:

			lea	DosName,a1
			sub.l	d0,d0
			movea.l	(4).l,a6
			jsr	_LVOOpenLibrary(a6)
			move.l	d0,DosBase
			beq	Exit


;Make msg port & msg:

			move.l	#140,d0			;Mem for msg port & msg structure
			move.l	#$10001,d1
			movea.l	(4).l,a6
			jsr	_LVOAllocMem(a6)
			move.l	d0,MsgPortPrt
			beq	Exit2

			suba.l	a1,a1
			movea.l	(4).l,a6
			jsr	_LVOFindTask(a6)

			movea.l	MsgPortPrt,a0
			move.l	d0,16(a0)

			moveq.l	#-1,d0
			movea.l	(4).l,a6
			jsr	_LVOAllocSignal(a6)

			movea.l	MsgPortPrt,a1
			move.b	#4,8(a1)
			move.l	#MsgPortName2,10(a1)
			move.b	d0,15(a1)
			bmi	Exit3
			
			move.b	#5,42(a1)
			move.l	a1,48(a1)
			move.w	#106,52(a1)

			movea.l	(4).l,a6
			jsr	_LVOAddPort(a6)


;Find  M A X's BBS door control port prt:

			movea.l	(4).l,a6
			jsr	_LVOForbid(a6)
			lea	MsgPortName,a1
			movea.l	(4).l,a6
			jsr	_LVOFindPort(a6)
			move.l	d0,ControlPortPrt
			movea.l	(4).l,a6
			jsr	_LVOPermit(a6)
			tst.l	ControlPortPrt
			beq	Exit4


;Main program area (with test example):

Main:			lea	HelloMsg,a0
			bsr	Print
			
.Input:			lea	InputMsg,a0
			moveq.l	#20,d0
			bsr	Input
			tst.b	(a0)
			beq.s	.PrintFile
			lea	YouMsg,a0
			bsr	Print
			lea	Buffer,a0
			bsr	Print
			bra.s	.Input
			
.PrintFile:		lea	InputMsg2,a0
			moveq.l	#40,d0
			bsr	Input
			tst.b	(a0)
			beq.s	.CheckFile
			bsr	PrintFile		
			bra.s	.PrintFile
		
.CheckFile:		lea	InputMsg3,a0
			moveq.l	#40,d0
			bsr	Input
			tst.b	(a0)
			beq.s	.Info
			bsr	CheckFile
			bmi.s	.Nope
			
			lea	YeapMsg,a0
			bsr	Print
			bra.s	.CheckFile

.Nope:			lea	NopeMsg,a0
			bsr	Print
			bra.s	.CheckFile
					
.Info:			lea	UserMsg,a0
			bsr	Print
			moveq.l	#1,d0			;Name
			bsr	GetStrInfo
			bsr	Print
			
			lea	UserMsg2,a0
			bsr	Print
			moveq.l	#2,d0			;Password
			bsr	GetStrInfo
			bsr	Print
			
			lea	UserMsg3,a0	
			bsr	Print
			moveq.l	#3,d0			;Suburb
			bsr	GetStrInfo
			bsr	Print
			
			lea	UserMsg8,a0
			bsr	Print
			moveq.l	#100,d0			;Phone #
			bsr	GetStrInfo
			bsr	Print

			lea	UserMsg9,a0
			bsr	Print
			moveq.l	#101,d0			;Computer
			bsr	GetStrInfo
			bsr	Print

			lea	UserMsg10,a0
			bsr	Print
			moveq.l	#102,d0			;Comment	
			bsr	GetStrInfo
			bsr	Print

			lea	UserMsg4,a0
			bsr	Print
			moveq.l	#7,d0			;Door path
			bsr	GetStrInfo
			bsr	Print
			
			lea	UserMsg5,a0
			bsr	Print
			moveq.l	#8,d0			;BBS path
			bsr	GetStrInfo
			bsr	Print
						
			lea	UserMsg6,a0
			bsr	Print
			moveq.l	#9,d0			;Date
			bsr	GetStrInfo
			bsr	Print
			
			lea	UserMsg7,a0
			bsr	Print
			moveq.l	#10,d0			;Time
			bsr	GetStrInfo
			bsr	Print

.Random:		lea	RandomMsg,a0
			bsr	HotKey
			cmpi.b	#13,d0
			beq.s	.Twit
			moveq.l	#20,d0
			bsr	GetRandom
			lea	Buffer,a0
			bsr	HEXtoASCII
			bsr	Print
			bra.s	.Random
			
.Twit:			lea	TwitMsg,a0
			bsr	HotKey
			cmpi.b	#$20,d0
			bne.s	.Skip
			bsr	Twit
			
.Skip:			lea	SmartMsg,a0
			bsr	Print
			
.Int:			lea	IntMsg,a0
			moveq.l	#3,d0
			bsr	Input
			tst.b	(a0)
			beq.s	.Change
			bsr	ASCIItoHEX
			bsr	GetIntInfo
			lea	Buffer,a0
			bsr	HEXtoASCII
			lea	IntMsg2,a0
			bsr	Print
			lea	Buffer,a0
			bsr	Print
			bra.s	.Int

.Change:		lea	ChangeMsg,a0
			moveq.l	#2,d0
			bsr	Input
			tst.b	(a0)
			beq.s	.Menu
			bsr	ASCIItoHEX
			move.l	d0,-(sp)
			lea	ChangeMsg2,a0
			moveq.l	#5,d0
			bsr	Input
			bsr	ASCIItoHEX
			move.l	d0,d1
			move.l	(sp)+,d0
			bsr	ChangeUserInt
			bra.s	.Change
			
.Menu:			lea	MenuMsg,a0
			moveq.l	#3,d0
			bsr	Input
			tst.b	(a0)
			beq.s	.Done
			bsr	ASCIItoHEX
			addi.w	#100,d0
			move.l	d0,-(sp)
			lea	MenuMsg2,a0
			moveq.l	#5,d0
			bsr	Input
			bsr	ASCIItoHEX
			move.l	d0,-(sp)
			lea	MenuMsg3,a0
			moveq.l	#42,d0
			bsr	Input
			move.l	(sp)+,d1
			move.l	(sp)+,d0
			bsr	MenuFunct
			bra.s	.Menu

.Done:			lea	PressMsg,a0
			bsr	HotKey
			bra.s	Shutdown
			

;Code to execute if carrier lost:			

LostCarrier:		nop



;Tell  M A X's BBS I'm finished:

Shutdown:		bsr	GetMsgPrt
			move.w	#20,(a2)		;Cmd
			
			movea.l	ControlPortPrt,a0
			movea.l	(4).l,a6
			jsr	_LVOPutMsg(a6)
			
.Wait:			movea.l	MsgPortPrt,a0
			movea.l	(4).l,a6
			jsr	_LVOWaitPort(a6)
			
			movea.l	MsgPortPrt,a0
			movea.l	(4).l,a6
			jsr	_LVOGetMsg(a6)
			tst.l	d0
			beq.s	.Wait
			

;Clean up and return:
			
Exit4:			movea.l	MsgPortPrt,a1		;Free port
			movea.l	(4).l,a6
			jsr	_LVORemPort(a6)

			sub.l	d0,d0			;Free signal
			movea.l	MsgPortPrt,a0
			move.b	15(a0),d0
			movea.l	(4).l,a6
			jsr	_LVOFreeSignal(a6)

Exit3:			movea.l	MsgPortPrt,a1		;Free mem
			move.l	#140,d0
			movea.l	(4).l,a6
			jsr	_LVOFreeMem(a6)

Exit2:			movea.l	DosBase,a1		;Close DOS
			movea.l	(4).l,a6
			jsr	_LVOCloseLibrary(a6)

Exit:			movea.l	StackPrt,sp
			sub.l	d0,d0
			rts


;Print string (a0):

Print:			bsr	GetMsgPrt
			move.w	#1,(a2)+		;Cmd
			clr.w	(a2)+			;Data

.Loop:			move.b	(a0)+,(a2)+		;String
			bne.s	.Loop
			
			bsr	PutWaitMsg
			rts


;Input & print string (a0) max chars (d0):
;Returns input string in buffer (a0)

Input:			bsr	GetMsgPrt
			move.w	#6,(a2)+		;Cmd
			move.w	d0,(a2)+		;Data

.Loop:			move.b	(a0)+,(a2)+		;String
			bne.s	.Loop
			
			bsr	PutWaitMsg
			
SaveBuffer:		lea	Buffer,a2
.Loop:			move.b	(a0)+,(a2)+
			bne.s	.Loop
			lea	Buffer,a0
			rts


;Hotkey & print string (a0):
;Returns char in d0
;d1 = 0 if from local
;d1 = 1 if from serial

HotKey2:		lea	Nothing,a0
HotKey:			bsr	GetMsgPrt
			move.w	#8,(a2)+		;Cmd
			clr.w	(a2)+			;Data

.Loop:			move.b	(a0)+,(a2)+		;String
			bne.s	.Loop
			
			bsr	PutWaitMsg
			move.b	(a0),d0
			move.b	-(a0),d1
			rts


;Hangup on the user:

Twit:			bsr.s	GetMsgPrt
			move.w	#9,(a2)			;Cmd
			bsr	PutWaitMsg
			rts


;Print a text file, filename (a0):

PrintFile:		bsr.s	GetMsgPrt
			move.w	#10,(a2)+		;Cmd
			clr.w	(a2)+			;Data

.Loop:			move.b	(a0)+,(a2)+		;String
			bne.s	.Loop
			
			bsr.s	PutWaitMsg
			rts


;Check if file accessible, filename (a0):
;d0 = 1 if yes
;d0 = -1 if no

CheckFile:		bsr.s	GetMsgPrt
			move.w	#11,(a2)+		;Cmd
			clr.w	(a2)+			;Data

.Loop:			move.b	(a0)+,(a2)+		;String
			bne.s	.Loop
			
			bsr.s	PutWaitMsg
			sub.l	d0,d0
			move.w	-(a0),d0
			rts


;Get int info (d0):
;Returns int in d0

GetIntInfo:		bsr.s	GetMsgPrt
			move.w	#13,(a2)+		;Cmd
			move.w	d0,(a2)			;Data
			bsr.s	PutWaitMsg
			sub.l	d0,d0
			move.w	-(a0),d0
			rts


;Get string info (d0):
;Returns string in buffer (a0)

GetStrInfo:		bsr.s	GetMsgPrt
			move.w	#14,(a2)+		;Cmd
			move.w	d0,(a2)			;Data
			bsr.s	PutWaitMsg
			bra.s	SaveBuffer


;Get a random number from 0 to d0:
;Returns number in d0

GetRandom:		bsr.s	GetMsgPrt
			move.w	#17,(a2)+		;Cmd
			move.w	d0,(a2)			;Data
			bsr.s	PutWaitMsg
			sub.l	d0,d0
			move.w	-(a0),d0
			rts


;Does a  M A X's BBS menu function:
;d0 = menu function number (101 - 133, ie. functions 1 - 33) 
;d1 = Extra
;a0 = Name/Filename/Dest string

MenuFunct:		bsr.s	GetMsgPrt
			move.w	d0,(a2)+		;Cmd
			move.w	d1,(a2)+		;Data

.Loop:			move.b	(a0)+,(a2)+		;String
			bne.s	.Loop
			
			bsr.s	PutWaitMsg
			rts


;Changes any of the current user's int values:
;M A X's BBS only!
;d0 = which one (1 - 15)
;d1 = new value (long word!)

ChangeUserInt:		bsr.s	GetMsgPrt
			move.w	#200,(a2)+		;Cmd
			move.w	d0,(a2)+		;Data
			move.l	d1,(a2)			;String
			bsr.s	PutWaitMsg
			rts
			

;Get msg prt:

GetMsgPrt:		movea.l	MsgPortPrt,a1
			movea.l	a1,a2
			adda.w	#34,a1
			adda.w	#54,a2
			clr.l	2(a2)
			rts
			

;Wait for reply msg
;returns prt to string (a0):			
			
PutWaitMsg:		movea.l	ControlPortPrt,a0
			movea.l	(4).l,a6
			jsr	_LVOPutMsg(a6)
			
.Wait:			movea.l	MsgPortPrt,a0
			movea.l	(4).l,a6
			jsr	_LVOWaitPort(a6)
			
			movea.l	MsgPortPrt,a0
			movea.l	(4).l,a6
			jsr	_LVOGetMsg(a6)
			tst.l	d0
			beq.s	.Wait
			
			movea.l	d0,a0
			adda.w	#24,a0
			tst.w	80(a0)			;Lost carrier?
			bne	LostCarrier
			rts


;Subroutine to convert long int (d0) to ASCII (a0):

HEXtoASCII:		tst.l	d0
			bne.s	.Skip
			movea.l	a0,a1
			move.b	#$30,(a1)+
			clr.b	(a1)
			rts

.Skip:			lea	CBuff3,a1
			move.l	#$30303030,d1
			move.l	d1,(a1)+
			move.l	d1,(a1)+
			move.w	d1,(a1)
			suba.w	#28,a1
			move.l	d1,(a1)+
			move.l	d1,(a1)+
			move.w	#$3031,(a1)

.NextBit:		btst.l	#0,d0
			bne.s	.GoAddASCII
.Return:		lsr.l	#1,d0
			beq.s	.End
			lea	CBuff2,a1
			lea	CBuff,a2
			move.l	(a2)+,(a1)+
			move.l	(a2)+,(a1)+
			move.w	(a2),(a1)
			addq.l	#1,a1
			addq.l	#1,a2
			bsr.s	.AddASCII
			bra.s	.NextBit

.End:			lea	CBuff3,a2
.Loop:			cmpi.b	#$30,(a2)+
			beq.s	.Loop
			subq.l	#1,a2
			movea.l	a0,a1
.Loop2:			move.b	(a2)+,(a1)+
			bne.s	.Loop2
			subq.l	#1,a1
			rts

.GoAddASCII:		lea	CBuff+9,a1
			lea	CBuff3+9,a2
			bsr.s	.AddASCII
			bra.s	.Return

.AddASCII:		moveq.l	#9,d1
.Next:			move.b	(a1),d2
			subi.b	#$30,d2
			add.b	d2,(a2)
.Check:			cmpi.b	#$39,(a2)
			bhi.s	.Overflow
			subq.l	#1,a2
.Return2:		subq.l	#1,a1
			dbf	d1,.Next
			rts

.Overflow:		subi.b	#10,(a2)
			addq.b	#1,-(a2)
			move.l	a1,-(sp)
			move.l	a2,-(sp)
			move.l	d1,-(sp)
			sub.l	d1,d1
			bsr.s	.Check
			move.l	(sp)+,d1
			movea.l	(sp)+,a2
			movea.l	(sp)+,a1
			bra.s	.Return2

CBuff:			dcb.b	10,0
CBuff2:			dcb.b	10,0
CBuff3:			dcb.b	11,0


;Subroutine to convert to ASCII (a0) into long int (d0):

ASCIItoHEX:		tst.b	(a0)
			bne.s	.Okay
			moveq.l	#-1,d0
			rts

.Okay:			movea.l	a0,a1
.Loop:			tst.b	(a0)+
			bne.s	.Loop

			sub.l	d0,d0
			sub.l	d2,d2
			subq.l	#1,a0
			moveq.l	#9,d5
			moveq.l	#1,d4

.Loop2:			move.b	-(a0),d2
			subi.b	#$30,d2
			move.l	d4,d1
			move.l	d4,d3
			mulu	d2,d1
			swap.w	d3
			mulu	d2,d3
			swap.w	d3
			clr.w	d3
			add.l	d3,d1
			add.l	d1,d0
			move.l	d4,d3
			mulu	#10,d4
			swap.w	d3
			mulu	#10,d3
			swap.w	d3
			clr.w	d3
			add.l	d3,d4
			cmpa.l	a0,a1
			beq.s	.End
			dbf	d5,.Loop2
.End:			rts


;Strings and pointers etc:

StackPrt:		dc.l	0
DosBase:		dc.l	0
MsgPortPrt:		dc.l	0
ControlPortPrt:		dc.l	0

DosName:		dc.b	"dos.library",0
MsgPortName:		dc.b	"DoorControl#",0
MsgPortName2:		dc.b	"DoorReply#",0
Nothing:		dc.b	0
Buffer:			dcb.b	80,0


;Text for example code:

HelloMsg:		dc.b	13,13,$1b,"[32mHello there! Welcome to the door"
			dc.b	13,"starter pac by Anthony Barrett...",$1b,"[0m",0
InputMsg:		dc.b	13,13,"Enter some shit (CR - skip): ",0
YouMsg:			dc.b	13,"You entered: ",0			
InputMsg2:		dc.b	13,13,"Enter a text filename to print (CR - skip): ",0
PressMsg:		dc.b	13,13,13,"Press any key to return to the BBS... ",0
InputMsg3:		dc.b	13,13,"Enter a filename to check (CR - skip): ",0
YeapMsg:		dc.b	13,"File online!",0
NopeMsg:		dc.b	13,"Can't find that file!",0
UserMsg:		dc.b	13,13,13,"Here is some info about you & the BBS:"
			dc.b	13,13,"    Name: ",0
UserMsg2:		dc.b	13,"Password: ",0
UserMsg3:		dc.b	13,"  Suburb: ",0
UserMsg4:		dc.b	13,13,"Door path: ",0
UserMsg5:		dc.b	13," BBS path: ",0
UserMsg6:		dc.b	13,"     Date: ",0
UserMsg7:		dc.b	13,"     Time: ",0		
UserMsg8:		dc.b	13," Phone #: ",0
UserMsg9:		dc.b	13,"Computer: ",0
UserMsg10:		dc.b	13," Comment: ",0
RandomMsg:		dc.b	13,13,"Hit a key for a random number (CR - skip): ",0
TwitMsg:		dc.b	13,13,$1b,"[31mHit <SPACE> to twit yourself... ",$1b,"[0m",0
SmartMsg:		dc.b	13,"Okay, don't then!",0
IntMsg:			dc.b	13,13,"Enter the data number to get a user int value (1 - 110, CR - skip): ",0
IntMsg2:		dc.b	13,"Return value is: ",0
ChangeMsg:		dc.b	13,13,"Enter the data number of the user int to change (1 - 15, CR - skip): ",0
ChangeMsg2:		dc.b	13,"Enter the new value to change to: ",0
MenuMsg:		dc.b	13,13,"Enter a menu function number (1 - 33, CR - skip): ",0
MenuMsg2:		dc.b	13,"Enter the extra value to use with this funct: ",0
MenuMsg3:		dc.b	13,"Enter the Name/Filename/Dest string: ",0

