; *** ORIC Emulator. Amiga Version 680x0 ***
; *** Copyright 1995/96 JF FABRE ***
; *** Main program ***

; D0   : **scratch**
; d1.b : A
; d2.b : X
; d3.b : Y
; d4.b : P
; d5.b : S
; D6   : **scratch**
; D7   : **scratch**

; a0.l : Mem Ptr
; a1.l : Mem Ptr + $304
; a2.l : Functable pour les instructions
; a3.l : Pointeur sur diverses tables
; a4.l : PC+Base Adr
; a5.l : **Scratch**
; a6.l : **Scratch**

        XDEF    _RunOric		; C
        XDEF    _ReturnToMonitor
	XDEF	_StepOric		; C
	XDEF	_HandleCtrl
	XDEF	_MainLoop
	XDEF	_MainLoopReload

	XDEF    _BreakReason
               
        XREF    _InitKbTableOnce
	XREF	_InitKbTable
	XREF    _InitFonctions
        XREF    _IRQ
        XREF    _RegistersToMem
        XREF    _MemToRegisters
	XREF	_RefreshScreen
	XREF	_RewindTapeLoadAsm
	XREF	_GotoTextMode

	XREF	_RefreshScr
	XREF	_ShowHelp
	XREF	_InitSound
	XREF	_StopSound

	XREF	_SoundOn
	XREF	_CtrlKeyPressed

	XREF	_NextJump

	XREF	_UserLoadT1
	XREF	_UserLoadT2

        XREF    _M
        XREF    _A
        XREF    _X
        XREF    _Y
        XREF    _S
        XREF    _P
        XREF    _PC

NB_CYCLE = 4
   
        include "my_defs.i"
	include	"libs.i"
	include	"my_macros.asm"

		
; *** Programme principal ***

	
_RunOric:			; Point d'entree du C
@RunOric:
        STORE_REGS
	move.l	AbsExecbase,A6
	CALLLIB	_LVOForbid
	jsr	_InitSound
        jsr     _MemToRegisters
_MainLoopReload:
	move.l	#_MainLoop,_NextJump
_MainLoop:
	;*** Horloge Timer 1

Timer1:
	subq.b	#NB_CYCLE,(A1)	; 3 = Nb de Cycles moyen par instruction
	bcs.b	Dec305
Timer2:
	subq.b	#NB_CYCLE,4(A1)		; 4 = Nb de Cycles moyen par instruction
	bcs.b	Dec309

ProcessInst:
	moveq.l	#0,D6
	move.b	(A4)+,D6	; Incrementation de 1 de A4 = PC++	
	MACRO_PROCESSINST
	jmp	(A6)

InvertPB7:
	bchg	#7,-4(A1)
	bra.b	T1Int_Suite

Dec305:
	DEC_TxH	1
	subq.b	#1,1(A1)
	bne.b	Timer2

T1Int:
	RELOAD_TIMER1		; Rechargement des cellules

	btst	#6,$7(A1)	; Test du bit 6 de $30B -> Si 1 : Interruptions Continues
	bne.b	T1DoInt		; Si 0 : Interruptions uniquement lors d'un load

	btst	#7,$7(A1)	; Test du bit 7 de $30B -> Si 1 : Inversion de PB7
	bne.b	InvertPB7
T1Int_Suite:
	tst.b	_UserLoadT1
	beq.b	Timer2
	clr.b	_UserLoadT1

T1DoInt:

	moveq	#6,D6
	bset	D6,$9(A1)	; Met le bit 6 de $30D a 1
	btst	D6,$A(A1)
	beq.b	Timer2		; IT masquee -> Ne fait rien
	TST_PB	I_BIT
	bne.b	Timer2		; Interruptions masquees : Ne fait rien
	CLR_PB	B_BIT
	jmp	_IRQ		; Saut a l'interruption IRQ


Dec309:
	DEC_TxH	2
	subq.b	#1,5(A1)
	bne.b	ProcessInst

T2Int:
	btst	#5,$7(A1)	; 30B ACR
	bne.b	ProcessInst	; Countdown pulse pas implémenté
	tst.b	_UserLoadT2
	beq.b	ProcessInst
	clr.b	_UserLoadT2

	moveq	#5,D6
	bset	D6,$9(A1)	; Met le bit 5 de $30D a 1
	btst	D6,$A(A1)
	beq.b	ProcessInst	; Masque = 0 -> Interruption masquee
	TST_PB	I_BIT
	bne.b	ProcessInst	; Interruptions masquees : Ne fait rien
	CLR_PB	B_BIT
	jmp	_IRQ		; Saut a l'interruption IRQ
	

_StepOric:			; Point d'entree du C
	STORE_REGS
	jsr	_MemToRegisters
	move.l	#_ReturnToMonitor,_NextJump
	move.b	#STEP_COMMAND,_BreakReason
	bra	_MainLoop	; Ensuite, ca reviendra a _ReturnToMonitor


_ReturnToMonitor:	
	
	jsr	_RegistersToMem
	RESTORE_REGS
        
	moveq.l	#0,D0
        move.b  _BreakReason(PC),D0
	move.l	AbsExecbase,A6
	CALLLIB	_LVOPermit
        rts     ; Retour au C (moniteur)
        
BreakReq:
	move.b	#USER_BREAK,_BreakReason
	bra.b	_ReturnToMonitor

ChtLoad:
	move.b	#CHANGE_TAPE,_BreakReason
	bra.b	_ReturnToMonitor

_HandleCtrl:
	move.b	_CtrlKeyPressed,D6
	clr.b	_CtrlKeyPressed
	andi.w	#$FF,D6
	subq.w	#1,D6
	lea	ControlTable(PC),A6
	MACRO_HANDLECTRL
	jmp	(A6)

WarmReset:
	jsr	_InitKbTable
	clr.b	-4(A1)	; Port B a 0
	moveq.l	#0,D6
	moveq.l	#0,D6
	move.w	#$FFFA,D6
	move.b	1(A0,D6.L),D0
	lsl.w	#8,D0
	move.b	(A0,D6.L),D0
	move.l	A0,A4
	add.l	D0,A4
	bra	_MainLoopReload

ColdReset:
	jsr	_StopSound
	jsr	_InitKbTable
	clr.b	-4(A1)
	moveq.l	#4,D4	; Interrupts off
	moveq.l	#0,D6
	moveq.l	#0,D0
	move.w	#$FFFC,D6
	move.b	1(A0,D6.L),D0
	lsl.w	#8,D0
	move.b	(A0,D6.L),D0
	move.l	A0,A4
	add.l	D0,A4
	jsr	_GotoTextMode
	bra	_MainLoopReload


HotRewind:
	jsr	_RewindTapeLoadAsm
	bra	_MainLoopReload
	
ToggleSound:
	tst.b	_SoundOn
	beq.b	SoundWasOff
	clr.b	_SoundOn
	jsr	_StopSound
	bra	_MainLoopReload

SoundWasOff:
	st.b	_SoundOn
	bra	_MainLoopReload
	


_BreakReason:
	dc.b	0
	even

ControlTable:
	dc.l	WarmReset,_RefreshScr,ChtLoad,_MainLoopReload,ColdReset
	dc.l	ToggleSound,HotRewind,_MainLoopReload,_MainLoopReload,BreakReq
	dc.l	_MainLoopReload,_MainLoopReload,_MainLoopReload
	dc.l	_MainLoopReload,_MainLoopReload,_ShowHelp

