; *** ORIC Emulator. Amiga Version 680x0 ***
; *** Copyright 1995/96 JF FABRE (fabre@cert.fr) ***
; *** Memory Write Access Routines ***

; 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**

	include "my_defs.i"
	include "my_macros.asm"

        XDEF    _Place
        XDEF    @Place
        XDEF    _FinPlace
        XDEF	_case300

	XDEF	_PagexAddTableText
	XDEF	_PagexAddTableHires
	XDEF	_MemPagePtr

	XDEF	_UserLoadT1
	XDEF	_UserLoadT2

        XREF    _Reg8912
        XREF    _Reg8912Req
        XREF    _CB2_CA2
        XREF	_OricMem

        XREF    _TestClavierOric
	XREF	_JoyTest
        XREF    _Which8912Reg
        
        XREF    _CurrentContext
	XREF	_BreakReason

        XREF	_BaseAdr
        XREF    _dispmode
        XREF    _gctxt
        XREF    _gcink
        XREF    _gcdbl
        XREF    _gcpap
        XREF    _gcchm
        XREF	_ScreenGridText
        XREF	_ColumnGridText
        XREF	_ScreenGridHires
        XREF	_ColumnGridHires

	XREF	_RefreshCtl

	XREF	_SetGridHires
	XREF	_SetGridText
        
	XREF	_MainLoop

	
;*** Place un octet en memoire ***
;*** Point d'entree du C ***
;*** Prototype : void Place(UBYTE octet,UWORD adresse) ***
_Place:
	move.l	8(A7),addr
	move.l	4(A7),vh
	STORE_REGS
	move.l	_OricMem,A0
	move.l	A0,A1
	add.l	#$304,A1
	move.l	addr(PC),D6
	move.l	vh(PC),D7
	bsr.b	@Place
	RESTORE_REGS
	rts

vh:
	dc.l	0
addr:
	dc.l	0

;*** Place un octet en memoire ***
;*** D7 : donnee, D6 : emplacement ***

@Place:
	MOVEM.L	A3/A4/D4/D5,-(A7)

	and.l	#$FFFF,D6
	move.w	D6,D5
	lsr.w	#8,D5
	move.l	_MemPagePtr(PC),A6
	JMPTABLE1
	jmp	(A6)

Page03:

;*** Page 3 : 6522 registers ***
			
	move.l	D6,D5
	and.w	#$0F,D5
	lea	Page3AddTable(PC),A6
	JMPTABLE1
	jmp	(A6)

;*** VIA Port B ***

case300:
	and.b	#%11100111,$9(A1)	; Ecriture -> annule bit 3-4 de IFR

	; ** Registre 0E du 8912 : Clavier **
_case300:
	cmp.b	#$0E,_Reg8912
	bne.w	FinPlace
	jsr	_TestClavierOric
	ECRIRE_PAGE3	#0
	bra.w	FinPlace

;*** VIA Port A ***

case30F:
case301:
	and.b	#%11111100,$9(A1)	; Ecriture -> annule bit 0-1 de IFR
PortA:
	move.b	-1(A1),D6	; D6 = $303
	and.b	D6,D7		; D7 = Juste les sorties
	jsr	_JoyTest
	not.b	D6
	and.b	D6,D5		; D5 = Juste les entrees
	or.b	D5,D7		; On reunit le tout dans D7
	ECRIRE_PAGE3	#$1	; Et on ecrit dans le port A
	ECRIRE_PAGE3	#$F	; (Les 2 adresses)

	move.b	-4(A1),D7
	bra.b	_case300

case302:
case303:
	ECRIRE_PAGE3	D5
	bra.w	FinPlace


; *** 304-305 : T1C H-L ***

case305:
	st.b	_UserLoadT1
	bclr	#6,$9(A1)	; Clr IFR bit 6
case304:
	ECRIRE_PAGE3	D5
	bra.w	FinPlace

; *** 306-307 : T1L H-L ***

case306:
case307:
	ECRIRE_PAGE3	D5
	bra.w	FinPlace

; *** 308-309 : T2C H-L ***

case309:
	st.b	_UserLoadT2
	bclr	#5,$9(A1)	; Clr IFR bit 5
case308:
	ECRIRE_PAGE3	D5
	bra.w	FinPlace

; *** 30A : SR ***
; *** Non connecte au 6502 ***

case30A:
;	ECRIRE_PAGE3	D5
	bra.w	FinPlace

; *** 30B : ACR ***

case30B:
	ECRIRE_PAGE3	D5
	bra.w	FinPlace

; *** 30C : PCR ***
	
case30C:
	and.b	#$EE,D7
	ECRIRE_PAGE3	#$C
	cmp.b	#$CC,D7
	bne.b	LoadSomething

	;*** Lecture du no de registre ou de la donnee

	cmp.b	#$EE,_CB2_CA2
	beq.s	Change8912Register

	; *** C'est une donnee : le 8912 execute son truc
	
	move.b	D7,_CB2_CA2
	move.b	$B(A1),D7	; $30F
	jsr	_Which8912Reg
	bra.b	FinPlace

	; *** Il faut changer le numero du registre 8912

Change8912Register:
	move.b	$B(A1),_Reg8912
	move.b	D7,_CB2_CA2
	bra.b	FinPlace
	
	; *** Requete de charger un truc :
	; *** soit changer de registre, soit stocker une valeur

LoadSomething:	
	move.b	D7,_CB2_CA2	; Pour qu'au prochain appel PCR avec CC,
;	cmp.b	#$EE,D7		; on sache quoi faire
;	bne.b	LoadValue

	; *** Requete changer de registre

Load8912Register:
	bra.b	FinPlace

	; *** Requete charger une valeur

LoadValue:
	bra.b	FinPlace
			
case30D:
	and.b	#$7F,D7	; Virer le bit 8
	not.b	D7
	move.b	$9(A1),D6	; valeur 30D
	and.b	D6,D7
	bne.b	IFRNotCleared
	bclr	#7,D7
	bra.b	StoreIxR
IFRNotCleared:
	bset	#7,D7
StoreIxR:
	ECRIRE_PAGE3	D5
	bra.b	FinPlace

case30E:
	move.b	$A(A1),D6	; valeur 30E
	tst.b	D7
	bmi.b	SetIER
ClrIER:
	not.b	D7
	and.b	D6,D7
	bset	#1,D7	
	bra.s	StoreIxR
SetIER:
	or.b	D6,D7
	bra.s	StoreIxR

; Page de BB00 a BC00

PageTexMem:
	cmp.w	#$BFE0,D6
	bcc	Pagexx
	bra.b	PageTex

PageMemTex:
	cmp.w	#$BB80,D6
	bcs	Pagexx

PageTex:
	; *** On est dans l'ecran texte, en mode texte
	; *** Ou HIRES dans les 3 dernieres lignes de l'ecran.

	move.b	D7,(A0,D6.L)	; Place la donnee en memoire	

	; On va maintenant tester si c'est un attribut qui est affiche
	; auquel cas il faut rafraichir la fin de la ligne egalement

	bclr	#7,D7
	cmp.b	#' ',D7
	bcc.b	MT_PasAttribut

	cmp.b	#$18,D7
	bcs.b	MT_PasScreenAttribut

	lea	ScreenAttTable(PC),A6
	moveq.l	#0,D0
	move.b	D7,D0
	JMPTABLE2
	jsr	(A6)

MT_PasScreenAttribut:
	moveq.l	#0,D7
	move.w	D6,D7
	sub.w	#$BB80,D7	; D7 = X+Y*X_MAX ecran
	lea	_ScreenGridText,A3
	lea	_ColumnGridText,A4
	bra	MT_AttributModifie
	
	; On va maintenant tester si un attribut a ete ecrase
	; auquel cas il faut egalement rafraichir la fin de la ligne

	; Preparation de la mise a jour du ScreenGrid
	; Afin de dire a l'IT Refresh quels caracteres
	; doivent etre redessines

MT_PasAttribut:
	moveq.l	#0,D7
	move.w	D6,D7
	sub.w	#$BB80,D7	; D7 = X+Y*X_MAX ecran
	lea	_ScreenGridText,A3
	lea	_ColumnGridText,A4

	; Test de l'attribut ecrase

	bclr	#7,D4
	cmp.b	#' ',D4
	bcs	MT_AttributModifie

	; *** Aucun attribut n'a ete ecrase

	move.w	D7,D6		; On garde D7 tel quel
	divu.w	#X_MAX,D6	; D6h=X, D6l=Y
	st.b	(A3,D7.L)	; Positionnement de ScreenGrid pour le caractere
	st.b	(A4,D6.W)	; Positionnement de ColumnGrid pour la ligne courante

	move.b	#DO_REFRESH,_RefreshCtl	; Declenche le rafraichissement ecran
	bra	FinPlace

	; *** Un attribut a ete ecrase/modifie

MT_AttributModifie:
	
	; *** Il faut calculer combien de caracteres sont a redessiner

	move.w	D7,D6		; On garde D7 tel quel
	divu.w	#X_MAX,D6	; D6h=X, D6l=Y
	st.b	(A4,D6.W)	; Positionnement de ColumnGrid pour la ligne courante
	swap.w	D6		; Seul X nous interesse
MT_AMLoop:
	st.b	(A3,D7.L)	; Positionnement de ScreenGrid pour les caracteres
	addq.w	#1,D7
	addq.w	#1,D6
	cmp.b	#X_MAX,D6		; Jusqu'a la fin de la ligne
	bcs.b	MT_AMLoop

	move.b	#DO_REFRESH,_RefreshCtl	; Declenche le rafraichissement ecran
	bra	FinPlace

; De BF00 a BF3F : Hires de BF3F a BFDF : Text et de BFDF a BFFF memoire normale

PageHiTexMem:
	cmp.w	#$BF3F,D6
	bcc.b	Test3Lignes

	; *** On est en mode HIRES c'est a dire 1 octet = 1x6 pixels

PageHi:

	; *** On est dans l'ecran texte, en mode texte
	; *** Ou HIRES dans les 3 dernieres lignes de l'ecran.

	move.b	D7,(A0,D6.L)	; Place la donnee en memoire	

	; On va maintenant tester si c'est un attribut qui est affiche
	; auquel cas il faut rafraichir la fin de la ligne egalement

	bclr	#7,D7
	cmp.b	#' ',D7
	bcc.b	MH_PasAttribut

	cmp.b	#$18,D7
	bcs.b	MH_PasScreenAttribut

	lea	ScreenAttTable(PC),A6
	moveq.l	#0,D0
	move.b	D7,D0
	JMPTABLE2
	jsr	(A6)

MH_PasScreenAttribut:
	moveq.l	#0,D7
	move.w	D6,D7
	sub.w	#$A000,D7	; D7 = X+Y*X_MAX ecran
	lea	_ScreenGridHires,A3
	lea	_ColumnGridHires,A4
	bra	MT_AttributModifie
	
	; On va maintenant tester si un attribut a ete ecrase
	; auquel cas il faut egalement rafraichir la fin de la ligne

	; Preparation de la mise a jour du ScreenGrid
	; Afin de dire a l'IT Refresh quels caracteres
	; doivent etre redessines

MH_PasAttribut:
	moveq.l	#0,D7
	move.w	D6,D7
	sub.w	#$A000,D7	; D7 = X+Y*X_MAX ecran
	lea	_ScreenGridHires,A3
	lea	_ColumnGridHires,A4

	; Test de l'attribut ecrase

	bclr	#7,D4
	cmp.b	#' ',D4
	bcs	MT_AttributModifie	; Meme routine qu'en TEXT

	; *** Aucun attribut n'a ete ecrase

	move.w	D7,D6		; On garde D7 tel quel
	divu.w	#X_MAX,D6	; D6h=X, D6l=Y
	st.b	(A3,D7.L)	; Positionnement de ScreenGrid pour le caractere
	st.b	(A4,D6.W)	; Positionnement de ColumnGrid pour la ligne courante

	move.b	#DO_REFRESH,_RefreshCtl	; Declenche le rafraichissement ecran
	bra	FinPlace

Test3Lignes:
	cmp.w	#$BF68,D6
	bcs.b	Pagexx		; Skip 1 ligne
	cmp.w	#$BFE0,D6
	bcs.w	PageTex

; Page Normale, aucun probleme

Pagexx:
	move.b	D7,(A0,D6.L)	; Place la donnee en memoire	

; ROM : Ne fait rien

PageRom:
FinPlace:		
_FinPlace:
	MOVEM.L	(A7)+,A3/A4/D4/D5
	RTS


ATT_TEXT60:
ATT_TEXT50:
	cmp.b	#MODE_TEXT,_dispmode
	beq.b	DoRTS
	jsr	_SetGridText
DoRTS:
	rts

ATT_HIRES60:
ATT_HIRES50:
	rts
	cmp.b	#MODE_HIRES,_dispmode
	beq.b	DoRTS
	jsr	_SetGridHires
	rts

Page3AddTable:
	dc.l	_case300,case301,case302,case303,case304,case305
	dc.l	case306,case307,case308,case309,case30A,case30B
	dc.l	case30C,case30D,case30E,case30F

_PagexAddTableText:
	dc.l	Pagexx,Pagexx,Pagexx,Page03,Pagexx,Pagexx,Pagexx,Pagexx ; $0000-$07FF
	dc.l	Pagexx,Pagexx,Pagexx,Pagexx,Pagexx,Pagexx,Pagexx,Pagexx ; $0800-$0FFF
	dc.l	Pagexx,Pagexx,Pagexx,Pagexx,Pagexx,Pagexx,Pagexx,Pagexx ; $1000-$17FF
	dc.l	Pagexx,Pagexx,Pagexx,Pagexx,Pagexx,Pagexx,Pagexx,Pagexx ; $1800-$1FFF
	dc.l	Pagexx,Pagexx,Pagexx,Pagexx,Pagexx,Pagexx,Pagexx,Pagexx ; $2000-$27FF
	dc.l	Pagexx,Pagexx,Pagexx,Pagexx,Pagexx,Pagexx,Pagexx,Pagexx ; $2800-$2FFF
	dc.l	Pagexx,Pagexx,Pagexx,Pagexx,Pagexx,Pagexx,Pagexx,Pagexx ; $3000-$37FF
	dc.l	Pagexx,Pagexx,Pagexx,Pagexx,Pagexx,Pagexx,Pagexx,Pagexx ; $3800-$3FFF
	dc.l	Pagexx,Pagexx,Pagexx,Pagexx,Pagexx,Pagexx,Pagexx,Pagexx ; $4000-$47FF
	dc.l	Pagexx,Pagexx,Pagexx,Pagexx,Pagexx,Pagexx,Pagexx,Pagexx ; $4800-$4FFF
	dc.l	Pagexx,Pagexx,Pagexx,Pagexx,Pagexx,Pagexx,Pagexx,Pagexx ; $5000-$57FF
	dc.l	Pagexx,Pagexx,Pagexx,Pagexx,Pagexx,Pagexx,Pagexx,Pagexx ; $5800-$5FFF
	dc.l	Pagexx,Pagexx,Pagexx,Pagexx,Pagexx,Pagexx,Pagexx,Pagexx ; $6000-$67FF
	dc.l	Pagexx,Pagexx,Pagexx,Pagexx,Pagexx,Pagexx,Pagexx,Pagexx ; $6800-$6FFF
	dc.l	Pagexx,Pagexx,Pagexx,Pagexx,Pagexx,Pagexx,Pagexx,Pagexx ; $7000-$77FF
	dc.l	Pagexx,Pagexx,Pagexx,Pagexx,Pagexx,Pagexx,Pagexx,Pagexx ; $7800-$7FFF
	dc.l	Pagexx,Pagexx,Pagexx,Pagexx,Pagexx,Pagexx,Pagexx,Pagexx ; $8000-$87FF
	dc.l	Pagexx,Pagexx,Pagexx,Pagexx,Pagexx,Pagexx,Pagexx,Pagexx ; $8800-$8FFF
	dc.l	Pagexx,Pagexx,Pagexx,Pagexx,Pagexx,Pagexx,Pagexx,Pagexx ; $9000-$97FF
	dc.l	Pagexx,Pagexx,Pagexx,Pagexx,Pagexx,Pagexx,Pagexx,Pagexx ; $9800-$9FFF

	dc.l	Pagexx,Pagexx,Pagexx,Pagexx,Pagexx,Pagexx,Pagexx,Pagexx ; $A000-$A7FF
	dc.l	Pagexx,Pagexx,Pagexx,Pagexx,Pagexx,Pagexx,Pagexx,Pagexx ; $A800-$AFFF
	dc.l	Pagexx,Pagexx,Pagexx,Pagexx,Pagexx,Pagexx,Pagexx,Pagexx ; $B000-$B7FF
	dc.l	Pagexx,Pagexx,Pagexx,PageMemTex,PageTex,PageTex,PageTex,PageTexMem ; $B800-$BFFF

	; ROM Area

	dc.l	PageRom,PageRom,PageRom,PageRom,PageRom,PageRom,PageRom,PageRom ; $C000-$C7FF
	dc.l	PageRom,PageRom,PageRom,PageRom,PageRom,PageRom,PageRom,PageRom ; $C800-$CFFF
	dc.l	PageRom,PageRom,PageRom,PageRom,PageRom,PageRom,PageRom,PageRom ; $D000-$D7FF
	dc.l	PageRom,PageRom,PageRom,PageRom,PageRom,PageRom,PageRom,PageRom ; $D800-$DFFF
	dc.l	PageRom,PageRom,PageRom,PageRom,PageRom,PageRom,PageRom,PageRom ; $E000-$E7FF
	dc.l	PageRom,PageRom,PageRom,PageRom,PageRom,PageRom,PageRom,PageRom ; $E800-$EFFF
	dc.l	PageRom,PageRom,PageRom,PageRom,PageRom,PageRom,PageRom,PageRom ; $F000-$F7FF
	dc.l	PageRom,PageRom,PageRom,PageRom,PageRom,PageRom,PageRom,PageRom ; $F800-$FFFF

_PagexAddTableHires:
	dc.l	Pagexx,Pagexx,Pagexx,Page03,Pagexx,Pagexx,Pagexx,Pagexx ; $0000-$07FF
	dc.l	Pagexx,Pagexx,Pagexx,Pagexx,Pagexx,Pagexx,Pagexx,Pagexx ; $0800-$0FFF
	dc.l	Pagexx,Pagexx,Pagexx,Pagexx,Pagexx,Pagexx,Pagexx,Pagexx ; $1000-$17FF
	dc.l	Pagexx,Pagexx,Pagexx,Pagexx,Pagexx,Pagexx,Pagexx,Pagexx ; $1800-$1FFF
	dc.l	Pagexx,Pagexx,Pagexx,Pagexx,Pagexx,Pagexx,Pagexx,Pagexx ; $2000-$27FF
	dc.l	Pagexx,Pagexx,Pagexx,Pagexx,Pagexx,Pagexx,Pagexx,Pagexx ; $2800-$2FFF
	dc.l	Pagexx,Pagexx,Pagexx,Pagexx,Pagexx,Pagexx,Pagexx,Pagexx ; $3000-$37FF
	dc.l	Pagexx,Pagexx,Pagexx,Pagexx,Pagexx,Pagexx,Pagexx,Pagexx ; $3800-$3FFF
	dc.l	Pagexx,Pagexx,Pagexx,Pagexx,Pagexx,Pagexx,Pagexx,Pagexx ; $4000-$47FF
	dc.l	Pagexx,Pagexx,Pagexx,Pagexx,Pagexx,Pagexx,Pagexx,Pagexx ; $4800-$4FFF
	dc.l	Pagexx,Pagexx,Pagexx,Pagexx,Pagexx,Pagexx,Pagexx,Pagexx ; $5000-$57FF
	dc.l	Pagexx,Pagexx,Pagexx,Pagexx,Pagexx,Pagexx,Pagexx,Pagexx ; $5800-$5FFF
	dc.l	Pagexx,Pagexx,Pagexx,Pagexx,Pagexx,Pagexx,Pagexx,Pagexx ; $6000-$67FF
	dc.l	Pagexx,Pagexx,Pagexx,Pagexx,Pagexx,Pagexx,Pagexx,Pagexx ; $6800-$6FFF
	dc.l	Pagexx,Pagexx,Pagexx,Pagexx,Pagexx,Pagexx,Pagexx,Pagexx ; $7000-$77FF
	dc.l	Pagexx,Pagexx,Pagexx,Pagexx,Pagexx,Pagexx,Pagexx,Pagexx ; $7800-$7FFF
	dc.l	Pagexx,Pagexx,Pagexx,Pagexx,Pagexx,Pagexx,Pagexx,Pagexx ; $8000-$87FF
	dc.l	Pagexx,Pagexx,Pagexx,Pagexx,Pagexx,Pagexx,Pagexx,Pagexx ; $8800-$8FFF
	dc.l	Pagexx,Pagexx,Pagexx,Pagexx,Pagexx,Pagexx,Pagexx,Pagexx ; $9000-$97FF
	dc.l	Pagexx,Pagexx,Pagexx,Pagexx,Pagexx,Pagexx,Pagexx,Pagexx ; $9800-$9FFF

	dc.l	PageHi,PageHi,PageHi,PageHi,PageHi,PageHi,PageHi,PageHi ; $A000-$A7FF
	dc.l	PageHi,PageHi,PageHi,PageHi,PageHi,PageHi,PageHi,PageHi ; $A800-$AFFF
	dc.l	PageHi,PageHi,PageHi,PageHi,PageHi,PageHi,PageHi,PageHi ; $B000-$B7FF
	dc.l	PageHi,PageHi,PageHi,PageHi,PageHi,PageHi,PageHi,PageHiTexMem ; $B800-$BFFF

	; ROM Area

	dc.l	PageRom,PageRom,PageRom,PageRom,PageRom,PageRom,PageRom,PageRom ; $C000-$C7FF
	dc.l	PageRom,PageRom,PageRom,PageRom,PageRom,PageRom,PageRom,PageRom ; $C800-$CFFF
	dc.l	PageRom,PageRom,PageRom,PageRom,PageRom,PageRom,PageRom,PageRom ; $D000-$D7FF
	dc.l	PageRom,PageRom,PageRom,PageRom,PageRom,PageRom,PageRom,PageRom ; $D800-$DFFF
	dc.l	PageRom,PageRom,PageRom,PageRom,PageRom,PageRom,PageRom,PageRom ; $E000-$E7FF
	dc.l	PageRom,PageRom,PageRom,PageRom,PageRom,PageRom,PageRom,PageRom ; $E800-$EFFF
	dc.l	PageRom,PageRom,PageRom,PageRom,PageRom,PageRom,PageRom,PageRom ; $F000-$F7FF
	dc.l	PageRom,PageRom,PageRom,PageRom,PageRom,PageRom,PageRom,PageRom ; $F800-$FFFF
	dc.l	PageRom,PageRom,PageRom,PageRom,PageRom,PageRom,PageRom,PageRom ; $F800-$FFFF

ScreenAttTable:
	dc.l	0,0,0,0,0,0,0,0
	dc.l	0,0,0,0,0,0,0,0
	dc.l	0,0,0,0,0,0,0,0
	dc.l	ATT_TEXT60,ATT_TEXT60,ATT_TEXT50,ATT_TEXT50
	dc.l	ATT_HIRES60,ATT_HIRES60,ATT_HIRES50,ATT_HIRES50

_MemPagePtr:
	dc.l	_PagexAddTableText

; ** 6522

_UserLoadT2:
	dc.b	0
	even
_UserLoadT1:
	dc.b	0
	even
