Forum: Mikrocontroller und Digitale Elektronik Intel 8080 CP/M Emulator für Mikrocontroller (ARM7, ARM9, CortexM3, AVR32)


von Ole R. (olereinhardt)


Lesenswert?

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

von Ole R. (olereinhardt)


Angehängte Dateien:

Lesenswert?

Sorry... Bild vergessen...

Anbei ein Screenshot der Ausgaben des laufenden Emulators (in minicom).

Viele Grüße,

Ole

von Michael E. (cuby)


Lesenswert?

Hi Ole,

long time no see :-).

Ole Reinhardt schrieb:
> Turbo Pascal 1.0

Hmm... war Turbo Pascal nicht Z80-only?

Grüße,
    Michael

von Maestro (Gast)


Lesenswert?

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...

von Ole R. (olereinhardt)


Lesenswert?

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

von Andreas J. (antibyte)


Lesenswert?

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)); }

von Ole R. (olereinhardt)


Lesenswert?

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.

von Ole R. (olereinhardt)


Lesenswert?

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
Noch kein Account? Hier anmelden.