; Constants about machine.

COREND	= 8.*1024.	; First unusable word


WIDTH	= 1024.		; Height of display
HEIGHT	= 768.		; Width of display

; Address of registers.

DPC     = 172000        ; VT40 Program counter
DSR     = 172002        ; VT40 Status register
XSR     = 172004        ; X status register
YSR     = 172006        ; Y status register

; Recommended mnemomics

CHAR    = 100000        ; Character mode
SHORTV  = 104000        ; Short vector mode
LONGV   = 110000        ; Long vector mode
POINT   = 114000        ; Point mode
GRAPHX  = 120000        ; Graphplot X mode
GRAPHY  = 124000        ; Graphplot Y mode
RELATV  = 130000        ; Relative point mode

INT0    = 2000          ; Intensity modes
INT1    = 2200
INT2    = 2400
INT3    = 2600
INT4    = 3000
INT5    = 3200
INT6    = 3400
INT7    = 3600

LPOFF   = 100           ; Light pen off
LPON    = 140           ; and on

BLKOFF  = 20            ; Blink off
BLKON   = 30            ; and on

LINE0   = 4             ; Solid line
LINE1   = 5             ; Long dash
LINE2   = 6             ; Short dash
LINE3   = 7             ; Dot dash

DJMP    = 160000        ; Display jump
DNOP    = 164000        ; Display NOP

STATSA  = 170000        ; Load status A
DSTOP   = 173400        ; Display stop and interrupt

SINON   = 1400          ; Stop interrupt on
SINOFF  = 1000          ; Stop interrupt off
LPLITE  = 200           ; Light pen hit on
LPDARK  = 300           ; and off

ITAL0   = 40            ; Italics off
ITAL1   = 60            ; and on

SYNC    = 4             ; Halt and resume in Sync

STATSB  = 174000        ; Load status B
INCR    = 100           ; Graphplot increment

INTX    = 40000         ; Intensify vector or point
MAXX    = 1777          ; Max delta-x
MAXY    = 1377          ; Max delta-y

MINUSX  = 20000         ; -ve delta-x
MINUSY  = 20000         ; -ve delta-y

MAXSX   = 17600         ; Max delta-x in short mode
MAXSY   = 77            ; Max delta-y

MISVX   = 20000         ; -ve delta-x
MISVY   = 100           ; -ve delta-y

        .PSECT

;       Simple PDP-11 program

	MOV	#COREND-2,SP	; Set up stack

; R2 - x
; R3 - DPC when writing display file
MAIN:	MOV	#END,R3		; where to start writing point data
	CLR	R2		; start x at 0

LOOP:

	; compute next point on graph
	MOV	R2,R0
	JSR	PC,SQRT
	; validate return value
	BIT	#176000,R1	; Y range check - max 10 bits
	BNE	BOOB
	MOV	R1,(R3)+
	INC	R2
	CMP	#WIDTH-1,R2
	BPL	LOOP		; loop until x>WIDTH-1

DISPLAY:
	MOV	#DJMP,(R3)+	; fix up end of display program
	MOV	#DLOOP,(R3)+

	MOV	#DPROG,@#DPC	; start displayprocessor runnig

	WAIT			; for ever
	HALT

BOOB:	; Got a duff value from sqrt!
	MOV	#1,@#DSR	; Beep!
	BR	DISPLAY

; Integer square root, Martin Guy, June 1988.
; Negative arguments are simply negated to make things easy.
; Status: works for arguments -32767 to +32767
; Argument in R0 -> result in R1, remainder in R0

; R0	op
; R1	res
; R2	one
; R3	tmp (op-res-one)
SQRT:
	; validate argument
	TST	R0
	BEQ	SQRT1		; if (op == 0) return(0);
	BPL	SQRT2		; op = abs(op)
	NEG	R0

	; preserve temporary registers
SQRT2:	MOV	R2,-(SP)	; preserve temporaries
	MOV	R3,-(SP)

	; initialise: res = 0; op = highest power of 4 <= op
	CLR	R1

	MOV	#40000,R2
	BR	SQRT4
SQRT3:	ASR	R2
	ASR	R2
SQRT4:	CMP	R0,R2
	BMI	SQRT3		; loop until one <= op (R2 <= R0)
				; ie until (R0 - R2) is positive or 0

	; main sqrt loop
SQRT5:	MOV	R0,R3		; op2 = op -res - one
	SUB	R1,R3
	ASR	R1		; loop reinit moved here from end for speed
	SUB	R2,R3
	BMI	SQRT6		; can't do it if it underflowed
	; it can happen - do it.
	MOV	R3,R0		; op = op2
	ADD	R2,R1		; res += 2 * one (+=1*one cos R1 already >>)
SQRT6:
	ASR	R2		; one >>= 2
	ASR	R2
	BNE	SQRT5		; while (one > 0);

	; all done
	MOV	(SP)+,R3
	MOV	(SP)+,R2
	RTS	PC

; Code fragment: 
SQRT1:
	CLR	R1
	RTS	PC

; end of SQRT

DPROG:	
	STATSB+INCR+1

DLOOP:	POINT
	0
	0
	GRAPHY
END:	.END
	; rest of display program follows...
