;_______________________________________________________________________
; VCXXSYNC - Initialize the VCX-Q for external sync
; Procedural Outline:
; - Map I/O page into program virtual address space.
; - Check for existence of registers. On trap, report address and terminate.
; - Load initialization parameters into the CRTC registers.
; - Set up for being driven by external sync.
; - Print success message.
;
; patch these locations for non-standard addresses
	.psect	data
basereg::	.address	base
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
; vcxxsync - initialize CRTC
	.psect	code
	.entry	vcxxsync,^M<r2,r3,r4,r5,r6>

 	; use system service routine to map in I/O page
	ashl	#-9.,basereg,tmpbuf
	$crmpsc_s	-	; create and map section
	  inadr=adrstr,       -	; start/ending virtual adrs to use (these
			      -	; are overridden by the sec$m_expreg flag)
	  retadr=mapadr,      -	; where to return virtual address
	  flags=#sec$m_wrt!sec$m_pfnmap!sec$m_expreg, - ; option flags:
				- ; wrt: section is read/write, 
				- ; pfnmap: physical page-frame section, 
				- ; expreg: use first avail. virtual adr space
	  pagcnt=#1, -		; size of section in pages
 	  vbn=tmpbuf		; physical page frame number of I/0 page 
	blbs	r0,10$		;ERROR ON MAPPING?
	pushl	r0		; pass error code to system error handler
	calls	#1,G^LIB$SIGNAL	; report the error
	ret

	; set up new virtual addresses for registers 
10$:	bicl3 	#^xfffffe00,basereg,r2	; r2 = i/o page offset for registers
	addl3	mapadr,r2,acrtadr	; CRTC address register
	addl3	#2,acrtadr,acrtbuf	; CRTC data buffer register
	addl3	#8,acrtadr,glar
	addl3	#10.,acrtadr,gcmmdbr
	addl3	#12.,acrtadr,gcsrreg
	addl3	#14.,acrtadr,gcrtbuf
	clrw	@gcsrreg		; graphics off
	clrw	@acrtadr		; alpha off
	movw	#^o36,@acrtbuf
	movw	#vrcfm0,@acrtadr
	movw	#^o204,@acrtbuf		; sync input mode

	clrw	@glar
	movw	#^o36,@gcrtbuf
	movw	#1,@glar
	movw	#^o204,@gcrtbuf		; sync input mode

	clrl	r4			; clear error flag

; wait for xodd field to be set
	movl	#^x80000,r2  
205$:	bitw	#xodd,@gcrtbuf
	bneq	210$
	sobgtr	r2,205$
	callg	a$m2,G^LIB$PUT_OUTPUT

; wait for xodd field to be cleared
210$:	movl	#^x80000,r2 
215$:	bitw	#xodd,@gcrtbuf
	beql	220$
	sobgtr	r2,215$
	callg	a$m3,G^LIB$PUT_OUTPUT

; wait for vsyncx field to be set
220$:	movl	#^x80000,r2
225$:	bitw	#vsyncx,@gcrtbuf
	bneq	230$
	sobgtr	r2,225$
	callg	a$m4,G^LIB$PUT_OUTPUT
	incl	r4			; set error flag

; wait for vsyncx field to be cleared
230$:	movl	#^x80000,r2
235$:	bitw	#vsyncx,@gcrtbuf
	beql	240$
	sobgtr	r2,235$
	callg	a$m5,G^LIB$PUT_OUTPUT
	brb	250$

240$:	tstl	r4
	bneq	250$

; Mod by Joel Welling, PSC, 1/20/88 follows
;	movl	#^x8000,r2		; original line, changed in consult
					; with Dave Gotwisner of Peritek
	movl	#^o77,r2		; changed line
; End of mod by Joel Welling, PSC, 1/20/88
245$:	tstw	@gcsrreg		; delay for a while -- CRTC quirk
	sobgtr	r2,245$

	movw	#gcrtcon,@gcsrreg
	movw	#acrtcon!xsyncon!vcoclk,@acrtadr

; Mod by Joel Welling, PSC, 1/20/88 follows  (to silence field operation)
; 	callg	a$m6,G^LIB$PUT_OUTPUT
; End of mod by Joel Welling, PSC, 1/20/88
	ret

250$:	callg	a$m7,G^LIB$PUT_OUTPUT
	callg	a$m8,G^LIB$PUT_OUTPUT

	; restore state
	clrw	@gcsrreg		; graphics off
	clrw	@acrtadr		; alpha off
	movw	#^o36,@acrtbuf
	movw	#vrcfm0,@acrtadr
	clrw	@acrtbuf		; not sync input mode

	clrw	@glar
	movw	#^o36,@gcrtbuf
	movw	#1,@glar
	clrw	@gcrtbuf		; not sync input mode

	movw	#gcrtcon,@gcsrreg
	movw	#acrtcon,@acrtadr
	ret
;**************************************************************************
;	Memory trap handler
; Note: When returning from a memory trap, the state of the pc depends on
; 	the type of instruction that caused the trap. For some instructions
;	the pc is not updated (i.e., on return it points to the instruction
;	that caused the trap) (e.g., tstw). For other instructions it is
;	updated (i.e., on return it points to the instruction following
;	the instruction that caused the trap) (e.g., clrw).
;**************************************************************************
	.entry	exhand,^M<>
	incl	trpflg		; set memory trap flag
	movzwl	#SS$_CONTINUE,r0
	ret
	.psect	data
	;variables
adrstr:		.blkl	2	; needed for $crmpsc but not actually used
mapadr:		.blkl	2	; returned virtual address from $crmpsc
trpflg:		.blkl	1	; memory trap flag
savtrap:	.blkl	1	; save memory trap address

;alpha
acrtadr:	.blkl	1	; crtc address register pointer
acrtbuf:	.blkl	1	; crtc data buffer register pointer

;graphics
glar:		.blkl	1
gcmmdbr:	.blkl	1
gcsrreg:	.blkl	1
gcrtbuf:	.blkl	1	; crtc data buffer register pointer

badadr:		.blkl	1	; address that caused a trap
tmpbuf:		.blkl	1	; used for mapping memory address to virt addr

; Output Text Section
; argument lists begin with "a$"
; argument descriptors begin with "d$"
;
a$m1:	.long	1
	.address d$m1
a$a1f:	.long	2
	.long	badadr
	.address d$a1
a$m2:	.long	1
	.address d$m2
a$m3:	.long	1
	.address d$m3
a$m4:	.long	1
	.address d$m4
a$m5:	.long	1
	.address d$m5
a$m6:	.long	1
	.address d$m6
a$m7:	.long	1
	.address d$m7
a$m8:	.long	1
	.address d$m8
;---------------------------------------------------------------
; MACRO to set up a string descriptor
; arguments are:
;	stradr - string address
;	dscnam - label to use for the descriptor
;	strlen (optional) - length of string in bytes; if omitted, string must 
;		immediately preceed this descriptor
.macro  strdsc  stradr,dscnam,strlen
  dscnam:			; descriptor label
	.if b <strlen>		; if length not specified
	  .word	.-stradr	; compute length
	.iff
	  .word	strlen		; else use given length
	.endc
	.byte	dsc$k_dtype_t	; character string descriptor data type 
	.byte	dsc$k_class_s	; fixed length descriptor class
	.address stradr		; string pointer
.endm strdsc
;---------------------------------------------------------------
m1:	.ascii	/VCX register not found at address 0x/
a1:	.ascii	/12345678 (hex)/
	strdsc	m1,d$m1
	strdsc	a1,d$a1,8
;---------------------------------------------------------------
d$m2:	.ascid	/field bit not detected set/
d$m3:	.ascid	/field bit not detected clear/
d$m4:	.ascid	/external vertical sync bit not detected set/
d$m5:	.ascid	/external vertical sync bit not detected clear/
d$m6:	.ascid	/VCX initialized for external sync/
d$m7:	.ascid	/VCX not put into external sync mode because no/
d$m8:	.ascid	/    external vertical sync detected/

;	commented out the .end directive [PLA]
;	.end	vcxxsync
