*
* 6510SC.asm - Einzelzyklus-6510-Emulation
*
* Copyright (C) 1995-1996 by Christian Bauer
*

*
* Anmerkungen:
* ------------
*
* Registerbelegung:
* d5: Von VIC-Emulation benutzt
* d6: Von VIC-Emulation benutzt
* d7: 6510-Programmzähler
* a3: Von VIC-Emulation benutzt
* a4: Zeiger für Near-Adressierung
* a5: Zeiger in C64-RAM, Offset 32K (für Adressierung mit Vorzeichen)
* a6: Zeiger auf die Routine für den nächsten Taktzyklus. Er wird immer
*     am Ende einer Zyklusroutine gesetzt.
*
* Opcode-Ausführung:
*  - Alle Opcodes sind in einzelne Taktzyklen aufgelöst, für jeden
*    Taktzyklus eines Opcodes existiert eine Routine
*  - Die Zyklusroutinen werden vom VIC-Emulator über jsr (CONT)
*    angesprungen, jede Routine setzt diesen Zeiger am Ende auf die
*    nächste Routine
*  - Die Taktzyklen werden von 1 bis 8 gezählt, jede Zyklusroutine
*    enthält die Nummer der Zyklus im Namen getrennt durch einen Punkt
*  - Im ersten Taktzyklus wird immer der Opcode gelesen
*  - In jedem Taktzyklus findet genau ein Speicherzugriff statt
*
* Speicherkonfigurationen:
*
* $01  $a000-$bfff  $d000-$dfff  $e000-$ffff
* -----------------------------------------------
*  0       RAM          RAM          RAM
*  1       RAM       Char-ROM        RAM
*  2       RAM       Char-ROM    Kernal-ROM
*  3    Basic-ROM    Char-ROM    Kernal-ROM
*  4       RAM          RAM          RAM
*  5       RAM          I/O          RAM
*  6       RAM          I/O      Kernal-ROM
*  7    Basic-ROM       I/O      Kernal-ROM
*
* Zugriff auf den C64-Speicher:
*  - Alle Speicherzugriffe laufen über die Read/Write-Makros,
*    es sind keine Abkürzungen erlaubt
*  - Das RAM wird immer über ein 16-Bit-Offset angesprochen (also mit
*    Vorzeichen)
*
* Inkompatibilitäten:
*  - RRA und ISB kennen keinen Dezimalmodus
*  - BRK kann nicht von IRQ/NMI unterbrochen werden
*  - Wenn BA low und AEC high ist, sollte ein Lesezugriff stattfinden
*

DEBUG_DETAIL	SET 0
DEBUG_PC	= $0942

DE00_COMPATIBLE	SET 1

		MACHINE 68020

		INCLUDE	"exec/types.i"
		INCLUDE	"exec/macros.i"
		INCLUDE	"dos/dostags.i"
		INCLUDE	"Frodo_rev.i"
CATCOMP_NUMBERS	= 1
		INCLUDE	"LocStrings.i"
		INCLUDE	"debug.i"

		XREF	_SysBase
		XREF	_DOSBase
		XREF	_IntuitionBase

		XREF	GetString	;Strings.o
		XREF	TheLocale

		XDEF	TheRAM		;Main.asm
		XDEF	TheBasic
		XDEF	TheKernal
		XDEF	TheChar
		XDEF	TheColor
		XREF	MainTask
		XREF	Random
		XREF	ResetC64

		XREF	_InitDisplayFrom6510	;Display.c
		XREF	_ExitDisplayFrom6510
		XREF	_EmulToBack
		XREF	_EmulToFront

		XREF	ReadFrom6526A	;6526SC.asm
		XREF	ReadFrom6526B
		XREF	WriteTo6526A
		XREF	WriteTo6526B

		XREF	Main6569	;6569SC.asm
		XREF	ReadFrom6569
		XREF	WriteTo6569
	IFNE	DE00_COMPATIBLE
		NREF	LastVICByte
	ENDC
		NREF	CycleCounter

		XREF	ReadFrom6581	;6581.asm
		XREF	WriteTo6581

		XREF	IECOut		;IEC.asm
		XREF	IECOutATN
		XREF	IECOutSec
		XREF	IECIn
		XREF	IECSetATN
		XREF	IECRelATN
		XREF	IECTurnaround
		XREF	IECRelease

		XDEF	Init6510
		XDEF	Reset6510
		XDEF	Start6510
		XDEF	Stop6510
		XDEF	_Pause6510
		XDEF	_Resume6510
		XDEF	_SAMReadByte
		XDEF	_SAMWriteByte
		XDEF	Localize6510
		XDEF	IntIsRESET
		XDEF	IntIsNMI
		XDEF	IntIsIRQ
		XDEF	IntIsVICIRQ
		XDEF	IntIsCIAIRQ
		XDEF	FirstIRQCycle
		XDEF	FirstNMICycle
		XDEF	NMIState
		XDEF	BALow
		XDEF	CPUTask
		XDEF	IsFrodoSC
		XDEF	_IsFrodoSC
		XDEF	_InvokeSAMSet
	IFNE	DEBUG_DETAIL
		XDEF	DEBUGON
	ENDC

		NEAR	a4,-2
		XREF	_DATA_BAS_

		SECTION	"text",CODE

		FAR


**
** Definitionen
**

; Registerbelegung
RPC		EQUR	d7	;PC
RAMPTR		EQUR	a5	;Zeiger in C64-RAM, Offset 32K (für Adressierung mit Vorzeichen)
CONT		EQUR	a6	;Zyklusfortsetzungszeiger


**
** Emulation vorbereiten (Sprungtabellen aufbauen)
**

; ReadTabs aufbauen
Init6510	lea	ReadTab0,a0		;Alle mit RAM vorbelegen
		move.w	#256*8-1,d0
1$		move.l	#ReadByteRAM,(a0)+
		dbra	d0,1$

		move.l	#ReadBytePage0,ReadTab0	;Zeropage immer speziell
		move.l	#ReadBytePage0,ReadTab1
		move.l	#ReadBytePage0,ReadTab2
		move.l	#ReadBytePage0,ReadTab3
		move.l	#ReadBytePage0,ReadTab4
		move.l	#ReadBytePage0,ReadTab5
		move.l	#ReadBytePage0,ReadTab6
		move.l	#ReadBytePage0,ReadTab7

		lea	ReadTab3+160*4,a0	;Basic-ROM
		moveq	#31,d0
21$		move.l	#ReadByteBasic,(a0)+
		dbra	d0,21$

		lea	ReadTab7+160*4,a0
		moveq	#31,d0
22$		move.l	#ReadByteBasic,(a0)+
		dbra	d0,22$

		lea	ReadTab2+224*4,a0	;Kernal-ROM
		moveq	#31,d0
31$		move.l	#ReadByteKernal,(a0)+
		dbra	d0,31$

		lea	ReadTab3+224*4,a0
		moveq	#31,d0
32$		move.l	#ReadByteKernal,(a0)+
		dbra	d0,32$

		lea	ReadTab6+224*4,a0
		moveq	#31,d0
33$		move.l	#ReadByteKernal,(a0)+
		dbra	d0,33$

		lea	ReadTab7+224*4,a0
		moveq	#31,d0
34$		move.l	#ReadByteKernal,(a0)+
		dbra	d0,34$

		lea	ReadTab5+208*4,a0	;I/O-Bereich
		move.l	#ReadByteVIC,(a0)+
		move.l	#ReadByteVIC,(a0)+
		move.l	#ReadByteVIC,(a0)+
		move.l	#ReadByteVIC,(a0)+
		move.l	#ReadByteSID,(a0)+
		move.l	#ReadByteSID,(a0)+
		move.l	#ReadByteSID,(a0)+
		move.l	#ReadByteSID,(a0)+
		move.l	#ReadByteColor,(a0)+
		move.l	#ReadByteColor,(a0)+
		move.l	#ReadByteColor,(a0)+
		move.l	#ReadByteColor,(a0)+
		move.l	#ReadByteCIA1,(a0)+
		move.l	#ReadByteCIA2,(a0)+
		move.l	#ReadByteUndef,(a0)+
		move.l	#ReadByteUndef,(a0)

		lea	ReadTab6+208*4,a0
		move.l	#ReadByteVIC,(a0)+
		move.l	#ReadByteVIC,(a0)+
		move.l	#ReadByteVIC,(a0)+
		move.l	#ReadByteVIC,(a0)+
		move.l	#ReadByteSID,(a0)+
		move.l	#ReadByteSID,(a0)+
		move.l	#ReadByteSID,(a0)+
		move.l	#ReadByteSID,(a0)+
		move.l	#ReadByteColor,(a0)+
		move.l	#ReadByteColor,(a0)+
		move.l	#ReadByteColor,(a0)+
		move.l	#ReadByteColor,(a0)+
		move.l	#ReadByteCIA1,(a0)+
		move.l	#ReadByteCIA2,(a0)+
		move.l	#ReadByteUndef,(a0)+
		move.l	#ReadByteUndef,(a0)

		lea	ReadTab7+208*4,a0
		move.l	#ReadByteVIC,(a0)+
		move.l	#ReadByteVIC,(a0)+
		move.l	#ReadByteVIC,(a0)+
		move.l	#ReadByteVIC,(a0)+
		move.l	#ReadByteSID,(a0)+
		move.l	#ReadByteSID,(a0)+
		move.l	#ReadByteSID,(a0)+
		move.l	#ReadByteSID,(a0)+
		move.l	#ReadByteColor,(a0)+
		move.l	#ReadByteColor,(a0)+
		move.l	#ReadByteColor,(a0)+
		move.l	#ReadByteColor,(a0)+
		move.l	#ReadByteCIA1,(a0)+
		move.l	#ReadByteCIA2,(a0)+
		move.l	#ReadByteUndef,(a0)+
		move.l	#ReadByteUndef,(a0)

		lea	ReadTab1+208*4,a0	;Char-ROM
		moveq	#15,d0
41$		move.l	#ReadByteChar,(a0)+
		dbra	d0,41$

		lea	ReadTab2+208*4,a0
		moveq	#15,d0
42$		move.l	#ReadByteChar,(a0)+
		dbra	d0,42$

		lea	ReadTab3+208*4,a0
		moveq	#15,d0
43$		move.l	#ReadByteChar,(a0)+
		dbra	d0,43$

; WriteTabs aufbauen
		lea	WriteTab0,a0		;Alle mit RAM vorbelegen
		move.w	#256*8-1,d0
5$		move.l	#WriteByteRAM,(a0)+
		dbra	d0,5$

		move.l	#WriteBytePage0,WriteTab0 ;Zeropage immer speziell
		move.l	#WriteBytePage0,WriteTab1
		move.l	#WriteBytePage0,WriteTab2
		move.l	#WriteBytePage0,WriteTab3
		move.l	#WriteBytePage0,WriteTab4
		move.l	#WriteBytePage0,WriteTab5
		move.l	#WriteBytePage0,WriteTab6
		move.l	#WriteBytePage0,WriteTab7

		lea	WriteTab5+208*4,a0	;I/O-Bereich
		move.l	#WriteByteVIC,(a0)+
		move.l	#WriteByteVIC,(a0)+
		move.l	#WriteByteVIC,(a0)+
		move.l	#WriteByteVIC,(a0)+
		move.l	#WriteByteSID,(a0)+
		move.l	#WriteByteSID,(a0)+
		move.l	#WriteByteSID,(a0)+
		move.l	#WriteByteSID,(a0)+
		move.l	#WriteByteColor,(a0)+
		move.l	#WriteByteColor,(a0)+
		move.l	#WriteByteColor,(a0)+
		move.l	#WriteByteColor,(a0)+
		move.l	#WriteByteCIA1,(a0)+
		move.l	#WriteByteCIA2,(a0)+
		move.l	#WriteByteUndef,(a0)+
		move.l	#WriteByteUndef,(a0)

		lea	WriteTab6+208*4,a0
		move.l	#WriteByteVIC,(a0)+
		move.l	#WriteByteVIC,(a0)+
		move.l	#WriteByteVIC,(a0)+
		move.l	#WriteByteVIC,(a0)+
		move.l	#WriteByteSID,(a0)+
		move.l	#WriteByteSID,(a0)+
		move.l	#WriteByteSID,(a0)+
		move.l	#WriteByteSID,(a0)+
		move.l	#WriteByteColor,(a0)+
		move.l	#WriteByteColor,(a0)+
		move.l	#WriteByteColor,(a0)+
		move.l	#WriteByteColor,(a0)+
		move.l	#WriteByteCIA1,(a0)+
		move.l	#WriteByteCIA2,(a0)+
		move.l	#WriteByteUndef,(a0)+
		move.l	#WriteByteUndef,(a0)

		lea	WriteTab7+208*4,a0
		move.l	#WriteByteVIC,(a0)+
		move.l	#WriteByteVIC,(a0)+
		move.l	#WriteByteVIC,(a0)+
		move.l	#WriteByteVIC,(a0)+
		move.l	#WriteByteSID,(a0)+
		move.l	#WriteByteSID,(a0)+
		move.l	#WriteByteSID,(a0)+
		move.l	#WriteByteSID,(a0)+
		move.l	#WriteByteColor,(a0)+
		move.l	#WriteByteColor,(a0)+
		move.l	#WriteByteColor,(a0)+
		move.l	#WriteByteColor,(a0)+
		move.l	#WriteByteCIA1,(a0)+
		move.l	#WriteByteCIA2,(a0)+
		move.l	#WriteByteUndef,(a0)+
		move.l	#WriteByteUndef,(a0)
		rts


**
** 6510 zurücksetzen
**

Reset6510	st.b	IntIsRESET
		rts


**
** 6510-Task starten
** Rückgabe: d0#0 = Fehler
**

; Signale einrichten
Start6510	move.l	_SysBase,a6
		moveq	#-1,d0
		JSRLIB	AllocSignal
		move.b	d0,ReadySig
		moveq	#0,d1
		bset	d0,d1
		move.l	d1,ReadySet

		moveq	#-1,d0
		JSRLIB	AllocSignal
		move.b	d0,InvokeSAMSig
		moveq	#0,d1
		bset	d0,d1
		move.l	d1,InvokeSAMSet

; Task starten
		move.l	_DOSBase,a6
		move.l	#ProcTags,d1
		JSRLIB	CreateNewProc
		move.l	d0,CPUProc
		beq	1$

; Auf Signal warten
		move.l	_SysBase,a6
		move.l	ReadySet,d0
		JSRLIB	Wait
		moveq	#0,d0		;Alles OK
		rts

; Fehler aufgetreten
1$		moveq	#-1,d0
		rts


**
** 6510-Task stoppen
**

; Task stoppen
Stop6510	move.l	_SysBase,a6
		tst.l	CPUProc
		beq	1$
		st	RESETIsEXIT	;EXIT-Reset auslösen
		st	IntIsRESET
		move.l	ReadySet,d0
		JSRLIB	Wait

; Signale freigeben
1$		move.b	InvokeSAMSig,d0
		JSRLIB	FreeSignal

		move.b	ReadySig,d0
		JMPLIB	FreeSignal


**
** 6510-Task anhalten, Zustand sichern
**

_Pause6510	move.l	a6,-(sp)
		move.l	_SysBase,a6
		st	RESETIsPause	;Pause-Reset auslösen
		st	IntIsRESET
		move.l	ReadySet,d0
		JSRLIB	Wait
		move.l	(sp)+,a6
		rts


**
** 6510-Task fortsetzen, Zustand übernehmen
**

_Resume6510	move.l	a6,-(sp)
		move.l	_SysBase,a6
		move.l	CPUTask,a1	;Continue-Signal schicken
		move.l	ContinueSet,d0
		JSRLIB	Signal
		move.l	(sp)+,a6
		rts


**
** Byte lesen (für SAM)
**

_SAMReadByte	moveq	#0,d0
		move.w	6(sp),d0
		movem.l	d2/a4/RAMPTR,-(sp)
		lea	_DATA_BAS_,a4
		lea	32766(a4),a4
		move.l	TheRAMPTR,RAMPTR
		move.l	d0,d1
		lsr.w	#8,d1
		move.b	_SAMMemConfig,d2
		and.w	#7,d2
		move.l	(ConfigTab,d2.w*8),a0
		move.l	(a0,d1.w*4),a0
		jsr	(a0)
		movem.l	(sp)+,d2/a4/RAMPTR
		rts


**
** Byte schreiben (für SAM)
**

_SAMWriteByte	moveq	#0,d0
		move.w	6(sp),d0
		move.l	8(sp),d1
		cmp.w	#$d000,d0
		blo	1$
		movem.l	d2/a4/RAMPTR,-(sp)
		lea	_DATA_BAS_,a4
		lea	32766(a4),a4
		move.l	TheRAMPTR,RAMPTR
		move.b	_SAMMemConfig,d2
		and.w	#7,d2
		move.l	(ConfigTab+4,d2.w*8),a0
		move.l	d0,d2
		lsr.w	#8,d2
		move.l	(a0,d2.w*4),a0
		jsr	(a0)
		movem.l	(sp)+,d2/a4/RAMPTR
		rts
1$		move.l	TheRAMPTR,a0
		move.b	d1,(a0,d0.w)
		rts


**
** Strings in Datenstrukturen lokalisieren
**

GetStr		MACRO	;Label
		lea	TheLocale,a0
		move.l	#\1,d0
		jsr	GetString
		ENDM

Localize6510	GetStr	MSG_REQTITLE
		move.l	d0,IllegalOpReq+8

		GetStr	MSG_REQGADS6
		move.l	d0,IllegalOpReq+16

		GetStr	MSG_ILLEGALOP
		move.l	d0,IllegalOpReq+12
		rts


**
** 6510-Emulator
**

		NEAR

*
* Makros
*

; Speicherkonfiguration neu einstellen
NewConfig	MACRO
		move.b	RDDR,d0		;Zustand der Ausgabepins lesen
		not.b	d0		;Eingabepins sind 1
		or.b	RPR,d0
		and.w	#7,d0		;Relevante Bits maskieren
		move.l	(ConfigTab,d0.w*8),RDTAB
		move.l	(ConfigTab+4,d0.w*8),WRTAB
		ENDM

; Abschluß einer Zyklusroutine, Fortsetzungszeiger setzen
Next		MACRO	;Nächste Routine
		lea	\1,CONT
		rts
		ENDM

; Abschluß eines Opcodes, im nächsten Zyklus neuen Opcode lesen
Last		MACRO
		Next	Fetch
		ENDM

; Anfang eines Opcodes, Zeiger auf ersten Zyklus holen
Execute		MACRO
		ReadPCInc
		and.w	#$00ff,d0
		move.l	(OpcodeTable,d0.w*4),CONT
		rts
		ENDM

; Stackzeiger erhöhen
IncS		MACRO
		addq.b	#1,RS+1
		ENDM

; Stackzeiger erniedrigen
DecS		MACRO
		subq.b	#1,RS+1
		ENDM

; Byte bei (PC) lesen
ReadPC		MACRO	;[Ziel]
		move.w	RPC,d0
		bsr	ReadByte
	IFGE	NARG-1
		move.b	d0,\1
	ENDC
		ENDM

; Byte bei (PC) lesen und PC inkrementieren
ReadPCInc	MACRO	;[Ziel]
		move.w	RPC,d0
		bsr	ReadByte
		addq.w	#1,RPC
	IFGE	NARG-1
		move.b	d0,\1
	ENDC
		ENDM

; Byte bei (ADR) lesen
ReadADR		MACRO	;[Ziel]
		move.w	RADR,d0
		bsr	ReadByte
	IFGE	NARG-1
		move.b	d0,\1
	ENDC
		ENDM

; Byte bei (ADR2) lesen
ReadADR2	MACRO	;[Ziel]
		move.w	RADR2,d0
		bsr	ReadByte
	IFGE	NARG-1
		move.b	d0,\1
	ENDC
		ENDM

; Byte bei $0100,S lesen
ReadStack	MACRO	;[Ziel]
		move.w	RS,d0		;S ist ja 16-Bit, $01xx
		bsr	ReadByte
	IFGE	NARG-1
		move.b	d0,\1
	ENDC
		ENDM

; Status vom Stack holen
PopP		MACRO
		ReadStack
		clr.b	RCCR+1
		tst.b	d0		;N holen
		bpl	PopPNoN\@
		or.b	#$08,RCCR+1
PopPNoN\@	add.b	d0,d0		;V holen
		smi	ROVERFLOW
		lsl.b	#3,d0		;D holen
		smi	RDECIMAL
		add.b	d0,d0		;I holen
		smi	RINTERRUPT
		add.b	d0,d0		;Z holen
		bpl	PopPNoZ\@
		or.b	#$04,RCCR+1
PopPNoZ\@	add.b	d0,d0		;C holen
		smi	RCARRY
		ENDM

; Byte nach (ADR) schreiben
WriteADR	MACRO	;Quelle
		move.w	RADR,d0
		move.b	\1,d1
		bsr	WriteByte
		ENDM

; Byte nach $0100,S schreiben
WriteStack	MACRO	;[Quelle]
		move.w	RS,d0
	IFGE	NARG-1
		move.b	\1,d1
	ENDC
		bsr	WriteByte
		ENDM

; Status auf den Stack legen
PushP		MACRO	;Break-Bit
		moveq	#0,d1
		move.w	RS,d0
		btst	#3,RCCR+1	;N dazunehmen
		beq	PushPNoN\@
		or.b	#$80,d1
PushPNoN\@	tst.b	ROVERFLOW	;V dazunehmen
		beq	PushPNoV\@
		or.b	#$40,d1
PushPNoV\@	tst.b	RDECIMAL	;D dazunehmen
		beq	PushPNoD\@
		or.b	#$08,d1
PushPNoD\@	tst.b	RINTERRUPT	;I dazunehmen
		beq	PushPNoI\@
		or.b	#$04,d1
PushPNoI\@	btst	#2,RCCR+1	;Z dazunehmen
		beq	PushPNoZ\@
		or.b	#$02,d1
PushPNoZ\@	tst.b	RCARRY		;C dazunehmen
		beq	PushPNoC\@
		or.b	#$01,d1
PushPNoC\@	
	IFEQ	\1
		or.b	#$20,d1		;1 setzen
	ELSE
		or.b	#$30,d1		;B und 1 setzen
	ENDC
		bsr	WriteByte		
		DecS
		ENDM

; Zyklus 2: Byte über unmittelbare Adressierung lesen
ReadByteImm	MACRO	;[Ziel]
		ReadPCInc \1
		ENDM

; Zyklus 2: Adresse für Zero-Page-Adressierung nach ADR lesen
ReadAdrZero	MACRO	;Name des Opcodes
		ReadPCInc RADRL
		clr.b	RADRH
		Next	\1_3
\1_3
		ENDM

; Zyklus 2/3: Byte über Zero-Page-Adressierung lesen
ReadByteZero	MACRO	;Name des Opcodes, [Ziel]
		ReadAdrZero \1
		ReadADR	\2
		ENDM

; Zyklus 2/3/4: Byte über Zero-Page-Adressierung nach RDBUF lesen und zurückschreiben
ReadRMWZero	MACRO	;Name des Opcodes
		ReadAdrZero \1
		ReadADR	RDBUF
		Next	\1_4
\1_4		WriteADR RDBUF
		Next	\1_5
\1_5
		ENDM

; Zyklus 2/3: Adresse für X-indizierte Zero-Page-Adressierung nach ADR lesen
ReadAdrZeroX	MACRO	;Name des Opcodes
		ReadPCInc RADRL
		clr.b	RADRH
		Next	\1_3
\1_3		ReadADR
		move.b	RX,d0
		add.b	d0,RADRL	;Keine Seitenüberschreitung
		Next	\1_4
\1_4
		ENDM

; Zyklus 2/3/4: Byte über X-indizierte Zero-Page-Adressierung lesen
ReadByteZeroX	MACRO	;Name des Opcodes, [Ziel]
		ReadAdrZeroX \1
		ReadADR	\2
		ENDM

; Zyklus 2/3/4/5: Byte über X-indizierte Zero-Page-Adressierung nach RDBUF lesen und zurückschreiben
ReadRMWZeroX	MACRO	;Name des Opcodes
		ReadAdrZeroX \1
		ReadADR	RDBUF
		Next	\1_5
\1_5		WriteADR RDBUF
		Next	\1_6
\1_6
		ENDM

; Zyklus 2/3: Adresse für Y-indizierte Zero-Page-Adressierung nach ADR lesen
ReadAdrZeroY	MACRO	;Name des Opcodes
		ReadPCInc RADRL
		clr.b	RADRH
		Next	\1_3
\1_3		ReadADR
		move.b	RY,d0
		add.b	d0,RADRL	;Keine Seitenüberschreitung
		Next	\1_4
\1_4
		ENDM

; Zyklus 2/3/4: Byte über Y-indizierte Zero-Page-Adressierung lesen
ReadByteZeroY	MACRO	;Name des Opcodes, [Ziel]
		ReadAdrZeroY \1
		ReadADR	\2
		ENDM

; Zyklus 2/3: Adresse für absolute Adressierung nach ADR lesen
ReadAdrAbs	MACRO	;Name des Opcodes
		ReadPCInc RADRL
		Next	\1_3
\1_3		ReadPCInc RADRH
		Next	\1_4
\1_4
		ENDM

; Zyklus 2/3/4: Byte über absolute Adressierung lesen
ReadByteAbs	MACRO	;Name des Opcodes, [Ziel]
		ReadAdrAbs \1
		ReadADR	\2
		ENDM

; Zyklus 2/3/4/5: Byte über absolute Adressierung nach RDBUF lesen und zurückschreiben
ReadRMWAbs	MACRO	;Name des Opcodes
		ReadAdrAbs \1
		ReadADR	RDBUF
		Next	\1_5
\1_5		WriteADR RDBUF
		Next	\1_6
\1_6
		ENDM

; Zyklus 2/3/4: Adresse für X-indizierte absolute Adressierung nach ADR lesen
;  Kein Extrazyklus bei Seitenüberschreitung
ReadAdrAbsX	MACRO	;Name des Opcodes
		ReadPCInc RADRL
		Next	\1_3
\1_3		ReadPCInc RADRH
		move.b	RX,d0
		add.b	d0,RADRL
		bcs	\@1$		;Seitenüberschreitung?
		Next	\1_4a
\@1$		Next	\1_4b
\1_4a		ReadADR			;Nein, von Adresse lesen
		Next	\1_5
\1_4b		ReadADR			;Ja, von falscher Adresse lesen
		addq.b	#1,RADRH	; und Adresse korrigieren
		Next	\1_5
\1_5
		ENDM

; Zyklus 2/3/(4)/5: Byte über X-indizierte absolute Adressierung lesen
;  Extrazyklus bei Seitenüberschreitung
ReadByteAbsX	MACRO	;Name des Opcodes, [Ziel]
		ReadPCInc RADRL
		Next	\1_3
\1_3		ReadPCInc RADRH
		move.b	RX,d0
		add.b	d0,RADRL
		bcs	\@1$		;Seitenüberschreitung?
		Next	\1_5
\@1$		Next	\1_4
\1_4		ReadADR			;Ja, erst von falscher Adresse lesen
		addq.b	#1,RADRH	; und Adresse korrigieren
		Next	\1_5
\1_5		ReadADR	\2		;Byte lesen
		ENDM

; Zyklus 2/3/4/5/6: Byte über X-indizierte absolute Adressierung nach RDBUF lesen und zurückschreiben
;  Kein Extrazyklus bei Seitenüberschreitung
ReadRMWAbsX	MACRO	;Name des Opcodes
		ReadAdrAbsX \1
		ReadADR	RDBUF
		Next	\1_6
\1_6		WriteADR RDBUF
		Next	\1_7
\1_7
		ENDM

; Zyklus 2/3/4: Adresse für Y-indizierte absolute Adressierung nach ADR lesen
;  Kein Extrazyklus bei Seitenüberschreitung
ReadAdrAbsY	MACRO	;Name des Opcodes
		ReadPCInc RADRL
		Next	\1_3
\1_3		ReadPCInc RADRH
		move.b	RY,d0
		add.b	d0,RADRL
		bcs	\@1$		;Seitenüberschreitung?
		Next	\1_4a
\@1$		Next	\1_4b
\1_4a		ReadADR			;Nein, von Adresse lesen (unnötig)
		Next	\1_5
\1_4b		ReadADR			;Ja, von falscher Adresse lesen
		addq.b	#1,RADRH	; und Adresse korrigieren
		Next	\1_5
\1_5
		ENDM

; Zyklus 2/3/(4)/5: Byte über Y-indizierte absolute Adressierung lesen
;  Extrazyklus bei Seitenüberschreitung
ReadByteAbsY	MACRO	;Name des Opcodes, [Ziel]
		ReadPCInc RADRL
		Next	\1_3
\1_3		ReadPCInc RADRH
		move.b	RY,d0
		add.b	d0,RADRL
		bcs	\@1$		;Seitenüberschreitung?
		Next	\1_5
\@1$		Next	\1_4
\1_4		ReadADR			;Ja, erst von falscher Adresse lesen
		addq.b	#1,RADRH	; und Adresse korrigieren
		Next	\1_5
\1_5		ReadADR	\2		;Byte lesen
		ENDM

; Zyklus 2/3/4/5/6: Byte über Y-indizierte absolute Adressierung nach RDBUF lesen und zurückschreiben
;  Kein Extrazyklus bei Seitenüberschreitung
ReadRMWAbsY	MACRO	;Name des Opcodes
		ReadAdrAbsY \1
		ReadADR	RDBUF
		Next	\1_6
\1_6		WriteADR RDBUF
		Next	\1_7
\1_7
		ENDM

; Zyklus 2/3/4/5: Adresse für indiziert-indirekte Adressierung nach ADR lesen
ReadAdrIndX	MACRO	;Name des Opcodes
		ReadPCInc RADR2L
		clr.b	RADR2H
		Next	\1_3
\1_3		ReadADR2
		move.b	RX,d0
		add.b	d0,RADR2L
		Next	\1_4
\1_4		ReadADR2 RADRL
		addq.b	#1,RADR2L	;Keine Seitenüberschreitung
		Next	\1_5
\1_5		ReadADR2 RADRH
		Next	\1_6
\1_6
		ENDM

; Zyklus 2/3/4/5/6: Byte über indiziert-indirekte Adressierung lesen
ReadByteIndX	MACRO	;Name des Opcodes, [Ziel]
		ReadAdrIndX \1
		ReadADR	\2
		ENDM

; Zyklus 2/3/4/5/6/7: Byte über indiziert-indirekte Adressierung nach RDBUF lesen und zurückschreiben
ReadRMWIndX	MACRO	;Name des Opcodes
		ReadAdrIndX \1
		ReadADR	RDBUF
		Next	\1_7
\1_7		WriteADR RDBUF
		Next	\1_8
\1_8
		ENDM

; Zyklus 2/3/4/5: Adresse für indirekt-indizierte Adressierung nach ADR lesen
;  Kein Extrazyklus bei Seitenüberschreitung
ReadAdrIndY	MACRO	;Name des Opcodes
		ReadPCInc RADR2L
		clr.b	RADR2H
		Next	\1_3
\1_3		ReadADR2 RADRL
		addq.b	#1,RADR2L	;Keine Seitenüberschreitung
		Next	\1_4
\1_4		ReadADR2 RADRH
		move.b	RY,d0
		add.b	d0,RADRL
		bcs	\@1$		;Seitenüberschreitung?
		Next	\1_5a
\@1$		Next	\1_5b
\1_5a		ReadADR			;Nein, von Adresse lesen (unnötig)
		Next	\1_6
\1_5b		ReadADR			;Ja, von falscher Adresse lesen
		addq.b	#1,RADRH	; und Adresse korrigieren
		Next	\1_6
\1_6
		ENDM

; Zyklus 2/3/4/(5)/6: Byte über indirekt-indizierte Adressierung lesen
;  Extrazyklus bei Seitenüberschreitung
ReadByteIndY	MACRO	;Name des Opcodes, [Ziel]
		ReadPCInc RADR2L
		clr.b	RADR2H
		Next	\1_3
\1_3		ReadADR2 RADRL
		addq.b	#1,RADR2L	;Keine Seitenüberschreitung
		Next	\1_4
\1_4		ReadADR2 RADRH
		move.b	RY,d0
		add.b	d0,RADRL
		bcs	\@1$		;Seitenüberschreitung?
		Next	\1_6
\@1$		Next	\1_5
\1_5		ReadADR			;Ja, erst von falscher Adresse lesen
		addq.b	#1,RADRH	; und Adresse korrigieren
		Next	\1_6
\1_6		ReadADR	\2		;Byte lesen
		ENDM

; Zyklus 2/3/4/5/6/7: Byte über indirekt-indizierte Adressierung nach RDBUF lesen und zurückschreiben
;  Kein Extrazyklus bei Seitenüberschreitung
ReadRMWIndY	MACRO	;Name des Opcodes
		ReadAdrIndY \1
		ReadADR	RDBUF
		Next	\1_7
\1_7		WriteADR RDBUF
		Next	\1_8
\1_8
		ENDM

*
* Byte lesen
*

; Ein Byte von der CPU aus lesen
; -> d0.w: Adresse
; <- d0.b: Byte
ReadByte	tst.b	BALow		;BA low?
		bne	ReadBAIsLow

	IFNE	DEBUG_DETAIL
	tst.b	DEBUGON
	beq	1$
	move.l	d0,-(sp)
	bsr	1$
	move.l	(sp)+,d1
	and.l	#$00ff,d0
	and.l	#$ffff,d1
	DPRINTF	"CPU Read %04lx -> #%02lx",d1,d0
	rts
1$
	ENDC

		move.w	d0,d1		;Nein, Lesezugriff ausführen
		lsr.w	#8,d1
		move.l	RDTAB,a0
		move.l	(a0,d1.w*4),a0
		jmp	(a0)

ReadBAIsLow	move.w	d0,HALTADRSTORE	;Sonst Register retten
		move.l	CONT,HALTCONTSTORE
		move.l	(sp)+,HALTRETADR
	IFNE	DEBUG_DETAIL
	tst.b	DEBUGON
	beq	1$
	DPRINTF	"CPU Halted (RDY 1->0)"
1$
	ENDC
		Next	ReadCheckBA	;und in Warteschleife gehen

ReadCheckBA	tst.b	BALow		;Nächster Zyklus: BA immer noch low?
		beq	ReadBADone
	IFNE	DEBUG_DETAIL
	tst.b	DEBUGON
	beq	1$
	DPRINTF	"CPU Halted (RDY 0)"
1$
	ENDC
		Next	ReadCheckBA	;Ja, weiter warten

ReadBADone	move.w	HALTADRSTORE,d0	;Nein, Register wieder holen
		move.l	HALTCONTSTORE,CONT
		move.w	d0,d1
		move.l	HALTRETADR,-(sp)

	IFNE	DEBUG_DETAIL
	tst.b	DEBUGON
	beq	1$
	move.l	d0,-(sp)
	bsr	1$
	move.l	(sp)+,d1
	and.l	#$00ff,d0
	and.l	#$ffff,d1
	DPRINTF	"CPU Read %04lx -> #%02lx",d1,d0
	rts
1$
	ENDC

		lsr.w	#8,d1
		move.l	RDTAB,a0
		move.l	(a0,d1.w*4),a0
		jmp	(a0)

ReadBytePage0	cmp.w	#2,d0
		bhs	ReadByteRAM
		tst.w	d0		;Adresse 0: DDR
		bne	1$
		move.b	RDDR,d0
		rts
1$		move.b	RDDR,d0		;Adresse 1: PR
		move.b	d0,d1
		not.b	d1
		and.b	RPR,d0
		and.b	#%00010111,d1	;Eingabepins
		or.b	d1,d0
		rts

ReadByteRAM	move.b	(RAMPTR,d0.w),d0
		rts

ReadByteBasic	and.w	#$1fff,d0
		move.l	TheBasic,a0
		move.b	(a0,d0.w),d0
		rts

ReadByteVIC	and.w	#$3f,d0
		bra	ReadFrom6569

ReadByteSID	and.w	#$1f,d0
		jmp	ReadFrom6581

ReadByteColor	and.w	#$03ff,d0
		move.l	TheColor,a0
		move.b	(a0,d0.w),d0
		and.b	#$0f,d0
	IFNE	DE00_COMPATIBLE
		move.b	LastVICByte,d1	;Oberes Nibble kommt vom VIC
		and.b	#$f0,d1
		or.b	d1,d0
	ENDC
		rts

ReadByteCIA1	and.w	#$0f,d0
		bra	ReadFrom6526A

ReadByteCIA2	and.w	#$0f,d0
		bra	ReadFrom6526B

ReadByteUndef
	IFNE	DE00_COMPATIBLE
		move.b	LastVICByte,d0
	ELSE
		move.b	#$aa,d0
	ENDC
		rts

ReadByteKernal	and.w	#$1fff,d0
		move.l	TheKernal,a0
		move.b	(a0,d0.w),d0
		rts

ReadByteChar	and.w	#$0fff,d0
		move.l	TheChar,a0
		move.b	(a0,d0.w),d0
		rts


*
* Byte schreiben
*

; Ein Byte von der CPU aus schreiben
; -> d0.w: Adresse
; -> d1.b: Byte
WriteByte
	IFNE	DEBUG_DETAIL
	tst.b	DEBUGON
	beq	1$
	and.l	#$ffff,d0
	and.l	#$00ff,d1
	DPRINTF	"CPU Write #%02lx -> %04lx",d1,d0
1$
	ENDC

		move.w	d0,d2
		lsr.w	#8,d2
		move.l	WRTAB,a0
		move.l	(a0,d2.w*4),a0
		jmp	(a0)

WriteBytePage0	cmp.w	#2,d0
		bhs	WriteByteRAM
		tst.w	d0
		bne	1$
		move.b	d1,RDDR		;Adresse 0: DDR
	IFNE	DE00_COMPATIBLE
		move.b	LastVICByte,(RAMPTR)
	ENDC
		NewConfig
		rts
1$		move.b	d1,RPR		;Adresse 1: PR
	IFNE	DE00_COMPATIBLE
		move.b	LastVICByte,1(RAMPTR)
	ENDC
		NewConfig
		rts

WriteByteRAM	move.b	d1,(RAMPTR,d0.w)
		rts

WriteByteVIC	and.w	#$3f,d0
		bra	WriteTo6569

WriteByteSID	and.w	#$1f,d0
		jmp	WriteTo6581

WriteByteColor	and.w	#$03ff,d0
		move.l	TheColor,a0
		move.b	d1,(a0,d0.w)
		rts

WriteByteCIA1	and.w	#$0f,d0
		bra	WriteTo6526A

WriteByteCIA2	and.w	#$0f,d0
		bra	WriteTo6526B

WriteByteUndef	rts


*
* Start
*

; Near-Adressierung initialisieren
CPUTaskProc	lea	_DATA_BAS_,a4
		lea	32766(a4),a4

; Stackpointer retten
		move.l	a7,InitialSP

; Task ermitteln
		move.l	_SysBase,a6
		sub.l	a1,a1
		JSRLIB	FindTask
		move.l	d0,CPUTask

; Continue-Signal holen
		moveq	#-1,d0
		JSRLIB	AllocSignal
		move.b	d0,ContinueSig
		moveq	#0,d1
		bset	d0,d1
		move.l	d1,ContinueSet

; Grafik initialisieren
		jsr	_InitDisplayFrom6510

; Signal an den Emulator schicken
		move.l	_SysBase,a6
		move.l	MainTask,a1
		move.l	ReadySet,d0
		JSRLIB	Signal

; RAM mit Einschaltmuster initialisieren
		move.l	TheRAM,d0
		add.l	#$8000,d0
		move.l	d0,TheRAMPTR

		move.l	TheRAM,a0
		move.w	#511,d1
3$		moveq	#63,d0
1$		clr.b	(a0)+		;Abwechselnd 64 Bytes $00
		dbra	d0,1$
		moveq	#63,d0
2$		st	(a0)+		;Und 64 Bytes $ff
		dbra	d0,2$
		dbra	d1,3$

; Farb-RAM mit Zufallswerten initialisieren
		move.l	TheColor,a2
		move.w	#$03ff,d2
4$		jsr	Random
		move.b	d0,(a2)+
		dbra	d2,4$

; Prozessor initilisieren
		move.l	TheRAMPTR,RAMPTR

		clr.l	Interrupt	;Interrupts aus
		clr.b	RESETIsEXIT
		clr.b	RESETIsPause
		clr.b	NMIState

		clr.b	RA		;Register löschen
		clr.b	RX
		clr.b	RY
		move.w	#$01ff,RS
		clr.w	RCCR
		st	RINTERRUPT
		clr.b	RDECIMAL
		clr.b	RCARRY
		clr.w	RADR

		clr.b	RDDR		;Speicherkonfiguration einstellen
		clr.b	RPR
		NewConfig

		clr.b	BALow

; Reset-Vektor lesen, PC setzen und für ersten Befehl vorbereiten
		move.w	#$fffd,d0
		bsr	ReadByte
		move.b	d0,RPC
		lsl.w	#8,RPC
		move.w	#$fffc,d0
		bsr	ReadByte
		move.b	d0,RPC
		lea	Fetch,CONT

; Ab jetzt kontrolliert der VIC alles
		bra	Main6569


*
* Opcode lesen
*

Fetch
	IFNE	DEBUG_DETAIL
	cmp.w	#DEBUG_PC,RPC
	bne	1$
	st	DEBUGON
1$
	ENDC

		tst.l	Interrupt
		bne	HandleInt
		Execute


*
* Ungültiger Opcode
*

; Unbekannten Opcode entdeckt: Requester darstellen
IllegalOp	subq.w	#1,RPC			;PC korrigieren
		movem.l	a2-a6,-(sp)

		ReadPC
		and.w	#$00ff,d0
		move.w	d0,RequestStream	;Opcode
		move.w	RPC,RequestStream+2	;und PC anzeigen

		jsr	_EmulToBack

		move.l	_IntuitionBase,a6
		sub.l	a0,a0
		lea	IllegalOpReq,a1
		move.l	a0,a2
		lea	RequestStream,a3
		JSRLIB	EasyRequestArgs

		move.l	d0,-(sp)
		jsr	_EmulToFront
		move.l	(sp)+,d0

		movem.l	(sp)+,a2-a6

		tst.l	d0
		beq	1$
		jsr	ResetC64		;Ja
		Last

1$		move.l	a6,-(sp)		;Nein, SAM aufrufen
		move.l	_SysBase,a6
		move.l	MainTask,a1		;Den Haupttask benachrichtigen
		move.l	InvokeSAMSet,d0
		JSRLIB	Signal
		move.l	(sp)+,a6
		bsr	Pause			;In Pause-Zustand gehen
		clr.b	IntIsRESET
		clr.b	RESETIsPause
		NewConfig
		bra	Fetch


*
* Interrupts handhaben
*

; Art des Interrupt feststellen (Priorität)
HandleInt	tst.b	IntIsRESET
		bne	HandleRESET
		tst.b	IntIsNMI
		bne	HandleNMI
		tst.w	IntIsIRQ
		bne	HandleIRQ

; Kein Interrupt, Befehl ausführen
IntDont		Execute

; IRQ: Interrupt-Bit testen, nach ($fffe) springen
HandleIRQ	move.l	CycleCounter,d0	;IRQ muß seit zwei Zyklen anliegen
		sub.l	FirstIRQCycle,d0
		moveq	#2,d1
		cmp.l	d1,d0
		blo	IntDont
		tst.b	RINTERRUPT
		bne	IntDont

	IFNE	DEBUG_DETAIL
	tst.b	DEBUGON
	beq	1$
	DPRINTF	"CPU IRQ Sequence"
1$
	ENDC

IRQ_1		ReadPC
		Next	IRQ_2
IRQ_2		ReadPC
		Next	IRQ_3
IRQ_3		move.w	RPC,d1
		lsr.w	#8,d1
		WriteStack
		DecS
		Next	IRQ_4
IRQ_4		move.b	RPC,d1
		WriteStack
		DecS
		Next	IRQ_5
IRQ_5		PushP	0		;B auf 0
		Next	IRQ_6
IRQ_6		st	RINTERRUPT
		move.w	#$fffe,d0	;IRQ-Vektor
		bsr	ReadByte
		move.b	d0,RPC
		lsl.w	#8,RPC
		Next	IRQ_7
IRQ_7		move.w	#$ffff,d0
		bsr	ReadByte
		move.b	d0,RPC
		ror.w	#8,RPC
		Last

; NMI: Nach ($fffa) springen
HandleNMI	move.l	CycleCounter,d0	;NMI muß seit zwei Zyklen anliegen
		sub.l	FirstNMICycle,d0
		moveq	#2,d1
		cmp.l	d1,d0
		blo	IntDont

		clr.b	IntIsNMI	;Simuliert einen flankengetriggerten Eingang

	IFNE	DEBUG_DETAIL
	tst.b	DEBUGON
	beq	1$
	DPRINTF	"CPU NMI Sequence"
1$
	ENDC

NMI_1		ReadPC
		Next	NMI_2
NMI_2		ReadPC
		Next	NMI_3
NMI_3		move.w	RPC,d1
		lsr.w	#8,d1
		WriteStack
		DecS
		Next	NMI_4
NMI_4		move.b	RPC,d1
		WriteStack
		DecS
		Next	NMI_5
NMI_5		PushP	0		;B auf 0
		Next	NMI_6
NMI_6		st	RINTERRUPT
		move.w	#$fffa,d0	;NMI-Vektor
		bsr	ReadByte
		move.b	d0,RPC
		lsl.w	#8,RPC
		Next	NMI_7
NMI_7		move.w	#$fffb,d0
		bsr	ReadByte
		move.b	d0,RPC
		ror.w	#8,RPC
		Last

; RESET: Emulator beenden, anhalten oder nach ($fffc) springen
HandleRESET	tst.b	RESETIsEXIT	;Beenden?
		bne	HandleEXIT
		tst.b	RESETIsPause	;Pause?
		bne	HandlePause

		clr.l	Interrupt	;Nein, RESET
		clr.b	NMIState

		move.l	TheRAM,a0	;Adressierung ohne Vorzeichen!
		cmp.l	#$c3c2cd38,$4(a0) ; $4 ist $8004!
		bne	1$
		cmp.b	#$30,$8(a0)
		bne	1$
		clr.b	$4(a0)		;CBM80 löschen, wenn vorhanden

1$		clr.b	RDDR		;Speicherkonfiguration einstellen
		clr.b	RPR
		NewConfig

		move.w	#$fffd,d0	;RESET-Vektor
		bsr	ReadByte
		move.b	d0,RPC
		lsl.w	#8,RPC
		move.w	#$fffc,d0
		bsr	ReadByte
		move.b	d0,RPC
		bra	Fetch

; EXIT: Signal an den Emulator schicken
HandleEXIT	jsr	_ExitDisplayFrom6510	;Grafik aufräumen

		move.l	_SysBase,a6
		moveq	#0,d0
		move.b	ContinueSig,d0
		JSRLIB	FreeSignal

		JSRLIB	Forbid
		move.l	MainTask,a1
		move.l	ReadySet,d0
		JSRLIB	Signal
		move.l	InitialSP,a7
		moveq	#0,d0
		rts

; Pause: Signal an den Emulator schicken und dann selbst auf
;  ein Signal warten
HandlePause	bsr	Pause
		NewConfig
		bra	Fetch

Pause		clr.b	IntIsRESET
		clr.b	RESETIsPause

		move.b	RA,_RA		;Register für SAM bereitstellen
		move.b	RX,_RX
		move.b	RY,_RY

		moveq	#0,d0
		btst	#3,RCCR+1	;N dazunehmen
		beq	1$
		or.b	#$80,d0
1$		tst.b	ROVERFLOW	;V dazunehmen
		beq	2$
		or.b	#$40,d0
2$		tst.b	RDECIMAL	;D dazunehmen
		beq	3$
		or.b	#$08,d0
3$		tst.b	RINTERRUPT	;I dazunehmen
		beq	4$
		or.b	#$04,d0
4$		btst	#2,RCCR+1	;Z dazunehmen
		beq	5$
		or.b	#$02,d0
5$		tst.b	RCARRY		;C dazunehmen
		beq	6$
		or.b	#$01,d0
6$		move.b	d0,_RP

		move.b	RDDR,_RDDR
		move.b	RPR,d0
		and.b	#$3f,d0
		move.b	d0,_RPR

		move.b	RDDR,d0
		not.b	d0
		or.b	RPR,d0
		and.b	#$07,d0
		move.b	d0,_SAMMemConfig

		move.w	RPC,_RPC
		move.w	RS,_RS

		move.l	a6,-(sp)
		move.l	_SysBase,a6
		move.l	MainTask,a1
		move.l	ReadySet,d0
		JSRLIB	Signal
		move.l	ContinueSet,d0
		JSRLIB	Wait
		move.l	(sp)+,a6

		move.b	_RA,RA		;Register von SAM lesen
		move.b	_RX,RX
		move.b	_RY,RY

		clr.b	RCCR+1
		move.b	_RP,d0		;N holen
		bpl	7$
		or.b	#$08,RCCR+1
7$		add.b	d0,d0		;V holen
		smi	ROVERFLOW
		lsl.b	#3,d0		;D holen
		smi	RDECIMAL
		add.b	d0,d0		;I holen
		smi	RINTERRUPT
		add.b	d0,d0		;Z holen
		bpl	8$
		or.b	#$04,RCCR+1
8$		add.b	d0,d0		;C holen
		smi	RCARRY

		move.b	_RDDR,RDDR
		move.b	_RPR,RPR
		move.w	_RPC,RPC
		move.w	_RS,RS
		move.b	#$01,RS
		rts


**
** Opcodes
**

*
* Load-Gruppe
*

LoadA		MACRO
		move.b	d0,RA
		move	ccr,RCCR
		Last
		ENDM

LDAImm_2	ReadByteImm
		LoadA

LDAZero_2	ReadByteZero	LDAZero
		LoadA

LDAZeroX_2	ReadByteZeroX	LDAZeroX
		LoadA

LDAAbs_2	ReadByteAbs	LDAAbs
		LoadA

LDAAbsX_2	ReadByteAbsX	LDAAbsX
		LoadA

LDAAbsY_2	ReadByteAbsY	LDAAbsY
		LoadA

LDAIndX_2	ReadByteIndX	LDAIndX
		LoadA

LDAIndY_2	ReadByteIndY	LDAIndY
		LoadA


LoadX		MACRO
		move.b	d0,RX
		move	ccr,RCCR
		Last
		ENDM

LDXImm_2	ReadByteImm
		LoadX

LDXZero_2	ReadByteZero	LDXZero
		LoadX

LDXZeroY_2	ReadByteZeroY	LDXZeroY
		LoadX

LDXAbs_2	ReadByteAbs	LDXAbs
		LoadX

LDXAbsY_2	ReadByteAbsY	LDXAbsY
		LoadX


LoadY		MACRO
		move.b	d0,RY
		move	ccr,RCCR
		Last
		ENDM

LDYImm_2	ReadByteImm
		LoadY

LDYZero_2	ReadByteZero	LDYZero
		LoadY

LDYZeroX_2	ReadByteZeroX	LDYZeroX
		LoadY

LDYAbs_2	ReadByteAbs	LDYAbs
		LoadY

LDYAbsX_2	ReadByteAbsX	LDYAbsX
		LoadY


LoadAX		MACRO
		move.b	d0,RA
		move.b	d0,RX
		move	ccr,RCCR
		Last
		ENDM

LAXZero_2	ReadByteZero	LAXZero
		LoadAX

LAXZeroY_2	ReadByteZeroY	LAXZeroY
		LoadAX

LAXAbs_2	ReadByteAbs	LAXAbs
		LoadAX

LAXAbsY_2	ReadByteAbsY	LAXAbsY
		LoadAX


*
* Store-Gruppe
*

StoreA		MACRO
		WriteADR RA
		Last
		ENDM

STAZero_2	ReadAdrZero	STAZero
		StoreA

STAZeroX_2	ReadAdrZeroX	STAZeroX
		StoreA

STAAbs_2	ReadAdrAbs	STAAbs
		StoreA

STAAbsX_2	ReadAdrAbsX	STAAbsX
		StoreA

STAAbsY_2	ReadAdrAbsY	STAAbsY
		StoreA

STAIndX_2	ReadAdrIndX	STAIndX
		StoreA

STAIndY_2	ReadAdrIndY	STAIndY
		StoreA


STXZero_2	ReadAdrZero	STXZero
		WriteADR RX
		Last

STXZeroY_2	ReadAdrZeroY	STXZeroY
		WriteADR RX
		Last

STXAbs_2	ReadAdrAbs	STXAbs
		WriteADR RX
		Last


STYZero_2	ReadAdrZero	STYZero
		WriteADR RY
		Last

STYZeroX_2	ReadAdrZeroX	STYZeroX
		WriteADR RY
		Last

STYAbs_2	ReadAdrAbs	STYAbs
		WriteADR RY
		Last


StoreAX		MACRO
		move.b	RA,d1
		move.w	RADR,d0
		and.b	RX,d1
		bsr	WriteByte
		Last
		ENDM

SAXZero_2	ReadAdrZero	SAXZero
		StoreAX

SAXZeroY_2	ReadAdrZeroY	SAXZeroY
		StoreAX

SAXAbs_2	ReadAdrAbs	SAXAbs
		StoreAX

SAXIndX_2	ReadAdrIndX	SAXIndX
		StoreAX


*
* Transfer-Gruppe
*

TAX_2		ReadPC
		move.b	RA,RX
		move	ccr,RCCR
		Last

TAY_2		ReadPC
		move.b	RA,RY
		move	ccr,RCCR
		Last

TXA_2		ReadPC
		move.b	RX,RA
		move	ccr,RCCR
		Last

TYA_2		ReadPC
		move.b	RY,RA
		move	ccr,RCCR
		Last

TXS_2		ReadPC
		move.b	RX,RS+1
		Last

TSX_2		ReadPC
		move.b	RS+1,RX
		move	ccr,RCCR
		Last


*
* Stack-Gruppe
*

PHA_2		ReadPC
		Next	PHA_3
PHA_3		WriteStack RA
		DecS
		Last

PLA_2		ReadPC
		Next	PLA_3
PLA_3		ReadStack
		IncS
		Next	PLA_4
PLA_4		ReadStack
		move.b	d0,RA
		move	ccr,RCCR
		Last

PHP_2		ReadPC
		Next	PHP_3
PHP_3		PushP	1		;B immer 1
		Last

PLP_2		ReadPC
		Next	PLP_3
PLP_3		ReadStack
		IncS
		Next	PLP_4
PLP_4		PopP
		Last


*
* Vergleichs-Gruppe
*

CompareA	MACRO
		move.b	RA,d1
		cmp.b	d0,d1
		move	ccr,RCCR
		scc	RCARRY		;Inverses Carry holen
		Last
		ENDM

CMPImm_2	ReadByteImm
		CompareA

CMPZero_2	ReadByteZero	CMPZero
		CompareA

CMPZeroX_2	ReadByteZeroX	CMPZeroX
		CompareA

CMPAbs_2	ReadByteAbs	CMPAbs
		CompareA

CMPAbsX_2	ReadByteAbsX	CMPAbsX
		CompareA

CMPAbsY_2	ReadByteAbsY	CMPAbsY
		CompareA

CMPIndX_2	ReadByteIndX	CMPIndX
		CompareA

CMPIndY_2	ReadByteIndY	CMPIndY
		CompareA


CompareX	MACRO
		move.b	RX,d1
		cmp.b	d0,d1
		move	ccr,RCCR
		scc	RCARRY		;Inverses Carry holen
		Last
		ENDM

CPXImm_2	ReadByteImm
		CompareX

CPXZero_2	ReadByteZero	CPXZero
		CompareX

CPXAbs_2	ReadByteAbs	CPXAbs
		CompareX


CompareY	MACRO
		move.b	RY,d1
		cmp.b	d0,d1
		move	ccr,RCCR
		scc	RCARRY		;Inverses Carry holen
		Last
		ENDM

CPYImm_2	ReadByteImm
		CompareY

CPYZero_2	ReadByteZero	CPYZero
		CompareY

CPYAbs_2	ReadByteAbs	CPYAbs
		CompareY


*
* Logik-Gruppe
*

AndA		MACRO
		and.b	d0,RA
		move	ccr,RCCR
		Last
		ENDM

ANDImm_2	ReadByteImm
		AndA

ANDZero_2	ReadByteZero	ANDZero
		AndA

ANDZeroX_2	ReadByteZeroX	ANDZeroX
		AndA

ANDAbs_2	ReadByteAbs	ANDAbs
		AndA

ANDAbsX_2	ReadByteAbsX	ANDAbsX
		AndA

ANDAbsY_2	ReadByteAbsY	ANDAbsY
		AndA

ANDIndX_2	ReadByteIndX	ANDIndX
		AndA

ANDIndY_2	ReadByteIndY	ANDIndY
		AndA


OrA		MACRO
		or.b	d0,RA
		move	ccr,RCCR
		Last
		ENDM

ORAImm_2	ReadByteImm
		OrA

ORAZero_2	ReadByteZero	ORAZero
		OrA

ORAZeroX_2	ReadByteZeroX	ORAZeroX
		OrA

ORAAbs_2	ReadByteAbs	ORAAbs
		OrA

ORAAbsX_2	ReadByteAbsX	ORAAbsX
		OrA

ORAAbsY_2	ReadByteAbsY	ORAAbsY
		OrA

ORAIndX_2	ReadByteIndX	ORAIndX
		OrA

ORAIndY_2	ReadByteIndY	ORAIndY
		OrA


EorA		MACRO
		eor.b	d0,RA
		move	ccr,RCCR
		Last
		ENDM

EORImm_2	ReadByteImm
		EorA

EORZero_2	ReadByteZero	EORZero
		EorA

EORZeroX_2	ReadByteZeroX	EORZeroX
		EorA

EORAbs_2	ReadByteAbs	EORAbs
		EorA

EORAbsX_2	ReadByteAbsX	EORAbsX
		EorA

EORAbsY_2	ReadByteAbsY	EORAbsY
		EorA

EORIndX_2	ReadByteIndX	EORIndX
		EorA

EORIndY_2	ReadByteIndY	EORIndY
		EorA


BitTest		MACRO
		tst.b	d0		;N holen
		move	ccr,RCCR
		btst	#6,d0		;Bit 6 -> V
		sne	ROVERFLOW
		and.b	RA,d0		;A AND M -> Z
		beq	BitZ\@
		and.b	#$fb,RCCR+1
		Last
BitZ\@		or.b	#$04,RCCR+1
		Last
		ENDM

BITZero_2	ReadByteZero	BITZero
		BitTest

BITAbs_2	ReadByteAbs	BITAbs
		BitTest


*
* Arithmetik-Gruppe
*

AdcA		MACRO
		move.b	RCARRY,d1
		tst.b	RDECIMAL
		bne	\@1$

		add.b	d1,d1		;Carry -> X
		move.b	RA,d1
		addx.b	d0,d1
		scs	RCARRY		;Carry holen
		svs	ROVERFLOW	;Overflow holen
		move.b	d1,RA
		move	ccr,RCCR	;N und Z holen
		Last

\@1$		bsr	AdcDec
		Last
		ENDM

AdcDec		move.b	d0,TMPS		;Dezimalmodus
		move.b	RA,d2
		move.b	d2,TMPA

		clr.w	RCCR
		clr.b	ROVERFLOW

		move.b	d2,d3		;Unteres Nybble berechnen
		and.b	#$0f,d0
		and.b	#$0f,d3
		add.b	d1,d1		;Carry -> X
		addx.b	d0,d3		; -> d3

		cmp.b	#10,d3		;BCD-Fixup für das untere Nybble
		blo	2$
		addq.b	#6,d3
2$
		move.b	TMPS,d0		;Oberes Nybble berechnen
		lsr.b	#4,d0
		lsr.b	#4,d2
		add.b	d0,d2
		cmp.b	#$10,d3
		blo	1$
		addq.b	#1,d2		; -> d2
1$
		move.b	TMPS,d0		;Z holen (wie im Binärmodus)
		move.b	TMPA,d4
		add.b	d1,d1		;Carry -> X
		addx.b	d0,d4
		tst.b	d4		;Wegen addx
		bne	6$
		or.w	#$04,RCCR
6$
		btst	#3,d2		;N berechnen
		beq	4$
		or.w	#$08,RCCR
4$
		move.b	d2,d0		;V berechnen
		lsl.b	#4,d0
		move.b	TMPA,d1
		eor.b	d1,d0
		bpl	5$
		move.b	TMPS,d0
		eor.b	d1,d0
		spl	ROVERFLOW
5$
		cmp.b	#10,d2		;BCD-Fixup für das obere Nybble
		blo	3$
		addq.b	#6,d2
3$
		cmp.b	#$10,d2		;Carry holen
		shs	RCARRY

		and.b	#$0f,d3		;Ergebnis zusammensetzen
		lsl.b	#4,d2
		or.b	d3,d2
		move.b	d2,RA
		rts

ADCImm_2	ReadByteImm
		AdcA

ADCZero_2	ReadByteZero	ADCZero
		AdcA

ADCZeroX_2	ReadByteZeroX	ADCZeroX
		AdcA

ADCAbs_2	ReadByteAbs	ADCAbs
		AdcA

ADCAbsX_2	ReadByteAbsX	ADCAbsX
		AdcA

ADCAbsY_2	ReadByteAbsY	ADCAbsY
		AdcA

ADCIndX_2	ReadByteIndX	ADCIndX
		AdcA

ADCIndY_2	ReadByteIndY	ADCIndY
		AdcA


SbcA		MACRO
		move.b	RCARRY,d1
		not.b	d1
		tst.b	RDECIMAL
		bne	\@1$

		add.b	d1,d1		;Inverses Carry -> X
		move.b	RA,d1
		subx.b	d0,d1
		scc	RCARRY		;Inverses Carry holen
		svs	ROVERFLOW	;Overflow holen
		move.b	d1,RA
		move	ccr,RCCR
		Last

\@1$		bsr	SbcDec
		Last
		ENDM

SbcDec		move.b	d0,TMPS		;Dezimalmodus
		move.b	RA,d2
		move.b	d2,TMPA

		and.b	#$0f,d0		;Unteres Nybble berechnen
		and.b	#$0f,d2
		add.b	d1,d1		;Inverses Carry -> X
		subx.b	d0,d2
		move	ccr,d4
		bcc	1$		;BCD-Fixup
		subq.b	#6,d2
		st	d4
1$		and.b	#$0f,d2
		move.b	d2,d3		;-> d3

		move.b	TMPS,d0		;Oberes Nybble berechnen
		move.b	TMPA,d2
		and.b	#$f0,d0
		and.b	#$f0,d2
		sub.b	d0,d2
		bcc	2$		;BCD-Fixup
		and.b	#$f0,d2
		sub.b	#$60,d2
		btst	#0,d4
		beq	4$
		sub.b	#$10,d2
		bra	4$
2$		and.b	#$f0,d2
		btst	#0,d4
		beq	4$
		sub.b	#$10,d2
		bcc	4$
		sub.b	#$60,d2
4$		or.b	d3,d2		;Ergebnis zusammenbauen
		move.b	d2,RA

		add.b	d1,d1		;Inverses Carry -> X
		move.b	TMPS,d0		;Flags berechnen (wie im Binärmodus)
		move.b	TMPA,d1
		subx.b	d0,d1		;Flags berechnen
		scc	RCARRY		;Inverses Carry holen
		svs	ROVERFLOW	;Overflow holen
		tst.b	d1
		move	ccr,RCCR	;N und Z holen
		rts

SBCImm_2	ReadByteImm
		SbcA

SBCZero_2	ReadByteZero	SBCZero
		SbcA

SBCZeroX_2	ReadByteZeroX	SBCZeroX
		SbcA

SBCAbs_2	ReadByteAbs	SBCAbs
		SbcA

SBCAbsX_2	ReadByteAbsX	SBCAbsX
		SbcA

SBCAbsY_2	ReadByteAbsY	SBCAbsY
		SbcA

SBCIndX_2	ReadByteIndX	SBCIndX
		SbcA

SBCIndY_2	ReadByteIndY	SBCIndY
		SbcA


*
* Inkrement/Dekrement-Gruppe
*

Increment	MACRO
		move.b	RDBUF,d1
		move.w	RADR,d0
		addq.b	#1,d1
		move	ccr,RCCR
		bsr	WriteByte
		Last
		ENDM

INCZero_2	ReadRMWZero	INCZero
		Increment

INCZeroX_2	ReadRMWZeroX	INCZeroX
		Increment

INCAbs_2	ReadRMWAbs	INCAbs
		Increment

INCAbsX_2	ReadRMWAbsX	INCAbsX
		Increment


Decrement	MACRO
		move.b	RDBUF,d1
		move.w	RADR,d0
		subq.b	#1,d1
		move	ccr,RCCR
		bsr	WriteByte
		Last
		ENDM

DECZero_2	ReadRMWZero	DECZero
		Decrement

DECZeroX_2	ReadRMWZeroX	DECZeroX
		Decrement

DECAbs_2	ReadRMWAbs	DECAbs
		Decrement

DECAbsX_2	ReadRMWAbsX	DECAbsX
		Decrement


INX_2		ReadPC
		addq.b	#1,RX
		move	ccr,RCCR
		Last

INY_2		ReadPC
		addq.b	#1,RY
		move	ccr,RCCR
		Last

DEX_2		ReadPC
		subq.b	#1,RX
		move	ccr,RCCR
		Last

DEY_2		ReadPC
		subq.b	#1,RY
		move	ccr,RCCR
		Last


*
* Schiebe-/Rotations-Gruppe
*

ShiftLeft	MACRO
		move.b	RDBUF,d1
		move.w	RADR,d0
		add.b	d1,d1
		move	ccr,RCCR
		scs	RCARRY		;Carry holen
		bsr	WriteByte
		Last
		ENDM

ASLA_2		ReadPC
		move.b	RA,d0
		add.b	d0,d0
		move	ccr,RCCR
		scs	RCARRY		;Carry holen
		move.b	d0,RA
		Last

ASLZero_2	ReadRMWZero	ASLZero
		ShiftLeft

ASLZeroX_2	ReadRMWZeroX	ASLZeroX
		ShiftLeft

ASLAbs_2	ReadRMWAbs	ASLAbs
		ShiftLeft

ASLAbsX_2	ReadRMWAbsX	ASLAbsX
		ShiftLeft


ShiftRight	MACRO
		move.b	RDBUF,d1
		move.w	RADR,d0
		lsr.b	#1,d1
		move	ccr,RCCR
		scs	RCARRY		;Carry holen
		bsr	WriteByte
		Last
		ENDM

LSRA_2		ReadPC
		move.b	RA,d0
		lsr.b	#1,d0
		move	ccr,RCCR
		scs	RCARRY		;Carry holen
		move.b	d0,RA
		Last

LSRZero_2	ReadRMWZero	LSRZero
		ShiftRight

LSRZeroX_2	ReadRMWZeroX	LSRZeroX
		ShiftRight

LSRAbs_2	ReadRMWAbs	LSRAbs
		ShiftRight

LSRAbsX_2	ReadRMWAbsX	LSRAbsX
		ShiftRight


RotateLeft	MACRO
		move.b	RCARRY,d2
		move.b	RDBUF,d1
		move.w	RADR,d0
		add.b	d2,d2		;Carry -> X
		roxl.b	#1,d1		;Vorsicht bei addx und dem Z-Flag!
		move	ccr,RCCR
		scs	RCARRY		;Carry holen
		bsr	WriteByte
		Last
		ENDM

ROLA_2		ReadPC
		move.b	RCARRY,d2
		move.b	RA,d1
		add.b	d2,d2		;Carry -> X
		roxl.b	#1,d1		;Vorsicht bei addx und dem Z-Flag!
		move	ccr,RCCR
		scs	RCARRY		;Carry holen
		move.b	d1,RA
		Last

ROLZero_2	ReadRMWZero	ROLZero
		RotateLeft

ROLZeroX_2	ReadRMWZeroX	ROLZeroX
		RotateLeft

ROLAbs_2	ReadRMWAbs	ROLAbs
		RotateLeft

ROLAbsX_2	ReadRMWAbsX	ROLAbsX
		RotateLeft


RotateRight	MACRO
		move.b	RCARRY,d2
		move.b	RDBUF,d1
		move.w	RADR,d0
		add.b	d2,d2		;Carry -> X
		roxr.b	#1,d1
		move	ccr,RCCR
		scs	RCARRY		;Carry holen
		bsr	WriteByte
		Last
		ENDM

RORA_2		ReadPC
		move.b	RCARRY,d2
		move.b	RA,d1
		add.b	d2,d2		;Carry -> X
		roxr.b	#1,d1
		move	ccr,RCCR
		scs	RCARRY		;Carry holen
		move.b	d1,RA
		Last

RORZero_2	ReadRMWZero	RORZero
		RotateRight

RORZeroX_2	ReadRMWZeroX	RORZeroX
		RotateRight

RORAbs_2	ReadRMWAbs	RORAbs
		RotateRight

RORAbsX_2	ReadRMWAbsX	RORAbsX
		RotateRight


*
* Sprungbefehle
*

JMPAbs_2	ReadPCInc RADRL
		Next	JMPAbs_3
JMPAbs_3	ReadPC	RPC
		lsl.w	#8,RPC
		move.b	RADRL,RPC
		Last

JMPInd_2	ReadByteAbs	JMPInd,RPC
		addq.b	#1,RADRL	;Keine Seitenüberschreitung
		lsl.w	#8,RPC
		Next	JMPInd_5
JMPInd_5	ReadADR RPC
		ror.w	#8,RPC
		Last


JSR_2		ReadPCInc RADRL
		Next	JSR_3
JSR_3		ReadStack
		Next	JSR_4
JSR_4		move.w	RPC,d1
		lsr.w	#8,d1
		WriteStack
		DecS
		Next	JSR_5
JSR_5		move.b	RPC,d1
		WriteStack
		DecS
		Next	JSR_6
JSR_6		ReadPC	RPC
		lsl.w	#8,RPC
		move.b	RADRL,RPC
		Last

RTS_2		ReadPC
		Next	RTS_3
RTS_3		ReadStack
		IncS
		Next	RTS_4
RTS_4		ReadStack RADRL
		IncS
		Next	RTS_5
RTS_5		ReadStack RPC
		lsl.w	#8,RPC
		move.b	RADRL,RPC
		Next	RTS_6
RTS_6		ReadPCInc
		Last


BRK_2		ReadPC
		Next	BRK_3
BRK_3		move.w	RPC,d1
		lsr.w	#8,d1
		WriteStack
		DecS
		Next	BRK_4
BRK_4		move.b	RPC,d1
		WriteStack
		DecS
		Next	BRK_5
BRK_5		PushP	1		;B auf 1
		Next	BRK_6
BRK_6		st	RINTERRUPT
		move.w	#$fffe,d0	;IRQ-Vektor
		bsr	ReadByte
		move.b	d0,RPC
		lsl.w	#8,RPC
		Next	BRK_7
BRK_7		move.w	#$ffff,d0
		bsr	ReadByte
		move.b	d0,RPC
		ror.w	#8,RPC
		Last


RTI_2		ReadPC
		Next	RTI_3
RTI_3		ReadStack
		IncS
		Next	RTI_4
RTI_4		PopP
		IncS
		Next	RTI_5
RTI_5		ReadStack RADRL
		IncS
		Next	RTI_6
RTI_6		ReadStack RPC
		lsl.w	#8,RPC
		move.b	RADRL,RPC
		Last


*
* Verzweigungsbefehle
*

BranchB		MACRO	;Name des Opcodes, zu testendes Bit, 0/1
			;Also: Verzweige, wenn Bit \2 in RCCR gleich \4 ist
		ReadByteImm RADRL
		btst	#\2,RCCR+1	;Verzweigung genommen?
	IFEQ	\3
		beq	\1Yes
	ELSE
		bne	\1Yes
	ENDC
		Last			;Nein, nächster Opcode
\1Yes		Next	\1_3
\1_3		ReadPC
		move.b	RADRL,d0	;Ja, PC erhöhen
		bpl	\1Forward
		neg.b	d0		;Sprung zurück, Seitenüberschreitung?
		sub.b	d0,RPC
		bcs	\1BPage
		Last			;Nein, nächster Opcode
\1BPage		Next	\1_4b
\1_4b		ReadPC			;Ja, PC korrigieren
		sub.w	#$100,RPC
		Last
\1Forward	add.b	d0,RPC		;Sprung nach vorne, Seitenüberschreitung?
		bcs	\1FPage
		Last			;Nein, nächster Opcode
\1FPage		Next	\1_4f
\1_4f		ReadPC
		add.w	#$100,RPC	;Ja, PC korrigieren
		Last
		ENDM

BranchF		MACRO	;Name des Opcodes, Flag, 0/1
			;Also: Verzweige, wenn \2 gleich \3 ist
		ReadByteImm RADRL
		tst.b	\2		;Verzweigung genommen?
	IFEQ	\3
		beq	\1Yes
	ELSE
		bne	\1Yes
	ENDC
		Last			;Nein, nächster Opcode
\1Yes		Next	\1_3
\1_3		ReadPC
		move.b	RADRL,d0	;Ja, PC erhöhen
		bpl	\1Forward
		neg.b	d0		;Sprung zurück, Seitenüberschreitung?
		sub.b	d0,RPC
		bcs	\1BPage
		Last			;Nein, nächster Opcode
\1BPage		Next	\1_4b
\1_4b		ReadPC			;Ja, PC korrigieren
		sub.w	#$100,RPC
		Last
\1Forward	add.b	d0,RPC		;Sprung nach vorne, Seitenüberschreitung?
		bcs	\1FPage
		Last			;Nein, nächster Opcode
\1FPage		Next	\1_4f
\1_4f		ReadPC
		add.w	#$100,RPC	;Ja, PC korrigieren
		Last
		ENDM

BVC_2		BranchF	BVC,ROVERFLOW,0

BVS_2		BranchF	BVS,ROVERFLOW,1

BEQ_2		BranchB	BEQ,2,1

BNE_2		BranchB	BNE,2,0

BPL_2		BranchB	BPL,3,0

BMI_2		BranchB	BMI,3,1

BCC_2		BranchF	BCC,RCARRY,0

BCS_2		BranchF	BCS,RCARRY,1


*
* Flag-Gruppe
*

CLI_2		ReadPC
		clr.b	RINTERRUPT
		Last

SEI_2		ReadPC
		st	RINTERRUPT
		Last

CLC_2		ReadPC
		clr.b	RCARRY
		Last

SEC_2		ReadPC
		st	RCARRY
		Last

CLD_2		ReadPC
		clr.b	RDECIMAL
		Last

SED_2		ReadPC
		st	RDECIMAL
		Last

CLV_2		ReadPC
		clr.b	ROVERFLOW
		Last


*
* NOPs
*

NOPImpl_2	ReadPC
		Last

NOPImm_2	ReadByteImm
		Last

NOPZero_2	ReadByteZero	NOPZero
		Last

NOPZeroX_2	ReadByteZeroX	NOPZeroX
		Last

NOPAbs_2	ReadByteAbs	NOPAbs
		Last

NOPAbsX_2	ReadByteAbsX	NOPAbsX
		Last


*
* ASL/ORA-Gruppe (SLO)
*

ShiftLeftOr	MACRO
		move.b	RDBUF,d1
		move.w	RADR,d0
		add.b	d1,d1
		scs	RCARRY		;Carry holen
		or.b	d1,RA
		move	ccr,RCCR
		bsr	WriteByte
		Last
		ENDM

SLOZero_2	ReadRMWZero	SLOZero
		ShiftLeftOr

SLOZeroX_2	ReadRMWZeroX	SLOZeroX
		ShiftLeftOr

SLOAbs_2	ReadRMWAbs	SLOAbs
		ShiftLeftOr

SLOAbsX_2	ReadRMWAbsX	SLOAbsX
		ShiftLeftOr

SLOAbsY_2	ReadRMWAbsY	SLOAbsY
		ShiftLeftOr

SLOIndX_2	ReadRMWIndX	SLOIndX
		ShiftLeftOr

SLOIndY_2	ReadRMWIndY	SLOIndY
		ShiftLeftOr


*
* ROL/AND-Gruppe (RLA)
*

RotateLeftAnd	MACRO
		move.b	RCARRY,d2
		move.b	RDBUF,d1
		move.w	RADR,d0
		add.b	d2,d2		;Carry -> X
		roxl.b	#1,d1
		scs	RCARRY		;Carry holen
		and.b	d1,RA
		move	ccr,RCCR
		bsr	WriteByte
		Last
		ENDM

RLAZero_2	ReadRMWZero	RLAZero
		RotateLeftAnd

RLAZeroX_2	ReadRMWZeroX	RLAZeroX
		RotateLeftAnd

RLAAbs_2	ReadRMWAbs	RLAAbs
		RotateLeftAnd

RLAAbsX_2	ReadRMWAbsX	RLAAbsX
		RotateLeftAnd

RLAAbsY_2	ReadRMWAbsY	RLAAbsY
		RotateLeftAnd

RLAIndX_2	ReadRMWIndX	RLAIndX
		RotateLeftAnd

RLAIndY_2	ReadRMWIndY	RLAIndY
		RotateLeftAnd


*
* LSR/EOR-Gruppe (SRE)
*

ShiftRightEor	MACRO
		move.b	RDBUF,d1
		move.w	RADR,d0
		lsr.b	#1,d1
		scs	RCARRY		;Carry holen
		eor.b	d1,RA
		move	ccr,RCCR
		bsr	WriteByte
		Last
		ENDM

SREZero_2	ReadRMWZero	SREZero
		ShiftRightEor

SREZeroX_2	ReadRMWZeroX	SREZeroX
		ShiftRightEor

SREAbs_2	ReadRMWAbs	SREAbs
		ShiftRightEor

SREAbsX_2	ReadRMWAbsX	SREAbsX
		ShiftRightEor

SREAbsY_2	ReadRMWAbsY	SREAbsY
		ShiftRightEor

SREIndX_2	ReadRMWIndX	SREIndX
		ShiftRightEor

SREIndY_2	ReadRMWIndY	SREIndY
		ShiftRightEor


*
* ROR/ADC-Gruppe (RRA)
*

RotateRightAdc	MACRO
		move.b	RCARRY,d2
		move.b	RDBUF,d1
		move.w	RADR,d0
		add.b	d2,d2		;Carry -> X
		roxr.b	#1,d1
		scs	RCARRY		;Carry holen
		move.b	RA,d2
		addx.b	d1,d2
		svs	ROVERFLOW	;Overflow holen
		move.b	d2,RA
		move	ccr,RCCR
		bsr	WriteByte
		Last
		ENDM

RRAZero_2	ReadRMWZero	RRAZero
		RotateRightAdc

RRAZeroX_2	ReadRMWZeroX	RRAZeroX
		RotateRightAdc

RRAAbs_2	ReadRMWAbs	RRAAbs
		RotateRightAdc

RRAAbsX_2	ReadRMWAbsX	RRAAbsX
		RotateRightAdc

RRAAbsY_2	ReadRMWAbsY	RRAAbsY
		RotateRightAdc

RRAIndX_2	ReadRMWIndX	RRAIndX
		RotateRightAdc

RRAIndY_2	ReadRMWIndY	RRAIndY
		RotateRightAdc


*
* DEC/CMP-Gruppe (DCP)
*

DecCompare	MACRO
		move.b	RA,d2
		move.b	RDBUF,d1
		move.w	RADR,d0
		subq.b	#1,d1
		cmp.b	d1,d2
		move	ccr,RCCR
		scc	RCARRY		;Inverses Carry holen
		bsr	WriteByte
		Last
		ENDM

DCPZero_2	ReadRMWZero	DCPZero
		DecCompare

DCPZeroX_2	ReadRMWZeroX	DCPZeroX
		DecCompare

DCPAbs_2	ReadRMWAbs	DCPAbs
		DecCompare

DCPAbsX_2	ReadRMWAbsX	DCPAbsX
		DecCompare

DCPAbsY_2	ReadRMWAbsY	DCPAbsY
		DecCompare

DCPIndX_2	ReadRMWIndX	DCPIndX
		DecCompare

DCPIndY_2	ReadRMWIndY	DCPIndY
		DecCompare


*
* INC/SBC-Gruppe (ISB)
*

IncSbc		MACRO
		move.b	RCARRY,d2
		move.b	RDBUF,d1
		not.b	d2
		move.w	RADR,d0
		addq.b	#1,d1
		add.b	d2,d2		;Inverses Carry -> X
		move.b	RA,d2
		subx.b	d1,d2
		scc	RCARRY		;Inverses Carry holen
		svs	ROVERFLOW	;Overflow holen
		move.b	d2,RA
		move	ccr,RCCR
		bsr	WriteByte
		Last
		ENDM

ISBZero_2	ReadRMWZero	ISBZero
		IncSbc

ISBZeroX_2	ReadRMWZeroX	ISBZeroX
		IncSbc

ISBAbs_2	ReadRMWAbs	ISBAbs
		IncSbc

ISBAbsX_2	ReadRMWAbsX	ISBAbsX
		IncSbc

ISBAbsY_2	ReadRMWAbsY	ISBAbsY
		IncSbc

ISBIndX_2	ReadRMWIndX	ISBIndX
		IncSbc

ISBIndY_2	ReadRMWIndY	ISBIndY
		IncSbc


*
* Unübliche Befehle
*

ANCImm_2	ReadByteImm		;??? ($0b, $2b)
		and.b	d0,RA
		move	ccr,RCCR
		smi	RCARRY		;N -> C (??)
		Last

SBXImm_2	ReadByteImm
		move.b	RX,d1
		and.b	RA,d1
		sub.b	d0,d1
		move	ccr,RCCR
		scc	RCARRY		;Inverses Carry holen
		move.b	d1,RX
		Last


*
* Erweiterte Opcodes
*

; $f2 $xx
OpIEC		ReadPCInc
		tst.b	d0
		beq	OpIECOut
		cmp.b	#1,d0
		beq	OpIECOutATN
		cmp.b	#2,d0
		beq	OpIECOutSec
		cmp.b	#3,d0
		beq	OpIECIn
		cmp.b	#4,d0
		beq	OpIECSetATN
		cmp.b	#5,d0
		beq	OpIECRelATN
		cmp.b	#6,d0
		beq	OpIECTurnaround
		cmp.b	#7,d0
		beq	OpIECRelease
		bra	IllegalOp

OpIECOut	move.b	$95(RAMPTR),d0	;Auszugebendes Byte holen
		move.b	$a3(RAMPTR),d1	;EOI-Flag holen
		jsr	IECOut
		bra	IECSetST

OpIECOutATN	move.b	$95(RAMPTR),d0	;Auszugebendes Byte holen
		jsr	IECOutATN
		bra	IECSetST

OpIECOutSec	move.b	$95(RAMPTR),d0	;Auszugebendes Byte holen
		jsr	IECOutSec
		bra	IECSetST

OpIECIn		jsr	IECIn
		move.b	d1,RA		;Byte in den Akku
		move	ccr,RCCR	;Flags entsprechend setzen
		bra	IECSetST

OpIECSetATN	jsr	IECSetATN
		move.w	#$edfb,RPC	;Nach $edfb springen
		Last

OpIECRelATN	jsr	IECRelATN
		bra	IECReturn

OpIECTurnaround	jsr	IECTurnaround
		bra	IECReturn

OpIECRelease	jsr	IECRelease
		bra	IECReturn

IECSetST	or.b	d0,$90(RAMPTR)	;Status setzen
		clr.b	RCARRY		;Carry löschen
IECReturn	bra	RTS_2		;RTS ausführen


**
** Konstanten
**

*
* Opcode Dispatch Table
* Jeder Eintrag zeigt auf die erste Zyklusroutine (d.h. die Routine
* des zweiten Zyklus) eines Opcodes
* "*" bezeichnet einen undokumentierten Opcode
*

		CNOP	0,4
OpcodeTable	dc.l	BRK_2		;$00
		dc.l	ORAIndX_2
		dc.l	IllegalOp
		dc.l	SLOIndX_2	;*
		dc.l	NOPZero_2	;*
		dc.l	ORAZero_2
		dc.l	ASLZero_2
		dc.l	SLOZero_2	;*

		dc.l	PHP_2		;$08
		dc.l	ORAImm_2
		dc.l	ASLA_2
		dc.l	ANCImm_2	;*
		dc.l	NOPAbs_2	;*
		dc.l	ORAAbs_2
		dc.l	ASLAbs_2
		dc.l	SLOAbs_2	;*

		dc.l	BPL_2		;$10
		dc.l	ORAIndY_2
		dc.l	IllegalOp
		dc.l	SLOIndY_2	;*
		dc.l	NOPZeroX_2	;*
		dc.l	ORAZeroX_2
		dc.l	ASLZeroX_2
		dc.l	SLOZeroX_2	;*

		dc.l	CLC_2		;$18
		dc.l	ORAAbsY_2
		dc.l	NOPImpl_2	;*
		dc.l	SLOAbsY_2	;*
		dc.l	NOPAbsX_2	;*
		dc.l	ORAAbsX_2
		dc.l	ASLAbsX_2
		dc.l	SLOAbsX_2	;*

		dc.l	JSR_2		;$20
		dc.l	ANDIndX_2
		dc.l	IllegalOp
		dc.l	RLAIndX_2	;*
		dc.l	BITZero_2
		dc.l	ANDZero_2
		dc.l	ROLZero_2
		dc.l	RLAZero_2	;*

		dc.l	PLP_2		;$28
		dc.l	ANDImm_2
		dc.l	ROLA_2
		dc.l	ANCImm_2	;*
		dc.l	BITAbs_2
		dc.l	ANDAbs_2
		dc.l	ROLAbs_2
		dc.l	RLAAbs_2	;*

		dc.l	BMI_2		;$30
		dc.l	ANDIndY_2
		dc.l	IllegalOp
		dc.l	RLAIndY_2	;*
		dc.l	NOPZeroX_2	;*
		dc.l	ANDZeroX_2
		dc.l	ROLZeroX_2
		dc.l	RLAZeroX_2	;*

		dc.l	SEC_2		;$38
		dc.l	ANDAbsY_2
		dc.l	NOPImpl_2	;*
		dc.l	RLAAbsY_2	;*
		dc.l	NOPAbsX_2	;*
		dc.l	ANDAbsX_2
		dc.l	ROLAbsX_2
		dc.l	RLAAbsX_2	;*

		dc.l	RTI_2		;$40
		dc.l	EORIndX_2
		dc.l	IllegalOp
		dc.l	SREIndX_2	;*
		dc.l	NOPZero_2	;*
		dc.l	EORZero_2
		dc.l	LSRZero_2
		dc.l	SREZero_2	;*

		dc.l	PHA_2		;$48
		dc.l	EORImm_2
		dc.l	LSRA_2
		dc.l	IllegalOp
		dc.l	JMPAbs_2
		dc.l	EORAbs_2
		dc.l	LSRAbs_2
		dc.l	SREAbs_2	;*

		dc.l	BVC_2		;$50
		dc.l	EORIndY_2
		dc.l	IllegalOp
		dc.l	SREIndY_2	;*
		dc.l	NOPZeroX_2	;*
		dc.l	EORZeroX_2
		dc.l	LSRZeroX_2
		dc.l	SREZeroX_2	;*

		dc.l	CLI_2		;$58
		dc.l	EORAbsY_2
		dc.l	NOPImpl_2	;*
		dc.l	SREAbsY_2	;*
		dc.l	NOPAbsX_2	;*
		dc.l	EORAbsX_2
		dc.l	LSRAbsX_2
		dc.l	SREAbsX_2	;*

		dc.l	RTS_2		;$60
		dc.l	ADCIndX_2
		dc.l	IllegalOp
		dc.l	RRAIndX_2	;*
		dc.l	NOPZero_2	;*
		dc.l	ADCZero_2
		dc.l	RORZero_2
		dc.l	RRAZero_2	;*

		dc.l	PLA_2		;$68
		dc.l	ADCImm_2
		dc.l	RORA_2
		dc.l	IllegalOp
		dc.l	JMPInd_2
		dc.l	ADCAbs_2
		dc.l	RORAbs_2
		dc.l	RRAAbs_2	;*

		dc.l	BVS_2		;$70
		dc.l	ADCIndY_2
		dc.l	IllegalOp
		dc.l	RRAIndY_2	;*
		dc.l	NOPZeroX_2	;*
		dc.l	ADCZeroX_2
		dc.l	RORZeroX_2
		dc.l	RRAZeroX_2	;*

		dc.l	SEI_2		;$78
		dc.l	ADCAbsY_2
		dc.l	NOPImpl_2	;*
		dc.l	RRAAbsY_2	;*
		dc.l	NOPAbsX_2	;*
		dc.l	ADCAbsX_2
		dc.l	RORAbsX_2
		dc.l	RRAAbsX_2	;*

		dc.l	NOPImm_2	;* $80
		dc.l	STAIndX_2
		dc.l	NOPImm_2	;*
		dc.l	SAXIndX_2	;*
		dc.l	STYZero_2
		dc.l	STAZero_2
		dc.l	STXZero_2
		dc.l	SAXZero_2	;*

		dc.l	DEY_2		;$88
		dc.l	NOPImm_2	;*
		dc.l	TXA_2
		dc.l	IllegalOp
		dc.l	STYAbs_2
		dc.l	STAAbs_2
		dc.l	STXAbs_2
		dc.l	SAXAbs_2	;*

		dc.l	BCC_2		;$90
		dc.l	STAIndY_2
		dc.l	IllegalOp
		dc.l	IllegalOp
		dc.l	STYZeroX_2
		dc.l	STAZeroX_2
		dc.l	STXZeroY_2
		dc.l	SAXZeroY_2	;*

		dc.l	TYA_2		;$98
		dc.l	STAAbsY_2
		dc.l	TXS_2
		dc.l	IllegalOp
		dc.l	IllegalOp
		dc.l	STAAbsX_2
		dc.l	IllegalOp
		dc.l	IllegalOp

		dc.l	LDYImm_2	;$a0
		dc.l	LDAIndX_2
		dc.l	LDXImm_2
		dc.l	IllegalOp
		dc.l	LDYZero_2
		dc.l	LDAZero_2
		dc.l	LDXZero_2
		dc.l	LAXZero_2	;*

		dc.l	TAY_2		;$a8
		dc.l	LDAImm_2
		dc.l	TAX_2
		dc.l	IllegalOp
		dc.l	LDYAbs_2
		dc.l	LDAAbs_2
		dc.l	LDXAbs_2
		dc.l	LAXAbs_2	;*

		dc.l	BCS_2		;$b0
		dc.l	LDAIndY_2
		dc.l	IllegalOp
		dc.l	IllegalOp
		dc.l	LDYZeroX_2
		dc.l	LDAZeroX_2
		dc.l	LDXZeroY_2
		dc.l	LAXZeroY_2	;*

		dc.l	CLV_2		;$b8
		dc.l	LDAAbsY_2
		dc.l	TSX_2
		dc.l	IllegalOp
		dc.l	LDYAbsX_2
		dc.l	LDAAbsX_2
		dc.l	LDXAbsY_2
		dc.l	LAXAbsY_2	;*

		dc.l	CPYImm_2	;$c0
		dc.l	CMPIndX_2
		dc.l	NOPImm_2	;*
		dc.l	DCPIndX_2	;*
		dc.l	CPYZero_2
		dc.l	CMPZero_2
		dc.l	DECZero_2
		dc.l	DCPZero_2	;*

		dc.l	INY_2		;$c8
		dc.l	CMPImm_2
		dc.l	DEX_2
		dc.l	SBXImm_2	;*
		dc.l	CPYAbs_2
		dc.l	CMPAbs_2
		dc.l	DECAbs_2
		dc.l	DCPAbs_2	;*

		dc.l	BNE_2		;$d0
		dc.l	CMPIndY_2
		dc.l	IllegalOp
		dc.l	DCPIndY_2	;*
		dc.l	NOPZeroX_2	;*
		dc.l	CMPZeroX_2
		dc.l	DECZeroX_2
		dc.l	DCPZeroX_2	;*

		dc.l	CLD_2		;$d8
		dc.l	CMPAbsY_2
		dc.l	NOPImpl_2	;*
		dc.l	DCPAbsY_2	;*
		dc.l	NOPAbsX_2	;*
		dc.l	CMPAbsX_2
		dc.l	DECAbsX_2
		dc.l	DCPAbsX_2	;*

		dc.l	CPXImm_2	;$e0
		dc.l	SBCIndX_2
		dc.l	NOPImm_2	;*
		dc.l	ISBIndX_2	;*
		dc.l	CPXZero_2
		dc.l	SBCZero_2
		dc.l	INCZero_2
		dc.l	ISBZero_2	;*

		dc.l	INX_2		;$e8
		dc.l	SBCImm_2
		dc.l	NOPImpl_2
		dc.l	SBCImm_2	;*
		dc.l	CPXAbs_2
		dc.l	SBCAbs_2
		dc.l	INCAbs_2
		dc.l	ISBAbs_2	;*

		dc.l	BEQ_2		;$f0
		dc.l	SBCIndY_2
		dc.l	OpIEC		;Patch
		dc.l	ISBIndY_2	;*
		dc.l	NOPZeroX_2	;*
		dc.l	SBCZeroX_2
		dc.l	INCZeroX_2
		dc.l	ISBZeroX_2	;*

		dc.l	SED_2		;$f8
		dc.l	SBCAbsY_2
		dc.l	NOPImpl_2	;*
		dc.l	ISBAbsY_2	;*
		dc.l	NOPAbsX_2	;*
		dc.l	SBCAbsX_2
		dc.l	INCAbsX_2
		dc.l	ISBAbsX_2	;*


*
* Speicherkonfigurationstabelle
*

; Diese Tabelle enthält für alle 8 Speicherkonfigurationen
; die Zeiger auf die zugehörigen Read- und WriteTabs
ConfigTab	dc.l	ReadTab0,WriteTab0
		dc.l	ReadTab1,WriteTab1
		dc.l	ReadTab2,WriteTab2
		dc.l	ReadTab3,WriteTab3
		dc.l	ReadTab4,WriteTab4
		dc.l	ReadTab5,WriteTab5
		dc.l	ReadTab6,WriteTab6
		dc.l	ReadTab7,WriteTab7

*
* Sonstige Konstanten
*

; Taglist für CreateNewProc
ProcTags	dc.l	NP_Entry,CPUTaskProc
		dc.l	NP_Name,CPUTaskName
		dc.l	NP_Priority,-1
		dc.l	0

; Strings
CPUTaskName	dc.b	"6510",0

; Flag: Dies ist Frodo SC
		CNOP	0,4
_IsFrodoSC
IsFrodoSC	dc.w	1


**
** Initialisierte Daten
**

		SECTION	"DATA",DATA

; Requester
IllegalOpReq	dc.l	20,0,0,0,0


**
** Nicht initialisierte Daten
**

		SECTION	"BSS",BSS

; Sprungtabellen für Speicherzugriff: Ein Eintrag pro Seite
; Eine Tabelle für jede der 8 Speicherkonfigurationen
ReadTab0	ds.l	256
ReadTab1	ds.l	256
ReadTab2	ds.l	256
ReadTab3	ds.l	256
ReadTab4	ds.l	256
ReadTab5	ds.l	256
ReadTab6	ds.l	256
ReadTab7	ds.l	256

WriteTab0	ds.l	256
WriteTab1	ds.l	256
WriteTab2	ds.l	256
WriteTab3	ds.l	256
WriteTab4	ds.l	256
WriteTab5	ds.l	256
WriteTab6	ds.l	256
WriteTab7	ds.l	256


		SECTION	"__MERGED",BSS

; 6510-Task
CPUProc		ds.l	1	;Prozess-Handle
		XDEF	_CPUTask
_CPUTask
CPUTask		ds.l	1	;Task des Prozesses
InitialSP	ds.l	1	;Stackpointer
ReadySet	ds.l	1	;Signal des Hauptprogramms
_InvokeSAMSet
InvokeSAMSet	ds.l	1	;Signal -> Hauptprogramm: SAM aufrufen
ContinueSet	ds.l	1	;Signal des CPU-Tasks
ReadySig	ds.b	1
InvokeSAMSig	ds.b	1
ContinueSig	ds.b	1

; 6510-Register
		CNOP	0,4
RA		ds.b	1	;A
RX		ds.b	1	;X
RY		ds.b	1	;Y
RDBUF		ds.b	1	;Puffer für RMW-Befehle
RS		ds.w	1	;S (16-Bit, $01xx)
RCCR		ds.w	1	;CCR, nur N und Z
RCARRY		ds.b	1	;6510-Carry
ROVERFLOW	ds.b	1	;6510-Overflow-Flag
RDECIMAL	ds.b	1	;6510-Dezimalflag
RINTERRUPT	ds.b	1	;6510-Interruptflag
RADR
RADRH		ds.b	1	;Adreß-Latch
RADRL		ds.b	1
RADR2
RADR2H		ds.b	1	;Zweites Adreß-Latch für indiziert-indirekt
RADR2L		ds.b	1
RPR		ds.b	1	;Prozessorport Datenregister
RDDR		ds.b	1	;Prozessorport Datenrichtungsregister

; Zwischenspeicher für Adc/Sbc im Dezimalmodus
TMPS		ds.b	1
TMPA		ds.b	1

	IFNE	DEBUG_DETAIL
DEBUGON		ds.b	1
	ENDC

; Zeiger auf die der aktuellen Speicherkonfiguration entsprechenden
;  Read/WriteTab
		CNOP	0,4
RDTAB		ds.l	1
WRTAB		ds.l	1

; Speicherzeiger
TheRAM		ds.l	1	;Zeiger auf C64-RAM (64K)
TheRAMPTR	ds.l	1	;Zeiger auf C64-RAM, Offset 32K (für Adressierung mit Vorzeichen)
TheBasic	ds.l	1	;Zeiger auf Basic-ROM
TheKernal	ds.l	1	;Zeiger auf Kernal-ROM
TheChar		ds.l	1	;Zeiger auf Char-ROM
TheColor	ds.l	1	;Zeiger auf Farb-RAM

; Interrupt-Flags. Bei einem Interrupt wird eins dieser Flags gesetzt.
; Das bewirkt, daß beim nächsten Opcode-Fetch der 6510-Task in die
; Routine "HandleInt" springt. Dort werden diese Flags ausgewertet und
; entsprechend verzweigt.
		CNOP	0,4
Interrupt			;Zusammenfassung als Langwort
IntIsRESET	ds.b	1	;RESET aufgetreten, 6510 beenden oder Pause
IntIsNMI	ds.b	1	;NMI aufgetreten
IntIsIRQ			;Zusammenfassung als Wort
IntIsVICIRQ	ds.b	1	;IRQ durch VIC aufgetreten
IntIsCIAIRQ	ds.b	1	;IRQ durch CIA-A aufgetreten

FirstIRQCycle	ds.l	1	;Zyklus, an dem IRQ zuletzt auf low ging
FirstNMICycle	ds.l	1	;Zyklus, an dem NMI zuletzt auf low ging

RESETIsEXIT	ds.b	1	;Zur Unterscheidung von RESET und EXIT
RESETIsPause	ds.b	1	;Zur Unterscheidung von RESET und Pause

NMIState	ds.b	1	;Aktueller Zustand der NMI-Leitung (für Flankentriggerung)

; Bus Available vom VIC
BALow		ds.b	1

; Zwischenspeicher für Lesezugriff mit BA
		CNOP	0,4
HALTCONTSTORE	ds.l	1
HALTRETADR	ds.l	1
HALTADRSTORE	ds.w	1

; Argumente für EasyRequest
		CNOP	0,4
RequestStream	ds.l	16

; Registerinhalte für SAM, nur gültig innerhalb von Pause6510/Resume6510
		XDEF	_RA
_RA		ds.b	1
		XDEF	_RX
_RX		ds.b	1
		XDEF	_RY
_RY		ds.b	1
		XDEF	_RP
_RP		ds.b	1
		XDEF	_RPR
_RPR		ds.b	1
		XDEF	_RDDR
_RDDR		ds.b	1
		XDEF	_RPC
_RPC		ds.w	1
		XDEF	_RS
_RS		ds.w	1

		XDEF	_SAMMemConfig
_SAMMemConfig	ds.b	1	;CHAREN, LORAM, HIRAM

		END
