* myinstal.asm	Copyright 1987 by Scott Turner ALL RIGHTS RESERVED
*
* This program was inspired by the plight of PD authors who could not even do
* an 'INSTALL' command on their PD disks because of a repressive policy on
* the part of Commodore-Amiga Inc. This one is for you guys!
*
* Also a big thanks to MetaComCo for the upgrade to version 11.0 of the Macro
* Assembler. Not only did I get my $27 worth, but I'm tickled pink. Twice as
* fast as the old assembler PLUS new options, and bug fixes. If you don't have
* it yet, get it!
*
* This program writes 1024 bytes into blocks 0 and 1 of the diskette in drive
* DF0:. If someone wishes it could be adapted to take the drive number from
* the command line. But I have two hard disk drives, thus I only have ONE
* floppy disk drive :).
*
* The 'INSTALL' program is VERY VERY VERY ugly! It writes uninitilized data
* from ram onto the disk when it installs it. Myinstal allocates a 1024
* byte buffer from CHIP ram with the 'please clear to zero' bit set so that
* the ram is all nice an zeroed. It then copies in the payload code, calculates
* the checksum and writes the whole thing to disk.
*
* This program is distributed with a 'stock' bootstrap. This bootstrap will
* function like the one used by the INSTALL program. BUT it clears D0 before
* calling OpenLibrary and doesn't do any branching to branches. The potential
* for doing some INTERESTING things in addition to the basic bootstrap 
* requirements DO seem to exist. The code could be modified to print a 
* 'This is NOT a boot disk' type message for example. Or new CLI's and
* console handlers could be installed... Operational parameters not covered
* by prefs could be tweaked. Try not to have too much fun now :-).
*
* If you have questions/comments/requests concerning this source code, please
* direct them in WRITING (no I don't mean via phone!) to:
*
* Scott Turner
* L5 Computing
* 12311 Maplewood Avenue
* Edmonds, WA. 98020-1115
*
* I may also be reached via:
*
* JST on GEnie
* scotty@l5comp.UUCP or stride!l5comp!scotty
*
* I am NOT releasing this source code into the public domain. However, I here
* by grant a license for distribution via AmigaDOS format 3.5" diskette or via
* an online telecommunications medium provided that the party charges less than
* the following to do so:
*
* USA $10 for a copy on an AmigaDOS 3.5" disk.
* USA $10 an hour for 1200 baud connection at 18:00 PST from Seattle, WA USA.
*
* I reserve all other rights. This source code is made available "AS IS" and I
* make no warranties for it's fitness for any purpose.
*
*------------------------------------------------------------------------------
*
* I hate assembling 3,000 lines of include files. How about you?
*
* External EXEC references
_Supervisor	EQU	-6*5
_FindResident	EQU	-6*16
_AllocMem	EQU	-6*33
_FreeMem	EQU	-6*35
_FindTask	EQU	-6*49
_OpenLibrary	EQU	-6*68
_CloseLibrary	EQU	-6*69
_OpenDevice	EQU	-6*74
_CloseDevice	EQU	-6*75
_DOIO		EQU	-6*76
*
* External AmigaDOG references
_Write		EQU	-6*8
_Output		EQU	-6*10
*
* Setup global registers
		MOVEA.L	4,A6			; ExecBase
		SUBA.L	A4,A4			; Pointer to memory buffer
		LEA	DiskIOReq(PC),A3	; Pointer to disk I/O Request
		MOVEQ	#0,D6			; Completion result
		MOVE.L	A7,D5			; Stack pointer
		MOVEQ	#1,D4			; Disk opened flag <>0 <>open
*
* Call the "dog"
		MOVEQ	#0,D0
		LEA	DogName(PC),A1
		JSR	_OpenLibrary(A6)
		MOVEA.L	D0,A5
		TST.L	D0
		BNE.S	LibraryOpen
*
* We arrive here because the system is in a phrase "royally fucked". Since the
* Amiga is not prone to this, some menacing outside influence must have caused
* it. Fight back by dropping a "Neutron bomb" on the rascals.
* This routine has been upgraded from the one in MoonMouse.
FireNeutronBomb	LEA	TheBomb(PC),A5
		JSR	_Supervisor(A6)
		STOP	#$2700

TheBomb		MOVE.L	#'HELP',0	; Shoot the Guru
		ADDQ.L	#1,A7	; The ONE hole in the 680X0's protection...
*
* "So long mom, I'm off to drop the bomb."
		RTE

*
* Allocate some CHIP ram for payload.
LibraryOpen	MOVE.L	#$10002,D1
		MOVE.L	#1024,D0	; Boot block size
		JSR	_AllocMem(A6)
		TST.L	D0
		BEQ.S	MissedIt
		MOVEA.L	D0,A4
*
* Now we copy the payload into the memory buffer. While doing so we calculate
* the checksum which we will patch into the buffer after the copy.
		MOVEQ	#0,D2		; Zero checksum
		MOVEQ	#PayloadSize/4-1,D0
		MOVEA.L	A4,A1
		LEA	ThePayload(PC),A0
0$		MOVE.L	(A0)+,D1
		MOVE.L	D1,(A1)+	; Shove into buffer
		ADD.L	D1,D2		; Bump checksum
		BCC.S	1$		; Did it rollover?
		ADDQ.L	#1,D2		; Bump by 1 if it rolled
1$		DBF	D0,0$
*
* Patch checksum into buffer
		NOT.L	D2
		MOVE.L	D2,4(A4)
*
* Init the port to use to access the trackdisk.device
		SUBA.L	A1,A1
		JSR	_FindTask(A6)
		LEA	DiskPort(PC),A0
		MOVE.L	D0,16(A0)
*
* Open the disk device
		MOVEQ	#0,D1
		MOVEQ	#0,D0
		MOVEA.L	A3,A1
		LEA	DiskName(PC),A0
		JSR	_OpenDevice(A6)
		MOVE.L	D0,D4			; Record if we opened device
		BNE.S	MissedIt
*
* Write payload to the disk 
		MOVEA.L	A3,A1
		MOVE.L	A4,40(A1)		; Pointer to Payload buffer
		JSR	_DOIO(A6)
		TST.L	D0
		BNE.S	MissedIt
*
* Flush data from track buffer onto the disk
		MOVEA.L	A3,A1
		MOVE.W	#4,28(A1)
		JSR	_DOIO(A6)
		TST.L	D0
		BNE.S	MissedIt
*
* Shutdown the motor
		MOVEA.L	A3,A1
		MOVE.W	#9,28(A1)
		CLR.L	36(A1)
		JSR	_DOIO(A6)
		TST.L	D0
		BEQ.S	MadeIt

MissedIt	MOVE.L	D0,D6		; Record error
		LEA	Ooops(PC),A0
		MOVEA.L	A0,A1
		MOVE.L	A0,D3
0$		TST.B	(A0)+
		BNE.S	0$
		SUBA.L	D3,A0
		MOVE.L	A0,D3
		SUBQ.L	#1,D3		;Length
		MOVE.L	A1,D2		;Buffer
		JSR	_Output(A5)
		MOVE.L	D0,D1		;FileHandle
		JSR	_Write(A5)
*
* Send the dog home
MadeIt		MOVEA.L	A5,A1
		JSR	_CloseLibrary(A6)
*
* Free up the memory buffer if it was allocated
		MOVE.L	A4,D0
		BEQ.S	0$
		MOVEA.L	D0,A1
		MOVE.L	#1024,D0
		JSR	_FreeMem(A6)
*
* Close the disk if we opened it
0$		TST.L	D4
		BNE.S	1$
		MOVEA.L	A3,A1
		JSR	_CloseDevice(A6)
1$		MOVE.L	D6,D0
		MOVEA.L	D5,A7
		RTS

		CNOP	0,4
*
* Payload, this is the code written to the disk's boot block
PayloadStart
ThePayload	DC.B	'DOS',0
		DC.L	0	; Checksum goes here
		DC.L	880	; Root block

*
* Do NOT change the statements above here, they are cast in the sands of time.
* From here on down is where you can insert a new bootstrap routine.
* Instead of doing the stuff below code could be inserted to throw up an
* alert telling the user that this is NOT a bootdisk.
* The following code may seem a tad 'weird', this is intentional. The original
* Copyrighted boostrap was so small that rewriting it without directly copying
* it was a tad tricky. But where there is a will there IS a way! :-)
		LEA	DogName(PC),A1
		JSR	_FindResident(A6)
		TST.L	D0
		BEQ.S	DingDongTheDogIsDead
		SUBA.L	A0,A0
		MOVE.L	22(A0,D0.L),A0
		EOR.L	D0,D0
		RTS

DogName		DC.B	'dos.library',0

DingDongTheDogIsDead
		MOVEQ	#-1,D0
		RTS

		CNOP	0,4
PayloadEnd
PayloadSize	EQU	PayloadEnd-PayloadStart

DiskName	DC.B	'trackdisk.device',0
Ooops		DC.B	'Disk was NOT installed',$A,0
		DS.W	0

DiskPort	DC.L	0	;0
		DC.L	0	;4
		DC.W	$0400	;8
		DC.L	0	;10
		DC.B	0	;14
		DC.B	31	;15
		DC.L	0	;16	Task addr goes here
LH1		DC.L	LH2	;20
LH2		DC.L	0	;24
		DC.L	LH1	;28
		DC.B	0	;32
		DC.B	0	;33
DiskIOReq	DC.L	0	;0
		DC.L	0	;4
		DC.B	5	;8
		DC.B	0	;9
		DC.L	0	;10
		DC.L	DiskPort ;14
		DC.W	48	;18
		DC.L	0	;20
		DC.L	0	;24
		DC.W	3	;28 IO_CMD
		DC.W	0	;30
		DC.L	0	;32
		DC.L	1024	;36 IO_LENGTH
		DC.L	0	;40 IO_DATA
		DC.L	0	;44 IO_OFFSET
		DC.L	0
		DC.L	0

		END
