#
# Copyright (c) 1995, 1996 Berkeley Software Design, Inc.  All rights reserved.
# The Berkeley Software Design Inc. software License Agreement specifies
# the terms and conditions for redistribution.
#
#	BSDI ncr_runop,v 1.4 1999/12/16 01:58:48 cp Exp

#
#	Don't reset location counter until after all code is done.
#	There is no filler when the location counter is moved.

#	If tracing is turned on and off in the firwmware, beware
#	that the next instruction may/will be skipped.



#
#	runop interrrupts run from 0x1000 up
#	selector interrupts run from 0x999 down
#
	
	i_i2long	= 0x1000
	i_o2long	= 0x1001
	i_phase		= 0x1002
	i_msghelp	= 0x1003
	i_nocode	= 0x1005
	i_debug1	= 0x1006


	slot_done	= 0x04		#must not step on selector bits
	slot_newwork	= 0x02		#must match entry in selector



start:
	memmv 4 physaddr dsa;
curop = . + 8
	memmv 4 virtual 0;
	memmv 4 temp savereturn;

	mv scratcha0 sfbr;
	jmp data 1 mask 1 reselectit;

newwork:
	memmv 4 zero save_partial;
	memmv 4 inlist	save_inlist;
	memmv 4 outlist	save_outlist;

	memmv 4 sendmsg scratcha;
	mv scratcha0 sfbr;
	jmp data 1 with_attention;
	select ti t_select r resel; 
	jmp phaselock;
with_attention:
	select atn ti t_select r resel; 

phaselock:
	jmp wait msg_in r p_msgin;
	jmp data_in r input_data;
	jmp data_out r output_data;
	jmp msg_out r p_msgout;
	jmp status r p_status;
	jmp cmd p_cmd;
	int i_phase;

resel:
	ld 1 scratchb;		# tell selector that we didn't start
	jmp leave;

p_msgout:
	memmv 4 ideflag scratcha;
	mv scratcha0 sfbr;
	or sist0 0 sfbr;
	jmp data 0x1 mask 0x1 perror;	
	blkmv msg_out ti t_id_msg;
msg_ostop:
	jmp phaselock;

perror:
	memmv 4 zero ideflag;
	blkmv msg_out 1 idemsg;		# initiator detected error 
	jmp phaselock;

p_cmd:
	blkmv cmd ti t_cmd;
	jmp phaselock;

p_status:
	blkmv status 1 status_byte;
	jmp phaselock;

p_msgin:
	blkmv msg_in 1 rcvmsg;
	jmp data 0x00 done;		# complete message is zero
	jmp data 0x01 extmsg;
	jmp data 0x02 savepointers;
	jmp data 0x03 restorepointers;
	jmp data 0x04 msg_disconnect;
	jmp data 0x80 mask 0x80 msg_id;
	jmp data 0x20 mask 0xf0 msg_twobyte;
	clear atn;
	int i_msghelp;
send_reply:
	set atn;
no_reply:
	clear ack;
	jmp phaselock;

msg_twobyte:
	clear ack;
	blkmv msg_in 1 rcvmsg + 1;
	clear atn;
	clear ack;
	int i_msghelp;

extmsg:
	clear ack;
	blkmv msg_in 1 rcvmsg + 1;
	clear ack;
	jmp data 3 extmsg3;
	jmp data 4 extmsg4;
	jmp data 5 extmsg5;
	jmp data 6 extmsg6;
#
#	If we get here we just want to get rid of the
#	message. This should never happen.
#
tossmsg:
	clear ack;
	jmp not wait msg_in tossmsg1;
	blkmv msg_in 1 rcvmsg;
	jmp tossmsg;
tossmsg1:
	int i_msghelp;

extmsg4:	blkmv msg_in 4 rcvmsg + 2;	jmp extmsg_done;		
extmsg5:	blkmv msg_in 5 rcvmsg + 2;	jmp extmsg_done;		
extmsg6:	blkmv msg_in 6 rcvmsg + 2;	jmp extmsg_done;		
extmsg3:	blkmv msg_in 3 rcvmsg + 2;

#
#	we need to re-arrange this if we want to allow the
#	driver to reply to these messages
#
extmsg_done:
	clear atn;
	clear ack;
	int i_msghelp;

done:
	ld 0 scntl2;
	clear ack;
	disconnect;

	memmv 4 virtual scratchb;
	memmv 4 status_byte scratcha;
	mv scratcha0 sfbr;
	jmp data 0x3e mask 0x2 leave; # let driver dequeue if check cond 
	or 2 scratchb0;
leave:
savereturn = . + 4
	jmp 0;

msg_id:
	clear ack;
	int i_debug1;
	jmp phaselock;

savepointers:
	clear ack;
	memmv 8 t_partial save_t_partial;
	memmv 4 partial save_partial;
	memmv 4 inlist	save_inlist;
	memmv 4 outlist	save_outlist;
	jmp phaselock;

restorepointers:
	clear ack;

restorepointers1:

	memmv 8 save_t_partial t_partial;
	memmv 4 save_partial partial;
	memmv 4 save_inlist inlist;
	memmv 4	save_outlist outlist;
	jmp phaselock;

msg_disconnect:
	ld 0 scntl2;
	clear ack;
	disconnect;
	ld 3 scratchb0;
	jmp leave;




output_data:
	memmv 4 partial scratcha;
	add 1 scratcha0;
	jmp not carry output_data1;
	memmv 8 t_partial t_data; 
	memmv 4 zero partial;
	jmp r  output_data2;
output_data1:
outlist = . + 4
	memmv 8 0 t_data;		
	memmv 4 t_data scratcha;
	add 1 scratcha3;		# ff stopper in unused byte
	int carry i_o2long;
output_data2:
	blkmv data_out ti t_data;
ostop:
	memmv 4 outlist scratcha;
	add 8 scratcha0;
	add carry 0 scratcha1;
	memmv 4 scratcha outlist;
	jmp wait data_out r output_data1;
	jmp phaselock;

otoss:
	set atn;
otoss1:
	jmp not wait data_out phaselock;
	blkmv data_out 1 trash;
	jmp otoss1;
	
input_data:
	memmv 4 partial scratcha;
	add 1 scratcha0;
	jmp not carry input_data1;
	memmv 8 t_partial t_data; 
	memmv 4 zero partial;
	jmp r  input_data2;
input_data1:
inlist = . + 4
	memmv 8 0 t_data;	
	memmv 4 t_data scratcha;
	add 1 scratcha3;		# ff stopper in unused byte
	int carry i_i2long;
input_data2:
	blkmv data_in ti t_data;
istop:
	memmv 4 inlist scratcha;
	add 8 scratcha0;
	add carry 0 scratcha1;
	memmv 4 scratcha inlist;
	jmp wait data_in r input_data1;
	jmp phaselock;

itoss:
	set atn;
itoss1:
	jmp not wait data_in phaselock;
	blkmv data_in 1 trash;
	jmp itoss1;

reselectit:
#	memmv 1 t_select + 3 scntl3;
#	memmv 1 t_select + 1 sxfer;
#	jmp not data 2 mask 2 restorepointers1;
#	clear ack;		# selector ate message in
	jmp restorepointers1;

endcode:

t_id_msg:	. = . + 8
t_cmd:		. = . + 8
t_extmsg:	. = . + 8
t_data:		. = . + 8
t_select:	. = . + 4

t_partial:	. = . + 8
partial:	. = . + 4
sendmsg:	. = . + 4	# send message at start of operation 

save_t_partial:	. = . + 8
save_partial:	. = . + 8
save_inlist:	. = . + 4
save_outlist:	. = . + 4
physaddr:	. = . + 4
virtual:	. = . + 4
msgctl:		. = . + 4
ideflag:	. = . + 4
rcvmsg:		. = . + 16
idemsg:		. = . + 4
trash:		. = . + 8
status_byte:	. = . + 4		# only use one byte but keep alignment

zero:		. = . + 4		# used as a zero source in memmv

nsg = 20
sg:		. = . + (nsg * 8)
eot:
