.PAGE
;*******************************************************
;*						       *
;*		  LOAD COMMAND			       *
;*						       *
;*  COPYRIGHT (c) 1982, 1983  SAGE Computer Technology *
;*  All Rights Reserved				       *
;*						       *
;*  12-Jul-83  Disabled interrupts & BUGBIOS on IS     *
;*						       *
;*******************************************************

CML
	LEA	SCML,A1		;Find command in table
	BRA	SRCHCMND

;LA - Load from auxillary port

CMLA
	MOVE.B	#1,LDDEVIC	;Set load device to auxillary channel
	BRA.S	CMLT1

;LT - Load from terminal

CMLT	CLR.B	LDDEVIC		;Set load device to terminal
CMLT1
	LEA	MSG24,A0	;Print Loading...
	BSR	TERMTEXT
	BRA.S	LOAD

;LFX XXX,[$X+]XXXXXX,XXXXXX - Load memory from floppy

CMLF
	CLR.L	D5		;Set read disk flag

; Perform disk transfer

DISKTRAN
	MOVEQ	#1,D2		;Get drive number
	BSR	GETNUM
	BMI	CMNDERR		;Drive number in error
	MOVE.W	D0,D6		;Save drive number
	MOVE.L	#0FFFFH,D2	;Get disk block number
	BSR	GETNUM
	BMI	CMNDERR		;Illegal block number
	MOVE.W	D0,-(A7)	;Store block num on stack
	BSR	CNVTADDR	;Get memory address for transfer
	BNE	CMNDERR		;Just address allowed
	MOVE.L	A1,-(A7)	;Store memory address on stack
	CLR.L	D2		;Get number of bytes to transfer
	BSR	GETNUM
	BMI	CMNDERR		;Command error detected
	MOVE.L	D0,-(A7)	;Store number of bytes on stack
	MOVE.W	D6,-(A7)	;Store drive number on stack
	TST.L	D5		;Read or write disk
	BEQ.S	$1		;Read disk
	LEA	MSG25,A0	;Print Loading...
	BSR	TERMTEXT
	BSR	FDWRITE		;Write to floppy
	BRA.S	$2
$1
	LEA	MSG24,A0	;Print Writing...
	BSR	TERMTEXT
	BSR	FDREAD		;Read floppy
$2
	BEQ	$3		;No errors detected
	LEA	DISKERR,A0	;Print disk error
	BSR	TERMTEXT
	BSR	TERMHEXB	;Print error number
$3
	RTS
DISKERR .BYTE	CR,LF		;Disk error message
	.ASCII	"Disk error: "
	.WORD	0
.PAGE
;****************************************************************************
;
;	Serial port loader:
;
;	A4 must be preset to the USART data address (control address is +2).
;
;	Routine register usage:
;	  D7 = load record type (in ASCII)
;		"0" - header record
;		"1" - data record with two byte address
;		"2" - data record with three byte address
;		"9" - terminating record
;	  D6 = byte count (working value is less one for checksum byte).
;	  D5 = checksum accumulator (proper checksum is 0FFH when the count
;				     address, data, and checksum bytes are
;				     added together).
;	  D1 = numeric accumulator
;
;****************************************************************************

LOAD	BSR.S	LDCHAR		;Get initial character
	CMPI.B	#"Q",D0
	BEQ	LOADERR		;Quit loading (with error) if Q detected
				;This can be forced from terminal channel
	CMPI.B	#"S",D0		;Wait for an S
	BNE.S	LOAD
	CLR.B	D5		;Clear checksum accumulator
	BSR.S	LDCHAR		;Get record type and save
	MOVE.B	D0,D7
	BSR	LDBYTE
	MOVE.B	D1,D6		;Save byte count
	SUBQ.B	#1,D6		;Compensate for checksum byte
	CLR.L	D1		;Clear numeric accumulator for address
	BSR	LDBYTE		;Get address
	BSR	LDBYTE
	MOVEA.L D1,A3		;Save address
	CMPI.B	#"0",D7		;Identify load record type
	BNE.S	$30		;Not header record

;	Dump remaining data in header record
$10	TST.B	D6		;Check byte count
	BEQ.S	$20		;Done with record
	BSR	LDBYTE		;Get rid of byte
	BRA.S	$10		;Back for more

;	Check the checksum and return to the main loop
$20	BSR.S	CHKSUM
	BRA.S	LOAD		;Back for next record

$30	CMPI.B	#"2",D7		;Check for extended address record
	BNE.S	$50		;Not extended address record

;	Found three byte address field
	MOVE.L	A3,D1		;Set up to append third byte
	BSR	LDBYTE		;Get extra address byte
	MOVEA.L D1,A3		;Save address again

;	Store data record in memory
$40	TST.B	D6		;Any bytes left?
	BEQ.S	$20		;Done with data, go check the checksum
	BSR	LDBYTE		;Get a data byte
	MOVE.B	D1,(A3)+	;Store the data byte in memory
	BRA.S	$40		;Back for another byte

$50	CMPI.B	#"1",D7		;Check for standard data record
	BEQ.S	$40		;Found standard record, transfer the data
	CMPI.B	#"9",D7		;Check for termination record
	BNE.S	LOADERR		;Unrecognized record type

;	Found termination record
	TST.B	D6		;Check that no more data exists
	BNE.S	LOADERR		;Should have been at end of data
	BSR.S	CHKSUM		;Check the checksum
	LEA	MSG7,A0		;Printout LOAD DONE
	BSR	TERMTEXT
	BRA	DEBUG		;Back to debugger

.PAGE
;****************************************************************************
;
;	Get characters from load device.
;
;	A4 must contain address of USART.
;
;	The routine returns a character from the selected device with
;	bit 7 stripped off.  If the device is not the terminal, the terminal
;	input is checked for the character Q.  If a Q is typed on the
;	terminal it is returned as the character to force termination of
;	the load process.
;
;****************************************************************************

LDCHAR	TST.B	LDDEVIC		;Check if using terminal port
	BEQ.S	$20		;Using terminal
	BTST	#1,AUX1_S	;Check USART for a character
	BEQ.S	$10		;No character yet
	MOVE.B	AUX1_I,D0	;Get the character
	BCLR	#7,D0		;Strip off bit 7
	RTS

;	Not loading from terminal, check for Q from terminal to abort
$10	BSR	KEYCHK		;Check for a terminal character
	BEQ.S	LDCHAR		;No terminal character
	BSR	KEYBCH		;Get keyboard character
	CMPI.B	#"Q",D0
	BNE.S	LDCHAR		;Not Q, try again
	RTS			;Return with Q as character

;	Loading from terminal
$20	BSR	KEYBCHAR	;Get a character
	CMPI.B	#CR,D0
	BEQ	TERMCRLF	;Was CR, Echo CR & LF and return
	BRA	TERMCHAR	;Echo the character and return
	
.PAGE
;****************************************************************************
;
;	Loader checksum test and loader error reporting
;
;	An illegal checksum will report BAD CHECKSUM and return to debugger.
;
;****************************************************************************

;	Loader checksum check routine
CHKSUM	BSR.S	LDBYTE		;Get the checksum byte
	NOT.B	D5		;Total should be 0FFH
	BNE.S	$10		;Illegal checksum
	RTS

$10	ADDQ.L	#4,A7		;Pop one return address from stack
	LEA	MSG9,A0		;Printout BAD CHECKSUM
	BSR	TERMTEXT
	BRA	DEBUG		;Back to debugger

;	Loader error reporting
LOADER2 ADDQ.L	#8,A7		;Pop two return addresses from stack
LOADERR LEA	MSG8,A0		;Printout BAD LOAD
	BSR	TERMTEXT
	BRA	DEBUG		;Back to debugger

.PAGE
;****************************************************************************
;
;	Assemble a byte of data from two ASCII hex characters
;
;	Byte value is shifted into the low byte of D1.	A non hex digit
;	will force a BAD LOAD message.
;
;****************************************************************************

LDBYTE	BSR.S	LDDIGT		;Get first digit
	BSR.S	LDDIGT		;Get second digit
	ADD.B	D1,D5		;Add new byte into checksum
	SUBQ.B	#1,D6		;Decrement byte count
	RTS

;	Shift a hex digit into the low nibble of D1
LDDIGT	BSR.S	LDCHAR		;Get a character
	CMPI.B	#"0",D0
	BLT.S	LOADER2		;Not a hex number
	CMPI.B	#"9",D0
	BGT.S	$20		;Not a decimal digit, maybe A-F
$10	SUBI.B	#"0",D0
	LSL.L	#4,D1
	ADD.B	D0,D1
	RTS

$20	CMPI.B	#"A",D0
	BLT.S	LOADER2		;Not a hex number
	CMPI.B	#"F",D0
	BGT.S	LOADER2		;Not a hex number
	SUBQ.B	#"A"-"0"-10.,D0 ;Remove alpha bias
	BRA.S	$10
.PAGE
;****************************************
;*					*
;*	     WRITE COMMAND		*
;*					*
;****************************************

CMW
	LEA	SCMW,A1		;Find command in table
	BRA	SRCHCMND
CMWF
	MOVEQ	#1,D5		;Set write flag
	BRA	DISKTRAN	;Perform transfer
CMWA
	BRA	DEBUG		;Currently stubbed out
.PAGE
;****************************************
;*					*
;*	  INITIALIZATION COMMANDS	*
;*					*
;****************************************

CMI
	LEA	SCMI,A1		;Find command in table
	BRA	SRCHCMND

;IS - Intialize system

REINITT
	.ASCII	"  System reinitializing...."
	.BYTE	0
	.ALIGN	2
CMIS
	MOVE	#2700H,SR
	MOVE.B	#25H,TERM_C	;Turn on transmit
	CLR.B	BUGBIOS		;Back to polled I/O
	LEA	REINITT,A0	;Display initialization message
	BSR	TERMTEXT
	MOVEQ	#-1,D0		;Delay for output
$10	DBF	D0,$10
	BRA	START
	
;IF[R]X - Boot floppy into location 400

CMIF
	CLR.L	D0		;Assume drive 0
	CLR.L	D7		;Assume clear ram
	MOVE.B	(A0),D0		;Clear memory
	CMPI.B	#"R",D0		;Clear ram?
	BNE.S	$2		;No
	MOVE.W	#100H,D7	;Set no ram clear flag
	ADDQ.L	#1,A0		;Move to next byte
 $2
	MOVE.B	(A0),D0		;Any drive selected
	BEQ.S	$1		;Yes
	MOVEQ	#1,D2		;Only drives 0,1
	BSR	GETNUM		;Get drive number
	BMI	CMNDERRA
$1
	OR.W	D7,D0		;Compute request parameter
	MOVE.W	D0,-(A7)	;Pass drive number on stack
	BSR	FDBOOT
	RTS
	
;IH - Initialize system from hard disk?

CMIH
	TST.B	SAGE4		;Check if is SAGE 4
	BEQ	CMNDERRA	;Error if not SAGE 4
	CLR.L	D0		;Assume drive 0
	CLR.L	D7		;Assume clear ram
	MOVEQ	#1,D6		;Default partition number
	MOVE.B	(A0),D0		;Clear memory
	CMPI.B	#"R",D0		;Clear ram?
	BNE.S	$2		;No
	MOVE.W	#100H,D7	;Set no ram clear flag
	ADDQ.L	#1,A0		;Move to next byte
 $2
	MOVE.B	(A0),D0		;Any drive selected
	BEQ.S	$100		;Use defaults
	
	CMPI.B	#" ",D0		;Check for delimiter
	BEQ.S	$20		;Found delimiter
	SUBI.B	#ZERO,D0
	BLT	CMNDERRA	;Not a number
	CMPI.B	#3,D0
	BGT	CMNDERRA	;Not a number
	OR.B	D0,D7		;Compute request parameter
	ADDQ.L	#1,A0		;Advance pointer

$20	BSR	SKIPSPAC	;Skip spaces
	TST.B	D0
	BEQ.S	$100		;No more characters
	CMPI.B	#"#",D0
	BNE	$30		;Must be a name
	ADDQ.L	#1,A0		;Advance pointer
	TST.B	(A0)
	BEQ.S	$100		;No more characters
	MOVEQ	#0FH,D2		;Partitions to 15
	BSR	GETNUM		;Get partition number
	BMI	CMNDERRA	;Command error
	MOVE.W	D0,D6		;Set up partition
	BRA.S	$100

;	Handle symbol
$30	MOVEQ	#8-1,D2		;Character limit
	LEA	BOOTNAME,A1
	MOVE.L	A1,D6		;Set up pointer to partition name
	CLR.L	(A1)		;Clear boot name
	CLR.L	4(A1)
	CLR.B	8(A1)
$40	BSR	GETCHAR
	BEQ.S	$100		;Done
	MOVE.B	D0,(A1)+	;Save character
	DBF	D2,$40

$100	MOVE.W	D7,-(A7)	;Pass drive number on stack
	MOVE.L	D6,-(A7)	;Partition number
	BSR	WDBOOT
	RTS

;IG - Initialize system from GHIB 488 bus

CMIG
	RTS

;IC - Initialize CRT (Clear CRT)

CMIC
	MOVEQ	#24,D2		;Send 25 lines to console
$1
	BSR	TERMCRLF
	DBF	D2,$1
	RTS

;IT - Initialize trace & trap 15

CMIT
	LEA	TRAP11,A1	;Set trace trap
	MOVE.L	A1,024H
	LEA	TRAP10,A1	;Set trap 15 (debugger trap)
	MOVE.L	A1,0BCH
	RTS

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