	TITLE	'INTERDOS: NORTH STAR/CPM FILE CONVERSIONS'
; THIS PROGRAM DOES THE NORTH STAR TO CP/M AND CP/M TO NORTH STAR FILE
; CONVERSIONS.  IT WILL BE NECESSARY FOR THE USER TO CHANGE THE NSBOOT
; ADDRESS AND DENSITY AS LISTED BELOW IN THE FOLLOWING TWO EQUATES.
NSBOOT	EQU	0E800H		;NEWER NS SYSTEMS USE E800, 
				;OLDER SYSTEMS USE E900
DENSITY	EQU	'D'		;S-SINGLE DENSITY
				;D-DOUBLE OR QUAD DENSITY

; COPYRIGHT 1980, G. YOUNG, INC
; WRITTEN BY G. YOUNG, INC, PO BOX 3218, NORTH HOLLYWOOD, CA 91609
; MODIFIED 02/01/81
DOS	EQU	2028H
DLOOK	EQU	201CH		;DIRECTORY LOOKUP
DCOM	EQU	2022H		;DISK IO
DBYTE	EQU	202FH		;ACTUAL DENSITY OF DISK
BDOS	EQU	5
	ORG	100H
START	LXI	SP,STACK+50
	MVI	A,DENSITY
	CPI	'S'
	JZ	SIGNON1
	LXI	D,SIGNOND
	JMP	SIGNON2
SIGNON1	LXI	D,SIGNONS
SIGNON2	CALL	PRINT
	LXI	D,BOOTMSG	;BOOT NORTH STAR DOS?
	CALL	PRINT
	CALL	INPUT
	CPI	'Y'
	JZ	NSBOOT		;BOOT NS DOS
	CALL	FILLBUFF
MESS1	LXI	D,DEST		;DESTINATION SYSTEM?
	CALL	PRINT
	CALL	INPUT
	STA	TODOS
	CPI	'N'		;TO NORTH STAR
	JZ	TONS
	CPI	'C'		;TO CP/M
	JZ	TOCPM
	JMP	MESS1
TONS	LXI	D,SRCCPM	;CONFIRM SOURCE ON CPM
	CALL	PRINT
	JMP	MESS2
TOCPM	LXI	D,SRCNS		;CONFIRM SOURCE ON NS
	CALL	PRINT
MESS2	LXI	D,LINEA		;DISPLAY OPTIONAL CONVERSION
	CALL	PRINT		;ROUTINES
	LXI	D,LINE0
	CALL	PRINT
	LXI	D,LINE1
	CALL	PRINT
	LXI	D,LINE2
	CALL	PRINT
	LXI	D,LINE3
	CALL	PRINT
	LXI	D,LINE4
	CALL	PRINT
	LXI	D,LINE5
	CALL	PRINT
	LXI	D,LINEB		;ASK QUESTION ABOUT OPTION
	CALL	PRINT
	CALL	INPUT
	STA	CNVRT
	CPI	'0'
	JC	MESS2
	CPI	'5'+1
	JNC	MESS2		;REASK QUESTION IF BAD INPUT
MESS3	LXI	D,EOFMSG	;HOW TO DETECT EOF?
	CALL	PRINT
	CALL	INPUT
	STA	EOFIND	
	CPI	'1'		;FIND AN 01 IN DATA
	JZ	MESS4
	CPI	'B'		;STOP ON BLOCK COUNT
	JNZ	MESS3		;REPEAT MESSAGE IF INVALID
MESS4	XRA	A		;RESET EOF INDICATOR
	STA	EOF
MESS6	LXI	D,MOUNT		;TYPE MOUNT MESSAGE
	CALL	PRINT		;DONE NOW SO THAT DISKS ARE LOADED
	CALL	INPUT		;WHEN FILE NAMES ARE ENTERED
MESS7	LXI	D,CPMFILE	;GET CPM FILE NAME
	CALL	PRINT
	CALL	INPUT
	CALL	GETFCB		;CREATE FCB
	CALL	OPENCPM
MESS8	LXI	D,NSFILE	;GET NORTH STAR FILE NAME
	CALL	PRINT
	MVI	A,DENSITY	;RESET THE TRUE DENSITY TO THE SYSTEM
	STA	TRUEDEN		;DENSITY. IT WILL LATER BE CHANGED IN
				;OPENNS TO THE ACTUAL DISK DENSITY
	CALL	INPUT
	CALL	OPENNS
	LXI	H,NSBUFF	;GET ADDR OF NS BUFFER
	SHLD	NSADDR
	LXI	H,CPMBUFF	;GET ADDR OF CPM BUFFER
	SHLD	CPMADDR
	XRA	A
	STA	NSCNT		;CLEAR CHARACTER COUNTER
	STA	NSCNT+1
	STA	CPMCNT		;CLEAR CPM CHAR COUNTER
	LDA	TODOS		;CHECK DESTINATION
	CPI	'N'
	JZ	CPMTONS		;CPM TO NS COPY
NSTOCPM	LDA	CNVRT		;CHECK THE CONVERSION OPTION
	CPI	'0'		;NO CONVERSTION
	JZ	NONSCNVT	;NO CONVERSION OF NS TO CPM
	CPI	'1'		;NS SECRTARY TO CPM ASM FILE
	JZ	SECTOASM
	CPI	'2'		;NS SECRTARY TO CPM ED FILE
	JZ	SECTOED
	CPI	'3'		;NS SECRTARY TO CPM BASIC FILE
	JZ	SECTOBAS
	CPI	'4'		;NS BASIC TO CPM BASIC
	JZ	BASTOBAS
	JMP	ERR1		;INVALID OPTION
CPMTONS	LDA	CNVRT
	CPI	'0'		;CPM TO NS WITHOUT CONVERSION
	JZ	NOCPMCNVT	;DATA OR SECRTARY FILES
	CPI	'5'		;CPM HEX TO NS TYPE 2 FILES
	JZ	HEXTO2
ERR1	LXI	D,ERRM1
	CALL	PRINT
	JMP	MESS1
CPMERR	LXI	D,ERRM2
	CALL	PRINT
	JMP	FINISHED
NSERR	LXI	D,ERRM3
	CALL	PRINT
	JMP	FINISHED
PRINT	PUSH	D
	LXI	D,CRLF
	MVI	C,9
	CALL	BDOS
	POP	D
PRINT2	MVI	C,9
	CALL	BDOS
	RET
INPUT	LXI	D,IBUF
	MVI	C,0AH
	CALL	BDOS
	LDA	IBUF+2
	RET

RESET	EQU	$		;RESET POINTERS AND COUNTERS
	XRA	A
	STA	EOF		;RESET EOF
	STA	NSCNT		;RESET CHAR COUNTERS
	STA	NSCNT+1
	STA	CPMCNT
	LXI	H,NSBUFF	;DEFINE BUFFER ADDRESSES
	SHLD	NSADDR
	LXI	H,CPMBUFF
	SHLD	CPMADDR
	RET


* SECRTARY FORMAT AS REFERENCED HERE IS THE OLD SCS FORMAT
* CONSISTING OF A LINE COUNT, 4 ASCII CHARACTERS FOR THE LINE
* NUMBER, THE TEXT, AND A SINGLE CARRIAGE RETURN AT THE END
* WITHOUT THE LINE FEED.

* CONVERT SECRTARY FORMAT TO ASCII BASIC FORMAT IE RETAIN THE
* LINE NUMBERS, BUT DELETE THE CHARACTER COUNT AND ADD A LINE
* FEED AFTER THE CARRIAGE RETURN

SECTOBAS	EQU	$
	CALL	RESET
	CALL	READNS
NEXTLINE3	CALL	GETNS		;GET THE NS CHAR COUNT
	CPI	1		;IS IT AN EOF?
	JZ	CLOSE2		;YES!!!
COPY3	CALL	GETNS
	CALL	PUTCPM
	LDA	TEMP
	CPI	0DH		;END OF LINE?
	JZ	ENDSTB		;YES
	JMP	COPY3
ENDSTB	MVI	A,0AH		;ADD THE LINEFEED
	STA	TEMP
	CALL	PUTCPM
	JMP	NEXTLINE3

* CONVERT SECRTARY FORMAT TO ED FORMAT IE DELETE THE LINE NUMBERS,
* DELETE THE CHARACTER COUNT ON EACH LINE, AND ADD A LINE FEED
* AFTER THE CARRIAGE RETURN

SECTOED	EQU	$
	CALL	RESET
	CALL	READNS
NEXTLINE4	CALL	GETNS
	CPI	1		;EOF
	JZ	CLOSE2
	CALL	GETNS		;GET LINE# CHAR 1
	CALL	GETNS		;GET LINE# CHAR 2
	CALL	GETNS		;GET LINE# CHAR 3
	CALL	GETNS		;GET LINE# CHAR 4
COPY4	CALL	GETNS
	CALL	PUTCPM
	CPI	0DH		;END OF LINE??
	JNZ	COPY4
ENDSTE	MVI	A,0AH
	STA	TEMP
	CALL	PUTCPM
	JMP	NEXTLINE4

* NS SECRTARY TO CPM ASSEMBLER FORMAT
* THIS IS SIMILAR TO NS SECRTARY TO ED FORMAT EXCEPT
* THIS CHANGES CERTAIN BLANKS TO TABS
SECTOASM	EQU	$
	CALL	RESET
	CALL	READNS		;GET ONE NS BUFFER
COPY2	CALL	GETNS		;GET CHAR/LINE COUNT
	CPI	1		;EOF?
	JZ	CLOSE2		;YES, EOF FOUND
	CALL	GETNS		;GET LINE # CHAR 1
	CALL	GETNS		;GET LINE # CHAR 2
	CALL	GETNS		;GET LINE # CHAR 3
	CALL	GETNS		;1ST CHAR AFTER LINE IS ALWAYS BLANK
	CALL	GETNS		;GET LINE # CHAR 4
	CALL	GETNS		;GET FIRST CHAR OF THE LINE
	CPI	20H		;IS IT A SPACE
	JNZ	LABEL2		;NO, IT MUST BE A LABEL THEN
	MVI	A,09
	STA	TEMP		;REPLACE SPACE WITH A TAB
	CALL	PUTCPM
	JMP	OPCODE
LABEL2	CALL	PUTCPM		;COPY THE LABEL
	CALL	GETNS		;GET NEXT CHAR OF LABEL
	CPI	20H		;LABEL DONE?
	JNZ	LABEL2
TAB2	MVI	A,09		;REPLACE THE SPACE BETWEEN THE LABEL
	STA	TEMP		;AND THE OPCODE WITH A TAB
	CALL	PUTCPM
OPCODE	CALL	GETNS		;COPY THE OPCODE
	CPI	20H
	JZ	TAB3
	CPI	0DH		;CARRIAGE RETURN?
	JZ	ENDLINE
OPCODE2	CALL	PUTCPM
	JMP	OPCODE
TAB3	MVI	A,09		;REPLACE THE SPACE BETWEEN THE
	STA	TEMP		;OPCODE AND THE OPERAND WITH A TAB
	CALL	PUTCPM
OPERAND	CALL	GETNS
	CPI	0DH
	JZ	ENDLINE
	CPI	20H
	JZ	TAB4
	CALL	PUTCPM		;COPY THE OPERAND
	JMP	OPERAND
TAB4	MVI	A,09		;REPLACE THE SPACE BETWEEN THE
	STA	TEMP		;OPERAND AND THE COMMENT
	CALL	PUTCPM
COMMENT	CALL	GETNS		;COPY THE REST OF THE LINE
	CPI	0DH
	JZ	ENDLINE
	CALL	PUTCPM
	JMP	COMMENT
ENDLINE	MVI	A,0DH		;REPLACE THE SINGLE CARRIAGE
	STA	TEMP		;RETURN WITH A CARRIAGE RETURN/LINE FEED
	CALL	PUTCPM
	MVI	A,0AH		;"DISPLAY" PUTS IN ITS OWN LINE FEED
	STA	TEMP		;SO IT DOES NOT HAVE TO BE CALLED
	CALL	PUTCPM		;TO PRINT THIS CHARACTER
	JMP	COPY2
CLOSE2	CALL	CLOSECPM
	JMP	MESS7

* COPY FILES FROM NORTH STAR TO CPM WITHOUT ANY CONVERSION

NONSCNVT	EQU	$	;COPY NS TO CPM WITHOUT CONVERSION
	CALL	RESET
	CALL	READNS
COPY1	CALL	GETNS		;GET ONE CHAR FROM NS
	CALL	PUTCPM		;PUT ONE CHAR INTO CPM BUFFER
	LDA	EOF		;CHECK FOR EOF
	ORA	A
	JZ	COPY1
	CALL	CLOSECPM
	JMP	MESS7


* COPY CPM HEX FILE TO NS TYPE 2 FILE
* ASSUME THAT THE ADDRESS OF THE TYPE 2 FILE CORRESPONDS
* TO THE HEX ADDRESSES

HEXTO2	CALL	RESET
	XRA	A
	STA	LAST
	CALL	READCPM
COLON	MVI	E,0
	MVI	C,0
	CALL	GETCPM		;GET THE COLON
	CPI	':'
	JNZ	NOTHEX
	CALL	GETBYTE		;GET THE COUNT
	ORA	A
	JZ	CLOSENS		;END WHEN BYTE COUNT IS ZERO
	MOV	C,A		;SAVE COUNT
	CALL	GETBYTE		;SKIP THE ADDRESS
	STA	ABCD+1
	CALL	GETBYTE		;SKIP THE ADDRESS BYTE 2
	STA	ABCD		;SAVE THE ADDRESS
	LDA	LAST		;IS THIS THE FIRST ADDRESS
	ORA	A	
	JNZ	CHECKADDR	;NO, SKIP INITIALIZATION
	MVI	A,1		;YES, INIT LAST ADDR
	STA	LAST
	LHLD	ABCD
	SHLD	WXYZ
CHECKADDR LHLD	ABCD
	XCHG			;DE=CURRENT ADDR
	LHLD	WXYZ		;HL=LAST ADDR
	MOV	A,D		;COMPARE FOR EQUAL
	CMP	H
	JNZ	ADDRGAP		;THERE IS A GAP IN THE ADDRESSES
	MOV	A,E
	CMP	L
	JZ	ADDROK		;NO GAP IN ADDRESSES
ADDRGAP MVI	A,00		;FILL GAP WITH LOW VALUES
	CALL	PUTNS
	LHLD	WXYZ
	INX	H
	SHLD	WXYZ
	JMP	CHECKADDR
ADDROK	EQU	$
	CALL	GETBYTE		;SKIP THE TYPE BYTE
NEXTHEX	CALL	GETBYTE
	CALL	PUTNS
	LHLD	WXYZ		;INCREMENT LAST ADDRESS SO THAT
	INX	H		;IT WILL BE EQUAL TO THE NEXT ADDR
	SHLD	WXYZ		;WHEN THE NEXT ADDR IS READ
	DCR	C
	JNZ	NEXTHEX
	CALL	GETBYTE		;SKIP THE CHECKSUM
	CALL	GETCPM		;SKIP CR
	CALL	GETCPM		;SKIP LF
	JMP	COLON
CLOSENS	CALL	CLOSECPM
	CALL	WRITENS
	JMP	MESS7
NOTHEX	LXI	D,HEXMSG
	CALL	PRINT
	JMP	MESS7
HEXMSG	DB	'THIS IS NOT A HEX FILE$'
GETBYTE	PUSH	H		;CONVERT TWO ASCII CHARACTERS INTO
	PUSH	B		;ONE BINARY BYTE
	LXI	H,0
	MVI	C,3		;TWO CHARACTERS
HEX	DCR	C
	JZ	FINI
	CALL	GETCPM
	DAD	H		;SHIFT LEFT
	DAD	H
	DAD	H
	DAD	H
	CALL	AHS1
	CPI	10H
	CMC
	JC	FINI
	ADD	L
	MOV	L,A
	JMP	HEX
FINI	POP	B
	POP	H
	RET
AHS1	SUI	48
	CPI	10
	RC
	SUI	7
	RET


* COPY CPM FILE TO NORTH STAR WITHOUT CONVERSION

NOCPMCNVT	EQU	$
	CALL	RESET
	CALL	READCPM
COPY6	CALL	GETCPM
	CALL	PUTNS
	LDA	EOF
	ORA	A
	JZ	COPY6
	JMP	CLOSENS




DISPLAY	LDA	TEMP		;GET CHAR TO DISPLAY
	CPI	13
	JZ	TYPECR
	CPI	20H
	JZ	TYPEIT
	RC
	CPI	7FH
	RNC
TYPEIT	MOV	E,A
	MVI	C,2
	CALL	BDOS		;CONSOLE OUTPUT
	RET
TYPECR	LXI	D,CRLF
	JMP	PRINT2


; CP/M IO ROUTINES

READCPM	LXI	D,CPMBUFF
	MVI	C,1AH		;SET DMA
	CALL	BDOS
	LXI	D,FCB
	MVI	C,14H
	CALL	BDOS		;SEQUENTIAL READ
	INR	A
	JZ	EOFCPM
RESET1	LXI	H,CPMBUFF	;RESET BUFFER ADDR
	SHLD	CPMADDR
	XRA	A		;RESET BYTE COUNT
	STA	CPMCNT
	RET
EOFCPM	MVI	A,01
	STA	EOF
	JMP	RESET1

GETCPM	PUSH	H
	PUSH	D
	PUSH	B
	LHLD	CPMADDR		;GET ONE CHAR FROM CPM BUFFER
	MOV	A,M
	STA	TEMP
	INX	H
	SHLD	CPMADDR
	LDA	CPMCNT
	INR	A
	STA	CPMCNT		;INCREMENT COUNTER AND ADDRESS
	CPI	128		;CHECK FOR EMPTY BUFFER
	CZ	READCPM		;REFILL BUFFER
	LDA	EOFIND
	CPI	'B'
	JZ	GETCPM1		;SEE IF EOF DEPENDED ON 01 OB BLOCK CNT
	LDA	TEMP		;WAS CHAR READ AN EOF INDICATOR 01
	CPI	01
	JNZ	GETCPM1		;NO
	STA	EOF
GETCPM1	LDA	TEMP
	POP	B
	POP	D
	POP 	H
	RET			;YES, SET INDICATOR ON

WRITECPM	LXI	D,FCB	;WRITE ONE CPM BUFFER FULL
	MVI	C,15H		;WRITE SEQUENTILA
	CALL	BDOS
	INR	A
	JZ	CPMERR		;PROBABLY DISK FULL
	CALL	FILLBUFF
	JMP	RESET1
FILLBUFF	LXI	D,CPMBUFF
	MVI	B,128		;FILL THE BUFFER WITH CPM 
	MVI	A,1AH		;END OF FILE CHARACTERS
FILL2	STAX	D		;ACCORDING TO CONVENTION
	INX	D
	DCR	B
	JNZ	FILL2
	RET

PUTCPM	PUSH	H		;PUT ONE CHAR INTO CPM BUFFER
	PUSH	D
	PUSH	B
	STA	TEMP
	LHLD	CPMADDR
	MOV	M,A
	INX	H
	SHLD	CPMADDR
	LDA	CPMCNT
	INR	A
	STA	CPMCNT
	CPI	128		;CHECK FOR FULL BUFFER
	CZ	WRITECPM	;DUMP IT IF FULL
	CALL	DISPLAY
	POP	B
	POP	D
	POP	H
	RET


FINISHED	MVI	C,0	;GO TO CPM
	JMP	BDOS


CLOSECPM	CALL	WRITECPM
	LXI	D,FCB
	MVI	C,10H
	CALL	BDOS		;CLOSE THE FILE
	RET


OPENCPM	LXI	D,FCB
	MVI	C,0FH
	CALL	BDOS		;OPEN THE FILE
	INR	A
	JNZ	EXISTS		;FILE ALREADY EXISTS
	LDA	TODOS		;FILE DOES NOT EXIST
	CPI	'C'		;THATS OK, IT IS TO CPM
	JZ	MAKEIT		;CREATE A FILE
NOTFND	LXI	D,NOFILE	;NO FILE ERR
	CALL	PRINT
	JMP	FINISHED
MAKEIT	LXI	D,FCB		;CREATE A FILE
	MVI	C,16H		;ON CPM
	CALL	BDOS
	INR	A
	JZ	CPMERR		;NO ROOM TO CREATE ONE
	RET
EXISTS	LDA	TODOS		;FILE ALREADY EXISTS
	CPI	'N'		;THATS OK BECAUSE COPY IT TO NS
	RZ
	LXI	D,FCB		;COPYING IT TO CPM SO DELETE
	MVI	C,13H		;THE EXISTING FILE AND MAKE
	CALL	BDOS		;A NEW ONE
	JMP	MAKEIT
GETFCB	LXI	H,IBUF+2	;GET ADDRESS OF INPUT LINE
	LDA	IBUF+1		;GET CHAR CNT FROM INPUT BUFFER
	ORA	A
	JZ	FINISHED	;QUIT IF NO NAME ENTERED
	MOV	B,A
	MVI	C,33
	XRA	A
	LXI	D,FCB		;CLEAR THE FCB
CLEARFCB	STAX	D
	INX	D
	DCR	C
	JNZ	CLEARFCB
	PUSH	H		;SAVE THE POSITION OF THE DRIVE NUMBER
	INX	H		;CHECK FOR A COLON
	MOV	A,M
	CPI	':'
	JNZ	NOCOLON
	POP	H
	MOV	A,M
	ANI	1FH		;CONVERT A=1...P=16
	STA	FCB
	INX	H
	INX	H		;PASS THE COLON
	DCR	B
	DCR	B
	JMP	GETNAME
NOCOLON	POP	H
GETNAME	LXI	D,FCB+1
	MVI	C,11
	MVI	A,20H		;BLANK OUT THE NAME
CLEARNAME	STAX	D
	INX	D
	DCR	C
	JNZ	CLEARNAME
	LXI	D,FCB+1
	MVI	C,8
MOVENAME	MOV	A,M	;MOVE THE NAME TO THE FCB
	CPI	'.'		;LOOK FOR THE PERIOD THAT SEPARATES
	JZ	PERIOD		;THE NAME  FROM THE TYPE
	CALL 	UPPERCASE
	STAX	D
	INX	D
	INX	H
	DCR	B		;DECREASE BYTE CNT IN INPUT BUFFER
	RZ
	DCR	C
	JNZ	MOVENAME
	MOV	A,M
	CPI	'.'
	JZ	PERIOD
	DCR	B
	RZ
	JMP	CPMFILENAME
PERIOD	LXI	D,TYPE
	INX	H
	MVI	C,3
MOVETYPE	MOV	A,M
	CALL	UPPERCASE
	STAX	D
	INX	D
	INX	H
	DCR	B
	RZ
	DCR	C
	JNZ	MOVETYPE
	RET
CPMFILENAME	LXI	D,ERRM4
	CALL	PRINT
	JMP	FINISHED
NSFILENAME	LXI	D,ERRM5
	CALL	PRINT
	JMP	FINISHED
UPPERCASE	CPI	60H	;CONVERT LOWER TO UPPER CASE
	RC
	SBI	20H
	RET


; NORTH STAR IO ROUTINES

OPENNS	MVI	A,1		;DEFAULT DISK DRIVE
	STA	DISK
	MVI	C,12		;CLEAR THE FILE NAME AREA
	MVI	A,20H
	LXI	D,FILE
BLKFILL	STAX	D
	INX	D
	DCR	C
	JNZ	BLKFILL
	LXI	H,IBUF+2	;SEARCH FOR THE NAME IN THE INPUT LINE
	ORA	A
	JZ	MESS8
	LDA	IBUF+1		;CHAR COUNT IN INPUT BUFFER
	MOV	B,A
MFILE	MVI	C,9
	LXI	D,FILE
FILL1	MOV	A,M
	CPI	' '
	JZ	UPPER
	CPI	','		;DRIVE NO IS ABOUT TO BE FOUND
	JZ	LOOKU
	CALL	UPPERCASE
	STAX	D
	INX	H
	INX	D
	DCR	B
	JZ	UPPER
	DCR	C
	JZ	NSFILENAME
	JMP	FILL1
LOOKU	INX	H		;GET THE DRIVE NO
	MOV	A,M
	DCR	B
	JZ	UPPER
	CPI	'1'
	JC	NSFILENAME
	CPI	'4'+1
	JNC	NSFILENAME
	ANI	0FH		;CONVERT TO BINARY
	STA	DISK
SINGLE	EQU	$
	INX	H
UPPER	LDA	DISK		;SEE IF THE FILE EXISTS
	LXI	H,FILE
	CALL	DLOOK
	JC	NOTFND
	MOV	E,M		;GET DISK ADDRESS
	INX	H
	MOV	D,M		;GET REST OF DISK ADDRESS
	INX	H
	MOV	A,M		;GET BLOCK COUNT
	INR	A		;INCREMENT BLOCK COUNT TO DECREMENT LA
	STA	BLOCKS
	XCHG
	SHLD	DISKADDR	;GET THE DISK ADDRESS
	MVI	A,DENSITY	;SET THE TRUE DENSITY TO SINGLE
	CPI	'S'		;IF THIS WAS A DOUBLE DENSITY SYSTEM
	RZ			;BUT THE DISK IS SINGLE DENSITY
	LDA	DBYTE		;CHECK TRUE DISK DENSITY
	ORA	A
	RNZ			;SYSTEM=DOUBLE DEN AND DISK=DOUBLE DEN
	MVI	A,'S'		;SYSTEM=DOUBLE DEN BUT DISK=SINGLE DEN
	STA	TRUEDEN
	RET

READNS	LDA	BLOCKS
	DCR	A
	JZ	EOFNS
	STA	BLOCKS
	LHLD	DISKADDR
	LDA	TRUEDEN
	CPI	'S'
	JZ	SINGDEN
	LDA	DISK
	ORI	80H
	STA	DISK
SINGDEN	LDA	DISK
	MOV	C,A
	MVI	A,1		;READ ONE BLOCK ON SINGLE DENSITY (256 CHAR)
				;OR ONE SECTOR ON DOUBLE DENSITY (512) CHAR
	MVI	B,1		;READ OPERATION
	LXI	D,NSBUFF
	CALL	DCOM
	JC	NSERR
IOGOOD	LHLD	DISKADDR
	INX	H
	SHLD	DISKADDR
RESET2	LXI	H,NSBUFF
	SHLD	NSADDR
	XRA	A
	STA	NSCNT
	STA	NSCNT+1
	RET
EOFNS	MVI	A,01
	STA	EOF
	JMP	RESET2

GETNS	PUSH	H		;GET ONE CHAR FROM NS BUFFER
	PUSH	D
	PUSH	B
	LHLD	NSADDR
	MOV	A,M
	STA	TEMP
	INX	H
	SHLD	NSADDR
	LHLD	NSCNT		;CHECK FOR BUFFER EMPTY
	INX	H
	SHLD	NSCNT
	MOV	A,L
	ORA	A
	JNZ	GETNS2
	LDA	TRUEDEN
	CPI	'S'
	JZ	GETNS3
	MOV	A,H		;CHECK FOR 2 BLOCKS IN DOUBLE DENSITY
	CPI	2
	JNZ	GETNS2
GETNS3	CZ	READNS
GETNS2	LDA	EOFIND
	CPI	'B'		;EOF BY BLOCK COUNT?
	JZ	GETNS1
	LDA	TEMP
	CPI	01
	JNZ	GETNS1
	STA	EOF
GETNS1	LDA	TEMP
	POP	B
	POP	D
	POP	H
	RET

WRITENS	EQU	$
	LDA	BLOCKS
	DCR	A
	JZ	EOFNS
	STA	BLOCKS		;BLOCK EOF IF FILE TOO BIG
	LHLD	DISKADDR
	LDA	DISK
	MOV	C,A
	MVI	A,1		;WRITE ONE BLOCK AT A TIME
	MVI	B,0		;WRITE OPERATION
	LXI	D,NSBUFF
	CALL	DCOM
	JNC	IOGOOD
	JMP	NSERR

PUTNS	PUSH	H		;PUT ONE CHAR INTO NS BUFFER
	PUSH	D
	PUSH	B
	STA	TEMP
	LHLD	NSADDR
	MOV	M,A
	INX	H
	SHLD	NSADDR
	LHLD	NSCNT		;CHECK BUFFER FULL
	INX	H
	SHLD	NSCNT
	MOV	A,L
	ORA	A
	JNZ	PUTNS1
	LDA	TRUEDEN
	CPI	'S'
	JZ	PUTNS2
	MOV	A,H
	CPI	2
	JNZ	PUTNS1
PUTNS2	CALL	WRITENS
PUTNS1	CALL	DISPLAY
	POP	B
	POP	D
	POP	H
	RET
CRLF	DB	0DH,0AH,'$'
DEST	DB	'DESTINATION SYSTEM (C/N)? $'
ERRM2	DB	'CPM IO ERROR$'
ERRM4	DB	'CPM FILE NAME ERROR$'
ERRM5	DB	'NORTH STAR FILE NAME ERROR$'
ERRM3	DB	'NORTH STAR IO ERROR$'
NOFILE	DB	'FILE NOT FOUND$'
SIGNONS	DB	0CH,'INTERDOS REL 2.0 SINGLE DENSITY AT E900$'
SIGNOND DB	0CH,'INTERDOS REL 2.O DOUBLE DENSITY AT E800$'
BOOTMSG	DB	'REBOOT NORTH STAR DOS (Y/N)? $'
SRCCPM	DB	'COPY FROM CP/M FILE TO NORTH STAR FILE$'
SRCNS	DB	'COPY FROM NORTH STAR FILE TO CP/M FILE$'
LINEA	DB	'CONVERSION FORMATS:$'
LINE0	DB	'  0 - NO CONVERSION$'
LINE1	DB	'  1 - SEC. TO ASM (NO #, TABS, CR+LF)$'
LINE2	DB	'  2 - SEC. TO ED  (NO #, CR+LF)$'
LINE3	DB	'  3 - SEC. TO CPM BASIC (CR+LF)$'
LINE4	DB	'  4 - NS BASIC TO CPM BASIC$'
LINE5	DB	'  5 - CPM HEX FILE TO NS TYPE 2$'
LINEB	DB	'WHICH CONVERESION FORMAT DO YOU WANT? $'
EOFMSG	DB	'EOF USING 01 OR BLOCK COUNT (1/B)? $'
VERMSG	DB	'VERIFY ON CONSOLE (Y/N)? $'
CPMFILE	DB	'CPM FILE NAME? $'
NSFILE	DB	'NORTH STAR FILE NAME? $'
MOUNT	DB	'MOUNT DISKETTES AND ENTER RETURN$'
ERRM1	DB	'INVALID OPTION AT THIS TIME$'
TODOS	DS	1
CNVRT	DS	1
EOFIND	DS	1
EOF	DS	1
VERIFY	DS	1
IBUF	DB	20
	DS	22
FCB	DS	9
TYPE	DS	3
	DS	25
FILE	DS	20
CPMCNT	DS	1
DISK	DS	1
DISKADDR	DS	2
NSCNT	DS	2
NSADDR	DS	2
CPMADDR	DS	2
BLOCKS	DS	1
TRUEDEN	DS	1		;TRUE DENSITY SINCE THERE MAY BE A
				;SINGLE DENSITY DISK ON A DOUBLE DENSITY
				;SYSTEM
TEMP	DS	1
LAST	DS	1
MPTY	DS	2
ABCD	DS	2
WXYZ	DS	2		;ABCD AND WXYZ WERE CHOSEN BECAUSE THE
				;USAGE OF TEMP AND TEMP2 IN BACTOBAC
				;CONFLICTED WITH USAGE IN THE REST OF THE
				;PROGRAM
STACK	DS	50
NSBUFF	DS	512
CPMBUFF	EQU	80H


* CONVERT NORTH STAR PACKED BASIC INTO ASCII BASIC FORMAT
* THIS CONVERTS THE BINARY LINE NUMBER TO ASCII AND CONVERTS
* THE TOKENS TO ASCII

BASTOBAS EQU	$
	CALL	RESET		;THIS CODE WAS TAKEN FROM THE NORTH STAR
	CALL	READNS		;VERSION OF SECRTARY WORD PROCESSOR
STRT1	CALL	GETNS	 ;SKIP CNT
	CPI	01
	JZ	CLOSE2
	CALL	GETNS	;GET LINE NUMBER
	MOV	C,A
	CALL	GETNS
	MOV	B,A
	CALL	ASCII	;LINE NO TO ASCII
LOAD1	CALL	GETNS
	CPI	13
	JZ	EOFLN
	CPI	09AH
	JZ	LNNO
	CPI	80
	JNC	DECOD
	CALL	PUTCPM		;PUT THE CHAR INTO CPM BUFFER
	JMP	LOAD1
LNNO	CALL	GETNS
	MOV	C,A
	CALL	GETNS
	MOV	B,A
	CALL	ASCII
	JMP	LOAD1
EOFLN	CALL	PUTCPM	;PUT OUT CR
	MVI	A,0AH
	CALL	PUTCPM	;PUT OUT LF
	JMP	STRT1
;CONVERT	BINARY	LINE	NO TO ASCII
ASCII	EQU	$
ASCI2	XRA	A
	STA	LAST
	MOV	H,B
	MOV	L,C
	SHLD	MPTY
	LXI	H,10000
	SHLD	ABCD
	CALL	DIVID
	LXI	H,1000
	SHLD	ABCD
	CALL	DIVID
	LXI	H,100
	SHLD	ABCD
	CALL	DIVID
	LXI	H,10
	SHLD	ABCD
	CALL	DIVID
	LDA	MPTY
	CALL	ASCX
	RET
DIVID	MVI	E,0
	LHLD	MPTY
	SHLD	WXYZ
SB2	LXI	B,WXYZ
	LXI	H,ABCD
	XRA	A
	LDAX	B
	SBB	M
	STAX	B
	INX	B
	INX	H
	LDAX	B
	SBB	M
	STAX	B
	JC	NEG
	INR	E
	PUSH	H
	LHLD	WXYZ
	SHLD	MPTY
	POP	H
	JMP	SB2
NEG	MOV	A,E
ASCX	ADI	'0'
	MOV	D,A
	LDA	LAST
	ORA	A
	JNZ	ZERO
	MOV	A,D
	CPI	'0'
	RZ
	STA	LAST
ZERO	MOV	A,D
	CALL	PUTCPM
	RET
;REPLACE	TOKEN	WITH	ASCII TEXT
DECOD	LXI	H,BTAB
	MOV	B,A
CODE1	MOV	A,M
	CPI	0FFH
	JZ	CODE6
	CPI	80H
	JNC	CODE2
CODE3	INX	H
	JMP	CODE1
CODE2	CMP	B
	JNZ	CODE3
	INX 	H
CODE4	MOV	A,M
	CPI	80H
	JNC	CODE5
	CALL	PUTCPM
	INX	H
	JMP	CODE4
CODE6	MOV	A,B
	CALL	PUTCPM
CODE5	JMP	LOAD1
BTAB	DB	80H
	DB	'LET'
	DB	81H
	DB	'FOR'
	DB	82H
	DB	'PRINT'
	DB	83H
	DB	'NEXT'
	DB	84H
	DB	'IF'
	DB	85H
	DB	'READ'
	DB	86H
	DB	'INPUT'
	DB	87H
	DB	'DATA'
	DB	88H
	DB	'GOTO'
	DB	89H
	DB	'GOSUB'
	DB	8AH
	DB	'RETURN'
	DB	8BH
	DB	'DIM'
	DB	8CH
	DB	'STOP'
	DB	8DH
	DB	'END'
	DB	8EH
	DB	'RESTORE'
	DB	8FH
	DB	'REM'
	DB	90H
	DB	'FN'
	DB	91H
	DB	'DEF'
	DB	92H
	DB	'!'
	DB	93H
	DB	'ON'
	DB	94H
	DB	'OUT'
	DB	95H
	DB	'FILL'
	DB	96H
	DB	'EXIT'
	DB	97H
	DB	'OPEN'
	DB	98H
	DB	'CLOSE'
	DB	99H
	DB	'WRITE'
	DB	9BH
	DB	'CHAIN'
	DB	9CH
	DB	'LINE'
	DB	9DH
	DB	'DESTROY'
	DB	9EH
	DB	'CREATE'
	DB	9FH
	DB	'ERRSET'
	DB	0A0H
	DB	'RUN'
	DB	0A1H
	DB	'LIST'
	DB	0A2H
	DB	'MEMSET'
	DB	0A3H
	DB	'SCR'
	DB	0A4H
	DB	'AUTO'
	DB	0A5H
	DB	'LOAD'
	DB	0A6H
	DB	'CONT'
	DB	0A7H
	DB	'APPEND'
	DB	0A8H
	DB	'REN'
	DB	0A9H
	DB	'NSAVE'
	DB	0AAH
	DB	'SAVE'
	DB	0ABH
	DB	'BYE'
	DB	0ACH
	DB	'EDIT'
	DB	0ADH
	DB	'DEL'
	DB	0AEH
	DB	'PSIZE'
	DB	0AFH
	DB	'CAT'
	DB	0B0H
	DB	'STEP'
	DB	0B1H
	DB	'TO'
	DB	0B2H
	DB	'THEN'
	DB	0B3H
	DB	'TAB'
	DB	0B4H
	DB	'ELSE'
	DB	0B5H
	DB	'CHR$'
	DB	0B6H
	DB	'ASC'
	DB	0B7H
	DB	'VAL'
	DB	0B8H
	DB	'STR$'
	DB	0B9H
	DB	'NOENDMARK'
	DB	0BAH
	DB	'INCHAR'
	DB	0BBH
	DB	'FILE'
	DB	0E0H
	DB	'('
	DB	0E0H
	DB	'['
	DB	0E2H
	DB	'*'
	DB	0E3H
	DB	'+'
	DB	0E5H
	DB	'-'
	DB	0E7H
	DB	'/'
	DB	0ECH
	DB	'AND'
	DB	0EDH
	DB	'OR'
	DB	0EFH
	DB	'>='
	DB	0F0H
	DB	'<='
	DB	0F1H
	DB	'<>'
	DB	0EFH
	DB	'>='
	DB	0F0H
	DB	'=<'
	DB	0F4H
	DB	'<'
	DB	0F5H
	DB	'='
	DB	0F6H
	DB	'>'
	DB	0F7H
	DB	'NOT'
	DB	0E1H
	DB	'^'
	DB	0C6H
	DB	'INT'
	DB	0CCH
	DB	'LEN'
	DB	0CDH
	DB	'CALL'
	DB	0CEH
	DB	'RND'
	DB	0CAH
	DB	'SGN'
	DB	0CBH
	DB	'SIN'
	DB	0C4H
	DB	'SQRT'
	DB	0D2H
	DB	'ATN'
	DB	0D8H
	DB	'FREE'
	DB	0D9H
	DB	'INP'
	DB	0DAH
	DB	'EXAM'
	DB	0DBH
	DB	'ABS'
	DB	0DCH
	DB	'COS'
	DB	0DDH
	DB	'LOG'
	DB	0DEH
	DB	'EXP'
	DB	0DFH
	DB	'TYP'
	DB	0FFH
	END	100H
