mirror of
				https://github.com/sethm/symon.git
				synced 2025-10-31 04:16:07 +00:00 
			
		
		
		
	This is something of a "Work in Progress" checkpoint of several features that are all half baked: 1. Allow loading of 16KB ROM files at address $C000 at run-time, not just at startup. See the "Load ROM..." File menu item. 2. Introduces the notion of "CPU Behaviors", so the core 6502 CPU implementation can match the behavior of either an early NMOS 6502, late NMOS 6502, or CMOS 65C02. Very little of this is actually implemented so far. 3. Adds a completely bogus implementation of the 6522 VIA (it does absolutely nothing right now). 4. Changes the address of the ACIA in the simulated system to match a real hardware implementation I put together.
		
			
				
	
	
		
			8692 lines
		
	
	
		
			244 KiB
		
	
	
	
		
			NASM
		
	
	
	
	
	
			
		
		
	
	
			8692 lines
		
	
	
		
			244 KiB
		
	
	
	
		
			NASM
		
	
	
	
	
	
| 
 | |
| ; Enhanced BASIC to assemble under 6502 simulator, $ver 2.22
 | |
| 
 | |
| ; $E7E1 $E7CF $E7C6 $E7D3 $E7D1 $E7D5 $E7CF $E81E $E825
 | |
| 
 | |
| ; 2.00	new revision numbers start here
 | |
| ; 2.01	fixed LCASE$() and UCASE$()
 | |
| ; 2.02	new get value routine done
 | |
| ; 2.03	changed RND() to galoise method
 | |
| ; 2.04	fixed SPC()
 | |
| ; 2.05	new get value routine fixed
 | |
| ; 2.06	changed USR() code
 | |
| ; 2.07	fixed STR$()
 | |
| ; 2.08	changed INPUT and READ to remove need for $00 start to input buffer
 | |
| ; 2.09	fixed RND()
 | |
| ; 2.10	integrated missed changes from an earlier version
 | |
| ; 2.20	added ELSE to IF .. THEN and fixed IF .. GOTO <statement> to cause error
 | |
| ; 2.21	fixed IF .. THEN RETURN to not cause error
 | |
| ; 2.22	fixed RND() breaking the get byte routine
 | |
| 
 | |
| ; zero page use ..
 | |
| 
 | |
| LAB_WARM 		= $00		; BASIC warm start entry point
 | |
| Wrmjpl 		= LAB_WARM+1; BASIC warm start vector jump low byte
 | |
| Wrmjph 		= LAB_WARM+2; BASIC warm start vector jump high byte
 | |
| 
 | |
| Usrjmp		= $0A		; USR function JMP address
 | |
| Usrjpl		= Usrjmp+1	; USR function JMP vector low byte
 | |
| Usrjph		= Usrjmp+2	; USR function JMP vector high byte
 | |
| Nullct		= $0D		; nulls output after each line
 | |
| TPos			= $0E		; BASIC terminal position byte
 | |
| TWidth		= $0F		; BASIC terminal width byte
 | |
| Iclim			= $10		; input column limit
 | |
| Itempl		= $11		; temporary integer low byte
 | |
| Itemph		= Itempl+1	; temporary integer high byte
 | |
| 
 | |
| nums_1		= Itempl	; number to bin/hex string convert MSB
 | |
| nums_2		= nums_1+1	; number to bin/hex string convert
 | |
| nums_3		= nums_1+2	; number to bin/hex string convert LSB
 | |
| 
 | |
| Srchc			= $5B		; search character
 | |
| Temp3			= Srchc	; temp byte used in number routines
 | |
| Scnquo		= $5C		; scan-between-quotes flag
 | |
| Asrch			= Scnquo	; alt search character
 | |
| 
 | |
| XOAw_l		= Srchc	; eXclusive OR, OR and AND word low byte
 | |
| XOAw_h		= Scnquo	; eXclusive OR, OR and AND word high byte
 | |
| 
 | |
| Ibptr			= $5D		; input buffer pointer
 | |
| Dimcnt		= Ibptr	; # of dimensions
 | |
| Tindx			= Ibptr	; token index
 | |
| 
 | |
| Defdim		= $5E		; default DIM flag
 | |
| Dtypef		= $5F		; data type flag, $FF=string, $00=numeric
 | |
| Oquote		= $60		; open quote flag (b7) (Flag: DATA scan; LIST quote; memory)
 | |
| Gclctd		= $60		; garbage collected flag
 | |
| Sufnxf		= $61		; subscript/FNX flag, 1xxx xxx = FN(0xxx xxx)
 | |
| Imode			= $62		; input mode flag, $00=INPUT, $80=READ
 | |
| 
 | |
| Cflag			= $63		; comparison evaluation flag
 | |
| 
 | |
| TabSiz		= $64		; TAB step size (was input flag)
 | |
| 
 | |
| next_s		= $65		; next descriptor stack address
 | |
| 
 | |
| 					; these two bytes form a word pointer to the item
 | |
| 					; currently on top of the descriptor stack
 | |
| last_sl		= $66		; last descriptor stack address low byte
 | |
| last_sh		= $67		; last descriptor stack address high byte (always $00)
 | |
| 
 | |
| des_sk		= $68		; descriptor stack start address (temp strings)
 | |
| 
 | |
| ;			= $70		; End of descriptor stack
 | |
| 
 | |
| ut1_pl		= $71		; utility pointer 1 low byte
 | |
| ut1_ph		= ut1_pl+1	; utility pointer 1 high byte
 | |
| ut2_pl		= $73		; utility pointer 2 low byte
 | |
| ut2_ph		= ut2_pl+1	; utility pointer 2 high byte
 | |
| 
 | |
| Temp_2		= ut1_pl	; temp byte for block move	
 | |
| 
 | |
| FACt_1		= $75		; FAC temp mantissa1
 | |
| FACt_2		= FACt_1+1	; FAC temp mantissa2
 | |
| FACt_3		= FACt_2+1	; FAC temp mantissa3
 | |
| 
 | |
| dims_l		= FACt_2	; array dimension size low byte
 | |
| dims_h		= FACt_3	; array dimension size high byte
 | |
| 
 | |
| TempB			= $78		; temp page 0 byte
 | |
| 
 | |
| Smeml			= $79		; start of mem low byte		(Start-of-Basic)
 | |
| Smemh			= Smeml+1	; start of mem high byte	(Start-of-Basic)
 | |
| Svarl			= $7B		; start of vars low byte	(Start-of-Variables)
 | |
| Svarh			= Svarl+1	; start of vars high byte	(Start-of-Variables)
 | |
| Sarryl		= $7D		; var mem end low byte		(Start-of-Arrays)
 | |
| Sarryh		= Sarryl+1	; var mem end high byte		(Start-of-Arrays)
 | |
| Earryl		= $7F		; array mem end low byte	(End-of-Arrays)
 | |
| Earryh		= Earryl+1	; array mem end high byte	(End-of-Arrays)
 | |
| Sstorl		= $81		; string storage low byte	(String storage (moving down))
 | |
| Sstorh		= Sstorl+1	; string storage high byte	(String storage (moving down))
 | |
| Sutill		= $83		; string utility ptr low byte
 | |
| Sutilh		= Sutill+1	; string utility ptr high byte
 | |
| Ememl			= $85		; end of mem low byte		(Limit-of-memory)
 | |
| Ememh			= Ememl+1	; end of mem high byte		(Limit-of-memory)
 | |
| Clinel		= $87		; current line low byte		(Basic line number)
 | |
| Clineh		= Clinel+1	; current line high byte	(Basic line number)
 | |
| Blinel		= $89		; break line low byte		(Previous Basic line number)
 | |
| Blineh		= Blinel+1	; break line high byte		(Previous Basic line number)
 | |
| 
 | |
| Cpntrl		= $8B		; continue pointer low byte
 | |
| Cpntrh		= Cpntrl+1	; continue pointer high byte
 | |
| 
 | |
| Dlinel		= $8D		; current DATA line low byte
 | |
| Dlineh		= Dlinel+1	; current DATA line high byte
 | |
| 
 | |
| Dptrl			= $8F		; DATA pointer low byte
 | |
| Dptrh			= Dptrl+1	; DATA pointer high byte
 | |
| 
 | |
| Rdptrl		= $91		; read pointer low byte
 | |
| Rdptrh		= Rdptrl+1	; read pointer high byte
 | |
| 
 | |
| Varnm1		= $93		; current var name 1st byte
 | |
| Varnm2		= Varnm1+1	; current var name 2nd byte
 | |
| 
 | |
| Cvaral		= $95		; current var address low byte
 | |
| Cvarah		= Cvaral+1	; current var address high byte
 | |
| 
 | |
| Frnxtl		= $97		; var pointer for FOR/NEXT low byte
 | |
| Frnxth		= Frnxtl+1	; var pointer for FOR/NEXT high byte
 | |
| 
 | |
| Tidx1			= Frnxtl	; temp line index
 | |
| 
 | |
| Lvarpl		= Frnxtl	; let var pointer low byte
 | |
| Lvarph		= Frnxth	; let var pointer high byte
 | |
| 
 | |
| prstk			= $99		; precedence stacked flag
 | |
| 
 | |
| comp_f		= $9B		; compare function flag, bits 0,1 and 2 used
 | |
| 					; bit 2 set if >
 | |
| 					; bit 1 set if =
 | |
| 					; bit 0 set if <
 | |
| 
 | |
| func_l		= $9C		; function pointer low byte
 | |
| func_h		= func_l+1	; function pointer high byte
 | |
| 
 | |
| garb_l		= func_l	; garbage collection working pointer low byte
 | |
| garb_h		= func_h	; garbage collection working pointer high byte
 | |
| 
 | |
| des_2l		= $9E		; string descriptor_2 pointer low byte
 | |
| des_2h		= des_2l+1	; string descriptor_2 pointer high byte
 | |
| 
 | |
| g_step		= $A0		; garbage collect step size
 | |
| 
 | |
| Fnxjmp		= $A1		; jump vector for functions
 | |
| Fnxjpl		= Fnxjmp+1	; functions jump vector low byte
 | |
| Fnxjph		= Fnxjmp+2	; functions jump vector high byte
 | |
| 
 | |
| g_indx		= Fnxjpl	; garbage collect temp index
 | |
| 
 | |
| FAC2_r		= $A3		; FAC2 rounding byte
 | |
| 
 | |
| Adatal		= $A4		; array data pointer low byte
 | |
| Adatah		= Adatal+1	; array data pointer high  byte
 | |
| 
 | |
| Nbendl		= Adatal	; new block end pointer low byte
 | |
| Nbendh		= Adatah	; new block end pointer high  byte
 | |
| 
 | |
| Obendl		= $A6		; old block end pointer low byte
 | |
| Obendh		= Obendl+1	; old block end pointer high  byte
 | |
| 
 | |
| numexp		= $A8		; string to float number exponent count
 | |
| expcnt		= $A9		; string to float exponent count
 | |
| 
 | |
| numbit		= numexp	; bit count for array element calculations
 | |
| 
 | |
| numdpf		= $AA		; string to float decimal point flag
 | |
| expneg		= $AB		; string to float eval exponent -ve flag
 | |
| 
 | |
| Astrtl		= numdpf	; array start pointer low byte
 | |
| Astrth		= expneg	; array start pointer high  byte
 | |
| 
 | |
| Histrl		= numdpf	; highest string low byte
 | |
| Histrh		= expneg	; highest string high  byte
 | |
| 
 | |
| Baslnl		= numdpf	; BASIC search line pointer low byte
 | |
| Baslnh		= expneg	; BASIC search line pointer high  byte
 | |
| 
 | |
| Fvar_l		= numdpf	; find/found variable pointer low byte
 | |
| Fvar_h		= expneg	; find/found variable pointer high  byte
 | |
| 
 | |
| Ostrtl		= numdpf	; old block start pointer low byte
 | |
| Ostrth		= expneg	; old block start pointer high  byte
 | |
| 
 | |
| Vrschl		= numdpf	; variable search pointer low byte
 | |
| Vrschh		= expneg	; variable search pointer high  byte
 | |
| 
 | |
| FAC1_e		= $AC		; FAC1 exponent
 | |
| FAC1_1		= FAC1_e+1	; FAC1 mantissa1
 | |
| FAC1_2		= FAC1_e+2	; FAC1 mantissa2
 | |
| FAC1_3		= FAC1_e+3	; FAC1 mantissa3
 | |
| FAC1_s		= FAC1_e+4	; FAC1 sign (b7)
 | |
| 
 | |
| str_ln		= FAC1_e	; string length
 | |
| str_pl		= FAC1_1	; string pointer low byte
 | |
| str_ph		= FAC1_2	; string pointer high byte
 | |
| 
 | |
| des_pl		= FAC1_2	; string descriptor pointer low byte
 | |
| des_ph		= FAC1_3	; string descriptor pointer high byte
 | |
| 
 | |
| mids_l		= FAC1_3	; MID$ string temp length byte
 | |
| 
 | |
| negnum		= $B1		; string to float eval -ve flag
 | |
| numcon		= $B1		; series evaluation constant count
 | |
| 
 | |
| FAC1_o		= $B2		; FAC1 overflow byte
 | |
| 
 | |
| FAC2_e		= $B3		; FAC2 exponent
 | |
| FAC2_1		= FAC2_e+1	; FAC2 mantissa1
 | |
| FAC2_2		= FAC2_e+2	; FAC2 mantissa2
 | |
| FAC2_3		= FAC2_e+3	; FAC2 mantissa3
 | |
| FAC2_s		= FAC2_e+4	; FAC2 sign (b7)
 | |
| 
 | |
| FAC_sc		= $B8		; FAC sign comparison, Acc#1 vs #2
 | |
| FAC1_r		= $B9		; FAC1 rounding byte
 | |
| 
 | |
| ssptr_l		= FAC_sc	; string start pointer low byte
 | |
| ssptr_h		= FAC1_r	; string start pointer high byte
 | |
| 
 | |
| sdescr		= FAC_sc	; string descriptor pointer
 | |
| 
 | |
| csidx			= $BA		; line crunch save index
 | |
| Asptl			= csidx	; array size/pointer low byte
 | |
| Aspth			= $BB		; array size/pointer high byte
 | |
| 
 | |
| Btmpl			= Asptl	; BASIC pointer temp low byte
 | |
| Btmph			= Aspth	; BASIC pointer temp low byte
 | |
| 
 | |
| Cptrl			= Asptl	; BASIC pointer temp low byte
 | |
| Cptrh			= Aspth	; BASIC pointer temp low byte
 | |
| 
 | |
| Sendl			= Asptl	; BASIC pointer temp low byte
 | |
| Sendh			= Aspth	; BASIC pointer temp low byte
 | |
| 
 | |
| LAB_IGBY		= $BC		; get next BASIC byte subroutine
 | |
| 
 | |
| LAB_GBYT		= $C2		; get current BASIC byte subroutine
 | |
| Bpntrl		= $C3		; BASIC execute (get byte) pointer low byte
 | |
| Bpntrh		= Bpntrl+1	; BASIC execute (get byte) pointer high byte
 | |
| 
 | |
| ;			= $D7		; end of get BASIC char subroutine
 | |
| 
 | |
| Rbyte4		= $D8		; extra PRNG byte
 | |
| Rbyte1		= Rbyte4+1	; most significant PRNG byte
 | |
| Rbyte2		= Rbyte4+2	; middle PRNG byte
 | |
| Rbyte3		= Rbyte4+3	; least significant PRNG byte
 | |
| 
 | |
| NmiBase		= $DC		; NMI handler enabled/setup/triggered flags
 | |
| 					; bit	function
 | |
| 					; ===	========
 | |
| 					; 7	interrupt enabled
 | |
| 					; 6	interrupt setup
 | |
| 					; 5	interrupt happened
 | |
| ;			= $DD		; NMI handler addr low byte
 | |
| ;			= $DE		; NMI handler addr high byte
 | |
| IrqBase		= $DF		; IRQ handler enabled/setup/triggered flags
 | |
| ;			= $E0		; IRQ handler addr low byte
 | |
| ;			= $E1		; IRQ handler addr high byte
 | |
| 
 | |
| ;			= $DE		; unused
 | |
| ;			= $DF		; unused
 | |
| ;			= $E0		; unused
 | |
| ;			= $E1		; unused
 | |
| ;			= $E2		; unused
 | |
| ;			= $E3		; unused
 | |
| ;			= $E4		; unused
 | |
| ;			= $E5		; unused
 | |
| ;			= $E6		; unused
 | |
| ;			= $E7		; unused
 | |
| ;			= $E8		; unused
 | |
| ;			= $E9		; unused
 | |
| ;			= $EA		; unused
 | |
| ;			= $EB		; unused
 | |
| ;			= $EC		; unused
 | |
| ;			= $ED		; unused
 | |
| ;			= $EE		; unused
 | |
| 
 | |
| Decss			= $EF		; number to decimal string start
 | |
| Decssp1		= Decss+1	; number to decimal string start
 | |
| 
 | |
| ;			= $FF		; decimal string end
 | |
| 
 | |
| ; token values needed for BASIC
 | |
| 
 | |
| ; primary command tokens (can start a statement)
 | |
| 
 | |
| TK_END		= $80			; END token
 | |
| TK_FOR		= TK_END+1		; FOR token
 | |
| TK_NEXT		= TK_FOR+1		; NEXT token
 | |
| TK_DATA		= TK_NEXT+1		; DATA token
 | |
| TK_INPUT		= TK_DATA+1		; INPUT token
 | |
| TK_DIM		= TK_INPUT+1	; DIM token
 | |
| TK_READ		= TK_DIM+1		; READ token
 | |
| TK_LET		= TK_READ+1		; LET token
 | |
| TK_DEC		= TK_LET+1		; DEC token
 | |
| TK_GOTO		= TK_DEC+1		; GOTO token
 | |
| TK_RUN		= TK_GOTO+1		; RUN token
 | |
| TK_IF			= TK_RUN+1		; IF token
 | |
| TK_RESTORE		= TK_IF+1		; RESTORE token
 | |
| TK_GOSUB		= TK_RESTORE+1	; GOSUB token
 | |
| TK_RETIRQ		= TK_GOSUB+1	; RETIRQ token
 | |
| TK_RETNMI		= TK_RETIRQ+1	; RETNMI token
 | |
| TK_RETURN		= TK_RETNMI+1	; RETURN token
 | |
| TK_REM		= TK_RETURN+1	; REM token
 | |
| TK_STOP		= TK_REM+1		; STOP token
 | |
| TK_ON			= TK_STOP+1		; ON token
 | |
| TK_NULL		= TK_ON+1		; NULL token
 | |
| TK_INC		= TK_NULL+1		; INC token
 | |
| TK_WAIT		= TK_INC+1		; WAIT token
 | |
| TK_LOAD		= TK_WAIT+1		; LOAD token
 | |
| TK_SAVE		= TK_LOAD+1		; SAVE token
 | |
| TK_DEF		= TK_SAVE+1		; DEF token
 | |
| TK_POKE		= TK_DEF+1		; POKE token
 | |
| TK_DOKE		= TK_POKE+1		; DOKE token
 | |
| TK_CALL		= TK_DOKE+1		; CALL token
 | |
| TK_DO			= TK_CALL+1		; DO token
 | |
| TK_LOOP		= TK_DO+1		; LOOP token
 | |
| TK_PRINT		= TK_LOOP+1		; PRINT token
 | |
| TK_CONT		= TK_PRINT+1	; CONT token
 | |
| TK_LIST		= TK_CONT+1		; LIST token
 | |
| TK_CLEAR		= TK_LIST+1		; CLEAR token
 | |
| TK_NEW		= TK_CLEAR+1	; NEW token
 | |
| TK_WIDTH		= TK_NEW+1		; WIDTH token
 | |
| TK_GET		= TK_WIDTH+1	; GET token
 | |
| TK_SWAP		= TK_GET+1		; SWAP token
 | |
| TK_BITSET		= TK_SWAP+1		; BITSET token
 | |
| TK_BITCLR		= TK_BITSET+1	; BITCLR token
 | |
| TK_IRQ		= TK_BITCLR+1	; IRQ token
 | |
| TK_NMI		= TK_IRQ+1		; NMI token
 | |
| 
 | |
| ; secondary command tokens, can't start a statement
 | |
| 
 | |
| TK_TAB		= TK_NMI+1		; TAB token
 | |
| TK_ELSE		= TK_TAB+1		; ELSE token
 | |
| TK_TO			= TK_ELSE+1		; TO token
 | |
| TK_FN			= TK_TO+1		; FN token
 | |
| TK_SPC		= TK_FN+1		; SPC token
 | |
| TK_THEN		= TK_SPC+1		; THEN token
 | |
| TK_NOT		= TK_THEN+1		; NOT token
 | |
| TK_STEP		= TK_NOT+1		; STEP token
 | |
| TK_UNTIL		= TK_STEP+1		; UNTIL token
 | |
| TK_WHILE		= TK_UNTIL+1	; WHILE token
 | |
| TK_OFF		= TK_WHILE+1	; OFF token
 | |
| 
 | |
| ; opperator tokens
 | |
| 
 | |
| TK_PLUS		= TK_OFF+1		; + token
 | |
| TK_MINUS		= TK_PLUS+1		; - token
 | |
| TK_MUL		= TK_MINUS+1	; * token
 | |
| TK_DIV		= TK_MUL+1		; / token
 | |
| TK_POWER		= TK_DIV+1		; ^ token
 | |
| TK_AND		= TK_POWER+1	; AND token
 | |
| TK_EOR		= TK_AND+1		; EOR token
 | |
| TK_OR			= TK_EOR+1		; OR token
 | |
| TK_RSHIFT		= TK_OR+1		; RSHIFT token
 | |
| TK_LSHIFT		= TK_RSHIFT+1	; LSHIFT token
 | |
| TK_GT			= TK_LSHIFT+1	; > token
 | |
| TK_EQUAL		= TK_GT+1		; = token
 | |
| TK_LT			= TK_EQUAL+1	; < token
 | |
| 
 | |
| ; functions tokens
 | |
| 
 | |
| TK_SGN		= TK_LT+1		; SGN token
 | |
| TK_INT		= TK_SGN+1		; INT token
 | |
| TK_ABS		= TK_INT+1		; ABS token
 | |
| TK_USR		= TK_ABS+1		; USR token
 | |
| TK_FRE		= TK_USR+1		; FRE token
 | |
| TK_POS		= TK_FRE+1		; POS token
 | |
| TK_SQR		= TK_POS+1		; SQR token
 | |
| TK_RND		= TK_SQR+1		; RND token
 | |
| TK_LOG		= TK_RND+1		; LOG token
 | |
| TK_EXP		= TK_LOG+1		; EXP token
 | |
| TK_COS		= TK_EXP+1		; COS token
 | |
| TK_SIN		= TK_COS+1		; SIN token
 | |
| TK_TAN		= TK_SIN+1		; TAN token
 | |
| TK_ATN		= TK_TAN+1		; ATN token
 | |
| TK_PEEK		= TK_ATN+1		; PEEK token
 | |
| TK_DEEK		= TK_PEEK+1		; DEEK token
 | |
| TK_SADD		= TK_DEEK+1		; SADD token
 | |
| TK_LEN		= TK_SADD+1		; LEN token
 | |
| TK_STRS		= TK_LEN+1		; STR$ token
 | |
| TK_VAL		= TK_STRS+1		; VAL token
 | |
| TK_ASC		= TK_VAL+1		; ASC token
 | |
| TK_UCASES		= TK_ASC+1		; UCASE$ token
 | |
| TK_LCASES		= TK_UCASES+1	; LCASE$ token
 | |
| TK_CHRS		= TK_LCASES+1	; CHR$ token
 | |
| TK_HEXS		= TK_CHRS+1		; HEX$ token
 | |
| TK_BINS		= TK_HEXS+1		; BIN$ token
 | |
| TK_BITTST		= TK_BINS+1		; BITTST token
 | |
| TK_MAX		= TK_BITTST+1	; MAX token
 | |
| TK_MIN		= TK_MAX+1		; MIN token
 | |
| TK_PI			= TK_MIN+1		; PI token
 | |
| TK_TWOPI		= TK_PI+1		; TWOPI token
 | |
| TK_VPTR		= TK_TWOPI+1	; VARPTR token
 | |
| TK_LEFTS		= TK_VPTR+1		; LEFT$ token
 | |
| TK_RIGHTS		= TK_LEFTS+1	; RIGHT$ token
 | |
| TK_MIDS		= TK_RIGHTS+1	; MID$ token
 | |
| 
 | |
| ; offsets from a base of X or Y
 | |
| 
 | |
| PLUS_0		= $00		; X or Y plus 0
 | |
| PLUS_1		= $01		; X or Y plus 1
 | |
| PLUS_2		= $02		; X or Y plus 2
 | |
| PLUS_3		= $03		; X or Y plus 3
 | |
| 
 | |
| LAB_STAK		= $0100	; stack bottom, no offset
 | |
| 
 | |
| LAB_SKFE		= LAB_STAK+$FE
 | |
| 					; flushed stack address
 | |
| LAB_SKFF		= LAB_STAK+$FF
 | |
| 					; flushed stack address
 | |
| 
 | |
| ccflag		= $0200	; BASIC CTRL-C flag, 00 = enabled, 01 = dis
 | |
| ccbyte		= ccflag+1	; BASIC CTRL-C byte
 | |
| ccnull		= ccbyte+1	; BASIC CTRL-C byte timeout
 | |
| 
 | |
| VEC_CC		= ccnull+1	; ctrl c check vector
 | |
| 
 | |
| VEC_IN		= VEC_CC+2	; input vector
 | |
| VEC_OUT		= VEC_IN+2	; output vector
 | |
| VEC_LD		= VEC_OUT+2	; load vector
 | |
| VEC_SV		= VEC_LD+2	; save vector
 | |
| 
 | |
| ; Ibuffs can now be anywhere in RAM, ensure that the max length is < $80
 | |
| 
 | |
| Ibuffs		= IRQ_vec+$14
 | |
| 					; start of input buffer after IRQ/NMI code
 | |
| Ibuffe		= Ibuffs+$47; end of input buffer
 | |
| 
 | |
| Ram_base		= $0300	; start of user RAM (set as needed, should be page aligned)
 | |
| Ram_top		= $C000	; end of user RAM+1 (set as needed, should be page aligned)
 | |
| 
 | |
| ; This start can be changed to suit your system
 | |
| 
 | |
| 	.org	$C000
 | |
| 
 | |
| ; BASIC cold start entry point
 | |
| 
 | |
| ; new page 2 initialisation, copy block to ccflag on
 | |
| 
 | |
| LAB_COLD
 | |
| 	LDY	#PG2_TABE-PG2_TABS-1
 | |
| 					; byte count-1
 | |
| LAB_2D13
 | |
| 	LDA	PG2_TABS,Y		; get byte
 | |
| 	STA	ccflag,Y		; store in page 2
 | |
| 	DEY				; decrement count
 | |
| 	BPL	LAB_2D13		; loop if not done
 | |
| 
 | |
| 	LDX	#$FF			; set byte
 | |
| 	STX	Clineh		; set current line high byte (set immediate mode)
 | |
| 	TXS				; reset stack pointer
 | |
| 
 | |
| 	LDA	#$4C			; code for JMP
 | |
| 	STA	Fnxjmp		; save for jump vector for functions
 | |
| 
 | |
| ; copy block from LAB_2CEE to $00BC - $00D3
 | |
| 
 | |
| 	LDX	#StrTab-LAB_2CEE	; set byte count
 | |
| LAB_2D4E
 | |
| 	LDA	LAB_2CEE-1,X	; get byte from table
 | |
| 	STA	LAB_IGBY-1,X	; save byte in page zero
 | |
| 	DEX				; decrement count
 | |
| 	BNE	LAB_2D4E		; loop if not all done
 | |
| 
 | |
| ; copy block from StrTab to $0000 - $0012
 | |
| 
 | |
| LAB_GMEM
 | |
| 	LDX	#EndTab-StrTab-1	; set byte count-1
 | |
| TabLoop
 | |
| 	LDA	StrTab,X		; get byte from table
 | |
| 	STA	PLUS_0,X		; save byte in page zero
 | |
| 	DEX				; decrement count
 | |
| 	BPL	TabLoop		; loop if not all done
 | |
| 
 | |
| ; set-up start values
 | |
| 
 | |
| 	LDA	#$00			; clear A
 | |
| 	STA	NmiBase		; clear NMI handler enabled flag
 | |
| 	STA	IrqBase		; clear IRQ handler enabled flag
 | |
| 	STA	FAC1_o		; clear FAC1 overflow byte
 | |
| 	STA	last_sh		; clear descriptor stack top item pointer high byte
 | |
| 
 | |
| 	LDA	#$0E			; set default tab size
 | |
| 	STA	TabSiz		; save it
 | |
| 	LDA	#$03			; set garbage collect step size for descriptor stack
 | |
| 	STA	g_step		; save it
 | |
| 	LDX	#des_sk		; descriptor stack start
 | |
| 	STX	next_s		; set descriptor stack pointer
 | |
| 	JSR	LAB_CRLF		; print CR/LF
 | |
| 	LDA	#<LAB_MSZM		; point to memory size message (low addr)
 | |
| 	LDY	#>LAB_MSZM		; point to memory size message (high addr)
 | |
| 	JSR	LAB_18C3		; print null terminated string from memory
 | |
| 	JSR	LAB_INLN		; print "? " and get BASIC input
 | |
| 	STX	Bpntrl		; set BASIC execute pointer low byte
 | |
| 	STY	Bpntrh		; set BASIC execute pointer high byte
 | |
| 	JSR	LAB_GBYT		; get last byte back
 | |
| 
 | |
| 	BNE	LAB_2DAA		; branch if not null (user typed something)
 | |
| 
 | |
| 	LDY	#$00			; else clear Y
 | |
| 					; character was null so get memory size the hard way
 | |
| 					; we get here with Y=0 and Itempl/h = Ram_base
 | |
| LAB_2D93
 | |
| 	INC	Itempl		; increment temporary integer low byte
 | |
| 	BNE	LAB_2D99		; branch if no overflow
 | |
| 
 | |
| 	INC	Itemph		; increment temporary integer high byte
 | |
| 	LDA	Itemph		; get high byte
 | |
| 	CMP	#>Ram_top		; compare with top of RAM+1
 | |
| 	BEQ	LAB_2DB6		; branch if match (end of user RAM)
 | |
| 
 | |
| LAB_2D99
 | |
| 	LDA	#$55			; set test byte
 | |
| 	STA	(Itempl),Y		; save via temporary integer
 | |
| 	CMP	(Itempl),Y		; compare via temporary integer
 | |
| 	BNE	LAB_2DB6		; branch if fail
 | |
| 
 | |
| 	ASL				; shift test byte left (now $AA)
 | |
| 	STA	(Itempl),Y		; save via temporary integer
 | |
| 	CMP	(Itempl),Y		; compare via temporary integer
 | |
| 	BEQ	LAB_2D93		; if ok go do next byte
 | |
| 
 | |
| 	BNE	LAB_2DB6		; branch if fail
 | |
| 
 | |
| LAB_2DAA
 | |
| 	JSR	LAB_2887		; get FAC1 from string
 | |
| 	LDA	FAC1_e		; get FAC1 exponent
 | |
| 	CMP	#$98			; compare with exponent = 2^24
 | |
| 	BCS	LAB_GMEM		; if too large go try again
 | |
| 
 | |
| 	JSR	LAB_F2FU		; save integer part of FAC1 in temporary integer
 | |
| 					; (no range check)
 | |
| 
 | |
| LAB_2DB6
 | |
| 	LDA	Itempl		; get temporary integer low byte
 | |
| 	LDY	Itemph		; get temporary integer high byte
 | |
| 	CPY	#<Ram_base+1	; compare with start of RAM+$100 high byte
 | |
| 	BCC	LAB_GMEM		; if too small go try again
 | |
| 
 | |
| 
 | |
| ; uncomment these lines if you want to check on the high limit of memory. Note if
 | |
| ; Ram_top is set too low then this will fail. default is ignore it and assume the
 | |
| ; users know what they're doing!
 | |
| 
 | |
| ;	CPY	#>Ram_top		; compare with top of RAM high byte
 | |
| ;	BCC	MEM_OK		; branch if < RAM top
 | |
| 
 | |
| ;	BNE	LAB_GMEM		; if too large go try again
 | |
| 					; else was = so compare low bytes
 | |
| ;	CMP	#<Ram_top		; compare with top of RAM low byte
 | |
| ;	BEQ	MEM_OK		; branch if = RAM top
 | |
| 
 | |
| ;	BCS	LAB_GMEM		; if too large go try again
 | |
| 
 | |
| ;MEM_OK
 | |
| 	STA	Ememl			; set end of mem low byte
 | |
| 	STY	Ememh			; set end of mem high byte
 | |
| 	STA	Sstorl		; set bottom of string space low byte
 | |
| 	STY	Sstorh		; set bottom of string space high byte
 | |
| 
 | |
| 	LDY	#<Ram_base		; set start addr low byte
 | |
| 	LDX	#>Ram_base		; set start addr high byte
 | |
| 	STY	Smeml			; save start of mem low byte
 | |
| 	STX	Smemh			; save start of mem high byte
 | |
| 
 | |
| ; this line is only needed if Ram_base is not $xx00
 | |
| 
 | |
| ;	LDY	#$00			; clear Y
 | |
| 	TYA				; clear A
 | |
| 	STA	(Smeml),Y		; clear first byte
 | |
| 	INC	Smeml			; increment start of mem low byte
 | |
| 
 | |
| ; these two lines are only needed if Ram_base is $xxFF
 | |
| 
 | |
| ;	BNE	LAB_2E05		; branch if no rollover
 | |
| 
 | |
| ;	INC	Smemh			; increment start of mem high byte
 | |
| LAB_2E05
 | |
| 	JSR	LAB_CRLF		; print CR/LF
 | |
| 	JSR	LAB_1463		; do "NEW" and "CLEAR"
 | |
| 	LDA	Ememl			; get end of mem low byte
 | |
| 	SEC				; set carry for subtract
 | |
| 	SBC	Smeml			; subtract start of mem low byte
 | |
| 	TAX				; copy to X
 | |
| 	LDA	Ememh			; get end of mem high byte
 | |
| 	SBC	Smemh			; subtract start of mem high byte
 | |
| 	JSR	LAB_295E		; print XA as unsigned integer (bytes free)
 | |
| 	LDA	#<LAB_SMSG		; point to sign-on message (low addr)
 | |
| 	LDY	#>LAB_SMSG		; point to sign-on message (high addr)
 | |
| 	JSR	LAB_18C3		; print null terminated string from memory
 | |
| 	LDA	#<LAB_1274		; warm start vector low byte
 | |
| 	LDY	#>LAB_1274		; warm start vector high byte
 | |
| 	STA	Wrmjpl		; save warm start vector low byte
 | |
| 	STY	Wrmjph		; save warm start vector high byte
 | |
| 	JMP	(Wrmjpl)		; go do warm start
 | |
| 
 | |
| ; open up space in memory
 | |
| ; move (Ostrtl)-(Obendl) to new block ending at (Nbendl)
 | |
| 
 | |
| ; Nbendl,Nbendh - new block end address (A/Y)
 | |
| ; Obendl,Obendh - old block end address
 | |
| ; Ostrtl,Ostrth - old block start address
 | |
| 
 | |
| ; returns with ..
 | |
| 
 | |
| ; Nbendl,Nbendh - new block start address (high byte - $100)
 | |
| ; Obendl,Obendh - old block start address (high byte - $100)
 | |
| ; Ostrtl,Ostrth - old block start address (unchanged)
 | |
| 
 | |
| LAB_11CF
 | |
| 	JSR	LAB_121F		; check available memory, "Out of memory" error if no room
 | |
| 					; addr to check is in AY (low/high)
 | |
| 	STA	Earryl		; save new array mem end low byte
 | |
| 	STY	Earryh		; save new array mem end high byte
 | |
| 
 | |
| ; open up space in memory
 | |
| ; move (Ostrtl)-(Obendl) to new block ending at (Nbendl)
 | |
| ; don't set array end
 | |
| 
 | |
| LAB_11D6
 | |
| 	SEC				; set carry for subtract
 | |
| 	LDA	Obendl		; get block end low byte
 | |
| 	SBC	Ostrtl		; subtract block start low byte
 | |
| 	TAY				; copy MOD(block length/$100) byte to Y
 | |
| 	LDA	Obendh		; get block end high byte
 | |
| 	SBC	Ostrth		; subtract block start high byte
 | |
| 	TAX				; copy block length high byte to X
 | |
| 	INX				; +1 to allow for count=0 exit
 | |
| 	TYA				; copy block length low byte to A
 | |
| 	BEQ	LAB_120A		; branch if length low byte=0
 | |
| 
 | |
| 					; block is (X-1)*256+Y bytes, do the Y bytes first
 | |
| 
 | |
| 	SEC				; set carry for add + 1, two's complement
 | |
| 	EOR	#$FF			; invert low byte for subtract
 | |
| 	ADC	Obendl		; add block end low byte
 | |
| 
 | |
| 	STA	Obendl		; save corrected old block end low byte
 | |
| 	BCS	LAB_11F3		; branch if no underflow
 | |
| 
 | |
| 	DEC	Obendh		; else decrement block end high byte
 | |
| 	SEC				; set carry for add + 1, two's complement
 | |
| LAB_11F3
 | |
| 	TYA				; get MOD(block length/$100) byte
 | |
| 	EOR	#$FF			; invert low byte for subtract
 | |
| 	ADC	Nbendl		; add destination end low byte
 | |
| 	STA	Nbendl		; save modified new block end low byte
 | |
| 	BCS	LAB_1203		; branch if no underflow
 | |
| 
 | |
| 	DEC	Nbendh		; else decrement block end high byte
 | |
| 	BCC	LAB_1203		; branch always
 | |
| 
 | |
| LAB_11FF
 | |
| 	LDA	(Obendl),Y		; get byte from source
 | |
| 	STA	(Nbendl),Y		; copy byte to destination
 | |
| LAB_1203
 | |
| 	DEY				; decrement index
 | |
| 	BNE	LAB_11FF		; loop until Y=0
 | |
| 
 | |
| 					; now do Y=0 indexed byte
 | |
| 	LDA	(Obendl),Y		; get byte from source
 | |
| 	STA	(Nbendl),Y		; save byte to destination
 | |
| LAB_120A
 | |
| 	DEC	Obendh		; decrement source pointer high byte
 | |
| 	DEC	Nbendh		; decrement destination pointer high byte
 | |
| 	DEX				; decrement block count
 | |
| 	BNE	LAB_1203		; loop until count = $0
 | |
| 
 | |
| 	RTS
 | |
| 
 | |
| ; check room on stack for A bytes
 | |
| ; stack too deep? do OM error
 | |
| 
 | |
| LAB_1212
 | |
| 	STA	TempB			; save result in temp byte
 | |
| 	TSX				; copy stack
 | |
| 	CPX	TempB			; compare new "limit" with stack
 | |
| 	BCC	LAB_OMER		; if stack < limit do "Out of memory" error then warm start
 | |
| 
 | |
| 	RTS
 | |
| 
 | |
| ; check available memory, "Out of memory" error if no room
 | |
| ; addr to check is in AY (low/high)
 | |
| 
 | |
| LAB_121F
 | |
| 	CPY	Sstorh		; compare bottom of string mem high byte
 | |
| 	BCC	LAB_124B		; if less then exit (is ok)
 | |
| 
 | |
| 	BNE	LAB_1229		; skip next test if greater (tested <)
 | |
| 
 | |
| 					; high byte was =, now do low byte
 | |
| 	CMP	Sstorl		; compare with bottom of string mem low byte
 | |
| 	BCC	LAB_124B		; if less then exit (is ok)
 | |
| 
 | |
| 					; addr is > string storage ptr (oops!)
 | |
| LAB_1229
 | |
| 	PHA				; push addr low byte
 | |
| 	LDX	#$08			; set index to save Adatal to expneg inclusive
 | |
| 	TYA				; copy addr high byte (to push on stack)
 | |
| 
 | |
| 					; save misc numeric work area
 | |
| LAB_122D
 | |
| 	PHA				; push byte
 | |
| 	LDA	Adatal-1,X		; get byte from Adatal to expneg ( ,$00 not pushed)
 | |
| 	DEX				; decrement index
 | |
| 	BPL	LAB_122D		; loop until all done
 | |
| 
 | |
| 	JSR	LAB_GARB		; garbage collection routine
 | |
| 
 | |
| 					; restore misc numeric work area
 | |
| 	LDX	#$00			; clear the index to restore bytes
 | |
| LAB_1238
 | |
| 	PLA				; pop byte
 | |
| 	STA	Adatal,X		; save byte to Adatal to expneg
 | |
| 	INX				; increment index
 | |
| 	CPX	#$08			; compare with end + 1
 | |
| 	BMI	LAB_1238		; loop if more to do
 | |
| 
 | |
| 	PLA				; pop addr high byte
 | |
| 	TAY				; copy back to Y
 | |
| 	PLA				; pop addr low byte
 | |
| 	CPY	Sstorh		; compare bottom of string mem high byte
 | |
| 	BCC	LAB_124B		; if less then exit (is ok)
 | |
| 
 | |
| 	BNE	LAB_OMER		; if greater do "Out of memory" error then warm start
 | |
| 
 | |
| 					; high byte was =, now do low byte
 | |
| 	CMP	Sstorl		; compare with bottom of string mem low byte
 | |
| 	BCS	LAB_OMER		; if >= do "Out of memory" error then warm start
 | |
| 
 | |
| 					; ok exit, carry clear
 | |
| LAB_124B
 | |
| 	RTS
 | |
| 
 | |
| ; do "Out of memory" error then warm start
 | |
| 
 | |
| LAB_OMER
 | |
| 	LDX	#$0C			; error code $0C ("Out of memory" error)
 | |
| 
 | |
| ; do error #X, then warm start
 | |
| 
 | |
| LAB_XERR
 | |
| 	JSR	LAB_CRLF		; print CR/LF
 | |
| 
 | |
| 	LDA	LAB_BAER,X		; get error message pointer low byte
 | |
| 	LDY	LAB_BAER+1,X	; get error message pointer high byte
 | |
| 	JSR	LAB_18C3		; print null terminated string from memory
 | |
| 
 | |
| 	JSR	LAB_1491		; flush stack and clear continue flag
 | |
| 	LDA	#<LAB_EMSG		; point to " Error" low addr
 | |
| 	LDY	#>LAB_EMSG		; point to " Error" high addr
 | |
| LAB_1269
 | |
| 	JSR	LAB_18C3		; print null terminated string from memory
 | |
| 	LDY	Clineh		; get current line high byte
 | |
| 	INY				; increment it
 | |
| 	BEQ	LAB_1274		; go do warm start (was immediate mode)
 | |
| 
 | |
| 					; else print line number
 | |
| 	JSR	LAB_2953		; print " in line [LINE #]"
 | |
| 
 | |
| ; BASIC warm start entry point
 | |
| ; wait for Basic command
 | |
| 
 | |
| LAB_1274
 | |
| 					; clear ON IRQ/NMI bytes
 | |
| 	LDA	#$00			; clear A
 | |
| 	STA	IrqBase		; clear enabled byte
 | |
| 	STA	NmiBase		; clear enabled byte
 | |
| 	LDA	#<LAB_RMSG		; point to "Ready" message low byte
 | |
| 	LDY	#>LAB_RMSG		; point to "Ready" message high byte
 | |
| 
 | |
| 	JSR	LAB_18C3		; go do print string
 | |
| 
 | |
| ; wait for Basic command (no "Ready")
 | |
| 
 | |
| LAB_127D
 | |
| 	JSR	LAB_1357		; call for BASIC input
 | |
| LAB_1280
 | |
| 	STX	Bpntrl		; set BASIC execute pointer low byte
 | |
| 	STY	Bpntrh		; set BASIC execute pointer high byte
 | |
| 	JSR	LAB_GBYT		; scan memory
 | |
| 	BEQ	LAB_127D		; loop while null
 | |
| 
 | |
| ; got to interpret input line now ..
 | |
| 
 | |
| 	LDX	#$FF			; current line to null value
 | |
| 	STX	Clineh		; set current line high byte
 | |
| 	BCC	LAB_1295		; branch if numeric character (handle new BASIC line)
 | |
| 
 | |
| 					; no line number .. immediate mode
 | |
| 	JSR	LAB_13A6		; crunch keywords into Basic tokens
 | |
| 	JMP	LAB_15F6		; go scan and interpret code
 | |
| 
 | |
| ; handle new BASIC line
 | |
| 
 | |
| LAB_1295
 | |
| 	JSR	LAB_GFPN		; get fixed-point number into temp integer
 | |
| 	JSR	LAB_13A6		; crunch keywords into Basic tokens
 | |
| 	STY	Ibptr			; save index pointer to end of crunched line
 | |
| 	JSR	LAB_SSLN		; search BASIC for temp integer line number
 | |
| 	BCC	LAB_12E6		; branch if not found
 | |
| 
 | |
| 					; aroooogah! line # already exists! delete it
 | |
| 	LDY	#$01			; set index to next line pointer high byte
 | |
| 	LDA	(Baslnl),Y		; get next line pointer high byte
 | |
| 	STA	ut1_ph		; save it
 | |
| 	LDA	Svarl			; get start of vars low byte
 | |
| 	STA	ut1_pl		; save it
 | |
| 	LDA	Baslnh		; get found line pointer high byte
 | |
| 	STA	ut2_ph		; save it
 | |
| 	LDA	Baslnl		; get found line pointer low byte
 | |
| 	DEY				; decrement index
 | |
| 	SBC	(Baslnl),Y		; subtract next line pointer low byte
 | |
| 	CLC				; clear carry for add
 | |
| 	ADC	Svarl			; add start of vars low byte
 | |
| 	STA	Svarl			; save new start of vars low byte
 | |
| 	STA	ut2_pl		; save destination pointer low byte
 | |
| 	LDA	Svarh			; get start of vars high byte
 | |
| 	ADC	#$FF			; -1 + carry
 | |
| 	STA	Svarh			; save start of vars high byte
 | |
| 	SBC	Baslnh		; subtract found line pointer high byte
 | |
| 	TAX				; copy to block count
 | |
| 	SEC				; set carry for subtract
 | |
| 	LDA	Baslnl		; get found line pointer low byte
 | |
| 	SBC	Svarl			; subtract start of vars low byte
 | |
| 	TAY				; copy to bytes in first block count
 | |
| 	BCS	LAB_12D0		; branch if overflow
 | |
| 
 | |
| 	INX				; increment block count (correct for =0 loop exit)
 | |
| 	DEC	ut2_ph		; decrement destination high byte
 | |
| LAB_12D0
 | |
| 	CLC				; clear carry for add
 | |
| 	ADC	ut1_pl		; add source pointer low byte
 | |
| 	BCC	LAB_12D8		; branch if no overflow
 | |
| 
 | |
| 	DEC	ut1_ph		; else decrement source pointer high byte
 | |
| 	CLC				; clear carry
 | |
| 
 | |
| 					; close up memory to delete old line
 | |
| LAB_12D8
 | |
| 	LDA	(ut1_pl),Y		; get byte from source
 | |
| 	STA	(ut2_pl),Y		; copy to destination
 | |
| 	INY				; increment index
 | |
| 	BNE	LAB_12D8		; while <> 0 do this block
 | |
| 
 | |
| 	INC	ut1_ph		; increment source pointer high byte
 | |
| 	INC	ut2_ph		; increment destination pointer high byte
 | |
| 	DEX				; decrement block count
 | |
| 	BNE	LAB_12D8		; loop until all done
 | |
| 
 | |
| 					; got new line in buffer and no existing same #
 | |
| LAB_12E6
 | |
| 	LDA	Ibuffs		; get byte from start of input buffer
 | |
| 	BEQ	LAB_1319		; if null line just go flush stack/vars and exit
 | |
| 
 | |
| 					; got new line and it isn't empty line
 | |
| 	LDA	Ememl			; get end of mem low byte
 | |
| 	LDY	Ememh			; get end of mem high byte
 | |
| 	STA	Sstorl		; set bottom of string space low byte
 | |
| 	STY	Sstorh		; set bottom of string space high byte
 | |
| 	LDA	Svarl			; get start of vars low byte	(end of BASIC)
 | |
| 	STA	Obendl		; save old block end low byte
 | |
| 	LDY	Svarh			; get start of vars high byte	(end of BASIC)
 | |
| 	STY	Obendh		; save old block end high byte
 | |
| 	ADC	Ibptr			; add input buffer pointer	(also buffer length)
 | |
| 	BCC	LAB_1301		; branch if no overflow from add
 | |
| 
 | |
| 	INY				; else increment high byte
 | |
| LAB_1301
 | |
| 	STA	Nbendl		; save new block end low byte	(move to, low byte)
 | |
| 	STY	Nbendh		; save new block end high byte
 | |
| 	JSR	LAB_11CF		; open up space in memory
 | |
| 					; old start pointer Ostrtl,Ostrth set by the find line call
 | |
| 	LDA	Earryl		; get array mem end low byte
 | |
| 	LDY	Earryh		; get array mem end high byte
 | |
| 	STA	Svarl			; save start of vars low byte
 | |
| 	STY	Svarh			; save start of vars high byte
 | |
| 	LDY	Ibptr			; get input buffer pointer	(also buffer length)
 | |
| 	DEY				; adjust for loop type
 | |
| LAB_1311
 | |
| 	LDA	Ibuffs-4,Y		; get byte from crunched line
 | |
| 	STA	(Baslnl),Y		; save it to program memory
 | |
| 	DEY				; decrement count
 | |
| 	CPY	#$03			; compare with first byte-1
 | |
| 	BNE	LAB_1311		; continue while count <> 3
 | |
| 
 | |
| 	LDA	Itemph		; get line # high byte
 | |
| 	STA	(Baslnl),Y		; save it to program memory
 | |
| 	DEY				; decrement count
 | |
| 	LDA	Itempl		; get line # low byte
 | |
| 	STA	(Baslnl),Y		; save it to program memory
 | |
| 	DEY				; decrement count
 | |
| 	LDA	#$FF			; set byte to allow chain rebuild. if you didn't set this
 | |
| 					; byte then a zero already here would stop the chain rebuild
 | |
| 					; as it would think it was the [EOT] marker.
 | |
| 	STA	(Baslnl),Y		; save it to program memory
 | |
| 
 | |
| LAB_1319
 | |
| 	JSR	LAB_1477		; reset execution to start, clear vars and flush stack
 | |
| 	LDX	Smeml			; get start of mem low byte
 | |
| 	LDA	Smemh			; get start of mem high byte
 | |
| 	LDY	#$01			; index to high byte of next line pointer
 | |
| LAB_1325
 | |
| 	STX	ut1_pl		; set line start pointer low byte
 | |
| 	STA	ut1_ph		; set line start pointer high byte
 | |
| 	LDA	(ut1_pl),Y		; get it
 | |
| 	BEQ	LAB_133E		; exit if end of program
 | |
| 
 | |
| ; rebuild chaining of Basic lines
 | |
| 
 | |
| 	LDY	#$04			; point to first code byte of line
 | |
| 					; there is always 1 byte + [EOL] as null entries are deleted
 | |
| LAB_1330
 | |
| 	INY				; next code byte
 | |
| 	LDA	(ut1_pl),Y		; get byte
 | |
| 	BNE	LAB_1330		; loop if not [EOL]
 | |
| 
 | |
| 	SEC				; set carry for add + 1
 | |
| 	TYA				; copy end index
 | |
| 	ADC	ut1_pl		; add to line start pointer low byte
 | |
| 	TAX				; copy to X
 | |
| 	LDY	#$00			; clear index, point to this line's next line pointer
 | |
| 	STA	(ut1_pl),Y		; set next line pointer low byte
 | |
| 	TYA				; clear A
 | |
| 	ADC	ut1_ph		; add line start pointer high byte + carry
 | |
| 	INY				; increment index to high byte
 | |
| 	STA	(ut1_pl),Y		; save next line pointer low byte
 | |
| 	BCC	LAB_1325		; go do next line, branch always, carry clear
 | |
| 
 | |
| 
 | |
| LAB_133E
 | |
| 	JMP	LAB_127D		; else we just wait for Basic command, no "Ready"
 | |
| 
 | |
| ; print "? " and get BASIC input
 | |
| 
 | |
| LAB_INLN
 | |
| 	JSR	LAB_18E3		; print "?" character
 | |
| 	JSR	LAB_18E0		; print " "
 | |
| 	BNE	LAB_1357		; call for BASIC input and return
 | |
| 
 | |
| ; receive line from keyboard
 | |
| 
 | |
| 					; $08 as delete key (BACKSPACE on standard keyboard)
 | |
| LAB_134B
 | |
| 	JSR	LAB_PRNA		; go print the character
 | |
| 	DEX				; decrement the buffer counter (delete)
 | |
| 	.byte	$2C			; make LDX into BIT abs
 | |
| 
 | |
| ; call for BASIC input (main entry point)
 | |
| 
 | |
| LAB_1357
 | |
| 	LDX	#$00			; clear BASIC line buffer pointer
 | |
| LAB_1359
 | |
| 	JSR	V_INPT		; call scan input device
 | |
| 	BCC	LAB_1359		; loop if no byte
 | |
| 
 | |
| 	BEQ	LAB_1359		; loop until valid input (ignore NULLs)
 | |
| 
 | |
| 	CMP	#$07			; compare with [BELL]
 | |
| 	BEQ	LAB_1378		; branch if [BELL]
 | |
| 
 | |
| 	CMP	#$0D			; compare with [CR]
 | |
| 	BEQ	LAB_1384		; do CR/LF exit if [CR]
 | |
| 
 | |
| 	CPX	#$00			; compare pointer with $00
 | |
| 	BNE	LAB_1374		; branch if not empty
 | |
| 
 | |
| ; next two lines ignore any non print character and [SPACE] if input buffer empty
 | |
| 
 | |
| 	CMP	#$21			; compare with [SP]+1
 | |
| 	BCC	LAB_1359		; if < ignore character
 | |
| 
 | |
| LAB_1374
 | |
| 	CMP	#$08			; compare with [BACKSPACE] (delete last character)
 | |
| 	BEQ	LAB_134B		; go delete last character
 | |
| 
 | |
| LAB_1378
 | |
| 	CPX	#Ibuffe-Ibuffs	; compare character count with max
 | |
| 	BCS	LAB_138E		; skip store and do [BELL] if buffer full
 | |
| 
 | |
| 	STA	Ibuffs,X		; else store in buffer
 | |
| 	INX				; increment pointer
 | |
| LAB_137F
 | |
| 	JSR	LAB_PRNA		; go print the character
 | |
| 	BNE	LAB_1359		; always loop for next character
 | |
| 
 | |
| LAB_1384
 | |
| 	JMP	LAB_1866		; do CR/LF exit to BASIC
 | |
| 
 | |
| ; announce buffer full
 | |
| 
 | |
| LAB_138E
 | |
| 	LDA	#$07			; [BELL] character into A
 | |
| 	BNE	LAB_137F		; go print the [BELL] but ignore input character
 | |
| 					; branch always
 | |
| 
 | |
| ; crunch keywords into Basic tokens
 | |
| ; position independent buffer version ..
 | |
| ; faster, dictionary search version ....
 | |
| 
 | |
| LAB_13A6
 | |
| 	LDY	#$FF			; set save index (makes for easy math later)
 | |
| 
 | |
| 	SEC				; set carry for subtract
 | |
| 	LDA	Bpntrl		; get basic execute pointer low byte
 | |
| 	SBC	#<Ibuffs		; subtract input buffer start pointer
 | |
| 	TAX				; copy result to X (index past line # if any)
 | |
| 
 | |
| 	STX	Oquote		; clear open quote/DATA flag
 | |
| LAB_13AC
 | |
| 	LDA	Ibuffs,X		; get byte from input buffer
 | |
| 	BEQ	LAB_13EC		; if null save byte then exit
 | |
| 
 | |
| 	CMP	#'_'			; compare with "_"
 | |
| 	BCS	LAB_13EC		; if >= go save byte then continue crunching
 | |
| 
 | |
| 	CMP	#'<'			; compare with "<"
 | |
| 	BCS	LAB_13CC		; if >= go crunch now
 | |
| 
 | |
| 	CMP	#'0'			; compare with "0"
 | |
| 	BCS	LAB_13EC		; if >= go save byte then continue crunching
 | |
| 
 | |
| 	STA	Scnquo		; save buffer byte as search character
 | |
| 	CMP	#$22			; is it quote character?
 | |
| 	BEQ	LAB_1410		; branch if so (copy quoted string)
 | |
| 
 | |
| 	CMP	#'*'			; compare with "*"
 | |
| 	BCC	LAB_13EC		; if < go save byte then continue crunching
 | |
| 
 | |
| 					; else crunch now
 | |
| LAB_13CC
 | |
| 	BIT	Oquote		; get open quote/DATA token flag
 | |
| 	BVS	LAB_13EC		; branch if b6 of Oquote set (was DATA)
 | |
| 					; go save byte then continue crunching
 | |
| 
 | |
| 	STX	TempB			; save buffer read index
 | |
| 	STY	csidx			; copy buffer save index
 | |
| 	LDY	#<TAB_1STC		; get keyword first character table low address
 | |
| 	STY	ut2_pl		; save pointer low byte
 | |
| 	LDY	#>TAB_1STC		; get keyword first character table high address
 | |
| 	STY	ut2_ph		; save pointer high byte
 | |
| 	LDY	#$00			; clear table pointer
 | |
| 
 | |
| LAB_13D0
 | |
| 	CMP	(ut2_pl),Y		; compare with keyword first character table byte
 | |
| 	BEQ	LAB_13D1		; go do word_table_chr if match
 | |
| 
 | |
| 	BCC	LAB_13EA		; if < keyword first character table byte go restore
 | |
| 					; Y and save to crunched
 | |
| 
 | |
| 	INY				; else increment pointer
 | |
| 	BNE	LAB_13D0		; and loop (branch always)
 | |
| 
 | |
| ; have matched first character of some keyword
 | |
| 
 | |
| LAB_13D1
 | |
| 	TYA				; copy matching index
 | |
| 	ASL				; *2 (bytes per pointer)
 | |
| 	TAX				; copy to new index
 | |
| 	LDA	TAB_CHRT,X		; get keyword table pointer low byte
 | |
| 	STA	ut2_pl		; save pointer low byte
 | |
| 	LDA	TAB_CHRT+1,X	; get keyword table pointer high byte
 | |
| 	STA	ut2_ph		; save pointer high byte
 | |
| 
 | |
| 	LDY	#$FF			; clear table pointer (make -1 for start)
 | |
| 
 | |
| 	LDX	TempB			; restore buffer read index
 | |
| 
 | |
| LAB_13D6
 | |
| 	INY				; next table byte
 | |
| 	LDA	(ut2_pl),Y		; get byte from table
 | |
| LAB_13D8
 | |
| 	BMI	LAB_13EA		; all bytes matched so go save token
 | |
| 
 | |
| 	INX				; next buffer byte
 | |
| 	CMP	Ibuffs,X		; compare with byte from input buffer
 | |
| 	BEQ	LAB_13D6		; go compare next if match
 | |
| 
 | |
| 	BNE	LAB_1417		; branch if >< (not found keyword)
 | |
| 
 | |
| LAB_13EA
 | |
| 	LDY	csidx			; restore save index
 | |
| 
 | |
| 					; save crunched to output
 | |
| LAB_13EC
 | |
| 	INX				; increment buffer index (to next input byte)
 | |
| 	INY				; increment save index (to next output byte)
 | |
| 	STA	Ibuffs,Y		; save byte to output
 | |
| 	CMP	#$00			; set the flags, set carry
 | |
| 	BEQ	LAB_142A		; do exit if was null [EOL]
 | |
| 
 | |
| 					; A holds token or byte here
 | |
| 	SBC	#':'			; subtract ":" (carry set by CMP #00)
 | |
| 	BEQ	LAB_13FF		; branch if it was ":" (is now $00)
 | |
| 
 | |
| 					; A now holds token-$3A
 | |
| 	CMP	#TK_DATA-$3A	; compare with DATA token - $3A
 | |
| 	BNE	LAB_1401		; branch if not DATA
 | |
| 
 | |
| 					; token was : or DATA
 | |
| LAB_13FF
 | |
| 	STA	Oquote		; save token-$3A (clear for ":", TK_DATA-$3A for DATA)
 | |
| LAB_1401
 | |
| 	EOR	#TK_REM-$3A		; effectively subtract REM token offset
 | |
| 	BNE	LAB_13AC		; If wasn't REM then go crunch rest of line
 | |
| 
 | |
| 	STA	Asrch			; else was REM so set search for [EOL]
 | |
| 
 | |
| 					; loop for REM, "..." etc.
 | |
| LAB_1408
 | |
| 	LDA	Ibuffs,X		; get byte from input buffer
 | |
| 	BEQ	LAB_13EC		; branch if null [EOL]
 | |
| 
 | |
| 	CMP	Asrch			; compare with stored character
 | |
| 	BEQ	LAB_13EC		; branch if match (end quote)
 | |
| 
 | |
| 					; entry for copy string in quotes, don't crunch
 | |
| LAB_1410
 | |
| 	INY				; increment buffer save index
 | |
| 	STA	Ibuffs,Y		; save byte to output
 | |
| 	INX				; increment buffer read index
 | |
| 	BNE	LAB_1408		; loop while <> 0 (should never be 0!)
 | |
| 
 | |
| 					; not found keyword this go
 | |
| LAB_1417
 | |
| 	LDX	TempB			; compare has failed, restore buffer index (start byte!)
 | |
| 
 | |
| 					; now find the end of this word in the table
 | |
| LAB_141B
 | |
| 	LDA	(ut2_pl),Y		; get table byte
 | |
| 	PHP				; save status
 | |
| 	INY				; increment table index
 | |
| 	PLP				; restore byte status
 | |
| 	BPL	LAB_141B		; if not end of keyword go do next
 | |
| 
 | |
| 	LDA	(ut2_pl),Y		; get byte from keyword table
 | |
| 	BNE	LAB_13D8		; go test next word if not zero byte (end of table)
 | |
| 
 | |
| 					; reached end of table with no match
 | |
| 	LDA	Ibuffs,X		; restore byte from input buffer
 | |
| 	BPL	LAB_13EA		; branch always (all bytes in buffer are $00-$7F)
 | |
| 					; go save byte in output and continue crunching
 | |
| 
 | |
| 					; reached [EOL]
 | |
| LAB_142A
 | |
| 	INY				; increment pointer
 | |
| 	INY				; increment pointer (makes it next line pointer high byte)
 | |
| 	STA	Ibuffs,Y		; save [EOL] (marks [EOT] in immediate mode)
 | |
| 	INY				; adjust for line copy
 | |
| 	INY				; adjust for line copy
 | |
| 	INY				; adjust for line copy
 | |
| 	DEC	Bpntrl		; allow for increment (change if buffer starts at $xxFF)
 | |
| 	RTS
 | |
| 
 | |
| ; search Basic for temp integer line number from start of mem
 | |
| 
 | |
| LAB_SSLN
 | |
| 	LDA	Smeml			; get start of mem low byte
 | |
| 	LDX	Smemh			; get start of mem high byte
 | |
| 
 | |
| ; search Basic for temp integer line number from AX
 | |
| ; returns carry set if found
 | |
| ; returns Baslnl/Baslnh pointer to found or next higher (not found) line
 | |
| 
 | |
| ; old 541 new 507
 | |
| 
 | |
| LAB_SHLN
 | |
| 	LDY	#$01			; set index
 | |
| 	STA	Baslnl		; save low byte as current
 | |
| 	STX	Baslnh		; save high byte as current
 | |
| 	LDA	(Baslnl),Y		; get pointer high byte from addr
 | |
| 	BEQ	LAB_145F		; pointer was zero so we're done, do 'not found' exit
 | |
| 
 | |
| 	LDY	#$03			; set index to line # high byte
 | |
| 	LDA	(Baslnl),Y		; get line # high byte
 | |
| 	DEY				; decrement index (point to low byte)
 | |
| 	CMP	Itemph		; compare with temporary integer high byte
 | |
| 	BNE	LAB_1455		; if <> skip low byte check
 | |
| 
 | |
| 	LDA	(Baslnl),Y		; get line # low byte
 | |
| 	CMP	Itempl		; compare with temporary integer low byte
 | |
| LAB_1455
 | |
| 	BCS	LAB_145E		; else if temp < this line, exit (passed line#)
 | |
| 
 | |
| LAB_1456
 | |
| 	DEY				; decrement index to next line ptr high byte
 | |
| 	LDA	(Baslnl),Y		; get next line pointer high byte
 | |
| 	TAX				; copy to X
 | |
| 	DEY				; decrement index to next line ptr low byte
 | |
| 	LDA	(Baslnl),Y		; get next line pointer low byte
 | |
| 	BCC	LAB_SHLN		; go search for line # in temp (Itempl/Itemph) from AX
 | |
| 					; (carry always clear)
 | |
| 
 | |
| LAB_145E
 | |
| 	BEQ	LAB_1460		; exit if temp = found line #, carry is set
 | |
| 
 | |
| LAB_145F
 | |
| 	CLC				; clear found flag
 | |
| LAB_1460
 | |
| 	RTS
 | |
| 
 | |
| ; perform NEW
 | |
| 
 | |
| LAB_NEW
 | |
| 	BNE	LAB_1460		; exit if not end of statement (to do syntax error)
 | |
| 
 | |
| LAB_1463
 | |
| 	LDA	#$00			; clear A
 | |
| 	TAY				; clear Y
 | |
| 	STA	(Smeml),Y		; clear first line, next line pointer, low byte
 | |
| 	INY				; increment index
 | |
| 	STA	(Smeml),Y		; clear first line, next line pointer, high byte
 | |
| 	CLC				; clear carry
 | |
| 	LDA	Smeml			; get start of mem low byte
 | |
| 	ADC	#$02			; calculate end of BASIC low byte
 | |
| 	STA	Svarl			; save start of vars low byte
 | |
| 	LDA	Smemh			; get start of mem high byte
 | |
| 	ADC	#$00			; add any carry
 | |
| 	STA	Svarh			; save start of vars high byte
 | |
| 
 | |
| ; reset execution to start, clear vars and flush stack
 | |
| 
 | |
| LAB_1477
 | |
| 	CLC				; clear carry
 | |
| 	LDA	Smeml			; get start of mem low byte
 | |
| 	ADC	#$FF			; -1
 | |
| 	STA	Bpntrl		; save BASIC execute pointer low byte
 | |
| 	LDA	Smemh			; get start of mem high byte
 | |
| 	ADC	#$FF			; -1+carry
 | |
| 	STA	Bpntrh		; save BASIC execute pointer high byte
 | |
| 
 | |
| ; "CLEAR" command gets here
 | |
| 
 | |
| LAB_147A
 | |
| 	LDA	Ememl			; get end of mem low byte
 | |
| 	LDY	Ememh			; get end of mem high byte
 | |
| 	STA	Sstorl		; set bottom of string space low byte
 | |
| 	STY	Sstorh		; set bottom of string space high byte
 | |
| 	LDA	Svarl			; get start of vars low byte
 | |
| 	LDY	Svarh			; get start of vars high byte
 | |
| 	STA	Sarryl		; save var mem end low byte
 | |
| 	STY	Sarryh		; save var mem end high byte
 | |
| 	STA	Earryl		; save array mem end low byte
 | |
| 	STY	Earryh		; save array mem end high byte
 | |
| 	JSR	LAB_161A		; perform RESTORE command
 | |
| 
 | |
| ; flush stack and clear continue flag
 | |
| 
 | |
| LAB_1491
 | |
| 	LDX	#des_sk		; set descriptor stack pointer
 | |
| 	STX	next_s		; save descriptor stack pointer
 | |
| 	PLA				; pull return address low byte
 | |
| 	TAX				; copy return address low byte
 | |
| 	PLA				; pull return address high byte
 | |
| 	STX	LAB_SKFE		; save to cleared stack
 | |
| 	STA	LAB_SKFF		; save to cleared stack
 | |
| 	LDX	#$FD			; new stack pointer
 | |
| 	TXS				; reset stack
 | |
| 	LDA	#$00			; clear byte
 | |
| 	STA	Cpntrh		; clear continue pointer high byte
 | |
| 	STA	Sufnxf		; clear subscript/FNX flag
 | |
| LAB_14A6
 | |
| 	RTS
 | |
| 
 | |
| ; perform CLEAR
 | |
| 
 | |
| LAB_CLEAR
 | |
| 	BEQ	LAB_147A		; if no following token go do "CLEAR"
 | |
| 
 | |
| 					; else there was a following token (go do syntax error)
 | |
| 	RTS
 | |
| 
 | |
| ; perform LIST [n][-m]
 | |
| ; bigger, faster version (a _lot_ faster)
 | |
| 
 | |
| LAB_LIST
 | |
| 	BCC	LAB_14BD		; branch if next character numeric (LIST n..)
 | |
| 
 | |
| 	BEQ	LAB_14BD		; branch if next character [NULL] (LIST)
 | |
| 
 | |
| 	CMP	#TK_MINUS		; compare with token for -
 | |
| 	BNE	LAB_14A6		; exit if not - (LIST -m)
 | |
| 
 | |
| 					; LIST [[n][-m]]
 | |
| 					; this bit sets the n , if present, as the start and end
 | |
| LAB_14BD
 | |
| 	JSR	LAB_GFPN		; get fixed-point number into temp integer
 | |
| 	JSR	LAB_SSLN		; search BASIC for temp integer line number
 | |
| 					; (pointer in Baslnl/Baslnh)
 | |
| 	JSR	LAB_GBYT		; scan memory
 | |
| 	BEQ	LAB_14D4		; branch if no more characters
 | |
| 
 | |
| 					; this bit checks the - is present
 | |
| 	CMP	#TK_MINUS		; compare with token for -
 | |
| 	BNE	LAB_1460		; return if not "-" (will be Syntax error)
 | |
| 
 | |
| 					; LIST [n]-m
 | |
| 					; the - was there so set m as the end value
 | |
| 	JSR	LAB_IGBY		; increment and scan memory
 | |
| 	JSR	LAB_GFPN		; get fixed-point number into temp integer
 | |
| 	BNE	LAB_1460		; exit if not ok
 | |
| 
 | |
| LAB_14D4
 | |
| 	LDA	Itempl		; get temporary integer low byte
 | |
| 	ORA	Itemph		; OR temporary integer high byte
 | |
| 	BNE	LAB_14E2		; branch if start set
 | |
| 
 | |
| 	LDA	#$FF			; set for -1
 | |
| 	STA	Itempl		; set temporary integer low byte
 | |
| 	STA	Itemph		; set temporary integer high byte
 | |
| LAB_14E2
 | |
| 	LDY	#$01			; set index for line
 | |
| 	STY	Oquote		; clear open quote flag
 | |
| 	JSR	LAB_CRLF		; print CR/LF
 | |
| 	LDA	(Baslnl),Y		; get next line pointer high byte
 | |
| 					; pointer initially set by search at LAB_14BD
 | |
| 	BEQ	LAB_152B		; if null all done so exit
 | |
| 	JSR	LAB_1629		; do CRTL-C check vector
 | |
| 
 | |
| 	INY				; increment index for line
 | |
| 	LDA	(Baslnl),Y		; get line # low byte
 | |
| 	TAX				; copy to X
 | |
| 	INY				; increment index
 | |
| 	LDA	(Baslnl),Y		; get line # high byte
 | |
| 	CMP	Itemph		; compare with temporary integer high byte
 | |
| 	BNE	LAB_14FF		; branch if no high byte match
 | |
| 
 | |
| 	CPX	Itempl		; compare with temporary integer low byte
 | |
| 	BEQ	LAB_1501		; branch if = last line to do (< will pass next branch)
 | |
| 
 | |
| LAB_14FF				; else ..
 | |
| 	BCS	LAB_152B		; if greater all done so exit
 | |
| 
 | |
| LAB_1501
 | |
| 	STY	Tidx1			; save index for line
 | |
| 	JSR	LAB_295E		; print XA as unsigned integer
 | |
| 	LDA	#$20			; space is the next character
 | |
| LAB_1508
 | |
| 	LDY	Tidx1			; get index for line
 | |
| 	AND	#$7F			; mask top out bit of character
 | |
| LAB_150C
 | |
| 	JSR	LAB_PRNA		; go print the character
 | |
| 	CMP	#$22			; was it " character
 | |
| 	BNE	LAB_1519		; branch if not
 | |
| 
 | |
| 					; we are either entering or leaving a pair of quotes
 | |
| 	LDA	Oquote		; get open quote flag
 | |
| 	EOR	#$FF			; toggle it
 | |
| 	STA	Oquote		; save it back
 | |
| LAB_1519
 | |
| 	INY				; increment index
 | |
| 	LDA	(Baslnl),Y		; get next byte
 | |
| 	BNE	LAB_152E		; branch if not [EOL] (go print character)
 | |
| 	TAY				; else clear index
 | |
| 	LDA	(Baslnl),Y		; get next line pointer low byte
 | |
| 	TAX				; copy to X
 | |
| 	INY				; increment index
 | |
| 	LDA	(Baslnl),Y		; get next line pointer high byte
 | |
| 	STX	Baslnl		; set pointer to line low byte
 | |
| 	STA	Baslnh		; set pointer to line high byte
 | |
| 	BNE	LAB_14E2		; go do next line if not [EOT]
 | |
| 					; else ..
 | |
| LAB_152B
 | |
| 	RTS
 | |
| 
 | |
| LAB_152E
 | |
| 	BPL	LAB_150C		; just go print it if not token byte
 | |
| 
 | |
| 					; else was token byte so uncrunch it (maybe)
 | |
| 	BIT	Oquote		; test the open quote flag
 | |
| 	BMI	LAB_150C		; just go print character if open quote set
 | |
| 
 | |
| 	LDX	#>LAB_KEYT		; get table address high byte
 | |
| 	ASL				; *2
 | |
| 	ASL				; *4
 | |
| 	BCC	LAB_152F		; branch if no carry
 | |
| 
 | |
| 	INX				; else increment high byte
 | |
| 	CLC				; clear carry for add
 | |
| LAB_152F
 | |
| 	ADC	#<LAB_KEYT		; add low byte
 | |
| 	BCC	LAB_1530		; branch if no carry
 | |
| 
 | |
| 	INX				; else increment high byte
 | |
| LAB_1530
 | |
| 	STA	ut2_pl		; save table pointer low byte
 | |
| 	STX	ut2_ph		; save table pointer high byte
 | |
| 	STY	Tidx1			; save index for line
 | |
| 	LDY	#$00			; clear index
 | |
| 	LDA	(ut2_pl),Y		; get length
 | |
| 	TAX				; copy length
 | |
| 	INY				; increment index
 | |
| 	LDA	(ut2_pl),Y		; get 1st character
 | |
| 	DEX				; decrement length
 | |
| 	BEQ	LAB_1508		; if no more characters exit and print
 | |
| 
 | |
| 	JSR	LAB_PRNA		; go print the character
 | |
| 	INY				; increment index
 | |
| 	LDA	(ut2_pl),Y		; get keyword address low byte
 | |
| 	PHA				; save it for now
 | |
| 	INY				; increment index
 | |
| 	LDA	(ut2_pl),Y		; get keyword address high byte
 | |
| 	LDY	#$00
 | |
| 	STA	ut2_ph		; save keyword pointer high byte
 | |
| 	PLA				; pull low byte
 | |
| 	STA	ut2_pl		; save keyword pointer low byte
 | |
| LAB_1540
 | |
| 	LDA	(ut2_pl),Y		; get character
 | |
| 	DEX				; decrement character count
 | |
| 	BEQ	LAB_1508		; if last character exit and print
 | |
| 
 | |
| 	JSR	LAB_PRNA		; go print the character
 | |
| 	INY				; increment index
 | |
| 	BNE	LAB_1540		; loop for next character
 | |
| 
 | |
| ; perform FOR
 | |
| 
 | |
| LAB_FOR
 | |
| 	LDA	#$80			; set FNX
 | |
| 	STA	Sufnxf		; set subscript/FNX flag
 | |
| 	JSR	LAB_LET		; go do LET
 | |
| 	PLA				; pull return address
 | |
| 	PLA				; pull return address
 | |
| 	LDA	#$10			; we need 16d bytes !
 | |
| 	JSR	LAB_1212		; check room on stack for A bytes
 | |
| 	JSR	LAB_SNBS		; scan for next BASIC statement ([:] or [EOL])
 | |
| 	CLC				; clear carry for add
 | |
| 	TYA				; copy index to A
 | |
| 	ADC	Bpntrl		; add BASIC execute pointer low byte
 | |
| 	PHA				; push onto stack
 | |
| 	LDA	Bpntrh		; get BASIC execute pointer high byte
 | |
| 	ADC	#$00			; add carry
 | |
| 	PHA				; push onto stack
 | |
| 	LDA	Clineh		; get current line high byte
 | |
| 	PHA				; push onto stack
 | |
| 	LDA	Clinel		; get current line low byte
 | |
| 	PHA				; push onto stack
 | |
| 	LDA	#TK_TO		; get "TO" token
 | |
| 	JSR	LAB_SCCA		; scan for CHR$(A) , else do syntax error then warm start
 | |
| 	JSR	LAB_CTNM		; check if source is numeric, else do type mismatch
 | |
| 	JSR	LAB_EVNM		; evaluate expression and check is numeric,
 | |
| 					; else do type mismatch
 | |
| 	LDA	FAC1_s		; get FAC1 sign (b7)
 | |
| 	ORA	#$7F			; set all non sign bits
 | |
| 	AND	FAC1_1		; and FAC1 mantissa1
 | |
| 	STA	FAC1_1		; save FAC1 mantissa1
 | |
| 	LDA	#<LAB_159F		; set return address low byte
 | |
| 	LDY	#>LAB_159F		; set return address high byte
 | |
| 	STA	ut1_pl		; save return address low byte
 | |
| 	STY	ut1_ph		; save return address high byte
 | |
| 	JMP	LAB_1B66		; round FAC1 and put on stack (returns to next instruction)
 | |
| 
 | |
| LAB_159F
 | |
| 	LDA	#<LAB_259C		; set 1 pointer low addr (default step size)
 | |
| 	LDY	#>LAB_259C		; set 1 pointer high addr
 | |
| 	JSR	LAB_UFAC		; unpack memory (AY) into FAC1
 | |
| 	JSR	LAB_GBYT		; scan memory
 | |
| 	CMP	#TK_STEP		; compare with STEP token
 | |
| 	BNE	LAB_15B3		; jump if not "STEP"
 | |
| 
 | |
| 					;.was step so ..
 | |
| 	JSR	LAB_IGBY		; increment and scan memory
 | |
| 	JSR	LAB_EVNM		; evaluate expression and check is numeric,
 | |
| 					; else do type mismatch
 | |
| LAB_15B3
 | |
| 	JSR	LAB_27CA		; return A=FF,C=1/-ve A=01,C=0/+ve
 | |
| 	STA	FAC1_s		; set FAC1 sign (b7)
 | |
| 					; this is +1 for +ve step and -1 for -ve step, in NEXT we
 | |
| 					; compare the FOR value and the TO value and return +1 if
 | |
| 					; FOR > TO, 0 if FOR = TO and -1 if FOR < TO. the value
 | |
| 					; here (+/-1) is then compared to that result and if they
 | |
| 					; are the same (+ve and FOR > TO or -ve and FOR < TO) then
 | |
| 					; the loop is done
 | |
| 	JSR	LAB_1B5B		; push sign, round FAC1 and put on stack
 | |
| 	LDA	Frnxth		; get var pointer for FOR/NEXT high byte
 | |
| 	PHA				; push on stack
 | |
| 	LDA	Frnxtl		; get var pointer for FOR/NEXT low byte
 | |
| 	PHA				; push on stack
 | |
| 	LDA	#TK_FOR		; get FOR token
 | |
| 	PHA				; push on stack
 | |
| 
 | |
| ; interpreter inner loop
 | |
| 
 | |
| LAB_15C2
 | |
| 	JSR	LAB_1629		; do CRTL-C check vector
 | |
| 	LDA	Bpntrl		; get BASIC execute pointer low byte
 | |
| 	LDY	Bpntrh		; get BASIC execute pointer high byte
 | |
| 
 | |
| 	LDX	Clineh		; continue line is $FFxx for immediate mode
 | |
| 					; ($00xx for RUN from immediate mode)
 | |
| 	INX				; increment it (now $00 if immediate mode)
 | |
| 	BEQ	LAB_15D1		; branch if null (immediate mode)
 | |
| 
 | |
| 	STA	Cpntrl		; save continue pointer low byte
 | |
| 	STY	Cpntrh		; save continue pointer high byte
 | |
| LAB_15D1
 | |
| 	LDY	#$00			; clear index
 | |
| 	LDA	(Bpntrl),Y		; get next byte
 | |
| 	BEQ	LAB_15DC		; branch if null [EOL]
 | |
| 
 | |
| 	CMP	#':'			; compare with ":"
 | |
| 	BEQ	LAB_15F6		; branch if = (statement separator)
 | |
| 
 | |
| LAB_15D9
 | |
| 	JMP	LAB_SNER		; else syntax error then warm start
 | |
| 
 | |
| 					; have reached [EOL]
 | |
| LAB_15DC
 | |
| 	LDY	#$02			; set index
 | |
| 	LDA	(Bpntrl),Y		; get next line pointer high byte
 | |
| 	CLC				; clear carry for no "BREAK" message
 | |
| 	BEQ	LAB_1651		; if null go to immediate mode (was immediate or [EOT]
 | |
| 					; marker)
 | |
| 
 | |
| 	INY				; increment index
 | |
| 	LDA	(Bpntrl),Y		; get line # low byte
 | |
| 	STA	Clinel		; save current line low byte
 | |
| 	INY				; increment index
 | |
| 	LDA	(Bpntrl),Y		; get line # high byte
 | |
| 	STA	Clineh		; save current line high byte
 | |
| 	TYA				; A now = 4
 | |
| 	ADC	Bpntrl		; add BASIC execute pointer low byte
 | |
| 	STA	Bpntrl		; save BASIC execute pointer low byte
 | |
| 	BCC	LAB_15F6		; branch if no overflow
 | |
| 
 | |
| 	INC	Bpntrh		; else increment BASIC execute pointer high byte
 | |
| LAB_15F6
 | |
| 	JSR	LAB_IGBY		; increment and scan memory
 | |
| 
 | |
| LAB_15F9
 | |
| 	JSR	LAB_15FF		; go interpret BASIC code from (Bpntrl)
 | |
| 
 | |
| LAB_15FC
 | |
| 	JMP	LAB_15C2		; loop
 | |
| 
 | |
| ; interpret BASIC code from (Bpntrl)
 | |
| 
 | |
| LAB_15FF
 | |
| 	BEQ	LAB_1628		; exit if zero [EOL]
 | |
| 
 | |
| LAB_1602
 | |
| 	ASL				; *2 bytes per vector and normalise token
 | |
| 	BCS	LAB_1609		; branch if was token
 | |
| 
 | |
| 	JMP	LAB_LET		; else go do implied LET
 | |
| 
 | |
| LAB_1609
 | |
| 	CMP	#(TK_TAB-$80)*2	; compare normalised token * 2 with TAB
 | |
| 	BCS	LAB_15D9		; branch if A>=TAB (do syntax error then warm start)
 | |
| 					; only tokens before TAB can start a line
 | |
| 	TAY				; copy to index
 | |
| 	LDA	LAB_CTBL+1,Y	; get vector high byte
 | |
| 	PHA				; onto stack
 | |
| 	LDA	LAB_CTBL,Y		; get vector low byte
 | |
| 	PHA				; onto stack
 | |
| 	JMP	LAB_IGBY		; jump to increment and scan memory
 | |
| 					; then "return" to vector
 | |
| 
 | |
| ; CTRL-C check jump. this is called as a subroutine but exits back via a jump if a
 | |
| ; key press is detected.
 | |
| 
 | |
| LAB_1629
 | |
| 	JMP	(VEC_CC)		; ctrl c check vector
 | |
| 
 | |
| ; if there was a key press it gets back here ..
 | |
| 
 | |
| LAB_1636
 | |
| 	CMP	#$03			; compare with CTRL-C
 | |
| 
 | |
| ; perform STOP
 | |
| 
 | |
| LAB_STOP
 | |
| 	BCS	LAB_163B		; branch if token follows STOP
 | |
| 					; else just END
 | |
| ; END
 | |
| 
 | |
| LAB_END
 | |
| 	CLC				; clear the carry, indicate a normal program end
 | |
| LAB_163B
 | |
| 	BNE	LAB_167A		; if wasn't CTRL-C or there is a following byte return
 | |
| 
 | |
| 	LDA	Bpntrh		; get the BASIC execute pointer high byte
 | |
| 	EOR	#>Ibuffs		; compare with buffer address high byte (Cb unchanged)
 | |
| 	BEQ	LAB_164F		; branch if the BASIC pointer is in the input buffer
 | |
| 					; (can't continue in immediate mode)
 | |
| 
 | |
| 					; else ..
 | |
| 	EOR	#>Ibuffs		; correct the bits
 | |
| 	LDY	Bpntrl		; get BASIC execute pointer low byte
 | |
| 	STY	Cpntrl		; save continue pointer low byte
 | |
| 	STA	Cpntrh		; save continue pointer high byte
 | |
| LAB_1647
 | |
| 	LDA	Clinel		; get current line low byte
 | |
| 	LDY	Clineh		; get current line high byte
 | |
| 	STA	Blinel		; save break line low byte
 | |
| 	STY	Blineh		; save break line high byte
 | |
| LAB_164F
 | |
| 	PLA				; pull return address low
 | |
| 	PLA				; pull return address high
 | |
| LAB_1651
 | |
| 	BCC	LAB_165E		; if was program end just do warm start
 | |
| 
 | |
| 					; else ..
 | |
| 	LDA	#<LAB_BMSG		; point to "Break" low byte
 | |
| 	LDY	#>LAB_BMSG		; point to "Break" high byte
 | |
| 	JMP	LAB_1269		; print "Break" and do warm start
 | |
| 
 | |
| LAB_165E
 | |
| 	JMP	LAB_1274		; go do warm start
 | |
| 
 | |
| ; perform RESTORE
 | |
| 
 | |
| LAB_RESTORE
 | |
| 	BNE	LAB_RESTOREn	; branch if next character not null (RESTORE n)
 | |
| 
 | |
| LAB_161A
 | |
| 	SEC				; set carry for subtract
 | |
| 	LDA	Smeml			; get start of mem low byte
 | |
| 	SBC	#$01			; -1
 | |
| 	LDY	Smemh			; get start of mem high byte
 | |
| 	BCS	LAB_1624		; branch if no underflow
 | |
| 
 | |
| LAB_uflow
 | |
| 	DEY				; else decrement high byte
 | |
| LAB_1624
 | |
| 	STA	Dptrl			; save DATA pointer low byte
 | |
| 	STY	Dptrh			; save DATA pointer high byte
 | |
| LAB_1628
 | |
| 	RTS
 | |
| 
 | |
| 					; is RESTORE n
 | |
| LAB_RESTOREn
 | |
| 	JSR	LAB_GFPN		; get fixed-point number into temp integer
 | |
| 	JSR	LAB_SNBL		; scan for next BASIC line
 | |
| 	LDA	Clineh		; get current line high byte
 | |
| 	CMP	Itemph		; compare with temporary integer high byte
 | |
| 	BCS	LAB_reset_search	; branch if >= (start search from beginning)
 | |
| 
 | |
| 	TYA				; else copy line index to A
 | |
| 	SEC				; set carry (+1)
 | |
| 	ADC	Bpntrl		; add BASIC execute pointer low byte
 | |
| 	LDX	Bpntrh		; get BASIC execute pointer high byte
 | |
| 	BCC	LAB_go_search	; branch if no overflow to high byte
 | |
| 
 | |
| 	INX				; increment high byte
 | |
| 	BCS	LAB_go_search	; branch always (can never be carry clear)
 | |
| 
 | |
| ; search for line # in temp (Itempl/Itemph) from start of mem pointer (Smeml)
 | |
| 
 | |
| LAB_reset_search
 | |
| 	LDA	Smeml			; get start of mem low byte
 | |
| 	LDX	Smemh			; get start of mem high byte
 | |
| 
 | |
| ; search for line # in temp (Itempl/Itemph) from (AX)
 | |
| 
 | |
| LAB_go_search
 | |
| 
 | |
| 	JSR	LAB_SHLN		; search Basic for temp integer line number from AX
 | |
| 	BCS	LAB_line_found	; if carry set go set pointer
 | |
| 
 | |
| 	JMP	LAB_16F7		; else go do "Undefined statement" error
 | |
| 
 | |
| LAB_line_found
 | |
| 					; carry already set for subtract
 | |
| 	LDA	Baslnl		; get pointer low byte
 | |
| 	SBC	#$01			; -1
 | |
| 	LDY	Baslnh		; get pointer high byte
 | |
| 	BCS	LAB_1624		; branch if no underflow (save DATA pointer and return)
 | |
| 
 | |
| 	BCC	LAB_uflow		; else decrement high byte then save DATA pointer and
 | |
| 					; return (branch always)
 | |
| 
 | |
| ; perform NULL
 | |
| 
 | |
| LAB_NULL
 | |
| 	JSR	LAB_GTBY		; get byte parameter
 | |
| 	STX	Nullct		; save new NULL count
 | |
| LAB_167A
 | |
| 	RTS
 | |
| 
 | |
| ; perform CONT
 | |
| 
 | |
| LAB_CONT
 | |
| 	BNE	LAB_167A		; if following byte exit to do syntax error
 | |
| 
 | |
| 	LDY	Cpntrh		; get continue pointer high byte
 | |
| 	BNE	LAB_166C		; go do continue if we can
 | |
| 
 | |
| 	LDX	#$1E			; error code $1E ("Can't continue" error)
 | |
| 	JMP	LAB_XERR		; do error #X, then warm start
 | |
| 
 | |
| 					; we can continue so ..
 | |
| LAB_166C
 | |
| 	LDA	#TK_ON		; set token for ON
 | |
| 	JSR	LAB_IRQ		; set IRQ flags
 | |
| 	LDA	#TK_ON		; set token for ON
 | |
| 	JSR	LAB_NMI		; set NMI flags
 | |
| 
 | |
| 	STY	Bpntrh		; save BASIC execute pointer high byte
 | |
| 	LDA	Cpntrl		; get continue pointer low byte
 | |
| 	STA	Bpntrl		; save BASIC execute pointer low byte
 | |
| 	LDA	Blinel		; get break line low byte
 | |
| 	LDY	Blineh		; get break line high byte
 | |
| 	STA	Clinel		; set current line low byte
 | |
| 	STY	Clineh		; set current line high byte
 | |
| 	RTS
 | |
| 
 | |
| ; perform RUN
 | |
| 
 | |
| LAB_RUN
 | |
| 	BNE	LAB_1696		; branch if RUN n
 | |
| 	JMP	LAB_1477		; reset execution to start, clear variables, flush stack and
 | |
| 					; return
 | |
| 
 | |
| ; does RUN n
 | |
| 
 | |
| LAB_1696
 | |
| 	JSR	LAB_147A		; go do "CLEAR"
 | |
| 	BEQ	LAB_16B0		; get n and do GOTO n (branch always as CLEAR sets Z=1)
 | |
| 
 | |
| ; perform DO
 | |
| 
 | |
| LAB_DO
 | |
| 	LDA	#$05			; need 5 bytes for DO
 | |
| 	JSR	LAB_1212		; check room on stack for A bytes
 | |
| 	LDA	Bpntrh		; get BASIC execute pointer high byte
 | |
| 	PHA				; push on stack
 | |
| 	LDA	Bpntrl		; get BASIC execute pointer low byte
 | |
| 	PHA				; push on stack
 | |
| 	LDA	Clineh		; get current line high byte
 | |
| 	PHA				; push on stack
 | |
| 	LDA	Clinel		; get current line low byte
 | |
| 	PHA				; push on stack
 | |
| 	LDA	#TK_DO		; token for DO
 | |
| 	PHA				; push on stack
 | |
| 	JSR	LAB_GBYT		; scan memory
 | |
| 	JMP	LAB_15C2		; go do interpreter inner loop
 | |
| 
 | |
| ; perform GOSUB
 | |
| 
 | |
| LAB_GOSUB
 | |
| 	LDA	#$05			; need 5 bytes for GOSUB
 | |
| 	JSR	LAB_1212		; check room on stack for A bytes
 | |
| 	LDA	Bpntrh		; get BASIC execute pointer high byte
 | |
| 	PHA				; push on stack
 | |
| 	LDA	Bpntrl		; get BASIC execute pointer low byte
 | |
| 	PHA				; push on stack
 | |
| 	LDA	Clineh		; get current line high byte
 | |
| 	PHA				; push on stack
 | |
| 	LDA	Clinel		; get current line low byte
 | |
| 	PHA				; push on stack
 | |
| 	LDA	#TK_GOSUB		; token for GOSUB
 | |
| 	PHA				; push on stack
 | |
| LAB_16B0
 | |
| 	JSR	LAB_GBYT		; scan memory
 | |
| 	JSR	LAB_GOTO		; perform GOTO n
 | |
| 	JMP	LAB_15C2		; go do interpreter inner loop
 | |
| 					; (can't RTS, we used the stack!)
 | |
| 
 | |
| ; perform GOTO
 | |
| 
 | |
| LAB_GOTO
 | |
| 	JSR	LAB_GFPN		; get fixed-point number into temp integer
 | |
| 	JSR	LAB_SNBL		; scan for next BASIC line
 | |
| 	LDA	Clineh		; get current line high byte
 | |
| 	CMP	Itemph		; compare with temporary integer high byte
 | |
| 	BCS	LAB_16D0		; branch if >= (start search from beginning)
 | |
| 
 | |
| 	TYA				; else copy line index to A
 | |
| 	SEC				; set carry (+1)
 | |
| 	ADC	Bpntrl		; add BASIC execute pointer low byte
 | |
| 	LDX	Bpntrh		; get BASIC execute pointer high byte
 | |
| 	BCC	LAB_16D4		; branch if no overflow to high byte
 | |
| 
 | |
| 	INX				; increment high byte
 | |
| 	BCS	LAB_16D4		; branch always (can never be carry)
 | |
| 
 | |
| ; search for line # in temp (Itempl/Itemph) from start of mem pointer (Smeml)
 | |
| 
 | |
| LAB_16D0
 | |
| 	LDA	Smeml			; get start of mem low byte
 | |
| 	LDX	Smemh			; get start of mem high byte
 | |
| 
 | |
| ; search for line # in temp (Itempl/Itemph) from (AX)
 | |
| 
 | |
| LAB_16D4
 | |
| 	JSR	LAB_SHLN		; search Basic for temp integer line number from AX
 | |
| 	BCC	LAB_16F7		; if carry clear go do "Undefined statement" error
 | |
| 					; (unspecified statement)
 | |
| 
 | |
| 					; carry already set for subtract
 | |
| 	LDA	Baslnl		; get pointer low byte
 | |
| 	SBC	#$01			; -1
 | |
| 	STA	Bpntrl		; save BASIC execute pointer low byte
 | |
| 	LDA	Baslnh		; get pointer high byte
 | |
| 	SBC	#$00			; subtract carry
 | |
| 	STA	Bpntrh		; save BASIC execute pointer high byte
 | |
| LAB_16E5
 | |
| 	RTS
 | |
| 
 | |
| LAB_DONOK
 | |
| 	LDX	#$22			; error code $22 ("LOOP without DO" error)
 | |
| 	JMP	LAB_XERR		; do error #X, then warm start
 | |
| 
 | |
| ; perform LOOP
 | |
| 
 | |
| LAB_LOOP
 | |
| 	TAY				; save following token
 | |
| 	TSX				; copy stack pointer
 | |
| 	LDA	LAB_STAK+3,X	; get token byte from stack
 | |
| 	CMP	#TK_DO		; compare with DO token
 | |
| 	BNE	LAB_DONOK		; branch if no matching DO
 | |
| 
 | |
| 	INX				; dump calling routine return address
 | |
| 	INX				; dump calling routine return address
 | |
| 	TXS				; correct stack
 | |
| 	TYA				; get saved following token back
 | |
| 	BEQ	LoopAlways		; if no following token loop forever
 | |
| 					; (stack pointer in X)
 | |
| 
 | |
| 	CMP	#':'			; could be ':'
 | |
| 	BEQ	LoopAlways		; if :... loop forever
 | |
| 
 | |
| 	SBC	#TK_UNTIL		; subtract token for UNTIL, we know carry is set here
 | |
| 	TAX				; copy to X (if it was UNTIL then Y will be correct)
 | |
| 	BEQ	DoRest		; branch if was UNTIL
 | |
| 
 | |
| 	DEX				; decrement result
 | |
| 	BNE	LAB_16FC		; if not WHILE go do syntax error and warm start
 | |
| 					; only if the token was WHILE will this fail
 | |
| 
 | |
| 	DEX				; set invert result byte
 | |
| DoRest
 | |
| 	STX	Frnxth		; save invert result byte
 | |
| 	JSR	LAB_IGBY		; increment and scan memory
 | |
| 	JSR	LAB_EVEX		; evaluate expression
 | |
| 	LDA	FAC1_e		; get FAC1 exponent
 | |
| 	BEQ	DoCmp			; if =0 go do straight compare
 | |
| 
 | |
| 	LDA	#$FF			; else set all bits
 | |
| DoCmp
 | |
| 	TSX				; copy stack pointer
 | |
| 	EOR	Frnxth		; EOR with invert byte
 | |
| 	BNE	LoopDone		; if <> 0 clear stack and back to interpreter loop
 | |
| 
 | |
| 					; loop condition wasn't met so do it again
 | |
| LoopAlways
 | |
| 	LDA	LAB_STAK+2,X	; get current line low byte
 | |
| 	STA	Clinel		; save current line low byte
 | |
| 	LDA	LAB_STAK+3,X	; get current line high byte
 | |
| 	STA	Clineh		; save current line high byte
 | |
| 	LDA	LAB_STAK+4,X	; get BASIC execute pointer low byte
 | |
| 	STA	Bpntrl		; save BASIC execute pointer low byte
 | |
| 	LDA	LAB_STAK+5,X	; get BASIC execute pointer high byte
 | |
| 	STA	Bpntrh		; save BASIC execute pointer high byte
 | |
| 	JSR	LAB_GBYT		; scan memory
 | |
| 	JMP	LAB_15C2		; go do interpreter inner loop
 | |
| 
 | |
| 					; clear stack and back to interpreter loop
 | |
| LoopDone
 | |
| 	INX				; dump DO token
 | |
| 	INX				; dump current line low byte
 | |
| 	INX				; dump current line high byte
 | |
| 	INX				; dump BASIC execute pointer low byte
 | |
| 	INX				; dump BASIC execute pointer high byte
 | |
| 	TXS				; correct stack
 | |
| 	JMP	LAB_DATA		; go perform DATA (find : or [EOL])
 | |
| 
 | |
| ; do the return without gosub error
 | |
| 
 | |
| LAB_16F4
 | |
| 	LDX	#$04			; error code $04 ("RETURN without GOSUB" error)
 | |
| 	.byte	$2C			; makes next line BIT LAB_0EA2
 | |
| 
 | |
| LAB_16F7				; do undefined statement error
 | |
| 	LDX	#$0E			; error code $0E ("Undefined statement" error)
 | |
| 	JMP	LAB_XERR		; do error #X, then warm start
 | |
| 
 | |
| ; perform RETURN
 | |
| 
 | |
| LAB_RETURN
 | |
| 	BNE	LAB_16E5		; exit if following token (to allow syntax error)
 | |
| 
 | |
| LAB_16E8
 | |
| 	PLA				; dump calling routine return address
 | |
| 	PLA				; dump calling routine return address
 | |
| 	PLA				; pull token
 | |
| 	CMP	#TK_GOSUB		; compare with GOSUB token
 | |
| 	BNE	LAB_16F4		; branch if no matching GOSUB
 | |
| 
 | |
| LAB_16FF
 | |
| 	PLA				; pull current line low byte
 | |
| 	STA	Clinel		; save current line low byte
 | |
| 	PLA				; pull current line high byte
 | |
| 	STA	Clineh		; save current line high byte
 | |
| 	PLA				; pull BASIC execute pointer low byte
 | |
| 	STA	Bpntrl		; save BASIC execute pointer low byte
 | |
| 	PLA				; pull BASIC execute pointer high byte
 | |
| 	STA	Bpntrh		; save BASIC execute pointer high byte
 | |
| 
 | |
| 					; now do the DATA statement as we could be returning into
 | |
| 					; the middle of an ON <var> GOSUB n,m,p,q line
 | |
| 					; (the return address used by the DATA statement is the one
 | |
| 					; pushed before the GOSUB was executed!)
 | |
| 
 | |
| ; perform DATA
 | |
| 
 | |
| LAB_DATA
 | |
| 	JSR	LAB_SNBS		; scan for next BASIC statement ([:] or [EOL])
 | |
| 
 | |
| 					; set BASIC execute pointer
 | |
| LAB_170F
 | |
| 	TYA				; copy index to A
 | |
| 	CLC				; clear carry for add
 | |
| 	ADC	Bpntrl		; add BASIC execute pointer low byte
 | |
| 	STA	Bpntrl		; save BASIC execute pointer low byte
 | |
| 	BCC	LAB_1719		; skip next if no carry
 | |
| 
 | |
| 	INC	Bpntrh		; else increment BASIC execute pointer high byte
 | |
| LAB_1719
 | |
| 	RTS
 | |
| 
 | |
| LAB_16FC
 | |
| 	JMP	LAB_SNER		; do syntax error then warm start
 | |
| 
 | |
| ; scan for next BASIC statement ([:] or [EOL])
 | |
| ; returns Y as index to [:] or [EOL]
 | |
| 
 | |
| LAB_SNBS
 | |
| 	LDX	#':'			; set look for character = ":"
 | |
| 	.byte	$2C			; makes next line BIT $00A2
 | |
| 
 | |
| ; scan for next BASIC line
 | |
| ; returns Y as index to [EOL]
 | |
| 
 | |
| LAB_SNBL
 | |
| 	LDX	#$00			; set alt search character = [EOL]
 | |
| 	LDY	#$00			; set search character = [EOL]
 | |
| 	STY	Asrch			; store search character
 | |
| LAB_1725
 | |
| 	TXA				; get alt search character
 | |
| 	EOR	Asrch			; toggle search character, effectively swap with $00
 | |
| 	STA	Asrch			; save swapped search character
 | |
| LAB_172D
 | |
| 	LDA	(Bpntrl),Y		; get next byte
 | |
| 	BEQ	LAB_1719		; exit if null [EOL]
 | |
| 
 | |
| 	CMP	Asrch			; compare with search character
 | |
| 	BEQ	LAB_1719		; exit if found
 | |
| 
 | |
| 	INY				; increment index
 | |
| 	CMP	#$22			; compare current character with open quote
 | |
| 	BNE	LAB_172D		; if not open quote go get next character
 | |
| 
 | |
| 	BEQ	LAB_1725		; if found go swap search character for alt search character
 | |
| 
 | |
| ; perform IF
 | |
| 
 | |
| LAB_IF
 | |
| 	JSR	LAB_EVEX		; evaluate the expression
 | |
| 	JSR	LAB_GBYT		; scan memory
 | |
| 	CMP	#TK_THEN		; compare with THEN token
 | |
| 	BEQ	LAB_174B		; if it was THEN go do IF
 | |
| 
 | |
| 					; wasn't IF .. THEN so must be IF .. GOTO
 | |
| 	CMP	#TK_GOTO		; compare with GOTO token
 | |
| 	BNE	LAB_16FC		; if it wasn't GOTO go do syntax error
 | |
| 
 | |
| 	LDX	Bpntrl		; save the basic pointer low byte
 | |
| 	LDY	Bpntrh		; save the basic pointer high byte
 | |
| 	JSR	LAB_IGBY		; increment and scan memory
 | |
| 	BCS	LAB_16FC		; if not numeric go do syntax error
 | |
| 
 | |
| 	STX	Bpntrl		; restore the basic pointer low byte
 | |
| 	STY	Bpntrh		; restore the basic pointer high byte
 | |
| LAB_174B
 | |
| 	LDA	FAC1_e		; get FAC1 exponent
 | |
| 	BEQ	LAB_174E		; if the result was zero go look for an ELSE
 | |
| 
 | |
| 	JSR	LAB_IGBY		; else increment and scan memory
 | |
| 	BCS	LAB_174D		; if not numeric go do var or keyword
 | |
| 
 | |
| LAB_174C
 | |
| 	JMP	LAB_GOTO		; else was numeric so do GOTO n
 | |
| 
 | |
| 					; is var or keyword
 | |
| LAB_174D
 | |
| 	CMP	#TK_RETURN		; compare the byte with the token for RETURN
 | |
| 	BNE	LAB_174G		; if it wasn't RETURN go interpret BASIC code from (Bpntrl)
 | |
| 					; and return to this code to process any following code
 | |
| 
 | |
| 	JMP	LAB_1602		; else it was RETURN so interpret BASIC code from (Bpntrl)
 | |
| 					; but don't return here
 | |
| 
 | |
| LAB_174G
 | |
| 	JSR	LAB_15FF		; interpret BASIC code from (Bpntrl)
 | |
| 
 | |
| ; the IF was executed and there may be a following ELSE so the code needs to return
 | |
| ; here to check and ignore the ELSE if present
 | |
| 
 | |
| 	LDY	#$00			; clear the index
 | |
| 	LDA	(Bpntrl),Y		; get the next BASIC byte
 | |
| 	CMP	#TK_ELSE		; compare it with the token for ELSE
 | |
| 	BEQ	LAB_DATA		; if ELSE ignore the following statement
 | |
| 
 | |
| ; there was no ELSE so continue execution of IF <expr> THEN <stat> [: <stat>]. any
 | |
| ; following ELSE will, correctly, cause a syntax error
 | |
| 
 | |
| 	RTS				; else return to the interpreter inner loop
 | |
| 
 | |
| ; perform ELSE after IF
 | |
| 
 | |
| LAB_174E
 | |
| 	LDY	#$00			; clear the BASIC byte index
 | |
| 	LDX	#$01			; clear the nesting depth
 | |
| LAB_1750
 | |
| 	INY				; increment the BASIC byte index
 | |
| 	LDA	(Bpntrl),Y		; get the next BASIC byte
 | |
| 	BEQ	LAB_1753		; if EOL go add the pointer and return
 | |
| 
 | |
| 	CMP	#TK_IF		; compare the byte with the token for IF
 | |
| 	BNE	LAB_1752		; if not IF token skip the depth increment
 | |
| 
 | |
| 	INX				; else increment the nesting depth ..
 | |
| 	BNE	LAB_1750		; .. and continue looking
 | |
| 
 | |
| LAB_1752
 | |
| 	CMP	#TK_ELSE		; compare the byte with the token for ELSE
 | |
| 	BNE	LAB_1750		; if not ELSE token continue looking
 | |
| 
 | |
| 	DEX				; was ELSE so decrement the nesting depth
 | |
| 	BNE	LAB_1750		; loop if still nested
 | |
| 
 | |
| 	INY				; increment the BASIC byte index past the ELSE
 | |
| 
 | |
| ; found the matching ELSE, now do <{n|statement}>
 | |
| 
 | |
| LAB_1753
 | |
| 	TYA				; else copy line index to A
 | |
| 	CLC				; clear carry for add
 | |
| 	ADC	Bpntrl		; add the BASIC execute pointer low byte
 | |
| 	STA	Bpntrl		; save the BASIC execute pointer low byte
 | |
| 	BCC	LAB_1754		; branch if no overflow to high byte
 | |
| 
 | |
| 	INC	Bpntrh		; else increment the BASIC execute pointer high byte
 | |
| LAB_1754
 | |
| 	JSR	LAB_GBYT		; scan memory
 | |
| 	BCC	LAB_174C		; if numeric do GOTO n
 | |
| 					; the code will return to the interpreter loop at the
 | |
| 					; tail end of the GOTO <n>
 | |
| 
 | |
| 	JMP	LAB_15FF		; interpret BASIC code from (Bpntrl)
 | |
| 					; the code will return to the interpreter loop at the
 | |
| 					; tail end of the <statement>
 | |
| 
 | |
| ; perform REM, skip (rest of) line
 | |
| 
 | |
| LAB_REM
 | |
| 	JSR	LAB_SNBL		; scan for next BASIC line
 | |
| 	JMP	LAB_170F		; go set BASIC execute pointer and return, branch always
 | |
| 
 | |
| LAB_16FD
 | |
| 	JMP	LAB_SNER		; do syntax error then warm start
 | |
| 
 | |
| ; perform ON
 | |
| 
 | |
| LAB_ON
 | |
| 	CMP	#TK_IRQ		; was it IRQ token ?
 | |
| 	BNE	LAB_NOIN		; if not go check NMI
 | |
| 
 | |
| 	JMP	LAB_SIRQ		; else go set-up IRQ
 | |
| 
 | |
| LAB_NOIN
 | |
| 	CMP	#TK_NMI		; was it NMI token ?
 | |
| 	BNE	LAB_NONM		; if not go do normal ON command
 | |
| 
 | |
| 	JMP	LAB_SNMI		; else go set-up NMI
 | |
| 
 | |
| LAB_NONM
 | |
| 	JSR	LAB_GTBY		; get byte parameter
 | |
| 	PHA				; push GOTO/GOSUB token
 | |
| 	CMP	#TK_GOSUB		; compare with GOSUB token
 | |
| 	BEQ	LAB_176B		; branch if GOSUB
 | |
| 
 | |
| 	CMP	#TK_GOTO		; compare with GOTO token
 | |
| LAB_1767
 | |
| 	BNE	LAB_16FD		; if not GOTO do syntax error then warm start
 | |
| 
 | |
| 
 | |
| ; next character was GOTO or GOSUB
 | |
| 
 | |
| LAB_176B
 | |
| 	DEC	FAC1_3		; decrement index (byte value)
 | |
| 	BNE	LAB_1773		; branch if not zero
 | |
| 
 | |
| 	PLA				; pull GOTO/GOSUB token
 | |
| 	JMP	LAB_1602		; go execute it
 | |
| 
 | |
| LAB_1773
 | |
| 	JSR	LAB_IGBY		; increment and scan memory
 | |
| 	JSR	LAB_GFPN		; get fixed-point number into temp integer (skip this n)
 | |
| 					; (we could LDX #',' and JSR LAB_SNBL+2, then we
 | |
| 					; just BNE LAB_176B for the loop. should be quicker ..
 | |
| 					; no we can't, what if we meet a colon or [EOL]?)
 | |
| 	CMP	#$2C			; compare next character with ","
 | |
| 	BEQ	LAB_176B		; loop if ","
 | |
| 
 | |
| LAB_177E
 | |
| 	PLA				; else pull keyword token (run out of options)
 | |
| 					; also dump +/-1 pointer low byte and exit
 | |
| LAB_177F
 | |
| 	RTS
 | |
| 
 | |
| ; takes n * 106 + 11 cycles where n is the number of digits
 | |
| 
 | |
| ; get fixed-point number into temp integer
 | |
| 
 | |
| LAB_GFPN
 | |
| 	LDX	#$00			; clear reg
 | |
| 	STX	Itempl		; clear temporary integer low byte
 | |
| LAB_1785
 | |
| 	STX	Itemph		; save temporary integer high byte
 | |
| 	BCS	LAB_177F		; return if carry set, end of scan, character was
 | |
| 					; not 0-9
 | |
| 
 | |
| 	CPX	#$19			; compare high byte with $19
 | |
| 	TAY				; ensure Zb = 0 if the branch is taken
 | |
| 	BCS	LAB_1767		; branch if >=, makes max line # 63999 because next
 | |
| 					; bit does *$0A, = 64000, compare at target will fail
 | |
| 					; and do syntax error
 | |
| 
 | |
| 	SBC	#'0'-1		; subtract "0", $2F + carry, from byte
 | |
| 	TAY				; copy binary digit
 | |
| 	LDA	Itempl		; get temporary integer low byte
 | |
| 	ASL				; *2 low byte
 | |
| 	ROL	Itemph		; *2 high byte
 | |
| 	ASL				; *2 low byte
 | |
| 	ROL	Itemph		; *2 high byte, *4
 | |
| 	ADC	Itempl		; + low byte, *5
 | |
| 	STA	Itempl		; save it
 | |
| 	TXA				; get high byte copy to A
 | |
| 	ADC	Itemph		; + high byte, *5
 | |
| 	ASL	Itempl		; *2 low byte, *10d
 | |
| 	ROL				; *2 high byte, *10d
 | |
| 	TAX				; copy high byte back to X
 | |
| 	TYA				; get binary digit back
 | |
| 	ADC	Itempl		; add number low byte
 | |
| 	STA	Itempl		; save number low byte
 | |
| 	BCC	LAB_17B3		; if no overflow to high byte get next character
 | |
| 
 | |
| 	INX				; else increment high byte
 | |
| LAB_17B3
 | |
| 	JSR	LAB_IGBY		; increment and scan memory
 | |
| 	JMP	LAB_1785		; loop for next character
 | |
| 
 | |
| ; perform DEC
 | |
| 
 | |
| LAB_DEC
 | |
| 	LDA	#<LAB_2AFD		; set -1 pointer low byte
 | |
| 	.byte	$2C			; BIT abs to skip the LDA below
 | |
| 
 | |
| ; perform INC
 | |
| 
 | |
| LAB_INC
 | |
| 	LDA	#<LAB_259C		; set 1 pointer low byte
 | |
| LAB_17B5
 | |
| 	PHA				; save +/-1 pointer low byte
 | |
| LAB_17B7
 | |
| 	JSR	LAB_GVAR		; get var address
 | |
| 	LDX	Dtypef		; get data type flag, $FF=string, $00=numeric
 | |
| 	BMI	IncrErr		; exit if string
 | |
| 
 | |
| 	STA	Lvarpl		; save var address low byte
 | |
| 	STY	Lvarph		; save var address high byte
 | |
| 	JSR	LAB_UFAC		; unpack memory (AY) into FAC1
 | |
| 	PLA				; get +/-1 pointer low byte
 | |
| 	PHA				; save +/-1 pointer low byte
 | |
| 	LDY	#>LAB_259C		; set +/-1 pointer high byte (both the same)
 | |
| 	JSR	LAB_246C		; add (AY) to FAC1
 | |
| 	JSR	LAB_PFAC		; pack FAC1 into variable (Lvarpl)
 | |
| 
 | |
| 	JSR	LAB_GBYT		; scan memory
 | |
| 	CMP	#','			; compare with ","
 | |
| 	BNE	LAB_177E		; exit if not "," (either end or error)
 | |
| 
 | |
| 					; was "," so another INCR variable to do
 | |
| 	JSR	LAB_IGBY		; increment and scan memory
 | |
| 	JMP	LAB_17B7		; go do next var
 | |
| 
 | |
| IncrErr
 | |
| 	JMP	LAB_1ABC		; do "Type mismatch" error then warm start
 | |
| 
 | |
| ; perform LET
 | |
| 
 | |
| LAB_LET
 | |
| 	JSR	LAB_GVAR		; get var address
 | |
| 	STA	Lvarpl		; save var address low byte
 | |
| 	STY	Lvarph		; save var address high byte
 | |
| 	LDA	#TK_EQUAL		; get = token
 | |
| 	JSR	LAB_SCCA		; scan for CHR$(A), else do syntax error then warm start
 | |
| 	LDA	Dtypef		; get data type flag, $FF=string, $00=numeric
 | |
| 	PHA				; push data type flag
 | |
| 	JSR	LAB_EVEX		; evaluate expression
 | |
| 	PLA				; pop data type flag
 | |
| 	ROL				; set carry if type = string
 | |
| 	JSR	LAB_CKTM		; type match check, set C for string
 | |
| 	BNE	LAB_17D5		; branch if string
 | |
| 
 | |
| 	JMP	LAB_PFAC		; pack FAC1 into variable (Lvarpl) and return
 | |
| 
 | |
| ; string LET
 | |
| 
 | |
| LAB_17D5
 | |
| 	LDY	#$02			; set index to pointer high byte
 | |
| 	LDA	(des_pl),Y		; get string pointer high byte
 | |
| 	CMP	Sstorh		; compare bottom of string space high byte
 | |
| 	BCC	LAB_17F4		; if less assign value and exit (was in program memory)
 | |
| 
 | |
| 	BNE	LAB_17E6		; branch if >
 | |
| 					; else was equal so compare low bytes
 | |
| 	DEY				; decrement index
 | |
| 	LDA	(des_pl),Y		; get pointer low byte
 | |
| 	CMP	Sstorl		; compare bottom of string space low byte
 | |
| 	BCC	LAB_17F4		; if less assign value and exit (was in program memory)
 | |
| 
 | |
| 					; pointer was >= to bottom of string space pointer
 | |
| LAB_17E6
 | |
| 	LDY	des_ph		; get descriptor pointer high byte
 | |
| 	CPY	Svarh			; compare start of vars high byte
 | |
| 	BCC	LAB_17F4		; branch if less (descriptor is on stack)
 | |
| 
 | |
| 	BNE	LAB_17FB		; branch if greater (descriptor is not on stack)
 | |
| 
 | |
| 					; else high bytes were equal so ..
 | |
| 	LDA	des_pl		; get descriptor pointer low byte
 | |
| 	CMP	Svarl			; compare start of vars low byte
 | |
| 	BCS	LAB_17FB		; branch if >= (descriptor is not on stack)
 | |
| 
 | |
| LAB_17F4
 | |
| 	LDA	des_pl		; get descriptor pointer low byte
 | |
| 	LDY	des_ph		; get descriptor pointer high byte
 | |
| 	JMP	LAB_1811		; clean stack, copy descriptor to variable and return
 | |
| 
 | |
| 					; make space and copy string
 | |
| LAB_17FB
 | |
| 	LDY	#$00			; index to length
 | |
| 	LDA	(des_pl),Y		; get string length
 | |
| 	JSR	LAB_209C		; copy string
 | |
| 	LDA	des_2l		; get descriptor pointer low byte
 | |
| 	LDY	des_2h		; get descriptor pointer high byte
 | |
| 	STA	ssptr_l		; save descriptor pointer low byte
 | |
| 	STY	ssptr_h		; save descriptor pointer high byte
 | |
| 	JSR	LAB_228A		; copy string from descriptor (sdescr) to (Sutill)
 | |
| 	LDA	#<FAC1_e		; set descriptor pointer low byte
 | |
| 	LDY	#>FAC1_e		; get descriptor pointer high byte
 | |
| 
 | |
| 					; clean stack and assign value to string variable
 | |
| LAB_1811
 | |
| 	STA	des_2l		; save descriptor_2 pointer low byte
 | |
| 	STY	des_2h		; save descriptor_2 pointer high byte
 | |
| 	JSR	LAB_22EB		; clean descriptor stack, YA = pointer
 | |
| 	LDY	#$00			; index to length
 | |
| 	LDA	(des_2l),Y		; get string length
 | |
| 	STA	(Lvarpl),Y		; copy to let string variable
 | |
| 	INY				; index to string pointer low byte
 | |
| 	LDA	(des_2l),Y		; get string pointer low byte
 | |
| 	STA	(Lvarpl),Y		; copy to let string variable
 | |
| 	INY				; index to string pointer high byte
 | |
| 	LDA	(des_2l),Y		; get string pointer high byte
 | |
| 	STA	(Lvarpl),Y		; copy to let string variable
 | |
| 	RTS
 | |
| 
 | |
| ; perform GET
 | |
| 
 | |
| LAB_GET
 | |
| 	JSR	LAB_GVAR		; get var address
 | |
| 	STA	Lvarpl		; save var address low byte
 | |
| 	STY	Lvarph		; save var address high byte
 | |
| 	JSR	INGET			; get input byte
 | |
| 	LDX	Dtypef		; get data type flag, $FF=string, $00=numeric
 | |
| 	BMI	LAB_GETS		; go get string character
 | |
| 
 | |
| 					; was numeric get
 | |
| 	TAY				; copy character to Y
 | |
| 	JSR	LAB_1FD0		; convert Y to byte in FAC1
 | |
| 	JMP	LAB_PFAC		; pack FAC1 into variable (Lvarpl) and return
 | |
| 
 | |
| LAB_GETS
 | |
| 	PHA				; save character
 | |
| 	LDA	#$01			; string is single byte
 | |
| 	BCS	LAB_IsByte		; branch if byte received
 | |
| 
 | |
| 	PLA				; string is null
 | |
| LAB_IsByte
 | |
| 	JSR	LAB_MSSP		; make string space A bytes long A=$AC=length,
 | |
| 					; X=$AD=Sutill=ptr low byte, Y=$AE=Sutilh=ptr high byte
 | |
| 	BEQ	LAB_NoSt		; skip store if null string
 | |
| 
 | |
| 	PLA				; get character back
 | |
| 	LDY	#$00			; clear index
 | |
| 	STA	(str_pl),Y		; save byte in string (byte IS string!)
 | |
| LAB_NoSt
 | |
| 	JSR	LAB_RTST		; check for space on descriptor stack then put address
 | |
| 					; and length on descriptor stack and update stack pointers
 | |
| 
 | |
| 	JMP	LAB_17D5		; do string LET and return
 | |
| 
 | |
| ; perform PRINT
 | |
| 
 | |
| LAB_1829
 | |
| 	JSR	LAB_18C6		; print string from Sutill/Sutilh
 | |
| LAB_182C
 | |
| 	JSR	LAB_GBYT		; scan memory
 | |
| 
 | |
| ; PRINT
 | |
| 
 | |
| LAB_PRINT
 | |
| 	BEQ	LAB_CRLF		; if nothing following just print CR/LF
 | |
| 
 | |
| LAB_1831
 | |
| 	CMP	#TK_TAB		; compare with TAB( token
 | |
| 	BEQ	LAB_18A2		; go do TAB/SPC
 | |
| 
 | |
| 	CMP	#TK_SPC		; compare with SPC( token
 | |
| 	BEQ	LAB_18A2		; go do TAB/SPC
 | |
| 
 | |
| 	CMP	#','			; compare with ","
 | |
| 	BEQ	LAB_188B		; go do move to next TAB mark
 | |
| 
 | |
| 	CMP	#';'			; compare with ";"
 | |
| 	BEQ	LAB_18BD		; if ";" continue with PRINT processing
 | |
| 
 | |
| 	JSR	LAB_EVEX		; evaluate expression
 | |
| 	BIT	Dtypef		; test data type flag, $FF=string, $00=numeric
 | |
| 	BMI	LAB_1829		; branch if string
 | |
| 
 | |
| 	JSR	LAB_296E		; convert FAC1 to string
 | |
| 	JSR	LAB_20AE		; print " terminated string to Sutill/Sutilh
 | |
| 	LDY	#$00			; clear index
 | |
| 
 | |
| ; don't check fit if terminal width byte is zero
 | |
| 
 | |
| 	LDA	TWidth		; get terminal width byte
 | |
| 	BEQ	LAB_185E		; skip check if zero
 | |
| 
 | |
| 	SEC				; set carry for subtract
 | |
| 	SBC	TPos			; subtract terminal position
 | |
| 	SBC	(des_pl),Y		; subtract string length
 | |
| 	BCS	LAB_185E		; branch if less than terminal width
 | |
| 
 | |
| 	JSR	LAB_CRLF		; else print CR/LF
 | |
| LAB_185E
 | |
| 	JSR	LAB_18C6		; print string from Sutill/Sutilh
 | |
| 	BEQ	LAB_182C		; always go continue processing line
 | |
| 
 | |
| ; CR/LF return to BASIC from BASIC input handler
 | |
| 
 | |
| LAB_1866
 | |
| 	LDA	#$00			; clear byte
 | |
| 	STA	Ibuffs,X		; null terminate input
 | |
| 	LDX	#<Ibuffs		; set X to buffer start-1 low byte
 | |
| 	LDY	#>Ibuffs		; set Y to buffer start-1 high byte
 | |
| 
 | |
| ; print CR/LF
 | |
| 
 | |
| LAB_CRLF
 | |
| 	LDA	#$0D			; load [CR]
 | |
| 	JSR	LAB_PRNA		; go print the character
 | |
| 	LDA	#$0A			; load [LF]
 | |
| 	BNE	LAB_PRNA		; go print the character and return, branch always
 | |
| 
 | |
| LAB_188B
 | |
| 	LDA	TPos			; get terminal position
 | |
| 	CMP	Iclim			; compare with input column limit
 | |
| 	BCC	LAB_1897		; branch if less
 | |
| 
 | |
| 	JSR	LAB_CRLF		; else print CR/LF (next line)
 | |
| 	BNE	LAB_18BD		; continue with PRINT processing (branch always)
 | |
| 
 | |
| LAB_1897
 | |
| 	SEC				; set carry for subtract
 | |
| LAB_1898
 | |
| 	SBC	TabSiz		; subtract TAB size
 | |
| 	BCS	LAB_1898		; loop if result was +ve
 | |
| 
 | |
| 	EOR	#$FF			; complement it
 | |
| 	ADC	#$01			; +1 (twos complement)
 | |
| 	BNE	LAB_18B6		; always print A spaces (result is never $00)
 | |
| 
 | |
| 					; do TAB/SPC
 | |
| LAB_18A2
 | |
| 	PHA				; save token
 | |
| 	JSR	LAB_SGBY		; scan and get byte parameter
 | |
| 	CMP	#$29			; is next character )
 | |
| 	BNE	LAB_1910		; if not do syntax error then warm start
 | |
| 
 | |
| 	PLA				; get token back
 | |
| 	CMP	#TK_TAB		; was it TAB ?
 | |
| 	BNE	LAB_18B7		; if not go do SPC
 | |
| 
 | |
| 					; calculate TAB offset
 | |
| 	TXA				; copy integer value to A
 | |
| 	SBC	TPos			; subtract terminal position
 | |
| 	BCC	LAB_18BD		; branch if result was < 0 (can't TAB backwards)
 | |
| 
 | |
| 					; print A spaces
 | |
| LAB_18B6
 | |
| 	TAX				; copy result to X
 | |
| LAB_18B7
 | |
| 	TXA				; set flags on size for SPC
 | |
| 	BEQ	LAB_18BD		; branch if result was = $0, already here
 | |
| 
 | |
| 					; print X spaces
 | |
| LAB_18BA
 | |
| 	JSR	LAB_18E0		; print " "
 | |
| 	DEX				; decrement count
 | |
| 	BNE	LAB_18BA		; loop if not all done
 | |
| 
 | |
| 					; continue with PRINT processing
 | |
| LAB_18BD
 | |
| 	JSR	LAB_IGBY		; increment and scan memory
 | |
| 	BNE	LAB_1831		; if more to print go do it
 | |
| 
 | |
| 	RTS
 | |
| 
 | |
| ; print null terminated string from memory
 | |
| 
 | |
| LAB_18C3
 | |
| 	JSR	LAB_20AE		; print " terminated string to Sutill/Sutilh
 | |
| 
 | |
| ; print string from Sutill/Sutilh
 | |
| 
 | |
| LAB_18C6
 | |
| 	JSR	LAB_22B6		; pop string off descriptor stack, or from top of string
 | |
| 					; space returns with A = length, X=$71=pointer low byte,
 | |
| 					; Y=$72=pointer high byte
 | |
| 	LDY	#$00			; reset index
 | |
| 	TAX				; copy length to X
 | |
| 	BEQ	LAB_188C		; exit (RTS) if null string
 | |
| 
 | |
| LAB_18CD
 | |
| 
 | |
| 	LDA	(ut1_pl),Y		; get next byte
 | |
| 	JSR	LAB_PRNA		; go print the character
 | |
| 	INY				; increment index
 | |
| 	DEX				; decrement count
 | |
| 	BNE	LAB_18CD		; loop if not done yet
 | |
| 
 | |
| 	RTS
 | |
| 
 | |
| 					; Print single format character
 | |
| ; print " "
 | |
| 
 | |
| LAB_18E0
 | |
| 	LDA	#$20			; load " "
 | |
| 	.byte	$2C			; change next line to BIT LAB_3FA9
 | |
| 
 | |
| ; print "?" character
 | |
| 
 | |
| LAB_18E3
 | |
| 	LDA	#$3F			; load "?" character
 | |
| 
 | |
| ; print character in A
 | |
| ; now includes the null handler
 | |
| ; also includes infinite line length code
 | |
| ; note! some routines expect this one to exit with Zb=0
 | |
| 
 | |
| LAB_PRNA
 | |
| 	CMP	#' '			; compare with " "
 | |
| 	BCC	LAB_18F9		; branch if less (non printing)
 | |
| 
 | |
| 					; else printable character
 | |
| 	PHA				; save the character
 | |
| 
 | |
| ; don't check fit if terminal width byte is zero
 | |
| 
 | |
| 	LDA	TWidth		; get terminal width
 | |
| 	BNE	LAB_18F0		; branch if not zero (not infinite length)
 | |
| 
 | |
| ; is "infinite line" so check TAB position
 | |
| 
 | |
| 	LDA	TPos			; get position
 | |
| 	SBC	TabSiz		; subtract TAB size, carry set by CMP #$20 above
 | |
| 	BNE	LAB_18F7		; skip reset if different
 | |
| 
 | |
| 	STA	TPos			; else reset position
 | |
| 	BEQ	LAB_18F7		; go print character
 | |
| 
 | |
| LAB_18F0
 | |
| 	CMP	TPos			; compare with terminal character position
 | |
| 	BNE	LAB_18F7		; branch if not at end of line
 | |
| 
 | |
| 	JSR	LAB_CRLF		; else print CR/LF
 | |
| LAB_18F7
 | |
| 	INC	TPos			; increment terminal position
 | |
| 	PLA				; get character back
 | |
| LAB_18F9
 | |
| 	JSR	V_OUTP		; output byte via output vector
 | |
| 	CMP	#$0D			; compare with [CR]
 | |
| 	BNE	LAB_188A		; branch if not [CR]
 | |
| 
 | |
| 					; else print nullct nulls after the [CR]
 | |
| 	STX	TempB			; save buffer index
 | |
| 	LDX	Nullct		; get null count
 | |
| 	BEQ	LAB_1886		; branch if no nulls
 | |
| 
 | |
| 	LDA	#$00			; load [NULL]
 | |
| LAB_1880
 | |
| 	JSR	LAB_PRNA		; go print the character
 | |
| 	DEX				; decrement count
 | |
| 	BNE	LAB_1880		; loop if not all done
 | |
| 
 | |
| 	LDA	#$0D			; restore the character (and set the flags)
 | |
| LAB_1886
 | |
| 	STX	TPos			; clear terminal position (X always = zero when we get here)
 | |
| 	LDX	TempB			; restore buffer index
 | |
| LAB_188A
 | |
| 	AND	#$FF			; set the flags
 | |
| LAB_188C
 | |
| 	RTS
 | |
| 
 | |
| ; handle bad input data
 | |
| 
 | |
| LAB_1904
 | |
| 	LDA	Imode			; get input mode flag, $00=INPUT, $00=READ
 | |
| 	BPL	LAB_1913		; branch if INPUT (go do redo)
 | |
| 
 | |
| 	LDA	Dlinel		; get current DATA line low byte
 | |
| 	LDY	Dlineh		; get current DATA line high byte
 | |
| 	STA	Clinel		; save current line low byte
 | |
| 	STY	Clineh		; save current line high byte
 | |
| LAB_1910
 | |
| 	JMP	LAB_SNER		; do syntax error then warm start
 | |
| 
 | |
| 					; mode was INPUT
 | |
| LAB_1913
 | |
| 	LDA	#<LAB_REDO		; point to redo message (low addr)
 | |
| 	LDY	#>LAB_REDO		; point to redo message (high addr)
 | |
| 	JSR	LAB_18C3		; print null terminated string from memory
 | |
| 	LDA	Cpntrl		; get continue pointer low byte
 | |
| 	LDY	Cpntrh		; get continue pointer high byte
 | |
| 	STA	Bpntrl		; save BASIC execute pointer low byte
 | |
| 	STY	Bpntrh		; save BASIC execute pointer high byte
 | |
| 	RTS
 | |
| 
 | |
| ; perform INPUT
 | |
| 
 | |
| LAB_INPUT
 | |
| 	CMP	#$22			; compare next byte with open quote
 | |
| 	BNE	LAB_1934		; branch if no prompt string
 | |
| 
 | |
| 	JSR	LAB_1BC1		; print "..." string
 | |
| 	LDA	#$3B			; load A with ";"
 | |
| 	JSR	LAB_SCCA		; scan for CHR$(A), else do syntax error then warm start
 | |
| 	JSR	LAB_18C6		; print string from Sutill/Sutilh
 | |
| 
 | |
| 					; done with prompt, now get data
 | |
| LAB_1934
 | |
| 	JSR	LAB_CKRN		; check not Direct, back here if ok
 | |
| 	JSR	LAB_INLN		; print "? " and get BASIC input
 | |
| 	LDA	#$00			; set mode = INPUT
 | |
| 	CMP	Ibuffs		; test first byte in buffer
 | |
| 	BNE	LAB_1953		; branch if not null input
 | |
| 
 | |
| 	CLC				; was null input so clear carry to exit program
 | |
| 	JMP	LAB_1647		; go do BREAK exit
 | |
| 
 | |
| ; perform READ
 | |
| 
 | |
| LAB_READ
 | |
| 	LDX	Dptrl			; get DATA pointer low byte
 | |
| 	LDY	Dptrh			; get DATA pointer high byte
 | |
| 	LDA	#$80			; set mode = READ
 | |
| 
 | |
| LAB_1953
 | |
| 	STA	Imode			; set input mode flag, $00=INPUT, $80=READ
 | |
| 	STX	Rdptrl		; save READ pointer low byte
 | |
| 	STY	Rdptrh		; save READ pointer high byte
 | |
| 
 | |
| 					; READ or INPUT next variable from list
 | |
| LAB_195B
 | |
| 	JSR	LAB_GVAR		; get (var) address
 | |
| 	STA	Lvarpl		; save address low byte
 | |
| 	STY	Lvarph		; save address high byte
 | |
| 	LDA	Bpntrl		; get BASIC execute pointer low byte
 | |
| 	LDY	Bpntrh		; get BASIC execute pointer high byte
 | |
| 	STA	Itempl		; save as temporary integer low byte
 | |
| 	STY	Itemph		; save as temporary integer high byte
 | |
| 	LDX	Rdptrl		; get READ pointer low byte
 | |
| 	LDY	Rdptrh		; get READ pointer high byte
 | |
| 	STX	Bpntrl		; set BASIC execute pointer low byte
 | |
| 	STY	Bpntrh		; set BASIC execute pointer high byte
 | |
| 	JSR	LAB_GBYT		; scan memory
 | |
| 	BNE	LAB_1988		; branch if not null
 | |
| 
 | |
| 					; pointer was to null entry
 | |
| 	BIT	Imode			; test input mode flag, $00=INPUT, $80=READ
 | |
| 	BMI	LAB_19DD		; branch if READ
 | |
| 
 | |
| 					; mode was INPUT
 | |
| 	JSR	LAB_18E3		; print "?" character (double ? for extended input)
 | |
| 	JSR	LAB_INLN		; print "? " and get BASIC input
 | |
| 	STX	Bpntrl		; set BASIC execute pointer low byte
 | |
| 	STY	Bpntrh		; set BASIC execute pointer high byte
 | |
| LAB_1985
 | |
| 	JSR	LAB_GBYT		; scan memory
 | |
| LAB_1988
 | |
| 	BIT	Dtypef		; test data type flag, $FF=string, $00=numeric
 | |
| 	BPL	LAB_19B0		; branch if numeric
 | |
| 
 | |
| 					; else get string
 | |
| 	STA	Srchc			; save search character
 | |
| 	CMP	#$22			; was it " ?
 | |
| 	BEQ	LAB_1999		; branch if so
 | |
| 
 | |
| 	LDA	#':'			; else search character is ":"
 | |
| 	STA	Srchc			; set new search character
 | |
| 	LDA	#','			; other search character is ","
 | |
| 	CLC				; clear carry for add
 | |
| LAB_1999
 | |
| 	STA	Asrch			; set second search character
 | |
| 	LDA	Bpntrl		; get BASIC execute pointer low byte
 | |
| 	LDY	Bpntrh		; get BASIC execute pointer high byte
 | |
| 
 | |
| 	ADC	#$00			; c is =1 if we came via the BEQ LAB_1999, else =0
 | |
| 	BCC	LAB_19A4		; branch if no execute pointer low byte rollover
 | |
| 
 | |
| 	INY				; else increment high byte
 | |
| LAB_19A4
 | |
| 	JSR	LAB_20B4		; print Srchc or Asrch terminated string to Sutill/Sutilh
 | |
| 	JSR	LAB_23F3		; restore BASIC execute pointer from temp (Btmpl/Btmph)
 | |
| 	JSR	LAB_17D5		; go do string LET
 | |
| 	JMP	LAB_19B6		; go check string terminator
 | |
| 
 | |
| 					; get numeric INPUT
 | |
| LAB_19B0
 | |
| 	JSR	LAB_2887		; get FAC1 from string
 | |
| 	JSR	LAB_PFAC		; pack FAC1 into (Lvarpl)
 | |
| LAB_19B6
 | |
| 	JSR	LAB_GBYT		; scan memory
 | |
| 	BEQ	LAB_19C5		; branch if null (last entry)
 | |
| 
 | |
| 	CMP	#','			; else compare with ","
 | |
| 	BEQ	LAB_19C2		; branch if ","
 | |
| 
 | |
| 	JMP	LAB_1904		; else go handle bad input data
 | |
| 
 | |
| 					; got good input data
 | |
| LAB_19C2
 | |
| 	JSR	LAB_IGBY		; increment and scan memory
 | |
| LAB_19C5
 | |
| 	LDA	Bpntrl		; get BASIC execute pointer low byte (temp READ/INPUT ptr)
 | |
| 	LDY	Bpntrh		; get BASIC execute pointer high byte (temp READ/INPUT ptr)
 | |
| 	STA	Rdptrl		; save for now
 | |
| 	STY	Rdptrh		; save for now
 | |
| 	LDA	Itempl		; get temporary integer low byte (temp BASIC execute ptr)
 | |
| 	LDY	Itemph		; get temporary integer high byte (temp BASIC execute ptr)
 | |
| 	STA	Bpntrl		; set BASIC execute pointer low byte
 | |
| 	STY	Bpntrh		; set BASIC execute pointer high byte
 | |
| 	JSR	LAB_GBYT		; scan memory
 | |
| 	BEQ	LAB_1A03		; if null go do extra ignored message
 | |
| 
 | |
| 	JSR	LAB_1C01		; else scan for "," , else do syntax error then warm start
 | |
| 	JMP	LAB_195B		; go INPUT next variable from list
 | |
| 
 | |
| 					; find next DATA statement or do "Out of DATA" error
 | |
| LAB_19DD
 | |
| 	JSR	LAB_SNBS		; scan for next BASIC statement ([:] or [EOL])
 | |
| 	INY				; increment index
 | |
| 	TAX				; copy character ([:] or [EOL])
 | |
| 	BNE	LAB_19F6		; branch if [:]
 | |
| 
 | |
| 	LDX	#$06			; set for "Out of DATA" error
 | |
| 	INY				; increment index, now points to next line pointer high byte
 | |
| 	LDA	(Bpntrl),Y		; get next line pointer high byte
 | |
| 	BEQ	LAB_1A54		; branch if end (eventually does error X)
 | |
| 
 | |
| 	INY				; increment index
 | |
| 	LDA	(Bpntrl),Y		; get next line # low byte
 | |
| 	STA	Dlinel		; save current DATA line low byte
 | |
| 	INY				; increment index
 | |
| 	LDA	(Bpntrl),Y		; get next line # high byte
 | |
| 	INY				; increment index
 | |
| 	STA	Dlineh		; save current DATA line high byte
 | |
| LAB_19F6
 | |
| 	LDA	(Bpntrl),Y		; get byte
 | |
| 	INY				; increment index
 | |
| 	TAX				; copy to X
 | |
| 	JSR	LAB_170F		; set BASIC execute pointer
 | |
| 	CPX	#TK_DATA		; compare with "DATA" token
 | |
| 	BEQ	LAB_1985		; was "DATA" so go do next READ
 | |
| 
 | |
| 	BNE	LAB_19DD		; go find next statement if not "DATA"
 | |
| 
 | |
| ; end of INPUT/READ routine
 | |
| 
 | |
| LAB_1A03
 | |
| 	LDA	Rdptrl		; get temp READ pointer low byte
 | |
| 	LDY	Rdptrh		; get temp READ pointer high byte
 | |
| 	LDX	Imode			; get input mode flag, $00=INPUT, $80=READ
 | |
| 	BPL	LAB_1A0E		; branch if INPUT
 | |
| 
 | |
| 	JMP	LAB_1624		; save AY as DATA pointer and return
 | |
| 
 | |
| 					; we were getting INPUT
 | |
| LAB_1A0E
 | |
| 	LDY	#$00			; clear index
 | |
| 	LDA	(Rdptrl),Y		; get next byte
 | |
| 	BNE	LAB_1A1B		; error if not end of INPUT
 | |
| 
 | |
| 	RTS
 | |
| 
 | |
| 					; user typed too much
 | |
| LAB_1A1B
 | |
| 	LDA	#<LAB_IMSG		; point to extra ignored message (low addr)
 | |
| 	LDY	#>LAB_IMSG		; point to extra ignored message (high addr)
 | |
| 	JMP	LAB_18C3		; print null terminated string from memory and return
 | |
| 
 | |
| ; search the stack for FOR activity
 | |
| ; exit with z=1 if FOR else exit with z=0
 | |
| 
 | |
| LAB_11A1
 | |
| 	TSX				; copy stack pointer
 | |
| 	INX				; +1 pass return address
 | |
| 	INX				; +2 pass return address
 | |
| 	INX				; +3 pass calling routine return address
 | |
| 	INX				; +4 pass calling routine return address
 | |
| LAB_11A6
 | |
| 	LDA	LAB_STAK+1,X	; get token byte from stack
 | |
| 	CMP	#TK_FOR		; is it FOR token
 | |
| 	BNE	LAB_11CE		; exit if not FOR token
 | |
| 
 | |
| 					; was FOR token
 | |
| 	LDA	Frnxth		; get var pointer for FOR/NEXT high byte
 | |
| 	BNE	LAB_11BB		; branch if not null
 | |
| 
 | |
| 	LDA	LAB_STAK+2,X	; get FOR variable pointer low byte
 | |
| 	STA	Frnxtl		; save var pointer for FOR/NEXT low byte
 | |
| 	LDA	LAB_STAK+3,X	; get FOR variable pointer high byte
 | |
| 	STA	Frnxth		; save var pointer for FOR/NEXT high byte
 | |
| LAB_11BB
 | |
| 	CMP	LAB_STAK+3,X	; compare var pointer with stacked var pointer (high byte)
 | |
| 	BNE	LAB_11C7		; branch if no match
 | |
| 
 | |
| 	LDA	Frnxtl		; get var pointer for FOR/NEXT low byte
 | |
| 	CMP	LAB_STAK+2,X	; compare var pointer with stacked var pointer (low byte)
 | |
| 	BEQ	LAB_11CE		; exit if match found
 | |
| 
 | |
| LAB_11C7
 | |
| 	TXA				; copy index
 | |
| 	CLC				; clear carry for add
 | |
| 	ADC	#$10			; add FOR stack use size
 | |
| 	TAX				; copy back to index
 | |
| 	BNE	LAB_11A6		; loop if not at start of stack
 | |
| 
 | |
| LAB_11CE
 | |
| 	RTS
 | |
| 
 | |
| ; perform NEXT
 | |
| 
 | |
| LAB_NEXT
 | |
| 	BNE	LAB_1A46		; branch if NEXT var
 | |
| 
 | |
| 	LDY	#$00			; else clear Y
 | |
| 	BEQ	LAB_1A49		; branch always (no variable to search for)
 | |
| 
 | |
| ; NEXT var
 | |
| 
 | |
| LAB_1A46
 | |
| 	JSR	LAB_GVAR		; get variable address
 | |
| LAB_1A49
 | |
| 	STA	Frnxtl		; store variable pointer low byte
 | |
| 	STY	Frnxth		; store variable pointer high byte
 | |
| 					; (both cleared if no variable defined)
 | |
| 	JSR	LAB_11A1		; search the stack for FOR activity
 | |
| 	BEQ	LAB_1A56		; branch if found
 | |
| 
 | |
| 	LDX	#$00			; else set error $00 ("NEXT without FOR" error)
 | |
| LAB_1A54
 | |
| 	BEQ	LAB_1ABE		; do error #X, then warm start
 | |
| 
 | |
| LAB_1A56
 | |
| 	TXS				; set stack pointer, X set by search, dumps return addresses
 | |
| 
 | |
| 	TXA				; copy stack pointer
 | |
| 	SEC				; set carry for subtract
 | |
| 	SBC	#$F7			; point to TO var
 | |
| 	STA	ut2_pl		; save pointer to TO var for compare
 | |
| 	ADC	#$FB			; point to STEP var
 | |
| 
 | |
| 	LDY	#>LAB_STAK		; point to stack page high byte
 | |
| 	JSR	LAB_UFAC		; unpack memory (STEP value) into FAC1
 | |
| 	TSX				; get stack pointer back
 | |
| 	LDA	LAB_STAK+8,X	; get step sign
 | |
| 	STA	FAC1_s		; save FAC1 sign (b7)
 | |
| 	LDA	Frnxtl		; get FOR variable pointer low byte
 | |
| 	LDY	Frnxth		; get FOR variable pointer high byte
 | |
| 	JSR	LAB_246C		; add (FOR variable) to FAC1
 | |
| 	JSR	LAB_PFAC		; pack FAC1 into (FOR variable)
 | |
| 	LDY	#>LAB_STAK		; point to stack page high byte
 | |
| 	JSR	LAB_27FA		; compare FAC1 with (Y,ut2_pl) (TO value)
 | |
| 	TSX				; get stack pointer back
 | |
| 	CMP	LAB_STAK+8,X	; compare step sign
 | |
| 	BEQ	LAB_1A9B		; branch if = (loop complete)
 | |
| 
 | |
| 					; loop back and do it all again
 | |
| 	LDA	LAB_STAK+$0D,X	; get FOR line low byte
 | |
| 	STA	Clinel		; save current line low byte
 | |
| 	LDA	LAB_STAK+$0E,X	; get FOR line high byte
 | |
| 	STA	Clineh		; save current line high byte
 | |
| 	LDA	LAB_STAK+$10,X	; get BASIC execute pointer low byte
 | |
| 	STA	Bpntrl		; save BASIC execute pointer low byte
 | |
| 	LDA	LAB_STAK+$0F,X	; get BASIC execute pointer high byte
 | |
| 	STA	Bpntrh		; save BASIC execute pointer high byte
 | |
| LAB_1A98
 | |
| 	JMP	LAB_15C2		; go do interpreter inner loop
 | |
| 
 | |
| 					; loop complete so carry on
 | |
| LAB_1A9B
 | |
| 	TXA				; stack copy to A
 | |
| 	ADC	#$0F			; add $10 ($0F+carry) to dump FOR structure
 | |
| 	TAX				; copy back to index
 | |
| 	TXS				; copy to stack pointer
 | |
| 	JSR	LAB_GBYT		; scan memory
 | |
| 	CMP	#','			; compare with ","
 | |
| 	BNE	LAB_1A98		; branch if not "," (go do interpreter inner loop)
 | |
| 
 | |
| 					; was "," so another NEXT variable to do
 | |
| 	JSR	LAB_IGBY		; else increment and scan memory
 | |
| 	JSR	LAB_1A46		; do NEXT (var)
 | |
| 
 | |
| ; evaluate expression and check is numeric, else do type mismatch
 | |
| 
 | |
| LAB_EVNM
 | |
| 	JSR	LAB_EVEX		; evaluate expression
 | |
| 
 | |
| ; check if source is numeric, else do type mismatch
 | |
| 
 | |
| LAB_CTNM
 | |
| 	CLC				; destination is numeric
 | |
| 	.byte	$24			; makes next line BIT $38
 | |
| 
 | |
| ; check if source is string, else do type mismatch
 | |
| 
 | |
| LAB_CTST
 | |
| 	SEC				; required type is string
 | |
| 
 | |
| ; type match check, set C for string, clear C for numeric
 | |
| 
 | |
| LAB_CKTM
 | |
| 	BIT	Dtypef		; test data type flag, $FF=string, $00=numeric
 | |
| 	BMI	LAB_1ABA		; branch if data type is string
 | |
| 
 | |
| 					; else data type was numeric
 | |
| 	BCS	LAB_1ABC		; if required type is string do type mismatch error
 | |
| LAB_1AB9
 | |
| 	RTS
 | |
| 
 | |
| 					; data type was string, now check required type
 | |
| LAB_1ABA
 | |
| 	BCS	LAB_1AB9		; exit if required type is string
 | |
| 
 | |
| 					; else do type mismatch error
 | |
| LAB_1ABC
 | |
| 	LDX	#$18			; error code $18 ("Type mismatch" error)
 | |
| LAB_1ABE
 | |
| 	JMP	LAB_XERR		; do error #X, then warm start
 | |
| 
 | |
| ; evaluate expression
 | |
| 
 | |
| LAB_EVEX
 | |
| 	LDX	Bpntrl		; get BASIC execute pointer low byte
 | |
| 	BNE	LAB_1AC7		; skip next if not zero
 | |
| 
 | |
| 	DEC	Bpntrh		; else decrement BASIC execute pointer high byte
 | |
| LAB_1AC7
 | |
| 	DEC	Bpntrl		; decrement BASIC execute pointer low byte
 | |
| 
 | |
| LAB_EVEZ
 | |
| 	LDA	#$00			; set null precedence (flag done)
 | |
| LAB_1ACC
 | |
| 	PHA				; push precedence byte
 | |
| 	LDA	#$02			; 2 bytes
 | |
| 	JSR	LAB_1212		; check room on stack for A bytes
 | |
| 	JSR	LAB_GVAL		; get value from line
 | |
| 	LDA	#$00			; clear A
 | |
| 	STA	comp_f		; clear compare function flag
 | |
| LAB_1ADB
 | |
| 	JSR	LAB_GBYT		; scan memory
 | |
| LAB_1ADE
 | |
| 	SEC				; set carry for subtract
 | |
| 	SBC	#TK_GT		; subtract token for > (lowest comparison function)
 | |
| 	BCC	LAB_1AFA		; branch if < TK_GT
 | |
| 
 | |
| 	CMP	#$03			; compare with ">" to "<" tokens
 | |
| 	BCS	LAB_1AFA		; branch if >= TK_SGN (highest evaluation function +1)
 | |
| 
 | |
| 					; was token for > = or < (A = 0, 1 or 2)
 | |
| 	CMP	#$01			; compare with token for =
 | |
| 	ROL				; *2, b0 = carry (=1 if token was = or <)
 | |
| 					; (A = 0, 3 or 5)
 | |
| 	EOR	#$01			; toggle b0
 | |
| 					; (A = 1, 2 or 4. 1 if >, 2 if =, 4 if <)
 | |
| 	EOR	comp_f		; EOR with compare function flag bits
 | |
| 	CMP	comp_f		; compare with compare function flag
 | |
| 	BCC	LAB_1B53		; if <(comp_f) do syntax error then warm start
 | |
| 					; was more than one <, = or >)
 | |
| 
 | |
| 	STA	comp_f		; save new compare function flag
 | |
| 	JSR	LAB_IGBY		; increment and scan memory
 | |
| 	JMP	LAB_1ADE		; go do next character
 | |
| 
 | |
| 					; token is < ">" or > "<" tokens
 | |
| LAB_1AFA
 | |
| 	LDX	comp_f		; get compare function flag
 | |
| 	BNE	LAB_1B2A		; branch if compare function
 | |
| 
 | |
| 	BCS	LAB_1B78		; go do functions
 | |
| 
 | |
| 					; else was <  TK_GT so is operator or lower
 | |
| 	ADC	#TK_GT-TK_PLUS	; add # of operators (+, -, *, /, ^, AND, OR or EOR)
 | |
| 	BCC	LAB_1B78		; branch if < + operator
 | |
| 
 | |
| 					; carry was set so token was +, -, *, /, ^, AND, OR or EOR
 | |
| 	BNE	LAB_1B0B		; branch if not + token
 | |
| 
 | |
| 	BIT	Dtypef		; test data type flag, $FF=string, $00=numeric
 | |
| 	BPL	LAB_1B0B		; branch if not string
 | |
| 
 | |
| 					; will only be $00 if type is string and token was +
 | |
| 	JMP	LAB_224D		; add strings, string 1 is in descriptor des_pl, string 2
 | |
| 					; is in line, and return
 | |
| 
 | |
| LAB_1B0B
 | |
| 	STA	ut1_pl		; save it
 | |
| 	ASL				; *2
 | |
| 	ADC	ut1_pl		; *3
 | |
| 	TAY				; copy to index
 | |
| LAB_1B13
 | |
| 	PLA				; pull previous precedence
 | |
| 	CMP	LAB_OPPT,Y		; compare with precedence byte
 | |
| 	BCS	LAB_1B7D		; branch if A >=
 | |
| 
 | |
| 	JSR	LAB_CTNM		; check if source is numeric, else do type mismatch
 | |
| LAB_1B1C
 | |
| 	PHA				; save precedence
 | |
| LAB_1B1D
 | |
| 	JSR	LAB_1B43		; get vector, execute function then continue evaluation
 | |
| 	PLA				; restore precedence
 | |
| 	LDY	prstk			; get precedence stacked flag
 | |
| 	BPL	LAB_1B3C		; branch if stacked values
 | |
| 
 | |
| 	TAX				; copy precedence (set flags)
 | |
| 	BEQ	LAB_1B9D		; exit if done
 | |
| 
 | |
| 	BNE	LAB_1B86		; else pop FAC2 and return, branch always
 | |
| 
 | |
| LAB_1B2A
 | |
| 	ROL	Dtypef		; shift data type flag into Cb
 | |
| 	TXA				; copy compare function flag
 | |
| 	STA	Dtypef		; clear data type flag, X is 0xxx xxxx
 | |
| 	ROL				; shift data type into compare function byte b0
 | |
| 	LDX	Bpntrl		; get BASIC execute pointer low byte
 | |
| 	BNE	LAB_1B34		; branch if no underflow
 | |
| 
 | |
| 	DEC	Bpntrh		; else decrement BASIC execute pointer high byte
 | |
| LAB_1B34
 | |
| 	DEC	Bpntrl		; decrement BASIC execute pointer low byte
 | |
| TK_LT_PLUS	= TK_LT-TK_PLUS
 | |
| 	LDY	#TK_LT_PLUS*3	; set offset to last operator entry
 | |
| 	STA	comp_f		; save new compare function flag
 | |
| 	BNE	LAB_1B13		; branch always
 | |
| 
 | |
| LAB_1B3C
 | |
| 	CMP	LAB_OPPT,Y		;.compare with stacked function precedence
 | |
| 	BCS	LAB_1B86		; branch if A >=, pop FAC2 and return
 | |
| 
 | |
| 	BCC	LAB_1B1C		; branch always
 | |
| 
 | |
| ;.get vector, execute function then continue evaluation
 | |
| 
 | |
| LAB_1B43
 | |
| 	LDA	LAB_OPPT+2,Y	; get function vector high byte
 | |
| 	PHA				; onto stack
 | |
| 	LDA	LAB_OPPT+1,Y	; get function vector low byte
 | |
| 	PHA				; onto stack
 | |
| 					; now push sign, round FAC1 and put on stack
 | |
| 	JSR	LAB_1B5B		; function will return here, then the next RTS will call
 | |
| 					; the function
 | |
| 	LDA	comp_f		; get compare function flag
 | |
| 	PHA				; push compare evaluation byte
 | |
| 	LDA	LAB_OPPT,Y		; get precedence byte
 | |
| 	JMP	LAB_1ACC		; continue evaluating expression
 | |
| 
 | |
| LAB_1B53
 | |
| 	JMP	LAB_SNER		; do syntax error then warm start
 | |
| 
 | |
| ; push sign, round FAC1 and put on stack
 | |
| 
 | |
| LAB_1B5B
 | |
| 	PLA				; get return addr low byte
 | |
| 	STA	ut1_pl		; save it
 | |
| 	INC	ut1_pl		; increment it (was ret-1 pushed? yes!)
 | |
| 					; note! no check is made on the high byte! if the calling
 | |
| 					; routine assembles to a page edge then this all goes
 | |
| 					; horribly wrong !!!
 | |
| 	PLA				; get return addr high byte
 | |
| 	STA	ut1_ph		; save it
 | |
| 	LDA	FAC1_s		; get FAC1 sign (b7)
 | |
| 	PHA				; push sign
 | |
| 
 | |
| ; round FAC1 and put on stack
 | |
| 
 | |
| LAB_1B66
 | |
| 	JSR	LAB_27BA		; round FAC1
 | |
| 	LDA	FAC1_3		; get FAC1 mantissa3
 | |
| 	PHA				; push on stack
 | |
| 	LDA	FAC1_2		; get FAC1 mantissa2
 | |
| 	PHA				; push on stack
 | |
| 	LDA	FAC1_1		; get FAC1 mantissa1
 | |
| 	PHA				; push on stack
 | |
| 	LDA	FAC1_e		; get FAC1 exponent
 | |
| 	PHA				; push on stack
 | |
| 	JMP	(ut1_pl)		; return, sort of
 | |
| 
 | |
| ; do functions
 | |
| 
 | |
| LAB_1B78
 | |
| 	LDY	#$FF			; flag function
 | |
| 	PLA				; pull precedence byte
 | |
| LAB_1B7B
 | |
| 	BEQ	LAB_1B9D		; exit if done
 | |
| 
 | |
| LAB_1B7D
 | |
| 	CMP	#$64			; compare previous precedence with $64
 | |
| 	BEQ	LAB_1B84		; branch if was $64 (< function)
 | |
| 
 | |
| 	JSR	LAB_CTNM		; check if source is numeric, else do type mismatch
 | |
| LAB_1B84
 | |
| 	STY	prstk			; save precedence stacked flag
 | |
| 
 | |
| 					; pop FAC2 and return
 | |
| LAB_1B86
 | |
| 	PLA				; pop byte
 | |
| 	LSR				; shift out comparison evaluation lowest bit
 | |
| 	STA	Cflag			; save comparison evaluation flag
 | |
| 	PLA				; pop exponent
 | |
| 	STA	FAC2_e		; save FAC2 exponent
 | |
| 	PLA				; pop mantissa1
 | |
| 	STA	FAC2_1		; save FAC2 mantissa1
 | |
| 	PLA				; pop mantissa2
 | |
| 	STA	FAC2_2		; save FAC2 mantissa2
 | |
| 	PLA				; pop mantissa3
 | |
| 	STA	FAC2_3		; save FAC2 mantissa3
 | |
| 	PLA				; pop sign
 | |
| 	STA	FAC2_s		; save FAC2 sign (b7)
 | |
| 	EOR	FAC1_s		; EOR FAC1 sign (b7)
 | |
| 	STA	FAC_sc		; save sign compare (FAC1 EOR FAC2)
 | |
| LAB_1B9D
 | |
| 	LDA	FAC1_e		; get FAC1 exponent
 | |
| 	RTS
 | |
| 
 | |
| ; print "..." string to string util area
 | |
| 
 | |
| LAB_1BC1
 | |
| 	LDA	Bpntrl		; get BASIC execute pointer low byte
 | |
| 	LDY	Bpntrh		; get BASIC execute pointer high byte
 | |
| 	ADC	#$00			; add carry to low byte
 | |
| 	BCC	LAB_1BCA		; branch if no overflow
 | |
| 
 | |
| 	INY				; increment high byte
 | |
| LAB_1BCA
 | |
| 	JSR	LAB_20AE		; print " terminated string to Sutill/Sutilh
 | |
| 	JMP	LAB_23F3		; restore BASIC execute pointer from temp and return
 | |
| 
 | |
| ; get value from line
 | |
| 
 | |
| LAB_GVAL
 | |
| 	JSR	LAB_IGBY		; increment and scan memory
 | |
| 	BCS	LAB_1BAC		; branch if not numeric character
 | |
| 
 | |
| 					; else numeric string found (e.g. 123)
 | |
| LAB_1BA9
 | |
| 	JMP	LAB_2887		; get FAC1 from string and return
 | |
| 
 | |
| ; get value from line .. continued
 | |
| 
 | |
| 					; wasn't a number so ..
 | |
| LAB_1BAC
 | |
| 	TAX				; set the flags
 | |
| 	BMI	LAB_1BD0		; if -ve go test token values
 | |
| 
 | |
| 					; else it is either a string, number, variable or (<expr>)
 | |
| 	CMP	#'$'			; compare with "$"
 | |
| 	BEQ	LAB_1BA9		; branch if "$", hex number
 | |
| 
 | |
| 	CMP	#'%'			; else compare with "%"
 | |
| 	BEQ	LAB_1BA9		; branch if "%", binary number
 | |
| 
 | |
| 	CMP	#'.'			; compare with "."
 | |
| 	BEQ	LAB_1BA9		; if so get FAC1 from string and return (e.g. was .123)
 | |
| 
 | |
| 					; it wasn't any sort of number so ..
 | |
| 	CMP	#$22			; compare with "
 | |
| 	BEQ	LAB_1BC1		; branch if open quote
 | |
| 
 | |
| 					; wasn't any sort of number so ..
 | |
| 
 | |
| ; evaluate expression within parentheses
 | |
| 
 | |
| 	CMP	#'('			; compare with "("
 | |
| 	BNE	LAB_1C18		; if not "(" get (var), return value in FAC1 and $ flag
 | |
| 
 | |
| LAB_1BF7
 | |
| 	JSR	LAB_EVEZ		; evaluate expression, no decrement
 | |
| 
 | |
| ; all the 'scan for' routines return the character after the sought character
 | |
| 
 | |
| ; scan for ")" , else do syntax error then warm start
 | |
| 
 | |
| LAB_1BFB
 | |
| 	LDA	#$29			; load A with ")"
 | |
| 
 | |
| ; scan for CHR$(A) , else do syntax error then warm start
 | |
| 
 | |
| LAB_SCCA
 | |
| 	LDY	#$00			; clear index
 | |
| 	CMP	(Bpntrl),Y		; check next byte is = A
 | |
| 	BNE	LAB_SNER		; if not do syntax error then warm start
 | |
| 
 | |
| 	JMP	LAB_IGBY		; increment and scan memory then return
 | |
| 
 | |
| ; scan for "(" , else do syntax error then warm start
 | |
| 
 | |
| LAB_1BFE
 | |
| 	LDA	#$28			; load A with "("
 | |
| 	BNE	LAB_SCCA		; scan for CHR$(A), else do syntax error then warm start
 | |
| 					; (branch always)
 | |
| 
 | |
| ; scan for "," , else do syntax error then warm start
 | |
| 
 | |
| LAB_1C01
 | |
| 	LDA	#$2C			; load A with ","
 | |
| 	BNE	LAB_SCCA		; scan for CHR$(A), else do syntax error then warm start
 | |
| 					; (branch always)
 | |
| 
 | |
| ; syntax error then warm start
 | |
| 
 | |
| LAB_SNER
 | |
| 	LDX	#$02			; error code $02 ("Syntax" error)
 | |
| 	JMP	LAB_XERR		; do error #X, then warm start
 | |
| 
 | |
| ; get value from line .. continued
 | |
| ; do tokens
 | |
| 
 | |
| LAB_1BD0
 | |
| 	CMP	#TK_MINUS		; compare with token for -
 | |
| 	BEQ	LAB_1C11		; branch if - token (do set-up for functions)
 | |
| 
 | |
| 					; wasn't -n so ..
 | |
| 	CMP	#TK_PLUS		; compare with token for +
 | |
| 	BEQ	LAB_GVAL		; branch if + token (+n = n so ignore leading +)
 | |
| 
 | |
| 	CMP	#TK_NOT		; compare with token for NOT
 | |
| 	BNE	LAB_1BE7		; branch if not token for NOT
 | |
| 
 | |
| 					; was NOT token
 | |
| TK_EQUAL_PLUS	= TK_EQUAL-TK_PLUS
 | |
| 	LDY	#TK_EQUAL_PLUS*3	; offset to NOT function
 | |
| 	BNE	LAB_1C13		; do set-up for function then execute (branch always)
 | |
| 
 | |
| ; do = compare
 | |
| 
 | |
| LAB_EQUAL
 | |
| 	JSR	LAB_EVIR		; evaluate integer expression (no sign check)
 | |
| 	LDA	FAC1_3		; get FAC1 mantissa3
 | |
| 	EOR	#$FF			; invert it
 | |
| 	TAY				; copy it
 | |
| 	LDA	FAC1_2		; get FAC1 mantissa2
 | |
| 	EOR	#$FF			; invert it
 | |
| 	JMP	LAB_AYFC		; save and convert integer AY to FAC1 and return
 | |
| 
 | |
| ; get value from line .. continued
 | |
| 
 | |
| 					; wasn't +, -, or NOT so ..
 | |
| LAB_1BE7
 | |
| 	CMP	#TK_FN		; compare with token for FN
 | |
| 	BNE	LAB_1BEE		; branch if not token for FN
 | |
| 
 | |
| 	JMP	LAB_201E		; go evaluate FNx
 | |
| 
 | |
| ; get value from line .. continued
 | |
| 
 | |
| 					; wasn't +, -, NOT or FN so ..
 | |
| LAB_1BEE
 | |
| 	SBC	#TK_SGN		; subtract with token for SGN
 | |
| 	BCS	LAB_1C27		; if a function token go do it
 | |
| 
 | |
| 	JMP	LAB_SNER		; else do syntax error
 | |
| 
 | |
| ; set-up for functions
 | |
| 
 | |
| LAB_1C11
 | |
| TK_GT_PLUS	= TK_GT-TK_PLUS
 | |
| 	LDY	#TK_GT_PLUS*3	; set offset from base to > operator
 | |
| LAB_1C13
 | |
| 	PLA				; dump return address low byte
 | |
| 	PLA				; dump return address high byte
 | |
| 	JMP	LAB_1B1D		; execute function then continue evaluation
 | |
| 
 | |
| ; variable name set-up
 | |
| ; get (var), return value in FAC_1 and $ flag
 | |
| 
 | |
| LAB_1C18
 | |
| 	JSR	LAB_GVAR		; get (var) address
 | |
| 	STA	FAC1_2		; save address low byte in FAC1 mantissa2
 | |
| 	STY	FAC1_3		; save address high byte in FAC1 mantissa3
 | |
| 	LDX	Dtypef		; get data type flag, $FF=string, $00=numeric
 | |
| 	BMI	LAB_1C25		; if string then return (does RTS)
 | |
| 
 | |
| LAB_1C24
 | |
| 	JMP	LAB_UFAC		; unpack memory (AY) into FAC1
 | |
| 
 | |
| LAB_1C25
 | |
| 	RTS
 | |
| 
 | |
| ; get value from line .. continued
 | |
| ; only functions left so ..
 | |
| 
 | |
| ; set up function references
 | |
| 
 | |
| ; new for V2.0+ this replaces a lot of IF .. THEN .. ELSEIF .. THEN .. that was needed
 | |
| ; to process function calls. now the function vector is computed and pushed on the stack
 | |
| ; and the preprocess offset is read. if the preprocess offset is non zero then the vector
 | |
| ; is calculated and the routine called, if not this routine just does RTS. whichever
 | |
| ; happens the RTS at the end of this routine, or the end of the preprocess routine, calls
 | |
| ; the function code
 | |
| 
 | |
| ; this also removes some less than elegant code that was used to bypass type checking
 | |
| ; for functions that returned strings
 | |
| 
 | |
| LAB_1C27
 | |
| 	ASL				; *2 (2 bytes per function address)
 | |
| 	TAY				; copy to index
 | |
| 
 | |
| 	LDA	LAB_FTBM,Y		; get function jump vector high byte
 | |
| 	PHA				; push functions jump vector high byte
 | |
| 	LDA	LAB_FTBL,Y		; get function jump vector low byte
 | |
| 	PHA				; push functions jump vector low byte
 | |
| 
 | |
| 	LDA	LAB_FTPM,Y		; get function pre process vector high byte
 | |
| 	BEQ	LAB_1C56		; skip pre process if null vector
 | |
| 
 | |
| 	PHA				; push functions pre process vector high byte
 | |
| 	LDA	LAB_FTPL,Y		; get function pre process vector low byte
 | |
| 	PHA				; push functions pre process vector low byte
 | |
| 
 | |
| LAB_1C56
 | |
| 	RTS				; do function, or pre process, call
 | |
| 
 | |
| ; process string expression in parenthesis
 | |
| 
 | |
| LAB_PPFS
 | |
| 	JSR	LAB_1BF7		; process expression in parenthesis
 | |
| 	JMP	LAB_CTST		; check if source is string then do function,
 | |
| 					; else do type mismatch
 | |
| 
 | |
| ; process numeric expression in parenthesis
 | |
| 
 | |
| LAB_PPFN
 | |
| 	JSR	LAB_1BF7		; process expression in parenthesis
 | |
| 	JMP	LAB_CTNM		; check if source is numeric then do function,
 | |
| 					; else do type mismatch
 | |
| 
 | |
| ; set numeric data type and increment BASIC execute pointer
 | |
| 
 | |
| LAB_PPBI
 | |
| 	LSR	Dtypef		; clear data type flag, $FF=string, $00=numeric
 | |
| 	JMP	LAB_IGBY		; increment and scan memory then do function
 | |
| 
 | |
| ; process string for LEFT$, RIGHT$ or MID$
 | |
| 
 | |
| LAB_LRMS
 | |
| 	JSR	LAB_EVEZ		; evaluate (should be string) expression
 | |
| 	JSR	LAB_1C01		; scan for ",", else do syntax error then warm start
 | |
| 	JSR	LAB_CTST		; check if source is string, else do type mismatch
 | |
| 
 | |
| 	PLA				; get function jump vector low byte
 | |
| 	TAX				; save functions jump vector low byte
 | |
| 	PLA				; get function jump vector high byte
 | |
| 	TAY				; save functions jump vector high byte
 | |
| 	LDA	des_ph		; get descriptor pointer high byte
 | |
| 	PHA				; push string pointer high byte
 | |
| 	LDA	des_pl		; get descriptor pointer low byte
 | |
| 	PHA				; push string pointer low byte
 | |
| 	TYA				; get function jump vector high byte back
 | |
| 	PHA				; save functions jump vector high byte
 | |
| 	TXA				; get function jump vector low byte back
 | |
| 	PHA				; save functions jump vector low byte
 | |
| 	JSR	LAB_GTBY		; get byte parameter
 | |
| 	TXA				; copy byte parameter to A
 | |
| 	RTS				; go do function
 | |
| 
 | |
| ; process numeric expression(s) for BIN$ or HEX$
 | |
| 
 | |
| LAB_BHSS
 | |
| 	JSR	LAB_EVEZ		; process expression
 | |
| 	JSR	LAB_CTNM		; check if source is numeric, else do type mismatch
 | |
| 	LDA	FAC1_e		; get FAC1 exponent
 | |
| 	CMP	#$98			; compare with exponent = 2^24
 | |
| 	BCS	LAB_BHER		; branch if n>=2^24 (is too big)
 | |
| 
 | |
| 	JSR	LAB_2831		; convert FAC1 floating-to-fixed
 | |
| 	LDX	#$02			; 3 bytes to do
 | |
| LAB_CFAC
 | |
| 	LDA	FAC1_1,X		; get byte from FAC1
 | |
| 	STA	nums_1,X		; save byte to temp
 | |
| 	DEX				; decrement index
 | |
| 	BPL	LAB_CFAC		; copy FAC1 mantissa to temp
 | |
| 
 | |
| 	JSR	LAB_GBYT		; get next BASIC byte
 | |
| 	LDX	#$00			; set default to no leading "0"s
 | |
| 	CMP	#')'			; compare with close bracket
 | |
| 	BEQ	LAB_1C54		; if ")" go do rest of function
 | |
| 
 | |
| 	JSR	LAB_SCGB		; scan for "," and get byte
 | |
| 	JSR	LAB_GBYT		; get last byte back
 | |
| 	CMP	#')'			; is next character )
 | |
| 	BNE	LAB_BHER		; if not ")" go do error
 | |
| 
 | |
| LAB_1C54
 | |
| 	RTS				; else do function
 | |
| 
 | |
| LAB_BHER
 | |
| 	JMP	LAB_FCER		; do function call error then warm start
 | |
| 
 | |
| ; perform EOR
 | |
| 
 | |
| ; added operator format is the same as AND or OR, precedence is the same as OR
 | |
| 
 | |
| ; this bit worked first time but it took a while to sort out the operator table
 | |
| ; pointers and offsets afterwards!
 | |
| 
 | |
| LAB_EOR
 | |
| 	JSR	GetFirst		; get first integer expression (no sign check)
 | |
| 	EOR	XOAw_l		; EOR with expression 1 low byte
 | |
| 	TAY				; save in Y
 | |
| 	LDA	FAC1_2		; get FAC1 mantissa2
 | |
| 	EOR	XOAw_h		; EOR with expression 1 high byte
 | |
| 	JMP	LAB_AYFC		; save and convert integer AY to FAC1 and return
 | |
| 
 | |
| ; perform OR
 | |
| 
 | |
| LAB_OR
 | |
| 	JSR	GetFirst		; get first integer expression (no sign check)
 | |
| 	ORA	XOAw_l		; OR with expression 1 low byte
 | |
| 	TAY				; save in Y
 | |
| 	LDA	FAC1_2		; get FAC1 mantissa2
 | |
| 	ORA	XOAw_h		; OR with expression 1 high byte
 | |
| 	JMP	LAB_AYFC		; save and convert integer AY to FAC1 and return
 | |
| 
 | |
| ; perform AND
 | |
| 
 | |
| LAB_AND
 | |
| 	JSR	GetFirst		; get first integer expression (no sign check)
 | |
| 	AND	XOAw_l		; AND with expression 1 low byte
 | |
| 	TAY				; save in Y
 | |
| 	LDA	FAC1_2		; get FAC1 mantissa2
 | |
| 	AND	XOAw_h		; AND with expression 1 high byte
 | |
| 	JMP	LAB_AYFC		; save and convert integer AY to FAC1 and return
 | |
| 
 | |
| ; get first value for OR, AND or EOR
 | |
| 
 | |
| GetFirst
 | |
| 	JSR	LAB_EVIR		; evaluate integer expression (no sign check)
 | |
| 	LDA	FAC1_2		; get FAC1 mantissa2
 | |
| 	STA	XOAw_h		; save it
 | |
| 	LDA	FAC1_3		; get FAC1 mantissa3
 | |
| 	STA	XOAw_l		; save it
 | |
| 	JSR	LAB_279B		; copy FAC2 to FAC1 (get 2nd value in expression)
 | |
| 	JSR	LAB_EVIR		; evaluate integer expression (no sign check)
 | |
| 	LDA	FAC1_3		; get FAC1 mantissa3
 | |
| LAB_1C95
 | |
| 	RTS
 | |
| 
 | |
| ; perform comparisons
 | |
| 
 | |
| ; do < compare
 | |
| 
 | |
| LAB_LTHAN
 | |
| 	JSR	LAB_CKTM		; type match check, set C for string
 | |
| 	BCS	LAB_1CAE		; branch if string
 | |
| 
 | |
| 					; do numeric < compare
 | |
| 	LDA	FAC2_s		; get FAC2 sign (b7)
 | |
| 	ORA	#$7F			; set all non sign bits
 | |
| 	AND	FAC2_1		; and FAC2 mantissa1 (AND in sign bit)
 | |
| 	STA	FAC2_1		; save FAC2 mantissa1
 | |
| 	LDA	#<FAC2_e		; set pointer low byte to FAC2
 | |
| 	LDY	#>FAC2_e		; set pointer high byte to FAC2
 | |
| 	JSR	LAB_27F8		; compare FAC1 with FAC2 (AY)
 | |
| 	TAX				; copy result
 | |
| 	JMP	LAB_1CE1		; go evaluate result
 | |
| 
 | |
| 					; do string < compare
 | |
| LAB_1CAE
 | |
| 	LSR	Dtypef		; clear data type flag, $FF=string, $00=numeric
 | |
| 	DEC	comp_f		; clear < bit in compare function flag
 | |
| 	JSR	LAB_22B6		; pop string off descriptor stack, or from top of string
 | |
| 					; space returns with A = length, X=pointer low byte,
 | |
| 					; Y=pointer high byte
 | |
| 	STA	str_ln		; save length
 | |
| 	STX	str_pl		; save string pointer low byte
 | |
| 	STY	str_ph		; save string pointer high byte
 | |
| 	LDA	FAC2_2		; get descriptor pointer low byte
 | |
| 	LDY	FAC2_3		; get descriptor pointer high byte
 | |
| 	JSR	LAB_22BA		; pop (YA) descriptor off stack or from top of string space
 | |
| 					; returns with A = length, X=pointer low byte,
 | |
| 					; Y=pointer high byte
 | |
| 	STX	FAC2_2		; save string pointer low byte
 | |
| 	STY	FAC2_3		; save string pointer high byte
 | |
| 	TAX				; copy length
 | |
| 	SEC				; set carry for subtract
 | |
| 	SBC	str_ln		; subtract string 1 length
 | |
| 	BEQ	LAB_1CD6		; branch if str 1 length = string 2 length
 | |
| 
 | |
| 	LDA	#$01			; set str 1 length > string 2 length
 | |
| 	BCC	LAB_1CD6		; branch if so
 | |
| 
 | |
| 	LDX	str_ln		; get string 1 length
 | |
| 	LDA	#$FF			; set str 1 length < string 2 length
 | |
| LAB_1CD6
 | |
| 	STA	FAC1_s		; save length compare
 | |
| 	LDY	#$FF			; set index
 | |
| 	INX				; adjust for loop
 | |
| LAB_1CDB
 | |
| 	INY				; increment index
 | |
| 	DEX				; decrement count
 | |
| 	BNE	LAB_1CE6		; branch if still bytes to do
 | |
| 
 | |
| 	LDX	FAC1_s		; get length compare back
 | |
| LAB_1CE1
 | |
| 	BMI	LAB_1CF2		; branch if str 1 < str 2
 | |
| 
 | |
| 	CLC				; flag str 1 <= str 2
 | |
| 	BCC	LAB_1CF2		; go evaluate result
 | |
| 
 | |
| LAB_1CE6
 | |
| 	LDA	(FAC2_2),Y		; get string 2 byte
 | |
| 	CMP	(FAC1_1),Y		; compare with string 1 byte
 | |
| 	BEQ	LAB_1CDB		; loop if bytes =
 | |
| 
 | |
| 	LDX	#$FF			; set str 1 < string 2
 | |
| 	BCS	LAB_1CF2		; branch if so
 | |
| 
 | |
| 	LDX	#$01			;  set str 1 > string 2
 | |
| LAB_1CF2
 | |
| 	INX				; x = 0, 1 or 2
 | |
| 	TXA				; copy to A
 | |
| 	ROL				; *2 (1, 2 or 4)
 | |
| 	AND	Cflag			; AND with comparison evaluation flag
 | |
| 	BEQ	LAB_1CFB		; branch if 0 (compare is false)
 | |
| 
 | |
| 	LDA	#$FF			; else set result true
 | |
| LAB_1CFB
 | |
| 	JMP	LAB_27DB		; save A as integer byte and return
 | |
| 
 | |
| LAB_1CFE
 | |
| 	JSR	LAB_1C01		; scan for ",", else do syntax error then warm start
 | |
| 
 | |
| ; perform DIM
 | |
| 
 | |
| LAB_DIM
 | |
| 	TAX				; copy "DIM" flag to X
 | |
| 	JSR	LAB_1D10		; search for variable
 | |
| 	JSR	LAB_GBYT		; scan memory
 | |
| 	BNE	LAB_1CFE		; scan for "," and loop if not null
 | |
| 
 | |
| 	RTS
 | |
| 
 | |
| ; perform << (left shift)
 | |
| 
 | |
| LAB_LSHIFT
 | |
| 	JSR	GetPair		; get integer expression and byte (no sign check)
 | |
| 	LDA	FAC1_2		; get expression high byte
 | |
| 	LDX	TempB			; get shift count
 | |
| 	BEQ	NoShift		; branch if zero
 | |
| 
 | |
| 	CPX	#$10			; compare bit count with 16d
 | |
| 	BCS	TooBig		; branch if >=
 | |
| 
 | |
| Ls_loop
 | |
| 	ASL	FAC1_3		; shift low byte
 | |
| 	ROL				; shift high byte
 | |
| 	DEX				; decrement bit count
 | |
| 	BNE	Ls_loop		; loop if shift not complete
 | |
| 
 | |
| 	LDY	FAC1_3		; get expression low byte
 | |
| 	JMP	LAB_AYFC		; save and convert integer AY to FAC1 and return
 | |
| 
 | |
| ; perform >> (right shift)
 | |
| 
 | |
| LAB_RSHIFT
 | |
| 	JSR	GetPair		; get integer expression and byte (no sign check)
 | |
| 	LDA	FAC1_2		; get expression high byte
 | |
| 	LDX	TempB			; get shift count
 | |
| 	BEQ	NoShift		; branch if zero
 | |
| 
 | |
| 	CPX	#$10			; compare bit count with 16d
 | |
| 	BCS	TooBig		; branch if >=
 | |
| 
 | |
| Rs_loop
 | |
| 	LSR				; shift high byte
 | |
| 	ROR	FAC1_3		; shift low byte
 | |
| 	DEX				; decrement bit count
 | |
| 	BNE	Rs_loop		; loop if shift not complete
 | |
| 
 | |
| NoShift
 | |
| 	LDY	FAC1_3		; get expression low byte
 | |
| 	JMP	LAB_AYFC		; save and convert integer AY to FAC1 and return
 | |
| 
 | |
| TooBig
 | |
| 	LDA	#$00			; clear high byte
 | |
| 	TAY				; copy to low byte
 | |
| 	JMP	LAB_AYFC		; save and convert integer AY to FAC1 and return
 | |
| 
 | |
| GetPair
 | |
| 	JSR	LAB_EVBY		; evaluate byte expression, result in X
 | |
| 	STX	TempB			; save it
 | |
| 	JSR	LAB_279B		; copy FAC2 to FAC1 (get 2nd value in expression)
 | |
| 	JMP	LAB_EVIR		; evaluate integer expression (no sign check)
 | |
| 
 | |
| ; search for variable
 | |
| 
 | |
| ; return pointer to variable in Cvaral/Cvarah
 | |
| 
 | |
| LAB_GVAR
 | |
| 	LDX	#$00			; set DIM flag = $00
 | |
| 	JSR	LAB_GBYT		; scan memory (1st character)
 | |
| LAB_1D10
 | |
| 	STX	Defdim		; save DIM flag
 | |
| LAB_1D12
 | |
| 	STA	Varnm1		; save 1st character
 | |
| 	AND	#$7F			; clear FN flag bit
 | |
| 	JSR	LAB_CASC		; check byte, return C=0 if<"A" or >"Z"
 | |
| 	BCS	LAB_1D1F		; branch if ok
 | |
| 
 | |
| 	JMP	LAB_SNER		; else syntax error then warm start
 | |
| 
 | |
| 					; was variable name so ..
 | |
| LAB_1D1F
 | |
| 	LDX	#$00			; clear 2nd character temp
 | |
| 	STX	Dtypef		; clear data type flag, $FF=string, $00=numeric
 | |
| 	JSR	LAB_IGBY		; increment and scan memory (2nd character)
 | |
| 	BCC	LAB_1D2D		; branch if character = "0"-"9" (ok)
 | |
| 
 | |
| 					; 2nd character wasn't "0" to "9" so ..
 | |
| 	JSR	LAB_CASC		; check byte, return C=0 if<"A" or >"Z"
 | |
| 	BCC	LAB_1D38		; branch if <"A" or >"Z" (go check if string)
 | |
| 
 | |
| LAB_1D2D
 | |
| 	TAX				; copy 2nd character
 | |
| 
 | |
| 					; ignore further (valid) characters in the variable name
 | |
| LAB_1D2E
 | |
| 	JSR	LAB_IGBY		; increment and scan memory (3rd character)
 | |
| 	BCC	LAB_1D2E		; loop if character = "0"-"9" (ignore)
 | |
| 
 | |
| 	JSR	LAB_CASC		; check byte, return C=0 if<"A" or >"Z"
 | |
| 	BCS	LAB_1D2E		; loop if character = "A"-"Z" (ignore)
 | |
| 
 | |
| 					; check if string variable
 | |
| LAB_1D38
 | |
| 	CMP	#'$'			; compare with "$"
 | |
| 	BNE	LAB_1D47		; branch if not string
 | |
| 
 | |
| ; to introduce a new variable type (% suffix for integers say) then this branch
 | |
| ; will need to go to that check and then that branch, if it fails, go to LAB_1D47
 | |
| 
 | |
| 					; type is string
 | |
| 	LDA	#$FF			; set data type = string
 | |
| 	STA	Dtypef		; set data type flag, $FF=string, $00=numeric
 | |
| 	TXA				; get 2nd character back
 | |
| 	ORA	#$80			; set top bit (indicate string var)
 | |
| 	TAX				; copy back to 2nd character temp
 | |
| 	JSR	LAB_IGBY		; increment and scan memory
 | |
| 
 | |
| ; after we have determined the variable type we need to come back here to determine
 | |
| ; if it's an array of type. this would plug in a%(b[,c[,d]])) integer arrays nicely
 | |
| 
 | |
| 
 | |
| LAB_1D47				; gets here with character after var name in A
 | |
| 	STX	Varnm2		; save 2nd character
 | |
| 	ORA	Sufnxf		; or with subscript/FNX flag (or FN name)
 | |
| 	CMP	#'('			; compare with "("
 | |
| 	BNE	LAB_1D53		; branch if not "("
 | |
| 
 | |
| 	JMP	LAB_1E17		; go find, or make, array
 | |
| 
 | |
| ; either find or create var
 | |
| ; var name (1st two characters only!) is in Varnm1,Varnm2
 | |
| 
 | |
| 					; variable name wasn't var(... so look for plain var
 | |
| LAB_1D53
 | |
| 	LDA	#$00			; clear A
 | |
| 	STA	Sufnxf		; clear subscript/FNX flag
 | |
| 	LDA	Svarl			; get start of vars low byte
 | |
| 	LDX	Svarh			; get start of vars high byte
 | |
| 	LDY	#$00			; clear index
 | |
| LAB_1D5D
 | |
| 	STX	Vrschh		; save search address high byte
 | |
| LAB_1D5F
 | |
| 	STA	Vrschl		; save search address low byte
 | |
| 	CPX	Sarryh		; compare high address with var space end
 | |
| 	BNE	LAB_1D69		; skip next compare if <>
 | |
| 
 | |
| 					; high addresses were = so compare low addresses
 | |
| 	CMP	Sarryl		; compare low address with var space end
 | |
| 	BEQ	LAB_1D8B		; if not found go make new var
 | |
| 
 | |
| LAB_1D69
 | |
| 	LDA	Varnm1		; get 1st character of var to find
 | |
| 	CMP	(Vrschl),Y		; compare with variable name 1st character
 | |
| 	BNE	LAB_1D77		; branch if no match
 | |
| 
 | |
| 					; 1st characters match so compare 2nd characters
 | |
| 	LDA	Varnm2		; get 2nd character of var to find
 | |
| 	INY				; index to point to variable name 2nd character
 | |
| 	CMP	(Vrschl),Y		; compare with variable name 2nd character
 | |
| 	BEQ	LAB_1DD7		; branch if match (found var)
 | |
| 
 | |
| 	DEY				; else decrement index (now = $00)
 | |
| LAB_1D77
 | |
| 	CLC				; clear carry for add
 | |
| 	LDA	Vrschl		; get search address low byte
 | |
| 	ADC	#$06			; +6 (offset to next var name)
 | |
| 	BCC	LAB_1D5F		; loop if no overflow to high byte
 | |
| 
 | |
| 	INX				; else increment high byte
 | |
| 	BNE	LAB_1D5D		; loop always (RAM doesn't extend to $FFFF !)
 | |
| 
 | |
| ; check byte, return C=0 if<"A" or >"Z" or "a" to "z"
 | |
| 
 | |
| LAB_CASC
 | |
| 	CMP	#'a'			; compare with "a"
 | |
| 	BCS	LAB_1D83		; go check <"z"+1
 | |
| 
 | |
| ; check byte, return C=0 if<"A" or >"Z"
 | |
| 
 | |
| LAB_1D82
 | |
| 	CMP	#'A'			; compare with "A"
 | |
| 	BCC	LAB_1D8A		; exit if less
 | |
| 
 | |
| 					; carry is set
 | |
| 	SBC	#$5B			; subtract "Z"+1
 | |
| 	SEC				; set carry
 | |
| 	SBC	#$A5			; subtract $A5 (restore byte)
 | |
| 					; carry clear if byte>$5A
 | |
| LAB_1D8A
 | |
| 	RTS
 | |
| 
 | |
| LAB_1D83
 | |
| 	SBC	#$7B			; subtract "z"+1
 | |
| 	SEC				; set carry
 | |
| 	SBC	#$85			; subtract $85 (restore byte)
 | |
| 					; carry clear if byte>$7A
 | |
| 	RTS
 | |
| 
 | |
| 					; reached end of variable mem without match
 | |
| 					; .. so create new variable
 | |
| LAB_1D8B
 | |
| 	PLA				; pop return address low byte
 | |
| 	PHA				; push return address low byte
 | |
| LAB_1C18p2	= LAB_1C18+2
 | |
| 	CMP	#<LAB_1C18p2	; compare with expected calling routine return low byte
 | |
| 	BNE	LAB_1D98		; if not get (var) go create new var
 | |
| 
 | |
| ; This will only drop through if the call was from LAB_1C18 and is only called
 | |
| ; from there if it is searching for a variable from the RHS of a LET a=b statement
 | |
| ; it prevents the creation of variables not assigned a value.
 | |
| 
 | |
| ; value returned by this is either numeric zero (exponent byte is $00) or null string
 | |
| ; (descriptor length byte is $00). in fact a pointer to any $00 byte would have done.
 | |
| 
 | |
| ; doing this saves 6 bytes of variable memory and 168 machine cycles of time
 | |
| 
 | |
| ; this is where you would put the undefined variable error call e.g.
 | |
| 
 | |
| ;					; variable doesn't exist so flag error
 | |
| ;	LDX	#$24			; error code $24 ("undefined variable" error)
 | |
| ;	JMP	LAB_XERR		; do error #X then warm start
 | |
| 
 | |
| ; the above code has been tested and works a treat! (it replaces the three code lines
 | |
| ; below)
 | |
| 
 | |
| 					; else return dummy null value
 | |
| 	LDA	#<LAB_1D96		; low byte point to $00,$00
 | |
| 					; (uses part of misc constants table)
 | |
| 	LDY	#>LAB_1D96		; high byte point to $00,$00
 | |
| 	RTS
 | |
| 
 | |
| 					; create new numeric variable
 | |
| LAB_1D98
 | |
| 	LDA	Sarryl		; get var mem end low byte
 | |
| 	LDY	Sarryh		; get var mem end high byte
 | |
| 	STA	Ostrtl		; save old block start low byte
 | |
| 	STY	Ostrth		; save old block start high byte
 | |
| 	LDA	Earryl		; get array mem end low byte
 | |
| 	LDY	Earryh		; get array mem end high byte
 | |
| 	STA	Obendl		; save old block end low byte
 | |
| 	STY	Obendh		; save old block end high byte
 | |
| 	CLC				; clear carry for add
 | |
| 	ADC	#$06			; +6 (space for one var)
 | |
| 	BCC	LAB_1DAE		; branch if no overflow to high byte
 | |
| 
 | |
| 	INY				; else increment high byte
 | |
| LAB_1DAE
 | |
| 	STA	Nbendl		; set new block end low byte
 | |
| 	STY	Nbendh		; set new block end high byte
 | |
| 	JSR	LAB_11CF		; open up space in memory
 | |
| 	LDA	Nbendl		; get new start low byte
 | |
| 	LDY	Nbendh		; get new start high byte (-$100)
 | |
| 	INY				; correct high byte
 | |
| 	STA	Sarryl		; save new var mem end low byte
 | |
| 	STY	Sarryh		; save new var mem end high byte
 | |
| 	LDY	#$00			; clear index
 | |
| 	LDA	Varnm1		; get var name 1st character
 | |
| 	STA	(Vrschl),Y		; save var name 1st character
 | |
| 	INY				; increment index
 | |
| 	LDA	Varnm2		; get var name 2nd character
 | |
| 	STA	(Vrschl),Y		; save var name 2nd character
 | |
| 	LDA	#$00			; clear A
 | |
| 	INY				; increment index
 | |
| 	STA	(Vrschl),Y		; initialise var byte
 | |
| 	INY				; increment index
 | |
| 	STA	(Vrschl),Y		; initialise var byte
 | |
| 	INY				; increment index
 | |
| 	STA	(Vrschl),Y		; initialise var byte
 | |
| 	INY				; increment index
 | |
| 	STA	(Vrschl),Y		; initialise var byte
 | |
| 
 | |
| 					; found a match for var ((Vrschl) = ptr)
 | |
| LAB_1DD7
 | |
| 	LDA	Vrschl		; get var address low byte
 | |
| 	CLC				; clear carry for add
 | |
| 	ADC	#$02			; +2 (offset past var name bytes)
 | |
| 	LDY	Vrschh		; get var address high byte
 | |
| 	BCC	LAB_1DE1		; branch if no overflow from add
 | |
| 
 | |
| 	INY				; else increment high byte
 | |
| LAB_1DE1
 | |
| 	STA	Cvaral		; save current var address low byte
 | |
| 	STY	Cvarah		; save current var address high byte
 | |
| 	RTS
 | |
| 
 | |
| ; set-up array pointer (Adatal/h) to first element in array
 | |
| ; set Adatal,Adatah to Astrtl,Astrth+2*Dimcnt+#$05
 | |
| 
 | |
| LAB_1DE6
 | |
| 	LDA	Dimcnt		; get # of dimensions (1, 2 or 3)
 | |
| 	ASL				; *2 (also clears the carry !)
 | |
| 	ADC	#$05			; +5 (result is 7, 9 or 11 here)
 | |
| 	ADC	Astrtl		; add array start pointer low byte
 | |
| 	LDY	Astrth		; get array pointer high byte
 | |
| 	BCC	LAB_1DF2		; branch if no overflow
 | |
| 
 | |
| 	INY				; else increment high byte
 | |
| LAB_1DF2
 | |
| 	STA	Adatal		; save array data pointer low byte
 | |
| 	STY	Adatah		; save array data pointer high byte
 | |
| 	RTS
 | |
| 
 | |
| ; evaluate integer expression
 | |
| 
 | |
| LAB_EVIN
 | |
| 	JSR	LAB_IGBY		; increment and scan memory
 | |
| 	JSR	LAB_EVNM		; evaluate expression and check is numeric,
 | |
| 					; else do type mismatch
 | |
| 
 | |
| ; evaluate integer expression (no check)
 | |
| 
 | |
| LAB_EVPI
 | |
| 	LDA	FAC1_s		; get FAC1 sign (b7)
 | |
| 	BMI	LAB_1E12		; do function call error if -ve
 | |
| 
 | |
| ; evaluate integer expression (no sign check)
 | |
| 
 | |
| LAB_EVIR
 | |
| 	LDA	FAC1_e		; get FAC1 exponent
 | |
| 	CMP	#$90			; compare with exponent = 2^16 (n>2^15)
 | |
| 	BCC	LAB_1E14		; branch if n<2^16 (is ok)
 | |
| 
 | |
| 	LDA	#<LAB_1DF7		; set pointer low byte to -32768
 | |
| 	LDY	#>LAB_1DF7		; set pointer high byte to -32768
 | |
| 	JSR	LAB_27F8		; compare FAC1 with (AY)
 | |
| LAB_1E12
 | |
| 	BNE	LAB_FCER		; if <> do function call error then warm start
 | |
| 
 | |
| LAB_1E14
 | |
| 	JMP	LAB_2831		; convert FAC1 floating-to-fixed and return
 | |
| 
 | |
| ; find or make array
 | |
| 
 | |
| LAB_1E17
 | |
| 	LDA	Defdim		; get DIM flag
 | |
| 	PHA				; push it
 | |
| 	LDA	Dtypef		; get data type flag, $FF=string, $00=numeric
 | |
| 	PHA				; push it
 | |
| 	LDY	#$00			; clear dimensions count
 | |
| 
 | |
| ; now get the array dimension(s) and stack it (them) before the data type and DIM flag
 | |
| 
 | |
| LAB_1E1F
 | |
| 	TYA				; copy dimensions count
 | |
| 	PHA				; save it
 | |
| 	LDA	Varnm2		; get array name 2nd byte
 | |
| 	PHA				; save it
 | |
| 	LDA	Varnm1		; get array name 1st byte
 | |
| 	PHA				; save it
 | |
| 	JSR	LAB_EVIN		; evaluate integer expression
 | |
| 	PLA				; pull array name 1st byte
 | |
| 	STA	Varnm1		; restore array name 1st byte
 | |
| 	PLA				; pull array name 2nd byte
 | |
| 	STA	Varnm2		; restore array name 2nd byte
 | |
| 	PLA				; pull dimensions count
 | |
| 	TAY				; restore it
 | |
| 	TSX				; copy stack pointer
 | |
| 	LDA	LAB_STAK+2,X	; get DIM flag
 | |
| 	PHA				; push it
 | |
| 	LDA	LAB_STAK+1,X	; get data type flag
 | |
| 	PHA				; push it
 | |
| 	LDA	FAC1_2		; get this dimension size high byte
 | |
| 	STA	LAB_STAK+2,X	; stack before flag bytes
 | |
| 	LDA	FAC1_3		; get this dimension size low byte
 | |
| 	STA	LAB_STAK+1,X	; stack before flag bytes
 | |
| 	INY				; increment dimensions count
 | |
| 	JSR	LAB_GBYT		; scan memory
 | |
| 	CMP	#','			; compare with ","
 | |
| 	BEQ	LAB_1E1F		; if found go do next dimension
 | |
| 
 | |
| 	STY	Dimcnt		; store dimensions count
 | |
| 	JSR	LAB_1BFB		; scan for ")" , else do syntax error then warm start
 | |
| 	PLA				; pull data type flag
 | |
| 	STA	Dtypef		; restore data type flag, $FF=string, $00=numeric
 | |
| 	PLA				; pull DIM flag
 | |
| 	STA	Defdim		; restore DIM flag
 | |
| 	LDX	Sarryl		; get array mem start low byte
 | |
| 	LDA	Sarryh		; get array mem start high byte
 | |
| 
 | |
| ; now check to see if we are at the end of array memory (we would be if there were
 | |
| ; no arrays).
 | |
| 
 | |
| LAB_1E5C
 | |
| 	STX	Astrtl		; save as array start pointer low byte
 | |
| 	STA	Astrth		; save as array start pointer high byte
 | |
| 	CMP	Earryh		; compare with array mem end high byte
 | |
| 	BNE	LAB_1E68		; branch if not reached array mem end
 | |
| 
 | |
| 	CPX	Earryl		; else compare with array mem end low byte
 | |
| 	BEQ	LAB_1EA1		; go build array if not found
 | |
| 
 | |
| 					; search for array
 | |
| LAB_1E68
 | |
| 	LDY	#$00			; clear index
 | |
| 	LDA	(Astrtl),Y		; get array name first byte
 | |
| 	INY				; increment index to second name byte
 | |
| 	CMP	Varnm1		; compare with this array name first byte
 | |
| 	BNE	LAB_1E77		; branch if no match
 | |
| 
 | |
| 	LDA	Varnm2		; else get this array name second byte
 | |
| 	CMP	(Astrtl),Y		; compare with array name second byte
 | |
| 	BEQ	LAB_1E8D		; array found so branch
 | |
| 
 | |
| 					; no match
 | |
| LAB_1E77
 | |
| 	INY				; increment index
 | |
| 	LDA	(Astrtl),Y		; get array size low byte
 | |
| 	CLC				; clear carry for add
 | |
| 	ADC	Astrtl		; add array start pointer low byte
 | |
| 	TAX				; copy low byte to X
 | |
| 	INY				; increment index
 | |
| 	LDA	(Astrtl),Y		; get array size high byte
 | |
| 	ADC	Astrth		; add array mem pointer high byte
 | |
| 	BCC	LAB_1E5C		; if no overflow go check next array
 | |
| 
 | |
| ; do array bounds error
 | |
| 
 | |
| LAB_1E85
 | |
| 	LDX	#$10			; error code $10 ("Array bounds" error)
 | |
| 	.byte	$2C			; makes next bit BIT LAB_08A2
 | |
| 
 | |
| ; do function call error
 | |
| 
 | |
| LAB_FCER
 | |
| 	LDX	#$08			; error code $08 ("Function call" error)
 | |
| LAB_1E8A
 | |
| 	JMP	LAB_XERR		; do error #X, then warm start
 | |
| 
 | |
| 					; found array, are we trying to dimension it?
 | |
| LAB_1E8D
 | |
| 	LDX	#$12			; set error $12 ("Double dimension" error)
 | |
| 	LDA	Defdim		; get DIM flag
 | |
| 	BNE	LAB_1E8A		; if we are trying to dimension it do error #X, then warm
 | |
| 					; start
 | |
| 
 | |
| ; found the array and we're not dimensioning it so we must find an element in it
 | |
| 
 | |
| 	JSR	LAB_1DE6		; set-up array pointer (Adatal/h) to first element in array
 | |
| 					; (Astrtl,Astrth points to start of array)
 | |
| 	LDA	Dimcnt		; get dimensions count
 | |
| 	LDY	#$04			; set index to array's # of dimensions
 | |
| 	CMP	(Astrtl),Y		; compare with no of dimensions
 | |
| 	BNE	LAB_1E85		; if wrong do array bounds error, could do "Wrong
 | |
| 					; dimensions" error here .. if we want a different
 | |
| 					; error message
 | |
| 
 | |
| 	JMP	LAB_1F28		; found array so go get element
 | |
| 					; (could jump to LAB_1F28 as all LAB_1F24 does is take
 | |
| 					; Dimcnt and save it at (Astrtl),Y which is already the
 | |
| 					; same or we would have taken the BNE)
 | |
| 
 | |
| 					; array not found, so build it
 | |
| LAB_1EA1
 | |
| 	JSR	LAB_1DE6		; set-up array pointer (Adatal/h) to first element in array
 | |
| 					; (Astrtl,Astrth points to start of array)
 | |
| 	JSR	LAB_121F		; check available memory, "Out of memory" error if no room
 | |
| 					; addr to check is in AY (low/high)
 | |
| 	LDY	#$00			; clear Y (don't need to clear A)
 | |
| 	STY	Aspth			; clear array data size high byte
 | |
| 	LDA	Varnm1		; get variable name 1st byte
 | |
| 	STA	(Astrtl),Y		; save array name 1st byte
 | |
| 	INY				; increment index
 | |
| 	LDA	Varnm2		; get variable name 2nd byte
 | |
| 	STA	(Astrtl),Y		; save array name 2nd byte
 | |
| 	LDA	Dimcnt		; get dimensions count
 | |
| 	LDY	#$04			; index to dimension count
 | |
| 	STY	Asptl			; set array data size low byte (four bytes per element)
 | |
| 	STA	(Astrtl),Y		; set array's dimensions count
 | |
| 
 | |
| 					; now calculate the size of the data space for the array
 | |
| 	CLC				; clear carry for add (clear on subsequent loops)
 | |
| LAB_1EC0
 | |
| 	LDX	#$0B			; set default dimension value low byte
 | |
| 	LDA	#$00			; set default dimension value high byte
 | |
| 	BIT	Defdim		; test default DIM flag
 | |
| 	BVC	LAB_1ED0		; branch if b6 of Defdim is clear
 | |
| 
 | |
| 	PLA				; else pull dimension value low byte
 | |
| 	ADC	#$01			; +1 (allow for zeroeth element)
 | |
| 	TAX				; copy low byte to X
 | |
| 	PLA				; pull dimension value high byte
 | |
| 	ADC	#$00			; add carry from low byte
 | |
| 
 | |
| LAB_1ED0
 | |
| 	INY				; index to dimension value high byte
 | |
| 	STA	(Astrtl),Y		; save dimension value high byte
 | |
| 	INY				; index to dimension value high byte
 | |
| 	TXA				; get dimension value low byte
 | |
| 	STA	(Astrtl),Y		; save dimension value low byte
 | |
| 	JSR	LAB_1F7C		; does XY = (Astrtl),Y * (Asptl)
 | |
| 	STX	Asptl			; save array data size low byte
 | |
| 	STA	Aspth			; save array data size high byte
 | |
| 	LDY	ut1_pl		; restore index (saved by subroutine)
 | |
| 	DEC	Dimcnt		; decrement dimensions count
 | |
| 	BNE	LAB_1EC0		; loop while not = 0
 | |
| 
 | |
| 	ADC	Adatah		; add size high byte to first element high byte
 | |
| 					; (carry is always clear here)
 | |
| 	BCS	LAB_1F45		; if overflow go do "Out of memory" error
 | |
| 
 | |
| 	STA	Adatah		; save end of array high byte
 | |
| 	TAY				; copy end high byte to Y
 | |
| 	TXA				; get array size low byte
 | |
| 	ADC	Adatal		; add array start low byte
 | |
| 	BCC	LAB_1EF3		; branch if no carry
 | |
| 
 | |
| 	INY				; else increment end of array high byte
 | |
| 	BEQ	LAB_1F45		; if overflow go do "Out of memory" error
 | |
| 
 | |
| 					; set-up mostly complete, now zero the array
 | |
| LAB_1EF3
 | |
| 	JSR	LAB_121F		; check available memory, "Out of memory" error if no room
 | |
| 					; addr to check is in AY (low/high)
 | |
| 	STA	Earryl		; save array mem end low byte
 | |
| 	STY	Earryh		; save array mem end high byte
 | |
| 	LDA	#$00			; clear byte for array clear
 | |
| 	INC	Aspth			; increment array size high byte (now block count)
 | |
| 	LDY	Asptl			; get array size low byte (now index to block)
 | |
| 	BEQ	LAB_1F07		; branch if low byte = $00
 | |
| 
 | |
| LAB_1F02
 | |
| 	DEY				; decrement index (do 0 to n-1)
 | |
| 	STA	(Adatal),Y		; zero byte
 | |
| 	BNE	LAB_1F02		; loop until this block done
 | |
| 
 | |
| LAB_1F07
 | |
| 	DEC	Adatah		; decrement array pointer high byte
 | |
| 	DEC	Aspth			; decrement block count high byte
 | |
| 	BNE	LAB_1F02		; loop until all blocks done
 | |
| 
 | |
| 	INC	Adatah		; correct for last loop
 | |
| 	SEC				; set carry for subtract
 | |
| 	LDY	#$02			; index to array size low byte
 | |
| 	LDA	Earryl		; get array mem end low byte
 | |
| 	SBC	Astrtl		; subtract array start low byte
 | |
| 	STA	(Astrtl),Y		; save array size low byte
 | |
| 	INY				; index to array size high byte
 | |
| 	LDA	Earryh		; get array mem end high byte
 | |
| 	SBC	Astrth		; subtract array start high byte
 | |
| 	STA	(Astrtl),Y		; save array size high byte
 | |
| 	LDA	Defdim		; get default DIM flag
 | |
| 	BNE	LAB_1F7B		; exit (RET) if this was a DIM command
 | |
| 
 | |
| 					; else, find element
 | |
| 	INY				; index to # of dimensions
 | |
| 
 | |
| LAB_1F24
 | |
| 	LDA	(Astrtl),Y		; get array's dimension count
 | |
| 	STA	Dimcnt		; save it
 | |
| 
 | |
| ; we have found, or built, the array. now we need to find the element
 | |
| 
 | |
| LAB_1F28
 | |
| 	LDA	#$00			; clear byte
 | |
| 	STA	Asptl			; clear array data pointer low byte
 | |
| LAB_1F2C
 | |
| 	STA	Aspth			; save array data pointer high byte
 | |
| 	INY				; increment index (point to array bound high byte)
 | |
| 	PLA				; pull array index low byte
 | |
| 	TAX				; copy to X
 | |
| 	STA	FAC1_2		; save index low byte to FAC1 mantissa2
 | |
| 	PLA				; pull array index high byte
 | |
| 	STA	FAC1_3		; save index high byte to FAC1 mantissa3
 | |
| 	CMP	(Astrtl),Y		; compare with array bound high byte
 | |
| 	BCC	LAB_1F48		; branch if within bounds
 | |
| 
 | |
| 	BNE	LAB_1F42		; if outside bounds do array bounds error
 | |
| 
 | |
| 					; else high byte was = so test low bytes
 | |
| 	INY				; index to array bound low byte
 | |
| 	TXA				; get array index low byte
 | |
| 	CMP	(Astrtl),Y		; compare with array bound low byte
 | |
| 	BCC	LAB_1F49		; branch if within bounds
 | |
| 
 | |
| LAB_1F42
 | |
| 	JMP	LAB_1E85		; else do array bounds error
 | |
| 
 | |
| LAB_1F45
 | |
| 	JMP	LAB_OMER		; do "Out of memory" error then warm start
 | |
| 
 | |
| LAB_1F48
 | |
| 	INY				; index to array bound low byte
 | |
| LAB_1F49
 | |
| 	LDA	Aspth			; get array data pointer high byte
 | |
| 	ORA	Asptl			; OR with array data pointer low byte
 | |
| 	BEQ	LAB_1F5A		; branch if array data pointer = null (skip multiply)
 | |
| 
 | |
| 	JSR	LAB_1F7C		; does XY = (Astrtl),Y * (Asptl)
 | |
| 	TXA				; get result low byte
 | |
| 	ADC	FAC1_2		; add index low byte from FAC1 mantissa2
 | |
| 	TAX				; save result low byte
 | |
| 	TYA				; get result high byte
 | |
| 	LDY	ut1_pl		; restore index
 | |
| LAB_1F5A
 | |
| 	ADC	FAC1_3		; add index high byte from FAC1 mantissa3
 | |
| 	STX	Asptl			; save array data pointer low byte
 | |
| 	DEC	Dimcnt		; decrement dimensions count
 | |
| 	BNE	LAB_1F2C		; loop if dimensions still to do
 | |
| 
 | |
| 	ASL	Asptl			; array data pointer low byte * 2
 | |
| 	ROL				; array data pointer high byte * 2
 | |
| 	ASL	Asptl			; array data pointer low byte * 4
 | |
| 	ROL				; array data pointer high byte * 4
 | |
| 	TAY				; copy high byte
 | |
| 	LDA	Asptl			; get low byte
 | |
| 	ADC	Adatal		; add array data start pointer low byte
 | |
| 	STA	Cvaral		; save as current var address low byte
 | |
| 	TYA				; get high byte back
 | |
| 	ADC	Adatah		; add array data start pointer high byte
 | |
| 	STA	Cvarah		; save as current var address high byte
 | |
| 	TAY				; copy high byte to Y
 | |
| 	LDA	Cvaral		; get current var address low byte
 | |
| LAB_1F7B
 | |
| 	RTS
 | |
| 
 | |
| ; does XY = (Astrtl),Y * (Asptl)
 | |
| 
 | |
| LAB_1F7C
 | |
| 	STY	ut1_pl		; save index
 | |
| 	LDA	(Astrtl),Y		; get dimension size low byte
 | |
| 	STA	dims_l		; save dimension size low byte
 | |
| 	DEY				; decrement index
 | |
| 	LDA	(Astrtl),Y		; get dimension size high byte
 | |
| 	STA	dims_h		; save dimension size high byte
 | |
| 
 | |
| 	LDA	#$10			; count = $10 (16 bit multiply)
 | |
| 	STA	numbit		; save bit count
 | |
| 	LDX	#$00			; clear result low byte
 | |
| 	LDY	#$00			; clear result high byte
 | |
| LAB_1F8F
 | |
| 	TXA				; get result low byte
 | |
| 	ASL				; *2
 | |
| 	TAX				; save result low byte
 | |
| 	TYA				; get result high byte
 | |
| 	ROL				; *2
 | |
| 	TAY				; save result high byte
 | |
| 	BCS	LAB_1F45		; if overflow go do "Out of memory" error
 | |
| 
 | |
| 	ASL	Asptl			; shift multiplier low byte
 | |
| 	ROL	Aspth			; shift multiplier high byte
 | |
| 	BCC	LAB_1FA8		; skip add if no carry
 | |
| 
 | |
| 	CLC				; else clear carry for add
 | |
| 	TXA				; get result low byte
 | |
| 	ADC	dims_l		; add dimension size low byte
 | |
| 	TAX				; save result low byte
 | |
| 	TYA				; get result high byte
 | |
| 	ADC	dims_h		; add dimension size high byte
 | |
| 	TAY				; save result high byte
 | |
| 	BCS	LAB_1F45		; if overflow go do "Out of memory" error
 | |
| 
 | |
| LAB_1FA8
 | |
| 	DEC	numbit		; decrement bit count
 | |
| 	BNE	LAB_1F8F		; loop until all done
 | |
| 
 | |
| 	RTS
 | |
| 
 | |
| ; perform FRE()
 | |
| 
 | |
| LAB_FRE
 | |
| 	LDA	Dtypef		; get data type flag, $FF=string, $00=numeric
 | |
| 	BPL	LAB_1FB4		; branch if numeric
 | |
| 
 | |
| 	JSR	LAB_22B6		; pop string off descriptor stack, or from top of string
 | |
| 					; space returns with A = length, X=$71=pointer low byte,
 | |
| 					; Y=$72=pointer high byte
 | |
| 
 | |
| 					; FRE(n) was numeric so do this
 | |
| LAB_1FB4
 | |
| 	JSR	LAB_GARB		; go do garbage collection
 | |
| 	SEC				; set carry for subtract
 | |
| 	LDA	Sstorl		; get bottom of string space low byte
 | |
| 	SBC	Earryl		; subtract array mem end low byte
 | |
| 	TAY				; copy result to Y
 | |
| 	LDA	Sstorh		; get bottom of string space high byte
 | |
| 	SBC	Earryh		; subtract array mem end high byte
 | |
| 
 | |
| ; save and convert integer AY to FAC1
 | |
| 
 | |
| LAB_AYFC
 | |
| 	LSR	Dtypef		; clear data type flag, $FF=string, $00=numeric
 | |
| 	STA	FAC1_1		; save FAC1 mantissa1
 | |
| 	STY	FAC1_2		; save FAC1 mantissa2
 | |
| 	LDX	#$90			; set exponent=2^16 (integer)
 | |
| 	JMP	LAB_27E3		; set exp=X, clear FAC1_3, normalise and return
 | |
| 
 | |
| ; perform POS()
 | |
| 
 | |
| LAB_POS
 | |
| 	LDY	TPos			; get terminal position
 | |
| 
 | |
| ; convert Y to byte in FAC1
 | |
| 
 | |
| LAB_1FD0
 | |
| 	LDA	#$00			; clear high byte
 | |
| 	BEQ	LAB_AYFC		; always save and convert integer AY to FAC1 and return
 | |
| 
 | |
| ; check not Direct (used by DEF and INPUT)
 | |
| 
 | |
| LAB_CKRN
 | |
| 	LDX	Clineh		; get current line high byte
 | |
| 	INX				; increment it
 | |
| 	BNE	LAB_1F7B		; return if can continue not direct mode
 | |
| 
 | |
| 					; else do illegal direct error
 | |
| LAB_1FD9
 | |
| 	LDX	#$16			; error code $16 ("Illegal direct" error)
 | |
| LAB_1FDB
 | |
| 	JMP	LAB_XERR		; go do error #X, then warm start
 | |
| 
 | |
| ; perform DEF
 | |
| 
 | |
| LAB_DEF
 | |
| 	JSR	LAB_200B		; check FNx syntax
 | |
| 	STA	func_l		; save function pointer low byte
 | |
| 	STY	func_h		; save function pointer high byte
 | |
| 	JSR	LAB_CKRN		; check not Direct (back here if ok)
 | |
| 	JSR	LAB_1BFE		; scan for "(" , else do syntax error then warm start
 | |
| 	LDA	#$80			; set flag for FNx
 | |
| 	STA	Sufnxf		; save subscript/FNx flag
 | |
| 	JSR	LAB_GVAR		; get (var) address
 | |
| 	JSR	LAB_CTNM		; check if source is numeric, else do type mismatch
 | |
| 	JSR	LAB_1BFB		; scan for ")" , else do syntax error then warm start
 | |
| 	LDA	#TK_EQUAL		; get = token
 | |
| 	JSR	LAB_SCCA		; scan for CHR$(A), else do syntax error then warm start
 | |
| 	LDA	Cvarah		; get current var address high byte
 | |
| 	PHA				; push it
 | |
| 	LDA	Cvaral		; get current var address low byte
 | |
| 	PHA				; push it
 | |
| 	LDA	Bpntrh		; get BASIC execute pointer high byte
 | |
| 	PHA				; push it
 | |
| 	LDA	Bpntrl		; get BASIC execute pointer low byte
 | |
| 	PHA				; push it
 | |
| 	JSR	LAB_DATA		; go perform DATA
 | |
| 	JMP	LAB_207A		; put execute pointer and variable pointer into function
 | |
| 					; and return
 | |
| 
 | |
| ; check FNx syntax
 | |
| 
 | |
| LAB_200B
 | |
| 	LDA	#TK_FN		; get FN" token
 | |
| 	JSR	LAB_SCCA		; scan for CHR$(A) , else do syntax error then warm start
 | |
| 					; return character after A
 | |
| 	ORA	#$80			; set FN flag bit
 | |
| 	STA	Sufnxf		; save FN flag so array variable test fails
 | |
| 	JSR	LAB_1D12		; search for FN variable
 | |
| 	JMP	LAB_CTNM		; check if source is numeric and return, else do type
 | |
| 					; mismatch
 | |
| 
 | |
| 					; Evaluate FNx
 | |
| LAB_201E
 | |
| 	JSR	LAB_200B		; check FNx syntax
 | |
| 	PHA				; push function pointer low byte
 | |
| 	TYA				; copy function pointer high byte
 | |
| 	PHA				; push function pointer high byte
 | |
| 	JSR	LAB_1BFE		; scan for "(", else do syntax error then warm start
 | |
| 	JSR	LAB_EVEX		; evaluate expression
 | |
| 	JSR	LAB_1BFB		; scan for ")", else do syntax error then warm start
 | |
| 	JSR	LAB_CTNM		; check if source is numeric, else do type mismatch
 | |
| 	PLA				; pop function pointer high byte
 | |
| 	STA	func_h		; restore it
 | |
| 	PLA				; pop function pointer low byte
 | |
| 	STA	func_l		; restore it
 | |
| 	LDX	#$20			; error code $20 ("Undefined function" error)
 | |
| 	LDY	#$03			; index to variable pointer high byte
 | |
| 	LDA	(func_l),Y		; get variable pointer high byte
 | |
| 	BEQ	LAB_1FDB		; if zero go do undefined function error
 | |
| 
 | |
| 	STA	Cvarah		; save variable address high byte
 | |
| 	DEY				; index to variable address low byte
 | |
| 	LDA	(func_l),Y		; get variable address low byte
 | |
| 	STA	Cvaral		; save variable address low byte
 | |
| 	TAX				; copy address low byte
 | |
| 
 | |
| 					; now stack the function variable value before use
 | |
| 	INY				; index to mantissa_3
 | |
| LAB_2043
 | |
| 	LDA	(Cvaral),Y		; get byte from variable
 | |
| 	PHA				; stack it
 | |
| 	DEY				; decrement index
 | |
| 	BPL	LAB_2043		; loop until variable stacked
 | |
| 
 | |
| 	LDY	Cvarah		; get variable address high byte
 | |
| 	JSR	LAB_2778		; pack FAC1 (function expression value) into (XY)
 | |
| 					; (function variable), return Y=0, always
 | |
| 	LDA	Bpntrh		; get BASIC execute pointer high byte
 | |
| 	PHA				; push it
 | |
| 	LDA	Bpntrl		; get BASIC execute pointer low byte
 | |
| 	PHA				; push it
 | |
| 	LDA	(func_l),Y		; get function execute pointer low byte
 | |
| 	STA	Bpntrl		; save as BASIC execute pointer low byte
 | |
| 	INY				; index to high byte
 | |
| 	LDA	(func_l),Y		; get function execute pointer high byte
 | |
| 	STA	Bpntrh		; save as BASIC execute pointer high byte
 | |
| 	LDA	Cvarah		; get variable address high byte
 | |
| 	PHA				; push it
 | |
| 	LDA	Cvaral		; get variable address low byte
 | |
| 	PHA				; push it
 | |
| 	JSR	LAB_EVNM		; evaluate expression and check is numeric,
 | |
| 					; else do type mismatch
 | |
| 	PLA				; pull variable address low byte
 | |
| 	STA	func_l		; save variable address low byte
 | |
| 	PLA				; pull variable address high byte
 | |
| 	STA	func_h		; save variable address high byte
 | |
| 	JSR	LAB_GBYT		; scan memory
 | |
| 	BEQ	LAB_2074		; branch if null (should be [EOL] marker)
 | |
| 
 | |
| 	JMP	LAB_SNER		; else syntax error then warm start
 | |
| 
 | |
| ; restore Bpntrl,Bpntrh and function variable from stack
 | |
| 
 | |
| LAB_2074
 | |
| 	PLA				; pull BASIC execute pointer low byte
 | |
| 	STA	Bpntrl		; restore BASIC execute pointer low byte
 | |
| 	PLA				; pull BASIC execute pointer high byte
 | |
| 	STA	Bpntrh		; restore BASIC execute pointer high byte
 | |
| 
 | |
| ; put execute pointer and variable pointer into function
 | |
| 
 | |
| LAB_207A
 | |
| 	LDY	#$00			; clear index
 | |
| 	PLA				; pull BASIC execute pointer low byte
 | |
| 	STA	(func_l),Y		; save to function
 | |
| 	INY				; increment index
 | |
| 	PLA				; pull BASIC execute pointer high byte
 | |
| 	STA	(func_l),Y		; save to function
 | |
| 	INY				; increment index
 | |
| 	PLA				; pull current var address low byte
 | |
| 	STA	(func_l),Y		; save to function
 | |
| 	INY				; increment index
 | |
| 	PLA				; pull current var address high byte
 | |
| 	STA	(func_l),Y		; save to function
 | |
| 	RTS
 | |
| 
 | |
| ; perform STR$()
 | |
| 
 | |
| LAB_STRS
 | |
| 	JSR	LAB_CTNM		; check if source is numeric, else do type mismatch
 | |
| 	JSR	LAB_296E		; convert FAC1 to string
 | |
| 	LDA	#<Decssp1		; set result string low pointer
 | |
| 	LDY	#>Decssp1		; set result string high pointer
 | |
| 	BEQ	LAB_20AE		; print null terminated string to Sutill/Sutilh
 | |
| 
 | |
| ; Do string vector
 | |
| ; copy des_pl/h to des_2l/h and make string space A bytes long
 | |
| 
 | |
| LAB_209C
 | |
| 	LDX	des_pl		; get descriptor pointer low byte
 | |
| 	LDY	des_ph		; get descriptor pointer high byte
 | |
| 	STX	des_2l		; save descriptor pointer low byte
 | |
| 	STY	des_2h		; save descriptor pointer high byte
 | |
| 
 | |
| ; make string space A bytes long
 | |
| ; A=length, X=Sutill=ptr low byte, Y=Sutilh=ptr high byte
 | |
| 
 | |
| LAB_MSSP
 | |
| 	JSR	LAB_2115		; make space in string memory for string A long
 | |
| 					; return X=Sutill=ptr low byte, Y=Sutilh=ptr high byte
 | |
| 	STX	str_pl		; save string pointer low byte
 | |
| 	STY	str_ph		; save string pointer high byte
 | |
| 	STA	str_ln		; save length
 | |
| 	RTS
 | |
| 
 | |
| ; Scan, set up string
 | |
| ; print " terminated string to Sutill/Sutilh
 | |
| 
 | |
| LAB_20AE
 | |
| 	LDX	#$22			; set terminator to "
 | |
| 	STX	Srchc			; set search character (terminator 1)
 | |
| 	STX	Asrch			; set terminator 2
 | |
| 
 | |
| ; print [Srchc] or [Asrch] terminated string to Sutill/Sutilh
 | |
| ; source is AY
 | |
| 
 | |
| LAB_20B4
 | |
| 	STA	ssptr_l		; store string start low byte
 | |
| 	STY	ssptr_h		; store string start high byte
 | |
| 	STA	str_pl		; save string pointer low byte
 | |
| 	STY	str_ph		; save string pointer high byte
 | |
| 	LDY	#$FF			; set length to -1
 | |
| LAB_20BE
 | |
| 	INY				; increment length
 | |
| 	LDA	(ssptr_l),Y		; get byte from string
 | |
| 	BEQ	LAB_20CF		; exit loop if null byte [EOS]
 | |
| 
 | |
| 	CMP	Srchc			; compare with search character (terminator 1)
 | |
| 	BEQ	LAB_20CB		; branch if terminator
 | |
| 
 | |
| 	CMP	Asrch			; compare with terminator 2
 | |
| 	BNE	LAB_20BE		; loop if not terminator 2
 | |
| 
 | |
| LAB_20CB
 | |
| 	CMP	#$22			; compare with "
 | |
| 	BEQ	LAB_20D0		; branch if " (carry set if = !)
 | |
| 
 | |
| LAB_20CF
 | |
| 	CLC				; clear carry for add (only if [EOL] terminated string)
 | |
| LAB_20D0
 | |
| 	STY	str_ln		; save length in FAC1 exponent
 | |
| 	TYA				; copy length to A
 | |
| 	ADC	ssptr_l		; add string start low byte
 | |
| 	STA	Sendl			; save string end low byte
 | |
| 	LDX	ssptr_h		; get string start high byte
 | |
| 	BCC	LAB_20DC		; branch if no low byte overflow
 | |
| 
 | |
| 	INX				; else increment high byte
 | |
| LAB_20DC
 | |
| 	STX	Sendh			; save string end high byte
 | |
| 	LDA	ssptr_h		; get string start high byte
 | |
| 	CMP	#>Ram_base		; compare with start of program memory
 | |
| 	BCS	LAB_RTST		; branch if not in utility area
 | |
| 
 | |
| 					; string in utility area, move to string memory
 | |
| 	TYA				; copy length to A
 | |
| 	JSR	LAB_209C		; copy des_pl/h to des_2l/h and make string space A bytes
 | |
| 					; long
 | |
| 	LDX	ssptr_l		; get string start low byte
 | |
| 	LDY	ssptr_h		; get string start high byte
 | |
| 	JSR	LAB_2298		; store string A bytes long from XY to (Sutill)
 | |
| 
 | |
| ; check for space on descriptor stack then ..
 | |
| ; put string address and length on descriptor stack and update stack pointers
 | |
| 
 | |
| LAB_RTST
 | |
| 	LDX	next_s		; get string stack pointer
 | |
| 	CPX	#des_sk+$09		; compare with max+1
 | |
| 	BNE	LAB_20F8		; branch if space on string stack
 | |
| 
 | |
| 					; else do string too complex error
 | |
| 	LDX	#$1C			; error code $1C ("String too complex" error)
 | |
| LAB_20F5
 | |
| 	JMP	LAB_XERR		; do error #X, then warm start
 | |
| 
 | |
| ; put string address and length on descriptor stack and update stack pointers
 | |
| 
 | |
| LAB_20F8
 | |
| 	LDA	str_ln		; get string length
 | |
| 	STA	PLUS_0,X		; put on string stack
 | |
| 	LDA	str_pl		; get string pointer low byte
 | |
| 	STA	PLUS_1,X		; put on string stack
 | |
| 	LDA	str_ph		; get string pointer high byte
 | |
| 	STA	PLUS_2,X		; put on string stack
 | |
| 	LDY	#$00			; clear Y
 | |
| 	STX	des_pl		; save string descriptor pointer low byte
 | |
| 	STY	des_ph		; save string descriptor pointer high byte (always $00)
 | |
| 	DEY				; Y = $FF
 | |
| 	STY	Dtypef		; save data type flag, $FF=string
 | |
| 	STX	last_sl		; save old stack pointer (current top item)
 | |
| 	INX				; update stack pointer
 | |
| 	INX				; update stack pointer
 | |
| 	INX				; update stack pointer
 | |
| 	STX	next_s		; save new top item value
 | |
| 	RTS
 | |
| 
 | |
| ; Build descriptor
 | |
| ; make space in string memory for string A long
 | |
| ; return X=Sutill=ptr low byte, Y=Sutill=ptr high byte
 | |
| 
 | |
| LAB_2115
 | |
| 	LSR	Gclctd		; clear garbage collected flag (b7)
 | |
| 
 | |
| 					; make space for string A long
 | |
| LAB_2117
 | |
| 	PHA				; save string length
 | |
| 	EOR	#$FF			; complement it
 | |
| 	SEC				; set carry for subtract (twos comp add)
 | |
| 	ADC	Sstorl		; add bottom of string space low byte (subtract length)
 | |
| 	LDY	Sstorh		; get bottom of string space high byte
 | |
| 	BCS	LAB_2122		; skip decrement if no underflow
 | |
| 
 | |
| 	DEY				; decrement bottom of string space high byte
 | |
| LAB_2122
 | |
| 	CPY	Earryh		; compare with array mem end high byte
 | |
| 	BCC	LAB_2137		; do out of memory error if less
 | |
| 
 | |
| 	BNE	LAB_212C		; if not = skip next test
 | |
| 
 | |
| 	CMP	Earryl		; compare with array mem end low byte
 | |
| 	BCC	LAB_2137		; do out of memory error if less
 | |
| 
 | |
| LAB_212C
 | |
| 	STA	Sstorl		; save bottom of string space low byte
 | |
| 	STY	Sstorh		; save bottom of string space high byte
 | |
| 	STA	Sutill		; save string utility ptr low byte
 | |
| 	STY	Sutilh		; save string utility ptr high byte
 | |
| 	TAX				; copy low byte to X
 | |
| 	PLA				; get string length back
 | |
| 	RTS
 | |
| 
 | |
| LAB_2137
 | |
| 	LDX	#$0C			; error code $0C ("Out of memory" error)
 | |
| 	LDA	Gclctd		; get garbage collected flag
 | |
| 	BMI	LAB_20F5		; if set then do error code X
 | |
| 
 | |
| 	JSR	LAB_GARB		; else go do garbage collection
 | |
| 	LDA	#$80			; flag for garbage collected
 | |
| 	STA	Gclctd		; set garbage collected flag
 | |
| 	PLA				; pull length
 | |
| 	BNE	LAB_2117		; go try again (loop always, length should never be = $00)
 | |
| 
 | |
| ; garbage collection routine
 | |
| 
 | |
| LAB_GARB
 | |
| 	LDX	Ememl			; get end of mem low byte
 | |
| 	LDA	Ememh			; get end of mem high byte
 | |
| 
 | |
| ; re-run routine from last ending
 | |
| 
 | |
| LAB_214B
 | |
| 	STX	Sstorl		; set string storage low byte
 | |
| 	STA	Sstorh		; set string storage high byte
 | |
| 	LDY	#$00			; clear index
 | |
| 	STY	garb_h		; clear working pointer high byte (flag no strings to move)
 | |
| 	LDA	Earryl		; get array mem end low byte
 | |
| 	LDX	Earryh		; get array mem end high byte
 | |
| 	STA	Histrl		; save as highest string low byte
 | |
| 	STX	Histrh		; save as highest string high byte
 | |
| 	LDA	#des_sk		; set descriptor stack pointer
 | |
| 	STA	ut1_pl		; save descriptor stack pointer low byte
 | |
| 	STY	ut1_ph		; save descriptor stack pointer high byte ($00)
 | |
| LAB_2161
 | |
| 	CMP	next_s		; compare with descriptor stack pointer
 | |
| 	BEQ	LAB_216A		; branch if =
 | |
| 
 | |
| 	JSR	LAB_21D7		; go garbage collect descriptor stack
 | |
| 	BEQ	LAB_2161		; loop always
 | |
| 
 | |
| 					; done stacked strings, now do string vars
 | |
| LAB_216A
 | |
| 	ASL	g_step		; set step size = $06
 | |
| 	LDA	Svarl			; get start of vars low byte
 | |
| 	LDX	Svarh			; get start of vars high byte
 | |
| 	STA	ut1_pl		; save as pointer low byte
 | |
| 	STX	ut1_ph		; save as pointer high byte
 | |
| LAB_2176
 | |
| 	CPX	Sarryh		; compare start of arrays high byte
 | |
| 	BNE	LAB_217E		; branch if no high byte match
 | |
| 
 | |
| 	CMP	Sarryl		; else compare start of arrays low byte
 | |
| 	BEQ	LAB_2183		; branch if = var mem end
 | |
| 
 | |
| LAB_217E
 | |
| 	JSR	LAB_21D1		; go garbage collect strings
 | |
| 	BEQ	LAB_2176		; loop always
 | |
| 
 | |
| 					; done string vars, now do string arrays
 | |
| LAB_2183
 | |
| 	STA	Nbendl		; save start of arrays low byte as working pointer
 | |
| 	STX	Nbendh		; save start of arrays high byte as working pointer
 | |
| 	LDA	#$04			; set step size
 | |
| 	STA	g_step		; save step size
 | |
| LAB_218B
 | |
| 	LDA	Nbendl		; get pointer low byte
 | |
| 	LDX	Nbendh		; get pointer high byte
 | |
| LAB_218F
 | |
| 	CPX	Earryh		; compare with array mem end high byte
 | |
| 	BNE	LAB_219A		; branch if not at end
 | |
| 
 | |
| 	CMP	Earryl		; else compare with array mem end low byte
 | |
| 	BEQ	LAB_2216		; tidy up and exit if at end
 | |
| 
 | |
| LAB_219A
 | |
| 	STA	ut1_pl		; save pointer low byte
 | |
| 	STX	ut1_ph		; save pointer high byte
 | |
| 	LDY	#$02			; set index
 | |
| 	LDA	(ut1_pl),Y		; get array size low byte
 | |
| 	ADC	Nbendl		; add start of this array low byte
 | |
| 	STA	Nbendl		; save start of next array low byte
 | |
| 	INY				; increment index
 | |
| 	LDA	(ut1_pl),Y		; get array size high byte
 | |
| 	ADC	Nbendh		; add start of this array high byte
 | |
| 	STA	Nbendh		; save start of next array high byte
 | |
| 	LDY	#$01			; set index
 | |
| 	LDA	(ut1_pl),Y		; get name second byte
 | |
| 	BPL	LAB_218B		; skip if not string array
 | |
| 
 | |
| ; was string array so ..
 | |
| 
 | |
| 	LDY	#$04			; set index
 | |
| 	LDA	(ut1_pl),Y		; get # of dimensions
 | |
| 	ASL				; *2
 | |
| 	ADC	#$05			; +5 (array header size)
 | |
| 	JSR	LAB_2208		; go set up for first element
 | |
| LAB_21C4
 | |
| 	CPX	Nbendh		; compare with start of next array high byte
 | |
| 	BNE	LAB_21CC		; branch if <> (go do this array)
 | |
| 
 | |
| 	CMP	Nbendl		; else compare element pointer low byte with next array
 | |
| 					; low byte
 | |
| 	BEQ	LAB_218F		; if equal then go do next array
 | |
| 
 | |
| LAB_21CC
 | |
| 	JSR	LAB_21D7		; go defrag array strings
 | |
| 	BEQ	LAB_21C4		; go do next array string (loop always)
 | |
| 
 | |
| ; defrag string variables
 | |
| ; enter with XA = variable pointer
 | |
| ; return with XA = next variable pointer
 | |
| 
 | |
| LAB_21D1
 | |
| 	INY				; increment index (Y was $00)
 | |
| 	LDA	(ut1_pl),Y		; get var name byte 2
 | |
| 	BPL	LAB_2206		; if not string, step pointer to next var and return
 | |
| 
 | |
| 	INY				; else increment index
 | |
| LAB_21D7
 | |
| 	LDA	(ut1_pl),Y		; get string length
 | |
| 	BEQ	LAB_2206		; if null, step pointer to next string and return
 | |
| 
 | |
| 	INY				; else increment index
 | |
| 	LDA	(ut1_pl),Y		; get string pointer low byte
 | |
| 	TAX				; copy to X
 | |
| 	INY				; increment index
 | |
| 	LDA	(ut1_pl),Y		; get string pointer high byte
 | |
| 	CMP	Sstorh		; compare bottom of string space high byte
 | |
| 	BCC	LAB_21EC		; branch if less
 | |
| 
 | |
| 	BNE	LAB_2206		; if greater, step pointer to next string and return
 | |
| 
 | |
| 					; high bytes were = so compare low bytes
 | |
| 	CPX	Sstorl		; compare bottom of string space low byte
 | |
| 	BCS	LAB_2206		; if >=, step pointer to next string and return
 | |
| 
 | |
| 					; string pointer is < string storage pointer (pos in mem)
 | |
| LAB_21EC
 | |
| 	CMP	Histrh		; compare to highest string high byte
 | |
| 	BCC	LAB_2207		; if <, step pointer to next string and return
 | |
| 
 | |
| 	BNE	LAB_21F6		; if > update pointers, step to next and return
 | |
| 
 | |
| 					; high bytes were = so compare low bytes
 | |
| 	CPX	Histrl		; compare to highest string low byte
 | |
| 	BCC	LAB_2207		; if <, step pointer to next string and return
 | |
| 
 | |
| 					; string is in string memory space
 | |
| LAB_21F6
 | |
| 	STX	Histrl		; save as new highest string low byte
 | |
| 	STA	Histrh		; save as new highest string high byte
 | |
| 	LDA	ut1_pl		; get start of vars(descriptors) low byte
 | |
| 	LDX	ut1_ph		; get start of vars(descriptors) high byte
 | |
| 	STA	garb_l		; save as working pointer low byte
 | |
| 	STX	garb_h		; save as working pointer high byte
 | |
| 	DEY				; decrement index DIFFERS
 | |
| 	DEY				; decrement index (should point to descriptor start)
 | |
| 	STY	g_indx		; save index pointer
 | |
| 
 | |
| 					; step pointer to next string
 | |
| LAB_2206
 | |
| 	CLC				; clear carry for add
 | |
| LAB_2207
 | |
| 	LDA	g_step		; get step size
 | |
| LAB_2208
 | |
| 	ADC	ut1_pl		; add pointer low byte
 | |
| 	STA	ut1_pl		; save pointer low byte
 | |
| 	BCC	LAB_2211		; branch if no overflow
 | |
| 
 | |
| 	INC	ut1_ph		; else increment high byte
 | |
| LAB_2211
 | |
| 	LDX	ut1_ph		; get pointer high byte
 | |
| 	LDY	#$00			; clear Y
 | |
| 	RTS
 | |
| 
 | |
| ; search complete, now either exit or set-up and move string
 | |
| 
 | |
| LAB_2216
 | |
| 	DEC	g_step		; decrement step size (now $03 for descriptor stack)
 | |
| 	LDX	garb_h		; get string to move high byte
 | |
| 	BEQ	LAB_2211		; exit if nothing to move
 | |
| 
 | |
| 	LDY	g_indx		; get index byte back (points to descriptor)
 | |
| 	CLC				; clear carry for add
 | |
| 	LDA	(garb_l),Y		; get string length
 | |
| 	ADC	Histrl		; add highest string low byte
 | |
| 	STA	Obendl		; save old block end low pointer
 | |
| 	LDA	Histrh		; get highest string high byte
 | |
| 	ADC	#$00			; add any carry
 | |
| 	STA	Obendh		; save old block end high byte
 | |
| 	LDA	Sstorl		; get bottom of string space low byte
 | |
| 	LDX	Sstorh		; get bottom of string space high byte
 | |
| 	STA	Nbendl		; save new block end low byte
 | |
| 	STX	Nbendh		; save new block end high byte
 | |
| 	JSR	LAB_11D6		; open up space in memory, don't set array end
 | |
| 	LDY	g_indx		; get index byte
 | |
| 	INY				; point to descriptor low byte
 | |
| 	LDA	Nbendl		; get string pointer low byte
 | |
| 	STA	(garb_l),Y		; save new string pointer low byte
 | |
| 	TAX				; copy string pointer low byte
 | |
| 	INC	Nbendh		; correct high byte (move sets high byte -1)
 | |
| 	LDA	Nbendh		; get new string pointer high byte
 | |
| 	INY				; point to descriptor high byte
 | |
| 	STA	(garb_l),Y		; save new string pointer high byte
 | |
| 	JMP	LAB_214B		; re-run routine from last ending
 | |
| 					; (but don't collect this string)
 | |
| 
 | |
| ; concatenate
 | |
| ; add strings, string 1 is in descriptor des_pl, string 2 is in line
 | |
| 
 | |
| LAB_224D
 | |
| 	LDA	des_ph		; get descriptor pointer high byte
 | |
| 	PHA				; put on stack
 | |
| 	LDA	des_pl		; get descriptor pointer low byte
 | |
| 	PHA				; put on stack
 | |
| 	JSR	LAB_GVAL		; get value from line
 | |
| 	JSR	LAB_CTST		; check if source is string, else do type mismatch
 | |
| 	PLA				; get descriptor pointer low byte back
 | |
| 	STA	ssptr_l		; set pointer low byte
 | |
| 	PLA				; get descriptor pointer high byte back
 | |
| 	STA	ssptr_h		; set pointer high byte
 | |
| 	LDY	#$00			; clear index
 | |
| 	LDA	(ssptr_l),Y		; get length_1 from descriptor
 | |
| 	CLC				; clear carry for add
 | |
| 	ADC	(des_pl),Y		; add length_2
 | |
| 	BCC	LAB_226D		; branch if no overflow
 | |
| 
 | |
| 	LDX	#$1A			; else set error code $1A ("String too long" error)
 | |
| 	JMP	LAB_XERR		; do error #X, then warm start
 | |
| 
 | |
| LAB_226D
 | |
| 	JSR	LAB_209C		; copy des_pl/h to des_2l/h and make string space A bytes
 | |
| 					; long
 | |
| 	JSR	LAB_228A		; copy string from descriptor (sdescr) to (Sutill)
 | |
| 	LDA	des_2l		; get descriptor pointer low byte
 | |
| 	LDY	des_2h		; get descriptor pointer high byte
 | |
| 	JSR	LAB_22BA		; pop (YA) descriptor off stack or from top of string space
 | |
| 					; returns with A = length, ut1_pl = pointer low byte,
 | |
| 					; ut1_ph = pointer high byte
 | |
| 	JSR	LAB_229C		; store string A bytes long from (ut1_pl) to (Sutill)
 | |
| 	LDA	ssptr_l		;.set descriptor pointer low byte
 | |
| 	LDY	ssptr_h		;.set descriptor pointer high byte
 | |
| 	JSR	LAB_22BA		; pop (YA) descriptor off stack or from top of string space
 | |
| 					; returns with A = length, X=ut1_pl=pointer low byte,
 | |
| 					; Y=ut1_ph=pointer high byte
 | |
| 	JSR	LAB_RTST		; check for space on descriptor stack then put string
 | |
| 					; address and length on descriptor stack and update stack
 | |
| 					; pointers
 | |
| 	JMP	LAB_1ADB		;.continue evaluation
 | |
| 
 | |
| ; copy string from descriptor (sdescr) to (Sutill)
 | |
| 
 | |
| LAB_228A
 | |
| 	LDY	#$00			; clear index
 | |
| 	LDA	(sdescr),Y		; get string length
 | |
| 	PHA				; save on stack
 | |
| 	INY				; increment index
 | |
| 	LDA	(sdescr),Y		; get source string pointer low byte
 | |
| 	TAX				; copy to X
 | |
| 	INY				; increment index
 | |
| 	LDA	(sdescr),Y		; get source string pointer high byte
 | |
| 	TAY				; copy to Y
 | |
| 	PLA				; get length back
 | |
| 
 | |
| ; store string A bytes long from YX to (Sutill)
 | |
| 
 | |
| LAB_2298
 | |
| 	STX	ut1_pl		; save source string pointer low byte
 | |
| 	STY	ut1_ph		; save source string pointer high byte
 | |
| 
 | |
| ; store string A bytes long from (ut1_pl) to (Sutill)
 | |
| 
 | |
| LAB_229C
 | |
| 	TAX				; copy length to index (don't count with Y)
 | |
| 	BEQ	LAB_22B2		; branch if = $0 (null string) no need to add zero length
 | |
| 
 | |
| 	LDY	#$00			; zero pointer (copy forward)
 | |
| LAB_22A0
 | |
| 	LDA	(ut1_pl),Y		; get source byte
 | |
| 	STA	(Sutill),Y		; save destination byte
 | |
| 
 | |
| 	INY				; increment index
 | |
| 	DEX				; decrement counter
 | |
| 	BNE	LAB_22A0		; loop while <> 0
 | |
| 
 | |
| 	TYA				; restore length from Y
 | |
| LAB_22A9
 | |
| 	CLC				; clear carry for add
 | |
| 	ADC	Sutill		; add string utility ptr low byte
 | |
| 	STA	Sutill		; save string utility ptr low byte
 | |
| 	BCC	LAB_22B2		; branch if no carry
 | |
| 
 | |
| 	INC	Sutilh		; else increment string utility ptr high byte
 | |
| LAB_22B2
 | |
| 	RTS
 | |
| 
 | |
| ; evaluate string
 | |
| 
 | |
| LAB_EVST
 | |
| 	JSR	LAB_CTST		; check if source is string, else do type mismatch
 | |
| 
 | |
| ; pop string off descriptor stack, or from top of string space
 | |
| ; returns with A = length, X=pointer low byte, Y=pointer high byte
 | |
| 
 | |
| LAB_22B6
 | |
| 	LDA	des_pl		; get descriptor pointer low byte
 | |
| 	LDY	des_ph		; get descriptor pointer high byte
 | |
| 
 | |
| ; pop (YA) descriptor off stack or from top of string space
 | |
| ; returns with A = length, X=ut1_pl=pointer low byte, Y=ut1_ph=pointer high byte
 | |
| 
 | |
| LAB_22BA
 | |
| 	STA	ut1_pl		; save descriptor pointer low byte
 | |
| 	STY	ut1_ph		; save descriptor pointer high byte
 | |
| 	JSR	LAB_22EB		; clean descriptor stack, YA = pointer
 | |
| 	PHP				; save status flags
 | |
| 	LDY	#$00			; clear index
 | |
| 	LDA	(ut1_pl),Y		; get length from string descriptor
 | |
| 	PHA				; put on stack
 | |
| 	INY				; increment index
 | |
| 	LDA	(ut1_pl),Y		; get string pointer low byte from descriptor
 | |
| 	TAX				; copy to X
 | |
| 	INY				; increment index
 | |
| 	LDA	(ut1_pl),Y		; get string pointer high byte from descriptor
 | |
| 	TAY				; copy to Y
 | |
| 	PLA				; get string length back
 | |
| 	PLP				; restore status
 | |
| 	BNE	LAB_22E6		; branch if pointer <> last_sl,last_sh
 | |
| 
 | |
| 	CPY	Sstorh		; compare bottom of string space high byte
 | |
| 	BNE	LAB_22E6		; branch if <>
 | |
| 
 | |
| 	CPX	Sstorl		; else compare bottom of string space low byte
 | |
| 	BNE	LAB_22E6		; branch if <>
 | |
| 
 | |
| 	PHA				; save string length
 | |
| 	CLC				; clear carry for add
 | |
| 	ADC	Sstorl		; add bottom of string space low byte
 | |
| 	STA	Sstorl		; save bottom of string space low byte
 | |
| 	BCC	LAB_22E5		; skip increment if no overflow
 | |
| 
 | |
| 	INC	Sstorh		; increment bottom of string space high byte
 | |
| LAB_22E5
 | |
| 	PLA				; restore string length
 | |
| LAB_22E6
 | |
| 	STX	ut1_pl		; save string pointer low byte
 | |
| 	STY	ut1_ph		; save string pointer high byte
 | |
| 	RTS
 | |
| 
 | |
| ; clean descriptor stack, YA = pointer
 | |
| ; checks if AY is on the descriptor stack, if so does a stack discard
 | |
| 
 | |
| LAB_22EB
 | |
| 	CPY	last_sh		; compare pointer high byte
 | |
| 	BNE	LAB_22FB		; exit if <>
 | |
| 
 | |
| 	CMP	last_sl		; compare pointer low byte
 | |
| 	BNE	LAB_22FB		; exit if <>
 | |
| 
 | |
| 	STA	next_s		; save descriptor stack pointer
 | |
| 	SBC	#$03			; -3
 | |
| 	STA	last_sl		; save low byte -3
 | |
| 	LDY	#$00			; clear high byte
 | |
| LAB_22FB
 | |
| 	RTS
 | |
| 
 | |
| ; perform CHR$()
 | |
| 
 | |
| LAB_CHRS
 | |
| 	JSR	LAB_EVBY		; evaluate byte expression, result in X
 | |
| 	TXA				; copy to A
 | |
| 	PHA				; save character
 | |
| 	LDA	#$01			; string is single byte
 | |
| 	JSR	LAB_MSSP		; make string space A bytes long A=$AC=length,
 | |
| 					; X=$AD=Sutill=ptr low byte, Y=$AE=Sutilh=ptr high byte
 | |
| 	PLA				; get character back
 | |
| 	LDY	#$00			; clear index
 | |
| 	STA	(str_pl),Y		; save byte in string (byte IS string!)
 | |
| 	JMP	LAB_RTST		; check for space on descriptor stack then put string
 | |
| 					; address and length on descriptor stack and update stack
 | |
| 					; pointers
 | |
| 
 | |
| ; perform LEFT$()
 | |
| 
 | |
| LAB_LEFT
 | |
| 	PHA				; push byte parameter
 | |
| 	JSR	LAB_236F		; pull string data and byte parameter from stack
 | |
| 					; return pointer in des_2l/h, byte in A (and X), Y=0
 | |
| 	CMP	(des_2l),Y		; compare byte parameter with string length
 | |
| 	TYA				; clear A
 | |
| 	BEQ	LAB_2316		; go do string copy (branch always)
 | |
| 
 | |
| ; perform RIGHT$()
 | |
| 
 | |
| LAB_RIGHT
 | |
| 	PHA				; push byte parameter
 | |
| 	JSR	LAB_236F		; pull string data and byte parameter from stack
 | |
| 					; return pointer in des_2l/h, byte in A (and X), Y=0
 | |
| 	CLC				; clear carry for add-1
 | |
| 	SBC	(des_2l),Y		; subtract string length
 | |
| 	EOR	#$FF			; invert it (A=LEN(expression$)-l)
 | |
| 
 | |
| LAB_2316
 | |
| 	BCC	LAB_231C		; branch if string length > byte parameter
 | |
| 
 | |
| 	LDA	(des_2l),Y		; else make parameter = length
 | |
| 	TAX				; copy to byte parameter copy
 | |
| 	TYA				; clear string start offset
 | |
| LAB_231C
 | |
| 	PHA				; save string start offset
 | |
| LAB_231D
 | |
| 	TXA				; copy byte parameter (or string length if <)
 | |
| LAB_231E
 | |
| 	PHA				; save string length
 | |
| 	JSR	LAB_MSSP		; make string space A bytes long A=$AC=length,
 | |
| 					; X=$AD=Sutill=ptr low byte, Y=$AE=Sutilh=ptr high byte
 | |
| 	LDA	des_2l		; get descriptor pointer low byte
 | |
| 	LDY	des_2h		; get descriptor pointer high byte
 | |
| 	JSR	LAB_22BA		; pop (YA) descriptor off stack or from top of string space
 | |
| 					; returns with A = length, X=ut1_pl=pointer low byte,
 | |
| 					; Y=ut1_ph=pointer high byte
 | |
| 	PLA				; get string length back
 | |
| 	TAY				; copy length to Y
 | |
| 	PLA				; get string start offset back
 | |
| 	CLC				; clear carry for add
 | |
| 	ADC	ut1_pl		; add start offset to string start pointer low byte
 | |
| 	STA	ut1_pl		; save string start pointer low byte
 | |
| 	BCC	LAB_2335		; branch if no overflow
 | |
| 
 | |
| 	INC	ut1_ph		; else increment string start pointer high byte
 | |
| LAB_2335
 | |
| 	TYA				; copy length to A
 | |
| 	JSR	LAB_229C		; store string A bytes long from (ut1_pl) to (Sutill)
 | |
| 	JMP	LAB_RTST		; check for space on descriptor stack then put string
 | |
| 					; address and length on descriptor stack and update stack
 | |
| 					; pointers
 | |
| 
 | |
| ; perform MID$()
 | |
| 
 | |
| LAB_MIDS
 | |
| 	PHA				; push byte parameter
 | |
| 	LDA	#$FF			; set default length = 255
 | |
| 	STA	mids_l		; save default length
 | |
| 	JSR	LAB_GBYT		; scan memory
 | |
| 	CMP	#')'			; compare with ")"
 | |
| 	BEQ	LAB_2358		; branch if = ")" (skip second byte get)
 | |
| 
 | |
| 	JSR	LAB_1C01		; scan for "," , else do syntax error then warm start
 | |
| 	JSR	LAB_GTBY		; get byte parameter (use copy in mids_l)
 | |
| LAB_2358
 | |
| 	JSR	LAB_236F		; pull string data and byte parameter from stack
 | |
| 					; return pointer in des_2l/h, byte in A (and X), Y=0
 | |
| 	DEX				; decrement start index
 | |
| 	TXA				; copy to A
 | |
| 	PHA				; save string start offset
 | |
| 	CLC				; clear carry for sub-1
 | |
| 	LDX	#$00			; clear output string length
 | |
| 	SBC	(des_2l),Y		; subtract string length
 | |
| 	BCS	LAB_231D		; if start>string length go do null string
 | |
| 
 | |
| 	EOR	#$FF			; complement -length
 | |
| 	CMP	mids_l		; compare byte parameter
 | |
| 	BCC	LAB_231E		; if length>remaining string go do RIGHT$
 | |
| 
 | |
| 	LDA	mids_l		; get length byte
 | |
| 	BCS	LAB_231E		; go do string copy (branch always)
 | |
| 
 | |
| ; pull string data and byte parameter from stack
 | |
| ; return pointer in des_2l/h, byte in A (and X), Y=0
 | |
| 
 | |
| LAB_236F
 | |
| 	JSR	LAB_1BFB		; scan for ")" , else do syntax error then warm start
 | |
| 	PLA				; pull return address low byte (return address)
 | |
| 	STA	Fnxjpl		; save functions jump vector low byte
 | |
| 	PLA				; pull return address high byte (return address)
 | |
| 	STA	Fnxjph		; save functions jump vector high byte
 | |
| 	PLA				; pull byte parameter
 | |
| 	TAX				; copy byte parameter to X
 | |
| 	PLA				; pull string pointer low byte
 | |
| 	STA	des_2l		; save it
 | |
| 	PLA				; pull string pointer high byte
 | |
| 	STA	des_2h		; save it
 | |
| 	LDY	#$00			; clear index
 | |
| 	TXA				; copy byte parameter
 | |
| 	BEQ	LAB_23A8		; if null do function call error then warm start
 | |
| 
 | |
| 	INC	Fnxjpl		; increment function jump vector low byte
 | |
| 					; (JSR pushes return addr-1. this is all very nice
 | |
| 					; but will go tits up if either call is on a page
 | |
| 					; boundary!)
 | |
| 	JMP	(Fnxjpl)		; in effect, RTS
 | |
| 
 | |
| ; perform LCASE$()
 | |
| 
 | |
| LAB_LCASE
 | |
| 	JSR	LAB_EVST		; evaluate string
 | |
| 	STA	str_ln		; set string length
 | |
| 	TAY				; copy length to Y
 | |
| 	BEQ	NoString		; branch if null string
 | |
| 
 | |
| 	JSR	LAB_MSSP		; make string space A bytes long A=length,
 | |
| 					; X=Sutill=ptr low byte, Y=Sutilh=ptr high byte
 | |
| 	STX	str_pl		; save string pointer low byte
 | |
| 	STY	str_ph		; save string pointer high byte
 | |
| 	TAY				; get string length back
 | |
| 
 | |
| LC_loop
 | |
| 	DEY				; decrement index
 | |
| 	LDA	(ut1_pl),Y		; get byte from string
 | |
| 	JSR	LAB_1D82		; is character "A" to "Z"
 | |
| 	BCC	NoUcase		; branch if not upper case alpha
 | |
| 
 | |
| 	ORA	#$20			; convert upper to lower case
 | |
| NoUcase
 | |
| 	STA	(Sutill),Y		; save byte back to string
 | |
| 	TYA				; test index
 | |
| 	BNE	LC_loop		; loop if not all done
 | |
| 
 | |
| 	BEQ	NoString		; tidy up and exit, branch always
 | |
| 
 | |
| ; perform UCASE$()
 | |
| 
 | |
| LAB_UCASE
 | |
| 	JSR	LAB_EVST		; evaluate string
 | |
| 	STA	str_ln		; set string length
 | |
| 	TAY				; copy length to Y
 | |
| 	BEQ	NoString		; branch if null string
 | |
| 
 | |
| 	JSR	LAB_MSSP		; make string space A bytes long A=length,
 | |
| 					; X=Sutill=ptr low byte, Y=Sutilh=ptr high byte
 | |
| 	STX	str_pl		; save string pointer low byte
 | |
| 	STY	str_ph		; save string pointer high byte
 | |
| 	TAY				; get string length back
 | |
| 
 | |
| UC_loop
 | |
| 	DEY				; decrement index
 | |
| 	LDA	(ut1_pl),Y		; get byte from string
 | |
| 	JSR	LAB_CASC		; is character "a" to "z" (or "A" to "Z")
 | |
| 	BCC	NoLcase		; branch if not alpha
 | |
| 
 | |
| 	AND	#$DF			; convert lower to upper case
 | |
| NoLcase
 | |
| 	STA	(Sutill),Y		; save byte back to string
 | |
| 	TYA				; test index
 | |
| 	BNE	UC_loop		; loop if not all done
 | |
| 
 | |
| NoString
 | |
| 	JMP	LAB_RTST		; check for space on descriptor stack then put string
 | |
| 					; address and length on descriptor stack and update stack
 | |
| 					; pointers
 | |
| 
 | |
| ; perform SADD()
 | |
| 
 | |
| LAB_SADD
 | |
| 	JSR	LAB_IGBY		; increment and scan memory
 | |
| 	JSR	LAB_GVAR		; get var address
 | |
| 
 | |
| 	JSR	LAB_1BFB		; scan for ")", else do syntax error then warm start
 | |
| 	JSR	LAB_CTST		; check if source is string, else do type mismatch
 | |
| 
 | |
| 	LDY	#$02			; index to string pointer high byte
 | |
| 	LDA	(Cvaral),Y		; get string pointer high byte
 | |
| 	TAX				; copy string pointer high byte to X
 | |
| 	DEY				; index to string pointer low byte
 | |
| 	LDA	(Cvaral),Y		; get string pointer low byte
 | |
| 	TAY				; copy string pointer low byte to Y
 | |
| 	TXA				; copy string pointer high byte to A
 | |
| 	JMP	LAB_AYFC		; save and convert integer AY to FAC1 and return
 | |
| 
 | |
| ; perform LEN()
 | |
| 
 | |
| LAB_LENS
 | |
| 	JSR	LAB_ESGL		; evaluate string, get length in A (and Y)
 | |
| 	JMP	LAB_1FD0		; convert Y to byte in FAC1 and return
 | |
| 
 | |
| ; evaluate string, get length in Y
 | |
| 
 | |
| LAB_ESGL
 | |
| 	JSR	LAB_EVST		; evaluate string
 | |
| 	TAY				; copy length to Y
 | |
| 	RTS
 | |
| 
 | |
| ; perform ASC()
 | |
| 
 | |
| LAB_ASC
 | |
| 	JSR	LAB_ESGL		; evaluate string, get length in A (and Y)
 | |
| 	BEQ	LAB_23A8		; if null do function call error then warm start
 | |
| 
 | |
| 	LDY	#$00			; set index to first character
 | |
| 	LDA	(ut1_pl),Y		; get byte
 | |
| 	TAY				; copy to Y
 | |
| 	JMP	LAB_1FD0		; convert Y to byte in FAC1 and return
 | |
| 
 | |
| ; do function call error then warm start
 | |
| 
 | |
| LAB_23A8
 | |
| 	JMP	LAB_FCER		; do function call error then warm start
 | |
| 
 | |
| ; scan and get byte parameter
 | |
| 
 | |
| LAB_SGBY
 | |
| 	JSR	LAB_IGBY		; increment and scan memory
 | |
| 
 | |
| ; get byte parameter
 | |
| 
 | |
| LAB_GTBY
 | |
| 	JSR	LAB_EVNM		; evaluate expression and check is numeric,
 | |
| 					; else do type mismatch
 | |
| 
 | |
| ; evaluate byte expression, result in X
 | |
| 
 | |
| LAB_EVBY
 | |
| 	JSR	LAB_EVPI		; evaluate integer expression (no check)
 | |
| 
 | |
| 	LDY	FAC1_2		; get FAC1 mantissa2
 | |
| 	BNE	LAB_23A8		; if top byte <> 0 do function call error then warm start
 | |
| 
 | |
| 	LDX	FAC1_3		; get FAC1 mantissa3
 | |
| 	JMP	LAB_GBYT		; scan memory and return
 | |
| 
 | |
| ; perform VAL()
 | |
| 
 | |
| LAB_VAL
 | |
| 	JSR	LAB_ESGL		; evaluate string, get length in A (and Y)
 | |
| 	BNE	LAB_23C5		; branch if not null string
 | |
| 
 | |
| 					; string was null so set result = $00
 | |
| 	JMP	LAB_24F1		; clear FAC1 exponent and sign and return
 | |
| 
 | |
| LAB_23C5
 | |
| 	LDX	Bpntrl		; get BASIC execute pointer low byte
 | |
| 	LDY	Bpntrh		; get BASIC execute pointer high byte
 | |
| 	STX	Btmpl			; save BASIC execute pointer low byte
 | |
| 	STY	Btmph			; save BASIC execute pointer high byte
 | |
| 	LDX	ut1_pl		; get string pointer low byte
 | |
| 	STX	Bpntrl		; save as BASIC execute pointer low byte
 | |
| 	CLC				; clear carry
 | |
| 	ADC	ut1_pl		; add string length
 | |
| 	STA	ut2_pl		; save string end low byte
 | |
| 	LDA	ut1_ph		; get string pointer high byte
 | |
| 	STA	Bpntrh		; save as BASIC execute pointer high byte
 | |
| 	ADC	#$00			; add carry to high byte
 | |
| 	STA	ut2_ph		; save string end high byte
 | |
| 	LDY	#$00			; set index to $00
 | |
| 	LDA	(ut2_pl),Y		; get string end +1 byte
 | |
| 	PHA				; push it
 | |
| 	TYA				; clear A
 | |
| 	STA	(ut2_pl),Y		; terminate string with $00
 | |
| 	JSR	LAB_GBYT		; scan memory
 | |
| 	JSR	LAB_2887		; get FAC1 from string
 | |
| 	PLA				; restore string end +1 byte
 | |
| 	LDY	#$00			; set index to zero
 | |
| 	STA	(ut2_pl),Y		; put string end byte back
 | |
| 
 | |
| ; restore BASIC execute pointer from temp (Btmpl/Btmph)
 | |
| 
 | |
| LAB_23F3
 | |
| 	LDX	Btmpl			; get BASIC execute pointer low byte back
 | |
| 	LDY	Btmph			; get BASIC execute pointer high byte back
 | |
| 	STX	Bpntrl		; save BASIC execute pointer low byte
 | |
| 	STY	Bpntrh		; save BASIC execute pointer high byte
 | |
| 	RTS
 | |
| 
 | |
| ; get two parameters for POKE or WAIT
 | |
| 
 | |
| LAB_GADB
 | |
| 	JSR	LAB_EVNM		; evaluate expression and check is numeric,
 | |
| 					; else do type mismatch
 | |
| 	JSR	LAB_F2FX		; save integer part of FAC1 in temporary integer
 | |
| 
 | |
| ; scan for "," and get byte, else do Syntax error then warm start
 | |
| 
 | |
| LAB_SCGB
 | |
| 	JSR	LAB_1C01		; scan for "," , else do syntax error then warm start
 | |
| 	LDA	Itemph		; save temporary integer high byte
 | |
| 	PHA				; on stack
 | |
| 	LDA	Itempl		; save temporary integer low byte
 | |
| 	PHA				; on stack
 | |
| 	JSR	LAB_GTBY		; get byte parameter
 | |
| 	PLA				; pull low byte
 | |
| 	STA	Itempl		; restore temporary integer low byte
 | |
| 	PLA				; pull high byte
 | |
| 	STA	Itemph		; restore temporary integer high byte
 | |
| 	RTS
 | |
| 
 | |
| ; convert float to fixed routine. accepts any value that fits in 24 bits, +ve or
 | |
| ; -ve and converts it into a right truncated integer in Itempl and Itemph
 | |
| 
 | |
| ; save unsigned 16 bit integer part of FAC1 in temporary integer
 | |
| 
 | |
| LAB_F2FX
 | |
| 	LDA	FAC1_e		; get FAC1 exponent
 | |
| 	CMP	#$98			; compare with exponent = 2^24
 | |
| 	BCS	LAB_23A8		; if >= do function call error then warm start
 | |
| 
 | |
| LAB_F2FU
 | |
| 	JSR	LAB_2831		; convert FAC1 floating-to-fixed
 | |
| 	LDA	FAC1_2		; get FAC1 mantissa2
 | |
| 	LDY	FAC1_3		; get FAC1 mantissa3
 | |
| 	STY	Itempl		; save temporary integer low byte
 | |
| 	STA	Itemph		; save temporary integer high byte
 | |
| 	RTS
 | |
| 
 | |
| ; perform PEEK()
 | |
| 
 | |
| LAB_PEEK
 | |
| 	JSR	LAB_F2FX		; save integer part of FAC1 in temporary integer
 | |
| 	LDX	#$00			; clear index
 | |
| 	LDA	(Itempl,X)		; get byte via temporary integer (addr)
 | |
| 	TAY				; copy byte to Y
 | |
| 	JMP	LAB_1FD0		; convert Y to byte in FAC1 and return
 | |
| 
 | |
| ; perform POKE
 | |
| 
 | |
| LAB_POKE
 | |
| 	JSR	LAB_GADB		; get two parameters for POKE or WAIT
 | |
| 	TXA				; copy byte argument to A
 | |
| 	LDX	#$00			; clear index
 | |
| 	STA	(Itempl,X)		; save byte via temporary integer (addr)
 | |
| 	RTS
 | |
| 
 | |
| ; perform DEEK()
 | |
| 
 | |
| LAB_DEEK
 | |
| 	JSR	LAB_F2FX		; save integer part of FAC1 in temporary integer
 | |
| 	LDX	#$00			; clear index
 | |
| 	LDA	(Itempl,X)		; PEEK low byte
 | |
| 	TAY				; copy to Y
 | |
| 	INC	Itempl		; increment pointer low byte
 | |
| 	BNE	Deekh			; skip high increment if no rollover
 | |
| 
 | |
| 	INC	Itemph		; increment pointer high byte
 | |
| Deekh
 | |
| 	LDA	(Itempl,X)		; PEEK high byte
 | |
| 	JMP	LAB_AYFC		; save and convert integer AY to FAC1 and return
 | |
| 
 | |
| ; perform DOKE
 | |
| 
 | |
| LAB_DOKE
 | |
| 	JSR	LAB_EVNM		; evaluate expression and check is numeric,
 | |
| 					; else do type mismatch
 | |
| 	JSR	LAB_F2FX		; convert floating-to-fixed
 | |
| 
 | |
| 	STY	Frnxtl		; save pointer low byte (float to fixed returns word in AY)
 | |
| 	STA	Frnxth		; save pointer high byte
 | |
| 
 | |
| 	JSR	LAB_1C01		; scan for "," , else do syntax error then warm start
 | |
| 	JSR	LAB_EVNM		; evaluate expression and check is numeric,
 | |
| 					; else do type mismatch
 | |
| 	JSR	LAB_F2FX		; convert floating-to-fixed
 | |
| 
 | |
| 	TYA				; copy value low byte (float to fixed returns word in AY)
 | |
| 	LDX	#$00			; clear index
 | |
| 	STA	(Frnxtl,X)		; POKE low byte
 | |
| 	INC	Frnxtl		; increment pointer low byte
 | |
| 	BNE	Dokeh			; skip high increment if no rollover
 | |
| 
 | |
| 	INC	Frnxth		; increment pointer high byte
 | |
| Dokeh
 | |
| 	LDA	Itemph		; get value high byte
 | |
| 	STA	(Frnxtl,X)		; POKE high byte
 | |
| 	JMP	LAB_GBYT		; scan memory and return
 | |
| 
 | |
| ; perform SWAP
 | |
| 
 | |
| LAB_SWAP
 | |
| 	JSR	LAB_GVAR		; get var1 address
 | |
| 	STA	Lvarpl		; save var1 address low byte
 | |
| 	STY	Lvarph		; save var1 address high byte
 | |
| 	LDA	Dtypef		; get data type flag, $FF=string, $00=numeric
 | |
| 	PHA				; save data type flag
 | |
| 
 | |
| 	JSR	LAB_1C01		; scan for "," , else do syntax error then warm start
 | |
| 	JSR	LAB_GVAR		; get var2 address (pointer in Cvaral/h)
 | |
| 	PLA				; pull var1 data type flag
 | |
| 	EOR	Dtypef		; compare with var2 data type
 | |
| 	BPL	SwapErr		; exit if not both the same type
 | |
| 
 | |
| 	LDY	#$03			; four bytes to swap (either value or descriptor+1)
 | |
| SwapLp
 | |
| 	LDA	(Lvarpl),Y		; get byte from var1
 | |
| 	TAX				; save var1 byte
 | |
| 	LDA	(Cvaral),Y		; get byte from var2
 | |
| 	STA	(Lvarpl),Y		; save byte to var1
 | |
| 	TXA				; restore var1 byte
 | |
| 	STA	(Cvaral),Y		; save byte to var2
 | |
| 	DEY				; decrement index
 | |
| 	BPL	SwapLp		; loop until done
 | |
| 
 | |
| 	RTS
 | |
| 
 | |
| SwapErr
 | |
| 	JMP	LAB_1ABC		; do "Type mismatch" error then warm start
 | |
| 
 | |
| ; perform CALL
 | |
| 
 | |
| LAB_CALL
 | |
| 	JSR	LAB_EVNM		; evaluate expression and check is numeric,
 | |
| 					; else do type mismatch
 | |
| 	JSR	LAB_F2FX		; convert floating-to-fixed
 | |
| 	LDA	#>CallExit		; set return address high byte
 | |
| 	PHA				; put on stack
 | |
| 	LDA	#<CallExit-1	; set return address low byte
 | |
| 	PHA				; put on stack
 | |
| 	JMP	(Itempl)		; do indirect jump to user routine
 | |
| 
 | |
| ; if the called routine exits correctly then it will return to here. this will then get
 | |
| ; the next byte for the interpreter and return
 | |
| 
 | |
| CallExit
 | |
| 	JMP	LAB_GBYT		; scan memory and return
 | |
| 
 | |
| ; perform WAIT
 | |
| 
 | |
| LAB_WAIT
 | |
| 	JSR	LAB_GADB		; get two parameters for POKE or WAIT
 | |
| 	STX	Frnxtl		; save byte
 | |
| 	LDX	#$00			; clear mask
 | |
| 	JSR	LAB_GBYT		; scan memory
 | |
| 	BEQ	LAB_2441		; skip if no third argument
 | |
| 
 | |
| 	JSR	LAB_SCGB		; scan for "," and get byte, else SN error then warm start
 | |
| LAB_2441
 | |
| 	STX	Frnxth		; save EOR argument
 | |
| LAB_2445
 | |
| 	LDA	(Itempl),Y		; get byte via temporary integer (addr)
 | |
| 	EOR	Frnxth		; EOR with second argument (mask)
 | |
| 	AND	Frnxtl		; AND with first argument (byte)
 | |
| 	BEQ	LAB_2445		; loop if result is zero
 | |
| 
 | |
| LAB_244D
 | |
| 	RTS
 | |
| 
 | |
| ; perform subtraction, FAC1 from (AY)
 | |
| 
 | |
| LAB_2455
 | |
| 	JSR	LAB_264D		; unpack memory (AY) into FAC2
 | |
| 
 | |
| ; perform subtraction, FAC1 from FAC2
 | |
| 
 | |
| LAB_SUBTRACT
 | |
| 	LDA	FAC1_s		; get FAC1 sign (b7)
 | |
| 	EOR	#$FF			; complement it
 | |
| 	STA	FAC1_s		; save FAC1 sign (b7)
 | |
| 	EOR	FAC2_s		; EOR with FAC2 sign (b7)
 | |
| 	STA	FAC_sc		; save sign compare (FAC1 EOR FAC2)
 | |
| 	LDA	FAC1_e		; get FAC1 exponent
 | |
| 	JMP	LAB_ADD		; go add FAC2 to FAC1
 | |
| 
 | |
| ; perform addition
 | |
| 
 | |
| LAB_2467
 | |
| 	JSR	LAB_257B		; shift FACX A times right (>8 shifts)
 | |
| 	BCC	LAB_24A8		;.go subtract mantissas
 | |
| 
 | |
| ; add 0.5 to FAC1
 | |
| 
 | |
| LAB_244E
 | |
| 	LDA	#<LAB_2A96		; set 0.5 pointer low byte
 | |
| 	LDY	#>LAB_2A96		; set 0.5 pointer high byte
 | |
| 
 | |
| ; add (AY) to FAC1
 | |
| 
 | |
| LAB_246C
 | |
| 	JSR	LAB_264D		; unpack memory (AY) into FAC2
 | |
| 
 | |
| ; add FAC2 to FAC1
 | |
| 
 | |
| LAB_ADD
 | |
| 	BNE	LAB_2474		; branch if FAC1 was not zero
 | |
| 
 | |
| ; copy FAC2 to FAC1
 | |
| 
 | |
| LAB_279B
 | |
| 	LDA	FAC2_s		; get FAC2 sign (b7)
 | |
| 
 | |
| ; save FAC1 sign and copy ABS(FAC2) to FAC1
 | |
| 
 | |
| LAB_279D
 | |
| 	STA	FAC1_s		; save FAC1 sign (b7)
 | |
| 	LDX	#$04			; 4 bytes to copy
 | |
| LAB_27A1
 | |
| 	LDA	FAC1_o,X		; get byte from FAC2,X
 | |
| 	STA	FAC1_e-1,X		; save byte at FAC1,X
 | |
| 	DEX				; decrement count
 | |
| 	BNE	LAB_27A1		; loop if not all done
 | |
| 
 | |
| 	STX	FAC1_r		; clear FAC1 rounding byte
 | |
| 	RTS
 | |
| 
 | |
| 					; FAC1 is non zero
 | |
| LAB_2474
 | |
| 	LDX	FAC1_r		; get FAC1 rounding byte
 | |
| 	STX	FAC2_r		; save as FAC2 rounding byte
 | |
| 	LDX	#FAC2_e		; set index to FAC2 exponent addr
 | |
| 	LDA	FAC2_e		; get FAC2 exponent
 | |
| LAB_247C
 | |
| 	TAY				; copy exponent
 | |
| 	BEQ	LAB_244D		; exit if zero
 | |
| 
 | |
| 	SEC				; set carry for subtract
 | |
| 	SBC	FAC1_e		; subtract FAC1 exponent
 | |
| 	BEQ	LAB_24A8		; branch if = (go add mantissa)
 | |
| 
 | |
| 	BCC	LAB_2498		; branch if <
 | |
| 
 | |
| 					; FAC2>FAC1
 | |
| 	STY	FAC1_e		; save FAC1 exponent
 | |
| 	LDY	FAC2_s		; get FAC2 sign (b7)
 | |
| 	STY	FAC1_s		; save FAC1 sign (b7)
 | |
| 	EOR	#$FF			; complement A
 | |
| 	ADC	#$00			; +1 (twos complement, carry is set)
 | |
| 	LDY	#$00			; clear Y
 | |
| 	STY	FAC2_r		; clear FAC2 rounding byte
 | |
| 	LDX	#FAC1_e		; set index to FAC1 exponent addr
 | |
| 	BNE	LAB_249C		; branch always
 | |
| 
 | |
| LAB_2498
 | |
| 	LDY	#$00			; clear Y
 | |
| 	STY	FAC1_r		; clear FAC1 rounding byte
 | |
| LAB_249C
 | |
| 	CMP	#$F9			; compare exponent diff with $F9
 | |
| 	BMI	LAB_2467		; branch if range $79-$F8
 | |
| 
 | |
| 	TAY				; copy exponent difference to Y
 | |
| 	LDA	FAC1_r		; get FAC1 rounding byte
 | |
| 	LSR	PLUS_1,X		; shift FAC? mantissa1
 | |
| 	JSR	LAB_2592		; shift FACX Y times right
 | |
| 
 | |
| 					; exponents are equal now do mantissa subtract
 | |
| LAB_24A8
 | |
| 	BIT	FAC_sc		; test sign compare (FAC1 EOR FAC2)
 | |
| 	BPL	LAB_24F8		; if = add FAC2 mantissa to FAC1 mantissa and return
 | |
| 
 | |
| 	LDY	#FAC1_e		; set index to FAC1 exponent addr
 | |
| 	CPX	#FAC2_e		; compare X to FAC2 exponent addr
 | |
| 	BEQ	LAB_24B4		; branch if =
 | |
| 
 | |
| 	LDY	#FAC2_e		; else set index to FAC2 exponent addr
 | |
| 
 | |
| 					; subtract smaller from bigger (take sign of bigger)
 | |
| LAB_24B4
 | |
| 	SEC				; set carry for subtract
 | |
| 	EOR	#$FF			; ones complement A
 | |
| 	ADC	FAC2_r		; add FAC2 rounding byte
 | |
| 	STA	FAC1_r		; save FAC1 rounding byte
 | |
| 	LDA	PLUS_3,Y		; get FACY mantissa3
 | |
| 	SBC	PLUS_3,X		; subtract FACX mantissa3
 | |
| 	STA	FAC1_3		; save FAC1 mantissa3
 | |
| 	LDA	PLUS_2,Y		; get FACY mantissa2
 | |
| 	SBC	PLUS_2,X		; subtract FACX mantissa2
 | |
| 	STA	FAC1_2		; save FAC1 mantissa2
 | |
| 	LDA	PLUS_1,Y		; get FACY mantissa1
 | |
| 	SBC	PLUS_1,X		; subtract FACX mantissa1
 | |
| 	STA	FAC1_1		; save FAC1 mantissa1
 | |
| 
 | |
| ; do ABS and normalise FAC1
 | |
| 
 | |
| LAB_24D0
 | |
| 	BCS	LAB_24D5		; branch if number is +ve
 | |
| 
 | |
| 	JSR	LAB_2537		; negate FAC1
 | |
| 
 | |
| ; normalise FAC1
 | |
| 
 | |
| LAB_24D5
 | |
| 	LDY	#$00			; clear Y
 | |
| 	TYA				; clear A
 | |
| 	CLC				; clear carry for add
 | |
| LAB_24D9
 | |
| 	LDX	FAC1_1		; get FAC1 mantissa1
 | |
| 	BNE	LAB_251B		; if not zero normalise FAC1
 | |
| 
 | |
| 	LDX	FAC1_2		; get FAC1 mantissa2
 | |
| 	STX	FAC1_1		; save FAC1 mantissa1
 | |
| 	LDX	FAC1_3		; get FAC1 mantissa3
 | |
| 	STX	FAC1_2		; save FAC1 mantissa2
 | |
| 	LDX	FAC1_r		; get FAC1 rounding byte
 | |
| 	STX	FAC1_3		; save FAC1 mantissa3
 | |
| 	STY	FAC1_r		; clear FAC1 rounding byte
 | |
| 	ADC	#$08			; add x to exponent offset
 | |
| 	CMP	#$18			; compare with $18 (max offset, all bits would be =0)
 | |
| 	BNE	LAB_24D9		; loop if not max
 | |
| 
 | |
| ; clear FAC1 exponent and sign
 | |
| 
 | |
| LAB_24F1
 | |
| 	LDA	#$00			; clear A
 | |
| LAB_24F3
 | |
| 	STA	FAC1_e		; set FAC1 exponent
 | |
| 
 | |
| ; save FAC1 sign
 | |
| 
 | |
| LAB_24F5
 | |
| 	STA	FAC1_s		; save FAC1 sign (b7)
 | |
| 	RTS
 | |
| 
 | |
| ; add FAC2 mantissa to FAC1 mantissa
 | |
| 
 | |
| LAB_24F8
 | |
| 	ADC	FAC2_r		; add FAC2 rounding byte
 | |
| 	STA	FAC1_r		; save FAC1 rounding byte
 | |
| 	LDA	FAC1_3		; get FAC1 mantissa3
 | |
| 	ADC	FAC2_3		; add FAC2 mantissa3
 | |
| 	STA	FAC1_3		; save FAC1 mantissa3
 | |
| 	LDA	FAC1_2		; get FAC1 mantissa2
 | |
| 	ADC	FAC2_2		; add FAC2 mantissa2
 | |
| 	STA	FAC1_2		; save FAC1 mantissa2
 | |
| 	LDA	FAC1_1		; get FAC1 mantissa1
 | |
| 	ADC	FAC2_1		; add FAC2 mantissa1
 | |
| 	STA	FAC1_1		; save FAC1 mantissa1
 | |
| 	BCS	LAB_252A		; if carry then normalise FAC1 for C=1
 | |
| 
 | |
| 	RTS				; else just exit
 | |
| 
 | |
| LAB_2511
 | |
| 	ADC	#$01			; add 1 to exponent offset
 | |
| 	ASL	FAC1_r		; shift FAC1 rounding byte
 | |
| 	ROL	FAC1_3		; shift FAC1 mantissa3
 | |
| 	ROL	FAC1_2		; shift FAC1 mantissa2
 | |
| 	ROL	FAC1_1		; shift FAC1 mantissa1
 | |
| 
 | |
| ; normalise FAC1
 | |
| 
 | |
| LAB_251B
 | |
| 	BPL	LAB_2511		; loop if not normalised
 | |
| 
 | |
| 	SEC				; set carry for subtract
 | |
| 	SBC	FAC1_e		; subtract FAC1 exponent
 | |
| 	BCS	LAB_24F1		; branch if underflow (set result = $0)
 | |
| 
 | |
| 	EOR	#$FF			; complement exponent
 | |
| 	ADC	#$01			; +1 (twos complement)
 | |
| 	STA	FAC1_e		; save FAC1 exponent
 | |
| 
 | |
| ; test and normalise FAC1 for C=0/1
 | |
| 
 | |
| LAB_2528
 | |
| 	BCC	LAB_2536		; exit if no overflow
 | |
| 
 | |
| ; normalise FAC1 for C=1
 | |
| 
 | |
| LAB_252A
 | |
| 	INC	FAC1_e		; increment FAC1 exponent
 | |
| 	BEQ	LAB_2564		; if zero do overflow error and warm start
 | |
| 
 | |
| 	ROR	FAC1_1		; shift FAC1 mantissa1
 | |
| 	ROR	FAC1_2		; shift FAC1 mantissa2
 | |
| 	ROR	FAC1_3		; shift FAC1 mantissa3
 | |
| 	ROR	FAC1_r		; shift FAC1 rounding byte
 | |
| LAB_2536
 | |
| 	RTS
 | |
| 
 | |
| ; negate FAC1
 | |
| 
 | |
| LAB_2537
 | |
| 	LDA	FAC1_s		; get FAC1 sign (b7)
 | |
| 	EOR	#$FF			; complement it
 | |
| 	STA	FAC1_s		; save FAC1 sign (b7)
 | |
| 
 | |
| ; twos complement FAC1 mantissa
 | |
| 
 | |
| LAB_253D
 | |
| 	LDA	FAC1_1		; get FAC1 mantissa1
 | |
| 	EOR	#$FF			; complement it
 | |
| 	STA	FAC1_1		; save FAC1 mantissa1
 | |
| 	LDA	FAC1_2		; get FAC1 mantissa2
 | |
| 	EOR	#$FF			; complement it
 | |
| 	STA	FAC1_2		; save FAC1 mantissa2
 | |
| 	LDA	FAC1_3		; get FAC1 mantissa3
 | |
| 	EOR	#$FF			; complement it
 | |
| 	STA	FAC1_3		; save FAC1 mantissa3
 | |
| 	LDA	FAC1_r		; get FAC1 rounding byte
 | |
| 	EOR	#$FF			; complement it
 | |
| 	STA	FAC1_r		; save FAC1 rounding byte
 | |
| 	INC	FAC1_r		; increment FAC1 rounding byte
 | |
| 	BNE	LAB_2563		; exit if no overflow
 | |
| 
 | |
| ; increment FAC1 mantissa
 | |
| 
 | |
| LAB_2559
 | |
| 	INC	FAC1_3		; increment FAC1 mantissa3
 | |
| 	BNE	LAB_2563		; finished if no rollover
 | |
| 
 | |
| 	INC	FAC1_2		; increment FAC1 mantissa2
 | |
| 	BNE	LAB_2563		; finished if no rollover
 | |
| 
 | |
| 	INC	FAC1_1		; increment FAC1 mantissa1
 | |
| LAB_2563
 | |
| 	RTS
 | |
| 
 | |
| ; do overflow error (overflow exit)
 | |
| 
 | |
| LAB_2564
 | |
| 	LDX	#$0A			; error code $0A ("Overflow" error)
 | |
| 	JMP	LAB_XERR		; do error #X, then warm start
 | |
| 
 | |
| ; shift FCAtemp << A+8 times
 | |
| 
 | |
| LAB_2569
 | |
| 	LDX	#FACt_1-1		; set offset to FACtemp
 | |
| LAB_256B
 | |
| 	LDY	PLUS_3,X		; get FACX mantissa3
 | |
| 	STY	FAC1_r		; save as FAC1 rounding byte
 | |
| 	LDY	PLUS_2,X		; get FACX mantissa2
 | |
| 	STY	PLUS_3,X		; save FACX mantissa3
 | |
| 	LDY	PLUS_1,X		; get FACX mantissa1
 | |
| 	STY	PLUS_2,X		; save FACX mantissa2
 | |
| 	LDY	FAC1_o		; get FAC1 overflow byte
 | |
| 	STY	PLUS_1,X		; save FACX mantissa1
 | |
| 
 | |
| ; shift FACX -A times right (> 8 shifts)
 | |
| 
 | |
| LAB_257B
 | |
| 	ADC	#$08			; add 8 to shift count
 | |
| 	BMI	LAB_256B		; go do 8 shift if still -ve
 | |
| 
 | |
| 	BEQ	LAB_256B		; go do 8 shift if zero
 | |
| 
 | |
| 	SBC	#$08			; else subtract 8 again
 | |
| 	TAY				; save count to Y
 | |
| 	LDA	FAC1_r		; get FAC1 rounding byte
 | |
| 	BCS	LAB_259A		;.
 | |
| 
 | |
| LAB_2588
 | |
| 	ASL	PLUS_1,X		; shift FACX mantissa1
 | |
| 	BCC	LAB_258E		; branch if +ve
 | |
| 
 | |
| 	INC	PLUS_1,X		; this sets b7 eventually
 | |
| LAB_258E
 | |
| 	ROR	PLUS_1,X		; shift FACX mantissa1 (correct for ASL)
 | |
| 	ROR	PLUS_1,X		; shift FACX mantissa1 (put carry in b7)
 | |
| 
 | |
| ; shift FACX Y times right
 | |
| 
 | |
| LAB_2592
 | |
| 	ROR	PLUS_2,X		; shift FACX mantissa2
 | |
| 	ROR	PLUS_3,X		; shift FACX mantissa3
 | |
| 	ROR				; shift FACX rounding byte
 | |
| 	INY				; increment exponent diff
 | |
| 	BNE	LAB_2588		; branch if range adjust not complete
 | |
| 
 | |
| LAB_259A
 | |
| 	CLC				; just clear it
 | |
| 	RTS
 | |
| 
 | |
| ; perform LOG()
 | |
| 
 | |
| LAB_LOG
 | |
| 	JSR	LAB_27CA		; test sign and zero
 | |
| 	BEQ	LAB_25C4		; if zero do function call error then warm start
 | |
| 
 | |
| 	BPL	LAB_25C7		; skip error if +ve
 | |
| 
 | |
| LAB_25C4
 | |
| 	JMP	LAB_FCER		; do function call error then warm start (-ve)
 | |
| 
 | |
| LAB_25C7
 | |
| 	LDA	FAC1_e		; get FAC1 exponent
 | |
| 	SBC	#$7F			; normalise it
 | |
| 	PHA				; save it
 | |
| 	LDA	#$80			; set exponent to zero
 | |
| 	STA	FAC1_e		; save FAC1 exponent
 | |
| 	LDA	#<LAB_25AD		; set 1/root2 pointer low byte
 | |
| 	LDY	#>LAB_25AD		; set 1/root2 pointer high byte
 | |
| 	JSR	LAB_246C		; add (AY) to FAC1 (1/root2)
 | |
| 	LDA	#<LAB_25B1		; set root2 pointer low byte
 | |
| 	LDY	#>LAB_25B1		; set root2 pointer high byte
 | |
| 	JSR	LAB_26CA		; convert AY and do (AY)/FAC1 (root2/(x+(1/root2)))
 | |
| 	LDA	#<LAB_259C		; set 1 pointer low byte
 | |
| 	LDY	#>LAB_259C		; set 1 pointer high byte
 | |
| 	JSR	LAB_2455		; subtract (AY) from FAC1 ((root2/(x+(1/root2)))-1)
 | |
| 	LDA	#<LAB_25A0		; set pointer low byte to counter
 | |
| 	LDY	#>LAB_25A0		; set pointer high byte to counter
 | |
| 	JSR	LAB_2B6E		; ^2 then series evaluation
 | |
| 	LDA	#<LAB_25B5		; set -0.5 pointer low byte
 | |
| 	LDY	#>LAB_25B5		; set -0.5 pointer high byte
 | |
| 	JSR	LAB_246C		; add (AY) to FAC1
 | |
| 	PLA				; restore FAC1 exponent
 | |
| 	JSR	LAB_2912		; evaluate new ASCII digit
 | |
| 	LDA	#<LAB_25B9		; set LOG(2) pointer low byte
 | |
| 	LDY	#>LAB_25B9		; set LOG(2) pointer high byte
 | |
| 
 | |
| ; do convert AY, FCA1*(AY)
 | |
| 
 | |
| LAB_25FB
 | |
| 	JSR	LAB_264D		; unpack memory (AY) into FAC2
 | |
| LAB_MULTIPLY
 | |
| 	BEQ	LAB_264C		; exit if zero
 | |
| 
 | |
| 	JSR	LAB_2673		; test and adjust accumulators
 | |
| 	LDA	#$00			; clear A
 | |
| 	STA	FACt_1		; clear temp mantissa1
 | |
| 	STA	FACt_2		; clear temp mantissa2
 | |
| 	STA	FACt_3		; clear temp mantissa3
 | |
| 	LDA	FAC1_r		; get FAC1 rounding byte
 | |
| 	JSR	LAB_2622		; go do shift/add FAC2
 | |
| 	LDA	FAC1_3		; get FAC1 mantissa3
 | |
| 	JSR	LAB_2622		; go do shift/add FAC2
 | |
| 	LDA	FAC1_2		; get FAC1 mantissa2
 | |
| 	JSR	LAB_2622		; go do shift/add FAC2
 | |
| 	LDA	FAC1_1		; get FAC1 mantissa1
 | |
| 	JSR	LAB_2627		; go do shift/add FAC2
 | |
| 	JMP	LAB_273C		; copy temp to FAC1, normalise and return
 | |
| 
 | |
| LAB_2622
 | |
| 	BNE	LAB_2627		; branch if byte <> zero
 | |
| 
 | |
| 	JMP	LAB_2569		; shift FCAtemp << A+8 times
 | |
| 
 | |
| 					; else do shift and add
 | |
| LAB_2627
 | |
| 	LSR				; shift byte
 | |
| 	ORA	#$80			; set top bit (mark for 8 times)
 | |
| LAB_262A
 | |
| 	TAY				; copy result
 | |
| 	BCC	LAB_2640		; skip next if bit was zero
 | |
| 
 | |
| 	CLC				; clear carry for add
 | |
| 	LDA	FACt_3		; get temp mantissa3
 | |
| 	ADC	FAC2_3		; add FAC2 mantissa3
 | |
| 	STA	FACt_3		; save temp mantissa3
 | |
| 	LDA	FACt_2		; get temp mantissa2
 | |
| 	ADC	FAC2_2		; add FAC2 mantissa2
 | |
| 	STA	FACt_2		; save temp mantissa2
 | |
| 	LDA	FACt_1		; get temp mantissa1
 | |
| 	ADC	FAC2_1		; add FAC2 mantissa1
 | |
| 	STA	FACt_1		; save temp mantissa1
 | |
| LAB_2640
 | |
| 	ROR	FACt_1		; shift temp mantissa1
 | |
| 	ROR	FACt_2		; shift temp mantissa2
 | |
| 	ROR	FACt_3		; shift temp mantissa3
 | |
| 	ROR	FAC1_r		; shift temp rounding byte
 | |
| 	TYA				; get byte back
 | |
| 	LSR				; shift byte
 | |
| 	BNE	LAB_262A		; loop if all bits not done
 | |
| 
 | |
| LAB_264C
 | |
| 	RTS
 | |
| 
 | |
| ; unpack memory (AY) into FAC2
 | |
| 
 | |
| LAB_264D
 | |
| 	STA	ut1_pl		; save pointer low byte
 | |
| 	STY	ut1_ph		; save pointer high byte
 | |
| 	LDY	#$03			; 4 bytes to get (0-3)
 | |
| 	LDA	(ut1_pl),Y		; get mantissa3
 | |
| 	STA	FAC2_3		; save FAC2 mantissa3
 | |
| 	DEY				; decrement index
 | |
| 	LDA	(ut1_pl),Y		; get mantissa2
 | |
| 	STA	FAC2_2		; save FAC2 mantissa2
 | |
| 	DEY				; decrement index
 | |
| 	LDA	(ut1_pl),Y		; get mantissa1+sign
 | |
| 	STA	FAC2_s		; save FAC2 sign (b7)
 | |
| 	EOR	FAC1_s		; EOR with FAC1 sign (b7)
 | |
| 	STA	FAC_sc		; save sign compare (FAC1 EOR FAC2)
 | |
| 	LDA	FAC2_s		; recover FAC2 sign (b7)
 | |
| 	ORA	#$80			; set 1xxx xxx (set normal bit)
 | |
| 	STA	FAC2_1		; save FAC2 mantissa1
 | |
| 	DEY				; decrement index
 | |
| 	LDA	(ut1_pl),Y		; get exponent byte
 | |
| 	STA	FAC2_e		; save FAC2 exponent
 | |
| 	LDA	FAC1_e		; get FAC1 exponent
 | |
| 	RTS
 | |
| 
 | |
| ; test and adjust accumulators
 | |
| 
 | |
| LAB_2673
 | |
| 	LDA	FAC2_e		; get FAC2 exponent
 | |
| LAB_2675
 | |
| 	BEQ	LAB_2696		; branch if FAC2 = $00 (handle underflow)
 | |
| 
 | |
| 	CLC				; clear carry for add
 | |
| 	ADC	FAC1_e		; add FAC1 exponent
 | |
| 	BCC	LAB_2680		; branch if sum of exponents <$0100
 | |
| 
 | |
| 	BMI	LAB_269B		; do overflow error
 | |
| 
 | |
| 	CLC				; clear carry for the add
 | |
| 	.byte	$2C			; makes next line BIT $1410
 | |
| LAB_2680
 | |
| 	BPL	LAB_2696		; if +ve go handle underflow
 | |
| 
 | |
| 	ADC	#$80			; adjust exponent
 | |
| 	STA	FAC1_e		; save FAC1 exponent
 | |
| 	BNE	LAB_268B		; branch if not zero
 | |
| 
 | |
| 	JMP	LAB_24F5		; save FAC1 sign and return
 | |
| 
 | |
| LAB_268B
 | |
| 	LDA	FAC_sc		; get sign compare (FAC1 EOR FAC2)
 | |
| 	STA	FAC1_s		; save FAC1 sign (b7)
 | |
| LAB_268F
 | |
| 	RTS
 | |
| 
 | |
| ; handle overflow and underflow
 | |
| 
 | |
| LAB_2690
 | |
| 	LDA	FAC1_s		; get FAC1 sign (b7)
 | |
| 	BPL	LAB_269B		; do overflow error
 | |
| 
 | |
| 					; handle underflow
 | |
| LAB_2696
 | |
| 	PLA				; pop return address low byte
 | |
| 	PLA				; pop return address high byte
 | |
| 	JMP	LAB_24F1		; clear FAC1 exponent and sign and return
 | |
| 
 | |
| ; multiply by 10
 | |
| 
 | |
| LAB_269E
 | |
| 	JSR	LAB_27AB		; round and copy FAC1 to FAC2
 | |
| 	TAX				; copy exponent (set the flags)
 | |
| 	BEQ	LAB_268F		; exit if zero
 | |
| 
 | |
| 	CLC				; clear carry for add
 | |
| 	ADC	#$02			; add two to exponent (*4)
 | |
| 	BCS	LAB_269B		; do overflow error if > $FF
 | |
| 
 | |
| 	LDX	#$00			; clear byte
 | |
| 	STX	FAC_sc		; clear sign compare (FAC1 EOR FAC2)
 | |
| 	JSR	LAB_247C		; add FAC2 to FAC1 (*5)
 | |
| 	INC	FAC1_e		; increment FAC1 exponent (*10)
 | |
| 	BNE	LAB_268F		; if non zero just do RTS
 | |
| 
 | |
| LAB_269B
 | |
| 	JMP	LAB_2564		; do overflow error and warm start
 | |
| 
 | |
| ; divide by 10
 | |
| 
 | |
| LAB_26B9
 | |
| 	JSR	LAB_27AB		; round and copy FAC1 to FAC2
 | |
| 	LDA	#<LAB_26B5		; set pointer to 10d low addr
 | |
| 	LDY	#>LAB_26B5		; set pointer to 10d high addr
 | |
| 	LDX	#$00			; clear sign
 | |
| 
 | |
| ; divide by (AY) (X=sign)
 | |
| 
 | |
| LAB_26C2
 | |
| 	STX	FAC_sc		; save sign compare (FAC1 EOR FAC2)
 | |
| 	JSR	LAB_UFAC		; unpack memory (AY) into FAC1
 | |
| 	JMP	LAB_DIVIDE		; do FAC2/FAC1
 | |
| 
 | |
| 					; Perform divide-by
 | |
| ; convert AY and do (AY)/FAC1
 | |
| 
 | |
| LAB_26CA
 | |
| 	JSR	LAB_264D		; unpack memory (AY) into FAC2
 | |
| 
 | |
| 					; Perform divide-into
 | |
| LAB_DIVIDE
 | |
| 	BEQ	LAB_2737		; if zero go do /0 error
 | |
| 
 | |
| 	JSR	LAB_27BA		; round FAC1
 | |
| 	LDA	#$00			; clear A
 | |
| 	SEC				; set carry for subtract
 | |
| 	SBC	FAC1_e		; subtract FAC1 exponent (2s complement)
 | |
| 	STA	FAC1_e		; save FAC1 exponent
 | |
| 	JSR	LAB_2673		; test and adjust accumulators
 | |
| 	INC	FAC1_e		; increment FAC1 exponent
 | |
| 	BEQ	LAB_269B		; if zero do overflow error
 | |
| 
 | |
| 	LDX	#$FF			; set index for pre increment
 | |
| 	LDA	#$01			; set bit to flag byte save
 | |
| LAB_26E4
 | |
| 	LDY	FAC2_1		; get FAC2 mantissa1
 | |
| 	CPY	FAC1_1		; compare FAC1 mantissa1
 | |
| 	BNE	LAB_26F4		; branch if <>
 | |
| 
 | |
| 	LDY	FAC2_2		; get FAC2 mantissa2
 | |
| 	CPY	FAC1_2		; compare FAC1 mantissa2
 | |
| 	BNE	LAB_26F4		; branch if <>
 | |
| 
 | |
| 	LDY	FAC2_3		; get FAC2 mantissa3
 | |
| 	CPY	FAC1_3		; compare FAC1 mantissa3
 | |
| LAB_26F4
 | |
| 	PHP				; save FAC2-FAC1 compare status
 | |
| 	ROL				; shift the result byte
 | |
| 	BCC	LAB_2702		; if no carry skip the byte save
 | |
| 
 | |
| 	LDY	#$01			; set bit to flag byte save
 | |
| 	INX				; else increment the index to FACt
 | |
| 	CPX	#$02			; compare with the index to FACt_3
 | |
| 	BMI	LAB_2701		; if not last byte just go save it
 | |
| 
 | |
| 	BNE	LAB_272B		; if all done go save FAC1 rounding byte, normalise and
 | |
| 					; return
 | |
| 
 | |
| 	LDY	#$40			; set bit to flag byte save for the rounding byte
 | |
| LAB_2701
 | |
| 	STA	FACt_1,X		; write result byte to FACt_1 + index
 | |
| 	TYA				; copy the next save byte flag
 | |
| LAB_2702
 | |
| 	PLP				; restore FAC2-FAC1 compare status
 | |
| 	BCC	LAB_2704		; if FAC2 < FAC1 then skip the subtract
 | |
| 
 | |
| 	TAY				; save FAC2-FAC1 compare status
 | |
| 	LDA	FAC2_3		; get FAC2 mantissa3
 | |
| 	SBC	FAC1_3		; subtract FAC1 mantissa3
 | |
| 	STA	FAC2_3		; save FAC2 mantissa3
 | |
| 	LDA	FAC2_2		; get FAC2 mantissa2
 | |
| 	SBC	FAC1_2		; subtract FAC1 mantissa2
 | |
| 	STA	FAC2_2		; save FAC2 mantissa2
 | |
| 	LDA	FAC2_1		; get FAC2 mantissa1
 | |
| 	SBC	FAC1_1		; subtract FAC1 mantissa1
 | |
| 	STA	FAC2_1		; save FAC2 mantissa1
 | |
| 	TYA				; restore FAC2-FAC1 compare status
 | |
| 
 | |
| 					; FAC2 = FAC2*2
 | |
| LAB_2704
 | |
| 	ASL	FAC2_3		; shift FAC2 mantissa3
 | |
| 	ROL	FAC2_2		; shift FAC2 mantissa2
 | |
| 	ROL	FAC2_1		; shift FAC2 mantissa1
 | |
| 	BCS	LAB_26F4		; loop with no compare
 | |
| 
 | |
| 	BMI	LAB_26E4		; loop with compare
 | |
| 
 | |
| 	BPL	LAB_26F4		; loop always with no compare
 | |
| 
 | |
| ; do A<<6, save as FAC1 rounding byte, normalise and return
 | |
| 
 | |
| LAB_272B
 | |
| 	LSR				; shift b1 - b0 ..
 | |
| 	ROR				; ..
 | |
| 	ROR				; .. to b7 - b6
 | |
| 	STA	FAC1_r		; save FAC1 rounding byte
 | |
| 	PLP				; dump FAC2-FAC1 compare status
 | |
| 	JMP	LAB_273C		; copy temp to FAC1, normalise and return
 | |
| 
 | |
| ; do "Divide by zero" error
 | |
| 
 | |
| LAB_2737
 | |
| 	LDX	#$14			; error code $14 ("Divide by zero" error)
 | |
| 	JMP	LAB_XERR		; do error #X, then warm start
 | |
| 
 | |
| ; copy temp to FAC1 and normalise
 | |
| 
 | |
| LAB_273C
 | |
| 	LDA	FACt_1		; get temp mantissa1
 | |
| 	STA	FAC1_1		; save FAC1 mantissa1
 | |
| 	LDA	FACt_2		; get temp mantissa2
 | |
| 	STA	FAC1_2		; save FAC1 mantissa2
 | |
| 	LDA	FACt_3		; get temp mantissa3
 | |
| 	STA	FAC1_3		; save FAC1 mantissa3
 | |
| 	JMP	LAB_24D5		; normalise FAC1 and return
 | |
| 
 | |
| ; unpack memory (AY) into FAC1
 | |
| 
 | |
| LAB_UFAC
 | |
| 	STA	ut1_pl		; save pointer low byte
 | |
| 	STY	ut1_ph		; save pointer high byte
 | |
| 	LDY	#$03			; 4 bytes to do
 | |
| 	LDA	(ut1_pl),Y		; get last byte
 | |
| 	STA	FAC1_3		; save FAC1 mantissa3
 | |
| 	DEY				; decrement index
 | |
| 	LDA	(ut1_pl),Y		; get last-1 byte
 | |
| 	STA	FAC1_2		; save FAC1 mantissa2
 | |
| 	DEY				; decrement index
 | |
| 	LDA	(ut1_pl),Y		; get second byte
 | |
| 	STA	FAC1_s		; save FAC1 sign (b7)
 | |
| 	ORA	#$80			; set 1xxx xxxx (add normal bit)
 | |
| 	STA	FAC1_1		; save FAC1 mantissa1
 | |
| 	DEY				; decrement index
 | |
| 	LDA	(ut1_pl),Y		; get first byte (exponent)
 | |
| 	STA	FAC1_e		; save FAC1 exponent
 | |
| 	STY	FAC1_r		; clear FAC1 rounding byte
 | |
| 	RTS
 | |
| 
 | |
| ; pack FAC1 into Adatal
 | |
| 
 | |
| LAB_276E
 | |
| 	LDX	#<Adatal		; set pointer low byte
 | |
| LAB_2770
 | |
| 	LDY	#>Adatal		; set pointer high byte
 | |
| 	BEQ	LAB_2778		; pack FAC1 into (XY) and return
 | |
| 
 | |
| ; pack FAC1 into (Lvarpl)
 | |
| 
 | |
| LAB_PFAC
 | |
| 	LDX	Lvarpl		; get destination pointer low byte
 | |
| 	LDY	Lvarph		; get destination pointer high byte
 | |
| 
 | |
| ; pack FAC1 into (XY)
 | |
| 
 | |
| LAB_2778
 | |
| 	JSR	LAB_27BA		; round FAC1
 | |
| 	STX	ut1_pl		; save pointer low byte
 | |
| 	STY	ut1_ph		; save pointer high byte
 | |
| 	LDY	#$03			; set index
 | |
| 	LDA	FAC1_3		; get FAC1 mantissa3
 | |
| 	STA	(ut1_pl),Y		; store in destination
 | |
| 	DEY				; decrement index
 | |
| 	LDA	FAC1_2		; get FAC1 mantissa2
 | |
| 	STA	(ut1_pl),Y		; store in destination
 | |
| 	DEY				; decrement index
 | |
| 	LDA	FAC1_s		; get FAC1 sign (b7)
 | |
| 	ORA	#$7F			; set bits x111 1111
 | |
| 	AND	FAC1_1		; AND in FAC1 mantissa1
 | |
| 	STA	(ut1_pl),Y		; store in destination
 | |
| 	DEY				; decrement index
 | |
| 	LDA	FAC1_e		; get FAC1 exponent
 | |
| 	STA	(ut1_pl),Y		; store in destination
 | |
| 	STY	FAC1_r		; clear FAC1 rounding byte
 | |
| 	RTS
 | |
| 
 | |
| ; round and copy FAC1 to FAC2
 | |
| 
 | |
| LAB_27AB
 | |
| 	JSR	LAB_27BA		; round FAC1
 | |
| 
 | |
| ; copy FAC1 to FAC2
 | |
| 
 | |
| LAB_27AE
 | |
| 	LDX	#$05			; 5 bytes to copy
 | |
| LAB_27B0
 | |
| 	LDA	FAC1_e-1,X		; get byte from FAC1,X
 | |
| 	STA	FAC1_o,X		; save byte at FAC2,X
 | |
| 	DEX				; decrement count
 | |
| 	BNE	LAB_27B0		; loop if not all done
 | |
| 
 | |
| 	STX	FAC1_r		; clear FAC1 rounding byte
 | |
| LAB_27B9
 | |
| 	RTS
 | |
| 
 | |
| ; round FAC1
 | |
| 
 | |
| LAB_27BA
 | |
| 	LDA	FAC1_e		; get FAC1 exponent
 | |
| 	BEQ	LAB_27B9		; exit if zero
 | |
| 
 | |
| 	ASL	FAC1_r		; shift FAC1 rounding byte
 | |
| 	BCC	LAB_27B9		; exit if no overflow
 | |
| 
 | |
| ; round FAC1 (no check)
 | |
| 
 | |
| LAB_27C2
 | |
| 	JSR	LAB_2559		; increment FAC1 mantissa
 | |
| 	BNE	LAB_27B9		; branch if no overflow
 | |
| 
 | |
| 	JMP	LAB_252A		; normalise FAC1 for C=1 and return
 | |
| 
 | |
| ; get FAC1 sign
 | |
| ; return A=FF,C=1/-ve A=01,C=0/+ve
 | |
| 
 | |
| LAB_27CA
 | |
| 	LDA	FAC1_e		; get FAC1 exponent
 | |
| 	BEQ	LAB_27D7		; exit if zero (already correct SGN(0)=0)
 | |
| 
 | |
| ; return A=FF,C=1/-ve A=01,C=0/+ve
 | |
| ; no = 0 check
 | |
| 
 | |
| LAB_27CE
 | |
| 	LDA	FAC1_s		; else get FAC1 sign (b7)
 | |
| 
 | |
| ; return A=FF,C=1/-ve A=01,C=0/+ve
 | |
| ; no = 0 check, sign in A
 | |
| 
 | |
| LAB_27D0
 | |
| 	ROL				; move sign bit to carry
 | |
| 	LDA	#$FF			; set byte for -ve result
 | |
| 	BCS	LAB_27D7		; return if sign was set (-ve)
 | |
| 
 | |
| 	LDA	#$01			; else set byte for +ve result
 | |
| LAB_27D7
 | |
| 	RTS
 | |
| 
 | |
| ; perform SGN()
 | |
| 
 | |
| LAB_SGN
 | |
| 	JSR	LAB_27CA		; get FAC1 sign
 | |
| 					; return A=$FF/-ve A=$01/+ve
 | |
| ; save A as integer byte
 | |
| 
 | |
| LAB_27DB
 | |
| 	STA	FAC1_1		; save FAC1 mantissa1
 | |
| 	LDA	#$00			; clear A
 | |
| 	STA	FAC1_2		; clear FAC1 mantissa2
 | |
| 	LDX	#$88			; set exponent
 | |
| 
 | |
| ; set exp=X, clearFAC1 mantissa3 and normalise
 | |
| 
 | |
| LAB_27E3
 | |
| 	LDA	FAC1_1		; get FAC1 mantissa1
 | |
| 	EOR	#$FF			; complement it
 | |
| 	ROL				; sign bit into carry
 | |
| 
 | |
| ; set exp=X, clearFAC1 mantissa3 and normalise
 | |
| 
 | |
| LAB_STFA
 | |
| 	LDA	#$00			; clear A
 | |
| 	STA	FAC1_3		; clear FAC1 mantissa3
 | |
| 	STX	FAC1_e		; set FAC1 exponent
 | |
| 	STA	FAC1_r		; clear FAC1 rounding byte
 | |
| 	STA	FAC1_s		; clear FAC1 sign (b7)
 | |
| 	JMP	LAB_24D0		; do ABS and normalise FAC1
 | |
| 
 | |
| ; perform ABS()
 | |
| 
 | |
| LAB_ABS
 | |
| 	LSR	FAC1_s		; clear FAC1 sign (put zero in b7)
 | |
| 	RTS
 | |
| 
 | |
| ; compare FAC1 with (AY)
 | |
| ; returns A=$00 if FAC1 = (AY)
 | |
| ; returns A=$01 if FAC1 > (AY)
 | |
| ; returns A=$FF if FAC1 < (AY)
 | |
| 
 | |
| LAB_27F8
 | |
| 	STA	ut2_pl		; save pointer low byte
 | |
| LAB_27FA
 | |
| 	STY	ut2_ph		; save pointer high byte
 | |
| 	LDY	#$00			; clear index
 | |
| 	LDA	(ut2_pl),Y		; get exponent
 | |
| 	INY				; increment index
 | |
| 	TAX				; copy (AY) exponent to X
 | |
| 	BEQ	LAB_27CA		; branch if (AY) exponent=0 and get FAC1 sign
 | |
| 					; A=FF,C=1/-ve A=01,C=0/+ve
 | |
| 
 | |
| 	LDA	(ut2_pl),Y		; get (AY) mantissa1 (with sign)
 | |
| 	EOR	FAC1_s		; EOR FAC1 sign (b7)
 | |
| 	BMI	LAB_27CE		; if signs <> do return A=FF,C=1/-ve
 | |
| 					; A=01,C=0/+ve and return
 | |
| 
 | |
| 	CPX	FAC1_e		; compare (AY) exponent with FAC1 exponent
 | |
| 	BNE	LAB_2828		; branch if different
 | |
| 
 | |
| 	LDA	(ut2_pl),Y		; get (AY) mantissa1 (with sign)
 | |
| 	ORA	#$80			; normalise top bit
 | |
| 	CMP	FAC1_1		; compare with FAC1 mantissa1
 | |
| 	BNE	LAB_2828		; branch if different
 | |
| 
 | |
| 	INY				; increment index
 | |
| 	LDA	(ut2_pl),Y		; get mantissa2
 | |
| 	CMP	FAC1_2		; compare with FAC1 mantissa2
 | |
| 	BNE	LAB_2828		; branch if different
 | |
| 
 | |
| 	INY				; increment index
 | |
| 	LDA	#$7F			; set for 1/2 value rounding byte
 | |
| 	CMP	FAC1_r		; compare with FAC1 rounding byte (set carry)
 | |
| 	LDA	(ut2_pl),Y		; get mantissa3
 | |
| 	SBC	FAC1_3		; subtract FAC1 mantissa3
 | |
| 	BEQ	LAB_2850		; exit if mantissa3 equal
 | |
| 
 | |
| ; gets here if number <> FAC1
 | |
| 
 | |
| LAB_2828
 | |
| 	LDA	FAC1_s		; get FAC1 sign (b7)
 | |
| 	BCC	LAB_282E		; branch if FAC1 > (AY)
 | |
| 
 | |
| 	EOR	#$FF			; else toggle FAC1 sign
 | |
| LAB_282E
 | |
| 	JMP	LAB_27D0		; return A=FF,C=1/-ve A=01,C=0/+ve
 | |
| 
 | |
| ; convert FAC1 floating-to-fixed
 | |
| 
 | |
| LAB_2831
 | |
| 	LDA	FAC1_e		; get FAC1 exponent
 | |
| 	BEQ	LAB_287F		; if zero go clear FAC1 and return
 | |
| 
 | |
| 	SEC				; set carry for subtract
 | |
| 	SBC	#$98			; subtract maximum integer range exponent
 | |
| 	BIT	FAC1_s		; test FAC1 sign (b7)
 | |
| 	BPL	LAB_2845		; branch if FAC1 +ve
 | |
| 
 | |
| 					; FAC1 was -ve
 | |
| 	TAX				; copy subtracted exponent
 | |
| 	LDA	#$FF			; overflow for -ve number
 | |
| 	STA	FAC1_o		; set FAC1 overflow byte
 | |
| 	JSR	LAB_253D		; twos complement FAC1 mantissa
 | |
| 	TXA				; restore subtracted exponent
 | |
| LAB_2845
 | |
| 	LDX	#FAC1_e		; set index to FAC1
 | |
| 	CMP	#$F9			; compare exponent result
 | |
| 	BPL	LAB_2851		; if < 8 shifts shift FAC1 A times right and return
 | |
| 
 | |
| 	JSR	LAB_257B		; shift FAC1 A times right (> 8 shifts)
 | |
| 	STY	FAC1_o		; clear FAC1 overflow byte
 | |
| LAB_2850
 | |
| 	RTS
 | |
| 
 | |
| ; shift FAC1 A times right
 | |
| 
 | |
| LAB_2851
 | |
| 	TAY				; copy shift count
 | |
| 	LDA	FAC1_s		; get FAC1 sign (b7)
 | |
| 	AND	#$80			; mask sign bit only (x000 0000)
 | |
| 	LSR	FAC1_1		; shift FAC1 mantissa1
 | |
| 	ORA	FAC1_1		; OR sign in b7 FAC1 mantissa1
 | |
| 	STA	FAC1_1		; save FAC1 mantissa1
 | |
| 	JSR	LAB_2592		; shift FAC1 Y times right
 | |
| 	STY	FAC1_o		; clear FAC1 overflow byte
 | |
| 	RTS
 | |
| 
 | |
| ; perform INT()
 | |
| 
 | |
| LAB_INT
 | |
| 	LDA	FAC1_e		; get FAC1 exponent
 | |
| 	CMP	#$98			; compare with max int
 | |
| 	BCS	LAB_2886		; exit if >= (already int, too big for fractional part!)
 | |
| 
 | |
| 	JSR	LAB_2831		; convert FAC1 floating-to-fixed
 | |
| 	STY	FAC1_r		; save FAC1 rounding byte
 | |
| 	LDA	FAC1_s		; get FAC1 sign (b7)
 | |
| 	STY	FAC1_s		; save FAC1 sign (b7)
 | |
| 	EOR	#$80			; toggle FAC1 sign
 | |
| 	ROL				; shift into carry
 | |
| 	LDA	#$98			; set new exponent
 | |
| 	STA	FAC1_e		; save FAC1 exponent
 | |
| 	LDA	FAC1_3		; get FAC1 mantissa3
 | |
| 	STA	Temp3			; save for EXP() function
 | |
| 	JMP	LAB_24D0		; do ABS and normalise FAC1
 | |
| 
 | |
| ; clear FAC1 and return
 | |
| 
 | |
| LAB_287F
 | |
| 	STA	FAC1_1		; clear FAC1 mantissa1
 | |
| 	STA	FAC1_2		; clear FAC1 mantissa2
 | |
| 	STA	FAC1_3		; clear FAC1 mantissa3
 | |
| 	TAY				; clear Y
 | |
| LAB_2886
 | |
| 	RTS
 | |
| 
 | |
| ; get FAC1 from string
 | |
| ; this routine now handles hex and binary values from strings
 | |
| ; starting with "$" and "%" respectively
 | |
| 
 | |
| LAB_2887
 | |
| 	LDY	#$00			; clear Y
 | |
| 	STY	Dtypef		; clear data type flag, $FF=string, $00=numeric
 | |
| 	LDX	#$09			; set index
 | |
| LAB_288B
 | |
| 	STY	numexp,X		; clear byte
 | |
| 	DEX				; decrement index
 | |
| 	BPL	LAB_288B		; loop until numexp to negnum (and FAC1) = $00
 | |
| 
 | |
| 	BCC	LAB_28FE		; branch if 1st character numeric
 | |
| 
 | |
| ; get FAC1 from string .. first character wasn't numeric
 | |
| 
 | |
| 	CMP	#'-'			; else compare with "-"
 | |
| 	BNE	LAB_289A		; branch if not "-"
 | |
| 
 | |
| 	STX	negnum		; set flag for -ve number (X = $FF)
 | |
| 	BEQ	LAB_289C		; branch always (go scan and check for hex/bin)
 | |
| 
 | |
| ; get FAC1 from string .. first character wasn't numeric or -
 | |
| 
 | |
| LAB_289A
 | |
| 	CMP	#'+'			; else compare with "+"
 | |
| 	BNE	LAB_289D		; branch if not "+" (go check for hex/bin)
 | |
| 
 | |
| ; was "+" or "-" to start, so get next character
 | |
| 
 | |
| LAB_289C
 | |
| 	JSR	LAB_IGBY		; increment and scan memory
 | |
| 	BCC	LAB_28FE		; branch if numeric character
 | |
| 
 | |
| ; code here for hex and binary numbers
 | |
| 
 | |
| LAB_289D
 | |
| 	CMP	#'$'			; else compare with "$"
 | |
| 	BNE	LAB_NHEX		; branch if not "$"
 | |
| 
 | |
| 	JMP	LAB_CHEX		; branch if "$"
 | |
| 
 | |
| LAB_NHEX
 | |
| 	CMP	#'%'			; else compare with "%"
 | |
| 	BNE	LAB_28A3		; branch if not "%" (continue original code)
 | |
| 
 | |
| 	JMP	LAB_CBIN		; branch if "%"
 | |
| 
 | |
| LAB_289E
 | |
| 	JSR	LAB_IGBY		; increment and scan memory (ignore + or get next number)
 | |
| LAB_28A1
 | |
| 	BCC	LAB_28FE		; branch if numeric character
 | |
| 
 | |
| ; get FAC1 from string .. character wasn't numeric, -, +, hex or binary
 | |
| 
 | |
| LAB_28A3
 | |
| 	CMP	#'.'			; else compare with "."
 | |
| 	BEQ	LAB_28D5		; branch if "."
 | |
| 
 | |
| ; get FAC1 from string .. character wasn't numeric, -, + or .
 | |
| 
 | |
| 	CMP	#'E'			; else compare with "E"
 | |
| 	BNE	LAB_28DB		; branch if not "E"
 | |
| 
 | |
| 					; was "E" so evaluate exponential part
 | |
| 	JSR	LAB_IGBY		; increment and scan memory
 | |
| 	BCC	LAB_28C7		; branch if numeric character
 | |
| 
 | |
| 	CMP	#TK_MINUS		; else compare with token for -
 | |
| 	BEQ	LAB_28C2		; branch if token for -
 | |
| 
 | |
| 	CMP	#'-'			; else compare with "-"
 | |
| 	BEQ	LAB_28C2		; branch if "-"
 | |
| 
 | |
| 	CMP	#TK_PLUS		; else compare with token for +
 | |
| 	BEQ	LAB_28C4		; branch if token for +
 | |
| 
 | |
| 	CMP	#'+'			; else compare with "+"
 | |
| 	BEQ	LAB_28C4		; branch if "+"
 | |
| 
 | |
| 	BNE	LAB_28C9		; branch always
 | |
| 
 | |
| LAB_28C2
 | |
| 	ROR	expneg		; set exponent -ve flag (C, which=1, into b7)
 | |
| LAB_28C4
 | |
| 	JSR	LAB_IGBY		; increment and scan memory
 | |
| LAB_28C7
 | |
| 	BCC	LAB_2925		; branch if numeric character
 | |
| 
 | |
| LAB_28C9
 | |
| 	BIT	expneg		; test exponent -ve flag
 | |
| 	BPL	LAB_28DB		; if +ve go evaluate exponent
 | |
| 
 | |
| 					; else do exponent = -exponent 
 | |
| 	LDA	#$00			; clear result
 | |
| 	SEC				; set carry for subtract
 | |
| 	SBC	expcnt		; subtract exponent byte
 | |
| 	JMP	LAB_28DD		; go evaluate exponent
 | |
| 
 | |
| LAB_28D5
 | |
| 	ROR	numdpf		; set decimal point flag
 | |
| 	BIT	numdpf		; test decimal point flag
 | |
| 	BVC	LAB_289E		; branch if only one decimal point so far
 | |
| 
 | |
| 					; evaluate exponent
 | |
| LAB_28DB
 | |
| 	LDA	expcnt		; get exponent count byte
 | |
| LAB_28DD
 | |
| 	SEC				; set carry for subtract
 | |
| 	SBC	numexp		; subtract numerator exponent
 | |
| 	STA	expcnt		; save exponent count byte
 | |
| 	BEQ	LAB_28F6		; branch if no adjustment
 | |
| 
 | |
| 	BPL	LAB_28EF		; else if +ve go do FAC1*10^expcnt
 | |
| 
 | |
| 					; else go do FAC1/10^(0-expcnt)
 | |
| LAB_28E6
 | |
| 	JSR	LAB_26B9		; divide by 10
 | |
| 	INC	expcnt		; increment exponent count byte
 | |
| 	BNE	LAB_28E6		; loop until all done
 | |
| 
 | |
| 	BEQ	LAB_28F6		; branch always
 | |
| 
 | |
| LAB_28EF
 | |
| 	JSR	LAB_269E		; multiply by 10
 | |
| 	DEC	expcnt		; decrement exponent count byte
 | |
| 	BNE	LAB_28EF		; loop until all done
 | |
| 
 | |
| LAB_28F6
 | |
| 	LDA	negnum		; get -ve flag
 | |
| 	BMI	LAB_28FB		; if -ve do - FAC1 and return
 | |
| 
 | |
| 	RTS
 | |
| 
 | |
| ; do - FAC1 and return
 | |
| 
 | |
| LAB_28FB
 | |
| 	JMP	LAB_GTHAN		; do - FAC1 and return
 | |
| 
 | |
| ; do unsigned FAC1*10+number
 | |
| 
 | |
| LAB_28FE
 | |
| 	PHA				; save character
 | |
| 	BIT	numdpf		; test decimal point flag
 | |
| 	BPL	LAB_2905		; skip exponent increment if not set
 | |
| 
 | |
| 	INC	numexp		; else increment number exponent
 | |
| LAB_2905
 | |
| 	JSR	LAB_269E		; multiply FAC1 by 10
 | |
| 	PLA				; restore character
 | |
| 	AND	#$0F			; convert to binary
 | |
| 	JSR	LAB_2912		; evaluate new ASCII digit
 | |
| 	JMP	LAB_289E		; go do next character
 | |
| 
 | |
| ; evaluate new ASCII digit
 | |
| 
 | |
| LAB_2912
 | |
| 	PHA				; save digit
 | |
| 	JSR	LAB_27AB		; round and copy FAC1 to FAC2
 | |
| 	PLA				; restore digit
 | |
| 	JSR	LAB_27DB		; save A as integer byte
 | |
| 	LDA	FAC2_s		; get FAC2 sign (b7)
 | |
| 	EOR	FAC1_s		; toggle with FAC1 sign (b7)
 | |
| 	STA	FAC_sc		; save sign compare (FAC1 EOR FAC2)
 | |
| 	LDX	FAC1_e		; get FAC1 exponent
 | |
| 	JMP	LAB_ADD		; add FAC2 to FAC1 and return
 | |
| 
 | |
| ; evaluate next character of exponential part of number
 | |
| 
 | |
| LAB_2925
 | |
| 	LDA	expcnt		; get exponent count byte
 | |
| 	CMP	#$0A			; compare with 10 decimal
 | |
| 	BCC	LAB_2934		; branch if less
 | |
| 
 | |
| 	LDA	#$64			; make all -ve exponents = -100 decimal (causes underflow)
 | |
| 	BIT	expneg		; test exponent -ve flag
 | |
| 	BMI	LAB_2942		; branch if -ve
 | |
| 
 | |
| 	JMP	LAB_2564		; else do overflow error
 | |
| 
 | |
| LAB_2934
 | |
| 	ASL				; * 2
 | |
| 	ASL				; * 4
 | |
| 	ADC	expcnt		; * 5
 | |
| 	ASL				; * 10
 | |
| 	LDY	#$00			; set index
 | |
| 	ADC	(Bpntrl),Y		; add character (will be $30 too much!)
 | |
| 	SBC	#'0'-1		; convert character to binary
 | |
| LAB_2942
 | |
| 	STA	expcnt		; save exponent count byte
 | |
| 	JMP	LAB_28C4		; go get next character
 | |
| 
 | |
| ; print " in line [LINE #]"
 | |
| 
 | |
| LAB_2953
 | |
| 	LDA	#<LAB_LMSG		; point to " in line " message low byte
 | |
| 	LDY	#>LAB_LMSG		; point to " in line " message high byte
 | |
| 	JSR	LAB_18C3		; print null terminated string from memory
 | |
| 
 | |
| 					; print Basic line #
 | |
| 	LDA	Clineh		; get current line high byte
 | |
| 	LDX	Clinel		; get current line low byte
 | |
| 
 | |
| ; print XA as unsigned integer
 | |
| 
 | |
| LAB_295E
 | |
| 	STA	FAC1_1		; save low byte as FAC1 mantissa1
 | |
| 	STX	FAC1_2		; save high byte as FAC1 mantissa2
 | |
| 	LDX	#$90			; set exponent to 16d bits
 | |
| 	SEC				; set integer is +ve flag
 | |
| 	JSR	LAB_STFA		; set exp=X, clearFAC1 mantissa3 and normalise
 | |
| 	LDY	#$00			; clear index
 | |
| 	TYA				; clear A
 | |
| 	JSR	LAB_297B		; convert FAC1 to string, skip sign character save
 | |
| 	JMP	LAB_18C3		; print null terminated string from memory and return
 | |
| 
 | |
| ; convert FAC1 to ASCII string result in (AY)
 | |
| ; not any more, moved scratchpad to page 0
 | |
| 
 | |
| LAB_296E
 | |
| 	LDY	#$01			; set index = 1
 | |
| 	LDA	#$20			; character = " " (assume +ve)
 | |
| 	BIT	FAC1_s		; test FAC1 sign (b7)
 | |
| 	BPL	LAB_2978		; branch if +ve
 | |
| 
 | |
| 	LDA	#$2D			; else character = "-"
 | |
| LAB_2978
 | |
| 	STA	Decss,Y		; save leading character (" " or "-")
 | |
| LAB_297B
 | |
| 	STA	FAC1_s		; clear FAC1 sign (b7)
 | |
| 	STY	Sendl			; save index
 | |
| 	INY				; increment index
 | |
| 	LDX	FAC1_e		; get FAC1 exponent
 | |
| 	BNE	LAB_2989		; branch if FAC1<>0
 | |
| 
 | |
| 					; exponent was $00 so FAC1 is 0
 | |
| 	LDA	#'0'			; set character = "0"
 | |
| 	JMP	LAB_2A89		; save last character, [EOT] and exit
 | |
| 
 | |
| 					; FAC1 is some non zero value
 | |
| LAB_2989
 | |
| 	LDA	#$00			; clear (number exponent count)
 | |
| 	CPX	#$81			; compare FAC1 exponent with $81 (>1.00000)
 | |
| 
 | |
| 	BCS	LAB_299A		; branch if FAC1=>1
 | |
| 
 | |
| 					; FAC1<1
 | |
| 	LDA	#<LAB_294F		; set pointer low byte to 1,000,000
 | |
| 	LDY	#>LAB_294F		; set pointer high byte to 1,000,000
 | |
| 	JSR	LAB_25FB		; do convert AY, FCA1*(AY)
 | |
| 	LDA	#$FA			; set number exponent count (-6)
 | |
| LAB_299A
 | |
| 	STA	numexp		; save number exponent count
 | |
| LAB_299C
 | |
| 	LDA	#<LAB_294B		; set pointer low byte to 999999.4375 (max before sci note)
 | |
| 	LDY	#>LAB_294B		; set pointer high byte to 999999.4375
 | |
| 	JSR	LAB_27F8		; compare FAC1 with (AY)
 | |
| 	BEQ	LAB_29C3		; exit if FAC1 = (AY)
 | |
| 
 | |
| 	BPL	LAB_29B9		; go do /10 if FAC1 > (AY)
 | |
| 
 | |
| 					; FAC1 < (AY)
 | |
| LAB_29A7
 | |
| 	LDA	#<LAB_2947		; set pointer low byte to 99999.9375
 | |
| 	LDY	#>LAB_2947		; set pointer high byte to 99999.9375
 | |
| 	JSR	LAB_27F8		; compare FAC1 with (AY)
 | |
| 	BEQ	LAB_29B2		; branch if FAC1 = (AY) (allow decimal places)
 | |
| 
 | |
| 	BPL	LAB_29C0		; branch if FAC1 > (AY) (no decimal places)
 | |
| 
 | |
| 					; FAC1 <= (AY)
 | |
| LAB_29B2
 | |
| 	JSR	LAB_269E		; multiply by 10
 | |
| 	DEC	numexp		; decrement number exponent count
 | |
| 	BNE	LAB_29A7		; go test again (branch always)
 | |
| 
 | |
| LAB_29B9
 | |
| 	JSR	LAB_26B9		; divide by 10
 | |
| 	INC	numexp		; increment number exponent count
 | |
| 	BNE	LAB_299C		; go test again (branch always)
 | |
| 
 | |
| ; now we have just the digits to do
 | |
| 
 | |
| LAB_29C0
 | |
| 	JSR	LAB_244E		; add 0.5 to FAC1 (round FAC1)
 | |
| LAB_29C3
 | |
| 	JSR	LAB_2831		; convert FAC1 floating-to-fixed
 | |
| 	LDX	#$01			; set default digits before dp = 1
 | |
| 	LDA	numexp		; get number exponent count
 | |
| 	CLC				; clear carry for add
 | |
| 	ADC	#$07			; up to 6 digits before point
 | |
| 	BMI	LAB_29D8		; if -ve then 1 digit before dp
 | |
| 
 | |
| 	CMP	#$08			; A>=8 if n>=1E6
 | |
| 	BCS	LAB_29D9		; branch if >= $08
 | |
| 
 | |
| 					; carry is clear
 | |
| 	ADC	#$FF			; take 1 from digit count
 | |
| 	TAX				; copy to A
 | |
| 	LDA	#$02			;.set exponent adjust
 | |
| LAB_29D8
 | |
| 	SEC				; set carry for subtract
 | |
| LAB_29D9
 | |
| 	SBC	#$02			; -2
 | |
| 	STA	expcnt		;.save exponent adjust
 | |
| 	STX	numexp		; save digits before dp count
 | |
| 	TXA				; copy to A
 | |
| 	BEQ	LAB_29E4		; branch if no digits before dp
 | |
| 
 | |
| 	BPL	LAB_29F7		; branch if digits before dp
 | |
| 
 | |
| LAB_29E4
 | |
| 	LDY	Sendl			; get output string index
 | |
| 	LDA	#$2E			; character "."
 | |
| 	INY				; increment index
 | |
| 	STA	Decss,Y		; save to output string
 | |
| 	TXA				;.
 | |
| 	BEQ	LAB_29F5		;.
 | |
| 
 | |
| 	LDA	#'0'			; character "0"
 | |
| 	INY				; increment index
 | |
| 	STA	Decss,Y		; save to output string
 | |
| LAB_29F5
 | |
| 	STY	Sendl			; save output string index
 | |
| LAB_29F7
 | |
| 	LDY	#$00			; clear index (point to 100,000)
 | |
| 	LDX	#$80			; 
 | |
| LAB_29FB
 | |
| 	LDA	FAC1_3		; get FAC1 mantissa3
 | |
| 	CLC				; clear carry for add
 | |
| 	ADC	LAB_2A9C,Y		; add -ve LSB
 | |
| 	STA	FAC1_3		; save FAC1 mantissa3
 | |
| 	LDA	FAC1_2		; get FAC1 mantissa2
 | |
| 	ADC	LAB_2A9B,Y		; add -ve NMSB
 | |
| 	STA	FAC1_2		; save FAC1 mantissa2
 | |
| 	LDA	FAC1_1		; get FAC1 mantissa1
 | |
| 	ADC	LAB_2A9A,Y		; add -ve MSB
 | |
| 	STA	FAC1_1		; save FAC1 mantissa1
 | |
| 	INX				; 
 | |
| 	BCS	LAB_2A18		; 
 | |
| 
 | |
| 	BPL	LAB_29FB		; not -ve so try again
 | |
| 
 | |
| 	BMI	LAB_2A1A		; 
 | |
| 
 | |
| LAB_2A18
 | |
| 	BMI	LAB_29FB		; 
 | |
| 
 | |
| LAB_2A1A
 | |
| 	TXA				; 
 | |
| 	BCC	LAB_2A21		; 
 | |
| 
 | |
| 	EOR	#$FF			; 
 | |
| 	ADC	#$0A			; 
 | |
| LAB_2A21
 | |
| 	ADC	#'0'-1		; add "0"-1 to result
 | |
| 	INY				; increment index ..
 | |
| 	INY				; .. to next less ..
 | |
| 	INY				; .. power of ten
 | |
| 	STY	Cvaral		; save as current var address low byte
 | |
| 	LDY	Sendl			; get output string index
 | |
| 	INY				; increment output string index
 | |
| 	TAX				; copy character to X
 | |
| 	AND	#$7F			; mask out top bit
 | |
| 	STA	Decss,Y		; save to output string
 | |
| 	DEC	numexp		; decrement # of characters before the dp
 | |
| 	BNE	LAB_2A3B		; branch if still characters to do
 | |
| 
 | |
| 					; else output the point
 | |
| 	LDA	#$2E			; character "."
 | |
| 	INY				; increment output string index
 | |
| 	STA	Decss,Y		; save to output string
 | |
| LAB_2A3B
 | |
| 	STY	Sendl			; save output string index
 | |
| 	LDY	Cvaral		; get current var address low byte
 | |
| 	TXA				; get character back
 | |
| 	EOR	#$FF			; 
 | |
| 	AND	#$80			; 
 | |
| 	TAX				; 
 | |
| 	CPY	#$12			; compare index with max
 | |
| 	BNE	LAB_29FB		; loop if not max
 | |
| 
 | |
| 					; now remove trailing zeroes
 | |
| 	LDY	Sendl			; get output string index
 | |
| LAB_2A4B
 | |
| 	LDA	Decss,Y		; get character from output string
 | |
| 	DEY				; decrement output string index
 | |
| 	CMP	#'0'			; compare with "0"
 | |
| 	BEQ	LAB_2A4B		; loop until non "0" character found
 | |
| 
 | |
| 	CMP	#'.'			; compare with "."
 | |
| 	BEQ	LAB_2A58		; branch if was dp
 | |
| 
 | |
| 					; restore last character
 | |
| 	INY				; increment output string index
 | |
| LAB_2A58
 | |
| 	LDA	#$2B			; character "+"
 | |
| 	LDX	expcnt		; get exponent count
 | |
| 	BEQ	LAB_2A8C		; if zero go set null terminator and exit
 | |
| 
 | |
| 					; exponent isn't zero so write exponent
 | |
| 	BPL	LAB_2A68		; branch if exponent count +ve
 | |
| 
 | |
| 	LDA	#$00			; clear A
 | |
| 	SEC				; set carry for subtract
 | |
| 	SBC	expcnt		; subtract exponent count adjust (convert -ve to +ve)
 | |
| 	TAX				; copy exponent count to X
 | |
| 	LDA	#'-'			; character "-"
 | |
| LAB_2A68
 | |
| 	STA	Decss+2,Y		; save to output string
 | |
| 	LDA	#$45			; character "E"
 | |
| 	STA	Decss+1,Y		; save exponent sign to output string
 | |
| 	TXA				; get exponent count back
 | |
| 	LDX	#'0'-1		; one less than "0" character
 | |
| 	SEC				; set carry for subtract
 | |
| LAB_2A74
 | |
| 	INX				; increment 10's character
 | |
| 	SBC	#$0A			;.subtract 10 from exponent count
 | |
| 	BCS	LAB_2A74		; loop while still >= 0
 | |
| 
 | |
| 	ADC	#':'			; add character ":" ($30+$0A, result is 10 less that value)
 | |
| 	STA	Decss+4,Y		; save to output string
 | |
| 	TXA				; copy 10's character
 | |
| 	STA	Decss+3,Y		; save to output string
 | |
| 	LDA	#$00			; set null terminator
 | |
| 	STA	Decss+5,Y		; save to output string
 | |
| 	BEQ	LAB_2A91		; go set string pointer (AY) and exit (branch always)
 | |
| 
 | |
| 					; save last character, [EOT] and exit
 | |
| LAB_2A89
 | |
| 	STA	Decss,Y		; save last character to output string
 | |
| 
 | |
| 					; set null terminator and exit
 | |
| LAB_2A8C
 | |
| 	LDA	#$00			; set null terminator
 | |
| 	STA	Decss+1,Y		; save after last character
 | |
| 
 | |
| 					; set string pointer (AY) and exit
 | |
| LAB_2A91
 | |
| 	LDA	#<Decssp1		; set result string low pointer
 | |
| 	LDY	#>Decssp1		; set result string high pointer
 | |
| 	RTS
 | |
| 
 | |
| ; perform power function
 | |
| 
 | |
| LAB_POWER
 | |
| 	BEQ	LAB_EXP		; go do  EXP()
 | |
| 
 | |
| 	LDA	FAC2_e		; get FAC2 exponent
 | |
| 	BNE	LAB_2ABF		; branch if FAC2<>0
 | |
| 
 | |
| 	JMP	LAB_24F3		; clear FAC1 exponent and sign and return
 | |
| 
 | |
| LAB_2ABF
 | |
| 	LDX	#<func_l		; set destination pointer low byte
 | |
| 	LDY	#>func_l		; set destination pointer high byte
 | |
| 	JSR	LAB_2778		; pack FAC1 into (XY)
 | |
| 	LDA	FAC2_s		; get FAC2 sign (b7)
 | |
| 	BPL	LAB_2AD9		; branch if FAC2>0
 | |
| 
 | |
| 					; else FAC2 is -ve and can only be raised to an
 | |
| 					; integer power which gives an x +j0 result
 | |
| 	JSR	LAB_INT		; perform INT
 | |
| 	LDA	#<func_l		; set source pointer low byte
 | |
| 	LDY	#>func_l		; set source pointer high byte
 | |
| 	JSR	LAB_27F8		; compare FAC1 with (AY)
 | |
| 	BNE	LAB_2AD9		; branch if FAC1 <> (AY) to allow Function Call error
 | |
| 					; this will leave FAC1 -ve and cause a Function Call
 | |
| 					; error when LOG() is called
 | |
| 
 | |
| 	TYA				; clear sign b7
 | |
| 	LDY	Temp3			; save mantissa 3 from INT() function as sign in Y
 | |
| 					; for possible later negation, b0
 | |
| LAB_2AD9
 | |
| 	JSR	LAB_279D		; save FAC1 sign and copy ABS(FAC2) to FAC1
 | |
| 	TYA				; copy sign back ..
 | |
| 	PHA				; .. and save it
 | |
| 	JSR	LAB_LOG		; do LOG(n)
 | |
| 	LDA	#<garb_l		; set pointer low byte
 | |
| 	LDY	#>garb_l		; set pointer high byte
 | |
| 	JSR	LAB_25FB		; do convert AY, FCA1*(AY) (square the value)
 | |
| 	JSR	LAB_EXP		; go do EXP(n)
 | |
| 	PLA				; pull sign from stack
 | |
| 	LSR				; b0 is to be tested, shift to Cb
 | |
| 	BCC	LAB_2AF9		; if no bit then exit
 | |
| 
 | |
| 					; Perform negation
 | |
| ; do - FAC1
 | |
| 
 | |
| LAB_GTHAN
 | |
| 	LDA	FAC1_e		; get FAC1 exponent
 | |
| 	BEQ	LAB_2AF9		; exit if FAC1_e = $00
 | |
| 
 | |
| 	LDA	FAC1_s		; get FAC1 sign (b7)
 | |
| 	EOR	#$FF			; complement it
 | |
| 	STA	FAC1_s		; save FAC1 sign (b7)
 | |
| LAB_2AF9
 | |
| 	RTS
 | |
| 
 | |
| ; perform EXP()	(x^e)
 | |
| 
 | |
| LAB_EXP
 | |
| 	LDA	#<LAB_2AFA		; set 1.443 pointer low byte
 | |
| 	LDY	#>LAB_2AFA		; set 1.443 pointer high byte
 | |
| 	JSR	LAB_25FB		; do convert AY, FCA1*(AY)
 | |
| 	LDA	FAC1_r		; get FAC1 rounding byte
 | |
| 	ADC	#$50			; +$50/$100
 | |
| 	BCC	LAB_2B2B		; skip rounding if no carry
 | |
| 
 | |
| 	JSR	LAB_27C2		; round FAC1 (no check)
 | |
| LAB_2B2B
 | |
| 	STA	FAC2_r		; save FAC2 rounding byte
 | |
| 	JSR	LAB_27AE		; copy FAC1 to FAC2
 | |
| 	LDA	FAC1_e		; get FAC1 exponent
 | |
| 	CMP	#$88			; compare with EXP limit (256d)
 | |
| 	BCC	LAB_2B39		; branch if less
 | |
| 
 | |
| LAB_2B36
 | |
| 	JSR	LAB_2690		; handle overflow and underflow
 | |
| LAB_2B39
 | |
| 	JSR	LAB_INT		; perform INT
 | |
| 	LDA	Temp3			; get mantissa 3 from INT() function
 | |
| 	CLC				; clear carry for add
 | |
| 	ADC	#$81			; normalise +1
 | |
| 	BEQ	LAB_2B36		; if $00 go handle overflow
 | |
| 
 | |
| 	SEC				; set carry for subtract
 | |
| 	SBC	#$01			; now correct for exponent
 | |
| 	PHA				; save FAC2 exponent
 | |
| 
 | |
| 					; swap FAC1 and FAC2
 | |
| 	LDX	#$04			; 4 bytes to do
 | |
| LAB_2B49
 | |
| 	LDA	FAC2_e,X		; get FAC2,X
 | |
| 	LDY	FAC1_e,X		; get FAC1,X
 | |
| 	STA	FAC1_e,X		; save FAC1,X
 | |
| 	STY	FAC2_e,X		; save FAC2,X
 | |
| 	DEX				; decrement count/index
 | |
| 	BPL	LAB_2B49		; loop if not all done
 | |
| 
 | |
| 	LDA	FAC2_r		; get FAC2 rounding byte
 | |
| 	STA	FAC1_r		; save as FAC1 rounding byte
 | |
| 	JSR	LAB_SUBTRACT	; perform subtraction, FAC2 from FAC1
 | |
| 	JSR	LAB_GTHAN		; do - FAC1
 | |
| 	LDA	#<LAB_2AFE		; set counter pointer low byte
 | |
| 	LDY	#>LAB_2AFE		; set counter pointer high byte
 | |
| 	JSR	LAB_2B84		; go do series evaluation
 | |
| 	LDA	#$00			; clear A
 | |
| 	STA	FAC_sc		; clear sign compare (FAC1 EOR FAC2)
 | |
| 	PLA				;.get saved FAC2 exponent
 | |
| 	JMP	LAB_2675		; test and adjust accumulators and return
 | |
| 
 | |
| ; ^2 then series evaluation
 | |
| 
 | |
| LAB_2B6E
 | |
| 	STA	Cptrl			; save count pointer low byte
 | |
| 	STY	Cptrh			; save count pointer high byte
 | |
| 	JSR	LAB_276E		; pack FAC1 into Adatal
 | |
| 	LDA	#<Adatal		; set pointer low byte (Y already $00)
 | |
| 	JSR	LAB_25FB		; do convert AY, FCA1*(AY)
 | |
| 	JSR	LAB_2B88		; go do series evaluation
 | |
| 	LDA	#<Adatal		; pointer to original # low byte
 | |
| 	LDY	#>Adatal		; pointer to original # high byte
 | |
| 	JMP	LAB_25FB		; do convert AY, FCA1*(AY) and return
 | |
| 
 | |
| ; series evaluation
 | |
| 
 | |
| LAB_2B84
 | |
| 	STA	Cptrl			; save count pointer low byte
 | |
| 	STY	Cptrh			; save count pointer high byte
 | |
| LAB_2B88
 | |
| 	LDX	#<numexp		; set pointer low byte
 | |
| 	JSR	LAB_2770		; set pointer high byte and pack FAC1 into numexp
 | |
| 	LDA	(Cptrl),Y		; get constants count
 | |
| 	STA	numcon		; save constants count
 | |
| 	LDY	Cptrl			; get count pointer low byte
 | |
| 	INY				; increment it (now constants pointer)
 | |
| 	TYA				; copy it
 | |
| 	BNE	LAB_2B97		; skip next if no overflow
 | |
| 
 | |
| 	INC	Cptrh			; else increment high byte
 | |
| LAB_2B97
 | |
| 	STA	Cptrl			; save low byte
 | |
| 	LDY	Cptrh			; get high byte
 | |
| LAB_2B9B
 | |
| 	JSR	LAB_25FB		; do convert AY, FCA1*(AY)
 | |
| 	LDA	Cptrl			; get constants pointer low byte
 | |
| 	LDY	Cptrh			; get constants pointer high byte
 | |
| 	CLC				; clear carry for add
 | |
| 	ADC	#$04			; +4 to  low pointer (4 bytes per constant)
 | |
| 	BCC	LAB_2BA8		; skip next if no overflow
 | |
| 
 | |
| 	INY				; increment high byte
 | |
| LAB_2BA8
 | |
| 	STA	Cptrl			; save pointer low byte
 | |
| 	STY	Cptrh			; save pointer high byte
 | |
| 	JSR	LAB_246C		; add (AY) to FAC1
 | |
| 	LDA	#<numexp		; set pointer low byte to partial @ numexp
 | |
| 	LDY	#>numexp		; set pointer high byte to partial @ numexp
 | |
| 	DEC	numcon		; decrement constants count
 | |
| 	BNE	LAB_2B9B		; loop until all done
 | |
| 
 | |
| 	RTS
 | |
| 
 | |
| ; RND(n), 32 bit Galoise version. make n=0 for 19th next number in sequence or n<>0
 | |
| ; to get 19th next number in sequence after seed n. This version of the PRNG uses
 | |
| ; the Galois method and a sample of 65536 bytes produced gives the following values.
 | |
| 
 | |
| ; Entropy = 7.997442 bits per byte
 | |
| ; Optimum compression would reduce these 65536 bytes by 0 percent
 | |
| 
 | |
| ; Chi square distribution for 65536 samples is 232.01, and
 | |
| ; randomly would exceed this value 75.00 percent of the time
 | |
| 
 | |
| ; Arithmetic mean value of data bytes is 127.6724, 127.5 would be random
 | |
| ; Monte Carlo value for Pi is 3.122871269, error 0.60 percent
 | |
| ; Serial correlation coefficient is -0.000370, totally uncorrelated would be 0.0
 | |
| 
 | |
| LAB_RND
 | |
| 	LDA	FAC1_e		; get FAC1 exponent
 | |
| 	BEQ	NextPRN		; do next random # if zero
 | |
| 
 | |
| 					; else get seed into random number store
 | |
| 	LDX	#Rbyte4		; set PRNG pointer low byte
 | |
| 	LDY	#$00			; set PRNG pointer high byte
 | |
| 	JSR	LAB_2778		; pack FAC1 into (XY)
 | |
| NextPRN
 | |
| 	LDX	#$AF			; set EOR byte
 | |
| 	LDY	#$13			; do this nineteen times
 | |
| LoopPRN
 | |
| 	ASL	Rbyte1		; shift PRNG most significant byte
 | |
| 	ROL	Rbyte2		; shift PRNG middle byte
 | |
| 	ROL	Rbyte3		; shift PRNG least significant byte
 | |
| 	ROL	Rbyte4		; shift PRNG extra byte
 | |
| 	BCC	Ninc1			; branch if bit 32 clear
 | |
| 
 | |
| 	TXA				; set EOR byte
 | |
| 	EOR	Rbyte1		; EOR PRNG extra byte
 | |
| 	STA	Rbyte1		; save new PRNG extra byte
 | |
| Ninc1
 | |
| 	DEY				; decrement loop count
 | |
| 	BNE	LoopPRN		; loop if not all done
 | |
| 
 | |
| 	LDX	#$02			; three bytes to copy
 | |
| CopyPRNG
 | |
| 	LDA	Rbyte1,X		; get PRNG byte
 | |
| 	STA	FAC1_1,X		; save FAC1 byte
 | |
| 	DEX
 | |
| 	BPL	CopyPRNG		; loop if not complete
 | |
| 
 | |
| 	LDA	#$80			; set the exponent
 | |
| 	STA	FAC1_e		; save FAC1 exponent
 | |
| 
 | |
| 	ASL				; clear A
 | |
| 	STA	FAC1_s		; save FAC1 sign
 | |
| 
 | |
| 	JMP	LAB_24D5		; normalise FAC1 and return
 | |
| 
 | |
| ; perform COS()
 | |
| 
 | |
| LAB_COS
 | |
| 	LDA	#<LAB_2C78		; set (pi/2) pointer low byte
 | |
| 	LDY	#>LAB_2C78		; set (pi/2) pointer high byte
 | |
| 	JSR	LAB_246C		; add (AY) to FAC1
 | |
| 
 | |
| ; perform SIN()
 | |
| 
 | |
| LAB_SIN
 | |
| 	JSR	LAB_27AB		; round and copy FAC1 to FAC2
 | |
| 	LDA	#<LAB_2C7C		; set (2*pi) pointer low byte
 | |
| 	LDY	#>LAB_2C7C		; set (2*pi) pointer high byte
 | |
| 	LDX	FAC2_s		; get FAC2 sign (b7)
 | |
| 	JSR	LAB_26C2		; divide by (AY) (X=sign)
 | |
| 	JSR	LAB_27AB		; round and copy FAC1 to FAC2
 | |
| 	JSR	LAB_INT		; perform INT
 | |
| 	LDA	#$00			; clear byte
 | |
| 	STA	FAC_sc		; clear sign compare (FAC1 EOR FAC2)
 | |
| 	JSR	LAB_SUBTRACT	; perform subtraction, FAC2 from FAC1
 | |
| 	LDA	#<LAB_2C80		; set 0.25 pointer low byte
 | |
| 	LDY	#>LAB_2C80		; set 0.25 pointer high byte
 | |
| 	JSR	LAB_2455		; perform subtraction, (AY) from FAC1
 | |
| 	LDA	FAC1_s		; get FAC1 sign (b7)
 | |
| 	PHA				; save FAC1 sign
 | |
| 	BPL	LAB_2C35		; branch if +ve
 | |
| 
 | |
| 					; FAC1 sign was -ve
 | |
| 	JSR	LAB_244E		; add 0.5 to FAC1
 | |
| 	LDA	FAC1_s		; get FAC1 sign (b7)
 | |
| 	BMI	LAB_2C38		; branch if -ve
 | |
| 
 | |
| 	LDA	Cflag			; get comparison evaluation flag
 | |
| 	EOR	#$FF			; toggle flag
 | |
| 	STA	Cflag			; save comparison evaluation flag
 | |
| LAB_2C35
 | |
| 	JSR	LAB_GTHAN		; do - FAC1
 | |
| LAB_2C38
 | |
| 	LDA	#<LAB_2C80		; set 0.25 pointer low byte
 | |
| 	LDY	#>LAB_2C80		; set 0.25 pointer high byte
 | |
| 	JSR	LAB_246C		; add (AY) to FAC1
 | |
| 	PLA				; restore FAC1 sign
 | |
| 	BPL	LAB_2C45		; branch if was +ve
 | |
| 
 | |
| 					; else correct FAC1
 | |
| 	JSR	LAB_GTHAN		; do - FAC1
 | |
| LAB_2C45
 | |
| 	LDA	#<LAB_2C84		; set pointer low byte to counter
 | |
| 	LDY	#>LAB_2C84		; set pointer high byte to counter
 | |
| 	JMP	LAB_2B6E		; ^2 then series evaluation and return
 | |
| 
 | |
| ; perform TAN()
 | |
| 
 | |
| LAB_TAN
 | |
| 	JSR	LAB_276E		; pack FAC1 into Adatal
 | |
| 	LDA	#$00			; clear byte
 | |
| 	STA	Cflag			; clear comparison evaluation flag
 | |
| 	JSR	LAB_SIN		; go do SIN(n)
 | |
| 	LDX	#<func_l		; set sin(n) pointer low byte
 | |
| 	LDY	#>func_l		; set sin(n) pointer high byte
 | |
| 	JSR	LAB_2778		; pack FAC1 into (XY)
 | |
| 	LDA	#<Adatal		; set n pointer low addr
 | |
| 	LDY	#>Adatal		; set n pointer high addr
 | |
| 	JSR	LAB_UFAC		; unpack memory (AY) into FAC1
 | |
| 	LDA	#$00			; clear byte
 | |
| 	STA	FAC1_s		; clear FAC1 sign (b7)
 | |
| 	LDA	Cflag			; get comparison evaluation flag
 | |
| 	JSR	LAB_2C74		; save flag and go do series evaluation
 | |
| 
 | |
| 	LDA	#<func_l		; set sin(n) pointer low byte
 | |
| 	LDY	#>func_l		; set sin(n) pointer high byte
 | |
| 	JMP	LAB_26CA		; convert AY and do (AY)/FAC1
 | |
| 
 | |
| LAB_2C74
 | |
| 	PHA				; save comparison evaluation flag
 | |
| 	JMP	LAB_2C35		; go do series evaluation
 | |
| 
 | |
| ; perform USR()
 | |
| 
 | |
| LAB_USR
 | |
| 	JSR	Usrjmp		; call user code
 | |
| 	JMP	LAB_1BFB		; scan for ")", else do syntax error then warm start
 | |
| 
 | |
| ; perform ATN()
 | |
| 
 | |
| LAB_ATN
 | |
| 	LDA	FAC1_s		; get FAC1 sign (b7)
 | |
| 	PHA				; save sign
 | |
| 	BPL	LAB_2CA1		; branch if +ve
 | |
| 
 | |
| 	JSR	LAB_GTHAN		; else do - FAC1
 | |
| LAB_2CA1
 | |
| 	LDA	FAC1_e		; get FAC1 exponent
 | |
| 	PHA				; push exponent
 | |
| 	CMP	#$81			; compare with 1
 | |
| 	BCC	LAB_2CAF		; branch if FAC1<1
 | |
| 
 | |
| 	LDA	#<LAB_259C		; set 1 pointer low byte
 | |
| 	LDY	#>LAB_259C		; set 1 pointer high byte
 | |
| 	JSR	LAB_26CA		; convert AY and do (AY)/FAC1
 | |
| LAB_2CAF
 | |
| 	LDA	#<LAB_2CC9		; set pointer low byte to counter
 | |
| 	LDY	#>LAB_2CC9		; set pointer high byte to counter
 | |
| 	JSR	LAB_2B6E		; ^2 then series evaluation
 | |
| 	PLA				; restore old FAC1 exponent
 | |
| 	CMP	#$81			; compare with 1
 | |
| 	BCC	LAB_2CC2		; branch if FAC1<1
 | |
| 
 | |
| 	LDA	#<LAB_2C78		; set (pi/2) pointer low byte
 | |
| 	LDY	#>LAB_2C78		; set (pi/2) pointer high byte
 | |
| 	JSR	LAB_2455		; perform subtraction, (AY) from FAC1
 | |
| LAB_2CC2
 | |
| 	PLA				; restore FAC1 sign
 | |
| 	BPL	LAB_2D04		; exit if was +ve
 | |
| 
 | |
| 	JMP	LAB_GTHAN		; else do - FAC1 and return
 | |
| 
 | |
| ; perform BITSET
 | |
| 
 | |
| LAB_BITSET
 | |
| 	JSR	LAB_GADB		; get two parameters for POKE or WAIT
 | |
| 	CPX	#$08			; only 0 to 7 are allowed
 | |
| 	BCS	FCError		; branch if > 7
 | |
| 
 | |
| 	LDA	#$00			; clear A
 | |
| 	SEC				; set the carry
 | |
| S_Bits
 | |
| 	ROL				; shift bit
 | |
| 	DEX				; decrement bit number
 | |
| 	BPL	S_Bits		; loop if still +ve
 | |
| 
 | |
| 	INX				; make X = $00
 | |
| 	ORA	(Itempl,X)		; or with byte via temporary integer (addr)
 | |
| 	STA	(Itempl,X)		; save byte via temporary integer (addr)
 | |
| LAB_2D04
 | |
| 	RTS
 | |
| 
 | |
| ; perform BITCLR
 | |
| 
 | |
| LAB_BITCLR
 | |
| 	JSR	LAB_GADB		; get two parameters for POKE or WAIT
 | |
| 	CPX	#$08			; only 0 to 7 are allowed
 | |
| 	BCS	FCError		; branch if > 7
 | |
| 
 | |
| 	LDA	#$FF			; set A
 | |
| S_Bitc
 | |
| 	ROL				; shift bit
 | |
| 	DEX				; decrement bit number
 | |
| 	BPL	S_Bitc		; loop if still +ve
 | |
| 
 | |
| 	INX				; make X = $00
 | |
| 	AND	(Itempl,X)		; and with byte via temporary integer (addr)
 | |
| 	STA	(Itempl,X)		; save byte via temporary integer (addr)
 | |
| 	RTS
 | |
| 
 | |
| FCError
 | |
| 	JMP	LAB_FCER		; do function call error then warm start
 | |
| 
 | |
| ; perform BITTST()
 | |
| 
 | |
| LAB_BTST
 | |
| 	JSR	LAB_IGBY		; increment BASIC pointer
 | |
| 	JSR	LAB_GADB		; get two parameters for POKE or WAIT
 | |
| 	CPX	#$08			; only 0 to 7 are allowed
 | |
| 	BCS	FCError		; branch if > 7
 | |
| 
 | |
| 	JSR	LAB_GBYT		; get next BASIC byte
 | |
| 	CMP	#')'			; is next character ")"
 | |
| 	BEQ	TST_OK		; if ")" go do rest of function
 | |
| 
 | |
| 	JMP	LAB_SNER		; do syntax error then warm start
 | |
| 
 | |
| TST_OK
 | |
| 	JSR	LAB_IGBY		; update BASIC execute pointer (to character past ")")
 | |
| 	LDA	#$00			; clear A
 | |
| 	SEC				; set the carry
 | |
| T_Bits
 | |
| 	ROL				; shift bit
 | |
| 	DEX				; decrement bit number
 | |
| 	BPL	T_Bits		; loop if still +ve
 | |
| 
 | |
| 	INX				; make X = $00
 | |
| 	AND	(Itempl,X)		; AND with byte via temporary integer (addr)
 | |
| 	BEQ	LAB_NOTT		; branch if zero (already correct)
 | |
| 
 | |
| 	LDA	#$FF			; set for -1 result
 | |
| LAB_NOTT
 | |
| 	JMP	LAB_27DB		; go do SGN tail
 | |
| 
 | |
| ; perform BIN$()
 | |
| 
 | |
| LAB_BINS
 | |
| 	CPX	#$19			; max + 1
 | |
| 	BCS	BinFErr		; exit if too big ( > or = )
 | |
| 
 | |
| 	STX	TempB			; save # of characters ($00 = leading zero remove)
 | |
| 	LDA	#$18			; need A byte long space
 | |
| 	JSR	LAB_MSSP		; make string space A bytes long
 | |
| 	LDY	#$17			; set index
 | |
| 	LDX	#$18			; character count
 | |
| NextB1
 | |
| 	LSR	nums_1		; shift highest byte
 | |
| 	ROR	nums_2		; shift middle byte
 | |
| 	ROR	nums_3		; shift lowest byte bit 0 to carry
 | |
| 	TXA				; load with "0"/2
 | |
| 	ROL				; shift in carry
 | |
| 	STA	(str_pl),Y		; save to temp string + index
 | |
| 	DEY				; decrement index
 | |
| 	BPL	NextB1		; loop if not done
 | |
| 
 | |
| 	LDA	TempB			; get # of characters
 | |
| 	BEQ	EndBHS		; branch if truncate
 | |
| 
 | |
| 	TAX				; copy length to X
 | |
| 	SEC				; set carry for add !
 | |
| 	EOR	#$FF			; 1's complement
 | |
| 	ADC	#$18			; add 24d
 | |
| 	BEQ	GoPr2			; if zero print whole string
 | |
| 
 | |
| 	BNE	GoPr1			; else go make output string
 | |
| 	
 | |
| ; this is the exit code and is also used by HEX$()
 | |
| ; truncate string to remove leading "0"s
 | |
| 
 | |
| EndBHS
 | |
| 	TAY				; clear index (A=0, X=length here)
 | |
| NextB2
 | |
| 	LDA	(str_pl),Y		; get character from string
 | |
| 	CMP	#'0'			; compare with "0"
 | |
| 	BNE	GoPr			; if not "0" then go print string from here
 | |
| 
 | |
| 	DEX				; decrement character count
 | |
| 	BEQ	GoPr3			; if zero then end of string so go print it
 | |
| 
 | |
| 	INY				; else increment index
 | |
| 	BPL	NextB2		; loop always
 | |
| 
 | |
| ; make fixed length output string - ignore overflows!
 | |
| 
 | |
| GoPr3
 | |
| 	INX				; need at least 1 character
 | |
| GoPr
 | |
| 	TYA				; copy result
 | |
| GoPr1
 | |
| 	CLC				; clear carry for add
 | |
| 	ADC	str_pl		; add low address
 | |
| 	STA	str_pl		; save low address
 | |
| 	LDA	#$00			; do high byte
 | |
| 	ADC	str_ph		; add high address
 | |
| 	STA	str_ph		; save high address
 | |
| GoPr2
 | |
| 	STX	str_ln		; X holds string length
 | |
| 	JSR	LAB_IGBY		; update BASIC execute pointer (to character past ")")
 | |
| 	JMP	LAB_RTST		; check for space on descriptor stack then put address
 | |
| 					; and length on descriptor stack and update stack pointers
 | |
| 
 | |
| BinFErr
 | |
| 	JMP	LAB_FCER		; do function call error then warm start
 | |
| 
 | |
| ; perform HEX$()
 | |
| 
 | |
| LAB_HEXS
 | |
| 	CPX	#$07			; max + 1
 | |
| 	BCS	BinFErr		; exit if too big ( > or = )
 | |
| 
 | |
| 	STX	TempB			; save # of characters
 | |
| 
 | |
| 	LDA	#$06			; need 6 bytes for string
 | |
| 	JSR	LAB_MSSP		; make string space A bytes long
 | |
| 	LDY	#$05			; set string index
 | |
| 
 | |
| 	SED				; need decimal mode for nibble convert
 | |
| 	LDA	nums_3		; get lowest byte
 | |
| 	JSR	LAB_A2HX		; convert A to ASCII hex byte and output
 | |
| 	LDA	nums_2		; get middle byte
 | |
| 	JSR	LAB_A2HX		; convert A to ASCII hex byte and output
 | |
| 	LDA	nums_1		; get highest byte
 | |
| 	JSR	LAB_A2HX		; convert A to ASCII hex byte and output
 | |
| 	CLD				; back to binary
 | |
| 
 | |
| 	LDX	#$06			; character count
 | |
| 	LDA	TempB			; get # of characters
 | |
| 	BEQ	EndBHS		; branch if truncate
 | |
| 
 | |
| 	TAX				; copy length to X
 | |
| 	SEC				; set carry for add !
 | |
| 	EOR	#$FF			; 1's complement
 | |
| 	ADC	#$06			; add 6d
 | |
| 	BEQ	GoPr2			; if zero print whole string
 | |
| 
 | |
| 	BNE	GoPr1			; else go make output string (branch always)
 | |
| 
 | |
| ; convert A to ASCII hex byte and output .. note set decimal mode before calling
 | |
| 
 | |
| LAB_A2HX
 | |
| 	TAX				; save byte
 | |
| 	AND	#$0F			; mask off top bits
 | |
| 	JSR	LAB_AL2X		; convert low nibble to ASCII and output
 | |
| 	TXA				; get byte back
 | |
| 	LSR				; /2	shift high nibble to low nibble
 | |
| 	LSR				; /4
 | |
| 	LSR				; /8
 | |
| 	LSR				; /16
 | |
| LAB_AL2X
 | |
| 	CMP	#$0A			; set carry for +1 if >9
 | |
| 	ADC	#'0'			; add ASCII "0"
 | |
| 	STA	(str_pl),Y		; save to temp string
 | |
| 	DEY				; decrement counter
 | |
| 	RTS
 | |
| 
 | |
| LAB_NLTO
 | |
| 	STA	FAC1_e		; save FAC1 exponent
 | |
| 	LDA	#$00			; clear sign compare
 | |
| LAB_MLTE
 | |
| 	STA	FAC_sc		; save sign compare (FAC1 EOR FAC2)
 | |
| 	TXA				; restore character
 | |
| 	JSR	LAB_2912		; evaluate new ASCII digit
 | |
| 
 | |
| ; gets here if the first character was "$" for hex
 | |
| ; get hex number
 | |
| 
 | |
| LAB_CHEX
 | |
| 	JSR	LAB_IGBY		; increment and scan memory
 | |
| 	BCC	LAB_ISHN		; branch if numeric character
 | |
| 
 | |
| 	ORA	#$20			; case convert, allow "A" to "F" and "a" to "f"
 | |
| 	SBC	#'a'			; subtract "a" (carry set here)
 | |
| 	CMP	#$06			; compare normalised with $06 (max+1)
 | |
| 	BCS	LAB_EXCH		; exit if >"f" or <"0"
 | |
| 
 | |
| 	ADC	#$0A			; convert to nibble
 | |
| LAB_ISHN
 | |
| 	AND	#$0F			; convert to binary
 | |
| 	TAX				; save nibble
 | |
| 	LDA	FAC1_e		; get FAC1 exponent
 | |
| 	BEQ	LAB_MLTE		; skip multiply if zero
 | |
| 
 | |
| 	ADC	#$04			; add four to exponent (*16 - carry clear here)
 | |
| 	BCC	LAB_NLTO		; if no overflow do evaluate digit
 | |
| 
 | |
| LAB_MLTO
 | |
| 	JMP	LAB_2564		; do overflow error and warm start
 | |
| 
 | |
| LAB_NXCH
 | |
| 	TAX				; save bit
 | |
| 	LDA	FAC1_e		; get FAC1 exponent
 | |
| 	BEQ	LAB_MLBT		; skip multiply if zero
 | |
| 
 | |
| 	INC	FAC1_e		; increment FAC1 exponent (*2)
 | |
| 	BEQ	LAB_MLTO		; do overflow error if = $00
 | |
| 
 | |
| 	LDA	#$00			; clear sign compare
 | |
| LAB_MLBT
 | |
| 	STA	FAC_sc		; save sign compare (FAC1 EOR FAC2)
 | |
| 	TXA				; restore bit
 | |
| 	JSR	LAB_2912		; evaluate new ASCII digit
 | |
| 
 | |
| ; gets here if the first character was  "%" for binary
 | |
| ; get binary number
 | |
| 
 | |
| LAB_CBIN
 | |
| 	JSR	LAB_IGBY		; increment and scan memory
 | |
| 	EOR	#'0'			; convert "0" to 0 etc.
 | |
| 	CMP	#$02			; compare with max+1
 | |
| 	BCC	LAB_NXCH		; branch exit if < 2
 | |
| 
 | |
| LAB_EXCH
 | |
| 	JMP	LAB_28F6		; evaluate -ve flag and return
 | |
| 
 | |
| ; ctrl-c check routine. includes limited "life" byte save for INGET routine
 | |
| ; now also the code that checks to see if an interrupt has occurred
 | |
| 
 | |
| CTRLC
 | |
| 	LDA	ccflag		; get [CTRL-C] check flag
 | |
| 	BNE	LAB_FBA2		; exit if inhibited
 | |
| 
 | |
| 	JSR	V_INPT		; scan input device
 | |
| 	BCC	LAB_FBA0		; exit if buffer empty
 | |
| 
 | |
| 	STA	ccbyte		; save received byte
 | |
| 	LDX	#$20			; "life" timer for bytes
 | |
| 	STX	ccnull		; set countdown
 | |
| 	JMP	LAB_1636		; return to BASIC
 | |
| 
 | |
| LAB_FBA0
 | |
| 	LDX	ccnull		; get countdown byte
 | |
| 	BEQ	LAB_FBA2		; exit if finished
 | |
| 
 | |
| 	DEC	ccnull		; else decrement countdown
 | |
| LAB_FBA2
 | |
| 	LDX	#NmiBase		; set pointer to NMI values
 | |
| 	JSR	LAB_CKIN		; go check interrupt
 | |
| 	LDX	#IrqBase		; set pointer to IRQ values
 | |
| 	JSR	LAB_CKIN		; go check interrupt
 | |
| LAB_CRTS
 | |
| 	RTS
 | |
| 
 | |
| ; check whichever interrupt is indexed by X
 | |
| 
 | |
| LAB_CKIN
 | |
| 	LDA	PLUS_0,X		; get interrupt flag byte
 | |
| 	BPL	LAB_CRTS		; branch if interrupt not enabled
 | |
| 
 | |
| ; we disable the interrupt here and make two new commands RETIRQ and RETNMI to
 | |
| ; automatically enable the interrupt when we exit
 | |
| 
 | |
| 	ASL				; move happened bit to setup bit
 | |
| 	AND	#$40			; mask happened bits
 | |
| 	BEQ	LAB_CRTS		; if no interrupt then exit
 | |
| 
 | |
| 	STA	PLUS_0,X		; save interrupt flag byte
 | |
| 
 | |
| 	TXA				; copy index ..
 | |
| 	TAY				; .. to Y
 | |
| 
 | |
| 	PLA				; dump return address low byte, call from CTRL-C
 | |
| 	PLA				; dump return address high byte
 | |
| 
 | |
| 	LDA	#$05			; need 5 bytes for GOSUB
 | |
| 	JSR	LAB_1212		; check room on stack for A bytes
 | |
| 	LDA	Bpntrh		; get BASIC execute pointer high byte
 | |
| 	PHA				; push on stack
 | |
| 	LDA	Bpntrl		; get BASIC execute pointer low byte
 | |
| 	PHA				; push on stack
 | |
| 	LDA	Clineh		; get current line high byte
 | |
| 	PHA				; push on stack
 | |
| 	LDA	Clinel		; get current line low byte
 | |
| 	PHA				; push on stack
 | |
| 	LDA	#TK_GOSUB		; token for GOSUB
 | |
| 	PHA				; push on stack
 | |
| 
 | |
| 	LDA	PLUS_1,Y		; get interrupt code pointer low byte
 | |
| 	STA	Bpntrl		; save as BASIC execute pointer low byte
 | |
| 	LDA	PLUS_2,Y		; get interrupt code pointer high byte
 | |
| 	STA	Bpntrh		; save as BASIC execute pointer high byte
 | |
| 
 | |
| 	JMP	LAB_15C2		; go do interpreter inner loop
 | |
| 					; can't RTS, we used the stack! the RTS from the ctrl-c
 | |
| 					; check will be taken when the RETIRQ/RETNMI/RETURN is
 | |
| 					; executed at the end of the subroutine
 | |
| 
 | |
| ; get byte from input device, no waiting
 | |
| ; returns with carry set if byte in A
 | |
| 
 | |
| INGET
 | |
| 	JSR	V_INPT		; call scan input device
 | |
| 	BCS	LAB_FB95		; if byte go reset timer
 | |
| 
 | |
| 	LDA	ccnull		; get countdown
 | |
| 	BEQ	LAB_FB96		; exit if empty
 | |
| 
 | |
| 	LDA	ccbyte		; get last received byte
 | |
| 	SEC				; flag we got a byte
 | |
| LAB_FB95
 | |
| 	LDX	#$00			; clear X
 | |
| 	STX	ccnull		; clear timer because we got a byte
 | |
| LAB_FB96
 | |
| 	RTS
 | |
| 
 | |
| ; these routines only enable the interrupts if the set-up flag is set
 | |
| ; if not they have no effect
 | |
| 
 | |
| ; perform IRQ {ON|OFF|CLEAR}
 | |
| 
 | |
| LAB_IRQ
 | |
| 	LDX	#IrqBase		; set pointer to IRQ values
 | |
| 	.byte	$2C			; make next line BIT abs.
 | |
| 
 | |
| ; perform NMI {ON|OFF|CLEAR}
 | |
| 
 | |
| LAB_NMI
 | |
| 	LDX	#NmiBase		; set pointer to NMI values
 | |
| 	CMP	#TK_ON		; compare with token for ON
 | |
| 	BEQ	LAB_INON		; go turn on interrupt
 | |
| 
 | |
| 	CMP	#TK_OFF		; compare with token for OFF
 | |
| 	BEQ	LAB_IOFF		; go turn off interrupt
 | |
| 
 | |
| 	EOR	#TK_CLEAR		; compare with token for CLEAR, A = $00 if = TK_CLEAR
 | |
| 	BEQ	LAB_INEX		; go clear interrupt flags and return
 | |
| 
 | |
| 	JMP	LAB_SNER		; do syntax error then warm start
 | |
| 
 | |
| LAB_IOFF
 | |
| 	LDA	#$7F			; clear A
 | |
| 	AND	PLUS_0,X		; AND with interrupt setup flag
 | |
| 	BPL	LAB_INEX		; go clear interrupt enabled flag and return
 | |
| 
 | |
| LAB_INON
 | |
| 	LDA	PLUS_0,X		; get interrupt setup flag
 | |
| 	ASL				; Shift bit to enabled flag
 | |
| 	ORA	PLUS_0,X		; OR with flag byte
 | |
| LAB_INEX
 | |
| 	STA	PLUS_0,X		; save interrupt flag byte
 | |
| 	JMP	LAB_IGBY		; update BASIC execute pointer and return
 | |
| 
 | |
| ; these routines set up the pointers and flags for the interrupt routines
 | |
| ; note that the interrupts are also enabled by these commands
 | |
| 
 | |
| ; perform ON IRQ
 | |
| 
 | |
| LAB_SIRQ
 | |
| 	CLI				; enable interrupts
 | |
| 	LDX	#IrqBase		; set pointer to IRQ values
 | |
| 	.byte	$2C			; make next line BIT abs.
 | |
| 
 | |
| ; perform ON NMI
 | |
| 
 | |
| LAB_SNMI
 | |
| 	LDX	#NmiBase		; set pointer to NMI values
 | |
| 
 | |
| 	STX	TempB			; save interrupt pointer
 | |
| 	JSR	LAB_IGBY		; increment and scan memory (past token)
 | |
| 	JSR	LAB_GFPN		; get fixed-point number into temp integer
 | |
| 	LDA	Smeml			; get start of mem low byte
 | |
| 	LDX	Smemh			; get start of mem high byte
 | |
| 	JSR	LAB_SHLN		; search Basic for temp integer line number from AX
 | |
| 	BCS	LAB_LFND		; if carry set go set-up interrupt
 | |
| 
 | |
| 	JMP	LAB_16F7		; else go do "Undefined statement" error and warm start
 | |
| 
 | |
| LAB_LFND
 | |
| 	LDX	TempB			; get interrupt pointer
 | |
| 	LDA	Baslnl		; get pointer low byte
 | |
| 	SBC	#$01			; -1 (carry already set for subtract)
 | |
| 	STA	PLUS_1,X		; save as interrupt pointer low byte
 | |
| 	LDA	Baslnh		; get pointer high byte
 | |
| 	SBC	#$00			; subtract carry
 | |
| 	STA	PLUS_2,X		; save as interrupt pointer high byte
 | |
| 
 | |
| 	LDA	#$C0			; set interrupt enabled/setup bits
 | |
| 	STA	PLUS_0,X		; set interrupt flags
 | |
| LAB_IRTS
 | |
| 	RTS
 | |
| 
 | |
| ; return from IRQ service, restores the enabled flag.
 | |
| 
 | |
| ; perform RETIRQ
 | |
| 
 | |
| LAB_RETIRQ
 | |
| 	BNE	LAB_IRTS		; exit if following token (to allow syntax error)
 | |
| 
 | |
| 	LDA	IrqBase		; get interrupt flags
 | |
| 	ASL				; copy setup to enabled (b7)
 | |
| 	ORA	IrqBase		; OR in setup flag
 | |
| 	STA	IrqBase		; save enabled flag
 | |
| 	JMP	LAB_16E8		; go do rest of RETURN
 | |
| 
 | |
| ; return from NMI service, restores the enabled flag.
 | |
| 
 | |
| ; perform RETNMI
 | |
| 
 | |
| LAB_RETNMI
 | |
| 	BNE	LAB_IRTS		; exit if following token (to allow syntax error)
 | |
| 
 | |
| 	LDA	NmiBase		; get set-up flag
 | |
| 	ASL				; copy setup to enabled (b7)
 | |
| 	ORA	NmiBase		; OR in setup flag
 | |
| 	STA	NmiBase		; save enabled flag
 | |
| 	JMP	LAB_16E8		; go do rest of RETURN
 | |
| 
 | |
| ; MAX() MIN() pre process
 | |
| 
 | |
| LAB_MMPP
 | |
| 	JSR	LAB_EVEZ		; process expression
 | |
| 	JMP	LAB_CTNM		; check if source is numeric, else do type mismatch
 | |
| 
 | |
| ; perform MAX()
 | |
| 
 | |
| LAB_MAX
 | |
| 	JSR	LAB_PHFA		; push FAC1, evaluate expression,
 | |
| 					; pull FAC2 and compare with FAC1
 | |
| 	BPL	LAB_MAX		; branch if no swap to do
 | |
| 
 | |
| 	LDA	FAC2_1		; get FAC2 mantissa1
 | |
| 	ORA	#$80			; set top bit (clear sign from compare)
 | |
| 	STA	FAC2_1		; save FAC2 mantissa1
 | |
| 	JSR	LAB_279B		; copy FAC2 to FAC1
 | |
| 	BEQ	LAB_MAX		; go do next (branch always)
 | |
| 
 | |
| ; perform MIN()
 | |
| 
 | |
| LAB_MIN
 | |
| 	JSR	LAB_PHFA		; push FAC1, evaluate expression,
 | |
| 					; pull FAC2 and compare with FAC1
 | |
| 	BMI	LAB_MIN		; branch if no swap to do
 | |
| 
 | |
| 	BEQ	LAB_MIN		; branch if no swap to do
 | |
| 
 | |
| 	LDA	FAC2_1		; get FAC2 mantissa1
 | |
| 	ORA	#$80			; set top bit (clear sign from compare)
 | |
| 	STA	FAC2_1		; save FAC2 mantissa1
 | |
| 	JSR	LAB_279B		; copy FAC2 to FAC1
 | |
| 	BEQ	LAB_MIN		; go do next (branch always)
 | |
| 
 | |
| ; exit routine. don't bother returning to the loop code
 | |
| ; check for correct exit, else so syntax error
 | |
| 
 | |
| LAB_MMEC
 | |
| 	CMP	#')'			; is it end of function?
 | |
| 	BNE	LAB_MMSE		; if not do MAX MIN syntax error
 | |
| 
 | |
| 	PLA				; dump return address low byte
 | |
| 	PLA				; dump return address high byte
 | |
| 	JMP	LAB_IGBY		; update BASIC execute pointer (to chr past ")")
 | |
| 
 | |
| LAB_MMSE
 | |
| 	JMP	LAB_SNER		; do syntax error then warm start
 | |
| 
 | |
| ; check for next, evaluate and return or exit
 | |
| ; this is the routine that does most of the work
 | |
| 
 | |
| LAB_PHFA
 | |
| 	JSR	LAB_GBYT		; get next BASIC byte
 | |
| 	CMP	#','			; is there more ?
 | |
| 	BNE	LAB_MMEC		; if not go do end check
 | |
| 
 | |
| 					; push FAC1
 | |
| 	JSR	LAB_27BA		; round FAC1
 | |
| 	LDA	FAC1_s		; get FAC1 sign
 | |
| 	ORA	#$7F			; set all non sign bits
 | |
| 	AND	FAC1_1		; AND FAC1 mantissa1 (AND in sign bit)
 | |
| 	PHA				; push on stack
 | |
| 	LDA	FAC1_2		; get FAC1 mantissa2
 | |
| 	PHA				; push on stack
 | |
| 	LDA	FAC1_3		; get FAC1 mantissa3
 | |
| 	PHA				; push on stack
 | |
| 	LDA	FAC1_e		; get FAC1 exponent
 | |
| 	PHA				; push on stack
 | |
| 
 | |
| 	JSR	LAB_IGBY		; scan and get next BASIC byte (after ",")
 | |
| 	JSR	LAB_EVNM		; evaluate expression and check is numeric,
 | |
| 					; else do type mismatch
 | |
| 
 | |
| 					; pop FAC2 (MAX/MIN expression so far)
 | |
| 	PLA				; pop exponent
 | |
| 	STA	FAC2_e		; save FAC2 exponent
 | |
| 	PLA				; pop mantissa3
 | |
| 	STA	FAC2_3		; save FAC2 mantissa3
 | |
| 	PLA				; pop mantissa1
 | |
| 	STA	FAC2_2		; save FAC2 mantissa2
 | |
| 	PLA				; pop sign/mantissa1
 | |
| 	STA	FAC2_1		; save FAC2 sign/mantissa1
 | |
| 	STA	FAC2_s		; save FAC2 sign
 | |
| 
 | |
| 					; compare FAC1 with (packed) FAC2
 | |
| 	LDA	#<FAC2_e		; set pointer low byte to FAC2
 | |
| 	LDY	#>FAC2_e		; set pointer high byte to FAC2
 | |
| 	JMP	LAB_27F8		; compare FAC1 with FAC2 (AY) and return
 | |
| 					; returns A=$00 if FAC1 = (AY)
 | |
| 					; returns A=$01 if FAC1 > (AY)
 | |
| 					; returns A=$FF if FAC1 < (AY)
 | |
| 
 | |
| ; perform WIDTH
 | |
| 
 | |
| LAB_WDTH
 | |
| 	CMP	#','			; is next byte ","
 | |
| 	BEQ	LAB_TBSZ		; if so do tab size
 | |
| 
 | |
| 	JSR	LAB_GTBY		; get byte parameter
 | |
| 	TXA				; copy width to A
 | |
| 	BEQ	LAB_NSTT		; branch if set for infinite line
 | |
| 
 | |
| 	CPX	#$10			; else make min width = 16d
 | |
| 	BCC	TabErr		; if less do function call error and exit
 | |
| 
 | |
| ; this next compare ensures that we can't exit WIDTH via an error leaving the
 | |
| ; tab size greater than the line length.
 | |
| 
 | |
| 	CPX	TabSiz		; compare with tab size
 | |
| 	BCS	LAB_NSTT		; branch if >= tab size
 | |
| 
 | |
| 	STX	TabSiz		; else make tab size = terminal width
 | |
| LAB_NSTT
 | |
| 	STX	TWidth		; set the terminal width
 | |
| 	JSR	LAB_GBYT		; get BASIC byte back
 | |
| 	BEQ	WExit			; exit if no following
 | |
| 
 | |
| 	CMP	#','			; else is it ","
 | |
| 	BNE	LAB_MMSE		; if not do syntax error
 | |
| 
 | |
| LAB_TBSZ
 | |
| 	JSR	LAB_SGBY		; scan and get byte parameter
 | |
| 	TXA				; copy TAB size
 | |
| 	BMI	TabErr		; if >127 do function call error and exit
 | |
| 
 | |
| 	CPX	#$01			; compare with min-1
 | |
| 	BCC	TabErr		; if <=1 do function call error and exit
 | |
| 
 | |
| 	LDA	TWidth		; set flags for width
 | |
| 	BEQ	LAB_SVTB		; skip check if infinite line
 | |
| 
 | |
| 	CPX	TWidth		; compare TAB with width
 | |
| 	BEQ	LAB_SVTB		; ok if =
 | |
| 
 | |
| 	BCS	TabErr		; branch if too big
 | |
| 
 | |
| LAB_SVTB
 | |
| 	STX	TabSiz		; save TAB size
 | |
| 
 | |
| ; calculate tab column limit from TAB size. The Iclim is set to the last tab
 | |
| ; position on a line that still has at least one whole tab width between it
 | |
| ; and the end of the line.
 | |
| 
 | |
| WExit
 | |
| 	LDA	TWidth		; get width
 | |
| 	BEQ	LAB_SULP		; branch if infinite line
 | |
| 
 | |
| 	CMP	TabSiz		; compare with tab size
 | |
| 	BCS	LAB_WDLP		; branch if >= tab size
 | |
| 
 | |
| 	STA	TabSiz		; else make tab size = terminal width
 | |
| LAB_SULP
 | |
| 	SEC				; set carry for subtract
 | |
| LAB_WDLP
 | |
| 	SBC	TabSiz		; subtract tab size
 | |
| 	BCS	LAB_WDLP		; loop while no borrow
 | |
| 
 | |
| 	ADC	TabSiz		; add tab size back
 | |
| 	CLC				; clear carry for add
 | |
| 	ADC	TabSiz		; add tab size back again
 | |
| 	STA	Iclim			; save for now
 | |
| 	LDA	TWidth		; get width back
 | |
| 	SEC				; set carry for subtract
 | |
| 	SBC	Iclim			; subtract remainder
 | |
| 	STA	Iclim			; save tab column limit
 | |
| LAB_NOSQ
 | |
| 	RTS
 | |
| 
 | |
| TabErr
 | |
| 	JMP	LAB_FCER		; do function call error then warm start
 | |
| 
 | |
| ; perform SQR()
 | |
| 
 | |
| LAB_SQR
 | |
| 	LDA	FAC1_s		; get FAC1 sign
 | |
| 	BMI	TabErr		; if -ve do function call error
 | |
| 
 | |
| 	LDA	FAC1_e		; get exponent
 | |
| 	BEQ	LAB_NOSQ		; if zero just return
 | |
| 
 | |
| 					; else do root
 | |
| 	JSR	LAB_27AB		; round and copy FAC1 to FAC2
 | |
| 	LDA	#$00			; clear A
 | |
| 
 | |
| 	STA	FACt_3		; clear remainder
 | |
| 	STA	FACt_2		; ..
 | |
| 	STA	FACt_1		; ..
 | |
| 	STA	TempB			; ..
 | |
| 
 | |
| 	STA	FAC1_3		; clear root
 | |
| 	STA	FAC1_2		; ..
 | |
| 	STA	FAC1_1		; ..
 | |
| 
 | |
| 	LDX	#$18			; 24 pairs of bits to do
 | |
| 	LDA	FAC2_e		; get exponent
 | |
| 	LSR				; check odd/even
 | |
| 	BCS	LAB_SQE2		; if odd only 1 shift first time
 | |
| 
 | |
| LAB_SQE1
 | |
| 	ASL	FAC2_3		; shift highest bit of number ..
 | |
| 	ROL	FAC2_2		; ..
 | |
| 	ROL	FAC2_1		; ..
 | |
| 	ROL	FACt_3		; .. into remainder
 | |
| 	ROL	FACt_2		; ..
 | |
| 	ROL	FACt_1		; ..
 | |
| 	ROL	TempB			; .. never overflows
 | |
| LAB_SQE2
 | |
| 	ASL	FAC2_3		; shift highest bit of number ..
 | |
| 	ROL	FAC2_2		; ..
 | |
| 	ROL	FAC2_1		; ..
 | |
| 	ROL	FACt_3		; .. into remainder
 | |
| 	ROL	FACt_2		; ..
 | |
| 	ROL	FACt_1		; ..
 | |
| 	ROL	TempB			; .. never overflows
 | |
| 
 | |
| 	ASL	FAC1_3		; root = root * 2
 | |
| 	ROL	FAC1_2		; ..
 | |
| 	ROL	FAC1_1		; .. never overflows
 | |
| 
 | |
| 	LDA	FAC1_3		; get root low byte
 | |
| 	ROL				; *2
 | |
| 	STA	Temp3			; save partial low byte
 | |
| 	LDA	FAC1_2		; get root low mid byte
 | |
| 	ROL				; *2
 | |
| 	STA	Temp3+1		; save partial low mid byte
 | |
| 	LDA	FAC1_1		; get root high mid byte
 | |
| 	ROL				; *2
 | |
| 	STA	Temp3+2		; save partial high mid byte
 | |
| 	LDA	#$00			; get root high byte (always $00)
 | |
| 	ROL				; *2
 | |
| 	STA	Temp3+3		; save partial high byte
 | |
| 
 | |
| 					; carry clear for subtract +1
 | |
| 	LDA	FACt_3		; get remainder low byte
 | |
| 	SBC	Temp3			; subtract partial low byte
 | |
| 	STA	Temp3			; save partial low byte
 | |
| 
 | |
| 	LDA	FACt_2		; get remainder low mid byte
 | |
| 	SBC	Temp3+1		; subtract partial low mid byte
 | |
| 	STA	Temp3+1		; save partial low mid byte
 | |
| 
 | |
| 	LDA	FACt_1		; get remainder high mid byte
 | |
| 	SBC	Temp3+2		; subtract partial high mid byte
 | |
| 	TAY				; copy partial high mid byte
 | |
| 
 | |
| 	LDA	TempB			; get remainder high byte
 | |
| 	SBC	Temp3+3		; subtract partial high byte
 | |
| 	BCC	LAB_SQNS		; skip sub if remainder smaller
 | |
| 
 | |
| 	STA	TempB			; save remainder high byte
 | |
| 
 | |
| 	STY	FACt_1		; save remainder high mid byte
 | |
| 
 | |
| 	LDA	Temp3+1		; get remainder low mid byte
 | |
| 	STA	FACt_2		; save remainder low mid byte
 | |
| 
 | |
| 	LDA	Temp3			; get partial low byte
 | |
| 	STA	FACt_3		; save remainder low byte
 | |
| 
 | |
| 	INC	FAC1_3		; increment root low byte (never any rollover)
 | |
| LAB_SQNS
 | |
| 	DEX				; decrement bit pair count
 | |
| 	BNE	LAB_SQE1		; loop if not all done
 | |
| 
 | |
| 	SEC				; set carry for subtract
 | |
| 	LDA	FAC2_e		; get exponent
 | |
| 	SBC	#$80			; normalise
 | |
| 	ROR				; /2 and re-bias to $80
 | |
| 	ADC	#$00			; add bit zero back in (allow for half shift)
 | |
| 	STA	FAC1_e		; save it
 | |
| 	JMP	LAB_24D5		; normalise FAC1 and return
 | |
| 
 | |
| ; perform VARPTR()
 | |
| 
 | |
| LAB_VARPTR
 | |
| 	JSR	LAB_IGBY		; increment and scan memory
 | |
| 	JSR	LAB_GVAR		; get var address
 | |
| 	JSR	LAB_1BFB		; scan for ")" , else do syntax error then warm start
 | |
| 	LDY	Cvaral		; get var address low byte
 | |
| 	LDA	Cvarah		; get var address high byte
 | |
| 	JMP	LAB_AYFC		; save and convert integer AY to FAC1 and return
 | |
| 
 | |
| ; perform PI
 | |
| 
 | |
| LAB_PI
 | |
| 	LDA	#<LAB_2C7C		; set (2*pi) pointer low byte
 | |
| 	LDY	#>LAB_2C7C		; set (2*pi) pointer high byte
 | |
| 	JSR	LAB_UFAC		; unpack memory (AY) into FAC1
 | |
| 	DEC	FAC1_e		; make result = PI
 | |
| 	RTS
 | |
| 
 | |
| ; perform TWOPI
 | |
| 
 | |
| LAB_TWOPI
 | |
| 	LDA	#<LAB_2C7C		; set (2*pi) pointer low byte
 | |
| 	LDY	#>LAB_2C7C		; set (2*pi) pointer high byte
 | |
| 	JMP	LAB_UFAC		; unpack memory (AY) into FAC1 and return
 | |
| 
 | |
| ; system dependant i/o vectors
 | |
| ; these are in RAM and are set by the monitor at start-up
 | |
| 
 | |
| V_INPT
 | |
| 	JMP	(VEC_IN)		; non halting scan input device
 | |
| V_OUTP
 | |
| 	JMP	(VEC_OUT)		; send byte to output device
 | |
| V_LOAD
 | |
| 	JMP	(VEC_LD)		; load BASIC program
 | |
| V_SAVE
 | |
| 	JMP	(VEC_SV)		; save BASIC program
 | |
| 
 | |
| ; The rest are tables messages and code for RAM
 | |
| 
 | |
| ; the rest of the code is tables and BASIC start-up code
 | |
| 
 | |
| PG2_TABS
 | |
| 	.byte	$00			; ctrl-c flag		-	$00 = enabled
 | |
| 	.byte	$00			; ctrl-c byte		-	GET needs this
 | |
| 	.byte	$00			; ctrl-c byte timeout	-	GET needs this
 | |
| 	.word	CTRLC			; ctrl c check vector
 | |
| ;	.word	xxxx			; non halting key input	-	monitor to set this
 | |
| ;	.word	xxxx			; output vector		-	monitor to set this
 | |
| ;	.word	xxxx			; load vector		-	monitor to set this
 | |
| ;	.word	xxxx			; save vector		-	monitor to set this
 | |
| PG2_TABE
 | |
| 
 | |
| ; character get subroutine for zero page
 | |
| 
 | |
| ; For a 1.8432MHz 6502 including the JSR and RTS
 | |
| ; fastest (>=":")	=  29 cycles =  15.7uS
 | |
| ; slowest (<":")	=  40 cycles =  21.7uS
 | |
| ; space skip	= +21 cycles = +11.4uS
 | |
| ; inc across page	=  +4 cycles =  +2.2uS
 | |
| 
 | |
| ; the target address for the LDA at LAB_2CF4 becomes the BASIC execute pointer once the
 | |
| ; block is copied to it's destination, any non zero page address will do at assembly
 | |
| ; time, to assemble a three byte instruction.
 | |
| 
 | |
| ; page 0 initialisation table from $BC
 | |
| ; increment and scan memory
 | |
| 
 | |
| LAB_2CEE
 | |
| 	INC	Bpntrl		; increment BASIC execute pointer low byte
 | |
| 	BNE	LAB_2CF4		; branch if no carry
 | |
| 					; else
 | |
| 	INC	Bpntrh		; increment BASIC execute pointer high byte
 | |
| 
 | |
| ; page 0 initialisation table from $C2
 | |
| ; scan memory
 | |
| 
 | |
| LAB_2CF4
 | |
| 	LDA	$FFFF			; get byte to scan (addr set by call routine)
 | |
| 	CMP	#TK_ELSE		; compare with the token for ELSE
 | |
| 	BEQ	LAB_2D05		; exit if ELSE, not numeric, carry set
 | |
| 
 | |
| 	CMP	#':'			; compare with ":"
 | |
| 	BCS	LAB_2D05		; exit if >= ":", not numeric, carry set
 | |
| 
 | |
| 	CMP	#' '			; compare with " "
 | |
| 	BEQ	LAB_2CEE		; if " " go do next
 | |
| 
 | |
| 	SEC				; set carry for SBC
 | |
| 	SBC	#'0'			; subtract "0"
 | |
| 	SEC				; set carry for SBC
 | |
| 	SBC	#$D0			; subtract -"0"
 | |
| 					; clear carry if byte = "0"-"9"
 | |
| LAB_2D05
 | |
| 	RTS
 | |
| 
 | |
| ; page zero initialisation table $00-$12 inclusive
 | |
| 
 | |
| StrTab
 | |
| 	.byte	$4C			; JMP opcode
 | |
| 	.word LAB_COLD		; initial warm start vector (cold start)
 | |
| 
 | |
| 	.byte	$00			; these bytes are not used by BASIC
 | |
| 	.word	$0000			; 
 | |
| 	.word	$0000			; 
 | |
| 	.word	$0000			; 
 | |
| 
 | |
| 	.byte	$4C			; JMP opcode
 | |
| 	.word	LAB_FCER		; initial user function vector ("Function call" error)
 | |
| 	.byte	$00			; default NULL count
 | |
| 	.byte	$00			; clear terminal position
 | |
| 	.byte	$00			; default terminal width byte
 | |
| 	.byte	$F2			; default limit for TAB = 14
 | |
| 	.word	Ram_base		; start of user RAM
 | |
| EndTab
 | |
| 
 | |
| LAB_MSZM
 | |
| 	.byte	$0D,$0A,"Memory size ",$00
 | |
| 
 | |
| LAB_SMSG
 | |
| 	.byte	" Bytes free",$0D,$0A,$0A
 | |
| 	.byte	"Enhanced BASIC 2.22",$0A,$00
 | |
| 
 | |
| ; numeric constants and series
 | |
| 
 | |
| 					; constants and series for LOG(n)
 | |
| LAB_25A0
 | |
| 	.byte	$02			; counter
 | |
| 	.byte	$80,$19,$56,$62	; 0.59898
 | |
| 	.byte	$80,$76,$22,$F3	; 0.96147
 | |
| ;##	.byte	$80,$76,$22,$F1	; 0.96147
 | |
| 	.byte	$82,$38,$AA,$40	; 2.88539
 | |
| ;##	.byte	$82,$38,$AA,$45	; 2.88539
 | |
| 
 | |
| LAB_25AD
 | |
| 	.byte	$80,$35,$04,$F3	; 0.70711	1/root 2
 | |
| LAB_25B1
 | |
| 	.byte	$81,$35,$04,$F3	; 1.41421	root 2
 | |
| LAB_25B5
 | |
| 	.byte	$80,$80,$00,$00	; -0.5
 | |
| LAB_25B9
 | |
| 	.byte	$80,$31,$72,$18	; 0.69315	LOG(2)
 | |
| 
 | |
| 					; numeric PRINT constants
 | |
| LAB_2947
 | |
| 	.byte	$91,$43,$4F,$F8	; 99999.9375 (max value with at least one decimal)
 | |
| LAB_294B
 | |
| 	.byte	$94,$74,$23,$F7	; 999999.4375 (max value before scientific notation)
 | |
| LAB_294F
 | |
| 	.byte	$94,$74,$24,$00	; 1000000
 | |
| 
 | |
| 					; EXP(n) constants and series
 | |
| LAB_2AFA
 | |
| 	.byte	$81,$38,$AA,$3B	; 1.4427	(1/LOG base 2 e)
 | |
| LAB_2AFE
 | |
| 	.byte	$06			; counter
 | |
| 	.byte	$74,$63,$90,$8C	; 2.17023e-4
 | |
| 	.byte	$77,$23,$0C,$AB	; 0.00124
 | |
| 	.byte	$7A,$1E,$94,$00	; 0.00968
 | |
| 	.byte	$7C,$63,$42,$80	; 0.05548
 | |
| 	.byte	$7E,$75,$FE,$D0	; 0.24023
 | |
| 	.byte	$80,$31,$72,$15	; 0.69315
 | |
| 	.byte	$81,$00,$00,$00	; 1.00000
 | |
| 
 | |
| ;##	.byte	$07			; counter
 | |
| ;##	.byte	$74,$94,$2E,$40	; -1/7! (-1/5040)
 | |
| ;##	.byte	$77,$2E,$4F,$70	;  1/6! ( 1/720)
 | |
| ;##	.byte	$7A,$88,$02,$6E	; -1/5! (-1/120)
 | |
| ;##	.byte	$7C,$2A,$A0,$E6	;  1/4! ( 1/24)
 | |
| ;##	.byte	$7E,$AA,$AA,$50	; -1/3! (-1/6)
 | |
| ;##	.byte	$7F,$7F,$FF,$FF	;  1/2! ( 1/2)
 | |
| ;##	.byte	$81,$80,$00,$00	; -1/1! (-1/1)
 | |
| ;##	.byte	$81,$00,$00,$00	;  1/0! ( 1/1)
 | |
| 
 | |
| 					; trigonometric constants and series
 | |
| LAB_2C78
 | |
| 	.byte	$81,$49,$0F,$DB	; 1.570796371 (pi/2) as floating #
 | |
| LAB_2C84
 | |
| 	.byte	$04			; counter
 | |
| 	.byte	$86,$1E,$D7,$FB	; 39.7109
 | |
| ;##	.byte	$86,$1E,$D7,$BA	; 39.7109
 | |
| 	.byte	$87,$99,$26,$65	;-76.575
 | |
| ;##	.byte	$87,$99,$26,$64	;-76.575
 | |
| 	.byte	$87,$23,$34,$58	; 81.6022
 | |
| 	.byte	$86,$A5,$5D,$E1	;-41.3417
 | |
| ;##	.byte	$86,$A5,$5D,$E0	;-41.3417
 | |
| LAB_2C7C
 | |
| 	.byte	$83,$49,$0F,$DB	; 6.28319 (2*pi) as floating #
 | |
| ;##	.byte	$83,$49,$0F,$DA	; 6.28319 (2*pi) as floating #
 | |
| 
 | |
| LAB_2CC9
 | |
| 	.byte	$08			; counter
 | |
| 	.byte	$78,$3A,$C5,$37	; 0.00285
 | |
| 	.byte	$7B,$83,$A2,$5C	;-0.0160686
 | |
| 	.byte	$7C,$2E,$DD,$4D	; 0.0426915
 | |
| 	.byte	$7D,$99,$B0,$1E	;-0.0750429
 | |
| 	.byte	$7D,$59,$ED,$24	; 0.106409
 | |
| 	.byte	$7E,$91,$72,$00	;-0.142036
 | |
| 	.byte	$7E,$4C,$B9,$73	; 0.199926
 | |
| 	.byte	$7F,$AA,$AA,$53	;-0.333331
 | |
| 
 | |
| ;##	.byte	$08			; counter
 | |
| ;##	.byte	$78,$3B,$D7,$4A	; 1/17
 | |
| ;##	.byte	$7B,$84,$6E,$02	;-1/15
 | |
| ;##	.byte	$7C,$2F,$C1,$FE	; 1/13
 | |
| ;##	.byte	$7D,$9A,$31,$74	;-1/11
 | |
| ;##	.byte	$7D,$5A,$3D,$84	; 1/9
 | |
| ;##	.byte	$7E,$91,$7F,$C8	;-1/7
 | |
| ;##	.byte	$7E,$4C,$BB,$E4	; 1/5
 | |
| ;##	.byte	$7F,$AA,$AA,$6C	;-1/3
 | |
| 
 | |
| LAB_1D96	= *+1			; $00,$00 used for undefined variables
 | |
| LAB_259C
 | |
| 	.byte	$81,$00,$00,$00	; 1.000000, used for INC
 | |
| LAB_2AFD
 | |
| 	.byte	$81,$80,$00,$00	; -1.00000, used for DEC. must be on the same page as +1.00
 | |
| 
 | |
| 					; misc constants
 | |
| LAB_1DF7
 | |
| 	.byte	$90			;-32768 (uses first three bytes from 0.5)
 | |
| LAB_2A96
 | |
| 	.byte	$80,$00,$00,$00	; 0.5
 | |
| LAB_2C80
 | |
| 	.byte	$7F,$00,$00,$00	; 0.25
 | |
| LAB_26B5
 | |
| 	.byte	$84,$20,$00,$00	; 10.0000 divide by 10 constant
 | |
| 
 | |
| ; This table is used in converting numbers to ASCII.
 | |
| 
 | |
| LAB_2A9A
 | |
| LAB_2A9B = LAB_2A9A+1
 | |
| LAB_2A9C = LAB_2A9B+1
 | |
| 	.byte	$FE,$79,$60		; -100000
 | |
| 	.byte	$00,$27,$10		; 10000
 | |
| 	.byte	$FF,$FC,$18		; -1000
 | |
| 	.byte	$00,$00,$64		; 100
 | |
| 	.byte	$FF,$FF,$F6		; -10
 | |
| 	.byte	$00,$00,$01		; 1
 | |
| 
 | |
| LAB_CTBL
 | |
| 	.word	LAB_END-1		; END
 | |
| 	.word	LAB_FOR-1		; FOR
 | |
| 	.word	LAB_NEXT-1		; NEXT
 | |
| 	.word	LAB_DATA-1		; DATA
 | |
| 	.word	LAB_INPUT-1		; INPUT
 | |
| 	.word	LAB_DIM-1		; DIM
 | |
| 	.word	LAB_READ-1		; READ
 | |
| 	.word	LAB_LET-1		; LET
 | |
| 	.word	LAB_DEC-1		; DEC			new command
 | |
| 	.word	LAB_GOTO-1		; GOTO
 | |
| 	.word	LAB_RUN-1		; RUN
 | |
| 	.word	LAB_IF-1		; IF
 | |
| 	.word	LAB_RESTORE-1	; RESTORE		modified command
 | |
| 	.word	LAB_GOSUB-1		; GOSUB
 | |
| 	.word	LAB_RETIRQ-1	; RETIRQ		new command
 | |
| 	.word	LAB_RETNMI-1	; RETNMI		new command
 | |
| 	.word	LAB_RETURN-1	; RETURN
 | |
| 	.word	LAB_REM-1		; REM
 | |
| 	.word	LAB_STOP-1		; STOP
 | |
| 	.word	LAB_ON-1		; ON			modified command
 | |
| 	.word	LAB_NULL-1		; NULL		modified command
 | |
| 	.word	LAB_INC-1		; INC			new command
 | |
| 	.word	LAB_WAIT-1		; WAIT
 | |
| 	.word	V_LOAD-1		; LOAD
 | |
| 	.word	V_SAVE-1		; SAVE
 | |
| 	.word	LAB_DEF-1		; DEF
 | |
| 	.word	LAB_POKE-1		; POKE
 | |
| 	.word	LAB_DOKE-1		; DOKE		new command
 | |
| 	.word	LAB_CALL-1		; CALL		new command
 | |
| 	.word	LAB_DO-1		; DO			new command
 | |
| 	.word	LAB_LOOP-1		; LOOP		new command
 | |
| 	.word	LAB_PRINT-1		; PRINT
 | |
| 	.word	LAB_CONT-1		; CONT
 | |
| 	.word	LAB_LIST-1		; LIST
 | |
| 	.word	LAB_CLEAR-1		; CLEAR
 | |
| 	.word	LAB_NEW-1		; NEW
 | |
| 	.word	LAB_WDTH-1		; WIDTH		new command
 | |
| 	.word	LAB_GET-1		; GET			new command
 | |
| 	.word	LAB_SWAP-1		; SWAP		new command
 | |
| 	.word	LAB_BITSET-1	; BITSET		new command
 | |
| 	.word	LAB_BITCLR-1	; BITCLR		new command
 | |
| 	.word	LAB_IRQ-1		; IRQ			new command
 | |
| 	.word	LAB_NMI-1		; NMI			new command
 | |
| 
 | |
| ; function pre process routine table
 | |
| 
 | |
| LAB_FTPL
 | |
| LAB_FTPM	= LAB_FTPL+$01
 | |
| 	.word	LAB_PPFN-1		; SGN(n)	process numeric expression in ()
 | |
| 	.word	LAB_PPFN-1		; INT(n)		"
 | |
| 	.word	LAB_PPFN-1		; ABS(n)		"
 | |
| 	.word	LAB_EVEZ-1		; USR(x)	process any expression
 | |
| 	.word	LAB_1BF7-1		; FRE(x)		"
 | |
| 	.word	LAB_1BF7-1		; POS(x)		"
 | |
| 	.word	LAB_PPFN-1		; SQR(n)	process numeric expression in ()
 | |
| 	.word	LAB_PPFN-1		; RND(n)		"
 | |
| 	.word	LAB_PPFN-1		; LOG(n)		"
 | |
| 	.word	LAB_PPFN-1		; EXP(n)		"
 | |
| 	.word	LAB_PPFN-1		; COS(n)		"
 | |
| 	.word	LAB_PPFN-1		; SIN(n)		"
 | |
| 	.word	LAB_PPFN-1		; TAN(n)		"
 | |
| 	.word	LAB_PPFN-1		; ATN(n)		"
 | |
| 	.word	LAB_PPFN-1		; PEEK(n)		"
 | |
| 	.word	LAB_PPFN-1		; DEEK(n)		"
 | |
| 	.word	$0000			; SADD()	none
 | |
| 	.word	LAB_PPFS-1		; LEN($)	process string expression in ()
 | |
| 	.word	LAB_PPFN-1		; STR$(n)	process numeric expression in ()
 | |
| 	.word	LAB_PPFS-1		; VAL($)	process string expression in ()
 | |
| 	.word	LAB_PPFS-1		; ASC($)		"
 | |
| 	.word	LAB_PPFS-1		; UCASE$($)		"
 | |
| 	.word	LAB_PPFS-1		; LCASE$($)		"
 | |
| 	.word	LAB_PPFN-1		; CHR$(n)	process numeric expression in ()
 | |
| 	.word	LAB_BHSS-1		; HEX$(n)		"
 | |
| 	.word	LAB_BHSS-1		; BIN$(n)		"
 | |
| 	.word	$0000			; BITTST()	none
 | |
| 	.word	LAB_MMPP-1		; MAX()	process numeric expression
 | |
| 	.word	LAB_MMPP-1		; MIN()		"
 | |
| 	.word	LAB_PPBI-1		; PI		advance pointer
 | |
| 	.word	LAB_PPBI-1		; TWOPI		"
 | |
| 	.word	$0000			; VARPTR()	none
 | |
| 	.word	LAB_LRMS-1		; LEFT$()	process string expression
 | |
| 	.word	LAB_LRMS-1		; RIGHT$()		"
 | |
| 	.word	LAB_LRMS-1		; MID$()		"
 | |
| 
 | |
| ; action addresses for functions
 | |
| 
 | |
| LAB_FTBL
 | |
| LAB_FTBM	= LAB_FTBL+$01
 | |
| 	.word	LAB_SGN-1		; SGN()
 | |
| 	.word	LAB_INT-1		; INT()
 | |
| 	.word	LAB_ABS-1		; ABS()
 | |
| 	.word	LAB_USR-1		; USR()
 | |
| 	.word	LAB_FRE-1		; FRE()
 | |
| 	.word	LAB_POS-1		; POS()
 | |
| 	.word	LAB_SQR-1		; SQR()
 | |
| 	.word	LAB_RND-1		; RND()		modified function
 | |
| 	.word	LAB_LOG-1		; LOG()
 | |
| 	.word	LAB_EXP-1		; EXP()
 | |
| 	.word	LAB_COS-1		; COS()
 | |
| 	.word	LAB_SIN-1		; SIN()
 | |
| 	.word	LAB_TAN-1		; TAN()
 | |
| 	.word	LAB_ATN-1		; ATN()
 | |
| 	.word	LAB_PEEK-1		; PEEK()
 | |
| 	.word	LAB_DEEK-1		; DEEK()		new function
 | |
| 	.word	LAB_SADD-1		; SADD()		new function
 | |
| 	.word	LAB_LENS-1		; LEN()
 | |
| 	.word	LAB_STRS-1		; STR$()
 | |
| 	.word	LAB_VAL-1		; VAL()
 | |
| 	.word	LAB_ASC-1		; ASC()
 | |
| 	.word	LAB_UCASE-1		; UCASE$()		new function
 | |
| 	.word	LAB_LCASE-1		; LCASE$()		new function
 | |
| 	.word	LAB_CHRS-1		; CHR$()
 | |
| 	.word	LAB_HEXS-1		; HEX$()		new function
 | |
| 	.word	LAB_BINS-1		; BIN$()		new function
 | |
| 	.word	LAB_BTST-1		; BITTST()		new function
 | |
| 	.word	LAB_MAX-1		; MAX()		new function
 | |
| 	.word	LAB_MIN-1		; MIN()		new function
 | |
| 	.word	LAB_PI-1		; PI			new function
 | |
| 	.word	LAB_TWOPI-1		; TWOPI		new function
 | |
| 	.word	LAB_VARPTR-1	; VARPTR()		new function
 | |
| 	.word	LAB_LEFT-1		; LEFT$()
 | |
| 	.word	LAB_RIGHT-1		; RIGHT$()
 | |
| 	.word	LAB_MIDS-1		; MID$()
 | |
| 
 | |
| ; hierarchy and action addresses for operator
 | |
| 
 | |
| LAB_OPPT
 | |
| 	.byte	$79			; +
 | |
| 	.word	LAB_ADD-1
 | |
| 	.byte	$79			; -
 | |
| 	.word	LAB_SUBTRACT-1
 | |
| 	.byte	$7B			; *
 | |
| 	.word	LAB_MULTIPLY-1
 | |
| 	.byte	$7B			; /
 | |
| 	.word	LAB_DIVIDE-1
 | |
| 	.byte	$7F			; ^
 | |
| 	.word	LAB_POWER-1
 | |
| 	.byte	$50			; AND
 | |
| 	.word	LAB_AND-1
 | |
| 	.byte	$46			; EOR			new operator
 | |
| 	.word	LAB_EOR-1
 | |
| 	.byte	$46			; OR
 | |
| 	.word	LAB_OR-1
 | |
| 	.byte	$56			; >>			new operator
 | |
| 	.word	LAB_RSHIFT-1
 | |
| 	.byte	$56			; <<			new operator
 | |
| 	.word	LAB_LSHIFT-1
 | |
| 	.byte	$7D			; >
 | |
| 	.word	LAB_GTHAN-1
 | |
| 	.byte	$5A			; =
 | |
| 	.word	LAB_EQUAL-1
 | |
| 	.byte	$64			; <
 | |
| 	.word	LAB_LTHAN-1
 | |
| 
 | |
| ; keywords start with ..
 | |
| ; this is the first character table and must be in alphabetic order
 | |
| 
 | |
| TAB_1STC
 | |
| 	.byte	"*"
 | |
| 	.byte	"+"
 | |
| 	.byte	"-"
 | |
| 	.byte	"/"
 | |
| 	.byte	"<"
 | |
| 	.byte	"="
 | |
| 	.byte	">"
 | |
| 	.byte	"?"
 | |
| 	.byte	"A"
 | |
| 	.byte	"B"
 | |
| 	.byte	"C"
 | |
| 	.byte	"D"
 | |
| 	.byte	"E"
 | |
| 	.byte	"F"
 | |
| 	.byte	"G"
 | |
| 	.byte	"H"
 | |
| 	.byte	"I"
 | |
| 	.byte	"L"
 | |
| 	.byte	"M"
 | |
| 	.byte	"N"
 | |
| 	.byte	"O"
 | |
| 	.byte	"P"
 | |
| 	.byte	"R"
 | |
| 	.byte	"S"
 | |
| 	.byte	"T"
 | |
| 	.byte	"U"
 | |
| 	.byte	"V"
 | |
| 	.byte	"W"
 | |
| 	.byte	"^"
 | |
| 	.byte	$00			; table terminator
 | |
| 
 | |
| ; pointers to keyword tables
 | |
| 
 | |
| TAB_CHRT
 | |
| 	.word	TAB_STAR		; table for "*"
 | |
| 	.word	TAB_PLUS		; table for "+"
 | |
| 	.word	TAB_MNUS		; table for "-"
 | |
| 	.word	TAB_SLAS		; table for "/"
 | |
| 	.word	TAB_LESS		; table for "<"
 | |
| 	.word	TAB_EQUL		; table for "="
 | |
| 	.word	TAB_MORE		; table for ">"
 | |
| 	.word	TAB_QEST		; table for "?"
 | |
| 	.word	TAB_ASCA		; table for "A"
 | |
| 	.word	TAB_ASCB		; table for "B"
 | |
| 	.word	TAB_ASCC		; table for "C"
 | |
| 	.word	TAB_ASCD		; table for "D"
 | |
| 	.word	TAB_ASCE		; table for "E"
 | |
| 	.word	TAB_ASCF		; table for "F"
 | |
| 	.word	TAB_ASCG		; table for "G"
 | |
| 	.word	TAB_ASCH		; table for "H"
 | |
| 	.word	TAB_ASCI		; table for "I"
 | |
| 	.word	TAB_ASCL		; table for "L"
 | |
| 	.word	TAB_ASCM		; table for "M"
 | |
| 	.word	TAB_ASCN		; table for "N"
 | |
| 	.word	TAB_ASCO		; table for "O"
 | |
| 	.word	TAB_ASCP		; table for "P"
 | |
| 	.word	TAB_ASCR		; table for "R"
 | |
| 	.word	TAB_ASCS		; table for "S"
 | |
| 	.word	TAB_ASCT		; table for "T"
 | |
| 	.word	TAB_ASCU		; table for "U"
 | |
| 	.word	TAB_ASCV		; table for "V"
 | |
| 	.word	TAB_ASCW		; table for "W"
 | |
| 	.word	TAB_POWR		; table for "^"
 | |
| 
 | |
| ; tables for each start character, note if a longer keyword with the same start
 | |
| ; letters as a shorter one exists then it must come first, else the list is in
 | |
| ; alphabetical order as follows ..
 | |
| 
 | |
| ; [keyword,token
 | |
| ; [keyword,token]]
 | |
| ; end marker (#$00)
 | |
| 
 | |
| TAB_STAR
 | |
| 	.byte TK_MUL,$00		; *
 | |
| TAB_PLUS
 | |
| 	.byte TK_PLUS,$00		; +
 | |
| TAB_MNUS
 | |
| 	.byte TK_MINUS,$00	; -
 | |
| TAB_SLAS
 | |
| 	.byte TK_DIV,$00		; /
 | |
| TAB_LESS
 | |
| LBB_LSHIFT
 | |
| 	.byte	"<",TK_LSHIFT	; <<	note - "<<" must come before "<"
 | |
| 	.byte TK_LT			; <
 | |
| 	.byte	$00
 | |
| TAB_EQUL
 | |
| 	.byte TK_EQUAL,$00	; =
 | |
| TAB_MORE
 | |
| LBB_RSHIFT
 | |
| 	.byte	">",TK_RSHIFT	; >>	note - ">>" must come before ">"
 | |
| 	.byte TK_GT			; >
 | |
| 	.byte	$00
 | |
| TAB_QEST
 | |
| 	.byte TK_PRINT,$00	; ?
 | |
| TAB_ASCA
 | |
| LBB_ABS
 | |
| 	.byte	"BS(",TK_ABS	; ABS(
 | |
| LBB_AND
 | |
| 	.byte	"ND",TK_AND		; AND
 | |
| LBB_ASC
 | |
| 	.byte	"SC(",TK_ASC	; ASC(
 | |
| LBB_ATN
 | |
| 	.byte	"TN(",TK_ATN	; ATN(
 | |
| 	.byte	$00
 | |
| TAB_ASCB
 | |
| LBB_BINS
 | |
| 	.byte	"IN$(",TK_BINS	; BIN$(
 | |
| LBB_BITCLR
 | |
| 	.byte	"ITCLR",TK_BITCLR	; BITCLR
 | |
| LBB_BITSET
 | |
| 	.byte	"ITSET",TK_BITSET	; BITSET
 | |
| LBB_BITTST
 | |
| 	.byte	"ITTST(",TK_BITTST
 | |
| 					; BITTST(
 | |
| 	.byte	$00
 | |
| TAB_ASCC
 | |
| LBB_CALL
 | |
| 	.byte	"ALL",TK_CALL	; CALL
 | |
| LBB_CHRS
 | |
| 	.byte	"HR$(",TK_CHRS	; CHR$(
 | |
| LBB_CLEAR
 | |
| 	.byte	"LEAR",TK_CLEAR	; CLEAR
 | |
| LBB_CONT
 | |
| 	.byte	"ONT",TK_CONT	; CONT
 | |
| LBB_COS
 | |
| 	.byte	"OS(",TK_COS	; COS(
 | |
| 	.byte	$00
 | |
| TAB_ASCD
 | |
| LBB_DATA
 | |
| 	.byte	"ATA",TK_DATA	; DATA
 | |
| LBB_DEC
 | |
| 	.byte	"EC",TK_DEC		; DEC
 | |
| LBB_DEEK
 | |
| 	.byte	"EEK(",TK_DEEK	; DEEK(
 | |
| LBB_DEF
 | |
| 	.byte	"EF",TK_DEF		; DEF
 | |
| LBB_DIM
 | |
| 	.byte	"IM",TK_DIM		; DIM
 | |
| LBB_DOKE
 | |
| 	.byte	"OKE",TK_DOKE	; DOKE note - "DOKE" must come before "DO"
 | |
| LBB_DO
 | |
| 	.byte	"O",TK_DO		; DO
 | |
| 	.byte	$00
 | |
| TAB_ASCE
 | |
| LBB_ELSE
 | |
| 	.byte	"LSE",TK_ELSE	; ELSE
 | |
| LBB_END
 | |
| 	.byte	"ND",TK_END		; END
 | |
| LBB_EOR
 | |
| 	.byte	"OR",TK_EOR		; EOR
 | |
| LBB_EXP
 | |
| 	.byte	"XP(",TK_EXP	; EXP(
 | |
| 	.byte	$00
 | |
| TAB_ASCF
 | |
| LBB_FN
 | |
| 	.byte	"N",TK_FN		; FN
 | |
| LBB_FOR
 | |
| 	.byte	"OR",TK_FOR		; FOR
 | |
| LBB_FRE
 | |
| 	.byte	"RE(",TK_FRE	; FRE(
 | |
| 	.byte	$00
 | |
| TAB_ASCG
 | |
| LBB_GET
 | |
| 	.byte	"ET",TK_GET		; GET
 | |
| LBB_GOSUB
 | |
| 	.byte	"OSUB",TK_GOSUB	; GOSUB
 | |
| LBB_GOTO
 | |
| 	.byte	"OTO",TK_GOTO	; GOTO
 | |
| 	.byte	$00
 | |
| TAB_ASCH
 | |
| LBB_HEXS
 | |
| 	.byte	"EX$(",TK_HEXS	; HEX$(
 | |
| 	.byte	$00
 | |
| TAB_ASCI
 | |
| LBB_IF
 | |
| 	.byte	"F",TK_IF		; IF
 | |
| LBB_INC
 | |
| 	.byte	"NC",TK_INC		; INC
 | |
| LBB_INPUT
 | |
| 	.byte	"NPUT",TK_INPUT	; INPUT
 | |
| LBB_INT
 | |
| 	.byte	"NT(",TK_INT	; INT(
 | |
| LBB_IRQ
 | |
| 	.byte	"RQ",TK_IRQ		; IRQ
 | |
| 	.byte	$00
 | |
| TAB_ASCL
 | |
| LBB_LCASES
 | |
| 	.byte	"CASE$(",TK_LCASES
 | |
| 					; LCASE$(
 | |
| LBB_LEFTS
 | |
| 	.byte	"EFT$(",TK_LEFTS	; LEFT$(
 | |
| LBB_LEN
 | |
| 	.byte	"EN(",TK_LEN	; LEN(
 | |
| LBB_LET
 | |
| 	.byte	"ET",TK_LET		; LET
 | |
| LBB_LIST
 | |
| 	.byte	"IST",TK_LIST	; LIST
 | |
| LBB_LOAD
 | |
| 	.byte	"OAD",TK_LOAD	; LOAD
 | |
| LBB_LOG
 | |
| 	.byte	"OG(",TK_LOG	; LOG(
 | |
| LBB_LOOP
 | |
| 	.byte	"OOP",TK_LOOP	; LOOP
 | |
| 	.byte	$00
 | |
| TAB_ASCM
 | |
| LBB_MAX
 | |
| 	.byte	"AX(",TK_MAX	; MAX(
 | |
| LBB_MIDS
 | |
| 	.byte	"ID$(",TK_MIDS	; MID$(
 | |
| LBB_MIN
 | |
| 	.byte	"IN(",TK_MIN	; MIN(
 | |
| 	.byte	$00
 | |
| TAB_ASCN
 | |
| LBB_NEW
 | |
| 	.byte	"EW",TK_NEW		; NEW
 | |
| LBB_NEXT
 | |
| 	.byte	"EXT",TK_NEXT	; NEXT
 | |
| LBB_NMI
 | |
| 	.byte	"MI",TK_NMI		; NMI
 | |
| LBB_NOT
 | |
| 	.byte	"OT",TK_NOT		; NOT
 | |
| LBB_NULL
 | |
| 	.byte	"ULL",TK_NULL	; NULL
 | |
| 	.byte	$00
 | |
| TAB_ASCO
 | |
| LBB_OFF
 | |
| 	.byte	"FF",TK_OFF		; OFF
 | |
| LBB_ON
 | |
| 	.byte	"N",TK_ON		; ON
 | |
| LBB_OR
 | |
| 	.byte	"R",TK_OR		; OR
 | |
| 	.byte	$00
 | |
| TAB_ASCP
 | |
| LBB_PEEK
 | |
| 	.byte	"EEK(",TK_PEEK	; PEEK(
 | |
| LBB_PI
 | |
| 	.byte	"I",TK_PI		; PI
 | |
| LBB_POKE
 | |
| 	.byte	"OKE",TK_POKE	; POKE
 | |
| LBB_POS
 | |
| 	.byte	"OS(",TK_POS	; POS(
 | |
| LBB_PRINT
 | |
| 	.byte	"RINT",TK_PRINT	; PRINT
 | |
| 	.byte	$00
 | |
| TAB_ASCR
 | |
| LBB_READ
 | |
| 	.byte	"EAD",TK_READ	; READ
 | |
| LBB_REM
 | |
| 	.byte	"EM",TK_REM		; REM
 | |
| LBB_RESTORE
 | |
| 	.byte	"ESTORE",TK_RESTORE
 | |
| 					; RESTORE
 | |
| LBB_RETIRQ
 | |
| 	.byte	"ETIRQ",TK_RETIRQ	; RETIRQ
 | |
| LBB_RETNMI
 | |
| 	.byte	"ETNMI",TK_RETNMI	; RETNMI
 | |
| LBB_RETURN
 | |
| 	.byte	"ETURN",TK_RETURN	; RETURN
 | |
| LBB_RIGHTS
 | |
| 	.byte	"IGHT$(",TK_RIGHTS
 | |
| 					; RIGHT$(
 | |
| LBB_RND
 | |
| 	.byte	"ND(",TK_RND	; RND(
 | |
| LBB_RUN
 | |
| 	.byte	"UN",TK_RUN		; RUN
 | |
| 	.byte	$00
 | |
| TAB_ASCS
 | |
| LBB_SADD
 | |
| 	.byte	"ADD(",TK_SADD	; SADD(
 | |
| LBB_SAVE
 | |
| 	.byte	"AVE",TK_SAVE	; SAVE
 | |
| LBB_SGN
 | |
| 	.byte	"GN(",TK_SGN	; SGN(
 | |
| LBB_SIN
 | |
| 	.byte	"IN(",TK_SIN	; SIN(
 | |
| LBB_SPC
 | |
| 	.byte	"PC(",TK_SPC	; SPC(
 | |
| LBB_SQR
 | |
| 	.byte	"QR(",TK_SQR	; SQR(
 | |
| LBB_STEP
 | |
| 	.byte	"TEP",TK_STEP	; STEP
 | |
| LBB_STOP
 | |
| 	.byte	"TOP",TK_STOP	; STOP
 | |
| LBB_STRS
 | |
| 	.byte	"TR$(",TK_STRS	; STR$(
 | |
| LBB_SWAP
 | |
| 	.byte	"WAP",TK_SWAP	; SWAP
 | |
| 	.byte	$00
 | |
| TAB_ASCT
 | |
| LBB_TAB
 | |
| 	.byte	"AB(",TK_TAB	; TAB(
 | |
| LBB_TAN
 | |
| 	.byte	"AN(",TK_TAN	; TAN(
 | |
| LBB_THEN
 | |
| 	.byte	"HEN",TK_THEN	; THEN
 | |
| LBB_TO
 | |
| 	.byte	"O",TK_TO		; TO
 | |
| LBB_TWOPI
 | |
| 	.byte	"WOPI",TK_TWOPI	; TWOPI
 | |
| 	.byte	$00
 | |
| TAB_ASCU
 | |
| LBB_UCASES
 | |
| 	.byte	"CASE$(",TK_UCASES
 | |
| 					; UCASE$(
 | |
| LBB_UNTIL
 | |
| 	.byte	"NTIL",TK_UNTIL	; UNTIL
 | |
| LBB_USR
 | |
| 	.byte	"SR(",TK_USR	; USR(
 | |
| 	.byte	$00
 | |
| TAB_ASCV
 | |
| LBB_VAL
 | |
| 	.byte	"AL(",TK_VAL	; VAL(
 | |
| LBB_VPTR
 | |
| 	.byte	"ARPTR(",TK_VPTR	; VARPTR(
 | |
| 	.byte	$00
 | |
| TAB_ASCW
 | |
| LBB_WAIT
 | |
| 	.byte	"AIT",TK_WAIT	; WAIT
 | |
| LBB_WHILE
 | |
| 	.byte	"HILE",TK_WHILE	; WHILE
 | |
| LBB_WIDTH
 | |
| 	.byte	"IDTH",TK_WIDTH	; WIDTH
 | |
| 	.byte	$00
 | |
| TAB_POWR
 | |
| 	.byte	TK_POWER,$00	; ^
 | |
| 
 | |
| ; new decode table for LIST
 | |
| ; Table is ..
 | |
| ; byte - keyword length, keyword first character
 | |
| ; word - pointer to rest of keyword from dictionary
 | |
| 
 | |
| ; note if length is 1 then the pointer is ignored
 | |
| 
 | |
| LAB_KEYT
 | |
| 	.byte	3,'E'
 | |
| 	.word	LBB_END		; END
 | |
| 	.byte	3,'F'
 | |
| 	.word	LBB_FOR		; FOR
 | |
| 	.byte	4,'N'
 | |
| 	.word	LBB_NEXT		; NEXT
 | |
| 	.byte	4,'D'
 | |
| 	.word	LBB_DATA		; DATA
 | |
| 	.byte	5,'I'
 | |
| 	.word	LBB_INPUT		; INPUT
 | |
| 	.byte	3,'D'
 | |
| 	.word	LBB_DIM		; DIM
 | |
| 	.byte	4,'R'
 | |
| 	.word	LBB_READ		; READ
 | |
| 	.byte	3,'L'
 | |
| 	.word	LBB_LET		; LET
 | |
| 	.byte	3,'D'
 | |
| 	.word	LBB_DEC		; DEC
 | |
| 	.byte	4,'G'
 | |
| 	.word	LBB_GOTO		; GOTO
 | |
| 	.byte	3,'R'
 | |
| 	.word	LBB_RUN		; RUN
 | |
| 	.byte	2,'I'
 | |
| 	.word	LBB_IF		; IF
 | |
| 	.byte	7,'R'
 | |
| 	.word	LBB_RESTORE		; RESTORE
 | |
| 	.byte	5,'G'
 | |
| 	.word	LBB_GOSUB		; GOSUB
 | |
| 	.byte	6,'R'
 | |
| 	.word	LBB_RETIRQ		; RETIRQ
 | |
| 	.byte	6,'R'
 | |
| 	.word	LBB_RETNMI		; RETNMI
 | |
| 	.byte	6,'R'
 | |
| 	.word	LBB_RETURN		; RETURN
 | |
| 	.byte	3,'R'
 | |
| 	.word	LBB_REM		; REM
 | |
| 	.byte	4,'S'
 | |
| 	.word	LBB_STOP		; STOP
 | |
| 	.byte	2,'O'
 | |
| 	.word	LBB_ON		; ON
 | |
| 	.byte	4,'N'
 | |
| 	.word	LBB_NULL		; NULL
 | |
| 	.byte	3,'I'
 | |
| 	.word	LBB_INC		; INC
 | |
| 	.byte	4,'W'
 | |
| 	.word	LBB_WAIT		; WAIT
 | |
| 	.byte	4,'L'
 | |
| 	.word	LBB_LOAD		; LOAD
 | |
| 	.byte	4,'S'
 | |
| 	.word	LBB_SAVE		; SAVE
 | |
| 	.byte	3,'D'
 | |
| 	.word	LBB_DEF		; DEF
 | |
| 	.byte	4,'P'
 | |
| 	.word	LBB_POKE		; POKE
 | |
| 	.byte	4,'D'
 | |
| 	.word	LBB_DOKE		; DOKE
 | |
| 	.byte	4,'C'
 | |
| 	.word	LBB_CALL		; CALL
 | |
| 	.byte	2,'D'
 | |
| 	.word	LBB_DO		; DO
 | |
| 	.byte	4,'L'
 | |
| 	.word	LBB_LOOP		; LOOP
 | |
| 	.byte	5,'P'
 | |
| 	.word	LBB_PRINT		; PRINT
 | |
| 	.byte	4,'C'
 | |
| 	.word	LBB_CONT		; CONT
 | |
| 	.byte	4,'L'
 | |
| 	.word	LBB_LIST		; LIST
 | |
| 	.byte	5,'C'
 | |
| 	.word	LBB_CLEAR		; CLEAR
 | |
| 	.byte	3,'N'
 | |
| 	.word	LBB_NEW		; NEW
 | |
| 	.byte	5,'W'
 | |
| 	.word	LBB_WIDTH		; WIDTH
 | |
| 	.byte	3,'G'
 | |
| 	.word	LBB_GET		; GET
 | |
| 	.byte	4,'S'
 | |
| 	.word	LBB_SWAP		; SWAP
 | |
| 	.byte	6,'B'
 | |
| 	.word	LBB_BITSET		; BITSET
 | |
| 	.byte	6,'B'
 | |
| 	.word	LBB_BITCLR		; BITCLR
 | |
| 	.byte	3,'I'
 | |
| 	.word	LBB_IRQ		; IRQ
 | |
| 	.byte	3,'N'
 | |
| 	.word	LBB_NMI		; NMI
 | |
| 
 | |
| ; secondary commands (can't start a statement)
 | |
| 
 | |
| 	.byte	4,'T'
 | |
| 	.word	LBB_TAB		; TAB
 | |
| 	.byte	4,'E'
 | |
| 	.word	LBB_ELSE		; ELSE
 | |
| 	.byte	2,'T'
 | |
| 	.word	LBB_TO		; TO
 | |
| 	.byte	2,'F'
 | |
| 	.word	LBB_FN		; FN
 | |
| 	.byte	4,'S'
 | |
| 	.word	LBB_SPC		; SPC
 | |
| 	.byte	4,'T'
 | |
| 	.word	LBB_THEN		; THEN
 | |
| 	.byte	3,'N'
 | |
| 	.word	LBB_NOT		; NOT
 | |
| 	.byte	4,'S'
 | |
| 	.word	LBB_STEP		; STEP
 | |
| 	.byte	5,'U'
 | |
| 	.word	LBB_UNTIL		; UNTIL
 | |
| 	.byte	5,'W'
 | |
| 	.word	LBB_WHILE		; WHILE
 | |
| 	.byte	3,'O'
 | |
| 	.word	LBB_OFF		; OFF
 | |
| 
 | |
| ; opperators
 | |
| 
 | |
| 	.byte	1,'+'
 | |
| 	.word	$0000			; +
 | |
| 	.byte	1,'-'
 | |
| 	.word	$0000			; -
 | |
| 	.byte	1,'*'
 | |
| 	.word	$0000			; *
 | |
| 	.byte	1,'/'
 | |
| 	.word	$0000			; /
 | |
| 	.byte	1,'^'
 | |
| 	.word	$0000			; ^
 | |
| 	.byte	3,'A'
 | |
| 	.word	LBB_AND		; AND
 | |
| 	.byte	3,'E'
 | |
| 	.word	LBB_EOR		; EOR
 | |
| 	.byte	2,'O'
 | |
| 	.word	LBB_OR		; OR
 | |
| 	.byte	2,'>'
 | |
| 	.word	LBB_RSHIFT		; >>
 | |
| 	.byte	2,'<'
 | |
| 	.word	LBB_LSHIFT		; <<
 | |
| 	.byte	1,'>'
 | |
| 	.word	$0000			; >
 | |
| 	.byte	1,'='
 | |
| 	.word	$0000			; =
 | |
| 	.byte	1,'<'
 | |
| 	.word	$0000			; <
 | |
| 
 | |
| ; functions
 | |
| 
 | |
| 	.byte	4,'S'			;
 | |
| 	.word	LBB_SGN		; SGN
 | |
| 	.byte	4,'I'			;
 | |
| 	.word	LBB_INT		; INT
 | |
| 	.byte	4,'A'			;
 | |
| 	.word	LBB_ABS		; ABS
 | |
| 	.byte	4,'U'			;
 | |
| 	.word	LBB_USR		; USR
 | |
| 	.byte	4,'F'			;
 | |
| 	.word	LBB_FRE		; FRE
 | |
| 	.byte	4,'P'			;
 | |
| 	.word	LBB_POS		; POS
 | |
| 	.byte	4,'S'			;
 | |
| 	.word	LBB_SQR		; SQR
 | |
| 	.byte	4,'R'			;
 | |
| 	.word	LBB_RND		; RND
 | |
| 	.byte	4,'L'			;
 | |
| 	.word	LBB_LOG		; LOG
 | |
| 	.byte	4,'E'			;
 | |
| 	.word	LBB_EXP		; EXP
 | |
| 	.byte	4,'C'			;
 | |
| 	.word	LBB_COS		; COS
 | |
| 	.byte	4,'S'			;
 | |
| 	.word	LBB_SIN		; SIN
 | |
| 	.byte	4,'T'			;
 | |
| 	.word	LBB_TAN		; TAN
 | |
| 	.byte	4,'A'			;
 | |
| 	.word	LBB_ATN		; ATN
 | |
| 	.byte	5,'P'			;
 | |
| 	.word	LBB_PEEK		; PEEK
 | |
| 	.byte	5,'D'			;
 | |
| 	.word	LBB_DEEK		; DEEK
 | |
| 	.byte	5,'S'			;
 | |
| 	.word	LBB_SADD		; SADD
 | |
| 	.byte	4,'L'			;
 | |
| 	.word	LBB_LEN		; LEN
 | |
| 	.byte	5,'S'			;
 | |
| 	.word	LBB_STRS		; STR$
 | |
| 	.byte	4,'V'			;
 | |
| 	.word	LBB_VAL		; VAL
 | |
| 	.byte	4,'A'			;
 | |
| 	.word	LBB_ASC		; ASC
 | |
| 	.byte	7,'U'			;
 | |
| 	.word	LBB_UCASES		; UCASE$
 | |
| 	.byte	7,'L'			;
 | |
| 	.word	LBB_LCASES		; LCASE$
 | |
| 	.byte	5,'C'			;
 | |
| 	.word	LBB_CHRS		; CHR$
 | |
| 	.byte	5,'H'			;
 | |
| 	.word	LBB_HEXS		; HEX$
 | |
| 	.byte	5,'B'			;
 | |
| 	.word	LBB_BINS		; BIN$
 | |
| 	.byte	7,'B'			;
 | |
| 	.word	LBB_BITTST		; BITTST
 | |
| 	.byte	4,'M'			;
 | |
| 	.word	LBB_MAX		; MAX
 | |
| 	.byte	4,'M'			;
 | |
| 	.word	LBB_MIN		; MIN
 | |
| 	.byte	2,'P'			;
 | |
| 	.word	LBB_PI		; PI
 | |
| 	.byte	5,'T'			;
 | |
| 	.word	LBB_TWOPI		; TWOPI
 | |
| 	.byte	7,'V'			;
 | |
| 	.word	LBB_VPTR		; VARPTR
 | |
| 	.byte	6,'L'			;
 | |
| 	.word	LBB_LEFTS		; LEFT$
 | |
| 	.byte	7,'R'			;
 | |
| 	.word	LBB_RIGHTS		; RIGHT$
 | |
| 	.byte	5,'M'			;
 | |
| 	.word	LBB_MIDS		; MID$
 | |
| 
 | |
| ; BASIC messages, mostly error messages
 | |
| 
 | |
| LAB_BAER
 | |
| 	.word	ERR_NF		;$00 NEXT without FOR
 | |
| 	.word	ERR_SN		;$02 syntax
 | |
| 	.word	ERR_RG		;$04 RETURN without GOSUB
 | |
| 	.word	ERR_OD		;$06 out of data
 | |
| 	.word	ERR_FC		;$08 function call
 | |
| 	.word	ERR_OV		;$0A overflow
 | |
| 	.word	ERR_OM		;$0C out of memory
 | |
| 	.word	ERR_US		;$0E undefined statement
 | |
| 	.word	ERR_BS		;$10 array bounds
 | |
| 	.word	ERR_DD		;$12 double dimension array
 | |
| 	.word	ERR_D0		;$14 divide by 0
 | |
| 	.word	ERR_ID		;$16 illegal direct
 | |
| 	.word	ERR_TM		;$18 type mismatch
 | |
| 	.word	ERR_LS		;$1A long string
 | |
| 	.word	ERR_ST		;$1C string too complex
 | |
| 	.word	ERR_CN		;$1E continue error
 | |
| 	.word	ERR_UF		;$20 undefined function
 | |
| 	.word ERR_LD		;$22 LOOP without DO
 | |
| 
 | |
| ; I may implement these two errors to force definition of variables and
 | |
| ; dimensioning of arrays before use.
 | |
| 
 | |
| ;	.word ERR_UV		;$24 undefined variable
 | |
| 
 | |
| ; the above error has been tested and works (see code and comments below LAB_1D8B)
 | |
| 
 | |
| ;	.word ERR_UA		;$26 undimensioned array
 | |
| 
 | |
| ERR_NF	.byte	"NEXT without FOR",$00
 | |
| ERR_SN	.byte	"Syntax",$00
 | |
| ERR_RG	.byte	"RETURN without GOSUB",$00
 | |
| ERR_OD	.byte	"Out of DATA",$00
 | |
| ERR_FC	.byte	"Function call",$00
 | |
| ERR_OV	.byte	"Overflow",$00
 | |
| ERR_OM	.byte	"Out of memory",$00
 | |
| ERR_US	.byte	"Undefined statement",$00
 | |
| ERR_BS	.byte	"Array bounds",$00
 | |
| ERR_DD	.byte	"Double dimension",$00
 | |
| ERR_D0	.byte	"Divide by zero",$00
 | |
| ERR_ID	.byte	"Illegal direct",$00
 | |
| ERR_TM	.byte	"Type mismatch",$00
 | |
| ERR_LS	.byte	"String too long",$00
 | |
| ERR_ST	.byte	"String too complex",$00
 | |
| ERR_CN	.byte	"Can't continue",$00
 | |
| ERR_UF	.byte	"Undefined function",$00
 | |
| ERR_LD	.byte	"LOOP without DO",$00
 | |
| 
 | |
| ;ERR_UV	.byte	"Undefined variable",$00
 | |
| 
 | |
| ; the above error has been tested and works (see code and comments below LAB_1D8B)
 | |
| 
 | |
| ;ERR_UA	.byte	"Undimensioned array",$00
 | |
| 
 | |
| LAB_BMSG	.byte	$0D,$0A,"Break",$00
 | |
| LAB_EMSG	.byte	" Error",$00
 | |
| LAB_LMSG	.byte	" in line ",$00
 | |
| LAB_RMSG	.byte	$0D,$0A,"Ready",$0D,$0A,$00
 | |
| 
 | |
| LAB_IMSG	.byte	" Extra ignored",$0D,$0A,$00
 | |
| LAB_REDO	.byte	" Redo from start",$0D,$0A,$00
 | |
| 
 | |
| AA_end_basic
 |