;
;	LIST FUNCTION FOR MITS BASIC DSAVE FILE
;		BASIC 3.2 VERSION
;		RLR REV 0.1 4/21/77
;
	ORG	100H
	JMP	START
	EXT	FNAME,XOPN,XNEW,GCHAR,PUTC,PRNT,XCLOS
	EXT	BINDF,NEGHL
	ROG
SFCB	EQU	5CH
CR	EQU	13
SPC	EQU	20H
XFCBL	EQU	164
	DS	32
STAK:	DS	0
EOLV:	DS	2
NUMBUF	DS	10
LIN1:	DB	0	;STATE OF ADR PTRS
LINADR:	DW	0	;START OF NEXT LINE
LINCNT:	DB	0	;COUNT OF LINE
BXFCB	DS	XFCBL	;BASIC SOURCE OUTPUT
IXFCB	DS	XFCBL	;BASIC INT. INPUT
CFCB	DB	255,2	;CONSOLE OUTPUT
;
;
START:	LXI	SP,STAK
	LXI	D,IXFCB
	LXI	H,SFCB
	MVI	A,'I'
	LXI	B,'NT'
	CALL	FNAME
	LXI	D,IXFCB
	CALL	XOPN	; OPEN(<NAME>.INT)
;
	LXI	D,BXFCB
	LXI	H,SFCB
	MVI	A,'B'
	LXI	B,'AS'
	CALL	FNAME
	LXI	D,BXFCB
	CALL	XNEW	;NEW(<NAME>.BAS)
;
	XRA	A
	STA	LIN1	;STATE:=LINE 1
;
NXTLIN:	CALL	GETCI
	MOV	L,A
	CALL	GETCI
	MOV	H,A
	SHLD	EOLV	; END OF LINE ADDR VALUE
;
	LHLD	LINADR
	LXI	B,4
	DAD	B
	SHLD	LINADR	; SKIP PTR(2), LINE NUM(2)
;
;	OUTPUT LINE NUMBER
;
LINUM:	LHLD	EOLV
	MOV	A,H
	ORA	L
	JZ	GDEND	; 0=GOOD END
;
	CALL	GETCI
	MOV	C,A
	CALL	GETCI
	MOV	B,A
	LXI	H,NUMBUF
	CALL	BINDF
	MVI	M,SPC	; SEPARATE # FROM TEXT
	INX	H
	MVI	M,0	; TERMINATE STRING
	LXI	H,NUMBUF
	CALL	PUTLB	; DO IT
;
;	DO A CHAR OF INT. CODE
NXTCHR:	CALL	GETCI
	ORA	A
	JM	WORD
	JZ	EOLIN
;
;	NORMAL CHAR / OUTPUT
	CALL	PUTCB
	JMP	FINCHR
;			FIND WORD / OUTPUT
WORD:	ANI	7FH
	MOV	C,A
	MVI	B,0
	LXI	H,TADR
	DAD	B
	DAD	B	; HL^=A(WORD)
	MOV	E,M
	INX	H
	MOV	D,M
	XCHG		; HL=WORD
	CALL	PUTLB	; PRINT IT (TERMINATED BY NUL)
;
FINCHR:	LHLD	LINADR
	INX	H
	SHLD	LINADR
	JMP	NXTCHR
;
;	END OF LINE
;
EOLIN:	CALL	PUTCR	; CR/LF AT END
	LDA	LIN1
	ORA	A
	LXI	D,0
	LHLD	EOLV
	JZ	EOLN1	;	IF LINE>1 THEN TEST END
	XCHG
	LHLD	LINADR
	INX	H
	CALL	NEGHL
	DAD	D
	XCHG		; DE=EOLV-(LINADR+1) (SHOULD =0)
;
EOLN1:	SHLD	LINADR	; POINT TO NEXT LINE (EOLV)
	MVI	A,1
	STA	LIN1	; STATE:=LINE N
;
	MOV	A,D
	ORA	E
	JZ	NXTLIN	; IF EOLV=LINADR+1 THEN OK
;
;	BAD ENDING
;
BADEND:	CALL	PUTCR	; TERMATE WHAT'S THERE
	LXI	H,BADM
	JMP	THEND
;
GDEND:	LXI	H,GODM
;
THEND:	LXI	D,CFCB
	CALL	PRNT
;
	LXI	D,BXFCB
	CALL	XCLOS		; CLOSE(LIST FILE)
	JMP	0	; DONE - GO BYEBYE
;
;	UTILITIES
;
;		RETURNS CHAR =A
GETCI:	PUSH	D
	LXI	D,IXFCB
	CALL	GCHAR
	POP	D
	RNZ
	POP	H
	JMP	BADEND		; END OF FILE (FOR REAL)
;
;		OUTPUT CHAR FROM A
PUTCB:	PUSH	D
	PUSH	B
	MOV	C,A
	LXI	D,BXFCB
	CALL	PUTC
	POP	B
	POP	D
	RET
;
;	PUT A LINE OUT 
;
PUTCR:	LXI	H,CRLIN	; CR/LF ONLY
;
PUTLB:	LXI	D,BXFCB
	JMP	PRNT
;
CRLIN:	DB	CR
BADM:	DB	' BAD ENDING',CR
GODM:	DB	' LIST DONE',CR
;
;	WORD ADDRESS TABLE
;
TADR:	DW	W00,W01,W02,W03,W04,W05,W06,W07
	DW	W08,W09,W0A,W0B,W0C,W0D,W0E,W0F
	DW	W10,W11,W12,W13,W14,W15,W16,W17
	DW	W18,W19,W1A,W1B,W1C,W1D,W1E,W1F
	DW	W20,W21,W22,W23,W24,W25,W26,W27
	DW	W28,W29,W2A,W2B,W2C,W2D,W2E,W2F
	DW	W30,W31,W32,W33,W34,W35,W36,W37
	DW	W38,W39,W3A,W3B,W3C,W3D,W3E,W3F
	DW	W40,W41,W42,W43,W44,W45
;
;	WORD	TABLE
;
W00:	DB	'END',0
W01:	DB	'FOR',0
W02:	DB	'NEXT',0
W03:	DB	'DATA',0
W04:	DB	'INPUT',0
W05:	DB	'DIM',0
W06:	DB	'READ',0
W07:	DB	'LET',0
;
W08:	DB	'GOTO',0
W09:	DB	'RUN',0
W0A:	DB	'IF',0
W0B:	DB	'RESTORE',0
W0C:	DB	'GOSUB',0
W0D:	DB	'RETURN',0
W0E:	DB	'REM',0
W0F:	DB	'STOP',0
;
W10:	DB	'OUT',0
W11:	DB	'ON',0
W12:	DB	'NULL',0
W13:	DB	'WAIT',0
W14:	DB	'DEF',0
W15:	DB	'POKE',0
W16:	DB	'PRINT',0
W17:	DB	'CONT',0
;
W18:	DB	'LIST',0
W19:	DB	'CLEAR',0
W1A:	DB	'DLOAD',0
W1B:	DB	'DSAVE',0
W1C:	DB	'NEW',0
W1D:	DB	'TAB',0
W1E:	DB	'TO',0
W1F:	DB	'FN',0
;
W20:	DB	'SPC',0
W21:	DB	'THEN',0
W22:	DB	'NOT',0
W23:	DB	'STEP',0
W24:	DB	'+',0
W25:	DB	'-',0
W26:	DB	'*',0
W27:	DB	'/',0
;
W28:	DB	'^',0
W29:	DB	'AND',0
W2A:	DB	'OR',0
W2B:	DB	'>',0
W2C:	DB	'=',0
W2D:	DB	'<',0
W2E:	DB	'SGN',0
W2F:	DB	'INT',0
;
W30:	DB	'ABS',0
W31:	DB	'USR',0
W32:	DB	'FRE',0
W33:	DB	'INP',0
W34:	DB	'POS',0
W35:	DB	'SQR',0
W36:	DB	'RND',0
W37:	DB	'LOG',0
;
W38:	DB	'EXP',0
W39:	DB	'COS',0
W3A:	DB	'SIN',0
W3B:	DB	'TAN',0
W3C:	DB	'ATN',0
W3D:	DB	'PEEK',0
W3E:	DB	'LEN',0
W3F:	DB	'STR$',0
;
W40:	DB	'VAL',0
W41:	DB	'ASC',0
W42:	DB	'CHR$',0
W43:	DB	'LEFT$',0
W44:	DB	'RIGHT$',0
W45:	DB	'MID$',0
