home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Brotikasten
/
BROTCD01.iso
/
amiga
/
frodov13.lha
/
src
/
6510.asm
< prev
next >
Wrap
Assembly Source File
|
1995-02-22
|
57KB
|
3,093 lines
*
* 6510.asm - 6510-Emulation (eigener Task)
*
* Copyright (C) 1994-1995 by Christian Bauer
*
*
* Anmerkungen:
* ------------
*
* Register d0/d1 - WICHTIG:
* - Der Emulator geht davon aus, da▀ die MSWs von d0 und d1 immer Null
* sind. Denn dadurch kann das C64-RAM mittels (RAMPTR,d0.l) ohne
* Vorzeichen indiziert angesprochen werden.
* - Die Makros Read#?Zero#? und Read#?Ind#? gehen zusΣtlich davon aus,
* da▀ nur das untere Byte von d0 Null ist, da diese Makros immer nur
* am Anfang eines Befehls stehen und d0 vom Next-Makro noch gel÷scht
* ist
*
* 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:
* - Fast alle Speicherzugriffe laufen ⁿber die ReadByte/WriteByte-Makros,
* die die eingestellte Speicherkonfiguration dadurch berⁿcksichtigen,
* da▀ die oberen 8 Adre▀bits als Index in eine Sprungtabelle
* (ReadTab/WriteTab) dienen, die Zeiger auf die ReadByte*/WriteByte*-
* Routinen enthalten, ⁿber die der tatsΣchliche Zugriff erfolgt.
* Fⁿr jede der 8 Speicherkonfigurationen existiert jeweils eine solche
* Tabelle Bei einer ─nderung der Speicherkonfiguration (NewConfig)
* werden die Zeiger auf die Tabellen (RDTAB/WRTAB) geΣndert.
* - Das LESEN aus der Zero-Page geschieht immer direkt,
* da dort keine Register liegen ($01 wird auch im RAM abgelegt)
* - Beim Schreiben in die Zero-Page wird nur auf $00/$01 getestet,
* ansonsten direkt zugegriffen
* - Der Stack wird immer direkt angesprochen
* - Die ReadByte-Routinen dⁿrfen nur d0-d1/a0 verΣndern.
* a1 enthΣlt die Rⁿcksprungadresse, die Routinen mⁿssen also mit
* "jmp (a1)" enden.
* - Die WriteByte-Routinen dⁿrfen nur d0-d1/a0-a1 verΣndern
*
* ProgrammzΣhler:
* - Aus Geschwindigkeitsgrⁿnden wird der PC durch einen 32-Bit-
* Amiga-Zeiger reprΣsentiert und ⁿber diesen direkt auf den
* Speicher zugegriffen (und nicht ⁿber ReadByte). Bei einem
* Sprungbefehl wird aus dem 16-Bit Sprungziel und der aktuellen
* Speicherkonfiguration die neue 32-Bit-Adresse berechnet,
* indem Σhnlich zur ReadTab die oberen 8 Bit des Sprungziels
* als Index in die JumpTab verwendet werden. Die darⁿber aufgerufenen
* Routinen fⁿhren die Umrechnung durch.
* - Durch die Art, wie das Hauptprogramm den Speicher anfordert,
* entsprechen die unteren 16 Bit des 32-Bit-PCs immer der
* 16-Bit-C64-Adresse. Das erleichtert erheblich das Ablegen des
* PC auf dem Stack, da dazu einfach nur die unteren 16 Bit
* genommen werden mⁿssen (ansonsten mⁿ▀te man je nach RAM/ROM-
* Bereich erst die jeweilige Basisadresse subtrahieren).
* - Durch diese Art der PC-Verwaltung bestehen folgende InkompatibilitΣten:
* - Es gibt keinen Wraparound ⁿber Adresse $ffff/$0000 hinweg
* - Ein Branch oder ein Hineinlaufen in einen anderen Speicherbereich
* (z.B. RAM->ROM) funktioniert nicht. Das sollte allerdings kein
* Problem darstellen.
* - Ein Sprung in den I/O-Bereich ist z.Z. nicht m÷glich
*
* Condition-Codes:
* - Die Emulation verwendet zwei Register, um die Prozessorflags zu
* speichern: RCCR und RP.
* - RCCR ist ein Abbild des 680x0-CCR und wird nach den entsprechenden
* Operationen mit "move ccr,RCCR" gelesen. Von RCCR werden nur das N-
* und das Z-Flag verwendet.
* - Die einzigen Opcodes, die V Σndern, sind ADC, SBC, CLV, PLP und RTI.
* Darum wird das V-Flag nicht aus dem 680x0-V-Flag erzeugt, sondern
* gegebenenfalls von Hand gesetzt.
* - Im oberen Byte (Bit 8-15) von RP sind die 6510-Flags V,B,D und I
* in der selben Anordnung wie beim 6510 gespeichert. Das untere Byte
* enthΣlt in Bit 0 das Carry-Flag in 6510-Interpretation (bei SBC und
* CMP/CPX/CPY inverse Bedeutung zum 680x0), das bei den entsprechenden
* Opcodes aus dem CCR gelesen (und ggf. invertiert) wird. Der Einfachheit
* halber wird immer das ganze untere Byte von CCR gelesen, da nur Bit 0
* interessant ist.
*
* Opcode-Ausfⁿhrung:
* - Es gibt keine Fetch-Decode-Schleife, sondern jede Opcode-Routine
* enthΣlt am Schlu▀ den Code, der den nΣchsten Befehl ausfⁿhrt
* ("Next"-Makro).
* - Die Verzweigung in die einzelnen Opcode-Routinen geschieht ⁿber
* eine Sprungtabelle, die OpcodeTable. Das Register OPTABPTR enthΣlt
* einen Zeiger auf diese Tabelle (vor der Tabelle steht noch der
* ZyklenzΣhler, auf den so schneller zugegriffen werden kann).
*
* ZyklenzΣhler/Periodic/Interrupts:
* - Die Variable CyclesLeft (erreichbar ⁿber (OPTABPTR)) enthΣlt die
* Anzahl Zyklen, die dem 6510 in der augenblicklichen Rasterzeile noch
* zur Verfⁿgung stehen
* - Nach jeder Opcode-Ausfⁿhrung wird dieser ZΣhler um die Zyklenzahl
* des gerade ausgefⁿhrten Befehls erniedrigt. Dazu wird dem Next-Makro
* die Anzahl Zyklen ⁿbergeben. Unterschreitet der ZΣhler Null, wird
* die Routine "Periodic" aufgerufen.
* - In dieser Routine werden die Unterroutinen von VIC und CIA
* ausgefⁿhrt, die die Aktionen fⁿr eine Rasterzeile durchfⁿhren
* (VIC (Periodic6569): Eine Bildschirmzeile aufbauen, CIA
* (Periodic6526): Timer zΣhlen)
* - In Periodic6569 wird der ZyklenzΣhler neu gesetzt (der Wert hΣngt
* davon ab, ob eine Bad Line stattfand oder nicht)
*
* Interrupts:
* - Die Haupt-Interruptquellen sind VIC und CIA, daher prⁿft der
* Emulator das Auftreten eines Interrupts im Rahmen der Periodic-
* Routine
* - Es gibt folgende Interrupt-M÷glichkeiten (PrioritΣten):
* - RESET, Sprung nach ($FFFC) oder 6510-Task beenden (RESETIsEXIT-Flag)
* - NMI, Sprung nach ($FFFA)
* - VIC-IRQ, I-Flag wird geprⁿft, Sprung nach ($FFFE)
* - CIA-IRQ, I-Flag wird geprⁿft, Sprung nach ($FFFE)
* - Die Aufteilung in VIC- und CIA-IRQ erleichtert die Handhabung, wenn
* beide IRQs gleichzeitig auftreten
* - Die einzige M÷glichkeit, au▀erhalb des Periodic einen Interrupt
* auszul÷sen, ist das L÷schen des I-Flags, wenn ein IRQ ansteht.
* Die Opcode-Routinen fⁿr PLP, RTI und CLI enthalten deswegen besondere
* Abfragen, die ggf. in den Interrupt-Handler verzweigen.
*
* Erweiterungen:
* - ▄ber den Opcode $f2 sind die 1541-Routinen implementiert. Dem Opcode
* folgt ein Byte, das die Nummer der auzurufenden Routine angibt.
*
* InkompatibilitΣten:
* - ($ff),Y-Adressierung liest das zweite Byte der indirekten Adresse
* aus $0100 statt $0000. Dies geschieht aus Geschwindigkeitsgrⁿnden,
* der korrekte Code ist im Makro ReadAdrIndY auskommentiert.
* - In der Verwaltung des PCs bestehen einige Ungenauigkeiten (siehe
* Abschnitt "ProgrammzΣhler")
* - RMW-Befehle sollten erst die Originaldaten und dann die geΣnderten
* schreiben, aber das spielt nur eine Rolle fⁿr Register wie das
* VIC-IRQFLAG-Register, das in 6569.asm deswegen speziell behandelt wird
* - Zyklen werden nur fⁿr ganze Befehle gezΣhlt, Extra-Zyklen fⁿr
* Seitenⁿberschreitungen werden nicht berechnet (dies betrifft die
* Adressierungsarten xxxx,X xxxx,Y (xx),Y und die Branch-Befehle)
* - ADC und SBC im Dezimalmodus setzen die Flags nicht korrekt
* - RRA und ISB berⁿcksichtigen das D-Flag nicht
*
MACHINE 68020
INCLUDE "exec/types.i"
INCLUDE "exec/macros.i"
INCLUDE "exec/execbase.i"
INCLUDE "exec/nodes.i"
INCLUDE "dos/dos.i"
INCLUDE "dos/dostags.i"
INCLUDE "Frodo_rev.i"
CATCOMP_NUMBERS = 1
INCLUDE "Strings.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 ReadFrom6526A ;6526.asm
XREF ReadFrom6526B
XREF WriteTo6526A
XREF WriteTo6526B
XREF Reset6526
XREF Init6569 ;6569.asm
XREF Exit6569
XREF ReadFrom6569
XREF WriteTo6569
XREF Periodic6569
XREF AmigaToFront
XREF EmulToFront
XREF ReadFrom6581 ;65