;---------------------------------------------------------------------------
;
; Ducati 996 Biposto 16M Webber ECU
;
; Assembly language for 68HC11
;
; If you are not familiar with the 68HC11, get the M68HC11RM.pdf
; from Freescale Semiconductor (was Motorola Semiconductor)
;
; The 16M ECU system has a 64KB EPROM but the first 32K is Blank ($ff)
;
;
;---------------------------------------------------------------------------
; The Memory Map is arranged as
;
; 0000 - 003f	Registers
;
; 0040 - 03ff	RAM
;
; 0400		Read from external hardware
;
; 0800		Write to external hardware
;
; 0e00 - 0fff	EEPROM
;
; 8000 - c0cf	Main program code
;
; c0d0 - efff	Special diag code
;
; f000 - ffbf	ROM constants (fuel map, etc)
;
; ffc0 - fffd	Interrupt Vectors

; fffe - ffff	Reset Vector
;


;---------------------------------------------------------------------------
; Hardware Notes
; 
; Port A timer driven IO, Output Compare, Input Capture
; b7	Input/Output
; b6	OC2	Coil1
; b5	OC3	Vertical cylinder injector
; b4	OC4	Coil2
; b3	OC5	Horizontal cylinder injector
; b2	IC1
; b1	IC2
; b0	IC3
;
; Port D data direction
; b7	Input
; b6	Input
; b5	Output
; b4	Input
; b3	Input
; b2	Output
; b1	Output	serial TX
; b0	Input	serial RX
;
; Port E - analog inputs
;
; an7   Air Temp		ADR4
; an6   unknown			ADR3
; an5   not used		ADR2
; an4   Water Temp		ADR1
; an3   Air Pressure		ADR4
; an2   TPS			ADR3
; an1   Battery Voltage		ADR2
; an0   not used		ADR1

; 
;---------------------------------------------------------------------------
; Constants
;
InitRegister	EQU	$103D	; Init register here until remaped to start at 0

XtalFreq	EQU	16000000	; looks like crystal is 16 MHz
E_CLOCK		EQU	(XtalFreq/4)	; E clock is 1/4 of xtal = 4MHz

TimerFreq	EQU	(E_CLOCK / 8)	; Main 16 bit timer, 500KHz
; Period is 2 micro seconds

MaxInjectorDuration	EQU $7D00	; 32000 * 2 / 1000 = 64ms !

; index values for LogDiagError function
LogSensorErrorIdx	EQU $0
LogOutputErrorIdx	EQU $2
LogFunctionErrorIdx	EQU $4

; Flags For var CurrentSensorErrors
TPS_SensorError		EQU %00000001
Pressure_SensorError	EQU %00000010
O2_SensorError		EQU %00000100 ; for cars, O2 feedback disabled in ducati version
WaterTemp_SensorError	EQU %00001000
AirTemp_SensorError	EQU %00010000
BatteryVoltage_SensorError EQU %00100000

; CurrentOutputErrors
Injector_OutputError	EQU %00000001
Coil1_OutputError	EQU %00000010
Coil2_OutputError	EQU %00000100
;Stepper_OutputError	EQU %00001000
;Canister_OutputError	EQU %00010000
AC_OutputError		EQU %00100000
FuelPump_OutputError	EQU %01000000
;Generic_OutputError	EQU %10000000

; CurrentFunctionErrors
RAM_Error		EQU %00000010
ROM_Error		EQU %00000100
EEPROM_Error		EQU %00001000
CPU_Error		EQU %00010000
RevPickup_SensorError	EQU %00100000

; InternalErrors
StackError		EQU %00000001
COP_Timeout		EQU %00000010
BadOpCode		EQU %00000100
UnexpectedISR		EQU %00001000
ClockMonitor_Timeout	EQU %00010000
RAM_Failure2		EQU %00100000
RAM_Failure1		EQU %10000000

; TxFlags
TxFlags_SentIDstring	EQU %00000001
TxFlags_TxPending	EQU %00010000
TxFlags_TxSync		EQU %00100000
TxFlags_NotConnected	EQU %01000000
TxFlags_RxOfCmdComplete	EQU %10000000

; FGSTAT
FGSTAT_WaterTemp	EQU %00000001
FGSTAT_MotorTurning	EQU %00000010
FGSTAT_PositionSensorOK	EQU %00000100
FGSTAT_TPS_MinOrMax	EQU %00001000	; butterfly in minim or flood opening
FGSTAT_O2_LoopClosed	EQU %00010000
FGSTAT_AC_On		EQU %00100000	; not used,  Air Conditionion on - always on on a moto!
FGSTAT_AutoTrim		EQU %01000000	; not sure --
FGSTAT_StepperTest	EQU %10000000	; execution of stepper test is active 

; Flag01
SkipFirstPickupCheck	EQU %00000100

; Flag02
InjectorsDisabled	EQU %00010000

; Flag04
Coil2_Error		EQU %00000100
Coil1_Error		EQU %01000000

; Flag08
CheckCoil1Flag		EQU %00000001
CheckCoil2Flag		EQU %00000010

; InjectorFlags
Timer131ms		EQU %01000000
HorizInjectorOffTimePending EQU %00000010

; O2Flags
O2_LoopClosed		EQU %00010000

; Flag08
TimerOverflowCaught	EQU %00100000

; Flag17
NewInputCapture2	EQU %00100000
NewRev			EQU %00001000

; Flag15
MotorRunning1		EQU %00000001
MotorRunning2		EQU %00000010
TPS_Closed		EQU %01000000
TPS_WideOpen		EQU %10000000

; Flag27
RequestClearDiagErrors	EQU %00000100


; Flag28
DiagTestStarted		EQU %00000001
DiagTestInProgress	EQU %00000010
Diag_8E_TestFlag	EQU %00000100
DiagStoreTPSFlag	EQU %00001000
DiagCancelTest		EQU %00010000

; PORTA_DataReg
HorizInjectorBit	EQU %00001000
Coil2Bit		EQU %00010000
VertInjectorBit		EQU %00100000
Coil1Bit		EQU %01000000

; PORTD_DataReg
TxBit			EQU %00000010
RxBit			EQU %00000001

; HardwarePort_write
FuelPumpBit		EQU %00010000
RevCounterBit		EQU %00001000

;---------------------------------------------------------------------------
; bit constants for registers
SCSR_RxComplete	EQU	%01000000
SCSR_RxChar	EQU	%00100000
SCSR_RxError	EQU	%00001110

SCCR2_TxISR_Enable	EQU %10000000
SCCR2_TxCompleteISR_Enable EQU %01000000
SCCR2_RxISR_Enable	EQU %00100000
SCCR2_TxEnable		EQU %00001000
SCCR2_RxEnable		EQU %00000100

TMSK1_OC2		EQU %01000000
TMSK1_OC3		EQU %00100000
TMSK1_OC4		EQU %00010000
TMSK1_OC5		EQU %00001000
TMSK1_IC2		EQU %00000010

TFLG1_OC2		EQU %01000000
TFLG1_OC3		EQU %00100000
TFLG1_OC4		EQU %00010000
TFLG1_OC5		EQU %00001000
TFLG1_IC1		EQU %00000100
TFLG1_IC2		EQU %00000010
TFLG1_IC3		EQU %00000001

; CFORC reg
FORCE_OC1		EQU %10000000
FORCE_OC2		EQU %01000000	; coil 1
FORCE_OC3		EQU %00100000	; horiz injector
FORCE_OC4		EQU %00010000	; coil 2
FORCE_OC5		EQU %00001000	; vert injector

; TCTL1
TCTL1_OM2		EQU %10000000
TCTL1_OL2		EQU %01000000
TCTL1_OM3		EQU %00100000
TCTL1_OL3		EQU %00010000
TCTL1_OM4		EQU %00001000
TCTL1_OL4		EQU %00000100
TCTL1_OM5		EQU %00000010
TCTL1_OL5		EQU %00000001

PPROG_EEPGM		EQU %00000001
PPROG_EELAT		EQU %00000010
PPROG_ERASE		EQU %00000100
PPROG_BYTE		EQU %00010000


;
; ---------------------------------------------------------------------------------
; MACROS

SetupForCalcMapNdxFrac	Macro	input, tbl_address, tbl_size
	ldX	#tbl_address
	ldaB	#tbl_size
	decB			; index of last entry
	lslB			; *2 for word table
	aBX			; get address
	clrA			
	lsrB			; back to index	
	xgDY			; put in Y	
	ldD	>input
	Endm

CalcMapNdxFrac	Macro	input, tbl_address, tbl_size
	SetupForCalcMapNdxFrac	input, tbl_address, tbl_size
	call	DoCalcMapNdxFrac
	Endm

ReadExtraPort Macro
	pushA	
	ldaA	HardwarePort_read
	staA	HardwarePortInValue
	popA	
	Endm

WriteExtraPort Macro
	pushA	
	ldaA	ExtraPortOutShadow
	staA	HardwarePort_write
	popA	
	Endm

SetExtraPortBit Macro bitMask
	bset	ExtraPortOutShadow, bitMask
	WriteExtraPort bitMask
	Endm

ClearExtraPortBit Macro bitMask
	bclr	ExtraPortOutShadow, bitMask
	WriteExtraPort bitMask
	Endm


;
; ---------------------------------------------------------------------------------
; Registers are remapped to 0000
;

PORTA_DataReg		=	$0000
DDRA_DataDirectionReg 	=	$0001
PIOC_ParallelIOcontrolReg =	$0002
PORTC_DataReg		=	$0003
PORTB_DataReg		=	$0004
PortF_DataRegister	=	$0005 ; but used as address bus
ReservedRegister_6 	=	$0006
DDRC_DataDirectionReg	=	$0007
PORTD_DataReg 		=	$0008
DDRD_DataDirectionReg	=	$0009
PORTE_DataReg		=	$000A
CFORC_ForceOutputCompareReg =	$000B
OC1Mregister 		=	$000C
OC1Dregister 		=	$000D
TCNT_TimerCountReg 	=	$000E
TIC1_TimerCaptureReg 	=	$0010
TIC2_TimerCaptureReg 	=	$0012
TIC3_TimerCaptureReg 	=	$0014
TOC1_TimerCaptureReg 	=	$0016
TOC2_TimerCompareReg 	=	$0018
TOC3_TimerCompareReg 	=	$001A
TOC4_TimerCompareReg 	=	$001C
TOC5_TimerCompareReg 	=	$001E
TCTL1_TimerControlReg 	=	$0020
TCTL2_TimerControlReg 	=	$0021
TMSK1_TimerInterruptMask1Reg =	$0022
TFLG1_TimerInterruptFlag1Reg =	$0023
TMSK2register 		=	$0024
TFLG2register 		=	$0025
PACTL_PulseAccumulatorControlReg = $0026
PACNT_PulseAccumulatorCountReg	 = $0027
SPCRregister 		=	$0028
SPSRregister 		=	$0029
baud_Register 		=	$002B
SCCR1_SerialControlReg	=	$002C
SCCR2_SerialControlReg	=	$002D
SCSR_SerialStatusReg	=	$002E
SCDR_SerialDataReg	=	$002F
ADCtlRegister		=	$0030
ADR1Register		=	$0031
ADR2Register		=	$0032
ADR3Register		=	$0033
ADR4Register		=	$0034
BProtRegister		=	$0035
EProgRegister		=	$0036	; not on all h/w
OptionRegister		=	$0039
CopRstRegister		=	$003A
PPROG_EEPROM_ProgramReg	=	$003B
HPRIOregister		=	$003C
ConfigRegister 		=	$003F

CSCTL_ChipSelect	=	$005D



;
;-----------------------------------------------------------------------
; RAM Variables
;
; mem from here to SpecialDiagClearStart: is not cleared when entering special diag mode
;
; Notes on variable names
; -----------------------
;
; NdxFrac	Used as a basis for a table lookup.
;		Index byte (usually a 16 byte table) and a fraction byte /$100 of
;		the difference between the table values.
; 
; BreakPoints	Converting a value is a 2 step process. A break point table is used
;		to reduce the value to an index and a fraction
;
; Idx		Simple index to an array of values
;
; Raw		Is the value read from an analog to digital input.
;
; Current	Is the value after checking and maybe scaled with a table lookup.
;

	org	$60

ClearedOnStartupArea:

HardwarePortInValue:
	DS	1
ExtraPortOutShadow:
	DS	1
DiagMode:
	DS	1
SCI_ISR_Time:
	DS	2

DiagStateIdx:		; index for Diag state Function table
	DS	1

Diag_c:
	DS	1
DiagConnectFuncIdx:
	DS	1
DiagCmdCheckChar:
	DS	1
PreviousCharTime:
	DS	2

Vec4FunctionIdx:
	DS	1
Vec4Var_a:	DS	1
Vec4Var_b:	DS	1
Vec4Var_c:	DS	1
Vec4Var_d:	DS	1
DiagCmdRxCount:
	DS	1

DiagDataIdx:
	DS	1

L0072:
	DS	2

DiagCmdRxBuff:
	DS	12
	
;---------------------------------------------------------------------------
SpecialDiagClearStart:
SavedVariableArea:
	DS	6		; Sig check bytes - to see if RAM has been previously inited
	
TPS_LearnedClosedThrottle:
	DS	1
TPS_LearnedWideOpenThrottle:
	DS	1

FirstTimeSensorErrors:
	DS	1
FirstTimeOutputErrors:
	DS	1
FirstTimeFunctionErrors:
	DS	1

CurrentSensorErrors:
	DS	1

SensorHiLowErrors:
	DS	1

CurrentOutputErrors:
	DS	1
OutputHiLowErrors:
	DS	1
CurrentFunctionErrors:
	DS	1
FunctionErrorFlags:
	DS	1
Flag34:
	DS	1
Flag35:
	DS	1
InternalErrors:
	DS	1
L0094:	DS	1
L0095:	DS	2
	DS	1
L0098:	DS	1
L0099:	DS	1
O2FuelTrim_a:
	DS	1
L009B:	DS	1

ResetCount:
	DS	1
Flag33:
	DS	1
	DS	1

StepperPosition:
	DS	1

	DS	1
Flag30:
	DS	1

EndSavedVariableArea:
;---------------------------------------------------------------------------
	
SavedVariableAreaInited:
	DS	1

EndClearedOnStartupArea:
StartOfNonRestoredArea:
TempSaveArea:

;---------------------------------------------------------------------------
Flag01:
	DS	1
Flag02:
	DS	1
Flag03:
	DS	1
Flag04:
	DS	1
Flag05:
	DS	1
Flag06:
	DS	1
InjectorFlags:
	DS	1
Flag08:
	DS	1
O2Flags:
	DS	1
Flag10:
	DS	1
Flag11:
	DS	1
Flag12:
	DS	1
Flag13:
	DS	1
Flag14:
	DS	1
Flag15:
	DS	1
Flag16:
	DS	1
Flag17:
	DS	1
Flag18:
	DS	1
Flag19:
	DS	1
Flag20:
	DS	1
Flag21:
	DS	1
Flag22:
	DS	1
Flag23:
	DS	1
Flag24:
	DS	1
Flag25:
	DS	1
Flag26:
	DS	1
Flag27:
	DS	1
Flag28:
	DS	1
TxFlags:
	DS	1
L00C0:	DS	1
FGSTAT:
	DS	1
L00C2:	DS	1

RPM_Spark_always_005A:
	DS	2

L00C5:	DS	2

InjectorOpeningTime:		; time in 2 microsecond steps
				; Injector duration times below do not include
				; the opening time, which is mostly
				; dependent on battery votalge
	DS	2

HorizCurrentFuelValue:
	DS	2

HorizInjectorDuration:		; time in 2 microsecond steps
	DS	1
HorizInjectorDuration_lsB:
	DS	1

VertCurrentFuelValue:
	DS	2

VertInjectorDuration:		; time in 2 microsecond steps
	DS	2

CurrentVertCylinderTrim:
	DS	2
UntrimmedCurrentFuelValue:
	DS	2
Timer5_Interval2:
	DS	2
CurrentFuelValue:
	DS	1
CurrentFuelValue_lsB:
	DS	1
O2FuelTrim:
	DS	1
WaterTempTrim:
	DS	1
AirTempTrim:
	DS	1
AltitudeTrim:
	DS	1
L00DD:	DS	2
InputCapture3Time:	DS	1
L00E0:	DS	1
L00E1:	DS	2
	DS	1
L00E4:	DS	1
L00E5:	DS	1
L00E6:	DS	1
InputCapture2_SubValue:
	DS	2
L00E9:	DS	2
L00EB:	DS	2
L00ED:	DS	1
L00EE:	DS	1
InputCapture2_StoredValue:
	DS	2
L00F1:	DS	2
SparkAdvance:
	DS	1
O2FuncIdx:
	DS	1
O2_Var2:
	DS	1

TimerOverflowCount1:
	DS	1
L00F7:	DS	2

CurrentRevs:		; time in microseconds for 1/4 revolution
	DS	1	; (60 * 1e6 * 1/4 ) / Revs = RPM
CurrentRevs_lsB:
	DS	1

L00FB:	DS	1

CurrentAtmPressure:
	DS	2

Scratch5:
	DS	1
Scratch5_lsB:
	DS	1
L0100:	DS	1
Revs_c:	DS	1
Revs_d:	DS	1
Revs_e:	DS	1

CurrentRevs_b:
	DS	2

RPM_SparkMapNdxFrac:
	DS	2

RPM_SparkTableNdxFrac:
	DS	2

RPM_FuelMapNdxFrac:
	DS	2

AltitudeNdxFrac:
	DS	2

TPS_MinusClosedOffset:	DS	1
RevsDerivedSubstituteTPS:
	DS	1
L0110:	DS	1
Revs5_7:
	DS	1
AirTemp2:
	DS	1
WaterTemp6:
	DS	1
RevsByWaterTemp:
	DS	2
L0116:	DS	1
L0117:	DS	1
L0118:	DS	2

FuelAdjValue:
	DS	2

L011C:	DS	2
Revs4:	DS	1
Revs6:	DS	1
RPM_TPS_Check:
	DS	2
L0122:	DS	1
L0123:	DS	2
L0125:	DS	2
RevsDiv180:
	DS	1
L0128:	DS	1
L0129:	DS	2
L012B:	DS	2
L012D:	DS	2
L012F:	DS	2
L0131:	DS	1
L0132:	DS	2
L0134:	DS	2
L0136:	DS	1
L0137:	DS	1
L0138:	DS	1
L0139:	DS	1
Mult_lsB:
	DS	2
Scratch1:
	DS	2
	DS	2
L0140:	DS	1
WaterTempValue:
	DS	1
FilteredRevs:
	DS	1
L0143:	DS	1
L0144:	DS	2
L0146:	DS	1
L0147:	DS	1
BatteryVoltageSomething1:
	DS	1
L0149:	DS	1
L014A:	DS	1
CurrentSparkAdvance:
	DS	1
L014C:	DS	1
L014D:	DS	1
O2_Var1:
	DS	2
L0150:	DS	1
L0151:	DS	1
L0152:	DS	1
L0153:	DS	1
L0154:	DS	1
L0155:	DS	1
L0156:	DS	2
L0158:	DS	2

PickupFaultCount:
	DS	1

L015B:	DS	1
L015C:	DS	2
L015E:	DS	2
L0160:	DS	2
L0162:	DS	2
TimerOverflowCount2:
	DS	1
PreviousInputCapture3Time:
	DS	2
InputCapture3DifferenceOverflow:	; msb of word below
	DS	1
InputCapture3Difference:
	DS	1
L0169:	DS	1
L016A:	DS	1
L016B:	DS	1
L016C:	DS	1
L016D:	DS	2
L016F:	DS	1
L0170:	DS	20

L0184:	DS	1
	DS	1
L0186:	DS	1
L0187:	DS	1
L0188:	DS	1
	DS	18
L019B:	DS	1
V019C:	DS	2
L019E:	DS	2
OutputCompare2Interval:
	DS	2
L01A2:	DS	2
	DS	1
L01A5:	DS	1
L01A6:	DS	2
L01A8:	DS	2
OutputCompare4Interval:
	DS	2
L01AC:	DS	2
	DS	1
L01AF:	DS	1
L01B0:	DS	1
L01B1:	DS	1
L01B2:	DS	1
L01B3:	DS	1
L01B4:	DS	1
L01B5:	DS	2
L01B7:	DS	1
L01B8:	DS	1
L01B9:	DS	2
L01BB:	DS	2
L01BD:	DS	1
L01BE:	DS	1
L01BF:	DS	1
L01C0:	DS	1
L01C1:	DS	1
	DS	1
	DS	1
L01C4:	DS	1
L01C5:	DS	1
L01C6:	DS	1
L01C7:	DS	1
L01C8:	DS	2
StartingPulseCountdown:
	DS	1
L01CB:	DS	2
BatteryVoltageSomething2:
	DS	1
L01CE:	DS	1
L01CF:	DS	1

AirTempNdxFrac:
	DS	2
WaterTempNdxFrac:
	DS	2

ScaledBatteryVoltage:
	DS	2
BatteryVoltageNdxFrac:
	DS	2

TPS_SparkMapNdxFrac:
	DS	2

TPS_FuelMapNdxFrac:
	DS	2
	
WaterTemp_Value1:
	DS	1

L01DD:	DS	1
L01DE:	DS	2
L01E0:	DS	1
L01E1:	DS	2
L01E3:	DS	1
WaterTemp_Value2:
	DS	1
L01E5:	DS	1
L01E6:	DS	2
TestModeCounter:
	DS	1
Vec1TableIndex:
	DS	1
ResetFlag:
	DS	1
	DS	1
DiagCommand:
	DS	1
TxHold:
	DS	1

DiagCountdownTimer:
	DS	2

DiagResetCountdown:
	DS	1
DiagTestCountdown:
	DS	1
DiagTestPulseDuration:
	DS	2
PickupFaultCompareCount:
	DS	1

O2Var1:	DS	2
O2Var2:	DS	2

RomChecksumIdx:
	DS	2
RomChecksumSum:
	DS	2

WaterTempSomething:
	DS	2

ErrorBitIndex:		; which error
	DS	1
ErrorCountdown:		; repeat count before written to eeprom
	DS	1

L0201:	DS	1
L0202:	DS	1
L0203:	DS	2
L0205:	DS	2
DiagSlowInitCounter:
	DS	1
Scratch6:
	DS	1
	DS	1
	DS	1
L020B:	DS	2
Scratch4:
	DS	2
	DS	1
Scratch3:
	DS	1
Scratch3_low:
	DS	1
	DS	1
FilteredWaterTemp:
	DS	2
FilteredAirTemp:
	DS	2

FilteredWaterTempNdxFrac:		; not used
	DS	2
FilteredAirTempNdxFrac:		; not used
	DS	2

BatteryVoltage_a:
	DS	1
	DS	1
	DS	2
	DS	1
StepperIntergral:
	DS	1
	DS	2
	DS	1
StepperProportional:
	DS	1
	DS	1
	DS	1
TPS_Voltage:
	DS	1
TPSLookupTableIdx:
	DS	1
TPS_Trim:
	DS	1
CurrentTPS:
	DS	2
L022C:	DS	2
L022E:	DS	2
L0230:	DS	2
TPS_VoltgePrevious:
	DS	1
Filtered_TPS_Voltage2:
	DS	2
Filtered_TPS_Voltage3:
	DS	2

WaterTempOffset	EQU	55
CurrentWaterTemp:		; deg C = CurrentWaterTemp - 55
	DS	1
	
CurrentAirTemp:
	DS	1

; raw values are direct from the A to D
WaterTemp_raw:
	DS	1
AirTemp_raw:
	DS	1
Analog00:
	DS	1	; not used
BatteryVoltage_raw:
	DS	1
FuelTrimpot_raw:
	DS	1
AtmPressure_raw:
	DS	1
FilteredTPS:
	DS	2
TPS_raw:
	DS	1
Filtered_TPS_Voltage1:
	DS	2
Filtered_TPS_Voltage2a:
	DS	1
Filtered_TPS_Voltage3a:
	DS	1
TPS_Value_02or03:
	DS	1
TPS_ValueAlways_02:
	DS	1
L0248:	DS	1
L0249:	DS	1
L024A:	DS	1
L024B:	DS	1
L024C:	DS	1
L024D:	DS	1
FilteredBatteryVoltage:		; * 0.0625 = V
	DS	2
ScaledFuelTrimpot:
	DS	1
PowerOnFuelTrimpot:
	DS	1
L0252:	DS	1
L0253:	DS	1
L0254:	DS	1
L0255:	DS	1
CopyToEEPROM_Count:
	DS	1

EEPROM_WriteBuffer:
	DS	1
	DS	1
	DS	1
	DS	1
	DS	12
EEPROM_Status2:
	DS	1
EEPROM_Status1:
	DS	1
CopyToEEPROM_SourceAddr:
	DS	2
EEPROM_DestAddr:
	DS	2

; ROM InitialisedVarValues: are copied to here
InitVarCopyDest:

FuelTrimOffset:
	DS	1		; $00
RawFuelTrimpotScale:
	DS	1		; $82
L026F:	DS	1		; $00
L0270:	DS	1		; $80
	DS	1		; $00
	DS	1		; $00
	DS	1		; $00
L0274:	DS	1		; $B0
	DS	1		; $00
	DS	1		; $80
	DS	1		; $00
	DS	1		; $00
	DS	1		; $00
	DS	1		; $00
	DS	1		; $53
	DS	1		; $A8

Diag_Errors:
SavedSensorErrors:
	DS	1
SavedSensorHiLowErrors:
	DS	1
SavedOutputErrors:
	DS	1
SavedOutputHiLowErrors:
	DS	1
SavedFunctionErrors:
	DS	1
SavedFunctionErrorFlags:
	DS	1

StartEnrichmentCounter:
	DS	2
StartEnrichmentValue:
	DS	1
StartEnrichmentNdxFrac:
	DS	2
	
L0288:	DS	1
L0289:	DS	128
L0309:	DS	16
L0319:	DS	16
L0329:	DS	7
L0330:	DS	78
L037E:	DS	1

SpecialDiagClearEnd:
	DS	80
	
StackTop:
	DS	1

IsrJumpTableDest:
	DS	3		; SCI
	DS	3		; SPI (not used)
	DS	3		; Pulse Acc input edge (not used)
	DS	3		; Pulse Acc overflow
	DS	3		; Timer overflow
	DS	3		; OutputCompare 5
	DS	3		; OC 4
	DS	3		; OC 3
	DS	3		; OC 2
	DS	3		; OC 1 (not used)
	DS	3		; InputCapture 3 (not used)
	DS	3		; InputCapture 2
	DS	3		; InputCapture 1 (not used)
	DS	3		; Real-time
	DS	2
Scratch2:	
	DS	1		; IRQ (external pin)
	DS	3		; XIRQ

RAM_END:

	if	(RAM_END != $0400)
	error	"RAM area size wrong"
	endif

HardwarePort_read:		; $400
	DS	$400
HardwarePort_write:		; $800
	DS	$600

StartEEPROM:		; $0E00
	DS	7

L0E07:	DS	2
L0E09:	DS	7

L0E10:
	DS	$70
	
L0E80:
	DS	16
L0E90:
	DS	$70

L0F00:
	DS	16

DiagErrorsInEEPROM:
	DS	2	; sensor

	DS	2	; output
L0F14:
	DS	2	; function

	DS	10

L0F20:	DS	16
L0F30:	DS	16
L0F40:	DS	2
L0F42:	DS	2
L0F44:	DS	1
L0F45:	DS	1
L0F46:	DS	1
L0F47:	DS	9
L0F50:	DS	48

L0F80:	DS	1
StoredTPS_Trim:
	DS	1
	DS	1
L0F83:	DS	1
L0F84:	DS	1
	DS	8
EEPROM_Inited:
	DS	1
	DS	2
L0F90:	DS	47
L0FBF:	DS	1
L0FC0:	DS	6
L0FC6:	DS	9
L0FCF:	DS	1
L0FD0:	DS	1
	DS	47
BBRAM_end:			; should be $1000, ie RAM to $0FFF

	if	(BBRAM_end != $1000)
	error	"BBRAM area size wrong"
	endif

	;	Fill first 32K with FF's 
	; 	to match original EPROM
	org	$0000
	FILL	$ff, $8000

;---------------------------------------------------------------------------
;	Main Entry
;---------------------------------------------------------------------------
	org	$8000

EPROM_Start:

PwrOnReset:
	ldaA	#$FF
	staA	ResetFlag
WarmReset:
	di	
	ldS	#StackTop
	ldaA	#$00
	staA	InitRegister	; RAM starts at addr 0, Registers start at addr 0

	ldaA	#%10111011 
	staA	OptionRegister	; 1 = A to D powered on
				; 0 = A/D and EEPROM charge pumps use system E clock
				; 1 = IRQ Falling edge recognition
				; 1 = Osc Stabilization delay enabled on exit from stop mode
				; 1 = Slow or stopped clocks cause clock failure reset
				; 0 = unused bit
				;11 = slow COP timeout

	ldaA	#$02
	staA	TMSK2register	; disable interrupt sources, timer prescaler div by 8

	ldaA	#$10
	staA	BProtRegister	; Protect CONFIG register, disable EEPROM protect
	
	ldaA	#%10101101
	staA	CSCTL_ChipSelect	; 1 = CSIO1 enabled
					; 0 = CSIO1 active low
					; 1 = CSIO2 enabled
					; 0 = CSIO2 active low
					; 1 = General-purpose chip-select has priority
					;     over program chip-select
					; 1 = CSPROG enabled
					;01 = Program Chip Select Size is $8000 - $FFFF
	clrA	
	staA	TCTL1_TimerControlReg	; Timer disconnected from output pin logic
	staA	TMSK1_TimerInterruptMask1Reg		; Timer i/o interrupts disabled
	staA	PORTA_DataReg
	staA	PIOC_ParallelIOcontrolReg
					; 0 = STAF does not request interrupt
					; 0 = Port C outputs are normal CMOS outputs.
					; 0 = Simple strobe mode handshake
					; 0 = STRA falling edge selected for Strobe A
					; 0 = Active level is logic 0. for Strobe B
	
	ldaA	#%00000100		; guess this bit is the latch that holds the ECU relay on
	staA	ExtraPortOutShadow
	WriteExtraPort 
	ldaA	#%00000010
	staA	PORTD_DataReg
	ldaA	#$78
	staA	DDRA_DataDirectionReg
	ldaA	#%00100110		; 1 is output, 0 is input
	staA	DDRD_DataDirectionReg
	ldaA	#%00001000
	staA	PORTC_DataReg
	ldaA	HPRIOregister
	andA	#%11100000
	oraA	#%00000001
	staA	HPRIOregister		; Pulse accumulator overflow highest priority
	ldaA	ResetFlag
	bne	PwrOnInit
	jmp	SkipPwrOnInit
;
PwrOnInit:
	call	ResetCOPtimer
	clr	>InternalErrors
	ldaA	SavedVariableAreaInited
	cmpA	#$0F
	bne	@no				; inited ?
	ldX	#SavedVariableArea		; yes, save area in higher memory
	ldY	#TempSaveArea
	ldaB	#(EndSavedVariableArea - SavedVariableArea) ; $22
	call	MemCopy_XtoY_1
	clr	>SavedVariableAreaInited
@no	ldY	#Scratch2
	ldX	#EndClearedOnStartupArea
	stX	0, Y
	ldX	#ClearedOnStartupArea
	call	RamTestAndClear
	beq	@ok1
	; else bad ram
	call	InitSavedVariableAreaFromRom
	bset	InternalErrors, #RAM_Failure1
	jr	@cont
;
@ok1	call	ResetCOPtimer
	ldX	#TempSaveArea			; restore
	ldY	#SavedVariableArea
	ldaB	#(EndSavedVariableArea - SavedVariableArea) ; $22
	call	MemCopy_XtoY_1
	ldaA	#$0F
	staA	SavedVariableAreaInited
	ldD	#$0006
	ldY	#SavedVariableAreaInitialValues		; compare first 6 bytes with ROM
	ldX	#SavedVariableArea
@loop	ldaA	0, X
	cmpA	0, Y
	bne	@Corrupted
	incX	
	incY	
	decB	
	bne	@loop
	jr	@ok2
;
@Corrupted:
	clr	>FirstTimeFunctionErrors
	clr	>CurrentFunctionErrors
	call	InitSavedVariableAreaFromRom

@ok2:
@cont:
	ldS	#RAM_END-1
	ldX	#Scratch2
	ldY	#Scratch2
	stX	0, Y
	ldX	#StartOfNonRestoredArea
	call	RamTestAndClear
	beq	@ok3
	; else bad ram
	bset	InternalErrors, #RAM_Failure2
@ok3	ldS	#StackTop
	call	ResetCOPtimer
	ldaA	#$FF
	staA	ResetFlag
	brclr	InternalErrors, #RAM_Failure2, L80F5

	ldX	#StartOfNonRestoredArea
L80E6	clr	0, X
	incX	
	cmpX	#RAM_END-1
	bls	L80E6

	brclr	InternalErrors, #RAM_Failure1, L80F5
	call	ClearSavedDiagError
L80F5	ldaA	LF710
	staA	L0201
	ldaA	LF711
	lslA	
	staA	L0202
	bset	Flag02, #%00001000
	ldaA	#$FF
	staA	Flag03
	bset	Flag02, #%00000100
	ldaA	#$20
	staA	L00C0
	ldX	#DiagErrorsInEEPROM
	ldY	#Diag_Errors
	ldaB	#$06
	call	MemCopy_XtoY_1
	clrA	
	clrB	
	staA	Flag30
	staA	L00C2
	stD	L0203
	stD	L0205
	ldaA	StoredTPS_Trim
	staA	TPS_Trim
	ldaA	L0F83
	staA	StepperProportional
	ldaA	L0F84
	staA	L0288
	ldX	#IsrJumpTable1
	ldY	#IsrJumpTableDest
	ldaB	#(IsrJumpTable1_end - IsrJumpTable1)  ; $D0
	call	MemCopy_XtoY_1
	ldaA	#$01
	call	Vec1Entry_01
	bclr	Flag33, #%01000000
	bclr	Flag33, #%10000000
	call	LB492
	ldaA	LF699
	subA	#$0C
	staA	L0137
	ldaA	LF698
	subA	#$0C
	staA	L0136
	ldaA	L0137
	subA	L0136
	ldaB	#$0F
	mul	
	stD	L0132
	ldD	#$02D0
	subD	L0132
	stD	L0134
	ldD	StartEnrichmentInitialCount
	stD	StartEnrichmentCounter
	
SkipPwrOnInit:
	ldaA	#$14		; selects inputs 4 - 7
	staA	ADCtlRegister
	inc	>ResetCount
	call	InitComms
	ldD	#$FFFF
	stD	WaterTempSomething
	stD	O2Var1
	stD	O2Var2

	; Get initial values from analog inputs
@waitForConversion1
	ldaA	ADCtlRegister
	bpl	@waitForConversion1
	ldaA	ADR1Register
	staA	WaterTemp_raw
	ldaA	ADR3Register
	staA	FuelTrimpot_raw
	staA	ScaledFuelTrimpot
	staA	PowerOnFuelTrimpot
	ldaA	ADR4Register
	staA	AirTemp_raw
	ldaA	#$10		; selects inputs 0 - 3
	staA	ADCtlRegister
	SetExtraPortBit #%10000000
	
@waitForConversion2
	ldaA	ADCtlRegister
	bpl	@waitForConversion2
	ldaA	ADR2Register
	staA	BatteryVoltage_raw
	ldaA	ADR3Register
	staA	TPS_raw
	call	ProcessTPS
	clrB	
	stD	Filtered_TPS_Voltage1
	stD	Filtered_TPS_Voltage2
	stD	Filtered_TPS_Voltage3
	staA	Filtered_TPS_Voltage2a
	staA	Filtered_TPS_Voltage3a
	staA	TPS_VoltgePrevious
	ldaA	ADR4Register
	staA	AtmPressure_raw
	clrB	
	stD	>CurrentAtmPressure
	call	CheckPressureSensor
	call	CheckAirTempSensor
	ldaA	AirTemp_raw
	clrB	
	stD	FilteredAirTemp
	call	CheckWaterTempSensor
	ldaA	WaterTemp_raw
	clrB	
	stD	FilteredWaterTemp

MotorStopped1					; jumps to here
	ldaA	#$00
	staA	>O2FuncIdx
	staA	O2Flags
	ldaA	#%01000000
	staA	Flag13
	ldaA	#%10000000
	staA	Flag16
	ldaA	TPS_LearnedClosedThrottle
	cmpA	TPS_CompareLow
	bhi	@RangeError
	ldaA	TPS_LearnedWideOpenThrottle
	cmpA	TPS_CompareHigh
	bcs	@RangeError
	ldaA	L0098
	cmpA	LF73C
	bhi	@RangeError
	cmpA	LF73B
	bcs	@RangeError
	ldaA	L0099
	cmpA	LF73C
	bhi	@RangeError
	cmpA	LF73B
	bcs	@RangeError
	ldaA	O2FuelTrim_a
	cmpA	O2TrimMax
	bhi	@RangeError
	cmpA	LF73D
	bcc	L8244
@RangeError:
	call	InitSavedVariableAreaFromRom
L8244	brclr	InternalErrors, #RAM_Failure2, L8259
	bclr	InternalErrors, #RAM_Failure2
	brset	FirstTimeFunctionErrors, #RAM_Error, L8254
	bset	FirstTimeFunctionErrors, #RAM_Error
	jr	L8263
;
L8254	bset	CurrentFunctionErrors, #RAM_Error
	jr	L8263
;
L8259	brclr	Flag02, #%00000100, L8263
	bclr	FirstTimeFunctionErrors, #RAM_Error
	bclr	CurrentFunctionErrors, #RAM_Error
L8263	bclr	Flag02, #%00000100


MotorStopped2					; jumps to here
	ldD	#$0000
	stD	L0248
	stD	L024B
	staA	Flag11
	staA	Flag12
	tst	EEPROM_Status2
	bne	L8283
	ldD	#StartEEPROM
	stD	EEPROM_DestAddr
	ldaA	#$10
	staA	CopyToEEPROM_Count
L8283	ldD	#$0000
	stD	RPM_SparkMapNdxFrac
	stD	RPM_SparkTableNdxFrac
	stD	AltitudeNdxFrac
	stD	StartEnrichmentNdxFrac
	staA	Revs_d
	staA	Revs_e
	stD	CurrentRevs_b
	stD	>RPM_Spark_always_005A ; except 0 at power on!
	stD	L0123
	stD	L0125
	stD	RevsDiv180
	stD	L012B
	stD	L012D
	stD	L012F
	staA	Mult_lsB
	staA	Flag21
	ldD	#$8000
	call	L8D53
	call	L8D2C
	ldD	InjectorOpeningTimeTable
	stD	>InjectorOpeningTime
	call	CheckBatteryVoltage
	ldX	#Scratch4
	ldaB	L0270
	staB	0, X
	ldaB	L026F
	call	AddABmultX0mult2
	ldaB	#$84
	mul	
	lslD	
	bcc	L82DD
	ldaA	#$FF
L82DD	clrB	
	stD	FilteredBatteryVoltage
	call	ProcessBatteryVoltage
	ldD	ScaledBatteryVoltage
	ldY	#BatteryTable1
	call	InterpolateValue
	staA	BatteryVoltageSomething1
	ldD	#$FFFF
	stD	>CurrentRevs
	staA	L01A2
	staA	L01AC
	ldD	#$0000
	stD	L020B
	staA	Flag15
	staA	Flag05
	staA	Flag17
	staA	Flag18
	bset	Flag18, #%00000001
	staA	Flag19
	staA	Flag06
	staA	InjectorFlags
	staA	Flag08
	staA	Flag10
	staA	Flag22
	staA	>L00E5
	staA	>L00E6
	staA	L016F
	staA	L0186
	ldD	#L0170
	stD	L016D
	ldD	#$0187
	stD	L0184
	ldD	ScaledBatteryVoltage
	ldY	#BatteryTable2
	call	InterpolateValue
	staA	BatteryVoltageSomething2
	ldaB	#$28
	mul	
	stD	>L00EB
	stD	>L00ED
	stD	L01CB
	ldaA	#$03
	staA	StartingPulseCountdown
	ldaA	DefaultSparkAdvance
	staA	>SparkAdvance
	clrB	
	stD	L0144
	clrA	
	staA	Flag10
	staA	Flag24
	staA	L0147
	ldaA	#$A0
	staA	L01CE
	staA	L01CF
	ldD	#$FF00
	stD	L0149
	ldD	L0099
	ldaA	#$80
	staA	>AltitudeTrim
	ldD	#$0000
	staA	>AirTempTrim
	staA	>WaterTempTrim
	stD	>CurrentFuelValue
	stD	>HorizInjectorDuration
	stD	>HorizCurrentFuelValue
	ldD	#$0000
	staA	Flag20
	staA	L01E3
	ldD	WaterTempNdxFrac
	ldY	#WaterTemp_Table1
	call	InterpolateValue
	staA	WaterTemp_Value1
	bclr	InjectorFlags, #%00100000
	ldaA	#$80
	staA	L01E0
	ldD	#$0000
	stD	L01E1
	bset	Flag26, #%00010000
	ldaA	#$80
	staA	>O2FuelTrim
	clrA	
	staA	Flag23
	staA	L0152
	ldD	#$FFFE
	stD	RomChecksumIdx
	ldD	#$0000
	stD	RomChecksumSum
	bset	Flag05, #%00000001
	ldaA	#%00010101			; all three timer input channels capture on
						; rising edge only
	staA	TCTL2_TimerControlReg
	ldaA	#%01010001			; enabled, pulse counting, rising edge
						; RTI freq = Eclock / $4000
	staA	PACTL_PulseAccumulatorControlReg
	ldaA	#$FF
	staA	PACNT_PulseAccumulatorCountReg	; very next count will cause interrupt
	ldaA	#%11100010			; enable interrupt sources, timer prescaler div by 8
						; Timer Overflow Interrupt Enabled
						; Real-Time Interrupt Enabled
						; pulse accumulator overflow interrupt enabled
	staA	TMSK2register
	ldaA	#$FF
	staA	TFLG1_TimerInterruptFlag1Reg		; clear interrupt request flags
	staA	TFLG2register
	ei	
	jmp	MainLoop		; ready to crank!
;
;-----------------------------------------------------------------------
;
; Diagnostic port support
;
; Send 0F, AA, CC with timed gap between chars at 1200 Baud
; Diag interface will be enabled at 7812 Baud
;
; Timing
; ------
; DS means Diagnostic Software
;
; At power on
; ECU send: $55, $B0, $80, $80, $80, $85
; Delay	- not sure yet 1000ms
; DS send: 0F
; Delay min 85ms, max 131ms
; DS send: AA
; Delay min 85ms, max 131ms
; DS send: CC
;
;
; Sending char in range 1 to 48 ($30) will return
; a single byte response of the variable requested
;
; Sending $AA followed by $80 to $87 will run one of the tests
; documented below.


SerialDiagConnectFuncionTable:
	dw	DiagConnectFunc_00, DiagConnectFunc_01, DiagConnectFunc_02


; diag "modes" of operation
DiagMode_NormalSendVar	EQU	$03

; index meanings for state function
DiagSendVarState	EQU	$05

DiagStateFunctions:
	dw	DiagExitISR, DiagExitISR, DiagExitISR, DiagExitISR2
	dw	DiagDoCmdStateFunction, DiagSendVarStateFunction

DiagVarTable:
	dw	$FFFF				; 00  not valid
	dw	CurrentRevs			; 01  time in microseconds for 1/4 revolution
	dw	CurrentRevs_lsB			; 02  LSB of current revs 16 bit number
	dw	HorizInjectorDuration		; 03  time in 2 microsecond steps
	dw	HorizInjectorDuration_lsB	; 04
	dw	SparkAdvance			; 05  * 0.5 = degrees
	dw	CurrentAtmPressure		; 06  * 3 = mm Hg
	dw	CurrentAirTemp			; 07  deg C = CurrentWaterTemp - 55
	dw	CurrentWaterTemp		; 08  deg C = CurrentWaterTemp - 55
	dw	TPS_Voltage			; 09
	dw	FilteredBatteryVoltage		; 0a  * 0.0625 = Volts
	dw	O2FuelTrim			; 0b  O2 Lambda sensor
	dw	StepperPosition			; 0c  Stepper Position - not used
	dw	StepperIntergral		; 0d  not used
	dw	StepperProportional		; 0e  barely used
	dw	TPS_Trim			; 0f
	dw	CurrentSensorErrors		; 10  Indicates which sensors are currently out of spec.
						; See SensorError bit defininitions at start of file
	dw	CurrentOutputErrors		; 11  Error Output
	dw	CurrentFunctionErrors		; 12  Error Function
	dw	FGSTAT				; 13  FGSTAT
	dw	SavedSensorErrors		; 14  Error Valid Input
	dw	SavedOutputErrors		; 15  Error Valid Output
	dw	SavedFunctionErrors		; 16  Error Valid Fucntion
	dw	WeberPartNo			; 17  ECU part number
	dw	WeberPartNo + 1			; 18
	dw	WeberPartNo + 2			; 19
	dw	WeberPartNo + 3			; 1a
	dw	WeberPartNo + 4			; 1b
	dw	WeberPartNo + 5			; 1c
	dw	WeberPartNo + 6			; 1d
	dw	WeberPartNo + 7			; 1e
	dw	WeberPartNo + 8			; 1f
	dw	WeberPartNo + 9			; 20
	dw	WeberPartNo + 10		; 21
	dw	$FFFF				; 22 not used
	dw	$FFFF				; 23 not used
	dw	$FFFF				; 24 not used
	dw	$FFFF				; 25 not used
	dw	$FFFF				; 26 not used
	dw	$FFFF				; 27 not used
	dw	$FFFF				; 28 not used
	dw	$FFFF				; 29 not used
	dw	$FFFF				; 2a not used  FGSTAT2 
	dw	SensorHiLowErrors		; 2b Indicates if fault is open or short circuit
						; See SensorError bit defininitions at start of file
	dw	OutputHiLowErrors		; 2c
	dw	FunctionErrorFlags		; 2d
	dw	SavedSensorHiLowErrors		; 2e
	dw	SavedOutputHiLowErrors		; 2f
	dw	SavedFunctionErrorFlags		; 30

DiagTestFunctions:
	dw	DiagFuelPumpTest		; 80
	dw	DiagInjectorTestHoriz		; 81
	dw	DiagCoil1Test			; 82
	dw	DiagCoil2Test			; 83
	dw	DiagClearErrors			; 84
	dw	DiagUnusedTest			; 85
	dw	DiagRevCounterTest		; 86
	dw	DiagInjectorTestVert		; 87
	dw	$A000
	dw	$A000
	dw	$A000
	dw	$A000
	dw	$A000
	dw	$A000
	dw	DoWarmReset			; 8e	Disabled - will reset ECU
	dw	DoWarmReset			; 8f	Unfortunatly TPS trim is disabled -
						;	will reset ECU if command used

DiagFirstTest	EQU	$80	
DiagLastTest	EQU	$87	
Diag_8E_Test	EQU	$8E	; stepper on Fiat
DiagStoreTPS	EQU	$8F	
;
;-----------------------------------------------------------------------
;
; Sets initial baud rate at E CLOCK / 13 / 16 / 16
;
; 4 MHz / 3328 = 1202 baud
; 
;
InitComms:
	ldaA	DiagMode
	cmpA	#DiagMode_NormalSendVar
	beq	L8491
	clr	>Diag_c
	clr	>DiagStateIdx
	clr	>DiagConnectFuncIdx
	ldaA	#$FF
	staA	DiagMode
	bset	TxFlags, #TxFlags_NotConnected
	ldaA	#$34				; see above
	staA	baud_Register
L8491	clr	>SCCR1_SerialControlReg
	ldaA	#(SCCR2_RxISR_Enable | SCCR2_TxEnable | SCCR2_RxEnable)
	staA	SCCR2_SerialControlReg
	ret	
;
;-----------------------------------------------------------------------
SCI_isr:
	ldD	TCNT_TimerCountReg
	stD	SCI_ISR_Time
	brset	SCSR_SerialStatusReg, #SCSR_RxChar, L84A5
	bclr	SCCR2_SerialControlReg, #SCCR2_TxCompleteISR_Enable
	reti	
;
L84A5	ldaB	DiagMode
	brclr	SCSR_SerialStatusReg, #SCSR_RxError, @SerialRxCharGood
	ldaA	SCDR_SerialDataReg
	jmp	DiagResetInitSequence
;
@SerialRxCharGood:
	ldaA	SCDR_SerialDataReg
	cmpB	#DiagMode_NormalSendVar
	bne	@doConnectFunc
	jmp	ExecuteDiagStateFunc
;
@doConnectFunc
	brset	TxFlags, #TxFlags_NotConnected, ExecuteDiagConnectFunc
	jmp	ExecuteDiagStateFunc	; but if alreay connected do cmd processing
;
ExecuteDiagConnectFunc:
	ldX	#SerialDiagConnectFuncionTable
	ldaB	DiagConnectFuncIdx
	lslB	
	aBX	
	ldX	0, X
	jmp	0, X
;
;-----------------------------------------------------------------------
; A = Rx'ed Byte
DiagConnectFunc_00:
	cmpA	#$0F
	bne	L84D6
	inc	>DiagConnectFuncIdx
	ldX	SCI_ISR_Time
	stX	PreviousCharTime
L84D6	jmp	ExecuteDiagStateFunc
;
;-----------------------------------------------------------------------
; A = Rx'ed Byte
DiagConnectFunc_01:
	ldX	#PreviousCharTime
	call	CheckPreviousCharTimeout
	bcs	@InterCharTimeBad
	ldX	SCI_ISR_Time
	stX	PreviousCharTime
	ldaB	#$02
@loop	subD	#$0002
	ldX	#EnableDiagChars
	aBX	
	cmpA	0, X
	beq	L84F8
	tstB			; Always 0, possibly some ECU models have > 2 bytes to check
	bne	@loop
@InterCharTimeBad
	jmp	DiagResetInitSequence
;
L84F8	ldaA	1, X
	staA	DiagCmdCheckChar	; $CC
	inc	>DiagConnectFuncIdx	; next is DiagConnectFunc_02 
	jmp	ExecuteDiagStateFunc
;
;
;-----------------------------------------------------------------------
EnableDiagChars:
	db	$AA, $CC
;
;-----------------------------------------------------------------------
; Enters diag mode if correct char is recieved with correct timing
;
; Changes baud rate to 4 Mhz / 4 / 8 /16 = 7812.5 baud
;
; A = Rx'ed Byte
DiagConnectFunc_02:
	ldX	#PreviousCharTime
	call	CheckPreviousCharTimeout
	bcs	@InterCharTimeBad
	cmpA	DiagCmdCheckChar
	beq	@GotCC
@InterCharTimeBad
	jmp	DiagResetInitSequence
;
@GotCC	bclr	TxFlags, #TxFlags_NotConnected
	cmpA	#$CC
	bne	DiagResetInitSequence

	ldaA	#DiagMode_NormalSendVar
	staA	DiagMode
	ldaA	#DiagSendVarState
	staA	DiagStateIdx
	clr	>DiagConnectFuncIdx
	clr	>Flag28
	ldaA	#(SCCR2_RxISR_Enable | SCCR2_TxEnable | SCCR2_RxEnable)
	staA	SCCR2_SerialControlReg
	ldaA	#$23
	staA	baud_Register
	jr	DiagExitISR
;
DiagResetInitSequence:
	clr	>DiagConnectFuncIdx
	bset	TxFlags, #TxFlags_NotConnected

DiagExitISR:
	reti	
;
;-----------------------------------------------------------------------
ExecuteDiagStateFunc:
	ldX	#DiagStateFunctions
	ldaB	DiagStateIdx
	lslB	
	aBX	
	ldX	0, X
	jmp	0, X
;
;-----------------------------------------------------------------------
DiagExitISR2:
	jr	DiagExitISR3
;
;-----------------------------------------------------------------------
DiagDoCmdStateFunction:
	brset	TxFlags, #TxFlags_RxOfCmdComplete, DiagExitISR3
	ldX	#DiagCmdRxBuff
	ldaB	DiagDataIdx
	bne	L855C
	pushA	
	cmpA	#$05
	bls	L8558
	ldaA	#$05
L8558	incA	
	staA	DiagCmdRxCount
	popA	
L855C	aBX	
	staA	0, X
	inc	>DiagDataIdx
	dec	>DiagCmdRxCount
	bne	DiagExitISR3
	bset	TxFlags, #TxFlags_RxOfCmdComplete
DiagExitISR3:
	reti	
;
;-----------------------------------------------------------------------
DiagSendVarStateFunction:
	brset	Flag28, #DiagTestStarted, DiagTestRx
	cmpA	#$AA				; indicates diag test command to follow
	beq	@DiagTestRquested
	call	DiagVarSend
@exit	jmp	Exit_SCI_isr
;
@DiagTestRquested
	brset	Flag15, #MotorRunning1, @exit
	call	SerialSendByte			; echo AA
	bset	Flag28, #DiagTestStarted
	clr	DiagResetCountdown
	call	ShutdownIO
	ldaB	#%01000010			; disable timer overflow and pulse acc isr
						; as timer overflow will restart system every
						; 6 sec if engine not running
						; rti enabled
	staB	TMSK2register
	SetExtraPortBit #%00000100
	ei	

DiagTestWait:
		; turn off Rx isr, as test ID 80 - 8F byte read here
		; not in the interrupt handler
	bclr	SCCR2_SerialControlReg, #SCCR2_RxISR_Enable
WaitForRX
	call	ResetCOPtimer
		; not sure what is on this port bit
		; could be monitoring diag cable ???
	brset	PORTE_DataReg, #%00100000, @connected
		; if connector unplugged during test, then reset ???
	dec	DiagResetCountdown
	bne	@checkRX
	call	ResetCOPtimer
	di	
	ClearExtraPortBit #%00000100
; Power down, or wait for COP timout???
; Power down logical.... or hard reset?

@loop	jr	@loop
;
@connected
	clr	DiagResetCountdown
@checkRX
	brclr	SCSR_SerialStatusReg, #SCSR_RxChar, WaitForRX
	ldaA	SCDR_SerialDataReg
	brclr	SCSR_SerialStatusReg, #SCSR_RxError, SerialRxCharGood
	jr	WaitForRX
;
DiagTestRx
SerialRxCharGood
	cmpA	#$FF	; send FF after test complete to reset ECU
			; or cancel test in progress
	bne	@continue
	brset	Flag28, #DiagTestInProgress, @CancelTest
	bclr	Flag28, #DiagTestStarted
	ldaA	#$FF
	call	SerialSendByte
	clr	ResetFlag
	jmp	WarmReset
;
@CancelTest
	bset	Flag28, #DiagCancelTest
	jmp	Exit_SCI_isr
;
@continue
	ldaB	DiagCommand
	cmpB	#DiagStoreTPS		; was last byte received, tps command?
	beq	@tps			; if yes then this byte is value to store
	jr	NotTPSvalue
;
@tps	brclr	Flag28, #DiagStoreTPSFlag, L85F7
	staA	TPS_Trim
	call	SerialSendByte
	jr	Exit_SCI_isr
;
L85F7	jmp	DoDiagVarSend
;
NotTPSvalue
	brset	Flag28, #DiagTestInProgress, DoDiagVarSend
	cmpA	#DiagFirstTest		; < 80, treat as diag variable request
	bcs	DoDiagVarSend
	cmpA	#DiagLastTest
	bls	DoDiagTest		; Is  80 to 87
	cmpA	#Diag_8E_Test
	bne	@not8E
	bset	Flag28, #Diag_8E_TestFlag
	jr	DoDiagTest
;
@not8E	cmpA	#DiagStoreTPS
	bne	DoDiagVarSend
	bset	Flag28, #DiagStoreTPSFlag

DoDiagTest
	callr	SerialSendByte
	staA	DiagCommand
	call	ResetCOPtimer
	bset	Flag28, #DiagTestInProgress
	bset	SCCR2_SerialControlReg, #SCCR2_RxISR_Enable
	bclr	TxFlags, #%00001000
	ldX	#DiagTestFunctions
	tAB	
	lslB	
	aBX	
	ldX	0, X
	call	0, X
	brset	Flag28, #DiagCancelTest, L863D
	brset	TxFlags, #%00001000, L863D
	ldaA	#$EE
	jr	L863F
;
L863D	ldaA	#$FF
L863F	bclr	Flag28, #%00011110  ; DiagTestInProgress
	clr	DiagCommand
	callr	SerialSendByte
	jmp	DiagTestWait
;
DoDiagVarSend
	callr	DiagVarSend
	brset	Flag28, #DiagTestInProgress, Exit_SCI_isr
	jmp	DiagTestWait
	;	return to wait after test

;
Exit_SCI_isr	reti	
;
;-----------------------------------------------------------------------
DiagVarSend:
	tstA	
	beq	L8667
	cmpA	#$30
	bhi	L8667
	ldX	#DiagVarTable
	tAB	
	lslB	
	aBX	
	ldX	0, X
	ldaA	0, X
	callr	SerialSendByte
L8667	ret	
;
;-----------------------------------------------------------------------
SerialSendByte:
	brclr	TxFlags, #TxFlags_TxPending, L867F
	brclr	Flag28, #DiagTestStarted, L8688
	ldaB	DiagCommand
	cmpB	#$8E
	beq	L8688
	cmpB	#$8F
	beq	L8688
@loop	brset	TxFlags, #TxFlags_TxPending, @loop
L867F	staA	TxHold
	bclr	TxFlags, #TxFlags_TxSync
	bset	TxFlags, #TxFlags_TxPending
L8688	ret	
;
;-----------------------------------------------------------------------
DiagFuelPumpTest:
	SetExtraPortBit FuelPumpBit
	call	Delay100uS
	bcs	L86A3
	ldD	#7500			; * 4.096ms = 30.72 Sec
	call	DiagWaitForCountdown
	bcs	L86A3
	bset	TxFlags, #%00001000
L86A3	ClearExtraPortBit FuelPumpBit
	ret	
;
;
DiagCoil1Data:
	dw	PORTA_DataReg
	db	%01000000	; + 2 - bit to test
	dw	$0000		; + 3
	db	$04		; + 5
	dw	Delay500uS	; + 6
;
;-----------------------------------------------------------------------
DiagCoil1Test:
	ldD	#1500 / 2	; 1500 uS
	ldX	#DiagCoil1Data
	call	DoDiagPulsedOutputTest
	ret	
;
;
DiagCoil2Data:
	dw	PORTA_DataReg
	db	%00010000
	dw	$0000
	db	$04
	dw	Delay500uS
;
;-----------------------------------------------------------------------
DiagCoil2Test:
	ldD	#1500 / 2	; 1500 uS
	ldX	#DiagCoil2Data
	call	DoDiagPulsedOutputTest
	ret	
;
;-----------------------------------------------------------------------
DiagClearErrors:
	call	ResetCOPtimer
	tst	EEPROM_Status2
	bne	DiagClearErrors
	call	ClearSavedDiagError
	bset	TxFlags, #%00001000
	ret	
;
;-----------------------------------------------------------------------
DiagUnusedTest:
	ret	
;
;-----------------------------------------------------------------------
DiagRevCounterTest:
	ldaA	#$FA
	staA	DiagTestCountdown
	ldD	#7500 / 2	; uS
	stD	DiagTestPulseDuration
	SetExtraPortBit FuelPumpBit
	call	Delay100uS
	bcs	@abort
@loop	SetExtraPortBit RevCounterBit
	call	DiagPulseTestDelay
	bcs	@abort
	ClearExtraPortBit RevCounterBit
	call	Delay500uS
	dec	DiagTestCountdown
	bne	@loop
	bset	TxFlags, #%00001000
	jr	L8725
;
@abort	bclr	TxFlags, #%00001000
L8725	ClearExtraPortBit FuelPumpBit
	ClearExtraPortBit RevCounterBit
	ret	
;
;
DiagInjectorHorizData:
	dw	PORTA_DataReg
	db	HorizInjectorBit
	dw	$0060
	db	$40
	dw	Delay100uS
;
;-----------------------------------------------------------------------
DiagInjectorTestHoriz:
	ldD	#3900 / 2	; 3900 uS
	ldX	#DiagInjectorHorizData
	call	DoDiagPulsedOutputTest
	ret	
;
;
DiagInjectorVertData:
	dw	PORTA_DataReg
	db	VertInjectorBit
	dw	$0060
	db	$10
	dw	Delay100uS
;
;-----------------------------------------------------------------------
DiagInjectorTestVert:
	ldD	#3900 / 2	; 3900 uS
	ldX	#DiagInjectorVertData
	call	DoDiagPulsedOutputTest
	ret	
;
;-----------------------------------------------------------------------
DoWarmReset:
	clr	ResetFlag
	jmp	WarmReset
;
;-----------------------------------------------------------------------
L8764:	SetExtraPortBit FuelPumpBit
	callr	Delay100uS
	bcs	L8777
	ldD	#5	; * 4.096ms
	callr	DiagWaitForCountdown
L8777	ret	
;
;-----------------------------------------------------------------------
Delay250:
	ldD	#250	; * 4.096ms
	callr	DiagWaitForCountdown
	dec	DiagTestCountdown
	ret	
;
;-----------------------------------------------------------------------
DiagWaitForCountdown:
	stD	DiagCountdownTimer
@loop	ldD	DiagCountdownTimer
	beq	@timeout
	brset	Flag28, #DiagCancelTest, @abort
	brset	HardwarePortInValue, #%10000000, @loop
	ClearExtraPortBit FuelPumpBit
@abort	sec	
	ret	
;
@timeout
	clc	
	ret	
;
;-----------------------------------------------------------------------
Delay100uS:
	ldD	#100 / 2		; 100 uS
	jr	DelayCont
;
Delay500uS:
	ldD	#500 / 2		; 500 uS
DelayCont
	bclr	Flag28, #%01000000
	jr	L87B2
;
DiagPulseTestDelay:
	ldD	DiagTestPulseDuration
	bset	Flag28, #%01000000
L87B2	bclr	TMSK1_TimerInterruptMask1Reg, #TMSK1_OC3
	addD	TCNT_TimerCountReg
	stD	TOC3_TimerCompareReg
	ldaA	#TFLG1_OC3
	staA	TFLG1_TimerInterruptFlag1Reg
@loop	brset	TFLG1_TimerInterruptFlag1Reg, #TFLG1_OC3, @timeUp
	brset	Flag28, #DiagCancelTest, @cancel
	brclr	Flag28, #%01000000, @loop
	brset	HardwarePortInValue, #%10000000, @loop

@abort	ClearExtraPortBit FuelPumpBit
@cancel	sec	
	ret	
;
@timeUp	brset	HardwarePortInValue, #%10000000, @ok
	jr	@abort
;
@ok	clc	
	ret	
;
;-----------------------------------------------------------------------
; Does the injector and coil tests
;
; D = time / cycles for test ??
; X = pointer to table of test parameters
; 
DoDiagPulsedOutputTest:
	stD	DiagTestPulseDuration
	ldaA	#$05
	staA	DiagTestCountdown
	call	L8764
	bcs	L8820
L87EE	callr	SetTestBitHigh
	ldY	6, X	; function ptr
	call	0, Y	; delay Function
	ldaA	5, X
	ldY	3, X
	cmpY	#$0002
	bne	L8808
	bitA	0, Y
	beq	L8820
	jr	L880D
;
L8808	bitA	0, Y
	bne	L8820
L880D	call	DiagPulseTestDelay
	bcs	L8820
	callr	SetTestBitLow
	call	Delay250
	bcs	L8820
	bne	L87EE
	bset	TxFlags, #%00001000
	jr	L8823
;
L8820	bclr	TxFlags, #%00001000
L8823	callr	SetTestBitLow
	ClearExtraPortBit FuelPumpBit
	ret	
;
;-----------------------------------------------------------------------
SetTestBitHigh:
	ldaA	2, X
	ldY	0, X
	oraA	0, Y
	staA	0, Y
	ret	
;
;-----------------------------------------------------------------------
SetTestBitLow:
	ldaA	2, X
	comA	
	ldY	0, X
	andA	0, Y
	staA	0, Y
	ret	
;
;-----------------------------------------------------------------------
; Min time is 42500 * 2 us =  85 ms
; Max time is 65535 * 2 us = 131 ms
;
CheckPreviousCharTimeout:
	pushA	
	ldD	SCI_ISR_Time
	subD	0, X
	cmpD	#42500
	bcs	L885D
	cmpD	#$FFFE
	bhi	L885D
	clc	
	jr	L885E
;
L885D	sec	
L885E	popA	
	ret	

;
;-----------------------------------------------------------------------
;-----------------------------------------------------------------------
;-----------------------------------------------------------------------
;
MainLoop:
	call	ResetCOPtimer
	call	UpdateDiagFlags
	sts	Scratch4
	ldX	Scratch4
	cmpX	#StackTop
	bne	@setError
	ldaA	TMSK2register
	tPA	
	andA	#%00010000	; interrupt mask bit
	beq	@InterruptsEnabled
	
@setError
	bset	InternalErrors, #StackError
	jr	@skip1

@InterruptsEnabled
	call	ResetCOPtimer
	
@skip1	brclr	InternalErrors, #%00011111, @noInternalErrors
	brset	FirstTimeFunctionErrors, #CPU_Error, @errorAlready
	bset	FirstTimeFunctionErrors, #CPU_Error
	jr	@skip2
;
@errorAlready
	bset	CurrentFunctionErrors, #CPU_Error
	ldaA	#CPU_Error
	ldaB	#LogFunctionErrorIdx
	xgDX	
	call	LogDiagError
	jr	@skip2
;
@noInternalErrors
	bclr	FirstTimeFunctionErrors, #CPU_Error
	bclr	CurrentFunctionErrors, #CPU_Error
@skip2	bclr	InternalErrors, #%00011111
	ldaA	#RAM_Error
	bitA	SavedFunctionErrors
	bne	L88B6
	bitA	CurrentFunctionErrors
	beq	L88B6
	ldaA	#RAM_Error
	ldaB	#LogFunctionErrorIdx
	xgDX	
	call	LogDiagError
L88B6	call	CheckFuelPump
	brclr	InjectorFlags, #Timer131ms, @skip
	; flag is set on timer overflow (every 131.072 ms)
	bclr	InjectorFlags, #Timer131ms
	call	CheckO2Sensor
	call	CoolingFanControl
	
@skip	call	DoRomChecksum
	ldaA	Revs_e
	cmpA	LF6FC
	bcc	L88DD
	ClearExtraPortBit #%01000000
	jr	L88E7
;
L88DD	SetExtraPortBit #%01000000
L88E7	brset	Flag17, #NewRev, L88EE
	jmp	SkipRevProcessing
;
L88EE	bclr	Flag17, #NewRev
	call	CheckPickupError
	ldX	>CurrentRevs
	cmpX	#$FFFC
	bls	L8901
	ldD	#$0000
	jr	L8928
;
L8901	ldY	#11
	ldD	#58594
	idiv	
	bcs	L8920
	stX	Scratch3
	ldX	>CurrentRevs
	fdiv	
	xgDX	
L8913	decY	
	beq	L8925
	lslD	
	rol	Scratch3_low
	rol	Scratch3
	bcc	L8913
L8920	ldD	#$FFFF
	jr	L8928
;
L8925	ldD	Scratch3
L8928	stD	CurrentRevs_b
	staA	Revs_e
	lsrD	
	lsrD	
	lsrD	
	lsrD	
	lsrD	
	lsrD	
	tstA	
	beq	L8939
	ldaB	#$FF
L8939	staB	Revs_c

	di	
	call	L9C33
	ei	
	CalcMapNdxFrac CurrentRevs_b, SparkMapRPM_BreakPoints, $10
	stD	RPM_SparkMapNdxFrac
	
	CalcMapNdxFrac CurrentRevs_b, FuelMapRPM_BreakPoints, $10
	stD	RPM_FuelMapNdxFrac
	
	CalcMapNdxFrac CurrentTPS, SparkMapTPS_BreakPoints, $10
	stD	TPS_SparkMapNdxFrac
	
	CalcMapNdxFrac CurrentAtmPressure, AltitudeTrim_BreakPoints, $10
	stD	AltitudeNdxFrac
	
	CalcMapNdxFrac CurrentTPS, FuelMapTPS_BreakPoints, $10
	di	
	stD	TPS_FuelMapNdxFrac
	ldD	CurrentTPS
	stD	L022C
	ei	
	
	call	CalculateFuel
	CalcMapNdxFrac CurrentRevs_b, RPM_SparkTable_BreakPoints, $10
	stD	RPM_SparkTableNdxFrac
	
	ldD	RPM_FuelMapNdxFrac
	ldY	#RevsToTPS_Table
	call	InterpolateValue
	staA	RevsDerivedSubstituteTPS
	
	ldX	#Scratch4
	ldD	FilteredRevs
	stD	0, X
	ldaA	RPM_FilterWeight
	brset	Flag13, #%00010000, L89E8
	ldaA	#$00
L89E8	staA	2, X
	ldD	>CurrentRevs
	call	FilterWordValue
	stD	FilteredRevs
	
	ldD	FilteredRevs
	cmpD	#$0E5C
	bls	L8A08
	lsrD	
	lsrD	
	lsrD	
	lsrD	
	xgDX	
	ldD	#$E4E2
	idiv	
	xgDX	
	jr	L8A0A
;
L8A08	ldaB	#$FF
L8A0A	staB	Revs_d
	ldX	WaterTempSomething
	cmpX	#$FFFF
	beq	L8A19
	decX	
	stX	WaterTempSomething
L8A19	ldX	#RPM_SparkMapNdxFrac
	ldY	#RPM_SparkSomethingTable
	call	InterpolateWordValue
	stD	>RPM_Spark_always_005A
	ldD	>RPM_Spark_always_005A
	lsrD	
	lsrD	
	ldaA	L0128
	mul	
	stD	>L00C5
	call	CalcSparkAdvance
	call	L8DA9
	ldD	WaterTempNdxFrac
	ldY	#WaterTemp_Table2
	call	InterpolateValue
	staA	WaterTemp_Value2

SkipRevProcessing
	brclr	Flag08, #%00000011, L8A69
	ldD	>CurrentRevs
	ldX	#$000C
	idiv	
	ldD	LF641
	fdiv	
	xgDX	
	tAB	
	clrA	
	stD	L020B
	ldX	#$001E
	ldaA	>SparkAdvance
	clrB	
	idiv	
	xgDX	
	addD	L020B
	stD	L01AF
L8A69	brclr	Flag08, #CheckCoil1Flag, L8A73
	bclr	Flag08, #CheckCoil1Flag
	call	CheckCoil1
L8A73	brclr	Flag08, #CheckCoil2Flag, L8A7D
	bclr	Flag08, #CheckCoil2Flag
	call	CheckCoil2
L8A7D	di	
	ldaA	>L00E6
	cmpA	#$02
	bne	L8A8A
	ldD	L01C6
	jr	L8A8D
;
L8A8A	ldD	InputCapture3Difference
L8A8D	stD	L01C6
	ei	
	call	LA8B5
	call	LA972
	call	CheckWaterTempSensor
	ldX	#Scratch3
	ldD	FilteredWaterTemp
	stD	Scratch3
	ldaA	WaterTemp_raw
	ldaB	WaterTemp_FilterWeight
	call	FilterByteValue
	stD	FilteredWaterTemp

	call	L8D2C
	call	CheckAirTempSensor
	ldX	#Scratch3
	ldD	FilteredAirTemp
	stD	Scratch3
	ldaA	AirTemp_raw
	ldaB	AirTemp_FilterWeight
	call	FilterByteValue
	stD	FilteredAirTemp

	call	L8D53
	ldX	#Scratch3
	ldD	FilteredTPS
	stD	Scratch3
	ldaA	CurrentTPS
	ldaB	TPS_FilterWeight
	call	FilterByteValue
	stD	FilteredTPS

	call	CheckBatteryVoltage
	ldX	#Scratch4
	ldaB	L0270
	staB	0, X
	ldaB	L026F
	call	AddABmultX0mult2
	ldaB	#$84
	mul	
	lslD	
	bcc	L8AFB
	ldaA	#$FF
L8AFB	staA	BatteryVoltage_a
	ldX	#Scratch3
	ldD	FilteredBatteryVoltage
	stD	Scratch3
	ldaB	BatteryVoltage_FilterWeight
	ldaA	BatteryVoltage_a
	call	FilterByteValue
	stD	FilteredBatteryVoltage
	call	ProcessBatteryVoltage
	ldD	ScaledBatteryVoltage
	ldY	#BatteryTable2
	call	InterpolateValue
	staA	BatteryVoltageSomething2
	ldaB	#$28
	mul	
	stD	L01CB
	ldD	AirTempNdxFrac
	ldY	#AirTempTrimTable2
	brclr	Flag15, #TPS_Closed, L8B38
	ldY	#AirTempTrimTable1
L8B38	call	InterpolateValue
	staA	>AirTempTrim
	ldD	WaterTempNdxFrac
	ldY	#WaterTempTrimTable
	call	InterpolateValue
	staA	>WaterTempTrim
	ldY	#AltitudeTrimTable
	ldD	AltitudeNdxFrac
	call	InterpolateValue
	staA	>AltitudeTrim
	ldD	ScaledBatteryVoltage
	ldY	#BatteryTable1
	call	InterpolateValue
	staA	BatteryVoltageSomething1
	ldX	#BatteryVoltageNdxFrac
	ldY	#InjectorOpeningTimeTable
	call	InterpolateWordValue
	stD	>InjectorOpeningTime
	call	LB799
	ldX	#Vec1Table
	ldaA	Flag26
	andA	#%00000010
	call	ExcecuteVec1Functions
	ldX	#$8BA0
	brset	Flag15, #MotorRunning1, L8B8E
	ldaA	Flag26
	andA	#%00001000
	bne	L8B8F
	beq	L8B92
L8B8E	clrA	
L8B8F	call	ExcecuteVec1Functions
L8B92	call	UpdateEEPROM
	jmp	MainLoop	; round again

;-----------------------------------------------------------------------
;-----------------------------------------------------------------------
;-----------------------------------------------------------------------


;-----------------------------------------------------------------------
;
;
Vec1Table:	; 0    1    2    3    4    5    6    7
	db	$00, $22, $AA, $78, $68, $68, $8D, $9B

		; 8    9    a    b    c    d    d    f
	db	$00, $22, $88, $45, $85, $C8, $78, $9E

Vec1FunctionTable:
	dw	Vec1Entry_00, Vec1Entry_01, Vec1Entry_02, Vec1Entry_03
	dw	Vec1Entry_04, Vec1Entry_05, Vec1Entry_06, Vec1Entry_07
	dw	Vec1Entry_08, Vec1Entry_09, Vec1Entry_0A, Vec1Entry_0B
	dw	Vec1Entry_0C, Vec1Entry_0D, Vec1Entry_0E


;-----------------------------------------------------------------------
; called with X = #Vec1Table
;
; if A = 0, then low nibble of Vec1Table is used is as index to Vec1FunctionTable,
; else high nibble is used
;
ExcecuteVec1Functions:
	ldaB	Vec1TableIndex
	aBX	
	ldaB	0, X
	tstA	
	bne	L8BD3
	andB	#%00001111
	jr	L8BD7
;
L8BD3	lsrB	
	lsrB	
	lsrB	
	lsrB	
L8BD7	tBA			; The function is called with A = to the function
	andA	#%00000111 	; index AND'ed with #%00000111
	lslB	
	ldX	#Vec1FunctionTable
	aBX	
	ldX	0, X
	call	0, X
	di	
	pushA	
	ldaA	ExtraPortOutShadow
	staA	HardwarePort_write
	popA	
	ei	
	ret	
;
;-----------------------------------------------------------------------
; Power down ??, but wait for eeprom write to complete first
;
Vec1Entry_00:
	call	SetNextVec1TableIndex
@loop	call	ResetCOPtimer
	ldaA	EEPROM_Status2
	bne	@loop
@loop2	di	
	ClearExtraPortBit #%00000100
	jr	@loop2

;-----------------------------------------------------------------------
; This one called with A = 1 at power up
;
Vec1Entry_01:
	call	SetNextVec1TableIndex
	clr	>Flag26
	clr	>Flag27
	ldaA	TestModeCountInitialValue ; $0A
	staA	TestModeCounter
	ret	
;
;-----------------------------------------------------------------------
; A = 2
Vec1Entry_02:
	call	SetNextVec1TableIndex	; table position2 points to Vec1Entry_0A
	ret	
;
;-----------------------------------------------------------------------
; A = 0A & 07 = 02
Vec1Entry_0A:
	brclr	Flag26, #%00000100, L8C31
	brset	Flag26, #%00000010, L8C2C
	brset	Flag26, #%00010000, L8C31
	ldaA	#$03
	call	Vec1Entry_03
	jr	L8C31
;
L8C2C	ldaA	#$07
	call	Vec1Entry_07
L8C31	ret	
;
;-----------------------------------------------------------------------
; A = 3
Vec1Entry_03:
	call	L8CF4
	ldaA	LF688
	staA	L01E5
	bclr	Flag26, #%00001000
	ret	
;
;-----------------------------------------------------------------------
Vec1Entry_0B:
	ldaA	#$02
	call	Vec1Entry_02
	call	Vec1Entry_0A
	call	L8D18
	ret	
;
;-----------------------------------------------------------------------
Vec1Entry_04:
	call	SetNextVec1TableIndex
	ret	
;
;-----------------------------------------------------------------------
Vec1Entry_0C:
	call	Vec1Entry_04
	ret	
;
;-----------------------------------------------------------------------
Vec1Entry_05:
	call	L8CF4
	ret	
;
;-----------------------------------------------------------------------
Vec1Entry_0D:
	call	Vec1Entry_05
	call	L8D18
	ret	
;
;-----------------------------------------------------------------------
Vec1Entry_06:
	call	SetNextVec1TableIndex
	call	SetInjectorAndCoilOutputsLow
	ret	
;
;-----------------------------------------------------------------------
Vec1Entry_0E:
	call	Vec1Entry_06
	ret	
;
;-----------------------------------------------------------------------
; A = 7
Vec1Entry_07:
	call	SetNextVec1TableIndex ; 7 => $9B
	call	SetInjectorAndCoilOutputsLow
	ldaA	DiagMode
	cmpA	#DiagMode_NormalSendVar
	bne	L8C7A
	ldD	#$0000
	jr	L8C7D
;
L8C7A	ldD	LF68A
L8C7D	stD	L01E6
	ldaA	SavedSensorErrors
	oraA	SavedOutputErrors
	oraA	SavedFunctionErrors
	beq	L8CA9
	ldaA	FirstTimeSensorErrors
	oraA	FirstTimeOutputErrors
	oraA	FirstTimeFunctionErrors
	beq	L8C99
	ldaA	L009B
	staA	L0094
	jr	L8CA9
;
L8C99	brset	Flag30, #%00000100, L8CA6
	ldaA	L009B
	subA	L0094
	cmpA	LF713
	bcs	L8CA9
L8CA6	bset	Flag27, #RequestClearDiagErrors
L8CA9	ret	
;
;-----------------------------------------------------------------------
Vec1Entry_09:
	call	ResetCOPtimer
	ldD	L01E6
	bne	L8CDA
	brset	Flag27, #%00000010, L8CDA
	call	LAC85
	ldaA	TPS_Trim
	staA	EEPROM_WriteBuffer + 1
	ldaA	StepperProportional
	staA	EEPROM_WriteBuffer + 3
	ldaA	L0288
	staA	EEPROM_WriteBuffer + 4
	ldX	#EEPROM_WriteBuffer
	ldY	#L0F80
	call	QueueWriteToEEPROM
	ldaA	#$00
	call	Vec1Entry_00
L8CDA	ret	
;
;-----------------------------------------------------------------------
Vec1Entry_08:
	ret	
;
;-----------------------------------------------------------------------
SetNextVec1TableIndex:
	staA	Vec1TableIndex
	ClearExtraPortBit FuelPumpBit
	SetExtraPortBit #%00000100
	ret	
;
;-----------------------------------------------------------------------
L8CF4:	brset	Flag02, #InjectorsDisabled, SetNextVec1TableIndex
	brclr	Flag03, #%01000000, SetNextVec1TableIndex
	brset	Flag26, #%00010000, SetNextVec1TableIndex
	staA	Vec1TableIndex
	SetExtraPortBit FuelPumpBit
	SetExtraPortBit #%00000100
	ret	
;
;-----------------------------------------------------------------------
L8D18:	ldaA	LF711
	lslA	
	staA	L0202
	bset	Flag02, #%00001000
	ret	
;
;-----------------------------------------------------------------------
SetInjectorAndCoilOutputsLow:
	ldaA	#%10101010
	staA	TCTL1_TimerControlReg		; set output compare to control pins
	ldaA	#%01111000
	staA	CFORC_ForceOutputCompareReg	; set OC2, 3, 4 and 5 low now
	ret	
;
;-----------------------------------------------------------------------
; convert air and water temps
L8D2C:	ldX	#FilteredTempBreakPoints
	ldaB	#$10
	ldaA	FilteredWaterTemp
	call	DoTableToNdxFrac
	stD	FilteredWaterTempNdxFrac
	ldY	#TemperatureTable
	call	InterpolateValue
	call	CheckAndStoreWaterTemp
	ldX	#TempBreakPoints
	ldaA	CurrentWaterTemp
	ldaB	#$10
	call	DoTableToNdxFrac
	stD	WaterTempNdxFrac
	ret	
;
;-----------------------------------------------------------------------
L8D53:	ldX	#FilteredTempBreakPoints
	ldaB	#$10
	ldaA	FilteredAirTemp
	call	DoTableToNdxFrac
	stD	FilteredAirTempNdxFrac
	ldY	#TemperatureTable
	call	InterpolateValue
	call	CheckAndStoreAirTemp
	ldX	#TempBreakPoints
	ldaA	CurrentAirTemp
	ldaB	#$10
	call	DoTableToNdxFrac
	stD	AirTempNdxFrac
	ret	
;
;-----------------------------------------------------------------------
ProcessBatteryVoltage:
	ldD	FilteredBatteryVoltage
	subD	#$8000
	bcc	L8D87
	ldD	#$0000
	jr	L8D96
;
L8D87	cmpD	#$7000
	bls	L8D92
	ldD	#$0700
	jr	L8D96
;
L8D92	lsrD	
	lsrD	
	lsrD	
	lsrD	
L8D96	stD	ScaledBatteryVoltage
	ldD	FilteredBatteryVoltage
	subD	#$6000
	bcc	L8DA2
	clrA	
L8DA2	ldaB	#$18
	mul	
	stD	BatteryVoltageNdxFrac
	ret	
;
;-----------------------------------------------------------------------
L8DA9:	ldaA	Revs_c
	brclr	PORTD_DataReg, #%00100000, L8DB9
	cmpA	#$8C
	bcs	L8DC0
	bclr	PORTD_DataReg, #%00100000
	jr	L8DC0
;
L8DB9	cmpA	#$78
	bhi	L8DC0
	bset	PORTD_DataReg, #%00100000
L8DC0	ret	
;
;-----------------------------------------------------------------------
; Guess fan or some external control based on water temp
;
CoolingFanControl:
	ldaA	CurrentWaterTemp
	brset	ExtraPortOutShadow, #%00100000, @OnAlready
	cmpA	FanOnTemp
	bls	L8DE1
	bset	ExtraPortOutShadow, #%10100000
	jr	L8DDA
;
@OnAlready
	cmpA	FanOffTemp
	bhi	L8DE1
	bclr	ExtraPortOutShadow, #%00100000
L8DDA	WriteExtraPort
L8DE1	ret	
;
;-----------------------------------------------------------------------
CalcSparkAdvance:
	ldD	>CurrentRevs
	brset	Flag10, #%01000000, L8DF4
	cmpD	LF614
	bhi	L8DFA
	bset	Flag10, #%01000000
	jr	L8DFE
;
L8DF4	cmpD	LF617
	bcs	L8DFE
L8DFA	ldaA	#$40
	jr	L8E0C
;
L8DFE	ldaA	Flag13
	cmpA	Flag24
	bne	L8E0C
	ldaA	WaterTempValue
	beq	L8E23
	decA	
	jr	L8E20
;
L8E0C	staA	Flag24
	brset	Flag24, #%00100000, L8E76
	brclr	Flag24, #%10010000, L8E23
	ldD	WaterTempNdxFrac
	ldY	#WaterTemp_Table4
	call	InterpolateValue
L8E20	staA	WaterTempValue
L8E23	brset	Flag24, #%10000000, L8E50
	bclr	Flag10, #%00001000
	brset	Flag24, #%00010000, L8E58
	bclr	Flag10, #%00000100
	brset	Flag24, #%00000001, L8E60
	brset	Flag24, #%00001000, L8E68
	brset	Flag24, #%00000100, L8E6D
	brset	Flag24, #%00100000, L8E8B
	ldaA	LF619
	brset	Flag10, #%01000000, L8E4B
	ldaA	DefaultSparkAdvance
L8E4B	staA	CurrentSparkAdvance
	jr	L8E8E
;
L8E50	bclr	Flag10, #%00000100
	call	LookupSparkAdvance
	jr	L8E8E
;
L8E58	call	LookupSpark_RPM_Temp_Table
	call	L8FEE
	jr	L8E8E
;
L8E60	call	L8F01
	call	L8F8B
	jr	L8E8E
;
L8E68	call	L8F05
	jr	L8E8E
;
L8E6D	call	LookupSparkMap
	clrB	
	stD	L0144
	jr	L8E8E
;
L8E76	call	LookupSparkMap
	addA	LF613
	call	RangeCheckSpark
	clrB	
	staA	CurrentSparkAdvance
	stD	L0144
	bclr	Flag10, #%00001100
	jr	L8E8E
;
L8E8B	call	LookupSpark_RPM_Temp_Table
L8E8E	ldaA	CurrentSparkAdvance
	clrB	
	subD	L0144
	bge	L8EA1
	ldX	#LF611
	cmpD	0, X
	blt	L8EAF
	jr	L8EA9
;
L8EA1	ldX	#LF60F
	cmpD	0, X
	bge	L8EAF
L8EA9	ldaA	CurrentSparkAdvance
	clrB	
	jr	L8EC3
;
L8EAF	ldD	L0144
	addD	0, X
	bge	L8EBA
	clrA	
	clrB	
	jr	L8EC3
;
L8EBA	cmpD	#$7E00
	bls	L8EC3
	ldD	#$7E00
L8EC3	stD	L0144
	staA	CurrentSparkAdvance
	ldY	#AltitudeSparkTrimTable
	ldD	AltitudeNdxFrac
	call	InterpolateValueSigned
	addA	CurrentSparkAdvance
	call	RangeCheckSpark
	staA	CurrentSparkAdvance
	ldaB	L0146
	brset	Flag10, #%00000100, L8EE5
	ldaB	#$00
L8EE5	aBA	
	call	RangeCheckSpark
	brset	FirstTimeSensorErrors, #%01000000, L8EF0
	staA	>SparkAdvance
L8EF0	ret	
;
;-----------------------------------------------------------------------
RangeCheckSpark:
	bge	L8EF6
	clrA	
	jr	L8EFC
;
L8EF6	cmpA	#$7E
	bcs	L8EFC
	ldaA	#$7E
L8EFC	ret	
;

;-----------------------------------------------------------------------
LookupSparkAdvance:
	brset	Flag15, #TPS_Closed, LookupSpark_RPM_Temp_Table
L8F01:	brset	Flag15, #TPS_WideOpen, LookupSpark_RPM_TPS_Temp_Table
L8F05:	callr	LookupSparkMap
	jr	ContinueToSparkTrims
;
;-----------------------------------------------------------------------
LookupSparkMap:
	ldD	TPS_SparkMapNdxFrac
	ldY	#Scratch1
	ldX	#SparkAdvanceMap
	staB	0, Y			; tps fraction
	tAB				; tps index
	aBX				; go across map
	ldD	RPM_SparkMapNdxFrac
	staB	1, Y			; rpm fraction
	ldaB	#$10
	staB	2, Y			; number of columns
	mul				; go down map
	aBX				; X = addr of map byte
	call	InterpolateMapPoint
	staA	CurrentSparkAdvance
	ret	
;
;-----------------------------------------------------------------------
LookupSpark_RPM_Temp_Table:
	ldY	#RPM_SparkAdvanceTableMax
	ldD	RPM_SparkMapNdxFrac
	call	InterpolateValue
	staA	CurrentSparkAdvance
	ldY	#WaterTemp_SparkAdvanceTable
	ldD	WaterTempNdxFrac
	call	InterpolateValueSigned
	addA	CurrentSparkAdvance
	call	RangeCheckSpark
	staA	CurrentSparkAdvance
	ret	
;
;-----------------------------------------------------------------------
LookupSpark_RPM_TPS_Temp_Table:
	ldY	#RPM_SparkAdvanceTableMin
	ldD	RPM_SparkTableNdxFrac
	call	InterpolateValue
	staA	CurrentSparkAdvance

ContinueToSparkTrims:
	ldX	#TPS_SparkTableBreakPoints
	ldaA	TPSLookupTableIdx
	ldaB	#$02
	call	DoTableToNdxFrac
	ldX	#TPS_TempSparkAdvanceTrimMap
	ldY	#Scratch1
	staB	0, Y
	tAB	
	aBX	
	ldD	WaterTempNdxFrac
	staB	1, Y
	ldaB	#$02
	staB	2, Y
	mul	
	aBX	
	call	InterpolateMapPointSigned
	addA	CurrentSparkAdvance
	call	RangeCheckSpark
	staA	CurrentSparkAdvance
	ret	
;
;-----------------------------------------------------------------------
L8F8B:	ldaA	TPS_Voltage
	subA	TPS_VoltgePrevious
	bpl	L8F95
	ldaA	#$00
L8F95	ldX	#$0010
	ldaB	#$FF
	call	LBC9A
	ldY	#YetAnotherSparkAdvanceTrim
	call	InterpolateValueSigned
	addA	CurrentSparkAdvance
	call	RangeCheckSpark
	staA	CurrentSparkAdvance
	ret	
;
;-----------------------------------------------------------------------
L8FAE:	ldX	#$0000
	clr	Scratch1
	ldD	>CurrentRevs
	subD	FilteredRevs
	bcc	L8FC5
	dec	Scratch1
	incY	
	negA	
	negB	
	sbcA	#$00
L8FC5	aBX	
	ldaB	0, Y
	pushB	
	mul	
	xgDX	
	popA	
	mul	
	adcA	#$00
	tAB	
	aBX	
	xgDX	
	lsrD	
	lsrD	
	lsrD	
	lsrD	
	adcB	#$00
	adcA	#$00
	beq	L8FDF
	ldaB	#$FF
L8FDF	cmpB	2, Y
	bls	L8FE7
	ldaB	2, Y
L8FE7	tst	Scratch1
	bpl	L8FED
	negB	
L8FED	ret	
;
;-----------------------------------------------------------------------
L8FEE:	ldaA	WaterTempValue
	beq	L8FF7
	bclr	Flag10, #%00000100
	ret	
;
L8FF7	brset	Flag10, #%00000100, L900A
	bset	Flag10, #%00000100
	ldD	>CurrentRevs
	stD	FilteredRevs
	ldaA	Revs_c
	staA	Revs_d
L900A	ldY	#LF62B
	callr	L8FAE
	staB	L0146
	ldaA	WaterTemp_Value2
	subA	LF62F
	bcc	L901C
	clrA	
L901C	cmpA	Revs_d
	bls	L902B
	ldaA	#$01
	staA	L0147
	ldD	#$FF00
	jr	L905A
;
L902B	ldaA	WaterTemp_Value2
	addA	LF62F
	bcc	L9035
	ldaA	#$FF
L9035	cmpA	Revs_d
	bcc	L9044
	ldaA	#$03
	staA	L0147
	ldD	#$00FF
	jr	L905A
;
L9044	ldaA	#$02
	staA	L0147
	ldD	L0149
	addA	LF630
	bcc	L9053
	ldaA	#$FF
L9053	addB	LF630
	bcc	L905A
	ldaB	#$FF
L905A	stD	L0149
	ldaB	L0146
	bpl	L9066
	negB	
	ldaA	L014A
L9066	mul	
	adcA	#$00
	tst	L0146
	bpl	L906F
	negA	
L906F	staA	L0146
	ret	
;
;-----------------------------------------------------------------------
L9073:	stD	L0162
	bclr	Flag04, #%00000001
	ldD	>CurrentRevs
	lslD	
	bcc	L9082
	ldD	#$FFFF
L9082	cmpD	L0162
	bhi	L908B
	bset	Flag04, #%00000001
L908B	cmpD	LF643
	bcs	L9094
	ldD	LF643
L9094	stD	L01C8
	ret	
;
;-----------------------------------------------------------------------
L9098:	brclr	Flag18, #%00000001, L90F1
	ldD	>InputCapture2_StoredValue
	lslD	
	lslD	
	pushB	
	ldaB	#$59
	mul	
	xgDX	
	popB	
	ldaA	#$59
	mul	
	adcA	#$00
	tAB	
	aBX	
	xgDX	
	lslD	
	pushB	
	ldaB	L0274
	mul	
	xgDX	
	popB	
	ldaA	L0274
	mul	
	adcA	#$00
	tAB	
	aBX	
	xgDX	
	stD	L01B5
	pushB	
	ldaB	BatteryVoltageSomething1
	mul	
	xgDX	
	popB	
	ldaA	BatteryVoltageSomething1
	mul	
	adcA	#$00
	tAB	
	aBX	
	xgDX	
	addD	L01B5
	cmpD	>L00EB
	bls	L90E6
	ldaA	L01CE
	cmpA	#$FF
	beq	L90F1
	incA	
	jr	L90EE
;
L90E6	ldaA	L01CE
	cmpA	#$80
	bls	L90F1
	decA	
L90EE	staA	L01CE
L90F1	ldaA	L01CE
	ldaB	BatteryVoltageSomething2
	mul	
	lsrD	
	lsrD	
	ret	
;
;-----------------------------------------------------------------------
L90FB:	brclr	Flag18, #%00000001, L9154
	ldD	>L00F1
	lslD	
	lslD	
	pushB	
	ldaB	#$59
	mul	
	xgDX	
	popB	
	ldaA	#$59
	mul	
	adcA	#$00
	tAB	
	aBX	
	xgDX	
	lslD	
	pushB	
	ldaB	L0274
	mul	
	xgDX	
	popB	
	ldaA	L0274
	mul	
	adcA	#$00
	tAB	
	aBX	
	xgDX	
	stD	L01B5
	pushB	
	ldaB	BatteryVoltageSomething1
	mul	
	xgDX	
	popB	
	ldaA	BatteryVoltageSomething1
	mul	
	adcA	#$00
	tAB	
	aBX	
	xgDX	
	addD	L01B5
	cmpD	>L00ED
	bls	L9149
	ldaA	L01CF
	cmpA	#$FF
	beq	L9154
	incA	
	jr	L9151
;
L9149	ldaA	L01CF
	cmpA	#$80
	bls	L9154
	decA	
L9151	staA	L01CF
L9154	ldaA	L01CF
	ldaB	BatteryVoltageSomething2
	mul	
	lsrD	
	lsrD	
	ret	
;
;-----------------------------------------------------------------------
L915E:	ldD	ScaledBatteryVoltage
	ldY	#BatteryTable2
	call	InterpolateValue
	ldaB	#$28
	mul	
	ret	
;
;-----------------------------------------------------------------------
L916C:	brclr	Flag16, #%00001000, L917D
	bclr	TCTL1_TimerControlReg, #(TCTL1_OL3 | TCTL1_OL5)
	ldD	#$000A
	addD	TCNT_TimerCountReg
	stD	TOC5_TimerCompareReg
	stD	TOC3_TimerCompareReg
	ret	
;
L917D	ldD	>CurrentRevs
	cmpD	RevLimit1
	bcc	L918B
	bset	Flag14, #%00010000
	jr	L9194
;
L918B	cmpD	RevLimit2
	bls	L9194
	bclr	Flag14, #%00010000
L9194	brclr	Flag14, #%00010000, L919C
	bclr	Flag06, #%00000010
	ret	
;
L919C	cmpD	#$085E
	bhi	L91CA
	ldD	>CurrentRevs
	subD	>L00C5
	bcs	L91BA
	lslD	
	lslD	
	brset	Flag05, #%00010000, L91B5
	subD	>VertInjectorDuration
	jr	L91B8
;
L91B5	subD	>HorizInjectorDuration
L91B8	bcc	L91BD
L91BA	ldD	#$0000
L91BD	stD	L012F
	brset	Flag05, #%00010000, L91C7
	jmp	L940F
;
L91C7	jmp	L93CD
;
L91CA	bclr	Flag06, #%00000010
	brset	Flag18, #%00000001, L9214
	brclr	InjectorFlags, #%10000000, L91F1
	brset	Flag05, #%00010000, L91E5
	ldD	>VertInjectorDuration
	call	L946B
	call	L9451
	jmp	L940F
;
L91E5	ldD	>HorizInjectorDuration
	call	L946B
	call	L9451
	jmp	L93CD
;
L91F1	brclr	InjectorFlags, HorizInjectorOffTimePending, L9201
	ldD	>HorizInjectorDuration
	call	L946B
	call	L9451
	call	L93CD
L9201	brclr	InjectorFlags, #%00001000, L9211
	ldD	>VertInjectorDuration
	call	L946B
	call	L9451
	call	L940F
L9211	jmp	L92C2
;
L9214	ldaA	Revs_e
	cmpA	#$0A
	bhi	L9233
	ldaA	LF47C
	staA	L0131
	bne	L924A
L9223	brclr	InjectorFlags, #%10000000, L9232
	brclr	Flag05, #%00010000, L922F
	call	TurnOnHorizInjectorIn20uS
	ret	
;
L922F	call	TurnOnVertInjectorIn20uS
L9232	ret	
;
L9233	ldD	>HorizInjectorDuration
	call	L946B
	ldD	L012D
	cmpD	#$000F
	bls	L9223
	ldX	#$000F
	idiv	
	xgDX	
	staB	L0131
L924A	bset	Flag06, #%00000010
	brclr	InjectorFlags, #%10000000, L9281
	brclr	Flag05, #%00010000, L926B
L9255:	ldaA	L0136				; call entry
	addA	L0131
	cmpA	#$2E
	bls	L9267
	subA	#$2E
	subA	#$02
	bhi	L9267
	ldaA	#$2E
L9267	staA	L0138
	ret	
;
;-----------------------------------------------------------------------
L926B:	ldaA	L0137
	addA	L0131
	cmpA	#$2E
	bls	L927D
	subA	#$2E
	subA	#$02
	bhi	L927D
	ldaA	#$2E
L927D	staA	L0139
	ret	
;
L9281	brclr	InjectorFlags, HorizInjectorOffTimePending, L92A0
	ldaA	>L00E5
	cmpA	L0136
	beq	L92A0
	bhi	L9291
	addA	#$30
L9291	subA	L0136
	cmpA	L0131
	bcc	L929D
	callr	L9255
	jr	L92A0
;
L929D	call	TurnOnHorizInjectorIn20uS
L92A0	brclr	InjectorFlags, #%00001000, L92BF
	ldaA	>L00E5
	cmpA	L0137
	beq	L92BF
	bhi	L92B0
	addA	#$30
L92B0	subA	L0137
	cmpA	L0131
	bcc	L92BC
	callr	L926B
	jr	L92BF
;
L92BC	call	TurnOnVertInjectorIn20uS
L92BF	jmp	L92C2
;
L92C2	brclr	Flag11, #%00010000, L92ED
	brset	Flag05, #%00010000, L92ED
	bset	Flag11, #%00000100
	brset	PORTA_DataReg, #HorizInjectorBit, L9318
	ldD	LF407
	addD	#$001E
	cmpD	>RPM_Spark_always_005A
	bhi	L9318
	ldD	CurrentTPS
	cmpD	RPM_TPS_Check
	bhi	L9318
	subD	L022E
	bcs	L9318
	jr	L9319
;
L92ED	brclr	Flag11, #%01000000, L9318
	brclr	Flag05, #%00010000, L9318
	bclr	Flag11, #%00000100
	brset	PORTA_DataReg, #VertInjectorBit, L9318
	ldD	LF407
	addD	#$001E
	cmpD	>RPM_Spark_always_005A
	bhi	L9318
	ldD	CurrentTPS
	cmpD	RPM_TPS_Check
	bhi	L9318
	subD	L0230
	bcs	L9318
	jr	L9319
;
L9318	ret	
;
L9319	cmpD	LF3F3
	bls	L9318
	stD	L011C
	ldX	L011C
	ldaA	LF409
	beq	L9318
	call	MultAbyX
	lsrD	
	ror	Mult_lsB
	lsrD	
	ror	Mult_lsB
	cmpA	#$00
	bne	L933F
	tBA	
	ldaB	Mult_lsB
	jr	L9342
;
L933F	ldD	#$FFFF
L9342	stD	>Timer5_Interval2
	ldD	RevsDiv180
	pushB	
	pushA	
	xgDY	
	popX	
	ldD	>Timer5_Interval2
	idiv	
	stD	Mult_lsB
	xgDY	
	lsrD	
	subD	Mult_lsB
	xgDX	
	bhi	L9365
	addD	#$0001
	bcc	L9365
	ldD	#$FFFF
L9365	addD	LF407
	bcc	L936F
	ldD	#$00B4
	jr	L9378
;
L936F	cmpD	#$00B4
	bls	L9378
	ldD	#$00B4
L9378	stD	L012B
	brclr	Flag11, #%00000100, L93A6
	ldD	L0134
	subD	L012B
	stD	L012D
	call	L9451
	ldD	TCNT_TimerCountReg
	subD	L0125
	subD	L012F
	bcc	TurnOnHorizInjectorIn20uS
	negA	
	negB	
	sbcA	#$00
	subD	#$000E
	bcs	TurnOnHorizInjectorIn20uS
	ldD	L012F
	addD	L0125
	jr	L93FE
;
L93A6	ldD	L0132
	subD	L012B
	stD	L012D
	call	L9451
	ldD	TCNT_TimerCountReg
	subD	L0123
	subD	L012F
	bcc	TurnOnVertInjectorIn20uS
	negA	
	negB	
	sbcA	#$00
	subD	#$000E
	bcs	TurnOnVertInjectorIn20uS
	ldD	L012F
	addD	L0123
	jr	L9440
;
;-----------------------------------------------------------------------
L93CD:	brclr	InjectorFlags, HorizInjectorOffTimePending, L940E
	brclr	PORTA_DataReg, #HorizInjectorBit, L93DB
	bclr	TCTL1_TimerControlReg, #TCTL1_OL5	; (Horiz Injector) low
	bset	CFORC_ForceOutputCompareReg, #FORCE_OC5	; now
L93DB	ldD	TCNT_TimerCountReg
	subD	L0123
	subD	L012F
	bcc	TurnOnHorizInjectorIn20uS
	negA	
	negB	
	sbcA	#$00
	subD	#$000E
	bcs	TurnOnHorizInjectorIn20uS
	ldD	L012F
	addD	L0123
	addD	#$0012
	jr	L93FE
;
TurnOnHorizInjectorIn20uS:	ldD	#10			; on in 20 uS
	addD	TCNT_TimerCountReg
L93FE	stD	TOC5_TimerCompareReg
	ldaA	#TFLG1_OC5
	staA	TFLG1_TimerInterruptFlag1Reg
	brset	Flag02, #InjectorsDisabled, L940B
	bset	TCTL1_TimerControlReg, #(TCTL1_OM5 | TCTL1_OL5)	; next match will set OC5 pin, horiz injector
L940B	bset	TMSK1_TimerInterruptMask1Reg, #TMSK1_OC5	; and trigger interrupt
L940E	ret	
;
;-----------------------------------------------------------------------
L940F:
	brclr	InjectorFlags, #%00001000, L9450
	brclr	PORTA_DataReg, #VertInjectorBit, L941D
	bclr	TCTL1_TimerControlReg, #TCTL1_OL3		; OC3 (VertInjector) low
	bset	CFORC_ForceOutputCompareReg, #FORCE_OC3		; now
L941D	ldD	TCNT_TimerCountReg
	subD	L0125
	subD	L012F
	bcc	TurnOnVertInjectorIn20uS
	negA	
	negB	
	sbcA	#$00
	subD	#$000E
	bcs	TurnOnVertInjectorIn20uS
	ldD	L012F
	addD	L0125
	addD	#$0012
	jr	L9440
;
TurnOnVertInjectorIn20uS:
	ldD	#10			; on in 20 uS
	addD	TCNT_TimerCountReg
L9440	stD	TOC3_TimerCompareReg
	ldaA	#TFLG1_OC3
	staA	TFLG1_TimerInterruptFlag1Reg
	brset	Flag02, #InjectorsDisabled, L944D
	bset	TCTL1_TimerControlReg, #(TCTL1_OM3 | TCTL1_OL3) ; next match will set OC3 pin, vert injector
L944D	bset	TMSK1_TimerInterruptMask1Reg, #TMSK1_OC3	; and trigger interrupt
L9450	ret	
;
;-----------------------------------------------------------------------
L9451:	ldD	RevsDiv180
	tBA	
	ldX	L012D
	call	MultAbyX
	tstA	
	bne	L9464
	tBA	
	ldaB	Mult_lsB
	jr	L9467
;
L9464	ldD	#$FFFF
L9467	stD	L012F
	ret	
;
;-----------------------------------------------------------------------
L946B:	ldX	RevsDiv180
	idiv	
	xgDX	
	stD	L0129
	addD	>RPM_Spark_always_005A
	bcs	L947E
	cmpD	#$02D0
	bls	L9481
L947E	ldD	#$02D0
L9481	stD	L012B
	ldD	#$02D0
	subD	L012B
	stD	L012D
	ret	
;
;-----------------------------------------------------------------------
; Horizontal cylinder injector timing
;
; This is called when the time in (2us steps) the TOC5_TimerCompareReg
; is reached. The normal action is to set the TOC5_TimerCompareReg to the
; time when you want the next interrupt
;
;-----------------------------------------------------------------------
OutputCompare5_isr:
	ldaA	#TFLG1_OC5
	staA	TFLG1_TimerInterruptFlag1Reg				; clear timer 5 interrupt
	bclr	TMSK1_TimerInterruptMask1Reg, #TMSK1_OC5		; disable timer 5 interrupt
	bclr	TCTL1_TimerControlReg, #TCTL1_OL5
	brset	InjectorFlags, HorizInjectorOffTimePending, L94AD
	bclr	Flag11, #%00010000
	ldD	TOC5_TimerCompareReg
	addD	>Timer5_Interval2
	addD	>InjectorOpeningTime
	stD	TOC5_TimerCompareReg
	call	LB2AC
	reti	
;
L94AD	bclr	InjectorFlags, HorizInjectorOffTimePending
	brclr	CurrentSensorErrors, #TPS_SensorError, @TPS_good
	; if most recent TPS value bad, just use last value
	ldD	>HorizCurrentFuelValue
	stD	>HorizInjectorDuration
	addD	TOC5_TimerCompareReg
	addD	>InjectorOpeningTime
	stD	TOC5_TimerCompareReg
	call	LB2AC
	reti	
;
@TPS_good
	ldaA	#$02		; conversion on pin an2 (TPS), result in ADR3
	staA	ADCtlRegister 	; start now, might be done by the time we need the result
	ldaA	L0118
	bpl	L94F9
	negA	
	cmpA	LF449
	bls	L9524
	ldX	L0116
	call	MultAbyX
	lsl	Mult_lsB
	rolB	
	rolA	
	lsl	Mult_lsB
	rolB	
	rolA	
	lsl	Mult_lsB
	rolB	
	rolA	
	stD	L011C
	ldD	>HorizCurrentFuelValue
	subD	L011C
	bcc	L9521
	ldD	#$0000
	jr	L9521
;
L94F9	cmpA	LF411
	bls	L9524
	ldX	RevsByWaterTemp
	call	MultAbyX
	lsl	Mult_lsB
	rolB	
	rolA	
	lsl	Mult_lsB
	rolB	
	rolA	
	lsl	Mult_lsB
	rolB	
	rolA	
	addD	>HorizCurrentFuelValue
	bcs	L951E
	cmpD	#MaxInjectorDuration
	bls	L9521
L951E	ldD	#MaxInjectorDuration
L9521	stD	>HorizInjectorDuration
L9524
@wait	ldaA	ADCtlRegister
	bpl	@wait
	ldaA	ADR3Register
	ldaB	TPS_Trim
	subB	#$80
	bcc	L953D
	ldaB	#$80
	subB	TPS_Trim
	sBA	
	bcc	L9542
	ldaA	#$00
	jr	L9542
;
L953D	aBA	
	bcc	L9542
	ldaA	#$FF
L9542	staA	TPSLookupTableIdx
	call	DoTPSTableLookup
	call	L96E0
	ldD	TOC5_TimerCompareReg
	addD	>HorizInjectorDuration
	addD	>InjectorOpeningTime
	stD	TOC5_TimerCompareReg
	ldaA	Revs_e
	cmpA	#$0A
	bls	L9565
	bset	Flag11, #%00010000
	ldD	CurrentTPS
	stD	L022E
L9565	call	LB2AC
	reti	
;
;-----------------------------------------------------------------------
; Vertical cylinder injector timing
;
; This is called when the time in (2us steps) the TOC3_TimerCompareReg
; is reached. The normal action is to set the TOC3_TimerCompareReg to the
; time when you want the next interrupt
;
;-----------------------------------------------------------------------
OutputCompare3_isr:
	ldaA	#TFLG1_OC3
	staA	TFLG1_TimerInterruptFlag1Reg
	bclr	TMSK1_TimerInterruptMask1Reg, #TMSK1_OC3
	bclr	TCTL1_TimerControlReg, #TCTL1_OL3
	brset	InjectorFlags, #%00001000, L9592
	ldaA	#TFLG1_OC3
	staA	TFLG1_TimerInterruptFlag1Reg
	bclr	TMSK1_TimerInterruptMask1Reg, #TMSK1_OC3
	bclr	TCTL1_TimerControlReg, #TCTL1_OL3
	bclr	Flag11, #%01000000
	ldD	TOC3_TimerCompareReg
	addD	>Timer5_Interval2
	addD	>InjectorOpeningTime
	stD	TOC3_TimerCompareReg
	call	LB31E
	reti	
;
L9592	bclr	InjectorFlags, #%00001000
	brclr	CurrentSensorErrors, #TPS_SensorError, L95AA
	ldD	>VertCurrentFuelValue
	stD	>VertInjectorDuration
	addD	TOC3_TimerCompareReg
	addD	>InjectorOpeningTime
	stD	TOC3_TimerCompareReg
	call	LB31E
	reti	
;
L95AA	ldaA	#$02
	staA	ADCtlRegister
	ldaA	L0118
	bpl	L95DE
	negA	
	cmpA	LF449
	bls	L9609
	ldX	L0116
	call	MultAbyX
	lsl	Mult_lsB
	rolB	
	rolA	
	lsl	Mult_lsB
	rolB	
	rolA	
	lsl	Mult_lsB
	rolB	
	rolA	
	stD	L011C
	ldD	>VertCurrentFuelValue
	subD	L011C
	bcc	L9606
	ldD	#$0000
	jr	L9606
;
L95DE	cmpA	LF411
	bls	L9609
	ldX	RevsByWaterTemp
	call	MultAbyX
	lsl	Mult_lsB
	rolB	
	rolA	
	lsl	Mult_lsB
	rolB	
	rolA	
	lsl	Mult_lsB
	rolB	
	rolA	
	addD	>VertCurrentFuelValue
	bcs	L9603
	cmpD	#MaxInjectorDuration
	bls	L9606
L9603	ldD	#MaxInjectorDuration
L9606	stD	>VertInjectorDuration
L9609
@loop	ldaA	ADCtlRegister
	bpl	@loop
	ldaA	ADR3Register
	ldaB	TPS_Trim
	subB	#$80
	bcc	L9622
	ldaB	#$80
	subB	TPS_Trim
	sBA	
	bcc	L9627
	ldaA	#$00
	jr	L9627
;
L9622	aBA	
	bcc	L9627
	ldaA	#$FF
L9627	staA	TPSLookupTableIdx
	call	DoTPSTableLookup
	call	L9768
	ldD	TOC3_TimerCompareReg
	addD	>VertInjectorDuration
	addD	>InjectorOpeningTime
	stD	TOC3_TimerCompareReg
	ldaA	Revs_e
	cmpA	#$0A
	bls	L964A
	bset	Flag11, #%01000000
	ldD	CurrentTPS
	stD	L0230
L964A	call	LB31E
	reti	
;
;-----------------------------------------------------------------------
L964E:	ldD	CurrentTPS
	cmpD	RPM_TPS_Check
	bls	L966D
	ldD	RPM_TPS_Check
	brclr	Flag08, #%00000100, L9668
	lslD	
	bcc	L9663
	ldaA	#$FF
L9663	staA	L0289
	jr	L96BE
;
L9668	bset	Flag08, #%00000100
	jr	L9670
;
L966D	bclr	Flag08, #%00000100
L9670	lslD	
	bcc	L9675
	ldaA	#$FF
L9675	pushA	
	subA	L0289
	tAB	
	beq	L96B4
	bcc	L9698
	negB	
	ldaA	L0118
	bmi	L968F
	sBA	
	bcc	L96B1
	cmpA	#$80
	bhi	L96B1
	ldaA	#$80
	jr	L96B1
;
L968F	sBA	
	cmpA	#$80
	bhi	L96B1
	ldaA	#$80
	jr	L96B1
;
L9698	ldaA	L0118
	bitA	#%10000000
	beq	L96AA
	aBA	
	bcc	L96B1
	cmpA	#$7F
	bcs	L96B1
	ldaA	#$7F
	jr	L96B1
;
L96AA	aBA	
	cmpA	#$7F
	bcs	L96B1
	ldaA	#$7F
L96B1	staA	L0118
L96B4	ldaA	L0122
	staA	L0289
	popA	
	staA	L0122
L96BE	brclr	Flag16, #%10000000, L96DF
	ldD	>CurrentRevs
	cmpD	#$FFFE
	bcc	L96DF
	cmpD	LF47A
	bls	L96DF
	bclr	InjectorFlags, #%10000000
	di	
	call	L97F0
	call	L98A8
	call	L916C
	ei	
L96DF	ret	
;
;-----------------------------------------------------------------------
L96E0:	ldD	CurrentTPS
	cmpD	RPM_TPS_Check
	bcs	L96FB
	ldD	RPM_TPS_Check
	subD	L022C
	bhi	L973D
L96F1	ldD	#$0000
	stD	L011C
	stD	FuelAdjValue
	ret	
;
L96FB	ldD	L022C
	cmpD	RPM_TPS_Check
	bcs	L970C
	ldD	RPM_TPS_Check
	subD	CurrentTPS
	jr	L971A
;
L970C	ldD	CurrentTPS
	subD	L022C
	beq	L96F1
	bcc	L973D
	negA	
	negB	
	sbcA	#$00
L971A	cmpD	LF405
	bls	L96F1
	stD	L011C
	ldX	L011C
	ldaA	Revs6
	call	MultAbyX
	lsrD	
	stD	FuelAdjValue
	ldD	>HorizInjectorDuration
	subD	FuelAdjValue
	bcc	L9764
	ldD	#$0000
	jr	L9764
;
L973D	cmpD	LF3F3
	bls	L96F1
	stD	L011C
	ldX	L011C
	ldaA	Revs4
	call	MultAbyX
	lsrD	
	stD	FuelAdjValue
	ldD	>HorizInjectorDuration
	addD	FuelAdjValue
	bcs	L9761
	cmpD	#MaxInjectorDuration
	bls	L9764
L9761	ldD	#MaxInjectorDuration
L9764	stD	>HorizInjectorDuration
	ret	
;
;-----------------------------------------------------------------------
L9768:	ldD	CurrentTPS
	cmpD	RPM_TPS_Check
	bcs	L9783
	ldD	RPM_TPS_Check
	subD	L022C
	bhi	L97C5
L9779	ldD	#$0000
	stD	L011C
	stD	FuelAdjValue
	ret	
;
L9783	ldD	L022C
	cmpD	RPM_TPS_Check
	bcs	L9794
	ldD	RPM_TPS_Check
	subD	CurrentTPS
	jr	L97A2
;
L9794	ldD	CurrentTPS
	subD	L022C
	beq	L9779
	bcc	L97C5
	negA	
	negB	
	sbcA	#$00
L97A2	cmpD	LF405
	bls	L9779
	stD	L011C
	ldX	L011C
	ldaA	Revs6
	call	MultAbyX
	lsrD	
	stD	FuelAdjValue
	ldD	>VertInjectorDuration
	subD	FuelAdjValue
	bcc	L97EC
	ldD	#$0000
	jr	L97EC
;
L97C5	cmpD	LF3F3
	bls	L9779
	stD	L011C
	ldX	L011C
	ldaA	Revs4
	call	MultAbyX
	lsrD	
	stD	FuelAdjValue
	ldD	>VertInjectorDuration
	addD	FuelAdjValue
	bcs	L97E9
	cmpD	#MaxInjectorDuration
	bls	L97EC
L97E9	ldD	#MaxInjectorDuration
L97EC	stD	>VertInjectorDuration
	ret	
;
;-----------------------------------------------------------------------
L97F0:	ldD	CurrentTPS
	cmpD	RPM_TPS_Check
	bcs	L9817
	ldD	RPM_TPS_Check
	subD	L022C
	bhi	L9869
L9801	ldD	#$0000
	stD	FuelAdjValue
	ldD	>HorizCurrentFuelValue
	stD	>HorizInjectorDuration
	ldD	>VertCurrentFuelValue
	stD	>VertInjectorDuration
	stD	L011C
	ret	
;
L9817	ldD	L022C
	cmpD	RPM_TPS_Check
	bcs	L9828
	ldD	RPM_TPS_Check
	subD	CurrentTPS
	jr	L9836
;
L9828	ldD	CurrentTPS
	subD	L022C
	beq	L9801
	bcc	L9869
	negA	
	negB	
	sbcA	#$00
L9836	cmpD	LF405
	bls	L9801
	stD	L011C
	ldX	L011C
	ldaA	Revs6
	call	MultAbyX
	lsrD	
	stD	FuelAdjValue
	ldD	>HorizCurrentFuelValue
	subD	FuelAdjValue
	bcc	L9857
	ldD	#$0000
L9857	stD	>HorizInjectorDuration
	ldD	>VertCurrentFuelValue
	subD	FuelAdjValue
	bcc	L9865
	ldD	#$0000
L9865	stD	>VertInjectorDuration
	ret	
;
;-----------------------------------------------------------------------
L9869	cmpD	LF3F3
	bls	L9801
	stD	L011C
	ldX	L011C
	ldaA	Revs4
	call	MultAbyX
	lsrD	
	stD	FuelAdjValue
	ldD	>HorizCurrentFuelValue
	addD	FuelAdjValue
	bcs	L988D
	cmpD	#MaxInjectorDuration
	bls	L9890
L988D	ldD	#MaxInjectorDuration
L9890	stD	>HorizInjectorDuration
	ldD	>VertCurrentFuelValue
	addD	FuelAdjValue
	bcs	L98A1
	cmpD	#MaxInjectorDuration
	bls	L98A4
L98A1	ldD	#MaxInjectorDuration
L98A4	stD	>VertInjectorDuration
	ret	
;
;-----------------------------------------------------------------------
L98A8:	ldaA	L0118
	bpl	L98E9
	negA	
	cmpA	LF449
	bls	L992B
	ldX	L0116
	call	MultAbyX
	lsl	Mult_lsB
	rolB	
	rolA	
	lsl	Mult_lsB
	rolB	
	rolA	
	lsl	Mult_lsB
	rolB	
	rolA	
	stD	L011C
	ldD	>HorizInjectorDuration
	subD	L011C
	bcc	L98D6
	ldD	#$0000
L98D6	stD	>HorizInjectorDuration
	ldD	>VertInjectorDuration
	subD	L011C
	bcc	L98E4
	ldD	#$0000
L98E4	stD	>VertInjectorDuration
	jr	L992B
;
L98E9	cmpA	LF411
	bls	L992B
	ldX	RevsByWaterTemp
	call	MultAbyX
	lsl	Mult_lsB
	rolB	
	rolA	
	lsl	Mult_lsB
	rolB	
	rolA	
	lsl	Mult_lsB
	rolB	
	rolA	
	stD	L011C
	addD	>HorizInjectorDuration
	bcs	L9911
	cmpD	#MaxInjectorDuration
	bls	L9914
L9911	ldD	#MaxInjectorDuration
L9914	stD	>HorizInjectorDuration
	ldD	>VertInjectorDuration
	addD	L011C
	bcs	L9925
	cmpD	#MaxInjectorDuration
	bls	L9928
L9925	ldD	#MaxInjectorDuration
L9928	stD	>VertInjectorDuration
L992B	ret	
;
;-----------------------------------------------------------------------
CalculateFuel:
	ldD	TPS_FuelMapNdxFrac
	ldX	#FuelMapTable
	ldY	#Scratch1
	staB	0, Y
	tAB	
	aBX	
	ldD	RPM_FuelMapNdxFrac
	staB	1, Y
	ldaB	#$10
	staB	2, Y
	mul	
	aBX	
	call	InterpolateMapPoint
	ldaB	FuelMapScaleFactor
	mul	
	cmpD	#MaxInjectorDuration
	bls	L9958
	ldD	#MaxInjectorDuration
L9958	stD	>CurrentFuelValue
	stD	>UntrimmedCurrentFuelValue
	ldD	TPS_FuelMapNdxFrac
	ldX	#VertCylinderTrimTable
	ldY	#Scratch1
	staB	0, Y
	tAB	
	aBX	
	ldD	RPM_FuelMapNdxFrac
	staB	1, Y
	ldaB	#$10
	staB	2, Y
	mul	
	aBX	
	call	InterpolateMapPoint
	addA	#$80
	staA	>CurrentVertCylinderTrim
	bpl	L9985
	negA	
L9985	ldaB	FuelMapScaleFactor
	mul	
	tst	>CurrentVertCylinderTrim
	bpl	L9992
	negA	
	negB	
	sbcA	#$00
L9992	stD	>CurrentVertCylinderTrim
	ldaA	O2_FeedBackEnabled
	beq	@noO2
	ldaA	L0099
	brset	Flag13, #%00010000, L99C6
	ldaA	L0098
	jr	L99C6
;
@noO2	ldaA	L0288
	bne	L99C3
	ldaA	ScaledFuelTrimpot
	subA	PowerOnFuelTrimpot
	bcs	L99B8
	cmpA	LF8CD
	bls	L9A31
	jr	L99BE
;
L99B8	negA	
	cmpA	LF8CD
	bls	L9A31
L99BE	ldaA	#$FF
	staA	L0288
L99C3	ldaA	ScaledFuelTrimpot
L99C6	ldaB	FuelTrimScaleFactor	; $40 * +-$80 = $2000 (max trim)
	subA	#$80
	bcc	L99FE
	negA	
	mul	
	lslA				; max * 2 =$4000
	staA	>Scratch5
	ldD	>CurrentRevs
	cmpD	RevsConst	; jmp if > 3000 rpm
	bcc	L99EB
	ldX	RevsConst	; 5000
	fdiv			; fraction of current/3000 rpm
	xgDX			; put msB in A
	staA	>Scratch5_lsB

	ldaB	>Scratch5	; trim
	mul	
	staA	>Scratch5	; trim of 0 to 0.256ms scaled from 0 to 3000 rpm
L99EB	clrA	
	ldaB	>Scratch5	; $4000 / 256 = $40
	lslD			; * 2 = $80 = 0.256 ms max trim above 3000 rpm
	addD	>CurrentFuelValue
	cmpD	#MaxInjectorDuration
	bls	L9A2E
	ldD	#MaxInjectorDuration
	jr	L9A2E
;
L99FE	mul	
	lslA	
	staA	>Scratch5
	ldD	>CurrentRevs
	cmpD	RevsConst
	bcc	L9A1B
	ldX	RevsConst
	fdiv	
	xgDX	
	staA	>Scratch5_lsB
	ldaB	>Scratch5
	mul	
	staA	>Scratch5
L9A1B	clrA	
	ldaB	>Scratch5
	lslD	
	stD	>Scratch5
	ldD	>CurrentFuelValue
	subD	>Scratch5
	bcc	L9A2E
	ldD	#$0000
L9A2E	stD	>CurrentFuelValue
L9A31	ldY	#RPM_Table6
	ldD	RPM_SparkMapNdxFrac
	call	InterpolateValue
	staA	Revs6

	ldY	#RPM_Table4
	ldD	RPM_SparkMapNdxFrac
	call	InterpolateValue
	staA	Revs4

	ldY	#RPM_To_TPS_Table
	ldX	#RPM_SparkMapNdxFrac
	call	InterpolateWordValue
	stD	RPM_TPS_Check
	
	ldY	#RPM_Table5
	ldD	RPM_SparkMapNdxFrac
	call	InterpolateValue
	staA	Revs5_7

	ldY	#WaterTemp_Table3
	ldD	WaterTempNdxFrac
	call	InterpolateValue
	staA	WaterTemp6

	ldY	#AirTempTable1
	ldD	AirTempNdxFrac
	call	InterpolateValue
	staA	AirTemp2
	ldaB	Revs5_7
	mul	
	stD	Revs5_7
	ldX	#Revs5_7
	ldaA	WaterTemp6
	call	MultDbyX0
	stD	RevsByWaterTemp

	ldY	#RPM_Table7
	ldD	RPM_SparkMapNdxFrac
	call	InterpolateValue
	staA	Revs5_7

	ldY	#WaterTemp_Table6
	ldD	WaterTempNdxFrac
	call	InterpolateValue
	staA	WaterTemp6

	ldY	#AirTempTable2
	ldD	AirTempNdxFrac
	call	InterpolateValue
	staA	AirTemp2

	ldaB	Revs5_7
	mul	
	stD	Revs5_7
	ldX	#Revs5_7
	ldaA	WaterTemp6
	call	MultDbyX0
	stD	L0116

	ldX	>CurrentFuelValue
	ldaA	>AltitudeTrim
	call	MultAbyX
	stY	>Scratch5
	lsl	>Scratch5_lsB
	rolB	
	rolA	
	cmpD	#MaxInjectorDuration
	bls	L9AE7
	ldD	#MaxInjectorDuration
L9AE7	stD	>CurrentFuelValue

	ldaA	O2_FeedBackEnabled
	beq	@no_O2
	ldX	#O2FuelTrim_a
	call	ApplyFuelAdjustment
	ldX	#O2FuelTrim
	call	ApplyFuelAdjustment

@no_O2	ldaA	>WaterTempTrim
	ldX	>CurrentFuelValue
	call	MultAbyX
	stY	>Scratch5
	lsl	>Scratch5_lsB
	rolB	
	rolA	
	cmpD	#MaxInjectorDuration
	bcc	@tooBig
	stD	>CurrentFuelValue
	ldD	StartEnrichmentCounter
	beq	L9B8C
	SetupForCalcMapNdxFrac StartEnrichmentCounter, StartEnrichment_BreakPoints, $10
	stD	StartEnrichmentCounter
	call	DoCalcMapNdxFrac
	stD	StartEnrichmentNdxFrac
	ldD	StartEnrichmentNdxFrac
	ldX	#StartEnrichmentMap
	ldY	#Scratch1
	staB	0, Y
	tAB	
	aBX	
	ldD	WaterTempNdxFrac
	staB	1, Y
	ldaB	#$10
	staB	2, Y
	mul	
	aBX	
	call	InterpolateMapPoint
	staA	StartEnrichmentValue
	ldX	>CurrentFuelValue
	call	MultAbyX
	stY	>Scratch5
	lsl	>Scratch5_lsB
	rolB	
	rolA	
	bcs	@tooBig
	lsl	>Scratch5_lsB
	rolB	
	rolA	
	bcs	@tooBig
	lsl	>Scratch5_lsB
	rolB	
	rolA	
	bcs	@tooBig
	tst	LF8D0
	bne	@L9B80
	lsl	>Scratch5_lsB
	rolB	
	rolA	
	bcs	@tooBig
@L9B80	cmpD	#MaxInjectorDuration
	bcs	L9B89
@tooBig	ldD	#MaxInjectorDuration
L9B89	stD	>CurrentFuelValue
L9B8C	ldX	>CurrentFuelValue
	ldaA	>AirTempTrim
	call	MultAbyX
	stY	>Scratch5
	lsl	>Scratch5_lsB
	rolB	
	rolA	
	cmpD	#MaxInjectorDuration
	bcs	L9BA7
	ldD	#MaxInjectorDuration
L9BA7	stD	>CurrentFuelValue
	stD	>HorizCurrentFuelValue
	brclr	Flag13, #%00000100, L9BB4
	ldD	#$0000
L9BB4	stD	>HorizInjectorDuration
	ldD	>CurrentVertCylinderTrim
	bpl	L9BC6
	addD	>HorizCurrentFuelValue
	bcs	L9BD4
	ldD	#$0000
	jr	L9BD4
;
L9BC6	addD	>HorizCurrentFuelValue
	bcs	L9BD1
	cmpD	#MaxInjectorDuration
	bcs	L9BD4
L9BD1	ldD	#MaxInjectorDuration
L9BD4	stD	>VertCurrentFuelValue
	brclr	Flag13, #%00000100, L9BDE
	ldD	#$0000
L9BDE	stD	>VertInjectorDuration
	ret	
;
;-----------------------------------------------------------------------
; X[0] is trim value + $80
;
; Fuel = Fuel + Fuel * X[0]/2
;
ApplyFuelAdjustment:
	ldaA	0, X
	lsrA	
	adcA	#$00
	subA	#$40
	bmi	L9C07
	pushA	
	ldaB	>CurrentFuelValue_lsB
	mul	
	adcA	#$00
	staA	>Scratch5_lsB
	ldaA	>CurrentFuelValue
	clr	>Scratch5
	popB	
	mul	
	addD	>Scratch5
	addD	>CurrentFuelValue
	bcs	L9C2C
	jr	L9C26
;
L9C07	negA	
	pushA	
	ldaB	>CurrentFuelValue_lsB
	mul	
	adcA	#$00
	staA	>Scratch5_lsB
	ldaA	>CurrentFuelValue
	clr	>Scratch5
	popB	
	mul	
	addD	>Scratch5
	stD	>Scratch5
	ldD	>CurrentFuelValue
	subD	>Scratch5
L9C26	cmpD	#MaxInjectorDuration
	bls	L9C2F
L9C2C	ldD	#MaxInjectorDuration
L9C2F	stD	>CurrentFuelValue
	ret	
;
;-----------------------------------------------------------------------
L9C33:	ldaB	L0118
	bpl	L9C6C
	negB	
	lsrB	
	lsrB	
	lsrB	
	lsrB	
	ldX	#LFA11
	aBX	
	ldaA	0, X
	ldaB	WaterTempNdxFrac
	ldX	#WaterTemp_Table9
	aBX	
	ldaB	0, X
	mul	
	staA	L0110
	ldD	L0118
	negA	
	negB	
	sbcA	#$00
	stD	L0118
	ldaA	L0110
	ldX	#$0118
	call	MultDbyX0
	negA	
	negB	
	sbcA	#$00
	bset	Flag20, #%00000001
	jr	L9C8C
;
L9C6C	lsrB	
	lsrB	
	lsrB	
	lsrB	
	ldX	#LF9F1
	aBX	
	ldaA	0, X
	ldaB	WaterTempNdxFrac
	ldX	#WaterTemp_Table7
	aBX	
	ldaB	0, X
	mul	
	staA	L0110
	ldX	#$0118
	call	MultDbyX0
	bclr	Flag20, #%00000001
L9C8C	stD	L0118
	call	DoNothingFeature
	ldX	StartEnrichmentCounter
	beq	L9CA0
	decX	
	stX	StartEnrichmentCounter
	bne	L9CA0
	inc	>L009B
L9CA0	brclr	Flag20, #%00010000, L9CB2
	ldaA	L01E3
	beq	L9CAF
	decA	
	staA	L01E3
	bne	L9CB2
L9CAF	bclr	Flag20, #%00010000
L9CB2	call	LA1FC
	ret	
;
;
;#######################################################################
; Due to Rom flag I named - O2_FeedBackEnabled 
; being 0, I think none of the code between the lines of ### is used
; except loading $80 (+-0) into O2FuelTrim
;
; Could have been an lambda O2 sensor trim system
; but not used so no need to spend time decoding :-)
; 
O2TrimFuctionTable:
	dw	O2TrimFunction_00, O2TrimFunction_01, O2TrimFunction_02, O2TrimFunction_03, O2TrimFunction_04, O2TrimFunction_05, O2TrimFunction_06, O2TrimFunction_07
	dw	O2TrimFunction_08

MiscTable1:	
	db	$00, $00, $00, $00, $00, $05, $01, $01, $01
;
;-----------------------------------------------------------------------
DoNothingFeature:
	tst	O2_FeedBackEnabled
	bne	@on
	ldaA	#$80
	staA	>O2FuelTrim
	ret	
;
@on	ldaA	L014D
	beq	L9CE4
	dec	L014D
L9CE4	ldaA	L014C
	beq	L9CEC
	dec	L014C
L9CEC	ldX	#O2TrimFuctionTable
	ldaB	>O2FuncIdx
	lslB	
	aBX	
	ldaB	ScaledFuelTrimpot
	ldX	0, X
	jmp	0, X
;
;-----------------------------------------------------------------------
O2TrimFunction_00:
	ldY	#WaterTemp_Table5
	ldD	WaterTempNdxFrac
	call	InterpolateValue
	tAB	
	clrA	
	lslD	
	lslD	
	lslD	
	xgDX	
	stX	O2_Var1
	ldaA	#$01
	jmp	L9D9D
;
;-----------------------------------------------------------------------
O2TrimFunction_01:
	ldX	O2_Var1
	beq	L9D1F
	decX	
	stX	O2_Var1
	jmp	L9DA0
;
L9D1F	cmpB	LF6BA
	bhi	L9D6C
	jr	L9D95
;
;-----------------------------------------------------------------------
O2TrimFunction_02:
	clr	>O2_Var2
	cmpB	LF6BB
	bhi	L9D47
	cmpB	LF6B9
	bcc	L9DA0
	jr	L9D4B
;
;-----------------------------------------------------------------------
O2TrimFunction_03:
	ldaA	>O2_Var2
	cmpA	LF6B8
	bcc	L9D6C
	cmpB	LF6B9
	bcc	L9DA0
	inc	>O2_Var2
	jr	L9D4B
;
L9D47	ldaA	#$03
	jr	L9D9D
;
L9D4B	ldaA	#$04
	jr	L9D9D
;
;-----------------------------------------------------------------------
O2TrimFunction_04:
	ldaA	>O2_Var2
	cmpA	LF6B8
	bcc	L9D95
	cmpB	LF6BB
	bls	L9DA0
	inc	>O2_Var2
	jr	L9D47
;
;-----------------------------------------------------------------------
O2TrimFunction_05:
	brclr	Flag11, #%00100000, L9D7C
	cmpB	LF6BA
	bcc	L9DA0
	jr	L9D95
;
L9D6C	bclr	FirstTimeSensorErrors, #%00000100
	bclr	CurrentSensorErrors, #%00000100
	ldaA	#$05
	jr	L9D9D
;
;-----------------------------------------------------------------------
O2TrimFunction_06:
	brclr	Flag11, #%00100000, L9DA0
	jr	L9D6C
;
L9D7C	ldaA	#$06
	jr	L9D9D
;
;-----------------------------------------------------------------------
O2TrimFunction_07:
	brclr	Flag11, #%00100000, L9DA0
	jr	L9D95
;
L9D86	ldaA	#$07
	jr	L9D9D
;
;-----------------------------------------------------------------------
O2TrimFunction_08:
	brclr	Flag11, #%00100000, L9D86
	cmpB	LF6BA
	bcs	L9DA0
	jr	L9D6C
;
L9D95	bclr	FirstTimeSensorErrors, #O2_SensorError
	bclr	CurrentSensorErrors, #O2_SensorError
	ldaA	#$08
L9D9D	staA	>O2FuncIdx
L9DA0	ldX	#MiscTable1
	ldaB	>O2FuncIdx
	aBX	
	ldaA	O2Flags
	andA	#%11111010
	addA	0, X
	staA	O2Flags
	brset	O2Flags, #O2_LoopClosed, L9DB8
	bclr	Flag06, #%10000000
	jr	L9DBB
;
L9DB8	bset	Flag06, #%10000000
L9DBB	bset	O2Flags, #O2_LoopClosed
	ldX	>CurrentRevs
	brset	Flag06, #%10000000, L9DDE
	cmpX	LF6C2
	bls	L9DFE
	ldaB	CurrentAirTemp
	cmpB	LF6C0
	bcs	L9DFE
	ldaB	LF6BE
	brset	Flag13, #%00010000, L9DF5
	ldaB	LF6BC
	jr	L9DF5
;
L9DDE	cmpX	LF6C4
	bcs	L9DFE
	ldaB	CurrentAirTemp
	cmpB	LF6C1
	bcs	L9DFE
	ldaB	LF6BF
	brset	Flag13, #%00010000, L9DF5
	ldaB	LF6BD
L9DF5	cmpB	CurrentWaterTemp
	bcc	L9DFE
	brclr	Flag13, #%00100000, L9E04
L9DFE	bclr	O2Flags, #O2_LoopClosed
	clr	L014C
L9E04	brset	Flag13, #%00000100, L9E10
	brclr	Flag13, #%10000000, L9E19
	brclr	Flag15, #TPS_Closed, L9E19
L9E10	bclr	O2Flags, #O2_LoopClosed
	ldaB	LF6D1
	staB	L014C
L9E19	brclr	Flag15, #TPS_WideOpen, L9E26
	bclr	O2Flags, #O2_LoopClosed
	ldaB	LF6D1
	staB	L014C
L9E26	brset	Flag06, #%10000000, L9E36
	brclr	O2Flags, #O2_LoopClosed, L9E36
	ldaB	L014C
	beq	L9E36
	bclr	O2Flags, #O2_LoopClosed
L9E36	brclr	O2Flags, #O2_LoopClosed, L9E4A
	bset	Flag11, #%00100000
	brset	CurrentSensorErrors, #%00000100, L9E45
	brset	O2Flags, #%00000001, L9E58
L9E45	bclr	O2Flags, #O2_LoopClosed
	jr	L9E4D
;
L9E4A	bclr	Flag11, #%00100000
L9E4D	bclr	O2Flags, #%01000000
	ldaA	#$80
	staA	>O2FuelTrim
	jmp	L9E8B
;
L9E58	brset	Flag06, #%10000000, L9E62
	clrA	
	staA	L0151
	jr	L9E70
;
L9E62	brset	O2Flags, #%00000100, L9E6C
	brclr	O2Flags, #%00001000, L9E88
	jr	L9E70
;
L9E6C	brset	O2Flags, #%00001000, L9E88
L9E70	call	L9EF1
	ldaA	LF6D1
	staA	L014C
	ldaA	LF6CF
	brclr	Flag13, #%00010000, L9E83
	ldaA	LF6D0
L9E83	staA	L014D
	jr	L9E8B
;
L9E88	call	L9E9A
L9E8B	brclr	O2Flags, #%00000100, L9E94
	bset	O2Flags, #%00001000
	jr	L9E97
;
L9E94	bclr	O2Flags, #%00001000
L9E97	jmp	L9F6E
;
;-----------------------------------------------------------------------
L9E9A:	brset	Flag13, #%00010000, L9EA3
	ldaA	L014C
	beq	L9EB8
L9EA3	bclr	O2Flags, #%10000000
	ldaA	L014D
	bne	L9EB5
	ldaB	#$01
	ldaA	LF6D0
	staA	L014D
	jr	L9ED8
;
L9EB5	clrB	
	jr	L9ED8
;
L9EB8	clrB	
	ldaA	L014D
	bne	L9ED8
	incB	
	staB	L014D
	brset	O2Flags, #%10000000, L9ECE
	bset	O2Flags, #%10000000
	staB	L0151
	jr	L9ED8
;
L9ECE	ldaA	L0151
	cmpA	#$FF
	beq	L9ED8
	inc	L0151
L9ED8	brset	O2Flags, #%00000100, L9EE6
	ldaA	>O2FuelTrim
	aBA	
	bcc	L9EE4
	ldaA	#$FF
L9EE4	jr	L9EED
;
L9EE6	ldaA	>O2FuelTrim
	sBA	
	bcc	L9EED
	clrA	
L9EED	staA	>O2FuelTrim
	ret	
;
;-----------------------------------------------------------------------
L9EF1:	ldaB	L0151
	lsrB	
	staB	L0151
	brclr	Flag13, #%00010000, L9F06
	ldaA	LF6C6
	addA	L0151
	bcs	L9F2F
	jr	L9F31
;
L9F06	ldaA	CurrentTPS
	ldaB	LF6C9
	mul	
	addD	LF6C7
	bcs	L9F2F
	addA	L0151
	bcs	L9F2F
	staA	L0150
	brset	O2Flags, #%00000100, L9F34
	ldaA	CurrentTPS
	ldaB	LF6CC
	mul	
	addD	LF6CA
	bcs	L9F2F
	addA	L0150
	bcc	L9F31
L9F2F	ldaA	#$FF
L9F31	staA	L0150
L9F34	ldaA	L0150
	cmpA	LF6CD
	bcc	L9F41
	ldaA	LF6CD
	jr	L9F49
;
L9F41	cmpA	LF6CE
	bls	L9F49
	ldaA	LF6CE
L9F49	brset	Flag06, #%10000000, L9F4E
	lsrA	
L9F4E	staA	L0150
	brset	O2Flags, #%00000100, L9F5E
	addA	>O2FuelTrim
	bcc	L9F5C
	ldaA	#$FF
L9F5C	jr	L9F67
;
L9F5E	ldaA	>O2FuelTrim
	subA	L0150
	bcc	L9F67
	clrA	
L9F67	staA	>O2FuelTrim
	bset	O2Flags, #%01000000
	ret	
;
L9F6E	brclr	O2Flags, #%01000000, L9F7E
	ldaA	CurrentWaterTemp
	cmpA	LF6E4
	bls	L9F7E
	brclr	Flag14, #%10000000, L9F81
L9F7E	jmp	LA030
;
L9F81	bclr	O2Flags, #%01000000
	brclr	Flag13, #%00010000, L9FB1
	brset	Flag23, #%00010000, L9FA8
	ldaA	#$10
	staA	Flag23
	ldD	#$0000
	stD	L0153
	ldaA	LF6D8
	staA	L0155
	ldD	LF6D9
	stD	L0156
	ldD	LF6DB
	stD	L0158
L9FA8	ldY	#$0099
	call	LA031
	jr	LA030
;
L9FB1	ldaA	CurrentTPS
	subA	FilteredTPS
	bcc	L9FBA
	negA	
L9FBA	cmpA	O2_TPS_Threshhold
	bcc	L9FCC
	; TPS changing
	ldaA	>CurrentRevs
	cmpA	O2_RPM_Min
	bcs	L9FCC
	cmpA	O2_RPM_Max
	bls	L9FCE
L9FCC	jr	LA02D
;
L9FCE	ldaA	CurrentTPS
	cmpA	O2_TPS_RangeA
	bhi	LA003
	brset	Flag15, #TPS_Closed, LA02D
	brset	Flag23, #%00010000, L9FFA
	ldaA	#$10
	staA	Flag23
	ldD	#$0000
	stD	L0153
	ldaA	LF6DD
	staA	L0155
	ldD	LF6DE
	stD	L0156
	ldD	LF6E0
	stD	L0158
L9FFA	ldY	#$0098
	call	LA031
	jr	LA030
;
LA003	cmpA	O2_TPS_RangeB
	bcs	LA02D
	brset	Flag23, #%00100000, LA028
	ldaA	#$20
	staA	Flag23
	ldD	#$0000
	stD	L0153
	ldaA	LF6D2
	staA	L0155
	ldD	LF6D3
	stD	L0156
	ldD	LF6D5
	stD	L0158
LA028	call	LA081
	jr	LA030
;
LA02D	clr	>Flag23
LA030	ret	
;
;-----------------------------------------------------------------------
LA031:	ldaB	>O2FuelTrim
	ldX	L0153
	aBX	
	stX	L0153
	dec	L0155
	bne	LA080
	ldaA	L0152
	cmpA	LF6E3
	bcc	LA07D
	cmpX	L0156
	bcs	LA062
	inc	L0152
	ldaA	0, Y
	addA	LF6E2
	bcs	LA05D
	cmpA	LF73C
	bls	LA07A
LA05D	ldaA	LF73C
	jr	LA07A
;
LA062	cmpX	L0158
	bhi	LA07D
	inc	L0152
	ldaA	0, Y
	subA	LF6E2
	bcs	LA077
	cmpA	LF73B
	bcc	LA07A
LA077	ldaA	LF73B
LA07A	staA	0, Y
LA07D	clr	>Flag23
LA080	ret	
;
;-----------------------------------------------------------------------
LA081:	ldaB	>O2FuelTrim
	ldX	L0153
	aBX	
	stX	L0153
	dec	L0155
	bne	LA0C5
	cmpX	L0156
	bcs	LA0A9
	clr	L0152
	ldaA	O2FuelTrim_a
	addA	LF6D7
	bcs	LA0A4
	cmpA	O2TrimMax
	bls	LA0C0
LA0A4	ldaA	O2TrimMax
	jr	LA0C0
;
LA0A9	cmpX	L0158
	bhi	LA0C2
	clr	L0152
	ldaA	O2FuelTrim_a
	subA	LF6D7
	bcs	LA0BD
	cmpA	LF73D
	bcc	LA0C0
LA0BD	ldaA	LF73D
LA0C0	staA	O2FuelTrim_a
LA0C2	clr	>Flag23
LA0C5	ret	
;-----------------------------------------------------------------------
; End of O2 trim code
;#######################################################################





;-----------------------------------------------------------------------
CheckForWideOpenOrClosedThrottle:
	ldaA	TPS_LearnedWideOpenThrottle
	subA	WideOpenThrottleThreshold
	cmpA	TPS_Voltage
	bcc	@notWOT
	cmpA	TPS_VoltgePrevious
	bcc	@notWOT
	bset	Flag15, #TPS_WideOpen
	jr	@isWOT
;
@notWOT
	ldaA	TPS_LearnedWideOpenThrottle
	subA	NotWideOpenThrottleThreshold
	cmpA	TPS_Voltage
	bls	@isWOT
	cmpA	TPS_VoltgePrevious
	bls	@isWOT
	bclr	Flag15, #TPS_WideOpen

@isWOT
	ldaA	TPS_LearnedClosedThrottle
	brset	Flag15, #TPS_Closed, @checkStillClosed
	addA	ClosedThrottleThreshold
	cmpA	TPS_Voltage
	bcs	@notClosed
	cmpA	TPS_VoltgePrevious
	bcs	@notClosed
	bset	Flag15, #TPS_Closed
@notClosed
	jr	@skip
;
@checkStillClosed
	addA	NotClosedThrottleThreshold
	cmpA	TPS_Voltage
	bcc	@skip
	bclr	Flag15, #TPS_Closed
@skip	ret	
;
;-----------------------------------------------------------------------
LA110:	brclr	Flag13, #%01000000, LA11F
	brset	Flag15, #MotorRunning1, LA11B
	jmp	LA1FB_exit
;
LA11B	ldaA	#%10000000
	staA	Flag13
LA11F	brset	Flag13, #%00010000, LA14A
	brclr	Flag15, #TPS_Closed, LA164
	brclr	Flag13, #%10000000, LA164
	ldaA	Revs_c
	cmpA	#$FF
	beq	LA164
	ldaB	WaterTemp_Value2
	addB	LF65E
	bcs	LA13D
	cBA	
	bcc	LA164
LA13D	ldaA	#%00010000	; Enable RPM filter
	staA	Flag13
	ldD	>CurrentRevs
	stD	FilteredRevs
	jmp	LA1FB_exit
;
LA14A	brclr	Flag15, #TPS_Closed, LA160
	ldaA	Revs_c
	cmpA	#$FF
	beq	LA160
	ldaB	WaterTemp_Value2
	addB	LF65F
	bcs	LA164
	cBA	
	bcs	LA164
LA160	ldaA	#$80
	staA	Flag13
LA164	brclr	Flag13, #%00000100, LA174
	brset	Flag15, #TPS_Closed, LA174
	ldaA	#$80
	staA	Flag13
	ldaA	#$80
	staA	Flag16
LA174	ldaA	Revs_c
	cmpA	LF64E
	bhi	LA1B2
	brclr	Flag13, #%00010001, LA182
	jr	LA1B2
;
LA182	ldaA	TPS_Voltage
	subA	Filtered_TPS_Voltage2
	bcs	LA19C
	cmpA	TPS_Value_02or03
	bcs	LA19C
	ldaA	TPS_VoltgePrevious
	subA	Filtered_TPS_Voltage2a
	bcs	LA19C
	cmpA	TPS_Value_02or03
	bcc	LA1A2
LA19C	brclr	Flag13, #%10000000, LA1FB_exit
	jr	LA1B2
;
LA1A2	ldaA	#$01
	staA	Flag13
	ldaA	LF645
	staA	>L00FB
	ldaA	#$80
	staA	Flag16
	jr	LA1FB_exit
;
LA1B2	ldaA	Revs_c
	cmpA	#$FF
	beq	LA1C4
	ldaB	WaterTemp_Value2
	addB	LF659
	bcs	LA1FB_exit
	cBA	
	bcs	LA1FB_exit
LA1C4	ldX	StartEnrichmentCounter
	bne	LA1FB_exit
	brclr	Flag13, #%10000001, LA1FB_exit
	ldaA	Filtered_TPS_Voltage3
	subA	TPS_Voltage
	bcs	LA1FB_exit
	cmpA	TPS_ValueAlways_02
	bcs	LA1FB_exit
	ldaA	Filtered_TPS_Voltage3a
	subA	TPS_VoltgePrevious
	bcs	LA1FB_exit
	cmpA	TPS_ValueAlways_02
	bcs	LA1FB_exit
	ldaA	#$08
	staA	Flag13
	ldaA	#$80
	staA	Flag16
	ldD	>CurrentRevs
	stD	FilteredRevs
	ldaA	LF65A
	staA	L01DD
LA1FB_exit
	ret	
;
;-----------------------------------------------------------------------
LA1FC:	brclr	Flag13, #%00000001, LA224
	brset	Flag15, #TPS_Closed, LA21C
	ldaA	>L00FB
	beq	LA20F
	decA	
	staA	>L00FB
	jr	LA224
;
LA20F	brset	Flag20, #%00000001, LA21C
	ldD	FuelAdjValue
	cmpD	LF64F
	bhi	LA224
LA21C	ldaA	#$80
	staA	Flag13
	ldaA	#$80
	staA	Flag16
LA224	brclr	Flag13, #%00001000, LA256
	ldaA	L01DD
	beq	LA233
	decA	
	staA	L01DD
	jr	LA240
;
LA233	brclr	Flag20, #%00000001, LA252
	ldD	FuelAdjValue
	cmpD	LF65B
	bls	LA252
LA240	ldaA	Revs_c
	cmpA	#$FF
	beq	LA256
	ldaB	WaterTemp_Value2
	addB	LF65D
	bcs	LA252
	cBA	
	bcc	LA256
LA252	ldaA	#$80
	staA	Flag13
LA256	brclr	Flag13, #%00000100, LA297
	ldaA	WaterTemp_Value2
	addA	LF685
	bcc	LA264
	ldaA	#$FF
LA264	cmpA	Revs_c
	bls	LA27D
	ldaA	#$20
	staA	Flag13
	bset	Flag20, #%00010000
	ldaA	LF684
	staA	L01E3
	ldaA	#$80
	staA	Flag16
LA27A	jmp	LA346
;
LA27D	ldD	L01DE
	beq	LA27A
	subD	#$0001
	stD	L01DE
	bhi	LA27A
	ldaA	#$80
	staA	Flag13
	ldaA	#$80
	staA	Flag16
	ldaA	#$FF
	staA	L01E0
LA297	brclr	Flag15, #TPS_Closed, LA2A8
	ldD	L01E1
	beq	LA2B9
	subD	#$0001
	stD	L01E1
	jr	LA2B9
;
LA2A8	ldD	RPM_SparkMapNdxFrac
	ldY	#RPM_Table2
	call	InterpolateValue
	tAB	
	clrA	
	lslD	
	lslD	
	stD	L01E1
LA2B9	brset	InjectorFlags, #%00100000, LA2EE
	ldaA	Revs_c
	cmpA	#$FF
	beq	LA2CF
	ldaB	WaterTemp_Value2
	addB	LF673
	bcs	LA2EE
	cBA	
	bls	LA2EE
LA2CF	ldaA	L01E0
	beq	LA2EB
	brclr	Flag15, #TPS_Closed, LA2EB
	cmpA	#$80
	beq	LA2EE
	ldaA	WaterTemp_Value2
	addA	LF685
	bcc	LA2E6
	ldaA	#$FF
LA2E6	cmpA	Revs_c
	bcs	LA2EE
LA2EB	bset	InjectorFlags, #%00100000
LA2EE	brclr	Flag13, #%10001000, LA33A
	ldD	LF670
	beq	LA338
	brclr	InjectorFlags, #%00100000, LA338
	ldaA	CurrentWaterTemp
	cmpA	WaterTemp_Value1
	bcs	LA338
	ldaA	Revs_c
	cmpA	#$FF
	beq	LA315
	ldaB	WaterTemp_Value2
	addB	LF672
	bcs	LA338
	cBA	
	bls	LA338
LA315	brclr	Flag15, #TPS_Closed, LA338
	bset	Flag10, #%00100000
	ldD	L01E1
	bne	LA338
	ldaA	#$04
	staA	Flag13
	ldaA	#$08
	staA	Flag16
	ldD	#$0000
	staA	L01E0
	bclr	InjectorFlags, #%00100000
	ldD	LF670
	stD	L01DE
LA338	jr	LA346
;
LA33A	brclr	Flag13, #%00100000, LA346
	brset	Flag20, #%00010000, LA346
	ldaA	#$80
	staA	Flag13
LA346	ret	
;
;-----------------------------------------------------------------------
; The PulseAccumulatorOverflow_isr is the main interrupt for the engine
; position sensor.
;
; The PACNT (Pulse Accumulator Count Register) is loaded with FF so that each new
; input pulse will trigger an interrupt.
;
; The timing of the pulses appears to be measured using the TIC3
; (Timer Capture 3 Reg) - I am not sure yet of the hardware relationship between
; Pulse accumulator input and the Timer capture 3 input.
;
;
PulseAccumulatorOverflow_isr:
	ldD	>InputCapture3Time
	stD	PreviousInputCapture3Time
	ldD	TIC3_TimerCaptureReg
	stD	>InputCapture3Time
	bmi	LA365			; jump if 8000 to ffff
	brclr	TFLG2register, #%10000000, LA365	; if there was an overflow, has been
	brset	Flag08, #TimerOverflowCaught, LA365	; delt with by timer overflow isr
	bset	Flag08, #TimerOverflowCaught
	inc	>TimerOverflowCount1			; else happen at same as impulse
	inc	TimerOverflowCount2			; so handle here

LA365	ldaA	#%00100000		; clear interrupt
	staA	TFLG2register
	ldaA	#$FF			; next edge triggers
	staA	PACNT_PulseAccumulatorCountReg
	ldD	>InputCapture3Time
	subD	PreviousInputCapture3Time
	stD	InputCapture3Difference
	ldaA	TimerOverflowCount2
	sbcA	#$00
	staA	InputCapture3DifferenceOverflow	; effectivly 3rd byte (most significant) of InputCapture3Difference
	ldaA	>L00E6
	staA	>L00E5
	bne	LA389
	jmp	LA465
;
LA389	cmpA	#$01
	bne	LA3D4
	ldD	>CurrentRevs
	brclr	Flag18, #%00000001, LA39F
	cmpD	LF694
	bhi	LA3A8
	bclr	Flag18, #%00000001
	jr	LA3A8
;
LA39F	cmpD	LF696
	bls	LA3A8
	bset	Flag18, #%00000001
LA3A8	ldX	L016D
	ldY	#L019B
	ldaB	#$08
	call	MemCopy_XtoY_1
	ldD	L016B
	subD	InputCapture3Difference
	ldaA	L016A
	sbcA	InputCapture3DifferenceOverflow
	bcc	LA3C5
	jmp	LA465
;
LA3C5	bclr	Flag17, #%00010000
	bclr	Flag06, #%00010000
	bset	Flag18, #%00000001
	inc	PickupFaultCount
	jmp	LA465
;
LA3D4	cmpA	L0136
	bne	LA3E5
	ldD	>InputCapture3Time
	stD	L0123
	clr	>TimerOverflowCount1
	jmp	LA465
;
LA3E5	cmpA	L0137
	bne	LA3F5
	ldD	>InputCapture3Time
	stD	L0125
	clr	>TimerOverflowCount1
	jr	LA465
;
LA3F5	cmpA	#$2E
	bne	LA41D
	ldD	InputCapture3DifferenceOverflow
	lsrD	
	stD	L01BF
	ldaA	L0169
	rorA	
	staA	L01C1
	ldD	L016B
	subD	L01C0
	ldaA	L016A
	sbcA	L01BF
	bcc	LA41D
	inc	L015B
	ldaA	#$01
	staA	>L00E5
LA41D	cmpA	#$02
	bcs	LA465
	beq	LA45B
	cmpA	#$08
	bcs	LA465
	beq	LA44F
	cmpA	#$0E
	bcs	LA465
	beq	LA45B
	cmpA	#$14
	bcs	LA465
	beq	LA44F
	cmpA	#$1A
	bcs	LA465
	beq	LA45B
	cmpA	#$20
	bcs	LA465
	beq	LA44F
	cmpA	#$26
	bcs	LA465
	beq	LA45B
	cmpA	#$2C
	bcs	LA465
	beq	LA44F
	jr	LA465
;
LA44F	SetExtraPortBit RevCounterBit
	jr	LA465
;
LA45B	ClearExtraPortBit RevCounterBit

LA465	ldaA	>L00E5
	cmpA	#$12
	bne	LA478
	ldX	L0184
	ldY	#$01A5
	ldaB	#$08
	call	MemCopy_XtoY_1
LA478	brclr	Flag18, #%00000001, LA47F
	jmp	LA514
;
LA47F	ldaA	>L00E5
	addA	#$01
	cmpA	#$2F
	bne	LA48A
	ldaA	#$01
LA48A	staA	>L00E6
	ldaA	>L00E5
	cmpA	L01A2
	bne	LA4AC
	ldaA	#(TFLG1_OC2 | TFLG1_IC2)
	staA	TFLG1_TimerInterruptFlag1Reg
	bset	TCTL1_TimerControlReg, #(TCTL1_OM2 | TCTL1_OL2)		; coil 1
	bset	TMSK1_TimerInterruptMask1Reg, #(TMSK1_OC2 | TMSK1_IC2)
	ldD	>InputCapture3Time
	addD	L019E
	stD	TOC2_TimerCompareReg
	stD	>InputCapture2_SubValue
	jr	LA4CD
;
LA4AC	cmpA	L019B
	bne	LA4CD
	brclr	TCTL1_TimerControlReg, #TCTL1_OL2, LA4BE
	ldaA	#$40
	staA	CFORC_ForceOutputCompareReg
	ldD	TCNT_TimerCountReg
	stD	>InputCapture2_SubValue
LA4BE	bclr	TCTL1_TimerControlReg, #TCTL1_OL2	; clear OC2 pin on compare
	ldaA	#TFLG1_OC2
	staA	TFLG1_TimerInterruptFlag1Reg
	ldD	>InputCapture3Time
	addD	V019C
	stD	TOC2_TimerCompareReg
LA4CD	ldaA	>L00E5
	ldaB	L01AC
	staB	L01AC
	cBA	
	bne	LA4F0
	ldaA	#(TFLG1_OC4 | TFLG1_IC2)
	staA	TFLG1_TimerInterruptFlag1Reg
	bset	TCTL1_TimerControlReg, #(TCTL1_OM4 | TCTL1_OL4) 	; coil 2
	bset	TMSK1_TimerInterruptMask1Reg, #(TMSK1_OC4 | TMSK1_IC2)
	ldD	>InputCapture3Time
	addD	L01A8
	stD	TOC4_TimerCompareReg
	stD	>L00DD
	jr	LA511
;
LA4F0	cmpA	L01A5
	bne	LA511
	brclr	TCTL1_TimerControlReg, #TCTL1_OL4, LA502
	ldaA	#$10
	staA	CFORC_ForceOutputCompareReg
	ldD	TCNT_TimerCountReg
	stD	>L00DD
LA502	bclr	TCTL1_TimerControlReg, #TCTL1_OL4
	ldaA	#TFLG1_OC4
	staA	TFLG1_TimerInterruptFlag1Reg
	ldD	>InputCapture3Time
	addD	L01A6
	stD	TOC4_TimerCompareReg
LA511	jmp	LA7D7
;
LA514	bclr	Flag05, #%00001000
	brclr	Flag17, #%00010000, LA51E
	jmp	LA5DD
;
LA51E	brset	Flag15, #MotorRunning1, LA544
	ldaA	StartingPulseCountdown
	bne	LA53A
	ldaA	InputCapture3DifferenceOverflow
	bne	LA53E
	ldD	InputCapture3Difference
	cmpD	CrankingThreshold1
	bhi	LA53E
	bset	Flag15, #MotorRunning1	; turning at > 200 RPM
	jr	LA53E
;
LA53A	decA	
	staA	StartingPulseCountdown
LA53E	clr	>TimerOverflowCount1
	jmp	LA5D7
;
LA544	brset	Flag06, #%00010000, LA589
	ldD	InputCapture3DifferenceOverflow
	lsrD	
	stD	L01BF
	ldaA	L0169
	rorA	
	staA	L01C1
	ldD	L016B
	subD	L01C0
	ldaA	L016A
	sbcA	L01BF
	bcc	LA583
	ldD	L01BF
	lsrD	
	stD	L01BF
	ldaA	L01C1
	rorA	
	staA	L01C1
	ldD	L016B
	subD	L01C0
	ldaA	L016A
	sbcA	L01BF
	bcs	LA583
	bset	Flag06, #%00010000
LA583	bset	Flag17, #NewRev
	jmp	LA5D7
;
LA589	ldD	L016A
	lsrD	
	stD	L01BF
	ldaA	L016C
	rorA	
	staA	L01C1
	ldD	InputCapture3Difference
	subD	L01C0
	ldaA	InputCapture3DifferenceOverflow
	sbcA	L01BF
	bcc	LA5D4
	ldD	L01BF
	lsrD	
	stD	L01BF
	ldaA	L01C1
	rorA	
	staA	L01C1
	ldD	InputCapture3Difference
	subD	L01C0
	ldaA	InputCapture3DifferenceOverflow
	sbcA	L01BF
	bcs	LA5D4
	bset	Flag17, #%00010000
	bset	Flag08, #%00000011
	bset	InjectorFlags, #%00001010
	call	TurnOnHorizInjectorIn20uS
	ldaA	#$02
	staA	>L00E5
	jr	LA5DD
;
LA5D4	bclr	Flag06, #%00010000
LA5D7	clr	>L00E6
	jmp	LA7D7
;
LA5DD	ldaA	>L00E5
	incA	
	cmpA	#$2F
	bne	LA5E7
	ldaA	#$01
LA5E7	staA	>L00E6
	ldaA	>L00E5
	cmpA	L0136
	beq	LA60F
	bcs	LA636
	cmpA	LF698
	bcs	LA639
	cmpA	L0137
	beq	LA607
	bcs	LA636
	cmpA	LF699
	bcs	LA639
	jr	LA636
;
LA607	bclr	Flag10, #%10000000
	ldaA	LF699
	jr	LA615
;
LA60F	bset	Flag10, #%10000000
	ldaA	LF698
LA615	clrB	
	pushA	
	ldX	#$001E
	ldaA	>SparkAdvance
	idiv	
	xgDX	
	addD	L020B
	stD	L01BB
	clrB	
	popA	
	subD	L01BB
	staB	L01B8
	staA	L01B7
	bclr	Flag22, #%10000000
	bclr	Flag19, #%00001000
LA636	jmp	LA7D7
;
LA639	brclr	Flag19, #%00001000, LA640
	jmp	LA736
;
LA640	ldD	InputCapture3Difference
	cmpD	LF692
	bcc	LA657
	brclr	Flag10, #%10000000, LA652
	ldD	>L00EB
	jr	LA65A
;
LA652	ldD	>L00ED
	jr	LA65A
;
LA657	ldD	L01CB
LA65A	stD	L01B9
	ldX	InputCapture3Difference
	idiv	
	xgDX	
	staB	L01BD
	xgDX	
	ldX	InputCapture3Difference
	fdiv	
	xgDX	
	staA	L01BE
	ldD	L01BD
	stD	L01BD
	addD	L01BB
	stD	L01BD
	brclr	Flag10, #%10000000, LA683
	ldaA	LF698
	jr	LA686
;
LA683	ldaA	LF699
LA686	subA	>L00E5
	ldaB	#$00
	subD	L01BD
	bcc	LA693
	ldD	#$0000
LA693	tstA	
	beq	LA699
	jmp	LA7D7
;
LA699	bset	Flag19, #%00001000
	pushB	
	ldaA	L0169
	mul	
	tAB	
	clrA	
	stD	L01BD
	popB	
	ldaA	InputCapture3Difference
	mul	
	addD	L01BD
	stD	L01BD
	ldD	L01B9
	cmpD	InputCapture3Difference
	bhi	LA6BF
	bset	Flag22, #%10000000
	jr	LA6C8
;
LA6BF	bclr	Flag22, #%10000000
	lslD	
	bcc	LA6C8
	ldD	#$FFFF
LA6C8	stD	OutputCompare2Interval
	stD	OutputCompare4Interval
	brclr	Flag10, #%10000000, LA705
	ldD	L01BD
	addD	>InputCapture3Time
	stD	>InputCapture2_SubValue
	stD	TOC2_TimerCompareReg
	ldaA	#(TFLG1_OC2 | TFLG1_IC2)
	staA	TFLG1_TimerInterruptFlag1Reg
	bset	TCTL1_TimerControlReg, #(TCTL1_OM2 | TCTL1_OL2)		; coil 1
	bset	TMSK1_TimerInterruptMask1Reg, #(TMSK1_OC2 | TMSK1_IC2)
	ldD	TCNT_TimerCountReg
	subD	>InputCapture3Time
	cmpD	L01BD
	bcs	LA736
	bset	CFORC_ForceOutputCompareReg, #FORCE_OC2
	ldD	TCNT_TimerCountReg
	stD	>InputCapture2_SubValue
	addD	#$000A
	stD	TOC2_TimerCompareReg
	ldaA	#TFLG1_OC2
	staA	TFLG1_TimerInterruptFlag1Reg
	jr	LA736
;
LA705	ldD	L01BD
	addD	>InputCapture3Time
	stD	>L00DD
	stD	TOC4_TimerCompareReg
	ldaA	#(TFLG1_OC4 | TFLG1_IC2)
	staA	TFLG1_TimerInterruptFlag1Reg
	bset	TCTL1_TimerControlReg, #(TCTL1_OM4 | TCTL1_OL4)		; coil 2
	bset	TMSK1_TimerInterruptMask1Reg, #(TMSK1_OC4 | TMSK1_IC2)
	ldD	TCNT_TimerCountReg
	subD	>InputCapture3Time
	cmpD	L01BD
	bcs	LA736
	bset	CFORC_ForceOutputCompareReg, #FORCE_OC4
	ldD	TCNT_TimerCountReg
	stD	>L00DD
	addD	#$000A
	stD	TOC4_TimerCompareReg
	ldaA	#TFLG1_OC4
	staA	TFLG1_TimerInterruptFlag1Reg
LA736	brset	Flag22, #%10000000, LA742
	ldaA	>L00E5
	cmpA	L01B7
	beq	LA745
LA742	jmp	LA7D7
;
LA745	brclr	Flag10, #%10000000, LA791
	bclr	TMSK1_TimerInterruptMask1Reg, #TMSK1_OC2
	brclr	TCTL1_TimerControlReg, #TCTL1_OL2, LA765		; coil 1
	bset	TCTL1_TimerControlReg, #(TCTL1_OM2 | TCTL1_OL2)
	bset	CFORC_ForceOutputCompareReg, #FORCE_OC2
	ldD	TCNT_TimerCountReg
	stD	>InputCapture2_SubValue
	addD	OutputCompare2Interval
	stD	TOC2_TimerCompareReg
	bclr	TCTL1_TimerControlReg, #%01000000
	jr	LA7D7
;
LA765	ldaA	InputCapture3Difference
	ldaB	L01B8
	mul	
	xgDX	
	ldaA	L0169
	ldaB	L01B8
	mul	
	adcA	#$00
	tAB	
	aBX	
	xgDX	
	stD	V019C
	addD	>InputCapture3Time
	stD	TOC2_TimerCompareReg
	ldD	TCNT_TimerCountReg
	subD	>InputCapture3Time
	cmpD	V019C
	bcs	LA7D7
	bset	CFORC_ForceOutputCompareReg, #FORCE_OC2
	jr	LA7D7
;
LA791	bclr	TMSK1_TimerInterruptMask1Reg, #TMSK1_OC4	; coil 2
	brclr	TCTL1_TimerControlReg, #TCTL1_OL4, LA7AD
	bset	TCTL1_TimerControlReg, #(TCTL1_OM4 | TCTL1_OL4)
	bset	CFORC_ForceOutputCompareReg, #FORCE_OC4
	ldD	TCNT_TimerCountReg
	stD	>L00DD
	addD	OutputCompare4Interval
	stD	TOC4_TimerCompareReg
	bclr	TCTL1_TimerControlReg, #TCTL1_OL4
	jr	LA7D7
;
LA7AD	ldaA	InputCapture3Difference
	ldaB	L01B8
	mul	
	xgDX	
	ldaA	L0169
	ldaB	L01B8
	mul	
	adcA	#$00
	tAB	
	aBX	
	xgDX	
	stD	V019C
	addD	>InputCapture3Time
	stD	TOC4_TimerCompareReg
	ldD	TCNT_TimerCountReg
	subD	>InputCapture3Time
	cmpD	V019C
	bcs	LA7D7
	bset	CFORC_ForceOutputCompareReg, #FORCE_OC4
LA7D7	clr	TimerOverflowCount2
	ldD	InputCapture3Difference
	stD	L016B
	ldaA	InputCapture3DifferenceOverflow
	staA	L016A
	ldaA	>L00E5
	cmpA	L0137
	bne	LA806
	bset	InjectorFlags, #%00001000
	brclr	PORTA_DataReg, #VertInjectorBit, LA7FB
	bclr	TCTL1_TimerControlReg, #TCTL1_OL3
	bset	CFORC_ForceOutputCompareReg, #FORCE_OC3		; Set vert injector low
LA7FB	bclr	Flag11, #%01000000
	bclr	Flag05, #%00010000
	call	LB31E
	jr	LA821
;
LA806	cmpA	L0136
	bne	LA82B
	bset	InjectorFlags, HorizInjectorOffTimePending
	brclr	PORTA_DataReg, #HorizInjectorBit, LA818
	bclr	TCTL1_TimerControlReg, #TCTL1_OL5
	bset	CFORC_ForceOutputCompareReg, #FORCE_OC5		; set horiz injector low
LA818	bclr	Flag11, #%00010000
	bset	Flag05, #%00010000
	call	LB2AC
LA821	bset	InjectorFlags, #%10000000
	brclr	Flag16, #%10000000, LA82B
	call	L916C
LA82B	brclr	Flag06, #%00000010, LA84D
	brclr	InjectorFlags, HorizInjectorOffTimePending, LA83E
	ldaA	>L00E5
	cmpA	L0138
	bne	LA83E
	call	TurnOnHorizInjectorIn20uS
LA83E	brclr	InjectorFlags, #%00001000, LA84D
	ldaA	>L00E5
	cmpA	L0139
	bne	LA84D
	call	TurnOnVertInjectorIn20uS
LA84D	ldaA	>L00E5
	cmpA	LF699
	beq	LA85B
	cmpA	LF698
	beq	LA85B
	reti	
;
LA85B	ldaA	>L00E5
	cmpA	LF699
	beq	LA87E
	bset	Flag08, #CheckCoil1Flag
	ldD	>InputCapture3Time
	subD	L0123
	stD	>CurrentRevs
	ldaA	>TimerOverflowCount1
	sbcA	#$00
	beq	LA897
	ldD	#$FFFF
	stD	>CurrentRevs
	jr	LA897
;
LA87E	bset	Flag08, #CheckCoil2Flag
	ldD	>InputCapture3Time
	subD	L0125
	stD	>CurrentRevs
	ldaA	>TimerOverflowCount1
	sbcA	#$00
	beq	LA897
	ldD	#$FFFF
	stD	>CurrentRevs
LA897	brset	Flag15, #MotorRunning2, @alreadySet
	ldD	>CurrentRevs
	cmpD	CrankingThreshold2	; equiv to 200 RPM
	bhi	@slower			; slower
	bset	Flag15, #MotorRunning2

@alreadySet	
@slower
	ldX	#180
	ldD	>CurrentRevs
	idiv	
	stX	RevsDiv180
	bset	Flag17, #NewRev
	reti	
;
;-----------------------------------------------------------------------
LA8B5:	ldY	#L0170
	ldaB	L016F
	xorB	#%00001010
	staB	L016F
	aBY	
	ldaA	LF698
	clrB	
	subD	L01AF
	stD	L01C4
	ldaA	L01C6
	mul	
	xgDX	
	ldaB	L01C5
	ldaA	L01C7
	mul	
	tAB	
	aBX	
	xgDX	
	cmpD	#$0096
	bcc	LA8F2
	addD	L01C6
	stD	1, Y
	ldaA	L01C4
	subA	#$01
	staA	0, Y
	jr	LA8FB
;
LA8F2	stD	1, Y
	ldaA	L01C4
	staA	0, Y
LA8FB	ldX	L01C6
	ldD	>L00EB
	stD	L01B3
	stD	8, Y
	idiv	
	xgDX	
	staB	L01B1
	xgDX	
	ldX	L01C6
	fdiv	
	xgDX	
	staA	L01B2
	ldD	L01B1
	cmpD	#$0300
	bhi	LA92B
	ldD	L01B3
	stD	5, Y
	ldaA	#$FF
	staA	0, Y
	jr	LA935
;
LA92B	ldD	L01B3
	lsrD	
	addD	L01B3
	stD	5, Y
LA935	ldD	L01C4
	subD	L01B1
	bcs	LA943
	cmpD	#$0200
	bhi	LA946
LA943	ldD	#$0200
LA946	stD	L01B1
	ldaA	L01C6
	mul	
	xgDX	
	ldaB	L01B2
	ldaA	L01C7
	mul	
	tAB	
	aBX	
	xgDX	
	cmpD	#$0096
	bcc	LA964
	addD	L01C6
	dec	L01B1
LA964	stD	3, Y
	ldaA	L01B1
	staA	7, Y
	stY	L016D
	ret	
;
;-----------------------------------------------------------------------
LA972:	ldY	#$0187
	ldaB	L0186
	xorB	#%00001010
	staB	L0186
	aBY	
	ldaA	LF699
	clrB	
	subD	L01AF
	stD	L01C4
	ldaA	L01C6
	mul	
	xgDX	
	ldaB	L01C5
	ldaA	L01C7
	mul	
	tAB	
	aBX	
	xgDX	
	cmpD	#$0096
	bcc	LA9AF
	addD	L01C6
	stD	1, Y
	ldaA	L01C4
	subA	#$01
	staA	0, Y
	jr	LA9B8
;
LA9AF	stD	1, Y
	ldaA	L01C4
	staA	0, Y
LA9B8	ldX	L01C6
	ldD	>L00ED
	stD	L01B3
	stD	8, Y
	idiv	
	xgDX	
	staB	L01B1
	xgDX	
	ldX	L01C6
	fdiv	
	xgDX	
	staA	L01B2
	ldD	L01B1
	cmpD	#$0300
	bhi	LA9E8
	ldD	L01B3
	stD	5, Y
	ldaA	#$FF
	staA	0, Y
	jr	LA9F2
;
LA9E8	ldD	L01B3
	lsrD	
	addD	L01B3
	stD	5, Y
LA9F2	ldD	L01C4
	subD	L01B1
	bcs	LAA00
	cmpD	#$1400
	bhi	LAA03
LAA00	ldD	#$1400
LAA03	stD	L01B1
	ldaA	L01C6
	mul	
	xgDX	
	ldaB	L01B2
	ldaA	L01C7
	mul	
	tAB	
	aBX	
	xgDX	
	cmpD	#$0096
	bcc	LAA21
	addD	L01C6
	dec	L01B1
LAA21	stD	3, Y
	ldaA	L01B1
	staA	7, Y
	stY	L0184
	ret	
;
;-----------------------------------------------------------------------
; Coil 1 output control interrupt
;
OutputCompare2_isr:
	ldaA	#TFLG1_OC2
	staA	TFLG1_TimerInterruptFlag1Reg
	bclr	TMSK1_TimerInterruptMask1Reg, #TMSK1_OC2	; disable this interrupt
	bclr	TCTL1_TimerControlReg, #TCTL1_OL2		; Next match will set OC2 pin low
	ldD	TOC2_TimerCompareReg
	addD	OutputCompare2Interval
	stD	TOC2_TimerCompareReg
	reti	
;
;-----------------------------------------------------------------------
; Coil 2 output control interrupt
;
OutputCompare4_isr:
	ldaA	#TFLG1_OC4
	staA	TFLG1_TimerInterruptFlag1Reg
	bclr	TMSK1_TimerInterruptMask1Reg, #TMSK1_OC4	; disable this interrupt
	bclr	TCTL1_TimerControlReg, #TCTL1_OL4		; Next match will set OC4 pin low
	ldD	TOC4_TimerCompareReg
	addD	OutputCompare4Interval
	stD	TOC4_TimerCompareReg
	reti	
;
;-----------------------------------------------------------------------
; Check coil operation
; assume based on time constant to charge coil??
;
InputCapture2_isr:
	ldaA	>L00E5
	cmpA	LF698
	bhi	LAA8B
	bclr	TMSK1_TimerInterruptMask1Reg, #TMSK1_IC2
	ldD	TIC2_TimerCaptureReg
	subD	>InputCapture2_SubValue
	bset	Flag17, #NewInputCapture2
	stD	>InputCapture2_StoredValue
	tst	InputCapture2CheckEnabled
	beq	LAA7C
	cmpD	InputCapture2_Min
	bcc	LAA7C
	ldaA	FilteredBatteryVoltage
	cmpA	MaxBatteryForCoilCheck
	bcs	LAA81
LAA7C	bclr	Flag04, #Coil1_Error
	jr	LAA8A
;
LAA81	bset	Flag04, #Coil1_Error
	bclr	TCTL1_TimerControlReg, #TCTL1_OL2
	bset	CFORC_ForceOutputCompareReg, #FORCE_OC2
LAA8A	reti	
;
LAA8B	bclr	TMSK1_TimerInterruptMask1Reg, #TMSK1_IC2
	ldD	TIC2_TimerCaptureReg
	subD	>L00DD
	bset	Flag17, #%01000000
	stD	>L00F1
	tst	LF706
	beq	LAAAC
	cmpD	InputCapture2_Min
	bcc	LAAAC
	ldaA	FilteredBatteryVoltage
	cmpA	MaxBatteryForCoilCheck
	bcs	LAAB1
LAAAC	bclr	Flag04, #Coil2_Error
	jr	LAABA
;
LAAB1	bset	Flag04, #Coil2_Error
	bclr	TCTL1_TimerControlReg, #TCTL1_OL4
	bset	CFORC_ForceOutputCompareReg, #FORCE_OC4
LAABA	reti	
;
;-----------------------------------------------------------------------
UpdateEEPROM:
	tst	EEPROM_Status2		; already busy?
	bne	@exit2
	brclr	Flag27, #RequestClearDiagErrors, @NotClearDiag
	di	
	tst	EEPROM_Status2
	bne	@exit
	bclr	Flag27, #RequestClearDiagErrors
	call	ClearSavedDiagError
@exit	jr	@exit2
;
@NotClearDiag
	ldaA	EEPROM_Inited
	cmpA	#$AA
	beq	@inited			; yes
	ldX	#EEPROM_InitialValues
	ldY	#L0F80
	call	QueueWriteToEEPROM
	ldaA	TPS_TrimDefault
	staA	TPS_Trim
	ldaA	StepperProportionalDefault
	staA	StepperProportional
	ldaA	LF029
	staA	L0288
@exit2	jr	LAB67_exit
;
@inited	ldaA	L0254
	bitA	#%00010000
	bne	LAB67_exit
	di	
	tst	EEPROM_Status2
	bne	LAB67_exit
	bitA	#%00001000
	beq	LAB0F
	andA	#%11110111
	staA	L0254
	jr	LAB25
;
LAB0F	ldY	#InitVarCopyDest
	call	LAC38
	ldaA	L0254
	bitA	L0255
	bne	LAB49
	ldD	14, Y
	subD	14, X
	bne	LAB49
LAB25	lsl	L0255
	ldaA	L0255
	cmpA	#$08
	bne	LAB67_exit
	ldD	#StartEEPROM
	stD	EEPROM_DestAddr
	ldaA	#$01
	staA	L0255
	ldaA	#$10
	staA	CopyToEEPROM_Count
	ldaA	L0254
	oraA	#%00010000
	staA	L0254
	jr	LAB67_exit
;
LAB49	ldaA	L0254
	oraA	#%00001000
	staA	L0254
	stX	EEPROM_DestAddr
	ldD	#EEPROM_WriteBuffer
	xgDY	
	xgDX	
	ldaB	#$10
	staB	CopyToEEPROM_Count
	call	MemCopy_XtoY_1
	ldaA	#$1A
	staA	EEPROM_Status2
LAB67_exit	ei	
	ret	
;
;-----------------------------------------------------------------------
ProcessEEPROM_Update:
	ldaA	EEPROM_Status2
	beq	LABDD
	bset	Flag27, #%00000010
	ldaB	EEPROM_Status1
	bne	LAB87
	ldX	#EEPROM_WriteBuffer
	stX	CopyToEEPROM_SourceAddr
	cmpA	#$0C
	beq	LABDE
	cmpA	#$0E
	bne	LABF0
	jmp	LAC1B
;
LAB87	decB	
	staB	EEPROM_Status1
	bne	LABA2
	clr	>PPROG_EEPROM_ProgramReg
	ldX	EEPROM_DestAddr
	incX	
	stX	EEPROM_DestAddr
	dec	CopyToEEPROM_Count
	beq	LABAB
	cmpA	#$1A
	beq	LABF0
	jr	LAC1B
;
LABA2	cmpB	#$05
	bne	LABDD
	clr	>PPROG_EEPROM_ProgramReg
	jr	LAC1B
;
LABAB	ldaA	L0254
	bitA	#%00010000
	beq	LABC2
	ldD	#StartEEPROM
	stD	EEPROM_DestAddr
	ldaA	#$01
	staA	L0255
	ldaA	#$10
	staA	CopyToEEPROM_Count
LABC2	ldaA	#$10
	ldX	#EEPROM_WriteBuffer
LABC7	clr	0, X
	incX	
	decA	
	bne	LABC7
	brclr	InternalErrors, #RAM_Failure1, LABD7
	bclr	InternalErrors, #RAM_Failure1
	clr	ErrorBitIndex
LABD7	clr	EEPROM_Status2
	bclr	Flag27, #%00000010
LABDD	ret	
;
LABDE	ldaA	#$01
	staA	CopyToEEPROM_Count
	ldaA	#$05
	staA	EEPROM_Status1
	ldY	#StartEEPROM
	ldaB	#$06
	jr	LAC2F
;
LABF0	call	LAC47
	ldX	CopyToEEPROM_SourceAddr
	ldY	EEPROM_DestAddr
@loop	ldaA	0, X
	cmpA	0, Y
	bne	@erase
	incX	
	incY	
	stX	CopyToEEPROM_SourceAddr
	stY	EEPROM_DestAddr
	dec	CopyToEEPROM_Count
	beq	LABAB
	jr	@loop
;
@erase	ldaA	#$0A
	staA	EEPROM_Status1
	ldaB	#(PPROG_BYTE | PPROG_ERASE | PPROG_EELAT)
	jr	LAC2B
;
LAC1B	ldaA	#$05
	staA	EEPROM_Status1
	ldX	CopyToEEPROM_SourceAddr
	ldaA	0, X
	incX	
	stX	CopyToEEPROM_SourceAddr
	ldaB	#PPROG_EELAT
LAC2B	ldY	EEPROM_DestAddr
LAC2F	staB	PPROG_EEPROM_ProgramReg
	staA	0, Y
	bset	PPROG_EEPROM_ProgramReg, #PPROG_EEPGM
	ret	
;
;-----------------------------------------------------------------------
LAC38:	ldaA	L0255
	ldaB	#$80
	ldX	#StartEEPROM
	jr	LAC43
;
LAC42	aBX	
LAC43	lsrA	
	bcc	LAC42
	ret	
;
;-----------------------------------------------------------------------
LAC47:	ldX	#EEPROM_WriteBuffer
	ldaB	#$0E
	aBX	
	ldD	0, X
	bne	LAC67
	ldD	#$55AA
	ldY	#EEPROM_WriteBuffer
LAC58	subD	0, Y
	incY	
	incY	
	cmpY	#$0265
	bne	LAC58
	stD	0, X
LAC67	ret	
;
;-----------------------------------------------------------------------
QueueWriteToEEPROM:
	di	
	tst	EEPROM_Status2
	bne	@alreadyBusy
	stY	EEPROM_DestAddr
	ldaB	#$10
	staB	CopyToEEPROM_Count
	ldY	#EEPROM_WriteBuffer
	call	MemCopy_XtoY_1
	ldaA	#$1A
	staA	EEPROM_Status2
@alreadyBusy
	ei	
	ret	
;
;-----------------------------------------------------------------------
LAC85:	ldX	#L0F80
	ldY	#EEPROM_WriteBuffer
	ldaB	#$0E
	call	MemCopy_XtoY_1
	ldD	#$0000
	stD	0, Y
	ret	
;
;
Cmd1	db	$03, $34, $51, $88		; AC98
Cmd2	db	$02, $38, $3A			; AC9C
Cmd3	db	$04, $00, $06, $00, $0A		; AC9F
Cmd4	db	$04, $00, $09, $00, $0D		; ACA4
Cmd5	db	$05, $0D, $02, $06, $00, $1A	; ACA9
Cmd6	db	$05, $0D, $02, $09, $00, $1D	; ACAF
Cmd7	db	$03, $0A, $00, $0D		; ACB5
Cmd8	db	$03, $0B, $00, $0E		; ACB9

Vec4Table:
	dw	Vec4Entry_00
	dw	Vec4Entry_01
	dw	Vec4Entry_02
	dw	Vec4Entry_03
	dw	Vec4Entry_04
	dw	Vec4Entry_05
	dw	Vec4Entry_06
	dw	Vec4Entry_07
	dw	Vec4Entry_08
;
;-----------------------------------------------------------------------
ExecuteVec4Functions:
	ldaA	DiagMode
	cmpA	#DiagMode_NormalSendVar	; not if diag active
	beq	LACFC
	ldaA	Vec4Var_b
	cmpA	#$FF
	beq	LACDE
	inc	>Vec4Var_b
LACDE	ldaA	Vec4Var_c
	brclr	PORTD_DataReg, #RxBit, LACEB
	cmpA	#$FF
	beq	LACEB
	inc	>Vec4Var_c
LACEB	ldX	#Vec4Table
	ldaB	Vec4FunctionIdx
	cmpB	#$09
	bhi	LACFC
	lslB	
	aBX	
	ldX	0, X
	ldaB	Vec4Var_b
	call	0, X
LACFC	ret	
;
Vec4Entry_00:
	brset	PORTD_DataReg, #RxBit, @RxHigh
	cmpB	#$31
	bcs	LAD19
	cmpA	#$06
	bhi	LAD13
	clr	>Vec4Var_a
	ldaA	#$01
	staA	Vec4Var_d
	inc	>Vec4FunctionIdx
@RxHigh
LAD13	clr	>Vec4Var_b
	clr	>Vec4Var_c
LAD19	ret	
;
Vec4Entry_01:
	cmpB	#$31
	bcs	LAD3F
	cmpA	#$06
	bls	LAD31
	cmpA	#$2B
	bcc	LAD2B
	clr	>Vec4FunctionIdx
	jr	LAD39
;
LAD2B	ldaB	Vec4Var_a
	oraB	Vec4Var_d
	staB	Vec4Var_a
LAD31	lsl	>Vec4Var_d
	bcc	LAD39
	inc	>Vec4FunctionIdx
LAD39	clr	>Vec4Var_b
	clr	>Vec4Var_c
LAD3F	ret	


;;-----------------------------------------------------------------------
; Sets baud rate at E CLOCK / 13 / 16 / 16
;
; 4 MHz / 13 / 2 / 16 = 9615 baud
;
Vec4Entry_02:
	cmpB	#$31
	bcs	LAD6B
	cmpA	#$2B
	bcs	LAD62
	ldaA	Vec4Var_a
	cmpA	#$7A
	beq	LAD52
	cmpA	#$10
	bne	LAD62
LAD52	bclr	TxFlags, #TxFlags_NotConnected
	ldaA	#(SCCR2_TxEnable | SCCR2_RxEnable)
	staA	SCCR2_SerialControlReg
	ldaA	#$31
	staA	baud_Register
	inc	>Vec4FunctionIdx
	jr	LAD65
;
LAD62	clr	>Vec4FunctionIdx
LAD65	clr	>Vec4Var_b
	clr	>Vec4Var_c
LAD6B	ret	
;
Vec4Entry_03:
	cmpB	#$46
	bcs	LAD88
	clr	>DiagDataIdx
	bclr	TxFlags, #TxFlags_SentIDstring
	ldaA	#$03
	staA	DiagStateIdx
	ldD	SCSR_SerialStatusReg
	bset	SCCR2_SerialControlReg, #SCCR2_RxISR_Enable
	inc	>Vec4FunctionIdx
	clr	>Vec4Var_b
	clr	>Vec4Var_d
LAD88	ret	
;
Vec4Entry_04:
	brclr	TxFlags, #TxFlags_SentIDstring, LADD6
	cmpB	#$01
	bne	LAD9E
	ldaA	Vec4Var_d
	bne	LAD9E
	clr	>DiagDataIdx
	bclr	TxFlags, #TxFlags_RxOfCmdComplete
	inc	>DiagStateIdx
LAD9E	cmpB	#$0A
	bcs	LADD9
	ldaA	Vec4Var_d
	cmpA	#$78
	bhi	@invalid
	inc	>Vec4Var_d
	brclr	TxFlags, #TxFlags_RxOfCmdComplete, LADD6
	ldY	#Cmd1
	pushY	
	popX	
	call	CompareCommand
	beq	@LADBF
	ldY	#Cmd2
@LADBF	stY	L0072
	clr	>DiagDataIdx
	dec	>DiagStateIdx
	inc	>Vec4FunctionIdx
	jr	LADD6
;
@invalid
	call	InitComms
	clr	>Vec4FunctionIdx
	clr	>Vec4Var_c
LADD6	clr	>Vec4Var_b
LADD9	ret	
;
Vec4Entry_05:
	cmpB	#$05
	bcs	LADE9
	call	LAE8F
	bne	LADE9
	inc	>Vec4FunctionIdx
	clr	>Vec4Var_b
LADE9	ret	
;
Vec4Entry_06:
	cmpB	#$01
	bne	LADF7
	clr	>DiagDataIdx
	bclr	TxFlags, #TxFlags_RxOfCmdComplete
	inc	>DiagStateIdx
LADF7	cmpB	#$7D
	bhi	LAE25
	brclr	TxFlags, #TxFlags_RxOfCmdComplete, LAE3C
	brset	Flag15, #MotorRunning1, LAE1F
	ldaA	#$09
	ldY	#Cmd6
	ldX	#Cmd4
	call	CompareCommand
	beq	LAE2B
	ldaA	#$06
	ldY	#Cmd5
	ldX	#Cmd3
	call	CompareCommand
	beq	LAE2B
LAE1F	ldY	#Cmd8
	jr	LAE29
;
LAE25	ldY	#Cmd7
LAE29	ldaA	#$FF
LAE2B	stY	L0072
	staA	DiagMode
	clr	>DiagDataIdx
	dec	>DiagStateIdx
	inc	>Vec4FunctionIdx
	clr	>Vec4Var_b
LAE3C	ret	
;
Vec4Entry_07:
	cmpB	#$05
	bcs	LAE4C
	call	LAE8F
	bne	LAE4C
	inc	>Vec4FunctionIdx
	clr	>Vec4Var_b
LAE4C	ret	
;
Vec4Entry_08:
	cmpB	#$03
	bcs	LAE6D
	ldaA	DiagMode
	cmpA	#$06
	beq	@go
	cmpA	#$09
	bne	@Invalid
@go	ldS	#StackTop
	jmp	EnableSpecialDiagMode
;
@Invalid:
	call	InitComms
	clr	>Vec4FunctionIdx
	clr	>Vec4Var_c
	clr	>Vec4Var_b
LAE6D	ret	
;
;-----------------------------------------------------------------------
CompareCommand:
	pushY	
	pushA	
	pushB	
	ldY	#DiagCmdRxBuff
	ldaB	0, Y
	cmpB	0, X
	bne	@different
@next	incY	
	incX	
	ldaA	0, X
	cmpA	0, Y
	bne	@different
	decB	
	bne	@next
@different
	popB	
	popA	
	popY	
	ret	
;
;-----------------------------------------------------------------------
LAE8F:	ldX	L0072
	ldaB	DiagDataIdx
	bne	LAE9A
	ldaA	0, X
	incA	
	staA	DiagCmdRxCount
LAE9A	brclr	SCSR_SerialStatusReg, #SCSR_RxComplete, LAEA9
	aBX	
	ldaA	0, X
	staA	SCDR_SerialDataReg
	inc	>DiagDataIdx
	dec	>DiagCmdRxCount
LAEA9	ret	
;
;-----------------------------------------------------------------------
SendPowerOnID:
	brset	TxFlags, #TxFlags_SentIDstring, @done
	brclr	SCSR_SerialStatusReg, #SCSR_RxComplete, @done
	ldX	#DiagIDString
	ldaB	DiagDataIdx
	aBX	
	ldaA	0, X
	staA	SCDR_SerialDataReg
	cmpB	#$05
	bcc	@IDstringFinished
	inc	>DiagDataIdx
	jr	@done
;
@IDstringFinished
	clr	>DiagDataIdx
	bset	TxFlags, #TxFlags_SentIDstring
@done	ret	
;
;-----------------------------------------------------------------------
ProcessTPS:
	ldaA	TPS_raw
	tst	UseTPS_RawMinMax
	beq	@NoTest
	cmpA	TPS_raw_Min
	bcs	@TooLow
	cmpA	TPS_raw_Max
	bhi	@TooHigh
@NoTest	bclr	FirstTimeSensorErrors, #TPS_SensorError
	bclr	CurrentSensorErrors, #TPS_SensorError
	jr	LAF12
;
@TooLow	bset	SensorHiLowErrors, #TPS_SensorError
	jr	LAEEE
;
@TooHigh
	bclr	SensorHiLowErrors, #TPS_SensorError

LAEEE	brset	FirstTimeSensorErrors, #TPS_SensorError, LAEF7
	bset	FirstTimeSensorErrors, #TPS_SensorError
	jr	LAF15
;
LAEF7	bset	CurrentSensorErrors, #TPS_SensorError
	ldaA	#TPS_SensorError
	ldaB	#LogSensorErrorIdx
	xgDX	
	call	LogDiagError
	ldaA	TPS_CompareHigh
	staA	TPS_LearnedWideOpenThrottle
	ldaA	TPS_CompareLow
	staA	TPS_LearnedClosedThrottle	; Bugger if TPS is bad, but
	ldaA	RevsDerivedSubstituteTPS	; substitute guess for TPS to limp home
	staA	TPS_VoltgePrevious
LAF12	staA	TPS_Voltage
LAF15	ret	
;
CheckPressureSensor:
	ldaA	UseAtmPressureMinMax
	beq	LAF30
	ldaA	AtmPressure_raw
	brset	FirstTimeSensorErrors, #Pressure_SensorError, LAF37
	cmpA	AtmPressure_raw_Min
	bcs	LAF2C
	cmpA	AtmPressure_raw_Max
	bls	LAF30
LAF2C	bset	FirstTimeSensorErrors, #Pressure_SensorError
	ret	
;
LAF30	bclr	FirstTimeSensorErrors, #Pressure_SensorError
	bclr	CurrentSensorErrors, #Pressure_SensorError
	ret	
;
LAF37	cmpA	AtmPressure_raw_Min
	bcs	LAF43
	cmpA	AtmPressure_raw_Max
	bhi	LAF48
	jr	LAF30
;
LAF43	bclr	SensorHiLowErrors, #%00000010
	jr	LAF4B
;
LAF48	bset	SensorHiLowErrors, #Pressure_SensorError
LAF4B	bset	CurrentSensorErrors, #Pressure_SensorError
	ldaA	#Pressure_SensorError
	ldaB	#LogSensorErrorIdx
	xgDX	
	call	LogDiagError
	ldaA	DefaultAtmPressure
	staA	>CurrentAtmPressure
	ret	
;
;-----------------------------------------------------------------------
CheckO2Sensor:
	ldaA	UseO2Sensor	; constant is 0
	bne	LAF72
	bclr	FirstTimeSensorErrors, #O2_SensorError
	bclr	CurrentSensorErrors, #O2_SensorError
LAF68	ldX	#$FFFF
	stX	O2Var1
	stX	O2Var2
	ret	
;
LAF72	ldX	O2Var1
	beq	LAF90
	cmpX	#$FFFF
	beq	LAF82
	decX	
	stX	O2Var1
	jr	LAF90
;
LAF82	ldX	O2Var2
	beq	LAF90
	cmpX	#$FFFF
	beq	LAF90
	decX	
	stX	O2Var2
LAF90	brclr	Flag11, #%00100000, LAF68
	brset	Flag14, #%10000000, LAF68
	ldaA	>O2FuncIdx
	cmpA	#$02
	bcs	LAFA8
	cmpA	#$04
	bhi	LAFA8
	call	LAFE5
	jr	LAF68
;
LAFA8	ldX	#O2Var1
	ldaA	>O2FuelTrim
	bne	LAFB7
	ldD	#$FFFF
	stD	2, X
	jr	LAFC2
;
LAFB7	cmpA	#$FF
	bne	LAF68
	ldD	#$FFFF
	stD	0, X
	incX	
	incX	
LAFC2	ldY	0, X
	cmpY	#$FFFF
	bne	LAFD0
	ldD	O2SensorRelated
	jr	LAFE2
;
LAFD0	ldY	0, X
	bne	LAFE4
	call	LAFE5
	di	
	ldaA	#$02
	staA	>O2FuncIdx
	ei	
	ldD	#$FFFF
LAFE2	stD	0, X
LAFE4	ret	
;
;-----------------------------------------------------------------------
LAFE5:	brset	FirstTimeSensorErrors, #O2_SensorError, LAFEE
	bset	FirstTimeSensorErrors, #O2_SensorError
	jr	LAFFB
;
LAFEE	bset	CurrentSensorErrors, #O2_SensorError
	pushX	
	ldaA	#O2_SensorError
	ldaB	#LogSensorErrorIdx
	xgDX	
	call	LogDiagError
	popX	
LAFFB	ret	
;
;-----------------------------------------------------------------------
CheckWaterTempSensor:
	ldaA	UseWaterTempMinMax
	beq	@SkipCheck
	ldaA	WaterTemp_raw
	cmpA	WaterTemp_raw_Min
	bcs	@TooLow
	cmpA	WaterTemp_raw_Max
	bhi	@TooHigh

@SkipCheck
	bclr	FirstTimeSensorErrors, #WaterTemp_SensorError
	bclr	CurrentSensorErrors, #WaterTemp_SensorError
	jr	@cont1
;
@TooLow
	bset	SensorHiLowErrors, #WaterTemp_SensorError
	jr	@cont2
;
@TooHigh
	bclr	SensorHiLowErrors, #WaterTemp_SensorError
@cont2
	brset	FirstTimeSensorErrors, #WaterTemp_SensorError, @AlreadyInError
	bset	FirstTimeSensorErrors, #WaterTemp_SensorError
	jr	@cont1
;
@AlreadyInError		; allows single erroneous reading, else flagged
	bset	CurrentSensorErrors, #WaterTemp_SensorError
	ldaA	#WaterTemp_SensorError
	ldaB	#LogSensorErrorIdx
	xgDX	
	call	LogDiagError
@cont1	brset	Flag01, #%00000001, LB040
	bset	Flag01, #%00000001
	brclr	FirstTimeSensorErrors, #WaterTemp_SensorError, LB040
	bset	Flag01, #%00000010
LB040	ret	

;
;-----------------------------------------------------------------------
CheckAndStoreWaterTemp:
	ldX	#$FFFF
	brclr	Flag01, #%00000010, @LB054
	bclr	Flag01, #%00000010
	brset	CurrentSensorErrors, #AirTemp_SensorError, @StoreDefault
	ldaA	CurrentAirTemp
	jr	@LB074
;
@LB054	brset	CurrentSensorErrors, #WaterTemp_SensorError, @ReuseCurrent
	brclr	FirstTimeSensorErrors, #WaterTemp_SensorError, @StoreTemp
	jr	@LB089
;
@ReuseCurrent
	ldaA	CurrentWaterTemp
	cmpA	MaxWaterTemp
	bcc	@StoreDefault
	ldX	WaterTempSomething
	cmpX	#$FFFF
	beq	@LB074
	ldX	WaterTempSomething
	bne	@Exit
	incA	
@LB074	pushA	
	clrA	
	ldaB	LF72E
	lslD	
	lslD	
	lslD	
	xgDX	
	popA	
	jr	@StoreTemp
;
@StoreDefault
	ldaA	MaxWaterTemp
	ldX	#$FFFF

@StoreTemp
	staA	CurrentWaterTemp
@LB089	stX	WaterTempSomething
@Exit	ret	
;

;-----------------------------------------------------------------------
CheckAirTempSensor:
	ldaA	UseAirTempMinMax
	beq	LB09F
	ldaA	AirTemp_raw
	cmpA	AirTemp_raw_Min
	bcs	LB0A7
	cmpA	AirTemp_raw_Max
	bhi	LB0AC
LB09F	bclr	FirstTimeSensorErrors, #AirTemp_SensorError
	bclr	CurrentSensorErrors, #AirTemp_SensorError
	jr	LB0C3
;
LB0A7	bset	SensorHiLowErrors, #AirTemp_SensorError
	jr	LB0AF
;
LB0AC	bclr	SensorHiLowErrors, #AirTemp_SensorError
LB0AF	brset	FirstTimeSensorErrors, #AirTemp_SensorError, LB0B8
	bset	FirstTimeSensorErrors, #AirTemp_SensorError
	jr	LB0C3
;
LB0B8	bset	CurrentSensorErrors, #AirTemp_SensorError
	ldaA	#AirTemp_SensorError
	ldaB	#LogSensorErrorIdx
	xgDX	
	call	LogDiagError
LB0C3	ret	
;

;-----------------------------------------------------------------------
CheckAndStoreAirTemp:
	brset	CurrentSensorErrors, #AirTemp_SensorError, LB0CE
	brclr	FirstTimeSensorErrors, #AirTemp_SensorError, LB0DD
	jr	LB0E0
;
LB0CE	brset	CurrentSensorErrors, #WaterTemp_SensorError, LB0DA
	; substitute water temp if air broken
	ldaA	CurrentWaterTemp
	cmpA	DefaultAirTemp
	bcs	LB0DD
LB0DA	ldaA	DefaultAirTemp
LB0DD	staA	CurrentAirTemp
LB0E0	ret	
;

;-----------------------------------------------------------------------
CheckBatteryVoltage:
	ldaA	BatteryVoltage_raw
	tst	UseBatteryVoltageMinMax
	beq	LB0F3
	cmpA	BatteryVoltage_raw_Min
	bcs	LB0FB
	cmpA	BatteryVoltage_raw_Max
	bhi	LB0FB
LB0F3	bclr	FirstTimeSensorErrors, #BatteryVoltage_SensorError 
	bclr	CurrentSensorErrors, #BatteryVoltage_SensorError 
	jr	LB112
;
LB0FB	brset	FirstTimeSensorErrors, #BatteryVoltage_SensorError , LB104
	bset	FirstTimeSensorErrors, #BatteryVoltage_SensorError 
	jr	LB10F
;
LB104	bset	CurrentSensorErrors, #BatteryVoltage_SensorError 
	ldaA	#BatteryVoltage_SensorError
	ldaB	#LogSensorErrorIdx
	xgDX	
	call	LogDiagError
LB10F	ldaA	LF734
LB112	ret	
;
;-----------------------------------------------------------------------
CheckCoil1:
	ldD	>L00EB
	call	L9073
	brclr	InternalErrors, #%01000000, LB121
	brset	Flag02, #%00000010, LB124
LB121	jmp	LB1C1
;
LB124	brclr	Flag17, #NewInputCapture2, LB163
	bclr	Flag17, #NewInputCapture2
	ldaA	InputCapture2CheckEnabled
	bne	LB138
	bclr	FirstTimeOutputErrors, #Coil1_OutputError
	bclr	CurrentOutputErrors, #Coil1_OutputError
	jr	LB15E
;
LB138	ldD	>InputCapture2_StoredValue
	cmpD	InputCapture2_Max
	bcs	LB14E
	ldaA	FilteredBatteryVoltage
	cmpA	MinBatteryForCoilCheck
	bcs	LB14E
	bset	Flag04, #%10000000
	jr	LB19D
;
LB14E	brset	Flag04, #Coil1_Error, LB1A2
	bclr	FirstTimeOutputErrors, #Coil1_OutputError
	bclr	CurrentOutputErrors, #Coil1_OutputError
	brclr	Flag04, #%10100000, LB15E
	jr	LB1C1
;
LB15E	call	L9098
	jr	LB1CF
;
LB163	ldaA	L01A2
	ldaB	L019B
	stD	L01BF
	ldD	L019E
	stD	L01BF
	ldD	OutputCompare2Interval
	stD	L01BF
	ldD	V019C
	stD	L01BF
	ldaA	InputCapture2CheckEnabled
	bne	LB18B
	bclr	FirstTimeOutputErrors, #Coil1_OutputError
	bclr	CurrentOutputErrors, #Coil1_OutputError
	jr	LB1C1
;
LB18B	brset	Flag04, #%00000001, LB1C1
	brclr	Flag01, #%00001000, LB1C1
	call	LB603
	brclr	InternalErrors, #%01000000, LB1C1
	bset	Flag04, #%00100000
LB19D	bclr	OutputHiLowErrors, #Coil1_OutputError
	jr	LB1A5
;
LB1A2	bset	OutputHiLowErrors, #Coil1_OutputError
LB1A5	brclr	Flag01, #%00001000, LB1C1
	brset	FirstTimeOutputErrors, #Coil1_OutputError, LB1B2
	bset	FirstTimeOutputErrors, #Coil1_OutputError
	jr	LB1C1
;
LB1B2	brset	CurrentOutputErrors, #FuelPump_OutputError, LB1C1
	bset	CurrentOutputErrors, #Coil1_OutputError
	ldaA	#Coil1_OutputError
	ldaB	#LogOutputErrorIdx
	xgDX	
	call	LogDiagError
LB1C1	brset	FirstTimeOutputErrors, #Coil1_OutputError, LB1CC
	brset	CurrentOutputErrors, #Coil1_OutputError, LB1CC
	bclr	Flag04, #%10100000
LB1CC	call	L915E
LB1CF	cmpD	L01C8
	bcs	LB1D8
	ldD	L01C8
LB1D8	stD	>L00EB
	bset	Flag01, #%00001000
	ret	
;
;-----------------------------------------------------------------------
CheckCoil2:
	ldD	>L00ED
	call	L9073
	brclr	InternalErrors, #%01000000, LB1ED
	brset	Flag02, #%00000010, LB1F0
LB1ED	jmp	LB28D
;
LB1F0	brclr	Flag17, #%01000000, LB22F
	bclr	Flag17, #%01000000
	ldaA	LF706
	bne	LB204
	bclr	FirstTimeOutputErrors, #Coil2_OutputError
	bclr	CurrentOutputErrors, #Coil2_OutputError
	jr	LB22A
;
LB204	ldD	>L00F1
	cmpD	InputCapture2_Max
	bcs	LB21A
	ldaA	FilteredBatteryVoltage
	cmpA	MinBatteryForCoilCheck
	bcs	LB21A
	bset	Flag04, #%00001000
	jr	LB269
;
LB21A	brset	Flag04, #Coil2_Error, LB26E
	bclr	FirstTimeOutputErrors, #Coil2_OutputError
	bclr	CurrentOutputErrors, #Coil2_OutputError
	brclr	Flag04, #%00001010, LB22A
	jr	LB28D
;
LB22A	call	L90FB
	jr	LB29B
;
LB22F	ldaA	L01AC
	ldaB	L01A5
	stD	L01BF
	ldD	L01A8
	stD	L01BF
	ldD	OutputCompare4Interval
	stD	L01BF
	ldD	L01A6
	stD	L01BF
	ldaA	LF706
	bne	LB257
	bclr	FirstTimeOutputErrors, #Coil2_OutputError
	bclr	CurrentOutputErrors, #Coil2_OutputError
	jr	LB28D
;
LB257	brset	Flag04, #%00000001, LB28D
	brclr	Flag01, #%00010000, LB28D
	call	LB603
	brclr	InternalErrors, #%01000000, LB28D
	bset	Flag04, #%00000010
LB269	bclr	OutputHiLowErrors, #Coil2_OutputError
	jr	LB271
;
LB26E	bset	OutputHiLowErrors, #Coil2_OutputError
LB271	brclr	Flag01, #%00010000, LB28D
	brset	FirstTimeOutputErrors, #Coil2_OutputError, LB27E
	bset	FirstTimeOutputErrors, #Coil2_OutputError
	jr	LB28D
;
LB27E	brset	CurrentOutputErrors, #FuelPump_OutputError, LB28D
	bset	CurrentOutputErrors, #Coil2_OutputError
	ldaA	#Coil2_OutputError
	ldaB	#LogOutputErrorIdx
	xgDX	
	call	LogDiagError
LB28D	brset	FirstTimeOutputErrors, #Coil2_OutputError, LB298
	brset	CurrentOutputErrors, #Coil2_OutputError, LB298
	bclr	Flag04, #%00001010
LB298	call	L915E
LB29B	cmpD	L01C8
	bcs	LB2A4
	ldD	L01C8
LB2A4	stD	>L00ED
	bset	Flag01, #%00010000
	ret	
;
XIRQ_isr:
	reti	
;
;-----------------------------------------------------------------------
LB2AC:
	ReadExtraPort
	brset	PORTA_DataReg, #HorizInjectorBit, LB2D5
	brset	HardwarePortInValue, #%01000000, LB2CC
	ldaA	LF704
	beq	LB317
	brclr	InternalErrors, #%01000000, LB317
	bset	Flag35, #%00000001
	bclr	OutputHiLowErrors, #Injector_OutputError
	jr	LB2F3
;
LB2CC	bclr	Flag35, #%00000001
	brset	Flag34, #%00000001, LB31D
	jr	LB317
;
LB2D5	brclr	HardwarePortInValue, #%01000000, LB2EA
	ldaA	LF704
	beq	LB30B
	brclr	InternalErrors, #%01000000, LB30B
	bset	Flag34, #%00000001
	bset	OutputHiLowErrors, #Injector_OutputError
	jr	LB2F3
;
LB2EA	bclr	Flag34, #%00000001
	brset	Flag35, #%00000001, LB31D
	jr	LB317
;
LB2F3	brset	FirstTimeOutputErrors, #Injector_OutputError, LB2FC
	bset	FirstTimeOutputErrors, #Injector_OutputError
	jr	LB30B
;
LB2FC	brset	CurrentOutputErrors, #FuelPump_OutputError, LB30B
	bset	CurrentOutputErrors, #Injector_OutputError
	ldaA	#Injector_OutputError
	ldaB	#LogOutputErrorIdx
	xgDX	
	call	LogDiagError
LB30B	brclr	OutputHiLowErrors, #Injector_OutputError, LB31D
	bclr	TCTL1_TimerControlReg, #TCTL1_OL5
	bset	CFORC_ForceOutputCompareReg, #FORCE_OC5		; set horiz injector low
	jr	LB31D
;
LB317	bclr	FirstTimeOutputErrors, #Injector_OutputError
	bclr	CurrentOutputErrors, #Injector_OutputError
LB31D	ret	
;
;-----------------------------------------------------------------------
LB31E:
	ReadExtraPort 
	brset	PORTA_DataReg, #VertInjectorBit, LB347
	brset	HardwarePortInValue, #%00010000, LB33E
	ldaA	LF704
	beq	LB389
	brclr	InternalErrors, #%01000000, LB389
	bset	Flag35, #%00100000
	bclr	OutputHiLowErrors, #AC_OutputError
	jr	LB365
;
LB33E	bclr	Flag35, #%00100000
	brset	Flag34, #%00100000, LB38F
	jr	LB389
;
LB347	brclr	HardwarePortInValue, #%00010000, LB35C
	ldaA	LF704
	beq	LB37D
	brclr	InternalErrors, #%01000000, LB37D
	bset	Flag34, #%00100000
	bset	OutputHiLowErrors, #AC_OutputError
	jr	LB365
;
LB35C	bclr	Flag34, #%00100000
	brset	Flag35, #%00100000, LB38F
	jr	LB389
;
LB365	brset	FirstTimeOutputErrors, #%00100000, LB36E
	bset	FirstTimeOutputErrors, #%00100000
	jr	LB37D
;
LB36E	brset	CurrentOutputErrors, #FuelPump_OutputError, LB37D
	bset	CurrentOutputErrors, #AC_OutputError
	ldaA	#AC_OutputError
	ldaB	#LogOutputErrorIdx
	xgDX	
	call	LogDiagError
LB37D	brclr	OutputHiLowErrors, #AC_OutputError, LB38F
	bclr	TCTL1_TimerControlReg, #TCTL1_OL3
	bset	CFORC_ForceOutputCompareReg, #FORCE_OC3		; Set vert injector low
	jr	LB38F
;
LB389	bclr	FirstTimeOutputErrors, #AC_OutputError
	bclr	CurrentOutputErrors, #AC_OutputError
LB38F	ret	
;
;-----------------------------------------------------------------------
CheckFuelPump:
	ldaA	FuelPumpCheckEnabled
	beq	LB3C2
	ldaA	#FuelPump_OutputError
	bitA	SavedOutputErrors
	beq	LB3A0
	bitA	Flag03
	beq	LB412
LB3A0	brset	Flag26, #%00000001, LB3DE
	ReadExtraPort
	brset	ExtraPortOutShadow, #%00010000, LB3CB
	brset	HardwarePortInValue, #%10000000, LB3C2
	ldaA	Vec1TableIndex
	cmpA	#$05
	beq	LB412
	bset	Flag34, #%01000000
	bclr	OutputHiLowErrors, #FuelPump_OutputError
	jr	LB3E6
;
LB3C2	bclr	Flag34, #%01000000
	brset	Flag35, #%01000000, LB412
	jr	LB3DE
;
LB3CB	brclr	HardwarePortInValue, #%10000000, LB3D7
	bset	Flag35, #%01000000
	bset	OutputHiLowErrors, #FuelPump_OutputError
	jr	LB3E6
;
LB3D7	bclr	Flag35, #%01000000
	brset	Flag34, #%01000000, LB412
LB3DE	bclr	FirstTimeOutputErrors, #FuelPump_OutputError
	bclr	CurrentOutputErrors, #FuelPump_OutputError
	jr	LB412
;
LB3E6	brset	FirstTimeOutputErrors, #FuelPump_OutputError, LB3EF
	bset	FirstTimeOutputErrors, #FuelPump_OutputError
	jr	LB412
;
LB3EF	ldaA	Vec1TableIndex
	cmpA	#$05
	bne	LB3F9
	bclr	ExtraPortOutShadow, #%00010000
LB3F9	ldaA	FirstTimeOutputErrors
	andA	#%01001000
	staA	FirstTimeOutputErrors
	ldaA	CurrentOutputErrors
	andA	#%00001000
	oraA	#FuelPump_OutputError
	staA	CurrentOutputErrors
	bclr	Flag03, #%01000000
	ldaA	#FuelPump_OutputError
	ldaB	#LogOutputErrorIdx
	xgDX	
	call	LogDiagError
LB412	ret	
;
;-----------------------------------------------------------------------
RamTestAndClear:
	ldaA	#$55
	staA	0, X
	cmpA	0, X
	bne	LB42A
	comA	
	staA	0, X
	cmpA	0, X
	bne	LB42A
	clr	0, X
	incX	
	cmpX	0, Y
	bne	RamTestAndClear
LB42A	ret	
;
;-----------------------------------------------------------------------
InitSavedVariableAreaFromRom:
	ldaA	FirstTimeFunctionErrors
	pushA	
	ldaA	CurrentFunctionErrors
	pushA	
	ldX	#SavedVariableAreaInitialValues
	ldY	#SavedVariableArea
	ldD	#(EndSavedVariableArea - SavedVariableArea) ; $22
	call	MemCopy_XtoY_1
	popA	
	andA	#RAM_Error
	staA	CurrentFunctionErrors
	popA	
	andA	#RAM_Error
	staA	FirstTimeFunctionErrors
	ret	
;
;-----------------------------------------------------------------------
; Adds one 16bit word to the checksum each time the function is called
;
;
DoRomChecksum:
	ldaA	RomChecksumEnabled
	beq	@disabled
	ldX	RomChecksumIdx
	ldD	RomChecksumSum
	addD	0, X
	stD	RomChecksumSum
	decX	
	decX	
	stX	RomChecksumIdx
	cmpX	#EPROM_Start
	bcc	@notDone
	cmpD	RomChecksum
	bne	@RomError
@disabled
	bclr	FirstTimeFunctionErrors, #ROM_Error
	bclr	CurrentFunctionErrors, #ROM_Error
	jr	@goAgain
;
@RomError
	brset	FirstTimeFunctionErrors, #ROM_Error, @doubleFault
	bset	FirstTimeFunctionErrors, #ROM_Error
	jr	@goAgain
;
@doubleFault
	bset	CurrentFunctionErrors, #ROM_Error
	ldaA	#ROM_Error
	ldaB	#LogFunctionErrorIdx
	xgDX	
	call	LogDiagError
@goAgain
	ldD	#$FFFE
	stD	RomChecksumIdx
	ldD	#$0000
	stD	RomChecksumSum
@notDone
	ret	
;
;-----------------------------------------------------------------------
LB492:	ldaA	#$01
LB494	staA	L0255
	call	LAC38
	pushX	
	ldY	#$0008
	ldD	#$0000
@loop	addD	0, X
	incX	
	incX	
	decY	
	bne	@loop
	popX	
	cmpD	#$55AA
	bne	LB4B9
	bclr	FirstTimeFunctionErrors, #EEPROM_Error
	bclr	CurrentFunctionErrors, #EEPROM_Error
	jr	LB4EE
;
LB4B9	ldaB	L0254
	oraB	L0255
	staB	L0254
	ldaA	LF70B
	bne	LB4CF
	bclr	FirstTimeFunctionErrors, #EEPROM_Error
	bclr	CurrentFunctionErrors, #EEPROM_Error
	jr	LB4E3
;
LB4CF	brset	FirstTimeFunctionErrors, #EEPROM_Error, LB4D8
	bset	FirstTimeFunctionErrors, #EEPROM_Error
	jr	LB4E3
;
LB4D8	bset	CurrentFunctionErrors, #EEPROM_Error
	ldaA	#EEPROM_Error
	ldaB	#LogFunctionErrorIdx
	xgDX	
	call	LogDiagError
LB4E3	ldaA	L0255
	lslA	
	cmpA	#$08
	bne	LB494
	ldX	#InitialisedVarValues
LB4EE	ldY	#InitVarCopyDest
	ldaB	#$10
	call	MemCopy_XtoY_1
	ldaA	#$01
	staA	L0255
	ldaA	L0254
	andA	#%11100111
	staA	L0254
	ret	
;
;-----------------------------------------------------------------------
CopTimout_isr:
	bset	InternalErrors, #COP_Timeout
	jr	LB50D
;
;-----------------------------------------------------------------------
ClkMonTimout_isr:
	bset	InternalErrors, #ClockMonitor_Timeout
LB50D	clr	ResetFlag
	jmp	WarmReset
;
;-----------------------------------------------------------------------
IllegalOpcode_isr:
	bset	InternalErrors, #BadOpCode
	jr	LB51B
;
;-----------------------------------------------------------------------
Unexpected_isr:
	bset	InternalErrors, #UnexpectedISR
LB51B	call	ShutdownIO
	SetExtraPortBit #%00000100
@loop	jr	@loop
;
;-----------------------------------------------------------------------
CheckPickupError:
	ldaB	PickupFaultCount
	ldaA	PickupCheckEnabled
	beq	LB540
	brset	Flag01, #SkipFirstPickupCheck, LB53B
	bset	Flag01, #SkipFirstPickupCheck
	jr	LB540
;
LB53B	cmpB	PickupFaultCompareCount
	bne	LB548
LB540	bclr	FirstTimeFunctionErrors, #RevPickup_SensorError
	bclr	CurrentFunctionErrors, #RevPickup_SensorError
	jr	LB55C
;
LB548	brset	FirstTimeFunctionErrors, #RevPickup_SensorError, LB551
	bset	FirstTimeFunctionErrors, #RevPickup_SensorError
	jr	LB55C
;
LB551	bset	CurrentFunctionErrors, #RevPickup_SensorError
	ldaA	#RevPickup_SensorError
	ldaB	#LogFunctionErrorIdx
	xgDX	
	call	LogDiagError
LB55C	ldaB	PickupFaultCount
	staB	PickupFaultCompareCount
	ret	
;
;-----------------------------------------------------------------------
; high byte of X = error bit
; low byte of X = index of error byte * 2
;		  0 = sensor errors
;		  2 = output errors
;		  4 = function errors
;
LogDiagError:
	tPA	
	pushA	
	pushX	
	xgDX	
	brset	InternalErrors, #RAM_Failure1, exit
	ldX	#DiagErrorsInEEPROM
	aBX	
	bitA	0, X
	bne	exit	; already got that error stored in eeprom
	di	
	lslB	
	lslB		; was *2 on function entry, now *8
@bitLow
	incB	
	lsrA	
	bcc	@bitLow ; B = bit index of error bit starting at 1
	tst	ErrorBitIndex 
	beq	@newError
	cmpB	ErrorBitIndex
	bne	exit
	jr	@sameError
;
@newError
	staB	ErrorBitIndex
	popA	
	popB	
	pushB	
	pushA	
	ldX	#ErrorCounts
	lsrB		; / 2 = 0, 1, 2 idx
	aBX	
	ldaB	0, X
	staB	ErrorCountdown

@sameError
	dec	ErrorCountdown
	bne	exit
	ldaB	EEPROM_Status2
	beq	LB5A6
	inc	ErrorCountdown
	jr	exit
;
LB5A6	ldaB	#$02
	staB	CopyToEEPROM_Count
	popA	
	popB	
	pushB	
	pushA	
	ldX	#DiagErrorsInEEPROM
	aBX	
	oraA	0, X
	staA	EEPROM_WriteBuffer
	popA	
	pushA	
	ldY	#SensorHiLowErrors
	aBY	
	andA	0, Y
	oraA	1, X
	staA	EEPROM_WriteBuffer + 1
	stX	EEPROM_DestAddr
	ldaB	#$1A
	staB	EEPROM_Status2
	bset	InternalErrors, #RAM_Failure1
	ldaA	L009B
	staA	L0094
	cmpX	#L0F14
	bne	exit
	ldaA	LF712
	staA	L0202
exit
	popX	
	popA	
	tAP	
	ret	
;
;-----------------------------------------------------------------------
ClearSavedDiagError:
	ldaA	#$06
	staA	CopyToEEPROM_Count
	ldD	#$0000
	stD	EEPROM_WriteBuffer
	stD	EEPROM_WriteBuffer + 2
	stD	EEPROM_WriteBuffer + 4
	ldD	#DiagErrorsInEEPROM
	stD	EEPROM_DestAddr
	ldaA	#$1A
	staA	EEPROM_Status2
	ret	
;
;-----------------------------------------------------------------------
LB603:	ldaA	#$10
LB605	brclr	PORTE_DataReg, #%00100000, LB60E
	decA	
	bne	LB605
	jr	LB614
;
LB60E	bclr	InternalErrors, #%01000000
	bclr	Flag01, #%01100000
LB614	ret	
;
;-----------------------------------------------------------------------
UpdateDiagFlags:
	ldaA	SavedSensorErrors
	andA	#%00001111
	bne	LB62F
	ldaA	SavedOutputErrors
	andA	#%00100111
	bne	LB62F
	ldaA	SavedFunctionErrors
	andA	#%00110001
	bne	LB62F
	bclr	Flag14, #%10000000
	jr	LB635
;
LB62F	bset	Flag14, #%10000000
	staA	Scratch3
LB635	ldaA	SavedOutputErrors
	bitA	#%00000110
	beq	LB648
	ldaA	EEPROM_InitialValues
	bitA	#%00000001
	beq	LB648
	bset	Flag02, #InjectorsDisabled
	jr	LB64B
LB648	bclr	Flag02, #InjectorsDisabled

LB64B	ldaA	CurrentWaterTemp
	cmpA	#(54 + WaterTempOffset)
	bcs	@lower
	bset	FGSTAT, #FGSTAT_WaterTemp
	jr	LB65A
@lower	bclr	FGSTAT, #FGSTAT_WaterTemp

LB65A	brset	Flag15, #MotorRunning1, @set
	bclr	FGSTAT, #FGSTAT_MotorTurning
	jr	LB666
@set	bset	FGSTAT, #FGSTAT_MotorTurning

LB666	brset	Flag17, #%00010000, @set
	bclr	FGSTAT, #FGSTAT_PositionSensorOK
	jr	LB672
@set	bset	FGSTAT, #FGSTAT_PositionSensorOK

LB672	brset	Flag15, #TPS_Closed, @set
	brset	Flag15, #TPS_WideOpen, @set
	bclr	FGSTAT, #FGSTAT_TPS_MinOrMax
	jr	LB682
@set	bset	FGSTAT, #FGSTAT_TPS_MinOrMax

LB682	brset	O2Flags, #O2_LoopClosed, @set
	bclr	FGSTAT, #FGSTAT_O2_LoopClosed
	jr	LB68E
@set	bset	FGSTAT, #FGSTAT_O2_LoopClosed

LB68E	brset	Flag28, #%00100000, @set
	bclr	FGSTAT, #FGSTAT_StepperTest
	jr	LB69A
@set	bset	FGSTAT, #FGSTAT_StepperTest

LB69A	brclr	Flag28, #DiagStoreTPSFlag, @clear
	brclr	Flag28, #DiagCancelTest, @clear
	bclr	Flag28, #DiagStoreTPSFlag
@clear	ret	
;
;-----------------------------------------------------------------------
ProcessDiagSlowInit:
	brset	Flag30, #%00000100, LB6D5
	brset	Flag02, #%00001000, LB6D5
	brset	Flag15, #MotorRunning1, LB6D5
	brset	Flag30, #%10000000, LB6D8
	brclr	PORTD_DataReg, #RxBit, @RxLow
	ldaA	DiagSlowInitCount_08
	staA	DiagSlowInitCounter
	jr	LB6D5
;
@RxLow	ldaA	DiagSlowInitCounter
	beq	LB6CC
	dec	DiagSlowInitCounter
	jr	LB6D5
;
LB6CC	bset	Flag30, #%10000000
	clrA	
	staA	SCCR2_SerialControlReg
	bclr	TMSK2register, #%00100000
LB6D5	jmp	LB779
;
LB6D8	brclr	Flag30, #%00000001, LB707
	brclr	Flag30, #%00000010, LB6E5
LB6E0	bclr	PORTD_DataReg, #TxBit
	jr	LB6D5
;
LB6E5	brset	PORTD_DataReg, #RxBit, LB6F4
	bclr	Flag30, #%00000011
	bclr	Flag30, #%00010000
	clr	DiagSlowInitCounter
	jr	LB752
;
LB6F4	ldaA	DiagSlowInitCounter
	beq	LB6FF
	decA	
	staA	DiagSlowInitCounter
	jr	LB6D5
;
LB6FF	bset	Flag30, #%00001100
	bclr	PORTD_DataReg, #TxBit
	jr	LB6D5
;
LB707	brset	Flag30, #%00010000, LB72B
	brset	PORTD_DataReg, #RxBit, LB714
	clr	DiagSlowInitCounter
	jr	LB752
;
LB714	ldaA	DiagSlowInitCounter
	incA	
	staA	DiagSlowInitCounter
	cmpA	DiagSlowInitCount_08
	bcs	LB752
	ldaA	DiagSlowInitCount_99
	staA	DiagSlowInitCounter
	bset	Flag30, #%00010000
	jr	LB752
;
LB72B	brclr	PORTD_DataReg, #RxBit, LB73F
	ldaA	DiagSlowInitCounter
	cmpA	DiagSlowInitCount_99
	beq	LB752
	bclr	Flag30, #%00010000
	clr	DiagSlowInitCounter
	jr	LB752
;
LB73F	ldaA	DiagSlowInitCounter
	beq	LB749
	dec	DiagSlowInitCounter
	jr	LB6E0
;
LB749	bset	Flag30, #%00000011
	ldaA	DiagSlowInitCount_26
	staA	DiagSlowInitCounter
LB752	brclr	Flag30, #%01000000, LB779
	brclr	Flag30, #%00100000, LB765
	ldD	L0203
	lsrD	
	bcc	LB773
	bclr	Flag30, #%00100000
	jr	LB773
;
LB765	ldD	L0203
	lsrD	
	bcc	LB773
	stD	L0203
	bclr	PORTD_DataReg, #TxBit
	jr	LB779
;
LB773	stD	L0203
	bset	PORTD_DataReg, #TxBit
LB779	brclr	Flag30, #%00000010, LB798
	ldaA	DiagSlowInitCounter
	beq	LB78F
	decA	
	staA	DiagSlowInitCounter
	bitA	#%00000010
	beq	LB798
	bset	PORTD_DataReg, #TxBit
	jr	LB798
;
LB78F	bclr	Flag30, #%00000010
	ldaA	DiagSlowInitCount_26
	staA	DiagSlowInitCounter
LB798	ret	
;
;-----------------------------------------------------------------------
LB799:	brset	Flag30, #%10000000, LB7A0
	jmp	LB843
;
LB7A0	brclr	Flag30, #%00001000, LB7B9
	clr	>FirstTimeSensorErrors
	clr	>FirstTimeOutputErrors
	clr	>FirstTimeFunctionErrors
	clr	>CurrentSensorErrors
	clr	>CurrentOutputErrors
	clr	>CurrentFunctionErrors
	bclr	Flag30, #%00001000
LB7B9	ldD	L0203
	beq	LB7C1
LB7BE	jmp	LB843
;
LB7C1	ldaB	L00C2
	andB	#%00001111
	beq	LB7CE
	ldaB	L00C2
	decB	
	staB	L00C2
	jr	LB821
;
LB7CE	ldD	L0205
	beq	LB7DB
	ldaA	L00C2
	addA	#$10
	staA	L00C2
	jr	LB80B
;
LB7DB	brclr	Flag02, #%10000000, LB7EE
	ldaB	SavedFunctionErrors
	beq	LB7E9
	bclr	Flag02, #%10000000
	jr	LB805
;
LB7E9	bclr	Flag02, #%10000000
	jr	LB7BE
;
LB7EE	ldaA	SavedSensorErrors
	bne	LB7FF
	ldaB	SavedOutputErrors
	beq	LB7FA
	jr	LB802
;
LB7FA	bset	Flag02, #%10000000
	jr	LB7BE
;
LB7FF	ldaB	SavedOutputErrors
LB802	bset	Flag02, #%10000000
LB805	stD	L0205
	clr	>L00C2
LB80B	bset	L00C2, #%00001111
LB80E	ldD	L0205
	lsrD	
	stD	L0205
	bcs	LB81F
	ldaA	L00C2
	addA	#$10
	staA	L00C2
	jr	LB80E
;
LB81F	ldaB	L00C2
LB821	brclr	Flag02, #%10000000, LB82A
	ldX	#LF74A
	jr	LB82D
;
LB82A	ldX	#LF84A
LB82D	aBX	
	ldaB	0, X
	cmpB	#$04
	bcs	LB837
	bset	Flag30, #%00100000
LB837	ldX	#LF742
	aBX	
	ldD	0, X
	stD	L0203
	bset	Flag30, #%01000000
LB843	ret	

;
;-----------------------------------------------------------------------
; Realtime ISR
; Frequency is 4Mhz / $4000 = 244.14 Hz, period is 4.096 ms
;
RTII_isr:
	ldaA	#%01000000
	staA	TFLG2register	; clear interrupt
	ldaA	DiagMode
	cmpA	#DiagMode_NormalSendVar
	bne	@NormalProcessing
	brclr	Flag28, #DiagTestInProgress, @B860
	ldD	DiagCountdownTimer
	beq	@zero
	subD	#$0001
	stD	DiagCountdownTimer

@zero	call	ResetCOPtimer
@B860	brclr	TxFlags, #TxFlags_TxPending, @LB873
	brclr	TxFlags, #TxFlags_TxSync, @LB870
	bclr	TxFlags, #(TxFlags_TxPending | TxFlags_TxSync)
	ldaA	TxHold
	staA	SCDR_SerialDataReg
@LB870	bset	TxFlags, #TxFlags_TxSync
@LB873	brclr	Flag28, #DiagTestStarted, @NormalProcessing
	ldaA	DiagCommand
	cmpA	#$8E			; Test >= 8E, can be made with engine running
	bcc	@NormalProcessing
	call	ProcessEEPROM_Update
	jmp	RTII_exit		; otherwise if diag test in progress
					; then skip normal real time processing
;
@NormalProcessing
	call	ExecuteVec4Functions
	brclr	Flag11, #%00000001, LB891
	inc	L015C
	jmp	RTII_exit
;
LB891	bset	Flag11, #%00000001
	ldaB	#$10
@checkAgain	
	brset	PORTE_DataReg, #%00100000, @diagConnected	; guess
	brset	Flag26, #%00000001, LB8AD
	jr	@skip
;
@diagConnected
	brclr	Flag26, #%00000001, LB8AD
@skip	decB	
	bne	@checkAgain
	ldaA	Flag26
	xorA	#%00000001
	jr	LB8BE
;
LB8AD	dec	TestModeCounter
	bne	LB8C6
	ldaA	Flag26
	oraA	#%00000100
	andA	#%11111101
	bitA	#%00000001
	beq	LB8BE
	oraA	#%00000010
LB8BE	staA	Flag26
	ldaA	TestModeCountInitialValue ; $0A
	staA	TestModeCounter
LB8C6	ei	
	brclr	PORTA_DataReg, #%00000100, LB8D9
	clr	L0253
	ldaA	L0252
	incA	
	beq	LB8E5
	inc	L0252
	jr	LB8E5
;
LB8D9	clr	L0252
	ldaA	L0253
	incA	
	beq	LB8E5
	inc	L0253
LB8E5	ldaA	LF6FA
	beq	LB91E
	ldaA	LF6FB
	beq	LB90B
	cmpA	L0253
	bhi	LB8F7
	bclr	Flag26, #%00010000
LB8F7	cmpA	L0252
	bhi	LB921
	bset	Flag26, #%00010000
	ClearExtraPortBit FuelPumpBit
	jr	LB921
;
LB90B	brclr	PORTA_DataReg, #%00000100, LB91E
	bset	Flag26, #%00010000
	ClearExtraPortBit FuelPumpBit
	jr	LB921
;
LB91E	bclr	Flag26, #%00010000
LB921	di	
	ldaA	#$14		; selects inputs 4 - 7
	staA	ADCtlRegister
	call	SendPowerOnID
@wait1	ldaA	ADCtlRegister
	bpl	@wait1
	ldaA	ADR1Register
	staA	WaterTemp_raw
	ldaA	ADR3Register
	staA	FuelTrimpot_raw
	ldaA	ADR4Register
	staA	AirTemp_raw
	ei	
	ldX	#Scratch6
	ldaB	RawFuelTrimpotScale	; initially $82
	staB	0, X
	ldaA	FuelTrimpot_raw
	ldaB	FuelTrimOffset		; initially 0
	call	AddABmultX0mult2	; (( trim + 0 ) * $82 * 2 ) / $100
	staA	ScaledFuelTrimpot	; = * 1.016 (ie, not much change)

	ldaA	TPS_Voltage
	staA	TPS_VoltgePrevious

	di	
	ldaA	#$10		; selects inputs 0 - 3
	staA	ADCtlRegister
@wait2	ldaA	ADCtlRegister
	bpl	@wait2
	ldaA	ADR1Register
	staA	Analog00	; not used
	ldaA	ADR2Register
	staA	BatteryVoltage_raw
	ldaA	ADR3Register
	staA	TPS_raw
	ldaA	ADR4Register
	staA	AtmPressure_raw
	ei	
	call	ProcessTPS
	ldaA	TPS_Voltage
	ldaB	TPS_Trim
	subB	#$80
	bcc	@positive
	ldaB	#$80
	subB	TPS_Trim
	sBA			; - trim
	bcc	LB993
	ldaA	#$00
	jr	LB993
;
@positive
	aBA			; + trim
	bcc	LB993
	ldaA	#$FF
LB993	staA	TPSLookupTableIdx
	call	DoTPSTableLookup
	ldaB	TPS_Voltage
	subB	TPS_LearnedClosedThrottle
	bcc	LB9A1
	clrB	
LB9A1	staB	TPS_MinusClosedOffset
	lsrB	
	lsrB	
	lsrB	
	lsrB	
	lsrB			; keep 3 msb's
	ldX	#TPS_ZoneTable1
	aBX	
	ldaA	0, X
	staA	TPS_ValueAlways_02
	ldX	#TPS_ZoneTable2
	aBX	
	ldaA	0, X
	staA	TPS_Value_02or03
	ldX	#Scratch6
	ldD	Filtered_TPS_Voltage1
	stD	0, X
	ldaA	TPS_Voltage
	ldaB	TPS_VoltageFilterWeight1
	call	FilterByteValue
	stD	Filtered_TPS_Voltage1
	ldD	Filtered_TPS_Voltage2
	staA	Filtered_TPS_Voltage2a
	cmpA	TPS_Voltage
	brclr	Flag13, #%00000001, LB9E5
	bcc	LB9F2
	cmpA	TPS_VoltgePrevious
	bcc	LB9F2
	jr	LB9EC
;
LB9E5	bls	LB9F2
	cmpA	TPS_VoltgePrevious
	bls	LB9F2
LB9EC	clrB	
	ldaA	TPS_Voltage
	jr	LBA00
;
LB9F2	ldX	#Scratch6
	stD	0, X
	ldaA	TPS_Voltage
	ldaB	TPS_VoltageFilterWeight2
	call	FilterByteValue
LBA00	stD	Filtered_TPS_Voltage2
	ldD	Filtered_TPS_Voltage3
	staA	Filtered_TPS_Voltage3a
	brclr	Flag13, #%10001001, LBA24
	cmpA	TPS_Voltage
	brclr	Flag13, #%00001000, LBA1D
	bls	LBA2A
	cmpA	TPS_VoltgePrevious
	bls	LBA2A
	jr	LBA24
;
LBA1D	bcc	LBA2A
	cmpA	TPS_VoltgePrevious
	bcc	LBA2A
LBA24	clrB	
	ldaA	TPS_Voltage
	jr	LBA35
;
LBA2A	stD	0, X
	ldaA	TPS_Voltage
	ldaB	TPS_VoltageFilterWeight3
	call	FilterByteValue
LBA35	stD	Filtered_TPS_Voltage3
	call	CheckForWideOpenOrClosedThrottle
	ldX	#Scratch6
	ldD	>CurrentAtmPressure
	stD	0, X
	ldaA	AtmPressure_raw
	ldaB	AtmPressureFilterWeight
	call	FilterByteValue
	stD	>CurrentAtmPressure
	call	CheckPressureSensor
	call	LA110
	call	L964E
	ldaA	TPS_LearnedWideOpenThrottle
	cmpA	Filtered_TPS_Voltage1
	bcc	LBA66
	ldaA	Filtered_TPS_Voltage1
	staA	TPS_LearnedWideOpenThrottle
	jr	LBA7E
;
LBA66	ldaA	TPS_Voltage
	cmpA	TPS_CompareHigh
	bls	LBA9A
	cmpA	TPS_LearnedWideOpenThrottle
	bcc	LBA9A
	ldD	L0248
	cmpD	LF6A6
	bcs	LBA89
	dec	>TPS_LearnedWideOpenThrottle
LBA7E	clr	L0248
	clr	L0249
	clr	L024A
	jr	LBA9A
;
LBA89	ldD	L0249
	addD	#$0040
	stD	L0249
	ldaA	L0248
	adcA	#$00
	staA	L0248
LBA9A	ldaA	TPS_LearnedClosedThrottle
	cmpA	Filtered_TPS_Voltage1
	bls	LBAA8
	ldaA	Filtered_TPS_Voltage1
	staA	TPS_LearnedClosedThrottle
	jr	LBAC0
;
LBAA8	ldaA	TPS_Voltage
	cmpA	TPS_CompareLow
	bcc	LBADC
	cmpA	TPS_LearnedClosedThrottle
	bls	LBADC
	ldD	L024B
	cmpD	LF6A6
	bcs	LBACB
	inc	>TPS_LearnedClosedThrottle
LBAC0	clr	L024B
	clr	L024C
	clr	L024D
	jr	LBADC
;
LBACB	ldD	L024C
	addD	#$0040
	stD	L024C
	ldaA	L024B
	adcA	#$00
	staA	L024B
LBADC	call	ProcessEEPROM_Update
	brset	InternalErrors, #RAM_Failure1, LBAEF
	ldX	#DiagErrorsInEEPROM
	ldY	#Diag_Errors
	ldaB	#$06
	call	MemCopy_XtoY_1
LBAEF	brset	Flag26, #%00000001, LBB08
	brset	Flag26, #%00010000, LBB08
	brclr	ExtraPortOutShadow, #%00010000, LBB08
	brclr	Flag01, #%00100000, LBB10
	brclr	Flag01, #%01000000, LBB15
	bset	InternalErrors, #%01000000
	jr	LBB18
;
LBB08	bclr	InternalErrors, #%01000000
	bclr	Flag01, #%01100000
	jr	LBB18
;
LBB10	bset	Flag01, #%00100000
	jr	LBB18
;
LBB15	bset	Flag01, #%01000000
LBB18	bclr	Flag11, #%00000001
RTII_exit
	reti	
;
;-----------------------------------------------------------------------
; Main timer is 4Mhz / 8 = 0.5 MHz
;
; Overflow once every $10000 times
; 500000 / 65536 = about 7.63 Hz
; (period 131.072ms)
;
TimerOverflow_isr:
	ldaA	#%10000000
	staA	TFLG2register				; clear overflow flag
	bset	InjectorFlags, #Timer131ms
	ldaA	>TimerOverflowCount1
	brclr	Flag08, #TimerOverflowCaught, @inc
	bclr	Flag08, #TimerOverflowCaught		; pulse accumulator isr happened at same time
	jr	@PAisrInc
;
@inc	inc	TimerOverflowCount2
	addA	#$01
	staA	>TimerOverflowCount1
@PAisrInc
	cmpA	EngineTurningTimout
	bcs	@skip
	jr	NotRunningRestart
;
@skip	brset	Flag15, #MotorRunning1, LBB57
	bset	PORTD_DataReg, #%00100000
	bset	Flag05, #%00000100
	tst	L01E5
	beq	LBB9D
	dec	L01E5
	bne	LBB9D
	bset	Flag26, #%00001000
	jr	LBB9D
;
LBB57	bclr	Flag26, #%00001000
	ldaA	LF687
	staA	L01E5
	ldaA	>TimerOverflowCount1
	cmpA	EngineStoppingTimout
	bcc	@hasStopped
	brclr	Flag18, #%00000001, LBB9A
	brclr	Flag05, #%00001000, LBB9A
@hasStopped
	ldaA	#%10101010
	staA	TCTL1_TimerControlReg
	ldaA	#%01111000
	staA	CFORC_ForceOutputCompareReg	; turn off all coil/inj outputs now
	brset	Flag15, #MotorRunning2, StopWithDelay

NotRunningRestart
	clr	>TimerOverflowCount1
	ldS	#StackTop
	jmp	MotorStopped2
;
StopWithDelay
	ldaA	MotorStoppedDelay
@delay	ldX	#$0299
@loop	decX	
	bne	@loop
	call	ResetCOPtimer
	decA	
	bne	@delay
	ldS	#StackTop
	jmp	MotorStopped1
;
LBB9A	bset	Flag05, #%00001000
LBB9D	ldD	L01E6
	beq	LBBA8
	subD	#$0001
	stD	L01E6
LBBA8	brclr	Flag28, #Diag_8E_TestFlag, LBBB7
	brset	Flag28, #%00100000, LBBB7
	ldaA	L00C0
	beq	LBBB7
	dec	>L00C0
LBBB7	brset	Flag17, #%00010000, LBBC3
	bclr	Flag02, #%00000001
	bclr	Flag02, #%00000010
	jr	LBBD3
;
LBBC3	brclr	Flag02, #%00000001, LBBD0
	brset	Flag02, #%00000010, LBBD3
	bset	Flag02, #%00000010
	jr	LBBD3
;
LBBD0	bset	Flag02, #%00000001
LBBD3	dec	L0201
	bne	LBBE8
	ldaA	LF710
	staA	L0201
	bclr	Flag34, #%00010000
	bclr	Flag35, #%00010000
	ldaA	#$FF
	jr	LBBF0
;
LBBE8	ldaA	SavedOutputErrors
	andA	CurrentOutputErrors
	andA	FirstTimeOutputErrors
	comA	
LBBF0	staA	Flag03
	brclr	Flag03, #%01000000, LBC0F
	brset	Flag26, #%00010000, LBC0F
	ldaA	Vec1TableIndex
	cmpA	#$03
	beq	LBC05
	cmpA	#$05
	bne	LBC0F
LBC05	SetExtraPortBit FuelPumpBit
LBC0F	ldaA	ErrorBitIndex
	beq	LBC39
	decA	
	bitA	#%00001000
	bne	LBC22
	bitA	#%00010000
	bne	LBC27
	ldX	#$0088
	jr	LBC2A
;
LBC22	ldX	#$0089
	jr	LBC2A
;
LBC27	ldX	#$008A
LBC2A	andA	#%00000111
	clrB	
	sec	
LBC2E	rolB	
	decA	
	bpl	LBC2E
	bitB	0, X
	bne	LBC39
	clr	ErrorBitIndex
LBC39	call	ProcessDiagSlowInit
	ldaA	ExtraPortOutShadow
	ldaB	L0202
	brset	Flag26, #%00000010, LBC8B
	brclr	Flag02, #%00001000, LBC5E
	decB	
	beq	LBC53
	cmpB	LF711
	bcc	LBC87
	jr	LBC8B
;
LBC53	bclr	Flag02, #%00001000
	tst	SavedFunctionErrors
	beq	LBC5E
	ldaB	LF712
LBC5E	ldaA	EEPROM_InitialValues
	bitA	#%00000010
	beq	LBC70
	ldaA	SavedSensorErrors
	oraA	SavedOutputErrors
	oraA	SavedFunctionErrors
	bne	LBC7E
LBC70	ldaA	SavedSensorErrors
	andA	CurrentSensorErrors
	bne	LBC7E
	ldaA	SavedOutputErrors
	andA	CurrentOutputErrors
	beq	LBC81
LBC7E	ldaB	LF712
LBC81	ldaA	ExtraPortOutShadow
	tstB	
	beq	LBC8B
	decB	
LBC87	oraA	#%00000001
	jr	LBC8D
;
LBC8B	andA	#%11111110
LBC8D	staA	ExtraPortOutShadow
	staB	L0202
	pushA	
	ldaA	ExtraPortOutShadow
	staA	HardwarePort_write
	popA	
	reti	
;
;-----------------------------------------------------------------------
LBC9A:	decX	
	cBA	
	bcs	LBCA3
	xgDX	
	tBA	
	clrB	
	jr	LBCAA
;
LBCA3	pushA	
	clrA	
	idiv	
	popA	
	clrB	
	idiv	
	xgDX	
LBCAA	ret	


;-----------------------------------------------------------------------
; Function takes a number and reduces it to
; an index and a fraction part based on the given table.
;
; Input
; 	A = number
;	X = pointer to first entry in table of bytes
;	B = count of values in table 
;
; Output
;	A = index of first table entry that number is between
;	B = f/$100 frational position between the table values 
;
DoTableToNdxFrac:
	tstB	
	bne	LBCB1
	clrA	
	jr	LBCDF
;
LBCB1	cmpA	0, X
	bhi	LBCBA
	ldD	#$0000
	jr	LBCDF
;
LBCBA	decB	
	aBX	
	cmpA	0, X
	bcs	LBCC4
	tBA	
	clrB	
	jr	LBCDF
;
LBCC4	decB	
	decX	
	cmpA	0, X
	bcs	LBCC4
	bne	LBCD0
	tBA	
	clrB	
	jr	LBCDF
;
LBCD0	pushB	
	subA	0, X
	ldaB	1, X
	subB	0, X
	ldX	#$0000
	aBX	
	clrB	
	idiv	
	xgDX	
	popA	
LBCDF	ret	


;-----------------------------------------------------------------------
; Function takes a number and reduces it to
; an index and a fraction part based on the given table.
; Assumes table values go from hi to low.
;
; Input
; 	D = number
;	X = pointer to last entry in table of words
;	Y = count of values in table - 1
;
; Output
;	A = index of entry that is just >= to D
;	B = f/$100 frational position between the table values 
;
DoCalcMapNdxFrac:
	cmpD	0, X
	bhi	LBCEB
	xgDY			; off end of table so index
	tBA			; index is last
	clrB			; fraction is 0
	jr	LBD1B
;
LBCEB	cmpY	#$0000
@loop	beq	@found		; at start of table
	cmpD	0, X
	bls	@found		; found table entry >=
	decX	
	decX	
	decY	
	jr	@loop
;
@found	pushY			; save index	
	cmpD	0, X
	bcc	LBD18		; off start of table
	subD	0, X
	negA	
	negB	
	sbcA	#$00		; 16 bit negate (make diff positive)
	xgDX			; save in X
	xgDY			; Y points to table entries
	ldD	0, Y
	subD	2, Y		; diff of table values
	xgDX	
	fdiv			; fractional divide (T[i] - number) / (T[i] - T[i+1])
	xgDX	
	tAB			; B = fractional part
	jr	LBD19
;
LBD18	clrB	
LBD19	popA			; toss hi byte of index (is 0)
	popA			; A = index
LBD1B	ret	

;-----------------------------------------------------------------------
; Input
;	Y = address of 16 byte table
;	A = index into table
;	B = fractional part between table values
;
; Output
;	A = new value
;
InterpolateValue:
	pushB	
	tAB	
	aBY	
	ldaA	1, Y
	subA	0, Y
	popB	
	bcs	LBD3D	; decreasing value table
	jr	LBD38	; increasing
;
;-----------------------------------------------------------------------
InterpolateValueSigned:
	pushB	
	tAB	
	aBY	
	ldaA	1, Y
	subA	0, Y
	popB	
	blt	LBD3D
LBD38	mul		; mul table diff by fraction
	adcA	#$00
	jr	LBD42
;
LBD3D	negA		; change to +ve
	mul	
	adcA	#$00
	negA		; back to -ve
LBD42	addA	0, Y	; add base part to fraction part
	ret	



;-----------------------------------------------------------------------
;
; Input
;	Y = address of 16 word table
;	X[0] = index into table
;	X[1] = fractional part between table values
;
; Output
;	D = new value
;
InterpolateWordValue:
	ldaB	0, X
	aBY	
	aBY	
	ldD	0, Y
	subD	2, Y
	bcs	LBD5C	; increasing value table
	callr	LBD66
	negA	
	negB	
	sbcA	#$00
	jr	LBD62
;
LBD5C	negA	
	negB	
	sbcA	#$00
	callr	LBD66
LBD62	addD	0, Y	; add base value
	ret	
;
;-----------------------------------------------------------------------
LBD66:	pushA		; 8 * 16bit multiply, lsB dropped
	ldaA	1, X
	mul	
	adcA	#$00
	tAB	
	popA	
	pushB	
	ldaB	1, X
	mul	
	xgDX	
	popB	
	aBX	
	xgDX	
	ret	


;-----------------------------------------------------------------------
; Input
;	y[0] = fractional value in X direction
;	y[1] = fractional value in Y direction 
;	y[2] = number of columns in map
; 	X = address of byte in map to use
;
; Output
;	A = 3 point interpolation of X[0], X[1] and X[columns]
;
InterpolateMapPoint:
	ldaB	0, Y
	ldaA	1, X
	subA	0, X
	bcs	LBD85
	mul	
	adcA	#$00
	jr	LBD8A
;
LBD85	negA	
	mul	
	adcA	#$00
	negA	
LBD8A	addA	0, X
	ldaB	2, Y
	pushA	
	pushA	
	aBX	
	ldaA	1, X
	subA	0, X
	ldaB	0, Y
	bcs	LBDA0
	mul	
	adcA	#$00
	jr	LBDA5
;
LBDA0	negA	
	mul	
	adcA	#$00
	negA	
LBDA5	addA	0, X
	popB	
	sBA	
	ldaB	1, Y
	bcs	LBDB3
	mul	
	adcA	#$00
	jr	LBDB8
;
LBDB3	negA	
	mul	
	adcA	#$00
	negA	
LBDB8	popB	
	aBA	
	ret	
;
;-----------------------------------------------------------------------
; Input
;	y[0] = fractional value in X direction
;	y[1] = fractional value in Y direction 
;	y[2] = number of columns in map
; 	X = address of byte in map to use
;
; Output
;	A = 3 point interpolation of X[0], X[1] and X[columns]
;
InterpolateMapPointSigned:
	ldaB	0, Y
	ldaA	1, X
	subA	0, X
	blt	LBDC9
	mul	
	adcA	#$00
	jr	LBDCE
;
LBDC9	negA	
	mul	
	adcA	#$00
	negA	
LBDCE	addA	0, X
	ldaB	2, Y
	pushA	
	pushA	
	aBX	
	ldaB	0, Y
	ldaA	1, X
	subA	0, X
	blt	LBDE4
	mul	
	adcA	#$00
	jr	LBDE9
;
LBDE4	negA	
	mul	
	adcA	#$00
	negA	
LBDE9	addA	0, X
	popB	
	sBA	
	blt	LBDF7
	ldaB	1, Y
	mul	
	adcA	#$00
	jr	LBDFF
;
LBDF7	negA	
	ldaB	1, Y
	mul	
	adcA	#$00
	negA	
LBDFF	popB	
	aBA	
	ret	

;-----------------------------------------------------------------------
;
;         (A * 256 - X) * B
; X new = -----------------  +  X
;                256
;
FilterByteValue:
	subA	0, X
	bcc	LBE0E
	negA	
	mul	
	negA	
	negB	
	sbcA	#$00
	jr	LBE0F
;
LBE0E	mul	
LBE0F	addD	0, X
	ret	


;-----------------------------------------------------------------------
;
;
FilterWordValue:
	subD	0, X
	bcc	LBE22
	negA	
	negB	
	sbcA	#$00
	callr	MultDbyX2
	negA	
	negB	
	sbcA	#$00
	jr	LBE24
;
LBE22	callr	MultDbyX2
LBE24	addD	0, X
	ret	

;-----------------------------------------------------------------------
;
; 16bit by 8bit multiply
;
MultDbyX2:
	pushB	
	ldaB	2, X
	mul	
	xgDY	
	popA	
	ldaB	2, X
	mul	
	adcA	#$01
	tAB	
	aBY	
	xgDY	
	ret	
;
;-----------------------------------------------------------------------
AddABmultX0mult2:
	tstB	
	bpl	LBE43
	aBA	
	bcs	LBE48
	ldaA	#$00
	jr	LBE50
;
LBE43	aBA	
	bcc	LBE48
	ldaA	#$FF
LBE48	ldaB	0, X
	mul	
	lslD	
	bcc	LBE50
	ldaA	#$FF
LBE50	ret	
;
;-----------------------------------------------------------------------
;
; 16 by 16 Multipy
;
MultDbyX0:
	pushA	
	ldaB	1, X
	mul	
	adcA	#$00
	popB	
	pushA	
	ldaA	0, X
	mul	
	tSX	
	addB	0, X
	adcA	#$00
	incS	
	ret	
;
;-----------------------------------------------------------------------
; 8 by 16 Multiply
;
MultAbyX:	pushX	
	tSX	
	ldaB	1, X
	staA	1, X
	mul	
	staB	Mult_lsB
	ldY	#$0000
	aBY	
	ldaB	0, X
	staA	0, X
	ldaA	1, X
	mul	
	addB	0, X
	adcA	#$00
	popX	
	ret	
;
;-----------------------------------------------------------------------
DoTPSTableLookup:
	ldaB	TPSLookupTableIdx
	ldX	#TPSLookupTable
	aBX	
	aBX	
	ldD	0, X
	stD	CurrentTPS
	ret	
;
;
TPSLookupTable:
	dw	$0000, $0000, $0000, $0000, $0000, $0000, $0000, $0000
	dw	$0000, $004B, $0096, $00E2, $012D, $0178, $01C4, $020F
	dw	$025A, $02A6, $02F1, $033D, $0388, $03D3, $041F, $046A
	dw	$04B5, $0501, $054C, $0597, $05E3, $062E, $067A, $06C5
	dw	$0710, $075C, $07A7, $07F2, $083E, $0889, $08D4, $0920
	dw	$096B, $09B7, $0A02, $0A4D, $0A99, $0AE4, $0B2F, $0B7B
	dw	$0BC6, $0C12, $0C5D, $0CA8, $0CF4, $0D3F, $0D8A, $0DD6
	dw	$0E21, $0E6C, $0EB8, $0F03, $0F4F, $0F9A, $0FE5, $1031
	dw	$107C, $10C7, $1113, $115C, $11A9, $11F5, $1240, $128C
	dw	$12D7, $1322, $1363, $13B9, $1404, $1450, $149B, $14E7
	dw	$1532, $157D, $15C9, $1614, $165F, $16AB, $16F6, $1741
	dw	$178D, $17D8, $1824, $186F, $18BA, $1906, $1951, $199C
	dw	$19E8, $1A33, $1A7E, $1ACA, $1B15, $1B61, $1BAC, $1BF7
	dw	$1C43, $1C8E, $1CD9, $1D25, $1D70, $1DBC, $1E07, $1E52
	dw	$1E9E, $1EE9, $1F34, $1F80, $1FCB, $2016, $2062, $20AD
	dw	$20F9, $2144, $218F, $21DB, $2226, $2271, $22BD, $2308
	dw	$2353, $239F, $23EA, $2436, $2481, $24CC, $2518, $2563
	dw	$25AE, $25FA, $2645, $2690, $26DC, $2727, $2773, $27BE
	dw	$2809, $2855, $28A0, $28EB, $2937, $2982, $29CE, $2A19
	dw	$2A64, $2AB0, $2AFB, $2B46, $2B92, $2BDD, $2C28, $2C74
	dw	$2CBF, $2D0B, $2D56, $2DA1, $2DED, $2E38, $2E83, $2ECF
	dw	$2F1A, $2F65, $2FB1, $2FFC, $311F, $323F, $335F, $347F
	dw	$359F, $36BF, $37DF, $38FF, $3A1F, $3B3F, $3C5F, $3D7F
	dw	$3E9F, $3FBF, $40DF, $41FF, $431F, $443F, $455F, $467E
	dw	$479E, $48BE, $49DE, $4AFE, $4C1E, $4D3E, $4E5E, $4F7E
	dw	$509E, $51BE, $52DE, $53FE, $551E, $563E, $575E, $587E
	dw	$599E, $5ABE, $5BDE, $5CFD, $5E1D, $5F3D, $605D, $617D
	dw	$629D, $63BD, $64DD, $65FD, $671D, $683D, $695D, $6A7D
	dw	$6B9D, $6CBD, $6DDD, $6EFD, $701D, $713D, $725C, $737C
	dw	$749C, $75BC, $76DC, $77FC, $791C, $7A3C, $7B5C, $7C7C
	dw	$7D9C, $7EBC, $7FDC, $80FC, $821C, $833C, $845C, $857C
	dw	$869C, $87BC, $88DB, $89FB, $8B1B, $8C3B, $8D5B, $8E7B
;
;-----------------------------------------------------------------------
IRQ_isr:
	reti	
;
;-----------------------------------------------------------------------
ResetCOPtimer:
	pushA	
	ldaA	#$55
	staA	CopRstRegister
	comA	
	staA	CopRstRegister
	popA	
	ret	
;
;-----------------------------------------------------------------------
MemCopy_XtoY_1:
	ldaA	0, X
	staA	0, Y
	incX	
	incY	
	decB	
	bne	MemCopy_XtoY_1
	ret	
;
;-----------------------------------------------------------------------
ShutdownIO:
	di	
	ldaA	#$02
	staA	TMSK2register
	clrA	
	staA	TCTL1_TimerControlReg
	staA	OC1Mregister
	staA	OC1Dregister
	staA	TMSK1_TimerInterruptMask1Reg
	staA	PORTA_DataReg
	staA	PIOC_ParallelIOcontrolReg
	ldaA	#%00000010
	staA	PORTD_DataReg
	bclr	Flag05, #%00000001
	ldaA	#%00000100
	staA	ExtraPortOutShadow
	pushA	
	ldaA	ExtraPortOutShadow
	staA	HardwarePort_write
	popA	
	ret	
;
;
	db	$50, $66, $00, $00, $00, $00
;
;
;-------------------------------------------------------------------
; Special Diag code starts
; Not used in normal running operation
;
; Re-uses RAM locations, so currently var names are not all correct
;-------------------------------------------------------------------
;


L0080			EQU	$0080
L0081			EQU	$0081
L0084			EQU	$0084
Diag2RxChar		EQU	$0085
SpecialDiagVarA		EQU	$0088
SpecialDiagVarB		EQU	$008b
SpecialDiagVarC		EQU	$008f
L009C			EQU	$009C
SpecialDiagVarD		EQU	$00a2
SpecialDiagVarE		EQU	$0086
SpecialDiagVarF		EQU	$0087
SpecialDiagG		EQU 	$009f


L00E8			EQU	$00E8
L00FD			EQU	$00FD
L015A			EQU	$015A
L0164			EQU	$0164
L0167			EQU	$0167
L0185			EQU	$0185
L0189			EQU	$0189
L018A			EQU	$018a
L018C			EQU	$018C
X0098			EQU	$0098
X009E			EQU	$009e
X00E3			EQU	$00e3
X00A0			EQU	$00a0

X019C			EQU	$019c
L019D			EQU	$019d
X0200			EQU	$0200

;-----------------------------------------------------------------------
IsrJumpTable2:
	jmp	SCI_isr_2
LC0D3:	jmp	Unexpected_isr_2
LC0D6:	jmp	PAII_isr_2
LC0D9:	jmp	Unexpected_isr_2
LC0DC:	jmp	TOI_isr_2
LC0DF:	jmp	OC5I_isr_2
LC0E2:	jmp	OC4I_isr_2
LC0E5:	jmp	Unexpected_isr_2
LC0E8:	jmp	OC2I_isr_2
LC0EB:	jmp	Unexpected_isr_2
LC0EE:	jmp	IC3I_isr_2
LC0F1:	jmp	IC2I_isr_2
LC0F4:	jmp	IC1I_isr_2
LC0F7:	jmp	RTII_isr_2
LC0FA:	jmp	Unexpected_isr_2
LC0FD:	jmp	XIRQ_isr_2
;
;
;-----------------------------------------------------------------------
FunctionTable1:
	db	$00
	dw	LC622
	db	$01
	dw	LC663
	db	$05
	dw	LD45E
	db	$10
	dw	LC6AC
	db	$11
	dw	LC6E0
	db	$30
	dw	LC78D
	db	$33
	dw	LC7F1
	db	$34
	dw	LC894
	db	$36
	dw	LC91C
	db	$50
	dw	LD400
	db	$51
	dw	LCA67
	db	$60
	dw	LD44C
	db	$FF	; FF marks end of table

LC125:
	db	$09
	dw	$000C
	db	$0A
	dw	$000D
	db	$0B
	dw	$000E
	db	$0C
	dw	$000F
;
;-----------------------------------------------------------------------
; Entry with DiagMode = 9 or 6
;
EnableSpecialDiagMode:
	di	
	ldS	#StackTop
	clrA	
	staA	SCCR2_SerialControlReg
	call	LC48F
	ldX	#SpecialDiagClearStart
LC13E	clr	0, X
	incX	
	cmpX	#SpecialDiagClearEnd
	bcs	LC13E
	clr	0, X
	call	LC48F
	ldX	#IsrJumpTable2
	ldY	#IsrJumpTableDest
	ldaB	#$D0
	call	MemCopy_XtoY_2
	callr	LC19B
	callr	Diag2InitComms
	call	LC1E6
	pushA	
	ldaA	>DiagMode
	cmpA	#$09
	popA
	bne	LC16A
	call	LCF97
LC16A	ei	
LC16B	call	LC48F
	call	LC216
	brclr	L0081, #%00010000, LC178
	call	LC3CA
LC178	brclr	L0081, #%01000000, LC17F
	bclr	L0081, #%01000000
LC17F	ldaA	SpecialDiagVarD
	beq	LC186
	call	LC36E
LC186	pushA	
	ldaA	>DiagMode
	cmpA	#$09
	popA		
	bne	LC199
	brset	X00E3, #%00001100, LC199
	bclr	X00E3, #%00001000
	call	LD00F
LC199	jr	LC16B
;
LC19B:	ldaA	#$F0
	staA	TFLG2register
	ldaA	#$40
	staA	TMSK2register
	bset	PACTL_PulseAccumulatorControlReg, #%00000001
	bclr	PACTL_PulseAccumulatorControlReg, #%00000010
	tPA	
	andA	#%10111111
	tAP	
	clrA	
	staA	TCTL1_TimerControlReg
	staA	OC1Mregister
	staA	OC1Dregister
	staA	TMSK1_TimerInterruptMask1Reg
	staA	PORTA_DataReg
	ldaA	#$40
	staA	PIOC_ParallelIOcontrolReg
	ldaA	#$02
	staA	PORTD_DataReg
	ldaA	#%00000100
	staA	ExtraPortOutShadow
	pushA	
	ldaA	ExtraPortOutShadow
	staA	HardwarePort_write
	popA	
	ldaA	#$78
	staA	DDRA_DataDirectionReg
	ldaA	#$26
	staA	DDRD_DataDirectionReg
	ldaA	#$48
	staA	PORTC_DataReg
	ret	
;
;-----------------------------------------------------------------------
; Sets baud rate at E CLOCK / 13 / 16 / 16
;
; 4 MHz / 13 / 2 / 16 = 9615 baud
;
Diag2InitComms:
	ldaA	#$31
	staA	baud_Register
	ldaA	#(SCCR2_RxISR_Enable | SCCR2_TxEnable | SCCR2_RxEnable)
	staA	SCCR2_SerialControlReg
	clr	>SCCR1_SerialControlReg
	ldD	SCSR_SerialStatusReg
	ret	
;
;-----------------------------------------------------------------------
LC1E6:	clrA	
	staA	L0081
	staA	X009E
	staA	SpecialDiagG
	staA	SpecialDiagVarD
	call	LC326
	ldD	#$C215
	stD	X00A0
	ldY	#$0330
	stY	SpecialDiagVarC
	stY	Flag34
	bset	L0081, #%00000100
	ldY	#$0350
	stY	SpecialDiagVarB
	stY	CurrentOutputErrors
	clrA	
	staA	Diag2RxChar
	staA	SpecialDiagVarE
	staA	SpecialDiagVarF
	ret	
;
;-----------------------------------------------------------------------
LC216:	brclr	L0081, #%10000000, LC22D
	pushA	
	ldaA	>DiagMode
	cmpA	#$09
	popA	
	bne	LC229
	brset	X00E3, #%00001100, LC229
	jr	LC22D
;
LC229	ldX	X00A0
	call	0, X
LC22D	brclr	L0081, #%00001000, LC266
	bclr	L0081, #%00001000
	ldX	CurrentOutputErrors
	ldaB	0, X
	staB	SpecialDiagVarA
	incX	
	ldaA	0, X
	staA	X009E
	incX	
	stX	CurrentOutputErrors
	cmpA	#$0A
	beq	LC25C
	cmpA	#$09
	beq	LC253
	ldX	#FunctionTable1
	call	GetFunctionPointer
	jmp	0, Y
;
LC253	ldaA	#$09
	staA	SpecialDiagVarD
	bset	L0081, #%10000000
	jr	LC266
;
LC25C	ldY	#$0330
	stY	Flag34
	bset	L0081, #%00010000
LC266	ret	
;
;-----------------------------------------------------------------------
GetFunctionPointer:
	cmpA	0, X
	beq	LC274
	incX	
	incX	
	incX	
	brset	0, X, #%11111111, LC278
	jr	GetFunctionPointer
;
LC274	ldY	1, X
	ret	
;
LC278	ldY	#$C215
	ldaA	#$0B
	staA	SpecialDiagVarD
	ret	
;
LC281:	ldaA	L0189
	beq	LC2CB
	bclr	X0098, #%00000001
	ldaB	L009B
	bne	LC29C
	ldX	#L018C
	stX	L0099
	cmpA	#$06
	beq	LC2CC
	cmpA	#$02
	beq	LC317
	jr	LC2E4
;
LC29C	decB	
	staB	L009B
	bne	LC2BC
	clr	>PPROG_EEPROM_ProgramReg
	ldaB	X009E
	cmpB	#$0E
	beq	LC2B1
	ldX	L018A
	incX	
	stX	L018A
LC2B1	dec	X019C
	beq	LC2C5
	cmpA	#$16
	beq	LC2E4
	jr	LC317
;
LC2BC	cmpB	#$05
	bne	LC2CB
	clr	>PPROG_EEPROM_ProgramReg
	jr	LC317
;
LC2C5	clr	L0189
	bset	X0098, #%00000001
LC2CB	ret	
;
LC2CC	ldaA	#$01
	staA	X019C
	ldaA	#$05
	staA	L009B
	ldaB	#(PPROG_ERASE | PPROG_EELAT)
	ldY	#StartEEPROM
LC2DB	staB	PPROG_EEPROM_ProgramReg
	staA	0, Y
	bset	PPROG_EEPROM_ProgramReg, #PPROG_EEPGM
	ret	
;
LC2E4	cmpA	#$0E
	bne	LC2F5
	ldaA	#$01
	staA	X019C
	ldaA	#$05
	staA	L009B
	ldaB	#$0E
	jr	LC311
;
LC2F5	ldX	L0099
	ldaA	0, X
	ldY	L018A
	cmpA	0, Y
	bne	LC30B
	incX	
	stX	L0099
	ldaA	#$01
	staA	L009B
	jr	LC2CB
;
LC30B	ldaB	#$0A
	staB	L009B
	ldaB	#$16
LC311	ldY	L018A
	jr	LC2DB
;
LC317	ldaA	#$05
	staA	L009B
	ldX	L0099
	ldaA	0, X
	incX	
	stX	L0099
	ldaB	#$02
	jr	LC311
;
LC326:	clr	L0189
	clr	>L009B
	clr	>PPROG_EEPROM_ProgramReg
	ret	
;
LC330:	tstB	
	bpl	LC33A
	aBA	
	bcs	LC33F
	ldaA	#$00
	jr	LC347
;
LC33A	aBA	
	bcc	LC33F
	ldaA	#$FF
LC33F	ldaB	0, X
	mul	
	lslD	
	bcc	LC347
	ldaA	#$FF
LC347	nop	
	ret	
;
LC349:	lslD	
	lslD	
	pushB	
	ldaB	#$59
	mul	
	xgDX	
	popB	
	ldaA	#$59
	mul	
	adcA	#$00
	tAB	
	aBX	
	xgDX	
	lslD	
	pushB	
	ldaB	L0153
	mul	
	xgDX	
	popB	
	ldaA	L0153
	mul	
	adcA	#$00
	tAB	
	aBX	
	xgDX	
	stD	L0152
	ret	
;
;-----------------------------------------------------------------------
LC36E:	bclr	L0081, #%00000100
	ldX	#L0330
	stX	Flag34
	stX	SpecialDiagVarC
	ldY	#LC125
	ldaB	#$03
	staB	0, X
	incX	
LC381	cmpA	0, Y
	beq	LC38E
	incY	
	incY	
	incY	
	jr	LC381
;
LC38E	ldaA	0, Y
	staA	0, X
	incX	
	incY	
	decB	
	bne	LC38E
	stX	SpecialDiagVarC
	clr	>SpecialDiagVarD
	bset	L0081, #%00010000
	ret	
;
LC3A2:	ldY	Flag34
	ldaA	0, Y
	incY	
	tAB	
	ldX	#$0000
	aBX	
	decA	
	decA	
LC3B1	ldaB	0, Y
	incY	
	aBX	
	decA	
	bne	LC3B1
	stX	0, Y
	ret	
;
;-----------------------------------------------------------------------
MemCopy_XtoY_2:
	ldaA	0, X
	staA	0, Y
	incX	
	incY	
	decB	
	bne	MemCopy_XtoY_2
	ret	
;
;-----------------------------------------------------------------------
LC3CA:	bclr	L0081, #%00010000
	ldX	Flag34
	ldaA	0, X
	staA	SpecialDiagVarA
	incX	
	stX	Flag34
	ldaB	SCSR_SerialStatusReg
	staA	SCDR_SerialDataReg
	bset	L0081, #%00100000
	ldaB	#(SCCR2_TxISR_Enable | SCCR2_TxEnable)
	staB	SCCR2_SerialControlReg
	ret	
;
;-----------------------------------------------------------------------
TxComplete_isr2:
	brset	L0081, #%00100000, LC3F1
	bclr	SCCR2_SerialControlReg, #SCCR2_TxISR_Enable
	ldaA	#$00
	ldaB	SCSR_SerialStatusReg
	staA	SCDR_SerialDataReg
	jr	LC444
;
LC3F1	dec	>SpecialDiagVarA
	ble	LC407
	ldY	Flag34
	ldaA	0, Y
	ldaB	SCSR_SerialStatusReg
	staA	SCDR_SerialDataReg
	incY	
	stY	Flag34
	jr	LC444
;
LC407	bne	LC41E
	ldaB	#$48
	staB	SCCR2_SerialControlReg
	ldY	Flag34
	ldaA	0, Y
	ldaB	SCSR_SerialStatusReg
	staA	SCDR_SerialDataReg
	incY	
	stY	Flag34
	jr	LC444
;
LC41E	bclr	L0081, #%00100000
	bset	L0081, #%01000000
	bset	L0081, #%00000100
	ldY	#$0350
	stY	SpecialDiagVarB
	stY	CurrentOutputErrors
	clrA	
	staA	Diag2RxChar
	staA	SpecialDiagVarE
	staA	SpecialDiagVarF
	ldaA	SCSR_SerialStatusReg
	ldaA	SCDR_SerialDataReg
	ldaA	#$24
	staA	SCCR2_SerialControlReg
	ldaA	SCSR_SerialStatusReg
	staA	SCDR_SerialDataReg
LC444	ret	
;
;-----------------------------------------------------------------------
RxChar_isr2:
	ldaA	SCDR_SerialDataReg
	ldaB	#$1A
	staB	L0084
	brclr	L0081, #%00000100, LC48A
	ldaB	SpecialDiagVarE
	bne	LC465
	cmpA	#$28
	bhi	LC48A
	staA	Diag2RxChar
LC459	ldX	SpecialDiagVarB
	staA	0, X
	incX	
	stX	SpecialDiagVarB
	inc	>SpecialDiagVarE
	jr	LC48E
;
LC465	cmpB	Diag2RxChar
	bne	LC459
	bclr	L0081, #%00000100
	ldX	SpecialDiagVarB
	staA	0, X
	incX	
	stX	SpecialDiagVarB
	decX	
	decX	
	ldD	0, X
	stD	L0095
	ldX	#$0350
	stX	Flag34
	call	LC3A2
	cmpX	L0095
	bne	LC48A
	bset	L0081, #%00001000
	jr	LC48E
;
LC48A	ldaA	#$0A
	staA	SpecialDiagVarD
LC48E	ret	
;
;-----------------------------------------------------------------------
LC48F:	ldaA	>DiagMode
	cmpA	#$09
	beq	LC49A
	cmpA	#$06
	bne	LC4A1
LC49A	ldaB	#$55
	staB	CopRstRegister
	comB	
	staB	CopRstRegister
LC4A1	ret	
;
;-----------------------------------------------------------------------
SCI_isr_2:
	ldD	TCNT_TimerCountReg
	stD	InternalErrors
	ldY	#$0000
	brclr	SCSR_SerialStatusReg, #SCSR_RxChar, LC4BC
	brclr	SCSR_SerialStatusReg, #%00001110, LC4C1
	ldaA	SCDR_SerialDataReg
	ldaA	SCSR_SerialStatusReg
	ldaA	#$0A
	staA	SpecialDiagVarD
	jr	LC4C4
;
LC4BC	call	TxComplete_isr2
	jr	LC4C4
;
LC4C1	call	RxChar_isr2
LC4C4	reti	
;
;-----------------------------------------------------------------------
PAII_isr_2:
	ldX	TCNT_TimerCountReg
	ldaA	#$10
	staA	TFLG2register
	ldaA	PACTL_PulseAccumulatorControlReg
	xorA	#%00010000	; flip edge that the PA responds to
	staA	PACTL_PulseAccumulatorControlReg
	ldaA	InputCapture3Difference
	cmpA	#$02
	bhi	LC4DE
	inc	InputCapture3Difference
	xgDX	
	callr	LC531
LC4DE	reti	
;
;-----------------------------------------------------------------------
TOI_isr_2:
	ldaA	#$80
	staA	TFLG2register
	inc	L0169
	ldX	L00E4
	incX	
	stX	L00E4
	ei	
	reti	
;
;-----------------------------------------------------------------------
OC5I_isr_2:
	brclr	ADCtlRegister, #%10000000, OC5I_isr_2
	ldX	#ADR1Register
	ldaA	0, X
	clr	FilteredRevs
	staA	L0143
	bclr	TMSK1_TimerInterruptMask1Reg, #TMSK1_OC5
	ldaA	#$00
	staA	ADCtlRegister
	reti	
;
;-----------------------------------------------------------------------
OC4I_isr_2:
	bclr	TMSK1_TimerInterruptMask1Reg, #TMSK1_OC4
	bclr	TCTL1_TimerControlReg, #%00001100
	bclr	PORTA_DataReg, #Coil2Bit
	reti	
;
;-----------------------------------------------------------------------
OC2I_isr_2:
	bclr	TMSK1_TimerInterruptMask1Reg, #TMSK1_OC2
	bclr	TCTL1_TimerControlReg, #%11000000
	bclr	PORTA_DataReg, #Coil1Bit
	reti	
;
;-----------------------------------------------------------------------
IC3I_isr_2:
	ldaA	#TFLG1_IC3
	staA	TFLG1_TimerInterruptFlag1Reg
	ldaA	TCTL2_TimerControlReg
	xorA	#%00000011
	staA	TCTL2_TimerControlReg
	ldaA	InputCapture3Difference
	cmpA	#$02
	bhi	LC530
	inc	InputCapture3Difference
	ldD	TIC3_TimerCaptureReg
	callr	LC531
LC530	reti	
;
;-----------------------------------------------------------------------
LC531:	ldX	L015C
	stD	1, X
	ldaB	L0169
	lslA	
	bcs	LC541
	brclr	TFLG2register, #%10000000, LC541
	incB	
LC541	staB	0, X
	ldaB	#$03
	aBX	
	stX	L015C
	ret	
;
;-----------------------------------------------------------------------
IC2I_isr_2:
	ldX	TIC2_TimerCaptureReg
	bclr	TMSK1_TimerInterruptMask1Reg, #TMSK1_IC2
	pushA	
	ldaA	>DiagMode
	cmpA	#$09
	popA	
	bne	LC566
	bclr	PORTA_DataReg, #Coil1Bit
	bclr	PORTA_DataReg, #Coil2Bit
	xgDX	
	subD	L015E
	stD	L00E1
	jr	LC5A9
;
LC566	ldaA	L01B1
	cmpA	#$55
	beq	LC576
	xgDX	
	subD	L015E
	stD	L0140
	jr	LC5A9
;
LC576	xgDX	
	subD	L015E
	stD	L00E1
	call	LC349
	addD	L015E
	stD	TOC2_TimerCompareReg
	stD	TOC4_TimerCompareReg
	ldaA	L01B0
	cmpA	#$02
	beq	LC59C
	bset	TCTL1_TimerControlReg, #%10000000
	bclr	TCTL1_TimerControlReg, #%01000000
	ldaA	#TFLG1_OC2
	staA	TFLG1_TimerInterruptFlag1Reg
	bset	TMSK1_TimerInterruptMask1Reg, #TMSK1_OC2
	jr	LC5A9
;
LC59C	bset	TCTL1_TimerControlReg, #%00001000
	bclr	TCTL1_TimerControlReg, #%00000100
	ldaA	#TFLG1_OC4
	staA	TFLG1_TimerInterruptFlag1Reg
	bset	TMSK1_TimerInterruptMask1Reg, #TMSK1_OC4
LC5A9	reti	
;
;-----------------------------------------------------------------------
IC1I_isr_2:
	ldaA	#TFLG1_IC1
	staA	TFLG1_TimerInterruptFlag1Reg
	ldaA	TCTL2_TimerControlReg
	xorA	#%00110000
	staA	TCTL2_TimerControlReg
	ldaA	InputCapture3Difference
	cmpA	#$02
	bhi	LC5C3
	inc	InputCapture3Difference
	ldD	TIC1_TimerCaptureReg
	call	LC531
LC5C3	reti	
;
;-----------------------------------------------------------------------
RTII_isr_2:
	ldaA	#$40
	staA	TFLG2register
	ldaA	L0084
	beq	LC5D9
	dec	>L0084
	bne	LC5D9
	brclr	L0081, #%00000100, LC5D9
	ldaA	#$38
	staA	FirstTimeFunctionErrors
LC5D9	ei	
	call	LC281
	reti	
;
;-----------------------------------------------------------------------
XIRQ_isr_2:
	ldD	TCNT_TimerCountReg
	bset	CFORC_ForceOutputCompareReg, #%01010000
	bclr	TMSK1_TimerInterruptMask1Reg, #(TMSK1_OC2 | TMSK1_OC4)
	bclr	TCTL1_TimerControlReg, #%11001100
	bclr	PORTA_DataReg, #%01010000
	subD	L015E
	stD	FilteredRevs
	ldaA	#$CC
	staA	L0080
	reti	
;
;-----------------------------------------------------------------------
Unexpected_isr_2:
	di	
	call	LC19B
LC5FB	call	LC48F
	jr	LC5FB
;
;
	db	$50, $66, $00, $00, $00, $00
	
;-----------------------------------------------------------------------
FunctionTable2:
	db	$43
	dw	LCADE
	db	$22
	dw	LCBBC
	db	$48
	dw	LCC0E
	db	$2B
	dw	LCCB8
	db	$2C
	dw	LCD61
	db	$2D
	dw	LCDE0
	db	$28
	dw	LCE47
	db	$AF
	dw	LCE89
	db	$00
	dw	FuncThatCallsRAM
	db	$FF
;
;-----------------------------------------------------------------------
LC622:	ldaA	SpecialDiagVarA
	cmpA	#$04
	bne	LC62E
	ldX	CurrentOutputErrors
	ldaA	0, X
	cmpA	#$06
LC62E	bne	LC65E
	ldY	#L0330
	stY	Flag34
	stY	SpecialDiagVarC
	ldaA	#$05
	staA	0, Y
	incY	
	ldaA	#$0D
	staA	0, Y
	incY	
	ldaA	#$00
	staA	0, Y
	incY	
	ldaA	#$06
	staA	0, Y
	incY	
	call	LC3A2
	bset	L0081, #%00010000
	jr	LC662
;
LC65E	ldaA	#$0B
	staA	SpecialDiagVarD
LC662	ret	
;
;-----------------------------------------------------------------------
LC663:	ldaA	SpecialDiagVarA
	cmpA	#$04
	bne	LC65E
	ldX	CurrentOutputErrors
	ldaB	0, X
	cmpB	#$03
	beq	LC67D
	cmpB	#$02
	beq	LC67D
	cmpB	#$00
	bne	LC65E
	brset	L0081, #%10000000, LC65E
LC67D	staB	L016B
	ldY	#L0330
	stY	Flag34
	stY	SpecialDiagVarC
	ldaA	#$05
	staA	0, Y
	incY	
	ldaA	#$0D
	staA	0, Y
	incY	
	staB	0, Y
	incY	
	ldaA	>DiagMode
	staA	0, Y
	incY	
	call	LC3A2
	bset	L0081, #%00010000
	ret	
;
;-----------------------------------------------------------------------
LC6AC:	ldaA	SpecialDiagVarA
	cmpA	#$04
	bne	LC6DB
	ldaB	L016B
	cmpB	#$00
	beq	LC6DB
	ldX	CurrentOutputErrors
	ldaA	0, X
	staA	SpecialDiagG
	bne	LC6CB
	cmpB	#$03
	bne	LC6DB
	ldY	#FuncThatCallsRAM
	jr	LC6D1
;
LC6CB	ldX	#FunctionTable2
	call	GetFunctionPointer
LC6D1	ldaA	#$09
	staA	SpecialDiagVarD
	bset	L0081, #%10000000
	jmp	0, Y
;
LC6DB	ldaA	#$0B
	staA	SpecialDiagVarD
	ret	
;
;-----------------------------------------------------------------------
LC6E0:	ldaA	SpecialDiagVarA
	cmpA	#$04
	bne	LC6DB
	brclr	L0081, #%10000000, LC6DB
	ldX	CurrentOutputErrors
	ldaA	0, X
	cmpA	SpecialDiagG
	bne	LC6DB
	bclr	L0081, #%10000000
	ldD	#$C6F2
	ldX	L015A
	call	0, X
	ldaA	#$04
	staA	SpecialDiagVarA
	ldY	#L0330
	stY	Flag34
	stY	SpecialDiagVarC
	incY	
	ldaA	#$EE
	staA	0, Y
	incY	
	ldaA	SpecialDiagG
	staA	0, Y
	incY	
	ldX	#$0140
	ldaB	L016A
	callr	LC77C
	ldD	#$C728
	stD	X00A0
	ret	
;
LC729	cmpX	#$0400
	bcs	LC73E
	cmpX	#$07FF
	bhi	LC73E
	ReadExtraPort
	ldaA	HardwarePortInValue
	jr	LC755
;
LC73E	cmpX	#$0800
	bcs	LC753
	cmpX	#$0DFF
	bhi	LC753
	pushA	
	ldaA	ExtraPortOutShadow
	staA	HardwarePort_write
	popA	
	ldaA	ExtraPortOutShadow
	jr	LC755
;
LC753	ldaA	0, X
LC755	staA	0, Y
	incY	
	incX	
	inc	>SpecialDiagVarA
	cmpX	#L0E10
	beq	LC779
	cmpX	#L0E90
	beq	LC779
	cmpX	#DiagErrorsInEEPROM
	beq	LC779
	cmpX	#L0F30
	beq	LC779
	cmpX	#L0F90
	beq	LC779
	jr	LC77B
;
LC779	ldaB	#$01
LC77B	decB	
LC77C:	bne	LC729
	ldaA	SpecialDiagVarA
	ldY	SpecialDiagVarC
	staA	0, Y
LC786	call	LC3A2
	bset	L0081, #%00010000
	ret	
;
;-----------------------------------------------------------------------
LC78D:	ldaA	SpecialDiagVarA
	cmpA	#$06
	bne	LC7CE
	ldX	CurrentOutputErrors
	ldaA	0, X
	incX	
	ldaB	0, X
	incX	
	stD	L0158
	ldaB	0, X
	incB	
	staB	L0167
	ldY	#L01B0
	ldD	0, Y
	cmpD	#$5641
	bne	LC7C0
	incY	
	incY	
	ldD	0, Y
	cmpD	#$4C45
	bne	LC7C0
	jr	LC7C8
;
LC7C0	ldaB	L0167
	call	LCF1D
	bcs	LC7CE
LC7C8	ldaA	#$CF
	staA	X009E
	jr	LC7D1
;
LC7CE	jmp	LC65E
;
LC7D1	ldY	#$0330
	stY	Flag34
	stY	SpecialDiagVarC
	ldaA	#$03
	staA	SpecialDiagVarA
	incY	
	ldaA	X009E
	staA	0, Y
	incY	
	ldX	L0158
	ldaB	L0167
	jmp	LC77C
;
;-----------------------------------------------------------------------
LC7F1:	pushA	
	ldaA	>DiagMode
	cmpA	#$09
	popA	
	bne	LC7FD
	jmp	LC65E
;
LC7FD	ldaA	SpecialDiagVarA
	cmpA	#$20
	bhi	LC878
	cmpA	#$04
	bcs	LC878
	subA	#$03
	staA	L0167
	cmpA	#$01
	beq	LC81C
	clrB	
	ldX	CurrentOutputErrors
LC813	oraB	0, X
	incX	
	decA	
	bne	LC813
	tBA	
	jr	LC820
;
LC81C	ldX	CurrentOutputErrors
	ldaA	0, X
LC820	staA	L0156
	andA	#%00001111
	beq	LC839
	ldaA	#$10
	staA	ADCtlRegister
LC82B	brclr	ADCtlRegister, #%10000000, LC82B
	ldD	ADR1Register
	stD	L0140
	ldD	ADR3Register
	stD	FilteredRevs
LC839	ldaA	L0156
	andA	#%11110000
	beq	LC848
	ldaA	#$14
	staA	ADCtlRegister
LC844	brclr	ADCtlRegister, #%10000000, LC844
LC848	ldY	#$0330
	stY	Flag34
	stY	SpecialDiagVarC
	ldaA	L0167
	lslA	
	addA	#$03
	staA	0, Y
	incY	
	ldaA	#$CC
	staA	0, Y
	incY	
	ldaA	L0156
	ldX	#$0140
	callr	LC87B
	ldX	#$0031
	callr	LC87B
	call	LC3A2
	bset	L0081, #%00010000
	ret	
;
LC878	jmp	LC65E
;
;-----------------------------------------------------------------------
LC87B:	ldaB	#$04
LC87D	lsrA	
	bcc	LC88F
	pushB	
	clrB	
	staB	0, Y
	incY	
	ldaB	0, X
	staB	0, Y
	popB	
	incY	
LC88F	incX	
	decB	
	bne	LC87D
	ret	
;
LC894:	ldaA	SpecialDiagVarA
	cmpA	#$1A
	bhi	LC8D4
	cmpA	#$06
	bcs	LC8D4
	subA	#$05
	staA	L0167
	ldX	CurrentOutputErrors
	ldaA	0, X
	incX	
	ldaB	0, X
	incX	
	stD	L0158
	cmpX	#$003B
	beq	LC8D4
	xgDY	
	ldaB	L0167
	pushA	
	ldaA	>DiagMode
	cmpA	#$09
	popA	
	bne	LC8CB
	cmpY	#$01C0
	bne	LC8D4
	cmpB	#$01
	bne	LC8D4
LC8CB	callr	LC8D9
	tstA	
	bne	LC8D4
	ldaA	#$09
	jr	LC8D6
;
LC8D4	ldaA	#$0B
LC8D6	staA	SpecialDiagVarD
	ret	
;
;-----------------------------------------------------------------------
LC8D9:	cmpY	#$0060
	bcs	LC8E7
	cmpY	#$0061
	bhi	LC8E7
	jr	LC919
;
LC8E7	ldaA	0, X
	staA	0, Y
	cmpY	#$005F
	bhi	LC8FA
	cmpY	#$0000
	bmi	LC8FA
	jr	LC911
;
LC8FA	cmpY	#$0800
	bcs	LC90C
	cmpY	#$0DFF
	bhi	LC90C
	staA	ExtraPortOutShadow
	cmpA	ExtraPortOutShadow
	jr	LC90F
;
LC90C	cmpA	0, Y
LC90F	bne	LC919
LC911	incY	
	incX	
	decB	
	bne	LC8D9
	clrA	
	ret	
;
LC919	ldaA	#$FF
	ret	
;
;-----------------------------------------------------------------------
LC91C:	pushA	
	ldaA	>DiagMode
	cmpA	#$09
	popA	
	bne	LC92D
	tst	L0189
	beq	LC92D
	jmp	LC65E
;
LC92D	ldaA	SpecialDiagVarA
	cmpA	#$16
	bls	LC936
	jmp	LC9D9
;
LC936	cmpA	#$06
	bcc	LC93D
	jmp	LC9D9
;
LC93D	subA	#$06
	staA	X019C
	staA	L016C
	ldX	CurrentOutputErrors
	ldaA	0, X
	staA	L019D
	incX	
	cmpA	#$00
	bne	LC955
	ldaB	#$02
	jr	LC98C
;
LC955	cmpA	#$01
	bne	LC95D
	ldaB	#$16
	jr	LC98C
;
LC95D	cmpA	#$03
	bne	LC965
	ldaB	#$0E
	jr	LC98C
;
LC965	cmpA	#$02
	bne	LC9D9
	ldaB	L0FCF
	cmpB	#$AA
	bne	LC98A
	ldY	#L01B0
	ldD	0, Y
	cmpD	#$5641
	bne	LC9D9
	incY	
	incY	
	ldD	0, Y
	cmpD	#$4C45
	bne	LC9D9
LC98A	ldaB	#$06
LC98C	staB	X009E
	ldaA	0, X
	incX	
	ldaB	0, X
	incX	
	stX	CurrentOutputErrors
	stD	L0158
	ldaB	X019C
	call	LCF1D
	bcc	LC9A4
	jmp	LC7CE
;
LC9A4	callr	LC9DC
	tst	>SpecialDiagVarD
	bne	LC9D8
	ldD	L0158
	stD	L018A
	stD	L0164
	ldaA	L019D
	cmpA	#$02
	beq	LC9CB
	cmpA	#$03
	beq	LC9CB
	ldX	CurrentOutputErrors
	ldY	#$018C
	ldaB	X019C
	call	LC8D9
LC9CB	ldaA	X009E
	staA	L0189
	ldD	#$C9FF
	stD	X00A0
	bset	L0081, #%10000000
LC9D8	ret	
;
LC9D9	jmp	LC65E
;
LC9DC:	ldaA	L0FCF
	cmpA	#$AA
	bne	LC9F8
	clrA	
	ldaB	X019C
	addD	L0158
	cmpD	#$0FC0
	bcs	LC9F8
	cmpD	#$0FCF
	bhi	LC9F8
	jr	LC9D9
;
LC9F8	ldX	#$1000
	stX	L0162
	ret	
;
;-----------------------------------------------------------------------
LC9FF:	ldaA	L0189
	bne	LCA66
	ldD	#$C728
	stD	X00A0
	bclr	L0081, #%10000000
	ldaA	L019D
	cmpA	#$02
	bne	LCA24
	ldX	#StartEEPROM
	ldaA	#$FF
LCA18	cmpA	0, X
	bne	LCA62
	incX	
	cmpX	L0162
	bne	LCA18
	jr	LCA5E
;
LCA24	cmpA	#$03
	bne	LCA45
	ldY	L018A
	ldaB	#$10
	aBY	
	stY	L0185
	ldX	L018A
	ldaA	#$FF
LCA39	cmpA	0, X
	bne	LCA62
	incX	
	cmpX	L0185
	bne	LCA39
	jr	LCA5E
;
LCA45	ldX	L0164
	ldY	#$018C
	ldaB	L016C
	beq	LCA62
LCA51	ldaA	0, X
	cmpA	0, Y
	bne	LCA62
	incX	
	incY	
	decB	
	bne	LCA51
LCA5E	ldaA	#$09
	jr	LCA64
;
LCA62	ldaA	#$0B
LCA64	staA	SpecialDiagVarD
LCA66	ret	
;
;-----------------------------------------------------------------------
LCA67:	ldaA	SpecialDiagVarA
	cmpA	#$04
	bne	LCAD9
	ldX	CurrentOutputErrors
	ldaA	0, X
	cmpA	#$01
	bne	LCAD9
	ldaA	L0FCF
	cmpA	#$AA
	beq	LCA98
	ldX	#LFFA4_SpecialDiagTable1
	stX	L0158
	ldY	#L0FC0
	ldaB	#$06
	staB	L0167
LCA8B	ldaA	0, X
	cmpA	0, Y
	bne	LCAAC
	incX	
	incY	
	decB	
	bne	LCA8B
LCA98	ldaA	#$10
	staA	L0167
	ldY	#$0FC0
	stY	L0158
	ldaA	#$AE
	staA	X009E
	jmp	LC7D1
;
LCAAC	ldY	#$0330
	stY	Flag34
	stY	SpecialDiagVarC
	ldaA	#$03
	addA	#$10
	staA	0, Y
	incY	
	ldaA	#$AE
	staA	0, Y
	incY	
	ldX	L0158
	ldaB	#$06
	call	MemCopy_XtoY_2
	ldX	#L0FC6
	ldaB	#$0A
	call	MemCopy_XtoY_2
	jmp	LC786
;
LCAD9	ldaA	#$0B
	staA	SpecialDiagVarD
	ret	
;
;-----------------------------------------------------------------------
LCADE:	pushA	
	ldaA	>DiagMode
	cmpA	#$09
	popA	
	bne	LCAEA
	jmp	LC65E
;
LCAEA	ldaA	L01B0
	call	LCBB1
	tstB	
	bne	LCAF6
	jmp	LCBA8
;
LCAF6	staB	L0187
	ldaA	L01B1
	cmpA	#$00
	beq	LCB0B
	cmpA	#$FF
	beq	LCB07
	jmp	LCBA8
;
LCB07	ldaA	#$01
	jr	LCB0D
;
LCB0B	ldaA	#$02
LCB0D	cmpB	#$80
	beq	LCB31
	lsrB	
	beq	LCB1B
	lslA	
	lslA	
	bne	LCB0D
	jmp	LCBA8
;
LCB1B	staA	L0188
	staA	TCTL2_TimerControlReg
	ldaA	L0187
	cmpA	#$08
	bne	LCB2B
	brclr	PACTL_PulseAccumulatorControlReg, #%00000100, LCBA8
LCB2B	staA	TFLG1_TimerInterruptFlag1Reg
	staA	TMSK1_TimerInterruptMask1Reg
	jr	LCB4A
;
LCB31	ldaA	L01B1
	cmpA	#$00
	beq	LCB3D
	bset	PACTL_PulseAccumulatorControlReg, #%00010000
	jr	LCB40
;
LCB3D	bclr	PACTL_PulseAccumulatorControlReg, #%00010000
LCB40	bclr	PACTL_PulseAccumulatorControlReg, #%00100000
	ldaA	#$10
	staA	TFLG2register
	bset	TMSK2register, #%00010000
LCB4A	clr	InputCapture3Difference
	ldD	#$016D
	stD	L015C
	ldaA	#$80
	staA	TFLG2register
	bset	TMSK2register, #%10000000
	ldaA	#$02
	staA	L016A
	ldX	#$CB74
	stX	L015A
	ldX	#$C728
	stX	X00A0
	ldX	#$0140
LCB6D	clr	0, X
	incX	
	decA	
	bne	LCB6D
LCB73	ret	
;
;-----------------------------------------------------------------------
LCB74:	ldaA	L0187
	cmpA	#$80
	bne	LCB7E
	bclr	TMSK2register, #%00010000
LCB7E	comA	
	andA	TMSK1_TimerInterruptMask1Reg
	staA	TMSK1_TimerInterruptMask1Reg
	bclr	TMSK2register, #%10000000
	ldaA	InputCapture3Difference
	cmpA	#$02
	bne	LCB73
	ldX	#L016D
	ldY	#L0140
	ldaA	3, X
	sec	
	sbcA	0, X
	bhi	LCBA3
	ldD	4, X
	subD	1, X
	lslD	
	stD	0, Y
LCBA3	incY	
	incY	
	ret	
;
LCBA8	bclr	L0081, #%10000000
	ldD	#$C728
	stD	X00A0
	ret	
;
LCBB1:	ldaB	#$01
LCBB3	decA	
	beq	LCBB9
	lslB	
	bne	LCBB3
LCBB9	andB	#%10000101
	ret	
;
LCBBC:	pushA	
	ldaA	>DiagMode
	cmpA	#$09
	popA	
	bne	LCBC8
	jmp	LC65E
;
LCBC8	ldaA	L01B0
	andA	#%00001111
	beq	LCBD5
	callr	LCC03
	oraB	#%00100000
	jr	LCBE0
;
LCBD5	ldaA	L01B0
	lsrA	
	lsrA	
	lsrA	
	lsrA	
	callr	LCC03
	oraB	#%00100100
LCBE0	staB	ADCtlRegister
	ldaA	#$04
	staA	L016A
	clrA	
	clrB	
	stD	L0140
	stD	FilteredRevs
LCBEF	brclr	ADCtlRegister, #%10000000, LCBEF
	ldX	#$CC7C
	stX	X00A0
	ldD	#$CBFF
	stD	L015A
	ret	
;
;
	db	$15, $22, $08, $39
;
;-----------------------------------------------------------------------
LCC03:	clrB	
LCC04	lsrA	
	bcs	LCC0A
	incB	
	jr	LCC04
;
LCC0A	staB	L0156
	ret	
;
LCC0E:	pushA	
	ldaA	>DiagMode
	cmpA	#$09
	popA	
	bne	LCC1A
	jmp	LC65E
;
LCC1A	ldaA	L01B0
	beq	LCC5A
	andA	#%00001111
	beq	LCC27
	callr	LCC03
	jr	LCC32
;
LCC27	ldaA	L01B0
	lsrA	
	lsrA	
	lsrA	
	lsrA	
	callr	LCC03
	oraB	#%00000100
LCC32	staB	ADCtlRegister
	ldY	#$CC42
	stY	L015A
	ldD	#$C728
	stD	X00A0
	ret	
;
;-----------------------------------------------------------------------
LCC42:	brclr	ADCtlRegister, #%10000000, LCC42
	ldY	#$0031
	ldaA	L01B0
	cmpA	#$40
	beq	LCC5E
	cmpA	#$02
	bne	LCC5A
	ldX	#$0E02
	jr	LCC61
;
LCC5A	bclr	L0081, #%10000000
	ret	
;
LCC5E	ldX	#StartEEPROM
LCC61	ldaA	#$80
	andA	ADCtlRegister
	beq	LCC70
	ldaA	0, Y
	ldaB	0, X
	incX	
	call	LC330
LCC70	clr	L0140
	staA	WaterTempValue
	ldaA	#$02
	staA	L016A
	ret	
;
LCC7C:	ldaB	#$04
	ldaA	L01B2
	ldX	#ADR1Register
LCC84	cmpA	0, X
	bls	LCC92
	incX	
	decB	
	bne	LCC84
	ldX	#$CC7C
	stX	X00A0
	ret	
;
LCC92	ldaA	0, X
	staA	WaterTempValue
	ldX	#$C728
	stX	X00A0
	di	
	ldaA	L01B4
	clrB	
	lsrD	
	lsrD	
	addD	TCNT_TimerCountReg
	addD	#$0001
	stD	TOC5_TimerCompareReg
	ldaA	#TFLG1_OC5
	staA	TFLG1_TimerInterruptFlag1Reg
	ldD	#$C728
	stD	X00A0
	bset	TMSK1_TimerInterruptMask1Reg, #TMSK1_OC5
	ei	
	ret	
;
;-----------------------------------------------------------------------
LCCB8:	pushA	
	ldaA	>DiagMode
	cmpA	#$09
	popA	
	bne	LCCC4
	jmp	LC65E
;
LCCC4	ldD	#$C728
	stD	X00A0
	ldD	#$CD54
	stD	L015A
	ldaA	L01B1
	cmpA	#$AA
	beq	LCCEE
	cmpA	#$55
	beq	LCCDD
	jmp	LCD5D
;
LCCDD	clr	L0151
	ldaA	L0E07
	staA	L0153
	bclr	TMSK2register, #%10000000
	clr	L016A
	jr	LCD01
;
LCCEE	clrA	
	clrB	
	stD	L0140
	stD	FilteredRevs
	ldaA	#$04
	staA	L016A
	bclr	TCTL2_TimerControlReg, #%00001000
	bset	TCTL2_TimerControlReg, #%00000100
LCD01	ldaA	L01B0
	cmpA	#$02
	bne	LCD27
	di	
	ldaA	#TFLG1_OC4
	staA	TFLG1_TimerInterruptFlag1Reg
	ldD	TCNT_TimerCountReg
	addD	#$2710
	stD	TOC4_TimerCompareReg
	bset	TMSK1_TimerInterruptMask1Reg, #TMSK1_OC4
	bset	PORTA_DataReg, #Coil2Bit
	ldD	TCNT_TimerCountReg
	subD	#$0001
	bset	TCTL1_TimerControlReg, #%00001000
	bclr	TCTL1_TimerControlReg, #%00000100
	jr	LCD48
;
LCD27	cmpA	#$01
	bne	LCD5D
	di	
	ldaA	#TFLG1_OC2
	staA	TFLG1_TimerInterruptFlag1Reg
	ldD	TCNT_TimerCountReg
	addD	#$2710
	stD	TOC2_TimerCompareReg
	bset	TMSK1_TimerInterruptMask1Reg, #TMSK1_OC2
	bset	PORTA_DataReg, #Coil1Bit
	ldD	TCNT_TimerCountReg
	subD	#$0001
	bset	TCTL1_TimerControlReg, #%10000000
	bclr	TCTL1_TimerControlReg, #%01000000
LCD48	stD	L015E
	ldaA	#TFLG1_IC2
	staA	TFLG1_TimerInterruptFlag1Reg
	bset	TMSK1_TimerInterruptMask1Reg, #TMSK1_IC2
	ei	
	ret	
;
;-----------------------------------------------------------------------
LCD54:	bclr	TCTL1_TimerControlReg, #%10001000
	bclr	TMSK1_TimerInterruptMask1Reg, #TMSK1_IC2
	bclr	PORTA_DataReg, #%01010000
LCD5D	bclr	L0081, #%10000000
	ret	
;
;-----------------------------------------------------------------------
LCD61:	pushA	
	ldaA	>DiagMode
	cmpA	#$09
	popA	
	bne	LCD79
	bset	X00E3, #%00000100
	ldD	#$CD79
	stD	X00A0
	ldD	#$CDBC
	stD	L015A
	ret	
;
LCD79	clrA	
	clrB	
	stD	L037E
	ldD	#$8000
	stD	L0154
	ldD	#$CD90
	stD	X00A0
	ldD	#$CDBC
	stD	L015A
	ret	
;
;-----------------------------------------------------------------------
LCD90:	ldD	L0154
	cmpD	#$FE00
	bne	LCDA0
	ldY	#$C728
	stY	X00A0
LCDA0	xgDX	
	ldY	#$0200
	ldD	L037E
	callr	LCDB1
	stD	L037E
	stX	L0154
	ret	
;
;-----------------------------------------------------------------------
LCDB1:	addD	0, X
	incX	
	incX	
	decY	
	decY	
	bne	LCDB1
	ret	
;
;-----------------------------------------------------------------------
LCDBC:	ldaA	#$FF
	ldX	L037E
	stX	RomChecksum
	cmpX	RomChecksum
	beq	LCDCB
	ldaA	#$00
LCDCB	staA	L0140
	ldaA	#$01
	staA	L016A
	pushA	
	ldaA	>DiagMode
	cmpA	#$09
	popA	
	bne	LCDDF
	bclr	X00E3, #%00000100
LCDDF	ret	
;
;-----------------------------------------------------------------------
LCDE0:	pushA	
	ldaA	>DiagMode
	cmpA	#$09
	popA	
	bne	LCDF8
	bset	X00E3, #%00000100
	ldD	#$CDF8
	stD	X00A0
	ldD	#$CE30
	stD	L015A
	ret	
;
LCDF8	ldD	#$C728
	stD	X00A0
	ldX	#HardwarePortInValue
LCE00	ldaB	0, X
	ldaA	#$55
	di	
	staA	0, X
	cmpA	0, X
	ei	
	bne	LCE23
	comA	
	di	
	staA	0, X
	cmpA	0, X
	ei	
	bne	LCE23
	staB	0, X
	incX	
	cmpX	#$0400
	bne	LCE00
	ldaA	#$FF
	staA	L009C
	jr	LCE29
;
LCE23	staB	0, X
	ldaA	#$00
	staA	L009C
LCE29	ldD	#$CE30
	stD	L015A
	ret	
;
;-----------------------------------------------------------------------
LCE30:	ldaA	L009C
	staA	L0140
	ldaA	#$01
	staA	L016A
	pushA	
	ldaA	>DiagMode
	cmpA	#$09
	popA	
	bne	LCE46
	bclr	X00E3, #%00000100
LCE46	ret	
;
;-----------------------------------------------------------------------
LCE47:	pushA	
	ldaA	>DiagMode
	cmpA	#$09
	popA	
	bne	LCE53
	jmp	LC65E
;
LCE53	ldD	#$FFFF
	stD	L0140
	clrA	
	staA	L0169
	staA	InputCapture3Difference
	ldaA	#$80
	staA	TFLG2register
	bset	TMSK2register, #%10000000
	di	
	ldD	TCNT_TimerCountReg
	stD	L0160
	bset	ExtraPortOutShadow, #%10000000
	ei	
	ldD	#$C728
	stD	X00A0
	ldD	#$CE7D
	stD	L015A
	ret	
;
;-----------------------------------------------------------------------
LCE7D:	bclr	TMSK2register, #%10000000
	bclr	ExtraPortOutShadow, #%10000000
	ldaA	#$02
	staA	L016A
	ret	
;
;-----------------------------------------------------------------------
LCE89:	pushA	
	ldaA	>DiagMode
	cmpA	#$09
	popA	
	bne	LCE94
	jr	LCF10
;
LCE94	ldD	#$CED5
	stD	X00A0
	clrB	
	ldaA	L01B0
	cmpA	#$55
	beq	LCEAF
	cmpA	#$AA
	beq	LCEB0
	ldD	#$C728
	stD	X00A0
	bclr	L0081, #%10000000
	jr	LCF05
;
LCEAF	comB	
LCEB0	pushB	
	ldX	#L018C
	pushX	
	ldaB	#$10
	staB	X019C
	ldaA	#$FF
LCEBC	staA	0, X
	incX	
	decB	
	bne	LCEBC
	popX	
	popB	
	staB	6, X
	clr	7, X
	ldX	#L0F20
	stX	L018A
	ldaA	#$16
	staA	L0189
	jr	LCF05
;
LCED5:	ldaA	L0189
	bne	LCF05
	ldD	#$C728
	stD	X00A0
	ldX	#L018C
	ldY	#L0F20
	ldaB	#$10
LCEE8	ldaA	0, Y
	cmpA	0, X
	bne	LCEFB
	incX	
	incY	
	decB	
	bne	LCEE8
	ldaA	#$FF
	staA	Flag01
	jr	LCEFF
;
LCEFB	ldaA	#$00
	staA	Flag01
LCEFF	ldD	#$CF06
	stD	L015A
LCF05	ret	
;
;-----------------------------------------------------------------------
LCF06:	ldaA	Flag01
	staA	L0140
	ldaA	#$01
	staA	L016A
LCF10	ret	
;
;
;-----------------------------------------------------------------------
FuncThatCallsRAM:
	ldD	#$C728
	stD	L015A
	stD	X00A0
	call	X0200
	ret	
;
;-----------------------------------------------------------------------
LCF1D:	jr	LCF69
;
;-----------------------------------------------------------------------
LCF1F:	clrA	
	tstB	
	beq	LCF24
	decB	
LCF24	addD	L0158
	cmpD	#L0E10
	bcs	LCF69
	cmpD	#L0E80
	bcs	LCF6B
	cmpD	#L0E90
	bcs	LCF69
	cmpD	#L0F00
	bcs	LCF6B
	cmpD	#DiagErrorsInEEPROM
	bcs	LCF69
	cmpD	#DiagErrorsInEEPROM
	bcs	LCF6B
	cmpD	#L0F20
	bcs	LCF69
	cmpD	#L0F40
	bcs	LCF6B
	cmpD	#L0F50
	bcs	LCF69
	cmpD	#L0FC0
	bcs	LCF6B
	cmpD	#L0FD0
	bcs	LCF69
LCF69	clc	
	ret	
;
LCF6B	sec	
	ret	
;
;
;-----------------------------------------------------------------------
	db	$50, $66, $00, $00, $00, $00
;-----------------------------------------------------------------------
Vec6Table:
	dw	Vec6Entry_00, Vec6Entry_01, Vec6Entry_02, Vec6Entry_03
	dw	Vec6Entry_04, Vec6Entry_05, Vec6Entry_06, Vec6Entry_07
	dw	Vec6Entry_08, Vec6Entry_09, Vec6Entry_10, Vec6Entry_11
	dw	Vec6Entry_12, Vec6Entry_13, Vec6Entry_14, Vec6Entry_15

LCF93:
	dw	$9E40, $F415
;
;-----------------------------------------------------------------------
LCF97:	bset	TCTL2_TimerControlReg, #%00000100
	bclr	TCTL2_TimerControlReg, #%00001000
	ldaA	ExtraPortOutShadow
	andA	#%11111011
	staA	ExtraPortOutShadow
	pushA	
	ldaA	ExtraPortOutShadow
	staA	HardwarePort_write
	popA	
	ldaA	L0E07
	staA	InputCapture2_SubValue
	ldaA	L0E09
	staA	L00E8
	bclr	PIOC_ParallelIOcontrolReg, #%00001000
	idiv	
	idiv	
	bset	PIOC_ParallelIOcontrolReg, #%00001000
	ldaA	#$1F
	ldX	#$00FD
LCFC1	staA	0, X
	incX	
	cmpX	#$011D
	bne	LCFC1
	clrA	
	clrB	
	stD	L00E4
	stD	L00E0
	stD	X00E3
	stD	L00E9
	stD	L00EB
	ldaA	L0F42
	cmpA	#$AA
	beq	LCFF5
	clrA	
	clrB	
	stD	L00ED
	stD	L00F1
	stD	SparkAdvance
	stD	O2_Var2
	stD	L00F7
	stD	CurrentRevs
	ldaA	#$AA
	ldaB	#$C9
	stD	InputCapture2_StoredValue
	call	LD333
	jr	LD001
;
LCFF5	ldX	#L0F40
	ldY	#$00ED
	ldaB	#$10
	call	MemCopy_XtoY_2
LD001	ldaA	#$80
	staA	TFLG2register
	bset	TMSK2register, #%10000000
	ldD	#$001E
	call	LD3F3
	ret	
;
;-----------------------------------------------------------------------
LD00F:	call	LC48F
	ldaA	L0189
	bne	LD057
	brset	X00E3, #%00000001, LD057
	ldD	L00E4
	cmpD	#$08F2
	bcs	LD039
	ldaA	L00EE
	addA	#$05
	staA	L00EE
	cmpA	#$3C
	bne	LD033
	inc	>L00ED
	clrA	
	staA	L00EE
LD033	clrA	
	clrB	
	stD	L00E4
	jr	LD03D
;
LD039	brclr	X00E3, #%00000010, LD057
LD03D	ldD	L00E9
	oraA	L0F44
	oraB	L0F45
	stD	L00F1
	ldD	L00EB
	oraA	L0F46
	oraB	L0F47
	stD	SparkAdvance
	call	LD333
	bclr	X00E3, #%00000010
LD057	brset	TFLG1_TimerInterruptFlag1Reg, #%00100000, LD05C
	ret	
;
LD05C	ldD	#$01F4
	call	LD3F7
	call	LC48F
	ldX	#Vec6Table
	ldaB	L00E0
	lslB	
	aBX	
	ldX	0, X
	call	0, X
	inc	>L00E0
	ldaB	L00E0
	cmpB	#$10
	bne	LD07C
	clr	>L00E0
LD07C	ret	
;
;-----------------------------------------------------------------------
Vec6Entry_00:
	ldaB	#$1F
	ldaA	ADR4Register
	cmpA	#$FF
	bcc	LD08C
	cmpA	#$FC
	bcs	LD08C
	staB	CurrentRevs_b
LD08C	ldaA	ADR1Register
	cmpA	#$33
	bcc	LD099
	cmpA	#$0E
	bcs	LD099
	staB	Revs_c
LD099	bset	TCTL2_TimerControlReg, #%00000001
	ldaA	#TFLG1_IC3
	staA	TFLG1_TimerInterruptFlag1Reg
	ldaA	#$10
	staA	ADCtlRegister
	ldaA	ExtraPortOutShadow
	oraA	#%10100000
	andA	#%10111111
	staA	ExtraPortOutShadow
	ldaA	ExtraPortOutShadow
	oraA	#%00010000
	staA	ExtraPortOutShadow
	pushA	
	ldaA	ExtraPortOutShadow
	staA	HardwarePort_write
	popA	
	bclr	PIOC_ParallelIOcontrolReg, #%00001000
	idiv	
	idiv	
	bset	PIOC_ParallelIOcontrolReg, #%00001000
	ret	
;
;-----------------------------------------------------------------------
Vec6Entry_01:
	ReadExtraPort
	ldaA	HardwarePortInValue
	ldX	#$0112
	bitA	#%10000000
	call	LD37E
	ldaB	#$1F
	ldaA	ADR4Register
	cmpA	#$93
	bcc	LD0E2
	cmpA	#$6A
	bcs	LD0E2
	staB	L0100
LD0E2	ldaA	ADR3Register
	cmpA	#$FF
	bcc	LD0F1
	cmpA	#$FC
	bcs	LD0F1
	staB	Scratch5_lsB
	staB	L0117
LD0F1	ldaA	ADR2Register
	cmpA	#$FF
	bcc	LD0FD
	cmpA	#$91
	bcs	LD0FD
	staB	Scratch5
LD0FD	ldaA	ExtraPortOutShadow
	oraA	#%00000001
	staA	ExtraPortOutShadow
	pushA	
	ldaA	ExtraPortOutShadow
	staA	HardwarePort_write
	popA	
	ldaA	ExtraPortOutShadow
	oraA	#%00000100
	staA	ExtraPortOutShadow
	pushA	
	ldaA	ExtraPortOutShadow
	staA	HardwarePort_write
	popA	
	ret	
;
;-----------------------------------------------------------------------
Vec6Entry_02:
	ReadExtraPort
	ldaA	HardwarePortInValue
	ldX	#$0119
	bitA	#%00001000
	call	LD37E
	ldaA	HardwarePortInValue
	ldX	#$0113
	bitA	#%00000001
	call	LD37E
	ldaA	TFLG1_TimerInterruptFlag1Reg
	ldX	#$010B
	xorA	#%00000001
	bitA	#%00000001
	call	LD37E
	bset	TCTL2_TimerControlReg, #%00000010
	ldaA	#TFLG1_IC3
	staA	TFLG1_TimerInterruptFlag1Reg
	ret	
;
;-----------------------------------------------------------------------
Vec6Entry_03:
	ldaA	ExtraPortOutShadow
	andA	#%11111110
	staA	ExtraPortOutShadow
	pushA	
	ldaA	ExtraPortOutShadow
	staA	HardwarePort_write
	popA	
	ret	
;
;-----------------------------------------------------------------------
Vec6Entry_04:
	ldaA	TFLG1_TimerInterruptFlag1Reg
	ldX	#$010B
	xorA	#%00000001
	bitA	#%00000001
	call	LD37E
	ReadExtraPort
	ldaA	HardwarePortInValue
	ldX	#$0119
	bitA	#%00001000
	call	LD391
	ldaA	ExtraPortOutShadow
	oraA	#%00001000
	staA	ExtraPortOutShadow
	pushA	
	ldaA	ExtraPortOutShadow
	staA	HardwarePort_write
	popA	
	bset	PORTA_DataReg, #HorizInjectorBit
	ret	
;
;-----------------------------------------------------------------------
Vec6Entry_05:
	ReadExtraPort
	ldaA	HardwarePortInValue
	ldX	#$010F
	bitA	#%00001000
	call	LD37E
	ldaA	#TFLG1_IC2
	staA	TFLG1_TimerInterruptFlag1Reg
	bset	TMSK1_TimerInterruptMask1Reg, #TMSK1_IC2
	bset	PORTA_DataReg, #Coil1Bit
	ldD	TCNT_TimerCountReg
	stD	L015E
	ret	
;
;-----------------------------------------------------------------------
Vec6Entry_06:
	ReadExtraPort
	ldaA	HardwarePortInValue
	ldX	#$0114
	bitA	#%01000000
	call	LD37E
	ldaA	ExtraPortOutShadow
	andA	#%11110111
	staA	ExtraPortOutShadow
	pushA	
	ldaA	ExtraPortOutShadow
	staA	HardwarePort_write
	popA	
	ret	
;
;-----------------------------------------------------------------------
Vec6Entry_07:
	ReadExtraPort
	ldaA	HardwarePortInValue
	ldX	#$010F
	bitA	#%00001000
	call	LD391
	ldX	#$0115
	ldD	L00E1
	cmpD	#$0032
	bcc	LD1E3
	ldaA	#$FF
	jr	LD1EC
;
LD1E3	brclr	PORTA_DataReg, #Coil1Bit, LD1EB
	ldaA	#$FF
	jr	LD1EC
;
LD1EB	clrA	
LD1EC	call	LD37E
	ldD	#$0000
	stD	L00E1
	bset	PORTA_DataReg, #VertInjectorBit
	bclr	PORTA_DataReg, #Coil1Bit
	ldaA	#$14
	staA	ADCtlRegister
	ret	
;
;-----------------------------------------------------------------------
Vec6Entry_08:
	ldaB	#$1F
	ldaA	ADR4Register
	cmpA	#$33
	bcc	LD20E
	cmpA	#$0E
	bcs	LD20E
	staB	CurrentRevs_b
LD20E	ldaA	ADR1Register
	cmpA	#$FF
	bcc	LD21B
	cmpA	#$FC
	bcs	LD21B
	staB	Revs_c
LD21B	ldaA	#$10
	staA	ADCtlRegister
	ldaA	ExtraPortOutShadow
	andA	#%11011111
	oraA	#%01000000
	staA	ExtraPortOutShadow
	pushA	
	ldaA	ExtraPortOutShadow
	staA	HardwarePort_write
	popA	
	bclr	PIOC_ParallelIOcontrolReg, #%00001000
	idiv	
	idiv	
	bset	PIOC_ParallelIOcontrolReg, #%00001000
	ret	
;
;-----------------------------------------------------------------------
Vec6Entry_09:
	ReadExtraPort
	ldaA	HardwarePortInValue
	ldX	#$0111
	bitA	#%00010000
	call	LD37E
	ldaB	#$1F
	ldaA	ADR4Register
	cmpA	#$93
	bcc	LD257
	cmpA	#$6A
	bcs	LD257
	staB	L0100
LD257	ldaA	ADR3Register
	cmpA	#$B8
	bcc	LD266
	cmpA	#$14
	bcs	LD266
	staB	Scratch5_lsB
	staB	L0117
LD266	ldaA	ADR2Register
	cmpA	#$FF
	bcc	LD272
	cmpA	#$91
	bcs	LD272
	staB	Scratch5
LD272	ldaA	ExtraPortOutShadow
	andA	#%11111011
	staA	ExtraPortOutShadow
	pushA	
	ldaA	ExtraPortOutShadow
	staA	HardwarePort_write
	popA	
	ret	
;
;-----------------------------------------------------------------------
Vec6Entry_10:
	ReadExtraPort
	ldaA	HardwarePortInValue
	ldX	#$0113
	xorA	#%00000001
	bitA	#%00000001
	call	LD391
	ret	
;
;-----------------------------------------------------------------------
Vec6Entry_11:
	ret	
;
;-----------------------------------------------------------------------
Vec6Entry_12:
	bclr	PORTA_DataReg, #HorizInjectorBit
	ret	
;
;-----------------------------------------------------------------------
Vec6Entry_13:
	ldaA	ExtraPortOutShadow
	andA	#%11101111
	staA	ExtraPortOutShadow
	pushA	
LD2A0:	ldaA	ExtraPortOutShadow
	staA	HardwarePort_write
	popA	
	ldaA	#TFLG1_IC2
	staA	TFLG1_TimerInterruptFlag1Reg
	bset	TMSK1_TimerInterruptMask1Reg, #TMSK1_IC2
	bset	PORTA_DataReg, #Coil2Bit
	ldD	TCNT_TimerCountReg
	stD	L015E
	ret	
;
;-----------------------------------------------------------------------
Vec6Entry_14:
	ReadExtraPort
	ldaA	HardwarePortInValue
	ldX	#$0114
	bitA	#%01000000
	call	LD391
	ldaA	HardwarePortInValue
	ldX	#$0112
	bitA	#%10000000
	call	LD391
	bclr	PORTA_DataReg, #VertInjectorBit
	ret	
;
;-----------------------------------------------------------------------
Vec6Entry_15:
	ldX	#$01C0
	ldaA	0, X
	cmpA	#$55
	bne	LD2E4
	ldD	#$3A98
	call	LD3F3
LD2E4	ReadExtraPort
	ldaA	HardwarePortInValue
	ldX	#$0111
	bitA	#%00010000
	call	LD391
	ldX	#$0115
	ldD	L00E1
	cmpD	#$0032
	bcc	LD303
	clrA	
	jr	LD30C
;
LD303	brclr	PORTA_DataReg, #Coil2Bit, LD30A
	clrA	
	jr	LD30C
;
LD30A	ldaA	#$FF
LD30C	call	LD391
	ldD	#$0000
	stD	L00E1
	bclr	PORTA_DataReg, #Coil2Bit
	ldaA	#$14
	staA	ADCtlRegister
	call	LD3A4
	brclr	X00E3, #%00000100, LD332
	ldaA	ExtraPortOutShadow
	andA	#%01111111
	staA	ExtraPortOutShadow
	pushA	
	ldaA	ExtraPortOutShadow
	staA	HardwarePort_write
	popA	
	bset	X00E3, #%00001000
LD332	ret	
;
;-----------------------------------------------------------------------
LD333:	ldY	#$00ED
	call	LD35D
	stD	L00FB
	ldX	#$00ED
	ldY	#$018C
	ldaB	#$10
	staB	X019C
	call	MemCopy_XtoY_2
	ldX	#L0F40
	stX	L018A
	ldaA	#$16
	staA	L0189
	ret	
;
;
; Unreferenced ?
LD357:	ldaB	#$C8
LD359	decB	
	bne	LD359
	ret	
;
;-----------------------------------------------------------------------
LD35D:	ldaB	#$07
	staB	L00E6
	ldD	#$0000
	stD	L00FB
LD366	ldD	0, Y
	addD	L00FB
	stD	L00FB
	incY	
	incY	
	dec	>L00E6
	bne	LD366
	ldD	#$55AA
	subD	L00FB
	stD	L00FB
	ret	
;
;-----------------------------------------------------------------------
LD37E:	beq	LD388
	ldaB	0, X
	andB	#%01111111
	staB	0, X
	jr	LD390
;
LD388	tst	0, X
	bmi	LD390
	ldaB	#$1F
	staB	0, X
LD390	ret	
;
;-----------------------------------------------------------------------
LD391:	bne	LD39B
	ldaB	0, X
	oraB	#%10000000
	staB	0, X
	jr	LD3A3
;
LD39B	tst	0, X
	bpl	LD3A3
	ldaB	#$1F
	staB	0, X
LD3A3	ret	
;
;-----------------------------------------------------------------------
LD3A4:	ldaB	#$01
	ldY	#$00E9
	ldX	#L00FD
LD3AD	ldaA	0, X
	andA	#%01111111
	bne	LD3E3
	tBA	
	pushX	
	pushY	
	xgDY	
	subD	#$00E9
	ldX	#LCF93
	aBX	
	xgDY	
	popY	
	andA	0, X
	popX	
	beq	LD3E1
	andA	0, Y
	bne	LD3E1
	tBA	
	oraA	0, Y
	staA	0, Y
	pushX	
	ldX	L00ED
	cmpX	#$0005
	popX	
	bcs	LD3E1
	bset	X00E3, #%00000010
LD3E1	jr	LD3E5
;
LD3E3	dec	0, X
LD3E5	lslB	
	bcc	LD3EC
	incY	
	ldaB	#$01
LD3EC	incX	
	cmpX	#$011D
	bne	LD3AD
	ret	
;
;-----------------------------------------------------------------------
LD3F3:	addD	TCNT_TimerCountReg
	jr	LD3F9
;
;-----------------------------------------------------------------------
LD3F7:	addD	TOC3_TimerCompareReg
LD3F9	stD	TOC3_TimerCompareReg
	ldaB	#TFLG1_OC3
	staB	TFLG1_TimerInterruptFlag1Reg
	ret	
;
;-----------------------------------------------------------------------
LD400:	ldaA	SpecialDiagVarA
	cmpA	#$03
	bne	LD447
	ldY	#$0330
	stY	Flag34
	stY	SpecialDiagVarC
	ldaA	#$04
	staA	SpecialDiagVarA
	incY	
	ldaA	#$AF
	staA	0, Y
	incY	
	ldaA	#$C9
	staA	0, Y
	incY	
	ldX	#$00E9
	ldaB	#$04
LD429	ldaA	0, X
	staA	0, Y
	incY	
	incX	
	inc	>SpecialDiagVarA
	decB	
	bne	LD429
	ldaA	SpecialDiagVarA
	ldY	#$0330
	staA	0, Y
	call	LC3A2
	bset	L0081, #%00010000
	ret	
;
;-----------------------------------------------------------------------
LD447	ldaA	#$0B
	staA	SpecialDiagVarD
	ret	
;
;-----------------------------------------------------------------------
LD44C:	ldaA	SpecialDiagVarA
	cmpA	#$03
	bne	LD447
	ldD	#$0000
	stD	L00E9
	stD	L00EB
	ldaA	#$09
	staA	SpecialDiagVarD
	ret	
;
;-----------------------------------------------------------------------
LD45E:	ldaA	SpecialDiagVarA
	cmpA	#$03
	bne	LD447
	clr	>SCCR2_SerialControlReg
	bset	X00E3, #%00000001
	ret	

;-------------------------------------------------------------------
; End of Special Diag code
;-------------------------------------------------------------------
;


;-----------------------------------------------------------------------
IsrJumpTable1:
	jmp	SCI_isr
	jmp	Unexpected_isr
	jmp	Unexpected_isr
	jmp	PulseAccumulatorOverflow_isr
	jmp	TimerOverflow_isr
	jmp	OutputCompare5_isr
	jmp	OutputCompare4_isr
	jmp	OutputCompare3_isr
	jmp	OutputCompare2_isr
	jmp	Unexpected_isr
	jmp	Unexpected_isr
	jmp	InputCapture2_isr
	jmp	Unexpected_isr
	jmp	RTII_isr
	jmp	IRQ_isr
	jmp	XIRQ_isr
	fill	$FF, $a0
IsrJumpTable1_end:
;
;

	fill	$FF, SavedVariableAreaInitialValues - IsrJumpTable1_end

;
; ---------------------------------------------------------------------------------
; Start Of ROM Constants
; ---------------------------------------------------------------------------------
;
	org	$f000


; $22 bytes from here are copied to address SavedVariableArea in RAM
SavedVariableAreaInitialValues:
	db	$B0, $0C, $00, $12, $3E, $02	; These 6 bytes are compared with RAM vaules, to
						; check if RAM is not inited or corrupt.
TPS_CompareLow:
	db	$25
TPS_CompareHigh:
	db	$F3

	db	$00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $20, $00, $00, $00
	db	$00, $80, $80, $80, $00, $00, $00, $00, $00, $00, $0F
	
EndSavedVariableAreaInitialValues:

InitVarSize	EQU	EndSavedVariableAreaInitialValues - SavedVariableAreaInitialValues

	if	((EndSavedVariableArea - SavedVariableArea) != (InitVarSize))
		error "ROM RAM var size mismatch"
	endif

	db	$0A

O2_FeedBackEnabled:
	db	$00

	db	$31

EEPROM_InitialValues:	; 16 bytes from here copied to EEPROM address L0F80
	db	$00
TPS_TrimDefault:
	db	$80
	db	$00
StepperProportionalDefault:
	db	$18
LF029:	db	$00
	db	$00, $00, $00, $00, $00, $00, $00, $00, $AA
LF033:	db	$00
	db	$00


DiagIDString:	; ISO code send from ECU at key-on.
	db	$55, $B0, $80, $80, $80, $85

WeberPartNo:
	db	"6160043100"
	db	$03

	db	$00, $FC, $01, $04, $02, $37, $02, $38, $00, $D3, $00, $F3, $00, $CB, $00
	db	$D9, $02, $2A, $00, $B1, $00, $B1, $00, $B1

SparkMapTPS_BreakPoints:
	dw	$8302, $6CA4, $57DF, $47E5, $3B1D, $2FEE, $27F1, $1FF4
	dw	$18C4, $132C, $0EB3, $09E8, $0759, $0546, $03AD, $028E
FuelMapTPS_BreakPoints:
	dw	$8302, $6CA4, $57DF, $47E5, $3B1D, $2FEE, $27F1, $1FF4
	dw	$18C4, $132C, $0EB3, $09E8, $0759, $0546, $03AD, $028E
SparkMapRPM_BreakPoints:
	dw	10300*4, 8600*4, 8250*4, 7800*4, 7500*4, 6750*4, 6250*4, 5750*4
	dw	5500 *4, 5000*4, 4500*4, 3500*4, 2750*4, 2000*4, 1500*4, 1000*4
RPM_SparkTable_BreakPoints:
	dw	10300*4, 8600*4, 8250*4, 7800*4, 7500*4, 6750*4, 6250*4, 5750*4
	dw	5500 *4, 5000*4, 4500*4, 3500*4, 2750*4, 2000*4, 1500*4, 1000*4
FuelMapRPM_BreakPoints:
	dw	10300*4, 8600*4, 8250*4, 7800*4, 7500*4, 6750*4, 6250*4, 5750*4
	dw	5500 *4, 5000*4, 4500*4, 3500*4, 2750*4, 2000*4, 1500*4, 1000*4

FilteredTempBreakPoints:
	db	$0D, $11, $17, $20, $2C, $3D, $53, $6F, $8F, $AF, $CB, $E1, $EF, $F7, $FC, $FE
TemperatureTable:
	db	$B4, $A8, $9C, $90, $84, $78, $6C, $60, $54, $48, $3C, $30, $24, $18, $0C, $00

TempBreakPoints:
	db	$00, $0C, $18, $24, $30, $3C, $48, $54, $60, $6C, $78, $84, $90, $9C, $A8, $B4
AltitudeTrim_BreakPoints:
	dw	$F4A7, $E458, $D408, $C3B9, $B369, $A31A, $92CB, $827B
	dw	$722C, $61DC, $518D, $413E, $30EE, $209F, $104F, $0000

InitialisedVarValues:
	db	$00, $82, $00, $80, $00, $00, $00, $B0, $00, $80, $00, $00, $00, $00, $53, $A8

;-----------------------------------------------------------------------
; TPS accross, RPM down
; Max to min
;
FuelMapTable:
	db	$B5, $A1, $8C, $79, $6B, $5A, $4F, $4A, $40, $32, $24, $1F, $1F, $1F, $1F, $1F
	db	$DA, $BD, $A2, $86, $71, $61, $54, $4B, $41, $34, $25, $1F, $1F, $1F, $1F, $1F
	db	$D7, $BD, $A3, $8C, $74, $64, $57, $4E, $44, $35, $26, $1F, $1F, $1F, $1F, $1F
	db	$D3, $C0, $A8, $93, $7A, $66, $5A, $4F, $44, $38, $27, $1F, $1F, $1F, $1F, $1F
	db	$D1, $B8, $A8, $94, $7E, $69, $5C, $51, $45, $3A, $28, $1F, $1F, $1F, $1F, $1F
	db	$DB, $C2, $AD, $99, $82, $6E, $60, $54, $47, $3D, $29, $1F, $1F, $1F, $1F, $1F
	db	$CB, $B8, $AA, $99, $84, $6D, $62, $56, $49, $3E, $2E, $1F, $1F, $1F, $1F, $1F
	db	$B5, $A2, $9C, $97, $85, $6F, $61, $54, $48, $3E, $2F, $1F, $1F, $1F, $1F, $1F
	db	$C3, $A9, $A1, $91, $80, $70, $61, $53, $48, $40, $30, $1F, $1F, $1F, $1F, $1F
	db	$B2, $A2, $A0, $9A, $8C, $7A, $6C, $5C, $50, $43, $31, $20, $1F, $1F, $1F, $1F
	db	$B1, $B0, $A8, $A2, $93, $83, $73, $63, $56, $45, $34, $24, $22, $1F, $1F, $1F
	db	$A6, $8D, $8F, $8D, $8A, $83, $77, $69, $5A, $48, $38, $28, $23, $20, $1F, $1F
	db	$A6, $94, $90, $8E, $8B, $80, $77, $6B, $5C, $4B, $3B, $32, $25, $24, $20, $20
	db	$A6, $95, $91, $8F, $8C, $83, $7B, $6D, $62, $5D, $3F, $34, $2E, $25, $22, $21
	db	$A6, $96, $92, $90, $8D, $86, $7D, $71, $68, $5E, $40, $34, $31, $2B, $25, $24
	db	$A6, $9A, $93, $91, $8E, $8A, $80, $75, $6A, $64, $50, $40, $39, $33, $29, $26

FuelMapScaleFactor:
	db	$10

;-----------------------------------------------------------------------
; TPS accross, RPM down
; Max to min
;
VertCylinderTrimTable:
	db	$8C, $8B, $80, $83, $80, $85, $84, $83, $83, $80, $80, $80, $80, $80, $80, $80
	db	$7E, $88, $7A, $80, $80, $82, $83, $82, $83, $80, $80, $80, $80, $80, $80, $80
	db	$85, $85, $7A, $7F, $7E, $81, $81, $81, $81, $80, $80, $80, $80, $80, $80, $80
	db	$7B, $7B, $78, $7D, $7B, $7F, $81, $80, $81, $80, $80, $80, $80, $80, $80, $80
	db	$6D, $7D, $77, $7F, $79, $7C, $80, $80, $81, $80, $80, $80, $80, $80, $80, $80
	db	$6C, $7C, $76, $7D, $7B, $7E, $82, $7B, $80, $80, $80, $80, $80, $80, $80, $80
	db	$76, $7C, $76, $80, $7C, $78, $82, $7A, $7E, $80, $80, $80, $80, $80, $80, $80
	db	$74, $7C, $76, $7F, $7C, $7C, $83, $7C, $81, $80, $80, $80, $80, $80, $80, $80
	db	$64, $74, $71, $82, $7F, $7C, $84, $80, $81, $80, $80, $80, $80, $80, $80, $80
	db	$79, $83, $7F, $82, $81, $7E, $84, $81, $82, $80, $80, $80, $80, $80, $80, $80
	db	$62, $6F, $70, $72, $7E, $80, $85, $81, $82, $80, $80, $80, $80, $80, $80, $80
	db	$89, $8F, $81, $8C, $87, $88, $8E, $85, $87, $80, $80, $80, $80, $80, $80, $80
	db	$80, $80, $80, $80, $80, $8B, $8E, $84, $88, $80, $80, $80, $80, $80, $80, $80
	db	$80, $80, $80, $80, $80, $80, $80, $80, $80, $80, $80, $80, $80, $80, $80, $80
	db	$80, $80, $80, $80, $80, $80, $80, $80, $80, $80, $80, $80, $80, $80, $80, $80
	db	$80, $80, $80, $80, $80, $80, $80, $80, $80, $80, $80, $80, $80, $80, $80, $80

AltitudeTrimTable:
	db	$86, $7E, $7C, $7A, $78, $76, $75, $74, $73, $80, $80, $80, $80, $80, $80, $80
AirTempTrimTable1:
	db	$80, $80, $9A, $8D, $8C, $84, $82, $80, $7E, $7D, $7B, $80, $80, $80, $80, $80
AirTempTrimTable2:
	db	$80, $80, $9A, $93, $8D, $85, $82, $80, $7E, $7B, $7B, $7B, $80, $80, $80, $80
WaterTempTrimTable:
	db	$B6, $B4, $AF, $AD, $A1, $95, $90, $8A, $89, $88, $86, $80, $7E, $7D, $7D, $80

InjectorOpeningTimeTable:
	dw	$0432, $03CC, $02C9, $024C, $01FA, $01D1, $01D1, $01D1
	dw	$0177, $0120, $00EB, $00AA, $008F, $004B, $002D, $0019

RevLimit1:		; time in microseconds for 1/4 revolution
	dw	1415	; (60 * 1e6 * 1/4 ) / 1415 = 10601 RPM
RevLimit2:
	dw	1442	; (60 * 1e6 * 1/4 ) / 1442 = 10402 RPM

RPM_To_TPS_Table:
	dw	$73E5, $73E5, $7088, $6491, $63C3, $603E, $5E52, $5BEB
	dw	$5A99, $59B2, $574B, $54E7, $5230, $4F28, $4BF6, $49E2

RPM_Table4:
	db	$00, $00, $00, $00, $00, $00, $00, $00, $08, $0B, $0F, $18, $23, $35, $53, $58

LF3F3:	dw	$07FD

RPM_Table6:
	db	$00, $00, $00, $00, $00, $04, $07, $0A, $0D, $10, $14, $22, $2B, $34, $3A, $3B

LF405:	dw	$07FD
LF407:	dw	$005A
LF409:	dw	$067D, $4000, $E696, $E650
LF411:	db	$0C

RPM_Table5:
	db	$14, $14, $14, $14, $14, $14, $14, $14, $14, $17, $18, $1E, $25, $30, $37, $41

AirTempTable1:
	db	$B4, $B4, $B4, $B4, $B4, $B4, $B4, $A2, $90, $90, $90, $B4, $B4, $B4, $B4, $B4

WaterTemp_Table3:
	db	$3C, $3C, $C8, $C8, $BC, $A4, $85, $42, $30, $26, $22, $20, $20, $20, $1F, $18

	db	$7D, $40, $00, $C8, $50, $80, $50

LF449:	db	$03

RPM_Table7:
	db	$14, $14, $14, $14, $14, $14, $14, $14, $1E, $28, $3C, $50, $64, $78, $82, $8C

AirTempTable2:
	db	$32, $32, $32, $32, $32, $32, $32, $32, $32, $32, $32, $32, $32, $32, $32, $32

WaterTemp_Table6:
	db	$02, $02, $38, $32, $2C, $25, $1F, $19, $13, $0C, $06, $01, $01, $01, $01, $01

LF47A:	dw	$1000
LF47C:	db	$12

RPM_SparkSomethingTable:
	dw	$005A, $005A, $005A, $005A, $005A, $005A, $005A, $005A
	dw	$005A, $005A, $005A, $005A, $005A, $005A, $005A, $005A

;-----------------------------------------------------------------------
; TPS accross, RPM down
; Max to min
;
SparkAdvanceMap:
	db	$52, $50, $64, $66, $6E, $70, $74, $74, $74, $74, $74, $74, $74, $74, $74, $74
	db	$52, $50, $5C, $62, $6E, $6E, $74, $74, $74, $74, $74, $74, $74, $74, $74, $74
	db	$50, $52, $5C, $5E, $6C, $6C, $74, $74, $74, $74, $74, $74, $74, $74, $74, $74
	db	$4E, $50, $58, $5C, $6A, $6C, $72, $74, $74, $74, $74, $74, $74, $74, $74, $74
	db	$4C, $4E, $54, $5C, $66, $6A, $6C, $74, $74, $74, $74, $74, $74, $74, $74, $74
	db	$4C, $4C, $54, $58, $62, $68, $6A, $74, $74, $74, $74, $74, $74, $74, $74, $74
	db	$4A, $50, $54, $56, $5A, $64, $6A, $74, $74, $74, $74, $74, $74, $74, $74, $74
	db	$48, $52, $52, $54, $58, $5E, $66, $70, $74, $74, $74, $74, $70, $6C, $6C, $6A
	db	$48, $4A, $4A, $50, $56, $54, $62, $70, $70, $74, $74, $72, $6E, $6C, $6A, $68
	db	$48, $48, $48, $50, $54, $4E, $54, $66, $6C, $74, $6E, $66, $6C, $68, $64, $5E
	db	$44, $4A, $48, $48, $48, $4A, $4A, $50, $50, $50, $50, $50, $50, $50, $50, $50
	db	$3C, $3C, $3C, $3C, $3C, $3C, $3C, $3C, $3C, $3C, $32, $28, $28, $28, $28, $28
	db	$32, $32, $32, $32, $32, $32, $32, $32, $28, $28, $1E, $14, $14, $14, $14, $14
	db	$28, $28, $28, $28, $28, $28, $28, $28, $24, $22, $18, $0E, $0E, $0C, $0C, $0C
	db	$22, $22, $22, $22, $22, $24, $22, $1E, $1A, $14, $10, $0A, $08, $04, $04, $04
	db	$16, $16, $16, $18, $18, $18, $18, $14, $10, $0C, $08, $08, $08, $08, $08, $08

RPM_SparkAdvanceTableMin:
	db	$52, $52, $50, $4E, $4E, $4A, $4A, $4A, $48, $48, $44, $3C, $3C, $2C, $22, $16

RPM_SparkAdvanceTableMax:
	db	$81, $7C, $7B, $78, $75, $71, $62, $5E, $45, $37, $1E, $08, $06, $05, $00, $09

;-----------------------------------------------------------------------
; TPS accross, water temp down
;
TPS_TempSparkAdvanceTrimMap:
	db	$00, $00, $00, $00, $14, $14, $14, $14, $14, $14, $10, $10, $00, $0E, $00, $0A
	db	$08, $08, $00, $00, $00, $00, $00, $00, $00, $FE, $02, $FE, $02, $FC, $00, $00

TPS_SparkTableBreakPoints:
	db	$70, $D0

YetAnotherSparkAdvanceTrim:
	db	$14, $0A, $04, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00

WaterTemp_SparkAdvanceTable:
	db	$1B, $19, $17, $14, $12, $0F, $0D, $0B, $07, $06, $05, $06, $00, $00, $02, $01

AltitudeSparkTrimTable:
	db	$00, $00, $03, $04, $05, $06, $07, $08, $00, $00, $00, $00, $00, $00, $00, $00

LF60F:	db	$14, $00
LF611:	db	$FF, $33
LF613:	db	$00
LF614:	dw	30000

DefaultSparkAdvance:
	db	$00

LF617:	dw	$927C
LF619:	db	$00
WaterTemp_Table4:
	db	$0A, $0A, $18, $18, $18, $18, $18, $18, $18, $18, $18, $18, $18, $18, $18, $0A
RPM_FilterWeight:
	db	$0A

LF62B:	db	$90, $03, $0C, $02
LF62F:	db	$03
LF630:	db	$80
BatteryTable2:
	db	$70, $54, $42, $36, $2E, $29, $23, $20

BatteryTable1:
	db	$90, $76, $60, $45, $3F, $38, $2D, $2B

LF641:	dw	$0017

LF643:	dw	$6400
LF645:	db	$04

TPS_ZoneTable2:
	db	$03, $02, $02, $02, $02, $02, $02, $02

LF64E:	db	$FF
LF64F:	dw	$0000

TPS_ZoneTable1:	; table indexed by TPS, not sure what for yet
	db	$02, $02, $02, $02, $02, $02, $02, $02

LF659:	db	$33
LF65A:	db	$0A
LF65B:	dw	$0000
LF65D:	db	$21
LF65E:	db	$40
LF65F:	db	$48
WaterTemp_Table1:
	db	$00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00

LF670:	dw	$0000
LF672:	db	$00
LF673:	db	$FF
RPM_Table2:
	db	$00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00

LF684:	db	$01
LF685:	db	$45
TestModeCountInitialValue:
	db	$0A
LF687:	db	$02
LF688:	db	$0B
MotorStoppedDelay:
	db	$FF
LF68A:	dw	$004C
EngineStoppingTimout:
	db	11	; 1.442 sec

EngineTurningTimout:	; number of timer overflows (131.072ms) without
	db	47	; impulse = engine not running restart (6.16 Seconds) 

CrankingThreshold1:
	dw	37500	; time between 1/4 turn impulses == (60 * 1e6) / (threshold * 4 * 2) =  200 RPM
CrankingThreshold2:
	dw	37500	; 

LF692:	dw	6250	; 1200 RPM
LF694:	dw	$1388
LF696:	dw	$1D4C
LF698:	db	$17
LF699:	db	$29

TPS_VoltageFilterWeight1:
	db	$01
AtmPressureFilterWeight:
	db	$80
TPS_FilterWeight:
	db	$05
AirTemp_FilterWeight:
	db	$40
WaterTemp_FilterWeight:
	db	$20
BatteryVoltage_FilterWeight:
	db	$20
TPS_VoltageFilterWeight2:
	db	$01
TPS_VoltageFilterWeight3:
	db	$01

ClosedThrottleThreshold:
	db	$03

NotClosedThrottleThreshold:
	db	$03

WideOpenThrottleThreshold:
	db	$05

NotWideOpenThrottleThreshold:
	db	$05

LF6A6:	dw	$0753

WaterTemp_Table5:
	db	$8C, $8C, $8C, $8C, $8C, $8C, $28, $28, $28, $28, $28, $28, $28, $28, $28, $28

LF6B8:	db	$01
LF6B9:	db	$3D
LF6BA:	db	$5C
LF6BB:	db	$8F
LF6BC:	db	$38
LF6BD:	db	$37
LF6BE:	db	$3C
LF6BF:	db	$3B
LF6C0:	db	$3B
LF6C1:	db	$39
LF6C2:	dw	$0D0D
LF6C4:	dw	$0C0C
LF6C6:	db	$08
LF6C7:	dw	$1010
LF6C9:	db	$0B
LF6CA:	dw	$0000
LF6CC:	db	$00
LF6CD:	db	$03
LF6CE:	db	$7F
LF6CF:	db	$04
LF6D0:	db	$0C
LF6D1:	db	$80
LF6D2:	db	$20
LF6D3:	dw	$1060
LF6D5:	dw	$0FA0
LF6D7:	db	$02
LF6D8:	db	$14
LF6D9:	dw	$0A0A
LF6DB:	dw	$0909
LF6DD:	db	$06
LF6DE:	dw	$0303
LF6E0:	dw	$0202
LF6E2:	db	$02
LF6E3:	db	$08
LF6E4:	db	$7D

; Thresholds for O2 lambda system
; Assume that you can't apply O2 correction when
; not in steady state, eg RPM or throttle changing
O2_TPS_Threshhold:
	db	$0A
O2_RPM_Min:
	db	$0F
O2_RPM_Max:
	db	$3A
O2_TPS_RangeA:
	db	$7E
O2_TPS_RangeB:
	db	$8C

WaterTemp_Table2:
	db	$5F, $5E, $5E, $5B, $58, $54, $52, $50, $4D, $4A, $4A, $4A, $4A, $4A, $4A, $4A
LF6FA:	db	$00
LF6FB:	db	$04
LF6FC:	db	$0E
UseTPS_RawMinMax:
	db	$FF
UseAtmPressureMinMax:
	db	$FF
UseO2Sensor:
	db	$00
UseWaterTempMinMax:
	db	$FF
UseAirTempMinMax:
	db	$FF
UseBatteryVoltageMinMax:
	db	$FF

	db	$FF

LF704:	db	$FF

InputCapture2CheckEnabled:
	db	$FF

LF706:	db	$FF, $00, $00

FuelPumpCheckEnabled:
	db	$FF
RomChecksumEnabled:
	db	$FF
LF70B:	db	$FF

PickupCheckEnabled:
	db	$FF

ErrorCounts:
	db	100, 5, 5	; in, out, function. count before error logged

LF710:	db	$04
LF711:	db	$20
LF712:	db	$40
LF713:	db	$10
TPS_raw_Min:
	db	$09
TPS_raw_Max:
	db	$FE

RevsToTPS_Table:
	db	$FC, $FC, $F4, $DE, $D8, $CC, $C5, $B7, $A8, $A1, $9A, $83, $6D, $55, $35, $09
AtmPressure_raw_Min:
	db	$03
AtmPressure_raw_Max:
	db	$FA
	
DefaultAtmPressure:
	db	$EA

O2SensorRelated:	; not used
	dw	$00E5

WaterTemp_raw_Min:
	db	$00
WaterTemp_raw_Max:
	db	$FD

MaxWaterTemp:
	db	104 + WaterTempOffset

LF72E:	db	$32

AirTemp_raw_Min:
	db	$02
AirTemp_raw_Max:
	db	$FB

DefaultAirTemp:		; if sensor failed
	db	$4E
BatteryVoltage_raw_Min:
	db	$62
BatteryVoltage_raw_Max:
	db	$F8
LF734:	db	$C0

InputCapture2_Min:
	dw	$01EE
InputCapture2_Max:
	dw	$1710
MinBatteryForCoilCheck:
	db	176	; 176 * 0.0625 = 11V
MaxBatteryForCoilCheck:
	db	240	; 240 * 0.0625 = 15V

LF73B:	db	$01
LF73C:	db	$FF
LF73D:	db	$01
O2TrimMax:
	db	$FF

DiagSlowInitCount_08:
	db	$08
DiagSlowInitCount_99:
	db	$99
DiagSlowInitCount_26:
	db	$26

LF742:	dw	$0AAA, $FF00, $8000, $1000	; these values are indexed via tables below

LF74A:	db	$00, $00, $00, $00, $06, $02, $02, $02, $04, $02, $02, $00, $00, $00, $00, $00
	db	$00, $00, $00, $06, $02, $02, $02, $02, $04, $02, $02, $00, $00, $00, $00, $00
	db	$00, $00, $06, $02, $02, $02, $02, $02, $04, $02, $02, $00, $00, $00, $00, $00
	db	$00, $06, $02, $02, $02, $02, $02, $02, $04, $02, $02, $00, $00, $00, $00, $00
	db	$00, $00, $00, $00, $00, $00, $06, $02, $04, $02, $02, $02, $00, $00, $00, $00
	db	$00, $00, $00, $00, $00, $06, $02, $02, $04, $02, $02, $02, $00, $00, $00, $00
	db	$00, $00, $00, $00, $06, $02, $02, $02, $04, $02, $02, $02, $00, $00, $00, $00
	db	$00, $00, $00, $06, $02, $02, $02, $02, $04, $02, $02, $02, $00, $00, $00, $00
	db	$00, $00, $00, $00, $00, $00, $06, $02, $04, $02, $00, $00, $00, $00, $00, $00
	db	$00, $00, $00, $00, $00, $06, $02, $02, $04, $02, $00, $00, $00, $00, $00, $00
	db	$00, $00, $00, $00, $06, $02, $02, $02, $04, $02, $00, $00, $00, $00, $00, $00
	db	$00, $00, $00, $06, $02, $02, $02, $02, $04, $02, $00, $00, $00, $00, $00, $00
	db	$00, $00, $06, $02, $02, $02, $02, $02, $04, $02, $00, $00, $00, $00, $00, $00
	db	$00, $06, $02, $02, $02, $02, $02, $02, $04, $02, $00, $00, $00, $00, $00, $00
	db	$00, $00, $00, $00, $00, $00, $06, $02, $04, $02, $02, $00, $00, $00, $00, $00
	db	$00, $00, $00, $00, $00, $06, $02, $02, $04, $02, $02, $00, $00, $00, $00, $00

LF84A:	db	$00, $00, $00, $00, $00, $00, $06, $02, $04, $02, $02, $02, $02, $02, $00, $00
	db	$00, $00, $00, $00, $00, $06, $02, $02, $04, $02, $02, $02, $02, $02, $00, $00
	db	$00, $00, $00, $00, $06, $02, $02, $02, $04, $02, $02, $02, $02, $02, $00, $00
	db	$00, $00, $00, $06, $02, $02, $02, $02, $04, $02, $02, $02, $02, $02, $00, $00
	db	$00, $00, $06, $02, $02, $02, $02, $02, $04, $02, $02, $02, $02, $02, $00, $00
	db	$00, $06, $02, $02, $02, $02, $02, $02, $04, $02, $02, $02, $02, $02, $00, $00
	db	$00, $00, $00, $00, $00, $00, $06, $02, $04, $02, $02, $02, $02, $02, $02, $00
	db	$00, $00, $00, $00, $00, $06, $02, $02, $04, $02, $02, $02, $02, $02, $02, $00

RevsConst:
	dw	5000 ; (60 * 1e6 * 1/4 ) / 5000 = 3000 RPM

FuelTrimScaleFactor:
	db	$40

LF8CD:	db	$10
StartEnrichmentInitialCount:
	dw	$0FA0
LF8D0:	db	$FF
StartEnrichment_BreakPoints:
	dw	$0F90, $0F80, $0F60, $0F20, $0ED8, $0E74, $0E10, $0DA2
	dw	$0CB2, $0BB8, $09C4, $07D0, $05DC, $03E8, $01F4, $0000

StartEnrichmentMap:
	db	$40, $38, $30, $2C, $24, $22, $20, $20, $20, $20, $20, $20, $21, $20, $20, $20
	db	$41, $39, $2F, $2C, $24, $22, $20, $23, $24, $23, $23, $23, $23, $22, $22, $20
	db	$F0, $D0, $A0, $80, $50, $30, $24, $25, $24, $24, $24, $24, $24, $24, $24, $20
	db	$F0, $D0, $A0, $80, $50, $30, $24, $26, $24, $24, $24, $24, $24, $24, $24, $20
	db	$B1, $8D, $60, $45, $37, $31, $24, $26, $24, $24, $24, $24, $24, $24, $24, $20
	db	$8D, $61, $4C, $3D, $36, $2F, $24, $24, $24, $24, $24, $24, $24, $24, $24, $20
	db	$79, $52, $3F, $37, $32, $2C, $24, $24, $24, $24, $24, $24, $24, $24, $24, $20
	db	$64, $44, $36, $32, $2B, $26, $24, $23, $23, $22, $22, $22, $22, $22, $21, $20
	db	$50, $34, $30, $2D, $26, $23, $23, $22, $22, $21, $21, $21, $21, $21, $20, $20
	db	$3F, $2F, $2B, $29, $25, $23, $22, $21, $21, $20, $20, $20, $20, $20, $20, $20
	db	$33, $2D, $28, $26, $25, $23, $22, $21, $21, $20, $20, $20, $20, $20, $20, $20
	db	$2C, $2A, $27, $26, $25, $23, $22, $21, $21, $20, $20, $20, $20, $20, $20, $20
	db	$2A, $28, $27, $26, $25, $23, $22, $21, $21, $20, $20, $20, $20, $20, $20, $20
	db	$28, $26, $24, $24, $24, $21, $21, $21, $21, $20, $20, $20, $20, $20, $20, $20
	db	$28, $26, $24, $24, $24, $21, $21, $21, $21, $20, $20, $20, $20, $20, $20, $20
	db	$28, $24, $22, $22, $22, $21, $21, $20, $20, $20, $20, $20, $20, $20, $20, $20

LF9F1:
	db	$C8, $C6, $C1, $B4, $A5, $8F, $6E, $58, $44, $30, $28, $1E, $1D, $1C, $18, $0D
WaterTemp_Table7:
	db	$4A, $46, $3F, $39, $35, $30, $2D, $27, $23, $1F, $1D, $1B, $18, $16, $14, $12
LFA11:
	db	$B4, $B4, $BC, $C2, $C8, $D2, $DC, $E6, $E6, $E6, $E6, $E6, $E6, $E6, $E6, $E6
WaterTemp_Table9:
	db	$56, $56, $84, $88, $88, $88, $85, $80, $78, $6A, $67, $63, $62, $60, $5B, $56

FanOnTemp:
	db	$9E
FanOffTemp:
	db	$9D

	fill	$FF, 1389

	db	$AA, $55, $CC, $33

LFFA4_SpecialDiagTable1:
	db	$50, $96, $06, $40, $01, $00, $98, $06, $16, $AA

RomChecksum:
	dw	$7E6F
	; adding the checksum to images changes it
	; so subtract it off and store in next word
	; to maintain original checksum
RomChecksumCorrection:
	dw	$ffff - $7E6F ; = $8190
	
	dw	$FFFF, $FFFF, $FFFF, $FFFF, $FFFF, $FFFF, $FFFF
	dw	$0000, $0000, $0000, $0000, $0000, $0000, $0000
	dw	$0000, $0000, $0000, $0000

InterruptVectors:
	dw	IsrJumpTableDest
	dw	IsrJumpTableDest + 3
	dw	IsrJumpTableDest + 6
	dw	IsrJumpTableDest + 9
	dw	IsrJumpTableDest + 12
	dw	IsrJumpTableDest + 15
	dw	IsrJumpTableDest + 18
	dw	IsrJumpTableDest + 21
	dw	IsrJumpTableDest + 24
	dw	IsrJumpTableDest + 27
	dw	IsrJumpTableDest + 30
	dw	IsrJumpTableDest + 33
	dw	IsrJumpTableDest + 36
	dw	IsrJumpTableDest + 39
	dw	IsrJumpTableDest + 42
	dw	IsrJumpTableDest + 45
	dw	PulseAccumulatorOverflow_isr
	dw	IllegalOpcode_isr
	dw	CopTimout_isr
	dw	ClkMonTimout_isr
	dw	PwrOnReset

	end
