Forum: Mikrocontroller und Digitale Elektronik Intel 4004 Assemblerprogrammierung


von Wolfgang R. (Firma: www.wolfgangrobel.de) (mikemcbike)


Angehängte Dateien:

Lesenswert?

8051 ist mir zu neu und ARM zu komplex. Da mir letztens ein 
Uralt-Programmer der Marke Pro-Log M900 in die Hände fiel...

http://www.wolfgangrobel.de/programmer/m900.htm

und der 4004-Code nicht mehr funktionierte, dachte ich mir, eine 
Neuprogrammierung wäre sinnfrei aber trotzdem fein.

Unter http://e4004.szyc.org/ gibt es einen hervorragenden Assembler / 
Disassembler / Emulator, der einem prächtig beim Ausprobieren der 
Programme auch ohne Hardware hilft.

Folgendes Programm habe ich mal geschrieben, um eine 16-stellige 
Dezimalmultiplikation zu erreichen. Das ist nicht ganz trivial bei so 
wenig Befehlen und nur 4 Bit Datenbreite...
1
; *********************************************************************
2
; * 4004 Testroutine - Rechner
3
; * *******************************************************************
4
; * WR - 2017-04-03
5
; * *******************************************************************
6
; * Version 1.0
7
; * *******************************************************************
8
; * Funktion: A += B; A -= B; A = C*D  
9
; *   P0_R0R1:  Datenpointer ZAHL A (Ergebnis)
10
; *    P1_R2R3:   Datenpointer ZAHL B
11
; *   P2_R4R5:  Datenpointer ZAHL C
12
; *   P3_R6R7:  Datenpointer ZAHL D
13
; *    P4_R8R9:  Schleifenzaehler / Austauschregister
14
; *    P5_R10R11:  Zaehler Subroutine / Austauschregister Subroutine
15
; *    P6_R12R13:  Datenpointer 1 Subroutine
16
; *    P7_R14R15:  Datenpointer 2 Subroutine
17
; *********************************************************************
18
19
; *********************************************************************
20
; *********************************************************************
21
; **************       Initialisierungen       **************
22
; *********************************************************************
23
; *********************************************************************
24
25
INIT  LDM 0      ; select RAM bank 0
26
    DCL        ; Set Command Line
27
    ; Register mit Zahlen fuellen
28
    FIM P0, DATAA  ; Look Up Adresse Zahl A
29
    FIM P1, $00    ; Registeradresse Zahl A
30
    JMS LDNUM
31
    FIM P0, DATAB  ; Look Up Adresse Zahl B
32
    FIM P1, $10    ; Registeradresse Zahl B
33
    JMS LDNUM
34
    FIM P0, DATAC  ; Look Up Adresse Zahl C
35
    FIM P1, $20    ; Registeradresse Zahl C
36
    JMS LDNUM
37
    FIM P0, DATAD  ; Look Up Adresse Zahl D
38
    FIM P1, $30    ; Registeradresse Zahl D
39
    JMS LDNUM    ; Sprung zum Programmstart
40
    JUN MAIN
41
    ; Kopierroutine
42
LDNUM  LDM $8
43
    XCH R8      ; Schleifenzaehler 8 Zugriffe
44
LDNUM1  FIN P2      ; Datum holen
45
    XCH R4
46
    SRC P1
47
    WRM
48
    XCH R5
49
    INC R3
50
    SRC P1
51
    WRM
52
    INC R3
53
    INC R1      ; naechstes Datum
54
    ISZ R8, LDNUM1
55
    BBL 0
56
*=$030          ; Lookup Table Start auf Vielfachem von 16!
57
DATAA    
58
    .BYTE $00    ; 00 00 00 00 00 00 00 00
59
    .BYTE $00    
60
    .BYTE $00
61
    .BYTE $00
62
    .BYTE $00
63
    .BYTE $00
64
    .BYTE $00
65
    .BYTE $00
66
DATAB    
67
    .BYTE $01    ; 00 00 00 89 76 54 32 10
68
    .BYTE $23
69
    .BYTE $45
70
    .BYTE $67
71
    .BYTE $89
72
    .BYTE $00
73
    .BYTE $00
74
    .BYTE $00
75
DATAC    
76
    .BYTE $01    ; 00 00 00 89 76 54 32 10
77
    .BYTE $23
78
    .BYTE $45
79
    .BYTE $67
80
    .BYTE $89
81
    .BYTE $00
82
    .BYTE $00
83
    .BYTE $00
84
DATAD    
85
    .BYTE $00    ; 00 00 00 00 00 00 00 00
86
    .BYTE $00
87
    .BYTE $00
88
    .BYTE $00
89
    .BYTE $00
90
    .BYTE $00
91
    .BYTE $00
92
    .BYTE $00  
93
      
94
; *********************************************************************
95
; *********************************************************************
96
; **************       Hauptprogramm         **************
97
; *********************************************************************
98
; *********************************************************************
99
  
100
MAIN  FIM P6, $10    ; Register 3 = Register 1
101
    FIM P7, $30
102
    JMS COPY
103
    JMS MUL01    ; Register 0 = Register 1 * Register 2
104
    FIM P6, $30    ; Register 1 = Register 3
105
    FIM P7, $10
106
    JMS COPY
107
    FIM P6, $30    ; Clear Register 3
108
    JMS CLEAR
109
    
110
LOCK  JUN LOCK  
111
  
112
; *********************************************************************
113
; *********************************************************************
114
; **************       Unterprogramme         **************
115
; *********************************************************************
116
; *********************************************************************  
117
118
; *********************************************************************
119
; Leftshift REG1 - Multiplikation mit 10
120
; *********************************************************************
121
; Aendert: Register File 1
122
; Aendert: ACC
123
; Aendert: R10, R11, P7(R14,R15)
124
; *********************************************************************
125
LSHFT  LDM $0
126
    XCH R10      ; Schleifenzaehler 16 Digits
127
    LDM $0
128
    XCH R11      ; Austauschregister (Anfang 0)
129
    FIM P7, $10    ; Register  Pointer P7 (R14,R15)
130
LS02  SRC P7      ; Adresspointer einstellen
131
    RDM        ; ACC <-  REG1[R10]
132
    XCH R11
133
    WRM        ; REG0[R10] <- R11
134
    INC R15      ; P7 += 1
135
    ISZ R10, LS02
136
    BBL 0
137
    
138
; *********************************************************************
139
; CLEAR (P6) = 0
140
; *********************************************************************
141
; Aendert: Register File (P6)
142
; Aendert: ACC
143
; Aendert: R10, P6(R12,R13)
144
; *********************************************************************; 
145
CLEAR  LDM $0
146
    XCH R10      ; Schleifenzaehler 16 Digits
147
CLEAR1  SRC P6      ; Adresspointer einstellen
148
    LDM $0
149
    WRM        ; REGn[R10] <- 0
150
    INC R13
151
    ISZ R10, CLEAR1 ; Naechste Stelle
152
    BBL 0    
153
154
; *********************************************************************
155
; COPY (P6)-->(P7)
156
; *********************************************************************
157
; Aendert: Register File (P7)
158
; Aendert: ACC
159
; Aendert: R10, Vorher P6 mit Quelle und P7 mit Ziel laden!
160
; *********************************************************************; 
161
COPY  LDM $0
162
    XCH R10      ; Schleifenzaehler 16 Digits
163
COPY04  SRC P6      ; Adresspointer einstellen
164
    RDM        ; ACC <-  REG0[P7]
165
    SRC P7
166
    WRM        ; REG1[R8] <- ACC
167
    INC R13
168
    INC R15
169
    ISZ R10, COPY04  ; Naechste Stelle
170
    BBL 0    
171
        
172
; *********************************************************************
173
; Addition REG0 = REG0 + REG1
174
; *********************************************************************
175
; Aendert: Register File 0
176
; Aendert: ACC
177
; Aendert: R10, P6(R12,R13), P7(R14,R15)
178
; *********************************************************************;
179
ADDAB  CLC
180
    LDM $0
181
    XCH R10      ; Schleifenzaehler 16 Digits
182
    FIM P6, $00    ; Summand 1, Summe
183
    FIM P7, $10    ; Summand 2
184
ADD01  SRC P6
185
    RDM        ; A lesen
186
    SRC P7
187
    ADM        ; B dazu addieren
188
    DAA
189
    SRC P6
190
    WRM        ; A schreiben
191
    INC R13
192
    INC R15
193
    ISZ R10, ADD01  ; Naechste Stelle
194
    BBL 0
195
196
; *********************************************************************
197
; Subtraktion REG0 = REG1 - REG2 oder REG2 - REG1
198
; *********************************************************************
199
; Aendert: Register File 0
200
; Aendert: ACC
201
; Aendert: R10, P0(R0,R1), P6(R12,R13), P7(R14,R15)
202
; *********************************************************************;    
203
SUBBC  LDM $0
204
    XCH R10      ; Schleifenzaehler 16 Digits
205
    FIM P6, $00    ; Subtrahend 1
206
    FIM P7, $10    ; Subtraktor 2
207
    FIM P0, $20    ; Differenz
208
SUBBC1  STC
209
SUBBC2  TCS        ; Transfer Carry Subtract
210
    SRC P6
211
    SBM        ; ACC = ACC - P1
212
    CLC
213
    SRC P7
214
    ADM        ; ACC = ACC + P0
215
    DAA        ; Decimal Adjust
216
    SRC P0
217
    WRM        ; P2 = ACC
218
    INC R1
219
    INC R13
220
    INC R15
221
    ISZ R10, SUBBC2  ; naechste Stelle
222
    JCN CN, SUBBC3  ; Wenn Ergebnis <0 --> Subtrahenden tauschen
223
    FIM P7, $00    ; Subtrahend 1
224
    FIM P6, $10    ; Subtraktor 2
225
    FIM P0, $20    ; Differenz
226
    SRC P0      ; Registeradresse einstellen
227
    LDM 1
228
    WR3        ; Status Ergebnis negativ
229
    JUN SUBBC1    ; Subtraktion noch mal machen
230
SUBBC3  BBL 0    
231
232
; *********************************************************************
233
; Multiplikation REG0 = REG1 * REG2
234
; *********************************************************************
235
; Aendert: Register File 0, 1
236
; Aendert: ACC
237
; Aendert: R10, P2(R4,R5)
238
; *********************************************************************;          
239
; Multiplikation REG0 = REG1 * REG2 (A = B * C)
240
MUL01  LDM $0
241
    XCH R8      ; Schleifenzaehler 16 Digits MUL
242
    FIM P2, $20    ; Pointer C
243
MUL02  SRC P2
244
    RDM        ; Digit lesen
245
    XCH R9      ; Additionszaehler
246
MUL03  LD  R9      ; Anzahl Schleifendurchlaeufe; 0: Break!
247
    JCN A0, MUL04  ; Abbruch bei 0
248
    DAC        ; ACC-=1
249
    XCH R9      ; Zaehler zurueckschreiben
250
    JMS ADDAB    ; A+=B
251
    JUN MUL03    ; naechster Schleifendurchlauf
252
MUL04   JMS LSHFT    ; B<<1
253
    INC R5
254
    ISZ R8, MUL02
255
MUL05  BBL 0     
256
    
257
.END

von Wolfgang R. (Firma: www.wolfgangrobel.de) (mikemcbike)


Lesenswert?

Der Spaß ist mir eingefallen, weil es hier im Forum schon mal die Frage 
nach einer solchen Multiplikation gab...

Wer will, kann den Code gerne ausprobieren oder auch eigene Routinen zur 
Verfügung stellen. Komisch, im Netz sind kaum Code-Snippets zum 4004 zu 
finden, woran mag das liegen?

;-)

von Georg (Gast)


Lesenswert?

Wolfgang R. schrieb:
> und der 4004-Code nicht mehr funktionierte

Programme nutzen sich nicht ab und hören auf zu funktionieren. Auf 
funktionsfähiger Hardware muss das Programm noch in Tausenden von Jahren 
laufen.

Georg

von (º°)·´¯`·.¸¸.·´¯`·.¸¸.·´¯`·.¸¸.·´¯`·.¸¸.·´¯`·.¸¸.· (Gast)


Lesenswert?

Den 4004 haette ich auch nur mit der Kneifzange angefasst.

Allein schon die von Intel dafuer vorgesehenen EPROMs,
mit 1/4 kByte und Programmierspannungen von > 50V wenn
ich mich richtig entsinne.

Und gegen die damals schon vorhandenen Minicomputer mit
16 oder 32 bit Verarbeitungsbreite, konnte ein 4004 auch
nichts reissen. Der einzige Vorteil waere die kleine moegliche
Bauform gewesen...


P.S.: Das Institut wo ich damals gearbeitet habe, hatte
ein komplettes IC-Kit vom 4004 im Panzerschrank.

Nur zusammenbauen wollte es keiner :-). Weil: Siehe oben...

von Wolfgang R. (Firma: www.wolfgangrobel.de) (mikemcbike)


Lesenswert?

Georg schrieb:
> Programme nutzen sich nicht ab und hören auf zu funktionieren.

Ach...

Aber EPROMs verlieren ihre Programmierung.

von Wolfgang R. (Firma: www.wolfgangrobel.de) (mikemcbike)


Lesenswert?

(º°)·´¯`·.¸¸.·´¯`·.¸¸.·´¯`·.¸¸.·´¯`·.¸¸.·´¯`·.¸¸.· schrieb im Beitrag 
#4962977:
> damals schon vorhandenen Minicomputer mit
> 16 oder 32 bit Verarbeitungsbreite

Welche waren das?

von Der Andere (Gast)


Lesenswert?

Wolfgang R. schrieb:
>> damals schon vorhandenen Minicomputer mit
>> 16 oder 32 bit Verarbeitungsbreite
>
> Welche waren das?

PDP 11

von Wolfgang R. (Firma: www.wolfgangrobel.de) (mikemcbike)


Lesenswert?

Der Andere schrieb:
> PDP 11

War vom Stromverbrauch und der benötigten Grundfläche nicht direkt 
vergleichbar... ;-)

von Der Andere (Gast)


Lesenswert?

Wolfgang R. schrieb:
> War vom Stromverbrauch und der benötigten Grundfläche nicht direkt
> vergleichbar... ;-)

Nein, aber ein damals verfügbarer "Minicomputer".

Und ein 4004 alleine macht auch noch keinen Rechner :-)
Der war doch eigentlich nur als Herzstück von Rechenmaschinen entwickelt 
worden, oder?

von Wolfgang R. (Firma: www.wolfgangrobel.de) (mikemcbike)


Lesenswert?

Vom Konzept her war er als 5-Chip Lösung ein funktionsfähiger Computer.

Prozessor: 4004
RAM: 4002
ROM: 4001 (verzichtbar, wenn EPROM)
Bus-Multiplexer 4008/9
und EPROM, z.B. 1702A oder 2708.

--> http://www.wolfgangrobel.de/programmer/img_m900/m900_05.jpg

Ein 6502 funktioniert auch nicht alleine...

von Bitwurschtler (Gast)


Lesenswert?

Der Andere schrieb:
> Wolfgang R. schrieb:
>> War vom Stromverbrauch und der benötigten Grundfläche nicht direkt
>> vergleichbar... ;-)
>
> Nein, aber ein damals verfügbarer "Minicomputer".
>
> Und ein 4004 alleine macht auch noch keinen Rechner :-)
> Der war doch eigentlich nur als Herzstück von Rechenmaschinen entwickelt
> worden, oder?

Naja, so einen richtigen standalone 4004 gab es eigentlich nicht. Dazu 
gabs "passend" entworfenen RAM/ROM. Und damit man für alle IC's das 
selbe billige Gehäuse nehmen kann wurde der 8bit Bus auf 4bit 
gemultiplexed. Also Datenrate mal mindestens halbiert nur um ein paar 
Cents für die Gehäuse zu sparen. Also Dämlichkeit ist keine Erfindung 
der letzen Jahre.

Da mal der Schaltplan zu dem Kerlchen: 
http://www.intel.com/Assets/PDF/General/4004_schematic.pdf

Ist heute nur noch als schlechtes Beispiel für Rechenwerkarchitektur 
brauchbar.

Vor 8008 sollte man keine CPU anfassen, erst mit Z80 kommt Spass auf. 
Meinetwegen noch 6502 und 6800, aber 4004 nimmer.

von Carl D. (jcw2)


Lesenswert?

Eigentlich sollte das doch ein Chipsatz für einen Tischrechner werden, 
aber ein kleiner Intel-Rebell hatte das Problem, daß er dieses Projekt 
ziemlich planlos geerbt hat. Durch die Idee der Programmierbarkeit, 
konnte er Hard- und Software parallel entwickeln und seinem Kunden, dem 
späteren Entwickler von Z80/Z8000 und 80286, plausibel machen, daß intel 
ihn nicht betrogen hatte. Und Rechenmaschinen leben von serieller 
BCD-Arithmetik und 4-Bit Speicherbreite. Es gibt auch die 
Original-Source der Busicom Rechenmaschine, in der man sehen kann, wie 
eine Virtuelle Maschine die Einzelziffern-Arithmetik zu komplexeren 
Operationen zusammenbaut.
Keine PDP11, aber auch keine Schrankwand!

http://www.4004.com/2009/Busicom-141PF-Calculator_asm_rel-1-0-1.txt

: Bearbeitet durch User
von Soul E. (Gast)


Lesenswert?

Bitwurschtler schrieb:

> Vor 8008 sollte man keine CPU anfassen, erst mit Z80 kommt Spass auf.
> Meinetwegen noch 6502 und 6800, aber 4004 nimmer.

Ford T-Modell fährt sich auch scheisse. Vor allem weil Gas und Bremse an 
der falschen Stelle sind.

von Manfred (Gast)


Lesenswert?

Wolfgang R. schrieb:
> Komisch, im Netz sind kaum Code-Snippets zum 4004 zu
> finden, woran mag das liegen?
Zu der Zeit haben die Leute noch gelesen und selbst nachgedacht.

Internet für Faule gab es damals noch nicht, wer der Materie nicht Herr 
wurde, hat sich einen anderen Beruf suchen müssen!

Wie Du sagst
Wolfgang R. schrieb:
> sinnfrei aber trotzdem fein
sehe ich das auch - aber mache es trotzdem weiter! Ich bin zu faul 
geworden, meine 6502 und 68HC805 noch einzusetzen.

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.