

	.TITL   SR
;SOME USEFUL SUBROUTINES FOR USE WITH RESUB
;THESE WILL NOT WORK WITH TSBAS
;THESE ARE SOME SUBROUTINES THAT WE HAVE BEEN
;USING WITH RESUB.  THEY ARE SELECTED TO GIVE EXAMPLES
;OF THE VARIOUS LINKAGES USED.  THE PTP AND PTR DRIVER 
;ROUTINES SHOULD WORK WITH THE STANDARD DGC INTERFACES
;SOME OF THIS IS FOR USE WITH SPECIAL INTERFACE EQUIPMENT
;THAT WAS BUILT AT SUNY/B FOR USE WITH MOLECULAR BEAM 
;EQUIPMENT.
.ENT .CTU,.PTR,.PTP,.CDR,.DVUS,INIT,CLOSE, RDINP, OUTPT
.EXTN STBY
.EXTD .ACBY
	.EXTN INTER, INTR, TELO, TELO1

	.ENT SBRTB,  ADR, SBRTC, DVINT, .REC, .TRANS, WOC
	.EXTN  INTER, INTR, TELO, TELO1, IOBT
	.EXTD .FIX,.FLOT,C377, .INTR,.TASK,RUP
	.ENT BASE0, BGNDP, IOMSK, STRUP, B, CLK
	.EXTN  DEBUG

	.RDX 4
SS=22000000	;TWO PARAMETERS TO SUBROUTINE
S =20000000
R =30000000
RR=33000000
SR=23000000
SSS=22200000
ST=10000000	;ONE STRING VARIABLE
SST=21000000
SSST=22100000
	.RDX 8
	.ZREL
.LPTO:	LPTO
ADR:	0	;ADDRESS FROM BASIC
.REC:	RECV
.TRANS:	TRANS
C12:	12
CDSF:	0
.DSP:	DSP
SCLR:	.BLK 2
CLK: AB:	B
IOMSK:	0	;DOES NOT HAVE TO BE IN PAGE ZERO

	.NREL

;SUBROUTINE TABLE - DEBUG MAY BE CALLED AS A CONSOLE CALL
;ONLY (A TEST WILL BE MADE TO SEE IF DEBUG HAS
;ACTUALLY BEEN LOADED.  THE REST OF THE SUBROUTINES MAY 
;BE CALLED FROM EITHER THE CONSOLE OR A PROGRAM
;WE HAVE NOT BEEN ABLE TO PASS A STRING TO A SUBROUTINE
;AS A CONSOLE COMMAND.  IT MUST BE IN A PROGRAM AND
;ASSIGNED A VARIABLE NAME SUCH AS A$,ETC
SBRTC:	100.	;CALL DEBUG
	DEBUG
	0

SBRTB:
	26.	;DISPLAY WHILE RUNNING BASIC
	IDSP	;MODE, NO OF PTS<=2047
	SS	;MODE=0	;CALLED BY *5N CODE_KILL, 1_XY, 2_SCAN

	10.	;READ A CHARACTER ON PTR
	GBCHR	;IN BINARY
	R

	11.	;PUNCH ONE CHAR ON PTP
	PBCHR	;IN BINARY
	S

	

	20.	;STORE XY IN BFR
	STD	;CALL(20,CH#,X,Y)
	SSS

	30.	;CALL 30,X,T
	RDSLR
	RR	;SCALER READING,TIME

	40.	;CALL 40
	LPTA	;ACTIVATE LINE PRINTER
	0	;WILL RETURN TO TTO ON ERROR OR END

	13.	;GET ASCII CHARACTER STRING FROM PTR
	GACHR
	ST

	14.	;PUNCH ASCII CHARACTER STRING
	PACHR	;ON PTP
	ST

	9.	;CALL 9
	FILL	;FILL THE PTR BUFFER
	0	;NO VARIABLES PASSED

	-1	;END OF SUBROUTINE TABLE

;INTERRUPT SERVICE ROUTINE

DVINT:	INTA 2	;DEVICE CODE
	LDA 1 C34
	SUB 2 1 SNR
	JMP @.CLKI
	LDA 1 C12
	SUB 2 1 SNR
	JMP .PTRI @	;PTR
	INC 1 1 SNR
	JMP .PTPI @
	LDA 1 C17
	SUB 2 1 SNR
	JMP	@.LPTI	;LINE PRINTER
	JMP @.+1	;BASIC WILL CLEAR UNIDENTIFIED
	INTER	;INTERRUPT
C17:	17
C34:	34
.PTPI:	PTPI
.LPTI:	LPTI

.PTRI:	PTRI
.CLKI:	CLKI



;FOLLOWING ARE ROUTINES CALLED BY BASIC.
;RETURN TO C3 + NUMBER OF PARAMETERS PASSED.  C3 SHOULD BE
;IN ADR BEFORE USING SUBROUTINE
;#20 STORE X,Y IN BFR FOR DISPLAY

STD:	STA 3 ADR
	JSR FPNT	;FORM ADDRESS OF CH# IN BFR
			;AND STORE IN SAV2

	JSR RECV
	2	;GET X
	STA 1 @SAV2	;STORE IN BFR
	JSR RECV	;GET Y
	3
	LDA 0 C377
	ANDS 0,1	;MASK Y AND SWAP
	LDA 2 @SAV2	;GET X
	AND 0 2		;MASK X
	ADD 2,1
	STA 1, @SAV2	;STORE XY IN BUFFER
STD1:	LDA 3 ADR
	JMP 3,3		;RETURN TO BASIC


;SUBROUTINE TO GET A PARAMETER FROM BASIC AND FIX IT LOW ORDER
;PART IN C1.
;CALLING PROCEDURE:	JSR RECV
;			PARAMETER NO
;			RETURN

RECV:	INC 3 3
	STA 3 SAV0
	LDA 0,-1,3	;PARAMETER NO
	LDA 3 ADR
	ADD 0,3		;ADDRESS
	LDA 3 -1 3
	LDA 0,0,3	;HIGH ORDER
	LDA 1,1,3	;LOW ORDER FD
	JSR @.FIX	;FIX IT
	JMP @SAV0

;LIKE RECV EXCEPT SEND A PARAMETER TO BASIC
TRANS:	STA 3 SAV0	;CLEAR C0 FOR SINGLE PRECISION NUMBER
			;FLOT WILL CONVERT DOUBLE PREC.
	JSR @.FLOT
	LDA 2 @SAV0
	LDA 3 ADR
	ADD 2,3
	LDA 3 -1 3
	STA 0,0,3
	STA 1,1,3
	LDA 3 SAV0
	JMP 1,3
SAV0:	0	;ADDRESS IN C3 AT CALL
;#10, READ ONE CHARACTER ON PTR AND GO TO BASIC
GBCHR:	STA 3,ADR
	JSR @ .GCHR	;READ TAPE
	MOV 0 1
	SUB 0 0
	JSR TRANS	;SEND TO BASIC
	1		;PARAMETER #1
GBCH1:	LDA 3, ADR
	JMP 1,3
;#11	PUNCH ONE CHARACTER 
PBCHR:	STA 3 ADR
	JSR RECV
	1
	MOV 1 0
	JSR @ .PCHR
	JMP GBCH1
;FORM ADDRESS IN BUFFER FROM POINTER IN PARAMETER
;STORE ADDRESS IN SAVE2 AT RETURN ADDRESS IS IN C3
FPNT:	STA 3, SAV1
	JSR RECV
	1
	LDA 0 NMAX
	SUBZ# 1 0 SNC
	SUB 1 1		;SET POINTER TO ZERO IF TOO LARGE
	LDA 3,B
	ADD 1,3
	STA 3, SAV2	;STORE ADDRESS
	JMP @SAV1	;RETURN
SAV1:	0
SAV2:	0
C10:	10
;HANDLE SCALER AND REAL TIME CLOCK
CLKI:	DIAC 0,34	;GET SCALER COUNT
	INTEN
	STA 0, SCLR
	ISZ SCLR+1
	JMP .+1
	LDA 2 @RUP	;IS BASIC RUNNING?
	MOV 2 2 SZR	;RUN TIME ACCUMULATOR IN BASIC
	ISZ -23, 2	;BASIC'S REAL TIME ACCUMULATOR
	JMP .+1
	LDA 1, CDSF
	LDA 2, CLK	;POINTER FOR DISPLAY
	INTDS
	MOVR 1,1 SZC	;SHOULD WE DISPLAY?
	JSR @ .DSP	;YES
	JMP @ .INTR


;NOTE:  DEVICE CODE 34 IS ASSIGNED TO A DUAL 16 BIT SCALER
;THAT IS GENERALLY CONNECTED TO A VIDAR VOLTAGE
;CONTROLLED OSCILLATOR TO FORM AN INTEGRATING DVM.
;THE CLOCK FREQUENCY IS CRYSTAL CONTROLLED BY THE
;CRYSTAL IN A GENERAL RADIO OSCILLATOR.  THE FREQUENCY
;HAS BE SET TO 10 HZ FOR USE BY RESUB IN THE STARTUP
;PROGRAM.



;DISPLAY CONTROL TABLE--DCT- - -THIS MUST MATCH THE 
;OFFSETS FROM C2 GIVEN IN THE DISPLAY PROGRAM

NMAX:	0	;MAX NUMBER OF POINTS AS ALLOWED BY STRUP
B:	0	;STRUP WILL ENTER ADDRESS OF BUFFER HERE
.NUM:	0	;NUMBER OF POINTS TO BE DISPLAYED/2
.INCRE:	0	;INCREMENT ALONG X AXIS 2 FOR 1024 PTS
.DSCAL:	0	;SCALE FACTOR SET BY PUSHBUTTONS
.BSLN:	1000	;BASELINE SET TO 1000 FOR SIGNED NUMBERS
	DOAP 1 30	;X-AXIS OUTPUT SUBROUTINE
	JMP 0 3
.CXY:	0	;0 FOR SCANNED DISP.  <>0 FOR XY
;ONCE ONLY CODE USED FOR INITIAL STARTUP
;ONLY   DISPLAY PROGRAM WILL OVERLAY THIS SPACE
;SEE DSP NOTES FOR USE

WOC:	LDA 1 20	;FIRST LOCATION NOT USED BY BASIC
	STA 1 B	;B=START OF DISPLAY BUFFER
	LDA 2 CTOP	;TOP OF AVAILABLE CORE BEFORE LOADER
	SUBZ 1 2 SNR	; #WORDS IN DSPLY BUFFER
	SUB  2 2
	STA 2 NMAX	;MAX NUMBER OF POINTS
	JMP 0 3		;GO TO WOCR


;SET UP DISPLAY SO THAT IT WILL RUN UNDER INTERRUPT
;CONTROL AT 10HZ SWEEP RATE

IDSP:	STA 3 ADR	;STORE BASIC'S REURN ADDRESS
	JSR SETDSP	;SET UP MODE AND NUMBER OF POINTS
	STA 1 CDSF	;CONTINUOUS DISPLAY FLAG
IDSP1:	LDA 3 ADR
	JMP 2 3		;BACK TO BASIC
			;WITH 2 PARAMETERS PASSED


;SUBROUTINE TO SET NUMBER OF CHANNELS AND CHOOSE
;SCANNED OR DISPLAY MODE. RETURNS TO CALL+1 WITH 
;MODE IN C1
C5.:	256.
C2:	2
SETDSP:	STA 3 SETD1
	JSR @.REC
	1	;NUMBER OF CHANNELS
	LDA 0 NMAX
	SUBZ# 1 0 SNC	;SKIP IF LESS THAN MAX
	MOV 0 1		;NUMBER OF CHANNELS
	MOVZR 1 1	;DIVIDE BY 2 FOR INTERLACCED
	STA 1 .NUM	;SCAN PROGRAM
	LDA 0 C5.
	LDA 2 C2
	NEGZL 2 3	;GET -4 FOR LOOP COUNT
;GET INCREMENT FOR SCANNED DISPLAY
	SUBZ# 0 1 SZC	;SET UP INCREMENT FOR
	JMP .+5
	MOVZR 0 0	;SIZE/2
	MOVZL 2 2
	INC 3 3 SZR
	JMP .-5
	STA 2 .INCRE	;STORE INCREMENT

;SET MODE EITHER FOR XY  OR SCANNED
	JSR @.REC
	2
	STA 1 .CXY
	MOV 1 1 SZR
	SUBZL 1 1
	JMP @SETD1

SETD1:	0


;STARTUP PROGRAM TO INITIALIZE POINTER ETC.
;THIS IS CALLED AUTOMATICALLY BY BASIC EACH TIME
;THE RESUB PROGRAM IS STARTED AT LOCATION 2
STRUP:	NIOC 60	;SET SCALER INTERRUPT CLOCK TO 10 HZ
	DIB 0 34
	SUB 0 0
	JSR TTOA	;ACTIVATE TTO
	LDA 0 .INTR	;GET INTR
	LDA 3 .PCHR
	SUB 1 1
	STA 1 -3 3
	STA 0 -2 3
	STA 0 -1 3	;INITIALIZE PCHR AND GCHR
	LDA 0 STRU1@
	STA 0 @STRU2	;INITIALIZE TAPE BUFFER
	JMP @.TASK
STRU1:	TBPE
STRU2:	TBPC	;TAPE BYTE POINTER CURRENT

;**********************
;CTOP NEEDS CHANGING IF CORE SIZE IS NOT 12K
;***********************
CTOP:	30000-200	;TOP OF 12K CORE ADJUSTED FOR
			;200 WORD LOADER


;BACKGROUND PROGRAM.  BGNDP IS EXECUTED PERIODICALLY 
;WHENEVER BASIC IS WAITING CHECKING WITH ITS TASK
;SCHEDULER TO SEE WHAT SHOULD BE DONE
BGNDP:	LDA 1 CDSF	;CHECK DISPLAY FLAG
	LDA 2 CLK
	INTDS
	MOVR 1 1 SZC	;CHECK BIT 15 FOR INTRRUPTED
	JSR @ .DSP	;DISPLAY
	JMP @.TASK	;BACK TO TASK SCHEDULER
	
;BOTTOM OF STACK MUST WAIT HERE FOR IN INTERRUPT
;THIS CODE WILL NOT BE REGULARLY EXECUTED, BUT 
;WE CAN GET A LITTLE MORE DISPLAY TIME BY USING 
;THIS FOR THAT PURPOSE
BASE0:	LDA 1 CDSF
	LDA 2 CLK
	INTDS
	MOVR 1 1 SZC
	JSR @.DSP
	INTEN
	JMP BASE0	;JUST WAIT HERE



;NOTE:  THE FOLLOWING ARE ROUTINES TO 
;SUBSTITUTE A LINE PRINTER FOR STANDARD TELETYPE
;SINCE OUR LINE PRINTER IS EXTRMEMLY SLOW, WE DID NOT
;HAVE TO BE CONCERNED ABOUT ANY SPECIAL TIMING CONSIDERATIONS
;THE TELETYPE WILL BE AUTOMATICALLY ACTIVATED AT THE
;END OF  PROGRAM OR IF AN ERROR MESSAGE 
;IS ENCOUNTERED.  (THERE IS A BELL CODE BEFORE ALL
;ERROR MESSAGES.)

;CALL 18.  ACITIVATE THE LINE PRINTER AS A SUBSTITUTE
;FOR THE TELETYPE PRINTER
LPTA:	LDA 0 LPTA1
	STA 0 @LPTA2	;STORE JSR @LPTO
	JMP 0 3	;BACK TO BASIC

LPTA1:	JSR @.LPTO	;LPTO SIMULATES TTO CMD
LPTA2:	TELO1		;ADDRESS OF TTO COMMAND
LPTA3:	DOAS 1 TTO	;TELETYPE OUTPUT INSTRUCTION
LPTA4:	0	;TEMP. LPT BUFFER
LPTA5:	TELO;BASIC'S TELETYPE HANDLER


;  ACTIVATE TLETYPE
;ALSO CALLED BY STRUP
;C2 IS UNCHANGED BY THIS ROUNTINE
TTOA:	LDA 0 LPTA3	;TTOACTIVATE
	STA 0 @LPTA2	;REPLACE TELETYE CMD IN BASIC
	JMP 0 3		;RETURN TO CALL

;HANDLE A LINE PRINTER INTERRUPT
LPTI:	NIOC LPT
	SUB 0 0
	LDA 1 LPTA4	;CHECK LPT BUFFER
	STA 0 LPTA4	;CLEAR IT
	MOV 1 1 SNR
	JMP @LPTA5	;TO BASIC TO HANDLE OUTPUT
	JMP LPTO3	;OUTPUT CHARACTER AND RETURN TO
			;BASIC AS THOUGH OUTPUT WERE DONE 
			;IMMEDIATELY
;ATTEMPT OUTPUT AS REQUESTED BY BASIC, BUT IF LPT IS BUSY
;STORE CHARACTER IN LPT BUFFER AND DO INTERRUPT 
;THIS WILL NOT WORK IN A TIME SHARE VERSON

LPTO:	LDA 2 @IOB	;GET IOBT ADDRESS IN BASIC
	MOV 2 2	 SNR
	JMP LPTO2	;NOT RUNNING RESET TELETYPE
	LDA 0 -5 2	;GET  MODE FROM BASIC
	MOVZR 0 0 SNR	;CHECK FOR ENTER MODE(1)
	MOV 0 0 SNC
	JMP LPTO2
LPTO1:	JSR TTOA ;ACTIVATE TTO
	JMP @LPTA2	;AND OUTPUT CHARACTER ON TTO
LPTO2:	LDA 0 C207;CHECK FOR BEL CODE
	SUB 1 0 SNR	;BEFORE ERROR MESSAGE,ETC.
	JMP LPTO1
	SKPBZ	LPT
	JMP LPTO4
LPTO3:	DOAS 1 LPT	;OUTPUT CHARACTER
	

	LDA 3 LPTA2
	JMP 1 3

;PRINTER IS BUSY SO STORE WOD IN BUFFER AND 
;GO TO INTERRUPT STACK PROCESSOR
LPTO4:	STA 1 LPTA4
	JMP @.INTR
IOB:	IOBT
C207:	207	;BEL CODE
;CALL 30., SCALER READING, TIME
;THIS WILL GET LAST SCALER READING AND T	ME
;IN UNITS OF 0.1 SECOND

RDSLR:	STA 3 ADR
	SUB 0 0 	;CLEAR AC0
	LDA 1 SCLR	;GET READING
	JSR @.TRANS	;SEND TO BASIC
	1
	SUB 0 0
	LDA 1 SCLR+1	;GET TIME
	JSR @.TRANS
	2
	LDA 3 ADR
	JMP 2 3		;BACK TO BASIC




	


;NOTE: THE FOLLOWING SUBROUTINE IS USED TO 
; CONTROL AN OSCILLOSCOPE DISPLAY 
;CONNECTED TO A SPECIAL INTERFACE CONSISTING OF TWO
;TEN BIT DAC'S AND A ONE SHOT MULTIVIBRATOR FOR
;INTENSITY MODULATION.
;THE OUTPUT COMMANDS USED ARE THE FOLLOWING:;	DOA  AC#,30	LOAD X-AXIS DAC
;	DOB  AC#,30	LOAD Y-AXIS DAC
;	A "P" WILL GENERATE A PULSE FOR THE INTENSITY
;	MODULATION.  INDEPENDANT DISPLAYS USE S OR C CODES

;WHEN USED WITH RESUB, THE DATA BUFFER FOR THE
;DISPLAY IS CONTAINED IN HIGH CORE JUST BELOW THE
;LOADER

;CALL DSP FOR SWEEP DISPLAY
;PROGRAM WILL DISPLAY ONE FIELD OF A 2:1 INTERLACED
;DISPLAY AND RETURN TO CALL +1 WHEN CALLED 
;BY JSR.  THIS IS  REENTRANT CODE AND MAY BE USED
;TO DISPLAY INDEPENTLY ON DIFFERENT DISPLAY UNITS
;FOR A SWEEP DISPLAY, THE 16 BIT WORD IS SHIFTED 
;ACCORDING TO DSCAL.
;FOR XY DISPLAY BITS 0-7 ARE Y;8-15 ARE X.
;BITS ARE SHIFTED FOR USE WITH 10 BIT DAC
;C2 MUST CONTAIN ADDRESS OF POINTERS AND STORAGE AT 
;ENTRY. DISPLACEMENTS 0-5 MUST BE ENTERED BEFORE CALL
;YOU MAY ENTER AT DSPR  IF YOU SET UP RET 
;BEFORE CALL.  SET CXY=0 FOR  XY DISPLAY
;AND 1 FOR XT DISPLAY

;DISPLACEMENTS FROM C2 FOLLOW
;DISPLAY CONTROL TABLE POINTERS

	BFR=0	;LOC OF DATA BLOCK TO BE DISPLAYED
	NUM=1	;NUMBER OF POINTS/2
	INCRE=2	;X INCREMENT 2 FOR 1024 PTS
	DSCAL=3	;SCALE CHANGE MUST BE <=12.
	BASLN=4	;BASELINE FOR SWEEP SET 1000 OCTAL FOR SIGNED NUMBERS
	CMD=5	;NORMALLY DOAP 1 30  SET S OR P TO SEL SCOPE
		;FOLLOWED BY JMP 0 3
	CXY=7	;SET=0 FOR SCANNED XT DISPLAY
	RET=10	;NORMAL RETURN ADDRESS AT END OF ONE FIELD
	CNT=11
	ADRE=12
	PAR=13
	JUMP=14	;END OF TEMP STORAGE

L=MOVZL 0 0
R0=MOVZR 0 0

	.NREL

DSP:	STA 3 RET 2	;STORE RETURN
DSPR:	LDA 0 CXY,2	;STORE OUTPUT CMD
	LDA 3 NUM 2
	MOV 3 3 SNR	;CHECK FOR ZERO COUNT
	JMP @RET 2
	STA 3 CNT 2
	ISZ PAR 2
	JMP .+1
	LDA 3 BFR 2
	MOVZR 0 0 SNC
	JMP DXY		;XY DISPLAY
	SUB 1 1	;SET X=0 FOR FIRST POINT
	LDA 0 PAR 2
	MOVR 0 0 SZC	;SKIP FOR EVEN SCAN
	JMP .+4
	INC 3 3
	LDA 1 INCRE 2
	MOVZR 1 1
	STA 3 ADRE 2
	LDA 0 JP	;GET JMP INST
	LDA 3 DSCAL 2
	ADD 3 0
	STA 0 JUMP 2
;LOOP FOR SCANNED DISPLAY

LP:	LDA @ 0 ADRE 2
J:	JMP @JUMP 2
	R0
	R0
	R0
	R0
	JMP .+4
	L
	L
	L
	LDA 3,BASLN,2	;ADD BASE LINE
	ADD 3, 0
	DOB 0,30	;Y OUTPUT
	JSR CMD 2	;X-OUTPUT
	LDA 3,INCRE,2
	ADD 3,1	;INC X
	ISZ ADRE 2		;INCREMENT ADRE 2
	ISZ ADRE 2		;FOR INTERLACE
	DSZ CNT, 2	;BUMP COUNT
	JMP  LP		;DO ANOTHER POINT
	JMP @ RET,2	;RETURN
;IF RET = DSPR, THIS WILL DISPLAY REPETITIVELY WITHOUT SUPPORT
 

JP:	J+1 


; X - Y  DISPLAY
DXY:	LDA 0 PAR 2
	MOVR 0 0 SZC	;INTERLACED SCAN
	JMP .+2
	INC 3 3
	STA 3  ADRE 2	;STORE ADRE
LOOP:	LDA 1 @ADRE 2	;GET X-Y DATA
	MOVS 1  0	;Y IN CO
	MOVZL 0 0
	MOVZL 0 0	;SHIFT FOR 10 BIT
	MOVZL 1 1	;DAC FOR SCOPE
	MOVZL 1 1
	DOB 0 30	;Y OUTPUT
	JSR CMD 2	;X AXIS AND PULSE
	ISZ ADRE 2
	ISZ ADRE 2
	DSZ CNT 2	;BUMP COUNT
	JMP LOOP
	JMP @ RET 2

;CALL 13,A$
;READ AN ASCII STRING ON THE PTP
GACHR:	STA 3 ADR	;STORE RETURN ADDRESS
	SUB 0 0
	STA 0 GACH1	;STORE 0 IN NULL FLAG
	JSR RECS	;SET UP POINTERS
	1		;FOR PARAMETER 1
GAC1:	JSR @.GCHR	;GET A BYTE
	MOV 0 0 SZR
	JMP GAC2	;GOT A BYTE
	LDA 1 GACH1	;ARE WE AT END OF FILE
	MOV 1 1 SNR
	JMP GAC1	;STILL IN LEADER
	JMP PACH1	;NO MORE BYTES-GO TO BASIC

GAC2:	STA 0 GACH1	;SET FLAG
	JSR STBYT	;AND STORE THE BYTE
	JMP PACH1	;END OF STRING
	JMP GAC1	;TRY TO GET ANOTHER BYTE
GACH1:	0


;CALL 14,A$
;PUNCH ASCII CHARACTER STRING ON PTP
PACHR:	STA 3 ADR
	JSR RECS
	1
	JSR GBYT
	JMP PACH1	;NO MORE BYTES-GO TO BASIC
	JSR @.PCHR	;PUNCH A BYTE
	JMP .-3

PACH1:	LDA 3 ADR
	JMP 1, 3	;BACK TO BASIC AFTER ONE PARAMTER

;SET UP POINTERS FOR A STRING
	;CALL JSR TO RECS
	;      PARAMETER NUMBER
	;      RETURN
RECS:	LDA 2 ADR
	LDA 1 0 3	;GET PARAMTER NUMBER
	ADD 1 2	
	LDA 2 -1 2	;GET ADDRESS
	LDA 0 0 2	;ADDRESS OF FIRST BYTE
	LDA 1 2 2	;FIRST SUBSCRIPT-1 OR ZERO
	ADD 0 1
	STA 1 STRS	;BEGINNING OS STRING
	LDA 1 3 2	;GET SECOND SUBSCRIPT OR DIMENSION
	ADD 0 1
	STA 1 STRE	;THIS IS END OF STRING+1
	LDA 1 1 2	;DIMENSION
	STA 1 STRD	;STORE DIMENSIONS OF STRING
	JMP 1 3
 
;FOLLOWING ARE BYTE POINTERS
.ZREL
STRS:	0	;FIRST CHARACTER IN STRING
STRE:	0	;FINAL CHARACHTER+1
STRD:	0	;STRING DIMENSION
.NREL


;GET A BYTE USING POINTERS FORMED IN RECS
;IF A NULL CHARACTER OR IF ALL BYTES HAVE
;BEEN TRANSFERRED RETURN TO CALL+1
;RETURN TO CALL+2 IF A BYTE IS IN AC0
;INCREMENT STRINGS AFTER GETTING BYCALLING PROCDEURS
;THIS WILL INCREMENT STRS

GBYT:	LDA 1 STRS
	LDA 0 STRE
	SUBZ# 0 1 SZC	;DO WE HAVE LAST BYTE
	JMP 0 3
	STA 3 GBYT1	;STORE RETURN
	JSR @.ACBY	;ACCESS BYTE POINTED BY BY C1
	LDA 3 GBYT1
	ISZ STRS	;INC POINTER
	MOV 2 0 SNR
	JMP 0 3		;NULL END OF STRIING
	JMP 1 3		;GOOD BYTE

GBYT1:	0	;RETURN FOR GBYT &STBYT

;STORE A BYTE IN C0 SIMILAR TO GBYT.  RETURN IS CALL+1 FOR 
;END OF STRING. CALL+2 FOR SUCESSFUL STORAGE

STBYT:	LDA 1 STRS
	STA 3 GBYT1
	LDA 2 46	;GET A 177 FOR PTR MASK
	AND 2,0
	LDA 2 C200
	ADD 2 0
	JSR @.STBY
	ISZ STRS
	LDA 1 STRS
	LDA 0 STRE
	LDA 3 GBYT1
	SUBZ# 0 1 SZC
	JMP 0 3
	JMP 1 3

.STBY:	STBY	;STORE BYTE IN AC0
	;USING POINTER IN AC1-SUBROUTINE IN
	;RESUB


;FOLLOWING ARE SUBROUTINES TO HANDLE PTP
;PTR FOR  DUMP AND TAPE COMMANDS IN BASIC
;OTHER SUBROUTINES MAY USE GCHR, PCHR, .PCH0, PCHL RUITINES
;THESE DRIVER ROUTINES USE INTERRUPT
;STACK IN RESUB.  THEY WILL NOT WORK IN 
;TIME SHARE BASIC

;DEVICE CONTROL TABLE DISPLACEMENTS
.DVUS = 0	;DEVICE IN USE FLAG
.INIT=1		;OPEN DEVICE CHANNEL
.IO=2	;TO ROUTINE
.CLO=3	;CLOSE DEVICE CHANNEL

;HANDLE PTR,PTP FROM DUMP AND TAPE COMMANDS IN BASIC

.ZREL
.PTR:	PTRON	;DEVICE CONTROL TABLE
.CTU: .CDR:	0	;POINTER
.PTP:	PTPON
.GCHR:	GCHR
.PCHR:	PCHR
.PCH0:	PCHL0
.PCHL:	PCHL
.NREL
PTRON: P:	0	;PTR DEVICE CONTROL TABLE
	STPTR	;INIT
	INPTR	;INPUT

PTPON:	0	;PTP DCT
	STPTP	;INIT PUNCH LOADER
	OPTP	;OUTPUT CLEAR
	CPTP	;CLOSE


;FILL THE TAPE BUFFER WITH 40 BYTES FROM 
;THE PTR. PTR OUTPUT IS BUFFERED TO 
;IMPROVE DEPENDABILITY OF UNIT.  RESUB
;IS TOO SLOW TO KEEP PTR RUNNING AT 
;MAXIMUM SPEED.  SEE THE "HOW TO USE"
;BOOK FOR COMMENT ON THIS.  AT LEAST 5" TAIL
;MUST BE ON ALL TAPES FOR PROPER OPERATION OR
;ELSE YOU CAN HANG UP SYSTEM.  IF THIS HAPPENS
;RESTART NOVA AT 2.  THERE ARE WAYS AROUND
;THIS PROBLEM.

;RESUB WILL CHECK TO MAKE SURE THAT THERE ARE NOT 
;TOO MANY CHARACTERS BETWEEN CR CODES.



FILL:	SUBZL 0 0
	STA 0 FIL5	;SET FLAG -DO NOT CHECK FOR NULL
	LDA 0 FIL1	;NO OF BYTES TO BE STORED
	STA 0 FIL2	;STORE COUNT
	LDA 0 TBPS	;START OF TAPE BUFFER
	STA 0 FIL3	;STORE BYTE POINTER
	STA 3 FIL4	;RETURN
FILL1:	JSR GCHR5	;GET CHARACTER FROM PTR
	LDA 1 FIL3	;BYTE POINTER
	STA 0 FIL6	;SAVE CHARACTER
	JSR @.STBY	;STORE BYE IN AC0
	LDA 0 FIL6	;GET CHARACTER
	LDA 1 FIL5	;AND FLAG
	ADD 0 1	SNR	;CHECK TERMINATOR IF NEEDED
	JMP FILL2
	ISZ FIL3	;INC POINTER
	DSZ FIL2	;BUMP COUNT
	JMP FILL1
	DSZ FIL3
FILL2:	LDA 0 TBPS	;START OF BUFFER
	STA 0 TBPC
	LDA 0 FIL3
	STA 0 TBPE
	JMP @FIL4
FIL1:	100.		;NO OF BYTES IN BUFFER
FIL2:	0		;COUNT
FIL3:	0		;POINTER
FIL4:	0		;RETURN
FIL5:	0
FIL6:	0

;GET A CHARACTER OUT OF THE BUFFER. IF NECESSARY
;FILL THE BUFFER
GCHR:	STA 3 GCHR2	;STORE RETURN
	LDA 1 TBPC	;CURRENT POINTER
	LDA 2 TBPE	;END
	SUBZ#  1 2 SNC	;SKIP IF BUFFER NOT EMPTY
	JSR FILL+2	;FILL IT
	LDA 1 TBPC
	JSR @.ACBY	;GET A BYTE IN C2
	LDA 0 C377
	ISZ TBPC	;INCREMENT TAPE BUFFER
	AND 2 0		;AND PUT IN C0
	JMP @GCHR2
GCHR2:	0		;RETURN
TBPS:	TB*2		;BYTE POINTER OF TAPE BUFFER
TBPC:	TB*2+100.	;CURRENT BYTE
TBPE:	TB*2+100.	;END OF BUFFER

;LINKAGES FROM BASIC TO DEVICE SUBROUTINES.  DCT ADDRESS 
;SHOULD BE IN C2 UPON CALL FROM BASIC
INIT:	JMP @ .INIT,2	;SET UP DEVICE
OUTPT:RDINP:	JMP @ .IO,2	;TRANSFER DATA
CLOSE:	JMP @ .CLO,2	;CLOSE DEVISE

C200:	200
C177:	177


;HANDLE PTR

;INIATE, SET DVUS FLAG AND RETURN

STPTR:	ISZ  PTRON	;SET DVUS FLAG
	NIOP  PTR	;SLOW FORWARD MODE
	JMP FILL	;FILL BUFFER AND GOTO RESUB
;GET CHARACTER FROM PTR
INRET:	0
INPTR:	STA 3, INRET	;GET CHARACTER
	JSR GCHR	;GET TAPE YOU MUST HAVE
	LDA 3, INRET	;TAPE IN READER
	LDA 1, C177	;CHECK FOR NULL
			;OR 300 CODE
	AND 0,1 SNR	;MASK 7 BITS
	JMP INPT
	LDA 0,C200	;WE HAVE A CLEAR
	SUB 2 2
	STA 2 FIL5	;SET TERMINATOR FLAG
	ADD 1,0		;SET BIT 8
	STA 0,PTRON	;GOT A CHARACTER 
	JMP 2,3		;BACK TO BASIC GOOD
			;CHARACTER IN C0
INPT:	LDA 0 PTRON 	;GOT A NULL
	MOVZR 0 0 SNR	;ARE WE IN BIGINNING LEADER?
	JMP INPTR+1	;YES
	JMP 1,3		;NO END OF FILE
			;BASIC CLEARS DVUS
;A JMP 0 3   IS RETURN WITH NO DATA
;BASIC WILL THEN TRY AGAIN LATER


;SUBROUTINE TO READ ONE CHARACTER INTO AC0
GCHR5:	STA 3, GCHR1	;READ 1 CHR FROM PTR
	NIOS PTR
	SKPDN PTR
	JMP @.INTR	;TO I.O. STACK
PTRI:	DIAC 0 PTR
	LDA 3 GCHR1
	LDA 2, .INTR	;IF WE GET FALSE
	STA 2, GCHR1	;INTERRUPT WE WILL JUST
	INTEN
	JMP 0,3		;RETURN

;FOLLOWING MUST BE LOCATED BEFORE PCHR--USED BY STRUP
PCHR2:	0	;TEMPORARY PUNCH BUFFER
GCHR1:	INTR	;RETURN
PCHR1:	INTR

;SUBROUTINE TO PUNCH 1 CHARACTER ON PTP FROM AC0
PCHR:	STA 3, PCHR1
	SKPBZ PTP	;CHECK PTP
	JMP PCHR3
PCHRO:	DOAS,0,PTP
	SUB 0 0	;CLEAR TEMP PUNCH BFR
	STA 0,PCHR2	;SET PUNCHED FLAG
	LDA 3 PCHR1
	LDA 2 .INTR
	STA 2 PCHR1
	INTEN
	JMP 0 3		;RETURN TO CALL+1
;PUNCH IS BUSY-STORE CHARACTER
PCHR3:	MOVOL 0 0
	STA 0 PCHR2	;STORE CHARACTER AND FLAG
	JMP @ .INTR	;WAIT UNTIL INTERRUPT
;INTERRUPT
PTPI:	LDA 0,PCHR2
	MOVZR 0 0 SZC	;DO WE HAVE CHR
	JMP PCHRO 	;YES
	NIOC PTP	;NO
	JMP @.INTR






;SUBROUTINE TO PUNCH LEADER TAPE
;ACO HAS NUMBER OF INCHES TO BE PUNCHED AT ENTRY
;WHEN PCHL IS CALLED
;CALL WITH JSR PCHL
;RETURN IS TO CALL+1
STPTP:	ISZ PTPON	;START PTP FROM BASIC
PCHL0:	LDA 0, C15.	;PUNCH 15. INCHES
PCHL:	STA 3 PCHL1
	MOVZL 0 1	;MULT C0*10.
	MOVZL 1 1
	ADDZL 1,0
	STA 0, PCHL2	;STORE COUNT
	SUB 0 0		;SET C0=0
	JSR PCHR	;PUNCH ANULL
	DSZ PCHL2	;BUMP COUNT
	JMP .-3
	JMP @ PCHL1	;RETURN
PCHL1:	0	;RETURN ADDRESS
PCHL2:	1	;COUNT
C15.:	15.	;LEADER TAPE





;OUTPUT ONE CHARACTER FROM BASIC
;RETURN	JMP 0 3	UNSUCCESSFUL OUTPUT OR BFR FULL
;	JMP 1,3		GOOD GET NEXT CHARACTER
OPTP:	STA 3,OPTP1	;STORE  RETURN
	JSR PCHR
	LDA 3, OPTP1
	JMP 1,3		;GOOD OUTPUT
OPTP1:	0
;CLOSE PTP, PUNCH LEADER AND CLEAR DVUS
;FLAG
;RETURN	JMP 0 3		;NOT YET CLOSED
;	JMP 1,3		PTP CLOSED

CPTP:	STA 3, OPTP1
	JSR PCHL0	;PUNCH TAIL
	SUB 0 0
	STA 0 @CPTP1	;CLEAR DVUS
	LDA 3 OPTP1
	JMP 1,3		;RETURN TO BASIC
CPTP1:	PTPON
TB:	.BLK 101.	;TAPE BUFFER
.END
*U*U*U*UUbV