www.mikrocontroller.net

Forum: Mikrocontroller und Elektronik 6502 Emulation auf AVR ?

Autor: Björn Wieck (bwieck)
Datum: 25.03.2007 03:24

Hat schon wer eine 6502 Emulation auf einen AVR hinbekommen ?

Hintergrund ist die Überlegung einen SID-Player für die SID Files zu
bauen.
Ich habe bei näherer Betrachtung dann festgestellt das im SidPlay für
für so ziemlich alle Systeme eigntlich ein C64 nachgebildet wird.
Also 6502 oder 6510 plus EA 6526 und ebend der SID selbst.
Die SID Files beinhalten auch immer eine Playerroutine für den 6502
Prozessor unter Anwendung der C64 Memorymap...

Ist es möglich einen AVR mit 16MHz so hinzubiegen das er einen 6502 mit
1MHz emulieren kann ?

Grüße
Björn
Autor: Jürgen (Gast)
Datum: 25.03.2007 08:31

Geht nicht. Dafür ist der AVR zu langsam und hat zu wenig Speicher.
Autor: Marvin (Gast)
Datum: 25.03.2007 09:18

So würde ich das nicht sehen.
Einen nackten 6502 kann man sicher emulieren, 6526 sollte auch drin sein
und mittels einem AVR mit Memory-Interface auch der Speicher.
Aber den SID selbst bekommt man nicht so einfach emuliert.
Eine "Ein-Chip-Lösung" wirds wohl nicht, aber ausprobieren könnte man es
ja mal.
Autor: Jürgen (Gast)
Datum: 25.03.2007 10:11

Er wollte einen 1MHz-6502 mit einem 16MHz AVR emulieren. Und das ist
sicherlich nicht möglich.
Er will ja SID-Files abspielen. Da spielt das Timing eine entscheidende
Rolle. Und das bekommt er mit einem AVR schlichtweg nicht hin.

@Björn:
Greif doch zu einem ARM, z.b. den ARM9 (STR9) von ST. Damit ist das kein
Problem. Und der ist auch noch für einen Hobbyisten nicht zu komplex.
Autor: Michael U. (Gast)
Datum: 25.03.2007 10:17

Hallo,

komisch....

Gestern beim aufräumen noch 2 SIDs gefunden, da kam mir ein ähnlicher
Gedanke.

Original-SID am AVR und eine Emu auf den AVR für CPU usw.

Speicher selbst wäre nicht zwingend nötig, den könnte eine
"Software-MMU" ummappen, weil die CPU sowieso emuliert werden muß.

Die Playerroutinen sind normalerweise relativ einfach. Vom 6226 wird
eigentlich nur der Timer benutzt, der Rest dürfte unnötig sein.

Wenn man Tabellen benutzt, könnte es vielleicht sogar schaffen.
Den SID selbst emuliert ein ATMega auf keinen Fall, der hat mehr
benutzte Ausnahmen und Tricks als offizielle Funktionen. ;)
Ich habe mal "SynthSample" im Netz wiedergefunden und es mit mehreren
Emus auf dem PC abgespielt, irgendwas stimmte immer nicht.
Ich habe dann einen C64 mit altem SID vorgekramt und von da gesampelt.
Ich hatte mich nicht geirrt, keine Emu hat es 100% hinbekommen...

Wäre eigentlich lustig, einige Chip-Tunes auf eine SD-Card kopiert,
reingesteckt und wirklich Original abgespielt. Hmmm....

Gruß aus Berlin
Michael
Autor: Marius S. (lupin) Benutzerseite
Datum: 25.03.2007 10:29

Michael sowas gibt es schon (für parallel port und auch mit controller,
vlt nicht avr)
Autor: Uhu Uhuhu (uhu)
Datum: 25.03.2007 11:09

Einen 6502 zu emulieren, geht mit dem AVR sicher nicht.

Auch bei stärkeren Prozessoren kann sich so eine Portierung als halbe
Lebensaufgabe erweisen, z.B. wenn der SID-Player mit aktiven
Warteschleifen und ähnlichen Sauereien arbeitet, die in der Zeit des
6502 häufiger benutzt wurden, als heute im Zeitalter der geschenkten
Timer.

Schreib lieber den Player für einen aktuellen Prozessor neu ;-)
Autor: Michael U. (Gast)
Datum: 25.03.2007 11:46

Hallo,

@Uhu Uhuhu: sicher? ;)
Der 6502 (6510) wird im C64 mit rund 1MHz getaktet. Es stehen also
maximal 16 Takte pro Befehl zur Verfügung.
Der 6502 hat 3 8Bit-Register, davon 1 Akku und 2 Index-Register.
Der Befehlsumfang läßt sich wohl zu 80% mit AVR-Befehlen direkt
abdecken, Sonderbehandlung brauchen die Adressierungsarten, die sollten
sich aber relativ elegant mit X,Y,Z abdecken lassen. Das Verhalten der
Flags wird vermutlich ein paar Unterschiede aufweisen, die Behandlung
der Dezimal-Befehle macht Probleme, die dürften aber in den Playern kaum
genutzt werden.

Das C64-Wiki hat die CPU so schön auseinandergenommen, da muß ich
nichtmal alte Bücher suchen. ;)
Ich sehe im Moment das größte Problem ganz woanders: der Chip-Tune muß
zum Abspielen komplett im Ram verfügbar sein, Es kommen also wohl nur
ATMega mit Hardware-Raminterface in Frage, weil der AVR beim Emulieren
keine Zeit hat, irgendwoher Daten zu holen.
Ein CTC auf auf Prescale 1 und Wert 8 sollte den E-Clock erzeugen
können, der Rest wäre geschicktes Sortieren der AVR-Befehle...

Ich halte es noch nicht für aussichtslos.

PS: ja, nutzlos vielleicht, aber das stört ja beim Hobby weniger. ;)

Gruß aus Berlin
Michael

Autor: Marvin (Gast)
Datum: 25.03.2007 12:46

... und es kommt noch hinzu, dass der 6502 zwischen 2 und 6(7?) Takte
pro Befehl benötigt. Je komplizierter der Befehl, desto mehr Taktzyklen
- das käme einer Emulation sehr entgegen.
Autor: Michael U. (Gast)
Datum: 25.03.2007 12:58

Hallo,

@Marvin:
ja, die aufwändigsten sind vermutlich die Indirekt Indiziert Zeropage
mit Offset, die dauern aber auch besagte 5-7 Zyklen.

Ich habe gerade mal 32k Ram und einen Mega8515 auf das STK200 gesteckt,
ich schau mal, wie eine Single-Step-Emu einiger dieser Befehle aussehen
könnte...
Muß nur mal schnell die 6510-Register definieren und die
UART-Debug-Ausgabe rumbasteln.
Ein Glück, daß man sich auch in Assembler schöne Baukasten-Routinen
machen kann. ;)

Ich werde mal pro Befehl 4 Byte in der Flashtabelle reservieren, ist
dann erstmal 1k weg.
ZH auf Tabellenanfang, dann den 6510-Befehl in ZL laden und indirekt
springen.
X erstmal für den 6510-Programmcounter und Y für den X/Y indizierten
Kram...

Mal schauen. ;)

Gruß aus Berlin
Michael
Autor: Uhu Uhuhu (uhu)
Datum: 25.03.2007 12:58

Habt Ihr auch an Interrupts auf dem AVR gedacht? Ich vermute, die werden
das Timing im Player ganz schön zerknittern...

Außerdem sind knapp 160 Takte - selbst wenn 160 AVR-Befehle reinpassen -
viel zu wenig, um eine saubere Emulation hinzubekommen.

Die Ähnlichkeiten verleiten zu Fehleinschätzungen. Der Teufel steckt in
den Unähnlichkeiten und darauf, daß die im Player keine BCD-Arithmetik
verwenden, würde ich mich schon garnicht verlassen. (Mal abgesehen
davon, daß diese Art von Überlegung - vornehm ausgedrückt - nicht gerade
professionell ist.)

Letztlich entscheidet das schwächste benutzte Teil im Emulator über die
Qualität und das Ohr findet unerbittlich die Schwachpunkte...
Autor: Dirk Hofmann (arm-dran)
Datum: 25.03.2007 13:03

Uhu Uhuhu wrote:
> Habt Ihr auch an Interrupts auf dem AVR gedacht? Ich vermute, die werden
> das Timing im Player ganz schön zerknittern...
>
> Außerdem sind knapp 160 Takte - selbst wenn 160 AVR-Befehle reinpassen -
> viel zu wenig, um eine saubere Emulation hinzubekommen.
>
> Die Ähnlichkeiten verleiten zu Fehleinschätzungen. Der Teufel steckt in
> den Unähnlichkeiten und darauf, daß die im Player keine BCD-Arithmetik
> verwenden, würde ich mich schon garnicht verlassen. (Mal abgesehen
> davon, daß diese Art von Überlegung - vornehm ausgedrückt - nicht gerade
> professionell ist.)
>
> Letztlich entscheidet das schwächste benutzte Teil im Emulator über die
> Qualität und das Ohr findet unerbittlich die Schwachpunkte...

Es gibt auch noch beschleunigte Nachbauten den 6502.
Den 65C02 von Western Design Center und Pheripheriechip.
Der 65C02 läuft mit 14MHz.
Vertrieb ist DEMA
Autor: Uhu Uhuhu (uhu)
Datum: 25.03.2007 13:09

Die Frage war, ob man den 6502 auf einem AVR emulieren kann um darauf
den SID-Player in 6502-Maschinencode laufen zu lassen.

Daran, daß man das Teil auf einem 65C02 zum Laufen bringen kann, habe
ich keine Zweifel - aber das wäre dann in Hardware, nicht emuliert.
Autor: Dirk Hofmann (arm-dran)
Datum: 25.03.2007 13:26

Uhu Uhuhu wrote:
> Habt Ihr auch an Interrupts auf dem AVR gedacht? Ich vermute, die werden
> das Timing im Player ganz schön zerknittern...
>
> Außerdem sind knapp 160 Takte - selbst wenn 160 AVR-Befehle reinpassen -
> viel zu wenig, um eine saubere Emulation hinzubekommen.
>
> Die Ähnlichkeiten verleiten zu Fehleinschätzungen. Der Teufel steckt in
> den Unähnlichkeiten und darauf, daß die im Player keine BCD-Arithmetik
> verwenden, würde ich mich schon garnicht verlassen. (Mal abgesehen
> davon, daß diese Art von Überlegung - vornehm ausgedrückt - nicht gerade
> professionell ist.)
>
> Letztlich entscheidet das schwächste benutzte Teil im Emulator über die
> Qualität und das Ohr findet unerbittlich die Schwachpunkte...

@Uhu,

verstehe die ganze Dískussion nicht.
1.) Kein Wort darüber, in welcher Programmiersprache Ihr die Emulation
schreiben wollt.

2.) Das Verhältniss steht nicht 1/160 sondern 1/16 (ca.)

3.) Wie wollt Ihr die Emulation vornehmen?
Was heiss7, der AVR kann 80% der Befehle direkt übernehmen.
Denke, das spielt wohl keine Rolle, da ja eine Art
6502Assembler-Interpreter geschrieben werden muss und damit kann kein
Befehl direkt emuliert werden.

4.) Der AVR ist eine Art Billig-FPGA Design, man hat Befehle auf biegen
und brechen auf eine Nahezu einheitlich Datenbreite reingequetscht.
Manche Register nur mit bestimmten Befehlen. Ist wohl der ungeeignetste
µC für Sowas.
Ein ARM9 is dagegen ja wohl total abgefahren und mit Kanonen nach
Spatzen geschossen.
Glaube kaum, daß Ihr den in Assem programmiert und würdet dadaurch jeden
Geschwindigkeitsvorteil wieder tot machen. Mit einem 32Biter nen 8 Biter
emulieren, naja.
Autor: Michael U. (Gast)
Datum: 25.03.2007 13:35

Hallo,

@Uhu Uhuhu: ich denke hier im Moment nur laut darüber nach, den 6502
Taktgenau nach außen zu emulieren, um einen echten SID an den AVR zu
hängen und spielen zu lassen.

160 AVR-Befehle, um selbst ein LDA ($50),Y zu emulieren sollten wohl
mehr als reichen.

Iterrupts sollten nicht stören, weil es in meiner momentanen Überlegung
keine gibt...

Befehlsdecoder:
Befehlsbyte des 6510 mit LD ZL,X+ aus dem Ram nach ZL holen, IJMP dahin.
Dort Datenbytes des Befehl holen und bearbeiten.
Programmzähler (X) zeigt dann schon auf den nächsten Befehl, wenn es ein
Sprung war eben dort hin.

Timing mit passender Anzahl AVR-NOPS auffüllen

Dann Sprung zurück zum Befehlsdecoder und wieder von vorn.

Zeropage im AVR-Ram, über die nötige Initialisierung denke ich später
nach...

Selbst die Behandlung der Dezimal-Geschichte sollte reinpassen, von
"professionell" war sowieso nicht die Rede. ;)

Den C64 mit der Nordic-Power kann ich immernoch aus dem Schramk holen,
um zu debuggen, was nicht freiwillig spielt.

Nenn es Back2Roots, ich habe ewig nichts mehr mit dem C64 gemacht. :)

Schlimmstenfalls habe ich ein paar Stunden Freizeit "nutzlos" verbracht,
darüber würde ich mich aber überhaupt nicht ärgern....

Gruß aus Berlin
Michael
Autor: Uhu Uhuhu (uhu)
Datum: 25.03.2007 13:57

@ Dirk Hofmann: Ich halte das Projekt für wenig aussichtsreich - egal in
welcher Programmiersprache man da ran geht. (Auch mit Deinem
heißgeliebten Assembler wirds nicht gehen.)

@ Michael U.: Du kannst natürlich Deine Erfahrungen sammeln und ich will
Dir da nicht reinreden.

Ich habe bereits etliche Erfahrungen mit Interpretern/Emulatoren und
schöpfe nur daraus. Der Teufel steckt wie immer im Detail - das man auf
den ersten Blick natürlich übersieht...
Autor: Michael U. (Gast)
Datum: 25.03.2007 14:10

Hallo,

@Dirk Hofmann:
zu 1) ASM
zu 2) das bezweifle ich mal:

ADC $hhll,X  addiert zum Akku den Inhalt von ($hhll + X)

Z - Zeiger auf Befehlstabelle
X - PC des 6510
Y - 16 Bit Hilfsregister

befehlsdecoder:
ld ZL,X+   #2# Befehlsbyte des 6510 in ZL, ZH zeigt sowieso auf
Tabellenanfang.
ijmp       #2# Sprung

6510adc:
mov XH_TEMP,YH   #1#      ; für Seitenwechsel des 6510
ld YH,X+  ; #2# H der Adresse
cp  XH,XH_TEMP           ; #1# Seitenwechsel der Quelladresse?
breq no_wait             ; #2# nein, nur 4 6510 Takte
nop                      ; einen Takt warten, also 15 nop (-1 wegen
breq)
nop
...
nop
nop

no_wait:
ld YL,X+  #2# L der Adresse
add YL, 6510_X #1#
adc YH,NULL  #1#         Hilfsregister, immer 0
ld TEMP,Y #2#
add  6510_AKKU,TEMP #1# ob Flags behandelt werden müssen, muß jeweils
geklört werden, sonst
mov 6510_STATUS,SREG  #1# Flags vom add merken für 6510
nop
nop
... dumm warten, bis 1µs rum ist
nop
nop
rjmp befehlsdecoder  #2# X zeigt auf nächstes 6510-Befehlsbyte

Das sind 20 Zyklen für diesen Befehl.
Der 6510 braucht dazu 4 Zyklen -> 64 AVR-Takte bei 16MHZ, 5 Zyklen, wenn
High/Low-Byte über einer Seitengrenze liegen.

Bleiben 44 AVR-Takte für Sachen, die ich hier auf die Schnelle übersehen
habe.

Sieht so schlecht doch nicht aus...

zu 3) wenn die Wirkung eines Befehl identisch ist, also z.B. die
Flag-Beeinflussung bei einem 6510 CMP der des CP/CPI des AVR enspricht,
muß nicht soviel Ausnahmen behandeln.

Wenn ich das gedanklich weiterspinne, sollte man einen 99,9% kopatiblem
6510 in einen Atmel bekommen, den man per Adaptersockel in einen C64
stecken können sollte... ;)

Gruß aus Berlin
Michael
Autor: Björn Wieck (bwieck)
Datum: 25.03.2007 18:22

Uhu Uhuhu wrote:

> Schreib lieber den Player für einen aktuellen Prozessor neu ;-)

Das wäre mir ja auch am liebsten wenn ich mit dem AVR nur die Daten zum
SIDChip rüberschaufeln müsste.
Leider ist in allen SID-Dateien ein eigener Player enthalten und es ist
noch nicht mal immer der gleiche. Ich hätte keine Lust in jeder
Sid-Datei erstmal zu schauen welcher Player drinsteckt, um dann
entsprechend die Daten aufzubereiten...

Lieber würde ich die Sid-Dateien so verwenden wie sie sind.

Grüße
Björn
Autor: Uhu Uhuhu (uhu)
Datum: 25.03.2007 18:44

> Leider ist in allen SID-Dateien ein eigener Player enthalten und es ist
> noch nicht mal immer der gleiche.

D.h., ein Hack, der für ein Musikstück vielleicht funktioniert, fällt
mit dem nächsten jämmerlich auf die Schnauze...

Da ist es wohl das Beste, wenn Du die Audiodaten aus dem Orginalkasten
rausholst und auf eine PC-Soundkarte gibst, um sie in heutige Formate
umzucodieren.
Autor: Björn Wieck (bwieck)
Datum: 25.03.2007 19:39

Uhu Uhuhu wrote:

> D.h., ein Hack, der für ein Musikstück vielleicht funktioniert, fällt
> mit dem nächsten jämmerlich auf die Schnauze...

So isses, deswegen bilden ja auch alle Programme zun Sidabspielen für
den PC
einen halben C64 (6510, 6526 und 6581) nach.

>
> Da ist es wohl das Beste, wenn Du die Audiodaten aus dem Orginalkasten
> rausholst und auf eine PC-Soundkarte gibst, um sie in heutige Formate
> umzucodieren.

Da wäre ja dann keinerlei Herausforderung mehr... das ist unsportlich ;)

Grüße
Björn
Autor: Uhu Uhuhu (uhu)
Datum: 25.03.2007 19:55

Würde eher drauf tippen, daß dieser Sport in allgemeiner Verfettung
endet. Fahrrad ist gesünder...
Autor: Michael U. (Gast)
Datum: 25.03.2007 19:59

Hallo,

> Leider ist in allen SID-Dateien ein eigener Player enthalten und es ist
> noch nicht mal immer der gleiche

naja, das liegt einfach daran, daß es keinen SID-Player auf dem C64
gibt.

Der SID wurde programmiert, der eigentlich erste brauchbare Tracker für
den C64 war der SidMon von Chris Hülsbeck.
Damit konnte man erstmals die SID-Eigenschaften nutzen und trotzdem mit
Noten-Einträgen arbeiten.
Ansonsten ist jedes Stück programmiert. So resourcensparend wie es geht,
Speicher sparen, CPU-Zeit sparen. Ein guter Sound sollte ein Spiel oder
ein Demo aufpeppen, nicht das Gameplay versauen oder den in Echtzeit
gerenderten bunten Würfel am Drehen hindern.

Ansonsten habe ich im Netz noch das gefunden...
http://www.tripoint.org/kevtris/Projects/sid/index.html

So, jetzt zähle ich weiter Befehle. ;)

Hoffentlich habe ich noch ein C64-Intern irgendwo, muß erstmal nach
Zeropage-Belegung und Vektor-Tabellen ausschau halten, ist doch schon
etliche Jahre her.....

Gruß aus Berlin
Michael


Autor: Hauke Sattler (hauke)
Datum: 26.03.2007 13:18

Nun will ich mal meinen Senf dazugeben.

Ich denke eine MOS6502 bzw MOS6510 (folgend nur noch als MOS bezeichnet)
Emulation auf einem AVR sollte unter folgenden Umständen möglich sein:

Der MOS Takt ist nicht höher als 1MHz
Der AVR Takt ist ein ganzes Vielfaches des MOS Taktes
Der AVR hat genug Flash (Mega64 wäre ideal)
Der Emulator wird in Assembler gecoded

Ich muß dazusagen das ich nie speziel auf den MOS gecoded habe.
Meine Anfänger CPU war der Z80

Aber was ich in den 6502 Datenblättern gesehen habe stimmt mich
zuversichtlich.

Die schnellsten MOS Befehle brauchen mindestens 2 MOS Takte und haben
während dessen 1 RAM zugriff.
Bei 1MHz MOS-Takt und 16 MHz AVR-Takt würden das bis zu 32 AVR-Assembler
Befehlen entsprechen.

Der RAM Zugriff müßte in Software realisiert werden (das Hardware XRAM
Interface wäre zu schnell für Busbausteine wie den SID)

Die MOS haben maximal 256 Opcodes (wenn ich mich nicht täusche)
Für jeden Opcode würde im AVR-Flash ein kurzes Unterprogramm stehen.
In jedem dieser Unterprogramme würde gegen Ende der nächste MOS-Befehl
gelesen und das dazugehörige Unterprogramm angesprungen werden.

die Notwendigen Befehle wären:
out PORTD,Adresshigh                            ;1 Takt
out PORTC,Adresslow                             ;1 Takt
...
SBI PORTB,Lesebit                               ;2 Takte
...
in zh,PINA                                      ;1 Takt
ijmp                                            ;2 Takte

Für das Einholen und dekodieren des Befehls gehen also 7 AVR-Takte weg.
Bleiben noch 25 AVR-Takte für die Ausführung des eigendlichen
MOS-Befehls.
Das sollte machbar sein.
Bei komplizierteren Addressierungsarten kommen dann noch zusätzliche
MOS-Takte dazu, so das man noch zusätzlich Zeit gewinnt.

Ich weiß jetzt nicht welche Interupts beim MOS vorhaden sind und wie
diese gehandhabt werden, aber um diese Taktsychron einzubinden könnte
man noch ein kurzes sei/cli Fenster in den o.g. Code einbringen.
out PORTD,Adresshigh                            ;1 Takt
out PORTC,Adresslow                             ;1 Takt
...
SBI PORTB,Lesebit                               ;2 Takte
...
sei                                             ;1 Takt
(exakt hier wuerden die entsprechenden ISR angesprungen werden)
cli                                             ;1 Takt
in zh,PINA                                      ;1 Takt
ijmp                                            ;2 Takte

Dies Beispiel würde jedoch 64kword Flash brauchen, (jeder MOS-Opcode
hätte 256 AVR-Befehle Platz) deshalb wäre es sinnvoll noch eine LUT für
die Opcode-Unterprogramme zu verwenden. Diese könnte aus
Geschwindigkeitsgründen im internen RAM stehen (512 Byte)

Die Zeropage und den Stackpointer würde ich ebenfalls in das interne RAM
packen. Ich denke nicht das externe Busbausteine im C64 auf die Zeropage
oder den Stack zugreifen oder diesen gar verändern dürfen. (Korregiert
mich wenn ich falsch liege)

Alles in allem halte ich eine Emulation für möglich. Aber wie gesagt ich
habe auf den MOS noch nicht programmiert, und ich finde auch keine
wirklich gute Doku zu den Chips. Das was ich bisher gefunden habe sind
ein paar schlecht gescannte Seiten oder PDFs von Vergleichstypen (bei
deren Kompatiblität ich mir nicht sicher sein kann.
Was ich gut gebrauchen könnte wäre eine Befehlsbeschreibung wie ich sie
von den AVRs gewohnt bin. Damit könnte man dann planen. (OK illegale
Opcodes sind dann noch so eine andere Sache)

cu
Hauke
Autor: Eckhard (Gast)
Datum: 26.03.2007 13:24

Hallo,

ich denke das könnet noch andere Probleme geben. Der 6502 hat eien von
Neumann Architektur und das wurde auch gerne ausgenutzt. Ich sag mal
Daten und Code mischen oder sogar selbstmodifizeirender Code. Das wird
nicht einfach mit dem AVR das nachzubilden.

Eckhard
Autor: Hauke Sattler (hauke)
Datum: 26.03.2007 13:33

@Eckhard
Solange man den MOS-Code und die Daten in einem exteren RAM behält und
diese gleich behandelt, dürfte diese Problem lößbar sein.
Der nächste Opcode wird ja erst gelesen wenn der Vorherige Befehl (evt.
ein schreibender RAM Zugriff) fertig ist.

cu
Hauke
Autor: pluto (Gast)
Datum: 26.03.2007 13:39

Ist vieleicht ganz Interessant.....
http://www.binkino.de/ecbm64DTV4.htm
Autor: Christoph Kessler (Firma db1uq) (christoph_kessler)
Datum: 26.03.2007 14:02

Es gibt schon länger (2002) einen 6502 in VHDL, wurde aber seither nicht
mehr gepflegt:
http://www.opencores.org/projects.cgi/web/t65/overview
http://www.opencores.org/cvsweb.shtml/6502vhdl/
Autor: Christoph Kessler (Firma db1uq) (christoph_kessler)
Datum: 26.03.2007 14:13

Hier gibts noch mehr 6502 und Peripheriebausteine in VHDL oder Verilog:
http://www.birdcomputer.ca/Cores/CoresToC.html
Autor: Michael U. (Gast)
Datum: 27.03.2007 20:28

Hallo,

ich habe mir das jetzt mal etwas näher angeschaut.
Rahmenbedingung bleibt mal ein SID-Player mit 6581 dran.
16MHz Mega8515 oder Mega162 mit externem Ram.

Experimentierumgebung:
STK200 mit Mega8515 und 32k externem Ram, z.Z. 8MHz getaktet.
UART für Debug mit 38400 Baud.

Testpbjekt: ein SID-Player-File mit knapp 500Byte Länge im EEPROM.

File wird beim AVR-Start an die Original-Adresse im externen Ram
kopiert.
6510 Befehlsdekoder/Interpreter mit LockUp-Table (512Byte im Flash).

Die Initialisierungsroutine des Players läuft inzwischen durch, das
heißt, es werden alle benutzten Befehle dekodiert und abgearbeitet.
Keine Rahmenbedingungen, Zugriffe auf IO laufen ins Leere usw.
Kein Timing, nur Test, ob ein Befehl überhaupt mit der zur Verfügung
stehenden AVR-Taktzahl bearbeitet werden kann.

Wenn der "6510" läuft, wird nichts anderes auf dem AVR gemacht.

Die - bis jetzt - ungünstigste Variante ist lda/ldx/ldy immediate mit 2
6510-Zyklen. Da bleiben als Reserve 5 AVR-Takte übrig.
Das Problem dabei ist, das der 6510 da die Flags setzt und das muß
bearbeitet werden.

Alle 3 Zyklen-Befehle haben bis jetzt genug Reserve, auch die indirekt
idizierten.

Mein Hauptproblem im Moment ist, daß ich zwar diverse Zyklen auf dem AVR
übrig behalte, die aber nicht sinnvoll nutzen kann, weil sie eben
"abgezählt" sein müssen.

Interruptlösungen scheiden meiner Meinung nach aus, 4 für IRQ-Start, 3
für den Sprung, 2 für SREG sichern und zurück und 4 für Reti sind 13
Takte, die habe ich bei 32 Takten für einen 2-Zyklen Befehl des 6510
nicht übrig.
6510 immer mit rund 1MHz gerechnet, also C64 Speed.

Falls jemand Interesse hat und mitdenken/mitbasteln will, packe ich das
AVR-Projekt gern mal hier rein.

Gruß aus Berlin
Michael
Autor: Walter (Gast)
Datum: 27.03.2007 20:42

>Mein Hauptproblem im Moment ist, daß ich zwar diverse Zyklen auf dem AVR
>übrig behalte, die aber nicht sinnvoll nutzen kann, weil sie eben
>"abgezählt" sein müssen.
kannst du dir nicht übrig gebliebene bis zu einem gewissen Wert
"aufsparen" um sie für zeitintensivere Befehle zu verwenden?
Autor: Benedikt K. (benedikt)
Datum: 27.03.2007 20:43

Was spricht gegen Pollen des Timers in der ungenutzen Freizeit als
Interrupt Ersatz ?
5 Takte sollten dazu ausreichen, das Interrupt Flag zu prüfen bzw. den
Pin abzufragen, das Interrupt Enable Flag abzufragen und gegenfalls zu
springen.
Autor: Michael U. (Gast)
Datum: 27.03.2007 21:07

Hallo,

@Walter: aufsparen bringt vermutlich Probleme, wenn es IO-Zugriffe zum
SID oder in der CIA-Timer-Emulation gibt, da spielt dann wohl schräg...

@Benedikt K.: spricht erstmal nichts dagegen, ich weiß einfach noch
nicht, ob und wofür ich die Rechenzeit brauche oder gebrauchen kann.

Von der CIA dürfte nur Timer/Counter genutzt werden, den kann der AVR
erledigen und darf auch IRQ machen. Das wird nur insofern etwas tricky,
weil ich da sozusagen mitten im 6510-Befehl stecken kann. Das IRQ-Timing
des 6510 muß ich mir erstmal wieder ansehen, ist zu lange her.

Da ist aber auf jeden Fall genug Zeit, 6510 PC und STATUS habe ich
schneller auf dem 6510-Stack als das Original.
Zugriffe auf $Dxxx, also IO, muß ich sowieso getrennt bearbeiten, wegen
Bank-Switching des C64 usw. Das ist aber auch relativ unkritisch, weil
daß alles 6510 Befehle mit mindestens 3, meist 4-5 Zyklen sind.

Ich bastle jetzt erstmal die Befehle zusmmen, die die Mini-Routine
benutzt, dann muß ich erstmal meine alten C64-Unterlagen suchen. ;)

Im Netz liegt viel, leider auch viel unvollständiges oder falschen...

Für den 6502 ist erstmal
http://www.6502.org/tutorials/6502opcodes.html
zu empfehlen.

Gruß aus Berlin
Michael

Autor: Walter (Gast)
Datum: 27.03.2007 21:12

>@Walter: aufsparen bringt vermutlich Probleme, wenn es IO-Zugriffe zum
>SID oder in der CIA-Timer-Emulation gibt, da spielt dann wohl schräg...

natürlich keine msec aufsparen, aber so 1-2µsec für einzelne 6502
Befehle die du vielleicht nicht in der Taktzeit schaffst sollten doch
wohl drin sein
Autor: Michael U. (Gast)
Datum: 27.03.2007 21:48

Hallo,

naja, sieht bis jetzt immernoch gut aus, geht alles ins Zeitraster. Es
bkeiben eben z.B. bei lsr addr,x rund 50 AVR-Zyklen übrig, die ich
Taktgenau verheizen muß.
Da muß ich mir noch was ausdenken.
Außerdem kommen noch 2 Dinge dazu: während gespielt wird, will ich ja
nur 2 Sachen machen können: Tasten abfragen, wenn eine gedrückte Taste
erkannt wird, ist sowieso Puse oder Ende für den 6510, dann will ich ja
irgendwas verändern, neuen Track, Pattern-Skip oder so. Da ist Timing
also egal.
Andere Sache ist es, das Display zu aktualisieren, also Laufzeit oder
Pattern-Nummer usw. Das muß zwischendurch passieren. Da wird es dann
wohl auf eine zeichenweise Ausgabe ans Display hinauslaufen, also Zeiger
auf Textbuffer und bei jedem Aufruf 1 Zeichen. Das dann in solche
Befehle reingehangen mit einer Timerabfrage, damit es gleichmäßig
aussieht.

Dann kommt noch erleichternd hinzu, daß die Play-Routinen normalerweise
in einem Timer-IRQ des C64 laufen, die werden also normalerweise nur
alle 20ms aufgerufen oder imn eigenem Timer-IRQ. Dazwischen sollte der
Original-C64 ja noch was nützliches machen, z.B. bewegte Grafik
darstellen.

Die CPU-Auslastung über die Zeit läßt also vermutlich auch noch
ausreichend Rechenzeit übrig.

Das kann ich aber erst abschätzen, wenn etwas mehr spielt. ;)

Gruß aus Berlin
Michael
Autor: T.S. (Gast)
Datum: 27.03.2007 22:35
Dateianhang: vc20.zip (130,3 KB, 115 Downloads)

Vor einiger Zeit habe ich diese angehängte Emulation im Netz gefunden;
Quelle vergessen, kann sein auf AVRFreaks oder so. Der VIC20 ist ein
Vorgänger vom C64, mit der gleichen CPU. Kann sein das sich etwas
unterscheidet, soweit ich mich (sehr gerne btw) erinnere hatte die CPU
im C64/Plus4 einen eingebauten IO-Port.

Vielleicht hilft das dem einen oder anderen.

Torsten
Autor: Läubi Mail@laeubi.de (laeubi) Benutzerseite
Datum: 28.03.2007 07:19

machs doch so:




.org 0x100
_nop:
nop
nop
nop
nop
.
.
.
nop
ret

(sagen wir mal 100 stück)

dann kanst du mit CALL 0x150 z.b. 50 Takte (+call + ret) "verbraten"

Autor: Björn Wieck (bwieck)
Datum: 28.03.2007 09:04

Michael U. wrote:

> Falls jemand Interesse hat und mitdenken/mitbasteln will, packe ich das
> AVR-Projekt gern mal hier rein.

Jaa, hier!

Grüße Björn
Autor: Michael U. (Gast)
Datum: 28.03.2007 09:11

Hallo,

@T.S.: Danke, schau ich mir mal an.
Allerdings sieht die 6502cpu.asm nicht so aus, als hätte er taktgenau
emuliert, ein paar Sachen scheint er auch noch nicht fertig gehabt zu
haben. Vielleicht finde ich ja den Ursprung im Netz.

@Läubi: so ähnlich sieht es auch aus, allerdings nur für 7...16 Takte
Wartezeit. :)

7 ist Minimum damit wegen rcall + ret, 16 ist rcall + ret + 9 nop,
jeweils mit eigener Sprungmarke, liest sich besser. Komplette
6510-Zyklen werden mit mehreren Aufrufen von warte_16 erledigt.

Kürzere Pausen sind eben mit 1...6 NOP direkt aufgefüllt.

lda/ldx/ldy habe ich so mal gestern fertig gemacht, das geht relativ
schnell, viel copy/paste, sind wenig Anpassungen nötig.

Ist im Moment mehr reine Fleißarbeit.......

Behandeln muß ich noch die Extra-6510-Zyklen bei Pagewechsel (indirekt
adressierte und bedingte Sprünge), das muß ich mir aber erst nochmal
anschauen.

Gruß aus Berlin
Michael
Autor: Michael U. (Gast)
Datum: 28.03.2007 09:33
Dateianhang: SID_6510.zip (25,3 KB, 74 Downloads)

Hallo,

@Björn Wieck:

AVR-Studio v4 Projekt, schau rein und frage, wenn es Unklarheiten gibt.
Ich habe hoffentlich alles wichtige kommentiert, natürlich bis jetzt
mehr für mich als für andere...

Die Befehle in den Includes sind im Moment nach Alphabet geordnet, war
für mich erstmal überschaubarer.
Meine Referenz ist im Moment
http://www.6502.org/tutorials/6502opcodes.html

Gruß aus Berlin
Michael
Autor: Michael U. (Gast)
Datum: 28.03.2007 10:01
Dateianhang: SID_6510.zip (26,5 KB, 72 Downloads)

Hallo,

hmmm. zu schnell gewesen...

Etliche L/H-Vertauschungen in allen Befehls-Includes beseitigt,
sta/stx/sty komplett.

Gruß aus Berlin
Michael
Autor: Christoph Kessler (Firma db1uq) (christoph_kessler)
Datum: 28.03.2007 10:13

http://www.npsnet.com/danf/cbm/cross-development.h...
da gibts u.a. einen 6502-Emulator auf ARM, mit 30MHz Takt soll er etwa 5
MHz 6502 emulieren. Ich habe noch irgendwo den 6502 Emulator für den
Atari ST, der hatte auch nur 8 MHz mit dem 68000 Prozessor.
Autor: Michael U. (Gast)
Datum: 28.03.2007 10:41

Hallo,

Danke, merke ich mir auch mal.

ist auch kein grundsätzliches Problem, von der Geschwindigkeit dürfte er
mit einem 16MHz-AVr so etwa auf 3MHz kommen.
Das wäre aber dann ein Durchschnitts-Wert, der von 6510-Befehl abhängt.

Ist dann aber nicht Zyklen-genau und das will ich. Da ist 1MHz für den
Original-C64-Takt drin.

Gruß aus Berlin
Michael
Autor: Hauke Sattler (hauke)
Datum: 28.03.2007 11:31

Hi
Ich habe auch mal angefangen einen mos6510 Emulator zu schreiben.
Ich versuche vor allen Dingen nicht nur das Timing sondern auch das
externe RAM Interface ähnlich hinzubekommen.

Würde gerne mitmachen.
Bin Assemblercoder und neige dazu Taktzyklen zu zählen.


cu
Hauke
Autor: Michael U. (Gast)
Datum: 28.03.2007 12:28

Hallo,

wie meinst Du das mit dem Ram-Interface?
Prinzipell könnte man den Bus sicher komplett in z.B.
C64-Originalgeschwindigkeit zusammenbasteln, ich habe das Problem
zumindest mit dem SID ja auch noch vor mir. Ich bin auch noch nicht so
sicher, welche Probleme der Zugriff auf das externe AVR-Ram mir so
beschert, die Timingdiagramme muß ich noch genauer studieren...

Gruß aus Berlin
Michael
Autor: Hauke Sattler (hauke)
Datum: 28.03.2007 13:16

@Michael

Da gibt es gleich mehrere Probleme.

Das AVR interface ein gemultiplexter (scheußliches denglish) Adress und
Datenbus mit zusätzlichen den Steuersignalen ALE /RD /WR

Das 6510 Interface ist nicht gemultiplexed, sondern verwendet getrennte
Daten und Adressbusse. Der Adressbus muß zudem von außen abschaltbar
(tristate) sein. Als Steuersignal gibt es nur ein einzelnes R/W Signal
mit dem die Signalrichtung gesteuert wird.
Weiterhin sollen Adresshigh Adresslow und R/W gleichzeitig umgeschaltet
werden. (ohne Tricks unmöglich auf dem AVR)

Weiterhin wird der Standartzugriff des AVR (braucht ca 3 Takte) viel zu
schnell für einen SID sein. Man kann zwar reichlich Waitstates einbauen
aber ich habe meine Zweifel ob diese reichen.


In meinem aktuellem Ansatz verwende ich ein paar Latches zur
synchronisierung, und einen zusätzlichen Port für den Datenbus.
So komme ich ohne Waitstates hin, und kann zwischen der Ausgabe der
Adresse und dem einlesen der Daten noch ein paar Sachen machen.

Ich frickle mich zur Zeit durch die einzelnen Adressierungmodi des 6510
anhand des Befehls AND.
Leider sind die Datenblätter die ich im Netz gefunden habe leicht
wiedersprüchlich. Mal wird von einem zusätzlichem Maschinenzyklus bei
einem Page-Wrap-Around gesprochen, mal von einem zusätzlichem
Maschinenzyklus beim Dezimal Modus. Wohl gesagt bei ein und demselben
Befehl und Adressierungsmodus.
Sehr verwirrend.

cu
Hauke
Autor: Michael U. (Gast)
Datum: 28.03.2007 15:20

Hallo,

die Problematik der Geschichte mit dem Zugriff auf echte 68xx-Perpherie
ist mir klar, ich habe da schlicht noch einen großen Bogen drum gemacht.
Etwas TTL-Kram ist da sicher fällig (nein, keine GAL, FPGA usw.usw. ;)).

Zu den Datenblättern kann ich Dir nur zustimmen, ich werde, wenn es
soweit ist, wohl den C64 entstauben müssen...

Ich werde jetzt erstmal den Befehlssatz soweit zuende machen, daß alles
durchläuft.

Dann CIA soweit wie nötig (Timer), dann den SID ranhängen.
Dezimal-Flag muß ich mir sowieso noch anschauen, ob es da einen
Zusatzzyklus gibt, weiß ich jetzt auch nicht.

Daß es beim gleichen Befehl und Adressmode passieren kann, daß dann 2
Zyklen zusätzlich eingefügt werden, kann schon sein.

Gruß aus Berlin
Michael
Autor: Michael U. (Gast)
Datum: 29.03.2007 21:11
Dateianhang: SID_6510.zip (43,5 KB, 75 Downloads)

Hallo,

falls doch noch jemand reinschaut:

6502-Befehlssatz komplett drin, Stackbehandlung drin, Bedingungen und
Sprungweiten-Berechnungen scheinen zu stimmen, Timing bei 16MHz
Zyklengenau 6510 1MHz.

Was noch fehlt: Dezimal-Flag noch nicht berücksichtigt, Zusatz-Zyklen
bei Page-Crossing nicht berücksichtigt.
Wie ich den SID an den ATMega mit möglichst wenig Aufwand ranhänge, ist
noch etwas unklar...

Vielleicht am Wochenende mal was probieren.

Gruß aus Berlin
Michael
Autor: A.K. (Gast)
Datum: 29.03.2007 22:10

Mal kurz überflogen:

Bei Adressierungen zeropage+X/Y wird die Adresse ohne Carry gerechnet.

SP arbeitet etwas anders als gewohnt: TOS ist leer, nach JSR ist die
Returnadresse an SP+1,SP+2.

Streng genommen besitzen 65xx-CPUs keine Befehle für Subtraktion,
sondern für Addition des Einerkomplements. Das hat Folgen für das C
Flag, es ist invers zum C-Flag des AVR. Erkennt man schon daran, dass
die übliche Subtration
   lda var1
   sec
   sbc var
lautete.
Autor: A.K. (Gast)
Datum: 29.03.2007 22:40

Tip zur Laufzeitkorrektur bei page crossing: Ein
  BRCS PC+1
braucht 1 Takt bei C=0, 2 Takte bei C=1.
Autor: Läubi Mail@laeubi.de (laeubi) Benutzerseite
Datum: 29.03.2007 23:30

Naja wenn eh immer gewartet werden mus... haeng das ganze doch an ein
Schieberegisterlatch (HC 4094 glaub ich) "reinholen" kannst das ganze
auch uber ein Parralle zu Seriell Wandlerchip (HC 4021 beim NES
Controller ist sowas drinn) braucht dann insgesammt am AVR nur 4 fuer
den Output und 3 fuer Input musst mal gucken obs schnell genug ist das
durch alles durch zu schieben, ansosnten kannst du auch 2 Datenleitungen
parrallel machen dann sind es halt 5+4 Leitungen.
Autor: Hauke Sattler (hauke)
Datum: 30.03.2007 00:29

Also Schieberegister dürften definitiv zu langsam sein.
Man hat für einen 6502 Daten Transfers 16 AVR Takte. Meines Wissens ist
die höchste SPI Frequenz (als Master) Freq/2. Das heißt für die 25 Bit
(16*Adress 1*R/W 8*Daten) Bräuchte man mindesterns 50 AVR Takte.

Und mit mehreren Schieberegistern parallel kann man auch vergessen. Das
müßte nen AVR dann in Software machen, was noch langsamer ist.
Ich habe es mir zur Zeit so überlegt, daß der Adressbus über zwei
Latches geleitet wird. Beide hängen an den AD0-AD7 XRAM Ausgängen. Das
eine Latch wird durch das ALE Signal gesteuert. Das andere durch das WR
Signal.
Der Datenbus hängt an einen unabhängigen Port.

mov yl,adresshigh
st y,adresslow
...
in daten,pinc

Spart Ports und zum zweiten ist der Adressbus über den
/OE-Steuereingänge der Latches abschaltbar.

cu
Hauke

P.S.
Auf welchem AVR seid ihr das am planen?
Ich code das zur Zeit (rein aus Simulationszwecken) auf einem M128
Autor: Michael U. (Gast)
Datum: 30.03.2007 08:44

Hallo,

@A.K.: Danke, korrigiere ich. Kann mich jetzt auch an die Carry-Sache
erinnern, werde wohl doch alt, ist ja schon mehr als 15 Jahre her, meine
C64-Zeit... ;)

Adresse zeropage+x/y habe ich sogar in der Doku als Hinweis gelesen und
dann ignoriert.

Stackpointer-Verhalten ist schon klar, aber was mir bei Deiner Anmerkung
auffiel ist, daß der wohl nach 6510-Rest auf $FF steht und nicht auf
$00, wie ich im annahm. Muß ich auch korrigieren.

Beim Page-Crossing habe ich einfach noch nicht zusammengesucht, wann da
genau ein Zyklus eingefügt wird, der Vergleich von PC-Highbyte vor und
nach der jeweiligen Aktion muß noch rein und den 6510-Zyklus einfügen,
wenn nötig.

@Hauke Sattler: ich habe im Moment nur einen sehr theoretischen Ansatz
für die SID-Anbindung, den ihc überlege.

SID-Daten an Memory-Datenport, SID Adressen an Memory-High-Adress-Port.
R/W an WR, CS an einen Extra-Port-Pin.

E-Clock (Phi2) per CTC (AVR-Clock/16) erzeugen und mit Pin toggle für
den SID bereitstellen.

Test auf Zugriff High-$D4, also SID. Ext-Mem ausschalten, Daten auf
Port, Adresse R/W auf Port, jetzt E-Zustand abwarten (CTC-Pin lesen oder
ähnlich) und passend vor E L/H CS setzen und nach E H/L wieder zurück.
Zurücksetzen kann man die AVR-Takte zählen, das Verhältnis ist ja
konstant.

Problematisch ist erstmal die Syncronisation von CTC-Phase und dem
setzen von /CS des SID ohne die 6510-Zyklenlänge durcheinanderzubringen.
Der Rest ist relativ unkritiisch, habe ich schonmal in einem
MP-Playerversuch mit 2,5" Platte und 32k Ram am Memory-Bus so gemacht.

Werde ich wohl am Wochenende mal ranstecken/löten und dem SID möglichst
erstmal ein paar Töne entlocken. Irgendwelche natürlich nur....

Wäre auch noch zu klären, welche 6510-Befehle überhaupt mit dem SID
eigesetzt werden können, er hat ja nur Lese- oder Schreibregister.
Memory-modified-Befehle wie dec adresse usw. fallen damit ja sowieso aus
und müssen dann auch nicht behandelt werden.

Gruß aus Berlin
Michael
Autor: Michael U. (Gast)
Datum: 30.03.2007 08:50

Hallo,

@Hauke Sattler:

im Moment ein Mega8515, falls mir der Flash knapp wird durch die
Tabellen auch Mega162. Allerdings kann man die Befehlsroutinen stark
kürzen, wenn sie erstmal "fehlerfrei" spielen, im Moment ist alles
einzeln, hat den NAchteil, daß Fehler einer Befehlsgruppe in allen
BEfehlen einzeln korrigiert werden müssen, hat aber den Vorteil, daß es
keine versehentlichen Abhängigkeiten gibt.

Gruß aus Berlin
Michael
Autor: A.K. (Gast)
Datum: 30.03.2007 09:19

> ist ja schon mehr als 15 Jahre her

Langt aber nicht zum imponieren. AIX65 ca. 1979. ;-)

> Stackpointer-Verhalten ist schon klar

Aber wohl nicht richtig in den AVR-Code eingeflossen. Denn ST -Z
subtrahiert ja wohl vorher, nicht nacher.
Autor: Patrick Dohmen (oldbug) (Moderator) Benutzerseite
Datum: 30.03.2007 09:29

Das wäre doch mal wieder ein richtiger schönes Projekt für's Wiki!
Michael: hast Du nicht Lust, das dort zumindest "rudimentär"
einzustellen?
Autor: Michael U. (Gast)
Datum: 30.03.2007 10:08

Hallo,

@A.K.: naja, ich meinte mehr den C64 als solchen von mir zuletzt
benutzten 8-Bitter.

Ansonsten: Um 1980 Eigenbau 6800 mit 1k Eprom und 1k Ram mit
hangeschmiedetem "Betriebssytem" und 300Baud Tape-Interface.

So, zumindest näher dran als vorher. ;))))


Stackpointer: ich meinte gelesen zu haben pre-decrement und
post-increment.

Das 6510-Datenblatt bei www.6502.org ist ja nicht zu lesen, eigene
Unterlagen muß ich erst suchen gehen (sofern sie hoffentlich noch
existieren...).

Gruß aus Berlin
Michael
Autor: A.K. (Gast)
Datum: 30.03.2007 10:19

Hatte deshalb gestern sicherheitshalber nochmal nachgesehen. 1FF vor
JSR, 1FD danach, mit Daten in 0x1FE,0x1FF. Eben deshalb wird SP ja auf
FF initialisiert, nicht auf 00.

Richtig fies war meiner Erinnerung nach 6800. Da hat TXS/TSX
entsprechend korrigiert um die Verwirrung noch zu steigern.