; Altirra BASIC - Execution control module
; Copyright (C) 2014 Avery Lee, All Rights Reserved.
;
; Copying and distribution of this file, with or without modification,
; are permitted in any medium without royalty provided the copyright
; notice and this notice are preserved.  This file is offered as-is,
; without any warranty.

;===========================================================================
; Input:
;	P.C		Set to run in direct mode, clear to run in normal mode
;
.proc exec
		ldx		#$ff
		txs
		mwa		runstk memtop2
				
		;reset error number
		mvy		#1 errno

		;if we're running in direct mode, stmcur is already set and we
		;should bypass changing that and checking for line 32768.		
		bcs		direct_bypass
		
		mwa		stmtab stmcur
		
		;reset DATA pointer
		jsr		execRestore

		;skip line number, but stash statement length
new_line:

		;##TRACE "Processing line: $%04X (line=%d)" dw(stmcur) dw(dw(stmcur))
		;##ASSERT dw(stmcur) != 32768
		;##ASSERT dw(stmcur)>=dw(stmtab) and dw(stmcur)<dw(starp)

		;check line number and make sure we're not executing the immediate
		;mode line
		ldy		#1
		lda		(stmcur),y
		bpl		direct_bypass

		;hitting the end of immediate mode does an implicit END
		jmp		stEnd

direct_bypass:
		iny

		;stash statement length
		mva		(stmcur),y+ exLineEnd
loop:
		;check if break has been pressed
		lda		brkkey
		bpl		execStop

		;check if we are at EOL
		cpy		exLineEnd
		bcs		next_line

		;stash statement offset
		lda		(stmcur),y
		sta		exLineOffsetNxt
		iny

		;get statement token
		;##TRACE "Processing statement: $%04X+$%04x -> %y (line=%d)" dw(stmcur) y dw(statementJumpTable+2*db(dw(stmcur)+y))+1 dw(dw(stmcur))
		lda		(stmcur),y+
		sty		exLineOffset
		
		tax
		jsr		dispatch
		
		;skip continuation or EOL token
		ldy		exLineOffsetNxt
		jmp		loop

next_line:
		;check if we're at the immediate mode line already
		ldy		#1
		lda		(stmcur),y
		bmi		hit_end

		;bump statement pointer
		lda		exLineEnd
		ldx		#stmcur
		jsr		VarAdvancePtrX
		jmp		new_line

hit_end:
		jmp		execLoop
		
dispatch:
		;push statement address onto stack
		lda		statementJumpTableHi,x
		pha
		lda		statementJumpTableLo,x
		pha
		
		;execute the statement
		rts
.endp

;===========================================================================
.proc execStop
		mva		#$80 brkkey
		sta		errno

		;load current line number
		ldx		stmcur
		ldy		stmcur+1
		jsr		fld0r

		jmp		errorDispatch
.endp

;===========================================================================
.macro STATEMENT_JUMP_TABLE
		;$00
		dta		:1[stRem-1]
		dta		:1[stData-1]
		dta		:1[stInput-1]
		dta		:1[stColor-1]
		dta		:1[stList-1]
		dta		:1[stEnter-1]
		dta		:1[stLet-1]
		dta		:1[stIf-1]
		dta		:1[stFor-1]
		dta		:1[stNext-1]
		dta		:1[stGoto-1]
		dta		:1[stGoto2-1]
		dta		:1[stGosub-1]
		dta		:1[stTrap-1]
		dta		:1[stBye-1]
		dta		:1[stCont-1]
		
		;$10
		dta		:1[stCom-1]
		dta		:1[stClose-1]
		dta		:1[stClr-1]
		dta		:1[stDeg-1]
		dta		:1[stDim-1]
		dta		:1[stEnd-1]
		dta		:1[stNew-1]
		dta		:1[stOpen-1]
		dta		:1[stLoad-1]
		dta		:1[stSave-1]
		dta		:1[stStatus-1]
		dta		:1[stNote-1]
		dta		:1[stPoint-1]
		dta		:1[stXio-1]
		dta		:1[stOn-1]
		dta		:1[stPoke-1]
		dta		:1[stPrint-1]
		dta		:1[stRad-1]
		dta		:1[stRead-1]
		dta		:1[stRestore-1]
		dta		:1[stReturn-1]
		dta		:1[stRun-1]
		dta		:1[stStop-1]
		dta		:1[stPop-1]
		dta		:1[stQuestionMark-1]
		dta		:1[stGet-1]
		dta		:1[stPut-1]
		dta		:1[stGraphics-1]
		dta		:1[stPlot-1]
		dta		:1[stPosition-1]
		dta		:1[stDos-1]
		dta		:1[stDrawto-1]
		dta		:1[stSetcolor-1]
		dta		:1[stLocate-1]
		dta		:1[stSound-1]
		dta		:1[stLprint-1]
		dta		:1[stCsave-1]
		dta		:1[stCload-1]
		dta		:1[stImpliedLet-1]
		dta		:1[stSyntaxError-1]
		dta		:1[stRem-1]
		dta		:1[stRem-1]
		dta		:1[stRem-1]
		dta		:1[stRem-1]
		dta		:1[stRem-1]
		dta		:1[stRem-1]
		dta		:1[stDpoke-1]
		dta		:1[stRem-1]

		;$40
		dta		:1[stRem-1]
		dta		:1[stRem-1]
		dta		:1[stRem-1]
		dta		:1[stRem-1]
		dta		:1[stRem-1]
		dta		:1[stRem-1]
		dta		:1[stRem-1]
		dta		:1[stFileOp-1]
		dta		:1[stFileOp-1]
		dta		:1[stFileOp-1]
		dta		:1[stDir-1]
		dta		:1[stFileOp-1]
		dta		:1[stMove-1]
.endm

statementJumpTableLo:
		STATEMENT_JUMP_TABLE	<

statementJumpTableHi:
		STATEMENT_JUMP_TABLE	>

;===========================================================================
; Input:
;	A0 (FR0)	Line number (integer)
;	A		Destination pointer
;
; Output:
;	(X)		Line address
;	P.C		Set if found, unset otherwise
;
; If the line is not found, the insertion point for the line is returned
; instead.
;
.proc exFindLineInt
_lptr = iterPtr
		;search for line
		pha
		
		;check if line is >= current line -- if so start there
		ldx		#0
		lda		fr0
		cmp		(stmcur,x)
		ldy		#1
		lda		fr0+1
		sbc		(stmcur),y
		bcc		use_start
		dta		{bit $0100}		;leave X=0 (stmcur-stmtab)
use_start:
		ldx		#$fe
		
		;load pointer
		lda.b	stmcur,x
		sta		_lptr
		lda.b	stmcur+1,x
		sta		_lptr+1			;!! must enter loop with Z=0

		ldx		#0
search_loop:
		lda		(_lptr),y		;load current lineno hi
		cmp		fr0+1			;subtract desired lineno hi
		bcc		next			;cur_hi < desired_hi => next line
		bne		not_found		;cur_hi > desired_hi => not found
		lda		(_lptr,x)
		cmp		fr0
		beq		found
		bcs		not_found
next:
		iny
		lda		_lptr
		adc		(_lptr),y
		dey
		sta		_lptr
		bcc		search_loop
		inc		_lptr+1
		bne		search_loop
		
		;whoops... hit the end!
not_found:
		clc
found:
		pla
		tax
		mwa		_lptr 0,x
.def :ExNop
		rts
.endp

;===========================================================================
; Check if the current token is end of statement/line.
;
; Output:
;	Y = current line offset
;	A = current token
;	P.Z = set if end of statement/line
;
.proc ExecTestEnd
		ldy		exLineOffset
		lda		(stmcur),y
		cmp		#TOK_EOS
		beq		is_end
		cmp		#TOK_EOL
is_end:
		rts
.endp

;===========================================================================
.proc execRestore
		lda		#0
		sta		dataln
		sta		dataln+1
		sta		dataptr+1
		rts
.endp

;===========================================================================
.proc ExecReset
		;silence all sound channels
		ldx		#7
		lda		#0
		sta:rpl	$d200,x-
		
		;close IOCBs 1-7
		ldx		#$70
close_loop:
		jsr		IoCloseX
		txa
		sec
		sbc		#$10
		tax
		bne		close_loop
		rts
.endp
