  .TITLE	IOBYTE - A.E.D. 512/767 DRIVER SUBROUTINES
.IDENT	/V02/
.LIST	TTM,MEB
.NLIST	BEX
.SBTTL	MACROS AND DEFINITIOS
.MCALL	.PRINT,.FETCH,.SPFUN,.EXIT,.LOOKUP,.WAIT
;
;
;COPYRIGHT (C) 1981 AED
;REPRODUCTION OR PUBLICATION IN ANY FORM
;OR FORMAT IS PROHIBITED.
;PROPERTY OF ADVANCED ELECTRONICS DESIGN, INC.
;
;PROGRAM P.N.	800009-01
;
;VERSION	V02.1
;		V02 HAS KSR ADDED 
;		V02.1 FUNCTION CODES WERE CHANGED TO SPEED UP DRIVER
;		DMA NOTERMINATE FUNCTIONS ADDED
;		WORK WAS DONE TO REDUCE THE SIZE OF THIS MODULE
;		512 CHANGED TO 512/767
;
;DATE:		01-JUL-81
;DATE V02.1:	15-JUN-82
;DATE V03	 9-JUL-85 ADDED NEW COMMAND DMA STUFF
;
;AUTHOR:	D.C. ARNOLD
;
;FORTRAN CALLABLE ROUTINS FOR GD.SYS
;LINK TO TAP+SOURCE PROGRAM
;SPECIAL FUNCTION CODES ARE AS FOLLOWS
;ALL CODES ARE IN OCTAL
;
;
		KSRC=200	;KEY STROKE STATUS
		RRDC=204	;READ RASTER DIRECT
		WRDC=210	;WRITE RASTER DIRECT
		RDAC=214	;READ DIRECT FROM AREA OF INTEREST
		WDAC=220	;WRITE DIRECT TO AREA OF INTEREST
		SCDC=224	;START COMAND DMA
		TSLC=230	;SELECT TERMINAL
		SKSC=234	;SEND KEYSTROKE
		RSTC=240	;DO A FULL RESET
		OBYTEC=244	;OUTPUT MULTIPLE BYTES
		IBYTEC=250	;INPUT MULTIPLE BYTES
;
;
;THE FOLLOWING MACRO JUST SETS THINGS UP FOR EACH ENTRY POINT
;
	.MACRO	SETUP,TYPE,ERRORM,FLAG
	MOV	#TYPE,R3
	MOV	#ERRORM,R4
	.IF	NB  FLAG
	JMP PARIO
	.IFF
	JMP DMASEC
	.ENDC
	.ENDM
.SBTTL	THE ROUTINES
; NEW COMMAND DMA ROUTINES
;  THE CALLS SETCD AND CLRCD SET AND CLR THE AUTO COMMAND DMA MODE.
;  TO USE AUTO COMMAND DMA FIRST CALL SETCD. NOW USE ANY TAP ROUTINES
;  EXCEPT THOSE USING VIDEO DMA OR RETURNED DATA FROM THE TERMINAL. 
;  TO SEND YOU BUFFER CALL SCD WITH NO PARAMETERS. YOU MUST DO ANOTHER
;  CALL SETCD TO REENTER AUTO COMMAND DMA. IF YOU OVERFLOW THE BUFFER,
;  A MESSAGE WILL BE SENT. BUFFER IS DMABUF.
;	SET/CLR  COMMAND DMA MODE
SETCD:: MOV 	#1,CDFLAG			;SET AUTO COMMAND DMA FLAG
	MOV	#DMABUF,DMAPTR			;LOAD POINTER
	RTS	PC

CLRCD::	CLR	CDFLAG				;CLR AUTO COMMAND DMA
	RTS	PC


; THE NEXT 3 CALLS ALLOW YOU TO DO OTHER PROCESSING WHILE THE TERMINAL 
; IS READING A COMMAND DMA BUFFER. THE DEFAULT MODE IS SYNC AND ALL CALLS
; WILL NOT RETURN UNTIL THEIR IO HAS BEEN COMPLETED. A CALL TO ASYNC WILL
; ALLOW CALLS TO RETURN WHEN THE IO IS QUEUED NOT COMPLETE. THE CALL TO
; IOWAIT WILL NOT RETURN UNTIL ALL IO HAS BEEN COMPLETED
; SET/CLR ASYNC
ASYNC:: MOV 	#1,IOMODE			;SET ASYNC IO FLAG
	RTS	PC

SYNC::	CLR	IOMODE				;SET SYNC IO 
	RTS	PC

IOWAIT:: .WAIT  #10.				;WAIT FOR IO COMPLETE
	RTS	PC

; 1280 DRAWING ACCELERATOR COMMAND SET
; RULES OF THE GAME
; 1) THESE COMMANDS ONLY WORK IN COMMAND DMA MODE. A CALL TO FSET WILL ENTER
;    COMMAND DMA IF YOU ARE NOT ALREADY IN IT.
; 2) ONLY FDVA,FSEC AND FMOV ARE ALLOWED BETWEEN FSET AND FXIT.
; 3) ONCE FXIT HAS BEEN CALLED, ALL COMMAND DMA COMMANDS ARE ALLOWED
; 4) TO EXECUTE CALL SCD  WITH NO PARAMETERS
;
; ENTER SPECIAL MODE
FSET::	TST	CDFLAG		;COMMAND DMA ON
	BNE	10$		;YES THEN LEAVE IT ALONE
	JSR	PC,SETCD	;TURN IT ON
10$:	BIT	#1,DMAPTR	;ON AN ODD BYTE
	BNE	20$		;YES THEN OK 
	CLRB	@DMAPTR		;PAD WITH A NULL
	INC	DMAPTR		;BUMP POINTER
20$:	MOVB	#43,@DMAPTR	;SEND DRAWING ACCEL START COMMAND
	INC	DMAPTR		;BUMP POINTER
	RTS	PC

; EXIT SPECIAL MODE
FXIT::	CMP	DMAPTR,#ODDERR	;BUFFER OVERFLO
	BLT	10$
	.PRINT 	#CDMAER		;TELL USER
	CLR	R0
	.EXIT			;	
10$:	MOV	#100000,@DMAPTR
	INC	DMAPTR
	MOV	#100000,@DMAPTR
	INC	DMAPTR
	RTS	PC

; FAST DVA
FDVA::	CMP	DMAPTR,#ODDERR	;BUFFER OVERFLO
	BLT	10$
	.PRINT 	#CDMAER		;TELL USER
	CLR	R0
	.EXIT			;	
10$:	TST	(R5)+		;BUMP AROUND # OF ARGS
	MOV	DMAPTR,R1	;GET DMA POINTER
	MOV	(R5)+,(R1)+	;SEND X COORD
	MOV	(R5)+,(R1)+	;SEND Y COORD
	MOV	R1,DMAPTR	;RESTORE DMA POINTER
	RTS	PC

; FAST MOV
FMOV::	CMP	DMAPTR,#ODDERR	;BUFFER OVERFLO
	BLT	10$
	.PRINT 	#CDMAER		;TELL USER
	CLR	R0
	.EXIT			;	
10$:	TST	(R5)+		;BUMP AROUND # OF ARGS
	MOV	DMAPTR,R1	;GET DMA POINTER
	MOV	(R5)+,(R1)+	;SEND X COORD
	MOV	(R5)+,(R1)	;SEND Y COORD
	BIS	#100000,(R1)+	;SET MOV BIT
	MOV	R1,DMAPTR	;RESTORE DMA POINTER
	RTS	PC


FSEC::	CMP	DMAPTR,#ODDERR	;BUFFER OVERFLO
	BLT	10$
	.PRINT 	#CDMAER		;TELL USER
	CLR	R0
	.EXIT			;	
10$:	TST	(R5)+		;BUMP AROUND # OF ARGS
	MOV	DMAPTR,R1	;GET DMA POINTER
	mov	(r5)+,(r1)	;send color
	bis	#100000,(R1)+	;SEND SET COLOR
	clr 	(R1)+		;SEND COLOR
	MOV	R1,DMAPTR	;RESTORE DMA POINTER
	RTS	PC


;
;	OBYTE-OUTPUT TO TERMINAL N BYTES FROM ARRAY BUFF
;	 FROM FORTRAN,	 CALL OBYTE(BUFF,N)
;	WHERE N=BYTE COUNT AND BUFF=BUFFER STARTING ADDRESS
;
OBYTE:: SETUP OBYTEC,OBYTER,0
;
;
;	IBYTE-INPUT FROM TERMINAL N BYTES TO ARRAY BUFF
;	FROM FORTRAN,	CALL IBYTE(BUFF,N)
;	WHERE N=BYTE COUNT AND BUFF=BUFFER STARTING ADD
;
IBYTE::	SETUP	IBYTEC,IBYTER,0
;
;
;	DMAO,WRD
;	FROM FORTRAN,	CALL DMAO(BUFF,-N) OR CALL WRD(BUFF,N)
;	WHERE BUFF=STARTING BUFFER ADDRESS AND N= WORD COUNT
;
WRD::
DMAO::	SETUP	WRDC,DMAOR
;
;
;	WRDNT SAME AS ABOVE BUT DO NOT SEND ESC AT WORD COUNT 0
;
WRDNT::	SETUP	WRDC!100,DMAOR
;
;
;	DMAI,RDA-DMA IN N WORDS TO ARRAY BUFF
;	FROM FORTRAN,	CALL DMAI(BUFF,-N) OR CALL RDA(BUFF,N)
;	WHERE BUFF=STARTING BUFFER ADDRESS AND N= WORD COUNT
;
;
RRD::
DMAI::	SETUP	RRDC,DMAIR
;
;
;	RRDNT: SAME AS ABOVE BUT SEND NO TERMINATE
;
RRDNT::	SETUP	RRDC!100,DMAIR
;
;
;	RDA-DMA IN FROM AREA OF INTEREST N WORDS TO ARRAY BUFF
;	FROM FORTRAN,	CALL RDA(BUFF,N)
;	WHERE BUFF=STARTING BUFFER ADDRESS AND N=NEGATIVE OR POSITIVE WORD COUNT
;
RDA::	SETUP	RDAC,RDAR
;
;
;	RDANT: SAME AS ABOVE BUT NO TERMINATE
;
RDANT::	SETUP	RDAC!100,RDAR
;
;
;	WDA-DMA TO AREA OF INTEREST N WORDS FROM ARRAY BUFF
;	FROM FORTRAN,	CALL WDA(BUFF,N)
;	WHERE BUFF=BUFFER STARTING ADDRESS AND N=NEGATIVE OR POSITIVE WORD COUNT
;
;
WDA::	SETUP	WDAC,WDAR
;
;
;	WDANT: SAME AS ABOVE BUT NO TERMINATE
;
WDANT::	SETUP	WDAC!100,WDAR
;
;
;     SCD-COMAND DMA TO TERMINAL N WORDS FROM ARRAY BUFF
;     FROM FORTRAN,	CALL SCD(BUFF,N)
;     WHERE BUFF=BUFFER STARTING ADDRESS AND N=NEGATIVE OR POSITIVE WORD COUNT
;
;
SCD::	SETUP	SCDC,SCDR
;
;
;	SCDNT: SAME AS ABOVE BUT NO TERMINATE
;
SCDNT::	SETUP	SCDC!100,SCDR
;
;
;	RESET-RESET THE TERMINAL
;	FROM FORTRAN CALL RESET
;
RESET::
RST512::TST	FCHFLG
	BNE	1$
	JSR	PC,FECHIT
1$:	MOV	#RSTC,R3
	MOV	#RSTR,R4
	CLR	R1
	CLR	R0
	MOV	#-1,R2
	JMP	COMMON
;
;
;	SELECT-SELECT TERMINAL 
;	FROM FORTRAN,	CALL SELECT(N)
;	WHERE N=TERMINAL NO.
;	NOTE CAN ALSO BE CALL SELECT(BUFF,1)
;
SELECT::
SEL512::	SETUP	TSLC,TSLR,0
;
;
;	KEYIN-GET A KEYSTROKE
;	FROM FORTRAN,	CALL KEYIN(BUFF,N) OR CALL SKS(BUFF,N)
;	WHERE BUFF=ADD OF BUFFER TO PUT KEYSTROKE
;	AND N=NO. OF KEYSTROKES TO BE SENT
;	NOTE IF ONLY ONE KESTROKE CAN BE CALL KEYIN(BUFF) OR CALL SKS(BUFF)
;
SKS::
KEYIN::	SETUP	SKSC,SKSR,0
;
;
;	KSR-INTEGER FUNCTION READ KEYSTROKE STATUS
;	JUST RETURN NON 0 OR 0 FOR KEYSTROKE READY OR NOT
;	NOTE. THE KEY VALUE IS NOT RETURNED THIS MUST BE DONE
;	WITH SKS.  THE MOST COMMON FORTRAN USAGE IS
;	IF (KSR(IARG).NE.0) CALL SKS(IARG)
;
KSR::	TST	FCHFLG		;TEST FETCH FLAGE
	BNE	1$		;DRIVER ALLREADY FETCHED
	JSR	PC,FECHIT	;GO FETCH DRIVER
1$:	MOV	#KSRC,R3	;MOVE SPECIAL FUNC. CODE
	CLR	R4		;NO ERROR MESSAGE NECESSARY
	MOV	#KSTAT,R1	;MOVE TEMP ADDRESS TO R1
	MOV	#-1,R2		;BYTE COUNT OF 1
	CLR	R0		;KILL BLOCK NO.
	JSR	PC,COMMON	;GO TO COMMON BUT RETURN HERE
	MOV	KSTAT,R0	;SET R0 TO TEMP VAL
	RTS	PC
;
;
PARIO:	TST	FCHFLG		;HAS THE DRIVER BEEN FETCHED YET
	BNE	1$		;YES
	JSR	PC,FECHIT	;NO GO DO IT
1$:	CMP	#1,(R5)+	;CHECK NO OF ARGUMENTS
	BNE	2$		;MORE THAN ONE
	MOV	(R5)+,R1	;SAVE BUFFER ADD
	MOV	#-1,R2		;NEG BYTE COUNT
	BR	22$		;GO NORMAL
2$:	MOV	(R5)+,R1	;SAVE BUFFER ADD IN R1
	MOV	@(R5)+,R2	;SAVE BYTE COUNT IN R2
	NEG	R2		;NEGATE IT
22$:	TST	CDFLAG		;COMMAND 
	BEQ	3$		;NO
	CMP	DMAPTR,#ODDERR	;BUFFER OVERFLO
	BLT	25$
	.PRINT 	#CDMAER		;TELL USER
	CLR	R0
	.EXIT			;	
25$:	MOVB	(R1)+,@DMAPTR	;PLACE IN BUFFER
	INC	DMAPTR		;ADJUST POINTER
	INC	R2		;DECREMENT COUNTER
	BNE	25$		;MORE TO DO?
	RTS	PC		;RETURN

3$:	BR	COMMON		;BRANCH TO COMMON SECTION
;
;
DMASEC:	TST	FCHFLG		;HAS THE DRIVER BEEN FETCHED YET
	BNE	1$		;YES
	JSR	PC,FECHIT	;NO GO DO IT
1$:	TST	(R5)+		;BUMP OFF NO OF ARGUMENTS
	BEQ	3$		;IF NO ARGS DUMP INTERNAL BUFF
	MOV	(R5)+,R1	;SAVE BUFFER ADD IN R1
	MOV	@(R5)+,R2	;SAVE NEGATIVE WORD COUNT IN R2
	BIT	#1,R1		;TO SEE IF ODD DMA ADD
	BEQ	2$		;NO
	.PRINT	#IOMODE		;YES PRINT ERROR MESSAGE
	.EXIT			;THEN EXIT
2$:	TST	R2		;SEE IF NEGATIVE
	BMI	COMMON		;YES
	NEG	R2		;NO NEGATE IT
	BR	COMMON

3$:	MOVB	#60.,@DMAPTR	;INSERT XCD
	INC	DMAPTR		;
	BIT	#1,DMAPTR	;ODD BYTE COUNT?
	BEQ	4$		;NO
	CLRB	@DMAPTR		;PAD WITH NULL
	INC 	DMAPTR		;
4$:	MOV	#DMABUF,R1	;GET ADDRESS OF BUFFER
	MOV	DMAPTR,R2	;GET POINTER
	SUB	#DMABUF,R2	;GET BYTE COUNT
	ROR	R2		;MAKE IT WORD COUNT
	NEG	R2		;MAKE IT NEGATIVE
	CLR	CDFLAG		;SHUT OFF AUTO COMMAND DMA
;
;	JUST FALL INTO COMMON
;
COMMON:	MOV	R1,R5		;PASS REAL ADD IN BLKN
	BIC	#1,R1		;MAKE SURE BA IS EVEN
	.SPFUN	#AREA,#10.,R3,R1,R2,R5,IOMODE
	BCS	1$		;IF ERROR PRINT MESSAGE AND ABORT
	RTS	PC		;IF NO ERROR JUST RETURN
1$:	.PRINT	R4		;PRINT ERROR MESSAGE
	.EXIT			;ABORT PROGRAM
;
;
FECHIT:	.FETCH	#DRVLOC,#GD	;FETCH THE DRIVER
	BCC	1$		;IF NO ERROR ASSIGN CHANEL NO.
	.PRINT	#FECHR		;PRINT FETCH ERROR MESSAGE
	.EXIT			;ABORT PROGRAM
1$:	.LOOKUP	#AREA,#10.,#GD	;ASSIGN CHANNEL NO. VIA LOOKUP
	BCC	2$		;IF NO ERROR SET FLAG EXIT
	.PRINT	#LOOKR		;PRINT LOOKUP ERROR MESSAGE
	.EXIT
2$:	INC	FCHFLG		;SET FETCH FLAG NON 0
	RTS	PC		;AND RETURN
;
;
;
AREA:	.WORD	0		;EMT ARGUMENT BLOCK
BOCK:	.WORD	0,0,0,0,0
GD:	.RAD50	/GD /		;DRIVER NAME
	.WORD	0,0,0		;DUMMY FILE NAME
TCNT:	.WORD	0		;TEMP STORAGE
FCHFLG:	.WORD	0		;FETCH FLAG 0=DRIVER NOT FETCHED
KSTAT:	.WORD	0		;TEMP LOC FOR KSR
DMAPTR:	.WORD	0		;POINTER FOR COMMAND DMA
CDFLAG:	.WORD	0		;COMMAND DMA FLAG
DMABUF:	.BLKW	1024.		;DMA BUFFER FOR COMMAND DMA
IOMODE:	.WORD	0		;SYNC OR ASYNC FLAG
ODDERR:	.ASCIZ	/?ODD DMA ADD. ERR?/
FECHR:	.ASCIZ	/?FETCH ERR?/	;
LOOKR:	.ASCIZ	/?LOOKUP ERR?/
DMAOR:	.ASCIZ	/?DMAO ERR?/
DMAIR:	.ASCIZ	/?DMAI ERR?/
OBYTER:	.ASCIZ	/?OBYTE ERR?/
IBYTER:	.ASCIZ	/?IBYTE ERR?/
RDAR:	.ASCIZ	/?RDA ERR?/
WDAR:	.ASCIZ	/?WDA ERR?/
SCDR:	.ASCIZ	/?SCD ERR?/
SKSR:	.ASCIZ	/?KEYIN ERR?/
TSLR:	.ASCIZ	/?SELECT ERR?/
RSTR:	.ASCIZ	/?RESET ERR?/
CDMAER:	.ASCIZ	/?COMMAND DMA BUFFER OVERFLOW?/
	.EVEN
DRVLOC:	.BLKW	1000		;DRIVER STORAGE OF 512 WORDS OR 2 DISK BLKS
	.END
 