Hi! Ich möchte Euch hiermit ein kleines Projekt vorstellen... http://www.embedded-it.de/bsp/demos/8080_emulator.php Ein Intel 8080 CP/M Emulator für Mikrocontroller. Und das beste dabei: Der eigentliche Emulator Code ist nur ca. 4K groß! Ein ähnliches Projekt wurde bereits in [1] besprochen. Wolltet Ihr nicht auch schon immer mal Eure alte Textverarbeitung (z.B. MicroPRO WordStar) oder Turbo Pascal 1.0 auf einem Mikrocontroller laufen lassen? Die Software ist für das Nut/OS Betriebssystem [2] geschrieben und lässt sich damit auf einer Reihe von Plattformen verwenden. Allen voran natürlich ARM (auf unserem eNet-sam7X Modul), aber auch AVR32, CortexM3. Es wird ein vollständiges CP/M System inkl. Terminal- und Disc-Controller emuliert. Da CP/M ein ein Disketten basiertes Betriebssystem ist, werden zwei Disk-Images (hier jeweils bis zu 8 MB groß) sowie das Bios des emulierten Rechners benötig. Alles zusammen wird auf einer SD-Karte abgelegt. Für ein minimales System sind damit z.B. nur ein At91sam7x512, ein SD-Sockel sowie etwas Vogelfutter nötig. Getestet habe ich das Programm auf dem Ethernut 3 board sowie unserem eNet-sam7X. Es sollte jedoch ohne größere Änderungen zumindest auch auf dem Elektor Internet Radio (EIR), Ethernut5, etc. laufen. Minimalvoraussetzungen für den nachbau sind eigentlich lediglich - eine CPU, für die ein Nut/OS Port existiert - ein SD-Karten Slot - ca. 80kByte RAM (davon werden 64K für das CP/M System benötigt). Diverse interessante Retro-Computing Software findet sich im übrigen unter [3]. Da das ganze OpenSource ist freue ich mich natürlich über alle Ideen, Vorschläge und Erweiterungen! Viele Grüße, Ole [1] Beitrag "CP/M auf ATmega88" [2] http://www.ethernut.de [3] http://www.retroarchive.org
Sorry... Bild vergessen... Anbei ein Screenshot der Ausgaben des laufenden Emulators (in minicom). Viele Grüße, Ole
Hi Ole, long time no see :-). Ole Reinhardt schrieb: > Turbo Pascal 1.0 Hmm... war Turbo Pascal nicht Z80-only? Grüße, Michael
Ole Reinhardt schrieb: > auf unserem eNet-sam7X Modul Üble Schleichwerbung... Erinnert irgendwie an Robert Teufel, der damals für NXP Guerilla-Werbung hier gemacht hat...
Sorry, dass es Leute gibt, die zufällig auch noch selber Hardware herstellen... Hier geht es jedoch konkret um ein reines Hobby und dazu auch noch OpenSource Projekt, welches völlig Hardware unabhängig ist (im Rahmen dessen, was von Nut/OS supported wird). Das hat nicht im geringsten was mit Schleichwerbung zu tun. Nut/OS ist im übrigen ebenfalls ein OpenSource Projekt unter BSD Lizenz... Viele Grüße, Ole
Der verwendete Emulator von Óscar Toledo Gutiérrez ist ja mal absolut krass. Das der den Code noch selbst verstanden hat kann man kaum glauben. Eine komplette 8080 Emulation mit zwei Seiten Code ... Wahnsinn. Sein Schachprogramm ist genauso heftig. 1,4K Quelltext. Der komplette Emulator :
1 | #include <stdio.h> |
2 | #define n(o,p,e)=y=(z=a(e)%16 p x%16 p o,a(e)p x p o),h(
|
3 | #define s 6[o]
|
4 | #define p z=l[d(9)]|l[d(9)+1]<<8,1<(9[o]+=2)||++8[o]
|
5 | #define Q a(7)
|
6 | #define w 254>(9[o]-=2)||--8[o],l[d(9)]=z,l[1+d(9)]=z>>8
|
7 | #define O )):((
|
8 | #define b (y&1?~s:s)>>"\6\0\2\7"[y/2]&1?0:(
|
9 | #define S )?(z-=
|
10 | #define a(f)*((7&f)-6?&o[f&7]:&l[d(5)])
|
11 | #define C S 5 S 3
|
12 | #define D(E)x/8!=16+E&198+E*8!=x?
|
13 | #define B(C)fclose((C))
|
14 | #define q (c+=2,0[c-2]|1[c-2]<<8)
|
15 | #define m x=64&x?*c++:a(x),
|
16 | #define A(F)=fopen((F),"rb+")
|
17 | unsigned char o[10],l[78114],*c=l,*k=l |
18 | #define d(e)o[e]+256*o[e-1]
|
19 | #define h(l)s=l>>8&1|128&y|!(y&255)*64|16&z|2,y^=y>>4,y^=y<<2,y^=~y>>1,s|=y&4
|
20 | +64506; e,V,v,u,x,y,z,Z; main(r,U)char**U;{ |
21 | |
22 | { { { } } } { { { } } } { { { } } } { { { } } } |
23 | { { { } } } { { { } } } { { { } } } { { { } } } |
24 | { { { } } } { { { } } } { { { } } } { { { } } } |
25 | { { { } } } { { { } } } { { { } } } { { { } } } |
26 | { { { } } } { { { } } } { { { } } } { { { } } } |
27 | { { { } } } { { { } } } { { { } } } { { { } } } |
28 | { { ; } } { { { } } } { { ; } } { { { } } } |
29 | { { { } } } { { { } } } { { { } } } { { { } } } |
30 | { { { } } } { { { } } } { { { } } } { { { } } } |
31 | { { { } } } { { { } } } { { { } } } { { { } } } |
32 | { { { } } } { { { } } } { { { } } } { { { } } } |
33 | { { { } } } { { { } } } { { { } } } { { { } } } |
34 | { { { } } } { { { } } } { { { } } } { { { } } } |
35 | |
36 | for(v A((u A((e A((r-2?0:(V A(1[U])),"C") |
37 | ),system("stty raw -echo min 0"),fread(l,78114,1,e),B(e),"B")),"A")); 118-(x |
38 | =*c++); (y=x/8%8,z=(x&199)-4 S 1 S 1 S 186 S 2 S 2 S 3 S 0,r=(y>5)*2+y,z=(x& |
39 | 207)-1 S 2 S 6 S 2 S 182 S 4)?D(0)D(1)D(2)D(3)D(4)D(5)D(6)D(7)(z=x-2 C C C C |
40 | C C C C+129 S 6 S 4 S 6 S 8 S 8 S 6 S 2 S 2 S 12)?x/64-1?((0 O a(y)=a(x) O 9 |
41 | [o]=a(5),8[o]=a(4) O 237==*c++?((int (*)())(2-*c++?fwrite:fread))(l+*k+1[k]* |
42 | 256,128,1,(fseek(y=5[k]-1?u:v,((3[k]|4[k]<<8)<<7|2[k])<<7,Q=0),y)):0 O y=a(5 |
43 | ),z=a(4),a(5)=a(3),a(4)=a(2),a(3)=y,a(2)=z O c=l+d(5) O y=l[x=d(9)],z=l[++x] |
44 | ,x[l]=a(4),l[--x]=a(5),a(5)=y,a(4)=z O 2-*c?Z||read(0,&Z,1),1&*c++?Q=Z,Z=0:( |
45 | Q=!!Z):(c++,Q=r=V?fgetc(V):-1,s=s&~1|r<0) O++c,write(1,&7[o],1) O z=c+2-l,w, |
46 | c=l+q O p,c=l+z O c=l+q O s^=1 O Q=q[l] O s|=1 O q[l]=Q O Q=~Q O a(5)=l[x=q] |
47 | ,a(4)=l[++x] O s|=s&16|9<Q%16?Q+=6,16:0,z=s|=1&s|Q>159?Q+=96,1:0,y=Q,h(s<<8) |
48 | O l[x=q]=a(5),l[++x]=a(4) O x=Q%2,Q=Q/2+s%2*128,s=s&~1|x O Q=l[d(3)]O x=Q / |
49 | 128,Q=Q*2+s%2,s=s&~1|x O l[d(3)]=Q O s=s&~1|1&Q,Q=Q/2|Q<<7 O Q=l[d(1)]O s=~1 |
50 | &s|Q>>7,Q=Q*2|Q>>7 O l[d(1)]=Q O m y n(0,-,7)y) O m z=0,y=Q|=x,h(y) O m z=0, |
51 | y=Q^=x,h(y) O m z=Q*2|2*x,y=Q&=x,h(y) O m Q n(s%2,-,7)y) O m Q n(0,-,7)y) O |
52 | m Q n(s%2,+,7)y) O m Q n(0,+,7)y) O z=r-8?d(r+1):s|Q<<8,w O p,r-8?o[r+1]=z,r |
53 | [o]=z>>8:(s=~40&z|2,Q=z>>8) O r[o]--||--o[r-1]O a(5)=z=a(5)+r[o],a(4)=z=a(4) |
54 | +o[r-1]+z/256,s=~1&s|z>>8 O ++o[r+1]||r[o]++O o[r+1]=*c++,r[o]=*c++O z=c-l,w |
55 | ,c=y*8+l O x=q,b z=c-l,w,c=l+x) O x=q,b c=l+x) O b p,c=l+z) O a(y)=*c++O r=y |
56 | ,x=0,a(r)n(1,-,y)s<<8) O r=y,x=0,a(r)n(1,+,y)s<<8)))); |
57 | system("stty cooked echo"); B((B((V?B(V):0,u)),v)); } |
Hi Andreas, genau. Für die Nut/OS Portierung musste ich allerdings ein paar Kleinigkeiten anpassen. War gar nicht so einfach sich in den obfuscateten Code einzuarbeiten. Das coolste ist jedoch, dass ca. 30 % des Quelltextes auf die Klammern (8080) drauf gehen... Btw: Der oben gepostete Code läuft im übrigen so 1a unter Linux. Einfach ein gcc -o 8080 8080.c und dann die drei Dateien A, B und C (C --> c_bios.bin oder c_basic.bin) zur Verfügung stellen.
Michael Engel schrieb: > Hmm... war Turbo Pascal nicht Z80-only? Hm, in der Tat :) Wikipedia lügt... Ich hatte es zuvor tatsächlich nur auf einem Z80 Emulator getestet.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.