;
;
;  OPCODE TABLE AND OPERAND EVALUATION ROUTINES
;
; BYTE 0, BASE OPCODE VALUE: BITS 7-3 RIGHT SHIFTED 1 BIT (BIT2 ALWAYS 0)
; BYTE 1, CODE IDENTIFYING VALID OPERAND MODES
;
;  0 -- NO OPERAND ALLOWED
;  1 -- RELATIVE ADDRESSING
;  2 -- XIND, ZP, IMM, ABS, INDY, ZPIND, ZPX, ABSY, ABSX
;  3 -- ZP, IMM, ABS
;  4 -- ZP, ACC, ABS, ZPX, ABSX
;  5 -- XIND, ZP, ABS, INDY, ZPIND, ZPX, ABSY, ABSX
;  6 -- ZP, ABS, ZPYSP
;  7 -- ZP, ABS, ZPX, ABSX (DEC, INC)
;  8 -- ZP, ABS, ZPX
;  9 -- ZP, ABS (BIT)
; 10 -- ABS, ABSIND (JMP)
; 11 -- (JSR)
; 12 -- ZP, IMM, ABS, ZPYSP, ABSYSP
; 13 -- ZP, IMM, ABS, ZPX, ABSX
;
;  DEFINE MODES
;
XIND	=	$00
ZP	=	$04
ACC	=	$08
IMM	=	$08
ABS	=	$0C
INDY	=	$10
ZPIND	=	$11
ZPX	=	$14
ABSY	=	$18
ABSX	=	$1C
;
OPS	DB	$B1,$02,'ADC'
	DB	$91,$02,'AND'
	DB	$82,$04,'ASL'
	DB	$C8,$01,'BCC'
	DB	$D8,$01,'BCS'
	DB	$F8,$01,'BEQ'
	DB	$90,$09,'BIT'
	DB	$98,$01,'BMI'
	DB	$E8,$01,'BNE'
	DB	$88,$01,'BPL'
	DB	$C0,$01,'BRA'
	DB	$80,$00,'BRK'
	DB	$A8,$01,'BVC'
	DB	$B8,$01,'BVS'
	DB	$8C,$00,'CLC'
	DB	$EC,$00,'CLD'
	DB	$AC,$00,'CLI'
	DB	$DC,$00,'CLV'
	DB	$E1,$02,'CMP'
	DB	$F0,$03,'CPX'
	DB	$E0,$03,'CPY'
	DB	$FF,$49,'DB'
	DB	$FF,$4A,'DC'
	DB	$E2,$07,'DEC'
	DB	$E6,$00,'DEX'
	DB	$C4,$00,'DEY'
	DB	$FF,$43,'DS'
	DB	$FF,$48,'DW'
	DB	$FF,$42,'END'
	DB	$A1,$02,'EOR'
EQCODE	DB	$FF,$41,'EQU'
	DB	$FF,$45,'INCLUDE'
	DB	$F2,$07,'INC'
	DB	$F4,$00,'INX'
	DB	$E4,$00,'INY'
	DB	$A0,$0A,'JMP'
	DB	$8C,$0B,'JSR'	;VERY FUNNY OPCODE (ABNORMAL)
	DB	$D1,$02,'LDA'
	DB	$D2,$0C,'LDX'
	DB	$D0,$0D,'LDY'
	DB	$FF,$44,'LIST'
	DB	$A2,$04,'LSR'
	DB	$FF,$4C,'MACRO'
	DB	$FF,$4D,'MEND'
	DB	$F6,$00,'NOP'
	DB	$81,$02,'ORA'
	DB	$FF,$40,'ORG'
	DB	$FF,$4B,'PAGE'
	DB	$A4,$00,'PHA'
	DB	$84,$00,'PHP'
	DB	$B4,$00,'PLA'
	DB	$94,$00,'PLP'
	DB	$92,$04,'ROL'
	DB	$B2,$04,'ROR'
	DB	$A0,$00,'RTI'
	DB	$B0,$00,'RTS'
	DB	$F1,$02,'SBC'
	DB	$9C,$00,'SEC'
	DB	$FC,$00,'SED'
	DB	$BC,$00,'SEI'
	DB	$C1,$05,'STA'
	DB	$C2,$06,'STX'
	DB	$C0,$08,'STY'
	DB	$FF,$47,'SUBTTL'
	DB	$D6,$00,'TAX'
	DB	$D4,$00,'TAY'
	DB	$FF,$46,'TITLE'
	DB	$DE,$00,'TSX'
	DB	$C6,$00,'TXA'
	DB	$CE,$00,'TXS'
	DB	$CC,$00,'TYA'
ENDOPS	DB	$FF,$FF
;
NOTHG	LDA	LABEL
	BNE	LABONL
COMMNT	LDA	#$80
	STA	ISVAL
LABONL	CLC
	RTS
;
GENCODE	LDY	#0
	JSR	GETSYM		;LABEL?
	LDA	SYMBOL
	BEQ	NOLBL		;NO DO OPCODE THEN
	LDX	#SYMSIZ+1
SAVLAB	LDA	SYMBOL-1,X
	STA	LABEL-1,X
	DEX
	BNE	SAVLAB
;
NOLBL	JSR	NXTFLD		;NEXT, SKIP OVER TO OPCODE
	LDA	#0
	STA	ISVAL
	STA	MODE
	STA	LEN
	STA	LEN+1
	LDA	#' '
	STA	ADRERR
	JSR	NXTFLD
	CMP	#';'		;COMMENT?
	BEQ	NOTHG
	TAX
	BMI	NOTHG
	CMP	#'='
	BNE	NOTEQ
	LDA	#LOW[EQCODE]
	STA	TABPTR
	LDA	#HIGH[EQCODE]
	STA	TABPTR+1
	INY
	JSR	NXTFLD
	STY	TXTPTR
	JMP	SPCLOP
;
NOTEQ	JSR	GETSYM
	JSR	NXTFLD
	STY	TXTPTR
;
	LDA	#LOW[OPS-1]
	STA	TABPTR
	LDA	#HIGH[OPS-1]
	STA	TABPTR+1
	LDY	#0
FINDOP	INY
	LDA	(TABPTR),Y
	BPL	FINDOP
	CLC
	TYA
	ADC	TABPTR
	STA	TABPTR
	LDA	#0
	ADC	TABPTR+1
	STA	TABPTR+1
	LDY	#1
	LDA	(TABPTR),Y
	BMI	NOTOPC		;IF NO MATCH IN THE TABLE
	LDX	#$FF
;
OPCPL	INY
	INX
	LDA	SYMBOL,X
	BEQ	TSTEM		;END OF SYMBOL, END OF TABENT?
	CMP	#$7B
	BCS	DOCOMP
	CMP	#$61
	BCC	DOCOMP
	SBC	#$20
DOCOMP	CMP	(TABPTR),Y
	BNE	FINDOP
	BEQ	OPCPL
;
NOTOPC	LDA	#'O'
	STA	ADRERR
	LDA	#$EA		;3 NOP INSTRUCTIONS
	STA	OPCODE
	STA	VALUE
	STA	VALUE+1
	LDA	#3
	STA	LEN
	LDY	#0		;CC=ZERO, PLUS (ERROR)
	RTS
;
TSTEM	LDA	(TABPTR),Y
	BPL	FINDOP		;NOT END OF TABLE ENTRY, NO MATCH
;
SPCLOP	LDY	#0
	LDA	(TABPTR),Y
	STA	OPCODE
	INY
	INC	LEN
	LDA	(TABPTR),Y
	BEQ	OPNDOK
	LDY	TXTPTR
	CMP	#$40
	BCC	MACHCD		;IF 6502 INSTRUCTION
	JMP	ASSDIR
;
MACHCD	JSR	RDOPND
	STY	TXTPTR
	BCC	OPNDOK
	LDA	#'E'
	STA	ADRERR
OPNDOK	LDA	OPCODE
	AND	#$FC
	CLC
	ADC	OPCODE
	CLC
	ADC	MODE
	STA	OPCODE
	JMP	CODOBJ
;
;  ESTABLISH MODE FROM SYNTAX OF OPERAND
;
RELJMP	JSR	EVALAB		;EVALUATE ADDRESS
	CLC
	LDA	VALUE
	SBC	PC
	STA	VALUE
	BNE	GRELV
	DEC	VALUE+1
GRELV	LDA	VALUE+1
	SBC	PC+1
	STA	VALUE+1
	DEC	VALUE
;
	LDA	VALUE
	ASL	A
	LDA	VALUE+1
	ADC	#0
	BEQ	RRELV
	LDA	#' '
	CMP	ADRERR
	BCC	RRELV
	LDA	#'V'
	STA	ADRERR
RRELV	CLC
	RTS
;
JMPGRP	LDA	(TEXTP),Y
	CMP	#'('
	BNE	JABS
	LDA	#$2C	;MODE OFFSET = 2C
	STA	MODE
	INY
	JSR	EVALAB
	DEY
	LDA	(TEXTP),Y
	CMP	#')'
	BNE	SMERR
	JMP	SMXIT
;
JABS	JSR	EVALAB
	JMP	SMABS
;
ACCREF	LDA	#1
	STA	LEN
	BNE	ACCJ
;
JSUB	JSR	EVALAB
ACCJ	LDA	#ACC
	JMP	SMRET
;
ABSOPD	JMP	ZPOPNOK
;
RDOPND	INC	LEN
	CMP	#1		;IF RELATIVE BRANCH, SPECIAL
	BEQ	RELJMP
	INC	LEN
	CMP	#$0A		;IF JUMP, ONLY ABS AND ABSIND ARE ALLOWED
	BEQ	JMPGRP
	CMP	#$0B
	BEQ	JSUB
	TAX			;SAVE FOR FUTURE REF.
	STA	MODE
	LDA	(TEXTP),Y
	CPX	#$04		;ACC OPERAND ALLOWED?
	BNE	NOACC		;NO, THEN "A" IS NOT SPECIAL
	CMP	#'a'
	BEQ	ISACC
	CMP	#'A'
	BNE	NOACC
ISACC	INY
	LDA	(TEXTP),Y
	CMP	#'0'
	BCC	ACCREF
	CMP	#'z'+1
	BCS	ACCREF
	DEY
	BCC	GOTACH
NOACC	CMP	#'#'
	BEQ	SMIMM
	CMP	#'('
	BEQ	SMIND
GOTACH	JSR	EVALAB		;EVALUATE ABSOLUTE OPERAND
	DEY
	LDA	FWDREF		;FORWARD REFERENCES ARE ALWAYS 16-BIT
	ORA	VALUE+1
	BNE	ABS16
	LDA	ADRERR
	CMP	#' '
	BEQ	ABSOPD
ABS16	LDA	(TEXTP),Y
	CMP	#','
	BNE	SMABS
	JSR	NEXTCHR		;GET NEXT CHAR (INY) AND FORCE UPPER CASE
	CMP	#'Y'
	BEQ	SMAY
	CMP	#'X'
	BEQ	SMAX
SMERR	SEC			;ELSE, ERROR
	RTS
;
SMIND	DEC	LEN
	INY
	JSR	EVALAB
	LDA	VALUE+1
	BNE	SMERR
	DEY
	LDA	(TEXTP),Y
	CMP	#','
	BEQ	SMINX
	CMP	#')'
	BNE	SMERR
	INY
	LDA	(TEXTP),Y
	CMP	#','
	BNE	SZI
	JSR	NEXTCHR		;GET NEXT CHAR (INY) AND FORCE UPPER CASE
	CMP	#'Y'
	BNE	SMERR
	LDA	#INDY
	DB	$2C		;BIT [ADDR16] (SKIP 2 BYTES)
;
SMABS	LDA	#ABS
	DB	$2C		;BIT [ADDR16] (SKIP 2 BYTES)
;
SMAX	LDA	#ABSX
	JMP	SMRET
;
SMZPY	CMP	#'Y'
TSMERR	BNE	SMERR
	LDX	MODE
	CPX	#$03
	BEQ	ZPYSP
	CPX	#$0C
	BEQ	ZPYSP
	CPX	#$06
	BEQ	ZPYSP
;
SMAY	LDA	#3
	STA	LEN
	LDX	MODE
	CPX	#$0C
	BEQ	SMAX
	LDA	#ABSY
	BNE	SMRET
;
SMIMM	DEC	LEN
	INY
	JSR	EVALAB
	LDA	VALUE+1
	BEQ	SMIMOK
	LDA	VALUE
	BPL	SMIMBD
	INC	VALUE+1
	BEQ	SMIMOK
SMIMBD	LDA	#' '
	CMP	ADRERR
	BCC	SMIMOK
	LDA	#'V'
	STA	ADRERR
SMIMOK	LDX	MODE
	CPX	#$03
	BEQ	XYIMM
	CPX	#$06
	BEQ	XYIMM
	CPX	#$08
	BEQ	XYIMM
	CPX	#$0C
	BEQ	XYIMM
	CPX	#$0D
	BEQ	XYIMM
	LDA	#IMM
	BNE	SMRET
;
SMINX	JSR	NEXTCHR		;GET NEXT CHAR (INY) AND FORCE UPPER CASE
	CMP	#'X'
	BNE	TSMERR
	INY
	LDA	(TEXTP),Y
	CMP	#')'
	BNE	TSMERR
XYIMM	LDA	#XIND
SMRET	STA	MODE
SMXIT	CLC
	RTS
;
SZI	LDA	#ZPIND
	BNE	SMRET
;
ZPYSP	LDA	#ZPX
	BNE	SMRET
;
SMZP	LDA	#ZP
	BNE	SMRET
;
ZPOPNOK	DEC	LEN
	LDA	(TEXTP),Y
	CMP	#','
	BNE	SMZP
	JSR	NEXTCHR		;GET NEXT CHAR (INY) AND FORCE UPPER CASE
	CMP	#'X'
	BEQ	ZPYSP
	JMP	SMZPY
;
NEXTCHR	INY
	LDA	(TEXTP),Y
	CMP	#$7B
	BCS	CHROK
	CMP	#$61
	BCC	CHROK
	SBC	#$20
CHROK	RTS
