	.IF	LIST2
	.LIST
	.PAGE
	.ELSE
	.NOLIST
	.ENDC
;****************************************************************************
;
;	Startup Initialization.
;
;	File:	SAGE.PROM2.TEXT
;	Date:	14-Jul-83
;	Issue:	3A
;
;	COPYRIGHT (c) 1982, 1983 SAGE Computer Technology
;	All Rights Reserved
;
;****************************************************************************
;
;	Release History:
;
;	1     13-Jun-82 Initial release.
;	2     10-Dec-82 Removed CPU test.  Major changes to initialization.
;			Revised memory size printout.  Added version info.
;	3     23-Mar-83 Initial SAGE IV release.
;	3A    14-Jul-83 Improved test for Winchester board equipped.
;			Changed back to immediate entry to high PROM address.
;			Changed startup message.
;			Added powerup delay for Winchester boot.
;
;****************************************************************************


PROM	.WORD	0000H		;Initial stack pointer
	.WORD	SYSSTACK
	.WORD	00FEH		;Startup vector - only used when prom is
	.WORD	START		;		  located at zero on startup.


.PAGE
;****************************************************************************
;
;	Jump vectors to PROM routines
;
;****************************************************************************

	BRA	KEYBCH		;8008H - Get keyboard character
	BRA	KEYCHK		;800CH - Check for a keyboard character
	BRA	DEBUG		;8010H - Direct entry to Debugger
	BRA	TERMCHAR	;8014H - Printout a character
	BRA	TERMTEXT	;8018H - Printout a text string
	BRA	TERMCRLF	;801CH - Printout a <CR> <LF> 
	BRA	TERMHEXB	;8020H - Printout a hex byte
	BRA	TERMHEXW	;8024H - Printout a hex word
	BRA	FDREAD		;8028H - Floppy disk read
	BRA	FDWRITE		;802CH - Floppy disk write
	BRA	USER		;8030H - General Debugger entry point
	
	.WORD	0000H		;PROM Checksum adjustment
	
	.BYTE	VERMAJ		;Major version number
	.BYTE	VERMIN		;Minor version number
	
	BRA	BOOTSX		;8038H - Re-Boot entry point
	BRA	RDCHAN9		;803CH - Winchester Driver
	BRA	WSELECT		;8040H - Winchester drive select
	

.PAGE
;****************************************************************************
;
;	START:
;
;	The startup initialization routine first uses the RESET instruction
;	to make sure that the hardware is initialized in case of a direct
;	entry from the user's program.
;
;****************************************************************************

START	RESET			;Insure that hardware is reinitialized
	
	LEA	SYSSTACK,A7	;Set up default system stack
	MOVE.B	#92H,F8255	;Initialize parallel port
	MOVE.B	#38H,F8255-2	;Idle condition to C port
	MOVE.B	#92H,C8255+6	;Initialize to Centronics port to inputs
	MOVE.B	#031H,C8255+4	;Idle condition to C port
	MOVEQ	#0,D0
	MOVEQ	#-1,D1
	MOVE.W	#17111.,D2
	LEA	0C0FEH,A0
$10	MOVE.W	D0,(A0)		;Strobe 0000 & FFFF to address FFCOFE
	MOVE.W	D1,(A0)		;For test observation (approx 1/4 sec).
	DBF	D2,$10
	
	LEA	0,A1
	LEA	7FFEH,A2
	MOVE.W	#13378.,D2
$12	MOVE.W	(A1),D0		;Read from addresses 000000, FFCOFE,
	MOVE.W	(A0),D0		;  and 7FFE
	MOVE.W	(A2),D0
	DBF	D2,$12
	

;	Strobe all peripheral chip select lines
	MOVE.W	#1733.,D2
$13	LEA	BAUD1_D-2,A0
	MOVEQ	#9-1,D1
$15	TST.B	(A0)		;Read each port
	ADDA.W	#10H,A0
	DBF	D1,$15
	DBF	D2,$13
	
;	Initialize terminal (without using RAM)
	LEA	$20,A1		;Set up return address for TERMINIT
	BRA	TERMINIT

$20	LEA	MSG18E,A4	;Message address of 'SAGE IV Startup Test'
	LEA	$30,A5		;Set up return address in high area
	BRA	NRTEXT		;Printout string
	
;	Initialize SAGE IV hardware
$30	LEA	$35,A0		;Set up Bus Error Trap
	MOVEA.L BE_TRAP,A1	;Save original contents
	MOVE.L	A0,BE_TRAP
	CMPA.L	BE_TRAP,A0	;Check if RAM is good
	BNE.S	$40		;Memory was not good

	MOVE.B	#90H,WP_1CB	;Init 8255 #1
	MOVE.B	#90H,WP_2CB	;Init 8255 #2
	MOVE.B	#0,WP_1B
	MOVE.B	#0CDH,WP_2B
	MOVE.B	#0,WP_1C
	MOVE.B	#5,WP_2C
	BRA.S	$37

;	Not a SAGE IV
$35	LEA	SYSSTACK,SP	;Set stack back from bus error

$37	MOVE.L	A1,BE_TRAP	;Restore previous contents
	
$40	MOVE.B	DIPSWT,D0	;Get switch settings
	BMI.S	PROMTEST	;No special maintenance mode
	LSR.B	#3,D0
	ANDI.W	#6,D0
	MOVE.W	MAINT(D0.W),D0
	JMP	MAINT(D0.W)
	
;	Special maintenance jump table
MAINT	.WORD	LOOPTEST-MAINT	;Test loop (reserved)
	.WORD	LOOPRAMX-MAINT	;Ram exercise loop
	.WORD	LOOPTEST-MAINT	;Test loop
	.WORD	NOCLEAR-MAINT	;No initialization or testing
	
;	Non clearing initialization
NOCLEAR CLR.B	BUGBIOS		;Set back to PROM drivers
	LEA	MSG28,A4	;Message 'Bypassed Init'
	LEA	DEBUG,A5	;Return to debugger
	BRA	NRTEXT

;	Loop test start
LOOPTEST
	LEA	MSG29,A4	;Message 'Loop Test'
	LEA	PROMTEST,A5	;Return to memory test
	BRA	NRTEXT

;	Ram exercise loop
LOOPRAMX
	LEA	MSG30,A4	;Message 'RAM write loop'
	LEA	$10,A5		;Return to test
	BRA	NRTEXT
	
$10	MOVEQ	#-1,D2
	MOVEQ	#0,D1
	MOVEQ	#0,D0
	MOVE.B	DIPSWT+2,D0	;Get data from port B
	NOT.B	D0
	BTST	#2,D0
	BEQ.S	$20
	MOVEQ	#-1,D1
$20	LSL.B	#1,D0
	ANDI.W	#6,D0
	SWAP	D0
	MOVEA.L D0,A0
$30	MOVE.W	D1,(A0)+
	DBF	D2,$30
	BRA	$10




;	PROM Checksum test
PROMTEST
	LEA	PROM,A0
	MOVE.W	#<PROMSIZE/2>-1,D2
	CLR.B	D0
	CLR.B	D1
$10	ADD.B	(A0)+,D0
	ADD.B	(A0)+,D1
	DBF	D2,$10
	TST.B	D0
	BEQ.S	$20		;Even PROM was good
	LEA	MSG27A,A4	;Message 'PROM 1 Bad'
	LEA	$15,A5		;Return address
	BRA	NRTEXT

$15	TST.B	DIPSWT
	BPL	LOOPFAIL	;Was in loop test
	
;	Check second PROM
$20	TST.B	D1
	BEQ.S	$30		;Odd PROM was good
	LEA	MSG27B,A4	;Message 'PROM 2 Bad'
	LEA	$25,A5		;Return address
	BRA	NRTEXT
	
$25	TST.B	DIPSWT
	BPL	LOOPFAIL	;Failure in loop test

$30

.PAGE
;****************************************************************************
;
;	RAM Memory testing and sizing.
;
;	First the bottom 128K of memory (which must always exist) is tested.
;	Then the system memory is sized by checking if the last location in
;	each 128K interval will hold data.  Then the remainder of the memory
;	is checked.
;
;****************************************************************************

MEMTEST
	MOVE.B	#1,CPARITY	;Disable parity
	MOVEA.W #0,A0		;Base of test area
	MOVEQ	#1,D1		;Set up top of test area @ 1FFFEH
	SWAP	D1
	MOVE.W	#0FFFEH,D1
	MOVEA.L D1,A1
	LEA	$10,A2		;Return address
	BRA	MEMCHK		;Go check the memory

;	Will return here if bottom 128K memory is good.
$10	BNE.S	$40		;Skip next mem check if error detected
	LEA	$15,A3		;Set up trap for no SAGE 4
	MOVE.L	A3,BE_TRAP
	BSET	#2,WP_2B
$15	LEA	SYSSTACK,SP	;Restore stack pointer
	LEA	$30,A3
	MOVE.L	A3,BE_TRAP	;Init Bus Error Trap for non existant memory
	MOVEQ	#2,D1		;128K interval
	SWAP	D1		;Load 20000H
	ADDA.L	D1,A1		;First test location = 3FFFEH
	MOVE.W	#0A5A5H,D0	;Test pattern

$20	MOVE.W	D0,(A1)		;Try location
	CMP.W	(A1),D0
	BNE.S	$30		;Location did not store correctly
	NOT.W	D0
	MOVE.W	D0,(A1)		;Try with complemented data
	CMP.W	(A1),D0
	BNE.S	$30		;Location did not store correctly
	NOT.W	D0
	ADDA.L	D1,A1		;Advance by 128K
	BRA.S	$20		;Try next group

;	This is first sizing failure
$30	LEA	SYSSTACK,SP	;Restore stack pointer
	SUBA.L	D1,A1		;Back off to top of memory
	LEA	$40,A2		;Return address
	BRA	MEMCHK		;Go check the memory

;	Will return here if all sized memory is good.
$40	BEQ.S	$45		;No error
	TST.B	DIPSWT
	BPL	LOOPFAIL	;Terminate loop test with failure
$45	MOVE.W	#192.-1,D0	;Clear debugger & BIOS RAM area
	LEA	MEMTOP,A0
$50	CLR.L	(A0)+
	DBF	D0,$50
	ADDQ.L	#2,A1		;Size of memory
	MOVE.L	A1,MEMTOP	;Set up TOP of Memory
	MOVE	A1,USP		;User stack is at top of memory
	MOVE.L	A1,REGUS	;Initialize user stack ram
	MOVE.L	A1,REGA7	;Initialize system stack ram
	LEA	$55,A1		;Set up Bus Error Trap for no SAGE 4
	MOVE.L	A1,BE_TRAP
	BCLR	#2,WP_2B
$55	LEA	SYSSTACK,SP	;Restore stack pointer
	BSR	SETTRAP		;Set up default traps
	MOVE.B	#0,CPARITY	;Re-enable parity on SAGE 2
	
	TST.B	DIPSWT		;Check if Looped
	BMI.S	MEMSIZ		;No looped testing
	MOVE.B	#7,C8255+6	;Turn off LED
	MOVEQ	#-1,D0
$60	DBF	D0,$60		;Short delay
	MOVE.B	#6,C8255+6	;Turn LED back on
	BRA	PROMTEST
	

;	Printout memory size
MEMSIZ	BSR	TERMCRLF
	LEA	MSG14,A0	;Printout 'RAM Size = '
	BSR	TERMTEXT
	MOVE.W	MEMTOP,D0	;Index to proper size message
	LSL.W	#6,D0
	BSR	TERMDECM
	MOVEQ	#"K",D0
	BSR	TERMCHAR
	BSR	TERMCRLF
	BRA.S	HARDC

;	Loop Test failure
LOOPFAIL
	STOP	#2700H


.PAGE
;****************************************************************************
;
;	Set up hardware configuration.
;
;	The floppy drive configuration for bootstrapping is selected by
;	DIP switch 7 on the CPU board.
;
;		SW 7	Configuration:
;		On	Double sided/double density (48 TPI)
;		Off	Double sided/double density (96 TPI)
;
;****************************************************************************

HARDC	MOVEQ	#40.,D1		;Default number of cylinders
	MOVEQ	#2,D2		;Number of sides
	BTST	#6,DIPSWT	;Get switch setting
	BEQ.S	$20		;Is 48 TPI
	MOVEQ	#80.,D1		;Number of cylinders
$20	MOVE.B	D2,FI_DRV0+FI_SIDE
	MOVE.B	D1,FI_DRV0+FI_NCYL
	CLR.B	FI_DRV0+FI_DRV
	MOVE.B	D2,FI_DRV1+FI_SIDE
	MOVE.B	D1,FI_DRV1+FI_NCYL
	MOVE.B	#1,FI_DRV1+FI_DRV
	
	MOVEQ	#6,D1		;Set up auxillary channel baud rate = 9600
	BSR	AUXBAUD

;	Determine if SAGE 4
	CLR.B	SAGE4		;Default to SAGE II
	MOVEA.L BE_TRAP,A1	;Save previous contents
	LEA	$30,A0
	MOVE.L	A0,BE_TRAP
	MOVE.B	#0AAH,WP_1B	;Set up a pattern
	MOVE.B	#5,WP_2C	;Try to disturb pattern
	CMPI.B	#0AAH,WP_1B
	BNE.S	$30		;Winchester port does not exist
	MOVE.B	#0,WP_1B	;Back to idle
	ST	SAGE4		;Set up SAGE IV flag
	MOVE.W	#230H,VCOCAL	;Set up VCO calibrate value for Winchester
$30	LEA	SYSSTACK,SP	;Restore SP in case of bus error
	MOVE.L	A1,BE_TRAP	;Restore previous contents


.PAGE
;****************************************************************************
;
;	Execute appropriate bootstrap.
;
;	The bootstrap is selected by DIP switches 5 & 6 on the CPU board.
;		SW 6	SW 5	Boot
;		off	off	Debugger
;		off	on	Floppy disk drives
;		on	off	Hard disk drive (future)
;		on	on	Network (future)
;
;****************************************************************************

BOOTS	MOVE.B	DIPSWT,D0	;Get switch settings
	AND.W	#30H,D0
	BEQ.S	BOOTS0		;Selected Network (default to debugger)
	CMP.W	#20H,D0
	BEQ.S	BOOTS2		;Selected floppy boot

;	Network currently defaults to debugger

	CMP.W	#10H,D0
	BEQ.S	BOOTS1		;Selected hard disk boot

;	Prepare to enter debugger
BOOTS0	MOVE.L	MEMTOP,REGUS	;Set up default user stack pointer
	MOVE.L	MEMTOP,REGA7	;Also is default system stack pointer
	MOVE.W	#2700H,REGSR	;Default status register
				;No trace, supervisor mode,
				;interrupts locked out
	LEA	USER,A0		;Set up default program counter
	MOVE.L	A0,REGPC
	BRA	DEBUG		;Now enter debugger

;	Floppy disk bootstrap
BOOTS2	CLR.W	-(A7)		;Drive number
BOOTSX	BSR	FDBOOT
	BRA	BOOTS0		;Couldn't boot, enter debugger

;	Winchester disk bootstrap
BOOTS1	TST.B	SAGE4		;Check if a SAGE 4
	BEQ	BOOTS0		;Not a SAGE 4
	MOVE.L	MEMTOP,D0	;Find out how much memory
	SWAP	D0
	MOVEQ	#12.,D1
	SUB.W	D0,D1
	BLE.S	$30		;No delay necessary
	MULU	#10.,D1
	SUBQ.W	#1,D1
$10	MOVE.W	#28570.,D0	;Set up 50 millisecond delay
$20	DBF	D0,$20
	DBF	D1,$10
$30	CLR.W	-(SP)		;Drive number
	MOVEQ	#1,D0
	MOVE.L	D0,-(SP)	;Partition number
	BSR	WDBOOT
	BRA	BOOTS0		;Couldn't boot, enter debugger


;	Default user routine when entering debugger
USER	TRAP	#15.		;Force debugger entry
	BRA.S	USER		;Don't let continue get loose



                                                                                                                                                                                                                                                                                