Forum: Mikrocontroller und Digitale Elektronik Z80 Spezies: Retro Fieber 2 - Es geht weiter.


von Christian J. (Gast)


Angehängte Dateien:

Lesenswert?

Hallo,

in Anlehnung an den Beitrag 
Beitrag "Retro Fieber: Z80 oder 68000 ?"

den ich mir neulich nochmal in Teilen durchgelesen habe und teilweise 
auch die Geduld der Leute bewunderte, die mir damals von Null an 
geholfen haben ein lauffähiges Z80 System aufzusetzen. Ganz besonders 
Frank M (UKW), der große Teile des Codes beisteuerte, die ganze Ausgabe 
basiert auf seinen Libs und auch Leo C für sein aufwendiges Makefile 
(was aber bis heute nicht eine Änderungen der .h erkennt.) für den sdcc 
Compiler.

Es ist kein CP/M System, war nie geplant, wenn gleich der Bank Switch 
sinnvoll gewesen wäre um mehr RAM zu haben. Geht aber nicht mehr, 
Kamm-Fädeltechnik ist nicht mehr veränderbar.

Aktuell gibt es einen Monitor, der im ROM werkelt und kleine Funktionen 
bereit stellt. Programm laden, Ram testen, LEDs einschalten, eine Life 
Demo, ein altes DDR/NVA Textverschluesselungssystem.

Aktuell sieht ein Userprogramm immer noch so aus, dass es alles 
mitschleppt, was schon im ROM ist: ncurses Lib für VT100 Terminal, 
putchar, getchar zur Ausgabe und auch xprintf. Eigene INT Mode 2 
Vektoren. Und das kostet Speicher! Wozu braucht ein Userpogramm Int 
Routinen? Vielleicht einen Timer Int. Das EPROM wird komplett nicht mehr 
benutzt, selbst die INT Tabelle klaue ich ihm, die wird dann bei 0x4040 
neu erzeugt für das Userprogramm das bei 0x4100 beginnt hinter der sog. 
Zeropage.

Was ist geplant? Aufräumen!

Programmiert wird nur in C mit dem sdcc, Assembler nur im Startup Code 
und sonst nirgends.

Die Basisfunktionen getchar und putchar, auf denen sowohl ncurses 
basiert als auch xprintf arbeiten vollautomatisch als ISR des MK3801 
Multi-Funktionsbausteins von MOSTEK (da ist eine USART drin und 4 Timer 
und dazu noch einige GPIO, die interruptfähig sind). Zieht sich 150mA 
der Stein und ist lecker warm aber er spielt. Zeichen die ich im PC 
tippe im VT100 Terminal werden per ISR abgeholt und ge-ringpuffert, 
Zeichen zur Ausgabe des Z80 marschieren auch in einen Puffer und werden 
zum PC mit 38400 baud gelenkt.
Das alles liegt bei Systemstart im EPROM drin.

Und da soll es auch bleiben!

Ein Userprogramm welches über IntelHex vom PC aus geladen wird soll sich 
aus den vielen Routinen des EPROMS bedienen, wo ich noch weiter alles 
mögliche Nützliche ablegen möchte, zb Funktionen der String Lib, die neu 
gekapselt werden. Bis es voll ist mit 16kb. Habe noch 8 kb übrig.

Im Header des Userprogramm werden diese EPROM Funktionen dann 
referenziert. Das ist mühsam, ich muss mir aus dem Kompiler Listing alle 
Einsprungadressen raussuchen und per Hand eintragen. Das EPROM wird 
quasi als Library eingebunden. Wie ich sowas bei

void xprintf (const char* fmt, ...);
void xsprintf (char* buff, const char* fmt, ...);
void xfprintf (void (*func)(unsigned char), const char* fmt, ...);

mit variablen Parameterlisten mache

genau mache weiss ich auch noch nicht, soweit reichen meine C Kenntnisse 
nicht.

Was ich noch nicht weiss ist:

Beim C64 gab es die Möglichkeit über sog. POKES viele Dinge des OS zu 
steuern. Mein EPROM hat ja auch einen eigenen Variablenbereich "oben" 
von 256 Bytes und der soll auch erhalten bleiben, braucht es ja auch für 
zb die ISR.

Welche technische Lösung gäbe es, dass ein Userprogramm sich in ISR 
einhackt, die aktuell im EPROM liegen, die Int Mode 2 Vektor Tabelle 
auch dort bei 0x0040.? Liesse sich da bereits beim Booten etwas 
vorbereiten? Ich mlchte ungern im Userprogramm die INT Tabelle 
verschieben müssen,was allerdings ginge.

Ich glaube der sdcc hat auch die Möglichkeit Variablen oder Vektoren auf 
festen Adressen anzusprechen, hat eigentlic jeder Kompiler.

Ideen willkommen...

Gruss,
Christian

von Frank K. (fchk)


Lesenswert?

Christian J. schrieb:

> Welche technische Lösung gäbe es, dass ein Userprogramm sich in ISR
> einhackt, die aktuell im EPROM liegen, die Int Mode 2 Vektor Tabelle
> auch dort bei 0x0040.? Liesse sich da bereits beim Booten etwas
> vorbereiten? Ich mlchte ungern im Userprogramm die INT Tabelle
> verschieben müssen,was allerdings ginge.

Damals waren zwei Methoden üblich:

1. Im ROM zu jedem Interrupt-Vektor ein LD HL, (<ramvektor>); JMP (HL) 
hineinsetzen und beim Start die RAM-Vektoren ins ROM zeigen lassen.

2. Beim Reset das ROM ab Adresse 0 UND noch irgendwo anders (ab E000 
oder F000) mappen und dann beim Booten in den oberen Adressbereich 
(immer noch ROM) springen und dann ab Adresse 0 RAM hinmappen. Das war 
bei CP/M-Maschinen Pflicht. Brauchte nur etwas Grips beim Designer und 
ein 74LS74. Aber ich glaube, das hast Du verpennt und dir buchstäblich 
verbaut. Ja, wer die Geschichte nicht kennt, ist dazu verdammt, sie zu 
wiederholen.

fchk

von (prx) A. K. (prx)


Lesenswert?

Frank K. schrieb:
> 2. Beim Reset das ROM ab Adresse 0 UND noch irgendwo anders (ab E000
> oder F000) mappen und dann beim Booten in den oberen Adressbereich
> (immer noch ROM) springen und dann ab Adresse 0 RAM hinmappen.

Sowas in der Art hatte ich damals schon erwähnt, als er das baute. Ein 
Modus, der ab Reset read=ROM,write=RAM schaltet und mit einem bestimmten 
I/O-Zugriff dann auf r/w=RAM wechselt. Die erste Aktion ab Reset ist 
dann eine Art memcpy(0, 0, N) um das ROM ins RAM zu kopieren. Danach 
wechselt man in den reinen RAM-Modus.

von Frank K. (fchk)


Lesenswert?

Das nennt man dann beratungsrenitent.

fchk

von Christian J. (Gast)


Lesenswert?

A. K. schrieb:

> Frank K. schrieb:
>> 2. Beim Reset das ROM ab Adresse 0 UND noch irgendwo anders (ab E000
>> oder F000) mappen und dann beim Booten in den oberen Adressbereich
>> (immer noch ROM) springen und dann ab Adresse 0 RAM hinmappen.
>
> Sowas in der Art hatte ich damals schon erwähnt, als er das baute. Ein
> Modus, der ab Reset read=ROM,write=RAM schaltet und mit einem bestimmten
> I/O-Zugriff dann auf r/w=RAM wechselt. Die erste Aktion ab Reset ist
> dann eine Art memcpy(0, 0, N) um das ROM ins RAM zu kopieren. Danach
> wechselt man in den reinen RAM-Modus.

Das geht aber jetzt nicht mehr und gut. Darüber zu philosophieren, was 
vor 3 Jahren war macht keinen Sinn. es gibt etliche systeme, die so 
ausgebaut waren wie meines, unten ROM, oben RAM. Der C64 lief auch 
damit. Mit CPM hatte ich nie was am Hut und es war nie Zweck das x.te 
CP/M Ding nachzubauen. Und damit kann man auch zurecht kommen. Die Idee 
die RAM Vektoren in die ROM Tabelle zeigen zu lassen werde ich mal 
aufgreifen...

von (prx) A. K. (prx)


Lesenswert?

Christian J. schrieb:
> Das geht aber jetzt nicht mehr und gut.

Könnte man m.E. nachrüsten.

von Christian J. (Gast)


Angehängte Dateien:

Lesenswert?

A. K. schrieb:
> Christian J. schrieb:
>> Das geht aber jetzt nicht mehr und gut.
>
> Könnte man m.E. nachrüsten.

Bitte...... Fädelkämme sind nicht mehr rückgängig zu machen! Teilweise 
mit Lack fixiert. Das 0,1mm dünne Kabel ist da zigfach umwickelt drin. 
Zudem keine freie Ecke mehr auf der Platine. Und nach 3 Jahren fange ich 
nicht an etwas Funktionierendes umzubauen, was nachher nicht mehr läuft. 
Der Datenbus + 8 Adressleitungen + Demuxer Leitungen sind rausgeführt 
und da kann man alles dran bauen. Ist auch alles schön bunt auf dem 
Bildschirm.

Heute bin ich ja 3 Jahre älter, etwas grauer und etwas klüger als 
damals.

So sieht das im Startup Code derzeit aus, da liegen nur Vektoren. Die 
Bodys der Routinen sind meist leer, nur ein RETFIE drin.
1
 .module crt0            ; Modul Name für den Linker
2
3
    ; Memory Map Adressen der Zeropage (vom Benutzer definierbar)
4
    ; Definitions
5
6
    offset           .equ   0x4000        ; Basisadresse des Codes
7
    reset_vector     .equ   offset
8
    stack            .equ   0x000        ; Stack
9
    adr_vec_table    .equ   offset + 0x40 ; Mode 2 Vektor Tabelle für STI Mostek Multi I/O
10
    adr_copyright    .equ   offset + 0x80
11
    heap_size        .equ   512         ; Benutzer definierte Heap Groesse
12
13
    ; Globale Funktionen und Variablen für das C-Programm
14
15
    .globl  _main
16
17
    ; Interruptroutinen für den Mostek MK3801 Multi I/O Baustein
18
    ; Manual STI Baustein MK3801 Figure 7
19
    .globl  _int_sti_gpi_0  ; General Purpose Interrupt 0
20
    .globl  _int_sti_gpi_1  ; General Purpose Interrupt 1
21
    .globl  _int_sti_gpi_2  ; General Purpose Interrupt 2
22
    .globl  _int_sti_gpi_3  ; General Purpose Interrupt 3
23
    .globl  _int_sti_timer_d
24
    .globl  _int_sti_timer_c
25
    .globl  _int_sti_gpi_4  ; General Purpose Interrupt 4
26
    .globl  _int_sti_gpi_5  ; General Purpose Interrupt 5
27
    .globl  _int_sti_timer_b
28
    .globl  _int_sti_transmit_buffer_empty
29
    .globl  _int_sti_transmit_error
30
    .globl  _int_sti_receive_error
31
    .globl  _int_sti_receive_buffer_full
32
    .globl  _int_sti_timer_a
33
    .globl  _int_sti_gpi_6  ; General Purpose Interrupt 6
34
    .globl  _int_sti_gpi_7  ; General Purpose Interrupt 7
35
36
    .globl l__INITIALIZER
37
    .globl s__INITIALIZER
38
    .globl s__INITIALIZED
39
40
    .globl __sdcc_heap_init
41
    .globl _letzte_code_adresse
42
    .globl _erste_code_adresse
43
44
    ; -------------------------------------------------------------
45
46
    .area   _HEADER (ABS)
47
    ; Reset vector bei Kaltstart und Sprung ins User Programm
48
    .org    reset_vector
49
    _erste_code_adresse:
50
     jp init
51
52
;///////////////////////////////////////////////////////////
53
    ; Tabelle der Mode 2 Int Vektoren auf die Handler Funktionen im C Modul
54
    ; Reihenfolge beachten !!! Siehe Manual Mostek 3801, Interrupt Tabelle
55
    .org adr_vec_table
56
    .dw (_int_sti_gpi_0)
57
    .dw (_int_sti_gpi_1)
58
    .dw (_int_sti_gpi_2)
59
    .dw (_int_sti_gpi_3)
60
    .dw (_int_sti_timer_d)
61
    .dw (_int_sti_timer_c)
62
    .dw (_int_sti_gpi_4)
63
    .dw (_int_sti_gpi_5)
64
    .dw (_int_sti_timer_b)
65
    .dw (_int_sti_transmit_error)
66
    .dw (_int_sti_transmit_buffer_empty)
67
    .dw (_int_sti_receive_error)
68
    .dw (_int_sti_receive_buffer_full)
69
    .dw (_int_sti_timer_a)
70
    .dw (_int_sti_gpi_6)
71
    .dw (_int_sti_gpi_7)

von Frank K. (fchk)


Lesenswert?

Christian J. schrieb:
> Der C64 lief auch damit.

Auha. Gefährliches Viertelwissen.
Der C64 hatte einen 6502, der seine drei Vektoren für Reset, NMI und IRQ 
bei FFFC, FFFA und FFFE hatte. Alle ROMs waren ausblendbar, und die 
Vektoren für die aktuellen NMI und IRQ-Routinen lagen in der Zeropage.

Ein ZX Spectrum wäre ein geeigneteres Beispiel für Dich gewesen.

Du hattest wohl weder das eine noch das andere gehabt.

fchk

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.