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

; 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 : Retour apres traitement d'instruction
; a6.l : **Scratch**

	MACHINE	68020

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

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

	XREF	_RefreshScr
	XREF	_ShowHelp

	XREF	_CtrlKeyPressed
	XREF	_KeyF10Lock

        XREF    _M
        XREF    _A
        XREF    _X
        XREF    _Y
        XREF    _S
        XREF    _P
        XREF    _PC
     
        include "my_defs.i"
	include	"my_macros.asm"

		
; *** Programme principal ***

	
_RunOric:			; Point d'entree du C
@RunOric:
        STORE_REGS
        jsr     _MemToRegisters
	clr.b	_KeyF10Lock
_MainLoopReload:
	lea	_MainLoop(PC),A5
_MainLoop:
	;*** Horloge Timer 1

	move.w	(A1),D6		; T1 en D6
	btst	#6,$7(A1)	; Test du bit 6 de $30B
	bne.b	T1Count
	tst.w	D6
	beq.b	T1SkipCount	
T1Count:
	sub.w	#$400,D6	; 3 = Nb de Cycles moyen par instruction
	bcs.b	Dec305
	bra.b	T1SkipInt
Dec305:
	subq.b	#1,D6
	bne.b	T1SkipInt
T1Int:
	SET_PB	B_BIT
	bset	#6,$9(A1)	; Met le bit 6 de $30D a 1
	btst	#6,$7(A1)	; Test du bit 6 de $30B
	beq.b	T1Zero
	move.w	$2(A1),(A1)	; Rechargement des cellules
	bra.b	T1SkipCount
T1Zero:
	moveq.w	#0,D6
T1SkipInt:
	move.w	D6,(A1)
	
T1SkipCount:	
	TST_PB	B_BIT
	beq.b	ProcessInst
	CLR_PB	B_BIT
	TST_PB	I_BIT
	bne.b	ProcessInst	; Interruptions masquees : Ne fait rien
	move.b	$A(A1),D6	; $30E
	tst.b	D6		
	bpl.b	ProcessInst	; bit 7 de 0x30E
	and.b	$9(A1),D6
	beq.b	ProcessInst
	jmp	_IRQ		; Saut a l'interruption IRQ
ProcessInst:
	moveq.l	#0,D6
	move.b	(A4)+,D6	; Incrementation de 1 de A4 = PC++
	
	move.l	(A2,D6.W*4),A6
	jmp	(A6)

_StepOric:			; Point d'entree du C
	STORE_REGS
	jsr	_MemToRegisters
	lea	_ReturnToMonitor(PC),A5
	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
        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
	move.l	(A6,D6.W*4),A6
	jmp	(A6)

WarmReset:
	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:
	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
	bra	_MainLoopReload


HotRewind:
	jsr	_RewindTapeLoadAsm
	bra	_MainLoopReload
	

_BreakReason:
	dc.b	0
	even

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

