.title	'LOGIN - log into the HiNet'
	.sbttl	'LOGIN'
version	==	2
revision==	1
	.pabs
	.phex
	.loc	100h
;----------
; Log into the HiNet by grabbing 
; the network code and executing it
; 
; (This code is almost identical to the PROM 'BN' code)
;
; Port definitions:
DMA	==	38h	; DMA chip
CTC3	==	33h	; CTC channel 3
SIO1AC	==	2Ah	; SIO-1 channel A, data -port 0
SIO1BC	==	2Bh	; SIO-1 channel B, control
SIO1BD	==	29h	; SIO-2 channel B, data -HiNet
PIOAC	==	0Ah	; PIO channel A, control
PIOAD	==	08h	; PIO channel A, data
PIOBC	==	0Bh	; PIO channel B, control
PIOBD	==	09h	; PIO channel B, data
SETMAP	==	03h	; Memory map register
HARDP	==	01h	; Hard disk parallel port
cr	==	0Dh	; carriage return
lf	==	0Ah	; line feed
NETusr	==	47h	; HiNet user number
;----------
; Step 1 - Greet the user, then flush floppy buffer
	lxi	D,greeting
	mvi	C,9
	call	5	; greet the user
	lda	NETusr
	ora	A
	jrnz	..flush	; if not master, then OK
	lxi	D,master
	mvi	C,9
	call	5	; if master, then can't login
	ret		; return to user
..flush:
	call	clrDDbuf; flush floppy write buffer
;----------
; Step 2 - cleanup all prior interrupts
	di
	lxi	H,rs232
	lxi	B,rs232$<8+SIO1AC
	outir		; reprogram port 0 w/o ints
	mvi	A,00000011b
	out	PIOAC	; deprogram front-panel int
	mvi	A,00000011b
	out	CTC3	; turn off timer interrupt
	sub	A
	out	PIOBD	; unload floppy head
;----------
; Step 3 - map in page 9 to the local RAM on DSC/4
	lxi	B,90h<8 + SETMAP
	mvi	A,0
	outp	A
;----------
; Step 4 - Boot from network
Network:
	mvi	A,(DMAvect>8)&0FFh
	stai
	im2
	mvi	A,1
	out	PIOAD	; multiplex SIO1B to DMA
	lxi	H,DMANprog
	lxi	B,DMAN$<8+DMA
	outir		; program the DMA chip
..rewait:
	lxi	H,RECprog
	lxi	B,REC$<8+SIO1BC
	outir		; program the SIO1B chip
;
; Wait for network boot code to begin flying by
	lxi	D,0
..wait:
	mvi	B,2
..loop:	in	SIO1BC	; wait for data addressed to us
	ani	1
	jrnz	..done
	djnz	..loop
	dcx	D
	mov	A,D
	ora	E
	jrnz	..wait	; timeout if nothing comes
	lxi	D,waiting
	mvi	C,9
	call	5	; tell the user we're waiting
	jmpr	..rewait
..done:
	in	SIO1BD	; throw away the user number
	mvi	A,87h	; enable DMA
	out	DMA
	ei
	hlt
	jmp	BOOTloc	; execute the bootstrap
;----------
; Process interrupt on DMA done
DMAvect:.word	DMARdone
DMARdone:
	push	PSW
	mvi	A,0C3h	; reset DMA chip
	out	DMA
	mvi	A,18h	; reset the SIO1B chip
	out	SIO1BC
	pop	PSW
	ret
;----------
; SDLC command strings
BOOTloc	==	9000h	; where to load boot code
lenBOOT	==	380h	; length of network boot code
BOOTusr	==	254	; boot pseudo user number
RECprog:
	.byte	    00011000b ; channel reset
	.byte	  4,00100000b ; SDLC mode
	.byte	15h,10000000b ; transmit disable
	.byte	  3,11111100b ; receiver info
	.byte	  6,BOOTusr   ; user number
	.byte	  7,01111110b ; flag byte
	.byte	11h,11100100b ; interrupt control
	.byte	23h,11111101b ; enable receiver
REC$	==	.-RECprog
;
DMANprog:
	.byte	0C3h	; master reset		    2D
	.byte	0C7h	; reset port A	 	    2D
	.byte	0CBh	; reset port B		    2D
	.byte	7Dh	; read from port B
	.word	BOOTloc	; DMA address
	.word	lenBOOT-1; DMA length - 1
	.byte	14h	; port A inc, memory	    1B
	.byte	28h	; port B fixed, I/O	    1B
	.byte	95h	; byte mode		    2B
	.byte	SIO1BD	; port B
	.byte	12h	; interrupt at end of block
	.byte	DMAvect&0FFh ; interrupt vector
	.byte	92h	; stop at end of block
	.byte	0CFh	; load starting address	    2C
	.byte	1	; read
	.byte	0CFh	; load starting address	    1A
	.byte	0ABh	; enable interrupts
DMAN$	==	.-DMANprog
;----------
; Messages
greeting:.ascii	[cr][lf]"HiNet Login version "
	.byte	version+'0','.',revision+'0'
	.ascii	[cr][lf]"$"
master:	.ascii	[cr][lf]
	.ascii	"Sorry, the master can't re-login.$"
waiting:.ascii	[cr][lf]"*** Waiting$"
;----------
; RS-232 command
rs232:
	.byte	18h		; channel reset
	.byte	14h,01001100b	; 2 stop bits
	.byte	 3 ,11000001b	; receiver enable
	.byte	 5 ,11101010b	; transmitter enable
	.byte	11h,00000000b	; no interrupts
rs232$	==	.-rs232
;----------
; Flush floppy write buffer
clrDDbuf:
	lhld	1	; HL = base of BIOS + 3
	lxi	D,5Ah
	dad	D	; compute offset of clrDDbuf
	pchl		; jump to clrDDbuf
.end
