;========================================================================
;
; Project...: Utility boot (VectorBOOT)
; Version...: V1.03
; Date......: 8-June-1991
; Author....: P. de Boer
; Assembler.: ASM-One V1.01, DevPac V2.14
;
; PS: You'll have to change a few things, if you want to assemble it in
;     DevPac or SEKA
;     (It even works on kick 2.0 !!)
;
;========================================================================

Installer	EQU	1

		IFEQ	Installer
WriteBB		EQU	0
		IFNE	WriteBB			;ASM-One directive
		AUTO	ws\BootBlock\0\2\cc\
		ENDC
		ELSEIF
WriteBB		EQU	1
		ENDC

;========================================================================
;HARDWARE EQU's

DMACONR	EQU	$002
VHPOSR	EQU	$006

POTGOR	EQU	$016
COP1LCH	EQU	$080
COPJMP1	EQU	$088
DIWSTRT	EQU	$08E
DIWSTOP	EQU	$090
DDFSTRT	EQU	$092
DDFSTOP	EQU	$094
DMACON	EQU	$096
INTENA	EQU	$09A
BPL1PTH	EQU	$0E0
BPL1PTL	EQU	$0E2
BPL2PTH	EQU	$0E4
BPL2PTL	EQU	$0E6
BPLCON0	EQU	$100
BPLCON1	EQU	$102
BPLCON2	EQU	$104
BPL1MOD	EQU	$108

COLOR00	EQU	$180
COLOR01	EQU	$182
COLOR08	EQU	$190
COLOR09	EQU	$192

CUSTOM	EQU	$DFF000

CIAB	EQU	$BFD000
CIAA	EQU	$BFE001

PRA	EQU	$000
SPx	EQU	$C00

NULL	EQU	0

;------ DOS LVO's

_LVOOpen		EQU	-30
_LVOClose		EQU	-36
_LVOWrite		EQU	-48
_LVOOutput		EQU	-60

MODE_NEW		EQU	1004

;------ GFX LVO's

_LVOOpenFont		EQU	-72

;------ EXEC LVO's

_LVOFindResident	EQU	-96
_LVOSuperState		EQU	-150
_LVOAllocMem		EQU	-198
_LVOFreeMem		EQU	-210
_LVOAvailMem		EQU	-216
_LVOFindTask		EQU	-294
_LVOAddPort		EQU	-354
_LVORemPort		EQU	-360
_LVOGetMsg		EQU	-372
_LVOReplyMsg		EQU	-378
_LVOWaitPort		EQU	-384
_LVOCloseLibrary	EQU	-414
_LVOOpenDevice		EQU	-444
_LVOCloseDevice		EQU	-450
_LVODoIO		EQU	-456
_LVOOpenLibrary		EQU	-552

ExecBase		EQU	$4

			RSRESET		;node structure
LN			RS.B	0
LN_SUCC			RS.L	1
LN_PRED			RS.L	1
LN_TYPE			RS.B	1
LN_PRI			RS.B	1
LN_NAME			RS.L	1
LN_SIZE			RS.W	0

NT_MSGPORT		EQU	4


;========================================================================

		opt	o+

		SECTION	MainCode,CODE

		IFEQ	Installer
		JMP	s
		ENDC

Start		move.l	a0,a5

		suba.l	a1,a1
		move.l	(ExecBase).w,a6
		JSR	_LVOFindTask(a6)
		move.l	d0,MyTask
		move.l	d0,MyPort+$10	;beetje gejat uit intern

		lea	MyPort(pc),a1
		move.l	(ExecBase).w,a6
		JSR	_LVOAddPort(a6)

		lea	_DOSName(pc),a1
		clr.l	d0
		move.l	(ExecBase).w,a6
		JSR	_LVOOpenLibrary(a6)
		move.l	d0,DOSBase
		beq	NoDOS

		move.l	DOSBase(pc),a6
		JSR	_LVOOutput(a6)
		move.l	d0,OutHandle

		move.l	#Hello.TXT,d2
		move.l	#Hello.LEN,d3
		BSR	Print

SkipSpaces	move.b	(a5)+,d0
		cmp.b	#$0A,d0
		beq.s	Fout
		cmp.b	#" ",d0
		beq.s	SkipSpaces

NotReturn	cmp.b	#"0",d0
		blt.s	SkipSpaces
		cmp.b	#"3",d0
		ble.s	Install

Fout		move.l	#Syntax.TXT,d2
		move.l	#Syntax.LEN,d3
		bra	PrintAndExit

Install		move.b	d0,Unit
		sub.b	#"0",d0
		ext.w	d0
		ext.l	d0
		clr.l	d1

		lea	TrdDevice(pc),a0
		lea	DiskIO(pc),a1
		move.l	(ExecBase).w,a6
		JSR	_LVOOpenDevice(a6)
		tst.l	d0
		beq.s	TrdOpen

		move.l	#NoTrd.TXT,d2
		move.l	#NoTrd.LEN,d3
		bra	PrintAndExit

TrdOpen		lea	BootBlock,a0
		clr.l	4(a0)
		clr.l	d0
		move.w	#1024/4-1,d7
CheckSum	add.l	(a0)+,d0
		bcc.s	.Ok
		addq.l	#1,d0
.Ok		dbf	d7,CheckSum
		not.l	d0
		move.l	d0,-(1024-4)(a0)

		lea	DiskIO(pc),a1
		move.l	#MyPort,14(a1)
		move.l	#BootBlock,40(a1)
		move.l	#2*512,36(a1)
		clr.l	44(a1)

		move.l	(ExecBase).w,a6

		move.w	#5,28(a1)
		JSR	_LVODoIO(a6)
		move.w	#3,28(a1)
		JSR	_LVODoIO(a6)
		move.w	#4,28(a1)
		JSR	_LVODoIO(a6)

		clr.l	36(a1)
		move.w	#9,28(a1)
		JSR	_LVODoIO(a6)

		lea	DiskIO(pc),a1
		move.l	(ExecBase).w,a6
		JSR	_LVOCloseDevice(a6)

		move.l	#Done.TXT,d2
		move.l	#Done.LEN,d3

PrintAndExit	BSR.S	Print

RemPort		lea	MyPort(pc),a1
		move.l	(ExecBase).w,a6
		JSR	_LVORemPort(a6)

CloseDOS	move.l	DOSBase(pc),a1
		move.l	(ExecBase).w,a6
		JSR	_LVOCloseLibrary(a6)

NoDOS		clr.l	d0
		rts

;========================================================================
Print		move.l	OutHandle(pc),d1
		beq.s	.Exit
		move.l	DOSBase(pc),a6
		JSR	_LVOWrite(a6)

.Exit		rts

;========================================================================

DOSBase		DC.L	0
OutHandle	DC.L	0
MyTask		DC.L	0

DiskIO		DCB.L	20,0
IO		DCB.L	12,0
IOReq		DCB.L	16,0

MyPort		DC.L	NULL			;message port structure
		DC.L	NULL
		DC.B	NT_MSGPORT
		DC.B	0
		DC.L	MyPortName
		DC.B	0
		DC.B	0
		DC.L	NULL
		DS.B	14


_DOSName	DC.B	"dos.library",$0
TrdDevice	DC.B	"trackdisk.device",$0
MyPortName	DC.B	"VectorBOOT port",$0

Hello.TXT	DC.B	$9B,"33;1mVectorBOOT"
		DC.B	$9B,"0m V1.1 by P. de Boer (VECTOR/Vision)",$0A
Hello.LEN	EQU	*-Hello.TXT
Syntax.TXT	DC.B	$9B,"33mSYNTAX:"
		DC.B	$9B,"0m VectorBOOT n",$0A
		DC.B	"  Where n stands for the drive you want to install",$0A
Syntax.LEN	EQU	*-Syntax.TXT
NoTrd.TXT	DC.B	"Unable to open trackdisk.device for unit "
Unit		DC.B	"0"
		DC.B	" !",$0A
NoTrd.LEN	EQU	*-NoTrd.TXT
Done.TXT	DC.B	"Bootblock installed.",$0A
Done.LEN	EQU	*-Done.TXT

;========================================================================
		IFEQ	Installer

		SECTION	TestCode,CODE

s		move.l	$4.w,a6
		move.w	#$4E75,EndAddr		; put rts into code
		jmp	Go

		ENDC

;========================================================================
		SECTION	VectorBOOT,DATA_C

		opt	o+,p+

ScrW		EQU	640
ScrH		EQU	88

BootBlock	DC.B	'DOS',0
		DC.L	0
		DC.L	880

Go		movem.l	d0-d7/a0-a6,-(a7)

AllocMem	pea	(ScrW/8*ScrH+$400).w
		move.l	(a7),d0			; ==> sp 4
		move.l	#$10002,d1
		JSR	_LVOAllocMem(a6)
		move.l	d0,d2
		beq.w	Exit
		move.l	d2,-(a7)		; ==> sp 8

		IFNE	WriteBB
ReadBB		movea.l	9*4+8(SP),a1	;a1=io struct only in bootblock !
		movea.l	d2,a0
		adda.w	#(ScrW/8)*ScrH,a0
		move.l	a0,40(a1)	;read buffer
		JSR	_LVODoIO(a6)

MotorOFF	addq.w	#7,28(a1)		;2+7=9
		suba.l	a3,a3
		BSR	DoIO
		ELSEIF
		DCB.W	14,$4E71
		ENDC

		clr.w	-(a7)			; ==> sp 10
		cmp.b	#60,530(a6)
		beq.s	OpenGFX
		move.w	#$0020,(a7)		;Freq

OpenGFX		lea	GFXName(pc),a1		; gfx name
		clr.l	d0
		JSR	_LVOOpenLibrary(a6)
		movea.l	d0,a6			; gfx base
		move.l	d0,-(a7)		; ==> sp 14

OpenFONT	lea	TextAttr(pc),a0
		lea	FontName(pc),a1
		move.l	a1,(a0)
		JSR	_LVOOpenFont(a6)
		movea.l	d0,a0
		movea.l	34(a0),a4		; bit ptr
		move.w	38(a0),d7		; modulo

		move.l	$4.w,a6			; execbase back

SetPtrs		lea	BitPlanes+2(pc),a0
		moveq	#80,d1
		add.l	d2,d1

		move.w	d1,(a0)
		swap	d1
		move.w	d1,4(a0)

		move.w	d2,8(a0)
		swap	d2
		move.w	d2,12(a0)

SetDMA		lea	CUSTOM+DMACON,a5
		move.w	DMACONR-DMACON(a5),-(a7)	; ==> sp 16
		move.w	#$7FFF,-(a7)		; ==> sp 18
		move.w	(a7),(a5)		; disable all dma's

		clr.l	BPL1MOD-DMACON(a5)

		lea	CList(pc),a0
		move.l	a0,COP1LCH-DMACON(a5)		; copper1 start adress
		move.w	#$C008,INTENA-DMACON(a5)
		clr.w	COPJMP1-DMACON(a5)		; start copper1


;========================================================================
WaitLoop

;========================================================================
PrintText	moveq	#80,d2

		lea	Text(pc),a0
		move.l	10(SP),a1		; screenptr
		lea	Address(pc),a3
		bra.s	SkipRow		

NextChar	moveq	#0,d0
		move.b	(a0)+,d0		; get char
ChangeAdr	EQU	*+2
		bmi	Restore			; last char ???
		bgt.s	TestSpace

SkipRow		moveq	#8,d1			; first column
		lea	80*8(a1),a1		; next line
		bra.s	NextChar		; get next char

TestSpace	subq.b	#1,d0			; space mark
		bne.s	TestAddress
		add.b	(a0)+,d1		; get spaces
		bra.s	NextChar

TestAddress	subq.b	#1,d0
		bne.s	TestAddress2

		move.w	(a3)+,a2
		move.l	(a2),d6
		cmp.w	#$00FC,(a2)
		bne.s	VIRUS
		bra.s	DoLong

TestAddress2	subq.b	#1,d0
		bne.s	TestAVAIL

		move.w	(a3)+,a2
		move.l	0(a2,a6.l),d6
		bne.s	VIRUS

DoLong		btst	#2,POTGOR-DMACON(a5)
		bne.s	ConvertULong

Change		lea	ChangeAdr(pc),a2
		move.w	#EndText-ChangeAdr,(a2)
		bra.s	ConvertULong

VIRUS		addq.w	#1,d1
		moveq	#"?",d0
		BSR.S	PutChar		
		subq.w	#2,d1

		lea	Streepje1(pc),a2
		move.w	#$0E30,(a2)
		move.w	(a2),Streepje2(a2)
		bra.s	Change

TestAVAIL	subq.b	#1,d0
		bne.s	TestDrives

		movem.l	d1/a0-a1,-(SP)
		clr.l	d1
		move.b	(a3)+,d1
		JSR	_LVOAvailMem(a6)
		movem.l	(SP)+,d1/a0-a1

		move.l	d0,d6
		bra.s	ConvertULong

TestDrives	subq.b	#1,d0
		bne.s	.Cont

		moveq	#1,d0

		IFNE	WriteBB
		BSR	GetPtr			;This code only in bootblock
		moveq	#3-1,d5
.Test		tst.l	(a0)+
		bne.s	.End
		addq.w	#1,d0
		dbf	d5,.Test

.End
		ELSEIF
		DCB.W	8,$4E71
		ENDC

		add.w	#"0"-5,d0

.Cont		addq.b	#5,d0
		BSR.S	PutChar
		bra.s	FakeNextChar

;========================================================================
ConvertULong	addq.w	#3,d1
		moveq	#"$",d0
		BSR.S	PutChar

		moveq	#8-1,d4
.Next		rol.l	#4,d6
		move.b	d6,d0
		and.w	#$000F,d0
		cmp.w	#10,d0
		blt.s	.Ok
		addq.w	#7,d0

.Ok		add.w	#"0",d0
		BSR.S	PutChar
		dbf	d4,.Next		

		addq.w	#8,d1
FakeNextChar	jmp	NextChar(pc)

;========================================================================
PutChar		move.w	d1,d3
		moveq	#8-1,d5			; copy 8 bytes
.Copy		move.b	-$20(a4,d0.w),0(a1,d3.w) ; copy one byte from char
		add.w	d7,d0			; next byte in char
		add.w	d2,d3
		dbf	d5,.Copy
		addq.w	#1,d1			; move 1 right
		rts
;========================================================================
EndText

MouseWait	move.w	#$87D0,(a5)	; enable dma's

		btst	#6,CIAA!PRA
		beq.s	Restore

PressWait	move.b	CIAA!SPx,d1
		btst	#0,d1
		beq.s	MouseWait

TestESC		cmp.b	#$75,d1
		bne.s	TestKeys

;========================================================================
Restore		move.w	(a7)+,(a5)			; disable dma
		or.w	#$8000,(a7)			; set bit 15
		move.w	(a7)+,(a5)			; enable dma

RestoreCList	movea.l	(a7)+,a1			; get gfx base
		move.l	$26(a1),COP1LCH-DMACON(a5)	; restore old copper ptr
		move.w	(a7)+,COPJMP1-DMACON(a5)	; start copper

CloseGFX	JSR	_LVOCloseLibrary(a6)

FreeMemory	movea.l	(a7)+,a1
		move.l	(a7)+,d0
		JSR	_LVOFreeMem(a6)

Exit		clr.l	COLOR00-DMACON(a5)
		movem.l	(a7)+,d0-d7/a0-a6

EndAddr		lea	DOSName(pc),a1
		move.w	#'do',(a1)
		JSR	_LVOFindResident(a6)
		tst.l	d0
		beq.s	.Foutje
		movea.l	d0,a0
		movea.l	22(a0),a0
		moveq	#-1,d0

.Foutje		not.l	d0
		rts

;========================================================================
GetPtr		movea.l	9*4+18+4(SP),a0		;io struct (a1)
		movea.l	20(a0),a0		;trackdisk device struct
		movea.l	60(a0),a0
		lea	52(a0),a0
		rts

;========================================================================
TestKeys	not.b	d1
		sub.w	#$A0-2,d1

TestF1		subq.b	#2,d1
		bne.s	TestF2
		eori.w	#$0020,8(SP)		;Freq

;========================================================================
TestF2		subq.b	#2,d1
		bne.s	TestF3

Go512Kb		movea.l	a6,a0
		movea.l	a5,a1
		move.l	(a7),(a1)+
		move.l	(a7),(a1)+
		moveq	#-1,d6			;prevents guru
		lea	$80000,a3
		suba.l	a4,a4
		lea	$676.w,a6
		move.l	#$FC0222,$80.W
		trap	#0

;========================================================================
TestF3		subq.b	#2,d1
		bne.s	TestF4

OneDrive	BSR.S	GetPtr
		moveq	#-1,d0
		move.l	d0,(a0)+
		move.l	d0,(a0)+
		move.l	d0,(a0)+

;========================================================================
TestF4		subq.b	#2,d1
		beq.s	SoftReset

TestF5		subq.b	#2,d1
		bne.s	TestF6

HardReset	clr.l	38(a6)			;just kill chkbase
SoftReset	JSR	_LVOSuperState(a6)	;this is the only
		lea	$2.w,a0			;correct way to reset
		RESET				;your amiga !!!
		JMP	(a0)

;========================================================================
TestF6		subq.b	#2,d1
		bne.s	ReleaseWait

		movea.l	9*4+18(SP),a1
		lea	28(a1),a2
		lea	$400.w,a3

		subq.w	#4,(a2)			;9-4=5 !
		BSR.S	DoIO
		subq.w	#2,(a2)			;5-2=3 !
		BSR.S	DoIO
		addq.w	#1,(a2)			;3+1=4 !
		BSR.S	DoIO
		addq.w	#5,(a2)			;4+5=9 !
		BSR.S	DoIO
		suba.l	a3,a3
		BSR.S	DoIO

;========================================================================
ReleaseWait	btst	#0,CIAA!SPx
		bne.s	ReleaseWait

		lea	FreqText(pc),a0
		move.b	#"5",(a0)
		move.w	8(SP),$1DC-DMACON(a5)		;freq
		beq.s	.Skip
		move.b	#"6",(a0)

.Skip		jmp	WaitLoop(pc)

;========================================================================
DoIO		move.l	a3,36(a1)
		JMP	_LVODoIO(a6)

;========================================================================
Address		DC.W	$64,42			;peek address
		DC.W	$68,46			;negative address means
		DC.W	$6C,50			;exec-base offset
		DC.W	$70
		DC.W	$74,546
		DC.W	$78,550
		DC.W	$7C,554
		DC.B	2,4

TextAttr	DC.L	0
		DC.W	8
		DC.B	0
		DC.B	0
		DC.W	8

FontName	DC.B	'topaz.font',0
GFXName		DC.B	'graph'
DOSName		DC.B	'ics.library',0

;========================================================================
CList		DC.W	BPLCON0,$A400,BPLCON1,$0010,BPLCON2,$0000
		DC.W	DIWSTRT,$6081,DIWSTOP,$60C2+(ScrH-1)<<8
		DC.W	DDFSTRT,$003C,DDFSTOP,$00D4

BitPlanes	DC.W	BPL1PTL,$0000,BPL1PTH,$0000
		DC.W	BPL2PTL,$0000,BPL2PTH,$0000

		DC.W	COLOR00,$0123,COLOR01,$0EEE
		DC.W	COLOR09,$0000

Streepje1	EQU	*+6
		DC.W	$5F0F,$FFFE,COLOR00,$03E0
		DC.W	$600F,$FFFE,COLOR00,$0455

Streepje2	EQU	(*-Streepje1)+6
		DC.W	$5F0F+ScrH<<8,$FFFE,COLOR00,$03E0
		DC.W	$600F+ScrH<<8,$FFFE,COLOR00,$0123

		DC.W	$FFFF,$FFFE

Text		DC.B	"I1:",2			;menu text
		DC.B	"COLD:",3		;0 =   end of line
		DC.B	"F1: 60Hz"		;1 =   space indentifier
FreqText	EQU	*-4			;      e.g. 1,amount of spaces
		DC.B	$00			;2/3 = get next peek address
		DC.B	"I2:",2			;      from list
		DC.B	"COOL:",3		;4 =   get mem. req. from list
		DC.B	"F2: 512Kb"		;      and do an availmem
		DC.B	$00			;5 =   check amount of drives
		DC.B	"I3:",2			;$FF = end of text (negative)
		DC.B	"WARM:",3
		DC.B	"F3: One drive"
		DC.B	$00
		DC.B	"I4:",2
		DC.B	1,25,"F4: Reset"
		DC.B	$00
		DC.B	"I5:",2
		DC.B	"MEM: ",3
		DC.B	"F5: KILL"
		DC.B	$00
		DC.B	"I6:",2
		DC.B	"TAG: ",3
		DC.B	"F6: Write boot"
		DC.B	$00
		DC.B	"I7:",2
		DC.B	"CHK: ",3
		DC.B	$00,$00
		DC.B	1,-2,"CHIP:",4
		DC.B	"FAST:",4
		DC.B	"DRIVES: ",5
		DC.B	$FF

Size		EQU	1024-(*-BootBlock)

;		PRINTV	*-BootBlock
;		PRINTV	Size

		IFLT	Size
		PRINTT	"Code to large !"
		ELSEIF
		DCB.B	1024-(*-BootBlock),$00
		ENDC

;========================================================================

