	ALWAYS	29MAR4	OUTPUT	<OUTPUT LOAD MODULE>				;29MAR4
	.MCALL	DIR$,CALLR							;**-1
 	.MCALL	FSRSZ$
 	.MCALL	FDBDF$,FDAT$A,FDRC$A,FDBK$A,FDOP$A
	.MCALL	OPEN$W,CLOSE$,WAIT$,WRITE$
 	.PAGE
 	.SBTTL	FILE CONTROL SERVICES DATA AREAS

 	FSRSZ$	1		; DEFINE 1 FILE STORAGE REGION

LMFDB::	FDBDF$			; DEFINE THE FILE DESCRIPTOR BLOCK

 	FDAT$A				; INITIALIZE FILE ATTRIBUTES
 	FDRC$A	FD.PLC!FD.RWM		; INITIALIZE RECORD ATTRIBUTES
	FDBK$A	RECORD,RECLEN,,32.,IOSTAT
 	FDOP$A	IOLUN,LMDS,,FO.WRT	; FILE OPEN INITIALIZATION

LMDS::				; FILE NAME DESCRIPTOR BLOCK
LMDSDL::	.WORD		; DEVICE DESCRIPTOR LENGTH
LMDSDP::	.WORD		; DEVICE DESCRIPTOR POINTER
LMDSUL::	.WORD		; UIC DESCRIPTOR LENGTH
LMDSUP::	.WORD		; UIC DESCRIPTOR POINTER
LMDSNL::	.WORD		; NAME DESCRIPTOR LENGTH
LMDSNP::	.WORD		; NAME DESCRIPTOR POINTER

	.PSECT
;************************************************************************
;*									*
;*	MODULE: OUTPUT							*
;*									*
;*	INPUT PARAMETERS:						*
;*									*
;*	R0 POINTS TO THE COMMAND LINE IN PROCESS			*
;*									*
;*	FUNCTION: OUTPUT LOAD MODULE					*
;*									*
;*	INPUT PARAMETERS:						*
;*									*
;*	R0 POINTS TO THE COMMAND LINE IN OUTPUTESS			*
;*									*
;*	OUTPUT PARAMETERS:						*
;*									*
;*	R0 POINTS JUST BEYOND COMMAND LINE				*
;*									*
;*	29MAR4 - Modified by Scott Smith, Telex Computer Products	*	;29MAR4
;*					  Raleigh, NC			*	;29MAR4
;*	Made minor changes to make this module compatable with Chris	*	;29MAR4
;*	Doran's version of HEX.						*	;29MAR4
;*									*
;************************************************************************	;**-1

OUTPUT::
	GETKEY	FILE		; GET FILE KEYWORD
	BEQ	7$		;  EQ: GOT IT
	OUTPUT	MSK		; MISSING KEYWORD
	BR	250$		; TAKE ERROR EXIT
7$:
	CALL	PARSLM		; PARSE THE FILE DESCRIPTOR
	BCS	250$		;  CS: PARSE FAILURE - TAKE ERROR EXIT
	OPEN$W	#LMFDB		; OPEN THE FILE FOR WRITE
	BCC	10$		;  CC: OPENED O.K.
	OUTPUT	FOE		; FILE OPEN ERROR
9$:
	BR	250$		; TAKE ERROR EXIT
	.PAGE
10$:
	CALL	LMHEAD		; COMPLETE AND OUTPUT LOAD MODULE HEADER
	BCS	250$		;  CS: I/O ERROR - TAKE ERROR EEXIT
	CALL	CODE		; OUTPUT BINARY CODE
	BCS	250$		;  CS: I/O ERROR - TAKE ERROR EEXIT
	CALL	APATCH		; OUTPUT ANY ALLOCATED PATCH SPACE
	BCC	250$		;  CC: I/O SUCCESS - TAKE SUCCESS EXIT
250$:				; ERROR EXIT
255$:				; SUCCESS EXIT
	CLOSE$	#LMFDB
	RETURN
 	.PAGE
 	.SBTTL	PARSLM - PARSE FILE DESCRIPTOR INTO NAMEBLOCK
;
;	PARSLM - PARSE FILE DESCRIPTOR INTO NAMEBLOCK
;
;	INPUT PARAMETERS:
;
;	R0 POINTS TO COMMAND LINE IN PROCESS
;
;	OUTPUT PARAMETERS:
;
;	R0 POINTS JUST BEYOND FILE DESCRIPTOR (IF SUCCESSFUL)
;
;	CARRY FLAG INDICATES SUCCESS (CLEAR) OR FAILURE (SET)
;
;	FUNCTION: SETS UP DATASET DESCRIPTOR BLOCK LMDS ACCORDING TO FILE
;		  SPECIFICATION IN COMMAND LINE. IF NO DEVICE/UIC IS
;		  SPECIFIED, THE ENTRY FOR DEVICE/UIC IS ZEROED.
;
;	AUTHOR: KEVIN ANGLEY
;
;	DATE:	26-JUL-82
;
PARSLM:
 	MOV	#LMDS,R1		; MAKE SOME DEFAULT ASSUMPTIONS
 	MOV	#SYSLEN,(R1)+		; SY: IS THE DEVICE
 	MOV	#SYS,(R1)+
 	CLR	(R1)			; AND NO UIC (DEFAULT IS CURRENT)
 	MOV	R0,R1		; SAVE POINTER TO SPECIFICATION
10$:				; PARSE DEVICE SPEC (IF ANY)
 	TSTB	(R1)		; AT THE END YET?
 	BEQ	20$		;  EQ: YES, AND NO DEVICE SPEC
	CMPB	#':,(R1)+	; HAVE WE SEEN A COLON?
 	BNE	10$		;  NE: NO, KEEP LOOKING
 	MOV	R0,LMDSDP	; START OF SPEC IS START OF DEVICE SPEC
 	PUSH	R1		; SAVE POINTER TO UIC/NAME SPEC
 	SUB	R0,R1		; COMPUTE LENGTH OF DEVICE SPEC
 	MOV	R1,LMDSDL	; SET DEVICE SPEC LENGTH
 	POP	R0		; RESTORE POINTER TO UIC/NAME SPEC TO R0
20$:				; PARSE UIC SPECIFICATION
	CMPB	#'[,(R0)	; DO WE HAVE A UIC SPECIFIED?
 	BNE	30$		;  NE: NO, GO PROCESS NAME
 	MOV	R0,LMDSUP	; SET START OF UIC SPECIFICATION
 	INC	R0		; MOVE PAST THE LEFT BRACKET
25$:
 	TSTB	(R0)		; AT THE END YET?
 	BNE	28$		; NO, KEEP LOOKING
 	OUTPUT	FNS		; FILE NAME SYNTAX ERROR
 	BR	250$
28$:
	CMPB	#'],(R0)+	; SEARCH FOR RIGHT BRACKET
 	BNE	25$		;  NE: KEEP LOOKING
 	PUSH	R0		; GOT IT - SAVE POINTER TO NAME SPEC
 	SUB	LMDSUP,R0	; COMPUTE LENGTH OF UIC SPEC
 	MOV	R0,LMDSUL	; SET UIC SPEC LENGTH
 	POP	R0		; RESTORE POINTER TO NAME SPEC
30$:				; PARSE NAME SPECIFICATION
 	MOV	#RECORD,R1	; USE RECORD FOR FILENAME WORK AREA
 	MOV	R1,LMDSNP	; SET POINTER TO FILENAME
35$:
 	TSTB	(R0)		; AT END OF COMMAND LINE?
 	BEQ	40$		;  EQ: YES - PUT IN .LOA
	CMPB	#'.,(R0)	; . SPECIFIED?
 	BEQ	50$		;  EQ: YES - JUST COPY REMAINDER
	CMPB	#';,(R0)	; VERSION SPECIFIED?
 	BEQ	40$		;  EQ: YES, INSERT .LDM, THEN COPY REMAINDER
 	MOVB	(R0)+,(R1)+	; GARDEN VARIETY CHARACTER
 	BR	35$		; KEEP PROCESSING PRE-EXTENSION PART

40$:				; INSERT .LOA
	MOVB	#'.,(R1)+	; INSERT .
	MOVB	#'L,(R1)+	; INSERT L
	MOVB	#'O,(R1)+	; INSERT O
	MOVB	#'A,(R1)+	; INSERT A

50$:				; COPY REMAINDER OF STRING
 	TSTB	(R0)		; AT END OF SOURCE STRING?
	BEQ	60$		;  EQ: YES, THAT'S ALL
 	MOVB	(R0)+,(R1)+	; COPY STRING
 	BR	50$		; KEEP PROCESSING POST-EXTENSION PART

60$:				; END OF STRING - COMPUTE LENGTH
 	SUB	#RECORD,R1	; SUBTRACT BEGINNING
 	MOV	R1,LMDSNL	; SET NAME LENGTH
 	CLC			; SET SUCCESS FLAG
 	BR	255$		; AND EXIT
250$:				; ERROR EXIT
 	SEC			; SET CARRY FLAG
255$:
 	RETURN

	.PAGE
	.SBTTL	CLEAR - NULL-FILL THE RECORD BUFFER

CLEAR:
	MOV	#RECORD,R0	; R0 POINTS TO RECORD
	MOV	#RECLEN/2,R1	; R1 CONTAINS THE LENGTH IN WORDS
10$:
	CLR	(R0)+		; ASSUMING WORD BOUNDARY, FILL WITH 00
	SOB	R1,10$		; FOR AS LONG AS IT TAKES
	RETURN			; THEN EXIT
	.PAGE
	.SBTTL	LMHEAD - COMPLETE AND OUTPUT LOAD MODULE HEADER

LMHEAD:
	TSTB	.KPROC		; IS REQUIRED PROCESSOR NAME GIVEN?
	BNE	10$		;  NE: YES, PROCEED
	OUTPUT	MPN		; "Processor name must be specified before..."
	BR	250$		; TAKE ERROR EXIT
10$:
	CALL	PROCEP		; MAKE SURE ENTRY POINTS ARE SET UP
	MOV	BCOUNT,R3	; IF COUNT OF DATA READ IS ZERO, SO IS		;29MAR4
	BEQ	12$		;  COUNT OF BINARY DATA TO BE OUTPUT		;**-1
	MOV	HIADDR,R3	; COMPUTE NUMBER OF BYTES OF BINARY CODE
	MOV	HIADDR+2,R4	;  AS THE RANGE
	SUB	LOADDR,R3	;  FROM LOADDR READ THRU HIADDR READ
	SBC	R4
	SUB	LOADDR+2,R4	;  (CAN'T POSSIBLY BE ANYTHING IN HIGH WORD)
	INC	R3		; COUNT IS HIGH-LOW +1
12$:
	MOV	R3,BYTCNT	; SET COUNT OF BINARY DATA TO BE OUTPUT		;29MAR4
	MOV	R3,.KLENG	; THIS IS .KLENG				;**-1
	ADD	#RECLEN-1,R3	; COMPUTE NUMBER OF BLOCKS IT WILL TAKE
	CLRB	R3		;  TO PUT OUT THE BINARY CODE
	SWAB	R3		;  BY ROUNDING TO NEXT RECORD LENGTH,
	ROR	R3		;  THEN DIVIDING BY RECORD LENGTH
	CMPB	(R3)+,(R3)+	; ADD TWO, SO NOW WE HAVE THE FIRST VIRTUAL
	MOV	R3,.KPVBN	;  BLOCK NUMBER AT WHICH PATCH SPACE BEGINS

	CLR	R2		; COMPUTE CHECKSUM
	MOV	#.KLMH,R0	; POINT TO BEGINNING OF HEADER
	MOV	#255.,R1	; ADD FIRST 255. WORDS
15$:
	ADD	(R0)+,R2	; ACCUMULATE CHECKSUM
	SOB	R1,15$
	MOV	R2,(R0)		; PUT CHECKSUM INTO HEADER

	MOV	#.KLMH,R0	; MOVE HEADER INTO THE RECORD SPACE
	MOV	#RECORD,R1
	MOV	#RECLEN/2,R2	; LENGTH IN WORDS
20$:
	MOV	(R0)+,(R1)+	; MOVE IT WORD-WISE
	SOB	R2,20$

	CALL	PUTBLK		; PUT OUT THE HEADER BLOCK
	BCC	255$		;  CC: OK
250$:				; ERROR EXIT
	SEC			; SET CARRY TO INDICATE FAILURE
255$:				; SUCCESS EXIT
	RETURN
	.PAGE
	.SBTTL	CODE - OUTPUT THE BINARY CODE

CODE:
	CALL	CLEAR		; CLEAR THE RECORD
	MOV	LOADDR,R3	; PUT BASE (REAL) ADDRESS IN R3/R4
	MOV	LOADDR+2,R4	; PUT BASE (REAL) ADDRESS IN R3/R4
	CALL	VALID		; OFFSET INTO R2
	ADD	#MEMORY,R2	; MAKE R0 POINT TO REAL LOCATION
	MOV	#RECORD,R3	; PUT RECORD BUFFER POINTER INTO R3
	MOV	BYTCNT,R4	; R4 CONTAINS COUNT OF CODE IN BYTES		;29MAR4
	CLR	R5		; R5 IS NUMBER OF BYTES IN THIS RECORD		;**-1
10$:
	TST	R4		; ANY MORE TO DO?
	BEQ	30$		;  EQ: NO - DUMP WHAT WE HAVE IN THIS RECORD
	CMP	#RECLEN,R5	; IS THIS RECORD FULL?
	BEQ	20$		;  EQ: YES, DUMP IT AND START ANEW
	MOVB	(R2)+,(R3)+	; MOVE THE BYTE FROM VIRTUAL MEMORY
	DEC	R4		; DECREMENT COUNT OF BYTES REMAINING
	INC	R5		; INCREMENT NUMBER OF BYTES THIS RECORD
	BR	10$		; AND CONTINUE

20$:
	CALL	PUTBLK		; PUT OUT A FULL RECORD
	BCS	250$		;  CS: FAILED - TAKE ERROR EXIT
	CLR	R5		; RESET NUMBER OF BYTES THIS RECORD
	MOV	#RECORD,R3	; START AT BEGINNING OF RECORD AGAIN
	CALL	CLEAR		; START WITH A CLEAN RECORD
	BR	10$		; AND CONTINUE

30$:
	TST	R5		; ANYTHING IN THIS RECORD?
	BEQ	255$		;  EQ: NO - WE ARE DONE
	CALL	PUTBLK		; PUT PARTIAL RECORD PADDED WITH 00
	BCC	255$		;  CC: OK

250$:				; ERROR EXIT
	SEC			; CARRY FLAG INDICATES FAILURE
255$:				; SUCCESS EXIT
	RETURN
	.PAGE
	.SBTTL	APATCH - OUTPUT ALLOCATED PATCH SPACE
APATCH:
	CALL	CLEAR		; CHECKBOARD THE RECORD BUFFER
	MOVB	PAT,R2		; LOAD R2 WITH NUMBER OF BLOCKS TO OUTPUT
10$:
	BEQ	255$		;  EQ: NO MORE TO OUTPUT
	CALL	PUTBLK		; PUT THE BLOCK AND RETURN
	BCS	250$		;  CS: I/O ERROR - TAKE ERROR EXIT
	DEC	R2		; DECREMENT NUMBER OF BLOCKS REMAINING
	BR	10$		; AND CONTINUE

250$:				; ERROR EXIT
	SEC			; CARRY FLAG INDICATES FAILURE
255$:				; SUCCESS EXIT
	RETURN
	.PAGE
	.SBTTL	PUTBLK - OUTPUT A VIRTUAL BLOCK

PUTBLK:
	MOV	#LMFDB,R0
	WRITE$	R0		; WRITE THE VIRTUAL BLOCK
	BCS	250$		;  CS: ERROR ON THE WRITE
	WAIT$	R0		; SYNCHRONIZE THE WRITE
	BCC	255$		;  CC: OK
250$:
	OUTPUT	IOE		; I/O ERROR
	SEC			; SET CARRY TO SHOW FAILURE
255$:
	RETURN

	.PAGE
	.SBTTL	OUTPUT DATA AREAS
	.PSECT	DATA	RW,D							;29MAR4
IOSTAT:	.BLKL			; DOUBLE WORD FOR I/O STATUS			;**-1
BYTCNT:: .BLKW			; COUNT OF BINARY DATA TO OUTPUT		;29MAR4
	.PSECT	PURE 	RO,D							;29MAR4
	DEFM	MPN	<Processor name must be specified prior to an OUTPUT>	;**-4
	.END

