;  CP/NET GENERATOR FOR CP/NET VER.1.0 NOS
;
;  1982 8.27.  VER.1.0
;
TITLE	CP/NET GENERATOR FOR NOS  VER.1.0
;
;  EQUATIONS OF DATA
;
LF	EQU	0AH		;LINE FEED
CR	EQU	0DH		;CARRIAGE RETURN
;
TOP	EQU	0		;MEMORY TOP
BDOS	EQU	5		;BDOS ENTRY
RESFCB	EQU	5CH		;RESIDENT FCB
SCTLNG	EQU	128		;SECTOR LENGTH
;
MINSIZ	EQU	50H		;MINIMUM TARGET SYSTEM SIZE IS 20K
;
;  EQUATIONS OF BDOS FUNCTION
;
CCONIN	EQU	1		;CONSOLE INPUT
CCONOT	EQU	2		;CONSOLE OUT
CBUFPR	EQU	9		;BUFFERED STRING PRINT
CGETVR	EQU	12		;GET VERSION NUMBER
COPEN	EQU	15		;OPEN FILE
CCLOSE	EQU	16		;CLOSE FILE
CDELET	EQU	19		;DELETE FILE
CREAD	EQU	20		;READ FILE
CWRITE	EQU	21		;WRITE FILE
CMAKE	EQU	22		;MAKE FILE
CSTDMA	EQU	26		;SET DMA ADDRESS
;
;
;  START OF MAIN
;
START:
	LXI	SP,STACK
	LXI	H,CSTUP
	CALL	BUFPRN		;START UP COMMENT
	LXI	B,RESFCB+1
	LDAX	B
	DCX	B
	CPI	' '
	JNZ	$+6		;EXIST SOME OUTPUT FILE NAME
	LXI	B,CCPNET	;DEFAULT NAME
	LXI	H,OUTFCB
	CALL	CPYFCB		;COPY FCB FOR OUTPUT FILE
LOOPR:				;RETRY LOOP
	LXI	SP,STACK
	LXI	H,CGTBTM
	CALL	BUFPRN
	LXI	H,-1		;DEFAULT VALUE OF BOTTOM IS 0FFH
	CALL	GETHEX		;GET BOTTOM PAGE
	MOV	A,L
	INR	A
	LXI	H,CSIZTS
	CPI	MINSIZ
	JC	WHYPR		;TARGET SYSTEM SIZE TOO SMALL
	MOV	H,A
	MVI	L,0		;GET RELOCATION BIAS
	XCHG
	LXI	H,BFRLBS	;BIAS DATA BUFFER
	PUSH	H
	LHLD	BDOS+1
	MVI	L,0		;GET LOADING BIAS
	LXI	B,IXFLNM	;LOADING FILE NAME INDEX
LOOP:				;ONE FILE LOADHNG LOOP
	XTHL
	MOV	M,E
	INX	H
	MOV	M,D		;SET POINTER
	XTHL
	PUSH	H
	LXI	H,INFCB
	CALL	CPYFCB		;SET FILE NAME TO FCB
	POP	H
	PUSH	B
	LXI	B,INFCB
	CALL	PRNFLN		;PRINT FILE NAME
	LXI	B,INFCB
	CALL	LOAD		;LOAD ONE FILE
	POP	B
	XTHL
	PUSH	D
	CALL	LOCPR		;PRINT TOP ADDRESS
	DCX	H
	MOV	A,M
	SUB	E
	MOV	E,A
	INX	H
	MOV	A,M
	SBB	D
	MOV	D,A		;GET LENGTH
	INX	H
	CALL	LOCPR		;PRINT LENGTH
	POP	D
	XTHL
	LDAX	B
	INR	A
	JNZ	LOOP		;TO NEXT FILE
	XTHL
	MOV	M,E
	INX	H
	MOV	M,D		;SAVE TOP POINT
	INX	H
	POP	D
	MOV	M,E
	INX	H
	MOV	M,D		;SAVE DATA BUFFER TOP
	CALL	CRLF
	LXI	B,OUTFCB
	CALL	PRNFLN		;PRINT OUTPUT FILE NAME
	LXI	H,CCHECK
	CALL	BUFPRN		;CHECK OK
	CALL	CONIN
	CPI	'Y'
	JNZ	LOOPR		;RETRY
	CALL	OUTFIL		;OUT SYSTEM FILE
	JMP	TOP
;
;  LOAD ONE FILE
;  INPUT
;  HL:BOTTOM OF FREE AREA
;  DE:LAST RELOCATION BIAS
;  BC:FCB
;  OUTPUT
;  HL:TOP OF LOADING BIAS
;  BC:TOP OF RELOCATION BIAS
;
LOAD:
	SHLD	LDBOTM		;SAVE BOTTOM
	XCHG
	SHLD	RLBOTM		;SAVE RELOCATION BIAS
	MOV	H,B
	MOV	L,C
	SHLD	LDFCB		;SAVE FCB POINT
	MVI	C,CSTDMA
	LXI	H,-SCTLNG	;SUBTRUCT ONE SECTOR LENGTH
	DAD	D
	SHLD	LDDMA		;SAVE DMA POINT FOR PARAMETER READ
	XCHG
	CALL	BDOS		;SET DMA ADDRESS TO SCRATCH AREA
	LHLD	LDFCB
	XCHG
	MVI	C,COPEN
	CALL	BDOS		;OPEN FILE
	LXI	H,CNTFND
	INR	A
	JZ	WHYPR		;FILE NOT FOUND
	CALL	OSREAD		;GET PARAMETER SECTOR
	LHLD	LDDMA
	INX	H
	MOV	E,M
	INX	H
	MOV	D,M		;GET CODE AREA LENGTH
	INX	H
	INX	H
	MOV	C,M
	INX	H
	MOV	B,M		;GET DATA AREA LENGTH
	XCHG
	SHLD	LDLNGT		;SAVE CODE AREA LENGTH
	DAD	B		;GET TOTAL LENGTH
	XCHG
	XRA	A
	SUB	E
	MOV	E,A
	MVI	A,0
	SBB	D
	MOV	D,A
	LHLD	RLBOTM		;GET LAST RELOCATION BIAS
	DAD	D
	MVI	L,0
	SHLD	RLTOP		;SAVE RELOCATION DATA OF THIS FILE
	LHLD	LDBOTM		;GET LOADING BOTTOM
	DAD	D		;SUBTRUCT LENGTH FROM BOTTOM POINT
	MVI	L,0		;GET LOADING TOP
	SHLD	LDTOP		;SAVE LOADING TOP (PROGRAM TOP)
	XCHG
	LXI	H,-SCTLNG
	DAD	D		;SUBTRUCT ONE SECTOR LENGTH
	SHLD	LDDMA		;SET RELOCATION DATA BUFFER TOP
	LXI	D,BOTTOM
	CALL	CPHLDE
	LXI	H,CSYSTS
	JC	WHYPR		;SYSTEM TOO SMALL
	CALL	OSREAD		;GET DATA & IGNORE
	LHLD	LDLNGT
	LXI	D,SCTLNG-1
	DAD	D		;ADJUST BOUNDARY
	MOV	A,L
	RAL
	MOV	A,H
	RAL			;GET SECTOR COUNT OF CODE AREA
	LHLD	LDTOP		;GET LOADING TOP
LOADLP:				;ONE SECTOR LOADING LOOP
	STA	LDCNT		;SAVE COUNT
	SHLD	LDPNT		;SAVE LOADING POINT
	XCHG
	MVI	C,CSTDMA
	CALL	BDOS		;SET DMA ADDRESS
	CALL	OSREAD		;READ ONE SECTOR DATA
	LHLD	LDPNT
	LXI	D,SCTLNG	;ONE SECTOR LENGTH
	DAD	D		;GET NEXT DMA ADDRESS
	LDA	LDCNT
	DCR	A		;SECTOR COUNT DOWN
	JNZ	LOADLP		;TO NEXT SECTOR
	LHLD	LDDMA		;GET BUFFER POINT FOR RELOCATION DATA
	XCHG
	MVI	C,CSTDMA
	CALL	BDOS		;SET TO RELOCATION BUFFER POINT
	LHLD	LDLNGT		;GET LENGTH TO GET RELOCATION DATA TOP
	MOV	B,H
	MOV	C,L
	XCHG
	LHLD	LDTOP		;CODE TOP
	XCHG
	DAD	D		;GET TOP OF RELOCATION DATA
	PUSH	H		;SAVE RELOCATION DATA POINT
	LDA	RLTOP+1
	MOV	H,A		;SET RELOCATION BIAS
LOADRL:				;RELOCATION LOOP
	MOV	A,B
	ORA	C
	JZ	LOADRE		;LOADING END
	DCX	B
	MOV	A,E
	ANI	07H
	JNZ	LOADRB		;NOT BYTE BOUNDARY
	XTHL			;BYTE BOUNDARY,  GET DATA POINT
	MOV	A,L
	ANI	07FH
	JNZ	LOADRS		;NOT SECTOR BOUNDARY
	PUSH	B
	PUSH	D
	PUSH	H
	LHLD	LDFCB		;GET FCB POINT
	XCHG
	MVI	C,CREAD
	CALL	BDOS		;GET ONE SECTOR DATA
	POP	H
	POP	D
	POP	B
	LHLD	LDDMA		;GET DATA TOP POINT
	ORA	A
	JNZ	OSRDER		;NO DATA, SO ERROR
LOADRS:
	MOV	A,M		;GET NEXT RELOCATION DATA
	INX	H
	XTHL
	MOV	L,A
LOADRB:
	MOV	A,L
	RAL			;GET ONE BIT DATA
	MOV	L,A
	JNC	$+6		;NOT RELOCATE
	LDAX	D		;RELOCATE
	ADD	H
	STAX	D
	INX	D
	JMP	LOADRL		;TO NEXT DATA
;
LOADRE:				;END OF LOADING
	POP	H
	LHLD	RLTOP
	XCHG
	LHLD	LDTOP		;GET PARAMETER
	RET
;
;  READ ONE SECTOR DATA
;
OSREAD:
	LHLD	LDFCB		;GET FCB
	XCHG
	MVI	C,CREAD
	CALL	BDOS		;READ ONE SECTOR
	ORA	A
	RZ			;NOT ERROR
OSRDER:				;NO DATA, SO ERROR
	LXI	H,CNODAT
	JMP	WHYPR		;NO DATA ERROR
;
;  OUTPUT SYSTEM FILE
;  SYSTEM PAGE
;  2B:NDOS TOP
;  2B:SNIOS TOP
;  2B:BDOS TOP
;  2B:BIOS TOP
;  2B:LENGTH
;
OUTFIL:
	LXI	D,OUTFCB
	MVI	C,CDELET
	CALL	BDOS		;DELETE FILE
	LXI	B,OUTFCB
	LXI	H,OUTFCB
	CALL	CPYFCB		;CLEAR FCB
	LXI	D,OUTFCB
	MVI	C,CMAKE
	CALL	BDOS		;MAKE OUTPUT FILE
	LXI	H,CNODIR
	INR	A
	JZ	WHYPR		;NO DIRECTORY SPACE
	LXI	H,DMABUF
	XRA	A
	MVI	B,SCTLNG
	MOV	M,A		;CLEAR DMA BUFFER
	INX	H
	DCR	B
	JNZ	$-3
	LHLD	BFRLBS+10	;GET BOTTOM
	LDA	BDOS+2
	SUB	H
	MOV	H,A		;GET LENGTH
	SHLD	BFRLBS		;SET LENGTH
	LXI	H,BFRLBS+10
	LXI	D,DMABUF
	MVI	B,5
	DCX	H
	MOV	C,M
	DCX	H
	MOV	A,M		;GET BIAS DATA
	STAX	D
	INX	D
	MOV	A,C
	STAX	D		;SET DATA
	INX	D
	DCR	B
	JNZ	$-10
	LXI	D,DMABUF
	CALL	WRITE		;WRITE SYSTEM PAGE
	LDA	BFRLBS+1	;GET LENGTH
	ADD	A		;GET SECTOR COUNT
	LHLD	BFRLBS+10	;TOP OF DATA
OUTFLL:
	XCHG
	LXI	H,SCTLNG
	DAD	D		;GET NEXT DMA ADDRESS
	PUSH	H
	PUSH	PSW		;SAVE COUNT
	CALL	WRITE		;WRITE ONE SECTOR
	POP	PSW
	POP	H
	DCR	A
	JNZ	OUTFLL		;TO NEXT SECTOR
	LXI	D,OUTFCB
	MVI	C,CCLOSE
	CALL	BDOS		;CLOSE FILE
	LXI	H,CCLSER
	INR	A
	JZ	WHYPR		;CLOSE ERROR
	RET
;
;  WRITE ONE SECTOR
;  INPUT
;  DE:DMA ADDRESS
;
WRITE:
	MVI	C,CSTDMA
	CALL	BDOS		;SET DMA ADDRESS
	LXI	D,OUTFCB
	MVI	C,CWRITE
	CALL	BDOS		;WRITE ONE SECTOR
	LXI	H,CWTERR
	ORA	A
	JNZ	WHYPR		;ERROR
	RET
;
;  GET HEXADECIMAL VALUE
;  INPUT
;  HL:DEFAULT VALUE
;  OUTPUT
;  HL:OUTPUT VALUE
;
GETHEX:
	CALL	CONIN		;GET FIRST CHARACTER
	CPI	CR
	RZ			;DEFAULT MODE
	LXI	H,0
GETHXL:				;ONE CHARACTER LOOP
	SUI	'0'
	JC	LOOPR		;TOO SMALL
	CPI	10
	JC	GETHXG		;0 TO 9
	SUI	'A'-'9'-1
	CPI	10
	JC	LOOPR		;ERROR
	CPI	16
	JNC	LOOPR		;TOO LARGE
GETHXG:				;GET CODE
	DAD	H
	DAD	H
	DAD	H
	DAD	H		;*16
	ADD	L
	MOV	L,A		;ADD CURRENT DATA
	CALL	CONIN
	CPI	CR
	JNZ	GETHXL		;TO NEXT
	RET			;END
;
;  PRINT FILE NAME
;  INPUT
;  BC:FCB TOP
;
PRNFLN:
	CALL	CRLF
	PUSH	D
	MVI	D,12
	INX	B
	LDAX	B
	CALL	CONOT
	DCR	D
	JNZ	$-6
	POP	D
	RET
;
;  ERROR COMMENT OUT & ABORT
;  INPUT
;  HL:COMMENT POINTER
;
WHYPR:
	CALL	BUFPRN
	JMP	TOP
;
;  COMPARE DOUBLE BYTES
;  FLAGS:SET BY HL-DE
;
CPHLDE:
	MOV	A,H
	SUB	D
	RNZ
	MOV	A,L
	SUB	E
	RET
;
;  COPY FCB
;  INPUT
;  BC:SOURCE DATA POINTER
;  HL:DESTINATION FCB
;
CPYFCB:
	PUSH	D
	MVI	D,12
	LDAX	B
	MOV	M,A		;COPY FILE NAME PART
	INX	B
	INX	H
	DCR	D
	JNZ	$-5
	MVI	D,21
	XRA	A
	MOV	M,A
	INX	H
	DCR	D
	JNZ	$-3		;CLEAR LEFT PART
	POP	D
	RET
;
;  CONSOLE INPUT
;  OUTPUT
;   A:DATA
;
CONIN:
	PUSH	H
	PUSH	D
	PUSH	B
	MVI	C,CCONIN
	CALL	BDOS
	POP	B
	POP	D
	POP	H
	CPI	3
	JZ	TOP		;ABORTED
	CPI	'Z'+1
	RC
	ANI	5FH		;LOWER CASE TO UPER CASE
	RET
;
;  CONSOLE OUT
;  INPUT
;   A:DATA
;
CONOT:
	PUSH	H
	PUSH	D
	PUSH	B
	MVI	C,CCONOT
	MOV	E,A
	CALL	BDOS
	POP	B
	POP	D
	POP	H
	RET
;
;  BUFFER PRINT
;  INPUT
;  HL:STRING POINT
;
BUFPRN:
	MOV	A,M
	INX	H
	ORA	A
	RZ
	CALL	CONOT
	JMP	BUFPRN
;
;  CARRIAGE RETURN & LINE FEED
;
CRLF:
	MVI	A,CR
	CALL	CONOT
	MVI	A,LF
	JMP	CONOT
;
;  PRINT BYTE DATA BY HEXADECIMAL
;  INPUT
;   A:DATA
;
HXPRN:
	PUSH	PSW
	RRC
	RRC
	RRC
	RRC
	CALL	NIBBLE		;UPER HALF
	POP	PSW
NIBBLE:				;NIBBLE OUT
	ANI	0FH
	ADI	'0'
	CPI	'9'+1
	JC	CONOT		;0 TO 9
	ADI	'A'-'9'-1
	JMP	CONOT		;A TO F
;
;  PRINT WORD DATA
;  INPUT
;  DE:DATA
;
LOCPR:
	MVI	A,' '
	CALL	CONOT
	MVI	A,' '
	CALL	CONOT		;PRINT SPACE
	MOV	A,D
	CALL	HXPRN		;HIGHER BYTE
	MOV	A,E
	CALL	HXPRN		;LOWER BYTE
	MVI	A,'H'
	JMP	CONOT
;
;  INDEX OF LOADING FILE NAME
;
IXFLNM:
	DB	0,'NBIOS   SPR'
	DB	0,'NBDOS   SPR'
	DB	0,'NNIOS   SPR'
	DB	0,'NDOS    SPR'
	DB	-1
;
CCPNET:	DB	0,'CPNET   SYS'	;DEFAULT OUTPUT FILE NAME
;
;  COMMENTS
;
CSTUP:	DB	CR,LF,LF,'CP/NET 1.0 GENERATOR'
	DB	CR,LF,'====================',CR,LF,0
;
;
CGTBTM:	DB	CR,LF,'BOTTOM PAGE ? (FF) ',0
CSIZTS:	DB	CR,LF,'SYSTEM SIZE TOO SMALL',0
CCHECK:	DB	' IS SYSTEM FILE NAME, OK ? (Y/N) ',0
CNODIR:	DB	CR,LF,'NO DIRECTORY SPACE',0
CCLSER:	DB	CR,LF,'CAN''T CLOSE OUTPUT FILE',0
CWTERR:	DB	CR,LF,'NO DATA SPACE',0
CNTFND:	DB	'   NOT FOUND',0
CNODAT:	DB	'   FILE TOO SHORT',0
CSYSTS:	DB	CR,LF,'HOST SYSTEM TOO SMALL',0
;
;  WORKINGS
;
;  FILE CONTROL BLOCKS
;
INFCB:	DS	33		;FOR INPUT FILE
OUTFCB:	DS	33		;FOR OUTPUT FILE
;
BFRLBS:	DS	2*6		;RELOCATION BIAS BUFFER
;
DMABUF:	DS	128		;ONE SECTOR BUFFER
;
;  LOADING ROUTINE WORKING
;
LDDMA:	DS	2		;DMA ADDRESS
LDLNGT:	DS	2		;CODE AREA LENGTH
LDFCB:	DS	2		;FCB POINTER
LDBOTM:	DS	2		;BOTTOM POINT OF FREE AREA
LDTOP:	DS	2		;TOP POINT OF PROGRAM
RLBOTM:	DS	2		;RELOCATION BOTTOM
RLTOP:	DS	2		;RELOCATION BIAS
LDCNT:	DS	1		;LOAD SECTOR COUNT
LDPNT:	DS	2		;LOADING POINTER
;
;
	DS	64
STACK:
;
;
BOTTOM:				;BOTTOM OF PROGRAM
;
;
	END
