Moin, vielleicht kennen die es, die wie ich Mitte 40 sind und in den 80igern Lochraster Aufbauten mit 6502 oder Z80 gemacht haben. Auch ich habe noch solche Kabelverhaue gefunden, die Leiterplatten aus Presspapier sind allerdings extrem dunkelbraun geworden und ich kann nichts mehr in Betrieb nehmen, da ich weder Eprom Simulator habe, noch Brenner, noch die alten Software tools von damals unter DOS. Das Netz ist ja voll davon aber das macht es auch unübersichtlich. Gibt ja teilweise Monsterprojekte mit Ram Disk usw. Habe hier noch Original Z80er liegen, die rund 20 Jahre alt sind im DIP40 und auch einige 68000er, Format Milchschnitte im Keramik Gehäuse. Auch nicht jünger. Aber der 68000 ist wohl etwas zu komplex um das auf Lochraster aufzubauen. Und ein ualter verstaubter "Microprofessor" liegt hier auch noch, Asemberprogramme auf Papier, in Codes mit Tabelle umrechnen, eintippen als Hex .... kenne ich noch aber war "nervtötend". Wer mal einen IMSAI programmiert hat weiss was ich meine, die müssen damals unendlich viel Zeit gehabt haben. Meine Vorstellung, um das Ganze etwas handlicher zu machen sind Verzicht auf VGA Ausgabe, keine Peripherie usw. Woher nehmen und nicht stehlen? 1. Schaltplan für Minimalsystem mit Uart, PIO, Ram, ROM => Ok, Internet 2. Eprom Emulator? 3. Eprom Brenner und Eproms => ibäh, schon bestellt 4. PIO Bausteine, Timer, zb 8155, 8153 .... finde ich schon noch irgendwo. 5. C Cross Compiler für Linux oder Windows? Ausgabe: Hex File für Brenner 6. Assembler? Och nö..... das dauert ja ewig da was Gescheites zu programmieren. Alternativ würde mir folgende Lösung gefallen: Ein RS232 Terminalanschluss am Z80 System, Uart-USB Konverter, im EPROM ein komfortabler Monitor und ich bediene das ganze aus der Konsole von Linux heraus, so wie ich mich auf einm Raspi auch einlogge. Programme sollten hochgeladen werden können und im RAM ausgeführt werden. Hat sich schonmal jemand an sowas gewagt? So ein bisschen Old School Feeling aber mit modernen Elementen? Gruss Christian
Vor langer Zeit habe ich so was mal mit einem 6502 aufgebaut, allerdings mit EPROM Emulator als Hilfe. Für den 68000 gibt es GCC als Cross-Compiler und auch Assembler. Für den Z80 gibt es zumindest reichlich Simulatoren - man kann also ggf. das Debugging erst mal auf dem PC machen und erst dann auf die richtige Hardware gehen - ohne EPROM Emulator ist das recht hilfreich. Unter Linux stehen die Chancen nicht schlecht auch eine Cross Assembler und ggf. sogar Compiler zu finden - notfalls auch als Compiler auf einem Simulierten Z80 Computer (CP/M ?) aus der Steinzeit. Die Idee mit dem Minimalsystem als eine Art Bootloader ist gut. Das muss für den Anfang keine kompletter Monitor sein - ein Bootloader über UART reicht für den Anfang. Das spart für die Entwicklung den Umweg über das EPROM. Ein statisches CMOS RAM mit Stützbatterie ist ggf. eine Alternative zu EPROM. Den Bootloader/Monitor könnt man ggf. sogar auf einem modernen µC laufe lassen, der parallel mit am BUS hängt, und Wahlweise zum Z80 läuft. Wenn man sowieso nicht in ASM Programmiert, braucht man auch keine Antike CPU. In C merkt man davon nicht viel. So schlimm ist ASM auch nicht. Auch ist es mit einer ggf. nicht normalen Hardware ggf. nötig den Startcode des Compilers anzupassen, ganz ohne ASM wird es also schwer.
Wozu das Ganze? Es hat damals (tm) wahnsinnig Spass gemacht, aber die Sachen haben sich gewaltig verändert. Ich seh da absolut keinen Sinn mehr drin, da lass ich nicht mal Nostalgie mehr gelten. Mit einer simplen Ein-Chip-Lösung schlägst du um Längen alles, was selbst ein getuntes Z80-Komplettsystem jemals konnte. Und das, ohne eine rel. komplizierte und inzwischen teure Hardware zu bauen. Die Zeit kommt nie wieder, der nutzbare Lerneffekt ist auch eher klein. Falls du dennoch was damit machen willst - habe ich alles noch da, bringe es einfach nicht übers Herz, das Zeug zu entsorgen. Aber ich weiss genau, dass ich es nie wieder anfassen werde.
Hallo, > vielleicht kennen die es, die wie ich Mitte 40 sind und in den 80igern > Lochraster Aufbauten mit 6502 oder Z80 gemacht haben. äh, nein. Also, ja. Also, gemacht ("in der Mache") ja, aber andere Randbedingungen. :-) Ich bin seit langer Zeit mehr oder weniger unregelmäßig dabei (je nach Zeit und Lust), ein Z80-System aufzubauen. Der Winter steht vor der Tür, die notwendigsten Bestellungen sind eingetroffen, mal schauen. Im Augenblick läuft CP/M in 32 KB RAM, dazu gibt es hier irgendwo auch einen Threads von mir, oder zwei. > Aber der 68000 ist wohl etwas zu komplex um das auf Lochraster > aufzubauen. Ein 16 Bit breiter Bus ist mehr Löterei, ansonsten dürften die sich nicht besonders unterscheiden. Aber dafür gibt es ja den 68008. > Meine Vorstellung, um das Ganze etwas handlicher zu machen sind Verzicht > auf VGA Ausgabe, keine Peripherie usw. Nun, ich möchte daraus mal einen echten Computer bauen, d.h. es gibt ein einfaches Bussystem, wo man Peripherie und RAM nachstecken kann. > 1. Schaltplan für Minimalsystem mit Uart, PIO, Ram, ROM => Ok, Internet Ja, oder auch hier gibt es schon einige relativ minimale Schaltungen. > 2. Eprom Emulator? > 3. Eprom Brenner und Eproms => ibäh, schon bestellt > 4. PIO Bausteine, Timer, zb 8155, 8153 .... finde ich schon noch > irgendwo. Auf all das habe ich in meinem Konzept verzichtet und durch einen einzigen AVR ersetzt. Der Z80 ist als Anwendungsprozessor dem AVR als Boardcontroller untergeordnet. Der AVR kann den RAM selbstständig beschreiben und den Z80 resetten, erspart mir also das ROM, und ist außerdem (braucht ein zusätzliches schnelles Gatter) ein I/O-Gerät, welches UART, Floppy und (später) Timer bereitstellt. Wenn du mit nichts kompatibel sein musst, brauchst du auch die alten Bausteine nicht nachbilden. > 5. C Cross Compiler für Linux oder Windows? Ausgabe: Hex File für > Brenner SDCC ist ein optimierender C-Compiler, der u.a. den Z80 kennt und einige fertige Routinen mitbringt. > Ein RS232 Terminalanschluss am Z80 System, Uart-USB Konverter, im EPROM > ein komfortabler Monitor und ich bediene das ganze aus der Konsole von > Linux heraus, so wie ich mich auf einm Raspi auch einlogge. Programme > sollten hochgeladen werden können und im RAM ausgeführt werden. Noch enthält bei mir der AVR das Monitorprogramm, mit dem ich einen Speicherabzug (Hex-Datei) direkt in den Speicher schreiben kann. Außerdem kann man dort einstellen, welche Geräte in den Slots stecken (das Betriebssystem kann das dann auslesen und die entsprechenden Treiber laden). Gruß
:
Bearbeitet durch User
Zu den 68000 gab es doch auch etliche interessante c't-Projekte. Die Artikel dazu sind auf DVD noch zu haben, notfalls bestimmt auch bei mir in Papierform, wenn ich lange genug suche.
P.S.: Ich hatte mal für eine Freundin ein paar Artikel zu dem Thema rausgesucht, vielleicht helfen sie ja (Heft/Seite/Titel): % c't 84/ 7 82 EPAC-80 (Prozessor Z80) % c't 84/ 8 93 Testprogramm für EPAC-80 (Prozessor Z80) % c't 85/ 3 47 Mehr als nur ein 16-bit-EPAC-95 (Prozessor TMS9995) % c't 85/ 3 52 EPAC-95 (Prozessor TMS9995) % c't 85/ 4 110 MONALISA: Monitor für EPAC-95 (Prozessor TMS9995) % c't 85/ 7 124 68000-Assembler-Programmierung unter RTOS % c't 86/ 6 60 Echtzeit-Multitasking mit RTOS/PEARL Teil 1: Mehrere Programme "gleichzeitig" - auf dem Atari ST % c't 86/ 6 76 EPAC-09 (Mit Prozessor 6809) % c't 86/ 7 62 Echtzeit-Multitasking mit RTOS/PEARL Teil 2: Umgang mit dem Betriebssystem % c't 86/ 8 38 Echtzeit-Multitasking mit RTOS/PEARL PEARL und Pascal - eine Gegenüberstellung % c't 86/ 8 94 Echtzeit-Multitasking mit RTOS/PEARL Teil 3: Programmieren in PEARL unter RTOS % c't 86/ 8 98 Cleo in neuem Gewand: Neue Disketten-Kommandos für RTOS/PEARL % c't 86/ 9 53 Echtzeit-Multitasking mit RTOS/PEARL Teil 4: Programmieren in PEARL unter RTOS % c't 86/10 80 Echtzeit-Multitasking mit RTOS/PEARL Teil 5: Maus, Grafik, Interrupt % c't 86/11 80 Echtzeit-Multitasking mit RTOS/PEARL Teil 6: Assembler-Programmierung in PEARL-Umgebung % c't 86/11 86 c't-KAT-Ce 68000-Einplatinensystem - Teil 1: Die Platine % c't 86/12 130 Echtzeit-Multitasking mit RTOS/PEARL Teil 7: RTOS-Pe(a)rlen % c't 86/12 156 c't-KAT-Ce 68000-Einplatinensystem - Teil 2: EPROM-Interna % c't 87/ 1 146 Echtzeit-Multitasking mit RTOS/PEARL Teil 8: Wir machen Musik... % c't 87/ 1 152 c't-KAT-Ce 68000-Einplatinensystem - Teil 3: REAL-Arithmetik % c't 87/ 2 88 EPAC 68008 Teil 1 % c't 87/ 2 92 Echtzeit-Multitasking mit RTOS/PEARL Teil 9: PEARL-Programme in EPROMs % c't 87/ 3 128 Echtzeit-Multitasking mit RTOS/PEARL Teil 10: Software-Upgrading % c't 87/ 3 134 Das "Grafische Kernsystem" in und unter PEARL % c't 87/ 3 140 EPAC 68008 Teil 3: RTOS % c't 87/ 5 94 PEARL-Texter - ein kleiner Editor für RTOS-UH % c't 87/ 5 148 EPAC 68008 Teil 3: P-Bus % c't 87/ 6 164 EPAC 68008 Teil 4: Scheibchenweise % c't 87/ 7 90 c't-KAT-Ce 68000-Einplatinensystem - Teil 4: KAT-Ce-Pascal % c't 87/ 7 94 Monsieur Fourier und Mister 68000: Schnelle Fourier-Transformation (FFT) mit der c't-KAT-Ce % c't 87/ 7 104 EPAC 68008-Programme auf Atari entwickeln % c't 87/ 9 166 Die c't-KAT-Ce mit doppelt soviel RAM % c't 87/ 9 168 RTOS-UH/PEARL für unseren Einplatinen-Computer % c't 87/ 9 168 RTOS-UH/PEARL für unseren Einplatinen-Computer % c't 88/ 6 92 Interrupt-Programmierung bei der c't-KAT-Ce % c't 88/ 7 156 EPAC 68000 1: Schaltung % c't 88/ 8 144 EPAC 68000 2: Software % c't 88/10 148 Task-Kommunikationssystem unter RTOS % c't 88/10 254 Pascal/Assembler-Entwicklungssystem für die KAT-Ce % c't 89/ 9 38 RTOS-UH/PEARL jetzt in Version 2.2 % c't 89/ 9 200 Einplatinen-Rechner KAT-Ce in Low-Power-Ausführun % c't 89/11 290 C für D- und EPACS
m68k ist nach wie vor eine von uCLinux unterstützte Architektur und wird gepflegt. Die kleinen Nachfolger der dicken 68000er sind z.B. der Dragonball M68(EZ/VZ)328, der in Palm Handhelds der ersten und zweiten Generation arbeitet (und auch im UcDimm und uCSimm). Ein kleines System könnte 2MB ROM/Flash und 8MB RAM haben, damit lässt sich ein 2.0er Linux bequem booten und zum Laufen bringen. http://www.uclinux.org/
:
Bearbeitet durch User
Ich habe mich damals mit dem 68000er versucht. Geplant war ein Slot-System mit viel DRAM, hochauflösender Grafik, Diskettenlaufwerk, paralleler und serieller Schnittstelle, Betriebssystem und was einem in seiner jugendlichen Naivität sonst noch so alles in den Kopf schießt. Daraus geworden ist immerhin etwas, was rechnen konnte, und womit ich mich selber mit der schieren Rechenpower des Prozessors (verglichen mit dem 6502 in meinem Apple) beeindrucken konnte. Christian J. schrieb: > 1. Schaltplan für Minimalsystem mit Uart, PIO, Ram, ROM => Ok, Internet Da ich bei der Sache etwas lernen und auch eigene Ideen realisieren wollte, habe ich versucht, weitgehend mit dem Buch "M68000 Familie Teil 1 Grundlagen und Architektur" von Werner Hilf und Anton Nausch auszukommen. Zusätzlich habe ich aber auch einige Tipps aus einer 68000-Artikelserie in der Zeitschrift "Elektronik" übernommen. > 2. Eprom Emulator? Den hatte ich nicht, brauchte ihn aber auch nicht. Stattdessen programmierte ich einen Boot-Loader ins EPROM, mit dem die eigentliche Software über eine UART-Schnittstelle ins RAM geladen werden konnte. Da ich kein UV-Löschgerät hatte, musste der Loader möglichst auf Anhieb funktionieren, weswegen er äußerst minimalistisch gehalten war und im Wesentlichen dazu diente, einen 2nd-Stage-Loader zu laden, der dann seinerseits die eigentliche Software lud. Die Loader-Firmware legte ich in den oberen Adressbereich der EPROMs. An der Adresse 0 (Startadresse nach Reset) lag ein Jump-Befehl zur Anfangsadresse des Loaders. Dieses Vorgehen ermöglichte es in beschränktem Umfang, neue Versionen der Loader-Firmware zu brennen, ohne die EPROMs dafür löschen zu müssen. > 3. Eprom Brenner und Eproms => ibäh, schon bestellt EPROMs hatte ich zwar, aber keinen Brenner dazu. Da ich ihn ohnehin nur für die Programmierung des Boot-Loaders benötigte, habe ich mir etwas ganz Primitves bestehend aus Adress- und Daten-Latch und etwas Software für den Apple selbst gebastelt. > 4. PIO Bausteine, Timer, zb 8155, 8153 .... finde ich schon noch > irgendwo. Bei mir war die einzige Peripherie ein UART MC6850, der sowohl zum Laden von Programmen als auch zur Interaktion mit dem Rechner verwendet wurde. Ein Gegenstück mit dem gleichen Chip lötete ich als Steckkarte für den Apple zusammen. Für diesen schrieb ich auch ein einfaches Terminalprogramm. > 5. C Cross Compiler für Linux oder Windows? Ausgabe: Hex File für > Brenner Wie schon geschrieben wurde: Dafür gibt es den GCC (C-Compiler) und die Binutils (Assembler, Linker und noch ein paar weitere Tools). Ich hatte so etwas damals leider nicht zur Verfügung :-( > 6. Assembler? Och nö..... das dauert ja ewig da was Gescheites zu > programmieren. Der 68000 ist eigentlich dank vieler Register und 16/32-Bit-Arithmetik ganz angenehm in Assembler zu programmieren. Meinen 68000-Rechner programmierte ich anfangs noch direkt mit Hex-Codes bis der Leidensdruck hoch genug war, dass ich einen einfachen Assembler schrieb. Die Schaltung hatte ich wie du auf Hartpapierlochraster aufgebaut. Die Rückseite der CPU-Platine war ein dichter Pelz aus Schaltdraht. 16 Daten- und streckenweise noch mehr Adressleitungen, die sich durch das ganze System ziehen, sind eben nicht ganz ohne. Einen Verdrahtungsfehler zu korrigieren war etwa vergleichbar mit einer Herzoperation ;-) Bald nach Fertigstellung der CPU-Platine sind die Preise für den Atari ST und den Amiga so weit gefallen, dass mir die Weiterentwicklung des eigenen Rechners nicht mehr als lohnend erschien und ich meine Freizeit vorerst lieber in Softwareprojekte auf dem Amiga investierte. Ja, das waren noch Zeiten. Heute bekommt man die gesamte Schaltung von damals mit vergleichbarer Rechenleistung und sogar erweiterter Peripherie auf einem winzigen Chip (bspw. einem ATtiny) für weniger als 2% des Preises geliefert. Deswegen hätte ich heute keine Motivation mehr, das Projekt von damals wieder aufleben zu lassen. Es gibt inzwischen genügend spannendere Dinge im Bereich Hardware und Software, mit denen man sich die Zeit totschlagen kann :)
Christian J. schrieb: > Hat sich schonmal jemand an sowas gewagt? So ein bisschen Old School > Feeling aber mit modernen Elementen? Den Z80 gibts auch in modern. Das macht dann echt Spaß - immer noch. http://www.zilog.com/index.php?option=com_product&task=product&businessLine=1&id=77&parent_id=77&Itemid=57 fchk
Christian J. schrieb: > Hat sich schonmal jemand an sowas gewagt? Tausende. Sie sind alle an der Software gescheitert. Ein Universalcomputer ist ohne Software nutzlos und die zu schreiben, alleine ein Betriebssystem, ist tausendmal mehr Arbeit als ein paar Chips zusammenzulöten. Schon ein BIOS überfordert die meisten. Also bleibt nur, hardwarekompatibel zu vorhandener Software zu sein. CP/M inklusive PL/M und GEM ist heute im Source verfügbar. Oder man baut etwas mit dedizierter Spezialsoftware, z.B. einen Schachcomputer.
Christian J. schrieb: ... > 2. Eprom Emulator? Braucht man nicht unbedingt. > 3. Eprom Brenner und Eproms => ibäh, schon bestellt Fehlkauf. Von alten PC-Mainboards kann man parallel ansteuerbare Flash- ROMs abziehen. Braucht man nur noch einen Brenner dafür. > 5. C Cross Compiler für Linux oder Windows? Ausgabe: Hex File für > Brenner > 6. Assembler? Och nö..... das dauert ja ewig da was Gescheites zu > programmieren. Ohne Assembler geht zu Anfang nichts. > Alternativ würde mir folgende Lösung gefallen: Was heißt hier alternativ? Wenn du nicht das Äquivalent einer Grafik- karte zusammenlöten willst, ist eine serielle Terminalschnittstelle zum PC das Mittel der Wahl. > Ein RS232 Terminalanschluss am Z80 System, Uart-USB Konverter, im EPROM > ein komfortabler Monitor und ich bediene das ganze aus der Konsole von > Linux heraus, so wie ich mich auf einm Raspi auch einlogge. Programme > sollten hochgeladen werden können und im RAM ausgeführt werden. Jepp. Genau so. Nur daß du dir den Monitor zumindest in Teilen selber schreiben mußt. Aus der alten Zeit gibt es zwar noch Quellcode für Monitorprogramme (u.a. von den Herren Hübler und Kramer oder vom LC80, Z1013 usw.). Aber die paßt sicher nicht 100%ig und man muß zumindest Teile anpassen. Das Minimum was der Monitor mitbringen muß, sind Funktionen zum Laden und Starten von Programmen im RAM. Wenn man das ganze mit Flash baut, könnte man sogar ins Flash laden. Mittelfristig würde man sicher ein BIOS implementieren wollen und darauf CP/M aufsetzen. Spätestens dann hat man auch einen Compiler für z.B. Turbo Pascal oder notfalls auch C. XL
:
Bearbeitet durch User
Ich hatte auch mal so etwas überlegt. Aber dann, was macht man damit? CP/M laufen lassen. Und dann die gleichen SW-Probleme wie damals? Langsam und umständlich? Wo jede SW-Emulation das 100mal schneller erledigt. Praktischen Nutzen gibt es nicht. Nochmal Wordstar? Nur für 10 Minuten ein warmes Gefühl? Denn Texte schreiben möchte ich damit nicht mehr. Oder das Konzept mit dem AVR als Slave Prozessor. Der könnte doch auch schon den Z80 mit emulieren. Vielleicht nicht ganz in Echtzeit, aber die Z80 ist überflüssig. Und für richtige Projekte ist der 64K Arbeitsspeicher zu klein. War er damals schon und das gilt heute immer noch. Ich habe mich dann dafür entschieden, doch lieber was neues zu machen, wo man was lernt oder den Horizont erweitert. FPGA, Muticore Arm, ungewöhnliche Architekturen wie XMOS Prozessoren ... das macht mehr Spass.
Ein 68K System ist recht einfach, EPROM/SRAM/Peripherie und eine einfache Adressauswertung(CS auf die Adressleitungen legen) und schon ist das System fertig. Oder das hier mal anschauen http://www.s100computers.com/My%20System%20Pages/68000%20Board/68K%20CPU%20Board.htm http://wandel.ca/homepage/mc68008/
Axel Schwenke schrieb: >> 5. C Cross Compiler für Linux oder Windows? Ausgabe: Hex File für >> Brenner >> 6. Assembler? Och nö..... das dauert ja ewig da was Gescheites zu >> programmieren. > > Ohne Assembler geht zu Anfang nichts. ACK. Assembler, Linker, Locater und C-Compiler gibt es als Freeware in guter Qualität. > Was heißt hier alternativ? Wenn du nicht das Äquivalent einer Grafik- > karte zusammenlöten willst, ist eine serielle Terminalschnittstelle zum > PC das Mittel der Wahl. Für den Anfang die imho beste Wahl. >> im EPROM >> ein komfortabler Monitor und ich bediene das ganze aus der Konsole von >> Linux heraus, so wie ich mich auf einm Raspi auch einlogge. Programme >> sollten hochgeladen werden können und im RAM ausgeführt werden. Sooo viel muss der Monitor nicht können. Im Prinzip reicht es hin, wenn er HEX Files laden kann. Für Debugging sind Breakpoints und Einzelschritt noch sinnvoll. > Jepp. Genau so. Nur daß du dir den Monitor zumindest in Teilen selber > schreiben mußt. Maximal müssen die Basisadressen des UART und - falls vorhanden - die Initialisierung des Baudraten CTC und einer PIO angepasst werden. Das sind aber schlichte Tabellen. > Mittelfristig würde man sicher ein > BIOS implementieren wollen und darauf CP/M aufsetzen. Eher kurzfristig, würde ich als erstes machen. Das Problem ist nur, dass dann auch eine Floppy (notfalls als Emulator) da sein muss. Als Anregung gibt es hier im Forum einen CP/M Computer auf AVR Basis.
Wollte ich auch mal machen, allerdings zur Zeit mache ich damit nichts mehr. Diverse RAM und Flash chips hier, 68000er CPUs, GAL Brenner, jede Menge Leiterplatten. 8031 habe ich auch hier, einfacher da nur 8bit. Es stellt sich aber die Sinnfrage, PIC32 hat den Speicher integriert und ist viel schneller.
Guten Morgen! Danke für die vielen Antworten !!!! Ich kann jetzt nicht auf jede eingehen aber sehe, dass ich nicht der einzige bin, der sowas mal angedacht hat. Die Hardware wäre wohl eher weniger ein Problem aber die Software müsste was Fertiges sein. Wenn man sich das alles recht überlegt wäre vielleicht die Anschaffung eines Apple 2, den es ab 500 Euro gibt mit 2 Floppys wohl besser oder vielleicht eines Atari. Dann kann ich wieder "Quit Update Compile" tippen (diese 3 Wörter haben sich vor 25 Jahren wohl in mein Hirn eingebrannt") und zuschauen und Kaffee trinken während der Apple die Floppys anwirft und das Pascal Programm kompiliert. Das UCSD Pascal gibt es auf Disk Images wie ich sah, muss man nur "irgendwie" auf die uralten Floppy kriegen. Das Ding auf dem Bild hahe ich noch, müsste nur mal die Elkos tauschen nach über 20 Jahren. Hier steht auch das ganze Leid von jemandem, der es an der VHS als "Retro Kurse" anbietet. http://www.simulationsraum.de/blog/tag/z80/ Gibt sogar ein eigenes Magazin "Retro Computer": https://www.csw-verlag.com/RETRO-Magazin/ Worüber ich noch nachdenken muss ist "Willst Du das wirklich antun?" .... Gruss Christian Wenn ich sowas hier sehe schüttelt es mich schon..... 68000er Asm.... als ich noch so programmierte drehte sich mir der Schädel wenn ich abends von der Arbeit nach Hause kam :-( validstr dc.b 'Invalid, must be one of the following:',13,10,0 baudtbl2 dc.b '75',0,'110',0,'134.5',0,'150',0,'300',0,'600',0 dc.b '1200',0,'2000',0,'2400',0,'4800',0 dc.b '1800',0,'9600',0,'19200',0,0 keepmsg dc.b 'Data table invalid - reset.',13,10,0 section one,code dumptokens move.b (a2)+,d0 beq.s tokend dcont bsr putchar bra dumptokens tokend moveq #' ',d0 bsr putchar move.b (a2)+,d0 bne.s dcont bra crlf getab bsr skipspc beq synerr addq.l #1,a3 bsr toupper cmp.b #'A',d0 beq.s gota cmp.b #'B',d0 bne synerr lea chanb,a5 lea p_mr1b,a6 rts gota lea chana,a5 lea p_mr1a,a6 rts
Hallo, Anfang der 80'er Jahre gab es den NDR Klein Computer zum selbst bauen. Das war ein modulares System von Rolf Dieter Klein und wurde mit dem NDR zusammen gemacht. Im Franzis Verlag gab es dazu Bücher und in der MC Artikel. Platinen und Halbleiter konnte man im Elektronikladen (Elmicro) bestellen. Es war damals nicht so einfach einen Mikrocontroller zu organisieren. Der Computer war modular, eine CPU Platine, eine für I/O, eine für serielle Schnittstelle, eine für ein Grafikterminal, eine für ein Spannungs-Frequenzwandler usw. Der Prozessor war ein 4MHz Z80A. Später gab es dann auch die 8 Bit Variante vom 68000, den 68008 und irgend wann in der MC auch den europaweit ersten Selbstbau Computer mit 32 Bit, ein 68020, glaub ich war das damals. Das war ein so cooles Projekt, ich konnte damals beim gut ein Jahrzehnt langen Bauen meines Computers sehr viel lernen. Das Buch und verschiedenen Sonderhefte, selbst den 68008 und den Grafikprozessor von Thomson hab ich noch heute. Lust hatte ich auch immer mal so ein System mit einem richtigen Bussystem wieder aufzubauen. Aber wenn man die Leistung der modernen Controller sieht mit ISP Schnittstelle, dann ist die Motivation doch nicht mehr so groß. Die Software halte ich gar nicht so für das Problem. Fehlende Programmierschnittstelen früher waren viel schwerwiegender. Es gab damals nur UV Licht löschbare EPROMS. Später gab es von Waferscale (übernommen von ST) Flash Speicher mit JTAG. Wenn es die Bausteine heute noch gibt, würde ich bei dem Z80 System darauf zurück greifen. Die Bausteine hatten auch ein wenig programmierbare Logik. Viel Erfolg bei Deinem Vorhaben. Gruß thomas Ergänzung: In der c't Hacks 4/2013 war ein Projekt: Z80 CP/M Rivival Buch: Rolf Dieter Klein Franzis Verlag 1983 Mikrocomputer selbstgebaut und programmiert ISBN: 37723-7162-0 gibt's vielleicht bei Ebay
:
Bearbeitet durch User
PittyJ schrieb: > Oder das Konzept mit dem AVR als Slave Prozessor. Der könnte doch auch > schon den Z80 mit emulieren. Vielleicht nicht ganz in Echtzeit, aber die > Z80 ist überflüssig. Da gibt es hier im Forum auch ein Projekt zu. Wenn der AVR einen Z80 emuliert und der DRAM sauber angeschlossen ist, kommt man auf knapp über 2 MHz, wenn ich mich recht entsinne. > Und für richtige Projekte ist der 64K Arbeitsspeicher zu klein. War er > damals schon und das gilt heute immer noch. Dafür gibt es ja Banking. Dummerweise unterstützt das kaum ein C-Compiler vernünftig. > FPGA, Muticore Arm, ungewöhnliche Architekturen wie XMOS Prozessoren ... > das macht mehr Spass. Hängt davon ab, was für dich Spaß ist. ;-) Wenn man die 80er nicht live miterlebt hat, ist auch ein Z80 eine neue Welt.
Hallo, ich lese seit Stunden Seiten wie die mit dem N80VEM oder dem NDR Computer durch und komme langsam zu der Erkenntnis, dass der Raspberry Pi die beste Wahl ist, wenn man auf Konsolen Look steht. Nur versteht man da nicht mal ansatweise mehr wie der innendrin funktioniert, weil die CPU viel zu komplex ist. An mi ist schon die virtuelle Adressraum vorbeigegangen, was eine MMU ist. Denn wer nur mit Controllern arbeitet braucht das ja nicht. Gibt es vielleicht noch Bausätze fix und fertig für Z80 Maschinen mit einer Art Bildschirm und Tastatur? Da kann man ja was Modernes nehmen.
Christian J. schrieb: > 5. C Cross Compiler für Linux oder Windows? Ausgabe: Hex File für > Brenner > 6. Assembler? Och nö..... das dauert ja ewig da was Gescheites zu > programmieren. Was soll dann der Quatsch mit Z80/68K? Wenn du sowieso nur eine (idealerweise alles egalisierende) Hochsprache drauf loslassen willst, spielt die konkrete Hardware doch überhaupt keine Rolle. Du kannst denselben Qualm dann auch für ein modernes µC-System übersetzen und die CPU-Opas dahin geben, wo sie wirklich nochmal etwas nützen (wenn auch nicht dir): zum Wertstoff-Hof. Retro ohne Asm ist wie Monte Carlo ohne Roulette. Langweilige Zeitverschwendung. Außer einer Auffrischung der Fertigkeiten bezüglich des Lötens auf Lochraster ist daraus keinerlei Gewinn zu erzielen, nichtmal ideeller.
Zumindest in Sacen Grafikarte habe ich hier schon was gefunden, was evtl mit einem PIC oder AVR angeschlossen werden könnte, damit man was sieht. http://www.watterott.com/de/Micro-VGA-Mikrocontroller-VGA-Grafikkarte
Sodele.... hier ist mein Wunschsystem :-) Wird direkt nachgebaut. Mit Monitor, Forth Interpreter, Laderoutine für Hex File usw. http://www.vaxman.de/projects/Z80_mini/index.html
Halloooooooooo............. ! Kann mal einer von den Z80 Cracks bitte zuhören bzw -lesen? Habe mir die ganze Hardware heute bestellt: - neue Zilog Z80 CPU's - Z80 PIO - 16C550 Uart - RAM - EPROM - Brenner und bin dabei den Schaltplan in Eagle ein zu hacken. Mit der 6510 kenne ich mich aus, damit habe ich viel gemacht damals, auch mit dem 8031 und seinem Multiplex Bus aber Z80 eben nüscht... Fragen: 1) I/O Der Z80 hat wie ich sehe I/O Funktionen IN und Out und eine IOREQ Leitung. Bindet man die Peripherie nun als I/O oder Memory Mapped ein? So wie ich das sehe kann ich die Register des 16C550 doch locker mappen über A15,14,13 (nutze eh nur A0 - A12), so dass ich alle Befehle drauf anwenden kann, statt nur IN und OUT, oder? Also .......A15 A14 A13 A12 ROM 0 0 0 1 RAM 0 0 1 0 UART 0 1 0 0 PIO 1 0 0 0 oder über Glue Logic eben decodieren, wobei ich das vermeiden will, damit kein TTL Grab entsteht. 2) Bus Der Z80 hat Bus-Steuerleitungen, Wait, HALT etc. Werden die bei einem Minimalsystem benötigt oder brauche ich den Bus nur, wenn ich den als extern ausführe, so dass ich Erweiterungskarten einstecken kann, die sich den Bus holen können um auf die RAM, ROM etc zuzugreifen? Gruss, Christian
Christian J. schrieb: > Der Z80 hat wie ich sehe I/O Funktionen IN und Out und eine IOREQ > Leitung. Bindet man die Peripherie nun als I/O oder Memory Mapped ein? Möglichst als I/O, ergibt sauberere Programme, und die PIO braucht das für die Interrupt-Bearbeitung. Christian J. schrieb: > Der Z80 hat Bus-Steuerleitungen, Wait, HALT etc. Werden die bei einem > Minimalsystem benötigt Hängt von deinem Minimalsystem ab. Das Timing des Z80 ist sehr eng. Gerade mit alten (langsamen) Speicherchips braucht man WAIT. Aber beim 16C550 nicht.
Ok! Also PIO, 16C550 und evtl. 8153 Timer als I/O mappen. Decodiert werden müssen die aber dann auch. ROM / RAM simpel über A15 decodieren? Mit PALoder GAL und so nem Driss fange ich nicht mehr an, keinen Brenner, keine Ahnung, keine Software :-)
Christian J. schrieb: > Der Z80 hat wie ich sehe I/O Funktionen IN und Out und eine IOREQ > Leitung. Bindet man die Peripherie nun als I/O oder Memory Mapped ein? Wie du gern möchtest. Allerdings ist der (Speicher) Adreßraum mit 64K nach heutigen Maßstäben ohnehin eher klein. Warum sollte man davon noch was für IO abzwacken wollen, wo man den separaten IO Adreßraum doch geschenkt kriegt? Auch von der Decodierungslogik her ist einfacher, separate Adreßräume zu verwenden. Nicht zu vergessen verlangen diverse Standardumgebungen (wie CP/M und Vettern) einen möglichst großen, von 0 an durchgehenden RAM. Ich würde so ein System nicht anders aufsetzen, als mit einem mindestens 64K großen RAM, das hier und da von (EP)ROM überdeckt wird. Eine neckische Idee ist z.B. das ROM nur nach RESET an Adresse 0x0000 einzubinden und dann als allererste Aktion ins RAM zu kopieren. Danach wird das ROM abgeschaltet und das System läuft komplett aus dem RAM. > Der Z80 hat Bus-Steuerleitungen, Wait, HALT etc. Werden die bei einem > Minimalsystem benötigt oder brauche ich den Bus nur, wenn ich den als > extern ausführe, so dass ich Erweiterungskarten einstecken kann, die > sich den Bus holen können um auf die RAM, ROM etc zuzugreifen? WAIT wirst du mit aktuellen Bausteinen eher nicht brauchen. Allerdings kann man damit auch nette Spielchen machen, wie z.B. Hardware- Einzelschrittbetrieb. Woran du recht zeitig denken solltest, ist welchen Interruptmode du verwenden willst. IM2 ist am leistungsfähigsten, muß aber bei der Adreßdecodierung berücksichtigt werden, damit sowohl das Lesen des Interruptvektors als auch das Snoopen des RETI Opcodes funktionieren. Es gibt in diesem Bereich auch ein paar known bugs - lies also mal ein paar Vintage Seiten genauer. XL
Ich kann das gut verstehen, wenn man sich wieder mit den "alten" CPUs und Systemen beschäftigt. Es geht doch eigentlich nur der Nostalgie willen, solche "Systeme" wieder zu bauen oder wieder ans Laufen zu bringen. Es geht doch garnicht darum, dass es heute besser MC/CPUs gibt. Ich habe heute noch ein Tektronix 4014 / Siemens 97801 kompatibles Terminal in Betrieb, das ich 1985 auf Basis der Intel 8031 und Zilog Z80 CPU entwickelt habe. Also 2 CPUs. Der Z80 kümmert sich um die grafische Darstellung. Die 8031 MCU macht nur die Kommunikation V.24/RS422 und bedient die serielle Tastatur. Das Terminal, das Gerät selbst ist ein Siemens 97801 mit meinem Motherboard, ist super für Debuggingzwecke via serieller Schnittstelle. Printerport und Mausanschluss inklusive. Ich verwende es heute noch. Besser als jede PC-Emulation. Daneben habe ich noch einen Unix System in Betrieb. Macht echte Laune, mit dem Maschinchen zu arbeiten. Hat eine NSC32016 CPU, 10 MHz Takt, 512 MB, 40 MB HD, bootet schneller als jeder aktuelle PC und hat schon Jahrzehnte auf dem Buckel. Baujahr 1985! Ausser der HD, original Hersteller war RODIME, jetzt Seagate , bis heute keinen Ausfall. Das soll mal ein aktuelles System nach machen! Ich habe oft den Eindruck, dass die "alten" Systeme besser gebaut waren. Das ist mein Sicht zu diesem Thema.
Ja, ja, alter Mann (55) erzählt vom Krieg! Es hat und heute auch noch, einfach Spass gemacht! Das vermisse ich oft, wenn ich mir die Beiträge so anschaue. Vor allem die nutzlosen Antworten. Habe eigentlich überhaupt das Denken gelernt? Es gab noch kein Internet, wo man Datasheets massig findet und viele nicht in der Lage sind diese wirklich zu verstehen. Da musste man die vorhandenen Infos wirklich verstehen lernen. Die Databooks musst man teilweise noch bezahlen!!!! Und Du musstest mit dem/den Lieferanten einen guten Draht aufbauen, sonst hattest du verloren. Und nicht wie hier so oft: Hau drauf, ohne Sinn und Verstand. Das wollte ich noch anmerken.
Hallo, > 1) I/O > Der Z80 hat wie ich sehe I/O Funktionen IN und Out und eine IOREQ > Leitung. Bindet man die Peripherie nun als I/O oder Memory Mapped ein? Das bleibt voll und ganz dir überlassen. Für I/O-Zugriffe legt der Z80 immer einen Wartezyklus ein, aber dafür bleibt dein RAM-Adressraum sauber. Im Gegensatz zum 8085 kannst du den I/O-Adressraum ebenfalls mit 16 Bit adressieren, aber mit 8 Bit ist es einfacher. Wenn ich das richtig sehe, haben EPROMs ein high-aktives enable, und SRAMs ein low-aktives. In dem Moment könntest du den Chip direkt mit A15 auswählen (und nur bei /MREQ aktivieren) und bekommst dann je 32 KB ROM (low) und RAM (high). Damit geht aber kein CP/M. > So wie ich das sehe kann ich die Register des 16C550 doch locker mappen > über A15,14,13 (nutze eh nur A0 - A12), so dass ich alle Befehle drauf > anwenden kann, statt nur IN und OUT, oder? Sinnvoll für Hardwarezugriffe sind nur Load- und Blockbefehle. Beide gibt es auch in der I/O-Variante. Eine vernünftige Ausdekodierung von I/O für bis zu 8 Geräte (je 32 Ports) kannst du z.B. mit einem einzigen 74xx138 machen: /M1 an EN1, /IORQ an /EN2, fertig. > 2) Bus > > Der Z80 hat Bus-Steuerleitungen, Wait, HALT etc. Werden die bei einem > Minimalsystem benötigt oder brauche ich den Bus nur, wenn ich den als > extern ausführe, so dass ich Erweiterungskarten einstecken kann, die > sich den Bus holen können um auf die RAM, ROM etc zuzugreifen? An sich sind die uninteressant. An /HALT kannst du eine LED hängen, die dir anzeigt, ob dein System gerade im Leerlauf ist (auf Interrupts wartet), das ist auch zum Testen hilfreich. @DingsDa: Magst du das Tektronix-kompatible Terminal etwas näher ausführen? Mir gefällt die Idee nämlich, relativ einfach Grafiken darstellen zu können, aber außer xterm kann das kein Terminalemulator. Wie machst du die Ausgabe? Gruß, Svenska
S. R. schrieb: > EPROMs ein high-aktives enable Datenblatt mal überflogen? /CE und /OE sind auch beim Eprom aktiv-LO. SRAMs gab es mal mit zwei Enable Eingängen, einer Hi und einer Lo aktiv. Für den TO: ich würde die Z80-SIO nehmen und einen externen Baudraten Generator. Wenn du mit Interrupts arbeiten willst (und das willst du irgendwann), ist das mit den Z80 Bausteinen einfacher. Die liefern dann den Vektor und du brauchst keine Klimmzüge im Programm zu machen.
Hi Christian J. (hobel) , du hast doch hier Beitrag "Re: Retro Fieber: Z80 oder 68000 ?" selbst das Foto des "Micro-Professor" uPF-1 MPF-1B eingestellt! Warum verwendest du dieses System nicht für deine Experimente? Ist mit Z-80 und hat ausführliches Handbuch, mit Sourcelisting, mit vielen Beispielen, auch Vektor-INT2 mode des Z80. Handbuch inzwischen auch online; Google findet es. Gruss
Z180-System mit integrierter PIO, CTC und SIO und 512k RAM, ein AVR ersetzt den EPROM. Beitrag "Z180-Stamp Modul" oder ganz klassisch mit Z80 http://www.projekte.daleske.de/cpm/06_z80hwe/cpm_z80hwe.htm
Hallo, danke für die Tipps! Habe mich heute nur den ganzen Tag mit "Daytrading" an der Börse befasst und da recht gute Gewinne gemacht, die ich jetzt wieder für Hardware verbraten werde :-) Also, das System soll bestehen aus .... nur die Hardware, Software weiss ich noch nicht so genau: Z80 Z80 PIO Z80 CTC bzw 8253 Timer Baustein 16C550 Serial Port 32 kb RAM 32 KB ROM evtl. eine Arduino 7-Segment Anzeige mit Atmel als Treiber, mal gucken. Video Interface .... gibt es auch für die UART, der C550 hat zwei davon: http://www.watterott.com/en/Micro-VGA-Cost-effective-Microcontroller-VGA-Interface So für einen 7z Bildschirm, man will ja was sehen. Tastatur macht keinen Sinn, dafür braucht man ja ein echte BIOS, Speichereinheiten etc. Und Programme werde ich auf dem Z80 nicht einhacken. Interrupts.... wofür? Es gibt 3 Stück, Mode 2 wird wohl am meisten benutzt. Auch die Timer 0.3. brauchen einen, den NMI vielleicht? Die 16C550 muss Zeichen melden, also gehen deren IRQ Ausgänge an die CPU. Glue Logic muss ich noch den Kopf rauchen lassen, der 74HC138 scheint mir geeignet wenigstens 3 Peripheriebausteine anzuschliessen. Für RAM/ROM braucht man nur die A15 über 2 Inverter nacheiander jeweils intervertiert an EPROM und RAM zu gehen, der eine ist negiert, der andere nicht. Software: Bisher noch keine Ahnung! Ich werde auf keinen Fall Asm Programme schreiben, brennen, löschen, korrigiere und alles von vorne wie früher. Das muss auf dem PC besser gehen mit einem Cross Assembler, wenn es geht mit Simulation des Programms aber da weiss ich nicht was es da gibt. Bin sehr verwöhnt mit grafischer Oberfläche von MPLAB und ARM IDE's. Der Z80 Asm ist "verständlich" .. habe das Buch "Z80" gekauft und mein Unterbwusst sein sagt mit jeder Seite: "Das hast du vor 25 Jahren alles mal gemacht, es ist nicht neu .... nur "ungewohnt". Irgendwas vergessen?
Weiter im Text: Was macht man überhaupt mit diesem System? Assembler erlaubt keine komplexen Anwendungen, zumindest nicht wenn man nicht endlos Zeit hat und vor allem KEIN BIOS dahinter wie das DOS BIOS füher, wo man zig INTs nutzen konnte um Dateien zu schreiben, Ausgaben zu machen und und und. Da freut man sich wenn Lämpchen blinken, etwas ausgegeben wird auf der Uart, vielleicht ein 7-Segment Display ein paar Zahlen anzeigt. Und vielleicht fühlt man sich "nostalgisch", wenn man den schwarzen Chip anschaut und nichts sieht aber weiss, dass er innendrin grad "rechnet". Mit dem Internet wird er sich ebenso wenig verbinden können, wie ein USB Gerät anzusteuern oder eine 3,5z Floppy, was ja denkbar wäre als Datenspeicher. Vermutlich wird also die Verwendung eine Art "physical computing" sein, Ports einlesen, ausgeben, irgend einen Sensor dran und 2-3 Relais, die irgendwas ansteuern. Oder sehe ich das falsch?
Du willst also ein Z80 System bauen. Finde ich sehr interessant. Beschäftige mich auch damit soweit es die Zeit erlaubt. Und nun führst du dein eigenes Projekt mit deinen letzten zwei posts ad absurdum.... Gespaltene Persönlichkeit?
Christian J. schrieb: > Was macht man überhaupt mit diesem System? Christian J. schrieb: > Oder sehe ich das falsch? Du erkennst langsam, waorum solche Schaltung Unsinn sind. Wenn du CP/M und GEM laufen lassen könntest, oder ein Arcade-Spiel aus MAME auf die Hardware ziehen könntest. Also erst die Anwendung suchen, die mit einen Uralt-OProzessor besser geht (weniger Bauaufwand weil Pläne und Software fertig) als mit einem Neuen, und dann bauen.
Das genau ist das Problem - erst die Software haucht dem Kerlchen Leben ein. Du hast nicht genug Zeit in deinem Leben, das alles selbst zu machen. 16C550 - du solltest bei der originalen Z80-SIO bleiben. Nur damit funktioniert das eigentlich geniale Interupt-System (Peripherie liefert den Opcode, IM2 (?) ) in seiner ganzen Schönheit.
Christian J. schrieb: > Hallo, > > danke für die Tipps! Habe mich heute nur den ganzen Tag mit > "Daytrading" an der Börse befasst und da recht gute Gewinne gemacht, die > ich jetzt wieder für Hardware verbraten werde :-) > > Also, das System soll bestehen aus .... nur die Hardware, Software weiss > ich noch nicht so genau: > > Z80 > Z80 PIO > Z80 CTC bzw 8253 Timer Baustein > 16C550 Serial Port > 32 kb RAM > 32 KB ROM Wenn ich das machen würde: EZ80F91: hat bereits 256k Flash, seriell, SPI, I2C, RTC und Glue Logic drin; http://www.digikey.de/product-detail/de/EZ80F91AZA50SG/269-4564-ND/1236489 Beschaltung gemäß Datenblatt dazu ein 128k SRAM wie dieses hier zB: http://www.digikey.de/product-detail/de/IS61C1024AL-12JLI-TR/706-1303-1-ND/4733133 oder mehr, wenn Du magst. Tu Dir keinen Zwang an. Denke daran: Du kannst Bankswitching machen, musst es aber nicht. Der EZ80 kann 16MB Adressraum linear (!) adressieren. Restliche Peripherie je nach Wunsch hinzufügen - genügend IO-Pins hat das Teil. Assembler/Compiler/RTOS gibts bei Zilog. Wenn Du magst, darfst Du auch noch einen DP83848C anklemmen und das 10/100 Ethernet in Betrieb nehmen. http://www.digikey.de/product-detail/de/DP83848CVV%2FNOPB/DP83848CVV%2FNOPB-ND/947542 Ansonsten gibts das alles fertig, wenn Dir SMD unheimlich ist (alles eine Frage der Übung und der richtigen Technik): http://www.digikey.de/product-detail/de/EZ80F910200KITG/269-4560-ND/1236485 Da ist dann auch ein Debuggerkabel dabei. fchk
Harald schrieb: > Du willst also ein Z80 System bauen. Finde ich sehr interessant. > Beschäftige mich auch damit soweit es die Zeit erlaubt. > > Und nun führst du dein eigenes Projekt mit deinen letzten zwei posts ad > absurdum.... > > Gespaltene Persönlichkeit? Nein, das nennt man den Prozess der Entscheidungsfindung. Pro und Contra .... solange bis man sich für eine Richtung entschieden hat oder etwas verwirft. Da hier nur der Weg zählt und es kein Ziel gibt entspricht es nicht der üblichen Vorgehensweise, die ich als Ingenieur so kenne. Da würde ich nämlich estmal eine Spec schreiben. @Frank: Mit den smd Chips und moderner CPU fehlt der "Geist der Nostalgie"... es sollen ja gerade die Uralt Steine sein die verbaut werden. Sonst geht auch ein Raspberry Pi, sicherlich komfortabler. DIe CPM/M Version ist deutlich aufwendiger und ich würde mal sagen, da geht ein Jahr ins Land bevor das alles läuft.... http://searle.hostei.com/grant/cpm/index.html Der hie baut sogar "Pong" selbst nahc mit TTL.... denke mal er hat keine Familie und sehr viel Zeit :-), siehe Bild. http://searle.hostei.com/grant/pong/index.html
H.Joachim Seifert schrieb: > 16C550 - du solltest bei der originalen Z80-SIO bleiben. Nur damit > funktioniert das eigentlich geniale Interupt-System (Peripherie liefert > den Opcode, IM2 (?) ) in seiner ganzen Schönheit. Jein. Er könnte die PIO, die er vorgesehen hat, als IM2 Quelle nutzen, in dem IRQ des 16C550 in den PIO geht. Aber bei 2 Quellen braucht er sowieso keinen IM2.
MaWin schrieb: > H.Joachim Seifert schrieb: >> 16C550 - du solltest bei der originalen Z80-SIO bleiben. Nur damit >> funktioniert das eigentlich geniale Interupt-System (Peripherie liefert >> den Opcode, IM2 (?) ) in seiner ganzen Schönheit. > > Jein. > > Er könnte die PIO, die er vorgesehen hat, als IM2 Quelle nutzen, in dem > IRQ des 16C550 in den PIO geht. > > Aber bei 2 Quellen braucht er sowieso keinen IM2. Hi, ich denke ich habe mich entschieden. der Junge hat alles wunderbar beschrieben, an jedes Detail gedacht und vor allem hat er ein komplettes BIOS geschrieben mit Basic Interpreter und einem Terminal Adapter für den PC. Das denke ich spart deutlich Arbit und Basic ist ja ok. http://searle.hostei.com/grant/z80/SimpleZ80.html Anbei mal ein echter "Bill Gates" von 1978 .... ein Basic Interpreter.
So, falls es jemanden interessiert,der ähnliches im Schilde führt, so denke ich, dass das der schnellste Weg zu einem "Retro Computer" ist. Basic! Und da es Peek und Poke gibt sind auch Peripherie Geräte wie Timer etc programmierbar und auslesbar. Evtl. muss ich da aber den Asm verändern, sofern die auf das Memory zugreifen und nicht auf die I/O. Anbei ein Bild des Erstellers diesen klasse Z80 System mit echtem BIOS dahinter.
Christian J. schrieb: > Mit den smd Chips und moderner CPU fehlt der "Geist der Nostalgie"... es > sollen ja gerade die Uralt Steine sein die verbaut werden. Sonst geht > auch ein Raspberry Pi, sicherlich komfortabler. Nun, man kann sich das Leben auch schwer machen. > DIe CPM/M Version ist deutlich aufwendiger und ich würde mal sagen, da > geht ein Jahr ins Land bevor das alles läuft.... Das haben schon andere vor Dir gemacht: http://www.shaels.net/index.php/mic80/mic80-general/38-mico-overview http://z80cpu.eu/mirrors/www.vegeneering.com/eZ80_CPM/index.html http://www.hsl.wz.cz/cpmez80.htm
Dann bau doch einen ZX80 oder ZX81 nach. Da gibt es sehr schöne Implementierungen mit Standardbauteilen. Suchbegriff "ZX97 wilf righter", "ZX81NU", "zx80 grant searle".
Christian J. schrieb: > So, > > falls es jemanden interessiert,der ähnliches im Schilde führt, so denke > ich, dass das der schnellste Weg zu einem "Retro Computer" ist. Basic! Ich denke, auf der Schiene fahren schon bessere Züge, die zeitgemäß und schneller sind. Beitrag "maximite TFT mmbasic Computer" Beitrag "PIC 32 schneller Basic Interpreter"
Hallo, ich habe mir mal den SDCC Compiler runtergelden und etwas quer durchs Manual gelesen. Das scheitn mir doch den ungeliebten Assembler zu ersparen (Nein..... ich habe keinen Bock da drauf! Seit 1995 nicht mehr...). Zumindest für eine Applikation und um die geht es ja was schickes für die Kiste zu schreiben. Einen Monitor, der sich Intel .hex Files über die Uart reinzieht und diese im Ram decodiert und ausführt habe ich schon. Ram ist bei mir Batterie gepuffert also bleibt es auch drin. Kennt sich jemand mit diesem SDCC Compiler aus? Alos erstes tauchen natürlich Fragen auf, wie - wie teile ich ihm die Memory Map meines Rechners mit? - wie bringe ich ihm bei, dass auf $80 die Timer I/O liegt und auf $A0 die Serielle Schnittstelle? - kann er Code erzeugen für I/O gemappte Devices? Oder nur für welche die memory mapped sind? - wie leite ich stdout um auf meine Z80 SIO Uart usw.? Beispiele gibt es keine im Netz, habe alles durchsucht.
Christian J. schrieb: > Beispiele gibt es keine im Netz, habe alles durchsucht. Das glaube ich dir nicht. > Kennt sich jemand mit diesem SDCC Compiler aus? Nur am Rande, habe ihn (bisher) nicht für größere Projekte benutzt. Es gibt wohl ein paar Bugs bei speziellen Sachen (z.B. __critical), aber der Codegenerator an sich soll gut sein. Auf der Webseite werben sie zumindest damit, dass sie fast so gut sind wie IAR (und damit besser als alle anderen). > - wie teile ich ihm die Memory Map meines Rechners mit? Sollte mit --code-loc und --data-loc gehen, notfalls musst du dir eine eigene Startup-Datei (crt0.rel) bauen. > - wie bringe ich ihm bei, dass auf $80 die Timer I/O liegt und > auf $A0 die Serielle Schnittstelle? Der Compiler kennt weder serielle Schnittstellen noch Timer, also wirst du dir dafür deine eigenen Treiber schreiben müssen. ;-) > - kann er Code erzeugen für I/O gemappte Devices? Ja. Du kannst Variablen mit ein paar Spezialflags deklarieren:
1 | __sfr __at 0x12 reg1; |
2 | __sfr __at __banked 0x1234 reg2; |
dann wird für Zugriffe darauf ein in- oder out-Befehl erzeugt. Letzteres erzeugt Code, der I/O mit allen 16 Adressbit macht (Eigenheit vom Z80). > Oder nur für welche die memory mapped sind? Wie dir andere bereits schrieben: Löse dich von MMIO. Das ist auf einem Z80 nicht zielführend. > - wie leite ich stdout um auf meine Z80 SIO Uart Naja, die mitgelieferten Funktionen rufen nicht mitgelieferte Funktionen auf... Ein Beispielcode für meine Hardware:
1 | #include <stdio.h> |
2 | |
3 | __sfr __at 0x10 uart_data; /* Datenregister */ |
4 | __sfr __at 0x11 uart_rxfill; /* Anzahl Bytes im Rx-Puffer */ |
5 | |
6 | void putchar(char c) { |
7 | uart_data = c; |
8 | }
|
9 | |
10 | void main(void) |
11 | {
|
12 | char rx; |
13 | char hello[] = "Hallo, Welt!\n"; |
14 | |
15 | printf("%s", hello); |
16 | while(uart_rxfill) { |
17 | rx = uart_data; |
18 | printf("%c", rx); |
19 | }
|
20 | }
|
Hallo S.R, danke für die Ausführungen, wird Zeit den Thread mal auszudrucken als pdf und ins Info Verzeichnis zu legen. Ich habe mir heute mal einen sehr aufwendigen Krypto DOS Virus angeschaut, den ich aus Interesse mal 1995 für IBM 486 geschrieben habe mit ca 23 J. Wurde sogar veröffentlicht als Demo Code. 30 Seiten Asm ausgedruckt. Frage mich wieso es mir heute so schwer fällt derart guten Asm wie damals zu schreiben? Alter? Das was Du da schreibst gefällt mir, vielleicht hast Du ja ein paar Sourcen deines projektes mal für mich, so dass ich Beispiele habe? Nicht für "C" sondern die Spezialfunktionen, wie SFR Register belegen und ansprechen usw. Einiges werde ich sicher inline asm codieren müssen aber das meiste in C. Da ich recht viel Sourcen gefunden habe, die man fast schon mit Ehrfurcht anschaut (1976er Orginal Sourcen von CP/M und Microsoft für Z80) würde ich gern einige tolle Sachen wie FORTH Interpreter Basic Interpreter übernehmen in den Monitor.
Christian J. schrieb: > Das was Du da schreibst gefällt mir, vielleicht hast Du ja ein paar > Sourcen deines projektes mal für mich, so dass ich Beispiele habe? Nicht > für "C" sondern die Spezialfunktionen, wie SFR Register belegen und > ansprechen usw. Das kann ich nicht, weil ich das bisher selbst nicht gemacht habe. Fast die gesamte Peripherie ist in einem AVR implementiert und daher aus Z80-Sicht extrem einfach zu bedienen. Im Augenblick läuft auch nur ein ziemlich minimales CP/M, bis ich mal wieder die Muße finde, das Speichersystem fertigzustellen. Zu dem Projekt findest du zwei Threads hier: Hardware: Beitrag "eigenes Z80 Mainboard - geht das so?" CP/M: Beitrag "CPM.SYS und wenig RAM" Gruß
S. R. (svenska) schrieb: > SFR Register Der Z80 hat ein einziges "SFR", das Register, das das Hi-Byte der Interrupt Vektor Tabelle enthält. SDCC kenne ich nicht, ich arbeite mit einer Variante von "QC". Der iwrd aber nicht grundsätzlich anders sein. Du hast eine Runtime-Lib und ein Startup-Programm dabei. Für die Runtime-Lib musst du üblicherweise Sachen wie Console Eingabe und Ausgabe definieren. Und im Startup werden die RAM Grenzen angegeben und es wird der Stack gesetzt und bei Bedarf das I-Register. Mehr ist nicht nötig. Es ist mit Sicherheit ein Hello-World Programm dabei. Nimm das als Anregung.
Ich finde den 8031 interessant da er viele interne Register hat, und einfach zu beschalten ist. Kann sogar Multiplikation. Schaltung bereits aufgebaut, jeweils 2 mal ein paar Stunden, kein Schaltplan. Muss nur noch das FLASH IC anschliessen. 6507 und 68000 Computer sind auch vorgesehen.
Hi, zumindest kam heute erstmal der Scinken, den ich brauche an, sehr gute Zustand, 19 Euro ..... denke mal ich mache da weiter und erst danach an dem Board. Ich kenne mich intern mit dem AVR nicht sonderlich aus, denke aber dass ich auf Arduino Basis eine gemischte Lösung machen kann, dass der Z80 über seine PIO und vielleicht 4 Leitungen von der einen Datenspeicher adressieren kann, der am Atmel dran hängt. So eine Art SPI mit Bit Banging. Ist ja kein Thema da eine SD Karte dran zu papen - Arduino eben - und eine Art kleinen Treiber zu schreiben, der mal eben das RAM Image ablegt und es sich auch wieder reinzieht, so dass Programme erhalten bleiben. Zu sfr steht folgendes im Manual: 3.5.2.1 __sfr (in/out to 8-bit addresses) The Z80 family has separate address spaces for memory and input/output memory. I/O memory is accessed with special instructions, e.g.: __sfr __at 0x78 IoPort; /* define a var in I/O space at 78h called IoPort */ Writing 0x01 to this variable generates the assembly code: 40 3.6. OTHER SDCC LANGUAGE EXTENSIONS CHAPTER 3. USING SDCC 3E 01 ld a,#0x01 D3 78 out (_IoPort),a 3.5.2.2 banked sfr (in/out to 16-bit addresses) The keyword __banked is used to support 16 bit addresses in I/O memory e.g.: __sfr __banked __at 0x123 IoPort; Writing 0x01 to this variable generates the assembly code: 01 23 01 ld bc,#_IoPort 3E 01 ld a,#0x01 ED 79 out (c),a
Hier ist übrigens eine Möglichkeit ohne eine PIO die IO Pins eines Z80 gewaltig aufzublasen.
Christian J. schrieb: > Ich kenne mich intern mit dem AVR nicht sonderlich aus, denke aber dass > ich auf Arduino Basis eine gemischte Lösung machen kann, dass der Z80 > über seine PIO und vielleicht 4 Leitungen von der einen Datenspeicher > adressieren kann, der am Atmel dran hängt. Wenn, dann nimm doch gleich die Z80-DMA für gemeinsamen Speicher. Ich finde, wer alte Prozessoren wiederbeleben will, sollte beim damaligen Stand verbleiben und ihn auch so nachvollziehen. Es macht keinen Sinn, damit einen PC nachzuhecheln. Ich habe damit 1990 aufgehört. Vielleicht noch stromsparende Chips, größere Speicher, einen Uhren-Chip usw. einzubauen, das ist zu akzeptieren. Es sind Oldtimer, die auch so behandelt werden wollen. Ein sehr gutes Buch ist Kieser-Meder Aufbau und Anwendung des Mikroprozessorsystems U880 (Z80).
> Ich finde, wer alte Prozessoren wiederbeleben will, sollte beim > damaligen Stand verbleiben und ihn auch so nachvollziehen. Nicht unbedingt. Das hängt davon ab, ob es "authentisch Retro" sein soll wie bei Autos oder nicht. EPROMs machen mir keinen Spaß, also lasse ich sie weg. PALs und 8"-Disketten sind schwer zu bekommen, also lasse ich sie weg. DRAMs möchte ich allerdings benutzen, sonst ließe ich sie auch weg. Niemand verbietet dir USB oder Ethernet an solchen Basteleien - gibt auch genug Leute, die das an ihren C64 oder KC85 gebastelt haben. Wenn du den Druck hast, damit auch Youtube schauen zu wollen, dann ist die Bastelei sowieso nichts für dich. Andererseits... Youtube auf nem KC... wäre definitiv cool. ;-)
Christian J. schrieb: > zumindest kam heute erstmal der Scinken, den ich brauche an, sehr gute > Zustand, 19 Euro Was? 19 Euro? Dann muss ich meinen Zaks mal verscherbeln. Hätte nicht gedacht, das das Ding so viel wert ist. Ich brauche ihn jedenfalls nicht mehr.
S. R. schrieb: > DRAMs möchte ich allerdings benutzen, sonst ließe ich sie auch > weg. Gibt es so kleine DRAMs noch? Ich hätte einfach einen 128kB*8 SRAM rangepappt. Das DRAM-Timing mit Z80 ist nicht ganz ohne. Oft waren in den Schaltungen RC-Glieder zum Feinabgleich.
Peter Dannegger schrieb: > S. R. schrieb: >> DRAMs möchte ich allerdings benutzen, sonst ließe ich sie auch >> weg. > > Gibt es so kleine DRAMs noch? Neu wohl nicht mehr. Obwohl Pollin ein 256Kx1 dRAM verkloppt. Aber so was schnuckeliges wie 64Kx4 (61464?) findet man wohl nur noch in gut sortierten Bastelkisten. > Das DRAM-Timing mit Z80 ist nicht ganz ohne. Oft waren in den > Schaltungen RC-Glieder zum Feinabgleich. Was aber nicht heißt daß es nicht besser gehen würde. Wenn man den doppelten (IIRC, kann auch 4x gewesen sein) CPU-Takt zur Verfügung hatte, dann konnte man auch einen synchronen Generater für das signaling bauen. Nicht zu vergessen die geniale Methode, Speicherzugriffe per WAIT auf 4 Takte zu verlängern (dann sind sie gleich lang wie M1 Zyklen), dann aber zwei unabhängige Speicherzugriffe in jeden 4-Takte Zyklus zu packen. Z.B. einen für die CPU und einen für die Grafikhardware. Ich hab ja mal günstig einen i82720 GDC geschossen und trage mich immer noch mit dem Gedanken, daraus eine Grafikkarte für eines meiner Z80 Schätzchen zu bauen. Man bräuchte einen Sponsor, damit man nicht mehr arbeiten gehen müßte ;) XL
Georg G. schrieb: > Der Z80 hat ein einziges "SFR", das Register, das das Hi-Byte der > Interrupt Vektor Tabelle enthält. Unvollständig: Das andere "SFR" ist nur 7 Bit breit und enthält die Refresh-Adresse für dynamische RAMs. Sie wird im M1-Zyklus im Takt 4 auf den Adressbus gelegt und automatisch inkrementiert.
:
Bearbeitet durch User
Ich halte es prinzipiell für Unfug ein CP/M System aus einem Z80 zu bauen und dann einen Amtel da als Slave dranzuketten. Entweder man macht die Peripherie und den Speicher mit dem Z80 selber (ok, für Ethernet und USB wird man Slaves brauchen) oder man läßt es. Wenn schon Retro dann IMHO richtig, man kann ein CP/M System mit 8MB Platten auf einer SD Karte betreiben, man kann aber auch einen 8272 (µPD765) da anknoten und ein Floppylaufwerk dran basteln. Ich empfehle da 5,25Zoll 800KB Laufwerke wege nder Zuverlässigkeit. die 3,5 Zoll PC Teile sind doch alle mehr oder weniger WORN Devices und alle unterschiedlich justiert. Console Interface ist dann eine SIO mit PC-Terminal dran, auf dem 2. Kanal kann noch ein Drucker landen. (Sofern man noch einen mit V.24 oder IFSS auftreiben kann). Übrigens weil einer mal Wordstar ansprach: auf einem 10Mhz Z80 macht sogar das Laune... Das Alles muß man nicht unbedingt alleine und zu Fuß machen, vieles davon wurde schon implementiert (Netzwerk, RAMdisk, SD-Card, IDE Interface, USB usw) und ist z.B: auf ollen DDR robotron K1520 Rechnern verfügbar. Ich habe solchen Kram auch noch da... Ehe der To ICs kauft: bitte bei mir nachfragen, ich sponsore die, will nur das Porto. Gruß, Holm
Holm Tiffe schrieb: > Ehe der To ICs kauft: bitte bei mir nachfragen, ich sponsore die, will > nur das Porto. Hi, tja, leider schon passiert, heute kamen alle IC's, dazu noch eine 8255 PIO (ist einfacher zu handhaben), 56k SRAMs im exotischen Gehäuse, Z80 CTC, Z80 SIO usw. Und mit CP/M wird nix, weil mir das viel zu aufwendig ist. Selbst durch Fremdprojekte durchzusteigen (zb FAT System für Flash Cards, angebunden durch IDE Schnittstelle) brauchst Du Tage. Es dreht sich alles immer um die Frage: Wie kriege ich meine Software da rein und teste sie, ohne dass zwischen Codeänderung und Test ne halbe Stunde vergeht. Wo drauf entwickel ich die Software? Auf dem Z80 oder einem PC? Wie speichere ich Programme ab? So nett wie beim PIC oder AVR wird es nicht sein, wo eine ISP dran ist und eine Uart zum Debuggen. Debuggen wird wohl gar nicht gehen. Heute mal geschaut.... einen Eprom Emulator kriegt man kaum noch und wenn dass fast 300 Euro. Damals an der uni hatte ich einen peps-3, damit ging das sehr einfach unter DOS.
> Wo drauf entwickel ich die Software? Auf dem Z80 oder einem PC? PC natürlich ;) Ausser du bist Masochist... > Debuggen wird wohl gar nicht gehen. Debugging wird überschätzt. Es reichen ein paar Leds zum Morsen schon aus, UART ist schon Luxus. Man lernt damit, auch etwas systematischer nachzudenken, was eigentlich wie schiefgehen kann, was zum Led-Pattern passt. > einen Eprom Emulator kriegt man kaum noch und wenn dass fast 300 Euro. Bau dir einen. Habs für mein allererstes eigenes uC-System (Z80, auch schon über ein Vierteljahrhundert her, urgs...) auch gebastelt. War recht trivial. Als Speicher ein SRAM (optional batteriegepuffert), daran für die Adressen 2*74HC590 und für die Daten ein 74HC595. Braucht nach aussen ~6 Leitungen. Wenn der Z80 im Reset ist, kann man bequem die Treiber der Zähler/SRs aktivieren und Daten ins SRAM reinschreiben (ging damals über den Parallelport). Dann OE wieder aus und Reset loslassen. Turnaroundzeit war im Bereich einiger 10s für ein paar KB Programm, war noch alles schnarchiges Basic... Den Emu habe ich vor ein paar Tagen beim Aufräumen sogar wieder gesehen :)
Christian J. schrieb: > Und mit CP/M wird nix, weil mir das viel zu aufwendig ist. Selbst durch > Fremdprojekte durchzusteigen (zb FAT System für Flash Cards, angebunden > durch IDE Schnittstelle) brauchst Du Tage. Ist das nicht das, was du willst? Oder ist dein Ziel nur, innerhalb von ein paar Stunden einen Z80 auf ein Brett zu löten und gut ist? Ein kleines CP/M-BIOS kriegt man in 300 Zeilen Assembly hin. > Es dreht sich alles immer um die Frage: Wie kriege ich meine Software da > rein und teste sie, ohne dass zwischen Codeänderung und Test ne halbe > Stunde vergeht. Da wirst du dir selbst was ausdenken müssen. In meinem Fall: "make", BREAK (für den Monitor), Hexfile verschicken, Reset. Dauert keine 10 Sekunden. > Wo drauf entwickel ich die Software? Auf dem Z80 oder > einem PC? Wie speichere ich Programme ab? SDCC ist ein Cross-Compiler. Der läuft nicht auf dem Z80. Wolltest du ihn nicht benutzen? > So nett wie beim PIC oder AVR wird es nicht sein, wo eine ISP dran ist > und eine Uart zum Debuggen. Debuggen wird wohl gar nicht gehen. Du bist sicher, dass du keinen Z80-Emulator benutzen willst? Da sind Debugschnittstellen meist drin, inklusive Breakpoints, Register gucken und so.
Christian J. schrieb: > Es dreht sich alles immer um die Frage: Wie kriege ich meine Software da > rein und teste sie, ohne dass zwischen Codeänderung und Test ne halbe > Stunde vergeht. Wo drauf entwickel ich die Software? Auf dem Z80 oder > einem PC? Wie speichere ich Programme ab? > > So nett wie beim PIC oder AVR wird es nicht sein, wo eine ISP dran ist > und eine Uart zum Debuggen. Debuggen wird wohl gar nicht gehen. Ein MODERNER Z80 hat JTAG und ZDS(ne Art Zweidraht-JTAG). Aber den willst Du ja nicht haben. fchk
>dazu noch eine 8255 PIO (ist einfacher zu handhaben)...
Unmengen von Programmierern und Elektronikern international ärgern sich
über das Ding und Du hältst es für einfacher?
Wolltest Du nicht ein Z80 System bauen? Die volle Leistungsfähigkeit der
Interruptkette im IM" bekommst Du nur mit Zilog ICs dieser Serie und die
PIO ist recht einfach zu handhaben :-)
Gruß,
Holm
Hallo, wie geil ist das denn? Einfach mal mit dem SDCC etwas gespielt, Nonsense Code geschrieben und es kommt Z80 Asm bei heraus! Kleines Script geschrieben, mit make2bin wird ein Bin File draus, sonst Intel-Hex-8. Ich weiss noch damals wie sehr ich mir einen Cross Compiler gewünscht habe, so um 1995 herum ..... gab es nicht oder war zu teuer. Dann kann es ja losgehen ..... muss nur noch die putchar überschreiben. Mal schauen, ob sich auch ein Monitor mit dem C Compiler schrieben lässt zumindest mit Inline Asm wegen der Int Tabelle, Startup Code usw. Ohne Asm geht es definiv nicht. Voila..... er macht was er soll, der SDCC :-) Aus
1 | #include <stdio.h> |
2 | #include <stdlib.h> |
3 | |
4 | int main() |
5 | {
|
6 | unsigned int a,i; |
7 | static __sfr __at 0x10 uart_data; |
8 | |
9 | i=0; |
10 | |
11 | for ( a = 0; a < 10; a++ ) |
12 | {
|
13 | i =i + a; |
14 | if (i>1000) |
15 | i=0; |
16 | }
|
17 | |
18 | i = 10; |
19 | while(--i>0) { |
20 | a = uart_data; |
21 | printf("%c", a); |
22 | }
|
23 | |
24 | return 0; |
25 | }
|
wird:
1 | 1 ;-------------------------------------------------------- |
2 | 2 ; File Created by SDCC : free open source ANSI-C Compiler |
3 | 3 ; Version 3.4.0 #8981 (Apr 5 2014) (Linux) |
4 | 4 ; This file was generated Sat Sep 6 11:09:47 2014 |
5 | 5 ;-------------------------------------------------------- |
6 | 6 .module test |
7 | 7 .optsdcc -mz80 |
8 | 8
|
9 | 9 ;-------------------------------------------------------- |
10 | 10 ; Public variables in this module |
11 | 11 ;-------------------------------------------------------- |
12 | 12 .globl _main |
13 | 13 .globl _printf |
14 | 14 ;-------------------------------------------------------- |
15 | 15 ; special function registers |
16 | 16 ;-------------------------------------------------------- |
17 | 0010 17 _main_uart_data_1_27 = 0x0010 |
18 | 18 ;-------------------------------------------------------- |
19 | 19 ; ram data |
20 | 20 ;-------------------------------------------------------- |
21 | 21 .area _DATA |
22 | 22 ;-------------------------------------------------------- |
23 | 23 ; ram data |
24 | 24 ;-------------------------------------------------------- |
25 | 25 .area _INITIALIZED |
26 | 26 ;-------------------------------------------------------- |
27 | 27 ; absolute external ram data |
28 | 28 ;-------------------------------------------------------- |
29 | 29 .area _DABS (ABS) |
30 | 30 ;-------------------------------------------------------- |
31 | 31 ; global & static initialisations |
32 | 32 ;-------------------------------------------------------- |
33 | 33 .area _HOME |
34 | 34 .area _GSINIT |
35 | 35 .area _GSFINAL |
36 | 36 .area _GSINIT |
37 | 37 ;-------------------------------------------------------- |
38 | 38 ; Home |
39 | 39 ;-------------------------------------------------------- |
40 | 40 .area _HOME |
41 | 41 .area _HOME |
42 | 42 ;-------------------------------------------------------- |
43 | 43 ; code |
44 | 44 ;-------------------------------------------------------- |
45 | 45 .area _CODE |
46 | 46 ;test.c:4: int main() |
47 | 47 ; --------------------------------- |
48 | 48 ; Function main |
49 | 49 ; --------------------------------- |
50 | 0000 50 _main_start:: |
51 | 0000 51 _main: |
52 | 52 ;test.c:9: i=0; |
53 | 53 ;test.c:11: for ( a = 0; a < 10; a++ ) |
54 | 0000 21 00 00 [10] 54 ld hl,#0x0000 |
55 | 0003 5D [ 4] 55 ld e,l |
56 | 0004 54 [ 4] 56 ld d,h |
57 | 0005 57 00107$: |
58 | 58 ;test.c:13: i =i + a; |
59 | 0005 19 [11] 59 add hl,de |
60 | 60 ;test.c:14: if (i>1000) |
61 | 0006 3E E8 [ 7] 61 ld a,#0xE8 |
62 | 0008 BD [ 4] 62 cp a, l |
63 | 0009 3E 03 [ 7] 63 ld a,#0x03 |
64 | 000B 9C [ 4] 64 sbc a, h |
65 | 000C 30 03 [12] 65 jr NC,00108$ |
66 | 66 ;test.c:15: i=0; |
67 | 000E 21 00 00 [10] 67 ld hl,#0x0000 |
68 | 0011 68 00108$: |
69 | 69 ;test.c:11: for ( a = 0; a < 10; a++ ) |
70 | 0011 13 [ 6] 70 inc de |
71 | 0012 7B [ 4] 71 ld a,e |
72 | 0013 D6 0A [ 7] 72 sub a, #0x0A |
73 | 0015 7A [ 4] 73 ld a,d |
74 | 0016 DE 00 [ 7] 74 sbc a, #0x00 |
75 | 0018 38 EB [12] 75 jr C,00107$ |
76 | 76 ;test.c:19: while(--i>0) { |
77 | 001A 11 0A 00 [10] 77 ld de,#0x000A |
78 | 001D 78 00104$: |
79 | 001D 1B [ 6] 79 dec de |
80 | 001E 7A [ 4] 80 ld a,d |
81 | 001F B3 [ 4] 81 or a,e |
82 | 0020 28 13 [12] 82 jr Z,00106$ |
83 | 83 ;test.c:20: a = uart_data; |
84 | 0022 DB 10 [11] 84 in a,(_main_uart_data_1_27) |
85 | 0024 6F [ 4] 85 ld l,a |
86 | 0025 26 00 [ 7] 86 ld h,#0x00 |
87 | 87 ;test.c:21: printf("%c", a); |
88 | 0027 01r39r00 [10] 88 ld bc,#___str_0 |
89 | 002A D5 [11] 89 push de |
90 | 002B E5 [11] 90 push hl |
91 | 002C C5 [11] 91 push bc |
92 | 002D CDr00r00 [17] 92 call _printf |
93 | 0030 F1 [10] 93 pop af |
94 | 0031 F1 [10] 94 pop af |
95 | 0032 D1 [10] 95 pop de |
96 | 0033 18 E8 [12] 96 jr 00104$ |
97 | 0035 97 00106$: |
98 | 98 ;test.c:24: return 0; |
99 | 0035 21 00 00 [10] 99 ld hl,#0x0000 |
100 | 0038 C9 [10] 100 ret |
101 | 0039 101 _main_end:: |
102 | 0039 102 ___str_0: |
103 | 0039 25 63 103 .ascii "%c" |
104 | 003B 00 104 .db 0x00 |
105 | 105 .area _CODE |
106 | 106 .area _INITIALIZER |
107 | 107 .area _CABS (ABS) |
Moin, so das Z80 ist in der Planung fertig. Auf dem Block, für einen sauberen Eagle Schaltplan fehlte mir doch der Nerv. Um ein wenig mehr zu haben wird noch ein antiker.. abstaub.... ADC 0804 AD/Wandler dran gepappt an eine freie decodierte Leitung des I/O Busses. Köstlichkeiten wie den 12 Bit ADC 84 und DAC 80 von Burr Brown habe ich auch noch, monströse schwere Chips in Keramik. Ich frage mich die ganze Zeit nur, wieso ich nicht noch einen Schritt in der Evoluion zurück gehe und zb eine PDP-11 nachbaue? So ein TTl Grab.... da sieht man ja fast die Elekronen flitzen, wenn man viele LEDs an die Ports klebt :-) Und diese weisse Herdplatte links oben mit den beiden Kochfeldern macht auch was her. Glaube damit kann man auch eine ganze CPU nachbauen, so im Format Backblech..... ;-) Frage: Ich habe mit der seriellen Schnittstelle noch ein Problem. In Grant's Plänen http://searle.hostei.com/grant/z80/SimpleZ80.html benutzt er einen TTL-USB Converter mit CTS/DTR Signal, angesteuert von einer 68B50. Keine Z80 SIO. So etwas habe ich nicht gefunden. Diese Arduino Cips für 2 Euro fuffzig haben nu RX und TX, was ja auch reicht. Mit einem 3,64 Mhz Quartz müssten 56 kBaud erreichbar sein. Wozu also diese beiden Modem Leitungen? Gruss, Christian
Christian J. schrieb: > Wozu also diese beiden Modem Leitungen? Um die Übertragung zu bremsen, falls es einer Seite zu schnell gehen sollte, was ja bei den alten Schätzchen u.U. häufiger vorkommen dürfte, als bei modernen Multicore-Gigahertz-CPUs.
Christian J. schrieb: > der Evoluion zurück gehe und zb eine PDP-11 nachbaue? So ein TTl > Grab.... da sieht man ja fast die Elekronen flitzen Wenn du damit das Bild meinst: Das ist ja schon eine neumodische VLSI-Version mit einer hochintegrierten CPU in Form ebendieser Herdplatte. Bei den vorherigen Typen war nicht nur das Drumrum aus TTLs der 74Sxx Serie, aufgebaut sondern auch die CPU selbst: http://www.neurotica.com/w/images/7/79/DEC-PDP1170-KB11C-3.jpg (hier ohne FPU, wie man unschwer erkennen kann).
:
Bearbeitet durch User
Für museumsreife Mikroprozessoren und deren Peripherie ist Kessler immer mal einen Blick wert. So findet sich da neben DMA und CTC auch ein PIO, allerdings in PLCC44: http://www.kessler-electronic.de/Halbleiter/integrierte_Schaltkreise/Mikrocontroller/Zilog_Z80_c245.htm Segor ist als Bezugsquelle verstaubter Hardware auch recht interessant und da findet sich auch der normale PIO in DIP40: http://www.segor.de
:
Bearbeitet durch User
Christian J. schrieb: > Ich weiss noch damals wie sehr ich mir einen Cross Compiler gewünscht > habe, so um 1995 herum ..... gab es nicht oder war zu teuer. TASM gabs aber damals schon lange und war immer sehr preisgünstige Shareware. Der konnte (und kann auch heute noch) einen Haufen Prozessoren programmieren, wie den Z80, 6502, 6800,MCS-48,MCS-51, TMS32020 usw. Du kannst auch neue Prozessoren definieren - ist eben ein Tabellengesteuerter Assembler. Hier mal ein Beispiel: http://www.vintagecomputer.net/software/GNICE/TASM/TASMTABS.HTM Falls du das Binary nicht auftreiben kannst, kann ich dir bestimmt mal was zusammensuchen. Im Anhang ist ein kleines Monitorprogramm in Z80 Assembler, eigentlich fur den Toshiba TMPZ84C015 gedacht, der ein komplettes Z80 System mit PIO,SIO und CTC beinhaltet - der CEPAC80 von der c't war ein Kleinsystem mit diesem Chip. Der Monitor residiert im Bereich von 0000h-1fffh. Ab 9000 ist ein RAM eingeblendet, der optional gepuffert wird und Programme oder Daten hält. So ein Dings hat jahrelang meinen alten (analogen) Satellitenempfänger gesteuert, im RAM waren die Programmspeicher. Der Monitor kann auch ein IntelHex empfangen und dann ausführen.
:
Bearbeitet durch User
Hallo, mit dem TASM habe ich damals einen Stealth Virus für DOS geschrieben, der war aber von Borland. War total happy, dass ich den an der Uni bekam. Danke erstmal für den Source, werde ich da mal einarbeiten sobald das System läuft und ich den Zaks durch habe, denn soooooo einfach ist das alles doch nicht. Die Interrupt Struktur des Z(0 ist mir so neu, der gibt ja über die PIO ein Register zuück, so dass die IR Quelle indentifiziert werden kann. der 6510 hatte nur eine IRQ Quelle, den NMI und den INT Pin. Ich finde den ARM7 schon komplex aber da habe ich eine astreine IDE von Rowley wo ich alles machen kann icl Singe Step Debugging, Test im RAM usw. CPU aus Gattern aufbauen? Hatten die sonst keine Hobbies? Am Zeichenbrett? Ich habe sowas mal gesehen in meiner alten Fima, hoch komplexe Schaltpläne mit Tusche auf A2 .... örks @Matthias: evtl habe ich später nochmal ne Frage, denn mich interessiert vom Monitor nur der Intel Hex Upload. Ich werde 8kb ROM einbauen und 56kb RAM, es wird nur ein Upload Programm geben und den Basic Interpreter, sowie ein Memory Dump. Also quasi Auswahl 1) Upload 2) Save 3) Basic 4) Memory Dump wobei das Save auch nur ein Listen ist, das ich mit dem Terminal wieder abspeichern kann. Gruss, Christian
Christian J. schrieb: > CPU aus Gattern aufbauen? Hatten die sonst keine Hobbies? http://www.mycpu.eu/
>Die Interrupt Struktur des Z80 ist mir so neu Diese Aussage zeigt, daß du dich mit dem in deinem Besitz befindlichen Z80-System "Microprofessor" niemals (ernsthaft) beschäftigst hast. Denn dort wird das ausführlich mit funktionsfähigen Beispielen gemacht. Beitrag "Re: Retro Fieber: Z80 oder 68000 ?" Gruss
Erich schrieb: > Z80-System "Microprofessor" niemals (ernsthaft) beschäftigst hast. Doch...... so ca 1986 mal und seitdem liegt das Ding in der Kiste und wurde nie wieder angeschaut, weil es mir zu blöd ist Asm per Tabelle in Hex umzurechnen..... hier noch ein Terminal eines CC85 den ich damals für 300 bei Conrad kaufte. RN = Return, BS = Backstep. AD = Adresse, DT = Data. Alles schön in Hex eintippen :-) Machen konnte man mit dem Ding nichts! Zumindest nichts sinnvolles. Habe nur noch ein Kassetten Interface dran gebaut und einen 8253 Timer und danach die Lust verloren. Übrigens bin ich gerade DABEI mich damit zu befassen. Hautpscahe ich verstehe wie die Cortex IRQ Struktur funktioniert, damit verdiene ich u.a. nämlich Geld das zu verstehen :-)
Joe G. schrieb: > Christian J. schrieb: >> CPU aus Gattern aufbauen? Hatten die sonst keine Hobbies? > > http://www.mycpu.eu/ Ich habe da mal quer gelesen und mir einige Schaltpläne angeschaut bzw Sourcen. Der Junge ist 32, hat E_technik studiert. Er kennt sich sehr gut damit aus wie eine ALU innendrin aufgebaut ist. Hat einen Befehlsdecoder mit Microcode realisiert, da der Aufwand das mit Gattern zu machen noch deutlich höher ist als 50 TTL Chips. Er wird Tage gebraucht habe die Timing Probleme in den Griff zu kriegen. Er hat einen eigenen Assembler geschrieben, eigenen Basic Interpreter, ein eigenes DOS, einen TCP IP Stack. Er hat eine vermutlich überdurchschnittliche Intelligenz und sicher keine Freundin, weil Frauen Zeit beanspruchen, die er nicht hat. Ich bewundere sowas aber ich habe nie Zeit verschwendet Dinge zu bauen, die es schon gibt, sondern das was es gab dazu benutzt etwas Neues daraus zu machen.
> Z80-System "Microprofessor" Ich habe auch so'n Teil, angeschafft 1981/1982, als es aktuell war. Da ich auch über ein CP/M System verfügte, habe ich die beiden Teile über eine am Microprofessor nachgerüstete serielle Schnittstelle ergänzt. Anfangs musste ich noch einen "Urbootloader" täglich inn Ram eintippen. Aber kurz später habe ich das Eprom gepatched und musste nur noch <Adresse><Go> drücken, damit wartete der Microprofessor auf ein ausführbares Programm für seinen Rambereich. Ob ich Intel-Hex benutzte oder Binärformat weiss ich jetzt nimmer. Auf jeden Fall schrieb ich meine Programm für den Microprofessor fortan auf dem CP/M System, assembliert mit M80/L80. Später ergänzte ich den Microprofessor auf seinem Lochrasterfeld mit einen Multiplex-Interface für eine Brother-Typenradschreibmaschine, deren Tastaturmatrix ich angezapft hatte (denn Schreibmaschinen mit Interface waren unbezahlbar). So konnte ich über den Microprofessor als Subsystem auch Schönschriften (Briefe etc.) in Wordstar verfasst schreiben und ausdrucken. Texte sauber in Blocksatz geschrieben (http://de.wikipedia.org/wiki/Blocksatz), als Student wohlgemerkt, nicht nur auf den Epson Matrixdrucker, da staunten manche Leute... Gruss
Wie gesagt, irgendwann kommen wir alle wieder bei den Keulen und Steinhämmern an ..... wenn ich sowas hier sehe, Transistor für Transistor Qualität :-) Und wirklch Geld verdient haben damit nur die beiden, zur richtigen zeit am richtigen Ort das Richtige gemacht. http://www.4004.com/assets/PB120046.JPG
Eine kurze Frage: Die Z80 PIO oder liebr den 8255? Der 8255 ist einfacher und hat 3 Ports. Die PIO hat alle mögichen Funktionenl die wohl mal für Drucker, Centronics, Lochkartenleser usw. vorgesehen waren, die aber heute kein Mensch mehr braucht. Leider haben beide Chips wohl gemeinsam, dass sich die Ports nur als Ganze auf Out oder IN setzen lassen. Ob man den Interrupt Firlefanz der PIO braucht sei mal dahin gestellt. Ich brauche eigentlich nur einen birdiretionalen Port um etwas anzuschliessen. Spricht also was gegen den 8255? Oder für die Z80 PIO?
Christian J. schrieb: > Ich brauche eigentlich nur einen birdiretionalen Port um etwas > anzuschliessen. Dann nimm einen bidirektionalen Bustreiber. Dein 8255 hat drei davon vereint und werde glücklich. Für deine einfachen Aufgaben reicht das. Die Z80-PIO hat jedoch Eigenschaften, welche man in den Ports moderner MC wiederfindet.
Christian J. schrieb: > Leider haben > beide Chips wohl gemeinsam, dass sich die Ports nur als Ganze auf Out > oder IN setzen lassen. Schon mal einen Blick ins Datenblatt riskiert?
Christian J. schrieb: > Die Z80 PIO oder liebr den 8255? Nimm das was Du da hast. > Der 8255 ist einfacher und hat 3 Ports. Vier. Zwei mit 8 bit und zwei mit 4 bit. Will sagen, Port C ist teilbar. Damit kann man den Handshake für die Ports A und B machen, z.B. für zwei Druckerports. > Ob man den Interrupt Firlefanz der PIO braucht sei mal dahin gestellt. Wenn Du "richtige" Z80-Interrupts haben willst, also mit 255 Vektoren, dann brauchst Du den. Der einfache Spring-Nach-0038h (mode 1) geht auch so. Oft reicht das -- Motorola hatte ja damals auch nur einen /IRQ mit festem Sprungziel.
Erich schrieb: >>Die Interrupt Struktur des Z80 ist mir so neu > Diese Aussage zeigt, daß du dich mit dem in deinem Besitz befindlichen > Z80-System "Microprofessor" niemals (ernsthaft) beschäftigst hast. Naja, ich habe damals relativ komplexe Sachen mit dem CEPAC80 gemacht, aber heute müsste ich mich da auch wieder einarbeiten, wenn ich das wollte. Christian J. schrieb: > Die Z80 PIO oder liebr den 8255? > > Der 8255 ist einfacher und hat 3 Ports. Die PIO hat alle mögichen > Funktionenl die wohl mal für Drucker, Centronics, Lochkartenleser usw. > vorgesehen waren, die aber heute kein Mensch mehr braucht. Das kann man vorher nicht wissen, die PIO ist halt für die etwas merkwürdige INT-Vektor Mimik des Z80 genau massgeschneidert und macht einiges automatisch, wozu du beim 8255 etwas Code brauchst. Der o.a. Satellitenempfänger hatte so viele Ports, das ich mit externen Latches (74373) und Input Ports (74244) nachhelfen musste. Für 'Pinchange' Interrupts im modernen Sinne gehts ohne PIO nur sehr schwer und mit externer Hardware neben dem 8255. Die IR-Fernbedienung meines Sat-RX nutzte deswegen die PIO Hardware des TMPZ Chips.
Christian J. schrieb: > Leider haben > beide Chips wohl gemeinsam, dass sich die Ports nur als Ganze auf Out > oder IN setzen lassen. Nö. Z80-PIO: In Mode 3 kann man die Richtung bitweise festlegen. Und mit einer Maske kann man festlegen, welche Pins einen Interrupt auslösen sollen.
>die PIO ist halt für die etwas >merkwürdige INT-Vektor Mimik des Z80 >genau massgeschneidert Das ist keine "merkwürdige Mimik", sondern der anno 1976 von Zilog eingeführt Vector-Interrupt-Mode "IM2". Hierbei liefern die Peripheriebausteine PIO, CTC oder SIO bei der Auslösungen eines INT direkt eine <Lo-Adresse> (die den Bausteinen bei ihrer Initialisierung zugewiesen wird). Zusammen mit der <Hi-Adresse> die im CPU Register "I" initialisiert wird, ergibt sich somit eine <16Bit-Adresse> als Zeiger. Der Zeiger zeigt auf eine Tabelle, unter der die Startadressen der jeweiligen Interrupt-Funktionen definiert sind. Denn man muss wissen: Jeder der Bausteine PIO, CTC, SIO hat mehrere Vektoren, kann somit mehrere Interrupt-Funktionen direkt auslösen. Der CTC (Counter/Timer) hat z.B. 4, je einen eigenen für seine 4 Timerkanäle. Wird jetzt beispielsweise der Kanal2-INT ausgelöst, so "landet" die Programmausführung wenige Takte später direkt in der Unterfunktion CTC_INT_CH2. Ohne daß irgendwo noch umständlich abgefragt werden muss, welcher Baustein oder welcher Unterkanal des Bausteins den INT ausgelöste hat. Die SIO (serieller Baustein) hat noch mehr Vektoren (8); sie unterscheidet zwischen ihren beiden Channels A/B sowie direkt zwischen Rx und Tx sowie Rx error und Tx error. Ein fast geniale Struktur, die andere Hersteller (bis heute) nicht verstanden haben. Konkretes gut erklärtes Beispiel mit Sourcecodelisting findet sich in der Datei MPF-1_experimentManual.pdf (Link über http://electrickery.xs4all.nl/comp/mpf1/doc/index.html). Dort "Experiment 15" ab Seite 103 (109/152 der PDF). Gruss
Erich schrieb: > Ein fast geniale Struktur, die andere Hersteller (bis heute) nicht > verstanden haben. Ja, man spart viel Zeit, da man nicht erst umständlich ermitteln muß, wer den Interrupt auslöste. Daher bin ich auch nie mit dem PIC warm geworden. Ich fands ja schon nervig, daß sich beim 8051 UART Senden und Empfang einen Vektor teilen mußten.
Erich schrieb: > Die SIO (serieller Baustein) hat noch mehr Vektoren (8); sie > unterscheidet zwischen ihren beiden Channels A/B sowie direkt zwischen > Rx und Tx sowie Rx error und Tx error. > Ein fast geniale Struktur, die andere Hersteller (bis heute) nicht > verstanden haben. Was Du schreibst, ist mehr als gewagt! Einerseits muß ich schmunzeln, andererseits aber auch dieser Aussage widersprechen. Als Beispiel nenne ich den RX62; die Interrupt-Vektor-Tabelle zeigt die Details.
@m.n: Du vergleichst jetzt nicht wirklich einen aktuellen Renesas Controller mit dem Z80 System von 1976 und stellst die auf eine Stufe? @Christian: Ich sags nochmal: Einfacher ist der 8255 nicht. Der wird sogar richtig lustig wenn Du die Betriebsarten zur laufzeit ändern willst. Das Ding ist voll von Glitches und kann eine büchse der Pandora sein wenn es drauf an kommt. Zilog hat sich beim PIO schon ziemlich viel gedacht, das IM2 Vektorsystem ist genial, auch wenn es an der Signallaufzeit der Prioritätskette seine Grenzen findet. Das Teil ist auch nicht kompliziert zu programmieren, hast Du schon mal ins Datenblatt geguckt? Für den Z80 Kram gibts gute deutsche Beschreibungen, suche ggf. einfach nach einem Datenblatt vom U855, der DDR Variante des PIOs. Man sollte aber auch das Interruptsystem im Interruptmode 2 verstanden haben, bzw. verstanden haben wollen ehe man das irgendwie abtut. >Der 8255 ist einfacher und hat 3 Ports. Die PIO hat alle mögichen >Funktionenl die wohl mal für Drucker, Centronics, Lochkartenleser usw. >vorgesehen waren, die aber heute kein Mensch mehr braucht. Du bist eine Pappnase. Ich würde einiges darum geben einen Controller zu haben dessen Inputports ein komplettes Datenwort über ein Strobesignal latchen können. Diese Funktionalität braucht wohl heute kein Mensch mehr.. außer mir. Heute löst man einen Interrupt aus und liest per Software den Port ein, Scheiße nur wenn das viel zu lange dauert. Umgekehrt das Selbe, ein OutputRegister mit einer Variable vorladen und mit einem Enable Signal von hochohmig auf Ausgabe schalten... geht heute nicht mehr, also löte ich zusätzliche Three-State Driver / Latch ein. (Ok, die Anwendung eines Controllers als intelligentes Interface an einem Rechnerbus eines alten Computers ist heute obskur, das ändert aber nichts daran, das diese Funktionalität meistens fehlt. Der Olle 8042 Tastaturcontroller aka UPI konnte genau das, die PIO kann es auch) Nimm den Mund nicht so voll bei Sachen die du nie verstanden hast. Das war früher schon eines Deiner Probleme :-) Zum Deinem Amp: Röhren sind nicht wegen ihrer schlechten elektrischen Eigenschaften abgeschafft worden sondern wegen ihrer Baugröße und des Energeiverbrauches. Es wundert mich deshalb überhaupt nicht, wenn Dein 12 Jahre alter EL84 Amp immer noch zur Zufriedenheit tut. "...Kannst du mir das Radio reaprieren? Ist bestimmt nur eine Röhre.." Nein, es ist nahezu nie eine Röhre die den Geist aufgegeben hat, sondern andere Dinge wie Koppelkondensatoren.. Gruß, Holm
Holm Tiffe schrieb: > @m.n: Du vergleichst jetzt nicht wirklich einen aktuellen Renesas > Controller mit dem Z80 System von 1976 und stellst die auf eine Stufe? Auf die Gefahr hin, dass Du auch mich als Pappnase beschimpfst oder den Mund verbieten willst, wiederhole ich Erichs Kernaussage: Erich schrieb: > Ein fast geniale Struktur, die andere Hersteller (bis heute) nicht > verstanden haben. Damit wird dem Z80 ein (bis heute) unerreichtes Alleinstellungmerkmal angedichtet; das geht mir einfach gegen den Strich! Allerdings sehe ich auch, dass zum Beispiel die STM32F4xx immer noch viele Interrupts über einen einzigen Vektor abhandeln und man alle relevanten Statusbits in der ISR 'abklappern' muß. Das geht mir auch gegen den Strich :-)
m.n. schrieb: > Holm Tiffe schrieb: >> @m.n: Du vergleichst jetzt nicht wirklich einen aktuellen Renesas >> Controller mit dem Z80 System von 1976 und stellst die auf eine Stufe? > > Auf die Gefahr hin, dass Du auch mich als Pappnase beschimpfst oder den > Mund verbieten willst, wiederhole ich Erichs Kernaussage: > > Erich schrieb: >> Ein fast geniale Struktur, die andere Hersteller (bis heute) nicht >> verstanden haben. > > Damit wird dem Z80 ein (bis heute) unerreichtes Alleinstellungmerkmal > angedichtet; das geht mir einfach gegen den Strich! Er hat trotzdem recht. Es ist nämlich vergleichsweise simpel, die diversen on-Chip Interruptquellen eines µC auf verschiedene Vektoren zu legen. Schließlich ist deren Zahl ja bekannt. Das Z80 System beherrschte das aber für eine fast beliebige Anzahl an IO-Bausteinen und mit einer variablen Anzahl Vektoren pro Baustein. XL
m.n. schrieb: >> Ein fast geniale Struktur, die andere Hersteller (bis heute) nicht >> verstanden haben. > > Was Du schreibst, ist mehr als gewagt! Insbesondere Hersteller, die in ihre Mikroprozessorentwicklung Erfahrung mit Minicomputern einfliessen liessen, hatten deutlich besser entwickelte Interrupt-Systeme, als die meisten 8-Bitter von Haus an Bord hatten. TI hatte den TMS9900 von der 990 Familie abgeleitet, war damit vor Zilog auf dem Markt und bot 16 Interrupts mit jeweils eigenem Registersatz für Kontextswitch (eigentlich wars RAM). National Semiconductor hatte kurz nach Intel 8080 mit der aus den Data General Novas abgeleiteten PACE Familie immerhin 5 Interrupts. Intels 8080 war ohnehin eher ein Bausatz als ein Single-Chip Mikroprozessor. Eigentlich ein 3-Chip Prozessor, denn ohne speziellem Taktgenerator und Buscontroller ging wenig. Mit dem für bessere Interrupts notwendigen Interruptcontroller waren es dann 4. Aber immerhin - Interrupts mit Prioritäten und getrennten Vektoren waren möglich. Der im PC auch heute noch schlummernde 8259 geht darauf zurück. Das besondere am Interrupt-System der Z80 war der ziemlich geringe Aufwand an Pins und externer Beschaltung, so lange nur wenige Bausteine benötigt wurden und die daisy chain dementsprechend kurz war. Für Integration von Fremdperipherie in dieses IM2 Verfahren musste man dann eben den PIO als Interruptcontroller verwenden.
:
Bearbeitet durch User
Hallo, na, jetzt gehen die Glaubenskriege aber los :-) Dass der 8255 Glitches hat war schon damals bekannt aber idr stellt man ihn einmal ein und damit hat es sich. Oder man stellt ihn um und wartet bis er fertig ist. Er ist schon einfacher, da er nicht so viel Innenleben hat. Sa mir doch mal wofür ich bei einem Bastelcomputer ein Bit Datenwort per Latch und Srobe übergeben muss? Maximal werded ich damit eine Bitbang SpI realisieren, die ein Arduino Display füttert. Und heutige Controller haben eben eine andre IRQ Struktur, die meisten eben Pins, die sich als IQ Quelle schalten lassen und dann weiss man woher er kommt. Der Z80 und Peropherie wurden aufenander abgestimmt als es noch für alles einen Baustein gab. Heute hast du alles in einem und jede Menge interne IQ Flags. die du auswerten kannst. Allein der ARM7 hat einen ganzen Korb voll, glaube es sind viele Dutzend. Aber es wächst, heute kam wieer der Postbote mit einer Hand voller Tüten an ... Einen Baustein für die CPU, einen Baustein für den Parallelport einen Baustein für das ROM einen Baustein für das RAM einen Baustein für die UART, einen Baustein für die Timer, einen Löffel für Papa und einen für die Mama :-) Wahnsinn, das hat man alles auf einen Attiny drauf und der ist noch 10 Mal schneller. Wieso nehme ich nicht gleich einen AVR? Bin ich denn gaga? ..... jetzt fehlt nur noch das passende T-Shirt dazu örks >>Das besondere am Interrupt-System der Z80 war der ziemlich geringe >>Aufwand an Pins Wie bitte? Man braucht 8 Datenleitungen, 4 Steuerleitungen, 3 Adressleitungen ..... das ginge doch auch alles Seriell mit I2c. Mfg Chris
So wird es werden, nur mal gesteckt. unten drunter Fädelkämme, daher die großen Abstände zwischen den Chips. Die I/O leiste kommt rechts neben den 8255 (oder Z80 PIO), dann ist noch ein Z80 CTC drauf (kein 8253 :-) und der 60B84 als Uart - Z80 SIO ist mir zu voll geladen -aber die habe ich in China bestellt und dauert noch. >> ein OutputRegister mit einer Variable vorladen und mit einem Enable >> Signal von hochohmig auf Ausgabe schalten Was geht nicht mehr ????? Wo ist das problem? Beim ARM7TDMI hast du Unterschiedliche register für Ein und Ausgabe. Du lädt die Ausgabe ins Output vor aber stellst den Port auf Input ein, damit wird er Tri-state. Dann geht das was dran ist ins Leseregister. Schaltest du die Datenrichtung um mit FIOSEL glaube ich geht das was im Output steht direkt auf den Port. Der ARM ist einer der genialsten Maschinen überhaupt, auch wenn man Romane schreiben muss, um nur die Clocks über die PLL einzustellen und die Teiler richtig zu berechnen. Da ist alles drin aber eben "unverdrahtet", die Drähte in Form von Code muss man selbst legen.
Christian J. schrieb: > Beim ARM7TDMI hast du Unterschiedliche register für > Ein und Ausgabe. Der ARM7TDMI ist ein Prozessorkern. Der hat keinerlei Ein/Ausgaberegister. Das ist Sache jenes Herstellers, der den Kern zusammen mit allerlei Peripherie zu einem LPC2000, STM7, ... zusammenklebt. Und je nach Genialität dieses Herstellers kommt da eine mehr oder auch weniger gute Lösung für I/O-Pins raus. Mit den Interrupts ist das ähnlich. Die ADuC7000 Serie darf man in dieser Hinsicht wohl als eher vorsintflutlich betrachten.
:
Bearbeitet durch User
Hallo, > Wenn Du "richtige" Z80-Interrupts haben willst, also mit 255 Vektoren, > dann brauchst Du den. Es gibt nur 127 Vektoren, weil die auf geraden Adressen liegen müssen (das unterste, von der Peripherie gelieferte Bit muss null sein). > Für Integration von Fremdperipherie in dieses IM2 Verfahren musste man > dann eben den PIO als Interruptcontroller verwenden. Oder man baut sich einen IM2-Controller mit 8 Interrupts aus einem '148 (Encoder) und einem '541 (für den Vektor) zusammen. Allerdings muss die Hardware dann den Interrupt so lange aktiv halten, bis er verarbeitet wurde. Das geht aber auch hinter der Daisy-Chain noch. > Ich würde einiges darum geben einen Controller zu haben dessen > Inputports ein komplettes Datenwort über ein Strobesignal latchen > können. Schau' dich mal bei den kleinen PICs um, die können das wohl. Mein AVR lässt, weil er genau das nicht kann, den Z80 per Extra-Gatter so lange Waitstates drehen (und dreht ihm danach auch noch den Bus ab), bis er in aller Ruhe analysiert hat, was ich gerade von ihm will. > Sa mir doch mal wofür ich bei einem Bastelcomputer ein Bit Datenwort > per Latch und Srobe übergeben muss? Maximal werded ich damit eine > Bitbang SpI realisieren, die ein Arduino Display füttert. Für IDE brauchst du einen 16 Bit breiten Datenbus (Ausnahme: antike Festplatten, CF-Karten im IDE-Modus oder 50% Platzverschwendung). Das gemeinsam latchen zu können, ist schon hilfreich. > Und heutige Controller haben eben eine andre IRQ Struktur, die meisten > eben Pins, die sich als IQ Quelle schalten lassen und dann weiss man > woher er kommt. Das ist genau dann besonders sinnvoll, wenn es um die Controller-internen Einheiten geht. ;-) > Wieso nehme ich nicht gleich einen AVR? Bin ich denn gaga? Offensichtlich. ;-) Aber AVR kann ja jeder. >>>Das besondere am Interrupt-System der Z80 war der ziemlich geringe >>>Aufwand an Pins > > Wie bitte? Man braucht 8 Datenleitungen, 4 Steuerleitungen, 3 > Adressleitungen ..... das ginge doch auch alles Seriell mit I2c. Eigentlich reichen, um IRQs zu verarbeiten, 2 Steuerleitungen (/M1 und /IORQ) und ausreichend (max. 7) Datenleitungen aus. Gruß, Svenska
Hi, ich habe einen recht guten Plan gefunden, den ich hier mal anhänge. Vor allem die Decodierung gefällt mir besser als diese Gattergräber. Da ich für die Uart einen 6850 benutze und einen CTC Timer denke ich mal, dass es ein Problem werden könnte beide Bausteine an den INT Pin zu hängen. Der Z80 erwartet ja diese Kette. Andererseits wäre es denkbar, dass der 6850 mit seinem INT Pin an den INT Eingang des CTC geht und der CTC wiederum an den Z80. Ich will auf jeden Fall den Timer Baustein benutzen, um zb Anzeigen anzusteuern.
Es ist zum Heulen! Wenn ich den Z80 CTC Timer verwenden will, muss der an den INT Pin der CPU dran, da die Timer ja INTs auslösen sollen, um zeitgesteuerte Aufgaben zu erledigen. Timer will ich haben, basta! Aber ich brauche auch die INTs der seriellen Schnittstelle und da sitzt eben ein einfacher 28poliger 6850 dran, der auch von seiner Größe auf die Eurokarte passt. Die Z80 SIO ist ein 40 pinniger Trümmer und ich brauche grad mal 4 Leitungen nach außen: TX,RX,CTS,RTS. Und die SIO ist recht komplex, ich müsste die Routinen selbst schreiben um mit dem PC in einem Terminal zu kommunizieren. Es gäbe keine Möglichkeit die INTs des CTC und die des 6850 (Zeichen ist da) der CPU mitzuteilen, da die dann nicht weiss woher der INT gekommen ist. Denkbar wäre den CTC an die CPU zu pappen über den INTOUT Pin und am INT_IN den 6850 dran zu hängen, der aber nicht die Fähigkeit hat einen Vektor auf den Bus zu legen. Andere Alternative: Das Minimalsystem auf einer Eurokarte aufbauen CPU, RAM, ROM, Glue Logic, Decoder + Z80 SIO zum PC Interface und einen kompletten Bus mit Decodierungsleitungen (sagen wir mal 4 Stück) nach außen zu legen (bewahre mich vor dem Verdrahten) an den dann eine weitere Eurokarte anzuschliessen, wo nur Peripherie drauf ist. Falls jemand einen Schaltplan hat, wo wirklich alles drauf ist immer her damit!
Christian J. schrieb: >>>Das besondere am Interrupt-System der Z80 war der ziemlich geringe >>>Aufwand an Pins > > Wie bitte? Man braucht 8 Datenleitungen, 4 Steuerleitungen, 3 > Adressleitungen Klar. Aber die brauchte man doch sowieso. Stichwort Bus. Aber im Gegensatz zum z.B. IBM-PC kam ein Z80 System mit einer einzelnen /INT Leitung aus - für bis zu 128 Interruptquellen. Der PC mit seinem PIC (Programmable Interrupt Controller) hat statt dessen eine handvoll separater Leitungen, die man erst wieder manuell jumpern muß um seine Interruptquellen auf Vektoren zu verteilen. Eine Krücke halt. Wie so vieles beim PC. S. R. schrieb: >> Ich würde einiges darum geben einen Controller zu haben dessen >> Inputports ein komplettes Datenwort über ein Strobesignal latchen >> können. > > Schau' dich mal bei den kleinen PICs um, die können das wohl. Bäh. PICs (vor allem die kleinen) sind doof und riechen nach Lulu. Oder anders gesagt: vom Regen in die Traufe. Dann nehme ich doch wirklich lieber ein separates Latch in Hardware. XL
Christian J. schrieb: > Es ist zum Heulen! > > Wenn ich den Z80 CTC Timer verwenden will, muss der an den INT Pin der > CPU dran, da die Timer ja INTs auslösen sollen, um zeitgesteuerte > Aufgaben zu erledigen. Timer will ich haben, basta! > > Aber ich brauche auch die INTs der seriellen Schnittstelle und da sitzt > eben ein einfacher 28poliger 6850 dran Einmal darfst du raten, warum dir hier immer wieder eine Z80 SIO ans Herz gelegt wurde. Wer nicht hören will ... Wenn du eine PIO verbaut hast und da noch Pins frei sind: führe den INT des 6850 an die PIO und laß die PIO stellvertretend einen "richtigen" Interrupt auslösen. XL
Das Verheiraten von Z80 oder 8080 Bausteinen mit 68xx Bauteilen war ja früher schon fast so eine Sünde wie wenn ein Katholischer eine Evangelische (oder umgekehrt) geheiratet hat. Das Businterface beider Bausteinfamilien passt einfach schlecht zusammen.
Axel Schwenke schrieb: > Einmal darfst du raten, warum dir hier immer wieder eine Z80 SIO ans > Herz gelegt wurde. Wer nicht hören will ... Sei mir nicht böse aber ich finde die SIO komplett unverständlich. Dagegen habe ich die vom LPC21xx noch ruck zuck kapiert und hatte auch schnell lauffähigen Code. Hasst du ne Ahnung wie das ist Routinen blind auszuprobieren wenn man "nichts sieht" weil kein Debugger da ist und eine nette printf(stdout,"Variable a =...%d",a) Funktion? Und das ist nicht nur meine Meinung denn die fand ich im Netz öfter, daher nimmt sie auch fast keiner, der ein Z80 System gebaut hat. Selbst der N8VM Rechner nimmt eine 8251 oder 16C550 Uart. http://www.izabella.me.uk/html/z80_sio_programming_hints.html The programming complexities of large scale integration components are usually directly proportional to the facilities and versatility of the device.In the case of the Z80SIO, it will probably take some time even for even the more experienced programmer to work out how to make it perform even the most rudimentary tasks. To the beginner at microprocessor programming, it is possible that the bewildering array of registers will cause a total confusion unless a logical approach is taken from the start. 6850 an PIO: Ok, die Idee hatte ich auch schon. Frage: Welcher INT Mode? 2 sicherlich denke ich mal. Und wohin springt die CPU, wenn der 6850 einen INT auslöst und keine Low Adresse auf dem Bus liegt? Ich erinnere mich schwach, dass auch M1 mit der SIO verdrahtet werden muss, hier im Plan verbindet er M1 mit dem CS0 des 6850.
Christian J. schrieb: > Ok, die Idee hatte ich auch schon. Frage: Welcher INT Mode? 2 sicherlich > denke ich mal. In dieser Schaltung IM1. IM0 und IM2 führen im IACK-Zyklus Code- bzw. Vektorzugriffe durch, die hier in den Wald laufen. > Und wohin springt die CPU, wenn der 6850 einen INT > auslöst und keine Low Adresse auf dem Bus liegt? Oeben. > Ich erinnere mich > schwach, dass auch M1 mit der SIO verdrahtet werden muss, hier im Plan > verbindet er M1 mit dem CS0 des 6850. Damit wird verhindert, dass der 6850 IACK-Zyklen als Zugriff auf seine Steuerregister interpretiert. In denen ist M1=0, CS0 muss aber 1 sein.
Christian J. schrieb: > nicht nur meine Meinung denn die fand ich im Netz öfter, daher nimmt sie > auch fast keiner, der ein Z80 System gebaut hat. Interessanter Ansatz. Ich kann ja verstehen, wenn jemand den 6850 verwendet, weil der weniger Pins braucht. Aber dass Leute ihn verwenden, weil sie vom Z80-SIO überfordert sind, das habe ich noch nicht erlebt. Jedenfalls sind mir Z80-SIOs oft begegnet, hab ihn auch selber schon verwendet, auch den neueren komplexeren Z8530 (an 68000). Z80 mit 6850 hingegen sah ich hier zum ersten Mal. Also das mit dem "fast keiner" ist eine reichlich gewagte Aussage. Meine Erfahrungen mit diesen Teilen stammen freilich aus der Zeit, als die aktuell waren. Für die heutige Retro-Generation mag sich das vielleicht anders darstellen. ;-) > nimmt eine 8251 oder 16C550 Uart. Als der 16C550 auf den Markt kam war die Z80 schon steinalt.
:
Bearbeitet durch User
Helmut S. schrieb: > Das Verheiraten von Z80 oder 8080 Bausteinen mit 68xx Bauteilen war ja > früher schon fast so eine Sünde Ging auch nicht immer. Etliche 65xx/68xx Bausteine verwendeten E nicht nur als Strobe für den Buszyklus, sondern auch als Takt für diverse Timer. Abgeleitet aus RD/WR war das nicht eben hilfreich. Zudem passte das Timing einer 4MHz Z80 nicht zu den gebräuchlichen 1MHz 65xx/68xx Bausteinen.
:
Bearbeitet durch User
Wenn Du Platz sparen möchtest, vielleicht gefällt Dir ja anstatt des 6850 ein SCC2691: 24-pol. schmales DIL-Gehäuse Und wenn Du noch viel Platz frei hast, ich hätte noch einen INS8154 :-)
Christian J. schrieb: > hier im Plan verbindet er M1 mit dem CS0 des 6850. Formal betrachtet ist 68xx Peripherie an Z80 nicht so einfach, wie hier in der Schaltung gezeigt. Denn beim 68B50 muss R/W mindestens 40ns for E anliegen. Das ist in dieser Schaltung mit E aus IORQ nicht gewährleistet. Und in einer anderen Variante, in der E aus RD+WR abgeleitet wird, natürlich ebenso wenig.
:
Bearbeitet durch User
m.n. schrieb: > Wenn Du Platz sparen möchtest, vielleicht gefällt Dir ja anstatt des > 6850 ein SCC2691: 24-pol. schmales DIL-Gehäuse Wie wärs mit 18 Pins? Damit kommt der TMS9902 aus.
Warum nimmste nicht den NMI für deinen 6850 (ein 6551 hätte es ja schon sein können :-P )?
Christian J. schrieb: > Sei mir nicht böse aber ich finde die SIO komplett unverständlich. Erzähl mal noch einen vom Pferd, was soll an nur 8+3 Registern kompliziert sein. Die SIO braucht allerdings noch nen CTC für die Baudrate. Christian J. schrieb: > Hasst du ne Ahnung wie das ist Routinen blind > auszuprobieren wenn man "nichts sieht" Ach komm, ein SW-putchar ist ruckzuck mit nem PIO-Pin und Delay zusammen gebastelt.
Ich hatte mal einen Z80 vectored Interrupt-Controller mit einem CPLD ATF750 geschrieben. Er hat 8 Interrupteingänge und erzeugt eine 3-Bit Vektor, die restlichen 5 Bits macht man mit einem Tristate-Buffer. Die Eingänge können einzeln enabled werden. 2 Eingänge sind flankengetriggert und 6 levelgetriggert.
Hier stellt sich langsam nochmals die Sinnfrage dieses Projekts. Geht es um Bastelspass? Was für SW soll darauf laufen? Was sollen die I/O tun können? Irgendein Zusammenhang oder Erweiterbarkeit Richtung CP/M? Generell ist wenig zielführend, den DIP-40 Z80 mit artfremden Peripheriebausteinen aus anderen Herstellerfamilien verheiraten zu wollen. Das Resultat wird nur ein Gemenge an Inkompatibilität. CPU, PIO, SIO, CTC. Fehlt noch der Taktgenerator. Dann sind wir gleich beim TMPZ84C015 (ursprünglich Toshiba). Alles drin. Voll kompatibel. Cmos. Damit war auch meine letzte "Z80" Platine (ein Industriegerät, Serienprodukt) ausgestattet, Baujahr war irgendwann Anfang-Mitte 1990 Jahre. Mit Flashspeicher Amd29f010, mit 128 kByte Ram, MMU und weitere Spezialperipherie für die Anwendung. Fast alles Smd. Mit Bootloader über RS232, Applikationssoftware im Feld updatebar ohne Eprom-Wechsel (neu damals). Eine einfache Platine mit dem TMPZ84C015 ist als "Z80mini3" bekannt, siehe http://www.mct.net/product/z80mini3.html bzw. http://elmicro.com/de/z80mini3.html Gruss
Erich schrieb: > Hier stellt sich langsam nochmals die Sinnfrage dieses Projekts. > Geht es um Bastelspass? Was für SW soll darauf laufen? Was sollen die > I/O tun können? Irgendein Zusammenhang oder Erweiterbarkeit Richtung > CP/M? Wie in der Überschrift steht, handelt es sich um ein Retro-Fieber, dessen Verlauf schlecht vorherzusehen ist. Ich gehe allerdings davon aus, dass sich einige Viren so verzetteln, dass es zu einer Spontanheilung kommt. Sofern man selber nicht infiziert ist, kann man sich zurücklehnen und an die schönen, alten Zeiten denken, wo man die Bits noch in die Hand nehmen und auf Magnetband abspeichern konnte :-) Erich schrieb: > Dann sind wir gleich > beim TMPZ84C015 (ursprünglich Toshiba). Alles drin. Voll kompatibel. Da könnte man jetzt den 68000 ins Spiel bringen; falls ihn jemand braucht, den TMP68301 hätte ich noch im Angebot.
m.n. schrieb: > die schönen, alten Zeiten denken, wo man die Bits noch in die Hand > nehmen und auf Magnetband abspeichern konnte :-) Neumodischer Kram! Ich habe mit 5 Kanal Lochstreifen und einer Zuse angefangen. DAS waren noch Zeiten. > Da könnte man jetzt den 68000 ins Spiel bringen; falls ihn jemand > braucht, den TMP68301 hätte ich noch im Angebot. Ich biete einen National NSC600 "Scamp" mit Eprom 5204 (512 Bytes, Vorsicht, Programmierspannung 50V).
Georg G. schrieb: > Ich biete einen National NSC600 "Scamp" Für den ist doch der INS8154 doch (wie) geschaffen.
m.n. schrieb: > Für den ist doch der INS8154 doch (wie) geschaffen. Möchtest du einen haben? Liegt hier noch in der Restekiste. Auch RAMs mit 256*4 Organisation sind noch da.
Hallo, wie ich sehe drehe ich mich im Kreis, zumindest was meine Lösung angeht, bei der etwas mehr drauf sein soll als nur Minimal. Beim 8085 damals war das deutlich einfacher, ok da habe ich auch nur 80xx verwendet. Ich mag die Z80 SIO nicht, iel zu gross für das wenige was sie leisten soll. Woebi ich nach einmal drüber schlafen jetzt soweit bin, dass ich dem 6850 die INT Leitung abklemmen werde und etl Polling benutzen werde, da er sowieso nix zu tun hat solange er auf was wartet. Ziel soll einfach nur sein etwas damit zu spielen, vielleicht ein Basic Programm zu schreiben, eine 7-Segment Anzeige dran zu bauen, Teperazuren anzuzeigen usw. Mehr nicht. Und da ich mir den "Kult Z80" mal antun wollte versuche ich es eben. Nen Arduinoi ans Rennen zu kriegen ist zu langweilig, da funktioniert ja eben alles sofort.
Christian J. schrieb: > Arduinoi ans Rennen zu kriegen ist zu > langweilig, da funktioniert ja eben alles sofort. Wie meinen Euer Ehren? Letztlich mal hier im Forum gelesen? Mein Eindruck ist eher das Gegenteil. Das kann aber auch an der Zielgruppe liegen :-)
Georg G. schrieb: > Wie meinen Euer Ehren? Letztlich mal hier im Forum gelesen? Mein > Eindruck ist eher das Gegenteil. Das kann aber auch an der Zielgruppe > liegen :-) Wie man es sieht. Wenn man wie ich im Innenleben der IDE rumfummelt, neue CPUs einbindet und Libs ändert kann es schon kompliziert werden. Vor allem wenn man nicht weiss wie die IDE drin genau arbeitet. Denn diese setup-loop Konstruktion kommt ja nicht irgendwo her. Außerdem weren da Sachen eingebunden die man nicht sieht, die man aber bemekert wenn man den Weg verlässt nur die Standafunktionen zu benutzten, zb mal den Timer 0 mit Low Level Code ändert. Dann klappt ganz schnell nix mehr :-)
Christian J. schrieb: > Es ist zum Heulen! [..] > > Falls jemand einen Schaltplan hat, wo wirklich alles drauf ist immer her > damit! Da Du immer hinterher fragst brauchst du Dich über Deine Effekte nicht wundern, Du baust simpel Scheiß. Du bist derartig clever das Du wieder über Deine Füße stolperst. Wenn Du erst gefragt und dann kaufen gegangen wärest, hätte ich Dich auf dieses Ding aufmerksam gemacht: http://www.wfms.org/sb180/z180-prelim.pdf Das Ding ist schon lange nicht mehr preliminary, falls die Frage kommt, der Link auf das PDF war nur günstig. Ich habe so ein Teil hier als 25Mhz Version (IMHO) bei den spezifizierten 33Mhz dürfte sich Deine Aussage "AVR 10x schneller" auch in heißen Dunst auflösen. Im PLCC68 Gehäuse gut für Lochraster geeignet. Du aber kaufst lieber nicht passende Peripherie ICs und wunderst dic das Käse dabei raus kommt. Zum CTC: Hänge den Interrupt ausgang Deiner blöden Sio an CLK/TRG3 vom CTC, programmiere den CTC Kanal 3 als Counter mit der preloaded Value von 1, nach H-L auf CLK/TRG3 löst der Kanal dann einen Interrupt aus und der Kanal kann einen Interrupt mit Vector generieren. >Sei mir nicht böse aber ich finde die SIO komplett unverständlich. >Dagegen habe ich die vom LPC21xx noch ruck zuck kapiert und hatte auch >schnell lauffähigen Code. Ach? Christian bei "aller Liebe", das haben Tausende von Ossis schon vor Jahrzehnten kapiert... Es gibt Bücher mit fertigen Routinen in Assembler, ebi normaler Async Kommunikation ist die SIO doch easy. Ok, die meisten Uarts in den MCUs heute sind primitiver da der ganze SDLC/HDLC Kram einfach nicht enthalten ist. Diese Version gibts aucher auch als Z80-DART. Gruß, Holm
Aber zum Vergleich mal die beiden Bastelprojekte: Links die Z80 Sache, rechts ein Arduino System mit Atmega. Glaubt jemand im Ernst er könnte eine grafische Anzeige auf dem Z80 für das Nokia 5110 in nur einem halben Tag mit Verdrahtung ans Laufen kriegen? Er würde sich die Füsse brechen die PIO zu programmieren, dann noch das Datenblatt des 5110 studieren müssen für den Treiber, dann noch Grafikfunktionen programmieren usw. usw. Früher waren Ingenieure die "Masters of Computer", heute machen das 14-jährige im Workshop an der Schule ...
Holm Tiffe schrieb: > Da Du immer hinterher fragst brauchst du Dich über Deine Effekte nicht > wundern, Du baust simpel Scheiß. Du bist derartig clever das Du wieder > über Deine Füße stolperst. > > Wenn Du erst gefragt und dann kaufen gegangen wärest, hätte ich Dich auf > dieses Ding aufmerksam gemacht: > > http://www.wfms.org/sb180/z180-prelim.pdf Also Holm....... ich frage nach einem Käfer und du kommst mit einem Panzer daher, für den es NICHTS irgendwo gibt. Google mal nach dieser CPU, die wird wohl nur in irgendwelchen Aktenschänken ihr Dasein vergammeln. Ich hoffe dieser thread wird einigen,die ähnlihes vorhaben bewusst mache vor welche Hürden man gestellt wird, wenn man alte Technik wieder beleben will. Und diese Vergewaltigung der CTC werde ich nicht machen ..... baue jetzt die SIO rein, dahinter einen USB Konverter, der ausnahmsweise auch RTC/CTS hat und fertig.
Christian J. schrieb: > Er würde sich die Füsse > brechen die PIO zu programmieren, dann noch das Datenblatt des 5110 > studieren müssen für den Treiber, dann noch Grafikfunktionen > programmieren usw. usw. Das ist aber dann nicht die Schuld des PIO, sondern desjenigen, der unbedingt in Assembler programmieren will. Nimm einfach nen Z80 C-Compiler und kopiere irgendeinen C-Treiber für das GLCD in Deinen Editor. Dann ersetze alle IO-Zugriffe auf das GLCD durch Aufrufe der PIO-Ausgabefunktion (falls die IO-Zugriffe nicht eh schon als Funktion gekapselt sind). Dann schreibe die PIO_Init und die PIO_Out Funktion (dauert ~5min) und fertig.
Christian J. schrieb: > Also Holm....... ich frage nach einem Käfer und du kommst mit einem > Panzer daher, für den es NICHTS irgendwo gibt. Google mal nach dieser > CPU, die wird wohl nur in irgendwelchen Aktenschänken ihr Dasein > vergammeln. Gleich Nebenan könntest Du Dich vom Gegenteil überzeugen. Beitrag "Z180-Stamp Modul"
Holm Tiffe schrieb: > Das Ding ist schon lange nicht mehr preliminary, falls die Frage kommt, > der Link auf das PDF war nur günstig. Datenblätter von Zilog sind fast immer preliminary.
Christian J. schrieb: > ... ich frage nach einem Käfer und du kommst mit einem > Panzer daher, für den es NICHTS irgendwo gibt. Hier sogar in zwei Varianten. Selbstverständlich mit CP/M :-)
Christian J. schrieb: [..] > > Also Holm....... ich frage nach einem Käfer und du kommst mit einem > Panzer daher, für den es NICHTS irgendwo gibt. Huh? Das Ding ist kein Panzer sondern ein Z180, HD64180.. > Google mal nach dieser > CPU, die wird wohl nur in irgendwelchen Aktenschänken ihr Dasein > vergammeln. Ich hoffe dieser thread wird einigen,die ähnlihes vorhaben > bewusst mache vor welche Hürden man gestellt wird, wenn man alte Technik > wieder beleben will. OMG. Christian ich schreibe kein aus den Fingern gesogenes Zeuch, ich weiß von was ich rede, Du wieder nicht. Ich empfehle Dir durchaus mal nach Z180 zu googeln, Beispiele gibts einige aber da die CPU einen Z80 Kern hat.. was soll es da für Beispiele nicht geben? Du vergleichst die Z80 mit heutigen ICs, die Z180 ist schon uralt aber offensichtlich bestehst Du auf unfairen Vergleichen? Und wieder schreibst Du ohne zu wissen... > > Und diese Vergewaltigung der CTC werde ich nicht machen ..... baue jetzt > die SIO rein, dahinter einen USB Konverter, der ausnahmsweise auch > RTC/CTS hat und fertig. Vergewaltigung? Das ist ein ganz normaler Betriebsmodus, bekannt seit Jahrzehnten und eine der hinlänglich bekannten und verwendeten Möglichkeiten einen systemfremden IC in die Interruptkette eine Z80 zu integrieren, genauso wie die mit PIO. Was soll der Käse mit dem Arduino? Du bekommst auch in einem halben Tag kein Atmel system mir grafischer Anzeige zum Laufen wenn Du alles zu Fuß programmieren mußt. Das man für den Z80, Z180 etc. bekannte und vorhandene Softwarebibliotheken nutzen kann, hältst Du offensichtlich auch für unwahrscheinlich. Ich frage mich nur warum? Wahrscheinlich deshalb, weil Du diese Dinge nicht kennst und deshalb hier behauptest das sie nicht existieren. Du hantierst wie selbstverständlich mit einem halbwegs modernen Atmel Prozessor, möchtest aber nicht mit einem halbwegs aktuellen Z80 vergleichen (und du kommst mit einem Panzer daher). Warum nicht? Weil Du dann nicht Recht hast? Was soll das? Von dem Verlinkten Datenblatt hast Du nichts gelesen sonst wüßtest Du das das ein Z80 Kern mir geringfügigen Erweiterungen, einer MMU und Peripherie ist, ohne ROM. Diese CPU ist älter als ein Atmel. Andere Hinweise über moderne Zilog Chips hattest Du auch schon erhalten, alles in den Wind geschlagen weil Du es besser weist. Wenn Du denkst das Du über einen ARM oder AVR mehr weist als ich hast Du wahrscheinlich auch Unrecht. Ich verdiene meine Brötchen mit solchen Sachen. Um Arduinos habe ich mich allerdings kaum gekümmert, ich Programmiere i.A. in C und Assembler. Ich empfehle Dir dringend Dich eingehend zu informieren bevor Du urteilst. Du manövrierst Dich sonst in Teufels Küche. Gruß, Holm
Christian J. schrieb: > die wird wohl nur in irgendwelchen Aktenschänken ihr Dasein > vergammeln. Auch die Originale von anno Dunnemal gibts noch, in PLCC68 und DIP64S beispielsweise bei http://www.kessler-electronic.de/Halbleiter/integrierte_Schaltkreise/Mikrocontroller/Zilog_Z80_c245.htm
:
Bearbeitet durch User
Axel Schwenke schrieb: [..] >> Schau' dich mal bei den kleinen PICs um, die können das wohl. > > Bäh. PICs (vor allem die kleinen) sind doof und riechen nach Lulu. Oder > anders gesagt: vom Regen in die Traufe. Dann nehme ich doch wirklich > lieber ein separates Latch in Hardware. > > > XL :-) Sehe ich auch so. Ich mach PIC wenn es der Auftraggeber unbedingt möchte, aber eher nicht freiwillig. Ok, die neueren sollen ja besser sein und über die MIPS Architektur zanke ich auch nicht.. Gruß, Holm
Holm Tiffe schrieb: > Sehe ich auch so. Ich mach PIC wenn es der Auftraggeber unbedingt > möchte, > aber eher nicht freiwillig. Ok, die neueren sollen ja besser sein und > über die MIPS Architektur zanke ich auch nicht.. Die 16 Bitter sind auch ganz angenehm. fchk
Meine letzte Erfahrung da war mit einem 16F577 (?) in Assembler, mir ging da das Banking auf den Wecker. Für irgend ein Peripherieding (keine Ahnung mehr ob Timer oder was das war) gab es die Hälfte der Konfiguration in der einen, den Rest in der anderen Bank. Sowas bin ich nicht gewöhnt und finde das schräg.. Gruß, Holm
Holm Tiffe schrieb: > Meine letzte Erfahrung da war mit einem 16F577 (?) in Assembler, mir > ging da das Banking auf den Wecker. Für irgend ein Peripherieding (keine > Ahnung mehr ob Timer oder was das war) gab es die Hälfte der > Konfiguration in der einen, den Rest in der anderen Bank. Sowas bin ich > nicht gewöhnt und finde das schräg.. Das war wohl eher ein PIC16F677. Bei den PIC18F muss man nicht mehr banken, kann aber, wenn man 16'er Code portieren will, und die 16-Bitter (dsPIC, PIC24) und 32 Bitter (PIC32) brauchen das ohnehin nicht mehr. fchk
Axel Schwenke schrieb: >> Schau' dich mal bei den kleinen PICs um, die können das wohl. > > Bäh. PICs (vor allem die kleinen) sind doof und riechen nach Lulu. Ach Axel, dem Rest der Welt ist es klar, daß ein begeisterter Atmel-Fan wie du keine Gelegenheit ausläßt, die PIC's zu schmähen. Daß du mentale Probleme mit deren Architektur hast, ist dein Problem. Aber die PIC's (vor allem die kleinen) sind eben gar nicht so doof, sondern es haben davon einige genau diese Ports, mit denen man sie als periphere IC's in größere Systeme einbinden kann. Im Prinzip sind das alle, die einen PortD (für 8 Bit Daten I/O) und PortE (für die Steuersignale) haben, PIC16F87x wenn ich mich recht erinnere. Damit können diese Teile direkt an einen Systembus angeschlossen werden. Versuche mal sowas bei anderen µC zu finden. So, dieser Thread ist zwar ganz interessant, aber auch ziemlich gespenstisch. Nostalgie scheint in zu sein. Ich hätte da jedoch ganz andere Vorschläge, nämlich den beklagenswerten Wissensstand der Jüngeren zu aktueller Hardware zu verbessern, indem man sich um den Aufbau von Rechner- oder Controller-Architekturen - nun ja von benutzbarer Hardware mit aktuellen Bauteilen kümmert. Also kein Board mit nem Z80 und CP/M drauf, sondern z.B. eines mit nem Cortex M4 drauf, WVGA TFT Display dran, Tastatur und Maus und Drehgeber und Tipptasten und mit nem CODEC und so weiter und mit nem Monitorprogramm drauf, das von SD-Karte Apps laden und ausführen kann. Aber das Ganze mit leicht verständlichem Quellcode, so daß Neulinge sich dort abgucken können, wie man dies und das so macht. Kurzum so etwas Ähnliches wie eine drastisch modernisierte Art Lernbetty. Sowas hätte einen echten Sinn, nämlich den Sinn der Bildung unseres Nachwuchses. Und es würde auch sowas wie Spaß machen. Also! W.S.
W.S. schrieb: > So, dieser Thread ist zwar ganz interessant, aber auch ziemlich > gespenstisch. Nostalgie scheint in zu sein. Was am Titel "Retro Fieber" hast du grad nicht verstanden? > sondern z.B. eines mit nem Cortex M4 drauf Als Empfehlung für "Retro" etwas befremdlich. Oder ist bei dir alles, was älter als eine Woche ist, schon Retro?
:
Bearbeitet durch User
W.S. schrieb: > Sowas hätte einen echten Sinn, nämlich den Sinn der Bildung unseres > Nachwuchses. Und es würde auch sowas wie Spaß machen. Na, solche Boards sehen aber sehr gruelig aus, wenn man "from scratch" loslegen will, d.h. mit einer leeren Editorseite. Außerdem habe ich gerade wieder die Erfarung gemacht, dass die "Cracks" es gar nicht wollen, dass "Expertenwissen" das der breiten Masse wird. Wo kämen wir denn da hin, wenn alles nicht "hochkopliziert" wäre, so dass es jeder versteht? Dann wären die Herren Experde ja überflüssig. Lach nicht, deswegen hatte ich eine handfeste Auseindanersetzung mit einem Ex Kollegen. Da ich im selbst verfallen bin ist der Raspeberry Pi das beste Lerngerät, wobei allerdings wohl keiner sein Innenleben vesteht, denn wer kann schon Treibr für eine GBU schreiben? Solche System sind ohne abstrahierte Hardware witzlos. Ach ja, um Holm noch eines vor den Latz zu geben.... PICs hatten schon immer Banking und seit ca 1996 benutzt mana auch C Compiler :-) Ich habe seit 1997 mit PICs gearbeitet, abertausende Zeilen Code, viele Dutzend Designs für die Industrie gemacht, ohne jemals auch nur eine einzige Zeile Asm geschrieben zu haben :-) Nie, nie! Bäh, das ist bei PICs ja wie das Gestammel eines Kleinkindes, dieser RISC Asm. Mit 35 Wörtern die Welt erklären zu wollen. Und es wurden tausende Geräte verkauft .... also so viel Retro muss es nicht sein. AVR hat mich nie interessiert, einfach weil alle es machten. Die PICS können alles was ein AVR auch kann und was sie mehr können braucht man eh nicht.
Christian J. schrieb: > gerade wieder die Erfarung gemacht, dass die "Cracks" es gar nicht > wollen, dass "Expertenwissen" das der breiten Masse wird. Weil du etwas Kritik angesichts deiner Aussage bezogen hast, dass der Z80 SIO für die breite Masse viel zu komplex sei? Wenn das alles ist - Code für SIO mit Interrupt anbei, entstanden in den 80ern. Der "STI" Kram gehört nicht zum SIO.
:
Bearbeitet durch User
W.S. schrieb: > Also kein Board mit nem Z80 und CP/M drauf, sondern z.B. eines mit nem > Cortex M4 drauf, WVGA TFT Display dran, Tastatur und Maus und Drehgeber > und Tipptasten und mit nem CODEC und so weiter und mit nem > Monitorprogramm drauf, das von SD-Karte Apps laden und ausführen kann. Grundlagenwissen vermittelst du der beklagenswerten Jugend m.E. besser mit einem Z80-System als mit den komplexen, aktuellen Controllern. Während beim Z80 die einzelnen Bausteine wie CPU, Busse, Decodierer, RAM, ROM, Timer, SIO, PIO usw., sowie deren Verbindung umtereinander noch mit bloßem Auge sichtbar und quasi "zum Anfassen" sind, verschwindet dies alles bei den µCs unter einem schwarzen Klecks. Wenn man die einzelnen Leitungen der Busse noch zusätzlich mit LEDs illuminiert und die Taktrate auf fürs menschliche Auge nachvollziehbare Frequenzen runterschraubt, kann der wißbegierige IT-Jünger den Bits sogar bei der Arbeit zuschauen. Ein Z80 ist wie der Lanz Bulldog, bei dem es weder Steuergeräte noch Turbolader oder ABS gibt. Nur nackte, primitive aber nachvollziehbare Technik.
IMHO muss man beim Lernen noch weiter zurück gehen. Anfangen bei gattern, weiter zu flipflops, Zählern, Registern. parallel programmieren am pc. Erst dann mit Prozessoren und controllern...
Harald schrieb: > IMHO muss man beim Lernen noch weiter zurück gehen. Anfangen bei > gattern, weiter zu flipflops, Zählern, Registern. parallel programmieren > am pc. Erst dann mit Prozessoren und controllern... Nein.... in vielleicht 30,50 Jahren wird unsere Technik so komplex sein, wie die auf dem Raumschiff Enterprise. Displays in 3D aus Glas, Computer die dir zuhören, Computer die Teile von sich selbst neu konfigurieren können (gibt es ja teilweise schon) usw, usw. Die Elementartechnik wird ganz und völlig in Bausteinen oder Libraries verschwinden. Du kannst nicht immer weiter hinauf wollen und alles was unten ist noch wissen oder verstehen wollen. Ich habe an der Uni noch Karnogh Diagramme gehabt, Minterm, Maxterm und aus deren Lösungen Gatterlogiken gemacht. Ist längst aus dem Lehrstoff verschwunden. Mein Sohn geht mit einem Smrtphone und Computer wie selbstverständlich um mit seinen 10 Jahren aber er hat keine Ahnung wie er fnktioniert. Und es interessiere ihn auch nicht sagte er, "hauptsache es funktioniert".
Christian J. schrieb: > in vielleicht 30,50 Jahren wird unsere Technik so komplex sein, > wie die auf dem Raumschiff Enterprise. Displays in 3D aus Glas, Computer > die dir zuhören, Computer die Teile von sich selbst neu konfigurieren > können (gibt es ja teilweise schon) usw, usw. Hmm, das führt irgendwann dorthin: http://de.wikipedia.org/wiki/Technologische_Singularit%C3%A4t Der Mensch wird dann allerdings überflüssig, weil er die Entwicklung nur hemmt.
Christian J. schrieb: > W.S. schrieb: > > Ach ja, um Holm noch eines vor den Latz zu geben.... PICs hatten schon > immer Banking und seit ca 1996 benutzt mana auch C Compiler :-) Ich habe Mach doch. Ich schrieb das ich kein Problem mit den Dingern habe wenn ich mit den Dingern arbeiten muß. Ich komme nur nicht selbst auf die Idee mir die Rübe so zu verkorksen das ich auf steinalte GI Architekturen abfahren muß. Wenn Du Dir die Rute über den Arsch ziehen willst, bitteschön. Auch andere Mütter haben schöne Töchter, mich zieht es da eher in die Ecke Coldfire und Konsorten oder aber MSP430. Das nur um Dir eine vor Deinen Latz zurück zu geben. Gruß, HOlm
Christian J. schrieb: > Mein Sohn geht mit einem Smrtphone und Computer wie selbstverständlich > um mit seinen 10 Jahren aber er hat keine Ahnung wie er fnktioniert. Und > es interessiere ihn auch nicht sagte er, "hauptsache es funktioniert". Ja, diese Sorte Nachwuchs kenne ich, sinngemäss: "Papi, kannst du mal vorbei kommen (halb Deutschland liegt dazwischen). Der Handtuchhalter bleibt nicht an der Wand hängen. Im Computerspiel tut er das immer."
:
Bearbeitet durch User
A. K. schrieb: > Christian J. schrieb: >> gerade wieder die Erfarung gemacht, dass die "Cracks" es gar nicht >> wollen, dass "Expertenwissen" das der breiten Masse wird. > > Weil du etwas Kritik angesichts deiner Aussage bezogen hast, dass der > Z80 SIO für die breite Masse viel zu komplex sei? Wenn das alles ist - > Code für SIO mit Interrupt anbei, entstanden in den 80ern. Der "STI" > Kram gehört nicht zum SIO. Was ist denn das für ein Code? Leider ist der Source wenig kommentert, so dass man zb nicht weiss welche Register bei welcher Routine mit was gefüllt sein müssen und welche Ausgabe eine Routine erzeugt. Ist das eine Makrosprache des Assemblers? /* start output sequence */ begseq:: { @imra = @imra & ~0x10; /* keyboard int off */ } /* end output sequence */ endseq:: { @imra = @imra | 0x10; /* keyboard int on */ if (xreq) { /* xoff request pending */ putnw (A=xreq;); xreq = 0; } }
Christian J. schrieb: > Ist das eine Makrosprache des Assemblers? Nö. Trivialcompiler Marke Eigenbau. Besseres Beispiel anbei - .PLZ der Quellcode, .s der resultierende Assemblercode. War auch nicht für 1:1 Übernahme gedacht. Sondern um zu zeigen, dass der Umgang damit kein Hexenwerk ist.
:
Bearbeitet durch User
Hallo Grundlagen schaden aber nicht. Die Mathematik bis zum ABI ist auch schon "uralt". Mir hilft es jedenfalls mit dem Wissen aus 6502, Z80 und 68k Zeiten aktuelle System zu programmieren.
Christian J. schrieb: > Nein.... in vielleicht 30,50 Jahren wird unsere Technik so komplex sein, > wie die auf dem Raumschiff Enterprise. Displays in 3D aus Glas, Computer > die dir zuhören, Computer die Teile von sich selbst neu konfigurieren > können (gibt es ja teilweise schon) usw, usw. Die Elementartechnik wird > ganz und völlig in Bausteinen oder Libraries verschwinden. Du kannst > nicht immer weiter hinauf wollen und alles was unten ist noch wissen > oder verstehen wollen. Ich habe an der Uni noch Karnogh Diagramme > gehabt, Minterm, Maxterm und aus deren Lösungen Gatterlogiken gemacht. > Ist längst aus dem Lehrstoff verschwunden. Naja, ich stelle nur immer wieder - gerade hier im Forum - fest, dass gerade bei den Hobbyanwendern, wo auch ich mich dazuzähle, ein extremer Mangel an Grundwissen herrscht. Das Problem ist IMHO nur das, dass euch, die beruflich in dieser Branche unterwegs seid, die Grundlagen so vertraut und in Fleisch und Blut über gegangen sind, dass euch gar nicht auffällt, dass die teilweise blöden Fragen daher rühren. Ich arbeite zwar in einer ganz anderen Branche, aber mir fällt das genauso auf. Die Grundlagen sind halt jedem in seinem Fachgebeit selbtverständlich. Btw wenn die Programmierung von Controllern soweit abstrahiert wird, dass es jeder kann; wozu braucht man dann euch Spezialisten noch? Was die Studienpläne betrifft: wer sagt, dass das so sinnvoll ist. Auswirkungen der aktuellen Lehrpläne werden sich erst zeigen. > Mein Sohn geht mit einem Smrtphone und Computer wie selbstverständlich > um mit seinen 10 Jahren aber er hat keine Ahnung wie er fnktioniert. Und > es interessiere ihn auch nicht sagte er, "hauptsache es funktioniert". Das hat mit der Programmierung von Controllern etc. nun so gar nichts zu tun, sondern ist ein gesellschaftlicher Fakt. Anwenden ist nicht gleich Implementieren. Ich wollte den Thread zwar nicht OT führen, aber andererseits ist's eh schon egal, wenn man hier mitliest...
Icke ®. schrieb: > Christian J. schrieb: >> in vielleicht 30,50 Jahren wird unsere Technik so komplex sein, >> wie die auf dem Raumschiff Enterprise. Displays in 3D aus Glas, Computer >> die dir zuhören, Computer die Teile von sich selbst neu konfigurieren >> können (gibt es ja teilweise schon) usw, usw. > > Hmm, das führt irgendwann dorthin: > > http://de.wikipedia.org/wiki/Technologische_Singularit%C3%A4t > > Der Mensch wird dann allerdings überflüssig, weil er die Entwicklung nur > hemmt. Wenn du dir mal den genialen Jules Verne durchgelesen hast, der um 1828 geboren wurde, da liest du wie er viele Dinge bereits vorausah, die heute Normal sind. Noch sind wir nicht soweit, dass ein Haufen Silizium diese 2kg graue Pampe ersetzen kann, die als Analogcomputer hinter meiner Brille arbeitet. Im Übrigen wird diese Thematik auch in einigen Filmen erwähnt, zb "Flucht ins 21.te Jahrhundert", oder "Die Zeitmaschine" wo die "Söhne und Töchter" nicht mehr das Wissen besassen was ihre Väter geschaffen hatten, um die Maschinen und alles andere in Gang zu halten. Aber das hat jetzt nichts mit dem Z80 zu tun...
A. K. schrieb: > Nö. Trivialcompiler Marke Eigenbau. Sorry, übersteigt meine Fähigkeiten einen "Trivialcompiler" zu schreiben. Bin ich zu blöde für. Anbei mal der Quelltext eines Virus, den ich 1995 geschrieben habe, sieht irgendwie "anders" aus, mein Asm-Stil.
Harald Nagy schrieb: > Btw wenn die Programmierung von Controllern soweit abstrahiert wird, > dass es jeder kann; wozu braucht man dann euch Spezialisten noch? Diese Abstrahierung wird auf allen Fronten aber voran getrieben! Du sollst schnell Erfolg haben, auf bewährtes aufsetzen können und nicht das Rad ewig neu erfinden müssen. Nehmen wir die A20 CPU, die einen ARM Core hat so merke ich, je länger ich mich damit befasse, dass es UNMÖGLICH ist für eine Einzelperson diese CPU , besser "system on chip" zu verstehen, gschweige denn da noch Asm zu programmieren. Du würdest jahre brauchen überhaupt einen Grundstock zu haben. Erst mit Linux drauf wird sie zu einem nutzbaren System.
Christian J. schrieb: > Sorry, übersteigt meine Fähigkeiten einen "Trivialcompiler" zu > schreiben. Bin ich zu blöde für. Kein Drama. Rund 2400 Zeilen, die Hälfte davon Yacc.
:
Bearbeitet durch User
A. K. schrieb: > Christian J. schrieb: >> Sorry, übersteigt meine Fähigkeiten einen "Trivialcompiler" zu >> schreiben. Bin ich zu blöde für. > > Kein Drama. Rund 2400 Zeilen, die Hälfte davon Yacc. Ok, ok. Ich erinnere mich schwach an Begriffe wie Keller-Automat, verkettete Bäume für die Strukuren, Parser usw. usw. Aber das sei denen vorbehalten die Informatik studiert haben, denen jeden Abend der Kopf explodiert und nicht jenen, die sie anwenden wollen :-)
Christian J. schrieb: > und nicht jenen, die sie anwenden wollen :-) Eben. Den Automaten des Parsers erzeugte Yacc. Ich war bloss der Anwender von Yacc, indem ich die Parser-Spezifikation schrieb (sowas wie BNF) und mit dem resultierenden Z80-Code verzierte. Das Ergebnis erreichte die Effizienz von Assembler, war aber viel besser lesbar. Einen Small C Compiler für 8080 (Z80?) gab es damals zwar wohl schon, aber dessen Ergebnis war schaurig.
:
Bearbeitet durch User
A. K. schrieb: > Christian J. schrieb: >> und nicht jenen, die sie anwenden wollen :-) > > Eben. Den Automaten erzeugt Yacc. Ich war bloss dessen Anwender, indem > ich die Spezifikation für Yacc schrieb (sowas wie BNF). Das Ergebnis > erreichte die Effizienz von Assembler, war aber viel besser lesbar. Darf ich das so verstehen, dass du nur die Syntax definierst und Yacc erzeugt das für dich? Ich bin da Laie aber ein "LDA A,$05" für den 6502, Lade Accu mit 0x05 muss ja übersetzt werden in A0 09 05, wobei die 09 nur für die direkte Adressierung steht, es aber noch einie andere wie indirekt, indiziert indirekt, zeropage usw gibt. Wie bringt man diese Regeln Yacc bei.
Christian J. schrieb: > Darf ich das so verstehen, dass du nur die Syntax definierst und Yacc > erzeugt das für dich? Ich bin da Laie aber So ungefähr. Siehe Anhang.
A. K. schrieb: > Christian J. schrieb: >> Darf ich das so verstehen, dass du nur die Syntax definierst und Yacc >> erzeugt das für dich? Ich bin da Laie aber > > So ungefähr. Siehe Anhang. Ok, andere Welt ... verstehe nicht eine Zeile davon. Ist aber hier verständlich beschrieben: http://www.eike-meinders.de/Yacc
Christian J. schrieb: > Woebi ich nach einmal drüber schlafen jetzt soweit bin, dass ich > dem 6850 die INT Leitung abklemmen werde und etl Polling benutzen werde, > da er sowieso nix zu tun hat solange er auf was wartet. Und nochmal meine Frage: Matthias Sch. schrieb: > Warum nimmste nicht den NMI für deinen 6850?
Matthias Sch. schrieb: > Christian J. schrieb: >> Woebi ich nach einmal drüber schlafen jetzt soweit bin, dass ich >> dem 6850 die INT Leitung abklemmen werde und etl Polling benutzen werde, >> da er sowieso nix zu tun hat solange er auf was wartet. > > Und nochmal meine Frage: > > Matthias Sch. schrieb: >> Warum nimmste nicht den NMI für deinen 6850? ..und warum besorgst Du erst einen TTL zu USB serial Wandler mit RTS/CTS wenn Du die signale gar nicht brauchst? Gruß, Holm
Matthias Sch. schrieb: > Christian J. schrieb: >> Woebi ich nach einmal drüber schlafen jetzt soweit bin, dass ich >> dem 6850 die INT Leitung abklemmen werde und etl Polling benutzen werde, >> da er sowieso nix zu tun hat solange er auf was wartet. > > Und nochmal meine Frage: > > Matthias Sch. schrieb: >> Warum nimmste nicht den NMI für deinen 6850? Handbuch: NMI. Nonmaskable Interrupt (input, negative edge-triggered). NMI contains a higher priority than INT. NMI is always recognized at the end of the current instruction, independent of the status of the interrupt enable flip-flop, and automatically forces the CPU to restart at location 0066h. The Z80 CPU contains two interrupt inputs: a software maskable interrupt (INT) and a nonmaskable interrupt (NMI). The nonmaskable interrupt cannot be disabled by the programmer and is accepted when a peripheral device requests it. This interrupt is generally reserved for important functions that can be enabled or disabled selectively by the programmer. This routine allows the programmer to disable the interrupt during periods when the program contains timing constraints that wont allow interrupt. In the Z80 CPU, there is an interrupt enable flip-flop (IFF) that is set or reset by the programmer using the Enable Interrupt (EI) and Disable Interrupt (DI) instructions. When the IFF is reset, an interrupt cannot be accepted by the CPU. ## ----------------- Moin, Da noch nix läuft kann ich auch noch nichts ausprobieren. Der NMI ist nicht maskierbar, d.h. er kann mir dazwischen hauen, wenn ein anderer Interrupt aktiv ist, zb einer der Timer oder der PIO (ja, ich nutze sie doch :) und ganz schlimm auch dann wenn ich grad in einem solchen INT die Register noch nicht auf dem Stack habe. Ich erinnere mich schwach, dass ein EI in einer INT Routine vorne böse Folgen haben kann, zb kann er sich bei pegel getriggerten INT (was der INT zu sein scheint) dann rekursiv aufhängen. Fragen: 1. Legt der Z80 die Retrun Adresse dabei auf dem Stack ab, so dass er zurückkehren kann? Mir liest sich das so als wenn das wie ein Warmstart Reset wäre "restart", d h. er springt nach 0x0066 und macht da einfach weiter. 2. Beherrscht die CPU nested interrupts, wenn ich die Register im NMI IRQ auf dem Stack rette wenn er grad aus einem 0038+x Timer INT ausgerissen wird? 3. Hier ist doch ein Widerspruch drin: "The nonmaskable interrupt cannot be disabled by the programmer and is accepted when a peripheral device requests it. This interrupt is generally reserved for important functions that can be enabled or disabled selectively by the programmer." Also, nun enabled oder disabled? Ich gebe zu dass dieses Handbuch teilweise etwas verwirrend geschrieben ist, auch die Bedeutung der beiden Flags IFF1 und IFF2 ist mir nicht ganz klar. Diese sind nicht im Status Register, sondern werden durch Befehle gesetzt und gelöscht. @Holm: Weil ich sie dann habe wenn ich sie brauche und wenn nicht, dann benutze ich sie nicht. Ganz einfach, oder? An 2,95 Euro soll es nicht scheitern. An USB Konvertern sind solche Leitungen ja sonst "out of date".
Die Bilder stammen aus Kieser/Meder[1]. Ich könnte mir vorstellen, daß das Buch für Dich etwas wäre. Gerade habe ich gesehen, daß auch die SIO darin ausfürhlich erklärt ist. > 3. Hier ist doch ein Widerspruch drin: Der NMI kann durch den Programmierer nicht disabled werden, die Funktionen aber schon. Kein Widerspruch. [1] http://www.zvab.com/advancedSearch.do?title=Mikroprozessortechnik+%3A+Aufbau+u&author=Kieser
Leo C. schrieb: > Die Bilder stammen aus Kieser/Meder[1]. Ich könnte mir vorstellen, daß > das Buch für Dich etwas wäre. Das Buch ist wirklich gut. Sehr ausführlich und verständlich geschrieben. Ich habe seinerzeit allein damit den Einstieg in die Mikroprozessorwelt geschafft, obwohl ich keinerlei Vorkenntnisse besaß.
Leo C. schrieb: > Der NMI kann durch den Programmierer nicht disabled werden, die > Funktionen aber schon. Kein Widerspruch. Das Buch ist ja super, gesehen hatte ich es schon bei amazon. Ich habe aber den Zaks bestellt. Habe einige DDR Mathe und Technik Bücher, weil die vor allem in Deutsch geschrieben sind. Die Funktionen? Also es kann nicht verhindert werden, dass 66 angesprungen wird, richtig? Was sind denn die Funktionen des NMI? Natürlich kann ich eine ISR sperren per Softfware, so dass sie gleich wieder verlassen wird.
Schaut Euch mal das Kiwi-Projekt von Simon Ferber an: https://www.ist-schlau.de/ Ein ziemlich beeindruckender Selbstaucomputer auf 68K-Basis. Er hat das in relativ kurzer Zeit beeindruckend weit gebracht, finde ich.
> Da noch nix läuft kann ich auch noch nichts ausprobieren. Der NMI ist > nicht maskierbar, d.h. er kann mir dazwischen hauen, wenn ein anderer > Interrupt aktiv ist, zb einer der Timer oder der PIO (ja, ich nutze sie > doch :) und ganz schlimm auch dann wenn ich grad in einem solchen INT > die Register noch nicht auf dem Stack habe. Wo ist das Problem? Vor und nach dem NMI sind die Register doch gleich. Du hast eine maximale Rekursionstiefe von 3 (Anwendung, Interrupt, NMI), für die du ausreichend Stack bereitstellen musst. Und für die Interrupts wurde der zweite Registersatz mal definiert. > 1. Legt der Z80 die Retrun Adresse dabei auf dem Stack ab, so dass er > zurückkehren kann? Ja, denn sonst könntest du nie aus einem Interrupt oder NMI zurückkehren. > 2. Beherrscht die CPU nested interrupts, wenn ich die Register im NMI > IRQ auf dem Stack rette wenn er grad aus einem 0038+x Timer INT > ausgerissen wird? Wenn du in einer ISR "EI" ausführst, dann kannst du auch Interrupts verschachteln. Ein NMI wird aber normalerweise nicht (bzw. nur durch einen NMI) unterbrochen.
1 | void nmi(void) __interrupt __critical |
2 | {
|
3 | static char flag_nmi = 0; |
4 | if(flag_nmi) return; |
5 | |
6 | flag_nmi = 1; |
7 | /* hier der Code */
|
8 | flag_nmi = 0; |
9 | return; |
10 | }
|
> 3. Hier ist doch ein Widerspruch drin: > > "The nonmaskable interrupt cannot be disabled by the programmer and is > accepted when a peripheral device requests it. This interrupt is > generally reserved for important functions that can be enabled or > disabled selectively by the programmer." "Dieser Interrupt wird normalerweise für wichtige Funktionen reserviert, die vom Programmierer gezielt ein- oder ausgeschaltet werden können." Nicht für andere Funktionen. ;-) > Also, nun enabled oder disabled? Ich gebe zu dass dieses Handbuch > teilweise etwas verwirrend geschrieben ist, auch die Bedeutung der > beiden Flags IFF1 und IFF2 ist mir nicht ganz klar. > Diese sind nicht im Status Register, sondern werden durch Befehle > gesetzt und gelöscht. Diese Flags speichern den Zustand des I-Flags, wenn ein NMI eintritt. Ohne NMIs sind IFF1 und IFF2 immer gleich, und mehr kannst du mit den Befehlen auch nicht beeinflussen.
Christian J. schrieb: > Was sind denn die Funktionen des NMI? Nun, es wird 0066h angesprungen, wenn der NMI low wird - mehr passiert erstmal nicht. Am besten fragst du dann gleich ACIA im 6850 ab, löschst die IRQ Anforderung und behandelst dann dein Ereignis. Du musst natürlich nur die Register retten, die deine Routine zermanschen würde. Du könntest auch eine kleine Hardware (Steckbrücke) vorsehen, damit du den NMI aussperren kannst. Die Funktion des NMI (und so ist der Zilog Satz vermutlich zu verstehen) werden normalerweise eben für SingleStep, Breakpoints usw. verwendet, das ist aber kein Zwang und der NMI ist ein ganz normaler IRQ mit hoher Priorität. Solange du im 6850 keine IRQ Bits setzt, wird da auch nichts ausgelöst. Denke nur dran, das der 6850 eine OpenDrain IRQ Ausgang hat und der Z80 keinen internen Pullup. Da muss also ein externer mit ran.
Draco schrieb: > Schaut Euch mal das Kiwi-Projekt von Simon Ferber an: > https://www.ist-schlau.de/ > Ein ziemlich beeindruckender Selbstaucomputer auf 68K-Basis. Er hat das > in relativ kurzer Zeit beeindruckend weit gebracht, finde ich. Das erfordert auch deutlich mehr kenntnisse und Zeit als Normalbürger zur Verfügung haben und FPGA hört es bei mir eh auf und Videoprozessor, Audio usw. Danke für die wertvollen Infos! Kapiert! Ich sehe eh schon, dass ich den Monitor selbst schreiben muss, bin zu weit weg von allem was auf Grants Page zu sehen ist und mache auch die Decodierung anders als er mit 74138ern. Schätze aber mal, dass ich den basic Interpeter auch so hineinkriege. Also kriegt der 6850 den NMI spendiert, was natürlich auch heisst, dass wenn der PC spricht der Z80 zuhören muss,ob es im passt oder nicht, es sei denn ich disabel die INT im 6850, zb wenn der Z80 sein Programm gestartet hat. Meine Frage bezog sich darauf dass der NMI mitten in einen INT reinquatschen darf, also während die ISR grad abgearbeitet wird.
1 | void nmi(void) __interrupt __critical |
2 | {
|
3 | static char flag_nmi = 0; |
4 | if(flag_nmi) return; |
5 | |
6 | flag_nmi = 1; |
7 | /* hier der Code */
|
8 | flag_nmi = 0; |
9 | return; |
10 | }
|
Du bist ein Schatz! Da ich eh vorhabe den Monitor in C zu schreiben mit etwas inline asm. Welcher Compiler ist das? SDCC? Genau das habe ich gesucht, void nmi(void) __interrupt __critical ist doch sicher ein keyword, damit er eine INT Routine anlegt an der richtigen Stelle, oder? Legt der Compiler auch die Vektortabelle im ROM an und lässt sich dazu bewegen zu einer RAM Routine zu springen. Wohl nicht, oder? Mir schwirren da so Ideen durch den Kopf das ROM wegzublenden, so dass die RAM Adressen auf 0000 rutschen nachdem er ein Programm empfangen hat aber weiss nicht wie ich das realisieren soll. Im Ram müsste dann ja eine identische Kopie der Zeropage liegen, also auch die INT Einsprünge und dere ń Zeiger auf Userroutinen. Das ROM könnte sich ja erst dorthin kopieren, dann den Usercode drüber an der richtigen Stelle und ZACK, schaltet es sich weg und als letzte Aktion muss der Pogrammzeiger dann auf das userprogramm gerichtet werden. Die Adressierung ROM/RAM unterscheidet sich ja nur durch die A15 Leitung, 1 = ROM, 0 = RAM bei mir. Oder spinne ich zu weit? 8255 vs. Z80 PIO: Schaut man sich die Bausteine an fällt auf, dass sie scheinbar für die damaligen peripheriegeräte entworfen wurden. heute hängt ja alles am seriellen USB Bus dran, was früher LPT und Centronics waren. Bei allen beiden scheint es nicht möglich, das was heute normal ist, zb einen Port bitweise als Eingang und Ausgang zu schalten, also Bit 0 = In, Bit 1 = Out, Bit 3 = Tristate usw.
Christian J. schrieb: > beiden scheint es nicht möglich, das was heute normal ist, zb einen Port > bitweise als Eingang und Ausgang zu schalten, also Bit 0 = In, Bit 1 = > Out, Bit 3 = Tristate usw. Beim 8255 geht das wirklich nicht, weil dessen Richtung nur portweise schaltbar ist. Beim Z80 PIO lässt sich jedoch die Richtung sehr wohl pinweise steuern. Tristate ist überflüssig, weil von aussen nicht von einem Input unterscheidbar. Open drain lässt sich wie bei AVRs über die Richtung steuern.
:
Bearbeitet durch User
Christian J. schrieb: > Meine Frage bezog sich darauf dass der NMI mitten in einen INT > reinquatschen darf, also während die ISR grad abgearbeitet wird. Ja. Und wo ist da das Problem? ;-) Der NMI kann durch einen weiteren NMI unterbrochen werden, davor musst du dich schützen. Ob die CPU gerade einen INT abgehandelt hat oder nicht, kann dir relativ egal sein: Dafür sind IFF1 und IFF2 da. > Welcher Compiler ist das? SDCC? Ja, aber ungetestet. Siehe SDCC-Manual. > Genau das habe ich gesucht, void nmi(void) __interrupt __critical ist > doch sicher ein keyword, damit er eine INT Routine anlegt an der > richtigen Stelle, oder? Nein. Siehe SDCC-Manual. NMI-Handler: "void nmi(void) __interrupt __critical" INT-Handler: "void int(void) __interrupt(1) __critical" > Legt der Compiler auch die Vektortabelle im ROM an und lässt sich dazu > bewegen zu einer RAM Routine zu springen. Wohl nicht, oder? Nicht für Z80, weil das vom Modus abhängt. Siehe SDCC-Manual. ;-) > Mir schwirren da so Ideen durch den Kopf das ROM wegzublenden, so dass > die RAM Adressen auf 0000 rutschen nachdem er ein Programm empfangen hat > aber weiss nicht wie ich das realisieren soll. Die Adressierung ROM/RAM > unterscheidet sich ja nur durch die A15 Leitung, 1 = ROM, 0 = RAM bei > mir. Wenn A15 == 1 ins ROM führt, dann sind das die oberen 32 KB. Da musst du erstmal hinkommen! Teilst du den Adressraum in zwei Hälften, je 32 KB ROM und RAM? Dann linke deine Programme an die richtigen Adressen und lass gut sein.
Zu den etwas selteren aber praktischen Bausteinen gehörte der Z80 STI, den Mostek einbrachte. 8 I/O Pins mit flankengetriggerten Interrupts, 4 Timer und eine UART. An diesem Baustein erkennt man recht gut, wozu die Interrupt-Vektoren gut waren. Denn davon hatte der immerhin 16. http://www.cpcwiki.eu/index.php/Z80-STI http://www.ebay.de/itm/1-Stuck-1-pieces-MK3801N04-Z80-STI-Serial-Timer-Interrupt-Contr-DIP40-NEU-NEW-/271339278196?pt=Bauteile&hash=item3f2d14cf74
:
Bearbeitet durch User
Harald schrieb: > Es gäbe auch noch das All-in-one Paket Z80 KIO.... Klar, aber so richtig Retro ist der Klops von anno 2002 ja nicht mehr. Retro Board mit LQFP100, also nee, da kannste den Kram auch gleich im FPGA versenken. ;-)
:
Bearbeitet durch User
A. K. schrieb: > Harald schrieb: >> Es gäbe auch noch das All-in-one Paket Z80 KIO.... > > Klar, aber so richtig Retro ist der Klops von anno 2002 ja nicht mehr. > Retro Board mit LQFP100, also nee, da kannste den Kram auch gleich im > FPGA versenken. ;-) PLCC84, ideal zum Verdrahten am Lochraster....
Moinse! Ist ja genial...... den Z80 STI habe ich mir direkt gekauft, spart geich 3 fette 40 Pinner ein! Ok..... ich könnte auch alles einsparen und einen Attiny84 einsam auf die Platine setzen :-)))) Der PLCC 84 "Klops" macht das Retro Design leider kaputt, das Auge isst mit und die kantige Ästehtik eines PLCC entspricht leider nicht dem Auge des Künstlers. PLCC auf Lochraster verdahtenn ist so als fährt man in einer Baustelle auf der Autobahn auf linken 2,50m Spur hat rechts neben sich die LKW. Nee... Ich teile den Adressraum üpbrigens in 8kb ROM und 56 KB Ram mit einem 128K RAM Baustein mit 30 Pins. Es wächst ...... danke an euch alle ! Supi! Gruss, Christian
Harald Nagy schrieb: > Naja, ich stelle nur immer wieder - gerade hier im Forum - fest, dass > gerade bei den Hobbyanwendern, wo auch ich mich dazuzähle, ein extremer > Mangel an Grundwissen herrscht. > Das Problem ist IMHO nur das, dass euch, die beruflich in dieser Branche > unterwegs seid, die Grundlagen so vertraut und in Fleisch und Blut über > gegangen sind, dass euch gar nicht auffällt, dass die teilweise blöden > Fragen daher rühren. Da täuschest du dich aber ganz gewaltig. Ich kenne genug junge Leute, die mit ihrem frisch erworbenen Master in der Tasche in die professionelle Elektronikentwicklung einsteigen wollen und die zwar einen Linux-Rechner benutzen können und geübt sind im Eingeben ihres Paßwortes und dem Benutzen der Kommandozeile, aber bereits den Sinn eines treiberinternen Ringpuffers für serielles I/O nicht zu erkennen vermögen und auch nicht verstehen können, warum ein Hintergrund-Monitor die empfangenen Zeichen echot, ebenso nicht wie man eine Leiterplatte designt und und und. Ich erwarte ja keine 100 Jahre Berufserfahrung von einem jungen Menschen, aber ich erwarte ein geschultes Denkvermögen und Auffassungsgabe - und da gibt es ganz häufig heftige Defizite. Sachlich interessierte Hobbyisten - sprich Amateure, zu deutsch "Liebhaber" obwohl das ne andere Assoziation mit sich bringt :-) kennen sich recht häufig viel besser aus als die sogenannten Profis. Nebenbei gesagt heißt "Profi" ja nur, daß einer das Thema nicht aus Liebe zum Thema beackert, sondern nur schnöd seinen Lebensunterhalt damit verdienen will. Von besserem Wissen ist da garnix gesagt. W.S.
PS. Zum SDCC: Es scheint doch zu gehen, müsste mir das mal im Am Listing anschauen, wenn ich dazu komme, was er dann produziert. Den Monitor in C zu schreiben macht mir deutlich mehr Spass. 3.10.4 Z80 Interrupt Service Routines The Z80 uses several different methods for determining the correct interrupt vector depending on the hardware implementation. Therefore, SDCC ignores the optional interrupt number and does not attempt to generate an interrupt vector table. By default, SDCC generates code for a maskable interrupt, which uses a RETI instruction to return from the interrupt. To write an interrupt handler for the non-maskable interrupt, which needs a RETN instruction instead, add the __critical keyword: void nmi_isr (void) __critical __interrupt { ... } However if you need to create a non-interruptable interrupt service routine you would also req
W.S. schrieb: > aber > bereits den Sinn eines treiberinternen Ringpuffers für serielles I/O > nicht zu erkennen vermögen und auch nicht verstehen können, warum ein > Hintergrund-Monitor die empfangenen Zeichen echot, ebenso nicht wie man > eine Leiterplatte designt und und und. Ich kann dir versichern, dass es in einer Firma für die ich früher mal gearbeitet habe - bevor ich den Kanal voll hatte - "Profis" gibt, zumindest halten die sich für solchen, die irgendwann mit 50 getrieben durch den Markt quer einsteigen mussten in uC und dabei Sachen produzieren, die einem die Haare zu Berge stehen lassen. Keine Ahnung was eine Statusmaschine oder ein Keller-Stack ist, nicht mal den Begriff gehört, Was ist ein Baum, was ein Zeiger - keine Ahnung von grundlegenden Programmiertechniken und Softwareplanung.... alles strotz vor globalen Variablen, die kreuz und quer verändert werden, einfach nur an den Rechner setzen und Code runtertippen, wo jede Variable i,jk,n heisst, jede Funtion func1,func2, func3 und kein Mensch mehr durchdblickt. Aber mit OP's, Transistoren und Dioden kennen sie sich aus..... darum sind sie Profis. Oder ein Bewerbungsgespräch 2004, wo ich zu hören bekam "Wir benutzen 8051 und programmieren alles in Assembler!", FPGA? CPLD? Wozu das! Warum? Weil der Entwicklungsleiter nichts anderes konnte und Angst hatte von einem Jüngeren "überflügelt" zu werden. Nicht nur über die Jungen kann man sich aufregen, da wir alle mal so waren, sondern ebenso über die Älteren die als Bremsklotz wirken, bloss weil die Panik haben entbehrlich zu werden oder etwas neues lernen müssen. Diese Mentalität hasse ich aber sie ist weit verbreitet. > ebenso nicht wie man eine Leiterplatte designt und und und Man sollte es als Ingenieur mal gemacht haben aber das ist fast überall Aufgabe von technikern und Layouter, die das besser und schneller machen und vor allem wissen wie es produziert werden kann. Hut ab vor manchen die 6 Lagen ohne Autorouter routen können! Es gibt ne Menge Funkamateure, die jeden Master Ingenieur in die Tasche stecken! Mein erster Chef hatte nie studiert und war ein Genie in Sachen Konstruktion am CAD System. Alles DIY .... Motivation ist durch nichts zu ersetzen.
Christian J. schrieb: > Aber mit OP's, Transistoren und Dioden kennen sie sich aus..... darum > sind sie Profis. Na, das ist dann ja doch wenigstens was. Aber mal ganz grundsätzlich: Heutzutage wird das Wort "Profi" von den meisten gleichgesetzt mit "besonders erfahrener Könner seines Gebietes" und das steckt nicht drin in dieser Büchse der Pandora. Ein Profi ist eben nur einer, der damit Geld verdienen will. Nix mehr. Und ein Amateur ist im Gegensatz zum Profi einer, der sich für die Sache interessiert aber damit kein Geld verdienen will. Beispiel Lernbetty: Die Betty-Fernbedienung wurde von Profis entwickelt, die damit gewaltig Knete machen wollten. Ist in die Hose gegangen. Als Fernbedienung ist das Teil lausig und relativ unbrauchbar, weil sie viel zu viel Strom frißt. Wenn ich hingegen mich hinsetze und abends bei einer Flasche Rotwein dafür eine Art Mini-Betriebssystem schreibe, damit man mit dieser Fernbedienung ein bissel was lernen kann, dann bin ich bezüglich Betty-Fernbedienung ein Amateur. Schließlich verdiene ich mein Geld mit anderen Dingen und eben nicht mit der Lernbetty. Es wäre sicherlich eine gute Sache gewesen für den Nachwuchs (sofern er nicht nur aus Möchtegern-Überfliegern besteht), wenn wesentlich mehr andere Amateure mit passendem Fachwissen sich dran beteiligt hätten. Die Crew damals war recht überschaubar. Aber damit sind wir wieder bei der unseligen Neigung von Profis, sich alles zuzuhalten was geht. Bloß das bißchen Wissen das man hat NICHT weitergeben, es könnte ja ein anderer verstehen und das schmälert die Berufschancen (wenn man im Grunde ein Schmalspur-Profi ist). Mentale Kleinkariertheit ist ein mächtiger Antrieb in unserer Gesellschaft. W.S.
Das mit dem ROM und RAM an der gleichen Addresse ist nicht so kompliziert: Das RAM kriegt immer die Schreibzugriffe. Die Lesezugriffe für den ROM Bereich werden halt umgeschaltet: mit ROM bekommt das ROM den Lesezugriff, und im RAM Mode kommt halt das RAM dran. Das CS Signal bekommen beide, Write Enable bekommt das RAM, nur OE wird halt getrennt. Das sollte nicht viel komplizierter sein als den Speicher in 8 K + 56 K zu teilen. Für ein einfaches System sollten aber auch 32 K RAM und bis zu 32 K EPROM reichen. Für die Interruptvektoren usw. ist es halt so, dass diese vor dem umschalten erst einmal ins RAM geschrieben (z.B. aus dem ROM) werden müssen. Ein Teil des Kodes kann ggf. auch Kopiert werden. Ein paar Bytes vom RAM sind also mehr oder weniger fest belegt, können aber natürlich auch angepasst werden (z.B. anderes Ziel für Interrupt-Vektoren).
N'abend! Mein Design wächst langsam mit der Demo Version des Eagle, denn auf dem Papier habe ich es schon länger aufgegeben. Falls jemand eine Z80 KIO als LIB hat bitte immer her damit. Die Eurokarte ist leider bereits randvoll, auch wenn CTC und SIO durch die Verwendung des KIO (tausend Dank an A.K. für den Hinweis), den ich mir bestellt habe wegfallen. Damit löst sich auc das INT Problem in Luft auf, da die Uart diesen erzeugen kann, 16 INT bietet der Chip. Über diesen Chip von Mostek gibt es sehr wenig, ich habe nur ein gescanntes uraltes Data Sheet gefunden. Musste auch 10 Euro für das Ding hinlegen. Was er drin hat reicht aber wohl auch, auch wenn ich den Horror habe vor "blind programmieren" (bin ziemlich LPCxxx Raspberry, und Arduino geschädigt mit Rundum-Sorglos-Paket durch die IDE), denn mehr als eine LED an HALT werde ich wohl nicht haben, um zb das Setup der KIO zu überpüfen. Bzw muss erst deren Uart laufen, um was zu sehen. Zuerst werde ich mir daher ein Debug Werkzeug schaffen müssen. Folgende Fragen tun sich mir noch auf: 1. Ich will kein Gattergrab erzeugen, was leider sehr schnell geht. Reicht ein 74HCT138 aus, um 3 I/O Bausteine zu decodieren? Viele machen es mit Einzelgattern aber die Lösung gefällt mir besser. 3 Adressleitungen auf 8 Demuxer Ports. 2. KIO Uart: Welchen uC Takt muss ich wählen, damit ich die bekannten Baudraten mit geringem Fehler erzeugen kann? Aktuell habe ich einen 3.6864 Mhz Oszillatorbaustein und einen 4.0000 Mhz Baustein. Der KIO wird sicherlich über einen Teiler die asynchrone Übertragung bedienen. 3. Damit das Design nicht rein digital und schnöde ist möchte ich den Uralt ADC0804 einsetzen, den ich noch reichlich hier habe und den man in "Schulungsbrettern" mit LED und Poti oft sieht. Was ist sinnvoller, wenn er keinen INT an die Z80 liefern kann bzw soll. weil das ja nicht decodiert werden kann: Ihn im free running mode laufen zu lassen, d.h. er wandelt dauernt oder die Wandlungen, die ja Zeit brauchen durch die CPU anzustossen? Wenn ich das Kuderwelsch da unten richtig deute wird ein I/O Lesezugriff die Wandlung anstossen. Aber nur anstossen. Beendet wird sie durch den INT, den ich ja nicht verwenden will. Und woher nehme ich das Clock Signal von 640 khz? RC Kombination? 10k, 150pf? Ich habe keinen Platz um den CPU Clock noch über Teiler zu jagen. Gruss, Christian Ich habe diesen Text jetzt 5 Mal gelesen und bin immer noch nicht schlauer :-( Datenbuch ADC0804: The converter is started by having CS and WR simultaneously low. This sets the start flip-flop (F/F) and the resulting “1” level resets the 8-bit shift register, resets the Interrupt (INTR) F/F and inputs a “1” to the D flop, F/F1, which is at the input end of the 8-bit shift register. Internal clock signals then transfer this “1” to the Q output of F/F1. The AND gate, G1, combines this “1” output with a clock signal to provide a reset signal to the start F/F. If the set signal is no longer present (either WR or CS is a “1”) the start F/F is reset and the 8-bit shift register then can have the “1” clocked in, which starts the conversion process. If the set signal were to still be present, this reset pulse would have no effect (both outputs of the start F/F would momentarily be at a “1” level) and the 8-bit shift register would continue to be held in the reset mode. This logic therefore allows for wide CS and WR signals and the converter will start after at least one of these signals returns high and the internal clocks again provide a reset signal for the start F/F.
Nimmst du nun doch den klops der das retrolayout kaputt macht und den A.K. so verflucht hatte? Tztztz
Christian J. schrieb: > Über diesen Chip von Mostek gibt es sehr wenig, ich habe nur ein > gescanntes uraltes Data Sheet gefunden. Da ich das Original-Databook von MOSTEK 82/83 vorliegen habe, mit ebendiesem STI drin: Mehr war auch damals nicht üblich. Datasheets wurden auf abgeholzten Wäldern an den Mann gebracht, nicht als PDF. > 1. Ich will kein Gattergrab erzeugen, was leider sehr schnell geht. > Reicht ein 74HCT138 aus, um 3 I/O Bausteine zu decodieren? Ja. Das war allgemein üblich. 2 Adressbits dekodieren reicht aus. Bei bis zu 4 Bausteinen tuts auch ein halber 74HCT139. > 2. KIO Uart: KIO war der PLCC 84 Klops. Du meinst sicherlich den STI. > Welchen uC Takt muss ich wählen, damit ich die bekannten > Baudraten mit geringem Fehler erzeugen kann? Wie bei so ziemlich jeder anderen UART ohne fraktionalem Baudratentimer auch. > Aktuell habe ich einen 3.6864 Mhz Oszillatorbaustein Also ein Baudratenquarz. Perfekt. > Was ist sinnvoller, wenn er keinen INT an die Z80 liefern kann Warum nicht? Die 8 I/Os des STI sind eigentlich Interrupt-Eingänge, die auch als Portbits verwendet werden können. > Und woher nehme ich das Clock Signal? RC Kombination? 10k, 150pf? Klar. > Ich habe diesen Text jetzt 5 Mal gelesen und bin immer noch nicht > schlauer :-( Schreibzugriff auf den ADC startet die A/D-Wandlung. Dann warten bis INTR aktiv und Ergebnis per Lesezugriff auslesen. Das wars auch schon.
:
Bearbeitet durch User
Harald schrieb: > Nimmst du nun doch den klops der das retrolayout kaputt macht und den > A.K. so verflucht hatte? Tztztz Ich nehme an, dass er die grad verwechselt hat. Denn der KIO ist nicht von MOSTEK und gekauft hat er den STI wohl: Es war kurz drauf einer weniger im eBay-Angebot.
:
Bearbeitet durch User
Harald schrieb: > Nimmst du nun doch den klops der das retrolayout kaputt macht und den > A.K. so verflucht hatte? Tztztz Nein! Nicht den Klops! den STI, sorry ! >>Schreibzugriff auf den ADC startet die A/D-Wandlung. Dann warten bis >>INTR aktiv und Ergebnis per Lesezugriff auslesen. Das wars auch schon. Und wieso schreiben die das nicht? umkipp Das interne Geschwurbel des Chips interessiert keinen. 30 Seiten Data Sheet für diesen einfachen Chip..... Ok, Schreibzugriff aber da er kein Register hat wo man reinschreiben kann wird es wohl egal sein was auf dem Datenbuss liegt. Nur RD wird den Inhalt auf diesen legen.
Christian J. schrieb: > Und wieso schreiben die das nicht? *umkipp* Tun sie doch. Erstens sieht das doch jeder im Functional Diagram ;-), zweitens wären da noch Fig 10A und 10B. > Ok, Schreibzugriff aber da er kein Register hat wo man reinschreiben > kann wird es wohl egal sein was auf dem Datenbuss liegt. So isses.
A. K. schrieb: > Ach ja: Richtig Retro wäre natürlich SN75188+189 statt MAX232. ;-) Das wird VOLL Retro .... ein kleiner Chinese schaufelt die Bits einzeln von der Uart zum PC hin und zurück. Nee..... habe schon sowas hier... Dumme Frage: Hast du die 74er Reihe komplett als "durchsuchbare" pdf's. Falls ja wäre eine dickes ZIP File Richtung meiner einer möglich?
Christian J. schrieb: > Gibt es vielleicht noch Bausätze fix und fertig für Z80 Maschinen mit > einer Art Bildschirm und Tastatur? Da kann man ja was Modernes nehmen. Ich glaub ja. Bin letztes Jahr auf einer Retro-Messe (hehe, es waren immerhin ein Dutzend Tische ;-) über Leute gestolpert, die neue Z80 Platinen gezielt für Retro-Fans anbieten.
Diesen Quark hier habe ich mir in München angetan, nach 1h war ich wieder weg :-( Mir schien, dass einige dort zu lange radioaktive Strahlung von Monitoren inhaliert haben oer sonstwie "geschädigt" waren. http://blog.spielquader.de/wp-content/gallery/muenchen-vcfe-2013/img_3060.jpg SN75..... bah, der braucht ja -15,+15, noch einen Retro DC/DC Wandler (Recom) kaufen für teuer Geld. Oder eine extra Schaltstufe als Spanungspumpe......
Christian J. schrieb: > Dumme Frage: Hast du die 74er Reihe komplett als "durchsuchbare" pdf's. > Falls ja wäre eine dickes ZIP File Richtung meiner einer möglich? Wenn du das hast, stellst du keine Fragen mehr. ebay 121429871779
Michael_ schrieb: > Christian J. schrieb: >> Dumme Frage: Hast du die 74er Reihe komplett als "durchsuchbare" pdf's. >> Falls ja wäre eine dickes ZIP File Richtung meiner einer möglich? > Wenn du das hast, stellst du keine Fragen mehr. > ebay 121429871779 Jahr: 1985, 2. Auflage Was it mit HCT, HC? Wo hört der auf? Bei 74xx200? Kann ich mir das auf meinen Kindle laden? :-) Die hatte ich mal, habe sie idiotischerweise weggeworfen bei einem Umzug. http://www.auctionworld.at/eBay-Bilder/ttl.jpg
Christian J. schrieb: > Dumme Frage: Hast du die 74er Reihe komplett Aber klar doch.
:
Bearbeitet durch User
Christian J. schrieb: > Was it mit HCT, HC? Wo hört der auf? Bei 74xx200? Was willst du z. Bsp. mit HC? Bei den alten Z80 Chip und der Pheripheri mußt du die Lastfaktoren beachten. Die Z80 sind sehr empfindlich gegenüber Timing. Eigentlich mußt du die Baugruppen über Bustreiber entkoppeln. Christian J. schrieb: > Kann ich mir das auf meinen Kindle laden? :-) Ja, leg das Buch einfach drauf.
Michael_ schrieb: > mußt du die Lastfaktoren beachten. > Die Z80 sind sehr empfindlich gegenüber Timing. Eigentlich mußt du die > Baugruppen über Bustreiber entkoppeln. Moment.... ohne da jetzt nachgeschaut zu haben..... "schneller ist besser"? Der Z80 geht ja nunmal gemächlich daher, die Zeiten im Manual sind recht gemütlich alles über 100ns. Der Ram den ich habe hat 20ns Zugriffszeit. Die HCT, die ich einsetze (LS habe ich auch noch) takten bis fast 100 Mhz. Was muss ich also beachten? Logik Anlyszer habe ich, nachschauen geht also immer.
Christian J. schrieb: > Diesen Quark hier habe ich mir in München angetan, nach 1h war ich > wieder weg :-( Nicht München, sondern CH, aber war ganz lustig. Aber nicht so sehr das was da rumstand. Vielmehr hatte ich recht angeregte Diskussion mit 2-3 anderen "Oldies", darunter einer aus der Münchner Szene. > SN75..... bah, der braucht ja -15,+15 +/-12V tun es auch. Und jetzt weisst du auch, warum die Stromversorgung vom PC bis heute -12V drauf hat. ;-)
:
Bearbeitet durch User
Michael_ schrieb: > Eigentlich mußt du die > Baugruppen über Bustreiber entkoppeln. Ach wo, nicht in der Dimension, also bei CPU, STI und 2xADC. Wenn er da einen externen Bus dran hängen wollte, ja dann.
A. K. schrieb: > +/-12V tun es auch. Und jetzt weisst du auch, warum die Stromversorgung > vom PC bis heute -12V drauf hat. ;-) Vielleicht macht hier ja noch einer einen Thread mit einem "4004" Design auf.... glaube der hatte auch -15V, +15V und brachte seine Programmierer schneller in die Klapse als der Z80. Das hier ist ein Die-Shot des 68000, gibt es bis 10000 Pixel, also ein 230 MG grosses Bild. Ich frage mich welche armen menschen da das Layout gemacht haben, so ohne Place & Route Tools, war doch Zeichenbrett Ära damals... http://www.visual6502.org/images/68000/Motorola_68000_die_20x_1a_top_1600w.png
Christian J. schrieb: > Die Eurokarte ist leider bereits randvoll, auch wenn CTC und SIO durch > die Verwendung des KIO ... wegfallen. [gemeint ist der STI, aber egal] > Über diesen Chip von Mostek gibt es sehr wenig, ich habe nur ein > gescanntes uraltes Data Sheet gefunden. Musste auch 10 Euro für das Ding > hinlegen. Was er drin hat reicht aber wohl auch, auch wenn ich den > Horror habe vor "blind programmieren" Tolle Wurst. Statt der gut dokumentierten SIO nimmst du also lieber den schlecht (bis gar nicht) dokumentierten STI, bei dem du noch nicht mal nachmessen kannst, ob du denn nun die Baudrate korrekt eingestellt hast. Ja, so wird das bestimmt was </ironie> Und eine Europakarte voll? Mit dem bisschen Zeug? Laß halt nicht so viel Luft dazwischen. Christian J. schrieb: > Das hier ist ein Die-Shot des 68000, gibt es bis 10000 Pixel, also ein > 230 MG grosses Bild. Ich frage mich welche armen menschen da das Layout > gemacht haben, so ohne Place & Route Tools, war doch Zeichenbrett Ära > damals... Das waren halt richtige Ingenieure damals. Die konnten sicher auch noch das Datenblatt der Z80 SIO lesen und verstehen ... SCNR XL
Axel Schwenke schrieb: > Tolle Wurst. Statt der gut dokumentierten SIO nimmst du also lieber den > schlecht (bis gar nicht) dokumentierten STI, bei dem du noch nicht mal > nachmessen kannst, ob du denn nun die Baudrate korrekt eingestellt hast. Keep cool. 16 Seiten, alles drin was man wissen muss. Da der keine synchronen Protokolle kann braucht man auch weniger Doku. Und da der Baudratentimer extern auf die Takteingänge der UART verkabelt wird, kann man problemlos nachmessen.
Christian J. schrieb: > Dumme Frage: Hast du die 74er Reihe komplett als "durchsuchbare" pdf's. > Falls ja wäre eine dickes ZIP File Richtung meiner einer möglich? Hier in linker Spalte Gruppe auswählen, und dann rein in die parametrische Suche: http://www.ti.com/lsds/ti/logic/home_overview.page A.K., von wann sind denn Deine TTL-Schinken? Bei mir ist das nur ein Band "Fifth European Edition 1982", 4cm dick.
Axel Schwenke schrieb: > Und eine Europakarte voll? Mit dem bisschen Zeug? Laß halt nicht so viel > Luft dazwischen. Du bist ein kleiner Klugsch..... denn solche Pingräber zu verbinden erfordert präzise und ordentliche Arbeitsweise. Und die wird bei mir unter der Leucht-Lupe mit Fädeltechnik gemacht, kleinen Stegen, die man drunter klebt vor jede Pinreihe, so dass das ganze Board mit einer Autobahn für 0,2mm Drähte versehen wird. Mit normalem Kupferlackdraht 0,5mm wird es schon zur Geduldsprobe zwei Kabel in einen Lötpunkt einzulöten, da der eine immer raushüpft, wenn du den anderen reinlöten willst. Mit 0,2mm passiert das aber nicht, da diese keine Eigenspannungen haben, du kanst locker 3-4 Kabel an einem Pin anbinden. In einem Kamm kann ich ca 30-40 Drähte parallel führen. Leider muss man dabei aber oben mehr Abstand lassen da die Kämme 2 Lochreihen für sich brauchen. Der grosse Nacteil ist, dass Falsche Verdrahtungen nicht mehr lösbar sind, da du den Draht nicht mehr rausziehen, nicht mal identifizieren kannst. Da hilft nur abschneiden am Pin und neuen ziehen, den alten drin liegen lassen. Das ist alles schon gut durchdacht und der STI hat "3 in 1" mit 40 Pins statt " 3 in 3" mit 100 Pins. :-)
So schauts aus bisher... wobei die rechte Platine eine andere ist.
Und das die vom Z80, weil der Schaltplan noch nicht fertig ist... da wird erstmal nur Basisverdrahtung gemacht, Vcc, Gnd usw.
Christian J. schrieb: > Leider muss man > dabei aber oben mehr Abstand lassen da die Kämme 2 Lochreihen für sich > brauchen. Der grosse Nacteil ist, dass Falsche Verdrahtungen nicht mehr > lösbar sind, da du den Draht nicht mehr rausziehen, nicht mal > identifizieren kannst. Da hilft nur abschneiden am Pin und neuen ziehen, > den alten drin liegen lassen. Und bei Fehlern suchst Du dir einen Wolf, weil Du die Drähte ja nicht verfolgen kannst. Dazu kommt noch das Übersprechen, wenn die Drähte über lange Strecken parallel liegen. Ohne die Kämme erreichst Du eine wesentlich höhere Packungsdichte, kannst jede einzelne Verbindung wieder finden, und hast deutlich reduziertes Übersprechen. Da ist ein Beispiel: Beitrag "Re: z80 system" Beitrag "Re: z80 system" Mit Kämmen hätte das nie auf eine Eurokarte gepasst, und die 16 dynamischen RAMs hätten wahrscheinlich nicht funktioniert.
Leo C. schrieb: > A.K., von wann sind denn Deine TTL-Schinken? Bei mir ist das nur ein > Band "Fifth European Edition 1982", 4cm dick. TI Vol 1, 74/74S/74LS: 1983, 6. Ausgabe TI Vol 2, 74AS/74ALS: 1983/84, 7. Ausgabe Motorola 74HC(T) von 1984 Valvo HEF4000 von 1980
Christian J. schrieb: > Das ist alles schon gut durchdacht und der STI hat "3 in 1" mit 40 Pins > statt " 3 in 3" mit 100 Pins. Sehr luftig. Geht auch anders, ebenfalls Retro (bis auf den zentralen Taktgenerator), mit dem RCA 1802: Beitrag "Re: Zeigt her Eure Kunstwerke !" Sehr praktisch ist, dass man ohne ROM auskommt. Die UART ist hier ein AY-3-1015 und die ist ganz nach deinem Geschmack, weil im Programm völlig ohne Konfiguration auskommt. ;-)
:
Bearbeitet durch User
Leo C. schrieb: > Und bei Fehlern suchst Du dir einen Wolf, weil Du die Drähte ja nicht > verfolgen kannst. Dazu kommt noch das Übersprechen, wenn die Drähte über > lange Strecken parallel liegen. > > Ohne die Kämme erreichst Du eine wesentlich höhere Packungsdichte, > kannst jede einzelne Verbindung wieder finden, und hast deutlich > reduziertes Übersprechen. Ich finds so aber schöner .... http://www.mikrocontroller.net/attachment/93660/z180_3.JPG Und da ich eh Brille trage und mit Lupe arbeite muss es nicht so extrem werden. Lieber etwas luftiger. Und Übersprechen hatte bei den bisschen Megahertz noch nie.
Ich bin ja mittelmäßig über das Interesse an Retrodesigns beeindruckt. Da die Frage nach einem Terminal aufkam. Christian J. schrieb: > Gibt es vielleicht noch Bausätze fix und fertig für Z80 Maschinen mit > einer Art Bildschirm und Tastatur? Da kann man ja was Modernes nehmen. Im AVR CP/M Projekt ist damals eine Variante mit VT100 Terminal entstanden. Beitrag "Re: CP/M auf ATmega88" Eine abgespeckte reine VT100 Terminal Version wandert bei mir gerade in ein kleines Gehäuse um an der VESA Aufnahme an einem handelsüblichen Monitors befestigt zu werden. Es wird also nur noch eine Tastatur angesteckt und fertig ist das Terminal. Die Schnittstelle ist derzeit USB und erhält gerade noch eine echte RS232. Der Code ist frei und darf gerne weiterentwickelt werden. Beitrag "Re: CP/M auf ATmega88" Vielleicht hat ja jemand Interesse daran…
A. K. schrieb: >> 1. Ich will kein Gattergrab erzeugen, was leider sehr schnell geht. >> Reicht ein 74HCT138 aus, um 3 I/O Bausteine zu decodieren? Wie schon mal geschrieben: Bei den wenigen IO Bausteinen, die du hast, ist ein extra Dekoder völlig überflüssig. Häng einfach jeden /CS an eine andere Adressleitung, angefangen mit A7 und dann abwärts. Damit kannst du 4 Bausteine bequem sortieren und hast noch jeweils die unteren 4 Adressen frei für interne Register.
Christian J. schrieb: > Moment.... ohne da jetzt nachgeschaut zu haben..... "schneller ist > besser"? Man sollte da vorsichtig sein. Prinzipiell werden HCT gehen. Aber wenn du eine Interruptsteuerkette benutzt, kommt es auf die Laufzeiten der Gatter an. Da wurden schon mal ein paar eingebaut, um ein paar ns zu verzögern. Und 1985, seitdem werden keine Logikschaltkreise dazugekommen sein. Im Moment habe ich auch 20ns CMOS-RAM im Verdacht, das sie in alten 80C31 Schaltungen Probleme machen. Eigentlich sind da ursprünglich 150ns eingebaut.
Michael_ schrieb: > Aber wenn du eine Interruptsteuerkette benutzt, kommt es auf die > Laufzeiten der Gatter an. Da wurden schon mal ein paar eingebaut, um ein > paar ns zu verzögern. Yep. Aber bei einem einzigen STI...
Zum Z80 STI (Mostek MK3801) hier ein deutliche besser gescanntes Datenblatt http://schuetz.thtec.org/mccomputer/Mostek%20-%20MK3801%20-%20Serial%20Timer%20Interrupt%20Controller.PDF (Achtung: 10 MByte) Das ist vorteilhaft auch "textdurchsuchbar" in der PDF, nicht nur Grafik. Gruss
Dass die IEI/IEO-Kette bei steigender Länge (typ mehr als 4 Devices in der Chain) irgendwann Ärger macht ist richtig. Da gab es 2 Möglichkeiten: Waitstates im IACK Zyklus, oder den IEI/IEO Durchlauf der langsamen ICs mittels externer Gatter zu beschleunigen. Doku dazu, in traumhaft schönem Retro-Design: http://www.z80.info/zip/z80-interrupts.pdf
:
Bearbeitet durch User
Christian J. schrieb: > In einem Kamm kann ich ca 30-40 Drähte parallel führen. VeroWire-Fädeltechnik ist eine feine Sache, aber lass bloss diese Plastikkämme weg! In den parallel geführten Drähten gibt es dermassen viel Übersprechen, dass Dein Z80 wahrscheinlich schon bei 4 MHz aussteigen wird. Anarchieverdrahtung ist angesagt, d.h. die Drähte mit ein paar Millimetern Überlänge per Luftlinie führen. Das sieht dann später aus wie eine noch nicht entflochtene Platine in der Guide- bzw Ratsnest-Ansicht. Masseleitungen kann man vorher als Gitter mit 0,6 mm-Silberdraht ausführen.
Erich schrieb: > Zum Z80 STI (Mostek MK3801) hier ein deutliche besser gescanntes > Datenblatt > http://schuetz.thtec.org/mccomputer/Mostek%20-%20MK3801%20-%20Serial%20Timer%20Interrupt%20Controller.PDF > (Achtung: 10 MByte) > Das ist vorteilhaft auch "textdurchsuchbar" in der PDF, nicht nur > Grafik. Danke, das mit den weißen Pilz-Geflechten links hatte ich schon gefunden. Und das wird erst so richtig Retro, wenn man auf Ökopapier ausdruckt und nen Kaffee drüber kippt :-) Habe denn Rat angenommen, IC Fassungen nochmal raus, Kämme auch und alles enger zusammen. Gegen die Kämme ist nichts zu sagen, damit laufen andere auch. Und daher bleiben sie drin. Bei meinem Röhrenamp war Durcheinander auch besser wegen der Brummstörungen die ein "geordnetes Design" sich einfängt aber hier wird es ordentlch und Chuck Norris macht keine Fehler beim Verdrahten.... die Drähte legen sich vor Angst von allein an den richtigen Pin! ;-)
Michael_ schrieb: > Im Moment habe ich auch 20ns CMOS-RAM im Verdacht, das sie in alten > 80C31 Schaltungen Probleme machen. Kann schon sein. Aber wohl weniger des Timings wegen, sondern weil die Power-Transienten die Abblockung überfordern oder weil die Flankenwechsel an 8 parallelen Datenleitungen die Verdrahtung überfordern. Die Flanken sind halt etwas fixer als bei den 450ns RAMs der 8041-Ära. In diesem Sinne auch Gruss an Christian mit seinen Fädelkämmen. ;-)
Moin, hoffe mal das ist so richtig, mehrere Wege führen nach ROM: Adressdecodierung ROM/RAM: A13 v A14 v A15 => CE/-ROM und CE-RAM (74HCT32) ROM = 0x0000 - 0x1FFF RAM = 0x2000 - 0x7FFF I/O: Z80 STI (24 register) + 8255 (4 Register) + ADC0804 (1 ro Register) Adressdecodierung I/O über 74HCT138 (3 zu 8 Muxer) Q3 11 = CS(ADC0804) A7 --> Q2 10 = CS(8255) - 74HCT138 Q1 01 = CS(Z80 STI) A6 --> Q0 00 = unbenutzt A3,A2,A1,A0 => Z80 STI (A0,A1,A2,A3) A1,A0 => 8255 (A0,A1) Memory Map 0x40 - 0x57 Z80 STI 0x80 - 0x83 8255 0xC0 - 0xC0 ADC0804 Ok?
> Ok?
Kommt drauf an.
Was ist mit den anderen 4 Eingängen vom '138?
Leo C. schrieb: >> Ok? > > Kommt drauf an. > > Was ist mit den anderen 4 Eingängen vom '138? Der 138 hat nur 3 Decoder Eingänge, brauchen tue ich aber nur 2 und am Ausgang 4, Q0 muss frei bleiben. Und ein EN kommt an IOREQ vom Z80.
> Der 138 hat nur 3 Decoder Eingänge, brauchen tue ich aber nur 2
Gibst Du den 3. an den Händler zurück?
Wie bitte? Das ist ein straight forward Decoder, da geht nix zurück. Nr.3 wird tot gelegt auf 0, so dass nur 4 Zustände decodiert werden für maximal 3 Devices. Bin nur unschlüssig, ob Q0 frei bleiben muss. E1/ macht ja die Freigabe über IOREQ.
Ich grüble nur grad nach, ob das so alles mit dem Timing und dem Fan-Out hinhaut. Mehr als 3 IO würden schon sicher einen Bustreiber bedeuten an D0-D7 . Und auch von den Laufzeiten her muss das passen. 107ns ist (26). Von Adress anlegen bis IOREQ kommt. Rotz, hat mal einer ein besseres Datasheet der alten B Variante vom Z80.....
> Wie bitte? Das ist ein straight forward Decoder, da geht nix zurück. Sorry, ich wollte meinen "Artikel" nochmal ergänzen, hatte aber ein Problem hier. > Nr.3 wird tot gelegt auf 0, so dass nur 4 Zustände decodiert werden für > maximal 3 Devices. Auf 0 legen ist schon mal besser als nix, bzw. offen lassen. > Bin nur unschlüssig, ob Q0 frei bleiben muss. Warum sollte der frei bleiben müssen. Wenn Eingang C auf GND liegt, kannst Du die ersten 4 Ausgänge beliebig verwenden. Wenn Du nur 3 brauchst, kannst Du sie Dir aussuchen. > E1/ macht ja die Freigabe über IOREQ. (In meinem Datenblatt heißen die Enable-Eingänge G1, G2A und G2B) /IOREQ auf G2A (oder G2B). Auf G1 solltest Du /M1 legen, da während des Interrupt Acknowledge Cycle /IOREQ und /M1 low sind. Ich würde allerdings A7 auf G2B legen, und A4, A5, A6 auf A, B, C. Kostet nichts, und die Adressen werden besser ausdekodiert. Vorteilhaft bei Erweiterungen, und Amok laufende Programme treffen seltener eine gültige Adresse.
Leo C. schrieb: > Auf G1 solltest Du /M1 legen, da während des Interrupt Acknowledge Cycle > /IOREQ und /M1 low sind. /M1 ist mir noch etwas ein Rätsel. Was soll der bei der Decodierung der I/O denn mitmischen? Ist nicht im Diagramm des I/O Zyklusses drin. Nur beim INT Acknowledge. Und M1 liegt brav am M1 der Z80 STI dran, nicht abe am Decoder.
1 | Interrupt Request/Acknowledge Cycle |
2 | |
3 | Figure 9 illustrates the timing associated with an interrupt cycle. The CPU |
4 | samples the interrupt signal (INT) with the rising edge of the last clock at the |
5 | end of any instruction. The signal is not accepted if the internal CPU |
6 | software controlled interrupt enable flip-flop is not set or if the BUSREQ |
7 | signal is active. When the signal is accepted, a special M1 cycle is |
8 | generated. During this special M1 cycle, the IORQ signal becomes active |
9 | (instead of the normal MREQ) to indicate that the interrupting device can |
10 | place an 8-bit vector on the data bus. Two wait states are automatically |
11 | added to this cycle. These states are added so that a ripple priority interrupt |
12 | scheme can be easily implemented. The two wait states allow sufficient time |
13 | for the ripple signals to stabilize and identify which |
14 | I/O device must insert the response vector. Refer to Chapter 6 for details on |
15 | how the interrupt response vector is utilized by the CPU. |
Christian J. schrieb: > Memory Map > 0x40 - 0x57 Z80 STI > 0x80 - 0x83 8255 > 0xC0 - 0xC0 ADC0804 Das ist keine Memory Map, sondern eine I/O Map. > Ok? Nicht Ok. Ein Interrupt-Acknowledge-Zyklus legt dir /IORQ auf Low und aktiviert damit ein zufälliges I/O-Gerät. Doofe Sache, sowas. ;-) So schwer ist der '138er nicht: Nichtinvertierendes Enable an /M1. Zwei Invertierende Enables an /IORQ. Drei Eingänge an A7 bis A5. Fertig. Damit hast du acht (ACHT!) Chip-Enables, die deinen I/O-Adressraum im 32er-Raster sauber aufteilen, und nicht alle davon werden benutzt. Erspart dir offene Eingänge. An die Peripherie selbst kommen dann A0..A4 (je nachdem, was du brauchst), D0..D7, /RD, /WR und der entsprechende Ausgang vom '138 an /CE. Dein Bild ist grausam. Besorge dir das normale Manual vom Z80 von Zilog, das sind bessere Diagramme drin. Dein (26) besagt, dass wenn /IORQ fällt, die Adresse gültig ist und du sie latchen darfst (Setup-Zeit ist 100 ns), und die Adresse auch für den ganzen Zyklus gültig bleibt (Hold-Zeit). Da ein I/O-Zyklus immer auch einen zusätzlichen Wartezyklus beinhaltet, brauchst du dir da eigentlich keine Sorgen machen.
> Was soll der bei der Decodierung der I/O denn mitmischen? Es soll verhindern, daß während des IntAck Cycles Deine Peripherie selektiert wird. Während dieses Cycles liegen mehr oder weniger zufällige Daten auf dem Adressbus, IORQ ist low, M1 aber auch. > Und M1 liegt brav am M1 der Z80 STI dran, nicht abe am Decoder. M1 liegt aber z.B nicht am 8255 an. Z80-Peripherie-Bausteine mögen den IntAck selber erkennen. Der 8255 kann das aber nicht. Du mußt verhindern, daß der decoder I/O-Selects generiert, wenn M1 aktiv ist. /E1 /E2 E3 /IOREQ A7 /M1
:
Bearbeitet durch User
Hier gibts die Datenblätter: http://www.zilog.com/index.php?option=com_product&Itemid=26&task=docs&businessLine=1&parent_id=139&familyId=20&productId=Z84C00 Du brauchst (mindestens) PS0178 und UM0080.
Hi, ich danke euch, ist klar jetzt. So langsam fängt es an Spass zu machen, auch wenn es sehr ungewohnt ist wenn man seit Jahren nur noch Controler verwendet hat wo alles drin ist. Bin noch dabei und habe in meinen umfangreichen Settkästen einen CD4060 gefunden, der vielleicht mit einen 32khz Quarz einen 1s Takt erzeugen könnt für "irgendwas sinnvolles" und einen SN74245 Bus bidirektionalen Treiber. Ist wahrscheinlich Mumpitz aber an Halt sitzt eine Low Power LED dran und ich überlege ob man irgendwas sehen würde, wenn man die D0...D7 oder andere Signale auf 8 LEDS führen würde. Wahrscheinlich würden sie aber nur flimmern und glimmen und das war es. Mal spasseshalber: Leite ich das Signal des Quarzoscillators auf einen CD4020 um, schalte dahinter einen Inverter als Treiber (4020 dürfte zu schwach sein die Z80 zu treiben), so komme ich nach 14 Stufen auf minimal 225 Hz. fmax des 4020 bei 5V sind 4 Mhz, passt also. Sagen wir der Z80 würde mit 10 khz getaktet, vorrausgesetzt er hat ein voll statisches Design, würden dann die anderen Bausteine noch arbeiten? (außer dem ADC080), so dass man mit Leds die Bits sehen könnte?
Leo C. schrieb: > Auf G1 solltest Du /M1 legen, da während des Interrupt Acknowledge Cycle > /IOREQ und /M1 low sind. Schadet nichts, nützt aber auch nichts. S. R. schrieb: > Nicht Ok. Ein Interrupt-Acknowledge-Zyklus legt dir /IORQ auf Low und > aktiviert damit ein zufälliges I/O-Gerät. Doofe Sache, sowas. ;-) Im IACK bleibt RD inaktiv, weshalb ein mögliches CS von den Bausteinen ignoriert wird.
:
Bearbeitet durch User
Christian J. schrieb: > Sagen wir der Z80 würde mit 10 khz > getaktet, vorrausgesetzt er hat ein voll statisches Design, Der Z80 hat ein vollständig statisches Design.
Christian J. schrieb: > Mehr als 3 IO würden schon sicher einen Bustreiber > bedeuten an D0-D7 Gerechnet, geraten oder gelesen? Würde mich auch interessieren, wo die Grenze ist. Und wenn, dann betrifft die nur die I/O-Zugriffe, da neben dem RAM auch das verwendete ROM viel schneller sein dürfte als damals üblich.
:
Bearbeitet durch User
>Der Z80 hat ein vollständig statisches Design. Ja. Daher gab es auch schon immer die "Bus-Monitor" Schaltungen. Zwecks Retro-Design unbedingt mit dem TIL311 (nervenstarke Netzteile sind dann Pflicht). http://www.s100computers.com/My%20System%20Pages/SMB%20Board/S100%20Bus%20SMB.htm Mit den Comparatoren kann man eine beliebige Adresse (/MREQ) oder IO-Zugriff (/IORQ) einstellen, wahlweise zusätzlich qualifiziert mit /RD oder /WR. Sobald die Adresse erreicht wird bleibt die ZPU stehen! Dann kann man mit dem Single-Step-Taster wirklich jeden einzelnen Zyklus weitertasten. Recht lustig bei 4-Byte-Befehlen wie RRC (IX+33) etc. Praktisch ist das dann ein Logicanalyser für Arme. Dies nur zur Info. Für das Projekt hier ist es jedoch nicht zielführend; später mal was grösseres bauen... Wenn ich heute Abend mal in meinen Kellerspeicher (wörtlich!) komme, suche ich mal meinen uralten Aufbau mit dem Z80 STI raus. Anno 1982 oder sorum, mit kreuz-und-quer Kupferlackdrähten von irgendeinem Trafo abgewickelt. Nix mit Fädelkämmen oder so' Zeug, das nimmt vielzuviel Platz weg, wie schon gesagt wurde. Und macht die Fehlersuche schwer. Praktische Tips: Sinnvoll ist es, das Schaltbild bzw. ALLE PINS JEDES Bauteils auszudrucken und nach den löten durchzupiepsen. Insbesondere auch darauf, daß Pins nicht mit benachbarten links/rechts verbunden sind (wo's nicht sein soll). Jeden Pin jedes Bauteils mit Markerstift auf der Liste abstreichen wenn ok. Auch darf kein Pin offen sein. Unbenutze nach Gnd oder auf eine "+Pullup" Lötinsel über 10k. Bei Beginn Verdrahtung mit GND und VCC (+5) beginnen; diese über Silberdraht. Einen 100nF an jedem IC z.B. unter dem Sockel "schräg". Smd-Cs wären einfacher, sind aber eher kein Retrodesign. Gute Laborplatine FR4 einsetzen, die sind doch stabiler als Hartpapier. Wie weit ist das Schaltbild? Gruss
TIL311? Sowas habe ich zu DDR Zeiten mal als Einsteckkarte für den K1520 Bus gebaut, mit "gewöhnlichen" 7 Seg anzeigen, einem U40511 und diversen Multiplexern. Die Steuersignale gingen auf Status-LEDs. Traurigerweise habe ich das irgendwann mal verschenkt... Der Nutzeffekt war aber damals nicht all zu hoch, da in den Rechnern dynamische RAMs werkelten die einen Refresh brauchten, da war nicht viel mit Schrittbetrieb. Gruß, Holm
Erich schrieb: > Wie weit ist das Schaltbild? Ich bin noch dabei, muss est den STI noch zeichnen, da es den nicht gibt bei eagle. Ich habe den M1 jetzt mit reingenommen und 1 zu 8 decodiert und alle Ves angeshclossen. Natürlich mache ich es auch so, nach em Löten wird alles gepiepst und danach ohne IC Strom angelegt und geschaut ob der da ist wo er hin soll. Oszi werkelt auch schon, mit dem 25 Euro Logix Analyszer von ebay kann man schon was machen. Bis später... heute nacht gehts weiter. Ich werde noch eine Taktreduzierung mit einbauen mit dem 4020, die per Dip/Jumper etc umsteckbar ist. >>Gerechnet, geraten oder gelesen? Würde mich auch interessieren, wo die >>Grenze ist. Und wenn, dann betrifft die nur die I/O-Zugriffe, da neben >>dem RAM auch das verwendete ROM viel schneller sein dürfte als damals >>üblich. Hängt vom Fan-Out und von den Kapaizitäten und Frequenzen ab. Müsste man wohl eher ausprobieren oder Ersatzschaltbild zeichnen und rechnen wo die Grenze liegt und bei welcher Frequenz. Wahrscheinlich gibt Jehova Rufe aber da wird noch ein AVR an den Steuer-Bus mit drankommen, der die Signal "mono-flopped" und zwar so dass man es sehen kann auf den LEDs.
>da in den Rechnern dynamische RAMs werkelten
Ja, das war leider so bei üblichen "simplen" CP/M Designs. Anders bekam
man ja 16k oder gar 64k Ram nicht auf 'ne kleine Europaplatine
(100x160).
In dem Betrieb wo ich mein Praxissemester machte Anfang der 80er, da
wurden allerdings Industriesteuerungen gebaut, im Doppeleuropaformat
(160x230). Da ging schon mehr drauf.
Kaum daß das statische Ram 2kx8 Cmos (6116) erfunden war, wurde eine
Leiterplatte entworfen mit 16 Stück drauf! Stückpreis des 2k Rams damals
ca. 40 Mark (pro Stück).
32 kByte statisches Ram auf EINER Platine, das hatte die Welt noch nicht
gesehen... Zwei Karten davon in das Rack, 64k, mit
Eprom-Ausblendungsmöglichkeit (umschaltbar), das war der erste Schritt
um die Industriesteuerung CP/M kompatibel zu machen. Kurz später haben
wir einen Floppycontroller dazugebaut, von 'ner S100 Platine
nachempfunden, aber das ist 'ne ganz eigene Geschichte.
Gruss
A. K. schrieb: > Schadet nichts, nützt aber auch nichts. Stimmt, war wohl schon zu früh. > Im IACK bleibt RD inaktiv, weshalb ein mögliches CS von den Bausteinen > ignoriert wird. Bei seinem jetzigen Plan stimmt das. Wenn er aber doch noch Peripherie ohne 8080-Bus-Interface anschließen sollte, wirds mit M1 auf dem Decoder einfacher. Z.B. könnte er an einen der Selects ein FF (oder gleich ein 8 Bit breites Latch) anschließen, um das EPROM abschalten zu können. Erich schrieb: > Daher gab es auch schon immer die "Bus-Monitor" Schaltungen. > Zwecks Retro-Design unbedingt mit dem TIL311 (nervenstarke Netzteile > sind dann Pflicht). Stimmt auch. Das A-Meter im Bild zeigt nur den Strom der Display-Platine. Der Rest (Z8S180, 512K RAM, ATmega1281, FT232RL) braucht knapp 50 mA bei jeweils 18,432MHz.
Erich schrieb: >>da in den Rechnern dynamische RAMs werkelten > Ja, das war leider so bei üblichen "simplen" CP/M Designs. Anders bekam > man ja 16k oder gar 64k Ram nicht auf 'ne kleine Europaplatine > (100x160). > In dem Betrieb wo ich mein Praxissemester machte Anfang der 80er, da > wurden allerdings Industriesteuerungen gebaut, im Doppeleuropaformat > (160x230). Da ging schon mehr drauf. Hmpf...die Rechner von denen ich redete (K1520) waren nicht simpel und auch nicht auf Europaformat, sondern auf DDR Standard K1520 mit 170x215 mm. Das war Industriehardware. Die DDR "Europaformat" Platinen waren 170x95 oder 170x215mm in den Abmessungen, Raster war metrisch 2,5mm genauso wie die dazugehörigen Steckverbinder. > > Kaum daß das statische Ram 2kx8 Cmos (6116) erfunden war, wurde eine > Leiterplatte entworfen mit 16 Stück drauf! Stückpreis des 2k Rams damals > ca. 40 Mark (pro Stück). > 32 kByte statisches Ram auf EINER Platine, das hatte die Welt noch nicht > gesehen... Zwei Karten davon in das Rack, 64k, mit > Eprom-Ausblendungsmöglichkeit (umschaltbar), das war der erste Schritt > um die Industriesteuerung CP/M kompatibel zu machen. Kurz später haben > wir einen Floppycontroller dazugebaut, von 'ner S100 Platine > nachempfunden, aber das ist 'ne ganz eigene Geschichte. > Gruss Der damals übliche Floppycontroller bestand aus Schieberegistern (7495), 2 Eproms (2708) mit Marken-Mustern und 2 PIOs und wurde meistens im DMA Betrieb (durch eine 2. CPU, keine Z80-DMA) gefahren. :-) Gruß, Holm
Hallo! Etwas Funktionsfähiges könnte auch so aussehen: #Toshiba TMPZ84C015AF6 mit "nur" 4,9 MHz #32K EPROM (Monitor, BASIC, BDOS, CCP ,BIOS) #64K RAM #480K RAM-Floppy "Gold-Akku" gepuffert #7 x 8M (CF-)"Harddisc" #Kassetten-Interface #eigenes BIOS #Kompatibilität: bisher läuft Alles u.a. TP3.01A
Schnelle Zischenfrage: Ein 3,6V Pufferakku übe eine Diode abgekoppelt von den 5V und mit Ladevorrichtung über Wierstand (10mA), würde der über das Ram die ganze restliche Schaltung mitversorgen? Ich weiss nicht wie sich stromlose Bausteine verhalten, wenn diese um einen guppiert sind, der 3V anliegen hat. PS: Der 2764 zieht 40mA Ruhestrom und 70mA Betrieb.... um die Stromrechnung brauchte sich wohl keiner damals Gedanken machen. In einem Zeitalter wo ein uC 5mA zieht ist das schon ..... bombatisch.
Christian J. schrieb: > Ein 3,6V Pufferakku übe eine Diode abgekoppelt von den 5V und mit > Ladevorrichtung über Wierstand (10mA), würde der über das Ram die ganze > restliche Schaltung mitversorgen? Ich weiss nicht wie sich stromlose > Bausteine verhalten, wenn diese um einen guppiert sind, der 3V anliegen > hat. Was für ein RAM-Chip ist es denn? Da war doch was mit 20ns - was nach Cache-RAM klingt, und sind nicht grad stromsparend. Ansonsten ist es nur CE=Vcc(RAM) wichtig.
:
Bearbeitet durch User
Hallo! Das gepufferte RAM ist ein 512Kx8 Low Power CMOS, wird über einen MAX691 Supervisor geschaltet und mit dem 1F GoldCap bleibt sein Inhalt locker drei Wochen erhalten, auch wenns rechnerisch wahrscheinlich nicht hin kommt. Für lange Speicherzeiten ist eh die Flash-Card da.
Wenn ichs richtig sehe, ist das RAM ein AS6C4008-55PCN. Also ein 512Kx8 mit 55ns Zugriffszeit. Für den guten alten Z80 auch nicht schlecht. Zum Puffern reicht auch eine billige 3V Knopfzelle. Allerdings wärs wohl besser, wenn Christian erst mal sein Grundsystem ans Laufen bringt.
>Ein 3,6V Pufferakku Prinzipiell solltest du dich weniger mit solchen gimmicks befassen. Vieles ist machbar, aber kaum alles gleichzeitig auf einer "einfachen" Platine. Mit deinem Taktkram bin ich schon skeptisch. Und die Ram-Bufferung funktioniert wirklich nur zuverlässig mit so'nem Maximchip; die hat ursprünglich Dallas Semiconductor erfunden, z.B. den DS1210. Maxim hat die Firma dann später aufgekauft. Und "low current" cmos, keine cacherams; also z.B. HM62256 (32k) oder HM628128 (128k). Programme debuggen im Ram kann sowieso das Ram selbst ruckzuck überschreiben, muss man also was richtig nonvolatile haben. Flash oder neu laden von RS232/PC. Ich würd' eher über so'n kleinen modernen 8-Pin serielles Flash nachdenken, das kann man an die Pio hängen und es nimmt wenig Platz weg. Die "Load/Loadgo" Routinen dafür kann man ins normale Eprom leicht unterbringen. Jedenfalls viel einfacher als "echte" Flashchips oder gar SD-Karten. Microchip 25LC1024 in DIP8 oder was von STM (dort aufpassen auf +5V und Gehäuseform). Allerdings sollte man 32k normales Eprom vorsehen (27C256) und ggf. eine Eprom-Ausblendemöglichkeit falls man 128k Ramchip einbaut (und nur zu 64k nutzt). Gruss
Erich schrieb: > Und die Ram-Bufferung funktioniert wirklich nur zuverlässig mit so'nem > Maximchip; Nö. Sowas hat man schon gemacht, bevor es solche Chips gab. Aber ich gebe Leo recht. Der Kram soll erst einmal ohne Gimmicks funktionieren. Lötpunktraster nachträglich anzupassen ist nicht sonderlich schwierig.
:
Bearbeitet durch User
Erich schrieb: > Die "Load/Loadgo" Routinen dafür kann man ins normale Eprom leicht > unterbringen. Tja, bei einer Retro-CPU mit eingebautem Bootloader hat man es eben etwas leichter. ;-) Wobei man sich natürlich auch den Spass machen kann, das EPROM komplett wegzulassen und einen AVR mit seinen Ports an den Bus zu hängen. Der krallt sich den Bus und füllt das RAM. Bei einem 40-Pinner fällt das nicht weiter auf, wenn man die Beschriftung durch "Z80 LDR" ersetzt.
:
Bearbeitet durch User
@prx >>> Und die Ram-Bufferung.. >Nö. Sowas hat man schon gemacht, bevor es solche Chips gab. Meine Erfahrung zeigte was anderes. Mag' aber sein daß es mit ausgesuchten Ramtypen eines Herstellers ging. Hat man "6264" Typen kreuz und quer eingekauft gings schief. >Retro-CPU Ein Z80 sollte der Chef auf der Platine sein. Sonst isses kein Retro. Dulden könnte man bestenfalls eine DMA. Da aber dem TE bereits die SIO schon zu kompliziert vorkam ist das kein Thema hier. Und ausser für DD floppy braucht sie nicht wirklich. Gruss
A. K. schrieb: > Wobei man sich natürlich auch den Spass machen kann, das EPROM komplett > wegzulassen und einen AVR mit seinen Ports an den Bus zu hängen. Der > krallt sich den Bus und füllt das RAM. Genau das wird hier realisiert: Beitrag "Re: Retro Fieber: Z80 oder 68000 ?"
Erich schrieb: >>Nö. Sowas hat man schon gemacht, bevor es solche Chips gab. > Meine Erfahrung zeigte was anderes. Dann deutlicher: Ich habe es gemacht, an einem 68000 System, mit NiCd Akkus. Frag mich nicht mehr, mit welcher Spannung, die muss natürlich zum RAM passen. Wobei das vor 3 Jahrzehnten nicht Retro war, sondern Stand der Technik. Die EPROM-Brennerei war mir zu blöd. > Mag' aber sein daß es mit ausgesuchten Ramtypen eines Herstellers ging. Die sind dabei völlig schnurz. Entscheidend ist, dass CE entsprechend kontrolliert wird. Wenn CE=Vcc(RAM), dann brennt da nix an. > Ein Z80 sollte der Chef auf der Platine sein. Wäre er ja auch, nachdem sein RAM den Inhalt hat. Wenn man einen Loader für ein ROM entwickelt hat, dann kann man den AVR ja wieder rausziehen > Da aber dem TE bereits die SIO schon zu kompliziert vorkam ist das kein > Thema hier. OK, überzeugt. ;-)
:
Bearbeitet durch User
A. K. schrieb: > Wobei man sich natürlich auch den Spass machen kann, das EPROM komplett > wegzulassen und einen AVR mit seinen Ports an den Bus zu hängen. Der > krallt sich den Bus und füllt das RAM. Tja, dazu gab es zwei Vorschläge hier zum dranhängen/mitmachen/ nachbauen. Beitrag "eigenes Z80 Mainboard - geht das so?" Beitrag "Z180-Stamp Modul" > Bei einem 40-Pinner fällt das > nicht weiter auf, wenn man die Beschriftung durch "Z80 LDR" ersetzt. Unter dieser Bedingung fällt der 2. Vorschlag allerdings weg (64 Pin QFP). Erich schrieb: > Ein Z80 sollte der Chef auf der Platine sein. Sonst isses kein Retro. > Dulden könnte man bestenfalls eine DMA. "Retro Modern" ist auch eine schöne Sportart.
Anbei schonmal eine eagle lib mit dem Z80 STI, wer Spass dran hat.... Und weiter gehts .... wurschtel
Wie heißt Dein RAM genau? Der Schaltplan paßt nicht zu meiner Behauptung, es sei ein AS6C4008-55PCN.
Route 66 schrieb: > Etwas Funktionsfähiges könnte auch so aussehen: > #Toshiba TMPZ84C015AF6 mit "nur" 4,9 MHz Hättest aber auch schreiben können, das das der CEPAC-80 ist. Wurde konstruiert von Stefan Wimmer und erschien in der c't 8/88: http://www.oocities.org/capecanaveral/6368/cepac_ct.html Genau das Dings hat jahrelang meinen SAT Empfänger gesteuert. Das schöne ist die kompakte Toshiba CPU mit allen Z80 Peripherien, die man so braucht, wie oben schon öfter erwähnt. Ich glaub' sogar, ich hab noch ein oder 2 CPU hier rumliegen... Hier ist übrigens 'ne nette Seite mit Z80 Basteleien: http://z80.info/homebrew.htm
:
Bearbeitet durch User
So, mir tun die Augen weh..... Rohbau steht, Details und Fehler müssen noch beseitigt werden. Einige Leitungen weiss ich auch noch nicht was damit tun. RAM ist ASC61008 laut Aufschrift.
A. K. schrieb: > Da fehlt aber noch ziemlich viel. Heute nicht mehr .... ich frage mich welcher Depp das alles verdrahten soll... finde hier keinen. Grobe Fehler vielleicht mal anführen, nicht verbundene Pins werden noch gemacht. tromversorgung etc kommt nicht drauf. Das ist nur ein Plan, wird nie eine Platine draus werden. PS: Was fehlt denn noch "Wichtiges" außer - Reset Schaltung und Taster - Stecker nach draußen - 5V Versorgung
Christian J. schrieb: > Einige Leitungen weiss ich auch noch nicht was damit tun. Hier mal ein Anfang: An WAIT, INT, NMI, BUSRQ, je ein Pullup. INT an STI anschließen. Am STI IEI ein Pullup. RD an OE von RAM und EPROM. WR an WE von RAM. MREQ an CS1 von RAM. Pullups generell 4,7k. > RAM ist ASC61008 laut Aufschrift. Das Datenblatt habe ich inzwischen auch gefunden. Dann ist das so in Ordnung. Meine Aussagen weiter oben passen natürlich trotzdem.
:
Bearbeitet durch User
In die Speicherdekodierung muss MREQ rein, sonst mischen die auch bei I/O-Zugriffen mit. Beim RAM täte es das /CS1, aber beim ROM gibts kein zweites /CS. Allerdings halte ich den Vorschlag von oben, statt getrennter Adressräume ein Flipflop zu verwenden, für sinnvoller. Also ab Reset lesen aus ROM, schreiben ins RAM. Nach Zugriff auf eine I/O-Adresse schaltet das FF um, und es wird aus dem RAM gelesen. Reset-Code kopiert ROM-Inhalt über sich selbst und schaltet dann um.
Da fehlt noch mehr, zb die MREQ,RD,WR Veroderung auf die Memories. Mache ich morgen. Danke!
A. K. schrieb: > Allerdings halte ich den Vorschlag von oben, statt getrennter > Adressräume ein Flipflop zu verwenden, für sinnvoller. Also ab Reset > lesen aus ROM, schreiben ins RAM. Nach Zugriff auf eine I/O-Adresse > schaltet das FF um, und es wird aus dem RAM gelesen. Reset-Code kopiert > ROM-Inhalt über sich selbst und schaltet dann um. Das wollte ich jetzt so nicht. Der Monitor läut schon aus dem ROM heraus, erst nach dem Laden eines User Progrs springt er rüber. Was bringt denn diese FF Geschichte für Vorteile? Und Wird da das ROM abgschaltet?
Christian J. schrieb: > Was bringt denn diese FF Geschichte für Vorteile? Die gesamten 64KB des Adressraums sind als RAM nutzbar. Es lassen sich die RST Befehle im RAM-Programm verwenden. Bei dir sind die im ROM und allenfalls über Sekundärvektoren nutzbar. > Und Wird da das ROM abgschaltet? Über einen der Ausgänge des 138ers.
!CE von RAM und EPROM muss mit MREQ verknüpft werden - oder Du bastelst Dir !MEMRD und !MEMWR. Ansonsten kommen Dir die Speicher bei IO-Zugriffen in die Quere. So, wie Du es jetzt machst, ist das Pfusch. Das merkst Du spätestens dann, wenn Du statt des UV-EPROMS entweder ein 28F256 EEPROM oder ein 29C256 Flash einsetzten möchtest. http://www.atmel.com/Images/doc0006.pdf http://www.ej9.ru/data/datasheet_ej9_at29c256.pdf Das könnte nämlich auf die Dauer wesentlich angenehmer sein. Die kleinen Unterschiede im Pinout bei Pin 1 und Pin 27 (A14, !WE, Vpp) handhabst Du über Jumper. Wurde früher auch so gemacht. Auch einen Schreibschutz kannst Du so realisieren. 100n Abblockkondensatoren nicht vergessen. fchk
So, sieht schon besser aus, Fehler auch korrigiert. Jetzt aber Feierabend und Danke Jungs! Mal schauen wie ich mich revanchieren kann. >>So, wie Du es jetzt machst, ist das Pfusch. Das merkst Du spätestens >>dann, wenn Du statt des UV-EPROMS entweder ein 28F256 EEPROM oder ein >>29C256 Flash einsetzten möchtest. Du warst jetzt schneller als ich korigieren konnte :-)
Und hier der Plan als Grundstock wer Spass hat sich da was eigenes draus zu entwickeln.... ist ja "open source" :-) Da ich alle Bausteine doppelt und dreifach habe wegen Minderbstellmenge würde ich die gerne, wenn Interesse besteht, den Herren hier verschenken, die mir derart viel geholfen haben.
wie gesagt: denke an die Jumper, um statt des 27c256 ein 28c256 oder 29c256 einsetzen zu können, wenn Du es Dir anders überlegst. Das nachträglich einzuflicken, wird hässlich. Oder ein M48Z08 oder M48Z35. Die gabs damals auch schon. Auch nahezu pinkompatibel. http://www.reichelt.de/Timekeeper-Zeropower/M-48Z35-Y70/3//index.html?ACTION=3&GROUPID=2948&ARTICLE=39921&OFFSET=16&WKID=0& fchk PS: http://www.reichelt.de/-EE-Flash-Eproms/28C256-150/3//index.html?ACTION=3&GROUPID=4510&ARTICLE=1945&SEARCH=28c256&OFFSET=16&WKID=0&
Eine Frage zum Reset: Muss der so aufwendig sein? Oder startet der Z80 auch von allein nach Anlegen der Spannung?
Ok, habe da noch was gefunden: http://books.google.de/books?id=mVQnFgWzX0AC&printsec=frontcover&hl=de#v=onepage&q&f=false Es ist vollständig einsehbar aber nicht downloadbar. Höchstens man snapshottet jede Seite einzeln :-) Heute kam auch das DDR Buch über den U080 von Amazon.
Christian J. schrieb: > Das wollte ich jetzt so nicht. Der Monitor läut schon aus dem ROM > heraus, erst nach dem Laden eines User Progrs springt er rüber. Was > bringt denn diese FF Geschichte für Vorteile? Du kannst den ganzen RAM als solchen nutzen. Der Monitor muß nicht bei 0000H liegen, sondern kann sich z.B. ans RAM-Ende verschieben. Die Vektoren bei 0x0038, 0x0018 etc. sind für Anwendercode frei. Du kannst Teile des Monitors im RAM überladen (und dadurch ausprobieren bevor du sie in ein EPROM brennst). Du kannst auch aus dem Monitor heraus ein Betriebssystem mit beliebigem Speicherlayout bootstrappen. Z.B. ein CP/M mit dem BIOS am RAM-Ende. Oder etwas ZX80-kompatibles mit dem ROM ab 0x0000. XL
> habe da noch was gefunden: http://retro.hansotten.nl/uploads/z80/BuildYourOwnZ80.pdf Gurgel mal nach Steve Ciarcia. Da wirst Du ziemlich viel finden.
Axel Schwenke schrieb: > Du kannst den ganzen RAM als solchen nutzen. Der Monitor muß nicht bei > 0000H liegen, sondern kann sich z.B. ans RAM-Ende verschieben. Die > Vektoren bei 0x0038, 0x0018 etc. sind für Anwendercode frei. Du kannst > Teile des Monitors im RAM überladen (und dadurch ausprobieren bevor du > sie in ein EPROM brennst). Du kannst auch aus dem Monitor heraus ein > Betriebssystem mit beliebigem Speicherlayout bootstrappen. Z.B. ein CP/M > mit dem BIOS am RAM-Ende. Oder etwas ZX80-kompatibles mit dem ROM ab > 0x0000. Ok, ist mir aber im ersten Ansatz zu kompliziert wenn noch nicht einmal das Einfache läuft. Mein Gedanke ist der, dass ab Start das ROM abläuft und auf Eingabe vom PC wartet, dass der ein Hex File einspielt. Das ROM hat Sprungadressen der Vektortabelle auf das RAM. Freigabe der INTS Das kann das Userprogramm dann nutzen. Denn die INTs brauche ich auf jeden Fall. So stelle ich mir das zumindest vor, habe mich damit aber noch nicht genau befasst. Wird doch hoffemntlich möglich sein im ROM weitere Sprünge zu hinterlegen, zb nachdem man gestestet hat ob Ram Code da ist.
Christian J. schrieb: > Das ROM hat Sprungadressen der Vektortabelle auf das RAM. Die Vektortabelle des IM2 kannst du platzieren wohin du willst. Sekundärvektoren über ROM ins RAM sind nicht sinnvoll. Der beschriebene Loader geht gut ohne Interrupts. Da gehts zunächst um eine einfachstmögliche Lösung um Programme vom PC ins RAM zu kriegen, mehr nicht. Das muss auch kein Intel Hex-Format sein. Ein Bootloader, der fix <n> KB binär an den Anfang vom RAM reinzieht und anspringt reicht. Der Rest passiert dann da. Eine Entwicklung über immer wieder zu brennende EPROMs ist einfach nur nervend, sollte also minimiert werden. Ein ROM-Monitor, der komplexer ist als besagter Bootloader, wird sinnvollerweise im RAM entwickelt, nicht im ROM.
:
Bearbeitet durch User
Hi, wie gesagt, dass mit dem FF ist mir zu kompliziert, ich müsste mir da erstmal eine Schritt ür Schritt Ablauffolge machen, was da im Einzelnen passiert und dann die entsprechende Logic dazu einbauen. Ich wüsste jetzt nicht wie ich die A13,14,15 Logik derart umarbeiten müsste, damit ich das RAM schwuppdiwupp da liegen habe wo vorher das ROM war und dass auch der Umschaltvorgang keinelei Probleme verursacht, weil der Z80 plötzlich im Nirgendwo ist. Eine CPU kann nicht stehen bleiben, die rennt immmer, d.h. das Umschalten müsste zwischen zwei Bus-Zyklen liegen und dann muss auch alles fertig sein im RAM. Wie Du schriebst würde ein IOREQ das FF kippen, d.h. zu dem Zeitpunkt gibt es keinen Memory-Zugriff, da der IO Befehl ja geladen wurde (Prefetch-Queue gibt es ja bei Z80 nicht), ausgeführt wird ....IOREQ kommt....zack....das RAM flippt durch Umschaltung der Adresscodierung auf den Platz des ROMs, dann kommt der nächste Buszyklus und der wird dann auf dem RAM ausgeführt an gleicher Adresse. Ich befasse mich ja erst seit 10 Tagen damit von Null an. Das schreibt sich siher einfacher hier als es ist, für jemand der das schon gemacht hat als für jemand, der das alles bis ins Detail verstehen muss, damit er es umsetzen kann. Der C64 hatte auch sowas, da lag unter dem BIOS noch RAM drunter, und man konnte umschalten. Trotzdem merke ich, dass eine gründliche Planung notwendig wird und Notizzettel nicht mehr reichen, da ich schon weit über das "Grant Minimalsystem" hinaus komme und ohnehin den Monitor neu schreiben muss. Es wird alles aus dem Ram heraus laufen, EPROMs brennen habe ich wirklich keine Lust zu zudem das ja auch nur einige Male geht. Und Retromässig bleiben die Fenster auch offen, damit man "Chip" sieht :-) Aktuell plane ich die Peripherie und wieviel Coderschalter ich brauche und wieviele Tasten. Damit das Ding auch was Sichtbares macht als Demo-Rechner und nicht nur schwarze Kästen zu sehen sind. Das Teil ist nur solange interessant, wie man daran basteln kann. Ein Attiny84 wird ein Interface zu einem 64KB EEPROM bilden, da I2C über Z80 nicht möglich ist., gibt zwar Steine die das können zb http://www.nxp.com/documents/leaflet/75016079.pdf abe ein AVR ist da die ideale Lösung mit einem Selbstbauprotokoll am PIO Port Daten des RAM ins EEPROM zu schaufeln. Eine SAVE und eine LOAD Taste werden das Userprogramm sichern und zurück laden und starten aus dem ROM heraus. Das kommt in den Monitor rein.
Christian ich lese dauernd "zu kompliziert".. Was zum Teufel willst Du eigentlich mit der Platine anfangen wenn dauernd was kompliziert ist? Ein Bisschen Nachdenken wird Dir Keiner abnehmen können. Ich weise noch darauf hin, das der CPU Clock nicht TTL konform ist, es werden CMOS Pegel benötigt (ist so auch dokumentiert). Es empfiehlt sich also einen PNP Transistor oder einen BS250 als aktiven Pullup an einem Leistungsgatter zu verwenden. Hier noch ein Bisschen Lesestoff den DU sicher in 3 Minuten überflogen hast und als zu kompliziert abhakst: http://www.z80.info/#BASICS_DATA Gruß, Holm
Holm Tiffe schrieb: > Es empfiehlt sich > also einen PNP Transistor oder einen BS250 als aktiven Pullup an einem > Leistungsgatter zu verwenden. Wenn sein Oszillator nicht sowieso schon CMOS Pegel liefert, dann hängt er eben ein HCT Gatter dazwischen.
Holm Tiffe schrieb: > Ich weise noch darauf hin, das der CPU Clock nicht TTL konform ist, es > werden CMOS Pegel benötigt (ist so auch dokumentiert). Was ist los ? Da ist alles ttl konform, auch bei mir. Der Wecker schwingt und hat einen Treiber....
Christian J. schrieb: > Was ist los ? Da ist alles ttl konform, auch bei mir. Der Wecker > schwingt und hat einen Treiber.... Andersrum. Der Takteingang der CPU hat eine ungewöhnliche Pegelanforderung und eine etwas höhere Eingangskapazität. Dein Oszillator liefert wenn du Pech hast aber nur TTL Pegel. Blick ins Datasheet hilft, bei CPU und Oszillator.
:
Bearbeitet durch User
Meint ihr jetzt die Pegel oder die Flankensteilheit? http://de.wikipedia.org/wiki/Logikpegel Ein Schmitt Trigger dürfte Abhilfe shcaffen, ich habe da aber sowieoso noch was anderes vor....
Hier die Pegel Spec..... Also wenn der Osc zwische 0.5V und 4.5V Pegel macht mit genügend "Dampf", also Push Pull Stufe, dann dürfte doch alles ok sein. Habe keinen Osczi hier, müsste ich mir mal wieder beschaffen......
Liebe Leute, bevor ihr jetzt stundenlang über nicht konformen Clock und Reset philosophiert, sollte man mal klären welche Z80 CPU jetzt Christian überhaupt einzubauen gedenkt: Einen echten original alten in NMOS (dto. die ostdeutsche Variante U880)oder doch 'ne neuere Cmos (Z84C00). Und was ist mit 74xx, sind hier "LS" oder "HC/HCT" geplant? Die reine Retrolehre ist diese Projekt sowieso nimmer. Mit 'nem Cmos Osc Baustein hast die alten LS Treiberprobleme eh nimmer. Den Kram mit der Clockauswahl (heute 08:44), weglassen! Die Resetschaltung dort ist Quark. Noch schlimmer ist die von gestern Abend 22:57, da wird der Taster recht schnell kaputt gehen (warum??). Standard ist 7705, wurde schon geraten. Oder was moderneres, wie LT1232, MIC1232. >Habe keinen Osczi hier Das kann noch ein grösseres Problem werden. Gruss
Erich schrieb: > Einen echten original alten in NMOS (dto. die ostdeutsche Variante > U880)oder doch 'ne neuere Cmos (Z84C00). Die Daten der CMOS-Version unterscheiden sich in dieser Frage nicht von der alten NMOS-Version.
Christian J. schrieb: > Ein Attiny84 wird ein Interface zu einem 64KB EEPROM bilden, da I2C über > Z80 nicht möglich ist., gibt zwar Steine die das können zb > http://www.nxp.com/documents/leaflet/75016079.pdf abe ein AVR ist da die > ideale Lösung mit einem Selbstbauprotokoll am PIO Port Daten des RAM ins > EEPROM zu schaufeln. Eine SAVE und eine LOAD Taste werden das > Userprogramm sichern und zurück laden und starten aus dem ROM heraus. > Das kommt in den Monitor rein. EEPROMs gab es zu der Zeit noch nicht. Das erste, was es gab, was der 28C64, parallel und fast 6264/27C64-pinkompatibel. Oder eben batteriegepuffertes RAM. Und wenn seriell: SPI ist deutlich einfacher zu implementieren. fchk
Joe G. schrieb: > Christian J. schrieb: >> ... ich frage nach einem Käfer und du kommst mit einem >> Panzer daher, für den es NICHTS irgendwo gibt. > > Hier sogar in zwei Varianten. Selbstverständlich mit CP/M :-) Sehr netter "Panzer" der grosse im rechten Bild :-) Wann geht der in Serie? .-)
Christian J. schrieb: > wie gesagt, dass mit dem FF ist mir zu kompliziert, ich müsste mir da > erstmal eine Schritt ür Schritt Ablauffolge machen, was da im Einzelnen > passiert und dann die entsprechende Logic dazu einbauen. Es ist zwar keineswegs so kompliziert wie du denkst, aber ja. Taktdiagramme und zu Fuß aufgebaute Decodierlogik sind doch gerade der Teil, der Retrocomputing von dem modernen Zeug unterscheidet und so interessant macht. > Ich wüsste > jetzt nicht wie ich die A13,14,15 Logik derart umarbeiten müsste, damit > ich das RAM schwuppdiwupp da liegen habe wo vorher das ROM war und dass > auch der Umschaltvorgang keinelei Probleme verursacht, weil der Z80 > plötzlich im Nirgendwo ist. Eine CPU kann nicht stehen bleiben, die > rennt immmer, d.h. das Umschalten müsste zwischen zwei Bus-Zyklen liegen > und dann muss auch alles fertig sein im RAM. Erstens: Die Idee ergibt nur dann einen Sinn, wenn du den ganzen Adreßraum (64K) voll RAM hast. Wenn du jetzt zusätzlich ein ROM hast, dann muß das in jedem Fall irgendwo ein- und das RAM entsprechend ausgeblendet werden. Zweitens: An dieser Stelle kommt jetzt ein weiteres Logiksignal ins Spiel. Nennen wir es ROMEN (wie ROM ENable). Die Dekodierlogik für das /CS von RAM bzw. ROM wird jetzt so erweitert, daß bei ROMEN=H das ROM eingeblendet ist und bei ROMEN=L eben nicht. Das ist keine Raketentechnik. Dazu braucht man nur irgendwo in der Logikkette zur Erzeugung der /CS Signale ein passendes Gatter mit einem freien Eingang. Optional kann man noch darüber nachdenken, ob man Lese- und Schreib- zugriffe separat betrachten will. Bspw. könnte man Schreibzugriffe immer ins RAM leiten, auch dann wenn an der entsprechenden Adresse eigentlich das ROM eingeblendet ist. Das macht die ganze Sache noch flexibler und war bei Heimcomputern auch üblich. Ist aber wie gesagt optional. Drittens: Das ROMEN Signal macht man jetzt nicht statisch (wozu ich auch einen manuell betätigten Schalter zählen würde) sondern generiert es selber. Da der Z80 nach RESET gerne bei 0000H ein Programm sehen möchte, ist es nur logisch, ihm das ROM bei 0000H zu zeigen und RESET das ROMEN auf H setzen zu lassen. Damit man ROMEN wieder auf L kriegt, kann man z.B. einen bisher ungenutzten Ausgang des IO-Adreßdecoders verwenden. Oder einen Pin der PIO. Oder sonst was. Und man würde wohl ein Flipflop nachschalten, das von RESET gesetzt und einem zweiten Signal gelöscht wird. Wer mitdenkt, würde vermutlich auch einen Weg vorsehen, das Flipflop per Software wieder setzen (und so das ROM einblenden) zu können. Dann kann man im Monitor einen "Warmstart" Befehl implementieren: "kopiere den Monitor frisch aus dem ROM ins RAM, laß den Rest vom RAM aber wie er ist". > Wie Du schriebst würde ein IOREQ das FF kippen, d.h. zu dem Zeitpunkt > gibt es keinen Memory-Zugriff, da der IO Befehl ja geladen wurde > (Prefetch-Queue gibt es ja bei Z80 nicht), ausgeführt wird ....IOREQ > kommt....zack....das RAM flippt durch Umschaltung der Adresscodierung > auf den Platz des ROMs, dann kommt der nächste Buszyklus und der wird > dann auf dem RAM ausgeführt an gleicher Adresse. Man kann sich alternativ auch einfach clever anstellen. Aus dem ROM führt man nur den Code aus, der den Monitor ins RAM kopiert. Dann springt man ins RAM in den Monitor und erst dort schaltet man das ROM aus. In dem Buch aus dem ich die Idee habe [1], macht es der Autor anders ^Wgenau so. Habs gerade nochmal rausgesucht. Dieses Stück Code ist sogar im Quellcode abgedruckt. Einen Scan des Hexdumps des dort verwendeten Monitors hätte ich auch noch. Mit Prüfsummen, die sogar stimmen. XL [1] "Mikroelektronik in der Amateurpraxis 3"; Teil 2: Bernd Hübler "BASIC-Kleincomputer mit Grafik". Militärverlag der DDR, 1987
Guido Lehwalder schrieb: > Sehr netter "Panzer" der grosse im rechten Bild :-) > Wann geht der in Serie? .-) Der Panzer ist schon durch, ich glaube es gibt keine Platinen mehr dazu. Den Originalthred vom Entwickler findest du übrigens hier: http://www.robotrontechnik.de/html/forum/thwb/showtopic.php?threadid=10189
Hi, Leute nehmt es mir nicht übel aber aus der Sicht des TS der jeden Beitrag liest wird es langsam "widersprüchlich", zb das mit der Reset Schaltung(taugt was, taugt nichts..... das sind Schaltungen aus Büchern!), der nächste kommt mit dem Clock usw. Da sind sich einige selbst nicht einig. Ich verwende eine moderne Z80 Typ C (habe aber auch andere hier, eine uralte "A" auch noch) und ansonsten nur HCT und LS Chips, was grad da ist. HCT aber 90%. Mir ist Retro wurst solange es funktioniert und ich mich nicht tot suche, zudem ich noch einen Oszi anschaffen muss. Der alte hat es hinter sich und ziert die Müllhalde. Diese Umschaltgeschichte ist jetzt vom Tisch bei mir, bei 8k ROM und 56k Ramist genug Platz für alles und CP/M wird nie laufen bei mir, da ich da keine Lebensaufgabe draus machen will und in 3 Wochen das Board hier fertig haben möchte. Wie es geht weiss ich aber jetzt, die 8kb ROM aus dem RAM aus wegblenden ist nicht so schwer. Aber wie zum Teufel soll man dafür noch Code erzeugen? Ich werde mit C arbeiten im Userprogramm und den Monitor mit Asm schreiben. Da ich bisher keine einzige Zeile geschrieben habe für den Z80 wird das auch noch mal einiges an Zeit kosten da erste Erolge zu sehen. Ich werde dennoch eine Dualtaktung bauen, eine mit 2 Hz und eine normale. Und die "Spielereien" mit dem Ausblenden und Einblenden braucht man nicht, wenn man nur etwas damit spielen will un sich freut, wenn es funktioniert. Also...... Resetschaltung für Taster ok? Oder nicht? Clock duch Inverter durchjagen? Ok? Gruss, Christian
Christian J. schrieb: > Holm Tiffe schrieb: >> Ich weise noch darauf hin, das der CPU Clock nicht TTL konform ist, es >> werden CMOS Pegel benötigt (ist so auch dokumentiert). > > Was ist los ? Da ist alles ttl konform, auch bei mir. Der Wecker > schwingt und hat einen Treiber.... Ist es nicht. Gruß, Holm
Erichs Kritik in Ehren, aber etwas konstruktiver hätte er schon auftreten können. Kannst dem Schalter, der den Elko kurzschliesst, noch ein 100 Ohm Widerstand in Reihe verpassen. Dann blitzt es nicht so und er lebt länger.
A. K. schrieb: > Holm Tiffe schrieb: >> Es empfiehlt sich >> also einen PNP Transistor oder einen BS250 als aktiven Pullup an einem >> Leistungsgatter zu verwenden. > > Wenn sein Oszillator nicht sowieso schon CMOS Pegel liefert, dann hängt > er eben ein HCT Gatter dazwischen. Was hast Du gegen einen einzelnen BS250 ohne weitere Bauteile? Source an VCC, Gate an en Eingang eines Negators, Drain an den Ausgang des Negators..ferdsch. Sieht sogar auf dem Oszillograf chick aus. Gruß, Holm
Holm Tiffe schrieb: > Was hast Du gegen einen einzelnen BS250 ohne weitere Bauteile? Oben schrieb mal wer, dass jemand, dem schon der SIO zu kompliziert ist ... Er sollte immerhin verstehen, was er da tut.
Holm Tiffe schrieb: > Was hast Du gegen einen einzelnen BS250 ohne weitere Bauteile? > Source an VCC, Gate an en Eingang eines Negators, Drain an den Ausgang > des Negators..ferdsch. Und was ist daran einfacher, als der Negator ohne BS250? ;-)
A. K. schrieb: [..] > > Und was ist daran einfacher, als der Negator ohne BS250? ;-) Ein transistor anstatt einem zusätzlichen IC mit mindestens 14 Beinen auf einer kleinen Eurokarte.. Latürnich nur wenn nicht das Gatter sowieso gerade irgendwo übrig ist. Gruß, Holm
OK, Christian sollte zunächst mal sein Schaltbild etwas weiterbringen, dann kann man über einzelne Punkte nochmals diskutieren. Hier noch der Link auf ein wirklich kleines System. http://petersieg.kilu.de/miniz80/miniz80.html Wurde erfragt hier Beitrag "Re: einfache Z80 Schaltung" aber dort hat dann der Fragesteller nicht mehr geantwortet. Schade daß die anderen Spezialisten hier (prx) und (souleye) darauf nicht verwiesen haben. Letzten Beitrag dort beachten; ein Jammer! Meinen alten Kram hab' ich noch irgendwo, muss ihn nur in den Listen finden... @Christian: Wennste schon 32-Pin-Ram einbaust, kannst nebendran den Sockel für's Eprom auch als 32-Pin machen. Auch wenn zunächst nur 27C256 reinkommt. Warum, schreibe ich dir später einmal. Aber Stichwort ist 29F010 (29F040). Da finde ich ein Stück SW bei mir... Gruss
Holm Tiffe schrieb: > Ein transistor anstatt einem zusätzlichen IC mit mindestens 14 Beinen > auf einer kleinen Eurokarte.. Und woher kommt dein Negator, wenn kein Gatter übrig ist?
Christian J. schrieb: > Ich verwende eine moderne Z80 Typ C (habe aber auch > andere hier, eine uralte "A" auch noch) Was steht genau auf dem Chip? "Typ C" gibt es nicht. Es gibt NMOS und CMOS Chips NMOS, Zilog Bezeichnung: Z8400 (+Zusatz) 2,5 MHz Z80 4 MHz Z80A 6 MHz Z80B 8 MHz Z80H CMOS, Zilog Bezeichnung Z84C00x 6 MHz Z84C006 8 MHz Z84C008 10 MHz Z84C0010 20 MHz Z84C0020 Wahrscheinlich gibts noch mehr, und andere Hersteller haben noch andere Bezeichnungen. Für Deine Schaltung macht es einen Unterschied, ob Du eine NMOS- oder eine CMOS-CPU einsetzen willst.
Leo C. schrieb: > Für Deine Schaltung macht es einen Unterschied, ob Du eine NMOS- oder > eine CMOS-CPU einsetzen willst. Worin? Klar, eine vorneweg für CMOS gebaute Schaltung kann stellenweise 74HC verwenden, weshalb die NMOS Version dann scheitert. Aber inwiefern sollte eine für NMOS gebaute Schaltung mit der CMOS Version Probleme bekommen? Es sei denn natürlich, er erwischt einen NSC800. ;-)
:
Bearbeitet durch User
A. K. schrieb: > Holm Tiffe schrieb: >> Ein transistor anstatt einem zusätzlichen IC mit mindestens 14 Beinen >> auf einer kleinen Eurokarte.. > > Und woher kommt dein Negator, wenn kein Gatter übrig ist? Alex! Gruß, Holm
Leo C. schrieb: [..] > > Wahrscheinlich gibts noch mehr, und andere Hersteller haben noch andere > Bezeichnungen. > > Für Deine Schaltung macht es einen Unterschied, ob Du eine NMOS- oder > eine CMOS-CPU einsetzen willst. Wieso eigentlich nur CPU, die restlichen Peripherie-ICs betrifft das genau so. Gruß, Holm
Leo C. schrieb: > Christian J. schrieb: >> Ich verwende eine moderne Z80 Typ C (habe aber auch >> andere hier, eine uralte "A" auch noch) > > Was steht genau auf dem Chip? > > "Typ C" gibt es nicht. > Es gibt NMOS und CMOS Chips > > NMOS, Zilog Bezeichnung: Z8400 (+Zusatz) > 2,5 MHz Z80 > 4 MHz Z80A > 6 MHz Z80B > 8 MHz Z80H > > CMOS, Zilog Bezeichnung Z84C00x > 6 MHz Z84C006 > 8 MHz Z84C008 > 10 MHz Z84C0010 > 20 MHz Z84C0020 Z8420BB1 Z84C0BB6 Klar macht das einen Unterschied! Ob 7400N oder 74LS00 macht auch einen :-) Die ....N habe ich mal alle wegeworfen, 50mA pro Chip waren etwas viel. Specialfrage für Holm: Glaubst Du .... bei Röhren gibt es ja auch vielleicht sowas .... dass es was ausmacht, wenn ich deinen Takt von 3,6Mhz duch den Inverter eines unschuldigen 7414 Inverter Gatters jage und gleich nebenan, sozusagen als Nachbarn liegt die reset Schaltung auf den beiden anderen Invertern. Merkt der Reset ob der Nachbar dauernt mit dem Presslufthammer arbeitet? :-)
Christian J. schrieb: > Kla macht das einen Unterschied! Ob 7400N oder 74LS00 macht auch einen Weshalb es angebracht wäre, im Schaltplan die realen Typen zu zeigen, nicht das, was ist der Liste zufällig oben stand. Oder meist du mit 7432/74138 wirklich die TTLs erster Generation?
> Z8420BB1 Das müßte eine PIO sein, keine CPU. > Z84C0BB6 Da stimmt was nicht. Scheint (auch) keine CPU zu sein.
:
Bearbeitet durch User
Links die CPUs.... >>Weshalb es angebracht wäre, im Schaltplan die realen Typen zu zeigen, >>nicht das, was ist der Liste zufällig oben stand. Oder meist du mit >>7432/74138 wirklich die TTLs erster Generation? Ja, schon als Kind holte ich die vom Sperrmüll etc aus Platinen raus, das war ca 1975. Ich hatte hunderte dieser "Käfer". So mit ca 10 betrieb ich die dann auch mal und merkte, dass sie 50ma "fressen". Dann kamen CD .... und die konnten nicht mal Leuchtiode treiben. Die Z80 kann eine blaue LED treiben, die sieht man noch mit 200uA hell genug.
"Darf" man die CMOS mit den alten kombinieren? Würd ich mich nicht trauen.
Harald schrieb: > "Darf" man die CMOS mit den alten kombinieren? Würd ich mich nicht > trauen. Also mit HCT ahre ich bisher immer gut, die haben hohen Eingangswiderstand, hohe Treiberleistung und sind TTL komptibel. Alles andere kenne ich auch nicht. Eine CMOS CPU wird wohl damit klarkommen, man merkt es sicher auch und sieht es au dem Oszi wenn da zu sehr was daneben liegt.
Die Daten der NMOS und CMOS Versionen der Z80 CPU sind ziemlich gleich, was die Pegel in einer Mischumgebung angeht. Die Timings habe ich nicht verglichen. Ich sehe keinen Grund, weshalb NMOS und CMOS Versionen von CPU und Peripherie nicht miteinander kooperieren sollten. Nur auf 74HC Bausteine sollte man verzichten. 74LS00 ist ok, 74HCT00 ist ok, aber 7400/74S00 haben neben dem Stromverbrauch einen zu hohen Fanin. Auch CD4000er sind tabu.
Ok, zurück zum Thema ..... wenn ich gleich vom Walken wiederkomme wolllte ich etwas basteln: Reset Schaltung ok, aber es blitzt eben. Ok, .... C etwas kleiner machen. Ausgang des Oszillator leite ich dann durch ein Inverter HCT Gatter aber leider sind dazu 6cm Lutstrecke nötig, d.h. er liegt nicht mehr direkt am Pin. Ok. Außerdem werde ich einen Jumper ür den Takt einbauen, so dass ich noch über einen CD4060 einen erzeugen kann, auch über HCT Gatter aun den Clock. Das sollte auch erstmal genügen ür heute...
Was die Logikchips betrifft war mir schon klar. Ich meinte CPU und Peripherie unterschiedlicher Typen.
Bisschen Grundlagen zu Mischkonfigurationen: In der Anfangszeit der Z80 üblich waren NMOS LSI-Chips kombiniert mit LS-TTL Logik, also 74LS00. Das war also schon ein Mix, aber die Pegel solcher NMOS-ICs orientierten sich notwendigerweise an TTL Pegeln, zumal das auch technisch passte. Sogar die ollen und langsamen PMOS-Chips mussten sich an TTLs orientieren, und da passte das eigentlich nicht so recht. Auch damalige CMOS Mikroprozessoren (z.B. NSC800 = Z80 in CMOS, aber inkompatiblem Gehäuse) orientierten sich teilweise an TTL Logik. RCA tat dies beim CDP1802 zwar nicht, aber die hatten ihre eigene CD4000er Logik im Auge. Und hatten Probleme beim Anschluss von normalem Speicher ausserhalb der RCA Reihe, denn normaler Speicher lieferte TTL Pegel und passte folglich nur mit Pegelkonverter an den Datenbus. Also dann CMOS in Breite aufkam, einerseits als 74HC(T) Logik, andererseits in den Mikroprozessoren der 80er, mussten die sich mit der bestehenden Welt arrangieren. Der Rest der Welt war ja weiterhin teils TTL, teils NMOS. Man konnte nicht alles mit einem Schlag umstellen und musste noch lange Zeit mit bestehender NMOS Peripherie und über TTL definierten Bussytemen auskommen. Also: Auch wenn Zilog die eigene Linie in einem Rutsch umstellte, mussten die Anwender weiterhin mit bestehenden Bausteinen anderer Hersteller leben. Mischkonfigurationen waren deshalb völlig normal. Deshalb gab es die TTL kompatible 74HCT00 Serie neben der nicht kompatiblem 74HC00 Serie. Und deshalb erwarten CMOS Prozessoren dieser Generation meist TTL-Pegel am Interface, keine CMOS-Pegel. Dass dies nicht auf alle Pins zutreffen muss, das wurde schon anhand des Takteingangs gezeigt. Der hatte schon in der NMOS Version eine sehr eigene Pegeldefinition. Überrascht hat mich eher, dass dies sogar noch auf die CMOS Version zutrifft.
Christian J. schrieb: > dass ich noch über einen CD4060 einen erzeugen kann Am 3,6MHz Takt wird das eng, den dieser Kollege hat bei 5V eine Maximalfrequenz von typisch 4MHz, mindestens 1,5MHz.
:
Bearbeitet durch User
Christian J. schrieb: > Reset Schaltung ok, aber es blitzt eben. Ok, .... C etwas kleiner > machen. Nö. Kleinen Widerstand in Reihe zum Schalter machen. > leider sind dazu 6cm Lutstrecke nötig Stört nicht. Die Taktleitung landet ja auch beim STI, und der wird wohl auch nicht direkt passend liegen. Nur wärs empfehlenswert, diese Taktleitungen nicht auf Länge parallel zu anderem Kram im Fädelkamm zu ziehen.
:
Bearbeitet durch User
Christian J. schrieb: > Z84C0BB6 Das ist ein Druckfehler. > > Klar macht das einen Unterschied! Ob 7400N oder 74LS00 macht auch einen > :-) Die ....N habe ich mal alle wegeworfen, 50mA pro Chip waren etwas > viel. Ich habe Rechner, bei denen 50mA mehr nicht auffallen aber in denen ein LS00 statt einem 00 nicht arbeitet. > > Specialfrage für Holm: > > Glaubst Du .... bei Röhren gibt es ja auch vielleicht sowas .... dass es > was ausmacht, wenn ich deinen Takt von 3,6Mhz duch den Inverter eines > unschuldigen 7414 Inverter Gatters jage und gleich nebenan, sozusagen > als Nachbarn liegt die reset Schaltung auf den beiden anderen Invertern. > Merkt der Reset ob der Nachbar dauernt mit dem Presslufthammer arbeitet? > :-) Nein. Gruß, Holm
Hallo, hier ist der vorläufige Stand. Es ist kein Konstruktionsplan, daher sind Massen auch nicht eingezeichnet und auch keine Blockkondensatoen, damit es nicht unübersichtlich wird. NMI ist noch frei und auch der INT des ADC liegt noch offen. Da muss ich mal schauen was damit machen. NMI für ADC ist mir zu viel, vielleicht ein Taster mal schauen.
Christian J. schrieb: > auch der INT des ADC liegt noch offen. Nu haste in der Kiste eigens einen Interrupt-Controller mit 8 Eingängen und willst ihn nicht nutzen?
Ich vermute mal das die STI sich über ein CLK Signal freuen würde. NMI und INT kannst Du erst mal mit einem Pullup (2,2k z.B.) nach VCC beschalten. Die Treibenden Ausgänge sind open Drain. Gruß, Holm
Das mit dem Takt müssen wir wohl noch ein paar Wochen üben. Ein 7414 Standard-TTL ist als Pegelkonverter für den Takteingang der CPU sowas von deplaziert. Das muss 74HCT sein. Und wenn das kein 7414 ist, dann schreib nicht 7414 ran. Dito 7432. Zum NMI: Was immer du damit machen willst: Du willst ihn garantiert nicht offen lassen.
:
Bearbeitet durch User
>Bisschen Grundlagen zu Mischkonfigurationen: Da habe ich jetzt auch einen Beitrag in Form des beigefügten Bilds. Ist ein Einplatinencomputer; kein herausgeführter Bus, nur I/Os. Die Platine hat ca. die Maße 280x225 mm, stammt lt. Labelaufkleber von der Fa. Bergmann (Spielautomaten). War aber wohl eher so'n Testgerät dafür, denke ich. Ein Ebaykauf, schon länger her, lag etwas eingestaubt im Keller bei mir. Am Datecode "9229" erkennbar hergestellt nach Mitte 1992. Mit 'ner schönen Mischbestückung, CPU, CTC und viele PIOs in NMOS, die beiden SIOs in Cmos (Tosbiba). Habe kein Schaltbild dafür. Decodierung für Memory und IO ist aber easy, da '138 Decoder, keine PALs/GALs. Schwieriger sind schon die ganzen Stecker aussenrum, muss man alles rauspiepsen. Naja, RS232 4x über die 2 Maxims, eh klar, das sind ja nicht so viele Pins (links oben). Spannungsregler "TA7805S", ist aber auch nur 1A (Toshiba). Die Platine zieht am Eingang des 7805 nur gute 0,6A ; erstaunlich. Platine ist nur 2-Lagen, keine Smds, Rückseite nur Leiterbahnen. Mein Respekt an den Layouter! Programm unbekannt, läuft jedoch, denn kurze Piepser und LED-Blinksequenzen kommen und nach ca. 10s kommt lauter Piepton, dann ist wohl Programmende/Abbruch. Über'n Winter werd' ich mal mein Monitorprogramm draufsetzen, wenn ich die SIO und Baudrate rausgepiepst habe. Nett sind die vielen Opto in und ULN Ausgänge, insofern wär' Schaltbild bzw. Steckeranschlußplan schon gut. ----> Wer dafür Schaltbild hat, bitte hier melden! Gruss
Auch schön ist das Drumrum. Eine kunterbunte Mischung aus 74HC, 74HCT, 74LS, 74-Std und CD4000. Fehlt eigentlich nur 74S. Und der HC138 an einer NMOS CPU wirkt etwas schräg. An alle Freunde von Bustreibern, von wegen knappem Timing, Fanin, Fanout und so: findet ihr welche? Da sind circa 18 VLSIs Devices am Bus, zzgl. Gatter.
:
Bearbeitet durch User
A. K. schrieb: > Das mit dem Takt müssen wir wohl noch ein paar Wochen üben. Ein 7414 > Standard-TTL ist als Pegelkonverter für den Takteingang der CPU sowas > von deplaziert. Das muss 74HCT sein. Es gibt keine HCT in der Lib ! Das ist nur ein Plan zum Verdrahten. Ich definiere mir doch keine neuen Bausteine, nur weil da ein Buchstabe fehlt.
Christian J. schrieb: > Es gibt keine HCT in der Lib ! Was für ein Programm ist das denn, in dem es keine andern Logikbausteine als TTL-Urfassung gibt? Kannst es auch separat in einem Eck als Text ranschreiben. Das wird ja wohl gehen. Spart dämliche Kommentare von irritierten Lesern.
Holm Tiffe schrieb: > Ich vermute mal das die STI sich über ein CLK Signal freuen würde. > NMI und INT kannst Du erst mal mit einem Pullup (2,2k z.B.) nach VCC Die hat ein Clock, es reicht wenn man den Netzen die gleichen Namen gibt anstatt ein Knäuel Leitungen durchs Design zu ziehen. In jobtechnischen Designs mache ich gar keine Leitungen rein bei uc, nur noch Bezeichner. Bei 144 Pins würde man sonst Augenkrebs kriegen.
Nur so aus Neugierde: Was für jobtechnische Designs macht du? Angesichts deiner Kenntnisse und Fragen liegt entsprechende Erfahrung nicht unbedingt nahe.
:
Bearbeitet durch User
Erich schrieb: >>Bisschen Grundlagen zu Mischkonfigurationen: > > Da habe ich jetzt auch einen Beitrag in Form des beigefügten Bilds. > Ist ein Einplatinencomputer; kein herausgeführter Bus, nur I/Os. > Die Platine hat ca. die Maße 280x225 mm, stammt lt. Labelaufkleber von > der Fa. Bergmann (Spielautomaten). War aber wohl eher so'n Testgerät > dafür, denke ich. Ein Ebaykauf, schon länger her, lag etwas eingestaubt > im Keller bei mir. > Am Datecode "9229" erkennbar hergestellt nach Mitte 1992. Damit kannste nix anfangen. Das sind I/O Karten für Geräte mit vielen Relais oder Lampen bzw Eingängen. Der Z80 wurde extrem aufgebohrt mit Ports. Ich würde da einen Bunsenbrenner mit Flachdüse hinter halten, vorne eine Crimpzange und die PIO's etc alle rausholen. geht bei mir ratzfatz sowas, 2s sind die draußen. Die Elkos, Batterie usw. dürften alle hinüber sein.
>Damit kannste nix anfangen. Hä? Wie meinen? Wie kommst DU auf das schmale Brett? Was weisst DU schon womit ich was anfangen kann? Geht's noch? Ich habe sämtliches Equipment für den Z80. Dinge, die du wahrscheinlich nicht mal gehört hast daß es sowas gibt oder gab. Ich habe fast 20 Jahre aktiv an entsprechenden Designs gearbeitet. In unterschiedlichen Firmen und Branchen. Angefangen beim 2708 und 2102. Endend mit dem TMPZ84C015 und drumrun, hier angedeutet Beitrag "Re: Retro Fieber: Z80 oder 68000 ?" Gruss und Gute Nacht.
Auf der weiter oben schon zitierten z80.info Seite findet sich auch noch mein altes Standalone Steuercomputer Projekt in Europlatinen-Größe. Ich häng Euch mal den Schaltplan ran. Highlight der Software ist u.a.eine SPS-ähnliche Programmierung mit bis zu 8 Threads und Programm-Eingabemöglichkeit via 3x4er Tastaturmatrix. Bei Interesse (PM) gerne mehr, Platinen und andere Bauteile wären auch noch vorrätig ;-)
Na, da ist bei LCD wenigstens mal eine saubere Erzeugung von R/W und E eines 6800 Busses drin. Bizarr: Wenn RAM2 ein EEPROM ist und per Port reingemappt wird, dann hat man zwar 32KB EPROM und 32KB EEPROM, aber 0 KB RAM. Was soll dieser Spuk?
:
Bearbeitet durch User
Christian J. schrieb: > Sorry, Vorgänger, hier der letzte Stand..... Das wird so nicht funktionieren. Du wehrst Dich ständig gegen ein Ein- und Ausblenden des EPROM. Ein gleichzeitiger Betrieb von RAM und EPROM geht aber so, wie Du es vorhast, nicht!
Route 66 schrieb: > Ein gleichzeitiger Betrieb von RAM und EPROM > geht aber so, wie Du es vorhast, nicht! Weshalb? Die ersten 8KB gehören dem EPROM, der Rest ist RAM.
Christian J. schrieb: > Es gibt keine HCT in der Lib ! Das ist nur ein Plan zum Verdrahten. Ich > definiere mir doch keine neuen Bausteine, nur weil da ein Buchstabe > fehlt. Natürlich nicht. Es gibt nur die Grundtypen. Ob das Dingsbums mit den sechs Invertern jetzt 7404, 74LS14, 74HCT14 oder SN74LVT14D-Q1 heisst, steht in dem >VALUE-Attribut. Das passt man nach Bedarf im Schaltplan an.
A. K. schrieb: > Weshalb? Die ersten 8KB gehören dem EPROM, der Rest ist RAM. Simmt. /CE vom EPROM geht ja an CE2 vom RAM
Route 66 schrieb: > Christian J. schrieb: >> Sorry, Vorgänger, hier der letzte Stand..... > > Das wird so nicht funktionieren. Du wehrst Dich ständig gegen ein Ein- > und Ausblenden des EPROM. Ein gleichzeitiger Betrieb von RAM und EPROM > geht aber so, wie Du es vorhast, nicht! Hallo, nicht böse sein, dass ich mich etwas aus dem Thread zurückgezogen habe, weil man mit immer neuen "Neuigkeiten" konfrontiert wird und sich dann fragt ob man noch auf dem rechten Kurs ist. Natürlich geht das, ging schon immer auch mit 8085. Memory ist Memory, wohin der PC zeigt ist dem Z80 egal, hauptsache die Weichen (Decoder) werden richtig gestellt. Da ich etwas Zeit hatte, habe ich die Verdrahtungfehler korrigiert - nicht gut nachts zu arbeiten und sich bei den Pins zu verzählen bzw. "spiegelbildlich" zu verdrahten. Und bevor es weitergeht muss ich erstmal im Zaks lesen, bzw dem DDR Buch über den U880 was heute gekommen ist. Außerdem fehlt mir noch der Programmer und ein Oszi muss auch wieder her. Und über LS, HCT und HC mache ich mir echt keinen Bart in einer Hobbyzeichnung. Es ist real alles HCT und das genügt mir auch. Sobald es läuft teste ich mal LS und man wird sehen.
Christian J. schrieb: > Und über LS, HCT und HC mache ich mir echt keinen Bart in einer > Hobbyzeichnung. Offensichtlich. Wenn du dann aber ein solches Oevre postest, um mögliche Kommentare zur Verbesserung zu erheischen, dann sorgt das für Verwirrung. Mindestens erklärende Worte wären dann angebracht.
:
Bearbeitet durch User
A. K. schrieb: > Christian J. schrieb: >> Und über LS, HCT und HC mache ich mir echt keinen Bart in einer >> Hobbyzeichnung. > > Offensichtlich. Wenn du dann aber ein solches Oevre postest, um mögliche > Kommentare zur Verbesserung zu erheischen, dann sorgt das für > Verwirrung. Mindestens erklärende Worte wären dann angebracht. Ok, wir sitzen uns hier ja nicht gegenüber, so dass man erklärende Worte mit einfügen kann..... PS: Oben ist ein Bild, ist die CPU von Signetics ein NMOS?
Da ist mehr als ein Bild, aber in keines mit Signetics. Wenn du das mit "SGS" meinst - das ist SGS, später SGS-Thomson, heute STM.
:
Bearbeitet durch User
Christian J. schrieb: > Oben ist ein Bild, ist die CPU von Signetics ein NMOS? Ja. Steht doch drauf: "Z8400". Und es ist eine für 2.5MHz: "Z80CPU" XL
Christian J. schrieb: > Klar macht das einen Unterschied! Ob 7400N oder 74LS00 macht auch einen > :-) Die ....N habe ich mal alle wegeworfen, N steht für die Gehäuseform (Pastic-Dual-Inline, bei TI). Ich wette, auf Deinen 74LS00 ist auch ein N angehängt. > NMI für ADC ist mir zu viel, vielleicht ein Taster mal schauen. Die Pullups wurden ja schon mehrfach erwähnt. Ene Taste an NMI halte ich nicht für sinnvoll, aber wenn Du das wirklich machen willst, dann nur mit Entprellung. A. K. schrieb: > Auch schön ist das Drumrum. Eine kunterbunte Mischung aus 74HC, > 74HCT, > 74LS, 74-Std und CD4000. Fehlt eigentlich nur 74S. Ich finde keine 74HCT in dem Bild. iInteressant finde ich die 4584B die alle gesockelt sind. > Und der HC138 an einer NMOS CPU wirkt etwas schräg. Das sehe ich auch so. Ansonsten ist gegen HC nichts einzuwenden. Mit CMOS-CPU könnte Christian auch HC stat HCT nehmen (Akademisch, da er ja nur HCT hat).
Leo C. schrieb: > Ich finde keine 74HCT in dem Bild. Stimmt. HC1, nicht HCT. ;-) > iInteressant finde ich die 4584B die alle gesockelt sind. Das folgt ungefähr der Regel, dass was nach draussen geht gesockelt ist. Also die Schmitt-Trigger 4584 (Eingänge) und die ULN2004 (Ausgänge). Was ist eigentlich ein OKI M82X42B?
:
Bearbeitet durch User
A. K. schrieb: > Was ist eigentlich ein OKI M82X42B? Das ist eine RTC http://www.alldatasheet.com/datasheet-pdf/pdf/11263/OKI/MSM62X42B.html
A. K. schrieb: > Das soll eine 6 sein? ;-) Scheinbar ja, denn diese Anordnung neben der Stützbatterie und das Gehäuse sind eindeutig. Ich muß mal im Keller nachsehen, ob bei meinem IC die 6 auch so undeutlich ist.
Passt schon. Denn mit 82 gibts weit und breit nix. Nie wieder OKI Drucker. ;-)
:
Bearbeitet durch User
A. K. schrieb: > Das folgt ungefähr der Regel, dass was nach draussen geht gesockelt ist. > Also die Schmitt-Trigger 4584 (Eingänge) und die ULN2004 (Ausgänge). Schmitt-Trigger und 15V Eingangsspannung. Und ja, gelegentlich Chip tauschen, ist wohl billiger, als eine gute Schutzbeschaltung. > Das soll eine 6 sein? ;-) Ach, so ist es ja einfach. Christian J. schrieb: > Außerdem fehlt mir noch der Programmer In dem Buch von Steve Ciarcia, daß Du neulich ausgegraben hast, sind mindestens 3 Programmer für den 2708 drin. Das erste mit manueller Address- und Dateneingabe über Kippschalter. ;-)
Leo C. schrieb: > Schmitt-Trigger und 15V Eingangsspannung. Fast alle 4000er erlauben nur Vdd+0,5V. Die 4049/4050 mit abweichender Eingangsschutzschaltung sind die Ausnahme.
Leo C. schrieb: > Das erste mit manueller Address- und Dateneingabe über Kippschalter. ;-) Würde für eine einfachen Bootloader sogar reichen. Muss ja nicht viel rein: STI-UART initialisieren, <n> Bytes reinziehen, springen.
A. K. schrieb: > Fast alle 4000er erlauben nur Vdd+0,5V. Die 4049/4050 mit abweichender > Eingangsschutzschaltung sind die Ausnahme. Autsch, dachte es wär ein 4049 mit Schmitt-Trigger. Ich hätte das Datenblatt doch richtig anschauen sollen. A. K. schrieb: > Würde für eine einfachen Bootloader sogar reichen. Muss ja nicht viel > rein: STI-UART initialisieren, <n> Bytes reinziehen, springen. Ich halte die Idee auch nicht für ganz abwegig. Für modernere EPROMs würde die Schaltung auch noch etwas einfacher werden. Die Schaltung auf dem Photo habe ich mal zusammengeklopft, um ein EEPROM zu programmieren. Die könnte man auch für EPROMs erweitern.
A. K. schrieb: > Bizarr: Wenn RAM2 ein EEPROM ist und per Port reingemappt wird, dann hat > man zwar 32KB EPROM und 32KB EEPROM, aber 0 KB RAM. Was soll dieser > Spuk? Das EEPROM dient hier nur als eine Art Disk für SPS- Anwenderprogramme. Diese werden dann vor Ausführung via CPU-Register in das RAM kopiert.
:
Bearbeitet durch User
Weiter oben jat jemand behauptet, das Schrittbetrieb nur bei S-RAM geht. Aber es geht auch mit D-RAM. Mit ein paar FF geht es aber. Bei KRAMER bin ich fündig geworden. Reinkopieren möchte ich es nicht, mit dem Nachfolger des DDR-Militärverlages ist nicht zu spaßen.
Michael_ schrieb: > Weiter oben jat jemand behauptet, das Schrittbetrieb nur bei S-RAM geht. > Aber es geht auch mit D-RAM. > Mit ein paar FF geht es aber. Bei KRAMER bin ich fündig geworden. > Reinkopieren möchte ich es nicht, mit dem Nachfolger des > DDR-Militärverlages ist nicht zu spaßen. Der Jemand war ich, gib mal die Seitennummer.... (Die Veröffentlichung einer Textstelle als Auszug bringt Dich in keinerlei Copyrightprobleme, Du kopierst ja nicht das Buch, sondern zitierst) Das das Prinzipiell funktioniert wenn der Refresh weiter gewährleistet ist, ist klar, ich habe aber mit kommerziellen Rechnerbausteinen des K1520 Systems zu tun gehabt, da war keine Eigenbauhardware involviert die das hätte bewerkstelligen können. Das der Einzelschrittbetrieb mit einer sogenannten Bedieneinheit K7622, die eine Refreshlogik enthielt, möglich war, ist eine andere Baustelle... Gruß, Holm
Michael_ schrieb: > Es ist Bild 1.26 S.39. Und was läßt dich glauben, die da gezeigte Simpel-Schaltung würde mit dRAM funktionieren? Die hält /WAIT schlicht aktiv und in dieser Zeit passiert auf dem Bus nichts, insbesondere auch kein Refresh. XL
Hier noch die Schaltung für alle, die nicht wissen was "der Kramer" ist. Oder die ihn gerade nicht haben ;) XL
Ja, habe den Kramer und hatte ja nach der Seite gefragt. Michael_ dies ist eine "normale" schaltung die den Prozessor so lange im Wait festhält, bis man die Schritt-Taste wieder drückt. Im Wait Zustand hält der Prozessor alle seine Signale statisch am Bus gleich solange /WAIT aktiv ist. Damit entfallen aber sämtliche Refreshcyclen auf dem Bus und der DRAM verliert deshalb seinen Inhalt. Klar funktioniert die Schaltung auch mit DRAM, aber der DRAM funktioniert nicht mit der Schaltung... Um das zu erreichen ist deutlich mehr Aufwand erforderlich, man muß dem Prozessor nach jedem Befehl den BUS wegnehmen und den Refresh selbst durchführen. Gruß, Holm
Allein - wo kriegt man heute noch passendes DRAM in passender Grösse? Vorzugsweise in der 16Kbit Version mit 3 Spannungen. Daher muss man wohl gezwungenermassen mit SRAM vorlieb nehmen und kann nicht ausprobieren, nach wievielen Sekunden der Inhalt tatsächlich entschwindet.
A. K. schrieb: > Allein - wo kriegt man heute noch passendes DRAM in passender Grösse? > Vorzugsweise in der 16Kbit Version mit 3 Spannungen. Daher muss man wohl > gezwungenermassen mit SRAM vorlieb nehmen und kann nicht ausprobieren, > nach wievielen Sekunden der Inhalt tatsächlich entschwindet. Machst Du Witze? U256/4116/K565RU3A habe ich da, sogar K565RU1 aka 2107, neu in OVP.. ...sagt Dir evita.lt was? Gruß, HOlm
Holm Tiffe schrieb: > Machst Du Witze? Ja, gelegentlich schon. > ...sagt Dir evita.lt was? Das Mädel kenn ich nicht und mein Litauisch ist nicht so besonders. > U256/4116/K565RU3A habe ich da Ich fürchte, Christian bleibt dennoch lieber bei seinem etwas aus der Zeit fallenden SRAM.
:
Bearbeitet durch User
A. K. schrieb: > Holm Tiffe schrieb: >> Machst Du Witze? > > Ja, gelegentlich schon. > >> ...sagt Dir evita.lt was? > > Das Mädel kenn ich nicht und mein Litauisch ist nicht so besonders. Das ist aber eine echte Bildungslücke. Wenn Du nicht so gut in Litausch bist, empfehle ich Dir mal auf den "EN" Link ganz oben zu clicken, es sei denn Du bevorzugst "RU". Anmerkung: Litauen ist EU Land. > >> U256/4116/K565RU3A habe ich da > > Ich fürchte, Christian bleibt dennoch lieber bei seinem etwas aus der > Zeit fallenden SRAM. Ich hoffe es inständig. Gruß, Holm
Holm Tiffe schrieb: > Das ist aber eine echte Bildungslücke. Ok, dann also in Englisch. Und was soll ich da finden? Suchen funktioniert bei mir nicht, das Angebot russischer Chips sagt mir nichts, deren Datasheets kann ich nicht lesen, und der Rest ist teils leicht angestaubt aber nicht derart exotisch.
:
Bearbeitet durch User
Logisch das Du fragst woher man irgendwelches Zeuch bekommt.. ist so ähnlich wie bei Christian. "Verstehe ich nicht" oder "kann ich nicht lesen" oder "sagt mir nichts" ist so ziemlich das Selbe.. Kennst Du noch ein Angebot für einen 8080A für 62 Cent? Gruß, Holm
Holm Tiffe schrieb: > Kennst Du noch ein Angebot für einen 8080A für 62 Cent? Nö. Aber wenn ich einen suchen würde, dann wärs mir egal ob der 0,62€ oder 6,20€ kostet, denn ich bräuchte ganz sicher keine 100 Stück davon. Abgesehen davon finde ich dort zwar einen 8085AH für 5,50@, aber keinen 8080A. Jedenfalls nicht unter Mikroprozessoren.
Moin, habe nichts weiter gemacht heute aber mal im "Keser Meder" gelesen, dem DDR Schmöker über U8.... . Sehr gut beschrieben aber ich finde es etwas amüsant wie die Autoren es als "Entwicklung der DDR" hinstellen, ohne ein Wort darüber zu verlieren, dass das Ding re-engineered wurde. Wie weiss ich nicht, entweder aus der Funktion her nachgebaut oder direkt von der Chipmaske? Von der Diadaktik aber zehnmal besser zu lesen als so mache engl. Literatur.
Holm Tiffe schrieb: >> Allein - wo kriegt man heute noch passendes DRAM in passender Grösse? > > ...sagt Dir evita.lt was? Danke. Hat lang gedauert, aber irgendwann fiel der Groschen. ;-) Auf die rhetorische Frage erwartete ich nämlich keine Antwort.
:
Bearbeitet durch User
Na gut, jetzt bin ich mal dran mit nicht verstehen, aber offensichtlich hast Du raus bekommen was man wie konvertieren muß damit die Seite interessant wird... Gruß, Holm
Christian J. schrieb: > Moin, > > habe nichts weiter gemacht heute aber mal im "Keser Meder" gelesen, dem > DDR Schmöker über U8.... . Sehr gut beschrieben aber ich finde es etwas > amüsant wie die Autoren es als "Entwicklung der DDR" hinstellen, ohne > ein Wort darüber zu verlieren, dass das Ding re-engineered wurde. Wie > weiss ich nicht, entweder aus der Funktion her nachgebaut oder direkt > von der Chipmaske? > Von der Diadaktik aber zehnmal besser zu lesen als so mache engl. > Literatur. Kannste denn wenigstens die Autoren beim richtigen Namen nennen? Der U880 ist in der DDR entwickelt worden, auch wen der Z80 kompatibel ist. Ob der re-engeneered worden ist, oder ob die Masterbänder vorlagen wie einige Informanten behaupten, sei dahin gestellt. Fakt ist allerdings das MME den Z80 besser im Griff hatte als Zilog. Meinen verschwommenen Infos nach ist KnowHow Richtung Zilog zurück geflossen, MME (später Thesys) konnte die besseren ICs bauen. (Ist auch nicht verwunderlich, Zilog selber hatte wohl keine Fabs. In der DDR ist aber richtig Entwicklungsaufwand in die Dinger gesteckt worden) Gruß, Holm
Holm Tiffe schrieb: > Na gut, jetzt bin ich mal dran mit nicht verstehen, aber offensichtlich > hast Du raus bekommen was man wie konvertieren muß damit die Seite > interessant wird... Hab ich nicht versucht, weil ich nicht auf der Suche nach dem Speicher bin. Eine rhetorische Frage ist eine, bei der man keine Antwort erwartet. Sollte ausdrücken, dass Z80 Kram im Handel deutlich häufiger zu finden sein dürfte, als antikes 3-Spannungs-DRAM. Mit Russen und Ablegern hatte ich da nicht gerechnet, die habe ich nicht auf dem Radar (Wessi eben ;-).
:
Bearbeitet durch User
Holm Tiffe schrieb: > Fakt ist allerdings > das MME den Z80 besser im Griff hatte als Zilog. Meinen verschwommenen > Infos nach ist KnowHow Richtung Zilog zurück geflossen, MME (später > Thesys) konnte die besseren ICs bauen. Kann es sein, daß Du Zilog mit den russischen Nachbauern verwechselst? http://zeptobars.ru/en/read/Zilog-Z80-Z0840004PSC (Auch die Links auf der Seite anschauen) > (Ist auch nicht verwunderlich, Zilog selber hatte wohl keine Fabs. In Zilog hat ohne Fab angefangen. Aber ziemlich bald eine gebaut. http://www.computerhistory.org/collections/catalog/102658073
Axel Schwenke schrieb: > Und was läßt dich glauben, die da gezeigte Simpel-Schaltung würde mit > dRAM funktionieren? Die hält /WAIT schlicht aktiv und in dieser Zeit > passiert auf dem Bus nichts, insbesondere auch kein Refresh. Glauben tu ich das schon, wissen nicht. Aber da Kramer D-RAM einsetzt, habe ich angenommen, das es geht. Getestet hab ich das nicht. Beim LC-80, welcher nur mit S-RAM arbeitet, wird das softwaremäßig mit NMI und der CTC gemacht. Gewisse Einschränkungen gibt es auch da. Christian J. schrieb: > Moin, > > habe nichts weiter gemacht heute aber mal im "Keser Meder" gelesen, dem > DDR Schmöker über U8.... . Sehr gut beschrieben aber ich finde es etwas > amüsant Amüsant haben wir damals(TM) darin die Aussage " Und wenn der Prozessor mal wieder Zeit hat, arbeitet er das vorhergehende Programm weiter ab" gefunden. Heute normal, aber damals mit starrer TTL- oder Analogtechnik war das etwas ganz seltsames. Kennt ihr noch "ELISA"? Damals(TM) der blanke Wahnsinn!
Michael_ schrieb: > Beim LC-80, welcher nur mit S-RAM arbeitet, wird das softwaremäßig mit > NMI und der CTC gemacht. Zwei paar Stiefel. Mit WAIT trackt man Buszyklen, HEX Anzeige oder was auch immer. Mit NMI gibts Single-Stepping im Debug-Monitor.
Leo C. schrieb: > Holm Tiffe schrieb: >> Fakt ist allerdings >> das MME den Z80 besser im Griff hatte als Zilog. Meinen verschwommenen >> Infos nach ist KnowHow Richtung Zilog zurück geflossen, MME (später >> Thesys) konnte die besseren ICs bauen. > > Kann es sein, daß Du Zilog mit den russischen Nachbauern verwechselst? > http://zeptobars.ru/en/read/Zilog-Z80-Z0840004PSC > (Auch die Links auf der Seite anschauen) > > >> (Ist auch nicht verwunderlich, Zilog selber hatte wohl keine Fabs. In > > Zilog hat ohne Fab angefangen. Aber ziemlich bald eine gebaut. > http://www.computerhistory.org/collections/catalog/102658073 Nein, ich verwechsele Nichts. Ich bezweifele aber, das die Russen die Chips selbst gemacht haben, die haben zwar alles Mögliche selbst gemacht, beim Z80 vermute ich aber nur Zyklus II. Deswegen gibt es IMHO auch Z80 in russischem Keramikgehäuse mit russisch aussehender Schrift und "80-CPU MME". Mich wundert nicht, das die Dies von Zilog und MME unterschiedlich sind. Die Annahme man könne einen Chip einfach so nachbauen, ist völliger Blödsinn. Selbst wenn man dann die Innenschaltung kennt, muß man diese auf eine verfügbare Technologie umsetzen, das heißt i.A. auch neues Layout. Aus diesem Grunde finde ich auch das seltsamerweise übereinstimmende leere Feld auf dem Chip putzig und es weist darauf hin, das die Chips alle aus der selben Fab kommen. Die Tatsache das irgend jemand ein "much denser peripherals layout" hat, heißt nicht das das irgendwie besser funktionieren muß, im Gegenteil. Wenn der Chip kleiner ist, ist es i.A. billiger, aber die Stromtragfähigkeit der Transistoren geht zurück, damit kann man u.U. einen externen Bus nur langsamer umladen.. Wenn die CPU selbst kleiner ist, läuft die eher schneller, aber dann braucht man auch kräftige Treiber. Fällt Dir was auf? Gruß, Holm
Zilog Z80 = 1976, MME U880 = 1980. Bisschen spät für nützliche Info von MME zu Zilog. Abgesehen davon wars nicht lizenziert. Mit Reproduktion über geklaute Masken wärs voll kompatibel, nicht bloss beihnahe.
:
Bearbeitet durch User
Hallo, wie auch immer ... ich habe noch keine russ Chips gehabt, weiss aber dass die natürlich auch welche bauen können. Wieso auch nicht. Allerdings billiger über die Auslandslieferanten. Für die DDR galt ja das Sperrabkommen, die haben sogar eine VAX damals in vielen teilen reingeschmuggelt, weiss noch wie das durch die Presse ging. http://www.focus.de/politik/deutschland/geheimdienste-heisse-stasi-scheiben_aid_149145.html "In der Tat tauchen in Stasi-Unterlagen neben kleinen Techno-Schiebern auch namhafte Westkonzerne auf: Ob Großrechner und Chiffriergeräte von Siemens, Abhöranlagen von Rhode & Schwarz oder VAX-Computer der US-Marke DEC – Stasi und KoKo beschafften alles. Sogar komplette Leiterplattenfabriken wurden via Schweiz und Österreich in die DDR geschleust (FOCUS 18/94)." Einen Chip aber kann man nicht 1:1 nachbauen, wohl aber seine Funktionen auf ein eigenes Design kopieren, also die Z80 nur als Vorlage nehmen. Egal..... sehr gutes Buch!
Christian J. schrieb: > Einen Chip aber kann man nicht 1:1 nachbauen, Doch, wenn man neben den Masken auch die Fabtechnik geklaut hat.
A. K. schrieb: > Christian J. schrieb: >> Einen Chip aber kann man nicht 1:1 nachbauen, > > Doch, wenn man neben den Masken auch die Fabtechnik geklaut hat. Und wie willst du die Masken aus einer Fab rausbringen? Die sind wie Staatsgeheimnisse. Ich habe sowas einmal erlebt, 1998 als ich noch bei der Chipschmiede XYZ war.... da wurden die Masken für MP3 und DSL "geklaut", d.h. irgendwie fanden die ihren Weg zu den Amis damals, vermutlich abgehörte emails etc.... gab ganz schön Ärger.
Christian J. schrieb: > Und wie willst du die Masken aus einer Fab rausbringen? Die sind wie > Staatsgeheimnisse. Eben. ;-) Genau damit hatte man reichlich Übung. Also an Staatsgeheimnisse ranzukommen. Weshalb sollte das bei Firmen nicht möglich gewesen sein?
Hier einiges dazu, James Bond ist ein Waisenknabe dagegen :) http://computer-oiger.de/2011/08/26/die-teure-jagd-auf-den-megabit-chip/2189 erledigten die sog "Beschaffungsorgane" ... grins :-) Implanter, Lithografiemaschinen und andere Anlagen, die für die DDR-Chipentwicklung dringend benötigt wurden, aber unter dem US-Technologie-Embargo CoCom standen, wurden meist mit hohen Bestechungsgeldern (in Devisen natürlich) im Westen eingekauft und dann über verschlungenen Wegen in die DDR gebracht, um diese Geschäfte zu verschleiern. Brief von Prof. Volker Kempe an Erich Honecker, 1986: „Die in der Republik hergestellte Rechentechnik bleibt in Menge, Zuverlässigkeit, Leistungsvermögen, Preis, Ausstattung und Software besorgniserregend hinter dem internationalen Stand zurück.“
Christian J. schrieb: > http://computer-oiger.de/2011/08/26/die-teure-jagd-auf-den-megabit-chip/2189 Besonders süss finde ich den abschliessenden Leserbrief: "Hätte die DDR 10 Jahre länger existiert, war das aus der Sicht vieler Spezialisten durchaus möglich im Schnitt den Standard der NSW Länder zu erreichen und in Teilbereichen sogar zu übertreffen ……" Dieser Stil hat sich seit Chruschtschow kaum geändert. ;-) Will das nicht schlechtreden. Aber das Problem war und ist nicht so sehr, mit mörderischem Aufwand einen Gleichstand zu erreichen, sondern ihn zu halten. Die finanziellen Mittel dazu waren einfach nicht da. Wie das läuft konnte man in den letzten 10 Jahren beobachten. Wieviele Firmen gibt es noch, die hochaktuelle Prozesstechniken beherrschen? Diese Zahl hat sich bös eingedampft. Warum? Enormes Investitionsvolumen, in jahrelanger Vorfinanzierung ohne das dafür Geld reinkommt. Kombiniert mit dem Schweinezyklus der Nachfrage hat das fast alle zu Aufgabe/Verkauf gezwungen. Ok, der Schweinezyklus entfällt in der Planwirtschaft.
:
Bearbeitet durch User
"Wobei das Nachbauen eine Kunst für sich war und einer Eigentwicklung an komplexität nicht nachstand. Die ORiginale wurden nur benötigt um 100% SW kompatibel mit dem Westen zu sein, um z.B. zu verhindern, dass SW aus dem Westen ohne änderung lauffähig ist." Ich kann nicht mehr ..... komme aus dem Grinse nicht mehr heraus :-) ROFL.
Die Z80 und U880 waren nicht ganz gleich. Das konnte man an den Pseudo-Befehlen erkennen. Es gab auch noch andere Hersteller. Mal gingen bestimmte Befehle, mal nicht.
Noch eine späte Frage: Was nehme ich als Kommunikations Platform? Mir schwebt da minicom vor, zudem es auch viele Protokolle beherrscht. Allerdings weiss ich nicht ob das ein Program ist, was auch Befehle senden kann, so dass es komfortabel ist. Ich bin grad dabei unter Linux eine Anwendung auf Konsole zu schreiben, die mir alles reinholt was von dem Z80 kommen wird und gleichzeitig meine Eingaben an ihn sendet. Vor allem will ich es komfortabel haben Intel Hex Files upzuloaden und nicht erst umständlich in minicom eine Datei öffnen und dann zig Tastendrücke später sie abzusenden. Aufgrund des Vorhandenseins aller Werkzeuge kommt für mich da nur Linux in Betracht, idealerweise die Kommandozeile. Oder gibt es da schon etwas in der Richtung, was gut passt? Hier ist so eine DDR-PIO .... könnte ich ja mal kaufen, um zu sehen ob sie kompatibel ist. http://www.ebay.de/itm/UB855D-DDR-MME-2-5MHz-Z80-PIO-paralleler-Interface-Chip-fur-Z80-U880-DIP40-/231125374265?pt=Bauteile&hash=item35d0255539
PS: Für das Ding hier habe ich damals 100 DM ausgeben müssen von meinem tasschengeld als 17 jähriger..... wahnsinn! Die habe ich heute noch aber sind beide tot nach 20 Mal brennen.....
Christian J. schrieb: > Oder gibt es da schon etwas in der Richtung, was gut passt? Für den von mir skzzierten ersten Bootloader: cp binfile /dev/ttyXXX Serielles Terminal-Programm für Linux gibts natürlich auch.
So eine Sch... Wollte auch mal wieder etwas mit Z80 versuchen, hab die ganzen Kisten durchsucht und natürlich festgestellt, dass gerade die mit den Z80 und Peripherie fehlt. Ist vielleicht besser so. Aber was anderes hab ich Depp aufbewahrt, wer sich noch erinnern kann...
Christian J. schrieb: > Was nehme ich als Kommunikations Platform? Mir schwebt da minicom vor, > zudem es auch viele Protokolle beherrscht. Minicom und Kermit habe ich nie wirklich benutzt. Ich erschlage solchen Kleinkram mit Picocom. Mit den lrzsz-Tools kann man damit auch X/Y/Z-Modem machen, Binärdateien gehen aber auch. > Ich bin grad dabei unter Linux eine Anwendung auf Konsole zu schreiben, > die mir alles reinholt was von dem Z80 kommen wird und gleichzeitig > meine Eingaben an ihn sendet. Was bist du umständlich. :-) "picocom --send-cmd cat" im richtigen Ordner starten. Die Datei sendest du dann mit Ctrl+A, Ctrl+S, Dateiname, Enter. Statt "cat" solltest du aber ein besseres Programm nehmen, wenn du Rückmeldungen magst (z.B. "pv", oder gleich "sz" für ZModem).
Michael_ schrieb: > Die Z80 und U880 waren nicht ganz gleich. Das konnte man an den > Pseudo-Befehlen erkennen. Es gab auch noch andere Hersteller. > Mal gingen bestimmte Befehle, mal nicht. Das ist einfach nicht wahr. Sämtliche Befehle waren implementiert, auch die undokumentierten. Die CPUs verhielten sich absolut identisch. Irgendwas war aber mal mit dem CTC, weiß aber nicht mehr was genau. Ich habe zu DDR Zeiten in der Halbleiterbranche gearbeitet und bin deshalb nicht auf seltsame Berichte angewiesen. Ja, ich habe auch an importierten Embargomaschinen gearbeitet. Gruß, Holm
Christian J. schrieb: > Noch eine späte Frage: > [..] > Hier ist so eine DDR-PIO .... könnte ich ja mal kaufen, um zu sehen ob > sie kompatibel ist. > > http://www.ebay.de/itm/UB855D-DDR-MME-2-5MHz-Z80-PIO-paralleler-Interface-Chip-fur-Z80-U880-DIP40-/231125374265?pt=Bauteile&hash=item35d0255539 Die PIO ist kompatibel, aber im metrischen Raster. Das auf Deinem Bild ist ein Z8 in der Entwicklerversion. Mit 8748/9 kann ich Dir sicherlich noch aushelfen, die Teile sind aber dumm wie ein Sack Holz... Gruß, Holm
Christian J. schrieb: > "Wobei das Nachbauen eine Kunst für sich war und einer Eigentwicklung an > komplexität nicht nachstand. Die ORiginale wurden nur benötigt um 100% > SW kompatibel mit dem Westen zu sein, um z.B. zu verhindern, dass SW aus > dem Westen ohne änderung lauffähig ist." > > Ich kann nicht mehr ..... komme aus dem Grinse nicht mehr heraus :-) > ROFL. Wo hast Du denn den Schmarrn her? Gruß, Holm
Holm Tiffe schrieb: > Das ist einfach nicht wahr. Sämtliche Befehle waren implementiert, auch > die undokumentierten. Die CPUs verhielten sich absolut identisch. Wikipedia: "Die Unterschiede beschränken sich auf spezielle Details wie ein nicht gesetztes CY-Flag bei dem OUTI-Befehl." und "The U880 is an almost identical copy of Zilog's 8-bit Z80 microprocessor. Differences include absence of CY flag setting in OUTI command (when L goes zero) and another behaviour of hidden bus register seen through undocumented F3 and F5 flags." Quellen werden dort leider nicht genannt. Muss folglich als unbestätigt gelten. Es ergibt in exakt dieser Formulierung auch keinen Sinn, denn laut Zilog Doku lässt OUTI das C Flag unverändert.
:
Bearbeitet durch User
A. K. schrieb: > Holm Tiffe schrieb: >> Das ist einfach nicht wahr. Sämtliche Befehle waren implementiert, auch >> die undokumentierten. Die CPUs verhielten sich absolut identisch. > > Wikipedia: "Die Unterschiede beschränken sich auf spezielle Details wie > ein nicht gesetztes CY-Flag bei dem OUTI-Befehl." und "The U880 is an > almost identical copy of Zilog's 8-bit Z80 microprocessor. Differences > include absence of CY flag setting in OUTI command (when L goes zero) > and another behaviour of hidden bus register seen through undocumented > F3 and F5 flags." > > Quellen werden dort leider nicht genannt. Muss folglich als unbestätigt > gelten. Es ergibt in exakt dieser Formulierung auch keinen Sinn, denn > laut Zilog Doku lässt OUTI das C Flag unverändert. Ich glaube das der Wikipedia aber nicht und halte das für Unfug. Es wäre auch ein ziemlicher Quatsch mit Sowas bei sonst identischem Befehlssatz einen Prozessor inkompatibel machen zu wollen, meinst Du nicht. Egal. Ich werde das mal aufgreifen und bei www.robotrontechnik.de diskutieren. Das sollte sich relativ leicht verifizieren lassen. Ich denke eher das sich das oben beschriebene Verhalten um steinalte Bugs in den ersten Masken gehandelt hat, auch bei Zilog. Jemand hat dann sozusagen 2 verschiedene paar Schuhe verglichen. Gruß, Holm
Holm Tiffe schrieb: > Es wäre auch ein ziemlicher Quatsch mit Sowas bei sonst identischem > Befehlssatz einen Prozessor inkompatibel machen zu wollen, meinst Du > nicht. Wollen mit Sicherheit nicht. Wenn das geschieht, dann unbeabsichtigt. Die genannte Auswirkung auf die eigentlich undefinierten F3/F5 Flags würde gut in diese Kategorie passen, vorausgesetzt da wurden nur Prinzip und Layout übernommen, nicht aber Masken auf eigene Fabtech portiert. > Egal. Ich werde das mal aufgreifen und bei www.robotrontechnik.de > diskutieren. Das sollte sich relativ leicht verifizieren lassen. Ich habe mal kurz die Historie im deutschen Wikipedia Artikel danach durchforstet. Diese Information kam erst in 2012 von "wdwd" = Walter Dvorak rein. Den müsste man fragen können. https://de.wikipedia.org/w/index.php?title=MME_U880&diff=103624554&oldid=103372272 Edit: wdwd hat das möglicherweise nur aus der englischen Version übersetzt. Da wars 2007, ein Bystrov Dmitry Mikhailovich: https://en.wikipedia.org/w/index.php?title=U880&diff=163599069&oldid=155211715 PS: Oder MME ist in eine Falle gelaufen. In der gestern verlinkten Unterhaltung kann man ja lesen, dass bewusst welche eingebaut wurden. Damals waren es die Japaner, die alles klauten was man brauchen konnte.
:
Bearbeitet durch User
Christian J. schrieb: > PS: Für das Ding hier habe ich damals 100 DM ausgeben müssen von meinem > tasschengeld als 17 jähriger..... wahnsinn! Die habe ich heute noch aber > sind beide tot nach 20 Mal brennen..... Lag das an den Chips oder am unsensiblen Brenner? Intel adressierte damit die Profis, nicht die Hobbyisten. Jedenfalls waren diese Preise nicht unwesentlich für all die EMUFs und EPACs verantwortlich, mit denen Hobbyisten ihre Controller strickten. Ein 6504 mit EPROM und 6532(RAM,Timer,IO) kostete ein Bruchteil und hatte zudem den gleichen Prozessor wie viele Pre-PCs. Es erklärt auch den späteren Erfolg von Microchip in dem Sektor, dank der PIC16 mit Fenster-EPROM. Auch die waren viel billiger.
:
Bearbeitet durch User
Holm Tiffe schrieb: > Mit 8748/9 kann ich Dir sicherlich noch aushelfen, die Teile sind aber > dumm wie ein Sack Holz... > > Gruß, > > Holm Die würden nur rumliegen wie die GU80 Röhre als Deko :-) Was heisst dumm? Die tun alles was man ihnen sagt. Hatte damals den Keil C Compiler und habe viel damit gemacht, Basis 8031, MCS 51 Befehlssatz. Völlig normale Mikrocontroller mit etwas sparsamer Ausrüstung an Bord. Aber ok sonst, finde die mit Fenster sowieso cool.
A. K. schrieb: > Intel adressierte damit die Profis, nicht die Hobbyisten. Missverständlich formuliert. Damit war der Preis gemeint.
:
Bearbeitet durch User
A. K. schrieb: > Es erklärt auch den späteren Erfolg von Microchip in dem Sektor, dank > der PIC16 mit Fenster-EPROM. Auch die waren viel billiger. Oh ja, 1996 als ich meinen ersten Job als HW Entwickler hatte waren "JW" Versionen in, selbst die 8 Pinner hatten kleine Fensterchen. Nur war ihre Haltbarkeit klein, mehr als 10 Löschvorgänge mit einem normalen Löschgerät erreichte ich auch nicht. Dann kam Flash Ende der 90iger und alles wurde gut. PIC habe ich bestimmt 6 Jahre benutzt, Hobby und Arbeit und die stehen AVR in nichts nach, alles genauso komfortabel. Selbstverständlich auch Single Step Hardware Debugging :-) Die JW kosten aber heute rund 10 USD / Stück, gibt es aber noch.
Christian J. schrieb: > Hatte damals den Keil C Compiler > und habe viel damit gemacht, Basis 8031, MCS 51 Befehlssatz Das nehme ich dir nicht so ohne weiteres ab. MCS-48 (und dein Foto ist ein 8749) war wirklich dumm wie ein Sack Holz und konnte nicht mal von alleine über eine Pagegrenze laufen, ohne das man ihn per AJMP dahin lockte. Das führte bei mir dann zu so abenteuerlichen Konstruktionen wie 'Alle INT auf Page 2', denn Page 0 und 1 waren besetzt vom Hauptprogramm etc. Ich habe es schon beim IBM PC Keyboard Kontroller bewundert, wie die Jungs in diesen MC was vernünftiges reinbekommen haben - der MCS-51 war dagegen Labsal für den Programmierer...
Matthias Sch. schrieb: > Das nehme ich dir nicht so ohne weiteres ab. MCS-48 (und dein Foto ist > ein 8749) war wirklich dumm wie ein Sack Holz und konnte nicht mal von > alleine über eine Pagegrenze laufen, ohne das man ihn per AJMP dahin > lockte. > Das führte bei mir dann zu so abenteuerlichen Konstruktionen wie 'Alle > INT auf Page 2', denn Page 0 und 1 waren besetzt vom Hauptprogramm etc. > Ich habe es schon beim IBM PC Keyboard Kontroller bewundert, wie die > Jungs in diesen MC was vernünftiges reinbekommen haben - der MCS-51 war > dagegen Labsal für den Programmierer... Sorry, mein Fehler, MCS 48 war eine Katastrophe, Page Jumg+127 Bytes. habe aber noch ein Board damit hier aus meinen Jugendjahren. Ich meinte den Nachfolger, den 51er.
Matthias Sch. schrieb: > konnte nicht mal von > alleine über eine Pagegrenze laufen, Das Datenblatt mal gelesen? Oder nur vergesslich? Der MCS48 war zu seiner Zeit nicht schlecht. Wir haben den millionenfach eingesetzt, zum Schluss mit 2764 als externem Programmspeicher. Du hast insofern recht, dass man ihn nicht mit Klicki-Bunti IDEs programmieren konnte. Assembler war schon notwendig. Und man sollte etwas Übung haben. Der MCS51 wird heute noch viel eingesetzt. Die Architektur hat durchaus ihre Vorteile.
Frühmorgendlicher Stand: Alle mal probesitzen bitte. An dem Osc Ausgang des 74HCT14 liegen 2.6V an, scheint also zu oszilieren ("Owon" Oszi ist noch irgendwo zwischen China und BRD unterwegs....). Reset tut auch was es soll, sogar mit Beleuchtung. Wird langsam eng, die nächst größere Platine hätte es auch getan. Denke mal eine Handvoll LEDs drüber verteilen, die Signale anzeigen bringt es nicht, man würde nichts sehen außer Glimmen. Die blauen Kingbright die ich hier habe sind auch mit 100uA zufrieden. Inzwischen ist auch der Eprom Brenner eingetroffen. Glaube wenn ich mal den Löffel abgebe können sie bei der Testatamentsveröffentlichung ein EPROM mit meinem letzten Wunsch auslesen, stilgerecht :-) Der schwierige Teil kommt ja noch ....
A. K. schrieb: > Zilog Z80 = 1976, MME U880 = 1980. Bisschen spät für nützliche Info von > MME zu Zilog. Abgesehen davon wars nicht lizenziert. Das lief so um 1990 und da war der Z80 noch nicht so altes Eisen wie er heute ist. > > Mit Reproduktion über geklaute Masken wärs voll kompatibel, nicht bloss > beihnahe. Ja, wenn man die Daten unverändert einfach so übernimmt, nicht wenn man sie überarbeitet und an die eigene Technologie anpaßt. Dabei verschwinden u.U auch Dreckeffekte... Gruß, Holm
Holm Tiffe schrieb: > A. K. schrieb: >> Holm Tiffe schrieb: >>> Das ist einfach nicht wahr. Sämtliche Befehle waren implementiert, auch >>> die undokumentierten. Die CPUs verhielten sich absolut identisch. >> >> Wikipedia: "Die Unterschiede beschränken sich auf spezielle Details wie >> ein nicht gesetztes CY-Flag bei dem OUTI-Befehl." und "The U880 is an >> almost identical copy of Zilog's 8-bit Z80 microprocessor. Differences >> include absence of CY flag setting in OUTI command (when L goes zero) >> and another behaviour of hidden bus register seen through undocumented >> F3 and F5 flags." >> >> Quellen werden dort leider nicht genannt. Muss folglich als unbestätigt >> gelten. Es ergibt in exakt dieser Formulierung auch keinen Sinn, denn >> laut Zilog Doku lässt OUTI das C Flag unverändert. > > Ich glaube das der Wikipedia aber nicht und halte das für Unfug. > Es wäre auch ein ziemlicher Quatsch mit Sowas bei sonst identischem > Befehlssatz einen Prozessor inkompatibel machen zu wollen, meinst Du > nicht. > > Egal. Ich werde das mal aufgreifen und bei www.robotrontechnik.de > diskutieren. Das sollte sich relativ leicht verifizieren lassen. > Ich denke eher das sich das oben beschriebene Verhalten um steinalte > Bugs in den ersten Masken gehandelt hat, auch bei Zilog. Jemand hat dann > sozusagen 2 verschiedene paar Schuhe verglichen. > > Gruß, > > Holm kaiOr vom robotrontechnik Forum hat das ausprobiert: "Hallo, habe meinen Frickel-KC85 offen auf dem Tisch (schon viel zu lange). Weiß nur nicht ob meine MC-Kenntnisse reichen um das sauber nachzuweisen: Quellcode: MODIFY 2000 21 FF FF -- LD HL,0FFFFh 01 80 01 -- LD BC,0180Ah 37 -- SCF ED A3 -- OUTI D2 00 F0 -- JP NC,0F000h 76 -- HALT go 2000 UA880D -> HALT UB880D -> HALT Z0840004PSC -> Kaltstart Z084C0010PEC -> Kaltstart SGS Z8400AB1 -> Kaltstart Lasse ich SCF weg bzw. ist zuvor CY nicht gesetzt gibts mit allen CPUs Kaltstart. Wie kann ich den anderen Unterschied mit F3 und F5 testen? MfG" Es ist tatsächlich so, das sich der U880 an die spezifizierte Funktion hält und die Zilog und SGS Teile nicht. Das heißt für mich das MME da einen Fehler gefunden und behoben hat, nicht ur den Originalchip 1:1 gecloned. Gruß, Holm
Holm Tiffe schrieb: > Ja, wenn man die Daten unverändert einfach so übernimmt, nicht wenn man > sie überarbeitet und an die eigene Technologie anpaßt. > Dabei verschwinden u.U auch Dreckeffekte... Im Wikipedia Artikel zu Mostek wird ein kleiner Spass aufgeführt, den Zilog mit Mostek angestellt haben soll. Und zwar soll Zilog denen Daten für den Chip geliefert haben, die gezielt die Ausbeute reduzieren. Vielleicht als neue Revision getarnt, als Zilog bereits eine eigene Fertigung hatte.
Holm Tiffe schrieb: > Es ist tatsächlich so, das sich der U880 an die spezifizierte Funktion > hält und die Zilog und SGS Teile nicht. Das ist ja nett. Zu den F3/F5 Flags siehe http://www.z80.info/z80sflag.htm. Die sind meist eine Kopie von Bits 3 und 5 vom Ergebnis der ALU.
Holm Tiffe schrieb: > Das lief so um 1990 und da war der Z80 noch nicht so altes Eisen wie er > heute ist. Ab 1990 dürfte es nicht mehr so einfach gewesen sein, einen unlizenzierten Nachbau zu verkaufen. Dass es zu diesem Zeitpunkt Kontakte zwischen MME (oder was daraus wurde) und Zilog gegeben hat, ist sehr gut vorstellbar.
:
Bearbeitet durch User
Hallo, schon 1986 war mir durch meinen Schwager (studierte damals Elektroniktechnologie) bekannt dass der Z80 einige Bugs im Bereich der Flagbehandlung aufwies. Ebenso war bekannt das MME diese Bugs beim U880 soweit bekannt behoben hat. Ich hätte hier noch "Datenbuch. Mikrorechnerschaltkreise Kramer, Würtenberger ISBN 3-327-00633-0 01600 aus 1988 bei Bedarf kann ich gern nachschlagen was interessie. Der U880 wie auch seine Peripher ausgiebig erläutert, inclusive Timingdiagramme. Namaste Das Thema kam damals in Zusammenhang mit dem ZX Spektrum OS auf, wo einige Klimmzüge notwendig waren ebenso gab es undokumentierte Opcode welche nicht releast wurden. Soweit mir bekannt waren sie Maskenfehlern zum Opfer gefallen ???
Winfried J. schrieb: > Das Thema kam damals in Zusammenhang mit dem ZX Spektrum OS auf Passt ins Bild. Derjenige, der in der englischen Wikipedia die Information über die Unterschied einpflegte, bezeichnet sich nämlich als "ZX Spectrum programmer from Russia."
Ich habe indessen auch noch ein bisschen gegoogelt, die Russen selbst sind der Meinung das Ihre Z80 Versionen eigentlich alle U880 sind, das heißt das sie entweder mit den MME Masken und deren Technologie produziert worden, oder was ich annehme nur in Russia verkappt worden sind. Ich habe indessen mehrfach gelesen das es in der DDR Engpässe beim Verkappen gab (wo gabs die nicht?), die Jield Raten der Chips selbst waren wohl verhältnismäßig gut. Es würde mich deswegen nicht wundern, wenn fertige Wafer in die "sozialistischen Bruderstaaten" exportiert worden wären. Gruß, Holm
Georg G. schrieb: > Der MCS48 war zu seiner Zeit nicht schlecht. Der wiederum als bereits verbesserte Version der damals sehr erfolgreichen F8 Familie von Fairchild verstanden werden kann. Die im Original einen recht eigentümlichen Aufbau hat, weil Mehrchip-Lösung. Dass Intel von ein paar ausgebüxten Fairchild-Leuten gegründet wurde, war sicher reiner Zufall. ;-)
:
Bearbeitet durch User
A. K. schrieb: > Holm Tiffe schrieb: >> Es ist tatsächlich so, das sich der U880 an die spezifizierte Funktion >> hält und die Zilog und SGS Teile nicht. > > Das ist ja nett. Naja, auch jeder heute erhältliche Chip hat ein Datenblatt und dann Ein Errata Sheet. Teilweise ist letzteres relativ statisch auch über Maskenversionen hinweg, z.B. bei TI MSP430Gxxxx. Wenn der Chip in Massen Produziert und verkauft wird, scheint der Leidensdruck zur Fehlerbehebung nicht mehr sehr hoch zu sein. Anmerkung: Die Russen haben jede Menge PDP11 Prozessoren gecloned, VAXen auch. Wenn man sich die Teile näher an sieht, stellt man fest das "Clone" da eigentlich das falsche Wort ist. Die Russen ahben PDP11 kompatible Prozessoren entwickelt für die es nie ein Original gab. Auc der erste VAX Mikroprozessor war ein VAX11/750 "Clone", Kenner der Materie werden realisieren das es niemals einen VAX Mikroprozessor in der 11/750 gab, das war im Original alles TTL Gemüse.. Ich habe eine russische PDP11/03 .. oder ähnlich, ein richtiges Original gibts auch da nicht. Das Teil heißt Elektronika E60, (Aus meiner Sicht ist das das Selbe wie Lehmann 60 oder Müller 60, alles bei den Russen heißt Elektronika) Das Ding hat einen QBUS mit metrischen Abmessungen und für die Teile auf der Rrozessorplatine gibts auch keine Originale. Das Ganze wurde dann in ein Gehäuse gebastelt das von außen einer 11/03 wie ein Ei dem anderen ähnelt.. komische "Clone", oder nicht? Ein Bild gibts hier, man sieht die 3 üblichen Schalter-Paddels rechts an der Front: http://www.tiffe.de/Robotron/PDP-VAX/E60/CPU-oben.jpg Die schweinchenrosa Chips links sind K565RU1A, das Equivalent zum I2107, 4Kx1 DRAMs. Die PDP11 Geschichte ging so weit, das die einen Sharp Taschenrechner gecloned haben, nur außen selbstverständlich. Im Inneren werkelt eine PDP11 CMOS CPU. gabs nie bei DEC: http://oldcomputermuseum.com/elektronika_mk85.html Ich habs probiert, eine russische 256KW Speicherplatine arbeitet mit Steckadapter auch in einer originalen 11/23. > > Zu den F3/F5 Flags siehe http://www.z80.info/z80sflag.htm. Die sind > meist eine Kopie von Bits 3 und 5 vom Ergebnis der ALU. Ich habe einen Link auf diesen Fred hier ins Robotrontechnik Forum gesetzt, Kai kann sich dann austoben.. Gruß, Holm
A. K. schrieb: > ausgebüxten Fairchild-Leuten Wobei Fairchild seinerseits heftige Anleihen bei Olympia Büromaschinen gemacht hat.
Zu den IN/OUT-String Befehlen und dem Carry Flag steht rein zufällig was auf einer Spectrum Seite. Wor sich auch zeigt, dass es nicht sonderlich geschickt ist, sowohl ein Register C als auch ein Flag C zu haben. ;-) http://www.worldofspectrum.org/faq/reference/z80reference.htm
:
Bearbeitet durch User
Hallöchen, so, was kann man noch an "Retro-Ware" dazu bauen? Eine einfache Taktkontrolle habe ich in Form einer glimmenden LED, so dass ein Taktausfall direkt sichtbar wird. Einen AD Wandler auch, 4 Ports, von denen einer mit 7 Segment bestückt wird (oder Arduino 8-fach Anzeige mit MAX ....). Das Auge isst mit und ein Holzkasten mit Plexiglasplatte drüber kommt auch noch.
Holm Tiffe schrieb: > Mikroprozessor in der 11/750 gab, das war im Original alles TTL Gemüse.. Ich las mal, dass in der 750 damals brandneue programmierbare Logik drin steckt, vermutlich PALs.
Holm Tiffe schrieb: > Ein Bild gibts hier, man sieht die 3 üblichen Schalter-Paddels rechts an > der Front: > http://www.tiffe.de/Robotron/PDP-VAX/E60/CPU-oben.jpg Und was ist das da rechts? Die Hochspannungsstufe für die Anoden der Endstufenröhren? Oder das Kühlaggregat? :-) >>Immer noch kein Interrupt ADC => STI? Uuuups.....
A. K. schrieb: > Ich las mal, dass in der 750 damals brandneue programmierbare Logik drin > steckt, vermutlich PALs. Die mit den PALs war die 730. In der 750 steckten Gate Arrays. Das einzige reine S-TTL Grab war die 780: http://bitsavers.informatik.uni-stuttgart.de/pdf/dec/vax/EG-21731-18_VAX_Product_Sales_Guide_Apr82.pdf
:
Bearbeitet durch User
Christian J. schrieb: > Und was ist das da rechts? Die Hochspannungsstufe für die Anoden der > Endstufenröhren? Oder das Kühlaggregat? :-) Linearnetzteil und Kühlpropeller, scheint mir.
Christian J. schrieb: > Uuuups..... Und ich bin nach wie vor sehr sicher, dass du NMI nicht offen lassen willst.
Christian J. schrieb: > Denke mal eine Handvoll LEDs drüber verteilen, die Signale anzeigen > bringt es nicht, man würde nichts sehen außer Glimmen. Deswegen gibt es Einzelschrittschaltungen wie die weiter oben gezeigte. > Der schwierige Teil kommt ja noch .... Hier noch ein praktischer Tip: die CPU auf einen Zwischensockel stecken, der die 8 Datenleitungen vom restlichen System abtrennt und fest auf GND legt. Die CPU liest jetzt permanent 0x00 = NOP, was dazu führt daß sie permanent immer im Kreis durch ganzen Adreßraum läuft. Mit Logikprüfstift / Oszi kann man jetzt die Adreßsignale, Chipselect etc. an den diversen Punkten der Platine prüfen. Man findet so relativ leicht Kurzschlüsse und Unterbrechungen. Und wenn man einen Logikanalysator hat oder sich mal ausleiht, kann man auch Adreßdecoder & Co prüfen. XL
Axel Schwenke schrieb: > Man findet so relativ leicht Kurzschlüsse und Unterbrechungen. Und wenn > man einen Logikanalysator hat oder sich mal ausleiht, kann man auch > Adreßdecoder & Co prüfen. > > > XL Ok, mache ich.. eine Logikanalyzer 8 kanal habe ich hier .... und den Zwischensockel baue ich mir gleich mal. By the way: Reicht die Treiberleistung von CMOS aus, um gegen einen 10k Pull Up anzukommen am NMI? Ich weiss jetzt nicht aus dem Stehgreif, in wieweit da die Spannung runterkommt, um den NMI zu "ziehen". Bis später, Christian
A. K. schrieb: > Christian J. schrieb: >> Und was ist das da rechts? Die Hochspannungsstufe für die Anoden der >> Endstufenröhren? Oder das Kühlaggregat? :-) > > Linearnetzteil und Kühlpropeller, scheint mir. Das Netzteil ist ein Sekundär-Schaltregler und dann sind da noch 4 Lüfter. Das mit den Gatearrays in der 750 ist mir bekannt und den DDR Nachbau der 11/780 (RVS K1840) kenne ich auch von innen, auch wenn es lange her ist :-) Gruß, Holm
Christian J. schrieb: > By the way: Reicht die Treiberleistung von CMOS aus, um gegen einen 10k > Pull Up anzukommen am NMI? Ach je... 74HC(T) zieht 4mA runter.
Hi, jedenfalls ist es eine Arbeit für Doofe bei der Fädeltechnik Fehlverdrahtungen zu suchen, von denen ich einige hatte wegen falscher Zählweise der Pins, zb spiegelverkehrt oder in die falsche Richtung. Ich weiss jetzt auch wieso sich "Grant" Aufkleber auf die Chips gemacht hat mit den Pins und Bezeichnungen. Denn es sind so viele durch die Adress und Datenbusse dass man da irre wird. Überschlagsweise sind es 250 Lötpins, die ich verdrahten múss. Man kann Fädeldraht im Kamm nicht zurück verfolgen und nur schwer wieder entfernen wenn da 10 Drähte drüber liegen. Dennoch ist es ordentlich und sauber. Und fasst man ihn mit der Pinzette an beschädigt man den Lack und es gibt leitende Ecken wie ich feststellen konnte beim Piepsen. Auch Draht der über abgeschnittene Pins ragt wird schnell aufgekratzt. Allerdings möchte ich icht mit normalem Draht bis zu 3 Anschlüsse auf ein Lötauge legen, das ist schon so schwer genug. Maximal 10 Leitungen derzeit, dann alles sauber durchpiepsen und auch zu den Nachbarn hin.
Weshalb ich isolierten Draht vom Typ Wrapdraht bevorzuge, ohne die Verdrahtung sonderlich zu strukturieren, statt Fädeltechnik mit Kämmen. Dünn genug um dichte Verdrahtung zu ermöglichen, aber problemlos verfolgbar und änderbar. Erste Aktion, wenn Fassung oder Verbinder drin: Unten den Pin 1 deutlich mit Stift markieren.
:
Bearbeitet durch User
A. K. schrieb: > Weshalb ich isolierten Draht vom Typ Wrapdraht bevorzuge, ohne die > Verdrahtung sonderlich zu strukturieren, statt Fädeltechnik mit Kämmen. > Dünn genug um dichte Verdrahtung zu ermöglichen, aber problemlos > verfolgbar und änderbar. > > Erste Aktion, wenn Fassung oder Verbinder drin: Unten den Pin 1 deutlich > mit Stift markieren. Hi AK, kanste mal kurz nen Bick drauf werfen, ob da Clock Konflikte zu erwarten sind? Der 374 latched nämlich auf der positiven Flanke und der 138er erzeugt negative. Müsste eigentlich noch passen, wenn er den 7-Segment Wert am Ende des I/O Zyklus rein nimmt .... allerdings kann ich WR nicht mehr decodieren, d.h. sowohl Schreib als auch Lesezugriffe werden das 374 ansprechen, im RD Fall allerdings mit Nonsens. Für einen extra 74er habe ich keinen Platz mehr, der zb ein NANd mit dazu nehmen würde, um WR in den Demuxer Ausgang einzumischen.... ach so: Ich möchte nur eine 7-Segment ins I/O einmappen. Nen Port kann man zwar auch verbraten aber auch da braucht man wieder Treiber, da die 8255 zu wenig Saft liefert und der STI auch, um LED zu treiben.
Christian J. schrieb: > Der 374 latched nämlich auf der positiven Flanke und der 138er > erzeugt negative. Passt so.
:
Bearbeitet durch User
Christian J. schrieb: > (...) Nur war > ihre Haltbarkeit klein, mehr als 10 Löschvorgänge mit einem normalen > Löschgerät erreichte ich auch nicht. Du musst die Dinger ausheizen, um die Ladungen komplett rauszukriegen. In den Backofen, dann auf Vollgas aufheizen (250°C oder so), 45 Minuten warten, dann Ofen aus und langsam abkühlen lassen. Bis Ende der '70er stand das auch so in den Datenblättern. Ein i1702 brauchte alle 5-10 UV-Löschgänge ein Annealing.
Axel Schwenke schrieb: > Hier noch ein praktischer Tip: die CPU auf einen Zwischensockel stecken, > der die 8 Datenleitungen vom restlichen System abtrennt und fest auf GND > legt. Die CPU liest jetzt permanent 0x00 = NOP, was dazu führt daß sie > permanent immer im Kreis durch ganzen Adreßraum läuft. > Mit Logikprüfstift / Oszi kann man jetzt die Adreßsignale, Chipselect > etc. an den diversen Punkten der Platine prüfen. Geht auch einfacher mit dem EPROM. Einfach alles auf "00" brennen. Der ist ja sowieso auf einer Fassung. Meinen hab ich sogar noch.
>Zwischensockel an CPU für NOP >Geht auch einfacher mit dem EPROM. Der Zwischensockel für die CPU ist normalerweise zu aufwendig. Der wäre auch nur dann sinnvoll, wenn irgendein Busteilnehmer aktiv auf den Bus seine Daten auflegt. Das kann man vermeiden, indem man Ram und Eproms (gesockelt!) zunächst heraus läßt. Und dafür einen Huckepack-Sockel am EPROM einsteckt, wo alle 8 Datenpins jeweils über einen 1kOhm gegen Gnd gezogen sind. Kann auf einem leeren Sockel mit gedrehten Pins einfach gemacht werden; Widerstände im Sockel unten nur einstecken; einen R an Gnd auch nur einstecken. Restliche R-Pins oben verlöten; nicht in der Nähe des Platiksockels. Der Vereinfachung mit dem "00" programmierten EPROM geht dann nicht, wenn der Adreßdecoder bereits richtig arbeitet! Dann würde das Eprom nur "NOP" liefern für seine decodierten Adressen. Man müsste dann /CE und /OE des Eproms dauerhaft auf Low legen. Gruss
soul eye schrieb: > Du musst die Dinger ausheizen, um die Ladungen komplett rauszukriegen. > In den Backofen, dann auf Vollgas aufheizen (250°C oder so), 45 Minuten > warten, dann Ofen aus und langsam abkühlen lassen. Das wären da so ca 5 Euro Strom und dafür bekam man auch schon wieder neue. Oder man packte sie beim Kuchen machen mit dabei?
Erich schrieb: > Der Vereinfachung mit dem "00" programmierten EPROM geht dann nicht, > wenn der Adreßdecoder bereits richtig arbeitet! Dann würde das Eprom nur > "NOP" liefern für seine decodierten Adressen. Man müsste dann /CE und > /OE des Eproms dauerhaft auf Low legen. Und wie geht das für Normalsterbliche? Ich meine um zu testen ob die CPU arbeiten sind doch NOPs das beste Mittel? Vom EPROM kommt nichts zurück außer Daten. Man müsste das Geklingel of den Adressleitungen sehen. Ich werde das mal testen heute am frühen Abend.....
Christian J. schrieb: >> (250°C oder so), 45 Minuten warten > Das wären da so ca 5 Euro Strom Kriegst Du deinen Strom vergoldet und im Mondschein gesammelt? 25-30ct/kWh, 2-3kW Leistung knapp 1h gibt unter 1€.
Christian J. schrieb: > Und wie geht das für Normalsterbliche? Was er schrieb: RAM raus, ROM raus und mit Stecksockel D0-7 auf GND.
>> Man müsste dann /CE und /OE des Eproms dauerhaft auf Low legen.
Damit sind dann ab dem Adressbereich des RAM sowohl das RAM als auch das
EPROM gleichzeitig auf den Datenleitungen aktiv. Das ist doch unsinnig.
Helmut S. schrieb: > Damit sind dann ab dem Adressbereich des RAM sowohl das RAM als auch das > EPROM gleichzeitig auf den Datenleitungen aktiv. Das ist doch unsinnig. Hier ging es um einen speziellen Testmodus ohne RAM.
Erich schrieb: > Der Vereinfachung mit dem "00" programmierten EPROM geht dann nicht, > wenn der Adreßdecoder bereits richtig arbeitet! Dann würde das Eprom nur > "NOP" liefern für seine decodierten Adressen. Man müsste dann /CE und > /OE des Eproms dauerhaft auf Low legen. Aber mit einem gelöschten EPROM (alles 0FFh) kann man den gesamten Speicherbereich und die Dekodierung von RAM und EPROM testen. Nach einem Befehlszugriff (M1) folgten dem Befehl 0FFh = RST 38H zwei Schreibzugriffe nacheinender über die vollen 64K. Es wird wiederholt die Returnadresse 0039h auf den Stack geschrieben.
>Aber mit einem gelöschten EPROM ...
Damit hast immer noch die Adressdekodierung dazuwischen, also kommen
"FF" nur vom Eprom.
Ausserdem lassen sich die entstehenden Zyklen nicht schön ansehen ohne
Speicherscope (und anno 1982 hatte das fast niemand).
Selbst mit dem NOP-Adapter hat man die störenden Refreshzyklen auf den
Adressen, aber das nur nebenbei.
Viele Theoretiker hier unterwegs.
Gruss
Route 66 schrieb: > Aber mit einem gelöschten EPROM (alles 0FFh) kann oder man baut sich ein NOP durch Drahtbrücken und kann dann alle Adressen am Takt erkennen...... aber egal, wenn ich Fieber hätte würde ich den Arzt bemühen, manchmal kommen mir auch so Ideen, wie z.B. meinen PC1500 mit der paralleln Schnittstelle zum apple wiederzubeleben. Aber in Blick in den relokatiblen Code mit den Asave und Aload Befehle hat mir gereicht (damals ohne Assembler in HEX auf Karopapier entworfen und eingepoked) um festzustellen das ich heute nicht mehr durchblicke. Das neu zu lernen wäre spannend aber für wen und mit welchem Nutzen ? Ich baue dann lieber an aktuelle Dinge wie word clock und lerne immer mehr über den Atmel der alles dabei hat was der Mensch so braucht. Vom Chinesen sogar billig mit Board und Schnittstelle. Ich würde 68k vor Z80 wählen oder den 6502 vor Z80, aber besser einen PC1500(A) (A besser mehr MEM oder ohne A und Mem einlöten -> die 4Mbit SRAM 512k x8 habe ich dann doch nicht mehr eingelötet) auf ebay schiessen, dann hätte ich LH5803 (?? mein Gedächnis) http://de.wikipedia.org/wiki/Sharp_PC-1500 jedenfalls eine interessante Mischung aus 6502 und Z80 Ähnlichkeit zur Z80 -> 16 bit Register und nicht clock gebundene Bus Abfrage Ähnlichkeit zum 6502 -> hat einen clock der 65xx Portbausteine syncron abfragen kann wie das mit der Clockverlängerung war bei Abfrage lahmer Bausteine war habe ich vergessen, hatte schon zwischen 1980 und 2004 keine Notwendigkeit dafür. also eine prima Mischung für beide Familien der Portbausteine, so man sie noch bekommt. jedenfalls mit einem PC1500 hat man LCD zur Ausgabe, Tastatur zur Eingabe, Daten und Adressbus frei zugänglich, kann in die freien Adress Bereiche eigene Dinge anschliessen http://www.pc1500.com/ http://pocket.free.fr/index.html
Erich schrieb: > Viele Theoretiker hier unterwegs. Ich würde an Deiner Stelle mit Vorurteilen vorsichtig sein! Die RST 38H Auswertung geht ja nach der ersten NOP Analyse den nächsten Schritt: Der Test der Ausdekodierung von RAM, ROM und Adressdekodierlogik. Dabei sind die saubere Trennung von einer Speicherleseoperationen (hier sogar Befehlslesen auf einer bekannten Adresse) und zwei Speicherschreibzyklen im gesamten Adressraum nachweisbar. Das geht auch ohne Speicheroszi.
Moin, weiter im Text.... ich weiss jetzt wie Bits ausehen! Ja wirklich! Sie sind BLAU! Eindeutig blau..... Bestückung abgeschlossen, jetzt gehts ans Eingemachte.....
Bevor ich diesen Schrott aufbauen würde, würde ich das allies lieber in die Tonne kloppen..... da hört man es wenigstens plumpsen :-( Wobei ein Blick in den Keller reicht um festzustellen, dass Hartpapierplatinen von 1990 auch eine Art Verkokungsprozess durchmachen, von Vollmich hellbraun bis zartbitter. Bringe es bisher nicht über mich den ganzen Schrott mal zu entsorgen aus Jugendzeiten.
Da kommen wieder echte Jugendgefühle auf, diese Dinger in den Ofen zu stecken, 20 Minuten zu warten bis zum nächsten Testlauf.... is ja voll retro! Nachdem ich die chin. Stecker abgeschnitten und durch europäische ersetzt habe, weil die alle zu kurze Stifte haben. Kein CE, kein Typenschild, nur eine Kiste mit Kabel und Uhrwerk zum Aufziehen aber für 13 Euro ok.
Christian J. schrieb: > Da kommen wieder echte Jugendgefühle auf, kann ich voll verstehen, irgendwo habe ich auch noch so eine Kiste.
Joachim B. schrieb: > Christian J. schrieb: >> Da kommen wieder echte Jugendgefühle auf, > > kann ich voll verstehen, irgendwo habe ich auch noch so eine Kiste. Habe früher Mutters Gesichtsbräuner genommen, den guten aus den 70ern.... http://www.fanie.org/infrarot/1.jpg auch ideal zum belichten von platinen, wenn man bücher drunter gelegt hat, damit er über der glasplatte zum liegen kommt. 5 minuten und dann rein in die braune suppe, die so schöne flecken in den hosen gab.
Christian J. schrieb: > Nachdem ich die chin. Stecker abgeschnitten und durch europäische > ersetzt habe, weil die alle zu kurze Stifte haben. Kein CE, kein > Typenschild, nur eine Kiste mit Kabel und Uhrwerk zum Aufziehen aber für > 13 Euro ok. Pins auf Plasik? Hm - frueher hatten wir darauf geachtet, dass die EPROM-pins beim Löschen wenigstens auf einer Metallplatte liegend - oder besser noch auf eine Metallstange gesteckt - kurzgeschlossen waren. Sicher nur Paranoia - aber da gab's auch noch den SM103 ;-)
Thomas J. schrieb: > Hm - frueher hatten wir darauf geachtet, dass die EPROM-pins beim > Löschen wenigstens auf einer Metallplatte liegend - oder besser noch auf > eine Metallstange gesteckt - kurzgeschlossen waren. Das muss das Boot abkönnen!
Joachim B. schrieb: > kann ich voll verstehen, irgendwo habe ich auch noch so eine Kiste. sogar wiedergefunden, über 10 Jahre nicht mehr benutzt mit original Staub drauf..... das nächste Projekt müsste dann win Arduino Eprombrenner sein weil ich den Brenner mit der IDE Schnitte nirgends mehr anschliessen kann :-)
Joachim B. schrieb: > Joachim B. schrieb: >> kann ich voll verstehen, irgendwo habe ich auch noch so eine Kiste. > > sogar wiedergefunden, über 10 Jahre nicht mehr benutzt mit original > Staub drauf..... > > das nächste Projekt müsste dann win Arduino Eprombrenner sein weil ich > den Brenner mit der IDE Schnitte nirgends mehr anschliessen kann :-) Geht mir ähnlöich mit dem Brenner für den C64.... Centronics Schnittstelle mit Klipsen dran...
Ich habe den hier: Beitrag "[V] ISEL EPROM-Löschgerät mit Timer" Musste ihn letztens sogar wieder benutzen. Da mein letzter EPROM Brenner vor gefühlten 10 Jahren über den Jordan ging, habe ich mir schnell den hier gebaut: http://www.qsl.net/iz7ath/web/02_brew/17_eprom/english/pag03_eng.htm Braucht allerdings ne Win98 Kiste oder ähnlich, damit die Brennsoftware an den Druckerport kommt. Zum Glück steht im Schuppen noch ein alter Win98 Laptop mit LPT.
Moin, habe jetzt von ebay den "Topwin 853" Programmer bekommen, neue Software V7 mal aus China runtergeladen. Das Ding ist echt klasse! Identifiziert und prüft sogar 74er Chip. So dass ich gleich einen defekten raussortieren konnte. Kann diese 35 Euro Programmer nur empfehlen!
Hmpf, das können alte ALL07 auch und für einen gebrauchten davon habe ich aus gutem Grund mehr als 35 Euro bezahlt. Gruß, Holm
Christian J. schrieb: > Bevor ich diesen Schrott aufbauen würde, würde ich das allies lieber in > die Tonne kloppen..... Heheheeee, so ähnlich sieht bei mir ein Steckbrett mit einem 8048-Derivat drauf aus. Aber ich möchte die Schaltung ja nicht für ewig darauf stehen lassen, und eben nur eine Weile lang einiges testen. Ich machte mal extra ein Foto für hier zur Ansicht. Die arg langen Drähte machen überhaupt nichts aus, der Eingangstakt beträgt weit unter 1MHz. Der Quarzoszillator hat zwar 5MHz, aber ich habe mit 4040-ern runter geteilt. Die Siebensegment-Multiplexung ist etwas brutal, aber funktioniert: Spaltentreiber ULN2003, Zeilentreiber 74LS245. Alles ohne Vorwiderstände, und fluppt gut. Der 74LS245 wird etwas heiß, aber wenn er verreckt: Tonne auf, Tonne zu, neu, hab da Vorrat. 80C382 von Siemens, bestimmt gut 30 Jahre alt. Die Steine haben aber schon sehr heraus ragende Leistungsmerkmale, z.B. sind sie in CMOS, voll statisch, haben bei 1MHz 1mA Stromaufnahme bei nur 3V Betriebsspannung. Sogar ein Sleep und Wakeup gibt es. Das alles ist für die damalige Zeit eine reife Leistung. Von den für MCS-48 bestimmten Portexpandern 8243 hab ich auch noch einige. Im Grunde hat der 80C382 den 8048-Core, man hat aber vom Befehlssatz 17 Befehle entfernt, dafür 5 leistungsfähige hinzu gefügt (was mit indirekter Adressierung). Das hab ich im Tabellen gesteuerten Assembler auch so angepaßt. Das Datenblatt bekam ich mal von einem Forenuser genannt, der wußte, wie es hieß. Unter dem Bauteilnamen findet man nämlich nichts. Bis dahin war ich ahnungslos und hatte eine Stange unbekannter ICs. Komische Erfahrungen mit Pagegrenzen und Interruptverhalten machte ich auch schon. Den Stein würde ich zum Einstieg in die µC-Welt noch empfehlen, aber dann auf einem Board mit Monitor-ROM, wo man kein EPROM brennen muß. Ich spiele einfach ein wenig mit den Dingen herum. Prozessen tut so ein alter Schinken auch, was man ihm sagt. Nur nicht der schnellste eben. Konkrete Anwendungen mache ich nicht, aber mal sehen, bei der nächsten Reichelt-Bestellung könnte es für mich ein PICkit geben.
Naja, mein Arduino Brett sieht auch so aus, zum testen eben. Wobei diese Kabel dauernd Wackelkontakt haben und absolut nichts taugen.
Christian J. schrieb: > habe jetzt von ebay den "Topwin 853" Programmer bekommen, neue Software > V7 mal aus China runtergeladen. Das Ding ist echt klasse! Identifiziert > und prüft sogar 74er Chip. So dass ich gleich einen defekten > raussortieren konnte. Kann diese 35 Euro Programmer nur empfehlen! Vorsicht! Teste den defekten 74... mal per hand durch. Mein TOP2005 mag auch nicht alle, obwohl sie in Ordnung sind.
Michael_ schrieb: > Vorsicht! Teste den defekten 74... mal per hand durch. > Mein TOP2005 mag auch nicht alle, obwohl sie in Ordnung sind. Habe ich schon bemerkt, dass er nicht alle mag, obwohl sie gelistet sind. Habe einen ganzen Setzkasten voll und manche Typen erkennt er einfach nicht, oder behauptet dass sie alle Bad sind. Gibt aber die neue Soft V7 jetzt beim Chinamann zu holen, die läuft besser als die V6. Ansonsten aber nettes Teilchen, ob PICs, SRAMs, serielle E2Proms oder AVR, er nimmt alles.
Moin, nein, das Projekt ist noch nicht "tot". Nur an einem Punkt wo ich einige Schritte zurück gehen musste. Die Idee "Fädelplatine" war Nosense, das Ganze wäre deutlich einfacher mit einem CAD Programm, Routen und dann Platine bauen lassen. Da ich einige Verdrahtungsfehler gemacht habe, die ich umständlich aus den Kämmen heraus "operieren" musste bin ich derzeit dabei anhand der Netzkliste von Eagle jede einzelne Verbindung nochmal durchzupiepsen und abzuhaken. Laut Netzliste sind es 350 Drahtverbindungungen, jede einzelne dauert etwa 3-4 Minuten die zu legen: Anschmelzen, einlöten, verlegen, abschneiden, wieder anschmelzen, einlöten. Aktuell habe ich erst ca 120 Verbindungen gelegt. Zuerst das EPROM an den Z80 und den Z80 betriebsbereit verbinden mit all seinen Leitungen über die Glue Logic zum EPROM und RAM hin. Dann wird das EPROM eingesteckt, was nur einen HALT Befehl am Ende hat und geschaut ob der erreicht wird. Danach ein leeres EPROM mit NOPs und mit Logic Analyzer über die Pins geschaut. Mühsam, mühsam....
Hi Retro-Fans! Klasse, die Z80 spielt !!! EPROM und Glue Logic verdrahtet, ein EPROM nur mit einem HALT am Ende bespielt und einen 100 khz Takt von einem Arduino auf den Clock gegeben. Da habe ich ja eine Weiche eingebaut. Nach einigen Sekunden leuchtet die HALT-LED. Ohne HALT mit nur NOPs tut sie das nicht. Mit dem Logic Analyzer klimpern auf den Adressleitungen auch die Bits herum! Klasse, ich haben nen 20 Jahre alten Z80 aus seinem Schlaf erweckt :-)
Holm Tiffe schrieb: > ..Wahnsinn! > > > :-| > > Holm Hey Mann, lass mir doch mal die Freude in unserem pfurz trockenen Job wo die meisten Verklemmten mit verbissenen Gesichtern rumrennen!
Naja, mein Gott...solche Sachen bauen die Jungs bei Robotrontechnik.de ständig, meist aber mit etwas mehr Funktionalität. Ich habe hier auch eine Z80-EMUF Platine liegen, die ich mal kurzerhand und aus "langer Weile" etwas frisiert hatte, da sind jetzt 64K RAM, 32K ROM, ne SIO und ne CTC zusätzlich drauf, inklusive Urladermimik und 6Mhz Takt. In dem Moment als das alles funktionierte habe ich das wieder beiseite gelegt.. Entschuldige also wenn mich das nicht gerade senkrecht aus dem Sessel drischt. Gruß, Holm
Hi, jetzt suche ich nur noch eine Beschriebung wie ich den SDCC einstellen muss, mit allen möglichen Header Files und Linker Optionen, damit er das tut was ich möchte. Das Netz gibgt da leider nichts her, was mit google findbar wäre. ASM wie gesagt nur sporadisch, alles weitere wird in C geschrieben.
Wenn Du sonst gar nichts findest, versuch es doch ausnahmsweise mal mit der mitgelieferten Doku.
Leo C. schrieb: > Wenn Du sonst gar nichts findest, versuch es doch ausnahmsweise mal mit > der mitgelieferten Doku. Das wäre ja schummeln. Ist ja nicht so, dass ich ihn nicht bereits mehrfach daraufgeschubst hätte...
Leute, das Manual habe ich natürlich! Das bringt einem aber nichts, wenn man nicht mal ein Projektverzeichnis hat, wo das alles schonmal eingestellt wurde. 1. Wie bringe ich ihm bei meine crt0.s zu benutzen und nicht die vorhande? 2. Wie bringe ich ihm bei den main code nicht auf 0x0000 zu pflastern, sondern auf 0x01000 und bei 0x0000 einen Jump drauf zu legen. 3. Wie bringe ich ihm bei die Vector Tabelle mit einzulinken und die Vektoren auf meine Routine zu legen. Ich bin nicht blöd aber sitz da bitte mal vor und versuche das alles selbst rauszufinden in einem Miniprojekt, wo einfach das Grundlegende funktionieren soll.
Hallooooooooooo............! Kann mal einer von euch Z80 Gurus einen Blick auf den Plan werfen? Ist das so richtig, was Eprom und SRAM angeht? Nachdem ich alles durchgepiepst habe ist das so miteinander verbunden und nicht anders. Denn... ein einfaches Programm mit dem SDCC, was auch "richtig" ist fährt nicht in den HALT Befehl, nachdem es vorher zwei Schleifen durchlaufen hat. Auch nicht wenn die Schleifen gelöscht wurden. Was bisher funktionierte war, dass ein leeres NOP EPROM mit einem Halt Befehl am Ende die LED leuchten liess, die am Halt Pin steckt.Aber sobald Variablen ins Spiel kommen oder der Compiler, der solche setzt, zb Stack Pointer klappt es nicht mehr. ROM : 0000 - 1fff RAM : 2000 - ffff Ich habe die Files mal angehängt, auch der Hex Code schaut ok aus im Hex Dump Monitor, die Befehle liegen da wo sie hingehören. Ratlos....
Anbei der Hex Dump.... Vorne C3 Sprung nach 0x01000, den Startup Code ausführen, dann der CALL Main mit CD 10 01 (Call 0x0110) und dann weiter in meiner Routine. Sieht alles soweit richtig aus.....
Deine crt0.s erzeugt Interruptvektoren bei 0x00, 0x08, 0x10, 0x18 ... und lässt den Code dann ab 0x100 beginnen. Du müsstest vermutlich die ganzen Areas zu Fuß definieren. Code, um statisch initialisierte Variablen nochmal zu kopieren (vom ROM ins RAM), erzeugt der SDCC immer - mir ist kein Weg bekannt, das abzustellen. Wenn du also den Code ab 0x1000 beginnen lassen möchtest, solltest du dem Compiler das sagen. ;-) Nachtrag: Du kannst dir mal die anderen Dateien anschauen. Da steht genau drin, wie welche Codezeile in welche Assemblersequenz an welchen Adressen zusammengebaut wird und ist relativ gut lesbar. Besser als ein Hexdump auf jeden Fall.
:
Bearbeitet durch User
Hi, so nachdem ich gefühlt 50 EPROMs gebrannt habe und auch den Quelltext korrigiert bin ich schlauer und nicht schlauer..... Es funktioniert...... manchmal ! D.h. es wird ja nur eine Schleife durchlaufen bevor ich die einzige Debugmöglichkeit nutze, die ich derzeit habe: HALT an LED. Und dieses "manchmal" lässt mich grad überlegen, ob ich das Platinchen zu vielen anderen in die Ecke lege. Vermutlich hat die CPU ein Timing oder ein Reset Problem. Sie startet beim Einschalten nur "manchmal" los und auch beim Druck des Reset führt die das Programm nur "manchmal" aus.... von 10 Reset Drückern sind mindestens 3 solche, wo die LED nicht nach 2s aufleuchtet. Mit der CPU von SGS arbeitet das Programm "oft aber nicht immer" Mit der CPU von ST arbeitet das Programm "fast nie". Wenn ich an die Verdrahtung da unten drunter denke kommen mit so Gedanken. Mangels Messgeräten derzeit aber schwer feststellbar. Nebenbei habe ich grad den offenen INT Pin per Pull Up an Vcc gezogen, der hing mangels Chip in Fassung in der Luft. Hätte ja sein können... PS: Die Zuverlässigkeit steigt DEUTLICH, wenn ich den Takt nicht über ein Gatter führe, sondern direkt vom OSC in die CPU einspeise auf dem 1cm kurzen Weg. Trotzdem weigert sich die CPU nach dem Kaltstart los zu laufen, es ist immer ein Reset per Hand nötig.
So, ich bin meinem Latein am Ende. Absolut unbefriedigendes Startverhalten, egal ob Kalt oder Warmstart! Testweise den Reset verlängert durch 10k und 10uf, man sieht ihn jetzt deutlich an der LED, die am Resetpin angeschlossen ist, wie er "aufblitzt" kurz nachdem Vcc da ist. Osc testweise durch 1 MHZ aufgetauscht, es wird geringfügig besser. Für die Schleife bis 40.000 braucht er dann schon stattliche 5s. Die uralte NMOS CPU läuft am besten, wird aber deutlich handwarm und zieht sich 150 mA rein. Manchmal leuchtet dei HALT LED auch sofort nach Einschalten auf. Solange das nicht 100% ig funktioniert, dass es bei jedem Reset und bei jedem Power Up immer das gleiche Resultat gibt hat es keinen Zweck das Projeklt weiter zu verfolgen. Das damals mit dem 8085 lief deutlich besser und da war die Verdrahtung deutlich chaotischer. Keine Ahnung ob 4 Mhz für Luftverdrahtung schon zu viel sind ;-( Halte ich fest: Verdrahtung scheint ok, da das programm ja ab und zu richtig abgearbeitet wird. Aber ohne Messgeräte weiss ich da auch nicht weiter.
> NMOS CPU läuft am besten, wird aber deutlich handwarm und zieht sich 150 > mA rein. Normal. Siehe Datenblatt. > Keine Ahnung ob 4 Mhz für Luftverdrahtung schon zu viel sind ;-( Für Luftverdrahtung nicht, für Fädelkämme schon. Du hast weiter oben von einem 100KHz Takt geschrieben. Wie siehts denn damit aus? Ansonsten: Scope.
Christian J. schrieb: > Das damals mit dem 8085 lief deutlich besser und da war die Verdrahtung > deutlich chaotischer. Keine Ahnung ob 4 Mhz für Luftverdrahtung schon zu > viel sind ;-( Von einem alten Mainframe hat mir jemand mal die Schote erzählt, dass sie ursprünglich die Backplane fein säuberlich geordnet verdrahtet hatten. Kabel neben Kabel. Nur Ärger. Im nächsten Anlauf haben sie den Kram dann chaotisch quergezogen, so dass das aussah wie ein Filzteppich. Nun lief er.
Welches EPROM hast Du denn genau? In Deinem Schaltplan steht "EEPROM2764". Das ist wohl eine Phantasiebezeichnung. Auf jeden Fall sind CE und OE vertauscht.
Leo C. schrieb: > Auf jeden Fall sind CE und OE vertauscht. Was hier aber keine Rolle spielt, sondern erst bei grenzwertiger Zugriffszeit.
Ich sehe auf deinem Schaltplan keinen einzigen Abblockkondensator.
User schrieb: > Ich sehe auf deinem Schaltplan keinen einzigen Abblockkondensator. Kannst Du auch nicht sehen, die sind unter den ICs mitten im Sockel. ;-)
>> Ich sehe auf deinem Schaltplan keinen einzigen Abblockkondensator. > Kannst Du auch nicht sehen, die sind unter den ICs mitten im Sockel. ;-) Auf dem Schaltplan sind nicht mal Sockel. ;-) (Gottseidank) Aber auf einem der letzten Bilder sind welche. Aber wie sie verdrahtet sind, sieht man dort auch nicht. (hint) >> Auf jeden Fall sind CE und OE vertauscht. > Was hier aber keine Rolle spielt, sondern erst bei grenzwertiger > Zugriffszeit. Grenzwertig wirds je nach CPU ab ca. 3,4 Mhz (SGS 2,5MHz CPU) oder 4 MHz (Zilog 6 MHz CPU), wenn er das 250ns EPROM genommen hat, daß in einem der Bilder zu sehen ist. Christian J. schrieb: > Die uralte NMOS CPU läuft am besten Spricht für die "Fädelkammtheorie", da die CMOS-CPUs steilere Signalflanken haben dürften.
Leo C. schrieb: > Aber auf einem der letzten Bilder sind welche. Aber wie sie verdrahtet > sind, sieht man dort auch nicht. (hint) Aber im Bild der Platine weiter oben, gewissermassen. Ausser beim EPROM im wohl zu niedrigen gedrehten Sockel sieht man da nämlich auch kaum welche. Aber im Thread hatte er erwähnt, dass er die im Plan wegliess. Bei Handverdrahtung unnötig, mache ich auch oft so. Bei den im Bild noch unbestückten Gatter-ICs sind aber wirklich keine Kerkos zu sehen. > Grenzwertig wirds je nach CPU ab ca. 3,4 Mhz (SGS 2,5MHz CPU) oder 4 MHz > (Zilog 6 MHz CPU), wenn er das 250ns EPROM genommen hat, daß in einem > der Bilder zu sehen ist. Aber nicht wenn er testweise mit 1MHz fährt und die Probleme immer noch auftreten.
:
Bearbeitet durch User
Christian J. schrieb: > Das damals mit dem 8085 lief deutlich besser und da war die Verdrahtung > deutlich chaotischer. Keine Ahnung ob 4 Mhz für Luftverdrahtung schon zu > viel sind ;-( Chaotische Verdrahtung ist ok. Mit parallel geführten Leitungen in Fädelkämmen dürfte aber schon bei deutlich kleineren Frequenzen Schluss sein. Die Dinger gehören verboten -- für getaktete Schaltungen sind die völlig ungeeignet. Mach mal einen 330 Ohm - Pullup an den CLK-Pin des Z80. Der will da nahezu VDD als Highpegel sehen und zieht noch ordentlich Strom dabei. Ein HCT14 sollte das in der Theorie auch liefern können, in der Praxis reicht es aber nicht immer.
Hi, 330 Ohm Pull-Up an Clock? Und wer soll das Schwergewicht wieder runter ziehen? Natürlich sind an jedem IC Blocker, unten drunter zwischen den Pins. Teilweise auch als smd, bzw sind auch viele Winderstände smd. Mit einem 100 khz Takt vom Arduino spielt die Musik bei jedem Reset. Allerdings funktioniert der Kaltstart nicht sauber. Mit 1 Mhz kann man allerdings nebenher laufen, für 1...40000 braucht der 6s ohne Schleifeninhalt. Da es mit 1 MHZ aber auch noch Probleme gibt, die kaum weniger sind und nur bei 100khz keine werde ich erstmal die beiden vertauschten Leitungen korrigieren. Und dann mal sehen ...... tja, ohne Oszi schlecht, brauche dringend wieder eines. Das OR Gatter ist übrigens ein ACT, hatte kein HCT mehr. Und die ST 2764 Eproms sind 250ns, thats right.
Christian J. schrieb: > Das OR Gatter ist übrigens ein ACT Autsch! ACT und Fädeltechnik ist wie Formel 1 auf dem Rübenacker. Egal mit welcher Frequenz Du taktest, die Flanken bleiben mörderisch. Dann nimm lieber TTL, wenn du eins ohne A drin hast.
:
Bearbeitet durch User
Hallo, also zuerst mal die beiden Leitungen korrigieren was bei Fädeltechnik abschneiden und neu legen ist. Dann dran gewöhnen dass 1-2MHZ die Grenze de Zumutbaren ist, also C64 Speed. Schade, 4 MHZ liefen schon recht flott daher. Und wenn das getan ist weiter im Teext... der SDCC ist übrigens wirklich schön, auch wenn ich mir retro-halber noch die Assembler Sprache des Z80 reinziehen werde von dem schön vergilbten Papier des Schmökers. Und ich gewöhne mich grad wieder dran, dass EPROM brennen Spass macht nach jeder Programmänderung, habe aber auch ein 2764 Flash gekauft. Sobald der Monitor läuft wird es ja einfacher... hoffe ich mal :-) Hat jemand noch eine Baudratenquarz Oszillator 1,832 Mhz rumfliegen ?
PS: Da ist der Trümmer, der noch be mir im Keller liegt.... ein CCS-85, damals für 300 DM..... vielleicht kennt jemand noch die Art wie da "programmiert" wurde.... hicks
Christian J. schrieb: > Hat jemand noch eine Baudratenquarz Oszillator 1,832 Mhz rumfliegen ? Den schenkt dir niemand. Nimm einen mit doppelter Frequenz, die gibt es wie Sand am Meer. Und lass erst mal deine SDCC weg! Es nervt nur. Wenn erst mal dein System läuft, kannst du sie immer noch einbauen.
Du hast wiedermal Verschiedenes "besser" gewußt.. Irgend ein Eingang hängt offen herum, checke nochmals BUSRQ, NMI und INT. Bevor Du einen C-Compiler anpaßt, teste das Ding mit kleinen Assemblerprogrammen, der Z80 läßt sich an interessanten Stellen leicht anhalten in dem man die CS Leitungen von RAM oder Peripherie temporär mit dem WAIT Eingang verbindet. Man hat dann endlos Zeit Signale zu kontrollieren. Stecke Deinen Kopf in die Bücher und verstehe was der Prozessor und die Peripherie machen soll, verifiziere das auf Deiner Hardware. Kümmere Dich um den Systemclock, das der etwas speziell ist, hatte ich schon mal durchgegeben. Besorge Dir einen Assembler und schreibe ein paar kleine Programme die die Funktionsfähigkeit z.B. des RAMs im Stackbereich kontrollieren. Gruß, Holm
Lieber Holm, du hast sicher recht. An eine Art Single Step habe ich auch schon gedacht. Nur ist es eben schwierig an einem System mit Hausmitteln zu arbeiten, welches einem kein Feedback gibt und wo die Turn Around Time von der Programmänderung zur Verifikation sehr hoch ist. Das war schon damals schwer aber es gab Hilfsmittel wie Eprom Emulatoren, Entwicklungs-Bretter, Debugger Karten, Single Step Bus Karten mit LEDs drauf, zb für den S100 Bus usw. Der SDCC hat einen Assembler mit dabei, den sdaz80. Ich bin dran.... aufgeben wäre zu früh.... Es hängt übrigens kein Eingang offen herum, alles kontrolliert und ge-pull-up'd.
Christian J. schrieb: > Dann dran gewöhnen dass 1-2MHZ die Grenze de Zumutbaren ist, Stimmt nicht. Gegenbeispiele wurden schon genannt[1]. Mein altes 64180-System läuft mit einem 18,432Mhz Quarz (9,2MHz Systemtakt). Und das mit dynamischen RAMs, die ja nach mancher Meinung auch nicht mit Fädeltechnik laufen sollen. Und im gleichen Thread ist noch ein '180-System mit 7,15Mhz und mit Fädelkämmen verdrahtet! [2] > also C64 Speed. Kann man so auch nicht sagen. [1] Beitrag "Re: Retro Fieber: Z80 oder 68000 ?" [2] Beitrag "Re: z80 system"
Christian J. schrieb: > PS: > > Da ist der Trümmer, der noch be mir im Keller liegt.... ein CCS-85, > damals für 300 DM..... vielleicht kennt jemand noch die Art wie da > "programmiert" wurde.... hicks Du mußt dich wirklich mal schlau machen. Das wird eine 8085 CPU sein. Fast der gleiche Befehlssatz wie der Z80, nur weniger. Der Z-80 ist die "Weiterentwicklung" von ZILOG.
Hallo, bevor ich bei dem Wetter mal rausgehe... es funktioniert! 1. 680 Ohm an Clock .... oh, Wunder! 3. OE un CS richtig verdrahtet !!!! 4. 3.8 Mhz Osc wieder rein. Klappt! Vermutlich wird eine der Maßnahmen das Problem beseitigt haben, vor allem vertauschte Leitungen sind Gift für ein Design, auch wenn die beiden fast zeitgleich takten. Kaltstart nicht immer..... ich verlängere den Reset schon an die Schmerzgrenze, er wird 0,5s nach Power Up jetzt ausgelöst., Schnelles Ein/Aus mag es nicht, es muss schon ein paar Sekunden der Strom weg sein. Kann sein, dass das was man heute Brownoout Reset nennt damit was zu tun hat. Der Power Up Zyklus hat ja mit einigem Aufwand bei PIC und AVR. Man kann die Z80 in einen Zustand bringen, wo sich nichts bewegt auf den Leitungen. Dann kann es ja weiter gehen..... An die Gegner des SDCC: So wie ich mich da bisher eingearbeitet habe hat er alle Features um ISR zu bearbeiten, IO Zugriffe, Vector Tabellen anlegen (als inline asm) usw. Asm werde ich mit einem Simulator mal üben am PC. Kann mir da jemand einen Assembler mit Z80 Emulator für Linux empfehlen? Am besten so wie auf dem ´Bild mit einem Debugger.
Bitte tu Dir (und uns;) einen Gefallen, und versuche die Ursache heraus zu finden! Die Verdrahtung würde ich nicht nochmal ändern, aber die Punkte 1. und 2. solltest Du einzeln und zusammen nochmal rückgängig machen, und schauen was passiert. Und bevor Du voran gallopierst, solltest Du auch den Reset richten. Es macht auf Dauer keinen Spaß, mit einem unzuverlässigen System zu "arbeiten".
Christian J. schrieb: > Kaltstart nicht immer..... ich verlängere den Reset schon an die > Schmerzgrenze, er wird 0,5s nach Power Up jetzt ausgelöst., Viel hilft hier nicht viel. Der Reset muß so lange auf low bleiben, bis die Versorgungsspannung oben ist, und der Taktoszillator stabil läuft (wenige 10ms). > Schnelles Ein/Aus mag es nicht, es muss schon ein paar Sekunden der Strom > weg sein. Die Diode ist in den Beispielen, die Du gepostet hast, nicht zum Spaß drin. Bei Dir gehört sie über R10.
Christian J. schrieb: > An die Gegner des SDCC: So wie ich mich da bisher eingearbeitet habe hat Hier hat niemand was gegen den SDCC. Einige sind nur der Meinung, daß Du die ersten Schritte zuerst machen solltest. > Kann mir da jemand einen Assembler mit Z80 Emulator für Linux empfehlen? Beim SDCC ist neuerdings einer dabei. ;-)
Leo C. schrieb: > Viel hilft hier nicht viel. Der Reset muß so lange auf low bleiben, bis > die Versorgungsspannung oben ist, und der Taktoszillator stabil läuft > (wenige 10ms). Leo C. schrieb: > Und bevor Du voran gallopierst, solltest Du auch den Reset richten. Es > macht auf Dauer keinen Spaß, mit einem unzuverlässigen System zu > "arbeiten". ich würde ja bei alten Designs einen Reset Controller nehmen TL7705 http://www.elektronik-kompendium.de/public/schaerer/bilder/u_supvi5.gif Leo C. schrieb: > Die Diode ist in den Beispielen, die Du gepostet hast, nicht zum Spaß > drin. Bei Dir gehört sie über R10. oder auf jeden Fall um den Elko schnell zu entladen Anode an +Elko Kathode an Vcc
:
Bearbeitet durch User
Leo C. schrieb: > Bitte tu Dir (und uns;) einen Gefallen, und versuche die Ursache heraus > zu finden! Die Verdrahtung würde ich nicht nochmal ändern, aber die > Punkte 1. und 2. solltest Du einzeln und zusammen nochmal rückgängig > machen, und schauen was passiert. Du bist ein kleiner Scherzkeks. Ich habe den Sch.... angefangen, jetzt löffel ich ihn auch aus. Ohne spezielle Messgeräte geht das nicht. Wenigstens einen Oszi muss ich wieder bald hier haben. Es läuft schon ziemlich gut und mit einem Logiktester sehe ich ja, dass auf den Pins Musik ist aber bei 10 AuS/EIN eben nur so 7 Mal, die restlichen 3 Male sind die Pins tot, Takt liegt aber an. Reset nützt nichts! So, und das versuche bitte mal rauszufinden. Du hast keine Chance, wenn Vcc da ist, Takt auch aber auf Daten und Adressleitungen ist nichts los und NICHT mal ein Reset ändert daran was. Nur nochmal AUS/EIN und dann klappt es beim nächsten Male. In einem Industriedesign würde ich da direkt den Supporter des Distis ranholen. Da Millionen davon verbaut wurden kann es aber nicht am Chip liegen. Ansonsten klappt es aber, er prüft sein RAM derzeit rauf und runter und oper NMI Taste kann ich ihm eine Speicherstelle fälschen, so dass er dann einen Vergleichsfehler findet und in den HALT geht. Auf den print und sprintf werde ich wohl verzichten müsse´n, die 8kb ROM sind dann nämlich halb voll, wenn ich den einbinde.
vor allem sollte das RAM sicher unter Ub unter 0.5V gehen während des powerdown. Sonst wir es ein lauwarmer Reset mit bankweise gekippten Bits. Da hilft kein langer reset, sondern nur ein ausreichend langer Powerdown! der z80 macht keinen Kaltstart solange das Warmflag im Ram gesetzt ist! aber du kannst in den Warmstartvector den link auf Kaltstart setzen. ;) Wenigstens die Systemvariablen und die Vectortabelle solltest du auch bei einem Warmstart reinitialisieren, zumindest solange du nicht modifizierte Vectortabellen nutzen willst. Und dann wäre es besser die sauber zu halten und woanders zeiger zu (ver)biegen. ;) es gipt auch Resetcontroller mit welchem ei Z80 mit brownoutdetector nachgerüstet werden kann.;) http://www.mikrocontroller.net/articles/Brownout
:
Bearbeitet durch User
Winfried J. schrieb: > der z80 macht keinen Kaltstart solange das Warmflag im Ram gesetzt ist! Wo hast du diese Weisheit her? Beim Z80 gibt es nur einen Reset Vektor, nämlich 0x0000. Der Rest ist Sache des Anwenders.
Winfried J. schrieb: > der z80 macht keinen Kaltstart solange das Warmflag im Ram gesetzt ist! > aber du kannst in den Warmstartvector den link auf Kaltstart setzen. ;) > > Wenigstens die Systemvariablen und die Vectortabelle solltest du auch > bei einem Warmstart reinitialisieren, zumindest solange du nicht > modifizierte Vectortabellen nutzen willst. Und dann wäre es besser die > sauber zu halten und woanders zeiger zu (ver)biegen. ;) Warmstart-Flag? Bahnhof-Flag? Systemvariablen? Vectortabelle.... liegt im ROM, nur RETI drin. Bin den ganzen Tag schon dran und weiss was los ist, auch mit Hausmitteln wie Logik-Tester ..... und das Problem ist vorerst nicht lösbar, da rundum das Problem ein schwarzer Kasten ist, eine Black-Box sozusagen :-) Den juckt auch kein Reset mehr in diesem "Zustand". Der "blinkt" richtig auf den Adressleitungen, ca 10 Hz Takt, ab und zu jedenfalls, sonst nimmt er die Füsse hoch oder runter, je nachdém.
Georg G. schrieb: > Winfried J. schrieb: >> der z80 macht keinen Kaltstart solange das Warmflag im Ram gesetzt ist! > > Wo hast du diese Weisheit her? Beim Z80 gibt es nur einen Reset Vektor, > nämlich 0x0000. Der Rest ist Sache des Anwenders. Christian J. schrieb: > Warmstart-Flag? Bahnhof-Flag? Systemvariablen? Boah, Leute. Mitdenken Ein Monitorprogramm, das nach jedem Hardware-Reset einen Kaltstart [1] macht, ist keinen Pfifferling wert. Es braucht eine wenigstens halbwegs zuverlässige Heuristik, um zu entscheiden ob ein Kaltstart oder Warmstart erforderlich ist. > Vectortabelle.... liegt im ROM, nur RETI drin. Blöde Idee <tm>. Dann brauchst du auch keine Vektortabelle. Die Tabelle muß natürlich im RAM liegen. Mit Einträgen, die ins ROM zeigen. XL [1] ein Kaltstart beinhaltet i.d.R. sowas wie komplette Löschung des RAMs. Oft auch einen kurzen Selbsttest oder einen Scan, wo denn überall RAM liegt (damit man z.B. den Stack ans Ende setzen kann). Natürlich müssen nach einem Kaltstart alle im RAM liegenden Variablen und Tabellen (beim Z80 insbesondere die Vektortabelle) initialisiert werden. [2] bei einem Warmstart versucht man, so wenig wie möglich RAM anzufassen, damit z.B. eine post mortem Analyse möglich bleibt. Einen Teil der Systemvariablen wird man aber trotzdem initialisieren wollen.
Nabend, er läuft... immmer, ohne Mucken, bei jedem Resetm, jedem Power Up .... hüstl. Ohne ins Detail zu gehen..... man hole sich neben der Hardware nicht eine zweite Fehlerquelle ins Haus.... den SDCC Compiler. Denn der hat es in sich und erzeugt fehlerhaften Code bzw wenn man nicht Dinge tut, die andere schon herausgefunden haben, die aber nicht im Manual stehen und auch nicht behoben worden sind. Spüielreien wie mit meheren Source Files arbeiten, Prototypen definieren, extern Variablen usw. sollte man erstmal lassen, da wird "noch dran gearbeitet", da der Linker damit nicht klar kommt. So muss die für den Z80 aussehen (Rohbau) und alles andere Zeugs da raus. Der Z80 braucht nicht mehr, Stackpointer setzen und loslaufen.
1 | .module crt0 |
2 | .globl _main |
3 | .area _HEADER (ABS) |
4 | ;; Reset vector |
5 | .org 0x0000 |
6 | jp init |
7 | init: |
8 | ld sp,#0xffff ;; Oder Testen, wo RAM zu ende |
9 | call _main ;; Hauptprogramm aufrufen |
10 | lo: halt ;; oder jp lo für Endlosschleife |
11 | |
12 | ;; Initialise global variables |
13 | call gsinit |
14 | call _main |
15 | ret |
16 | |
17 | ;; Ordering of segments for the linker. |
18 | .area _HOME |
19 | .area _CODE |
20 | .area _GSINIT |
21 | .area _GSFINAL |
22 | .area _GSINIT |
23 | gsinit:: |
24 | .area _GSFINAL |
25 | ret |
26 | .area _DATA |
27 | .area _BSEG |
28 | .area _BSS |
29 | .area _HEAP |
30 | |
31 | Konkret muss die ctr0.s modifiziert werden und genau deshalb spielte der auch verrückt. |
8255 tut es auch, LEDs blinken, 7 Segment kommt noch. ***************************************************** DANKE AN ALLE, DIE MIR BIS HIERHIN GEHOLFEN HABEN ! Ohne euch hätte ich das nie geschafft ! ******************************************************
Axel Schwenke schrieb: > Ein Monitorprogramm, das nach jedem Hardware-Reset einen Kaltstart [1] > macht, ist keinen Pfifferling wert. Es braucht eine wenigstens halbwegs > zuverlässige Heuristik, um zu entscheiden ob ein Kaltstart oder > Warmstart erforderlich ist. Vom Z-80 scheinst du keine Ahnung zu haben. Hardware-Reset ist Hardware-Reset! Das ist beim PC als auch beim AVR so.
Michael_ schrieb: > Das ist beim PC als auch beim AVR so. Eben dieser PC ist ein schönes Beispiel, dass auch ein ziemlich brutal wirkender Prozessor-Reset nicht ganz das sein muss, was Du dir darunter vorstellst. Da Intel keinen Weg aus dem protected mode in den real mode vorgesehen hatte, mussten Systeme, die diesen Weg dennoch benötigten, anfangs im vollen Galopp während des Normalbetriebs den Prozessor-Reset dafür verwenden: http://en.wikipedia.org/wiki/Protected_mode#Entering_and_exiting_protected_mode Der Trick besteht darin, im Monitor-Programm (oder eben dem BIOS) nicht gleich Grossputz zu machen. Sondern zu erkennen, dass im RAM sinnvoller Inhalt ist, der genutzt werden will.
:
Bearbeitet durch User
Michael_ schrieb: > Axel Schwenke schrieb: >> Ein Monitorprogramm, das nach jedem Hardware-Reset einen Kaltstart [1] >> macht, ist keinen Pfifferling wert. Es braucht eine wenigstens halbwegs >> zuverlässige Heuristik, um zu entscheiden ob ein Kaltstart oder >> Warmstart erforderlich ist. > > Vom Z-80 scheinst du keine Ahnung zu haben. Hardware-Reset ist > Hardware-Reset! Und du scheinst nicht lesen zu können. Natürlich startet der Z80 nach einem Reset immer bei 0000H. Aber was er dann macht, bestimmt das Monitorprogramm. Und wie bereits dargelegt, wäre es höchst kontraproduktiv, wenn es dann immer einen Kaltstart macht. XL
> Denn der hat es in sich und erzeugt fehlerhaften Code bzw wenn man > nicht Dinge tut, die andere schon herausgefunden haben, die aber > nicht im Manual stehen und auch nicht behoben worden sind. Och und ich dachte schon, das hätte sich zu meinem sdcc-Ärger im 8051-Mode von vor 14 Jahren mal irgendwie gebessert...
Georg A. schrieb: >> Denn der hat es in sich und erzeugt fehlerhaften Code bzw wenn man >> nicht Dinge tut, die andere schon herausgefunden haben, die aber >> nicht im Manual stehen und auch nicht behoben worden sind. > > Och und ich dachte schon, das hätte sich zu meinem sdcc-Ärger im > 8051-Mode von vor 14 Jahren mal irgendwie gebessert... Naja... so ganz frisch ist die Support Homepage auch nicht mehr... hüstl 17.05.09 Added a simple keyboard driver by Manoel Andrade Added a tool source by Stephan Le Meunier for counting machine cycles (mcs51) Ich schau dem Kleinen grad die ganze Zeit beim "Bit-Schaufeln" zu, wenn die LED anzeigen wo er grad ist beim RAM umschaufeln ....echt retro sowas :-) Ok, die Programmierung ist Einheitsbrei aber bald werde ich sicherlich noch voller Entzückung das Assembler-Gestammel lernen.... was schreibt sich eigentlich schneller? foo |= (1<<nr); // 2s zum tippen... oder incl "überlegen" das hier. Gefühlt 3 Minuten....
1 | ld a,4 (ix) |
2 | inc a |
3 | push af |
4 | ld e,#0x01 |
5 | pop af |
6 | jr 00110$ |
7 | 00109$: |
8 | sla e |
9 | 00110$: |
10 | dec a |
11 | jr NZ,00109$ |
12 | ld a,d |
13 | or a, e |
14 | ld d,a |
15 | jr 00103$ |
Ein Blick auf die Stromanzeige des Netzteils lässt allerdings die Frage aufkommen, ob Batterie-Applikationen vielleicht nicht so ganz angebracht waren damals... die NMOS CPU, die seit 1985 nicht mehr benutzt wurde ist erstens sehr heiss und auch der Rest hat einen gesunden Durst, 180mA die ganze Platine.
Das ist weniger als 1 Watt Leistung und völlig Ok. > inc a > push af > ld e,#0x01 > pop af > jr 00110$ Wozu push af und pop af? Ein Z80 hat Befehle für Bitmanipulation. Gruß, Holm
Christian J. schrieb: > die NMOS CPU, die seit 1985 nicht mehr benutzt wurde ist > erstens sehr heiss und auch der Rest hat einen gesunden Durst, 180mA die > ganze Platine. Ist doch völlig ok. NMOS heisst Dauerstrom, ob sie rennt oder pennt.
Christian J. schrieb: > oder incl "überlegen" das hier. Gefühlt 3 Minuten.... Der Compiler hat dafür garantiert keine 3 Minuten gebraucht, und auch keine 2 Sekunden. Wer auf die Idee kommt, sowas zu programmieren, und kein Compiler ist, ist ja wohl mit dem Klammerbeutel gepudert. Holm Tiffe schrieb: > Wozu push af und pop af? > Ein Z80 hat Befehle für Bitmanipulation. Wahrscheinlich hat er die Optimierung nicht eingeschaltet.
push af ld e,#0x01 pop af Das verstehe ich ehrlich gesagt auch nicht..... Optimierungen sind ein, aber ich habe das Gefühl, dass er mit dynamischen Variablenb, also Overlays auch Probleme hat. Der sheint die immer static anzulegen.
Axel Schwenke schrieb: > Natürlich startet der Z80 nach einem Reset immer bei 0000H. Aber was > er dann macht, bestimmt das Monitorprogramm. Und wie bereits dargelegt, > wäre es höchst kontraproduktiv, wenn es dann immer einen Kaltstart > macht. Bei klassischen Z-80 war das nicht üblich. Da wurde alles neu initialisiert. Wenn man Flash hat, kann man leicht eine Variable ablegen, welche man beim Neustart abfragt. Damals wäre das höchstens mit einem gepufferten C-MOS-RAM gegangen. Dies war aber nicht üblich.
Hängt vom Anwendungsfall ab. Der KC85 hat beispielsweise den RAM beim Warmstart nicht neu initialisiert, damit langwierig von Kassette geladene Anwendungen erhalten blieben. Bei Editoren u.ä. konnte man selbst entscheiden, ob man den Datenbereich neu initialisiert haben wollte (BASIC, WORDPRO) oder nicht (REBASIC, REWORDPRO). Dazu braucht es keinen gepufferten CMOS SRAM, das ging auch ohne prima. Was den SDCC angeht... der ist leider ziemlich beschränkt in seinem Weltbild. Aber sonst kenne ich nur den z88dk als halbwegs aktuellen C-Compiler für Z80.
Michael_ schrieb: > Axel Schwenke schrieb: >> Natürlich startet der Z80 nach einem Reset immer bei 0000H. Aber was >> er dann macht, bestimmt das Monitorprogramm. Und wie bereits dargelegt, >> wäre es höchst kontraproduktiv, wenn es dann immer einen Kaltstart >> macht. > > Bei klassischen Z-80 war das nicht üblich. Da wurde alles neu > initialisiert. Mit Verlaub, aber das ist Unsinn. Für die hier diskutierte Geräteklasse der Eigenbau-Computer gibt es gar kein üblich. Da waren die Monitore / BIOSe handgeklöppelte Einzelanfertigungen und haben gemacht was ihr Herrchen für sinnvoll hielt, nicht was üblich war (nach wessen Maßgabe eigentlich?). Aber auch der Z9001 aka KC87 hat z.B. sein RAM nach einem Reset nicht gelöscht. U.a. damit von Kassette nachgeladene Betriebssystemerweiterungen erhalten blieben. > Wenn man Flash hat, kann man leicht eine Variable ablegen, welche man > beim Neustart abfragt. > Damals wäre das höchstens mit einem gepufferten C-MOS-RAM gegangen. Dies > war aber nicht üblich. Jo. Und genau deswegen sprach Winfried von einem Flag im RAM. Weil RAM damals das einzige war, wo man sowas ablegen konnte. Und natürlich bringt das seine eigenen Probleme mit sich. Z.B. daß so ein Flag nach dem Kaltstart auch zufällig im RAM stehen kann. Weswegen man essentielle Initialisierungen (Stack, Interrupt-Vektoren) immer machen muß. Oder daß man bei einem Reset im laufenden Betrieb irgendwie den Refresh von evtl. vorhandenem DRAM sicherstellen muß. Aber nur weil du sowas nie gesehen (wohl eher: immer übersehen) hast und dir nie Gedanken darüber machen mußtest, heißt ja nicht daß es das nicht gab oder gibt. XL
naja, ich komm halt vom ATARI mit seiner 65C02. Die hatte auch nur RESET (auf 0xFFFF) aber die Resetroutine des Original-BIOS fragte als erstes das Warmflag im RAM ab, danach entschied sie über Kalt~ oder Warmstart. Im Kaltstartfall wurde dann mal gleich die Zeropage (0x000-0x400) initialisiert. Hier fanden sich alle nötigen Variablen und Vektoren des BIOS, da dieser RAM-Bereich mit minimaler Taktzyklenzahl zu lesen und zu schreiben war. ... Ich habe dann das Bios mit meinem Modifikationen in RAM Bänke hinter dem BIOS Rom geladen und dann mit gesetztem Warmflag das ROM abgesaltet und einen Reset ausgelöst schon lief mein Bios aus dem RAM und konnte 1MB in 16kB Blöcken einblenden das war schon recht ordentlich für einen 8-Bitter. ich meine damals auch aus der ZX-Spectrumecke solches gehört zu haben und muss mich schon sehr wundern hier so abgebürstet zu werden. eigentlich wa mir nur daran gelegen auf mögliche fehlerquellen in Startroutinen hinzuweisen. Aber sollte der TO daran weiters kein Interesse haben.... Ich hab auch genug anderes zu tun. @ Axel wir sind wohl zu alt für diese Retrowelt. Da ist ein Geradeausämpfänger das Grösste. Einen DoppelSuper baut hier keiner nach, geschweige ein vernünftiges BIOS. PS meinen Monitor habe ich natürlich auch selbst erweitert und in Assembler daran rumgestrickt. mit C Habe ich erst beim 386 angefangen. Namaste
:
Bearbeitet durch User
Axel Schwenke schrieb: > Mit Verlaub, aber das ist Unsinn. Für die hier diskutierte Geräteklasse > der Eigenbau-Computer gibt es gar kein üblich. Da waren die Monitore / > BIOSe handgeklöppelte Einzelanfertigungen und haben gemacht was ihr > Herrchen für sinnvoll hielt, nicht was üblich war (nach wessen Maßgabe > eigentlich?). Aber auch der Z9001 aka KC87 hat z.B. sein RAM nach einem > Reset nicht gelöscht. U.a. damit von Kassette nachgeladene > Betriebssystemerweiterungen erhalten blieben. Habs mir mal angeschaut. Reset ist eben nicht Reset. Beim obigen ist es eher ein Soft-Wiederstart. Einen richtigen kriegt man nur durch ziehen des Netzsteckers wieder hin. Oder man trägt softwaremäßig die Initialisierung ein. Übrigens wollte ich damals wissen wie es geht. Deshalb kein Z9001, sondern AC-1, LC-80, Z-1013. Letzterer mit ROM-Bank, 256K RAM, eigener Monitor (damit ist nicht der BS gemeint), TDL-Basic, Gens-Assembler usw. Alles nicht von der Stange, da mußte man schon im Gegensatz zu Z9001 o.ä. ein paar graue Zellen opfern.
Hallo, heute kam sie an, die "Special Edition Retro CPU" mit Firmenaufdruck. NMOS und wird schön warm :-) Gruss, Christian
Axel Schwenke schrieb: > Jo. Und genau deswegen sprach Winfried von einem Flag im RAM. Weil RAM > damals das einzige war, wo man sowas ablegen konnte. Und natürlich > bringt das seine eigenen Probleme mit sich. Z.B. daß so ein Flag nach > dem Kaltstart auch zufällig im RAM stehen kann. Luxusproblem. ;-) Über solche Probleme stolpert man nämlich erst, wenn man - faul wie man trotz Retro ja doch ist - statt einer Handvoll 4116 DRAMs modernere SRAMs verwendet. Bei DRAMs konnte man sich nämlich ziemlich drauf verlassen, dass nach ausreichend langer Zeit ohne Strom ein sinnvoll gewähltes Flag im RAM nicht den Warmstart-Wert enthält. Da war kein Zufall am Werk, sondern bloss ein paar Kondensatoren. Zumindest wenn man die Möhre nicht in der Tiefkühltruhe betrieben hat. Je kälter die Umgebung desto wärmer der Start. ;-) PS: Wenn man in der Geschichte noch weiter zurück geht, also vor die Ära des Z80 und der Halbleiter-RAMs, dann wird das noch interessanter. Da brauchts zwingend eine Unterscheidung zwischen Kalt- und Warmstart per Schalter, sonst wird das nie was. Ringkernspeicher war nicht-volatil.
:
Bearbeitet durch User
Michael_ schrieb: > TDL-Basic, Hallo! Leider habe ich mein handkommentiertes Disassembler-Listing irgendwo verlegt oder weggeworfen. Bevor ich noch aus dem 12K Maschinencode die restlichen Fehler gefunden hatte, war BASIC nicht mehr ganz so wichtig für mich. Es war aber erstaunlich leistungsfähig und umfangreich. Die Programmierer von von Technical Design Labs hatten eine Reihe von Tricks verwendet, um die Relokation (assemblieren für einen anderen Speicherbereich) zu erschweren. Das Reinspringen, mitten in sonst vernünftige Drei-Byte-Befehle, war so ein Trick.
Sowas hier?
1 | ; This is the commented BASIC listing of the |
2 | ; TDL 12K Extended "Zapple" BASIC, |
3 | ; by Roger Amidon and Neil Colvin, May 1977 |
4 | ; |
5 | ; This was produced by IDA disassembler |
6 | ; and further modified for readability (macros and long symbols) |
7 | ; note this is, although it looks like, not correct Z80 assembler |
8 | ; to be directly fed into an assembler program - mainly because |
9 | ; many symbols are too long for Z80 assemblers |
10 | ; use this as reference only, rather use the HEX dump |
11 | ; to produce a binary. |
12 | ; |
13 | ; The HEX dump has been compared with this commented file; |
14 | ; while commenting, several OCR errors were corrected. |
15 | ; |
16 | ; The hex dump was produced from the book |
17 | ; Rolf-Dieter Klein, Basic-Interpreter, Franzis Verlag M<FC>nchen, 1982; |
18 | ; in German language, ISBN 3-7723-6941-3 |
19 | ; The book author himself mentions in the book that he published |
20 | ; the hex dump because "Der Interpreter wurde urspruenglich von |
21 | ; TDL (Technical Design Labs) entwickelt und ist sehr leistungsfaehig. |
22 | ; Da die Firma nicht mehr existiert, soll durch den Abdruck des Listings |
23 | ; dem Leser die Moeglichkeit gegeben werden, Zugang zu diesem Basic zu |
24 | ; erhalten." (Seite 103) (Translation: the interpreter was developed |
25 | ; originally by TDL (Technical Design Labs) and is very powerful. |
26 | ; Because the company is no longer in existance, the reader is given |
27 | ; the chance, by printing this listing to get access to this Basic). |
28 | ; |
29 | ; The work of reverse engineering and commenting was done by Holger Veit, |
30 | ; 2012 - this whole work is published unter Creative Commons License |
31 | ; CC-BY-SA http://creativecommons.org/licenses/by-sa/3.0/ |
32 | |
33 | ;-------------------------------------------------------------------- |
34 | |
35 | ;**************************************************************** |
36 | ; some macro definitions for readability |
37 | CPHL_DE macro |
38 | ld a, h |
39 | sub d |
40 | jr nz, @@1 |
41 | ld a, l |
Da kann ich glaube ich helfen... http://www.tiffe.de/Robotron/Zapple-Basic/ Gruß, Holm
Holm Tiffe schrieb: > Da kann ich glaube ich helfen... > > http://www.tiffe.de/Robotron/Zapple-Basic/ > > Gruß, > > Holm und wie benutzt man diesen basic interpreter? muss man den an ein terminal anbinden? wie speichert er den quelltext usw?
Christian J. schrieb: > und wie benutzt man diesen basic interpreter? muss man den an ein > terminal anbinden? wie speichert er den quelltext usw? Doku ist doch dabei. Fernschreiber mit Lochstreifen-Stanzer/Leser waren damals gleichermassen Terminal, Drucker und Massenspeicher. Manche Bastler verwendeten auch alte Telex-Geräte mit dem eigentümlichen 5-Bit Baudot-Code, weil die hierzulande leichter zu kriegen waren als ASCII-Geräte. Das Basic arbeitete wie damals häufig über eine Sprungleiste, d.h. die Schnittstelle ist anpassbar. Das Arbeitsprinzip freilich nicht.
:
Bearbeitet durch User
Ok. Dachte man könnte den Quelltext in einen Speicherberei laden und er zieht sich dann Zeile für Zeile rein. Dann müsste man nur noch die putchar Funktion anpassen und hätte eine Ausgabe.
kennt Route_66 schrieb: > Hallo! > Leider habe ich mein handkommentiertes Disassembler-Listing irgendwo > verlegt oder weggeworfen. Bevor ich noch aus dem 12K Maschinencode die > restlichen Fehler gefunden hatte, war BASIC nicht mehr ganz so wichtig > für mich. Ja, einige Zeit später war ich stolzer Besitzer eines 286/12 mit Hercules. Ich hab aber meine Mappe wiedergefunden. Im ersten Bild ist der Anfang des Listings vom TDL. Vielleicht weiß jemand die Quelle. Wenn es rechtliche Probleme gibt, bitte löschen. Es stimmt mit dem ZAPPLE überein. Warum hieß das dann so? Über die Sprungtabelle und Änderungen des Codes hab ich es an den Z-1013 angepasst. Es lief dann prima. Die Abspeicherung hab ich dann zuletzt mit dem Header-Save von Brosig gemacht. Als Beispiel, wie mühsam es damals war, hab ich noch zwei Bilder angehängt. Per Hand analysiert und so Änderungen auch eingepflegt. Ohne Assembler! Drucken konnte ich auch schon mit einer S3004 Typenrad -Schreibmaschine. Da mußte man aber rausgehen und die Tür schließen, wenn die losgehämmert hat.
So, auch bei mir geht es weiter, klappte auf Anhieb die Anzeige und auch die Port Ansteuerung. Geht rihtig gut mit dem SDCC wenn man sich mit putty ein Terminal zum Cubietruck Linux Rechner öffnet, wo der Z80 Code per Bash Script kompiliert wird, dann Notepad ++ für den Source über das Samba Laufwerk und den Brenner, der sich sofort jeden veränderten Code automatisch reinzieht. Der TOP853 taugt schon. Nur jetzt mit 28C64B EEPROM statt der EPROM, das nervt doch zu sehr mit dem Löschen. Gebe gerne so rund 20 Stück ab. Schon schön, wie man Hardware einfach einmappen kann, reicht ein 8-fach D-Flip Flop dazu und schon hat man eine Portweriterung. Der I/O Bus, die Select Ausgänge des Demuxers und Ints sowie die Ports werdenn noch hinten über Pfosten herausgführt, eine Erweiterungsplatine ist schon in der Planung, die noch ein bisschen mehr Spielkram drauf haben wird. Aber erstmal den STI Baustein anschliessen, die Uart und Timer zu Laufen kriegen, damit ich Interrupts habe (muss in Asm gemacht werden, der SDCC kann das nicht) und eine Kommunikation mit dem PC herstellen. Das unten stehende Programm erzeugt 468 Bytes Code. Nur printf, sprintf sollte man nicht verwenden, dann explodiert der Code regelrecht. Evtl. werde ich doch noch 16kb einplanen und das RAM ein wenig kürzen auf 48kb. Eine Leitung ändern reicht ja.
1 | #include <asm/z80/features.h> |
2 | #include <stdlib.h> |
3 | #include <stdio.h> |
4 | #include <math.h> |
5 | #include <malloc.h> |
6 | #include <string.h> |
7 | |
8 | #include "main.h" |
9 | |
10 | |
11 | const char digits[11]= {0xc0,0xf5,0xa8,0xb0,0x95,0x92,0x92,0x82,0xf4,0x80,0x90}; |
12 | |
13 | |
14 | // PIO 8255 Special I/O |
15 | __sfr __at 0x20 PIO8255_PORT_A; |
16 | __sfr __at 0x21 PIO8255_PORT_B; |
17 | __sfr __at 0x22 PIO8255_PORT_C; |
18 | __sfr __at 0x23 PIO8255_CNTRL; |
19 | |
20 | // ADC 0804 |
21 | __sfr __at 0x40 ADC0804_READ; |
22 | |
23 | // 7b Segment |
24 | __sfr __at 0x60 SEG7; |
25 | |
26 | #define MAX_RAM 40000 |
27 | uint8_t ram[MAX_RAM+1]; |
28 | |
29 | // NMI Interrupt Handler |
30 | void cv_vint(void) |
31 | { |
32 | __asm |
33 | halt |
34 | __endasm ; |
35 | |
36 | } |
37 | |
38 | // Halte CPU an und lasse LED leuchten |
39 | void stop_cpu() |
40 | { |
41 | __asm |
42 | halt |
43 | __endasm ; |
44 | } |
45 | |
46 | // Setze oder lösche eine LED (0..7) am Port A |
47 | // Input: Led Nr, HIGH oder LOW |
48 | void SetLed(uint8_t lednr, bool stat) |
49 | { |
50 | uint8_t foo; |
51 | |
52 | // Read... |
53 | foo = PIO8255_PORT_A; |
54 | // Modify... |
55 | if (stat==TRUE) // LED ein = Bit LOW |
56 | foo &= ~(1<<lednr); |
57 | else |
58 | foo |= (1<<lednr); |
59 | // Write... |
60 | PIO8255_PORT_A = foo; |
61 | } |
62 | |
63 | // Zeitverzögerung |
64 | void delay(uint16_t cnt) { |
65 | volatile uint16_t k; |
66 | for (k=0;k<cnt;k++); |
67 | } |
68 | |
69 | /* |
70 | Stelle die Peripheriebausteine ein |
71 | */ |
72 | void InitHardware() |
73 | { |
74 | // 8255: Mode 0: Port A,B,C Output |
75 | PIO8255_CNTRL = 0x80; //Mode 0: Port A,B,C Output |
76 | PIO8255_PORT_A = 0xff; |
77 | PIO8255_PORT_B = 0; |
78 | PIO8255_PORT_C = 0; |
79 | |
80 | // 7-Segment .... |
81 | SEG7 = 0xff; |
82 | |
83 | // Interrupts der STI |
84 | |
85 | // STI Multi I/0 Uart |
86 | } |
87 | |
88 | int main() |
89 | { |
90 | uint8_t n,i; |
91 | uint16_t k; |
92 | |
93 | InitHardware(); |
94 | |
95 | for (n=0;n<10;n++) { |
96 | SetLed(0, HIGH); |
97 | SetLed(7, HIGH); |
98 | delay(5000); |
99 | SetLed(0, LOW); |
100 | SetLed(7, LOW); |
101 | delay(5000); |
102 | } |
103 | delay(20000); |
104 | |
105 | n = 0; |
106 | i = 0; |
107 | while (1) { |
108 | |
109 | SEG7 = digits[i++]; |
110 | if (i>9) |
111 | i=0; |
112 | |
113 | // RAM vollschreiben |
114 | for (k=0;k<MAX_RAM;k++) { |
115 | PIO8255_PORT_A = ~(uint8_t)k; |
116 | ram[k] = n; |
117 | } |
118 | // Ram auslesen und darstellen |
119 | for (k=0;k<MAX_RAM;k++) { |
120 | PIO8255_PORT_A = ~ram[k]; |
121 | |
122 | } |
123 | |
124 | n++; |
125 | } |
126 | |
127 | } |
Hallo, hoffe bin hier mit meiner Anfrage nicht völlig falsch. Kennt sich jemand mit dem Elzet 80 System aus und wo man dafür noch Unterlagen findet. Würde mir gerne so ein System oder ähnlich aufbauen (nachbauen). Leider finde ich fast keine Informationen dazu und eine Anfrage beim Hersteller nach alten Unterlagen ist bis jetzt Erfolglos. Hatte zwar Steckkarten dafür in der Bucht gefunden für Preise wo man ins grübeln kommt und 2 Seiten wo auch über dieses System nach Schaltplan und Unterlagen gesucht wird. Gruß und Danke Ronny
Hallo, ich möchte nochmal zu meinem Projekt nachfragen wie es denn mit der Treiberleistung des Z80 ausschaut? Aktuell hängen am Datenbus - RAM - ROM - STI Multi I/O - ADC Konverter - 8255 PIO - 74HCT274 Latch gefühlt ist das schon recht viel. Es sollen auf einer weiteren Karte noch mehr Bausteine dazu kommen, vor allem Portexpander und ein weiterer Timer Z80 CTC Baustein Muss ich dann zb einen 74LS640 bidir. Octal Bustreiber zur Entkopplung einsetzen?
Christian J. schrieb: > ich möchte nochmal zu meinem Projekt nachfragen wie es denn mit der > Treiberleistung des Z80 ausschaut? Das Thema hatten wir oben schon abgehakt. Erinnerst du dich an das Bild der grossen Platine mit 19 ICs am Bus, aber keinem einzigen Bustreiber? Beitrag "Re: Retro Fieber: Z80 oder 68000 ?" An den Datenbus zwischen CPU und Rest gepackt würde ein einzelner Treiber bei besagter Platine beim Lesen 18 Lasten auf 18 Lasten reduzieren ;-).
:
Bearbeitet durch User
> Muss ich dann zb einen 74LS640 bidir. Octal Bustreiber zur Entkopplung > einsetzen? Ich habe bei mir zwischen Z80 und Bus zwei 74LS243 (Datenbus) und drei 74LS244 (Adress- und Steuerleitungen) gesetzt, aber wahrscheinlich ginge es auch ohne. Nachteil: DMA von hinter den Bustreibern geht damit nicht mehr, weil die Steuerleitungen nicht von der Peripherie getrieben werden können. Das kann man zwar vermeiden, ist aber nicht ganz trivial von der Logik. :-)
S. R. schrieb: > Ich habe bei mir zwischen Z80 und Bus zwei 74LS243 (Datenbus) und drei > 74LS244 (Adress- und Steuerleitungen) gesetzt Wenn das die einzigen Treiber sind, dann ist der Effekt auf den Datenbus gleich Null. Denn beim Lesen müssen Speicher und IO-Bausteine genauso viele Lasten treiben wie ohne Treiber. Solche Treiber ergeben sich ganz natürlich, wenn der Kram auf allerlei Platinen verteilt ist und in einer Backplane steckt. Dann hat jede Platine ihren eigenen Treiber zur Backplane. Ist alles auf einer Platine, dann ist ein einzelner Datenbustreiber ziemlich sinnarm. Treiber für Steuerleitungen und einen Teil der Adressleitungen können dann zwingend werden, wenn etliche TTLs dran hängen (Dekoder, Logik, ...) und die statische Last der betreffenden Leitungen zu gross wird, also der Strom. NMOS und CMOS Bausteine hingegen stellen keine statische Last dar, nur eine kapazitive. Da ist es also eine Frage des Timings, und man darf raten, ab wieviel Bausteinen die stärkeren Treiber eines 74LS244 mehr Zeit einsparen als die Durchlaufzeit dieses Bausteine an Zeit kostet. > Nachteil: DMA von hinter den Bustreibern geht damit nicht > mehr, weil die Steuerleitungen nicht von der Peripherie getrieben werden > können. Das kann man zwar vermeiden, ist aber nicht ganz trivial von der > Logik. :-) Aus der Hüfte geschossen hätte ich gesagt, /BUSAK schaltet die Treiber der CPU ab, wenn der DMA auf Seite der Peripherie platziert wird. Und wenn du den DMA Controller auf der CPU-Seite deiner Treiber platzierst, damit der DMA auch von denen profitiert, dann schaltet dessen /CS den Datenbustreiber ab und das wars. Denkfehler?
:
Bearbeitet durch User
Hi, danke für die Info, dachte ich mir insgeheim auch schon. Und eine Backplane gibt es ja nicht, nur eine aufsteckbare Zusatzplatine. Dann werde ich mich mal mit dem Mode 2 Ints befassen und wie ich die dem sdcc compiler beibringe, der dafür nichts an Bord hat und wie ich meine auch der schlechtest dokumentierte Compiler überhaupt ist. Glücklicherweise hat er in der crt0.s die Möglchkeit Startup Code in Asm zu hinterlegen und kann auch inline asm verarbeiten (wobei schon Fehlermeldungen kommen, wenn man eine Variable von Asm aus adressieren will, die lokal ist und nicht global, zb einen Funktionsparameter. Ich bin noch nicht über Seite 50 in dem Zaks Buch aber soweit ich das verstehe kann der Mostek STI verschiedene Ints auslösen und ist kompatibl zum Z80. Ist dieser Gedankengang richtig? Der Z80 des Z80 wird mit "IM2" auf Mode 2 gestellt, das I Register mit dem Hibyte einer Adresse geladen zb 0x0080. Da der SDCC nur ROM Code erzeugen kann muss sich, sagen wir bei 0x0080 eine Tabelle befinden, die auf gerade Sprungadressen im ROM verweist. zb .org 0x80 jp int_1 jp int_2 jp int_3 usw. Jezt frage ich mich gerade, da das Datenblatt des STI doch sehr intensv studiert werden muss, ob die zurück gelieferten Vektoren der 16 Interrupts fix sind also zb 0...15 oder ich dem STI noch beibringen muss, welche Vektoren er zurück liefert? Es liest sich so, dass er seine 16 Ints auf 4 Bits abbildet und ich die oberen selbst einstellen kann. Das Ganze müsste natürlich vorher genau ausgerechnet werden, damit die Ints auch ihr Ziel "treffen" und wie ich vermute kann der sdcc wohl nicht dazu bewegt werden Funktionen auf feste Plätze zu legen, sondern der klatscht sie alle hintereinander.
Christian J. schrieb: > gefühlt ist das schon recht viel. Praktisch aber nicht. Denn das was du heutzutage an den Bus hängst, ist alles CMOS und braucht so gut wie keine Treiberleistung, verglichen mit dem nMOS-Krempel der früher üblich war. Kritischer sind die Lastkapazitäten. Sowohl durch die Eingänge der getriebenen IC als auch durch die Verdrahtung. Das wird sich so bemerkbar machen, daß dein System oberhalb einer gewissen Taktfrequenz instabil wird. XL
Christian J. schrieb: > Ich bin noch nicht über Seite 50 in dem Zaks Buch aber soweit ich das > verstehe kann der Mostek STI verschiedene Ints auslösen und ist > kompatibl zum Z80. Ja. > erzeugen kann muss sich, sagen wir bei 0x0080 eine Tabelle befinden, die > auf gerade Sprungadressen im ROM verweist. Das ist eine Vektortabelle, 16 Bits pro Zieladresse, keine Sprungleiste. Also sinngemäss struct { void (*vec0)(void); void (*vec1)(void); void (*vec2)(void); ... void (*vec127)(void); }; > welche Vektoren er zurück liefert? Ebendies. Jeder Z80 Device, das direkt den IM2 unterstützt, enthält eine Register, das den verwendeten Vektorbereich definiert.
Axel Schwenke schrieb: > Praktisch aber nicht. Denn das was du heutzutage an den Bus hängst, ist > alles CMOS und braucht so gut wie keine Treiberleistung, verglichen mit > dem nMOS-Krempel der früher üblich war. In einem Retro Thread ist der Begriff "heutzutage" etwas unpassend und er hat folgerichtig etlichen NMOS Kram auf der Platine. Aber NMOS hat auch doch auch bloss MOS-Gates am Eingang, anders als TTLs. Unterschiedlich ist die Charakteristik der Ausgänge.
A. K. schrieb: > Das ist eine Vektortabelle, 16 Bits pro Zieladresse, keine Sprungleiste. > Also sinngemäss > struct { > void (*vec0)(void); > void (*vec1)(void); > void (*vec2)(void); > ... > void (*vec127)(void); > }; Noch schöner wäre es, wenn es möglich wäre ein .org 0x0080 vor diesen Struct zu setzen, wenn er als const definiert würde. Aber das geht leider nicht. >> welche Vektoren er zurück liefert? > > Ebendies. Jeder Z80 Device, das direkt den IM2 unterstützt, enthält eine > Register, das den verwendeten Vektorbereich definiert. Da das STI das einzige Z80 Bauteil ist böte sich demzufolge an, die frei definierbaren Bits auf 0 zu setzen. Langsam wird es interessant :-)
Christian J. schrieb: > Der Z80 des Z80 wird mit "IM2" auf Mode 2 gestellt, das I Register mit > dem Hibyte einer Adresse geladen zb 0x0080. Und schon falsch. Die Tabelle startet immer bei einem Vielfachen von 0x100. 0x0080 ist also gar nicht möglich. 0x0400 wäre möglich. Ins I-Register müßte dann eine 0x04 geschrieben werden. > Da der SDCC nur ROM Code > erzeugen kann muss sich, sagen wir bei 0x0080 eine Tabelle befinden, die > auf gerade Sprungadressen im ROM verweist. Ja. Adressen > zb > > .org 0x80 > jp int_1 > jp int_2 > jp int_3 > > usw. Nein. Das erzeugt keine Liste von Adressen (2 Byte pro Eintrag) sondern eine Liste von Sprungbefehlen. Das sind immer 3 Byte pro Eintrag: ein Byte Opcode 0xC3 und dann zwei Byte Adresse. > Das Ganze müsste natürlich vorher genau ausgerechnet werden, damit die > Ints auch ihr Ziel "treffen" und wie ich vermute kann der sdcc wohl > nicht dazu bewegt werden Funktionen auf feste Plätze zu legen, sondern > der klatscht sie alle hintereinander. Das macht man in C auch anders. Stichwort Funktionszeiger (Artikel Funktionszeiger in C). In Assembler würde man einfach die Label für die Einsprungpunkte der Funktionen referenzieren. Da C vorinitialisierte Variablen kennt, würde man für die Interrupt- Vektortabelle einfach ein Array VoidFnct[256] anlegen, mit den Adressen (= Funktionspointern) für die ISR initialisieren und das Array fest auf die gewünschte Adresse der Vektortabelle binden. Dann legt der Compiler die initialen Daten ins ROM und der Startupcode kopiert sie ins RAM. In Assembler würde man eher die Tabelle einmal löschen und dann die handvoll Einträge die man braucht händisch überschreiben.
Christian J. schrieb: > Da das STI das einzige Z80 Bauteil ist böte sich demzufolge an, die frei > definierbaren Bits auf 0 zu setzen. Wenn du die Tabelle nach 0x0080 legen willst, was durchaus geht, dann wärs besser, wenn du die Vektoren auch passend nutzt. Denn beim STI sind die IM2 Adressbits A4..A7 frei definierbar, und wenn du die alle auf 0 setzt, dann landest du beim I7 Interrupt auf 0x0000=Reset statt 0x0080.
Axel Schwenke schrieb: > Die Tabelle startet immer bei einem Vielfachen von 0x100. 0x0080 ist > also gar nicht möglich. 0x0400 wäre möglich. Ins I-Register müßte dann > eine 0x04 geschrieben werden. Doch, das geht. Er braucht ja nur 16 Stück = 32 Bytes, nicht alle 127. Also I=0 und die Vektoren bei 0x80-0x9F verwenden.
:
Bearbeitet durch User
Axel Schwenke schrieb: > Praktisch aber nicht. Denn das was du heutzutage an den Bus hängst, ist > alles CMOS und braucht so gut wie keine Treiberleistung, verglichen mit > dem nMOS-Krempel der früher üblich war. Abgesehen vom CLOCK Pin sind die Lasten bei NMOS und CMOS Version der Z80 CPU exakt gleich definiert. 5pF pro Eingang, 15pF pro Ausgang (inkl. bidirektionale Pins). Das Timing spezifiziert Zilog für eine Last von 100pF, und zusätzliche 10ns pro zusätzliche 50pF Last, bis zusätzliche 100pF für Adressen/Steuerleitungen und 200pF für Datenleitungen. Wobei man aber nicht nur die Pins rechnen darf, die Verdrahtung zählt mit - Daumenregel 100pF/m, aber ob das auch auf Fädeltechnik mit dem extrem geringen Abstand benachbarter Leitungen zutrifft kann ich nicht sagen. Da ein SN74LS243 Treiber 12ns kostet ist man noch bei einer Buslast von insgesamt 150pF ohne Treiber schneller als mit.
:
Bearbeitet durch User
A. K. schrieb: > Axel Schwenke schrieb: >> Die Tabelle startet immer bei einem Vielfachen von 0x100. 0x0080 ist >> also gar nicht möglich. 0x0400 wäre möglich. Ins I-Register müßte dann >> eine 0x04 geschrieben werden. > > Doch, das geht. Er braucht ja nur 16 Stück = 32 Bytes, nicht alle 127. > Also I=0 und die Vektoren bei 0x80-0x9F verwenden. Ja. Dann liegt aber nicht die Tabelle bei 0x0080, sondern nur der erste genutzte Eintrag. Kleiner aber feiner Unterschied. XL
A. K. schrieb: > Da ein SN74LS243 Treiber 12ns kostet ist man noch bei einer Buslast von > insgesamt 150pF ohne Treiber schneller als mit. Bei komplettem Treibersatz, also Adress-, Steuer- und Datenleitungen hat man diese 12ns gleich zweimal an der Backe. Bei der grossen Platine mit rund 300pF am Datenbus musste eben etwas Reserve ins Timing rein, aber man war grad noch innerhalb von Zilogs Limit.
:
Bearbeitet durch User
A. K. schrieb: > Wenn du die Tabelle nach 0x0080 legen willst, was durchaus geht, dann > wärs besser, wenn du die Vektoren auch passend nutzt. Denn beim STI sind > die IM2 Adressbits A4..A7 frei definierbar, und wenn du die alle auf 0 > setzt, dann landest du beim I7 Interrupt auf 0x0000=Reset statt 0x0080. Also das kann irgendwie nicht sein, ohne mir jetzt I genau angeschaut zu haben. I gibt das MSB vor, also schonmal etwas was ICH ihm sage, also zb Tabelle bei 0x100. Das IO gibt den Rest vor, also 3 wählbare Bits und 4 für die 16 Ints. Ergo Zieladresse = I-Reg + (3 Bits vom STI) + (Interrupt Nummer) Kämpfe grad damit, bin nicht so fit in "Spezial-C", dass ich jetzt gleich die richtige Syntax für Zeiger auf Funktionen wüsste, die noch als const abgelegt sind. Klappt aber laut Hex Dump so auch. Es wird eine Tabelle erzeugt, die die Adresse der C Routinen enthält, wenn ich mir das Hex Dump anschaue. Nur muss ich wohl jeden Int, auch die die ich nicht brauche auf Routinen umlegen, damit keine Löcher entstehen.
1 | ;-------------------------------------------------------------------------- |
2 | ; crt0.s - Generic crt0.s for a Z80 |
3 | ;-------------------------------------------------------------------------- |
4 | |
5 | |
6 | .module crt0 |
7 | .globl _main |
8 | .globl _nmi_vint |
9 | .globl _int_sti_gpi_0 ; General Purpose Interrupt 0 |
10 | .globl _int_sti_gpi_1 ; General Purpose Interrupt 1 |
11 | .globl _int_sti_gpi_2 ; General Purpose Interrupt 2 |
12 | .globl _int_sti_gpi_3 ; General Purpose Interrupt 3 |
13 | |
14 | |
15 | |
16 | |
17 | .area _HEADER (ABS) |
18 | |
19 | ;/////////////////////////////////////////////////////////// |
20 | ; Reset vector bei Kaltstart |
21 | .org 0 |
22 | jp init ;; Sprung in die Init Routine |
23 | |
24 | ;/////////////////////////////////////////////////////////// |
25 | ;// Mode 1 Interrupt |
26 | .org 0x38 |
27 | reti |
28 | |
29 | ;/////////////////////////////////////////////////////////// |
30 | ; NMI Interrupt 0x66, muss mit retn abgeschlossen werden |
31 | .org 0x66 |
32 | push af |
33 | push bc |
34 | push de |
35 | push hl |
36 | push iy |
37 | push ix |
38 | call _nmi_vint ; Aufruf Handler im C Modul main.c |
39 | pop ix |
40 | pop iy |
41 | pop hl |
42 | pop de |
43 | pop bc |
44 | pop af |
45 | retn |
46 | |
47 | ;/////////////////////////////////////////////////////////// |
48 | ; Tabelle der Mode 2 Int Vektoren auf die Handler Funktionen |
49 | ;.org 0x80 |
50 | .dw _int_sti_gpi_0 |
51 | .dw _int_sti_gpi_1 |
52 | .dw _int_sti_gpi_2 |
53 | .dw _int_sti_gpi_3 |
54 | |
55 | |
56 | init: |
57 | ;; Stack an Spitze des RAM legen |
58 | ld sp,#0xffff |
59 | |
60 | ;; Globale Variablen initialisieren |
61 | call _main ;; Hauptprogramm aufrufen |
62 | halt |
63 | |
64 | ;; Ordering of segments for the linker. |
65 | .area _HOME |
66 | .area _CODE |
67 | .area _GSINIT |
68 | .area _GSFINAL |
69 | .area _GSINIT |
70 | .area _DATA |
71 | .area _BSEG |
72 | .area _BSS |
73 | .area _HEAP |
Christian J. schrieb: > Muss ich dann zb einen 74LS640 bidir. Octal Bustreiber Ich wusste doch, dass an dem was nicht stimmt... Ok, der geht im Prinzip schon. Aber ich schätze dass du bald den Spass dran verlierst, wenn du sämtliche Peripherie-Bits und IM2-Vektoren invertiert interpretieren musst. ;-)
In Mode 2, the programmer maintains a table of 16-bit starting addresses for every interrupt service routine. This table can be located anywhere in memory. When an interrupt is accepted, a 16-bit pointer must be formed to obtain the required interrupt service routine starting address from the table. The upper eight bits of this pointer is formed from the contents of the I Register. The I register must be loaded with the applicable value by the programmer, such as LD I, A. A CPU reset clears the I Register so that it is initialized to 0. The lower eight bits of the pointer must be supplied by the interrupting device. Only seven bits are required from the interrupting device, because the least-significant bit must be a 0. This process is required, because the pointer must receive two adjacent bytes to form a complete 16-bit service routine starting address; addresses must always start in even locations. Soviel zum Manual. Boah, dieses zehnmal über die Ecke indirekt indiziert denken macht mir nen Knoten ins Hirn :-( Da ich die Tabelle in der Zeropage liegen habe muss also das I Register = 0 sein.
Und bevor ich dne Text oben nicht mehr ändern kann, weil der nächste Beitrag kommt hier meine Vorstellung: I = 0x80 setzen, d.h. MSB = 0 STI Vektorregister auf 0, diese 3 Bits da drin STI löst Interrupt 3 aus und legt "0+3" auf den Bus, also 3 Z80 baut zusammen: I + "3" und landet bei 0x80 + (3 * 2Bytes) = 0x86 Bei 0x86 steht ein Doppelwort, also zb 1234 Z80 führt ein JMP 3412 aus, da zuerst Low, dann High Byte Soweit ok?
Christian J. schrieb: > Also das kann irgendwie nicht sein, ohne mir jetzt I genau angeschaut zu > haben. Herrje, immer diese Ungläubigen :-) Vektoradresse: A15..A8 = I A7..A5 = D7..D5 des PVR vom STI A4..A1 = Interrupt-Nummer A0 = 0 Wenn du auf 0x80 für den ersten Vektor kommen willst, dann muss 0b100 in D7..D5 des PVR.
Christian J. schrieb: > Z80 baut zusammen: I + "3" und landet bei 0x80 + (3 * 2Bytes) = 0x86 Bloss weil die Z80 CPU so heisst, zaubert die dir keine magischen 0x80 in die Rechnung. Dein Vektor landet auf 0x0006.
:
Bearbeitet durch User
A. K. schrieb: > Bloss weil die Z80 CPU so heisst, zaubert die die keine 80 in die > Rechnung. Dein Vektor landet auf 0x0006. Ok, das konnte ich nicht mehr ändern weil du schneller warst. Die 80 müssen vom STI kommen, was ich aber nicht so dolle finde. Aber über das I Reg lassen sich ja nur 0x100er Felder abdecken und bei 8k muss man schon etwas sparsam sein zudem der Compiler noch dazu kommt, denn der darf den Code nicht plattmachen, er weiss ja nichts von dieser Tabelle, wenn ich die erst zur Laufzeit erzeuge bzw einstelle. >Bei 0x86 steht ein Doppelwort, also zb 1234 >Z80 führt ein JMP 3412 aus, da zuerst Low, dann High Byte >Soweit ok? Da ist richtig denke ich mal.
Wenn es dir um Platz geht, dann leg die Tabelle auf die unbenutzten Adressen 0x0040-0x005F und definiere PVR[7-5]=0b010 und I=0x00. Ob du das nun toll findest oder nicht. Dein Programm kann dann direkt hinter dem NMI anfangen. Wenn dir der Platz egal ist, dann nimm 0x0100-0x011F mit PVR[7-5]=0x000 und I=0x01.
:
Bearbeitet durch User
Ok, da ist noch Platz :-) Auf jeden Fall assembliert er jetzt fehlerfrei durch und auch der C Compiler mecker nicht.
1 | .module crt0 |
2 | .globl _main |
3 | .globl _nmi_vint |
4 | .globl _int_sti_gpi_0 ; General Purpose Interrupt 0 |
5 | .globl _int_sti_gpi_1 ; General Purpose Interrupt 1 |
6 | .globl _int_sti_gpi_2 ; General Purpose Interrupt 2 |
7 | .globl _int_sti_gpi_3 ; General Purpose Interrupt 3 |
8 | |
9 | ;/////////////////////////////////////////////////////////// |
10 | ; Tabelle der Mode 2 Int Vektoren auf die Handler Funktionen |
11 | |
12 | .org 0x80 |
13 | .dw _int_sti_gpi_0 |
14 | .dw _int_sti_gpi_1 |
15 | .dw _int_sti_gpi_2 |
16 | .dw _int_sti_gpi_3 |
Und später im .c File
1 | void int_sti_gpi_0(void) |
2 | { |
3 | |
4 | } |
5 | |
6 | void int_sti_gpi_1(void) |
7 | { |
8 | |
9 | } |
10 | void int_sti_gpi_2(void) |
11 | { |
12 | |
13 | } |
14 | void int_sti_gpi_3(void) |
15 | { |
16 | |
17 | } |
Muss das aber noch im De-Assembler kontrollieren. Ergibt
1 | 354 ; --------------------------------- |
2 | 355 ; Function int_sti_gpi_0 |
3 | 356 ; --------------------------------- |
4 | 0149 357 _int_sti_gpi_0_start:: |
5 | 0149 358 _int_sti_gpi_0: |
Also Adresse 0x100 + 0x149 = 0x249 und im Map steht.
1 | 00000249 _int_sti_gpi_0 main |
2 | 00000249 _int_sti_gpi_0_start main |
3 | 0000024A _int_sti_gpi_0_end main |
4 | 0000024A _int_sti_gpi_1 main |
5 | 0000024A _int_sti_gpi_1_start main |
6 | 0000024B _int_sti_gpi_1_end main |
7 | 0000024B _int_sti_gpi_2 main |
8 | 0000024B _int_sti_gpi_2_start main |
9 | 0000024C _int_sti_gpi_2_end main |
10 | 0000024C _int_sti_gpi_3 main |
11 | 0000024C _int_sti_gpi_3_start main |
12 | 0000024D _int_sti_gpi_3_end main |
Im Asm Listing aber sind es Nullen. Allerdings assembliert er erst das Startup und linked dann alles zusammen, können also auch Platzhalter sein.
1 | Sxxxx Assembler V02.00 + NoICE + SDCC mods + Flat24 (Zilog Z80 / Hitachi HD64180), page 2. |
2 | |
3 | |
4 | |
5 | 0080 57 .org 0x80 |
6 | 0080 00 00 58 .dw _int_sti_gpi_0 |
7 | 0082 00 00 59 .dw _int_sti_gpi_1 |
8 | 0084 00 00 60 .dw _int_sti_gpi_2 |
9 | 0086 00 00 61 .dw _int_sti_gpi_3 |
Das Hex File sieht dann aber so aus.... wie in dem Bild und 02C9 ist ja nicht 0249. Häh??
Hier ist die Map Tabelle... den NMI setzt er richtig auf 0x137 mit CD 37 01 aber die .dw ..... sind falsch.
1 | Area Addr Size Decimal Bytes (Attributes) |
2 | -------------------------------- ---- ---- ------- ----- ------------ |
3 | _CODE 00000100 0000018F = 399. bytes (REL,CON) |
4 | |
5 | Value Global Global Defined In Module |
6 | ----- -------------------------------- ------------------------ |
7 | 00000100 _stop_cpu main |
8 | 00000100 _stop_cpu_start main |
9 | 00000102 _copyright main |
10 | 00000102 _stop_cpu_end main |
11 | 00000127 _digits main |
12 | 00000137 _nmi_vint main |
13 | 00000137 _nmi_vint_start main |
14 | 00000139 _InitHardware main |
15 | 00000139 _InitHardware_start main |
16 | 00000139 _nmi_vint_end main |
17 | 0000014E _InitHardware_end main |
18 | 0000014E _SetDigit main |
19 | 0000014E _SetDigit_start main |
20 | 00000174 _SetDigit_end main |
21 | 00000174 _SetLed main |
22 | 00000174 _SetLed_start main |
23 | 000001BB _SetLedByte main |
24 | 000001BB _SetLedByte_start main |
25 | 000001BB _SetLed_end main |
26 | 000001CC _SetLedByte_end main |
27 | 000001CC _delay main |
28 | 000001CC _delay_start main |
29 | 000001FA _LED_Rotate main |
30 | 000001FA _LED_Rotate_start main |
31 | 000001FA _delay_end main |
32 | 00000249 _LED_Rotate_end main |
33 | 00000249 _int_sti_gpi_0 main |
34 | 00000249 _int_sti_gpi_0_start main |
35 | 0000024A _int_sti_gpi_0_end main |
36 | 0000024A _int_sti_gpi_1 main |
37 | 0000024A _int_sti_gpi_1_start main |
38 | 0000024B _int_sti_gpi_1_end main |
39 | 0000024B _int_sti_gpi_2 main |
40 | 0000024B _int_sti_gpi_2_start main |
41 | 0000024C _int_sti_gpi_2_end main |
42 | 0000024C _int_sti_gpi_3 main |
43 | 0000024C _int_sti_gpi_3_start main |
44 | 0000024D _int_sti_gpi_3_end main |
45 | 0000024D _main main |
46 | 0000024D _main_start main |
47 | 0000028F _main_end main |
Ok, probieren geht über studieren, man muss Klammern setzen, da es ein Vektor ist... dann steht das richtige in der Tabelle drin. ;/////////////////////////////////////////////////////////// ; Tabelle der Mode 2 Int Vektoren auf die Handler Funktionen .org 0x80 .dw (_int_sti_gpi_0) .dw _int_sti_gpi_1 .dw _int_sti_gpi_2 .dw _int_sti_gpi_3
Nachwort: So, ich habe jetzt ein komplettes Programmgerüst für den SDCC Compiler für Z80 "Minisysteme" mit Nutzung der Interrupts, die mit einigen Workarounds eingebaut wurden, da der sdcc sie nicht unterstützt bzw nur marginall, zb durch __interrupt oder __naked Pragmas, die die Coderzeugung beinflussen. D.h. wenn jemand Spass an sowas hat aber weniger Assembler programmieren will oder nur da wo es nötig ist kann er von mir dieses Gerüst haben. Ich entwickle es noch um einiges weiter, es ist natürlich nur auf den STI angepasst und nicht auf andere Bausteine aber nirgendwo im Netz finden sich Informationen, die mit google findbar sind, die beschreiben wie das zu machen ist. Ich habe da Stunden gesucht, der sdcc ist sowas von wenig vertreten und erzeugt doch guten Code wenn man auf die Veewendung von Libs verzichtet, denn ein rand() knall mal eben 2000 Bytes Code dazu, wozu weiss keiner. Kann man das hier irgendwo ablegen, wenn es fertig ist?
A. K. schrieb: > Artikel dazu bauen. Bin zu blöd ein Wiki zu bedienen, da auch kein Interesse daran. Maixmal ein Plaintext File.
Christian J. schrieb: > Bin zu blöd ein Wiki zu bedienen, da auch kein Interesse daran. Maixmal > ein Plaintext File. Von Plaintext zum Wiki-Artikel ist der Schritt u.U. nicht sehr groß. Fang doch mit dem Textfile als Artikel an, der Rest findet sich dann...
A.K. !!!!!!!!!!!!!!!!!! Hilfe..... du hast mir doch den MK3801 empfohlen und den studiere ich jetzt grad mal näher. Hallo Baudrate? Der kann doch wohl nicht nur 1:1 und 1:16? Ich brauche ujnbedingt den async Mode, da ich nur USB Umsetzer habe und möglichst die bekannten Baudraten fahren will. Das steht nichts weiter von einem Prescaler drin...... Und alles ist schon eingebaut...
A. K. schrieb: > Wenn das die einzigen Treiber sind, dann ist der Effekt auf den Datenbus > gleich Null. Denn beim Lesen müssen Speicher und IO-Bausteine genauso > viele Lasten treiben wie ohne Treiber. Ja, aber dafür müssen dann die Einsteckkarten selbst sorgen. Die Treiber sitzen auf der Hauptplatine vor den Steckplätzen (und die Chips auf der Hauptplatine werden vom Z80 selbst gestrieben). > NMOS und CMOS Bausteine hingegen stellen keine statische > Last dar, nur eine kapazitive. NMOS braucht einen konstanten Stromfluss, um low-Pegel zu halten? > Aus der Hüfte geschossen hätte ich gesagt, /BUSAK schaltet die Treiber > der CPU ab, wenn der DMA auf Seite der Peripherie platziert wird. Und > wenn du den DMA Controller auf der CPU-Seite deiner Treiber platzierst, > damit der DMA auch von denen profitiert, dann schaltet dessen /CS den > Datenbustreiber ab und das wars. Denkfehler? Klingt logisch, aber ich habe ein paar Design-Entscheidungen getroffen, die das trotzdem verhindern. Da ich keine Z80-Peripherie benutze und auch sonst alles zu Fuß erledige, sind meine Slots nur I/O-fähig (bis auf den einen, wo der Speicher drin steckt) und der einzige DMA-Master sitzt auf der Hauptplatine. Einen DMA-Controller habe ich nicht. Beim nächsten Mal denke ich an dich. ;-)
Nochmal meiner einer: Ich sehe da nur eine Rettung bei dem Mostek 3801, man ja kaum mehr einen Suporter fragen kann: Timer C oder sind kastriert, können nur Delay. Ich vermute mal, dass die einfach endlos mit dem Prescaler Takt von 0..255 rennen und dann von vorn. Capture/Compare war ja wohl nicht vorgesehen (ich vermisse schcon wieder ARM Timer... der pure Luxus). Den Ausgang einer dieser Timer dann auf 1:x Teilen und diesen Ausgang an den RC und TC der USART gleichermaßen legen, damit die mit dem reduzierten Takt rumtackert und man sich irgendwie auf 56700 Baud einigt. Das Datenblatt ist so nett und spricht diesen Mode erst gar nicht an. Also muss ich 3.686.400 Hz des System Clock runterteilen / 64 und dann taketet er mit 56700 eins weiter. Aber das heisst ja noch nicht, dass der Timer Ausgang auch 56700 liefert. Wann wird der überhaupt gesetzt? Bei Überlauf von 255 auf 0? Oder zählen die wie es beim 8253 üblich war rückwärts und werden mit einem Reload Wert vorgeladen, denn sie immer wieder reinladen bei Überlauf? Etwas antike Technik.... Au weia.... Gibt aber Leute "Bitsavers", die sogar eine App.note gegescannt haben: http://schuetz.thtec.org/mccomputer/Mostek%20-%20MK3801%20Application%20Notes.pdf "Time Constant" scheint der Reload zu sein, 3 ist minimum damit 9600 baud bei rauskommen.
Christian J. schrieb: > Ich vermute mal Wie wäre es mit lesen? In der von dir zitierten App Note steht explizit drin, inklusive ASM-Schnipsel, wie man Timer C oder D als Baudraten Generator verwendet.
S. R. schrieb: >> NMOS und CMOS Bausteine hingegen stellen keine statische >> Last dar, nur eine kapazitive. > > NMOS braucht einen konstanten Stromfluss, um low-Pegel zu halten? Ein NMOS Eingang ist das Gate eines N-MOSFETs. Dass der intern eine Stromquelle am Drain hat, statt eines P-MOSFETs wie bei CMOS, das beeinflusst nur den Stromverbrauch des Chips. Bei einem NMOS Ausgang hast du Recht. Der hat eine Stromquelle als Pullup. Bei Ausgängen ist die CMOS Version der Z80 daher auch anders spezifiziert als die NMOS-Version, wesentlich höherer Source-Strom. Aber im Tristate ist diese Stromquelle abgeschaltet (wär ja sonst kein Tristate).
:
Bearbeitet durch User
Christian J. schrieb: > Also muss ich 3.686.400 Hz des System Clock runterteilen / 64 und dann > taketet er mit 56700 eins weiter. Aber das heisst ja noch nicht, dass > der Timer Ausgang auch 56700 liefert. Die UART benötigt wie üblich die 16fache Frequenz am Takteingang. Das muss einer der Timer liefern. Bei mir wars damals 9600 Baud mit Prescaler /4 und Timerwert 4. Andere Timerwerte waren 1=38400 und 2=19200. Systemtakt unbekannt, demgemäss offenbar 2,4576MHz.
:
Bearbeitet durch User
Hi, ich hatte das zweite Blatt der App nicht gesehen bzw hing der Reader etwas. Also läuft die Baudratenerzeugung auf der letzten Rille bei einem Wert von 3 oder 4, Finetuning kann man da vergessen. Nochmal zurück zu den Timern. Sind die vom 8253/54 abgekupfert? Das Mostek Datenblatt ist ja absolut unzureichend. Laufen die Timer also so, dass man ins Data Register einen Wert reinschreibt und die zählen dann rückwärts bis 0, setzen den Out Pin für einen Zykus HIGH und laden sich dann wieder den Startwert aus einem Latch rein? Wie gesagt sind heutige Timer deutlich aufwendiger und komplexer und ich erinnere mich nur schwach daran was ich mit 17 mal mit dem 8253 gemacht habe. Nur mal so gefragt: Hat das verkrampfte indirekte Adressieren einiger Register einen fertigungstechnischen Grund? Oder gingen denen die Pins aus, weil man dafür einen Adressierungspin mehr gebraucht hätte? Aktuell habe ich ja noch den sdasz80 Assembler, der eine "Eigenproduktion" von einem Brian ist und sich leider nicht an gängige Konventionen der Syntax hält. Leider ist er Bestandteil des sdcc. UNd bisher weiss auch niemand wie man aus einem inline asm Teile Variablen des C Teils anspricht. Allerdings stelle ich auch grad fest dass mans ich aus denb Linux Repos eine Version 3.1.0 von 2012 installiert. Zumindest wenn man sdcc auf einem A20 (Cubietruck) mit wheezy laufen lässt. Die Sourcen gibt es ja hier: http://sdcc.sourceforge.net/snap.php#Linux
Christian J. schrieb: > Also läuft die Baudratenerzeugung auf der letzten Rille bei einem > Wert von 3 oder 4, Finetuning kann man da vergessen. Was willst du denn da tunen? Fraktionale Baudratentimer gabs erst Jahrzehnte später, in Retro gibts die nicht. 57kbd und 115kbd gab es anno STI auch noch nicht. Manch olle UARTs konnten nicht mehr als 19200. > Nochmal zurück zu den Timern. Sind die vom 8253/54 abgekupfert? Nicht dass ich wüsste. Ich habe auch nicht den Eindruck, dass die Timer des STI sonderlich komplex wären. Und auch nicht, dass Komplexitität deine Spezialität wäre. ;-) > Das Mostek Datenblatt ist ja absolut unzureichend. Sieh es als frühe Form des Umweltschutzes ;-). Datasheets standen damals in Büchern, nicht in PDFs. Dickere Bücher kosteten mehr Bäume. Betrachte es doch mal als Herausforderung, nicht als Hindernis. > Laufen die Timer also so, Probiers halt aus. > Wie gesagt sind heutige Timer deutlich aufwendiger und komplexer Du bist ganz sicher, dass du es gerne komplexer hättest? Beim SIO hast du eben deshalb die Segel gestrichen und dabei war der deutlich einfacher als Zilogs SCC ein paar Jahre drauf. Retro gibts halt nicht ohne Retro-Stil. Oder fast nicht. Damals sass man rum, mit dem was man hatte, und probierte es im Zweifel eben aus, statt sich jedes Bit per Web erklären zu lassen. > Nur mal so gefragt: Hat das verkrampfte indirekte Adressieren einiger > Register einen fertigungstechnischen Grund? Ja. 41-PIN DIP Gehäuse sind sehr selten. ;-) > Aktuell habe ich ja noch den sdasz80 Assembler, der eine > "Eigenproduktion" von einem Brian ist und sich leider nicht an gängige > Konventionen der Syntax hält. Zugegeben, ich hatte meinen eigenen Assembler und "Compiler". Wie die funktionierten wusste ich zufällig. ;-) Allerdings gehst du mit dem Zwang, sofort unbedingt SDCC statt Assembler zu verwenden, den deutlich schwereren Weg eines Zweifrontenkriegs. Zudem ist das kein Bisschen Retro.
:
Bearbeitet durch User
A. K. schrieb: > Was willst du denn da tunen? Fraktionale Baudratentimer gabs erst > Jahrzehnte später, in Retro gibts die nicht. 57kbd und 115kbd gab es > anno STI auch noch nicht. Manch olle UARTs konnten nicht mehr als 19200. Ich werde mit leben .....müssen. > Probiers halt aus. Ich erinnere mich schwach, dass ich Datenbücher aus der Bibliothek holte und ansonsten alle möglichen Hersteller anrief, damit sie mir welche schicken. Weil Internet... gab es ja nicht :-( Telefonbuch und Auskunft. Und bei Firmen schonmal Müllcontainer wo man sich Bücher rausholen konnte. > ohne Retro-Stil. Oder fast nicht. Damals sass man rum, mit dem was man > hatte, und probierte es im Zweifel eben aus, statt sich jedes Bit per > Web erklären zu lassen. Das werde ich gern machen.... ich frage sie ob sie vorwärts oder rückwärts laufen :-) > Zugegeben, ich hatte meinen eigenen Assembler und "Compiler". Wie die > funktionierten wusste ich zufällig. ;-) Das ist schon das erste Problem, weil die mehr programmieren als Dokus machen. Und wie ich grad mit Schreck festelle zieht sich Debian eine andere Version runter als Mint. Aber das liegt eben auch an mir, dass ich den ganzen Kram vom PC aus in einem Terminal auf dem Cubie mache und das grad umgestellt habe. Und ein Vergleich lieferte 50 Bytes weniger Code bei 3.3.0 gegenüber 3.1.,0 und auch einige Macros funktionierten plötzlich. > Allerdings gehst du mit dem Zwang, sofort unbedingt SDCC statt Assembler > zu verwenden, den deutlich schwereren Weg eines Zweifrontenkriegs. Zudem > ist das kein Bisschen Retro. Versteh mich nicht falsch, ich lese das Zaks Buch gern und schaue mir auch die Listings mit diesem prähistorischen Gebrabbel an: ld, cpl, in, out ... (wer das den ganzen Tag macht wird sicher impotent davon) aber ein 16 Bit c=a+b tippt sich eben deutlich schneller als ld a,-2 (ix) add a, -4 (ix) ld d,a ld a,-1 (ix) adc a, -3 (ix) ld -6 (ix), d Genauso mit den EPROMs.. die hier jetzt rumliegen und so schöne Fenster haben durch die man die Bits sehen kann ..... habe 3 Flash EEPROM gekauft und finde das deutlich entspannter die zu flashen anstatt den Toaster wieder rauszuholen und 20 Minuten zu warten bzw die ganze Stange erst durchzubrenne bis die Soft läuft und dann 20 EPROMs zu je 5 Stück wieder zu löschen. Nenn es den Sieg des Menschen über die Maschinen :-)
Christian J. schrieb: > Nenn es den Sieg des Menschen über die Maschinen :-) Oder die Kapitulation des Menschen vor der ihm auf ewig unverständlich bleibenden Maschine. ;-)
Wusstest Du dass der T1000 Terminator auf ner 6510 CPU läuft und dass der Code von Steve Wosniak geschrieben wurde auf einem Apple ][ ? Der war wohl auch "Retro" :-)
Christian J. schrieb: > aber ein 16 Bit c=a+b tippt sich eben deutlich schneller als > > ld a,-2 (ix) > add a, -4 (ix) > ld d,a > ld a,-1 (ix) > adc a, -3 (ix) > ld -6 (ix), d Wer macht denn sowas? ADD HL,rr (rr=BC,DE,HL,SP) existiert. fchk
Christian J. schrieb: > Wusstest Du dass der T1000 Terminator auf ner 6510 CPU läuft und dass > der Code von Steve Wosniak geschrieben wurde auf einem Apple ][ ? Immerhin. 1-2 Jahrzehnte lang sahen interaktive Computer-Szenen meist irgendwie nach C64 aus. Wenn du bissel suchst, kannst du vielleicht auch einen 16-Bit 6502 mit 16MB Adressraum programmieren. Gabs wirklich!
A. K. schrieb: > Wenn du bissel suchst, kannst du vielleicht auch einen 16-Bit 6502 mit > 16MB Adressraum programmieren. Gabs wirklich! Seit ich im Netz Seiten fand von Leuten, die sich ihre eigenen CPUs aus Gattern und Mikrocode im EPROM aufbauten, was sie der Echtheit auch noch hätten weglassen können haut mich nichts mehr um. Sicher wird auch irgendeiner bald ne CPU aus einzelnen Transistoren zusammen löten, weil er grad geschieden wurde und seitdem zu viel Zeit hat :-) Da ich mir grad bei wikipedia einiges über das Pipelining moderner CPU durchgelesen habe und wie das mit L1 und L2 Cache zusammen wirkt kommt mir der Gedanke, dass Assembler keine Chance mehr hat, da ein Programmierer sich nun wirklich nicht für das Innenleben einer Super CPU interessieren muss um effinzienten Code zu schreiben. Das kann ein Compiler besser wenn er weiss wie die Architektur funktioniert, so dass zb Pipline Flushes vermieden werden durch geschickte bedingte Sprünge usw.
> ich hatte das zweite Blatt der App nicht gesehen bzw hing der Reader > etwas. Also läuft die Baudratenerzeugung auf der letzten Rille bei einem > Wert von 3 oder 4, Finetuning kann man da vergessen. Ein Baudratenquarz macht, dass die Baudrate exakt ist. Was willst du da noch tunen? > Aktuell habe ich ja noch den sdasz80 Assembler, der eine > "Eigenproduktion" von einem Brian ist und sich leider nicht an gängige > Konventionen der Syntax hält. Es gibt keine "gängige Konventionen der Syntax". Jeder Assembler macht das anders, und wenn du einen anderen Assembler benutzt als der Autor des Buches, dann sind gewisse Dinge halt anders. Im Gegensatz zum C-Compiler ist der Assembler aber gut dokumentiert. Zumindest habe ich mal eine passende ausreichende Doku zu dem gefunden und danach das BIOS gebaut. > Leider ist er Bestandteil des sdcc. UNd bisher weiss auch niemand wie > man aus einem inline asm Teile Variablen des C Teils anspricht. Du weißt es nicht. Alle anderen benutzen einfach den Symbolnamen, wie bei den großen Compilern auch. Möglicherweise mit Unterstrich davor.
Nicht grad Einzeltransistoren, sondern TTLs einschliesslich MSI und damit viel moderner als das ausschliesslich aus NORs gebaute Original. Aber immerhin komplett ohne Abkürzung per EPROM: http://klabs.org/history/build_agc/
S. R. schrieb: > Du weißt es nicht. Alle anderen benutzen einfach den Symbolnamen, wie > bei den großen Compilern auch. Möglicherweise mit Unterstrich davor. Das funktoniert aber leider nur bei globalen Variablen. Bei lokalen, also dynamisch erzeugten wirft er einen Fehler aus, dass er die nicht kennt. Zumindest habe ich es noch nicht mit V3.3.0 ausprobiert. Der _ dafür ist bekannt.
A. K. schrieb: > Nicht grad Einzeltransistoren, sondern TTLs einschliesslich MSI und > damit viel moderner als das ausschliesslich aus NORs gebaute Original. > Aber immerhin komplett ohne Abkürzung per EPROM: > http://klabs.org/history/build_agc/ Mal kurz quergelesen und ein pdf geöffnet. Das erfordert schon eine sehr gute Kenntnis von Computern die weit über das hinaus geht, was man so landläufig lernt. Hier ist der Weg das Ziel, denn das Ding kann ja faktisch nichts, was nicht jeder AVR heute auch kann, nur eben im Format Schrankwand. Also mit maximalem Aufwand etwas Minimales erreichen. Soll sicher so athentsich wie möglich sein. Allein die Recherchen die Spec zu bekommen dürften endlos gewesen sein. Nee, lass mal.... habe noch andere Hobbies (Börse und Daytrading), da brauche ich meinen Kopf für.
Christian J. schrieb: > da ein > Programmierer sich nun wirklich nicht für das Innenleben einer Super CPU > interessieren muss um effinzienten Code zu schreiben. Nur bedingt richtig. Gelebte Praxis aus der näheren Umgebung zeigt, dass man ohne Kenntnis der Mikroarchitektur solcher Kisten insbesondere bei Multithreading allzu leicht in einige Stolperfallen reinläuft. Das behebt sich zwar nicht durch Assembler, aber einfach C/C++/... programmieren und das Beste hoffen ist auch nix. Entsprechendes Lowlevel-Knowhow kann ein Programm ohne Änderung am grundlegenden Verfahren um ein Vielfaches beschleunigen. Und da kommt immer mal wieder eine Schweinerei dazu. Schau dir mal Haswells Transactional Memory an, wo du schon dabei bist: http://www.realworldtech.com/haswell-tm/ http://www.realworldtech.com/haswell-tm-alt/
Du, bin jetzt weg in die Sauna und noch ne Runde schwimmen im Keller-Bad. Hause ja hier in einem völlig leerstehendn Ferienheim :-) Wie gesagt freue ich mich, dass ich mit Hilfe dieses Forums und viel lesen ein Z80 System zum Laufen gekriegt habe statt wie sonst nur ein paar AVR zusammen zu pflastern oder einen Arduino, wo ja alles funktioniert. Das Boadr zählt grad munter von 0-9 und die LEDs oben wandern a la Knight Rider. Das reich erstmal. Muss noch den Mostek anschliessen, sind ja auch ca 20 Leitungen ohne die Ports, habe langsam Engpässe, da mehr als 3 Drähte in einen Lötpunkt eng werden für die Datenleitungen die ja an jedem Chip sind und die kämme sind auch schon recht voll, so dass da nichts mehr rein geht und ich quer verdrahten muss. Und danach fange ich den Monitor an denn das Ziel ist es ja Programme vom PC in die Kiste zu laden, so dass die Testzeit schneller wird. Muss mir da noch was einfallen lassen. Theorie: Monitor decodiert Intel Hex File oder alternativ zieht sich das .bin rein. Bin scheint einfacher und hex2bin habe ich ja. Wie ich das Programm vom PC da rein kriege weiss ich noch nicht. minicom? Terminal Programm? Irgendein Protokoll muss da ja auch herhalten. Und PC Programmierung habe ich lange nicht mehr gemacht, schon gar nicht unter Linux. Ein cat main.hex > /dev/tty0 wird es sicher nicht tun. Sprung ins RAM, Code muss natürlich für RAM codiert sein, also andere Einstellungen des sdcc. Bei Reset muss er wissen, dass im Ram was liegt und da rein. Bei Stromausfall ist bisher alles weg, habe keinen Pufferakku aber letzlich kann auch das ganze Board an eine Batterie dran. Der 3801 säuft sich locker 180ma rein, glaube ich dem Datenblatt, also kommen wir für das ganze Board mit NMOSs CPU auf fast 500mA und mit CMOs auf maximal 250. Derzeit ziehtes nur 60mA incl LEDs. Und dann wird das ganze irgendeine Anwendung steuern, wo ich mir noch was einfallen lassen will.
> Monitor decodiert Intel Hex File oder alternativ zieht sich das .bin > rein. Bin scheint einfacher und hex2bin habe ich ja. Intel Hex bietet dir Prüfsummen an, die du benutzen kannst, um Übertragungsfehler zu erkennen. Wenn die fehlerfrei geladen wurde, weißt du wenigstens, dass sie auch korrekt angekommen ist. > Wie ich das Programm vom PC da rein kriege weiss ich noch nicht. Das könnte vielleicht daran liegen, dass du nicht liest, was dir andere schon schrieben. Was soll's, ich wiederhole mich jetzt nicht. > Bei Reset muss er wissen, dass im Ram was liegt und da rein. Wozu? Mach in den Monitor einen "Jump to RAM"-Eintrag und gut. > Und dann wird das ganze irgendeine Anwendung steuern, wo ich mir noch > was einfallen lassen will. Eine autonome Steuerung beißt sich sehr stark mit "Anwendung wird als Hexdatei ins RAM geladen und von dort gestartet".
Ich lese schon eine Weile mit, hab was aehnliches mit den Bausteinen oben vor und einige Bücher von Keil über den 8085 und unter anderen Der Heimcomputer 8085 hier liegen mit Plänen vom EC 8085 SBC :) Allerdings fehlen mir noch ein paar Dinge. Soll evtl. mal mit Altair Basic rennen. Intressantes Board hast du da, gibts auch Fotos von der aktuellen Verdrahtung ?
:
Bearbeitet durch User
Hi, kann Bilder hier nicht einfügen unter Linux, mir fehlt ein Programm zur einfachen Größenreduzierung wie vallen jpegger. Aber die Kommunikation ist simpel, grad mal 20 Minuten zu einlesen stty raw ispeed 9600 ospeed 9600 -F /dev/ttyUSB0 stellt den USB/Rs232 konverter ein, ggf. noch einige andere Parameter. echo Hallo > /dev/ttyUSB schickt auch genau Hallo raus. und cat text.text > /dev/ttyUSB lässt auch auf meinem Raspi genau das erscheinen was in text.txt steht Easy :-) PS: Das Keil Buch (grün) habe ich auch seit ca 1986. Habe den 8085 nachgebaut damals. Habe auch nachgefragt ob sie dazu noch weitere Unterlagen haben vor allem die Firmware aber leider keine Antwort.
Anbei die Bilder. Oben eine Stiftleiste mit I/O Signalen zur Erweiterung. 2 Ports vom 8255 in der Wanne.
Christian J. schrieb: > kann Bilder hier nicht einfügen unter Linux, mir fehlt ein Programm zur > einfachen Größenreduzierung wie vallen jpegger. mogrify -scale xx% foo.jpg (mogrify ist Teil von imagemagick) Oder pnmscale (aus netpbm). Oder gimp. Oder ... XL
> Wie gesagt sind heutige Timer deutlich aufwendiger und komplexer Dann sieh' dir mal das Datenblatt des Am9513 an (AMD). http://www.hartetechnologies.com/manuals/AMD/AM9513.pdf >9600 Baud Es gab spezielle Baudrate Generatoren (8116, COM8116, AY5-8116), damit konnte man 16 Werte 50 Baud bis max. 19.200 einstellen. Mit Festfrequenz oder über Steckbrücken geht's auch so (http://retired.beyondlogic.org/serial/74hc4060.gif , jedoch Quarz 5,9152 MHz verwenden. Gruss
Erich schrieb: > Mit Festfrequenz oder über Steckbrücken geht's auch so > (http://retired.beyondlogic.org/serial/74hc4060.gif , jedoch Quarz > 5,9152 MHz verwenden. Ich würde 4.9152MHz verwenden. Und 57600/115200bd kann man dann vergessen.
Also im grünen Buch von Keil ist doch das Monitorprogramm/Firmware als Listening drinnen :) Sehr schön der Aufbau. Die Grösse von Bildern reduziere ich immer mit Gimp.
So fieber hatte ich auch, musste es mit hilfe von einem 68008 und einen paar 68020 heilen... und platinen :D. http://propeller.wikispaces.org/pPropQL http://propeller.wikispaces.org/pPropQL020
Erklär mir mal einer das: Mit so 16-19 schrieb ich hunderte Zeilen Asm locker auf dem Papier runter. Ummrechnungstabelle brauchte ich nicht, kannte die Hex Codes der Mnemonics auswendig. Mir 24 kannte ich jeden Interrupt des Bios, jeden Exe-Header einer Datei, wusste wie eine Fat aufgebaut ist, der TASM war mein Freund. Dann kam die dunkle (oder helle?) Zeit ab so 1996 wo ich die ersten C-Compiler bekam, Pascal lieben lernte, später kam noch Java hinzu und Pearl. Selbst die Bash verlor ihren Schrecken und es enstanden Backup Scripte und clvere kleine Programme. Aber mit 45 breche ich mir einen ab mit DIESEM SCHEISS ASSEMBLER !!!! Was interessieren mich Flags? Kann es mir nicht sch... egal sein, ob ein Carry gesetzt ist oder nicht? Wieso hat das Sch.. Ding nur 8 Bit? Meine Zahlen sind größer. Welcher Masochist hat sich das ausgedacht? Und wozu brauche ich diese verdammten ' Register im Z80? Dann fand ich diesen Satz im Internet: "Assembler ist eine Methode, Programme die zu langsam laufen so umzuschreiben, dass sie überhaupt nicht mehr laufen." Mal wieder etwas ernster: Da es keinen Sinn macht Code zu testen indem man ein Epom brennt muss ein Simulator her, damit ich sehen kann, ob er das macht was ich will. Es ist mühsam über Jahre eingefleischte Programmiertechniken zu vergessen und auf die Grundelemente runter zu brechen. Und erst dann setze ich den Code ins Monitor Programm ein. Was kann ich nehmen, um etwas komfortabel mit grafischer Oberfläche Z80 Code zu schreiben und auszutesten?
Ale schrieb: > So fieber hatte ich auch, musste es mit hilfe von einem 68008 und > einen > paar 68020 heilen... und platinen :D. > > http://propeller.wikispaces.org/pPropQL > http://propeller.wikispaces.org/pPropQL020 Sehr schöne Projekte - da sowohl der Propeller wie auch diverse 68k-Cores mittlerweile im Quellcode verfügbar sind, könnte man das ganze System sogar auf einen (recht großen) FPGA packen :-). Hast du vor, die Schaltpläne und den Code irgendwann zu veröffentlichen? -- Michael
Christian J. schrieb: > Was kann ich nehmen, um > etwas komfortabel mit grafischer Oberfläche Z80 Code zu schreiben und > auszutesten? Guckst du bei Jens Müller: http://www.jens-mueller.org/jkcemu/ Dieser wirklich gute Emulator wurde für die gängigen Klein- und Lerncomputer der DDR entwickelt und enthält auch einen Assembler. Paßt zwar nicht direkt zu deinem Hardwareaufbau, hilft aber vielleicht weiter. > "Assembler ist eine Methode, Programme die zu langsam laufen so > umzuschreiben, dass sie überhaupt nicht mehr laufen." Pah.. Gejammer von verweichlichten Hochsprachen-Pussies =8P
Christian J. schrieb: > komfortabel mit grafischer Oberfläche Z80 Code Mit dem Aufkommen der grafischen Oberflächen kam auch der Abschied vom Assembler. Insofern wirst du da kaum fündig werden. Ich wiederhole diverse frühere Statements von vielen Leuten aus diesem Thread: Nimm einen der vielen Debug Monitore. Dann lädst du dein Programm ins RAM und kannst mit Brechpunkten das Ding Stück für Stück durchgehen. Den Monitor an deine Hardware anzupassen ist eine Sache von 15 Minuten (maximal). Alternativ kannst du einen Z80 Simulator und deinen PC verwenden. Wenn es unbedingt ein Eprom Simulator sein soll, gibt es auch dafür Bauvorschläge. Mit etwas Lochraster ist das Ding an einem Abend aufgebaut.
Christian J. schrieb: > Wieso hat das Sch.. Ding nur 8 Bit? Darf ich dich dran erinnern, dass er deine Wahl war? ;-) Hättest auch eine 68000 CPU nehmen können. > Da es keinen Sinn macht Code zu testen indem man ein Epom brennt muss > ein Simulator her, damit ich sehen kann, ob er das macht was ich will. Kann helfen. Wenn du einen findest, der deine serielle Schnittstelle mit richtigem CPU Takt und den beiden zugehörigen Drähten simuliert. Denn das ist dein primäres Problem. Denn wenn diese Schnittstelle läuft, dann brauchst du nur einen winzigen Bootloader im EPROM, der ab Reset xKB am Stück direkt ins RAM läd und anspringt. Ohne Protokoll, ohne Intel-Hex, direkt binär ins RAM ab Anfangsadresse. > Was kann ich nehmen, um > etwas komfortabel mit grafischer Oberfläche Z80 Code zu schreiben und > auszutesten? Editor und Kommandozeile. Retro eben. Herrje, erst muss es Retro sein, aber dann mit allem neuzeitlichen Luxus. ;-) Aber wenn es dich unbedingt danach gelüstet, dann nimm Emacs. Damit geht das. Und der ist ausserdem selber schon gut Retro.
:
Bearbeitet durch User
Icke ®. schrieb: > Pah.. Gejammer von verweichlichten Hochsprachen-Pussies =8P Und das von einem Jungspund mit grad mal 45. ;-)
Georg G. schrieb: > Den Monitor an deine Hardware anzupassen ist eine Sache von > 15 Minuten (maximal). Deine 15min oder seine? Jeder Monitor braucht eine Schnittstelle nach aussen.
Christian J. schrieb: > Da es keinen Sinn macht Code zu testen indem man ein Epom brennt muss > ein Simulator her, damit ich sehen kann, ob er das macht was ich will. Hier darf ich mich noch mal kurz einklinken und auf meinen obigen Hinweis zurückkommen. Ein Statisches RAM welches über Bankswitching auf den selben Adressraum wie das BIOSROM meines 8 Bit ATARI eingeblendet wurde (huckepack aufgelötet) und eine kleine Datenschaufel ab Page ab 0x600 erfüllte genau diesen Zweck. Mit dem Monitor aufgerufen kopierte es mir das BIOS in SRAM und konnte on flay zwischen ROM und RAM per SW umschalten. Hier nahm ich meine Modifikationen vor und testete sie. Das setzt allerdings ein Memorymanager per IOPort und Adressdecoder auf das Chipselect vorraus. Ein Absturz wurde mit einem Reset (nach Möglichkeit im "Warmstart") behoben, der Monitor im RAM auf Integrität getestet (Chekcsumme/ Biosfunktion im ROM) ansonsten neu geladen und weiter ging es. Das dauerte keine 3 Sekunden. Half das nicht war nach einem Kaltstart alles wieder im grünen Sektor, da der Kaltstart immer das ROM einblendet. Ich hoffe du verstehst jetz meinen frühen Hinweis. Der Vorteil ist, es erfordert keinen externen Simulator und kann zudem später auch als RA(O)MDisk genutzt werden. Das auf dein Problem zu portieren sollte kein wirkliches Problem sein. Namaste und viel Spaß
:
Bearbeitet durch User
Christian J. schrieb: > Erklär mir mal einer das: > > Mit so 16-19 schrieb ich hunderte Zeilen Asm locker auf dem Papier > runter. Ummrechnungstabelle brauchte ich nicht, kannte die Hex Codes > der Mnemonics auswendig. ... > Aber mit 45 breche ich mir einen ab mit DIESEM SCHEISS ASSEMBLER !!!! Du bist einfach zu alt. Also nicht physiologisch, sondern geistig. Such dir ein anderes Hobby. Blumen züchten. Schnecken dressieren. Briefmarken sammeln. Was einfaches halt :P > Was interessieren mich Flags? Kann es mir nicht sch... egal sein, ob ein > Carry gesetzt ist oder nicht? Wieso hat das Sch.. Ding nur 8 Bit? Meine > Zahlen sind größer. Welcher Masochist hat sich das ausgedacht? Ich hätte eigentlich gedacht, daß man sich das 20 Jahren lang merken kann. Denn irgendwann mußt du es ja mal gewußt haben. Außerdem sind ALUs immer zu kurz - genau deswegen gibts ja Carry-Flag & Co. Und warst du das nicht, der unbedingt Retro machen wollte? > Und wozu brauche ich diese verdammten ' Register im Z80? Wenn du den zweiten Registersatz nicht brauchst, dann benutze ihn halt nicht. Andere freuen sich, daß sie ein paar extra-Register haben aber du maulst nur rum. > Dann fand ich diesen Satz im Internet: > > "Assembler ist eine Methode, Programme die zu langsam laufen so > umzuschreiben, dass sie überhaupt nicht mehr laufen." Typischer Möchtegern-Programmierer-Spruch. Wohl Generation Arduino. > Da es keinen Sinn macht Code zu testen indem man ein Epom brennt muss > ein Simulator her, damit ich sehen kann, ob er das macht was ich will. Dann mach doch. Wenn es für irgendeine Architektur viele Emulatoren gibt, dann für den Z80. XL
Axel Schwenke schrieb: > Typischer Möchtegern-Programmierer-Spruch. Wohl Generation Arduino. In dem Fall wohl Generation WINDOOF Wenn mich vor zwanzig Jahren etwas nervte dann das Einsetzen des Versteckens von Funktionen vor dem Anwender mit Ambitionen von Standardsoftwareanpssung an eigenene Bedürfnisse. Ich bin 56 aber das Grundlagenwissen aus der ASM-Zeit hilft mir bis heute. Mein Retrospielzeug heißt TFT Maximite für den ich mir gerade ein SW-Programmer für den 93C56 gebastelt habe. Zuvor habe ich allerdings schnell mal die IO~ und Touchfunktionen der MMBASICExtension debugged. Das ist für mich Urschleim genug. Und was war der Sinn des ganzen? ... ein EEPROM auf einer 20 Jahre alten Liftsteurung zu reinitialisieren leider hatte ich nicht genug Zeit, so war ich froh ein orignal EEPROM bestellen zu können (beim Hersteller). Aber backups werde ich nächstens selbt anlegen können. ;) Namaste
Axel Schwenke schrieb: > Schnecken dressieren. Davon kann ich nur abraten! Wenn du da nicht die ganze Zeit aufpasst wie ein Schießhund, dann brechen die aus. Ein winziger Moment nachlassender Aufmerksamkeit und die sind über alle Berge auf und davon, die erwischt du nie wieder. ;-)
Axel Schwenke schrieb: > Christian J. schrieb: >> Erklär mir mal einer das: >> >> Mit so 16-19 schrieb ich hunderte Zeilen Asm locker auf dem Papier >> runter. Ummrechnungstabelle brauchte ich nicht, kannte die Hex Codes >> der Mnemonics auswendig. > ... >> Aber mit 45 breche ich mir einen ab mit DIESEM SCHEISS ASSEMBLER !!!! > > Du bist einfach zu alt. Also nicht physiologisch, sondern geistig. > Such dir ein anderes Hobby. Blumen züchten. Schnecken dressieren. > Briefmarken sammeln. Was einfaches halt :P Glaubst du wirklich, deine Alternativen sind nicht einfach :-) Und lass ihn doch. Er hat es doch fein hingekriegt mit seiner Fädeltechnik. Nie im Leben würde ich mir das antun. Alle Achtung! Natürlich muß man fragen, wie sein Zustand mit 60 Jahren ist. Aber im Grunde hat er Recht. Das genannte TDL-Basic hab ich damals auch mit Hand eingetippt. Heute würde ich sowas nicht mehr machen. Die Luft ist raus!
Georg G. schrieb: > Ich wiederhole diverse frühere Statements von vielen Leuten aus diesem > Thread: Nimm einen der vielen Debug Monitore. Dann lädst du dein > Programm ins RAM und kannst mit Brechpunkten das Ding Stück für Stück > durchgehen. Den Monitor an deine Hardware anzupassen ist eine Sache von > 15 Minuten (maximal). Hallo, danke für die Antworten. Das hier scheint mir das Sinvollste zu sein, da ich an der Hardware nichts mehr ändern kann und auch nicht an das Ram unter dem ROM dran komme. Was ist "einer der vielen Debug Monitore", ich würde nicht einen einzigen finden. Und 15 Minuten sicher nicht weil ja eine Kommunikation mit dem PC hergestellt werden muss. Es gibt es sicherlich keine Out of the Box Komplettlösungen, also den Server im Z80 und den Cliebt im PC, oder? Und dann bitte auch die USB Kommunikation dazu. Den STI wird wohl keiner kennen, den muss ich zuerst schreiben, bzw die putchar und getchar Routinen. Sobald das steht geht alles viel fixer. Nochmal PC: Kann es wirklich sein, dass ein cat main.hex >> /dev/ttyUSB0 ausreicht um den Code in den Z80 zu schiessen? Ich meine so einfach? Zumindest wenn der mit dem Lesen mitkommt, denn beim Handshake wird es schwieriger, das habe ich nämlich nicht. Maximal Software HS aber kein RTS/CTS.
Nochmal zum Debugger Ich habe da einen "NoIce" Debugger gefunden,der nur leider 30 Tage Version ist und sich auch ständig unter XP mit einer Schutzverletzung verabschiedet. In dem Paket ist eine IDE mit etwas Komfort, die ein hex einlesen kann oder ein Projekt File mit Debug Infos. Auf dem Zielsystem wird ein Monitor installiert, der "blind" angepasst werden muss an die Serielle. Die IDE kommuniziert mit dem Monitor so als würde man den Code Single Steppen. Eben das was auch JTAG kann, oder Linux oder, oder oder. Das wäre schon sehr nett, wenn es das als Freeware gäbe und es nicht ständig abstürzen würde. Wenn ich mich zurück erinnere an meine Jugend, so war der C64 damals Eprommer und der Code für das 8085 musste einfach fehlerfrei geschrieben werden. Eine andere Möglichkeit hatte ich nicht mit Hausmitteln.
Christian J. schrieb: > Kann es wirklich sein, dass ein > cat main.hex >> /dev/ttyUSB0 > ausreicht um den Code in den Z80 zu schiessen? Ich meine so einfach? Nein, einfacher, wenn du dich endlich vom Hexfile lösen würdest. Da deine Probleme primär auf der Z80-Seite liegen, solltest du zumindest in der ersten Stufe deren EPROM-Bootloader so einfachst wie möglich halten, und da ist eine umständliche Hexfile-Dekodierung in der Z80 unnötig. Was du brauchst ist ein Binärimage des Codes, von beispielsweise exakt 8kB Länge. Dann die Z80 resetten, damit der Bootloader aktiv wird, und: cat main.bin > /dev/ttyUSB0 Nur solltest du die TTY so einstellen, dass darin kein Software-Handshake und keine CRLF-Translation stattfinden kann (=> stty), denn die muss dafür 8-Bit transparent sein. > Zumindest wenn der mit dem Lesen mitkommt, denn beim Handshake wird es > schwieriger, das habe ich nämlich nicht. Vergiss Handshake. Bei 57600 kriechen 5760 Bytes pro Sekunde über die Leitung. Das sind grob 500 Takte pro Byte. Da muss niemand warten.
:
Bearbeitet durch User
wenn ich das recht sehe ist dein ROM gesockelt? Huckepack ein SRAM drauf und RD/WR-Bein hoch und einen Fädeldraht rausgezogen. Das ist kein Hexenwerk, so habe ich in fertigen Gräte neben den Bios ROM ganze dynmische RAM-Bänke ergänzt sowie IO Ports um 36Bit parallel erweitert. Das war damals Homebrewstandard mehr Retrofealing geht gar nicht. Namaste
:
Bearbeitet durch User
Christian J. schrieb: > Was ist "einer der vielen Debug Monitore" Kannst gern ein Muster von mir bekommen. Allerdings für einen "normalen" Assembler (M80 kompatibel, den kannst du mit Doku auch bekommen), eventuell will der mit dem SDCC gelieferte nicht. Du musst nur die Initialisierung deines UART anpassen (Tabelle, Port, Wert, der da rein soll) und die getchr und putchr Routinen (da muss man vermutlich nur die Position des Statusbit anpassen). Auf der PC Seite nimmst du Teraterm oder was ähnliches. Und das Laden des zu prüfenden Programms geht mit "R", gefolgt von "File senden" in Teraterm. Handshake und ähnliches wird nicht gebraucht. Das Ding ist keine eierlegende Wollmilchsau, reicht für 99.9% aller Fälle aber aus. [code] Befehlsliste: defb 'd<start>,<ende> = Speicherdump',0dh,0ah defb 'f<start>,<ende>,<wert> = Speicher fuellen', 0dh,0ah defb 'g<start>[,<break1>[,break2]] = Programm ausfuehren', 0dh, 0ah defb 'h<a>,<b> = a + b, a - b', 0dh, 0ah defb 'i<port> = Port lesen', 0dh, 0ah defb 'm<von>,<bis>,<nach> = Speicher verschieben', 0dh, 0ah defb 'o<port>,<wert> = Port schreiben', 0dh, 0ah defb 'r<offset> = Hex-File lesen',0dh,0ah defb 's<adresse>,<wert> = Speicher aendern', 0dh,0ah defb 'w<von>,bis> = Hex-File schreiben', 0dh,0ah defb 'x[<register>[,<wert>]] = Register anzeigen/aendern', 0dh, 0ah [\code]
Habt Ihrs noch nicht verstanden? Christian möchte eine grafische Entwicklungsumgebung unter Windows, also mit Debugger, die Ihm Programme auf seine Hardware lädt und dort test- und ausführbar macht. Was er nicht möchte ist: 1. Selber machen 2. Doku lesen 3. sich anstrengen. Also bitte Jungs, das Ding sollte bitteschön schon fertig sein... Interfaceroutinen sollten ebenfalls vorhanden und getestet sein so das er sie nur noch einbinden muß. Es geh ja nicht das er sich auch noch mit Registerpointern herumärgern muß. SCNR, Holm
Ich möchte im Zusammenhang mit Retro mal auf einen Thread im Robotron Forum aufmerksam machen: http://www.robotrontechnik.de/html/forum/thwb/showtopic.php?threadid=11373 Da möchte Jemand den DDR LC80 als Platine neu auflegen und hat das zur Diskussion gestellt. der LC80 ist ein Einplatinenrechner aka Mikroprofessor o.Ä. mit 7-Seg Anzeige und Hexa Tastatur. Um meinem Sohn evtl. was Sinnvolles beibringen zu können würde ich so ein Teil evtl. bauen wollen, vielleicht gibts hier noch mehr Interessenten die die Platinenkosten drücken helfen oder Vorschläge haben. Ich bin nicht der Threadersteller da, nur interessiert.. Gruß, Holm
Axel Schwenke schrieb: >> Und wozu brauche ich diese verdammten ' Register im Z80? > > Wenn du den zweiten Registersatz nicht brauchst, dann benutze ihn halt > nicht. Andere freuen sich, daß sie ein paar extra-Register haben aber du > maulst nur rum. Damit kann man prima Kleinstprogramme bauen, ohne auch nur ein Byte RAM extern zu brauchen. Ich hab mal ein Miniboard mit Z80 gemacht, indem dann die beiden obersten Adressleitungen Output Ports waren, Input lief über einen simplen 74244. Mit Oszillator und EPROM waren das dann 4 integrierte Schaltkreise.
Matthias schrieb: > @Winfried was für ein Atari ist das ? 800XL ? 130XE mit 800XE Platine aber ein erweiterter 800XL ist auch noch hier ;) Die 130er Platine mit 1 MB RAM hat meine EX auf dem Gewissen. Silberleitlack hineingegossen als Frustkompensation. Sehr effizient gewesen die Platine war nicht zu retten.:( Also nie die OW unterschätzen ;)
:
Bearbeitet durch User
Holm Tiffe schrieb: > Ich möchte im Zusammenhang mit Retro mal auf einen Thread An die Freunde des 8bit-Retrocomputing: Schaut auch mal hier ins Nachbar-Forum: Beitrag "8bit-Computing mit FPGA"
Ja, KC87 auf FPGA. Das ist allerdings genau das, was ich nicht will. Man kann sich den FPGA nämlich dann auch ganz kneifen und das Problem mit JKCEMU abwickeln. Gruß, Holm
Holm Tiffe schrieb: > Ich möchte im Zusammenhang mit Retro mal auf einen Thread im Robotron > Forum aufmerksam machen: > http://www.robotrontechnik.de/html/forum/thwb/showtopic.php?threadid=11373 Danke für den Hinweis! Der derzeitige Preis geht doch. Vor einem Jahr hab ich eine leere Z-1013 Platine in der Bucht angeboten und die haben mir freiwillig 40 EUR dafür überlassen.
Holm Tiffe schrieb: > Ja, KC87 auf FPGA. > Das ist allerdings genau das, was ich nicht will. Man kann sich den FPGA > nämlich dann auch ganz kneifen und das Problem mit JKCEMU abwickeln. Falls sich das auf den vorherigen Beitrag von mir bezieht: Eine FPGA-Realisierung hat mit Software-Emulation rein gar nichts zu tun. Im FPGA werden alle Gatter und Flipflops des Zielsystems eins zu eins realisiert.
Wegen 680x0 und Propeller... man kann es auch in einem FPGA realisieren... Aber mindestens 30k LE verdenken gebraucht. Schaltungen sind verfügbar wenn jemand es möchte. Viel Code habe ich leider nicht geschrieben, auch verfügbar. Die Platinen waren nicht genau was ich wollte. Jetzt versuche ich mit RISCV und FPGAs.
O.T. >Axel Schwenke schrieb: >> Schnecken dressieren. >Davon kann ich nur abraten! Wenn du da nicht die ganze Zeit aufpasst wie >ein Schießhund, dann brechen die aus. Ein winziger Moment nachlassender >Aufmerksamkeit und die sind über alle Berge auf und davon, die erwischt >du nie wieder. ;-) Als mir neulich eine Weinbergschneck abgehauen war, hatte ich sie ruck-zuck eingefangen: Ein Steinpilz war vor ihr aus dem Boden geschossen und hatte den Fluchtweg verstellt.
Schneckenzüchter schrieb: > Als mir neulich eine Weinbergschneck abgehauen war, hatte ich sie > ruck-zuck eingefangen: Ein Steinpilz war vor ihr aus dem Boden > geschossen und hatte den Fluchtweg verstellt. Glück gehabt! ;-)
heute unangemeldet schrieb: > Holm Tiffe schrieb: >> Ja, KC87 auf FPGA. >> Das ist allerdings genau das, was ich nicht will. Man kann sich den FPGA >> nämlich dann auch ganz kneifen und das Problem mit JKCEMU abwickeln. > > Falls sich das auf den vorherigen Beitrag von mir bezieht: > Eine FPGA-Realisierung hat mit Software-Emulation rein gar > nichts zu tun. Im FPGA werden alle Gatter und Flipflops > des Zielsystems eins zu eins realisiert. ...das halte ich zwar im konkreten Falle so wie Du es schreibst für ein Gerücht, aber ja, ich weiß was ein FPGA ist und was es tut und nein, ich schrieb schon, so Etwas will ich gerade nicht. Eine FPGA Platine sieht genauso aus wie ein Handy von innen und tut irgend Etwas, das kann ich einem 9 Jährigen weiß Gott nicht zum lernen vorsetzen. Es ist dann für mich einfacher auch das FPGA zu emluieren, jetzt verstanden? BTW: mir ist klar das man hier als Gast schreiben kann und sich nennen kann wie man will, aber muß das so bescheuert sein? Kannst Du Dir nicht wenigstens einen Tarn-Vornamen einfallen lassen? Gruß, Holm
Georg G. schrieb: > Kannst gern ein Muster von mir bekommen. Allerdings für einen "normalen" > Assembler (M80 kompatibel, den kannst du mit Doku auch bekommen), > eventuell will der mit dem SDCC gelieferte nicht. Hi, kannst Du mir das hier mal posten? Danke! Gruss, Christian
Hi, nur mal so als Info für jene, die vielleicht auch an sowas Spass haben. Der SDCC Compiler ist in seiner Version 3.3.0 relativ fehlerfrei, erzeugt aber doch umständlicheren Code als man in Asm schreibt. Klar, ist eben ein Baukasten. Mit Z80 Interrups kann er nichts anfangen. Die crt0.s muss unbedingt angepasst werden, die mitgelieferte erzeugt nicht lauffähigen Code und enthält Zeugs, was niemand braucht, löscht man es läuft es nämlich alles. Ich habe Stunden gebraucht das heraus zu finden. Aufpassen muss man allerdings, dass die Debian Repos nur bis zur Version 3.0.0 reichen von 2012 und da sind noch eine Menge Bugs drin bzw passt die Aneitungen einfach nicht zu dem Compiler da zb auch im ASZ80 Assembler einiges geändert wurde. Am besten zieht man sich den Source Code hier runter da immer die aktuellen Snap Shots vorhanden sind http://sdcc.sourceforge.net/snap.php und kompiliert sich das Ding selbst, auf meinem Cubie Board, wo ich die Z80 Geschichte mache sind das gefühlte 20 Pakete Nachinstallation (gputils, libboost-system-tools usw) da ./configure ständig meckert. Nach ca 2 Stunden ist das Cubie Board mit dem Kompilieren auch durch. Von den Libs ist der SDCC soweit brauchbar,l auch ein malloc ist vorhanden, allerdings ist die Heap Grosse auf 1kb gefixt und muss in einem Script erst angepasst werden, was tief versteckt im /usr/sdcc Verzeichnis liegt. Vermeiden sollte man tunlichst printf, vprintf und rand Funktionen zu verwenden, auch keine math.h, da allein rand 2kb Speicher frisst und niemand weiss warum. printf sind fast 3kb.
Christian J. schrieb: > nur mal so als Info für jene, die vielleicht auch an sowas Spass haben. > Der SDCC Compiler ist in seiner Version 3.3.0 relativ fehlerfrei, > erzeugt aber doch umständlicheren Code als man in Asm schreibt Man kann noch etwas an den Dingen schrauben, so winzig ist das Manual mit der Beschreibung aller Optionen nun auch wieder nicht, mit der Zeit bekommt man so langsam ein Gefühl dafür. Zwar verwende ich den SDCC für 8051, nicht Z80. Letztens erzeugte ich damit auch Debug-Code für ein SiLabs-Board, geht auch einwandfrei. So habe ich auch für ein modernes neueres Board einen unlimitierten Compiler fürs Hobby. Die Profi-Tools sind ja preislich für mich unerschwinglich, kleines Hobby eben. Jedenfalls ist er unlimitiert, kann die ganzen für den 8051 möglichen 64k Codegröße nutzen, womöglich sogar noch Vielfache davon in Banking, und hat diesbezüglich keine Fallstricke. Allerdings benutzt der SDCC einen 80C517 wie einen simplen 8051. Mit den schönen Peripherals wie Multiple Datapointer oder MDU kann er nichts anfangen, das muß man sich selbst in die Libraries und Funktionen hinein stricken, z.B. in memcpy(). Es ist halt kein teueres Profi-Tool, dafür kost er aber nix. Das Registerfile 80C517.h aus dem SDCC war auch eine mittlere Baustelle. Dort standen Register drin, die der 80C517 gar nicht hat. Andererseits fehlten wiederum andere. Das war auch einen Tag Anpassung, nur das H-File alleine. Ein Softie von Sourceforge hat bei sowas bestimmt einen mittleren Anfall bekommen und für eine simple Liste zu erstellen keinen Bock gehabt. Kann ich irgendwie sogar ein wenig verstehen, das ist wie Doku schreiben, Strafarbeit. > Vermeiden sollte man tunlichst printf Willst du denn Zahlenumrechnungen wirklich von Hand machen, also z.B. Mehrbyte ADD, SUB, MUL, DIV, BIN-BCD, in Assembler? Aber es geht auch. In Zeiten, als noch keine C-Compiler und kein Internet verfügbar waren, gewöhnte ich mich auch an sowas. Ein 80535-Board mit nur 2k ROM mußte ich gezwungenermaßen in ASM programmieren. Es kam sogar dort noch auf jedes freie Byte am Ende an. Das Board konstruierte eine Semestergruppe mit seinem Prof. mal gemeinsam, wobei der Prof. aus der 8048-Ära stammte. Daher wohl das 2k-EPROM, denn es gab zur Bauzeit ca. 1990 auch schon 32k-EPROM, wenn nicht sogar 1 MByte. Ich lese gerade, daß es den SDCC jetzt in 3.3.0 gibt, habe noch 3.2.0. So, ab heute gehts aber an mein neues PICkit 3 Debug Express. Es liegt noch verpackt vor mir. Dabei ist ein einfachstes Board mit weitgehend nur einem PIC18F45K20 drauf, einer frei bestückbaren Experimentierfläche, und raus geführten Pins, dazu bestellte ich noch ein paar PIC18F26K20 DIL28 fürs Steckbrett mit. Das ist fast der gleiche wie auf dem Board, nur eben weniger Pins, kein Flat Pack, aber mit doppelt großem RAM und Flash. Mal sehen, ob ich daran Spaß bekomme. Sie stellen mein Intel-Gedönse mit 80xx performancemäßig auch etwas in den Schatten. Die ERRATA-Liste beeindruckte mich etwas, aber mal sehen, vielleicht ist das halb so wild wie es aus sieht.
Elektrobrazzzler schrieb: > Ich lese gerade, daß es den SDCC jetzt in 3.3.0 gibt, habe noch 3.2.0. Die neueste Version ist 3.4.1. vom 18.10.2014. Habe die gestern als Source durchkompiliert. 80535 war bei mir Studium, hatte etliche davon. Alles schon damals mit Keil in C.
Mit dem PIC18F45K20 habe ich ein Industriedesign gemacht, 2 Stück, 2 Kanalig. Mit CCS als Compiler. Er funktioniert wie jeder andere Controller auch, da es bei C sowieso egal ist welchen man nimmt. Ich arbeite mit PIC seit gut 18 Jahren, seit der erste herauskam. Damals nch mit dem völlig fehlerhaften Bytecraft Compiler, seit 1997 mit CCS. Nur musste ich es vermeiden Libs zu nehmen, die die Peripherie einbetten, da der TÜV den Code zeritifzieren musste. Den CCS kann man sich "besorgen" wenn man weiss wo man suchen muss. Es ist ein hochwertiger Compiler, hat aber leider keinen Linker. Es darf nur ein File geben, man muss alles andere mit Include einbinden und darauf achten, dass man für jede Funktion Prototypen in main.h definiert. Der schönste Controller, den ich bisher hatte mit den meisten Features und Ressourcen war der ARM7, LPC2368 mit GCC Compiler. Allein 40kb Ram onchip, 512kb Flash, Batterieram auch noch, USB Ram 16kb usw. Man kann das Programm im RAM entwickeln wenn es nicht größer als 32kb wird und erst dann flashen, da er Code aus dem Ram aus führen kann. Bootloader, Startup Code usw., macht alles die Rowley IDE, da muss man sich nicht drum kümmern. Heute erzeugt die auch den Code für den Clock, man stellt nur ein was man haben will und die bindet das mit ein. Allerdings eben 32 Bit und nicht mehr so einfach zu verstehen. SD anbinden bin ich gescheitert und musste fertigen Code nehmen, da ich die Einarbeitung in das SD Protokoll vermeiden wollte, sondern nur Funktionen nutzen. Allein die Clock und PLL einzustellen, sowie den APB Bustakt sind viele Zeilen Code. Aber mit 80Mhz rennt der auch.
Christian J. schrieb: > annst Du mir das hier mal posten? Dann mal eine Jugendsünde. Das Ding läuft in einem Flash und kann sich selbst aktualisieren. Es gibt auch noch Versionen mit Unterstützung für 1791 Floppy Controller oder WD1002 Harddisk Board. Als Assembler-Linker-Locater-Librarian verwende ich eine M80-L80-Lib80 kompatible Version von M. Röhner. Wenn es C sein soll, ist es eine Variante von QC. Diese Werkzeuge sind nur für nicht kommerzielle Anwendungen frei.
Danke, sieht doch schön aus und ist gut dokumentiert. Werde sicher einiges da rauskopieren. Wie man bei Assembler von "struktrierter Programmierung" sprechen kann wird mir allerdings ewig ein Rätsel bleiben, für mich bleibt das ein Aneinander klatschen von Routinen ohne gescheite Parameter Übergabe und Techniken wie Variablen Overlaying sind da ganz abhanden gekommen.
Eine Sünde finde ich nicht auf anhieb, wirkt recht aufgerämt auf mich. Namaste
Christian J. schrieb: > ewig ein Rätsel bleiben Du bist eindeutig etwa 30 Jahre zu spät geboren. :-) (Wobei früher nicht alles schlechter war. Nur so ein Beispiel: Wordmaster konnte man 10-Finger-blind schreiben. Und Rechtschreib Korrektur und Drucken im Hintergrund konnte der auch schon.)
Georg G. schrieb: > Du bist eindeutig etwa 30 Jahre zu spät geboren. :-) Mag sein, gewissen Dingen kann ich ja noch einen gewissen Charme abgewinnen, wie in dem Beispiel das Laden von Ports mit Konfigurationdaten. Zumindest wenn man schn mitzählt wo der Pointer hochgezählt wird bzw runtergezählt. Trotzdem keine Ahnung wie man einen Befehl OUTI ausdenken kann, oder OTIR der wahrscheinlich genau dafür gemacht wurde. Typisch CISC Maschine. Nen freien, grafisch zu bedienenden (ja, ich will das!) Simulator habe ich immmer noch nicht gefunden, werde wohl die 25 Euro für einen ausgeben, der recht nett gemacht ist. Spasseshalber habe ich mir mal den Quellcode eines 4 Gewinnt Spieles gegen den Computer besorgt. Das kann man dann auch so umprogrammieren, dass er ständig gegen sich selbst spielt. Kompiliert bisher einwandfrei durch, auch wenn rand etc viel Speicher braucht. Bin mal gespannt wie das Gewinnverhältnis nach ein paar Stunden sein wird, ob Computergegner 1 oder 2 mehr Spiele gewinnt. Heute abend mal an die STI rangehen und die verdrahten, damit endlich auf dem PC was zu sehen ist. Erinnert mich so ein wenig an "Wargames" :-) Na hauptsache der Z80 ist beschäftigt und sei es nur mit sich selbst :-)
Nochmal ein Special für A.K.: Ich programmiere grad Code für den MK3801 und bin da noch etws unsicher. Weiter oben siehst du einen Auszug aus einer Appnote, die ich übersetzt habe. Müssen die Uart Eingänge RC (Receiver Clock Input) und TC (Transmitter Clock Input) alle beide an den Ausgang des Timers D angebunden werden, der dann die Baudrate erzeugt? Async übertragung wird durch Sampling bewerkstelligt, d.h. wird hier mit 1:16 abgetastet? Ich verstehe auch nicht ganz wieso die die PIO Ports im DDR Register auf 0x64 geetzt haben? Die haben doch mit der UART nix zu tun, oder? Was hat dieser Codefetzen da verloren? PS:L Der MK3801 schraubt sich unglaubliche 180ma rein! Mit der NMOS CPU frisst die Karre jetzt schon 380mA auf 100km !!!
1 | // STI konfigurieren für Uart Ausgabe |
2 | STI_UCR = 0x88; // = 10001000 UART Control Register 8N1, DIV16 |
3 | STI_RSR = 0x01; // RX Status - Enable RX |
4 | STI_RSR = 0x01; // TX Status - TX High, TX enabled |
5 | STI_PVR = STI_DDR; // Zeiger PVR auf indirect 6 (DDR) |
6 | STI_IDR = 0x64; // ???? Was soll das? |
7 | STI_PVR = STI_TDDR; // Zeiger PVR auf Timer D Data |
8 | STI_IDR = 0x03; // Timer D Zeitkonstante |
9 | STI_PVR = STI_TCDCR; // Zeiger auf Timer C,D Control Register |
10 | STI_IDR = 0x89; // Timer D DIV 4, C = Stop |
Defintionen:
1 | 0x00 IDR Indirect Data Register |
2 | 0x01 GPIP Purpose I/O Data Register |
3 | 0x02 IPRB lnterrupt Pending Register B |
4 | 0x03 IPRA Interrupt Pending Register A . |
5 | 0x04 ISRB Interrupt -Service Register B |
6 | 0x05 ISRA Interrupt in-Service Register A |
7 | 0x06 IMRB lnterrupt Mask Register B |
8 | 0x07 IMRA Interrupt Mask Register A |
9 | 0x08 PVR Pointer,/Vector Register |
10 | 0x09 TABCR Timers A and B Control Register |
11 | 0x0A TBDR Timer B Data Register |
12 | 0x0B TADR Timer A Data Register |
13 | 0x0C UCR USART Control Register |
14 | 0x0D RSR Receiver Status Register |
15 | 0x0E TSR Transmitter Status Register |
16 | 0x0F UDR USART Data Register |
17 | |
18 | // Indirekt adressbierbare Register des STI |
19 | |
20 | #define STI_SCR 0 // Sync Character Register |
21 | #define STI_TDDR 1 // Timer D Data Register |
22 | #define STI_TCDR 2 // Timer C Data Register |
23 | #define STI_AER 3 // Active Edge Register |
24 | #define STI_IERB 4 // Interrupt Enable Register B |
25 | #define STI_IERA 5 // Interrupt Enable Register A |
26 | #define STI_DDR 6 // Data Direction Register |
27 | #define STI_TCDCR 7 // Timer C und D Control Register |
Christian J. schrieb: > Müssen die Uart Eingänge RC (Receiver Clock Input) und TC (Transmitter > Clock Input) alle beide an den Ausgang des Timers D angebunden werden, > der dann die Baudrate erzeugt? Kannst auch einen anderen Timer verwenden, aber ohne RC/TC UART Takt wird es nichts mit der UART. > Async übertragung wird durch Sampling > bewerkstelligt, d.h. wird hier mit 1:16 abgetastet? Korrekt. Das ist bei fast allen UARTs so. > PS:L Der MK3801 schraubt sich unglaubliche 180ma rein! Mit der NMOS CPU > frisst die Karre jetzt schon 380mA auf 100km !!! Tja nun, NMOS frisst Dauerstrom. Da spürt man, wo der Strom landet. > STI_PVR = STI_DDR; // Zeiger PVR auf indirect 6 (DDR) > STI_IDR = 0x64; // ???? Was soll das? Bei mit steht da 0xA7, wegen /BOOT,5",FDC-TC,/STROBE,RTC-DATA. Soll heissen: Das hängt davon ab, was an den Pins dran hängt. Da der gezeigte Code wohl nicht von dir ist, hängt das von dem System ab, wovon du den Code kopiert hast. Der Anhang sieht eher nach deiner Platine als nach einer Appnote aus. Und deine UART Taktverdrahtung solltest du mal überprüfen, denn so wie gezeigt wird das nix.
:
Bearbeitet durch User
A. K. schrieb: > Der Anhang sieht eher nach deiner Platine als nach einer Appnote aus. > Und deine UART Taktverdrahtung solltest du mal überprüfen, denn so wie > gezeigt wird das nix. Yep ... Pindreher. Im Schaltplan falsch, am Board aber richtig. Die Appnote sollte eigentlich nur die UART behandeln, da denkt man sich ja nicht, dass die die PIO noch für was anderes brauchen. Hätte ja sein können, da manche Pins noch extra auf Output geschaltet werden müssen. Ist ja oft dass keinen Override gibt, wenn Pins mehrere Funktionen haben.
Wozu dient eigentlich R26? Falls der für NMI ist: Der INT Ausgang vom STI ist Open Drain, der INT Pin braucht also auch einen.
A. K. schrieb: > Wozu dient eigentlich R26? Falls der für NMI ist: Der INT Ausgang vom > STI ist Open Drain, der INT Pin braucht also auch einen. In dem Board ist da auch einer (smd), nur im Schaltplan leider vergessen :-( Habe alle Ints an 10K gehängt. Ab 3 Drähte an einem Lötpin wird es eng.... Datenbus ist ja überall dran. Den MK3801 gibt es nicht zufällig als CMOS..... 37 Grad hat der laut Messung.
Christian J. schrieb: > 37 Grad hat der laut Messung. Na und? Bei 900mW hätte ich etwas mehr erwartet. Gemessen oder aus dem Datasheet abgeschrieben?
:
Bearbeitet durch User
Mit der Infrarot Pistole gemessen. Inzwischen sind es 43 Grad. Es gab noch einen 68...irgendwas 901 von Thompson als CMOS, der ein aufgebohrter STI ist mit 48 Pins aber dann eben kein 2,54er Raster mehr. Der Stromverbrauch nervt doch etwas. Die ersten 7400 die ich noch hier habe fressen auch 50mA pro Stück. Die Suche bringt auch nicht mehr hervor, außer diesen Thread der inzwischen indiziert wurde. So, mir tun die Augen weh trotz Lupenlampe unter der ich das verdrahte. Zeit aufzuhören....
A. K. schrieb: > Christian J. schrieb: >> Mit der Infrarot Pistole gemessen. > > Ich dachte eher an den Strom. Also, A.K. .... so schwer ist es ja nicht an der Anzeige eines PS den Strom abzulesen vor und nachdem man den Chip reingesteckt hat. Und der ist 180ma höher als vorher.
so als inspiration :-) Nen OS für den Z80 mit Multitasking, Windows, Task Manager etc :-)
sorry ich das hier mit meiner Begeisterung zumülle, aber das ist einfach zu geil! Mit Videoplayer und einem VDP9990 graphic chip für z80 https://www.youtube.com/watch?v=a6v2EFAhiQA
@A.K. Der MK3801 spielt einwandfrei. Und nochwas ..pssst.... : Die Timer laufen rückwärts..igitt! Und bei 0 heben die den Pin hoch und einen Takt später wieder runter, laden sich wieder mit ihrem Reload Wert. PWM geht auch. Aber nicht weitersagen! :-)
Wieso igitt? So kann man den Teiler direkt eintragen, wie schon aus den gezeigten Initialisierungswerten hervorging.
A. K. schrieb: > Wieso igitt? So kann man den Teiler direkt eintragen, wie schon aus den > gezeigten Initialisierungswerten hervorging. Das war ein kleiner ironischer Witz...... Muss nur noch rausfinden, was der sdcc anstellt, wenn man read/modify/write Operationen auf den Ports auführt. Ob da der richtige Code bei rauskommt. Nein, erzeugt einen "fatal internal compiler error" if (stat==TRUE) // Bit ein STI_GPIP |= (1<<bitnr); I/O können nur geladen, verändert und zurück geschrieben werden.
Kurz, da ich derzeit immer noch "blind" programmiere, bis die Leitung zum PC endlich steht: Interrupt im MK3081 aber auch generell: Es gibt für die UART Interrupt ENABLE Register Interrupt MASK Register Interrupt PENDING Register Ist das richtig: enable = 0, mask = 0; => es wird weder ein Hardwarevorgang ausgelöst, noch wird das pending bit gesetzt, wenn ein Zeichen kommt. enable = 1, mask = 0; => es wird pending gesetzt und kann gepollt werden, aber es wird kein Hardware Int ausgelöst, weil der Int "ausmaskiert" ist. pending muss manuell gelöscht werden, ggf. durch auslesen des registers? enable = 1, mask = 1; => pending wird gesetzt, hardware int wird ausgelöst, vektor geht auf den bus, pending wird automatisch gelöscht, sobald die Z80 den Vektor entgegen nahm und IOREQ und M1 gezogen hat.
Und bevor es ins Bett geht (und der Thread versickert) noch eine Sache: Interrupts und Timer A testen. Hardware und Software. Zunächst Mode 1, da einfacher. Test 1: INT Pin und Software 1. 0x38 zeigt auf Routine, die LEDs durchzählt 2. im 1 ei im Hauptprogramm 3. Stück Draht an Pin 16 (INT) und Masse anticken => LEDs zählen hoch. INT ist pegelgetriggert wie ich sehe Test 2: Timer A testen 1. Timer A konfigurieren 2. Hauptprogramm schleife zeigt Timer A Data auf LEDs an (mit delay) => Timer A laeuft und reloaded richtig, Bits schnubbeln auf die LEDs Test 3: Timer A Interrupts bei Nulldurchgang sollen Int Mode 1 (0x38) triggern 1. Timer A enable Bit = 1 2. Timer A Mask Bit = 1 3. Timer A Reload Wert 0xff und DIV 200, damit man was sieht Läuft nicht! Pin INT wird nicht von Timer A Int über INT Pin getoggelt. Test mit Drahtstück klappt aber.
Christian J. schrieb: > Interrupt ENABLE Register > Interrupt MASK Register > Interrupt PENDING Register Und optional das "Interrupt in-Service Register". Relevant wenn man verschachtelte Interrupts zulassen will. > Ist das richtig: Ja. > manuell gelöscht werden, ggf. durch auslesen des registers? Steht doch in der Doku. 0 schreiben löscht, 1 unverändert.
Ich kriege leider trotzem keine kontinuierliche INT Auslösung. Nur mit dem Draht, also kommt vom MK3801 nichts. Was fehlt denn jetzt noch, damit der Timer Überlauf eben dauerhaft Ints auslöst? Zumindest Mode 1 schonmal, Mode 2 wird dann sicher auch funktionieren. PS: Erledigt. Man sollte nicht eine Hardware in Main und im Int ansprechen, das gibt Murks.
Und auch das Thema ist damit erledigt ..... puhhh. Blöd ist der Compiler ja nicht: aus while ((STI_TSR & 0x80) == 0); // Warte bis Buffer frei... wird: 00101$: in a,(_STI_TSR) rlca jr NC,00101$
Christian J. schrieb: > Blöd ist der Compiler ja nicht: Nimm dir mal einen alten 4MHz Z80 CP/M Kasten (fairerweise mit Harddisk) und einen modernen PC. Und dann nimm dir Wordstar und Word und lass eine Sekretärin, die richtig Schreibmaschine kann nacheinander auf beide Kisten los. Das Ergebnis wird dich verblüffen. Damals (tm) wurde noch mit Hirn und Nachdenken programmiert. Es gab kein Klicki Bunti Mausgeschiebe. Aber die Ergebnisse konnten sich sehen lassen.
Hallo, der Thread ist inzwischen abgesoffen und hat sich auf einen Nebenschauplatz verlegt, wo internste Details des sdcc Compiler geklärt werden mussten, weil der damit nicht so recht klarkommt globale Variablen zu intitialisieren. Dazu musste dieses Loch erst bis zur Sohle beschritten werden und ein Programmierer des sdcc leistete dazu wertvolle Hilfe,den ich angeschrieben hatte. Beitrag "Re: Mehrdimensionale char-arrays" Es funktioniert bisher alles, auch die Mode 2 Ints aber dieser Mechanismus ist ja fix installiert, was soll da also schief gehen. Am Monitor bin ich dran, weiss noch nicth genau wieviel ich im Int erledigen soll, schöne Konstrukte mit FIFO Buffer usw oder ob alles in einer Polling Schleife? Vielleicht noch Basic Interpreter dabei, Hex Dump usw. Wird sich zeigen. Der Z80 sendet und empfängt Zeichen. Damit wäre dieser Thread also am Ende und wenn jemand auf die gleiche Idee kommt und den sdcc verwendet, so sind da alle Probleme bisher gelöst worden. Die Hardware ist abgetrennt vom User Code, ein HAL liegt bei mir jetzt dazwischen. Zumindest bis auf den Umstand, dass man keine static Variablen in Ints verwenden kann, die nicht 0 sind. Das kann er (noch) nicht. Jo, danke an alle hier und die Geduld.....Einarbeitung war erfolgreich. Und Asm echt nur da wo unbedingt nötig. Ich mag kein Asm und auf Zeit kommt es eh nicht an. Gruss Christian
retrogerecht 1.FIFO gab es zu Z80 nicht manlegte ringbuffer mit overflowflag an. 2.Static erledigt man in einem eigen Variablenbereich welcher der Funktion zugeordnet ist. Also nicht im variablenbereich von main liegt und welcher so für den rest des Programms invisible bleibt. wärend Global entweder von main angelegte werden oder durch die installierende Funktion an den Compiler angemeldet werden damit er sie visible generiert. lokal erledigt mann gern auf dem Stack, mus ihn aber schön aufräumen. Also nach dem poppen alles sauber aufwischen. ;) Namaste
Sehr cool! Vielleicht kannst du ja für die Nachwelt dein Endergebnis in Hardware und Software hier posten..
Hallo, stellt sich dennoch die ein oder andere Frage, da ich mich mit Protokollen von Schnittstellen nicht so genau aus kenne. Wenn vom PC ein Binärdatenstrom über das USB Interface in die Uart reinkommt, wie zeigt dann der PC das Datenende an? Ich habe nur zwei Leitungen, RX und TX, kein Hardware Flow Control, kein Handshake. Daten die kommen müssen entgegen genommen werden da sie unentwegt weiterlaufen. Kann ich das Datenende nur über Timeout erkennen? Denn die Vereinbarung eines speziellen Zeichens geht ja im Binärcode nicht. Aktuell laufen die Zeichen über den SIO Interrupt rein und füllen einen Ringpuffer, der 3/4 "voll" meldet hofft hofft dass das Hauptprogramm sich um ihn kümmert bevor Daten verworfen werden.
Wenn du kein spezielles Übertragungsprotokoll gewählt hast, hilft nur Timeout, mit allen Risiken und Nebenwirkungen. Eben deshalb wurde so Dinge wie Z-Modem oder Kermit entwickelt. Flowcontrol hilft dir da auch nicht weiter.
Hallo, grundsätzlich kann der Empfänger antworten aber ich will PC seitig keinen Aufwand treiben und die Binärdaten nur mit cat daten.bin > /ttyUSB0 absenden nachdem die Schnittstelle vorher eingestellt wurde. Dazu muss ein Shell Script reichen. Ein Protokoll als Frame fällt daher auch flach und ist nicht nötig, ZModem ist ja für Überseeübertragungen konzipiert und mir noch aus FidoNet Zeiten bekannt damals. 9600 sind auch "zum mitschreiben". Ok, also Timeout Verfahren, zwei rotiernde Zeiger in einem Array, einer der schreibt, der andere der die Leseposition nachzieht und aufpassen dass der Z80 keine Zeichen verliert da es keine Pausen gibt... schauen wir mal...
Du denkst viel zu kompliziert. Feste Länge definieren, oder vorneweg senden. Das Board erwartet 4K, der Sender sendet 4KB (als Beispiel). Auch dein FIFO ist erst einmal unnötig. Einfacher gehts nicht. Auf die Art kannst du dann beispielsweise einen Hex-oder X/Y/Z-Modem/Kermit Loader entwickeln und wenn er läuft diesen einbrennen. Oder was auch immer. Weshalb sollte da was verloren gehen? Hast du hungrige Bitmäuse im Lab?
:
Bearbeitet durch User
Christian J. schrieb: > Wenn vom PC ein Binärdatenstrom über das USB Interface in die Uart > reinkommt, wie zeigt dann der PC das Datenende an? A. K. schrieb: > Was du brauchst ist ein Binärimage des Codes, von beispielsweise exakt > 8kB Länge. Dann die Z80 resetten, damit der Bootloader aktiv wird, und: beispielsweise exakt 8kB Länge beispielsweise exakt 8kB Länge beispielsweise exakt 8kB Länge beispielsweise exakt 8kB Länge Es können aber beispielsweise auch exakt 4KB Länge sein. Edit zu spät
:
Bearbeitet durch User
Hi, der Compiler spuckt leider nur variable Länge aus und der Binärconverter auch. Muss mal schauen ob sich das ändern lässt. Timeout ist mir sympathischer, schon damit er sich nicht aufhängt. Stelle grad fest, dass der PC 7-bit Daten sendet. Habe mal einiges an den Z80 geschickt mit cat testdatei.bin > /dev/ttyUSB0 und stelle es auf der LED Zeile dar, LED Nr 7 bleibt dunkel, die anderen flackern im Bytetakt. 9600... es dauert eben :-) Muss mal schauen wie ich stty irgendwie umstelle, dass es Binärdaten sendet, nicht ganz eays, die Hilfe ist schon erschlagend.
Und jetzt habe ich mir auc noch /dev/ttyUSB0 "gelockt" mit screen und außer einem Reboot des PC weiss ich auch nicht wie ich das unlocken kann.
Christian J. schrieb: > der Compiler spuckt leider nur variable Länge aus und der Binärconverter > auch. man objcopy man dd
Christian J. schrieb: > der Compiler spuckt leider nur variable Länge aus und der Binärconverter > auch. Muss mal schauen ob sich das ändern lässt. Und dein PC hat irgendwie jede Fähigkeit verloren, ein Binärfile auf feste Länge zu erweitern? Sowas ist doch schneller programmiert als hier ins Forum getippt. Aber geht auch ohne: dd if=main.bin of=main.4kb ibs=4k conv=sync
Christian J. schrieb: > Und jetzt habe ich mir auc noch /dev/ttyUSB0 "gelockt" mit screen und > außer einem Reboot des PC weiss ich auch nicht wie ich das unlocken > kann. Hast du Angst, dass er beim Reboot nicht mehr hochkommt? Wobei man ein TTY mitunter mit "stty sane < /dev/ttyXXX" wieder sauber kriegt. Wäre aber sinnvoll, im stty mit deinem USB zu reden, nicht mit der X-Konsole, in der du das eintippst.
Der Compiler erzeugt keine object files :-( dd ist sehr praktisch da mit bs = 8192 ja die Blockgröße gesetzt werden kann. Aber egal, 8 Bit sind auch, weil... nun Ascii Textdateien sind nunmal 7 Bit codiert. So ein 200kb Bild braucht seine Zeit aber der Z80 kommt gut mit, bisher keine Zeichen verloren. Etwas anders wird schon schwieriger.... denn ein Programm im RAM ab 0x2000, dem fehlen die ganze Zeropage und da liegen bekanntlich einige Vektoren. Und ich kann ROM nicht nach RAM überblenden, da das darunter liegt. D.h. dass zb Int Mode 2 gar nicht möglich ist, denn der würde auf das ROM zugreifen und die Vektoren zeigen irgendwo hin aber nicht auf die Routinen im RAm da die jedesmal woanders liegen. Daran habe ich leider nicht gedacht, dass alles aus der Zeropage jetzt unerreichbar ist. Auch die Software Interrupts RST n, NMI sowieso, alle Timer Interrupts usw. Der Compiler lässt es leider nicht zu, dass man Routinen fixe Adressen verpasst, der will da sehr frei wählen wo jedes Segment liegt.
RAMDISK Bankswitching Mapping konnte der Z80 nicht auch Blöcke im RAM per ASM Befehl verschieben? .... ;)
:
Bearbeitet durch User
Christian J. schrieb: > Der Compiler erzeugt keine object files :-( Natürlich erzeugt der Compiler object files. Auch wenn sie .rel statt .o heißen mögen. Aber das spielt ja hier überhaupt keine Rolle. Falls Du den Linker Hex-Files erzeugen läßt (statt bin), könntest Du die mit objcopy in Binärfiles konvertieren. > dd ist sehr praktisch da > mit bs = 8192 ja die Blockgröße gesetzt werden kann. Die Blockgröße spielt hier überhaupt keine Rolle.
Leo C. schrieb: > Die Blockgröße spielt hier überhaupt keine Rolle. ibs !!!!!! Ok, Problem gelöst, braucht nicht mehr diskutiert zu werden. Alles schon fix und foxi in einem Script verarbeitet. Compilieren, Hexen, Binären, umwandeln nach 8192 Bytes usw :-) Das Thema mit den fehlenden Int Möglichkeiten eines Upload Programms wird wohl nicht zu lösen sein.
Christian J. schrieb: > Etwas anders wird schon schwieriger.... denn ein Programm im RAM ab > 0x2000, dem fehlen die ganze Zeropage und da liegen bekanntlich einige > Vektoren. Im IM2 liegen die dort, wo du sie per I Register hinlegst. Dieses Register brennt nicht ab, wenn man es im RAM-Code passend verändert.
Winfried J. schrieb: > RAMDISK > Bankswitching > Mapping > konnte der Z80 nicht auch Blöcke im RAM per ASM Befehl verschieben? > .... > ;) Ja, sogar mit ldir in einem Rutsch, so Power Befehle hat der. Nutze ich zum Initialisieren der Variablenfelder im Startupcode. ; Initialisiere globale Variablen ld bc, #l__INITIALIZER ld a, b or a, c jr Z, weiter ld de, #s__INITIALIZED ld hl, #s__INITIALIZER ldir Geswitched werden kann da nix, das ist fest verdrahtet und inzwischen "unlösbar" in Fädelkämmen. Das RAM liegt unter dem ROM drunter und ist unerreichbar. Da sich bei jedem Kompiliervorgang die Adressen ändern können die Vektoren nicht mehr benutzt werden. Hätte ich das vorher gewusst hätte ich ein Bankswitching eingebaut. Mir fällt nichts ein um das zu umgehen, Programme werden also int-los sein müssen was sehr schade ist, da aktuell der Timer die Hardware bedient und im User Code keine direkten HW Zugriffe mehr nötig sind. >>Dieses Register brennt nicht ab, wenn man es im RAM-Code passend verändert. Auch das nützt nichts! Denn die Adressen sind vielfache von 0x100 im I Register. Denke dass ich einen Compiler nutze wo der Linker diese Arbeit abnimmt diese Tabelle an ihre Zielorte zu leiten und dass er das kann, weil ihm die Zieladressen bekannt sind, da er crt0.rel und mail.rel zu einem verklumpatscht.
1 | ; Tabelle der Mode 2 Int Vektoren auf die Handler Funktionen im C Modul |
2 | ; Reihenfolge beachten !!! Siehe Manual Mostek 3801, Interrupt Tabelle |
3 | .org 0x40 |
4 | .dw (_int_sti_gpi_0) |
5 | .dw (_int_sti_gpi_1) |
6 | .dw (_int_sti_gpi_2) |
7 | .dw (_int_sti_gpi_3) |
8 | .dw (_int_sti_timer_d) |
9 | .dw (_int_sti_timer_c) |
10 | .dw (_int_sti_gpi_4) |
11 | .dw (_int_sti_gpi_5) |
12 | .dw (_int_sti_timer_b) |
13 | .dw (_int_sti_transmit_error) |
14 | .dw (_int_sti_transmit_buffer_empty) |
15 | .dw (_int_sti_receive_error) |
16 | .dw (_int_sti_receive_buffer_full) |
17 | .dw (_int_sti_timer_a) |
18 | .dw (_int_sti_gpi_6) |
19 | .dw (_int_sti_gpi_7) |
A. K. schrieb: > Im IM2 liegen die dort, wo du sie per I Register hinlegst. Dieses > Register brennt nicht ab, wenn man es im RAM-Code passend verändert. Das ist ja gerade die aus allem in der 8-Bit Welt vorher dawesenem herrausstechende Eigenschaft des Interrupt Mode 2. Christian J. schrieb: > D.h. dass zb Int Mode 2 gar nicht möglich ist, denn der würde auf > das ROM zugreifen und die Vektoren zeigen irgendwo hin aber nicht auf > die Routinen im RAm da die jedesmal woanders liegen. Wo die Vektoren hinzeigen bestimmt einzig und allein der Programmierer, und nicht etwa der Compiler oder sonst was.
Leo C. schrieb: > Wo die Vektoren hinzeigen bestimmt einzig und allein der Programmierer, > und nicht etwa der Compiler oder sonst was. Die CPU erwartet sie da, wo das I-Register hinzeigt! Die einzige Möglichkeit die bestünde wäre, das I Register so weit umzubiegen, dass es zb auf 0x2000 zeigt, dort liegt eine künstlich erzeugte Tabelle und der eigentliche Code beginnt erst bei 0x2100. Trotzdem habe ich (noch) keine Ahnung wie ich aus einem laufenden Programm heraus diese Tabelle erzeugen kann, da ich dazu die Position von Routinen ermitteln muss. Ob ein const int (*myvektor) ptr_int_1; myvektor = int_routine_1 funktioniert weiss ich noch nicht. C kann bekanntlich Zeiger auf Funktionen verarbeiten, die zur Kompilationszeit bekannt sind. Habe ich noch nie benutzen müssen sowas. Da ich die ganze Sache aber noch nicht zu Ende gedacht habe mache ich hier keine Schnellschüsse.
Christian J. schrieb: > Trotzdem habe ich (noch) > keine Ahnung wie ich aus einem laufenden Programm heraus diese Tabelle > erzeugen kann, da ich dazu die Position von Routinen ermitteln muss. Dass du einen Zweifrontenkrieg gegen Hardware und Compiler kämpfst, das hast du dir selbst zuzuschreiben. Aber was fürs ROM mit 0x0040 funktioniert, das funktioniert fürs RAM an 0x2040 genauso. Du kannst den RAM Code exakt so bauen wie den ROM Code. Nur eben ab 0x2000 statt 0x0000. Einzig NMIs und die RST-Befehle fallen flach.
:
Bearbeitet durch User
A. K. schrieb: > Dass du einen Zweifrontenkrieg gegen Hardware und Compiler kämpfst, > das hast du dir selbst zuzuschreiben. Da der ganze Apparillo nichts weiter ist als anderen in Kreuzworträsel und keinen praktischen Nutzen hat außer Denksport und Spass am Problemlösen und Gestalten denke ich, dass man das vernachlässigen kann. Du wirst sicher zugeben müssen, dass da Auge der Ästhetik unten stehendes Codebeispiel ohne Augenkrebs zu bekommen anschauen kann. Auf jedenFall sicher besser als eine Tabelle voller Nummern, die per djnz Schleife in die Ports geschrieben werden. Und wenn ich Lust habe kriegt jedes Bit auch noch eine define Zeile.... Welcher Depp ist eigenlich dafür verantwortlich, dass unter Unix und Windows cr/lf und lf als Zeilenende unterschiedlich sind?
1 | void InitHardware() |
2 | { |
3 | // 8255: Mode 0: Port A,B,C Output |
4 | PIO8255_CNTRL = 0x80; //Mode 0: Port A,B,C Output |
5 | PIO8255_PORT_A = 0xff; |
6 | PIO8255_PORT_B = 0; |
7 | PIO8255_PORT_C = 0; |
8 | |
9 | // 7-Segment .... |
10 | SEG7 = 0xff; |
11 | |
12 | // STI konfigurieren für Uart Ausgabe |
13 | STI_UCR = 0x88; // = 10001000 UART Control Register 8N1, DIV16 |
14 | STI_RSR = 0x01; // RX Status - Enable RX |
15 | STI_TSR = 0x05; // TX Status - TX High, TX enabled |
16 | // Timer D... |
17 | STI_PVR = STI_TDDR; // Zeiger PVR auf Timer D Data |
18 | STI_IDR = 0x03; // Timer D Zeitkonstante |
19 | STI_PVR = STI_TCDCR; // Zeiger auf Timer C,D Control Register |
20 | STI_IDR = 0x89; // Timer D DIV 4, C = Stop |
21 | // GPIO..... |
22 | STI_PVR = STI_DDR; // Zeiger PVR auf indirect 6 (DDR) |
23 | STI_IDR = 0xff; // GPIO als Output |
24 | STI_GPIP = 0x00; // GPIO auf Null setzen |
25 | // Timer A = endlos Run |
26 | STI_TADR = 0xff; // Reload Wert Timer A |
27 | STI_TABCR = 0x70; // Timer A DIV 200, 255x200 = maximale Verzögerung |
28 | STI_PVR = STI_IERA; // Timer A /RX Buffer Interrupt einschalten |
29 | STI_IDR = 0x30; |
30 | STI_IMRA = 0x30; // Timer A Interrupt / RX Buffer full unmask |
31 | STI_IPRA = 0x00; //Pending Ints löschen |
32 | |
33 | // Zuletzt Interrupt Vektor für Mode 2 laden |
34 | STI_PVR = 0x40; // Basisadresse der Ints für crt0.s Tabelle setzen |
35 | |
36 | __asm // Mode 2 Interrupt auswählen und Ints einschalten |
37 | im 2 |
38 | ei |
39 | __endasm ; |
40 | |
41 | } |
Christian J. schrieb: > A. K. schrieb: >> Dass du einen Zweifrontenkrieg gegen Hardware und Compiler kämpfst, >> das hast du dir selbst zuzuschreiben. > > Da der ganze Apparillo nichts weiter ist als anderen in Kreuzworträsel > und keinen praktischen Nutzen hat außer Denksport und Spass am > Problemlösen und Gestalten denke ich, dass man das vernachlässigen kann. Du mußt Dir unbedingt mal angewöhnen zuzuhören wenn Dir Jemand was erklärt und nicht einfach immer vernachlässigen. Das rächt sich: Das Problem beim Troubleshooting ist, der Trouble shootes back! > > Du wirst sicher zugeben müssen, dass da Auge der Ästhetik unten > stehendes Codebeispiel ohne Augenkrebs zu bekommen anschauen kann. Auf > jedenFall sicher besser als eine Tabelle voller Nummern, die per djnz > Schleife in die Ports geschrieben werden. Und wenn ich Lust habe kriegt > jedes Bit auch noch eine define Zeile.... > > Welcher Depp ist eigenlich dafür verantwortlich, dass unter Unix und > Windows cr/lf und lf als Zeilenende unterschiedlich sind? > Guckste eventuell mal was eher da war? Ich schätze mal das war die selbe stinkreiche Person die meinte das der "wrong slash" (Tm) irnkwie besser aussieht... Gruß, Holm BTW: Schnittstelle Locked es gibt da ein einfaches Verfahren mit angelegten Lockfiles in einem Directory, die bleiben nach einem Abschuß vielfach stehen. Unter FreeBSD liegen die Standardmäßig unter /var/spool/lock und heißen beispielsweise LCK..cuau3. So ein File enthält die Process ID des lockenden Prozesses. $ cat /var/spool/lock/LCK* 8760 $ $ ps -ax|grep 8760 21337 0 S+ 0:00,00 grep 8760 8760 4 Ss+ 0:28,19 seyon -noemulator -modems /dev/cuau3 -emulator xterm -nodefargs $ Der LOCKPATH ist unter Looser Unix leicht anders, aber ähnlich.
Holm Tiffe schrieb: > Guckste eventuell mal was eher da war? Ich schätze mal das war die selbe > stinkreiche Person die meinte das der "wrong slash" (Tm) irnkwie besser > aussieht... Das kommt aus CP/M, da kann Gates nix für. Der hat bloss ein abgekupfertes CP/M für 8088 aufgekauft. Die Programme in CP/M verwendeten auch schon "/xxx" für Kommandozeilenoptionen, damit war "/" für Pfade weg. Auch die Laufwerksbuchstaben sind aus CP/M.
Holm Tiffe schrieb: > Du mußt Dir unbedingt mal angewöhnen zuzuhören wenn Dir Jemand was > erklärt und nicht einfach immer vernachlässigen. Das rächt sich: > Das Problem beim Troubleshooting ist, der Trouble shootes back! Und Du musst mal vopn dieser Jogi/Schenk-Denke runterkommen, dass andere ihre eigenen Vorstellungen haben und nicht blind das übernehmen, was "alte Hasen" meinen richtig sei sonder evtkl lediglich Nuancen oder Tendenzen übernehmen. Assembler ist für mich Rummgestammel auf Bitniveau mit dem keine komplexen Dinge gescheit zu lösen sind und man verschwendet seine Zeit damit. Das wird sich auch nicht mehr ändern. Dein Wissen ist aber willkommen, vor allem das aus DDR tagen was ich sehr interessant fand. Das mit der /var/loch habe ich mir auch gegoogelt, inzwischen läuft das aber problemlos und ich denke, dass ich in ein paar Tagen soweit bin Uploads zu machen, wenn noch einiges mehr verkabelt ist und vor allem die Dokumentation des Ganzen mal wächst, denn ohne die blicke ich in in einigen Monaten nicht mehr durch. Die Sache mit den Ints ist soweit klar, nur muss ich das noch in die Compiler Directiven einarbeiten und rausfinden, wie ich diese Tabelle erzeuge. Denn inzwischen ist der Huckepack Sockel vom EEPROM doch schon ausgeleiert und es nervt dauernd jede Programmänderung neu zu brennen.
Christian J. schrieb: > Assembler ist für mich Rummgestammel auf Bitniveau > mit dem keine komplexen Dinge gescheit zu lösen sind und man > verschwendet seine Zeit damit. Das wird sich auch nicht mehr ändern. Das ulkige an dieser bereits hinreichend bekannten Grundeinstellung ist freilich, dass du dich trotzdem ausgerechnet in jener Retro-Sphäre bewegst, in der man als Assembler-Analphabet ziemlich hilflos ist.
A. K. schrieb: > Das ulkige an dieser bereits hinreichend bekannten Grundeinstellung ist > freilich, dass du dich trotzdem ausgerechnet in jener Retro-Sphäre > bewegst, in der man als Assembler-Analphabet ziemlich hilflos ist Amen :-) Ich gehöre auch zu den "Schändern" in deren Röhrenverstärker ein Mikroprozessor und ein fertiger Klangnetzwerk-Chip für Höhe/Bässe/Balance verbaut sind....Jehova!
Christian J. schrieb: >> Du mußt Dir unbedingt mal angewöhnen zuzuhören wenn Dir Jemand was >> erklärt und nicht einfach immer vernachlässigen. Das rächt sich: >> Das Problem beim Troubleshooting ist, der Trouble shootes back! > > Und Du musst mal vopn dieser Jogi/Schenk-Denke runterkommen, dass andere > ihre eigenen Vorstellungen haben und nicht blind das übernehmen, was > "alte Hasen" meinen richtig sei Seine Anmerkung bezog sich sicherlich nicht nur auf die Weigerung, Assembler kennenzulernen. Sondern auch darauf, wie du stur wie ein Panzer auf dem komplizierten Weg beharrst und völlig unnötige Komplexität ins EPROM einzubaust und dich dabei auch noch mit Compiler-Irrwegen abkämpfst, statt ins ROM nur das absolute Minimum einzubauen und danach ohne Sockelei im RAM weiterzuarbeiten.
A. K. schrieb: > Komplexität ins EPROM einzubaust und dich dabei auch noch mit > Compiler-Irrwegen abkämpfst, statt ins ROM nur das absolute Minimum > einzubauen und danach ohne Sockelei im RAM weiterzuarbeiten. Ist in Arbeit...keep it simple, as simple as possible. Trotzdem dran denken, dass es Hobby ist und ein wenig Spielerei dazu gehört. Schonmal bei Fingers elektrischer Welt vorbei geschaut.... geniale Seite, da sind auch Projekte von mir drauf :-)
Christian J. schrieb: > Hätte ich das vorher gewusst hätte ich ein Bankswitching eingebaut. ;)))) Tja ist das nun ein Hexenwerk, das zu in HW zu debuggen ? CS Draht ab SRAM Huckepack CS über MUX Und ein Pioportbit (alternativ kannst du ein HW Handshakepin der SIO... liegt eh rum missbrauchen) für den MUX Glaub mir je, länger du rumpopelst desto länger wird dir das Kopfweh machen und du wirst deine Zeit damit vertrödeln neue Krücken zu basten. Je eher du das nachrüstest, desto schneller wirst du glücklich mit dem was du vorhast. ... Namaste
:
Bearbeitet durch User
Christian J. schrieb: > Holm Tiffe schrieb: >> Du mußt Dir unbedingt mal angewöhnen zuzuhören wenn Dir Jemand was >> erklärt und nicht einfach immer vernachlässigen. Das rächt sich: >> Das Problem beim Troubleshooting ist, der Trouble shootes back! > > Und Du musst mal vopn dieser Jogi/Schenk-Denke runterkommen, dass andere > ihre eigenen Vorstellungen haben und nicht blind das übernehmen, was > "alte Hasen" meinen richtig sei sonder evtkl lediglich Nuancen oder > Tendenzen übernehmen. Assembler ist für mich Rummgestammel auf Bitniveau > mit dem keine komplexen Dinge gescheit zu lösen sind und man > verschwendet seine Zeit damit. Jawoll, da isser wieder uns Krischan... > Das wird sich auch nicht mehr ändern. Das Gefühl habe ich auch. IM2 ist sowieso Quatsch und die 8255 ist ein Top Teil .. > Dein Wissen ist aber willkommen, vor allem das aus DDR tagen was ich > sehr interessant fand. Ich denke mal Du interessierst Dich für Geschichte die Dir in der Schule nicht beigebracht wurde. Mein Wissen interessiert Dich nicht wirklich, das hast Du gerade eben wieder bewiesen. > > Das mit der /var/loch What? > habe ich mir auch gegoogelt, inzwischen läuft das > aber problemlos und ich denke, dass ich in ein paar Tagen soweit bin > Uploads zu machen, wenn noch einiges mehr verkabelt ist und vor allem > die Dokumentation des Ganzen mal wächst, denn ohne die blicke ich in in > einigen Monaten nicht mehr durch. > > Die Sache mit den Ints ist soweit klar, nur muss ich das noch in die > Compiler Directiven einarbeiten und rausfinden, wie ich diese Tabelle > erzeuge. Denn inzwischen ist der Huckepack Sockel vom EEPROM doch schon > ausgeleiert und es nervt dauernd jede Programmänderung neu zu brennen. Ich habe mir mein Wissen mit Lesen angeeignet, damit hast Du es wohl nicht so. Warum rennst Du immer mit dem Kopf gegen die Wand wenn es dunkel ist, anstatt Dich vorsichtig und mit Bedacht an die Wand heran zu arbeiten? Gruß, Holm
A. K. schrieb: > Holm Tiffe schrieb: >> Guckste eventuell mal was eher da war? Ich schätze mal das war die selbe >> stinkreiche Person die meinte das der "wrong slash" (Tm) irnkwie besser >> aussieht... > > Das kommt aus CP/M, da kann Gates nix für. Der hat bloss ein > abgekupfertes CP/M für 8088 aufgekauft. Die Programme in CP/M > verwendeten auch schon "/xxx" für Kommandozeilenoptionen, damit war "/" > für Pfade weg. Auch die Laufwerksbuchstaben sind aus CP/M. Der stinkreiche Arsch hat auch ein Rudel Systemrufe und die Pfade aus Unix übernommen die in QDOS nicht drin waren, er hat also entschieden. Garry kann man keinen Vorwurf machen ,der war ja fliegen.. Gruß, Holm
Christian J. schrieb: > A. K. schrieb: >> Das ulkige an dieser bereits hinreichend bekannten Grundeinstellung ist >> freilich, dass du dich trotzdem ausgerechnet in jener Retro-Sphäre >> bewegst, in der man als Assembler-Analphabet ziemlich hilflos ist > > Amen :-) Ich gehöre auch zu den "Schändern" in deren Röhrenverstärker > ein Mikroprozessor und ein fertiger Klangnetzwerk-Chip für > Höhe/Bässe/Balance verbaut sind....Jehova! Jaaa, das Wichtigste aber sind die blauen LEDs. Christian ein guter Rat: Lege Dich nicht mit mir an in dem Du versuchst mich zu provozieren. Wie das ausgeht weißt Du. Du bist mir rhetorisch nicht gewachsen. Ich will das aber nicht wirklich und amüsiere mich derzeit. Laß es also dabei, dann behältst Du die Unterhosen an. Im Ernst, hättest Du nicht alle Ratschläge hier immer wieder in den Wind geschlagen, hätte ich mich auch etwas besser um Dich gekümmert. Dein Ansatz möglichst in C programmieren zu wollen ist mir auch nicht neu, ich habe das selbe Problem mit dem 68k nebenan. Z80 Assembler ist aber einer der einfacheren, die Menmonics sind eingängig und gut zu merken, die CPU überschaubar. Lies doch den Thread einfach nochmal von vorne und analysiere was Du alles an Ratschlägen missachtet und dann korreliere mit welchen Problemen Du jetzt zu kämpfen hast. Die Sache mit dem Controller im Röhrenverstärker beeindruckt mich wirklich, aber nur dahingehend das Du das als Besonderheit erwähnst. Was glaubst Du wohl wie andere Leute Infrarotfernbedienungen realisieren? Mit nem Wasserrad und Preßluft? Boah ehy. Die Tatsache das Du erfolgreich einen EL84 Verstärker zusammengelötet hast beeindruckt mich eher gar nicht. Das habe ich schon vor 40 Jahren gemacht und in der Röhrenbude wird das immer für Anfänger empfohlen. Gruß, Holm
Hallo, > stellt sich dennoch die ein oder andere Frage, da ich mich mit > Protokollen von Schnittstellen nicht so genau aus kenne. Das liegt daran, dass du nicht liest, was andere dir schreiben. Oder du ignorierst alles bewusst und absichtlich, was gerade außerhalb deiner Scheuklappen sitzt und bist gleichzeitig nicht willens, später nochmal zurückzublättern. > Wenn vom PC ein Binärdatenstrom über das USB Interface in die Uart > reinkommt, wie zeigt dann der PC das Datenende an? Garnicht, weil Binärdaten das nicht können. Du sagtest, du arbeitest in einem technischen Bereich? Irgendwie kann ich mir das nicht vorstellen, weil du die selben Anfängerfragen immer und immer wieder stellst. > Ich habe nur zwei Leitungen, RX und TX, kein Hardware Flow Control, > kein Handshake. Daten die kommen müssen entgegen genommen werden > da sie unentwegt weiterlaufen. Tja, selbst schuld. Hättest du auch nur ein kleines bisschen vorher nachgedacht und ein Protokoll entworfen, wäre das alles kein Problem gewesen. Natürlich hättest du eins der vorhandenen Protokolle benutzen können, oder sogar die hier genannten Vorschläge benutzen können (Tipp: Die sind in diesem Thread immernoch drin!), aber du willst ja offensichtlich nicht. > Kann ich das Datenende nur über Timeout erkennen? Denn die Vereinbarung > eines speziellen Zeichens geht ja im Binärcode nicht. Klar kannst du das machen, und unter den angegebenen Bedingungen bleibt dir auch keine Alternative. Gibt zwar kaum dümmere Methoden, aber wem der Schuh passt... > Aktuell laufen die Zeichen über den SIO Interrupt rein und füllen einen > Ringpuffer, der 3/4 "voll" meldet hofft hofft dass das Hauptprogramm > sich um ihn kümmert bevor Daten verworfen werden. Wenn ein Ringpuffer ab 75% Füllstand anfängt, Daten wegzuschmeißen, dann ist er entweder exakt vier Byte groß oder hochgradig hirnrissig implementiert. Es schadet übrigens nicht, in einer Bootstrap-Schleife mit Polling zu arbeiten - schließlich hat die CPU ja noch nichts besseres zu tun. > der Compiler spuckt leider nur variable Länge aus und der Binärconverter > auch. Sehr überraschend. Ich bin zufrieden, wenn für ein 400 Byte großes Programm keine 8 KB übertragen werden müssen. Je nach Geschwindigkeit der Schnittstelle dauert das nämlich eine Weile... > Der Compiler erzeugt keine object files :-( dd ist sehr praktisch > da mit bs = 8192 ja die Blockgröße gesetzt werden kann. Klar erzeugt er Object Files, aber eben keine ELF-Dateien auf *.o, sondern Textdateien auf *.rel. Ist halt kein GNU-Compiler. > Etwas anders wird schon schwieriger.... denn ein Programm im RAM ab > 0x2000, dem fehlen die ganze Zeropage und da liegen bekanntlich einige > Vektoren. Erstens liegen in der Zeropage keine Vektoren, wenn du sie da nicht willst (der Z80 ist intelligent genug). Zweitens fehlt die Zeropage nicht, sondern enthält das, was du ihr da hingelegt hast. Wenn du das ROM nicht wegschaltest, liegt da das ROM. > Und ich kann ROM nicht nach RAM überblenden, da das darunter > liegt. D.h. dass zb Int Mode 2 gar nicht möglich ist, denn der würde auf > das ROM zugreifen und die Vektoren zeigen irgendwo hin aber nicht auf > die Routinen im RAm da die jedesmal woanders liegen. Ein Binärformat würde das ohne Probleme lösen. Alternativ eine neue Vektortabelle im RAM, die vom Startup-Code durch Änderung des I-Registers aktiviert wird. Das ist alles keine Raketentechnologie. Du willst Retro, aber irgendwie bist du unwillig, dir auch nur die Lösungen anzuschauen, die dir auf dem Silbertablett serviert werden. > Daran habe ich leider nicht gedacht, dass alles aus der Zeropage jetzt > unerreichbar ist. Wieso unerreichbar? Da ist immernoch das, was da vorher auch war. Ob du es benutzen willst oder nicht, spielt doch keine Rolle. Es gibt durchaus Monitorprogramme mit Funktionen, die ein nachgeschaltetes Anwendungsprogramm weiternutzen will - nennt man oft BIOS oder so. > Auch die Software Interrupts RST n, NMI sowieso, > alle Timer Interrupts usw. Die Interrupts kannst du per I-Register im IM2 verlegen. RST n und NMI kannst du indirekt nutzen, indem du an die passende Stelle im Monitor einfach einen Sprung an eine RAM-Adresse legst... das darf im Zweifelsfall auch eine dynamische Adresse sein, die sich aus einem Header des Anwendungsprogramms ergibt... ach ne, du willst ja nur rohe Binärdaten. Dann geht das natürlich alles nicht. > Der Compiler lässt es leider nicht zu, dass man Routinen fixe Adressen > verpasst, der will da sehr frei wählen wo jedes Segment liegt. Der Compiler ist nicht intelligent genug, um dir das zu verbieten. Wenn du ein Symbol passend deklarierst, dann nutzt der das auch. Muss man halt nur (in (Inline-)Assembler) machen. Aber auch das willst du ja nicht. Dann geht das natürlich auch nicht, da hast du schon recht... Gruß
Holm Tiffe schrieb: > Lege Dich nicht mit mir an in dem Du versuchst mich zu provozieren. > Wie das ausgeht weißt Du. Du bist mir rhetorisch nicht gewachsen. Ich > will das aber nicht wirklich und amüsiere mich derzeit. Laß es also > dabei, dann behältst Du die Unterhosen an. @S.R.: Danke für Deine Ausführungen, das Allermeiste hat sich aber inzwischen auch so gelöst und hätte nicht diskutiert werden müssen, wenn man mal drüber geschlafen hat. @Holm: Es mag rund 10 Jahre her sein aber ich sitze da mit einem breiten Grinsen, weil ich genau weiss welche Hebel und Knöpfe ich drücken muss, damit Du "aufsteigst". Also seien wir lieb, Du bist nämlich ein feiner Kerl glaube ich :-) Ich habe mich erstmal entschieden, dass der reine Upload zu öde ist, da der in ein paar Zeilen kodiert ist und mich für eine "Terminal" Umgebung entschieden. Reiner Upload ist mit echo "U" > /dev/tty stat -c %s binaer.bin > /dev/tty cat binaer.bin > /dev/tty gemacht, wenn man U als Startzeichen sieht, danach Dateigröße (als ascii), dann die Daten und fertig. Timeout ist ebenso legal und einfach, wenn man die n-fache Bytezeit bei 9600 als TO deklariert. Das Kopieren ins Ram geht nur über inline asm, war auch nicht schwer. Ich habe bis spät abends gestern Routinen kodiert die es ermöglichen dem Z80 System Kommandozeilen zu übergeben. Leider sendet minicom bei Tasteneingaben jedes Zeichen einzeln so dass ich im Z80 zb Cursor, ESC, BS und DEL abfangen und korrigieren müsste durch Versetzung des Pointers im RX Buffer, hterm unter Windows sendet erst bei CR Strings ab. Dafür entfällt die Timeout Funktion, da CR das Datenende signalisiert. Das Parsen der Strings ist recht einfach. Ob ein ausführbares Programm im Speicher liegt wird im Startup des Monitors erfragt da der erste Befehl ein immer JP xxxx" ist. Dann wird das Ausnullen übersprungen und direkt losgelegt, damit ein Reset nicht alles löscht. Von daher werde ich beides in einem Schreiben: Ein Art Bediener-Menüführung, zb auch um ein 4 Gewinnt Spiel etc zu spielen (printf und scanf arbeiten) aber auch die Möglichkeit per Steuerzeichen Uploads und andere Funktionen zu erreichen. Entgegen meinen Befürchtungen stellt sich die INT Problematik gar nicht, auch nicht bei NMI. RST lassen sich umlenken, Mode 2 Ints ja über I Register und das Compiler Image arbeitet bei 0x2000 genau wie bei 0x0000, es ist eben alles nur verschoben und der Offset bekannt. Aktuell sehe ich nur minicom, screen oder picocom als passendes "Terminal", da sind Upload Funktionen bereit halten und andere Dinge. Es wird schon....
Hallo, da ich dem Rechner(chen) noch etwas mehr einbauen möchte suche ich C-Quellcodes von Spielen etc. die sich ausschliesslich printf und scanf, bzw puts und gets als Ausgabe bedienen, rein textbasiert sind. Ich habe aktuell ein recht starkes 4 gewinnt gegen den Computer aber wenn es ein Text Schachprogramm oder Schiffe versenken etc geben würde wäre das auch nett. Kennt da jemand noch etwas? Gruss, Christian
Noch ein Wort zum sdcc Compiler für den, den es interessiert: Erfreulichwerweise erlaubt er es Variablen an fixe Plätze im Speicher zu legen und vermeidet auch die Prüfung ob diese Variablen mit anderen Inhalten des RAM kollidieren. Auf diese Weise lässt sich zb mit __at 0x2000 char ram[56x1024]; das ganze RAM direkt adressieren (natürlich auch der SP zerschiessen). Oder Inhalte des ROM mit __at 0x0 char rom[8192]; rüber kopieren. Was NICHT geht und das schränkt doch erheblich ein ist es mit inline asm lokale Variablen oder Funktionsparameter zu erreichen. Niente, geht nicht! Aus dem Grund, weil diese im Stack übergeben werden und die Übergabe jedesmal anders ist, man nicht weiss wo sie liegen. Manchmal auf im DE oder BC Register. Ein (_variable) gilt nur für globale Werte und die sollte man eh vermeiden wo es geht. Weiterhin klappt es nicht statische Variablen in Funktionen zu initialisieren, diese Funktion gibt es (noch) nicht.
Das kann so nicht sein wie Du es beschreibst. Ein Compiler hat immer calling conventions für Subroutinen und die sind auch nicht jedesmal anders, sie richten sich maximal nach der Art der übergebenen Variable. Ich gehe davon aus das Du die entsprechende Doku einfach nicht gelesen hast, Du bist genu so stinkend faul wie ich, abe rwenn man was Konkretes wissen will muß man halt dediziert nach den Definitionen suchen, manchmal auch im Sourcecode. Gruß, Holm
Christian J. schrieb: > Was NICHT geht und das schränkt doch erheblich ein ist es mit inline asm > lokale Variablen oder Funktionsparameter zu erreichen. Niente, geht > nicht! Die falschen Behauptungen werden auch durch ständige Wiederholung nicht wahr. > Aus dem Grund, weil diese im Stack übergeben werden und die > Übergabe jedesmal anders ist, man nicht weiss wo sie liegen. Parameter werden immer auf dem Stack übergeben, und die Reihenfolge ist definiert. > Manchmal auf im DE oder BC Register. Von diesen beiden wird eines für lokale Variable verwendet, und das findet man in der Doku. Holm Tiffe schrieb: > Das kann so nicht sein wie Du es beschreibst. Ein Compiler hat immer > calling conventions für Subroutinen und die sind auch nicht jedesmal > anders, sie richten sich maximal nach der Art der übergebenen Variable. > Ich gehe davon aus das Du die entsprechende Doku einfach nicht gelesen Die Doku dazu ist zugegebenermaßen sehr dünn. Ausprobieren würde helfen. Wie das geht ist allerdings für den 8051 sehr ausfürlich mit einer "Schritt für Schritt" Anleitung in der Doku beschrieben, ab Kapitel "3.14 Inline Assembler Code". Christian J. schrieb: > Weiterhin klappt es nicht statische Variablen in Funktionen zu > initialisieren, diese Funktion gibt es (noch) nicht. Auch diese Falschbehauptung wurde schon irgendwo widerlegt. Ich finde nur die Stelle nicht. Wie man in meinem angehängten Versuch sehen kann, erzeugt der Compiler dafür (derzeit) Code in der GSINIT-Area. Ziemlich ineffizient, aber geht. Die lokale Variable 'local' liegt hier auch auf dem Stack. Den Platz dafür schafft der 'push af' am Anfang der Funktion. Test:
1 | extern int f(int *x); |
2 | |
3 | int test( int a, int b) |
4 | {
|
5 | static int drei = 3; |
6 | |
7 | int local; |
8 | |
9 | local = a + b; |
10 | |
11 | return drei + f(&local); |
12 | }
|
Compiler Output:
1 | ;-------------------------------------------------------- |
2 | ; File Created by SDCC : free open source ANSI-C Compiler |
3 | ; Version 3.4.0 #8981 (Jul 5 2014) (Linux) |
4 | ; This file was generated Thu Oct 30 11:39:18 2014 |
5 | ;-------------------------------------------------------- |
6 | .module testpar |
7 | .optsdcc -mz80 |
8 | |
9 | ;-------------------------------------------------------- |
10 | ; Public variables in this module |
11 | ;-------------------------------------------------------- |
12 | .globl _test |
13 | .globl _f |
14 | ;-------------------------------------------------------- |
15 | ; special function registers |
16 | ;-------------------------------------------------------- |
17 | ;-------------------------------------------------------- |
18 | ; ram data |
19 | ;-------------------------------------------------------- |
20 | .area _DATA |
21 | _test_drei_1_3: |
22 | .ds 2 |
23 | ;-------------------------------------------------------- |
24 | ; ram data |
25 | ;-------------------------------------------------------- |
26 | .area _INITIALIZED |
27 | ;-------------------------------------------------------- |
28 | ; absolute external ram data |
29 | ;-------------------------------------------------------- |
30 | .area _DABS (ABS) |
31 | ;-------------------------------------------------------- |
32 | ; global & static initialisations |
33 | ;-------------------------------------------------------- |
34 | .area _HOME |
35 | .area _GSINIT |
36 | .area _GSFINAL |
37 | .area _GSINIT |
38 | ;testpar.c:5: static int drei = 3; |
39 | ld iy,#_test_drei_1_3 |
40 | ld 0 (iy),#0x03 |
41 | ld iy,#_test_drei_1_3 |
42 | ld 1 (iy),#0x00 |
43 | ;-------------------------------------------------------- |
44 | ; Home |
45 | ;-------------------------------------------------------- |
46 | .area _HOME |
47 | .area _HOME |
48 | ;-------------------------------------------------------- |
49 | ; code |
50 | ;-------------------------------------------------------- |
51 | .area _CODE |
52 | ;testpar.c:3: int test( int a, int b) |
53 | ; --------------------------------- |
54 | ; Function test |
55 | ; --------------------------------- |
56 | _test_start:: |
57 | _test: |
58 | push af |
59 | ;testpar.c:9: local = a + b; |
60 | ld hl,#6 |
61 | add hl,sp |
62 | ld iy,#4 |
63 | add iy,sp |
64 | ld a,0 (iy) |
65 | add a, (hl) |
66 | ld d,a |
67 | ld a,1 (iy) |
68 | inc hl |
69 | adc a, (hl) |
70 | ld e,a |
71 | ld iy,#0 |
72 | add iy,sp |
73 | ld 0 (iy),d |
74 | ld 1 (iy),e |
75 | ;testpar.c:11: return drei + f(&local); |
76 | ld hl,#0x0000 |
77 | add hl,sp |
78 | push hl |
79 | call _f |
80 | pop af |
81 | ld de,(_test_drei_1_3) |
82 | add hl,de |
83 | pop af |
84 | ret |
85 | _test_end:: |
86 | .area _CODE |
87 | .area _INITIALIZER |
88 | .area _CABS (ABS) |
Christian J. schrieb: [sdcc] > Aufpassen muss man allerdings, dass die Debian Repos nur bis zur Version > 3.0.0 reichen von 2012 und da sind noch eine Menge Bugs drin Debian testing enthält v3.4.0 (https://packages.debian.org/testing/electronics/sdcc). Kann man nicht meckern.
Christian J. schrieb: > Aus dem Grund, weil diese im Stack übergeben werden und die > Übergabe jedesmal anders ist, man nicht weiss wo sie liegen. Wie schon gesagt werden die Parameter immer gleich übergeben. Der Zugriff darauf kann aber je nach Optimierungsmöglichkeiten variieren. Einfacher wirds, wenn man den Compiler davon abhält, den Framepointer wegzuoptimieren. Option: --fno-omit-frame-pointer In dem Zusammenhang meine ich, einen Compiler-Bug gefunden zu haben. Das muß ich mir aber erst noch genauer anschauen.
Leo C. schrieb: > Parameter werden immer auf dem Stack übergeben, und die Reihenfolge ist > definiert. Hm, dann sind die Compiler, welche die ersten N Parameter einer Funktion auch per Register übergeben können, Teufelswerk?
Frank M. schrieb: > Hm, dann sind die Compiler, welche die ersten N Parameter einer Funktion > auch per Register übergeben können, Teufelswerk? Wie kommst Du denn hier auf "Compiler, welche die ersten N Parameter einer Funktion auch per Register übergeben können"?
Ich denke, es geht hier im einen ganz bestimmten Compiler. Da kann es schon sein, dass der alle Parameter per Stack übergibt. Das bedeutet nicht, dass alle Compiler es so machen.
Nabend, ich schreibe das mir nicht aus den Fingern heraus, daher bitte ich darum auf die Frozzeleien zu verzichten. Ich habe mir den erzeugetn Code (mit Optimierung!) genau angeschaut und es ist so, dass er mal auf dem Stack übergibt und mal einfach nur per Register! Und darauf verlasse ich mich garantiert nicht, sondern mache das mit einem Workaround, idem ich lokale Variablen, die nicht mit Symbol erreichbar sind zuerst in eine globale Variable kopiere und mir von dort aus hole. Die Doku ist völig unzureichend. da steht nicht mal was über die .areas drin. Bitschiebrei und testen ist in Schleifen per Asm deutlich effizienter, sonst ist es egal wenn es nur einmal durchlaufen wird, platz genug ist da. Debian main liefert 3.3.0 derzeit. aktuell ist 3.4.5 und das hat 700 Bytes Code um ganze 150 Bytes reduziert. Die letzte Code Änderung fand heute statt: http://sdcc.sourceforge.net/snap.php Und was static angeht so habe ich die Aussage eines der Programmierer dieses Compilers, das das noch nicht ausgereift ist. Ineffizient sowieso aber es wäre noch eine Baustelle, die ich nicht benutzen sollte. @Leo Welchen ASM Code hast Du denn im Startup unter der area GSINIT stehen? Bei mir ist da nur ein ret drin.
1 | ;/////////////////////////////////////////////////////////// |
2 | ; Anordung der Segmente fuer den Linker, ab hier nur relative |
3 | ; Adressen |
4 | |
5 | .area _CODE |
6 | .area _INITIALIZER |
7 | .area _HOME |
8 | .area _GSINIT |
9 | .area _GSFINAL |
10 | .area _DATA |
11 | .area _INITIALIZED |
12 | .area _BSEG |
13 | .area _BSS |
14 | .area _HEAP |
15 | |
16 | ;/////////////////////////////////////////////////////////// |
17 | ;; ------- Start des Hauptprogramms nach der Zeropage ----------- |
18 | |
19 | .area _CODE |
20 | init: |
21 | |
22 | ld sp,#stack ;; Stack an Spitze des RAM legen |
23 | |
24 | ; Teste ob Userprogramm im RAM vorhanden |
25 | ; .... |
26 | |
27 | ; Ram ausnullen (auskommentieren, wenn von PC Upload erfolgt) |
28 | xor a ; clear a and carry |
29 | ld bc,#0xdfff ; ram size left |
30 | ld hl,#0x2000 ; starting from 2000 |
31 | ld de,#0x2001 |
32 | ld (hl),a ; 0 -> (2000) |
33 | ldir ; (HL) -> (DE) |
34 | |
35 | ; Initialisiere globale Variablen im RAM |
36 | ld bc, #l__INITIALIZER |
37 | ld a, b |
38 | or a, c |
39 | jr Z, weiter |
40 | ld de, #s__INITIALIZED |
41 | ld hl, #s__INITIALIZER |
42 | ldir |
43 | |
44 | weiter: |
45 | |
46 | ; ###### Hauptprogramm aufrufen ####### |
47 | jp _main |
48 | |
49 | ; Endlos Schleife |
50 | halt |
51 | endlos: |
52 | jr endlos ; Sicher ist sicher |
53 | |
54 | ret |
55 | |
56 | |
57 | ; // reserved |
58 | .area _GSFINAL |
59 | ret |
Wenn Du nur mit "geheimen" Informationen operierst, kannst Du den Rest auch noch für Dich behalten, und mußt nicht das Forum hier belästigen. Du stellst hier ständig falsche Behauptungen über sdcc auf, ohne irgendwas mit nachvollziehbaren Beispielen zu belegen, so daß sich ein sdcc-Entwickler schon genötigt sieht, hier eine ganze Artikelserie mit Klarstellungen zu posten. Und wenn man versucht Dir auf die Sprünge zu helfen, wirst Du auch noch pampig.
Seitenweise Bit für Bit: Beitrag "Mehrdimensionale char-arrays" "Du brauchst dann, später noch den Sprung nach gsinit, da leider die Initalisierung mit _INITIALIZER / _INITALIZED zur Zeit nur für globale Variablen funktioniert. Der _GSINIT-Mechanismus wird noch für lokale Variablen mit storage class static gebraucht."
Christian J. schrieb: > Ich habe mir den erzeugetn Code (mit Optimierung!) genau angeschaut und > es ist so, dass er mal auf dem Stack übergibt und mal einfach nur per > Register! Hast du da ein konkretes Beispiel?
:
Bearbeitet durch User
Christian J. schrieb: > Ich habe mir den erzeugetn Code (mit Optimierung!) genau angeschaut und > es ist so, dass er mal auf dem Stack übergibt und mal einfach nur per > Register! Wo sind Deine Beispiele (C-Source und Compiler Output (.asm))? Christian J. schrieb: > Welchen ASM Code hast Du denn im Startup unter der area GSINIT stehen? > Bei mir ist da nur ein ret drin. hier: Leo C. schrieb: > ;-------------------------------------------------------- > ; global & static initialisations > ;-------------------------------------------------------- > .area _HOME > .area _GSINIT > .area _GSFINAL > .area _GSINIT > ;testpar.c:5: static int drei = 3; > ld iy,#_test_drei_1_3 > ld 0 (iy),#0x03 > ld iy,#_test_drei_1_3 > ld 1 (iy),#0x00 Wenn ich das richtig sehe, hast Du oben Deine crt0.s gepostet. Da kann der Initialsierungscode einer Funktion, die in einer anderen Datei steht natürlich nicht drin sein. In der crt0.s muß allerdings Code sein, der den Code in GSINIT aufruft. Christian J. schrieb: > Und was static angeht so habe ich die Aussage eines der Programmierer > dieses Compilers, Zeigen! (link) > das das noch nicht ausgereift ist. Ich habe ja auch nichts anderes behauptet. Du behauptest aber, lokale statische Variablen würden überhaupt nicht initialisiert. > Ineffizient sowieso aber es wäre noch eine Baustelle, die ich nicht > benutzen sollte. Wenn man nichts effizientes hat, muß man eben mit dem ineffizienten Vorlieb nehmen. Funktionieren tut es ja.
Christian J. schrieb: > Leo C. schrieb: >> Zeigen! (link) > > s.o. So wird das nichts. Bitte konkret, nicht als summarischen Link auf einen sich über 8 Jahre erstreckenden Thread. Und bitte auch nicht als summarischen Verweis auf diesen sich über 4 Seiten erstreckenden Thread.
:
Bearbeitet durch User
Version 1:
1 | ;driver.c:49: void printstrng(char *k) |
2 | 340 ; --------------------------------- |
3 | 341 ; Function printstrng |
4 | 342 ; --------------------------------- |
5 | 01BD 343 _printstrng_start:: |
6 | 01BD 344 _printstrng: |
7 | 345 ;driver.c:51: while ((*k) != '\0') |
8 | 01BD C1 [10] 346 pop bc |
9 | 01BE E1 [10] 347 pop hl |
10 | 01BF E5 [11] 348 push hl |
11 | 01C0 C5 [11] 349 push bc |
12 | 01C1 350 00101$: |
13 | 01C1 7E [ 7] 351 ld a,(hl) |
14 | 01C2 B7 [ 4] 352 or a, a |
15 | 01C3 C8 [11] 353 ret Z |
Version 2:
1 | ; --------------------------------- |
2 | 367 ; Function SetDigit |
3 | 368 ; --------------------------------- |
4 | 01D0 369 _SetDigit_start:: |
5 | 01D0 370 _SetDigit: |
6 | 371 ;driver.c:61: SEG7 = digits[i & 0x0f]; |
7 | 01D0 21 02 00 [10] 372 ld hl, #2+0 |
8 | 01D3 39 [11] 373 add hl, sp |
9 | 01D4 7E [ 7] 374 ld a, (hl) |
10 | 01D5 E6 0F [ 7] 375 and a, #0x0F |
11 | 01D7 5F [ 4] 376 ld e,a |
12 | 01D8 21r5Cr00 [10] 377 ld hl,#_digits |
Die Registervariante hatte ich auch mal in den Fingern aber ichfinde sie nicht mehr, da ich seitdem was verändert habe. Ist mir trotzdem zu undurchschaubar, daher "Workaround". Nur zum Verständnis: static heisst "Nur bei Programmstart", nicht bei jedem Aufruf der Routine.
Version 1 hatten wir doch schon mal. Da wird keineswegs per Register übergeben, wie ich an dieser Stelle auch deutlich beschrieb.
A. K. schrieb: > So wird das nichts. Bitte konkret, nicht als summarischen Link auf > einen sich über 8 Jahre erstreckenden Thread Die letzten 30 oder 40 Beiträge handeln nur von diesem Thema "Variablen" in diesem Thread, weil das bis aufs letzte Bit auseinander genommen wurde, wie da was organsiert ist. Gute Nacht! Beispiel "Segment Problem", ob behoben weiss ich nicht. http://comments.gmane.org/gmane.comp.compilers.sdcc.user/2405 Hi, When I use my custom crt0, in the final binary, gsinit: is pointing to GSFINAL instead of GSINIT. Therefore, global variables do not get initialised. Also, GSINIT is placed into DATA which seems to be wrong. Finally, since my device only has RAM and not ROM, I don't think I need separate CODE and DATA areas - all variables can be stored in CODE like consts are. Is there some way to tell the compiler to do that?
A. K. schrieb: > wie ich an dieser Stelle auch deutlich beschrieb. ... und wieder gelöscht hatte, nachdem ich sah, dass KHB sich bereits korrigiert hatte. Jedenfalls kriegt _printstrng seinen Parameter völlig korrekt auf dem Stack und ins richtige Register.
:
Bearbeitet durch User
Ok... es gibt wie man sieht aber verschiedene Wege, über push/pop und über Indexierung einer Stack Adresse mit IY, bzw. die gehört auch noch dazu. Oben ist es ja über HL + Offset + SP. und wie ermittelt man dann die korr. Position auf dem Stack? Bzw finde ich derzeit noch meine Lösung mit dem zeitweisen Umkopieren auf global praktiklabler, da ich nicht im Stack fummeln muss und zudem symbolische Namen habe, auf die einfach zuzugreifen ist.
Christian J. schrieb: > und wie ermittelt man dann die korr. Position auf dem Stack? Am Anfang der Funktion gilt: SP+0: Return-Adresse. SP+2: Erster Parameter. Wie es danach weiter geht hängt von den Parametern und dem ABI ab. Vermutlich werden pro Parameter mindestens 2 Bytes fällig. Etwaige Veränderungen an SP innerhalb der Funktion müssen natürlich eingerechnet werden, wenn man SP als Basis der Adressierung verwendet. Je nach Compiler, Optionen und Laune kann es auch einen Frame-Pointer geben, hier wohl IY, der im Unterschied zum SP innerhalb einer Funktion unverändert bleibt und als Basis der Adressierung lokaler Daten und Parameter dient. Deine beiden vorhin gezeigten Beispiele greifen beide auf SP+2 zu, nur auf höchst unterschiedliche Weise. Variante 1 poppt beide Worte vom Stack und schiebt sie sofort wieder zurück, Variante 2 rechnet SP+2 aus und fischt sich das indirekt von dort.
:
Bearbeitet durch User
A. K. schrieb: > Je nach Compiler, Optionen und Laune kann es auch einen Frame-Pointer > geben, hier wohl IY, Witziger Weise nimmt er IX als Framepointer, wenn man ihm per Option sagt, daß er den Framepointer nicht weglassen darf. > der im Unterschied zum SP innerhalb einer Funktion > unverändert bleibt und als Basis der Adressierung lokaler Daten und > Parameter dient. Der Preis für die größere Übersichtlichkeit ist, daß für jeden Funktionsaufruf 2 Byte zusätzlich auf dem Stack gebraucht werden, da der aktuelle Framepointer gerettet werden muß. Hier mal ein Beispiel
1 | extern int f(int *x); |
2 | |
3 | int test(int pa, int pb) |
4 | {
|
5 | int local; |
6 | |
7 | local = pa*2 + pb; |
8 | |
9 | return f(&local); |
10 | }
|
Compiliert mit: $ sdcc -mz80 -S testpar.c --fno-omit-frame-pointer
1 | .area _CODE |
2 | ;testpar.c:3: int test(int pa, int pb) |
3 | ; --------------------------------- |
4 | ; Function test |
5 | ; --------------------------------- |
6 | _test_start:: |
7 | _test: |
8 | push ix ;framepointer (fp) der aufrufenden Funktion retten |
9 | ld ix,#0 ; |
10 | add ix,sp ;ix mit stackpointer laden (neuer fp) |
11 | push af ;Platz auf Stack für lokale Variable 'local' |
12 | |
13 | ;Der Stack sieht jetzt so aus: |
14 | ; |
15 | ; | | höhere Adressen |
16 | ; +----------+ |
17 | ; | pb | sp+8 ix+6 |
18 | ; +----------+ |
19 | ; | pa | sp+6 ix+4 |
20 | ; +----------+ |
21 | ; | ret-addr | sp+4 ix+2 |
22 | ; +----------+ |
23 | ; | ix | sp+2 ix+0 |
24 | ; +----------+ |
25 | ; | local | sp+0 ix-2 |
26 | ; +----------+ |
27 | ; | | Niedrigere Adressen |
28 | ; |
29 | |
30 | ;testpar.c:7: local = pa*2 + pb; |
31 | ld l,4 (ix) ;pa nach hl |
32 | ld h,5 (ix) |
33 | add hl, hl ;pa*2 |
34 | ld e,6 (ix) ;pb nach de |
35 | ld d,7 (ix) |
36 | add hl,de ;pa*2 + pb |
37 | inc sp ;sp auf 'local' zeigen lassen |
38 | inc sp ;trotz fp, so gehts schneller |
39 | push hl ;hl in 'local' speichern |
40 | ;testpar.c:9: return f(&local); |
41 | ld hl,#0x0000 |
42 | add hl,sp ;addresse von local |
43 | push hl ;auf Stack als Parameter für f |
44 | call _f |
45 | ld sp,ix ;locale Variablen vom Stack entfernen |
46 | pop ix ;fp der aufrufenden Funktion wiederherstellen |
47 | ret |
48 | _test_end:: |
Wenn man dieses Beispiel ohne Framepointer compiliert, wird beim Laden des 2. Parameters das Zwischenergebnis in hl teilweise zerstört. (sdcc 3.4.0) :(
Christian J. schrieb: > und wie ermittelt man dann die korr. Position auf dem Stack? Zitat sdcc-Manual:
1 | 3.14.2 A Step by Step Introduction |
2 | |
3 | Starting from a small snippet of c-code this example shows for the MCS51 how to use inline assembly, access |
4 | variables, a function parameter and an array in xdata memory. The example uses an MCS51 here but is easily |
5 | adapted for other architectures. This is a buffer routine which should be optimized: |
Wenn Du Inline-Assembler verwenden willst, wirst Du ums Lernen von Assembler nicht herum kommen.
Leo C. schrieb: >> geben, hier wohl IY, > > Witziger Weise nimmt er IX als Framepointer, wenn man ihm per Option > sagt, daß er den Framepointer nicht weglassen darf. Ich hatte IY von Christians Aussage übernommen. Dass es eines dieser beiden Register sein würde lag nahe, nur offen welches. Framepointer waren in früheren C Compilern ziemlich üblich. Da waren Compiler noch recht schematisch, ohne statementübergreifende Optimierung und mit Registerverwaltung durch den Anwender (Keyword "register").
:
Bearbeitet durch User
A. K. schrieb: > Ich hatte IY von Christians Aussage übernommen. Dass es eines dieser > beiden Register sein würde lag nahe, nur offen welches. Deswegen witzigerweise. Ohne Framepointer nimmt er IY, wenn er mit HL nicht auskommt. Wenn man dann das hier im Handbuch sieht:
1 | --reserve-regs-iy |
2 | This option tells the compiler that it is not allowed to use register pair |
3 | iy. The option can be useful for systems where iy is reserved for the OS. |
4 | This option is incompatible with --fomit-frame-pointer. |
glaubt man erst recht, daß IY der Framepointer sei. Mit der Option "--fno-omit-frame-pointer" nimmt er aber konsequent IX.
Nimmt er IY dann als einmalig in der Funktion definierten echten Framepointer? Oder als normales transientes Adressregister, als Ersatz für das grad nicht verfügbare HL?
Dachte ich es mir doch. HL ist sowas wie ein 16-Bit Akkumulator. Der kann nicht immer auch als Adressregister operieren und ein ADD BC/DE,SP gibt es nicht. Also muss IY dran glauben. Völlig normales Registermanagement.
:
Bearbeitet durch User
Danke, damit kann ich schon was anfangen und mit Asm bin ich ja sowieso dabei, allerdings macht hier Übung der Meister, bis man nicht mehr alles nachschauen muss, zb was indirekte Adressierung angeht usw. Ich habe es bei PC und auch 8085 damals wo ich nur Asm programmierte immer vermieden den Stack zu manipulieren, da ich den als vom System verwaltet ansah und auch Ints, die mir "dazwischen" funken als riskant ansah. Nur zwischendurch wenn registerknappheit herrscht mal eben was weg gepoppt und danach wieder geholt. Dieses Prinzip Framepointer unterstützt Rekursion und verschachtelte Aufrufe wurde auch wohl deshalb eingeführt. Dann werkeln wir mal weiter......
Nachtrag zu: Leo C. schrieb: > Letzteres Sieht man auch in diesem Beitrag: Beitrag "Re: Retro Fieber: Z80 oder 68000 ?" IY wird hier im Gegensatz zum "echten" Frampointer auch nicht auf den Stack gesichert. Christian J. schrieb: > Beitrag "Mehrdimensionale char-arrays" Das war die Stelle, die ich hier meinte: Leo C. schrieb: > Christian J. schrieb: >> Weiterhin klappt es nicht statische Variablen in Funktionen zu >> initialisieren, diese Funktion gibt es (noch) nicht. > > Auch diese Falschbehauptung wurde schon irgendwo widerlegt. Ich finde > nur die Stelle nicht. Wie man in meinem angehängten Versuch sehen kann, Auf die Idee, in uralten gekaperten Threads zu suchen, kommt man halt nicht. Aber es funktioniert. Zugegebenermaßen etwas tricky. Wichtig ist, das man die C-Dateien getrennt kompiliert, und beim Linken die crt0.rel zuerst kommt, da darin die Reihenfolge der Segmente definiert ist. Außerdem darf man beim Linken die Optionen --code-loc und evtl. --data-loc nicht weglassen, sonst werden Segmente übereinander statt hintereinander gelegt. Es kommt dann nicht mal eine Fehlermeldung. Gestern Abend habe ich das mal ausprobiert. D.h. ich habe ein komplett lauffähiges Demo erstellt. Zum Testen bin ich aber gestern nicht mehr gekommen, weil "mein" Debugger leider auch noch ein paar Ecken hat. Jetzt gehts aber. Im Anhang ist das komplette Beispiel incl. Makefile, daß Du auch für Dein Projekt verwenden kannst. Die crt0 habe ich auf das für mich absolut notwendige reduziert. Die (ABS) Area braucht man im Grunde nicht, auch nicht, wenn das Programm ab 0 im EPROM laufen soll. Man linkt dann einfach mit '--code-loc 0', bzw 'CODE_LOC := 0' im Makefile. Die Restart-Vektoren und den NMI-Vektor könnte man dann nach dem 'JP init' auch noch platzieren. Schau Dir das mal an, und vor allem: probier's aus. Schreib Dir dazu eine eigene, einfache putchar(). Dazu brauchst Du nicht mal Inline-Assembler und erst recht keine Interrupts. ungefähr so: void putchar(char c) { while ((sti_statusregister & TX_ready_maske) == 0) ; /* warten */ sti_senderegister = c; }
Noch ein paar Ergänzungen. Das Beispiel sollte zeigen, daß die Initialisierung von lokalen static Variablen funktioniert. Deshalb ist count in main() static deklariert. putchar() ist __naked deklariert, damit der Assemblercode den Parameter c auf dem Stack findet, unabhängig davon, ob mit oder ohne Framepointer compiliert wird. Ohne __naked und mit Framepointer würde der Compiler diesen Prolog generieren:
1 | push ix |
2 | ld ix,#0 |
3 | add ix,sp |
Und dann wäre der Offset zu c nicht mehr 2 sondern 4. Schön wäre ein Compiler-Macro, daß den Zustand dieses Compilerschalters liefern würde, habe ich aber nicht gefunden. Headerdatei zu myputchar.c habe ich weggelassen, und statt dessen stdio.h included. Damit ist sichergestellt, daß der Prototyp von putchar() zur libc paßt.
Leo C. schrieb: > Aber es funktioniert. Zugegebenermaßen etwas tricky. Wichtig ist, das > man die C-Dateien getrennt kompiliert, und beim Linken die crt0.rel > zuerst kommt, da darin die Reihenfolge der Segmente definiert ist. > Außerdem darf man beim Linken die Optionen --code-loc und evtl. > --data-loc nicht weglassen, sonst werden Segmente übereinander statt > hintereinander gelegt. Es kommt dann nicht mal eine Fehlermeldung. Hi, da bin ich schon länger, dass man es so machen muss:
1 | # Assembliere das crt0 startup file |
2 | echo "Assembliere....." |
3 | sdasz80 -plosgff -o -l crt0.rel crt0.s |
4 | echo "Kompiliere main.c...." |
5 | sdcc -mz80 main.c -c |
6 | echo "Linke beide Dateien...." |
7 | sdcc -mz80 --verbose --no-std-crt0 --vc --code-loc 0x0100 --data-loc 0x2000 crt0.rel main.rel |
8 | # In Binaerformazt wandeln |
9 | ./hex2bin -p 0 crt0.ihx |
10 | #echo "Datei zum Target uebertragen..." |
11 | #cat crt0.bin > /dev/ttyUSB0 |
1 | ///////////////////////////////////////////////////////// |
2 | // Zeichenausgabe für printf auf der STI mit 9600 Baud |
3 | void putchar(char c) |
4 | { |
5 | while ((STI_TSR & 0x80) == 0); // Warte bis Buffer frei... |
6 | STI_UDR = c; // Byte einschreiben |
7 | |
8 | } |
putchar funktioniert schon, getchar auch. Die Files schaue ich mir mal heute abend in Ruhe an. gruss, Christian
Christian J. schrieb: > und mit Asm bin ich ja sowieso > dabei, allerdings macht hier Übung der Meister, bis man nicht mehr alles > nachschauen muss, zb was indirekte Adressierung angeht usw. Hier ist eine Gedächtnisstütze. Das Ding stammt aus einer mc von 1982 und war damals sehr hilfreich. Ausgegraben habe ich es wieder, als wir für den AVR-CP/M-Computer den Z80-Interpreter gebaut haben. Danach habe ich zwischendurch immer mal wieder einen Block davon eingetippt. Nur die Farbe hat immer noch gefehlt. Bis heute. Auch wenn man heutzutage wohl selten die Opcodes eintippt, als Übersicht, welcher Befehl mit welchen Operanden funktioniert, und ob und wie die Flags beeinflusst werden, ist das "Poster" immer noch gut zu gebrauchen.
Danke aber auch das habe ich schon... in bunt ist aber cool, gleich mal ausgedruckt.
Das geht bei mir nicht! Wenn gsinit in der Area _GSINIT liegt wird ein Sprung ins Ram erzeugt wo nichts ist. Ich habe ewig dazu gebraucht das rauszu finden. gsinti daherin die Code Area übernommen und den Call weg gemacht Daanke für das makefile... ist nicht so meine Welt sowas. Baue ich noch ein. geht nicht:
1 | ;; Initialise global variables |
2 | call gsinit |
3 | call _main |
4 | jp _exit |
5 | |
6 | .area _CODE |
7 | _exit:: |
8 | ;; Exit - ddtz breakpoint entry |
9 | rst 0x30 |
10 | 1$: |
11 | halt |
12 | jr 1$ |
13 | |
14 | .area _GSINIT |
15 | gsinit:: |
16 | ld bc, #l__INITIALIZER |
17 | ld a, b |
18 | or a, c |
19 | jr Z, gsinit_next |
20 | ld de, #s__INITIALIZED |
21 | ld hl, #s__INITIALIZER |
22 | ldir |
23 | gsinit_next: |
geht:
1 | ;/////////////////////////////////////////////////////////// |
2 | ;; ------- Start des Hauptprogramms nach der Zeropage ----------- |
3 | |
4 | .area _CODE |
5 | init: |
6 | |
7 | ld sp,#stack ;; Stack an Spitze des RAM legen |
8 | |
9 | ; Teste ob Userprogramm im RAM vorhanden |
10 | ; .... |
11 | |
12 | ; Ram ausnullen (auskommentieren, wenn von PC Upload erfolgt) |
13 | xor a ; clear a and carry |
14 | ld bc,#0xdfff ; ram size left |
15 | ld hl,#0x2000 ; starting from 2000 |
16 | ld de,#0x2001 |
17 | ld (hl),a ; 0 -> (2000) |
18 | ldir ; (HL) -> (DE) |
19 | |
20 | ; Initialisiere globale Variablen im RAM |
21 | ld bc, #l__INITIALIZER |
22 | ld a, b |
23 | or a, c |
24 | jr Z, weiter |
25 | ld de, #s__INITIALIZED |
26 | ld hl, #s__INITIALIZER |
27 | ldir |
28 | |
29 | weiter: |
30 | |
31 | ; ###### Hauptprogramm aufrufen ####### |
32 | jp _main |
33 | |
34 | ; Endlos Schleife |
35 | halt |
36 | endlos: |
37 | jr endlos ; Sicher ist sicher |
38 | halt |
39 | |
40 | ; // Hier muss ein ret rein |
41 | .area _GSFINAL |
42 | ret |
> Das geht bei mir nicht!
Dann poste mal die komplette crt0.s (als Anhang)
Christian J. schrieb: > Danke aber auch das habe ich schon... Dann weißt Du ja jetzt, wo Matthias Buchhorn die Seiten 7 bis 9 abgekupfert hat. ;) Allerdings hat er für die Schiebebefehle noch Graphiken zugefügt. Mal sehen, ob ich die auch noch rein bekomme. > in bunt ist aber cool, gleich mal ausgedruckt. Und dann die beiden Seiten in eine Klarsichthülle, zum leichten Greifen und Wenden. Besser als 11 Seiten, die man blättern muß.
Leo C. schrieb: > Dann poste mal die komplette crt0.s (als Anhang) s. Anhang. es funktioniert nur so, da sonst der CD (gsinit) eine RAM Adresse zugeordnet bekommrt, weil die ganze Area _GSINIT dem RAM Bereich zugeordnet wird aus dem --data-loc Wort des Aufrufes. Die Area kann über den Linker sdld - .... auf einen Wert gefixt werden aber es gibt kein Beispiel und die Man Page ist kryptisch. Ich habe den Linker nicht benutzt sondern lasse das über sdcc erledigen. btw Manual: Ich habe noch nie ein Variable "c;" allein gesehen. Keine Ahnung was das soll.
1 | void to_buffer( unsigned char c ) |
2 | { |
3 | c; // to avoid warning: unreferenced function argument |
4 | __asm |
5 | ; save used registers here. |
6 | ; If we were still using r2,r3 we would have to push them here. |
Da Du dich ja so gut auskennst, wie würde ein Preprozessor Makro in C aussehen was mir alle register Pop't und eines was alle Push'ed. Mehrzilige makros habe ich noch nicht benutzt und kenne die Syntax auch nicht.
> btw Manual: Ich habe noch nie ein Variable "c;" allein gesehen. Keine > Ahnung was das soll. Ich kenne das nur in der Variante "(void)variable;". Das sagt dem Compiler, dass diese Variable benutzt wird und nicht wegoptimiert werden darf. Damit fällt eine Warnung weg, wenn man eine Variable z.B. nur in Inline-Asm benutzt.
Hallo, Bleibt eigentlich noch zu klären warum RST7 die gleiche Adresse 0x38 hat wie der Mode 1 Interrupt, den ich mal ausprobiert habe und der auch gut funktioniert. Die crt0.s fasse ich soweit nicht mehr an, da jetzt einschliesslich aller Fehlerabfangmechanismen das Ding läuft und genau das tut, was es soll. Da habe ich mir mich philipp Krause, der an dem sdcc mitwirkt einen Worlf diskutiert wo nun welches Segment steht und in welcher Reihenfolge das alles sein muss. Da kommt man nämlich nie drauf, wenn man nicht in jede Falle reinlief. Grundsätzlich ist alles nach dem ersten .area "relativ" zu sehen und kein .org darf da mehr stehen, es sei denn man definiert die .area (ABS) als absolut und teilt dem Linker mit wohin er sie zu legen hat, was wiederum nicht dokumentiert ist und die Syntax dazu Raterei ist. Mit --data-loc und --code-loc ist soweit alles gesagt, dass er weiss wohin es kommt, klar zwischen ROM Code und RAM unterscheidet. ------ ROM Start --code-loc= 0x100 ------ .area _CODE .area _INITIALIZER .area _HOME .area _GSINIT .area _GSFINAL ------------ROM Ende = RAM Start 0x2000 --------- .area _DATA .area _INITIALIZED .area _BSEG .area _BSS .area _HEAP Demzufolge müsste GSINIT eigentlich ins ROM zeigen aber alles was ich da reinschreibe landet mit Bezug zum RAM .... rätsel. Das "Kerlchen" spielt schon ganz prima, säuft Sprit, ähm Strom wie ein LKW und es macht Spass mal was anderes als nur einen Controller zu haben, der plug & play funktioniert und dank Arduino von jedem Schulkind zu bedienen ist.
S. R. schrieb: > Ich kenne das nur in der Variante "(void)variable;". Das sagt dem > Compiler, dass diese Variable benutzt wird und nicht wegoptimiert werden > darf. Damit fällt eine Warnung weg, wenn man eine Variable z.B. nur in > Inline-Asm benutzt. Eigentlich ist das eher ein Hinweis an Compiler und sich selbst, dass es Absicht ist, und kein Versehen. Inhaltlich ergibt das m.E. keinen Unterschied.
Christian J. schrieb: > Bleibt eigentlich noch zu klären warum RST7 die gleiche Adresse 0x38 > hat wie der Mode 1 Interrupt Weil Zilog zu faul war, es anders zu machen. ;-) IM0 liest im IACK einen Befehl vom Bus. Wie 8080. Exakt deshalb gibt es überhaupt die RST Befehle, damit das ohne grossem Aufwand in einem Byte geht. IM1 tut genau das gleiche wie IM0, kriegt aber statt dessen 0xFF = RST7. IM1 springt also nicht wirklich nach 0x38, sondern führt RST7 aus.
:
Bearbeitet durch User
Christian J. schrieb: > Das geht bei mir nicht! > Wenn gsinit in der Area _GSINIT liegt wird ein Sprung ins Ram erzeugt wo > nichts ist. (Kein Sprung, sondern ein Call, der auch wieder zurückkommen soll.) In dem Fall wurde die GSINIT-Area ins RAM gelegt was natürlich nicht sein sollte. Das Problem hatte ich auch mal. Ca. 2 Wochen her, und dann hatte ich das nicht mehr weiter verfolgt. Die alte crt0.s habe ich nicht mehr. Könnte sein, daß ich beim Linken crt0 am Schluß statt am Anfang hatte. Christian J. schrieb: > Die crt0.s fasse ich soweit nicht mehr an, da jetzt einschliesslich > aller Fehlerabfangmechanismen das Ding läuft und genau das tut, was es > soll. Es tut bei Dir eben nicht was es soll. Die statischen lokalen Variablen werden nicht initialisiert, und irgendwann behauptest Du wieder, das wäre ein Fehler von sdcc. Außerdem hast Du mir vorhin per Mail geschrieben, daß Du Fehler eben nicht abfangen willst. Deine "Mechanismen" sind wirkungslos oder verschleiern sorgar Fehler. Hoffnungslos. Für anderen, die hier noch mitlesen.. Christians crt0.s habe ich so (zurück) geändert, das die Initialisierung der globalen Variablen wieder im Unterprogramm gsinit in der Area _GSINIT liegt. Seine Interruptvektoren habe ich durch Platzhalter ersetzt, sonst habe ich nichts verändert. Ich kann diese Datei mit meinem Testprogramm von weiter oben linken, und alles liegt am richtigen Platz. crt0.rst
1 | 138 .area _CODE |
2 | 0100 139 init: |
3 | 140 |
4 | 0100 31 FF FF [10] 141 ld sp,#stack ;; Stack an Spitze des RAM legen |
...
1 | 154 ;; Initialise global variables |
2 | 0110 CD 72 0C [17] 155 call gsinit |
3 | 156 |
4 | 157 ; ###### Hauptprogramm aufrufen ####### |
5 | 0113 C3 1A 01 [10] 158 jp _main |
6 | 159 |
7 | 160 ; Endlos Schleife |
8 | 0116 76 [ 4] 161 halt |
9 | 0117 162 endlos: |
10 | 0117 18 FE [12] 163 jr endlos ; Sicher ist sicher |
11 | 164 |
12 | 0119 C9 [10] 165 ret |
13 | 166 |
14 | 167 ; Initialisiere globale Variablen im RAM |
15 | 168 .area _GSINIT |
16 | 0C72 169 gsinit:: |
17 | 0C72 01 02 00 [10] 170 ld bc, #l__INITIALIZER |
18 | 0C75 78 [ 4] 171 ld a, b |
19 | 0C76 B1 [ 4] 172 or a, c |
20 | 0C77 28 08 [12] 173 jr Z, weiter |
21 | 0C79 11 02 20 [10] 174 ld de, #s__INITIALIZED |
22 | 0C7C 21 70 0C [10] 175 ld hl, #s__INITIALIZER |
23 | 0C7F ED B0 [21] 176 ldir |
24 | 0C81 177 weiter: |
25 | 178 |
26 | 179 ;**************************************** |
27 | 180 ; hier wird der Initialisierungscode für |
28 | 181 ; statische funktionslokole eingefügt |
29 | 182 ;**************************************** |
30 | 183 |
31 | 184 ; // Hier muss ein ret rein |
32 | 185 .area _GSFINAL |
33 | 0C91 C9 [10] 186 ret |
Liegt alles im ROM. hallo_static.rst:
1 | ;-------------------------------------------------------- |
2 | 36 ; global & static initialisations |
3 | 37 ;-------------------------------------------------------- |
4 | 38 .area _HOME |
5 | 39 .area _GSINIT |
6 | 40 .area _GSFINAL |
7 | 41 .area _GSINIT |
8 | 42 ;hallo-static.c:8: static int count = 5; |
9 | 43 ; genAssign |
10 | 44 ;fetchLitPair |
11 | 0C81 FD 21 00 20 [14] 45 ld iy,#_main_count_1_13 |
12 | 0C85 FD 36 00 05 [19] 46 ld 0 (iy),#0x05 |
13 | 47 ;fetchLitPair |
14 | 0C89 FD 21 00 20 [14] 48 ld iy,#_main_count_1_13 |
15 | 0C8D FD 36 01 00 [19] 49 ld 1 (iy),#0x00 |
Wie man sieht, wird der Initialisierungscode aus hallo_static in _GSINIT am Ende angehängt. Nach allen Initialisierungsabschnitten der C-Dateien (hier gibts nur den einen), kommt die GSFINAL-Area mit dem ret-Befehl. Die rst-Dateien erzeugt übrigens der Linker bei gesetztem Schalter '-u'. Er setzt dann in die lst-Dateien des Compilers die aufgelösten Adressen ein. Im Anhang ist das ganze "Projekt", mit den vollständigen Dateien.
A. K. schrieb: > IM1 tut genau das gleiche wie IM0, kriegt aber statt dessen 0xFF = RST7. > IM1 springt also nicht wirklich nach 0x38, sondern führt RST7 aus. Eben, die waren nicht zu faul, sondern haben es faulen Entwicklern noch einfacher gemacht.
Christian J. schrieb: > wie würde ein Preprozessor Makro in C > aussehen was mir alle register Pop't und eines was alle Push'ed. Wozu soll das gut sein? Im Inline-Assembler braucht braucht man die Register des Aufrufers nicht zu retten. Wenn Du da soviel Code reinschreibst, daß Du Deine eigenen Zwischenstände retten mußt, machst Du irgendwas falsch. Blieben noch Interrupt-Service-Routinen, die __naked deklariert sind. So viele können das nicht sein. Etwas copy-and-paste ist da sicher keine Zumutung. > Mehrzeilige makros habe ich noch nicht benutzt und kenne die Syntax auch > nicht. Es gibt keine mehrzeiligen Makros. Aber man kann eine (logische) Makrozeile mit '\' am Zeilenende über mehrere physikalische Zeilen verteilen.
Leo C. schrieb: > Wie man sieht, wird der Initialisierungscode aus hallo_static in _GSINIT > am Ende angehängt. Nach allen Initialisierungsabschnitten der C-Dateien > (hier gibts nur den einen), kommt die GSFINAL-Area mit dem ret-Befehl. Ich kann Dir grad genau sagen was dabei herauskommt wenn ich deine crt0.s verwende: CD 00 00 oder anders call 0x0000 im Hex File, also Brennfile. beim Aufruf call gsinit. Immerhin was Neues, gabs noch nicht. Init lokaler Vars zu Fuss: 123 ;interrupts.c:21: static int variable = 5; 0000 FD 21r51r00 [14] 124 ld iy,#_nmi_vint_variable_1_77 0004 FD 36 00 05 [19] 125 ld 0 (iy),#0x05
Christian J. schrieb:
Mit einer Antwort warte ich wohl noch eine Weile. Man weiß ja nie, wie
oft Du den Text noch änderst, oder wieviele Abschnitte, die alles wieder
anders aussehen lassen, anhängst.
ES GEHT NICHT ! Ok? Ich habe das schon hundertmal durchprobiert.... diese sch..... GSINIT liegt immer falsch ! Lassen wir es hier auch bitte gut sein. Es hat so funktioniert und ich habe auch keine Lust mehr da ewig dran zu sitzen, warum das mit den .areas so ist und nicht anders. Ich kann noch mal deine Sache gleich durchkompilieren aber dazu brauche ich zeit,.
Lieber Christian, mit den zwei Schnipseln oben kann man ohne weiteren Kontext absolut nichts anfangen. Ganz ehrlich.
Hier die crt0.s und den Memory Dump musst du mir glauben, den ich im Brenner Tool sehe und wo der Call auf 0x0000 zeigt. vorher nach 0x2000.
1 | ;-------------------------------------------------------------------------- |
2 | ; crt0.s - Generic crt0.s for a Z80 |
3 | ; |
4 | ; Minimum Z80 System mit Mostek 3801 Multi I/O Chip |
5 | ; |
6 | ;-------------------------------------------------------------------------- |
7 | |
8 | .module crt0 ; Modul Name für den Linker |
9 | |
10 | ; Memory Map Adressen der Zeropage (vom Benutzer definierbar) |
11 | ; 0x00 Reset Vector und Aufruf Hauptprogramm |
12 | ; 0x38 Mode 1 Int Vektor |
13 | ; 0x40 Mode 2 Vektor Tabelle für STI Mostek Multi I/O |
14 | ; 0x66 NMI Reset Vektor |
15 | ; 0x80 Copyright String |
16 | ; 0x100 User Programm |
17 | |
18 | ; Definitions |
19 | stack .equ 0xffff |
20 | adr_vec_table .equ 0x40 |
21 | adr_nmi .equ 0x66 |
22 | adr_copyright .equ 0x80 |
23 | adr_userprog .equ 0x100 |
24 | |
25 | ; Globale Funktionen und Variablen für das C-Programm |
26 | |
27 | .globl _main |
28 | .globl _nmi_vint ; Funktion des NMI Handlers |
29 | |
30 | ; Interruptroutinen für den Mostek MK3801 Multi I/O Baustein |
31 | ; Manual STI Baustein MK3801 Figure 7 |
32 | .globl _int_sti_gpi_0 ; General Purpose Interrupt 0 |
33 | .globl _int_sti_gpi_1 ; General Purpose Interrupt 1 |
34 | .globl _int_sti_gpi_2 ; General Purpose Interrupt 2 |
35 | .globl _int_sti_gpi_3 ; General Purpose Interrupt 3 |
36 | .globl _int_sti_timer_d |
37 | .globl _int_sti_timer_c |
38 | .globl _int_sti_gpi_4 ; General Purpose Interrupt 4 |
39 | .globl _int_sti_gpi_5 ; General Purpose Interrupt 5 |
40 | .globl _int_sti_timer_b |
41 | .globl _int_sti_transmit_error |
42 | .globl _int_sti_transmit_buffer_empty |
43 | .globl _int_sti_receive_error |
44 | .globl _int_sti_receive_buffer_full |
45 | .globl _int_sti_timer_a |
46 | .globl _int_sti_gpi_6 ; General Purpose Interrupt 6 |
47 | .globl _int_sti_gpi_7 ; General Purpose Interrupt 7 |
48 | ; Mode 1, alles auf eine Routine umleiten |
49 | .globl _int_sti_all |
50 | |
51 | .globl l__INITIALIZER |
52 | .globl s__INITIALIZER |
53 | .globl s__INITIALIZED |
54 | |
55 | ; ------------------------------------------------------------- |
56 | |
57 | .area _HEADER (ABS) |
58 | ; Reset vector bei Kaltstart und Sprung ins User Programm |
59 | .org 0 |
60 | jp init |
61 | |
62 | ;; Tabelle der RST Vektoren für Software Interrupts |
63 | .org 0x08 |
64 | ret |
65 | .org 0x10 |
66 | ret |
67 | .org 0x18 |
68 | ret |
69 | .org 0x20 |
70 | ret |
71 | .org 0x28 |
72 | ret |
73 | .org 0x30 |
74 | ret |
75 | ;.org 0x38 |
76 | ;reti |
77 | |
78 | |
79 | ;/////////////////////////////////////////////////////////// |
80 | ;// Mode 1 Interrupt |
81 | .org 0x38 |
82 | jp _int_sti_all |
83 | |
84 | |
85 | ;/////////////////////////////////////////////////////////// |
86 | ; Tabelle der Mode 2 Int Vektoren auf die Handler Funktionen im C Modul |
87 | ; Reihenfolge beachten !!! Siehe Manual Mostek 3801, Interrupt Tabelle |
88 | .org 0x40 |
89 | .dw (_int_sti_gpi_0) |
90 | .dw (_int_sti_gpi_1) |
91 | .dw (_int_sti_gpi_2) |
92 | .dw (_int_sti_gpi_3) |
93 | .dw (_int_sti_timer_d) |
94 | .dw (_int_sti_timer_c) |
95 | .dw (_int_sti_gpi_4) |
96 | .dw (_int_sti_gpi_5) |
97 | .dw (_int_sti_timer_b) |
98 | .dw (_int_sti_transmit_error) |
99 | .dw (_int_sti_transmit_buffer_empty) |
100 | .dw (_int_sti_receive_error) |
101 | .dw (_int_sti_receive_buffer_full) |
102 | .dw (_int_sti_timer_a) |
103 | .dw (_int_sti_gpi_6) |
104 | .dw (_int_sti_gpi_7) |
105 | |
106 | ;/////////////////////////////////////////////////////////// |
107 | ; NMI Interrupt 0x66, muss mit retn abgeschlossen werden |
108 | .org 0x66 |
109 | jp _nmi_vint ; Aufruf Handler im C Modul main.c |
110 | |
111 | ;/////////////////////////////////////////////////////////// |
112 | ; Anordung der Segmente fuer den Linker, ab hier nur relative |
113 | ; Adressen |
114 | |
115 | .area _CODE |
116 | .area _INITIALIZER |
117 | .area _HOME |
118 | .area _GSINIT |
119 | .area _GSFINAL |
120 | .area _DATA |
121 | .area _INITIALIZED |
122 | .area _BSEG |
123 | .area _BSS |
124 | .area _HEAP |
125 | |
126 | ;/////////////////////////////////////////////////////////// |
127 | ;; ------- Start des Hauptprogramms nach der Zeropage ----------- |
128 | |
129 | .area _CODE |
130 | init: |
131 | |
132 | ld sp,#stack ;; Stack an Spitze des RAM legen |
133 | |
134 | call gsinit |
135 | |
136 | ; Teste ob Userprogramm im RAM vorhanden |
137 | ; .... |
138 | |
139 | ; Ram ausnullen (auskommentieren, wenn von PC Upload erfolgt) |
140 | xor a ; clear a and carry |
141 | ld bc,#0xdfff ; ram size left |
142 | ld hl,#0x2000 ; starting from 2000 |
143 | ld de,#0x2001 |
144 | ld (hl),a ; 0 -> (2000) |
145 | ldir ; (HL) -> (DE) |
146 | |
147 | ; ###### Hauptprogramm aufrufen ####### |
148 | call _main |
149 | endlos: |
150 | halt |
151 | jr endlos |
152 | |
153 | .area _GSINIT |
154 | |
155 | ; Initialisiere globale Variablen im RAM |
156 | ld bc, #l__INITIALIZER |
157 | ld a, b |
158 | or a, c |
159 | jr Z, weiter |
160 | ld de, #s__INITIALIZED |
161 | ld hl, #s__INITIALIZER |
162 | ldir |
163 | |
164 | weiter: |
165 | |
166 | ; // Hier muss ein ret rein |
167 | .area _GSFINAL |
168 | ret |
Bei Dir sieht das ja auch anders aus da wird die Numerierung beo 0xc72 fortgesetzt, bei mir bei 0. 0119 C9 [10] 165 ret 166 167 ; Initialisiere globale Variablen im RAM 168 .area _GSINIT 0C72 169 gsinit:: 0C72 01 02 00 [10] 170 ld bc, #l__INITIALIZER 0C75 78 [ 4] 171 ld a, b 0C76 B1 [ 4] 172 or a, c 0C77 28 08 [12] 173 jr Z, weiter 0C79 11 02 20 [10] 174 ld de, #s__INITIALIZED 0C7C 21 70 0C [10] 175 ld hl, #s__INITIALIZER 0C7F ED B0 [21] 176 ldir 0C81 177 weiter: meines: 151 152 ; ###### Hauptprogramm aufrufen ####### 0013 CDr00r00 [17] 153 call _main 0016 154 endlos: 0016 76 [ 4] 155 halt 0017 18 FD [12] 156 jr endlos 157 158 .area _GSINIT 159 160 ; Initialisiere globale Variablen 0000 01r00r00 [10] 161 ld bc, #l__INITIALIZER 0003 78 [ 4] 162 ld a, b 0004 B1 [ 4] 163 or a, c 0005 28 08 [12] 164 jr Z, weiter 0007 11r00r00 [10] 165 ld de, #s__INITIALIZED 000A 21r00r00 [10] 166 ld hl, #s__INITIALIZER 000D ED B0 [21] 167 ldir 168 000F 169 weiter:
Hier alles zusammen, ich arbeite ohne Makefile, nur mit compile.sh
Wie kriegt man deine Kompiliert? >make > Fuer das Ziel all ist nichts zu tun"
Christian J. schrieb: > Hier die crt0.s und den Memory Dump musst du mir glauben, den ich im > Brenner Tool sehe und wo der Call auf 0x0000 zeigt. vorher nach 0x2000. Das muß ich überhaupt nicht glauben. ;) Schließlich habe ich oben den Linkerschalter gepostet. Falls Du immer noch das Shellscript zum compilieren verwendest, dann schreib doch mal das -u dazu. Konkret:
1 | sdcc -mz80 --verbose --no-std-crt0 -Wl-u --code-loc 0x0100 --data-loc 0x2000 crt0.rel main.rel |
Und dann schau dir die *.rst-Dateien an.
>make > Fuer das Ziel all ist nichts zu tun" In dem Archiv war ja auch alles schon fertig $ make clean $ make
Bei Dir liegt alles richtig, bei mir falsch :-( Kann also nur noch daran liegen dass ich ohne Makefile arbeite. ich versthehe von den Dingern nichts, habe sie noch nie benötigt. Kann ich das auch für 3 oder 4 Source dateien modifizieren? Bei mir binde ich die anderen dateien ja direkt ein, so dass nur noch main.c existiert für den Compiler. -u geht nur bei sdld nicht bei sdcc
Christian J. schrieb: > Compiler option -W1-u ignored ^ Das muß ein l sein. ell ell ell Außerdem: ?ASlink-Warning-Undefined Global 'gsinit' referenced by module 'crt0' Das label 'gsinit' fehlt in Deiner crt0. Da kommt dann auch der 'Call 0x0000' her. Das kommt davon, wenn man dem Assembler sagt, er soll alle undefinierten Symbole als Global annehmen. Das wiederum liegt aber nicht an Dir.
Zusammenfassung: Ich brauche eine Weile um das alles auf Makefile umzuschrieben. Das scheint mir auf jeden Fall sinnvoller, denn auch sonst überall wird zuerst alles kompiliert und dann gelinkt. All in One kenne ich nur vom CCS Compiler für PIC, der kann auch nur ein File verarbeiten und man muss tricksen, damit man mehr haben kann. Von Makefiles verstehe ich nichts, das hat bisher die jeweilige IDE alles übernommen. Es geht also nur darum ob es durch Ergänzung der Zeile SRC im Makefile um die anderen .c Sourcen ausreicht das Projekt zu kompilieren?
Habe das korrigiert, es wird immer noch CD 00 00 erzeugt, da _GSINIT auf 0x0000 definiert wurde. Bevor ich das alles umgearbeitet habe mache ich hier erstmal Sendepause. So schnell kann ich das nicht.
Christian J. schrieb: > Kann ich das auch für 3 oder 4 Source dateien modifizieren? Ja, einfach an die Zeile 'SRC = ' anfügen. Den Namen des Outputs (Hex- und bin-File kannst Du unter TARGET anpassen. > Bei mir binde ich die > anderen dateien ja direkt ein, so dass nur noch main.c existiert für den > Compiler. Das ist Murks.
das .rst File zeigt die gsinit übrigens an der richtigen Stelle.Da stimmt alles. Jetzt wird aber kein .ihx File mehr erzeugt, warum weiss ich auch nicht. Vorher ging das problemlos.... -opt-code-size verhindert das aus welchen Gründen.
Bevor du mir beim Modifzieren wieder daszwischen funkst und ich den Text nicht mehr ändern kann: --opt statt -opt..... und alles ist da. Grad alles gebrannt und eingesteckt. Es läuft. Mit der .sh Methode. Alles liegt richtig. Wie gesagt arbeite ich das heute abend auf Makefile um, weil mir das vernünftiger zu sein scheint als der "Murks". Dank Dir erstmal,war ne schwere Geburt aber das Kind ist da....
Hi, kurze Rückmeldung. Nach fixer Umarbeitung des Source auf Makefile und einigen "extern" die zugeführt werden mussten lief die Kiste auf Anhieb. Gruss, Christian
So..... mit dem Ram upload geht das Ganze doch schon deutlich entspannter vor sich als mit der EEPROM Stöpselei. Und bei einem reset bleibt auch alles im Ram erhalten und wird gestartet. NMI, Mode 2 Ints, alles klappt. Etwas nervig ist derzeit noch die fixe Größe der .bin datei da unnützer Müll übertragen wird aber aktuell fällt mir noch nichts Gescheites ein, wie ich sehr einfach das Ende des Datenstromes erkennen kann in dem ich die Dateilänge vorher sende ohne dass ich die Ascii Zeichenkette mit variabler Länge wiederin Binärzahlen wandeln muss.Gibt zwar ein paar umständliche Lösungen aber die gefallen mir alle nicht. Der Upload "Monitor" ist grad mal 150 Bytes. Wens interessiert, noch absolut suboptimal weil kein Fehlerababfangen etc aber es läuft. "st" sind die Startzeichen, die nacheinander erkannt werden müssen, "--" bläst irgendwelchen Einschalt-Einstöpsel-müll vorher raus, danach kommen die Daten fixer Länge. echo -n muss sein, da sonst ein Zeilentrenner mit gesendet wird.
1 | #!/bin/bash
|
2 | dd if=z80rom.bin of=z80rom4.bin ibs=4096 conv=sync |
3 | echo "Datei zum Target uebertragen..." |
4 | stty raw ospeed 9600 -F /dev/ttyUSB0 |
5 | echo -n "--st" > /dev/ttyUSB0 |
6 | cat z80rom4.bin > /dev/ttyUSB0 |
Etwas tricky ist die Verwendung von Variablen im Monitor Programm, da die nicht durch den Ram Upload überschrieben werden dürfen. Man muss sich weit weg genug legen, knapp unter "die Decke" des RAM. Eine ASM Lösung nur mit Registern wäre hier sicherlich optimaler gewesen.
Christian J. schrieb: > Etwas nervig ist derzeit noch die fixe Größe der .bin datei da unnützer > Müll übertragen wird aber aktuell fällt mir noch nichts Gescheites ein, So nervig können die paar Millisekunden doch nicht sein. Ansonsten: Lader für Intel-Hex einbauen. Das ist nicht so schwer, und Beispiele findes Du sicher massig im Netz. Da war noch was in der Pipeline.. Christian J. schrieb: > arbeite ich das heute abend auf Makefile > um, weil mir das vernünftiger zu sein scheint als der "Murks". "Murks" bezog sich nicht auf Script vs. Makefile. Du könntest ja auch im Script den Compiler für jede C-Datei einzeln aufrufen. Mit Murks meinte ich das hier:
1 | // Einbindung von weiteren Modulen.
|
2 | #include "driver.c" |
3 | |
4 | |
5 | void main() |
6 | {
|
7 | ....
|
8 | }
|
9 | |
10 | #include "interrupts.c" |
11 | |
12 | // An das Ende des Codes die Interrupt Routinen dran hängen
|
Und dann stehen die includes noch nicht mal am Anfang der Datei, wo man sie noch leicht finden könnte, sondern In der Mitte und am Ende. Wie heißt nochmal die Steigerung von Murks? ;-)
Leo C. schrieb: > Und dann stehen die includes noch nicht mal am Anfang der Datei, wo man > sie noch leicht finden könnte, sondern In der Mitte und am Ende. Wie > heißt nochmal die Steigerung von Murks? ;-) Tja, da denkst du wieder nicht soweit wie ich...... das habe ich ganz absichtlich gemacht, damit ich im Editor den .lst Code schnell wiederfinde und nicht mittendrin suchen muss, weil sich bei jedem Kompliervorgang die Fenster neu laden und der Cursor nach oben springt. Ich wollte die Ints hinten im Code liegen haben :-) Ich musste wegen dem Brenner unter Windows arbeiten und hatte folgendes Chaos auf dem Bildschirm: Brenneranwendung Notepad ++ putty Kompilier-Window zum Cubietruck wo die Z80 Sache abläuft noch ein putty zum Cubietruck für die USB Schnittstelle Terminalfenster für die Ausgabe ganz schön eng ;:-) // An das Ende des Codes die Interrupt Routinen dran hängen Stand auch da! >>Lader für Intel-Hex einbauen. Das ist nicht so schwer, und Beispiele >>findes Du sicher massig im Netz. Jede Menge aber die blasen die Code Size erst richtig auf durch scanf und jede Menge String Funktionen, schlucken ordentlich Memory im Ram und genau das habe ich nicht. Wobei ....15 Minuten mal eingelesen und reingeschaut in das Format... das schreibe ich auch selbst in 1/2 Tag. Nur Record Typ 00 wird verwendet. http://en.wikipedia.org/wiki/Intel_HEX
Wenigstens Record Type 01 solltest du unterstützen, sonst ist dein Ziel - nämlich das Dateiende zu erkennen - relativ schwierig. Geht übrigens auch ohne scanf und Stringfunktionen. Dann dürftest du den Lader in ein paar Bytes bekommen.
:
Bearbeitet durch User
Ja, ich habe mir das alles nochmal angeschaut. Problem ist, dass ich kein RTS/CTS habe, ich muss entweder on the fly decodieren oder eine ganze Zeile parsen und da ist nicht viel Zeit zwischen den Bytes (0,83ms = 3200 Maschinenzyklen, eher weniger), wenn ich Lib Funktionen benutze. Allerdings wird aus einer "5" auch durch Subtraktion von 0x48 auch eine \5, und BCD nach Binaer ist schnell gemacht. Codeprüfung evtl drauf verzichten. Den ganzen Satz auf einmal geht nicht, weil der das Ram füllt was ich ja brauche. Werde das Ganze heute mal in einer Statemachine codieren, wahrscheinlich in Asm. Leo ? Bist du da? Weisst Du ob der Compiler feststehende Ausdrücke hat, um zb die Adresse der Segmente (start und Ende) im Programmcode zu verarbeiten? Da würde einiges vereinfachen wie zb Prüfsummen über den RAM Bereich usw. Das hier scheint ja sowas zu sein: .globl l__INITIALIZER .globl s__INITIALIZER .globl s__INITIALIZED Sind die auch aus dem C Code erreichbar? Und gibt es davon noch mehr?
Christian J. schrieb: > Problem ist, dass ich kein RTS/CTS habe, XON/XOFF Software Handshake verwenden.
A. K. schrieb: > XON/XOFF Software Handshake verwenden. Das hat er ja auch nicht. Er denkt ja jetzt schon über den Lader, den er erst partout nicht haben und dann in einem halben Tag fertig haben wollte, so laut nach, bis irgend jemand so genervt ist, daß er ihm eine fertige Lösung präsentiert... Dabei könnte er ja durchaus mal eine Weile bei dem Binärlader bleiben, bis er ein besseres Gefühl für Codegrößen und Ausführungsgeschwindigkeiten bekommt. Ich bin nämlich der Meinung, daß es auch in C ohne Handschake gehen müßte. Frage mich allerdings, wie er auf 0,83ms/Zeichen kommt.
Leo C. schrieb: > Er denkt ja jetzt schon über den Lader, den er > erst partout nicht haben und dann in einem halben Tag fertig haben > wollte, so laut nach, bis irgend jemand so genervt ist, daß er ihm eine > fertige Lösung präsentiert... Nur mal kurz so ganz abseits der Technik: Das Internet besteht aus Leuten, die bereit sind das was sie machen anderen zu präsentieren. Ich kriege das alles (irgendwann) auch so hin, ohne hier darüber auch nur ein Wort zu verlieren. Ingenieure und Techniker gelten nicht gerade als "sozial kompetent" wie mir viele Jahre im Job zeigten wo ich genügend Spinner kennenlernte, die man bloss nicht aus dem Labor lassen sollte. Kein Thema, erledigt. Ein Mod kann den Thread gern zu machen. Ab hier gehts auch so weiter.... Die 0.83ms sind die reinen Maschinenzyklen, die vergehen, bis 9 x 1/9600 s Zeit vergangen ist für ein 8N1 protokoll. Grob über den Daumen gepeilt.
Wundere Dich doch bitte nicht Christian wenn hier Einer nach dem Anderen mitbekommt das Du Deine Probleme gerne gelöst bekommen hättest. :-) Ich habe vor ein paar Dave Dunfields Mon85 auf ein olles tschechisches Board mit 8080 Prozessor und 2 Mhz portiert. Ich weiß nicht ob u das weißt, ein 8080 ist der Vorgänger des Z80 und zeichnet sich dadurch aus, das ihm der komplette Schattenregistersatz, die Indexregister, der IM2 Interruptmode und etliche Z80 befehle fehlen (keine relativen Sprünge etc), der weiteren möchte der noch einen 2 Phasen Takt und 3 Betriebsspannungen, trotzdem hat das Ding nur eine geringfügig geringere Rechenleistung als ein Z80. CP/M2 läuft auch darauf. Der Monitor unterstützt jedenfalls bei dieser Gurke problemlos das laden von Intel-Hex Files, im meinem Falle über eine 8251 Uart. Da gibts kein Zeitproblem. Den Monitor gibts hier: https://github.com/phillipjohnston/8085-HI6130-Port/tree/master/Compiler/MON85 Evtl. möchtest Du da ja mal rein schauen, aber sei gewarnt, das Assembler File benutzt 8080 Mnemonics die nicht kompatibel zu Z80 Mnemonics sind, der Maschinencode ist aber für beide Prozessoren identisch. Es gibt aber auch jede Menge fertige Z80 Debug-Monitore die Leute schon ins Internet geladen haben, die haben nämlich kein Problem damit :-) und schwadronieren nicht nur drüber .. Du wurdest gewarnt: Nimm eine SIO ..nein Du wusstest das besser. Nimm IM2 .. nein..Du wusstest das besser. Die wird nahegelegt Dich nach der Source eines IHEX Loaders umzusehen.. nein, Du kannst das selber.. Dann mach mal.. Gruß, Holm
Naja Holm Man muß ihm schon zugestehen, dass er mit seinem Sturschädel schon weiter gekommen ist als manch andere Pussi hier im Forum und das ohne wirklich zu Ende durchdachtes Konzept. Namaste
:
Bearbeitet durch User
Leo C. schrieb: > Wenn man dieses Beispiel ohne Framepointer compiliert, wird beim Laden > des 2. Parameters das Zwischenergebnis in hl teilweise zerstört. (sdcc > 3.4.0) :( Der Bug wurde inzwischen bestätigt. Er tritt leider schon bei so etwas trivialem auf:
1 | int test(int pa, int pb) |
2 | {
|
3 | return pa*2 + pb; |
4 | }
|
Workaround: --fno-omit-framepointer
Leo C. schrieb: > Das hat er ja auch nicht. Brauchte er ja auch nicht. > Er denkt ja jetzt schon über den Lader, > den er erst partout nicht haben Was er jetzt hat ist das, was ich ihm geraten hatte. Einen einfachstmöglichen Loader, um die Brennerei los zu sein. Dem Hex-Loader kann er sich jetzt im RAM widmen, um den erst ins EPROM zu bannen, wenn fertig. > wollte, so laut nach, bis irgend jemand so genervt ist, daß er ihm eine > fertige Lösung präsentiert... Dabei hatte ich das schon beinahe, aber für SIO und nicht als C Programm. Aber psssst, nicht weitersagen. ;-) > Ich bin nämlich der Meinung, daß > es auch in C ohne Handschake gehen müßte. Vermute ich auch. Aber schaden tuts auch nicht und er will ja was zu tun haben. > Frage mich allerdings, wie er > auf 0,83ms/Zeichen kommt. 9600bd, 8 Bits pro Byte. Aber für BISYNC hätte er dann doch den Z80 SIO nehmen müssen. ;-)
:
Bearbeitet durch User
Tse....tse.... sowas habe ich schon 1987 mit dem 8085 mal gemacht, aber mit anderen Werkzeugen und dem Kenntnisstand von damals auch ich "drin" war. Das ist Jahre her. Upload vom C64 in das Ram des 8085 Systems. Es gibt noch einige Dinge nicht so erklärbar sind wie binäre Chaoszeichen nach dem Reset bei der Ausgabe über die Uart. Sporadisch, nicht ständig und immer in der ersten Zeile des Menu String Satzes. So als müsste die Uart sich erst "warmlaufen". Der Hex Uploder ist erstmal Konzept, verbal aufgeschrieben. Die Zeit reicht nicht um eine ganze Zeile zu bearbeiten bei 1 Byte Puffer Groesse des STI, wo es alle 0,9 ms mit einem neuen Bytes klingelt. Eas sei denn.... und dann verlassen wir den einfachen Bereich, ich mache die Zeicheneingabe über den Interrupt, spiele einen Puffer voll mit zwei Zeiger drauf, der dann vom Hauptprogramm abgearbeitet wird. Damit entkopple ich auf jeden Fall die Auswertung vom Datenstrom, da die Ints ja prior sind und jedes zeichen reingeholt wird. Endresultat soll ja mal sein, dass ein kleines Menü da steht. Einfache Befehle per Handeingabe aufzurufen sind und der Upload auch manuell aus Menüpunkt durchgeführt wird. Ein Erstellen im RAM und später brennen ins ROM ist nicht einfach, es warern unzählige Änderungen am Source nötig für die Adressen damit es aus dem RAM raus läuft, dam ich keine "Schlüsselwörter" kenne, die als Platzhalter fungieren. Da schüttel ich mir aber nicht aus dem Ärmel sonst muss da estmal ein Konzept machen, ein pflichteheft.
Christian J. schrieb: > des STI, wo es alle 0,9 ms mit einem neuen Bytes klingelt. Glaub ich dir nicht. Nicht bei 9600bd. Für die vorhin genannten 0,83ms bräuchtest du 12000bd.
:
Bearbeitet durch User
Über den Daumen! Fangen wir jetzt nicht an um die Mikrosekunden zu feilschen. 9600 baud = 9600 bit/s = 0,0001s / Bit 1 Byte 8N1 = 8 Bit Nutzlast + 2 Steuerbits = 10 Bits => 0,001s/byte = 1000 Bytes/s Maschinentakt 3.964.000 Takte /s = 0,25us/Takt => 3964 Takte zwischen den Bytes reicht für on-the-fly Decodierung aus aber NICHT um eine ganze Zeile komplett zu decodieren.
Christian J. schrieb: > => 0,001s/byte = 1000 Bytes/s Von hinten durch die Brust ins Auge. ;-) 9600bd bei 10 Bits sind 960 Bytes/s. > reicht für on-the-fly Decodierung aus Eben. Ok, das ist zunächst nicht absolut narrensicher, dafür wäre eine Adressvalidierung nötig, denn die könnte einen Übertragungsfehler haben.
:
Bearbeitet durch User
A. K. schrieb: > Von hinten durch die Brust ins Auge. ;-) > 9600bd bei 10 Bits sind 960 Bytes/s. Jaaaaaaaa.... Ok. Das ist auf jeden Fall machbar, wenn man etwas in Asm schreibt und vielleicht auf prüfsumme etc verzichtet. Der Abend ist noch lang..... > denn die könnte einen Übertragungsfehler haben. Hobby! Auf demSchreibtisch. Nicht Industrie! Keine Leitungen, die den Schrank verlassen daher auch keine Anwendung der Feldbus-Norm, die einen Zeitstempel+Frame+CRC etc verlangt :-)
Christian J. schrieb: > => 3964 Takte zwischen den Bytes Also mindestens 500 Befehle. Da geht einiges.
A. K. schrieb: > Christian J. schrieb: >> => 3964 Takte zwischen den Bytes > > Also mindestens 500 Befehle. Da geht einiges. Fetch = 3 T-Zyklen Decode = 3-4 T-Zyklen Execute = 2-5 T-Zyklen Eher deutlich weniger als 500. Worst Case eher 100-200. Oder eer kriegt einen Arduino davor mit 12 Mhz, der das fix macht..... naja, nicht so ganze Retro vielliecht.
Christian J. schrieb: > Fetch = 3 T-Zyklen > Decode = 3-4 T-Zyklen > Execute = 2-5 T-Zyklen Quark. Wo hast du das den aufgelesen? Einfache Befehle, die nur aus dem M1 Zyklus bestehen, brauchen 4 Takte. Fetch steckt in der ersten Hälfte vom M1, Decode in der zweiten (dem Refresh). Ausgeführt wird danach, währen dem M1 vom Folgebefehl.
:
Bearbeitet durch User
@A.K. Unbestätiogten Gerüchten zufolge, soll es bereits streng geheime Mikrocomputer geben, die den ganzen Klumpatsch an Chips auf EINEM EINZIGEN Chip haben! Mit 256kb Flassch, 80kb RAM, SIO, PIO, CTC, JTAG Debug Interface ... alles drauf! Kannst du dir das vorstellen? . . . . . :-)
Und was willst du mir damit sagen? Sorry, aber wie der Z80 tickt und timet weiss ich. Also das Original von Zilog aus den 70ern. Wer mal die Arbeitsweise eines Sinclar ZX80 analysiert hat, der kennt das, Sir Clive hatte da einige Tricks ausgenutzt. Und wenn du damit ausdrücken willst, es hätte in damaligen Mikroprozessoren keine Überlappung von F/D/X Phasen gegeben (= Pipelining), dann darf ich dich korrigieren. Es hat. Im 6502 auch.
:
Bearbeitet durch User
A. K. schrieb: > Und was willst du mir damit sagen? Das das Thema unangenehm wird, und er es gerne wechseln möchte... Im Anhang ist eine ein kompletter Intel-Hex-Lader in Assembler. Die Kommentare sind etwas spärlich, sollte aber reichen. Das Listing stammt ursprünglich aus einem Dissassembler. Hab den vor fast 30 Jahren auf ROM umgestellten ddtz auf dem Höhepunkt meines Retrofiebers ;) aus einem EPROM ausgelesen. Ein gedrucktes Listing hatte ich noch, so daß das ganz flott ging. Der Lader addiert zu jedem Byte einen Offset (normalerweise 0), überprüft untere und obere Ladegrenze und checkt natürlich an jedem Record-Ende die gleichnamige Summe.
Sehr kompakt...... ! bevor ich gleich pause mache .... Experimente mit gets und atoi sind zwar erfolgreich aber allein atoi bläst den Code um fast 500 Bytes auf um aus "2000" ein 0x2000 zu machen. printf schießt ihn auf 5300 Bytes hoch und scanf dabei sprengt die 8KB Grenze fast. Grundsätzlich aber ist mit minicom jetzt ein interaktiver Dialog möglich, mit Eingabe und Ausgabe. printf("a=?") scanf("%d",&a); printf("b=?") scanf("%d",&c); printf("a+b=&d",a+b); Läuft wie auf dem PC. Sehr nett...
Christian J. schrieb: > 8N1 Das funktioniert natürlich, zeigt aber sofort den Theoretiker. 8N2 ist wesentlich robuster und nur unwesentlich langsamer. (und ein Übertragungs "Protokoll" sind beide nicht)
Christian J. schrieb: > Tse....tse.... > > sowas habe ich schon 1987 mit dem 8085 mal gemacht, aber mit anderen > Werkzeugen und dem Kenntnisstand von damals auch ich "drin" war. Das ist > Jahre her. Upload vom C64 in das Ram des 8085 Systems. Ich nicht, ich hatte damals schon Z80. Ich habe aber im Wesentlichen die olle Karte repariert: http://www.tiffe.de/Robotron/TESLA/SM2138/P4070208s.JPG und wie man sieht ist due auch nicht so bestückt wie ursprünglich mal vorgesehen, die ziemlich vergriesgnaddelten Schaltpläne die ich da bekommen habe waren nur teilweise hilfreich. Das Ding stammt aus einem alten TESLA Terminal (CM7201 IMHO) das mal an einem tschechischen Nachbau einer PDP11 tätig war. Ich habe das eigntlich nur repariert um einem Freund aus dem Robotron-Forum die Reparatur des Terminals leichter zu machen, allerdings hat dieser in einem Anfalls von Aufräumwahn das Terminal entsorgt als ich fertig war. Die Karten von dem Ding hat er aber aufgehoben. Ich habe nun drüber nachgedacht Sohnemann das Ding zum Spielen auf den Tisch zu legen, mit einer 7Seg Anzeige und einer Hexa Tastatur dran, Allerdings ist Jemand aus dem Robotron-Frorum gerade dabei den LC80 neu aufzulegen, sowas wie die DDR Variante des "Mikroprofessors", ist wegen existierendem Handbuch sicher besser geeignet und mit Z80. > > Es gibt noch einige Dinge nicht so erklärbar sind wie binäre > Chaoszeichen nach dem Reset bei der Ausgabe über die Uart. Sporadisch, > nicht ständig und immer in der ersten Zeile des Menu String Satzes. So > als müsste die Uart sich erst "warmlaufen". Frequenzzähler an den Taktgenerator hängen... > > Der Hex Uploder ist erstmal Konzept, verbal aufgeschrieben. Die Zeit > reicht nicht um eine ganze Zeile zu bearbeiten bei 1 Byte Puffer Groesse > des STI, wo es alle 0,9 ms mit einem neuen Bytes klingelt. Eas sei > denn.... und dann verlassen wir den einfachen Bereich, ich mache die > Zeicheneingabe über den Interrupt, spiele einen Puffer voll mit zwei > Zeiger drauf, der dann vom Hauptprogramm abgearbeitet wird. Damit > entkopple ich auf jeden Fall die Auswertung vom Datenstrom, da die Ints > ja prior sind und jedes zeichen reingeholt wird. > > Endresultat soll ja mal sein, dass ein kleines Menü da steht. Einfache > Befehle per Handeingabe aufzurufen sind und der Upload auch manuell aus > Menüpunkt durchgeführt wird. > > Ein Erstellen im RAM und später brennen ins ROM ist nicht einfach, es > warern unzählige Änderungen am Source nötig für die Adressen damit es > aus dem RAM raus läuft, dam ich keine "Schlüsselwörter" kenne, die als > Platzhalter fungieren. > > Da schüttel ich mir aber nicht aus dem Ärmel sonst muss da erst mal ein > Konzept machen, ein pflichteheft. Christian, das Laden von Intel Hex Dateien funktioniert aus diesen 8 Bit Prozessoren seit über 20 Jahren ohne Zeitprobleme und damals liefen die Teile eher nicht mit 4Mhz. Gruß, Holm
Holm Tiffe schrieb: > Christian, das Laden von Intel Hex Dateien funktioniert aus diesen 8 Bit > Prozessoren seit über 20 Jahren ohne Zeitprobleme und damals liefen die > Teile eher nicht mit 4Mhz. Holm, nette Spielsachen, die du das hast..... da habe ich früher mit nem Luftgewehr drauf geschossen und geguckt wie das splittert :-) Sind sicher auf der Rückseite noch ein paar Gleichrichterröhren und Relais für die CPU? Wo ist denn der Anschluss für den Dampfdruck:-) Nee..... mache das schon mit etwas mehr Komfort, auch wenn es bisher nur ein 1-Wort Parser ist. Bald wird es schon mehr ... so wie einst Linus Trovalds nur einen Terminal schreiben wollte und dann entdeckte, dass er ein Betriebssystem geschrieben hat ... da fühlt man sich wie Kolumbus vor der Entdeckung Amerikas :-) Ich brauche kein Intel Hex mehr.... da wo ich hinfliege gibt es keine Strassen :-) Das Doofe ist nur, dass auch Backspace, Pfeile etc übertragen werden und bei gets() lässt sich da nix filtern, das sichere fgets gibt es nicht und es werden echos erzeugt. minicom hat als echtes Terminal keinen <CR> übertragungsmode.
Etwas nervig ist nur das "Krücken-Script", da ich noch versuche mit der Bash warm zu werden und sogar das "Galileo Shell programming" in der Nähe des Kopfkissens liegen habe. Allein schon der Umstand mit den Leerzeichen, die mal fehlen und mal zuviel sind. sleep kann nur 1s verzögern, ohne Verzögerung ist der PC zu schnell und es werden Zeichen verschluckt im riesigen 1-Byte Buffer der SIO. Vorteil ist nur: Es klappt, zusammen mti Geany, da drin angepassten Kompilieroptionen ist es ein sehr kurzer Weg von der Änderung zum Testen. 2 Klicks um genau zu sein.
1 | #!/bin/bash
|
2 | echo "---------------------------------" |
3 | echo "Datentrasnfer zum Z80" |
4 | echo "---------------------------------" |
5 | |
6 | echo "Stelle tty/USB0 auf 9600 baud ein....." |
7 | stty 9600 -crtscts -ixoff -F /dev/ttyUSB0 |
8 | |
9 | echo "Sende "load" Startsequenz...." |
10 | echo "load" > /dev/ttyUSB0 |
11 | sleep 1
|
12 | stat -c %s z80rom.bin > /dev/ttyUSB0 |
13 | sleep 1
|
14 | |
15 | echo "Uebertrage Daten...." |
16 | cat z80rom.bin > /dev/ttyUSB0 |
17 | sleep 1
|
18 | echo "Sende "start" Signal um Upload zu starten..." |
19 | sleep 1
|
20 | echo "start" > /dev/ttyUSB0 |
21 | echo "Fertig!" |
Christian J. schrieb: > Holm Tiffe schrieb: >> Christian, das Laden von Intel Hex Dateien funktioniert aus diesen 8 Bit >> Prozessoren seit über 20 Jahren ohne Zeitprobleme und damals liefen die >> Teile eher nicht mit 4Mhz. > > Holm, > > nette Spielsachen, die du das hast..... da habe ich früher mit nem > Luftgewehr drauf geschossen und geguckt wie das splittert :-) Sind > sicher auf der Rückseite noch ein paar Gleichrichterröhren und Relais > für die CPU? Wo ist denn der Anschluss für den Dampfdruck:-) > > Nee..... mache das schon mit etwas mehr Komfort, auch wenn es bisher nur > ein 1-Wort Parser ist. Du denkst scheinbar wirklich das Du da eine höhere Qualität erreicht hast? Einbildung ist auch eine Bildung, mancher Leute Einzigste.. :-) Komm mal wieder runter, in den ROMs der Platine steckt ein kompletter Debugger mit Assembler und Disassembler sowie u.A. auch ein IHEX Loader. Da darfst Du noch eine Weile dran herumschrauben. Auch für den 8080 Gibts C-compiler, BDS-C z.B. unter emuliertem CP/M. Den Menüchen da sieht zwar schön grün aus, ist aber nicht im Geringsten irgendwie beeindruckend. > Bald wird es schon mehr ... so wie einst Linus > Trovalds nur einen Terminal schreiben wollte und dann entdeckte, dass er > ein Betriebssystem geschrieben hat ... da fühlt man sich wie Kolumbus > vor der Entdeckung Amerikas :-) Joh..machmal. > > Ich brauche kein Intel Hex mehr.... da wo ich hinfliege gibt es keine > Strassen :-) > Ist recht. > Das Doofe ist nur, dass auch Backspace, Pfeile etc übertragen werden und > bei gets() lässt sich da nix filtern, das sichere fgets gibt es nicht > und es werden echos erzeugt. minicom hat als echtes Terminal keinen <CR> > übertragungsmode. Jaa, das ist einer der Gründe warum es Intel Hex gibt, brauchst Du aber nicht...ich weiß... Gruß, Holm
Christian J. schrieb: > Etwas nervig ist nur das "Krücken-Script", da ich noch versuche mit der > Bash warm zu werden und sogar das "Galileo Shell programming" in der > Nähe des Kopfkissens liegen habe. Allein schon der Umstand mit den > Leerzeichen, die mal fehlen und mal zuviel sind. > > sleep kann nur 1s verzögern, ohne Verzögerung ist der PC zu schnell und > es werden Zeichen verschluckt im riesigen 1-Byte Buffer der SIO. > > Vorteil ist nur: Es klappt, zusammen mti Geany, da drin angepassten > Kompilieroptionen ist es ein sehr kurzer Weg von der Änderung zum > Testen. 2 Klicks um genau zu sein. > >
1 | > #!/bin/bash |
2 | > echo "---------------------------------" |
3 | > echo "Datentrasnfer zum Z80" |
4 | > echo "---------------------------------" |
5 | > |
6 | > echo "Stelle tty/USB0 auf 9600 baud ein....." |
7 | > stty 9600 -crtscts -ixoff -F /dev/ttyUSB0 |
8 | > |
9 | > echo "Sende "load" Startsequenz...." |
10 | > echo "load" > /dev/ttyUSB0 |
11 | > sleep 1 |
12 | > stat -c %s z80rom.bin > /dev/ttyUSB0 |
13 | > sleep 1 |
14 | > |
15 | > echo "Uebertrage Daten...." |
16 | > cat z80rom.bin > /dev/ttyUSB0 |
17 | > sleep 1 |
18 | > echo "Sende "start" Signal um Upload zu starten..." |
19 | > sleep 1 |
20 | > echo "start" > /dev/ttyUSB0 |
21 | > echo "Fertig!" |
22 | > |
Oh Shit. Du überträgst wirklich Binärdaten über eine "nicht rohe" Schnittstelle. Laß Dir von Anderen erlären warum das keine gute Idee ist. Auf Sowas schieße ich normalerweise heute noch mit dem Luftgewehr. Dein Shellscript ist Scheiße. Es gibt Make und die dazugehörigen Makefiles die die Targets und deren Abhängigkeiten deklarieren. Diese Mechanismus wird sogar von den von Dir geliebten IDEs wie AVR-Studio benutzt, sollte einen Grund haben. Gruß, Holm
Lass gut sein, Holm. Das ist Beratungsresistenz vom allerfeinsten.
Holm Tiffe schrieb: > Dein Shellscript ist Scheiße. Es gibt Make und die dazugehörigen > Makefiles die die Targets und deren Abhängigkeiten deklarieren. Keine Ahnung von .... man muss nicht alles wissen und können. Makefiles gehören bei mir dazu.
Christian J. schrieb: > Holm Tiffe schrieb: >> Dein Shellscript ist Scheiße. Es gibt Make und die dazugehörigen >> Makefiles die die Targets und deren Abhängigkeiten deklarieren. > > Keine Ahnung von .... man muss nicht alles wissen und können. Makefiles > gehören bei mir dazu. Jawoll! Offensichtlich mußt DU nicht mal Wesentliches wissen, es reicht Dir Tatsachen einfach zu ignorieren. Ok, das ist auch eine Art Weltanschauung. Gruß, Holm
Christian J. schrieb: > .... man muss nicht alles wissen und können. Makefiles > gehören bei mir dazu. Es gibt einen Unterschied zwischen "nicht wissen" und "nicht wissen wollen". Für letzteres gibt es eigene Begriffe wie "Lernresistenz". Die meisten empfinden das als Schimpfwort. Du anscheinend nicht. 'nuff said, XL
Wär das nicht etwas für dich? "Der Kernel-Hacker Alan Cox hat ein unixoides Betriebssystem für den 8-Bit-Prozessor Zilog Z80 erstellt." http://www.golem.de/news/fuzixos-alan-cox-zeigt-betriebssystem-fuer-8-bit-cpu-z80-1411-110302.html
:
Bearbeitet durch User
Läuft wohl nur auf Z180 oder als -lite Z80 mit Banked memory :-( UZI180 makes extensive use of the Memory Management (MMU) of the Z180 core to provide as much process isolation as possible with the chip. Since the MMU granularity is 4k, this establishes the basic process structure. The top 4k of logical address space (one MMU slice) is defined as Common1 memory space and contains critical routines that either must always be resident in Minimal Requirements -------------------- - Z80 processor - 128K memory (the kernel itself wants between 32 and 40K R/O and about 8-16K R/W depending upon the configuration. - Some kind of memory banking giving a common area and multiple banks - A storage device, preferable hard disk or SD card or similar - A timer interrupt (but you can sort of run single user with just a serial / keyboard irq) In the ideal world 256K of RAM or more An RTC 16K flexible memory banking "....... Doch ganz ernst gemeint ist die Frage nicht, denn Fuzix bedient keinesfalls den Consumer- oder Desktop-Bereich, sondern richtet sich eher an Entwickler des in letzter Zeit vor allem im Enbedded-Bereich wiederentdeckten Zilog Z80 – ein 8-Bit-Mikroprozessor, der von der Firma Zilog Mitte der siebziger Jahre entwickelt wurde...."
Hmm....... das nächste Projekt? 512kB RAM. http://www.zcontrol.narod.ru/diagrams/ZramBankSwitch.pdf Grad durch die Sourcen durch ... ist noch sehr "rudimentär" aber alles für den SDCC, kompiliert so durch. Nur ein referenz Schaltplan wäre gut, Flopy usw scheint es auch zu geben. Allerdings würde ich beim nächsten Mal eine Möglichkeit vorsehen Software Breakpoints zu setzen und einen Single Step Mode. Den vermisse ich doch etwas und missbrauche RST dafür derzeit, um den Monitor und das wachsende Intel-Hex Decoding zu debuggen.
Bei folgendes Thema habe ich leider nicht genug Kenntnissem, bzw hatte ich damit noch nie zu tun: Ich benutze derzeit miniciom als Terminal. minicom schickt jeden Tastendruck an den Z80 und je nach Einstellung echot dieser es oder minicom macht es. Ich möchte den Monitor doch schon noch etwas ausbauen und habe mir auch den Tiny Basic Interpreter besorgt für den AVR, der sich sicherlich anpassen lassen wird. mincom soll bzw geht das überhaupt, dass der Z80 Steuerzeichen schickt, wie Cursor Move, Backspace usw und minicom tut genau das? zb einen blinkenden Cursor darstellen durch ein/aus eines _ usw? Die Eingabe soll genau der eines PC gleichen und mit EOL wird sie übernommen, an einen Parser gereicht und der decodiert dann den Befehl für den Z80 und die Parameterliste. Auf die Weise müsste sich eine erweiterbare Struktur bauen lassen die einfache Dinge erledigt und vielleicht später auch mal ein ganzes Basic Programm eingeben lässt bzw es auch abspeichert, da ich als "Floppy" ein 64K E2PROM im Auge habe, angesteuert durch einen AVR. Ginge das mit minicom? Oder mit was anderem?
Terminal-Programme unterstützen üblicherweise die ANSI Terminalemulation, die sich aus der Definition der DEC VT100 Terminals ableitet. Also mit Backspace/DEL, Cursorsteuerung etc.
Hi, lese grad die Scancodes aus, also was der Z80 sieht wenn ich auf den Tasten klimper... "Pfeil Links" = "D" = 0x44, wie unterscheidet man das denn dann? Kann allerdings nicht sehen ob zb 2 zeichen schnell nacheinander kommen, nur das letzte wird angezeigt und da sind die Codds für die beiden gleich. ANSI ist eingestellt.
Da kommen mehrere Zeichen, eine ESC Sequenz. Scancodes im herkömmlichen sinne sind das auch nicht,Scancodes liefert eine heute übliche Tastatur und erzählt damit welche Tastennummer gedrückt oder losgelassen wurde. Buchstaben/Zahlen etc werden vom Rechner den Scancodes erst später zugeordnet. Du mußt Folgen von Zeichen die mit ESC beginnen abfangen und einen Timeout-Mechanismus implementieren. Gruß, Holm
Das wird sowas wie <ESC>[D gewesen sein. Das was deine Linux-Konsole sowieso schon liefert. Probier mal cat >1 od -c 1 http://www.termsys.demon.co.uk/vtansi.htm http://en.wikipedia.org/wiki/ANSI_escape_code
:
Bearbeitet durch User
Christian J. schrieb: > Ich möchte den Monitor doch schon noch etwas ausbauen und habe mir auch > den Tiny Basic Interpreter besorgt für den AVR, der sich sicherlich > anpassen lassen wird. Sorry, ich habe das Szenario um Z80, AVR und Minicom noch nicht ganz verstanden. Was hat der AVR mit dem Z80 zu tun? Soll der AVR mit dem PC kommunizieren und von dort via Terminal-Emulation Befehle entgegennehmen und diese dann an den Z80 weitergeben? Ich habe da mal eine Art Mini-Curses für den AVR geschrieben, siehe MCURSES. Mit Hilfe dieser Lib werden über ein paar Dutzend Funktions-/Cursor- und andere Tasten "verstanden". Ausserdem kann man damit das Terminal (und den Cursor) gezielt, ansteuern, Positionen setzen, Scrollen (vorwärts und rückwärts), Attribute setzen usw. - halt alles, was ein VT102, VT200, VT320 oder VT400 so "versteht". EDIT: Im dazugehörenden Thread Beitrag "MCURSES - Mini Curses Bibliothek für Mikrocontroller" steht auch etwas zur Zusammenarbeit mit minicom, insb. was die Hardware-Flow-Control Problematik betrifft.
:
Bearbeitet durch Moderator
Frank M. schrieb: > Was hat der AVR mit dem Z80 zu tun? Soll der AVR mit dem PC > kommunizieren und von dort via Terminal-Emulation Befehle entgegennehmen > und diese dann an den Z80 weitergeben? Nein, ich habe mir nur C Sourcen heraus gesucht, wie zb einen Basic Interpreter, der nur einen AVR, eine RS232 hat und damit über ein Terminal zu bedienen ist, so als hacke man in einen C64 Basic ein. Da C portierbar ist brauhce ich nur die I/O Routinen umzuleiten und da keine Hardware benötigt wird müsste das auf dem Z80 auch laufen. Das mit den Esc Sequencen habe ich grad gelesen, der Stndard hat sich wohl auch mehrfach geändert seit den XT tastaturen. Schwierig, dann müsste ich zeichenweise durch die Eingabe durch und nicht mehr einfach bis zum ersten Leerzeichen. Frank, ich schaue mir das mal an... muss erstmal einen Überblick kriegen. Aktuell gehts nur darum: Z80 nimmt zeichenweise entgegen uns echot das so, dass man wie an einem normalen Terminal arbeitet. EOL (CR) sendet den String ab. Bewegt der User die Pfeiltasten muss natürlich der Zeichenpointer auch verschoben werden. Im Buffer soll immer das stehen, was auch in der sichtbare Zeile steht.
A. K. schrieb: > Das wird sowas wie <ESC>[D gewesen sein. Das was deine Linux-Konsole > sowieso schon liefert. Probier mal > cat >1 > od -c 1 > > http://www.termsys.demon.co.uk/vtansi.htm > http://en.wikipedia.org/wiki/ANSI_escape_code Pfeil links = ^[[D Pfeil recht = ^[[A usw.
Christian J. schrieb: > Da C > portierbar ist brauhce ich nur die I/O Routinen umzuleiten und da keine > Hardware benötigt wird müsste das auf dem Z80 auch laufen. Nunja, bedingt mag das funktionieren. > Das mit den Esc Sequencen habe ich grad gelesen, der Stndard hat sich > wohl auch mehrfach geändert seit den XT tastaturen. Das hat weniger mit den XT-Tastaturen eines PCs, sondern eher mit der Entwicklung des Terminal-Standards VT100->VT102->VT200->VT320->VT400 zu tun. DAS waren die Terminals der 80er! Mit PC-Tastaturen hatten die herzlich wenig zu tun. Damals gabe es für PCs auch schon einige wenige Terminal-Emulationen, welche die oben genannten Standards auch (mehr schlecht als recht) emulieren konnten. Jedoch mussten immer wieder Abstriche gemacht werden wegen des doch sehr abweichenden Tastatur-Layouts (z.B. Anordnung/Funktion der 6 EDIT-Tasten oberhalb der Cursor-Tasten, Keypad-Tasten PF1 bis PF4, VT200-Funktionstasten F6 bis F22). > Schwierig, dann > müsste ich zeichenweise durch die Eingabe durch und nicht mehr einfach > bis zum ersten Leerzeichen. Das erledigt MCURSES für Dich. Es interpretiert die von der Tastatur gesandten ESCAPE-Sequenzen und setzt diese in eine Konstante um, z.B. KEY_DOWN. Beispiel (kleiner Zeileneditor):
1 | uint8_t ch = getch (); |
2 | |
3 | switch (ch) |
4 | {
|
5 | case 'a': show_address(); break; |
6 | case 'v': show_value(); break; |
7 | case KEY_LEFT: go_left(); break; |
8 | case KEY_RIGHT: go_right(); break; |
9 | case KEY_UP: show_last_line(); break; |
10 | case KEY_DOWN: show_next_line(); break; |
11 | }
|
Du erhältst also nicht nur einzelne aphanumerische Zeichen, sondern auch direkt feste Codes für Funktionstasten. Um die Decodierung der Escape-Sequenzen brauchst Du Dich nicht mehr zu kümmern - das erledigt MCURSES für Dich. > Frank, ich schaue mir das mal an... muss erstmal einen Überblick > kriegen. MCURSES läuft nicht nur auf AVRs, sondern auch auf auf UNIX/Linux. Der Source ist modular auf Portabilität für andere Plattformen ausgelegt. Wenn Du das I/O-Interface anpasst (siehe phyio-Funktionen), sollte es auch auf einem Z80 laufen, da es auf minimalen Ressourcen-Verbrauch getrimmt wurde. > Aktuell gehts nur darum: > > Z80 nimmt zeichenweise entgegen uns echot das so, dass man wie an einem > normalen Terminal arbeitet. EOL (CR) sendet den String ab. Bewegt der > User die Pfeiltasten muss natürlich der Zeichenpointer auch verschoben > werden. Im Buffer soll immer das stehen, was auch in der sichtbare Zeile > steht. Ist mit MCURSES problemlos machbar. Und noch einiges mehr. Du musst es "nur" auf den Z80 portieren. Hier noch ein kleines Demo-Programm als Filmchen: http://www.mikrocontroller.net/wikifiles/e/ed/Mcurses.avi
:
Bearbeitet durch Moderator
Trotzdemm zum Verständnis, der Code ist ja auch etwas größer. RX/TX Z80 <--------> PC (minicom) Tastendrücke gehen direkt zum Z80 durch. gets() echot sie allein, getchar nicht. gets erkennt auch Pfeiltasten und Backspace! D.h. minicom fährt Cursor zurück uw. Aber im Puffer ist Müll drin, s.h. gebe ich ein resed, löassche das d dann mit BS und mache ein t draus steht im Buffer BS usw mit drin. Ärgerlich. Ich habe 1. getchar und putchar für meine I/0 2. buffer[80] für die Zeichen. Grundprinzip do { Hole Zeichen vom PC Werte aus und bearbeite Puffer Echo Zeichen zurück } while (c!=EOL) // Bis Return Eingaben beendet - Dann Parser aufrufen um String von Parameter aubzutrennen - Übergabe Kommando und Parametzer an richtige Unterfunktion Wo kann ich in diesem Prinzip jetzt Deine Routinen einbauen?
Christian J. schrieb: > Wo kann ich in diesem Prinzip jetzt Deine Routinen einbauen? Das passt schon alles. Du passt in mcurses.c die phyio-Funktionen unter Einsatz von putchar() und getchar() an und benutzt dann in Deiner Anwendung: addch() statt putchar() getch() statt getchar() addstr() statt puts() move() zum Bewegen des Cursors attrset() Zum Setzen von Attributen, wie Reverse, Farbe usw. Ein simples Beispiel:
1 | #include "mcurses.h" |
2 | |
3 | int main () |
4 | {
|
5 | unsigned char ch; |
6 | |
7 | initscr(); // init mcurses |
8 | |
9 | move (11, 10); // Cursor an Stelle y=11, x=10 setzen |
10 | addstr ("Hello, World!"); |
11 | |
12 | while ((ch == getch()) != KEY_DOWN) // Warten, bis Cursor runter gedrückt wird |
13 | {
|
14 | ;
|
15 | }
|
16 | |
17 | endwin(); // end mcurses |
18 | return 0; |
19 | }
|
Vielleicht mögen Dir solche Funktionsnamen wie initscr() und endwin() merkwürdig vorkommen. Ich persönlich hätte sie lieber anders genannt. Sie sind aber an die (n)curses-LIB von BSD, SYSV-UNIX bzw. Linux aus den 80er/90er angelehnt, siehe auch: http://de.wikipedia.org/wiki/Curses So findet sich so manch ein UNIX-Programmierer hier leichter wieder ;-) P.S. Das auf Wikipedia aufgeführte Beispiel-Programm benutzt printw() statt addstr(). printw() ist für die formatierte Ausgabe gedacht - analog zu printf(), ist aber wg. knapper Ressourcen auf dem µC nicht umgesetzt. Wikipedia hätte hier besser auch addstr() im Beispiel-Programm benutzen sollen, da von der Formatierungs-Fähigkeit von printw() im Beispiel überhaupt kein Gebrauch gemacht wird.
:
Bearbeitet durch Moderator
Hallo Frank, dank Dir erstmal ganz herzlich für deine vielen Infos und dass du das so ausführlich erklärt hast. Werde heute nachmittag mal einige Tests machen. Eine Frage trotzdem noch, wenn ich deinen Routinensatz anschaue: Muss ich mir selbst eine Schleife schreiben, die die Zeichen einzeln entgegen nimmt, diese auswertet und entsprechend etwas zurück gibt? Die schaut ob es ein Pfeil ist und dann den Befehl gibt den Coursor zu versetzen, die ein BS erkennnt und den Pointer auf den Buffer rück setzt? Oder ist das schon "fertig"? Ziel ist ja in einem Satz formuliert: Im Puffer soll exakt das stehen, was der User am Terminal eingetippt hat. Und wenn er sich 10 Mal vertippt hat und es korrigiert hat, soll die Endversion drin stehen aber keinerlei Sonderzeichen.
Christian J. schrieb: > Im Puffer soll exakt das stehen, was der User am Terminal eingetippt > hat. Und wenn er sich 10 Mal vertippt hat und es korrigiert hat, soll > die Endversion drin stehen aber keinerlei Sonderzeichen. Nein, diese Funktionalität ist nicht umgesetzt (sie entspricht eher der readline-Bibliothek von Linux), ist aber auch nicht schwierig zu programmieren. Was Du möchtest, ist ein Ein-Zeilen-Mini-Editor. Du übergibst einen Buffer und bekommst den gefüllt wieder zurück - also etwas entsprechend der stdio-Funktion gets(). Den Mini-Editor dafür hab ich ruckzuck zusammengestellt. Ich poste hier heute nachmittag den entsprechenden Code bzw. lege den direkt im MCURSES-Artikel ab.
So, die Funktion getnstr() ist fertig. Auch sie ist angelehnt an die entsprechende Curses-Funktion, siehe auch: http://linux.die.net/man/3/getstr Syntax: void getnstr (char * str, uint8_t maxlen) Einlesen eines Strings str, bis CR (ENTER) gedrückt wird - mit Editierfunktionen. maxlen ist dabei die maximale Eingabelänge inklusive(!) des terminierenden '\0'. Will man also maximal 80 Zeichen Input haben, muss der Buffer als buf[81] definiert sein und maxlen == 81 sein - analog zur stdio-Funktion fgets(). Weiteres Makro (kommt dann nach mcurses.h): void mvgetnstr (uint8_t y, uint8_t x, char * str, uint8_t maxlen) Hier wird erst der Cursor positioniert, dann geschieht die Eingabe. Beispiel:
1 | #include "mcurses.h" |
2 | |
3 | int
|
4 | main () |
5 | {
|
6 | char buf[81]; |
7 | |
8 | initscr (); // init mcurses |
9 | move (10, 10); // Eingabe in Zeile 11, Pos 11 |
10 | getnstr (buf, 81); // String einlesen |
11 | mvaddstr (15, 10, buf); // Eingabe in Zeile 16 wieder ausgeben |
12 | endwin (); // end mcurses |
13 | }
|
Mit folgende Sondertasten kann die Eingabe editiert werden: Pos1 - KEY_HOME: Sprung an den Anfang des Eingabebuffers Ende - KEY_END: Sprung an das Ende des Eingabebuffers Cursor links - KEY_LEFT: Cursor links Cursor rechts - KEY_RIGTH: Cursor rechts Backspace - KEY_BACKSPACE: Zeichen links vom Cursor löschen Entf - KEY_DC: Zeichen unter dem Cursor löschen Reicht Dir das? Für Einfüge-/Überschreibenmodus habe ich jetzt keine Lust gehabt. Eingegebene Zeichen werden daher immer eingefügt. Die Funktion getnstr() hängt im Anhang an - schon mal zum Anschauen. Ich werde die Download-Datei mcurses.zip im Laufe des heutigen Tages aktualisieren.
:
Bearbeitet durch Moderator
Frank M. schrieb: > Reicht Dir das? Für Einfüge-/Überschreibenmodus habe ich jetzt keine > Lust gehabt. Eingegebene Zeichen werden daher immer eingefügt. Mundgerechter gehts doch nicht ! :-) Dank dir ganz herzlich, wird heute umgesetzt ! Die Ringpuffer werde ich allerdings wohl an eine INT Routine anbinden, da ich die Z80 Uart puffern will, damit kein Zeichen mehr verloren geht bei Bearbeitungsschritten bzw Decodierung der Strings. Habe schon alles AVR maessige rausgeworfen und auch die Linux Funktionen, die ich gefunden habe. Nur getchar, putchar und mehr habe ich nicht was ich dem Code anbieten kann. Die hier sind vermutlich nicht erforderlich und können leer bleiben, gibt es keine Aequivalente bei mir zu. Ok, mal schauen wie es sich so durchkompiliert mit dem sdcc. /*---------------------------------------------------------------------- ------------------------------------------------------------------------ ----- * PHYIO: set/reset nodelay *----------------------------------------------------------------------- ------------------------------------------------------------------------ ---- */ static void mcurses_phyio_nodelay (uint8_t flag) { int fd; int fl; fd = fileno (stdin); if ((fl = fcntl (fd, F_GETFL, 0)) >= 0) { if (flag) { fl |= O_NDELAY; } else { fl &= ~O_NDELAY; } (void) fcntl (fd, F_SETFL, fl); mcurses_nodelay = flag; } } /*---------------------------------------------------------------------- ------------------------------------------------------------------------ ----- * PHYIO: flush output *----------------------------------------------------------------------- ------------------------------------------------------------------------ ---- */ static void mcurses_phyio_flush_output () { fflush (stdout); }
Christian J. schrieb: > * PHYIO: set/reset nodelay > * PHYIO: flush output Schau Dir besser die AVR-Version der phyio-Funktionen an und passe diese dann an. Du hast hier nämlich die Linux-/Unix-Versionen gepostet. Diese erscheinen für einen Nicht-Unixer erstmal wesentlich komplexer. mcurses.c ist da folgendermaßen aufgebaut:
1 | #ifdef unix // UNIX-/Linux-Version
|
2 | |
3 | * PHYIO: init |
4 | * PHYIO: done |
5 | * PHYIO: putc |
6 | * PHYIO: getc |
7 | * PHYIO: set/reset nodelay |
8 | * PHYIO: flush output |
9 | |
10 | #else // AVR-version
|
11 | (Wiederholung der phyio-Funktionen fuer AVR) |
12 | #endif
|
13 | |
14 | (Rest ist plattformunabhaengig) |
Du solltest das jetzt folgendermaßen erweitern:
1 | #ifdef unix // UNIX-/Linux-Version
|
2 | (Unix-phyio-Funktionen) |
3 | #elif defined (DEIN_Z80_KRITERIUM) // Z80 Version
|
4 | (Z80-phyio-Funktionen) |
5 | #else // AVR-version
|
6 | (AVR-phyio-Funktionen) |
7 | #endif
|
8 | (Rest ist plattformunabhaengig) |
Dafür kopierst Du Dir am besten die AVR-phyio-Funktionen und passt diese an. Sollte Deine Portierung dann erfolgreich sein, kann ich die neue mcurses-LIB, welche auch den Z80 unterstützt, gerne wieder zum Artikel als Download beifügen.
Christian J. schrieb: > Mundgerechter gehts doch nicht ! :-) Dank dir ganz herzlich, wird heute > umgesetzt ! Die neue Version ist online, siehe MCURSES. Solltest Du Fragen/Anregungen/Probleme bei der Portierung haben, empfehle ich dafür den Thread: Beitrag "MCURSES - Mini Curses Bibliothek für Mikrocontroller" Denn hier wirds allmählich offtopic.... ;-)
Christian J. schrieb: > Weil der Entwicklungsleiter nichts anderes konnte und Angst hatte > von einem Jüngeren "überflügelt" zu werden. Das ist kein µC-Buden spezifisches Problem und einer der häufigsten Hintergründe von Mobbing, sogar in Sozialberufen. Die Ursache dafür ist im ehemals satten Arbeitskräftemarkt zu suchen, nachdem es möglich wurde. (langjärige) Mitarbeiter nicht mehr weiterzuqualifizieren sondern durch jüngere scheinbar qualifiziertere Mitarbeiter nach dem Hire & Fire Prinzip zu ersetzen. ..... Namaste
Frank M. schrieb: > Die neue Version ist online, siehe MCURSES. Auch das zip? Da steht noch 2011..... >>Du solltest das jetzt folgendermaßen erweitern: Ich habe stur gelöscht :-) Alles weg was zuviel ist.
hallo frank, ich habe deinen code erstmal beiseite gelegt, da mir der kopf raucht und ich alles durcheinander werfe. da muss sehr viel geändert werden, da der Z80 ja eine CPU ist, alles andere ist individuell. Und ich brauche auch nur eine Sache, nämlich getch. Du holst Zeichen im Interrupt, ich aktuell noch per Hand. Trotzdem steige ich noch nicht hinter das Prinzip, habe alles erstmal bei mir gelöscht und auf wenige Zeilen reduziert um mit diesem minicom klar zu kommen. gets sendet echos und macht es "richtig" aber getchar nicht, da muss ich alles per hand machen. do { ch = getchar(); putchar(ch); } while (ch!=0x0d); printf("\r\nFertig"); Man sollte annehmen, dass ich dann genau das sehe was ich tippe aber da fängt es schon an. Backspace löscht keine Zeichen sondern ist wie Cursor verschieben. Pfeiltasten laufen hoch und runter im Terminal: ok. Up und Down muss ich eh unterbinden bei einem Einzeilen Editor. Lese ich Pfeiltaste als hex aus erhalte ich immmer 0x1b 0x51 als Code, egal welche ich tippe. Wieviel Bytes sind das überhaupt? 2 oder 3? Pos1 und Ende erzeugen "F"'s. Kann aber sein, dass zeichen verschluckt werden bei mir, printf ist schon sehr zeitintensiv. Bevor ich da nicht durch die Grundlagen durchsteige unddie Zeicheneingabe auf einen Interrupt lege in einen Puffer hat es keinen Zweck da weiter zu machen. Das gibt Murks. Und jetzt ist Ende... Kopffestplatte ist voll.
Entschuldigt falls das hier falsch sein sollte. Ist das Board hier geeignet für ein Retro PC MX98726 + 80186 MACRONIX Demo Board A24/2923 Danke schon mal.
Christian J. schrieb: > ich habe deinen code erstmal beiseite gelegt, da mir der kopf raucht und > ich alles durcheinander werfe. Ja, merkt man. > da muss sehr viel geändert werden, da der > Z80 ja eine CPU ist, alles andere ist individuell. Nein, da muss gar nicht viel geändert werden. > Und ich brauche auch > nur eine Sache, nämlich getch. Du holst Zeichen im Interrupt, ich > aktuell noch per Hand. Das spielt überhaupt keine Rolle, wie die Zeichen geholt werden. Du musst nur die phyio-Funktionen anpassen, mehr nicht. Aber das sagte ich ja bereits. Hier eine Minimalversion:
1 | /*---------------------------------------------------------------------------------------------------------------------------------------------------
|
2 | * PHYIO: init
|
3 | *---------------------------------------------------------------------------------------------------------------------------------------------------
|
4 | */
|
5 | static void |
6 | mcurses_phyio_init (void) |
7 | {
|
8 | // Deine UART Initialisierung, falls notwendig.
|
9 | }
|
10 | |
11 | /*---------------------------------------------------------------------------------------------------------------------------------------------------
|
12 | * PHYIO: done
|
13 | *---------------------------------------------------------------------------------------------------------------------------------------------------
|
14 | */
|
15 | static void |
16 | mcurses_phyio_done (void) |
17 | {
|
18 | // Kann leer bleiben.
|
19 | }
|
20 | |
21 | /*---------------------------------------------------------------------------------------------------------------------------------------------------
|
22 | * PHYIO: putc
|
23 | *---------------------------------------------------------------------------------------------------------------------------------------------------
|
24 | */
|
25 | static void |
26 | mcurses_phyio_putc (uint8_t ch) |
27 | {
|
28 | putchar (ch); |
29 | }
|
30 | |
31 | /*---------------------------------------------------------------------------------------------------------------------------------------------------
|
32 | * PHYIO: getc
|
33 | *---------------------------------------------------------------------------------------------------------------------------------------------------
|
34 | */
|
35 | static uint8_t |
36 | mcurses_phyio_getc (void) |
37 | {
|
38 | uint8_t ch; |
39 | |
40 | ch = getchar (); |
41 | |
42 | return (ch); |
43 | }
|
44 | |
45 | /*---------------------------------------------------------------------------------------------------------------------------------------------------
|
46 | * PHYIO: set/reset nodelay
|
47 | *---------------------------------------------------------------------------------------------------------------------------------------------------
|
48 | */
|
49 | static void |
50 | mcurses_phyio_nodelay (uint8_t flag) |
51 | {
|
52 | // kannst Du erstmal leer lassen, für Dich nicht relevant
|
53 | }
|
54 | |
55 | /*---------------------------------------------------------------------------------------------------------------------------------------------------
|
56 | * PHYIO: flush output
|
57 | *---------------------------------------------------------------------------------------------------------------------------------------------------
|
58 | */
|
59 | static void |
60 | mcurses_phyio_flush_output () |
61 | {
|
62 | // leer lassen
|
63 | }
|
> Trotzdem steige ich noch nicht hinter das Prinzip, habe alles erstmal > bei mir gelöscht und auf wenige Zeilen reduziert um mit diesem minicom > klar zu kommen. gets sendet echos und macht es "richtig" aber getchar > nicht, da muss ich alles per hand machen. mcurses benutzt für die Plattformunabhängigkeit ein Mini-Schichtenmodell: - Unabhängige Funktionen wie getch() und addch() usw. - Plattformabhängige PHYIO-Funktionen wie getchar(), putchar Alles einfach rauszuschmeissen, was Du nicht verstehst, ist der komplett falsche Weg. Offenbar hast Du Probleme, systematisch eine Aufgabe zu lösen. > > do > { > ch = getchar(); > putchar(ch); > } while (ch!=0x0d); > printf("\r\nFertig"); Genau das macht macht getnstr() - nur auf der mcurses-Ebene und nicht auf der Low-Level-PHYIO-Ebene. Auf der Low-Level-Ebene bist Du verratzt und verkauft, wenn man Cursor-Tasten etc. drückt. Das klappt nicht! > Man sollte annehmen, dass ich dann genau das sehe was ich tippe aber da > fängt es schon an. Backspace löscht keine Zeichen sondern ist wie Cursor > verschieben. Pfeiltasten laufen hoch und runter im Terminal: ok. Up und > Down muss ich eh unterbinden bei einem Einzeilen Editor. Ist doch klar: Die Sondertasten senden ESCAPE-Sequenzen, die Du nicht auswertest, sondern einfach in Deinem Buffer abspeicherst. Das klappt nicht! Entweder Du machst es richtig oder Du lässt es. Wenn Du alles rausschmeisst, was Du nicht verstehst, ist das alles zum Scheitern verurteilt. Also bohre - so wie gestern skizziert - die Struktur auf: #ifdef unix #elif defined (DEIN_Z80_KRITERIUM) #else // AVR #endif und knalle da einfach die PHYIO-Routinen, die ich oben aufgeführt habe, in den Z80-Bereich! Was ist da so schwierig? Ich habe irgendwie das Gefühl, dass Du mal gerne Hinweise anderer ignorierst und Dich dabei dann in einer Sackgasse verrennst. Ja, ich kenne den SDCC-Thread. Dann musst Du oben in mcurses.c noch dort, wo die plattformabhängigen includes geschehen, noch die Z80-Anpassungen machen:
1 | #ifdef unix
|
2 | #include <termio.h> |
3 | #include <fcntl.h> |
4 | #define PROGMEM
|
5 | #define PSTR(x) (x)
|
6 | #define pgm_read_byte(s) (*s)
|
7 | #elif defined (DEIN_Z80_KRITERIUM) // NEU
|
8 | #define PROGMEM // NEU
|
9 | #define PSTR(x) (x) // NEU
|
10 | #define pgm_read_byte(s) (*s) // NEU
|
11 | #else
|
12 | #include <avr/io.h> |
13 | #include <avr/pgmspace.h> |
14 | #include <avr/interrupt.h> |
15 | #endif
|
> Lese ich Pfeiltaste als hex aus erhalte ich immmer 0x1b 0x51 als Code, > egal welche ich tippe. Wieviel Bytes sind das überhaupt? 2 oder 3? Pos1 > und Ende erzeugen "F"'s. Kann aber sein, dass zeichen verschluckt werden > bei mir, printf ist schon sehr zeitintensiv. Google nach "vt100 escape" und Du wirst jede Menge Listen finden, wo die Tasten erklärt sind. Aber ich glaube nicht, dass Du in der Lage bist, Dein Problem auf dieser unteren Ebene zu lösen. Deshalb habe ich Dir mcurses angeboten. Für die Entwicklung eines Monitors musst Du sowieso auf dem Bildschirm frei positionieren können. Ich rate Dir daher, sämtliche Benutzer-Interaktionen mit mcurses zu machen - nicht nur die Kommando-Eingabe. > Bevor ich da nicht durch die Grundlagen durchsteige unddie > Zeicheneingabe auf einen Interrupt lege in einen Puffer hat es keinen > Zweck da weiter zu machen. Das gibt Murks. Du musst überhaupt keinen Interrupt einbauen! Ich habe Dir gestern schon gesagt, dass Du putchar() und getchart() in die Phyio-Funktionen einbauen musst - mehr nicht! Höre doch einfach mal zu! Du brauchst die untere Ebene und die Escape-Sequenzen gar nicht zu kennen, wenn Du mcurses nutzt! Lass den mcurses-Source im Ganzen stehen! Wirf nichts raus, sondern erweitere den Source! Nur so kann ein Software-Paket wachsen. Ein Paket zu schnappen und dann rigoros abzuspecken ("ich brauche nur getch()!") ist der falsche Weg, denn damit löst sich alles in Luft auf und es bleibt nichts lauffähiges übrig. Und jetzt am Ende noch 3 Bitten: - Lies dieses Posting 3 mal - Lies dieses Posting 3 mal - Lies dieses Posting 3 mal
:
Bearbeitet durch Moderator
Christian J. schrieb: > ich habe deinen code erstmal beiseite gelegt, da mir der kopf raucht und > ich alles durcheinander werfe. So, ich habs nicht mehr ausgehalten ("das kann doch nicht so schwer sein!") und habe mir mal den SDCC installiert, die oben aufgeführten Änderungen eingebaut, noch hier und da eine kleine Änderung/Optimierung (include-Tausch, Mini-itoa-Ersatz geschrieben, um sprintf-Aufruf einzusparen) und dann durch den SDCC gejagt. Die Übersetzung von mcurses.c funktioniert nun. Aufwand meinerseits zur Code-Anpassung: 10 Minuten. Ich habe das mcurses-Paket (s. Download im Artikel MCURSES) mit der neuen Version 2.0.0 hochgeladen. Die Änderungen erkennst Du an __SDCC_z80 in mcurses.c. Diese Konstante wird automatisch vom SDCC gesetzt, wenn man mit -mz80 compiliert. Jetzt brauchst Du nur noch zu testen, am besten mit diesem main.c:
1 | #include "mcurses.h" |
2 | |
3 | int main () |
4 | {
|
5 | char buf[40]; |
6 | |
7 | mvaddstr (9, 10, "Bitte eine Zeichenkette eingeben:"); |
8 | mvgetnstr (10, 10, buf, 40); // Einlesen eines String mit 79 Zeichen + '\0' |
9 | mvaddstr (11, 10, buf); // Ausgabe des Strings eine Zeile darunter |
10 | return 0; |
11 | }
|
:
Bearbeitet durch Moderator
Hi, ist schon deutlich klarer und ich werde es heut abend auf meine Int gesteuerte Zeichenausgabe/eingabe anpassen. Gestern war nur ein Punkt wo nichts mehr ging und wo man besser aufhört und sich nicht in Dinge verbeisst, die an dem Tag einfach nicht mehr gehen. Dass die Low Level Ebene nicht ganz einfach ist habe ich auch gemerkt, da ich angefangen hatte das alles selbst zu schreiben. Ok..... melde mich erst wieder wenn es klappt.
Christian J. schrieb: > ist schon deutlich klarer Hast Du auch meinen Beitrag von 10:53 Uhr gelesen? Ich habe mcurses.c bereits auf SDCC portiert, Du kannst Dir mcurses.zip daher nochmal runterladen. Viel Spaß!
Es kompiliert auf dem Cubie Truck fehlerfrei durch, grad ausprobiert, bzw nur die Warnungen wegen der crt0.s, die ich noch anpassen muss, weil da die .globl definiert werden wollen. 2046 Bytes Code. Bin noch dran die Verbindung zwischen meinem Empfangspuffer her zustellen, da ich gestern abend mit der letzten kraft nach 3 Kaffee nachts um 2 Uhr auf Int umgestellt habe, damit nicht ewig Zeichen verschwinden. itoa ist auf dem sdcc verfügbar, allerdings etwas speicherfressend. Dumme Frage: Das Schlüsselwort "unix" vorne, wo wird das definiert? Vom system her oder dem GCC? Preprozessor Sachen habe ich bisher wenig gemacht. Uart u.a. Init sieht übrigens so aus, das ist bei jedem anders, je nachdem welche Chipse man nimmt
1 | // 8255: Mode 0: Port A,B,C Output |
2 | PIO8255_CNTRL = 0x80; //Mode 0: Port A,B,C Output |
3 | PIO8255_PORT_A = 0xff; |
4 | PIO8255_PORT_B = 0; |
5 | PIO8255_PORT_C = 0; |
6 | |
7 | // 7-Segment .... |
8 | SEG7 = 0xff; |
9 | |
10 | // STI konfigurieren für Uart Ausgabe |
11 | STI_UCR = 0x88; // = 10001000 UART Control Register 8N1, DIV16 |
12 | STI_RSR = 0x01; // RX Status - Enable RX |
13 | STI_TSR = 0x05; // TX Status - TX High, TX enabled |
14 | // Timer D... |
15 | STI_PVR = STI_TDDR; // Zeiger PVR auf Timer D Data |
16 | STI_IDR = 0x03; // Timer D Zeitkonstante |
17 | STI_PVR = STI_TCDCR; // Zeiger auf Timer C,D Control Register |
18 | STI_IDR = 0x89; // Timer D DIV 4, C = Stop |
19 | // GPIO..... |
20 | STI_PVR = STI_DDR; // Zeiger PVR auf indirect 6 (DDR) |
21 | STI_IDR = 0xff; // GPIO als Output |
22 | STI_GPIP = 0x00; // GPIO auf Null setzen |
23 | // Timer A = endlos Run |
24 | |
25 | //STI_TADR = 0xb8; // Reload Wert Timer A, ca 100 HZ |
26 | //STI_TABCR = 0x70; // Timer A DIV 200, maximale Verzögerung |
27 | STI_PVR = STI_IERA; // RX Buffer Interrupt ein |
28 | STI_IDR = 0x10; |
29 | STI_IMRA = 0x10; // RX full unmask |
30 | |
31 | STI_IPRA = 0x00; // Lösche Pending Ints |
32 | STI_PVR = 0x40; // Vektor auf Mode 2 Tabelle |
33 | |
34 | __asm |
35 | im 2 |
36 | ld a,#RAM_START >> 8 & 0xff |
37 | ld i,a |
38 | ei |
39 | __endasm; |
Christian J. schrieb: > Es kompiliert auf dem Cubie Truck fehlerfrei durch, grad ausprobiert, > bzw nur die Warnungen wegen der crt0.s, die ich noch anpassen muss, weil > da die .globl definiert werden wollen. 2046 Bytes Code. Prima. > itoa ist auf dem sdcc verfügbar, allerdings etwas speicherfressend. Dann lass es so, wie es ist. Da es sich um maximal dreistellige Dezimalzahlen handelt (für die Cursor-Positionierung), habe ich das ganz nativ in C in 10 Zeilen gelöst - siehe Funktion mcurses_puti(). > Dumme Frage: Das Schlüsselwort "unix" vorne, wo wird das definiert? Das wird definiert, wenn man einen C-Code für ein Unix-/Linux-System compiliert. Da Du für einen Z80 compilierst, ist "unix" NICHT definiert. Es geht also hier immer um das Zielsystem! Der SDCC setzt automatisch __SDCC_z80. Deshalb findest Du in mcurses.c nun vor:
1 | #if defined(unix)
|
2 | mache Unix-spezifischen Code |
3 | #elif defined(__SDCC_z80)
|
4 | mache Z80-spezifischen Code |
5 | #else // AVR
|
6 | mache AVR-spezifischen Code |
7 | #endif
|
Die plattformabhängigen Teile sind also komplett voneinander getrennt. Die nicht zutreffenden Teile werden NICHT compiliert, sondern komplett ignoriert. > Vom system her oder dem GCC? Der gcc (aber auch jeder andere C-Compiler) setzt das, wenn das Zielsystem ein Unix ist. Das ist schon seit 1969 so, da gab es noch keinen gcc. Wenn das Zielsystem aber ein AVR ist, ist unix NICHT gesetzt. Ebenso nicht beim SDCC, wenn -mz80 für das Zielsystem angegeben ist. > Preprozessor Sachen habe ich bisher wenig gemacht. Hm, eine vom Compiler definierte Konstante abzufragen gehört aber zum Basis-Wissen. Hast Du mal in SDCC-Manual geschaut? Da wird genau erklärt, für welches Zielsystem der SDCC was setzt. > Uart u.a. Init sieht übrigens so aus, das ist bei jedem anders, je > nachdem welche Chipse man nimmt Okay, du musst das Uart-Init ja nicht in initscr() machen, sondern kannst das aufrufen, wo und wann Du willst. Aber mindestens vor initscr(), damit mcurses mit einem vollständig initialisiertem UART loslegen kann.
Lass Dich knutschen Frank :-) (scherz) siehe Bild. Erstmal ohne Interrupts, damit es endlich was zu sehen gab. Für die Ints werde ich getchar und putchar umschreiben, so dass sie direkt auf den Buffer gehen und nicht mehr auf die Hardware. Damit nichts doppelt gemoppelt wird: Deine Ringbuffer sind nur für AVR bei Verwendung von ISR? Ich habe die Funktion getchar und putchar einige Male gefunden, die ich ja durch meine eigene überschrieben habe. >>Hm, eine vom Compiler definierte Konstante abzufragen gehört aber zum >>Basis-Wissen. Es gab in 17 jahre nie eine Notwendigkeit Code zu schreiben, der für mehr als das Zielsystem benutzt wurde und niemals veröffentlicht worden ist. Man weiss nur das was man braucht, nicht das was man nicht benutzt.
Na also, geht doch :-) Wie schon erwähnt: Ich würde Dir raten, das komplette Benutzerinterface Deiner Anwendung über mcurses abzuwickeln, nicht nur die Eingabe eines Kommandos. Damit hast Du eine Menge Komfort gewonnen. Du kannst dann den Bildschirm löschen, Deinen Text beliebig positionieren und auch noch mit Attributen (Bold, Underline, Vorder- und Hintergrund-Farben etc) versehen. > Damit nichts doppelt gemoppelt wird: Deine Ringbuffer sind nur für AVR > bei Verwendung von ISR? Ja, die sind nur für AVR. Unter Unix-/Linux laufen die Interrupts komplett im Betriebssystem selbst, getchar() und putchar() arbeiten bereits mit Buffern, ohne dass es der Programmierer überhaupt mitbekommt. > Ich habe die Funktion getchar und putchar einige > Male gefunden, die ich ja durch meine eigene überschrieben habe. Du hast also in mcurses.c die putchar() und getchar()-Aufrufe nochmal ersetzt? Warum? Okay, Du könntest für Deine eigenen IO-Funktionen natürlich auch noch einen Interrupt-gesteuerten Ringbuffer einbauen. Aber das ist eine Optimierung, die ich erst machen würde, wenn alle anderen Probleme glattgebügelt sind. First make it work, then make it fine ;-) Das einzige, was für mich jetzt noch für eine vollständige Portierung auf SDCC (Z80) interessant wäre, ein nicht-blockierendes getchar() hinzubekommen. Das dafür zuständige flag kann man ja über die mcurses-Funktion nodelay(flag) setzen. Funktioniert auch für Unix-/Linux und AVR perfekt. Wenn Du da etwas weisst bzw. einen Tipp hast, würde ich diesen noch offentstehenden Teil in mcurses ebenso noch für SDCC umsetzen. Dann wäre für mich alles komplett und rund.
:
Bearbeitet durch Moderator
Frank M. schrieb: > Das einzige, was für mich jetzt noch für eine vollständige Portierung > auf SDCC (Z80) interessant wäre, ein nicht-blockierendes getchar() > hinzubekommen. Das bin ich schon dran. Aber das ist nicht "portierbar", da jedes Z80 System anders ist, je nachdem welche Chips man benutzt. Ich nehme den Stromfresser MK3801 Multi I/O Chip mit dem Seltenheitswert eines Oldtimers, da der 3 in 1 hat, Timer, SIO, GPIO und ncht 3 40-Pinner-Trümmer die Platine zustellen. Dafür benutze ich den Timer A im Free Running Mode, der so halbwegs auf 100Hz eingestellt ist und nach ca 0,5 das Timeout auslöst und die getchar Routine darüber informiert wird. [code] /////////////////////////////////////////////////////// // Zeicheneingabe von der Uart // Achtung, kein Timeout! char getchar() { while ((STI_RSR & 0x80) == 0); return(STI_UDR); } wird dann zu: while ( !(STI_RSR & 0x80) && !(rx_timeout); das ginge "portabel" nur in dem bei mcurses die Existenz eines putchar_timeout Flags vorausgesetzt würde. >>Du hast also in mcurses.c die putchar() und getchar()-Aufrufe nochmal >>ersetzt? Ich habe in mcurses nicht eine einzige zeile angefasst, gar nichts. Nein, meine eigene überschreibt die interne putchar. Damit nutzt dein Modul, da es als letztes kompiliert wird natürlich auch meine Routine. Die im sdcc sind leer, da der sdcc nicht weiss was gemacht werden soll.
Christian J. schrieb: >
1 | > char getchar() |
2 | > { |
3 | > while ((STI_RSR & 0x80) == 0); |
4 | > return(STI_UDR); |
5 | > } |
6 | > |
Danke, dann ist es einfach. Du musst nur folgende Funktionen ersetzen:
1 | /*---------------------------------------------------------------------------------------------------------------------------------------------------
|
2 | * PHYIO: getc
|
3 | *---------------------------------------------------------------------------------------------------------------------------------------------------
|
4 | */
|
5 | static uint8_t |
6 | mcurses_phyio_getc (void) |
7 | {
|
8 | while ((STI_RSR & 0x80) == 0) |
9 | {
|
10 | if (mcurses_nodelay) |
11 | { // if nodelay set, return ERR |
12 | return (ERR); |
13 | }
|
14 | }
|
15 | return(STI_UDR); |
16 | }
|
17 | |
18 | /*---------------------------------------------------------------------------------------------------------------------------------------------------
|
19 | * PHYIO: set/reset nodelay
|
20 | *---------------------------------------------------------------------------------------------------------------------------------------------------
|
21 | */
|
22 | static void |
23 | mcurses_phyio_nodelay (uint8_t flag) |
24 | {
|
25 | mcurses_nodelay = flag; |
26 | }
|
Die Definition der Variablen z80_nodelay kannst Du dann löschen. Oder Du baust die Abfrage auf mcurses_nodelay in Deine eigene getchar()-Funktion. mcurses_nodelay ist aber im Moment "versteckt", d.h. static. Das static müsstest Du dann entfernen, damit Du aus Deinen eigenen Routinen drauf zugreifen kannst. Ist aber Geschmackssache. Denn eigentlich sind die PHYIO-Funktionen genau für den Hardware-Teil gedacht.
:
Bearbeitet durch Moderator
Habe ich, klappt immer noch, a die puts und gets ja in den Hardware Teil gehören ujnd nicht ins Userprog. Nochmal: Du schlägst also vor, dass ich meine Menüsterung unter Nicht Verndung von printf oder meinem Speichersparenden printstrng komplett auf mcurses umstelle? Nur werden dann so Themen wie Scrolling aktut, denn ein normales Terminal läuft ja nach oben immer weiter. Bisher sehe ich nur absolute Zeilenadressierung in den Funktionen. (Ein 4 Gewinnt Spiel wird da allerdings interesannt, da es stehen bleibt und nicht immer wieder neu erzeugt wird) Das sieht ja später so aus menü 1.......... menü 2.......... menü 3.......... menü 4.......... usr> <usereingabe> Habe nur das hier gefunden: extern void setscrreg (uint8_t, uint8_t); // set scrolling region z80> <Antwort auf Eingabe> PS: Ich möchte nicht wissen wie jetzt genau das Cursor Verschieben und das verschieben von text funktioniert, wenn man im Wort weitertippt. Ich nehme es einfach so hin.
Christian J. schrieb: > Nochmal: Du schlägst also vor, dass ich meine Menüsterung unter Nicht > Verndung von printf oder meinem Speichersparenden printstrng komplett > auf mcurses umstelle? Ja, wäre doch nur eine logische Konsequenz. > Nur werden dann so Themen wie Scrolling aktut, > denn ein normales Terminal läuft ja nach oben immer weiter. Bisher sehe > ich nur absolute Zeichenadressierung in den Funktionen. Ich weiß nicht, wieviel Output Du da machst. Kannst Du den nicht so portionieren, dass immer eine Seite ausgegeben wird? Wie gesagt, die Funktionen clear() und clrtobot() existieren :-) Ausserdem kann mcurses sogenannte Scrolling Regions. Beispiel: Das Terminal soll nur von den Zeilen 2 bis 22 Scrollen und damit die Zeilen 1, 23 und 24 "einfrieren". Dann kannst Du oben bzw. unten Statuszeilen anzeigen (Temperatur, Uhrzeit und was weiß ich), die immer an derselben Stelle sein sollen. dafür gibt es die folgenden mcurses-Funktionen, die Du mal im Artikel näher betrachten und ausprobieren solltest: - setscrreg() setzt Scrolling-Region - deleteln() löscht eine Zeile an der aktuellen Position. Darunter liegende Zeilen innerhalb der Scrolling-Region rollen damit automatisch hoch! - insertln() fügt eine Zeile an der aktuellen Position ein. Darunter liegende Zeilen innerhalb der Scrolling-Region rollen damit automatisch runter! - scroll() rollt die komplette Scrolling-Region hoch. > Das sieht ja später so aus > > menü 1.......... > menü 2.......... > menü 3.......... > menü 4.......... > z80> <usereingabe> Ja, prima, damit kannst Du dafür sorgen, dass das Menü immer an derselben Stelle erscheint. Das wirkt wesentlich professioneller. Nach der Eingabe machst Du erstmal einen clear(), wenn die Ausgabe länger wird. Dann kannst Du oben links innerhalb der Scrolling-Region anfangen. Wenn Du rollen willst, dann rufst Du scroll() auf. Spiel mal ein wenig mit den mcurses-Funktionen rum! Es lohnt sich. P.S. Vielleicht hast Du es schon gemerkt: mcurses fängt bei 0 bzgl. Spalten und Zeilen zu zählen. Bei 24 Zeilen kannst Du mit setscrreg(0, 23) die Scrolling-Region auf den kompletten Bildschirminhalt setzen. Dann rollt alles wie gewohnt. Bei setscrreg(0, 22) hast Du unten immer eine Statuszeile, die nicht mitrollt, bei setscrreg(1, 23) ist die eingefrorene Zeile oben. Vielleicht willst Du aber auch, dass nur der halbe Bildschirm gerollt wird? Dann rufe setscrreg(12, 23) auf. Dann hast Du oben 12 feststehende Zeilen fürs Menü etc. und unten rollt die Ausgabe. Du könntest damit zum Beispiel auch einen einfachen Hex-Editor bauen...
:
Bearbeitet durch Moderator
Ok, ich denke ich habe jetzt ne Menge erstmal auszuprobieren (ohne das dämliche EPROM Brennen. Sieht ganz witzig aus mit rand x,y Positonen zu erzeugen und alles vollzuschreiben, kreuz und quer. Muss erstmal sschauen wie ich minicom beibringe eine feste Bildschirmgröße zu haben, das Fenster ist ja beliebig scalierbar bisher. Letzte Frage: Wie hatst du es geschafft dass getnstr (buf, 40); und andere sowohl eine Position als Paramdeter verstehen als auch ohne Positionsangabe? eit: erledigt. mv... mit und ohne. Man lernt immer was Neues dazu... #define erase() clear() // clear total screen, same as clear() #define mvaddch(y,x,c) move((y),(x)), addch((c)) // move cursor, then add character #define mvaddstr(y,x,s) move((y),(x)), addstr((s)) // move cursor, then add string #define mvaddstr_P(y,x,s) move((y),(x)), addstr_P((s)) // move cursor, then add string (PROGMEM) #define mvinsch(y,x,c) move((y),(x)), insch((c)) // move cursor, then insert character #define mvdelch(y,x) move((y),(x)), delch() // move cursor, then delete character #define mvgetnstr(y,x,s,n) move((y),(x)), getnstr(s,n) // move cursor, then get string #define getyx(y,x) y = mcurses_cury, x = mcurses_curx // get cursor coordinates
Christian J. schrieb: > Letzte Frage: Wie hatst du es geschafft dass getnstr (buf, 40); und > andere sowohl eine Position als Paramdeter verstehen als auch ohne > Positionsangabe? Die Funktion heisst getnstr(char * str, uint8_t maxlen). Aber es gibt noch ein Makro in mcurses.h:
1 | #define mvgetnstr(y,x,s,n) move((y),(x)), getnstr(s,n)
|
Es wird also hier erst ein move(), dann getnstr() aufgerufen. Die beiden Befehle sind durch Komma getrennt statt Semikolon. Das bewirkt, dass der Compiler beides wie einen (geklammerten) Block betrachtet. Sonst könnte dies Probleme machen: if (irgendeine_Bedingung) mvgetnstr(....); else tuewasanderes(); Das else würde der Compiler in den falschen Hals kriegen, wenn oben ein Semikolon stünde, da hier nix geklammert ist. (Deshalb klammere ich immer alles, auch wenn es nur ein Statement unter einem if ist).
Frank M. schrieb:
1 | > #define mvgetnstr(y,x,s,n) move((y),(x)), getnstr(s,n) |
Besser:
1 | #define mvgetnstr(y,x,s,n) do { move((y),(x)); getnstr(s,n); } while (0)
|
> Das else würde der Compiler in den falschen Hals kriegen, wenn oben ein > Semikolon stünde, da hier nix geklammert ist. Dann passiert das nicht. > (Deshalb klammere ich > immer alles, auch wenn es nur ein Statement unter einem if ist). Und die Klammern in diesen Fällen sind wieder reine Geschmacksache.
:
Bearbeitet durch User
Leo C. schrieb: > Besser: >
1 | > #define mvgetnstr(y,x,s,n) do { move((y),(x)); getnstr(s,n); } |
2 | > while (0) |
3 | >
|
Ja, ich kenne diese Konstruktion und benutze sie im allgemeinen auch gern. Da aber nicht alle Compiler so schlau auf dieser Welt sind wie gcc, wird daraus manchmal auch im Compiler-Output eine echte do-while-Schleife - mit dem einzigen Effekt, dass der Code aufgeblasen wird und eine unnötige Bedingung getestet wird. Kann der SDCC das genauso gut wie der gcc? > Dann passiert das nicht. Das passiert mit dem Komma-Operator auch nicht. Auch hier kannst Du dann im Code die Klammern gefahrlos weglassen. > Und die Klammern in diesen Fällen sind wieder reine Geschmacksache. Eben. Wie gesagt: Der Komma-Operator löst die Aufgabe genauso gut wie eine geklammerte do-while-Fake-Schleife.
Zusatz: Der Komma-Operator hat noch einen Vorteil: Man kann im Macro mit return-Werten arbeiten, z.B. #define mvgetch(y,x) move(y,x), getch() Dann kann man schreiben: int ch; ch = mvgetch(10, 11); Mit einer do-while-Schleife wäre das nicht lösbar. (Man muss dazu anmerken, dass beim Komma-Operator, der Return-Wert immer derjenige der zuletzt aufgerufenen Funktion ist. Das ist einfach praktisch :-) )
:
Bearbeitet durch Moderator
Frank M. schrieb: > Kann der SDCC das genauso gut wie der > gcc? Sieht so aus. Hab dein Demo grade in aller Eile durch den Compiler gejagt. Hier ein Outputschnipsel:
1 | ;demo.c:138: mvdelch (3,0); |
2 | ; genIpush |
3 | push de |
4 | ;fetchPairLong |
5 | ;fetchLitPair |
6 | ld hl,#0x0003 |
7 | push hl |
8 | ; genCall |
9 | call _move |
10 | pop af |
11 | ; genCall |
12 | ; peephole 44 eleminated dead pop/push pair. |
13 | call _delch |
14 | ;demo.c:139: PAUSE (25); |
>> Und die Klammern in diesen Fällen sind wieder reine Geschmacksache. > > Eben. Wie gesagt: Der Komma-Operator löst die Aufgabe genauso gut wie > eine geklammerte do-while-Fake-Schleife. Mit dem Komma im Makro sind sie zwingend, keine Geschmacksache. Muss jetzt leider dringend weg. Ich melde mich später in deinem MCURSES-Thread wieder.
Leo C. schrieb: > Mit dem Komma im Makro sind sie zwingend, keine Geschmacksache. Da irrst Du gewaltig. Beweis:
1 | #include <stdio.h> |
2 | |
3 | int
|
4 | main () |
5 | {
|
6 | int i = 3; |
7 | |
8 | if (i == 3) |
9 | printf ("ist drei\n"), printf ("und bleibt drei\n"); |
10 | else
|
11 | printf ("ist NICHT drei\n"); |
12 | |
13 | return 0; |
14 | }
|
$ cc a.c && ./a.out ist drei und bleibt drei
Frank M. schrieb: > Da irrst Du gewaltig. Hast recht, da war ich zu sehr im Zeitdruck. Kommaoperator mag ich an der Stelle trotzdem nicht. ;) Frank M. schrieb: > Der Komma-Operator hat noch einen Vorteil: Man kann im Macro mit > return-Werten arbeiten, z.B. > > #define mvgetch(y,x) move(y,x), getch() Wenns aussieht wie eine Funktion, die einen Wert liefert, sollte es auch überall so verwendet werden können. Als Parameter einer Funktion gehts aber schief. Das Beste wäre 'static inline' statt '#define'. Funktioniert auch mit sdcc. Allerdings baut er den Funktionskörper der inline-Funktion mit ein, obwohl die Funktion selbst nicht aufgerufen wird.
Nabend, dank Franks Mini-Editor und anderer Funktionen sind nun die Möglichkeiten um ein Vielfaches erweitert. es wird langsam Zeit sich Gedanken um die Struktur der Software zu machen, uns ob Leo Makedatei noch ausreicht aber ioch hoffe noch mit einem einzigen Verzeichnis auszukommen und maximal 5-8 Quelldateien. Kommen wir zu einem Punkt der "Bedienung" über das Terminal. Es wird sicher nie ein Linux aber elementare Dinge sollen möglich sein. Load User program Execute User program Memory Hex Dump [Adresse] Kill User Programm Reset System Text Spiele Hardware Funktion 1 Hardware Funktion 2 Hardware Funktion 3 Basic interpreter? Safe Funktion (wie auch immer) Ein normaler Parser zerlegt Kommandos in eine Baumstruktur und ist ein maechtiges Stück Software. Aktuell hat nur der Befehl dump numerische Parameter nämlich die Adresse die angezeigt werden soll. Ich denke es reicht, wenn ich mit strcmp eine Liste abklapper const command const* [] = {"Befehl1", "Befehl2",.... und die Ergebnisse in struct parsed { char command token; char no_params; int params[n]; } packe. Ein Routine verzweigt dann in die jeweilige Funktion und übergibt die Struktur bzw ist die eh global. Dort werden dann weitere Ausgaben erzeugt, zb bei dump ist noch einiges möglich. Erweiterbar ist das alles nicht sonderlich. String Parameter müssten gesondert behandelt werden aber ein dump 0000 2000 mit der Ausgabe eines Hex Editor werde ich noch hinbekommen. In der Ausgabe aber editieren wird schon schwieriger. Nötig wäre es aber nicht. Im Kopf gehen da noch Sachen herum, wie ein 64k E2PROM, in welches der RAM Inhalt gespiegelt werden kann, so dass er er sich beim Kaltstart wieder reinzieht und ausführt aber Platz habe ich keinen mehr, nur noch auf der Erweiterungsplatine ginge das. I2C über den 8255 ist eine andere Sache, müsste aber softwaremaessig gehen, Hi, LO, tri State hat er ja, leider aber eben nur einen ganzen Port mit gleicher Richtung, Bits wählweise In oder out geht nicht. Da wäre es wenig Retro-mässig einen AVR oder PIC an den I/O Bus zu hängen und den das E2PROM bedienen zu lassen. Aber machbar, schnell genug ist er und der Z80 könnte den PIC als I/O Device einbinden, eine Speicheradresse als Parmeter übergeben usw. Was können denn andere Monitore so alles? Einen Debugger habe ich ja leider nicht, da ich eh in C programmiere und keinen Single Step habe. Gruss, Christian
Christian J. schrieb: > Im Kopf gehen da noch Sachen herum, wie ein 64k E2PROM, in welches der > RAM Inhalt gespiegelt werden kann, so dass er er sich beim Kaltstart > wieder reinzieht und ausführt aber Platz habe ich keinen mehr, Häng einen Akku an dein SRAM, und ein Gatter, das ohne Hauptspannung inaktives /CS sicherstellt.
Christian J. schrieb: > Erweiterbar ist das alles nicht sonderlich. String Parameter müssten > gesondert behandelt werden aber ein dump 0000 2000 mit der Ausgabe eines > Hex Editor werde ich noch hinbekommen. In der Ausgabe aber editieren > wird schon schwieriger. Nötig wäre es aber nicht. Ein Hex-Editor mit mcurses ist nicht sehr schwierig. Wenn Du nichts dagegen hast, kann ich das gerne übernehmen.
Christian J. schrieb: > I2C über den 8255 ist eine andere > Sache, müsste aber softwaremaessig gehen, Hi, LO, tri State hat er ja, > leider aber eben nur einen ganzen Port mit gleicher Richtung, Bits > wählweise In oder out geht nicht. Mit der Z80-PIO ginge das. Aber der STI hat doch auch noch ein paar I/O-Leitungen. Christian J. schrieb: > Was können denn andere Monitore so alles? Einen Debugger habe ich ja > leider nicht, da ich eh in C programmiere und keinen Single Step habe.
1 | ### Reset reason(s): External. |
2 | ### Setting I2C clock Frequency to 20000 Hz. |
3 | |
4 | ATMEGA1281+Z8S180 Stamp Monitor |
5 | |
6 | ### main_loop entered: bootdelay=-1 |
7 | |
8 | ### main_loop: bootcmd="pin ${pins}; reset; loadf; go ${startaddr}" |
9 | => help |
10 | !cpe - EEPROM copy |
11 | !mde - EEPROM dump |
12 | !mdr - RAM dump |
13 | ? - alias for 'help' |
14 | base - print or set address offset |
15 | cmp - memory compare |
16 | connect - Connect to CPU console i/o |
17 | cp - memory copy |
18 | date - get/set/reset date & time |
19 | defaultenv - set all environment variables to their default values |
20 | echo - echo args to console |
21 | go - start application at address 'addr' |
22 | help - print command description/usage |
23 | loadf - load srec_cat prepared image from controller flash |
24 | loop - infinite loop on address range |
25 | md - memory display |
26 | mm - memory modify (auto-incrementing address) |
27 | mstep - execute one M cycle |
28 | mw - memory write (fill) |
29 | nm - memory modify (constant address) |
30 | pin - Set or query pin state |
31 | printenv - print environment variables |
32 | reset - Keep CPU in RESET state |
33 | restart - Perform RESET of the CPU |
34 | run - run commands in an environment variable |
35 | saveenv - save environment variables to persistent storage |
36 | setenv - set environment variables |
37 | sleep - delay execution for some time |
38 | => printenv bootcmd |
39 | bootcmd=pin ${pins}; reset; loadf; go ${startaddr} |
40 | => run bootcmd |
41 | ## CPU now in reset state. |
42 | Loading Z180 memory... |
43 | From: 0x00000 to: 0x001B9 ( 442 bytes) |
44 | From: 0x001C2 to: 0x02D9E (11229 bytes) |
45 | From: 0x02DAE to: 0x03194 ( 999 bytes) |
46 | ## Starting application at 0x0000 ... |
47 | => z80_memfifo_init: 0, 7c320 |
48 | z80_memfifo_init: 1, 7c21d |
49 | z80_memfifo_init: 2, 7c423 |
50 | z80_memfifo_init: 3, 7c526 |
51 | connect |
52 | DDT/Z - HD64180 (ROM) |
53 | > ? |
54 | DDT/Z180 (ROM) Commands: |
55 | > @ examine/substitute the displacement register @ |
56 | > A [address] Assemble |
57 | > B[X] display [or clear] all Breakpoints |
58 | B breakp [:count] [breakp..] set Breakpoints |
59 | BX address [address..] clear Breakpoints |
60 | >>C[N][J] [count] trace over Calls [No list] [Jumps only] |
61 | C[N][J] W|U expression trace over Calls While|Until ... |
62 | >>D [startadr] [endadr] Display memory in hex and ascii |
63 | > G [startadr] [;breakp..] Go [to start] [temporary breakpoints] |
64 | > H [expression [expression]] compute expressions / show High/max load adr. |
65 | >>I [port] Input a byte from port |
66 | >>L [startadr] [endadr] List disassembled code |
67 | > M[V] startadr endadr destadr Move memory [and verify] |
68 | >>O [byte] [port] Output a byte to port |
69 | > Q[J] startadr endadr bytes Qery memory for byte string [Justified] |
70 | > R [displacement] Read intel hex from console [add displacemt] |
71 | > S address Substitute memory |
72 | >>T[N][J] [count] Trace [No list] [Jumps only] [count steps] |
73 | T[N][J] W|U expression Trace While|Until expression |
74 | > V startadr endadr destadr Verify (compare) two memory areas |
75 | > X[register] eXamine [and substitute] registers |
76 | > Y[0..9] eXamine [and substitute] Y variables |
77 | > Z startadr endadr bytes Zap (fill) memory with a byte string |
78 | > |
Der erste Teil läuft auf dem Steuer-AVR. Der Teil nach dem "connect" kommt dann Debugger auf dem Z180.
Super! Da kommen ja einige Ideen zusammen, auch wenn es fertige Lösungen wie CPM oder das neue Unix gibt, wo alles drin ist. Besonders die händische Ansteuerung der Peripherie und Ports werde ich übernehmen von > ? DDT/Z180 (ROM) Commands. @Frank: wieso sollte ich was dagegen haben? Ist doch dein Kind. Nur das Interface für den dump und setup sollte einfach sein. Normalerweise kreist man doch mit dem Cursor in einem Hex Zahlen Feld herum, rechts die Ascii Code, links die Adresse. Und CR übernimmt die Daten dann. Das User Interface aber hat es schon etwas in sich..... vor allem wenn es plattform unabhängig sein soll, da ja direkter Zugriff auf die Hardware erfolgt, die ram Zellen.
So Chris jetzt hast du mich angesteckt ;) Leider habe ich nicht soviel Zeit wie du, aber dafür hoffe ich einen Schritt schneller zu starten damit ----> Beitrag "2* UB8830D was mach ich nur mit Ihnen?" Namaste
Christian J. schrieb: > @Frank: wieso sollte ich was dagegen haben? Ist doch dein Kind. Nur das > Interface für den dump und setup sollte einfach sein. Normalerweise > kreist man doch mit dem Cursor in einem Hex Zahlen Feld herum, rechts > die Ascii Code, links die Adresse. Und CR übernimmt die Daten dann. Okay, ich baue einen.
Frank M. schrieb: > Okay, ich baue einen. Ok. Aber das Interface ...... da muss man mal kurz die Hirnzelle strapazieren. Input: 1. Memory Range 2. Darstellungsweise: adress, hex.....hex....., ascii? 3. Darstellungs Format? indivuielle Physical I/O Routinen: Peek und Poke? Das Interface sollte abgesetzt sein vom übrigen Code und userfreundlich sein. Basic Interpreter: das setzt schon ein Speichermedium voraus. Wo soll derQuelltext hin? Oder die Tokens? Und solch große Code kann ich auch nicht mal eben portieren. Das ist aktuell noch ne nummer zu gross für mich. Habe aber eine Lösung im Web gefunden, wo ein PIC für den ich alles habe an den I/O Buss dran geschlossen wird. Auf die idee kamen schon andere.
Winfried J. schrieb: > So Chris jetzt hast du mich angesteckt ;) > Leider habe ich nicht soviel Zeit wie du, aber dafür hoffe ich einen > Schritt schneller zu starten damit ----> > Beitrag "2* UB8830D was mach ich nur mit Ihnen?" > > Namaste Wenn das so weitergeht wir das hier irgendwann ein Projekt wie N8VM, größer und größer und immer mehr wollen auch haben. Platinen werden gemacht. Modulares Konzept und erweiterbar. Denn ich erinnere mich an dde Sätze von Rheinhardt Keil (heute ARM) auf seinem 8085 Buch von 1986: Wer hat mehr von einem Computer? Der ihn fertig kauft oder der ihn selbst baut und auch versteht?)
Christian J. schrieb: > Basic Interpreter: das setzt schon ein Speichermedium voraus. Wo soll > derQuelltext hin? Oder die Tokens? Ins RAM. Ein Interpreter ist kein Compiler. Ob du Tokens verwendest oder nicht: Quelltext = Programm. Als persitenten Programmspeicher tut es ein Dataflash, oder eine SD-Card. Alternativ zu BASIC käme auch FORTH im Frage, da sollte sich auch was auftreiben lassen.
A. K. schrieb: > Häng einen Akku an dein SRAM, und ein Gatter, das ohne Hauptspannung > inaktives /CS sicherstellt. Ein Akku auf einem IC draufgeschnallt sieht sch.... aus. Kein Platz mehr. Nur Knopfzelle unter Platine ginge noch. >>Alternativ zu BASIC käme auch FORTH im Frage, da sollte sich >>uch was auftreiben lassen. FORTH? Grausam! Kommt mir nicht ins Haus. Du meintest vielleicht FORTRAN aber das ist eine Compiler Sprache.
Basic Struktur wäre dann also wie folgt PC -> Z80 Eingabe Quelltext über ncurses Z80 legt Quelltext zeilen im RAM ab RUN Command liest diese duch, interpretiert sie und erzeugt auf Konsole die Ausgabe. Leider liesse sich der Quelltext aktuell nicht abspeichern, nur indirekt über den PC als Aufzeichnung über minicom. Eines nach dem anderen, erst Speichermedium bauen ode ne echte Floppy dranhängen, aber dann käme FAT noch hinzu.
Leo C. schrieb: > Christian J. schrieb: >> Nur Knopfzelle unter Platine ginge noch. > > Reicht doch Knopfzelle = 1.5V, nur die großen 3V. Abkopplung von Betriebsspannung nötig und außerdem muss der CS Pin auf Low gehalten werden und darf nicht floaten. Das ginge notfalls mit einem Widerstand gegen Masse.
Christian J. schrieb: > FORTH? Grausam! Kommt mir nicht ins Haus. Du meintest vielleicht FORTRAN > aber das ist eine Compiler Sprache. Nö, FORTH stimmt schon, den Unterschied kenne ich. War mein Favorit beim AIX65 (6502). BASIC und PL/65 (ein Compiler in 8KB, der mich zum oben gezeigten PLZ inspirierte) hatte ich dafür auch, aber FORTH war mein Favorit.
Ich kriege das Zittern:
1 | \ --------------------------------------------- LOAD AND STORE |
2 | |
3 | : COMPLEXES ( n -- n*/complex ) 2* FLOATS ; |
4 | : COMPLEX+ ( f-addr -- f-addr+/complex ) [ 1 COMPLEXES ] LITERAL + ; |
5 | [UN] COMPLEX [IF] 1 COMPLEXES CONSTANT COMPLEX [THEN] |
6 | |
7 | \ hidden, *nonnestable* scratch storage for stuff from fp stack |
8 | FALIGN HERE 3 COMPLEXES ALLOT VALUE fnoname |
9 | |
10 | : z@ ( addr -- f: -- z) DUP F@ FLOAT+ F@ ; |
11 | : z! ( addr -- f: z --) DUP FLOAT+ F! F! ; |
12 | |
13 | : ZVARIABLE ( "name" -- ) \ compile |
14 | ( -- addr ) \ run |
15 | FALIGN HERE [ 1 COMPLEXES ] LITERAL ALLOT CONSTANT ; |
16 | |
17 | : ZLITERAL ( f: z -- ) \ compile |
18 | ( f: -- z ) \ run |
19 | STATE @ 0= IF -14 THROW THEN |
20 | FSWAP POSTPONE FLITERAL POSTPONE FLITERAL ; IMMEDIATE |
21 | |
22 | : ZCONSTANT ( "name" f: z -- ) \ compile |
23 | ( f: -- z ) \ run |
24 | ( |
25 | Based on Anton Ertl's portable definition of CONSTANT, |
26 | comp.lang.forth, "Re: Alternative DEFER strategies?", 16 Dec |
27 | 2008, but avoiding the return stack. |
28 | ) |
29 | [ fnoname ] LITERAL z! |
30 | : [ fnoname ] LITERAL z@ POSTPONE zliteral POSTPONE ; ; |
Christian J. schrieb: > Knopfzelle = 1.5V, nur die großen 3V. "Gross" ist gut. Die Lithium-Zellen gibts auch in klein und Sockel dafür auch vertikal. Ausserdem darf ein Akku notfalls ein Kabel dran haben, die Hauptstromversorgung hast du ja auch nicht mit Trafo und Elko und allem Gedöns auf der Platine drauf.
Christian J. schrieb: > Ich kriege das Zittern: Du bist aber leicht zu schockieren ;-). Aber da geht noch was, angefangen habe ich damit (Siehe S.10): http://fafner.dyndns.org/~vaxman/publications/apl.pdf
APL is dead! :-) An der Uni haben sie uns mit Fortran 77 "bearbeitet" und machte sogar noch Spass, Fortran war meine Sprache bis ich Pascal entdeckte.
Christian J. schrieb: > APL is dead! :-) Nicht annähernd so tot wie der Inhalt deines Retro-Boards. ;-)
:
Bearbeitet durch User
Hast aber Glück, das Ram hat eine Data Retension Voltage von 1,5V und 1uA..... das passt noch.... nur nicht oben drauf, absolut kein Platz mehr nicht mal für einen Widerfstand. Die Kämme machen alles dicht.
http://hc-ddr.hucki.net/wiki/lib/exe/fetch.php/tiny:u883bas.zip schau dir mal den Tinibasic interpreter an der stammt aus dem UB8830 den solltest du leicht portiern können ASM listing liegt bei ;) Namaste
A. K. schrieb: > <grins> Jaaaaaaaaaaaaaaaaaaa......... ich weiss es !!! Und es lassen sich auch kein Drähte neu ziehen, weil man sie nicht identifizieren kann und schon gar nicht wieder ausfädeln. Aber es sieht schön aus, sehr aufgeräumt :-)
Winfried J. schrieb: > http://hc-ddr.hucki.net/wiki/lib/exe/fetch.php/tiny:u883bas.zip > > schau dir mal den Tinibasic interpreter an der stammt aus dem UB8830 den > solltest du leicht portiern können > > ASM listing liegt bei ;) > > Namaste Sehr schön.... und ich hätte nicht die geringste Ahnung wie ich das Ding "anschliessen" soll an das Terminal, wie das Interface aussieht usw. Das sieht mir wie reassemblert aus. Habe auch sowas, den Microsoft Interpreter. Gibt es aber schöner in C. Kommt später.....
Christian J. schrieb: > Z80 legt Quelltext zeilen im RAM ab Aber nicht doch! Schon der selige PET 2001 hat zeilenweise geparst und nur Tokens im RAM abgelegt.
Winfried J. schrieb: > schau dir mal den Tinibasic interpreter an der stammt aus dem UB8830 den > solltest du leicht portiern können Von Z8 auf Z80? Das glaube ich eher nicht. Es gibt ja auch genug fertige Z80 Basic-Interpreter in allen Größen.
Winfried J. schrieb: > schau dir mal den Tinibasic interpreter an der stammt aus dem UB8830 den > solltest du leicht portiern können Nochmal <grins>. Von Z8 auf Z80 macht keinen Spass. Z8 ist die eleganteste 8-Bit Mikrocontroller-Architektur für Assembler-Programmierung, der ich begegnet bin, wenn man mit den 256 Bytes Datenadressraum auskommt. eZ8 hat da gezwungenermassen schwer nachgelassen. Es zeugt von gutem Geschmack, dass sie "drüben" die Z8 abgekupfert haben, statt Fairchilds F8.
:
Bearbeitet durch User
Konrad S. schrieb: > Christian J. schrieb: >> Z80 legt Quelltext zeilen im RAM ab > > Aber nicht doch! Schon der selige PET 2001 hat zeilenweise geparst und > nur Tokens im RAM abgelegt. Sagte ich doch und dann wurde es hier wieder rumgedreht. Auch der C64 legte nur Tokens ab und rück interpretierte sie beim Listung wieder.
Christian J. schrieb: > aber dann käme FAT noch hinzu. Du denkst mal wieder zu kompliziert. Bei dem Weg landest du bei Board V2 und sowas wie CP/M. Wie hat man damals, als das Zeug neu war, Daten gespeichert? Disketten waren anfangs 8 Zoll gross, mit Laufwerken gross wie eine Schublade und mit 220V-Motor (hatte sowas etwas später). Normalmensch mit bescheidenen Finanzen verwendete einen Kassettenrekorder. Das "Filesystem" hiess Zählwerk und Zettel. Ok, soweit Retro würde ich nicht empfehlen ;-). Aber das Prinzip lässt sich auch mit einem Dataflash nutzen: Du teilst ein 2MB Dataflash in 64 Sektoren zu je 32KB auf und verwendest als "Filename" die Nummer des Sektors. Toteinfach und in ein paar Zeilen erledigt.
:
Bearbeitet durch User
Gerade mal aus dem Regal gekramt. Nachtrag: Ist von 1979
:
Bearbeitet durch User
Christian J. schrieb: > Ok. Aber das Interface ...... da muss man mal kurz die Hirnzelle > strapazieren. Ich habe die erste Version hier mal drangehängt. Das Ding kann noch keine Werte ändern, aber Du kannst schon mit dem Cursor rumlaufen: links, rechts, oben, unten. Es wird nach oben/unten gerollt, wenn Du anschlägst. Dann wird die entsprechende Zeile nachgeladen. Die oberste Zeile bleibt natürlich stehen; hier werden die Scrolling Regions genutzt. > Basic Interpreter: das setzt schon ein Speichermedium voraus. Wo soll > derQuelltext hin? Oder die Tokens? Und solch große Code kann ich auch > nicht mal eben portieren. Das ist aktuell noch ne nummer zu gross für > mich. Habe aber eine Lösung im Web gefunden, wo ein PIC für den ich > alles habe an den I/O Buss dran geschlossen wird. Auf die idee kamen > schon andere. Zum Basic hatte ich Dir eben im mcurses-Thread Beitrag "Re: MCURSES - Mini Curses Bibliothek für Mikrocontroller" schon mal Uwe Bergers Basic-Interpreter ans Herz gelegt. Läuft auf AVR, XMC2GO und auf STM32F4xxx - und benutzt mcurses für den Full-Screen-Editor. Schau da mal rein, ich habe Dir dort bereits ein paar Links zum Stöbern serviert.
:
Bearbeitet durch Moderator
Frank M. schrieb: > Ich habe die erste Version hier mal drangehängt. Hast Du programmieren mit der Muttermilch aufgesaugt? Oder sprichst "C" fliessend wie Deutsch? Ist ja irre..... basic Thrad habe ich gesehen, ist aber Unmengen zu lesen und daher verschoben auf die Tage.
Leo C. schrieb: > Gerade mal aus dem Regal gekramt. > > Nachtrag: > Ist von 1979 369 Euro bei Amazon: http://www.amazon.de/Best-of-Interface-Age/dp/0918398363 2925 Euro: http://www.amazon.de/Best-Interface-Age-General-Software/dp/0918398371
Christian J. schrieb: > Hast Du programmieren mit der Muttermilch aufgesaugt? Oder > sprichst "C" fliessend wie Deutsch? Ist ja irre..... Ich "spreche" C seit über 30 Jahren... 1982 damit angefangen ;-) Für heute mache ich Schluss, morgen noch ein Stündchen, dann ist er fertig. > basic Thrad habe ich gesehen, ist aber Unmengen zu lesen und daher > verschoben auf die Tage. Naja, so ein Basic-Interpreter ist schon eine andere Hausnummer... das geht nicht ganz so schnell.
Christian J. schrieb: > 369 Euro bei Amazon: Darf ja nicht wahr sein. Ich glaube, ich muß ein Teil meines Regals in einen Tresor verfrachten...
Frank M. schrieb: > Ich "spreche" C seit über 30 Jahren... 1982 damit angefangen ;-) > Für heute mache ich Schluss, morgen noch ein Stündchen, dann ist er > fertig. Ich habe hier was für Dich, nur um den Schwierigkeitsgrad noch etwas zu erhöhen .... nhur was für echte Junkies, ist ja klar :-)
Leo C. schrieb: > Darf ja nicht wahr sein. Ich glaube, ich muß ein Teil meines Regals in > einen Tresor verfrachten... Ging mir 2001 bei Philips Semiconductor so als wir liquidiert wurden. Durften stangenweise ICs mitnehmen, alles was da war. packte also einige Stangen bzw Tape reels ein und da ja Arbeitslosigkeit bevorstand stellte ich die bei ebay rein. Bezeichnunga abgeschrieben und gut...... Am Abend stand das Gebot für eine Spule bei etwas über 1800 Euro :-) Es waren hochwertigste DAC, damals richtig teuer. Habe mich sehr gefreut als die dann für über 2000 Euro weg ging die Spulen.
PS. Philipp Krause war sehr fleissig bei der neuesten Version des SDCC Compiler von gestern. Cubietruck compiliert den Source grad durch, 3 Stunden.... 2014-11-07 Philipp Klaus Krause <philipp AT informatik.uni-frankfurt.de> * device/lib/_modslonglong.c, device/lib/_modulonglong.c, device/lib/Makefile.in, device/lib/*/Makefile.in, doc/sdccman.lyx: Implement % for long long and unsigned long long. * doc/Makefile.in: More sensible error behaviour when building documentation. * src/SDCCval.c, src/SDCCerr.c: Only warn about long long constants for large values. * device/lib/_mullonglong.c: Fix long long multiplication. * support/regression/tests/*.c: Enable some long long regression test that pass now. 2014-11-06 Philipp Klaus Krause <philipp AT informatik.uni-frankfurt.de> * src/z80/gen.c: More efficient assignment of literals to 16-bit globals and statics. 2014-11-06 Philipp Klaus Krause <philipp AT informatik.uni-frankfurt.de> * src/z80/gen.c, support/regression/tests/bug-2306.c: Fixed bug #2306. 2014-11-06 Philipp Klaus Krause <philipp AT informatik.uni-frankfurt.de> * src/z80/gen.c, support/regression/tests/bug-2304.c: Fixed bug #2304. * src/z80/ralloc.c, support/regression/tests/bug-2305.c: Fixed bug #2305. 2014-10-29 Philipp Klaus Krause <philipp AT informatik.uni-frankfurt.de> * support/regression/tests/bug-2254.c: Regression test for bug #2254. 2014-10-22 Philipp Klaus Krause <pkk AT spth.de> * src/stm8/gen.c: Spelling fix inspired by Debian patch 02_fix_spelling. 2014-10-22 Ben Shi <powerstudio1st AT 163.com> * device/lib/stm8/Makefile.in: * device/stm8/_modslong.s: * device/stm8/_divslong.s: Optimized mod & div of signed long.
A. K. schrieb: > Christian J. schrieb: >> aber dann käme FAT noch hinzu. > > Du denkst mal wieder zu kompliziert. Bei dem Weg landest du bei Board V2 > und sowas wie CP/M. > > Wie hat man damals, als das Zeug neu war, Daten gespeichert? Disketten > waren anfangs 8 Zoll gross, mit Laufwerken gross wie eine Schublade und > mit 220V-Motor (hatte sowas etwas später). Normalmensch mit bescheidenen > Finanzen verwendete einen Kassettenrekorder. Das "Filesystem" hiess > Zählwerk und Zettel. > > Ok, soweit Retro würde ich nicht empfehlen ;-). Aber das Prinzip lässt > sich auch mit einem Dataflash nutzen: Du teilst ein 2MB Dataflash in 64 > Sektoren zu je 32KB auf und verwendest als "Filename" die Nummer des > Sektors. Toteinfach und in ein paar Zeilen erledigt. Ja, aber ein Kassetteninterface wäre "Retro" :-) Sowas geht heute aber auch mit einem MP3 Bläher... Aber ich würde statt Dataflash eine Micro-SD Karte empfeheln, die kann man auf dem PC ggf. "von außen" laden/sichern/ändern. Gruß, Holm PS: Retro: Ich habe gestern meinen BK0010-01 hervorgekramt und einen Philips Monitor angeschlossen. Der Text nach dem Einschalten ist rot und ich habe keine Kabel vertauscht. Das ist ein russischer Homecomputer mit PDP11-CPU. Heute kommt der Kassettenrecorder dran, es gibt eine Python Software die die Binärfiles nach WAV umdreht, damit kann ich die Spiele laden. ..Für Sohnemann als Daddelmaschine..schaunmermal.. Gruß, Holm
A. K. schrieb: > Winfried J. schrieb: >> schau dir mal den Tinibasic interpreter an der stammt aus dem UB8830 den >> solltest du leicht portiern können > > Nochmal <grins>. Von Z8 auf Z80 macht keinen Spass. Z8 ist die > eleganteste 8-Bit Mikrocontroller-Architektur für > Assembler-Programmierung, der ich begegnet bin, wenn man mit den 256 > Bytes Datenadressraum auskommt. eZ8 hat da gezwungenermassen schwer > nachgelassen. > > Es zeugt von gutem Geschmack, dass sie "drüben" die Z8 abgekupfert > haben, statt Fairchilds F8. "Die" haben alle Z abgekupfert. Z80,Z8,Z8000. Ich habe hier auch ein Unix (Wega) mit 4 Mhz Z8000. Gruß, Holm
Holm Tiffe schrieb: > Aber ich würde statt Dataflash eine Micro-SD Karte empfeheln, die kann > man auf dem PC ggf. "von außen" laden/sichern/ändern. Oder das, am Interface ändert das wenig. Ich hatte eher die Organisation gemeint. Ein relativ komplexes Filesystem wie FAT ist im Grunde völlig unnötig. Er wird das System wohl kaum intensiv fileorientiert betreiben, wird den Compiler nicht auf die Z80 verlagern (so wars bei Retro in echt) sondern braucht den Platz nur für ein paar Programm-Images.
Holm Tiffe schrieb: > Ja, aber ein Kassetteninterface wäre "Retro" :-) > Sowas geht heute aber auch mit einem MP3 Bläher... Ja, das wärs, analog mit FSK via MP3 Player auf µSD. ;-)
Holm Tiffe schrieb: > ..Für Sohnemann als Daddelmaschine..schaunmermal.. Ähm.... glaube meiner würde auswandern...... unter XBOX One mit Headset und Gamer Account bei GTA geht da nix mehr....
A. K. schrieb: > Oder das, am Interface ändert das wenig. Ich hatte eher die Organisation > gemeint. Ein relativ komplexes Filesystem wie FAT ist im Grunde völlig > unnötig. Ich habe die Chan Fat erfolgreich auf einem LPC2368 ARM7 zum Laufen gekriegt. Nur die PHY dazu aus dem Netz besorgt und eingebunden. Einen Block Treiber haabe ich 2007 mal für PIC mit CCS geschrieben, einfach nur Blocks ansprechen als Filenummern. Außerdem gibts das fertig bei Arduino als Lib für die SPI. Plug & play. Nur die SPI anpassen, Header inkludieren und feddich. Das wäre es also nicht. Passt allerdings kaum mehr in 8kb EPROM rein, sidn deutlich mehr als 32KB, dei FAT des Arduino. Ixh kann nur noch eine zweite Euro karte nehmen und den Rechner auf der anderen Seite weiter bauen, die beiden über Drahtstege oder Kleber etc miteinander verbinden. habe leider nicht dran gedacht mehr Platz zu beschaffen, dachte das bleibt bei einem Minimal System. Bzw sind wir dann schon bei V2 und einer Messerleiste für den Rechner, einem Rückwandbus, vielleicht schon bei einem DMA Controller... und jede Menge Zeit zu haben das zu machen ;-(
Und bevor ich mich schon weit in die Zukunft vergallopiere werde ich erstmal den Ringpuffer fertig machen, den ich für die Uart geschrieben habe. Der muss noch gestestet werden, da ich den Fall eines Überlaufes auch abfangen muss und schauen, ob kein Byte verschwindet am Array Ende, kennt das ja mit > und >= und dass da schonmal Fehler passieren.
1 | uint8_t rx_buffer[RX_BUF_LAST+1]; // Buffer für Zeichenempfang |
2 | uint8_t rx_rd_ptr = 0; // Read Pointer, nur durch Hauptprogramm lesen |
3 | uint8_t rx_wr_ptr = 0; // Write Pointer, nur durch Interrupt schreiben |
4 | |
5 | |
6 | uint8_t rx_buf_full = FALSE; // Es sind Zeichen da |
7 | uint8_t rx_buf_crash = FALSE; // WR Zeiger hat RD überholt: Buffer wertlos |
8 | |
9 | |
10 | // Löscht den Buffer und setzt Zeiger auf 0 |
11 | void clear_rx_buffer() |
12 | { |
13 | rx_wr_ptr = 0; |
14 | rx_rd_ptr = 0; |
15 | rx_buf_full = FALSE; |
16 | rx_buf_crash = FALSE; |
17 | } |
18 | |
19 | /* |
20 | Holt ein Zeichen aus dem Buffer für das Hauptprogramm |
21 | Darf nur von getchar aufgerufen werden, wenn rx_buf_full = TRUE ist! |
22 | |
23 | */ |
24 | |
25 | char rx_read_char() |
26 | { |
27 | static char ch; |
28 | |
29 | // Keine Zeichen da? |
30 | if (!rx_buf_full) |
31 | return(0); |
32 | |
33 | // RX Int aus, da Lesezugriff |
34 | __asm |
35 | di |
36 | __endasm ; |
37 | |
38 | // Zeichen auslesen |
39 | ch = rx_buffer[rx_rd_ptr++]; |
40 | |
41 | // Read Pointer am Array Ende zurück setzen |
42 | if (rx_rd_ptr > RX_BUF_LAST) |
43 | rx_rd_ptr = 0; |
44 | |
45 | // Alle Zeichen gelesen? Dann liegen Pointer übereinander |
46 | if (rx_rd_ptr == rx_wr_ptr) |
47 | rx_buf_full = FALSE; |
48 | |
49 | __asm |
50 | ei |
51 | __endasm ; |
52 | |
53 | return(ch); |
54 | } |
55 | |
56 | |
57 | ///////////////////////////////////////////////////////// |
58 | // Handler der Mode 2 Interrupts der STI |
59 | |
60 | void int_sti_receive_buffer_full(void) __interrupt |
61 | { |
62 | static char zeichen; |
63 | static char crash = 0; |
64 | |
65 | zeichen = STI_UDR; |
66 | PIO8255_PORT_A = ~zeichen; |
67 | |
68 | // Ringpuffer beschreiben |
69 | rx_buffer[rx_wr_ptr] = zeichen; |
70 | |
71 | // wr Zeiger auf letztem Element? |
72 | if (++rx_wr_ptr > RX_BUF_LAST) |
73 | rx_wr_ptr = 0; // Zeiger zurück setzen |
74 | |
75 | // WR==RD oder WR > RD: Buffer Crash |
76 | rx_buf_crash = (rx_wr_ptr==rx_rd_ptr); |
77 | |
78 | rx_buf_full = TRUE; // Meldung an Hauptprogramm: Zeichen ist da |
79 | |
80 | __asm |
81 | ei |
82 | __endasm ; |
83 | } |
@Frank M: Als C Spezi ...... mir haut ndie Verwendung von sprintf(buf.. locker 6 kb weg und ich habe nur 8. Aber wenn ich was Gescheites ausgeben will mti Variablen brauche ich das natürlich. Float muss nicht sein aber %s,%d,%x schon. Entweder ich rupfe die Adressleitungen wieder auseinander und hole mir 16KB ROM und nur 48kb RAM oder ich finde eine Lösung Gemischte Strings preiswerter auszugeben als mit sprintf. Die mcurses erfordert ja, dass ich auf printf verzichte und stattdessen sprintf(buf, <Stringausdruck>) add(<stringbuffer>) benutze. Idee?
Christian J. schrieb: > Passt allerdings kaum mehr in 8kb EPROM rein Eben. Dass du den FAT Code nicht selbst zimmern würdest war klar.
Christian J. schrieb: > Als C Spezi ...... mir haut ndie Verwendung von sprintf(buf.. locker 6 > kb weg und ich habe nur 8. Und ohne (s)printf kannst du nicht leben... Obacht, auch 64kB reichen nicht ewig, wenn du in dem Schema weiter denkst und allein für sprintf fast sowiel Platz brauchst wie Rockwell für einen kompletten Compiler.
:
Bearbeitet durch User
Christian J. schrieb: > Holm Tiffe schrieb: >> ..Für Sohnemann als Daddelmaschine..schaunmermal.. > > Ähm.... glaube meiner würde auswandern...... unter XBOX One mit Headset > und Gamer Account bei GTA geht da nix mehr.... Sowas gibts in meinem Haushalt nicht. Computer,Elektronik,Basteln ja. Bei ständig Glotze werde ich ätzend und einen Gameboy habe ich schon mal höchstpersönlich zerlatscht da die von Nachwuchs gesetzten Prioritäten justiert werden mußten. Seit Jahrzehnten repariere ich elektronischen Krempel, die Aktion ging mir total gegen den Strich, aber sie hat wie gewünscht gewirkt. Deswegen werfe ich dem Kurzen auch speziell so olle Computer vor, da kann man auch mal ein Relais anschließen und was steuern. o.ä... Das ist aber noch Zukunft. Wenn Deiner auswandern will wegen nicht möglicher Daddelei hast Du erzieherisch was versaut. @Christian: Komm,komm.. diesen Ringpuffer schaffst Du auch in Assembler, das ist eigentlich Pillepalle auf einem Z80. Da die Sache Deiner Meinung nach zeitkritisch ist, ist das eine gute Gelegenheit mal 3 ASM Befehle des Z80 zusammenzurühren. Hier gibts genug Leute die Dir dabei helfen. Gruß, Holm
Tjaaaaa..... aber wenn sprintf einmal drin ist sind alle weitere Aufrufe eben nur Calls. und da fange ich grad an meine schöne Kämme zu hassen, denn um auf 16KB aufzubohren muss ich umverdrahten. A13 | A14 | A15 => CS für 0x0000 - 0x1fff ROM, darüber RAM für 0x0000 - 0x2fff ROM wäre das A14 | A15 also A13 abknipsen, Pin auf "1" legen, dazu am EPROM 1 Adressleitung mehr anschliessen. Am RAM bleibt alles wie gehabt, liegt ja eh unter dem EPROm. Leider kann ich dann auch die schönen 8KB EEPROM wegwerfen, die ich bestellt hatte um das Löschen zu vermeiden. >einen Gameboy habe ich schon mal höchstpersönlich zerlatscht da die von >Nachwuchs gesetzten Prioritäten justiert werden mußten. Ähmm..... Demokratie? DDR Erziehung? :-) Ja, Ringbuffer in Asm ist recht überschaubar und eine gute Übung. leider nur kann ich Asm nicht debuggen, habe nur inline Assembler und wenn da Fehler drin sind endet das in Ausprobieren, weil eben einen printf dazwischen geht leider nicht.
Holm Tiffe schrieb: > Komm,komm.. diesen Ringpuffer schaffst Du auch in Assembler, > das ist eigentlich Pillepalle auf einem Z80. Da die Sache Deiner Meinung > nach zeitkritisch ist, ist das eine gute Gelegenheit mal 3 ASM Befehle > des Z80 zusammenzurühren. Hier gibts genug Leute die Dir dabei helfen. Und wenn er auch dazu keine Lust hat, dann nimmt er eben meinen oben schon geposteten Code für Z80-SIO, mit Puffer und Hard- und Software-Handshake, und transponiert ihn auf STI. ;-)
Christian J. schrieb: > Tjaaaaa..... aber wenn sprintf einmal drin ist sind alle weitere Aufrufe > eben nur Calls. Wie hast du eigentlich in Pascal ohne printf programmiert? ;-)
Ob das mal lohnt..... das ist der komplette Asm der INT Routine, Leseroutine ist unkritisch, hauptsache die STI ballert die anrollenden Truppen der Zeichen Kollonnen ins Quartier hinein.
1 | ;interrupt.c:90: ch = rx_buffer[rx_rd_ptr++]; |
2 | ld de,#_rx_buffer+0 |
3 | ld hl,#_rx_rd_ptr + 0 |
4 | ld b, (hl) |
5 | ld hl, #_rx_rd_ptr+0 |
6 | inc (hl) |
7 | ld l,b |
8 | ld h,#0x00 |
9 | add hl,de |
10 | ld a,(hl) |
11 | ld iy,#_rx_read_char_ch_1_11 |
12 | ld 0 (iy),a |
13 | ld a,#0x50 |
14 | ld iy,#_rx_rd_ptr |
15 | sub a, 0 (iy) |
16 | jr NC,00104$ |
17 | ld iy,#_rx_rd_ptr |
18 | ld 0 (iy),#0x00 |
19 | 00104$: |
20 | ld a,(#_rx_rd_ptr + 0) |
21 | ld iy,#_rx_wr_ptr |
22 | sub a, 0 (iy) |
23 | jr NZ,00106$ |
24 | ld iy,#_rx_buf_full |
25 | ld 0 (iy),#0x00 |
26 | 00106$: |
27 | ;interrupt.c:102: __endasm ; |
A. K. schrieb: > Wie hast du eigentlich in Pascal ohne printf programmiert? ;-) Da hatte ich writeln :-)
PS: Ausserdem wirkt ein printf in 6kB ziemlich aufgeblasen. Ok, Z80 ist kein AVR, aber Leute haben schon Mega8 mit printf programmiert und der hat nur 8KB ROM insgesamt. Das kann man reduzieren, indem nicht zwingend nötige Formatvariationen rausfliegen.
Christian J. schrieb: > leider nur kann ich Asm nicht debuggen, Ach? Dabei hat dein Board meiner vagen Erinnerung nach einen wunderhübschen Debug-Port mit LED-Anzeige drauf. Wie geschaffen fürs lowlevel-debugging in Assembler.
und das ist readchar
1 | ; --------------------------------- |
2 | ; Function rx_read_char |
3 | ; --------------------------------- |
4 | _rx_read_char_start:: |
5 | _rx_read_char: |
6 | ld iy,#_rx_buf_full |
7 | ld a,0 (iy) |
8 | or a,a |
9 | jr NZ,00102$ |
10 | ld l,a |
11 | ret |
12 | 00102$: |
13 | di |
14 | ld de,#_rx_buffer+0 |
15 | ld hl,#_rx_rd_ptr + 0 |
16 | ld b, (hl) |
17 | ld hl, #_rx_rd_ptr+0 |
18 | inc (hl) |
19 | ld l,b |
20 | ld h,#0x00 |
21 | add hl,de |
22 | ld a,(hl) |
23 | ld iy,#_rx_read_char_ch_1_11 |
24 | ld 0 (iy),a |
25 | ld a,#0x50 |
26 | ld iy,#_rx_rd_ptr |
27 | sub a, 0 (iy) |
28 | jr NC,00104$ |
29 | ld iy,#_rx_rd_ptr |
30 | ld 0 (iy),#0x00 |
31 | 00104$: |
32 | ld a,(#_rx_rd_ptr + 0) |
33 | ld iy,#_rx_wr_ptr |
34 | sub a, 0 (iy) |
35 | jr NZ,00106$ |
36 | ld iy,#_rx_buf_full |
37 | ld 0 (iy),#0x00 |
38 | 00106$: |
39 | ei |
A.K: In der 51er SDCC Variante gibt es printf light, ohne Float. In der Z80 habe ich die aber nicht gefunden. Float hat die aber auch nicht sondern spuckt nur <NOFLOAT> aus. printd verbraucht 3,5 kb, sprintf fast 6KB.
A. K. schrieb: > Ach? Dabei hat dein Board meiner vagen Erinnerung nach einen > wunderhübschen Debug-Port mit LED-Anzeige drauf. Wie geschaffen fürs > lowlevel-debugging in Assembler. Holm,. wie oft wollen wir die Kartoffel jetzt noch umdrehen? HALT hat eine LED dran, NMI liegt auf einenm Taster. NMI kann man auch wonaders anschliesse, weiss ich. Aber mit Fädelkämmen ist da eine Grenze, nämlich das ist ein write only Board, von modify-read ist da keine Rede mehr. Einmal verdrahtet ist Ende im Gelände. Ich werde heute nachdem Spaziergang im schönen Herbstwald noch auf 16KB ROM umverdrahten und dann soll es gut sein. Ohne sprintf geht es nicht. und wenn ich hier nahc links schaue, da liegt ein ARM7 Board, 512 KLB Flash, 60KB RAM, über 100 IO Pins, 3 Uarts, 5 GPIOs, 3 SPIs, 10 Timer usw. Wieso nehme ich das nicht? :-)
Schau mal, ob dir das weiterhilft. Evtl. Datentypen anpassen. Hast du eigentlich jemals was selber programmiert? Also so richtig.
:
Bearbeitet durch User
A. K. schrieb: > Hast du eigentlich jemals was selber programmiert? Also so richtig. Ja, sogar viele tausend Zeilen pro Projekt (VB und C#) aber wenn es geht nehme ich fertige Sachen ...
Christian J. schrieb: > Holm,. wie oft wollen wir die Kartoffel jetzt noch umdrehen? Ein Holm ist für mich ein Flugzeugteil. ;-) Nix NMI, HALT etc. Deine LED-Anzeige ist wie printf, nur mit weniger Platz drauf. Wenn ich auf AVRs debugge, dann höchst selten per JTAG, meistens ohne. Der STK500 hat 8 LEDs drauf, so macht man Debugging.
A. K. schrieb: > Der STK500 hat 8 LEDs drauf, so macht man Debugging. AK, für mich war Debugging bisher dass ein gelber Balken im Source Code herum läuft, dass ich links hardware Break Points gesetzt habe, rote pfeile da stehen und Fenster wo ich eine Watchliste habe, die ich mir selbst aussuchen kann. Ebenso ein Stack Fenster, einen laufzeit Analyser usw. Du weisst wie eine Keil IDE aussieht für ARM? Oder Rowley IDE mit JTAG Interface? Das ist wei Mercedes fahren, statt Fiat panda. Und davon muss man erstmal runter kommen.....
Christian J. schrieb:Entwicklungsumgebung > AK, für mich war Debugging bisher dass ein gelber Balken im Source Code > herum läuft, dass ich links hardware Break Points gesetzt habe, Ist mir schon klar. Hoffnungslos verwöhnt. :-) Bloss ist es ziemlich verwegen, sich an ein Retro-Projekt zu setzen und den gleichen Luxus vorauszusetzen. Wenn du Z80 Retro programmieren willst, dann solltest du nicht erwarten, eine Developer Studio mit allem Gedöns vorzufinden. Sondern eben Retro. Und dabei bist du immer noch viel besser dran als jene, die Retro programmierten als das noch Hightech war. Du hast nämlich einen PC daneben, mit Compiler, Editor usw. Hatte man damals nicht. > Oder Rowley IDE mit JTAG Interface? Weiss ich, hab ich, mache ich. Aber ich kann auch ohne.
Christian J. schrieb: > Ähmm..... Demokratie? DDR Erziehung? :-) Nö, just "old style". Wenn Hausaufgaben nicht mehr erledigt werden und die Zensuren auf dreiviertel 12 hängen gibt es keine Demokratie mehr, basta. Ich halte es da bezüglich Demokratie (die wir eh nicht haben, wir haben eine Korruption als Gesellschaftsform) wie Volker Pispers. > > Ja, Ringbuffer in Asm ist recht überschaubar und eine gute Übung. leider > nur kann ich Asm nicht debuggen, habe nur inline Assembler und wenn da > Fehler drin sind endet das in Ausprobieren, weil eben einen printf > dazwischen geht leider nicht. Mach nix. Wieviele Timer Kanäle hat eigentlich so eine STI? bei einem CTC konnte man z.B. den Kanal3, der eh keinen Ausgang hat,so programmieren, dass er nach jedem Befehl einen Interrupt auslöst. Damit läßt sich Software-Schrittbetrieb bewerkstelligen. Ein oller DDR Computer, der MC80.2x hatte ein Zeilenassembler-Disassembler-Testsystem, das beste was ich kenne um Z80 Code zu debuggen... Ich habe die Disassemblierten und kommtentierten Assembler Quellen dafür von Lochstreifen gerettet. Kannste haben wenn Du willst. Gruß, Holm
A. K. schrieb: > Und dabei bist du immer noch viel besser dran als jene, die Retro > programmierten als das noch Hightech war. Du hast nämlich einen PC > daneben, mit Compiler, Editor usw. Hatte man damals nicht. > >> Oder Rowley IDE mit JTAG Interface? > > Weiss ich, hab ich, mache ich. Aber ich kann auch ohne. Hier gibts auch printf mit 1.2kb für 8 Bitter http://www.sparetimelabs.com/tinyprintf/tinyprintf.php Und wie haben die damals entwickelt? Natürlich an einem PC bzw CPM oder was auch immer? Ich weiss doch noch wie das n der Schule war, allerdings auch 1984 war es da schon. Wie wurden denn Spiel für den C64 gemacht? Doch nicht auf dem C64 selbst sondern auf einer größeren Maschine. Es gab WEerkzeuge, jede Menge aber die habe ich nicht und wenn könnte ich damit nicht umgehen.
Holm Tiffe schrieb: > Wieviele Timer Kanäle hat eigentlich so eine STI? Einer geht weg für die Baudrate, bleiben drei.
A. K. schrieb: > Holm Tiffe schrieb: >> Wieviele Timer Kanäle hat eigentlich so eine STI? > > Einer geht weg für die Baudrate, bleiben drei. Und wenn man Reload = 1 setzt wird bei jedem Takt ein Interrupt ausgelöst, da der CTC am Takt dran hängt. Da ein Int aber nur ausgelöst wird, wenn ein Bfehl abgearbeitet wurde kann man damit Einzelschritt machen. Das mit dem Lochkartenleser ist cool, das hätte was. Rrrrr....ratter.... oder beseht da doch die Gefahr in die Steinzeit zu kommen? Haben damals als Kind mit Vater Streifen gespielt, der bracht Lochband immer mit vom Telex. Für Holm: https://www.youtube.com/watch?v=xqlY0QLmVtw https://www.youtube.com/watch?v=EapLXvQ4pt8
Christian J. schrieb: > Und wie haben die damals entwickelt? Kommt drauf an wer "die" waren. Die wirklich professionellen Entwickler in den 70ern hatte manchmal In-Circuit-Emulatoren. Und Maschinen der PDP-11 Klasse als Entwicklungssysteme für Mikrocomputer, klar. Mit in FORTRAN programmiertem Crossassembler und so. Aber das war insgesamt gesehen eine winzige Minderheit. Die vielen Bastler programmierten barebone-mässig. Anders als Daddler heute hatte man selber in 70ern nicht fertig programmierte Spiele gekauft, sondern selber an den Kisten rumgebastelt und programmiert. Und hatte eben keinen Minicomputer daneben, sondern genau das was als "Computer" da war, nicht mehr. Und das war in meinem Fall ein AIM65 mit 4KB RAM, einer einzeiligen Anzeige aus 20 alphanumerischen LEDs und einem 20-stelligen Thermodrucker à la Registrierkasse. Und immerhin einer kompletten Tastatur. Nix Bildschirm. Massenspeicher war Muttis Kassettenrecorder. Und so konnte man wirklich Programme schreiben. Darauf baute man dann auf und erweiterte. Echten Drucker dranhängen. Floppy-Controller-Karte bauen und dranhängen, mit besagtem 8-Zoll Laufwerk. Filesystem dafür bauen (in FORTH). Bildschirmkarte besorgen (die war ein Bausatz) und dranhängen. Und bis der Bildschirm funktioniert programmiert man eben mit besagtem 20-stelligen LED-Display. > Es gab WEerkzeuge, jede Menge aber die habe ich nicht und wenn könnte > ich damit nicht umgehen. Die hatte auch sonst kaum einer.
Ok..... da die Werkzeuge heute aber wensentlich besser sind hat sich die Entwicklung auch mit exponentuieller Geschwindigkeit A. K. schrieb: > Die hatte auch sonst kaum einer. Ich habe damals für den C64 ein Speeddos implementiert und eine Parallelleitung an die 1541 gelötet. Dazu musste auch für den C64 was geschrieben werden. In 6502 Assembler, wie vieles damals. Da der Schaltplan und der ROM Coder der 1541 offen waren bzw irgendwo her kamen ging das. Da war ich 18.
Christian J. schrieb: > In 6502 Assembler, wie vieles damals. Und diese Techniken hast du mittlerweile vollständig vergessen?
Christian J. schrieb: > Ok..... da die Werkzeuge heute aber wensentlich besser sind Ok, der Compiler ist auf dem PC. Aber der in den letzten 10 Jahren sehr beliebte ATmega8 hat kein JTAG. Debugging, so wie du dir das vorstellst, ist mit diesem Teil technisch ummöglich.
A. K. schrieb: > Und diese Techniken hast du mittlerweile vollständig vergessen? Ja, vieles ist "weg". Schade aber im Hirn ist nur Platz für 100%. Kommt was dazu muss einiges vergessen werden. Und 30% sind bestimmt derzeit mit Normung im Bereich der Maschinenrichtlinie ausgefüllt. Meinem Beruf eben. Mein C64, der meine Eltern 1200 DM gekostet hatte landete wegen dem idiotischen Hausmeister auf dem Sperrmüll und war sofort weg, genau wie vielen Disketten Wannen. Allerdings habe ich den auch nie wirklich vermisst und die restlichen Disketten sind leider nicht mehr lesbar mit dem vielen Asm Code und UCSD Pascal war es auch dafür gab. Habe es vor 3-4 Jahren mal ausprobiert bei einem Bekannten, Bad Blocks überall.
A. K. schrieb: > Ok, der Compiler ist auf dem PC. Aber der in den letzten 10 Jahren sehr > beliebte ATmega8 hat kein JTAG. Debugging, so wie du dir das vorstellst, > ist mit diesem Teil technisch ummöglich. Häh? das ging schon 1997 mit einem PIC und der MPLAB IDE. Da wurden einfach Software Breakpoints gesetzt, die einen Int aufriefen. Mit dem teuren Hardware Debugger sogar HW breakpoints. Luxus. Arduino ist da Mist gegen, der hat nichts.
Christian J. schrieb: > Häh? das ging schon 1997 mit einem PIC und der MPLAB IDE. Mit dem ATmega32 und JTAG-Adapter auch. Aber eben nicht mit dem ATmega8. Der funktioniert ziemlich exakt so wie dein Board. Mehr als einen Bootloader (d.h. Atmels Programmierschnittstelle) gibts nicht.
:
Bearbeitet durch User
Glaube ohne JTAG und einem "Wiggler" könnte ich heute gar nicht mehr arbeiten... das war die Erlösung als dass Ende der 90iger aufkam und zum Standard wurde, endlich In-Target programmieren und testen zu können. Bei PIC wurden damals Spezial Asics gebaut, die einen PIC Core enthielten aber eben auch Debug Strukturen. Habe einige von den Probes gehimmelt damals. Glaube 2500 DM das Hauptgerät und jede Probe so um die 500 DM :-) Ok. bis später mal.
Christian J. schrieb: > Glaube ohne JTAG und einem "Wiggler" könnte ich heute gar nicht mehr > arbeiten... Merkt man. Schlechte Basis für Z80 Retro.
Christian J. schrieb: > Als C Spezi ...... mir haut ndie Verwendung von sprintf(buf.. locker 6 > kb weg und ich habe nur 8. Vergiss sprintf(). Du hast einen Z80 - mehr nicht. Aber wenn ich was Gescheites ausgeben will > mti Variablen brauche ich das natürlich. Float muss nicht sein aber > %s,%d,%x schon. Der Hex-Editor gibt doch auch Hex-Zahlen aus: Siehe Funktion itoxx(). Das reicht. Integer-Zahlen gehen auch: Schau Dir mcurses_puti() an. Okay, das gibt nur 3-stellige Integers aus (Das reicht hier), lässt sich aber auch auf 5-stellige Zahlen (max. 65535 = 0xFFFF) leicht erweitern. Die 3-stellige Ausgabe ist "loop-unrolled", lässt sich aber leicht wieder zu einer Schleife umbauen, die X Stellen ausgeben kann. > Entweder ich rupfe die Adressleitungen wieder auseinander und hole mir > 16KB ROM und nur 48kb RAM oder ich finde eine Lösung Gemischte Strings > preiswerter auszugeben als mit sprintf. Unsinn. Du solltest Dir lieber einen Bootloader für Deinen Z80 stricken, damit er er Programme (Anwendungen) ins RAM laden kann. > Die mcurses erfordert ja, dass ich auf printf verzichte und stattdessen > > sprintf(buf, <Stringausdruck>) sprintf() ist viel zu fett! Für %d und %x reicht obiges, das sind ein paar hundert Bytes.
A. K. schrieb: > Holm Tiffe schrieb: >> Ja, aber ein Kassetteninterface wäre "Retro" :-) >> Sowas geht heute aber auch mit einem MP3 Bläher... > > Ja, das wärs, analog mit FSK via MP3 Player auf µSD. ;-) MP3 ist wegen der verlustbehafteten Kompression problematisch. Aber Christian könnte ja SOUNDRX vom ATmega auf den Z80 portieren. Dann kann er den Z80 mit Daten über die Soundkarte füttern - durch Abspielen von WAV-Dateien. Ein PC-Programm, welches Daten in WAV-Dateien überführt, ist beim SOUNDRX-Paket dabei.
Frank M. schrieb: > Unsinn. Du solltest Dir lieber einen Bootloader für Deinen Z80 stricken, > damit er er Programme (Anwendungen) ins RAM laden kann. Hat er doch schon, ich spiele über die uart die Soft ein, Reset startet die auch wieder..... Strom weg = Programm weg. Oder ick packe einen meiner Modellflug Lipo Akkus davor und der übernimmt dann (kurzzeitig). Intel Hex Decoder ist in Arbeit, weil meine Lösung etwas "unschön ist", ich muss die Dateilänge per echo und stat -C.... File dem Z80 mitteilen.
Hier ist ne fertige Sparversion, auch von sprintf.... über Schalter lässt sich genau einstellen was man haben will... natürlich kein Float. 1,2kb.
Frank M. schrieb: >> Ja, das wärs, analog mit FSK via MP3 Player auf µSD. ;-) > > MP3 ist wegen der verlustbehafteten Kompression problematisch. Bei simplem FSK auch? Es geht in diesem Kontext ja nicht um QAM64. Aber mir ging es eher um die Absurdität des Umwegs über Töne, um dann doch wieder auf dem digitalen Medium SD-Karte zu speichern.
An meinem 8085 damals habe ich 2 Tongeneratoren angebaut, 1,2 und 2,4khz mit NE555 für 0 und 1, die gingen auf einen Kassettenrekorder. Direktory war der Zaehlerstand. Geht aber auch so derzeit, der Upload meine ich.
1 | TARGET := z80rom |
2 | INTERFACE := /dev/ttyUSB0 |
3 | |
4 | CODE_LOC := 0x2100 |
5 | DATA_LOC := 0x8000 |
6 | |
7 | [....] |
8 | |
9 | upload: |
10 | @echo "----------------------------------------------------" |
11 | @echo " >>> Dateitransfer zum Z80" |
12 | @echo "----------------------------------------------------" |
13 | stty 9600 raw -parenb -crtscts -ixoff -F $(INTERFACE) |
14 | echo "load" > $(INTERFACE) |
15 | stat -c %s $(TARGET).bin > $(INTERFACE) |
16 | @echo "Uebertrage Daten...." |
17 | cat $(TARGET).bin > $(INTERFACE) |
18 | echo "start" > $(INTERFACE) |
19 | @echo "User programm Upload fertig!...Run!" |
Christian J. schrieb: > A. K. schrieb: >> Holm Tiffe schrieb: >>> Wieviele Timer Kanäle hat eigentlich so eine STI? >> >> Einer geht weg für die Baudrate, bleiben drei. > > Und wenn man Reload = 1 setzt wird bei jedem Takt ein Interrupt > ausgelöst, da der CTC am Takt dran hängt. Da ein Int aber nur ausgelöst > wird, wenn ein Bfehl abgearbeitet wurde kann man damit Einzelschritt > machen. > > Das mit dem Lochkartenleser ist cool, das hätte was. Rrrrr....ratter.... > oder beseht da doch die Gefahr in die Steinzeit zu kommen? Haben damals > als Kind mit Vater Streifen gespielt, der bracht Lochband immer mit vom > Telex. > > Für Holm: > > > https://www.youtube.com/watch?v=xqlY0QLmVtw > > https://www.youtube.com/watch?v=EapLXvQ4pt8 Ähh.. hinter mir auf dem Fußboden, mitten im Sediment steht ein Lochstreifenleser. Der Stanzer steht im Lager. Meinst Du das Du Holz in den Wald tragen mußt? Ich sagte "Ich habe das von Lochstreifen gerettet", das heißt nicht, das ich damit Jemand anderen belästigt hätte :-) Da hängt ne Platine mit Atmega16 am Leser.. Ich habe auch einen A5120, der steht allerdings im Lager. Hier zu Hause habe ich einen K8924 der einen zum A5120 äquivalenten Inhalt hat, man kommt aber vor vorne an die Karten ran weshalb das Ding besser zum Basteln ist... nix Neues im Osten also :-) Gruß, Holm
Nun Holm, es gibt sicher nichts was Du nicht hast :-) Und solltest du mal ableben müssen wir dein Hirn konservieren damit das alles nicht verloren geht. Ich habe auchn noch sowas hier wie auf dem Bild, ein Teac Laufwerk für Musik. Und noch 3 Bänder dafür. gab mal ne Zeit um 2000 herum, da wolte ich unbedingt einen Tape Streamer im Wandformat haben, um darin eine Hife Anlage unter zu bringen aber leider keinen bekommen, wurden wohl alle entsorgt damals. Und die Nasa rennt sich die Hacken danach ab, da die Daten der Mondlandung auch so gesichert wurden und nicht mehr lesbar sind heute. Vielleicht hast du ja sowas "auf Lager"+
sehe ich da einen Nakamichi RX-505 im Hintergrund :-) Die 9spur-Computerbänder waren 1/2 Zoll breit. Müsstest Du also der Länge nach halbieren, damit sie auf die Teac passen. 9spur-Maschinen gibt es regelmäßig auf ebay, und bei d.a.f.c wechselt auch ab und zu mal eine den Besitzer.
Ich habe ein iDigital TSZ70 und ein CM5300.01 aus Bulgarien an 9 Track Tapes für Daten. Dazu gesellen sich die Unterschiedlichsten Streamer wobei ich ein Ultrium 2 aktuell zur Sicherung benutze. Ein Grundig TS945, ein Tesla B115 (braucht neue Riemen, ist gerade erst aufgelaufen), einen Jupiter 204, ein BG20 Smaragd und ein BG19 habe ich an Audiobandgeräten, Kassettenzeuch nix Besonderes DDR Kram und irgendwas von Sony. Deine TEAC ist nett aber das hier wäre mein Traum: http://latemag.com/panasonic-design-museum Gruß, Holm
Holm Tiffe schrieb: > Deine TEAC ist nett aber das hier wäre mein Traum: > > http://latemag.com/panasonic-design-museum Weisst du was diese Dinger kosten? Schon damals? Das war High End, das Beste vom Besten? Revox war da Marktführer drin. Das Bild ist aus dem Netz, den Teac habe ich damals günstig bekommen, 250 Euro nur. Ich finde es stilechter wenn sich da was dreht. Hast Du mal Bilder von Deinen Streamern? Kaputt ist egal! Sollen nur gut aussehen :-) Gruss, Christian
Ja ich weiß was die Technics kostet, deswegen habe ich ja Keine :-( Bilder von den 9 Track Tapes habe ich gerade nicht. Ein CM5300.01 gibts hier auf Robotrontechnik.de: http://www.robotrontechnik.de/bilder/Grossrechner/K1600/Bandlaufwerk_CM5300/Bandlaufwerk_CM5300_k.jpg http://www.robotrontechnik.de/index.htm?/html/zubehoer/mbe.htm Das TSZ70 heißt eigentlich TSZ07, ein paar Bilder vom Gerät und seinem Netztzteil an das ich noch mal ran muß gibts hier bei mir: http://www.tiffe.de/Robotron/TSZ07/ Das Netzteil funktioniert zwar, aber im Standby ohne Lüfter wird da der Kram drin zu heiß. Das Ding steht eine Etage tiefer in einer Abstelle. Gruß, Holm
Holm Tiffe schrieb: > Ja ich weiß was die Technics kostet, deswegen habe ich ja Keine :-( Hier ist eine für dich: http://www.ebay.de/itm/TECHNICS-RS-1700-TOP-Zustand-komplett-uberholt-gewartet-und-neu-eingemessen-/321555481281?pt=Bandmaschinen&hash=item4ade3342c1 Taschengeld!
Weiter gehts mit der Extension Platine. Mit einem DIY Busadapter mangels Platz für Messerleiste etc. Geplante HW da drauf: 2 Stück 7-Segment Leisten a 8 Digits mit Maxim Interface Controller (Libs schon da, daher easy), einige LEDs noch dazu, 1 Timer 8254 (Uhrenn kann man nie genug haben), einer Taktquelle für eine Uhr, vieleicht auch ne RTC dazu, und vor allem eine Art latenten Datenspeicher, vermutlich einen AVR oder PIC mit 64k I2C EPROM dran oder eine Compact Flash karte. Entwder am I/O Bus selbst oder an einer GPIO. Das muss ich mal sehen...
Christian J. schrieb: > Hat er doch schon, ich spiele über die uart die Soft ein, Reset startet > die auch wieder..... Strom weg = Programm weg. Aha. Ich dachte, Du müsstest immer noch jedes mal ein EPROM brennen ;-) Der Full-Screen-Hex-Editor ist übrigens fertig, siehe Anhang. Tasten: Links - Ein Byte zurück Rechts - Ein Byte vor Rauf - Eine Zeile rauf Runter - Eine Zeile runter TAB - Wechsel zwischen Hex- und ASCII-Spalten 2 x ESCAPE - Exit Jede andere Taste bewirkt ein Ändern der aktuellen Speicherstelle. In den HEX-Spalten: - Es müssen 2 gültige Hex-Ziffern eingegeben werden, es werden also nur 0-9, A-F oder a-f akzeptiert. In den ASCII-Spalten: - Es muss ein druckbares Zeichen eingeben werden. Eingebene Werte ändern sofort WYSIWYG den Speicher. Die Anzeige wird sowohl in der HEX- als auch in der ASCII-Spalte aktualisiert. Die Eingabe muss NICHT mit CR (=Enter) bestätigt werden. Man könnte jetzt noch die Bild-Tasten zum seitenweisen Blättern einbauen, bzw. Pos1 und Ende zum Positionieren innerhalb der Zeilen (Sprung zu Anfang, Ende). Ist relativ einfach, kostet aber zusätzlichen Code im Binary. Ich weiß nur nicht, wieviel Komfort Du möchtest ;-) Die ASCII-Anzeige habe ich noch erweitert: Es werden nun auch druckbare 8-Bit Zeichen wie Umlaute korrekt angezeigt. Dafür wichtig ist, dass Deine Terminal-Emulation irgendeinen ISO8859-Zeichensatz (vorzugsweise ISO8859-1 oder ISO8859-15) verwendet. UTF-8 ist dafür ungeeignet. Passt auch nicht ins Retro-Muster ;-) Viel Spaß, Frank
:
Bearbeitet durch Moderator
Danke ! :-)
Läuft hexedit allein durch include des Headers oder muss ich es zu dem
anderen Grundmodul dazu linken?
>>Aha. Ich dachte, Du müsstest immer noch jedes mal ein EPROM brennen ;-)
Nur die ersten 100 Male.....
Christian J. schrieb: > Läuft hexedit allein durch include des Headers oder muss ich es zu dem > anderen Grundmodul dazu linken? Du musst mcurses.c und hexedit.c zusammen kompilieren und linken. Wenn Du schon ein main() hast (z.B. Dein Menü), kannst Du daraus ja hexedit() aufrufen. In diesem Fall schmeisst Du das main() aus hexedit.c raus.
:
Bearbeitet durch Moderator
Hallo, hier mal ein Gehäuse Tip gibt es ab und zu in der Bucht. Ist ein altes Industrial Touch von HP Model 3082 Was ich Persönlich daran gut finde ist die Tastatur Matrix und das Display mit der Filterscheibe die da verbaut sind. Gruß Ronny
Frank M. schrieb: > Du musst mcurses.c und hexedit.c zusammen kompilieren und linken. Wenn Dazu passend eine Antwort auf eine ältere Frage: Christian J. schrieb: > es wird langsam Zeit sich > Gedanken um die Struktur der Software zu machen, uns ob Leo Makedatei > noch ausreicht aber ioch hoffe noch mit einem einzigen Verzeichnis > auszukommen und maximal 5-8 Quelldateien. Ausreichend ist es für Deine Zwecke sicherlich. Inzwischen habe ich es aber etwas ausgebaut. Die wichtigsten Erweiterungen sind"Autodependency generation" und (optional) getrennte Build- und Output-Directories. Zufügen/ändern/löschen von Headerdateien wird erkannt, und die betreffenden C-Dateien werden ggf. neu compiliert. Da SDCC viele Dateien generiert (.rel, .asm, .lst, .rst .sym und diverse Dateien für Debugger), kann das Source-Verzeichnis schnell unübersichtlich werden, wenn man alles in einem Verzeichnis läßt. TODO: - 'make clean' löscht z.Zt. zu wenig Dateien. Immerhin besser als andersrum. ;) - Variantenunterstützung (make debug/release) - Schalter --fno-omit-frame-pointer abhängig von der SDCC-Version setzen. Der Bug, für den der Schalter ein work araound ist, ist ab SVN Revision #9096 gefixed. - ... Backup nicht vergessen. Bei Fragen fragen.
:
Bearbeitet durch User
Hi, meine Mutter wäre stolz wenn meine Sockenschublade je so aufgeräumt gewesen wäre wie dieses Skript! Teste es mal (Backup vorher :-) und schaue wie es mit Unterverzeichnisse klappt.
Christian J. schrieb: > Läuft hexedit allein durch include des Headers oder muss ich es zu dem > anderen Grundmodul dazu linken? Die Frage erinnert mich daran, daß ich vorletzten Sonntag einen längeren Artikel zu Deinem damals (tm) aktuellen Programm angefangen hatte, aber kurz vor Fertig unterbrochen wurde. Das Meiste davon scheint noch aktuell zu sein, deshalb jetzt doch noch der Text: Christian J. schrieb: > kurze Rückmeldung. Nach fixer Umarbeitung des Source auf Makefile und > einigen "extern" die zugeführt werden mussten lief die Kiste auf Anhieb. Wenn mit "Umarbeitung" war auch die Beseitigung der Includes von ganzen C-Dateien gemeint war, dann wäre deren Verteidigung weiter unten ja völlig überflüssig. Für den "Murks" gibts sowieso keine Rechtfertigung, auch kein noch so suboptimaler Windowmanager. Das C-Schlüsselwort 'extern' braucht man nur in seltenen Ausnahmefällen, wenn man ordentliche Headerdateien hat. > Weisst Du ob der Compiler feststehende Ausdrücke hat, um zb die Adresse > der Segmente (start und Ende) im Programmcode zu verarbeiten? Da würde > einiges vereinfachen wie zb Prüfsummen über den RAM Bereich usw. Compiler- und Linker-Output anschauen? Mapfile, .sym- und .rst-Files? Meiner Meinung nach solltest Du aber erst mal Dein bestehendes Gerüst auf Vorderman bringen. Das fängt bei den Compiler-Warnungen an. Stand Gestern warens ja nur zwei:
1 | driver.c:93: warning 85: in function dump_memory unreferenced function argument : 'start' |
2 | driver.c:93: warning 85: in function dump_memory unreferenced function argument : 'ende' |
3 | main.c:123: warning 196: pointer target lost const qualifier |
Die erste war genau hier Thema: Beitrag "Re: Retro Fieber: Z80 oder 68000 ?" Die 2. kann durchaus auf ein ernstes Problem hinweisen. main.h:
1 | #define uint8_t unsigned char
|
2 | #define uint16_t unsigned int
|
3 | #define sint8_t signed char
|
4 | #define sint16_t signed int
|
Sowas geht garnicht. Eigene Namen definieren für Standard-Datentypen ist eine Unsitte, die nur Verwirrung stiftet. Andere machen das um kürzere Namen schneller schreiben zu können (#define u8 unsigned char) oder weil ihr Compiler zu alt ist. Die Namen, die Du definierst gibts seit ca. ISO C99 (jedenfalls die sinnvollen). --> #include <stdint.h> einfügen, und Du hast sie.
1 | #define bool unsigned int
|
Für bool würde ja auch ein char reichen. Allerdings gibts das seit ISO C99 native als _Bool. SDCC hat das eingebaut und kann _Bool auch besser optimieren als den selbst definierten Typ. Und wenn Du lieber bool statt _Bool schreiben willst (und true/false statt 1/0) --> #include <stdbool.h>
1 | #define STACK_SIZE 0x00ff
|
2 | #define RAM_START 0x2000
|
3 | #define RAM_END (0xFFFF-STACK_SIZE)
|
4 | #define RAM_SIZE (RAM_END-RAM_START)
|
5 | #define ROM_START 0x0000
|
6 | #define ROM_END 0x1fff
|
7 | #define ROM_SIZE (ROM_END-ROM_START)
|
Laß Dir ROM_SIZE von Deinem Programm mal in dezimal ausgeben, und vergleiche den Wert mit der Angabe im EPROM-Datenblatt. Das meine ich wirklich so, ist ganz sicher eine nützliche Übung. Für RAM_SIZE gilt analog das gleiche, aber da das RAM in Deiner Schaltung ja nicht komplett addressiert wird, ist der Vergleich mit dem Datenblatt eher sinnlos. Danach wäre dann der Stack dran. 254 Byte ist möglicherweise etwas knapp, aber nicht der Punkt auf den ich hinaus will.
Fehlermeldungen bei crt0.s. Menomic error, org in REL Area usw. Die vorher nicht da waren. #define uint8_t unsigned char #define uint16_t unsigned int #define sint8_t signed char #define sint16_t signed int Sowas geht garnicht. Ich möchte das aber so haben. Für mich. :-) Schon mal was von MISRA gehört? Variablen werden da so definiert, vor jede kommt der Typ vor. Und da int überall anders ist, hier 16Bit, beim ARM 32 ist das für mich leichter zu merken. u8_MeinName
Christian J. schrieb: > Fehlermeldungen bei crt0.s. Menomic error, org in REL Area usw. so so > Die vorher nicht da waren. Was war denn vorher, und was ist nachher? > #define uint8_t unsigned char > #define uint16_t unsigned int > #define sint8_t signed char > #define sint16_t signed int > > Sowas geht garnicht. > > Ich möchte das aber so haben. Für mich. :-) Du hast den Text dazu nicht gelesen? Lesen und darüber nachdenken ist in der kurzen Zeit ja auch nicht möglich.
Wie gesagt..... nachdenken geht in der kurzen zeit eher weniger.. bool ist raus, _Bool wird genommen... weiter im Text.
Das .org in REL Area nicht geht, weißt Du ja eigentlich. Das Makefile kann da ganz bestimmt nix für. Kann es sein, daß Du mehrere crt0.s hast, und jetzt eine andere genommen hast? Den undefined-Error bekommst Du weg, wenn Du im Makefile zu den Assembler-Optionen ein 'g' zufügst. Besser wäre es aber, die Symbole in crt0.s als extern (.globl) zu deklarieren.
Spock'sche Logik: Mit dem alten Make file ging es. alt = klein = weniger Fehlermöglichkeiten. Mit dem neuen makefile, auf die gleichen Sourcen los gelassen geht es da nicht. neu = lang = mehr Fehler möglich. Zeilen wie diese define makedepend = set -e #$(CC) -MM $(CFLAGS) -o .dep/$(*F).d $< (echo -n '$(OBJDIR)/'; $(CC) -MM $(CFLAGS) $< ) >.dep/$(*F).d $(CP) .dep/$(*F).d .dep/$(*F).P $(SED) -e 's/#.*//' -e 's/^[^:]*: *//' -e 's/ *\\$$//' \ -e '/^$$/ d' -e 's/$$/ :/' < .dep/$(*F).d >> .dep/$(*F).P $(RM) .dep/$(*F).d endef sind "menschenverachtend" :-) Hier scheint es aber ok zu sein:
1 | $(STARTUPOBJ): $(STARTUP) |
2 | $(AS) $(AFLAGS) $@ $< |
Christian J. schrieb: > Zeilen wie diese > > define makedepend = > set -e > #$(CC) -MM $(CFLAGS) -o .dep/$(*F).d $< > (echo -n '$(OBJDIR)/'; $(CC) -MM $(CFLAGS) $< ) >.dep/$(*F).d > $(CP) .dep/$(*F).d .dep/$(*F).P > $(SED) -e 's/#.*//' -e 's/^[^:]*: *//' -e 's/ *\\$$//' \ > -e '/^$$/ d' -e 's/$$/ :/' < .dep/$(*F).d >> .dep/$(*F).P > $(RM) .dep/$(*F).d > endef > > sind "menschenverachtend" :-) Ja, hab's grade gändert. So ist's auch nicht optimal, aber schon besser:
1 | define makedepend = |
2 | (set -e; echo -n '$(OBJDIR)/'; $(CC) -MM $(CFLAGS) $< ) >.dep/$(*F).d |
3 | $(CP) .dep/$(*F).d .dep/$(*F).P |
4 | $(SED) -e 's/#.*//' -e 's/^[^:]*: *//' -e 's/ *\\$$//' \ |
5 | -e '/^$$/ d' -e 's/$$/ :/' < .dep/$(*F).d >> .dep/$(*F).P |
6 | $(RM) .dep/$(*F).d |
7 | endef |
Immer noch Fehgler drin. mcursees compilieren geht gar nicht, weil der den AVR da einbinden will. Sorry, kann nur scrrenshot anhängen, ist ein putty Fenster. PS: Keine Ahnung was diese krypischen zeichen bedeuten. sed finde ich schrecklich. Muss man sich wohl einlesen...
LIBDIRS: crt0: build/crt0.rel SOURCES: main.c driver.c interrupt.c crt0.s OBJS: build/main.rel build/driver.rel build/interrupt.rel clean_list: build/z80rom.bin.lnk build/main.asm build/main.lst build/main.rst build/main.sym build/main.rel build/driver.asm build/driver.lst build/driver.rst build/driver.sym build/driver.rel build/interrupt.asm build/interrupt.lst build/interrupt.rst build/interrupt.sym build/int errupt.rel build/crt0.asm build/crt0.lst build/crt0.rst build/crt0.sym build/crt0.rel ----------- misc ------------- dr: build build ddd: build build echo build/crt0.lst build/crt0.sym build/driver.asm build/driver.lst build/driver.rel build/driver.sym build/interrupt.asm build/interrupt.ls t build/interrupt.rel build/interrupt.sym build/main.asm build/main.lst build/main.rel build/main.sym build/crt0.lst build/crt0.sym build/driver.asm build/driver.lst build/driver.rel build/driver.sym build/interrupt.asm build/interrupt.lst bui ld/interrupt.rel build/interrupt.sym build/main.asm build/main.lst build/main.rel build/main.sym echo 3.1.0_r7066 3.1.0_r7066 cjulius@kirk:~/nasdata/Z80/src/ram$
cjulius@kirk:~/nasdata/Z80/src/ram$ make /usr/bin/sdcc -mz80 --std-sdcc99 --opt-code-size --fno-omit-frame-pointer -o build/main.rel -c main.c at 1: warning 117: unknown compiler option '--fno-omit-frame-pointer' ignored In file included from main.c:16: mcurses.h:18:26: error: avr/pgmspace.h: No such file or directory main.c:116: warning 85: in function main unreferenced local variable : 'buf' /usr/bin/sdcc -mz80 --std-sdcc99 --opt-code-size --fno-omit-frame-pointer -o build/driver.rel -c driver.c at 1: warning 117: unknown compiler option '--fno-omit-frame-pointer' ignored /usr/bin/sdcc -mz80 --std-sdcc99 --opt-code-size --fno-omit-frame-pointer -o build/interrupt.rel -c interrupt.c at 1: warning 117: unknown compiler option '--fno-omit-frame-pointer' ignored /usr/bin/sdasz80 -plosff build/crt0.rel crt0.s crt0.s:15: Error: <o> .org in REL area or directive / mnemonic error crt0.s:16: Error: <o> .org in REL area or directive / mnemonic error crt0.s:17: Error: <o> .org in REL area or directive / mnemonic error crt0.s:18: Error: <o> .org in REL area or directive / mnemonic error crt0.s:19: Error: <o> .org in REL area or directive / mnemonic error crt0.s:20: Error: <o> .org in REL area or directive / mnemonic error crt0.s:21: Error: <o> .org in REL area or directive / mnemonic error crt0.s:55: Error: <u> undefined symbol encountered during assembly crt0.s:78: Error: <u> undefined symbol encountered during assembly crt0.s:98: Error: <u> undefined symbol encountered during assembly crt0.s:101: Error: <u> undefined symbol encountered during assembly crt0.s:125: Error: <u> undefined symbol encountered during assembly removing build/crt0.rel make: *** [build/crt0.rel] Fehler 2 cjulius@kirk:~/nasdata/Z80/src/ram$
Altes makefile:
1 | rm -f *.rel *.asm *.sym *.ihx *.noi *.bin *.lk \ |
2 | z80rom.lk z80rom.map z80rom.noi |
3 | sdasz80 -plosgff crt0.s |
4 | sdcc -mz80 --std-c99 --opt-code-size --fomit-frame-pointer -c main.c |
5 | main.c:116: warning 85: in function main unreferenced local variable : 'buf' |
6 | sdcc -mz80 --std-c99 --opt-code-size --fomit-frame-pointer -c driver.c |
7 | sdcc -mz80 --std-c99 --opt-code-size --fomit-frame-pointer -c interrupt.c |
8 | sdcc -mz80 --std-c99 --opt-code-size --fomit-frame-pointer -c mcurses.c |
9 | sdcc -mz80 --std-c99 --opt-code-size --fomit-frame-pointer -c hexedit.c |
10 | sdcc -mz80 --no-std-crt0 -Wl-u --code-loc 0x2100 --data-loc 0x8000 crt0.rel main.rel driver.rel interrupt.rel mcurses.rel hexedit.rel -o z80rom.ihx |
11 | objcopy --input-target=ihex --output-target=binary --gap-fill 0xff z80rom.ihx z80rom.bin |
12 | cjulius@kirk:~/nasdata/Z80/src/ram$ |
Was ich witzig finde ist, dass der sdecc ins Bin File alles reinpackt, ob es benutzt wird oder nicht. Sämtliche Routinen sind drin. Gibt es da nicht eine Anaylse, was ausgehend von main.c alles eingebunden werden muss und wer wen aufruft? Allein schon für die Stacksszie muss das ja geprüft werden.
Version 3.1.0, der ist ja Asbach Christian J. schrieb: > at 1: warning 117: unknown compiler option '--fno-omit-frame-pointer' Di Option kennt er noch nicht, kannst Du dann auch rausnehmen. > mcurses.h:18:26: error: avr/pgmspace.h: No such file or directory Mach mal:
1 | $ touch empty.c; sdcc -mz80 -E -dM empty.c |
> /usr/bin/sdasz80 -plosff build/crt0.rel crt0.s > crt0.s:15: Error: <o> .org in REL area or directive / mnemonic error ... > crt0.s:55: Error: <u> undefined symbol encountered during assembly siehe oben
Version 3.4.1, die von gestern abend :-) Frisch kompiliert. cjulius@kirk:~/nasdata/Z80/src/ram$ sdcc -v SDCC : mcs51/z80/z180/r2k/r3ka/gbz80/tlcs90/ds390/pic16/pic14/TININative/ds400/ hc08/s08/stm8 3.4.1 #9098 (Nov 9 2014) (Linux) published under GNU General Public License (GPL) cjulius@kirk:~/nasdata/Z80/src/ram$
cjulius@kirk:~/nasdata/Z80/src/ram$ touch empty.c; sdcc -mz80 -E -dM empty.c #define SDCC_FLOAT_REENT 1 #define SDCC_INT_LONG_REENT 1 #define __z80 1 #define SDCC_STACK_AUTO 1 #define SDCC_z80 1 #define __SDCC_INT_LONG_REENT 1 #define _STDC_HOSTED_ 0 #define __SDCC_z80 1 #define SDCC 341 #define __SDCC_FLOAT_REENT 1 #define SDCC_REVISION 9098 #define _STDC_NO_VLA_ 1 #define __SDCC 3_4_1 #define _STDC_NO_THREADS_ 1 #define _STDC_NO_ATOMICS_ 1 #define __SDCC_STACK_AUTO 1 #define _STDC_ 1 #define __SDCC_REVISION 9098 #define _STDC_NO_COMPLEX_ 1 cjulius@kirk:~/nasdata/Z80/src/ram$
> Version 3.4.1, die von gestern abend :-) Frisch kompiliert.
Dann schreib den Pfad zu dieser Version in PREFIX.
Jetzt interessiert mich aber auch noch
1 | $ touch empty.c; /usr/bin/sdcc -mz80 -E -dM empty.c |
>> Version 3.4.1, die von gestern abend :-) Frisch kompiliert. > Dann schreib den Pfad zu dieser Version in PREFIX. Achso, wenn diese Version über $PATH der Shell gefunden wird, kannst Du PREFIX im Makefile auch leer lassen. Das sollte sowieso der Default im Muster-Makefile sein.
Christian J. schrieb: > Version 3.4.1, die von gestern abend :-) Frisch kompiliert.
1 | SDCC : mcs51/z80/z180/r2k/r3ka/gbz80/tlcs90/ds390/pic16/pic14/TININative/ds400/hc08/s08/stm8 3.4.1 #9098 (Nov 9 2014) (Linux) |
Wieso habe ich denn dann #9101 von gestern Abend?
1 | SDCC : mcs51/z80/z180/r2k/r3ka/gbz80/tlcs90/ds390/TININative/ds400/hc08/s08/stm8 3.4.1 #9101 (Nov 10 2014) (Linux) |
Ich hätte das gerne mit "/usr/bin/sdcc" Oben steht ohne "/usr/bin"
Ist das wichtig,. obh die von nachmittag oder abends war? Da kann es ja nicht dran liegen. Da steht doch jeden Tag ne neue in den snapshots. Ich habe erstmal auf altes Makefile zurück gebaut. Der Editor ist eh selektiv und zeigt nur .c und .h an Kannst du mir sagen, warum der sdcc alles in den bin File reinzieht? Auch wenn die Main leer ist? Da muss man ja alles nachher löschen, was man nicht braucht? Bzw eine Abhängigkeits analyse machen was nicht einfach ist.
Ok.... #define SDCC_FLOAT_REENT 1 #define SDCC_INT_LONG_REENT 1 #define __z80 1 #define SDCC_STACK_AUTO 1 #define SDCC_z80 1 #define _STDC_HOSTED_ 0 #define SDCC 310 #define SDCC_REVISION 7066 #define _STDC_ 1 cjulius@kirk:~/nasdata/Z80/src/ram$
Da liegen 2 Versioen bei mir..... eine 3.1.0 noch. Shit! Und zwardie alte aus den Debian Main repos. Muss die mal rauswerfen eben.
Oh Wunder.... sdcc liegt in /usr/local/bin, wenn man ihn über den make instal installiert und in /usr/bin wenn man apt-get verwendet, zumindest die asbach version. bleibt noch übrig cjulius@kirk:~/nasdata/Z80/src/ram$ make /usr/local/bin/sdcc -mz80 --std-sdcc99 --opt-code-size --fno-omit-frame-pointer -o build/main.rel -c main.c main.c:116: warning 85: in function main unreferenced local variable : 'buf' /usr/local/bin/sdcc -mz80 --std-sdcc99 --opt-code-size --fno-omit-frame-pointer -o build/driver.rel -c driver.c /usr/local/bin/sdcc -mz80 --std-sdcc99 --opt-code-size --fno-omit-frame-pointer -o build/interrupt.rel -c interrupt.c /usr/local/bin/sdasz80 -plosff build/crt0.rel crt0.s /usr/local/bin/sdldz80 -n -f build/z80rom.lnk ?ASlink-Error-<cannot open> : "build/z80rom.lnk" make: *** [build/z80rom.ihx] Fehler 3 cjulius@kirk:~/nasdata/Z80/src/ram$
Christian J. schrieb: > eine 3.1.0 noch. Shit! Habe ich oben ja geschrieben. Wenn ich in Deinem Makefile diese Zeile - Unter Beachtung des darüberstehenden Kommentars - editiere, läuft das Makefile ohne Fehler durch.
1 | TARGETNAME = z80rom.bin |
Da muß ich noch was abfangen... Version 3.4.1:
1 | #define __SDCC_z80 1 |
Version 3.4.1:
1 | #define SDCC_z80 1 |
Auf das obere Makro wird von mcurses getestet...
> Ist das wichtig,. obh die von nachmittag oder abends war? Da kann es ja
Da hätte ich wohl ein Smiley hinmachen sollen.
:
Bearbeitet durch User
Leo C. schrieb: > TARGETNAME = z80rom.bin > > Da muß ich noch was abfangen... Mit und ohne .bin erzeugt es Fehlermeldung. Bin da ja auch dran, so wie du grad und suche Fehler. cjulius@kirk:~/nasdata/Z80/src/ram$ make /usr/local/bin/sdldz80 -n -f build/z80ram.lnk ?ASlink-Error-<cannot open> : "build/z80ram.lnk" make: *** [build/z80ram.ihx] Fehler 3 Nochmal: Kannst du mir sagen, warum der sdcc alles in den bin File reinzieht? Auch wenn die Main leer ist? Da muss man ja alles nachher löschen, was man nicht braucht? Bzw eine Abhängigkeits analyse machen was nicht einfach ist.
Lass das .bin an der Stelle auf jeden Fall weg. Auch wenn das Makefile damit funktionieren würde, bekämst Du am Ende z80rom.bin.hex und z80rom.bin.bin und z80rom.bin.map usw. Glaube nicht, daß Du das möchtest. Christian J. schrieb: > Kannst du mir sagen, warum der sdcc alles in den bin File reinzieht? > Auch wenn die Main leer ist? Da muss man ja alles nachher löschen, was > man nicht braucht? Bzw eine Abhängigkeits analyse machen was nicht > einfach ist. SDCC hat halt einen recht konventionellen Linker. Sozusagen Retro halt. Der Programmierer sagt dem Linker, was er linken soll, und das macht er kann auch. Wenn Du prophylaktisch alles übergeben willst, was vielleicht mal gebraucht werden könnte, kannst Du Dich ja mal mit Libraries beschäftigen. Der Compiler packt bisher aber auch nicht-referenzierte statische Funktionen und Variablen (z.B. auch static inline Funktionen) in den Output. Das wird vielleicht mal geändert. Ist bei einem One-Pass-Compiler aber nicht so einfach.
Christian J. schrieb: > Da muss man ja alles nachher löschen, was > man nicht braucht? Bzw eine Abhängigkeits analyse machen was nicht > einfach ist. Vorher erst garnicht reinschreiben, ist die bessere Alternative, und bei Leuten, die wissen was sie tun, die übliche Praxis.
Es funktioniert leider auch ohnhe das bin nicht. Der Fehler kommt immer. Und ich habe noch nie einen Compiler gesehen, der nicht benutzte Funktionen nicht weg optmiert. Was nicht aufgerufen wird fliegt raus. Der CCS macht das auch und ist nur 1-Pass, nur 1 Source File, alles andere mit include einbinden. Kein Linker! Der Compiler macht doch eh einen Baum auf wer wen anruft und was zurück kommt. Da kann man ja kein Modul benutzen, wie das von Frank M. Libs sind kompilierte dateien mit Header dran. Man bindet nur das ein was man braucht. Ich habe 18 Jahre nie eine Lib benötigt oder je geschrieben sondern immer nur Quelltext Libs, die ich in einem Unterverz ablegte nund bei Beaarf reinholte. Nur bei VB gab es propietäre Libs, die waren vorkompliiert, weil wir die ja mit der Interface Karte gekauft hatten um eine Maschine anzusteuern.
Christian J. schrieb: > cjulius@kirk:~/nasdata/Z80/src/ram$ make > /usr/local/bin/sdldz80 -n -f build/z80ram.lnk > ?ASlink-Error-<cannot open> : "build/z80ram.lnk" > make: *** [build/z80ram.ihx] Fehler 3 Da make nix neu compiliert hat, sondern nur linken will, wurde wahrscheinlich auch das linkfile "build/z80ram.lnk" nicht neu erzeugt. Das alte heißt vielleicht noch "build/z80ram.bin.lnk" oder so. Dann sollte ein 'make clean' helfen. Bei mir funktionierts jedenfalls mit dem "ram.rar" von oben und den 2 Änderungen an PREFIX und TARGETNAME Christian J. schrieb: > PS: Keine Ahnung was diese krypischen zeichen bedeuten. sed finde ich > schrecklich. Da sind wir einer Meinung. Daran sieht man auch, daß der Kern dieses "eingedosten Rezepts" ;) nicht von mir ist[1]. Ich hätte awk genommen... [1] Was da gemacht wird ist an der Quelle erklärt, die ich ja auch angegeben habe: http://make.paulandlesley.org/autodep.html
Leo C. schrieb: > Version 3.4.1: >
1 | > #define __SDCC_z80 1 |
2 | > |
> Version 3.4.1: >
1 | > #define SDCC_z80 1 |
2 | > |
Unschön. Wieso eigentlich 2 mal 3.4.1? ;-) Wenn man in mcurses.c das
1 | #elif defined(__SDCC_z80)
|
durch
1 | #elif defined(__SDCC_z80) || defined(SDCC_z80)
|
ersetzt, dann ist (mir persönlich) die SDCC-Version schnuppe.
Frank M. schrieb: > Unschön. Wieso eigentlich 2 mal 3.4.1? ;-) Copy&paste Schlamperei. > das#elif defined(__SDCC_z80) > durch#elif defined(__SDCC_z80) || defined(SDCC_z80) Keine Ahnung, ob man die Variante ohne die führenden "__" noch unterstützen muß. Die SDCC-Leute habe wohl auch gemerkt, daß das nicht so gut ist. Ich würde aber noch einen Schritt weiter gehen, und auf __SDCC testen (oder "defined(__SDCC) || defined(SDCC)"). Dann gehts mit z180 (und all den anderen) auch.
:
Bearbeitet durch User
Christian J. schrieb: > Da kann man ja kein > Modul benutzen, wie das von Frank M. Wenn man es benutzt muß es kompiliert und eingebunden werden. Wenn nicht, dann nicht. Wo ist das Problem. > Ich habe 18 Jahre nie eine Lib benötigt oder je > geschrieben sondern immer nur Quelltext Libs, die ich in einem Unterverz > ablegte nund bei Beaarf reinholte. Eben bei Bedarf. Den Nicht-Bedarf erkennt der Linker halt nicht. Du aber schon. Auch beim GNU Linker ist das Feature, daß nicht benötigte Programmteile rauswirft, relativ neu.
Leo C. schrieb: > wahrscheinlich auch das linkfile "build/z80ram.lnk" nicht neu erzeugt. > Das alte heißt vielleicht noch "build/z80ram.bin.lnk" oder so. > Dann sollte ein 'make clean' helfen. Nein, es geht nicht. .lnk wurd nicht gefunden und angemeckert. Kanste mal die komplette make korrigiert wieder posten? Hier meines mit der Änderung.
Mit Deinem neuesten Makefile:
1 | leo@cb:~/Projekte/HD64180/z80-stamp/sdcc/hobel/2014-11-10-1530$ make -f Makefile-1732 |
2 | /usr/local/bin/sdcc -mz80 --std-sdcc99 --opt-code-size --fno-omit-frame-pointer -o build/mcurses.rel -c mcurses.c |
3 | /usr/local/bin/sdcc -mz80 --std-sdcc99 --opt-code-size --fno-omit-frame-pointer -o build/hexedit.rel -c hexedit.c |
4 | /usr/local/bin/sdldz80 -n -f build/z80ram.lnk |
5 | Multiple definition of _main |
6 | Multiple definition of _main_start |
7 | Multiple definition of _main_end |
8 | Makefile-1732:310: recipe for target 'build/z80ram.ihx' failed |
9 | make: *** [build/z80ram.ihx] Error 2 |
10 | make: *** Deleting file 'build/z80ram.ihx' |
11 | leo@cb:~/Projekte/HD64180/z80-stamp/sdcc/hobel/2014-11-10-1530$ |
Dein Target heiß jetzt z80ram, aber das ist egal. Das Makefile, mit dem es geht (mit den 2 Änderungen), ist hier im Anhang: Beitrag "Re: Retro Fieber: Z80 oder 68000 ?" Die Unterschiede (und damit den neuen Fehler) müßtest Du leicht selber finden.
Kleine Änderung, nun kompilierts auch mit Deinem letzten Archiv. Obs läuft kann ich natürlich nicht sagen. Geändertes Projekt im Anhang.
1 | leo@cb:~/Projekte/HD64180/z80-stamp/sdcc/hobel/2014-11-10-1530$ make -f Makefile-1732 |
2 | /usr/local/bin/sdcc -mz80 --std-sdcc99 --opt-code-size --fno-omit-frame-pointer -o build/main.rel -c main.c |
3 | /usr/local/bin/sdcc -mz80 --std-sdcc99 --opt-code-size --fno-omit-frame-pointer -o build/driver.rel -c driver.c |
4 | /usr/local/bin/sdcc -mz80 --std-sdcc99 --opt-code-size --fno-omit-frame-pointer -o build/interrupt.rel -c interrupt.c |
5 | /usr/local/bin/sdcc -mz80 --std-sdcc99 --opt-code-size --fno-omit-frame-pointer -o build/mcurses.rel -c mcurses.c |
6 | /usr/local/bin/sdcc -mz80 --std-sdcc99 --opt-code-size --fno-omit-frame-pointer -o build/hexedit.rel -c hexedit.c |
7 | /usr/local/bin/sdasz80 -plosff build/crt0.rel crt0.s |
8 | /usr/local/bin/sdldz80 -n -f build/z80ram.lnk |
9 | objcopy --input-target=ihex --output-target=binary --gap-fill 0xff build/z80ram.ihx build/z80ram.bin |
10 | leo@cb:~/Projekte/HD64180/z80-stamp/sdcc/hobel/2014-11-10-1530$ |
nein, immer nioch das gleiche und deine Andeutungen verstehe ich leider nicht woran es liegen könnte. diff brachte jetzt nicht die Erkenntnis und z80ram oder rom dürfte egal sein. .lnk gibt es einfach nicht da wo es sein sollte.
Leo C. schrieb: > Ich würde aber noch einen Schritt weiter gehen, und auf __SDCC testen > (oder "defined(__SDCC) || defined(SDCC)"). Dann gehts mit z180 (und all > den anderen) auch. Ja, da hast Du recht. Warum sollte man sich unnötig auf den Z80 beschränken. Ich werde das abändern.
mach mal folgendes: Im Makefile-1732 an 2 Stellen die "@" vor dem Befehl entfernen:
1 | $(LDSCRIPT): $(OBJS) $(STARTUPOBJ) |
2 | $(makelinkscript) |
3 | |
4 | $(STARTUPOBJ): $(STARTUP) |
5 | $(AS) $(AFLAGS) $@ $< |
6 | |
7 | $(OBJDIR)/%$(OEXT): %.c |
8 | $(makedepend) |
9 | $(CC) $(CFLAGS) -o $@ -c $< |
also vor $(makelinkscript) und vor $(makedepend) anschließend:
1 | $ make -f Makefile-1732 realclean |
2 | $ make -dp -f Makefile-1732 >output.txt |
Und dann schickst Du mir die Datei output.txt. (Geht auch per EMail.)
1 | Die Target-Datei »build/crt0.rel« wurde erfolgreich aktualisiert. |
2 | Fertig mit den Voraussetzungen für die Ziel-Datei »build/z80ram.lnk«. |
3 | Das Target »build/z80ram.lnk« muss neu erzeugt werden. |
4 | Die Target-Datei »build/z80ram.lnk« wurde erfolgreich aktualisiert. |
5 | Fertig mit den Voraussetzungen für die Ziel-Datei »build/z80ram.ihx«. |
6 | Das Target »build/z80ram.ihx« muss neu erzeugt werden. |
7 | /usr/local/bin/sdldz80 -n -f build/z80ram.lnk |
8 | Nehme Kindprozess 0x002ebd78 (build/z80ram.ihx) PID 31628 in die Kette auf. |
9 | Aktiver Kindprozess 0x002ebd78 (build/z80ram.ihx) PID 31628 |
10 | Sammle erfolglosen Kindprozess 0x002ebd78 PID 31628 |
11 | Removing child 0x002ebd78 PID 31628 from chain. |
Das wird heute nix mehr. Bei Dir wird offensichtlich die Datei 'build/z80ram.lnk' nicht erzeugt. Woran das liegt, sieht man aber auch in dem Log nicht. Es kann fast nur an der Umgebung liegen. Makefile und der Rest der Dateien sind ja bei uns gleich. Christian J. schrieb: > diff brachte jetzt nicht die Erkenntnis > und z80ram oder rom dürfte egal sein. .lnk gibt es einfach nicht da wo > es sein sollte. Diff hilft mir oft. Meistens aber eins mit graphischer Oberfläche. Da gibt es einige. Meld (kann auch ganze Verzeichnisbäume vergleichen), fldiff, diffuse liegen hier rum. Sicher gibts noch andere. Hier ist das auch mühsam, weil die Make-Versionen arg unterschiedlich sind. Meins spricht Deutsch/Englisch-Kauderwelsch.
Ich spiele mir grad sdcc auf den PC rein, er kompiliert es grad. Vielleicht liegt es auch daran dass Z80 Sachen bei mir auf dem Cubie Truck gemacht werden, wo alle Daten als NAS liegen und über samba erreichbar sind. Ich arbeite da nur mit nano, mc und Konsole. Der Z80 hängt da auch mit dran. Schonn ein Unterschied, ob man mit Quadcore oder Cubie kompiliert :-) Cubie: 2,5h, raspberry Pi 4h. PC ca 10 Minuten.
letzte Melduing: ich kriege sdcc auf PC unter Mint 17 nicht installiert, da eine GL...irgendwas LIB fehlt. Aus den paketquellen von Mint 17 kriege ich nur die 3.3.0 raus. Das make install bei dem Source endet mit einer fehlermeldung dass Berechtigungen fehlen, die auch als root nicht behebar sind. Direktes Düberkopieren der neuen sdcc Binaries in /usr/bin ergibt wieder eine Fehlermeldung beim Aufruf, dass eine spezielle lib unter /usr/lib nicht gefunden wird. Vorerst auch keine Idee..... edit: Ist installiert aber fehlermeldung bleibt. Also unter Debian auf Cubitruck und auf PC das Gleiche.
Frank M. schrieb: > Tasten: > > Links - Ein Byte zurück > Rechts - Ein Byte vor > Rauf - Eine Zeile rauf > Runter - Eine Zeile runter > TAB - Wechsel zwischen Hex- und ASCII-Spalten > 2 x ESCAPE - Exit Hallo Frank, ich habe das grad getestet. Läuft jetzt! Fehler lag bei mir in dem Ringpuffer. Verbesserungsvorschlag: Nach Eingabe eines Hex wertes in die nächstes Spalte springen. Hochscrollen und wieder runter läuft noch nicht, da springt er einfach raus und beendet es,. Tritt aber nur bei tastenwiderholung auf, einzeltasten drücken klappt es. Eher meine Hardware, da zu langsam und kein Duplex. Bleibt noch die Frage: wieso getch() und nicht mehr getchar() ? getchar ist bei mir überschrieben durch eine eigene Funktion, getch aber ncht.
Christian J. schrieb: > ich habe das grad getestet. Läuft jetzt! Fehler lag bei mir in dem > Ringpuffer. Verbesserungsvorschlag: Nach Eingabe eines Hex wertes in die > nächstes Spalte springen. Ja, habe ich auch schon daran gedacht. Hast Du mal mit der Tabulator-Taste rechts in die ASCII-Darstellung gewechselt und dort schon ein paar Bytes geändert, z.B. Deine Z80-Mini-System-Meldung? > Hochscrollen und wieder runter läuft noch > nicht, da springt er einfach raus und beendet es. Ein eindeutiges Signal, dass Dein getchar Zeichen verschluckt - also nicht schnell genug die Zeichen abholt. Wenn Du eine der Cursor-Tasten runterdrückst, dann schickt das Terminal wiederholt <ESC>[D, also z.B. <ESC>[D<ESC>[D<ESC>[D<ESC>[D<ESC>[D<ESC>[D<ESC>[D. Der Hex-Editor beendet sich bei 2x <ESC> hintereinander, d.h. irgendwann/irgendwo werden [D verschluckt und mcurses sieht 2x <ESC>. Da musst Du noch dran arbeiten, das muss besser gehen. Soooo schnell repetiert Deine Tastatur auch nicht. Irgendwo steckt noch der Wurm in Deinem Ringbuffer. > Tritt aber nur bei > tastenwiderholung auf, einzeltasten drücken klappt es. Eher meine > Hardware, da zu langsam und kein Duplex. Ja, siehe oben. > Bleibt noch die Frage: wieso getch() und nicht mehr getchar() ? getchar > ist bei mir überschrieben durch eine eigene Funktion, getch aber ncht. Du hast es immer noch nicht verstanden, oder? getch() ist die High-Level-mcurses-Funktion, welche sich mittels (u.U. mehrfachem) getchar()-Aufruf die Zeichen holt und solche Escapesequenzen, wie "<ESC>[D" zu einem Tastencode KEY_DOWN zusammenfasst. Denk Dir das wie ein Schichtenmodell: Applikation hexedit() sieht KEY_DOWN | mcurses getch() <ESC>[D -> KEY_DOWN | low-level-IO getchar() sieht <ESC>, dann [, dann D | SIO-Device Deine I/O-Fktn. liest SIO Die Applikation benutzt getch() oder getnstr(), um Tasten oder ganze Strings einzulesen, getch() ruft mehrmals getchar() auf, um die Zeichen einzusammeln, die zu EINEM Tastendruck gehören. Bei den Cursor-Tasten muss getch() dreimal(!) getchar() aufrufen! Die Applikation bekommt bei getch() aber nur EINEN Tastencode, nämlich KEY_DOWN. Die mcurses-Funktionen (s. MCURSES) sind die High-Level-Funktionen. Wenn die Applikation mcurses benutzt, dann darf die Anwendung ausschließlich über mcurses die Interaktion machen. Für die Applikation sind dann getchar()/putchar() usw. verboten und ausschließlich den internen mcurses-Funktionen vorbehalten. Sonst gibt's Zeichensalat! Dieses hier schrieb ich Dir hier schon vor ein paar Tagen: Alt (stdio) Neu (mcurses) ============================= getchar() getch() putchar() addch() puts() addstr() ---- move() usw. usw.
:
Bearbeitet durch Moderator
Christian J. schrieb: > Hochscrollen und wieder runter läuft noch > nicht, da springt er einfach raus und beendet es,. Noch etwas dazu: Wenn Du oben anschlägst, wird nicht nur der scroll-Befehl ans Terminal geschickt, sondern auch knapp 80 Zeichen, um die neue Zeile unten/oben einzublenden. Ich hoffe, Du hast auch für die Ausgabe einen interrupt-gesteuerten Ringbuffer. Denn während die 80 Zeichen geschickt werden, sendet Deine Tastatur weiter <ESC>[D<ESC>[D<ESC>[D<ESC>[D<ESC>[D<ESC>[D<ESC>[D<ESC>[D, wenn Du die Cursor-Taste runterhältst. Wir haben es hier mit FullDuplex zu tun! Sowohl Input und Output müssen über Interrupts laufen. Insbesondere Deine Output-Funktion darf NICHT warten, bis das Zeichen komplett gesendet wurde. Sonst bist Du verratzt und verkauft.
Frank M. schrieb: > Ich hoffe, Du hast auch für die Ausgabe einen interrupt-gesteuerten > Ringbuffer. Denn während die 80 Zeichen geschickt werden, sendet Deine > Tastatur weiter > <ESC>[D<ESC>[D<ESC>[D<ESC>[D<ESC>[D<ESC>[D<ESC>[D<ESC>[D, wenn Du die > Cursor-Taste runterhältst. Wir haben es hier mit FullDuplex zu tun! Hallo Frank, ja, das weiss ich schon, bin ja auch schon weiter. Ich habe nur Halb Duplex und ich werde auch den Sendebuffer schreiben müssen. Mit 9600 ist das ganze auch recht langsam aber durchaus interessant. Ich mache hier erstmal einen Break bis ich hier weiter bin. >Insbesondere Deine Output-Funktion darf NICHT warten, bis das Zeichen >komplett gesendet wurde. Sonst bist Du verratzt und verkauft. Tut sie aber (noch) :-O
Christian J. schrieb: >> Insbesondere Deine Output-Funktion darf NICHT warten, bis das Zeichen >> komplett gesendet wurde. Sonst bist Du verratzt und verkauft. > > Tut sie aber (noch) :-O Tut sie nicht. Wahrscheinlich ein Mißverständnis.
1 | // Zeichenausgabe für printf auf der STI mit 9600 Baud
|
2 | void putchar(char c) |
3 | {
|
4 | while ((STI_TSR & 0x80) == 0); // Warte bis Buffer frei... |
5 | STI_UDR = c; // Byte einschreiben |
6 | |
7 | }
|
0x80 ist das "Transmit-Buffer-Empty"-Flag. Deine Routine wartet also, bis ein neues Zeichen im Transmitbuffer passt. Mit dem Senden des vorhergehenden Zeichens wurde dann gerade erst begonnen. Den erratzten Fall hättest Du, wenn Du auf das "End-Of-Transmission"-Flag warten würdest.
:
Bearbeitet durch User
Leo C. schrieb: > 0x80 ist das "Transmit-Buffer-Empty"-Flag. Deine Routine wartet also, > bis ein neues Zeichen im Transmitbuffer passt. Okay. Aber ist diese Warteschleife unterbrechbar, wenn währenddessen ein Zeichen hereinkommt? Und passiert das denn auch?
> Okay. Aber ist diese Warteschleife unterbrechbar, wenn währenddessen ein > Zeichen hereinkommt? Und passiert das denn auch? Wenn er fürs Empfangen die ISR mit Empfansfifo verwendet, ja. Jedenfalls sollte es, wenn die Routinen so funktionieren, wie gedacht. Ich habe mir aber nicht alles so genau angesehen. Und das letzte Programm, in dem der Editor auch aufgerufen wird, kenne ich nicht.
Hallo, letzlich ist ein Bitbanging in den Flaschenhals der TX Einheit. Das ist was anderes als wenn ein Int ständig läuft, der bei Buffer Empty aufgerufen wird. Und die hauptroutine schriebt ständig neue Bytes in den Software Buffer rein. Das ganze lässt sich schon automatisieren druch die Verwendung von Ints, die aber dann auch mit RX kollidieren. Beides gleichzeitig in der CPU geht eben nicht, auch wenn TX und RX einheit gleichzeitig arbeiten können. Ihr müsst da aber auch nicht reinkriechen, das ist meine Sache. Ich teste aber gern eure Software für euch. >Okay. Aber ist diese Warteschleife unterbrechbar, wenn währenddessen ein >Zeichen hereinkommt? Und passiert das denn auch? Natürlich wird die dann unterbrochen. Ich möchte aber hier noch nicht weiter spekulieren, da alles noch halbfertig ist und ich auch nicht weiss, ob ich heute abend dazu komme bzw Lust habe. War etwas viel die letzte Zeit und ich habe noch 2 Kinder....
Christian J. schrieb: > Hallo, > > letzlich ist ein Bitbanging in den Flaschenhals der TX Einheit. Das ist > was anderes als wenn ein Int ständig läuft, der bei Buffer Empty > aufgerufen wird. Die STI wird nicht um Bits bangen... was schreibst Du wieder fürn Zeuch? Das ist Hardware, ein Schieberegister das die Bits rausklappert mit konstantem Takt. > Und die hauptroutine schriebt ständig neue Bytes in den Software Buffer > rein. Das ganze lässt sich schon automatisieren druch die Verwendung von > Ints, die aber dann auch mit RX kollidieren. Beides gleichzeitig in der > CPU geht eben nicht, auch wenn TX und RX einheit gleichzeitig arbeiten > können. Ich weiß nicht was Deine STI so kann, hatte ja ne SIO empfohlen. So eine SIO hat erstens Prioritäten bei internen Interrups und eine Mimik namens "Status affects Vector" um so schnell wie möglich die richtige ISR anspringen zu können, die SIO hat selbst je nach Interrupt Grund den Vector im IM2 Mode modifiziert. Ich besutze 0 Stück STI ber so ca 50 SIOs und habe deshalb keinen richtigen Bock darauf ein STI Datenblatt zu lesen. > > Ihr müsst da aber auch nicht reinkriechen, das ist meine Sache. Ich > teste aber gern eure Software für euch. Genau. Und dann solltest Du mal von Deiner Meinung wegkommen das die Z80 mit 4Mhz zu langsam ist eine Serielle mit 9600 Baud zu bedienen. Das geht mit 2,5Mhz auch prima. Nur weil Du Atmels mit 20Mhz kennst ist die 4Mhz Z80 nicht langsam. Du kannst das nur nicht einschätzen. > >>Okay. Aber ist diese Warteschleife unterbrechbar, wenn währenddessen ein >>Zeichen hereinkommt? Und passiert das denn auch? > > Natürlich wird die dann unterbrochen. Ich möchte aber hier noch nicht > weiter spekulieren, da alles noch halbfertig ist und ich auch nicht > weiss, ob ich heute abend dazu komme bzw Lust habe. War etwas viel die > letzte Zeit und ich habe noch 2 Kinder.... Mach Dir mal einen richtigen Plan mit diesen Umlaufpuffern. Lies die Doku zur STI wie die das bei konkurrierenden Interrupts löst. Der Fall ist ja nicht wirklich selten und auch schon zu Z80 Zeiten haben die Leute Synchronprotokolle mit mehr als 9600 Baud über SIOs gefahren.. (wobei diese Protokolle auch Füllzeichen senden können) Gruß, Holm
Holm Tiffe schrieb: > Mach Dir mal einen richtigen Plan mit diesen Umlaufpuffern. Lies die > Doku zur STI wie die das bei konkurrierenden Interrupts löst. Feste Priorisierung der 16 internen Interruptquellen mit getrennte Vektoren. Die 8 externen Interrupt-Eingänge (IO Pins), 4 Timer, 4 UART-Fälle. Für verschachtelte STI Interrupts muss man dessen "in service" Register einschalten. Das "I" in STI steht für Interrupt-Controller. Eigentlich sollte ich mich ja wundern, wie man aus dieser Mücke so einen Elefanten machen kann, aber ... Synchron würde ich mit dem STI aber wirklich nicht machen wollen. Bitsync kann er nicht, aber irgendeine nahezu undokumentierte Bytesync Variation. Bei der hätte man wohl gute Chancen, der erste zu sein, der das seit Erfindung des Bausteins ausprobiert. Jeder, der Sync im Auge hatte, hat den SIO verwendet.
:
Bearbeitet durch User
A. K. schrieb: > Holm Tiffe schrieb: >> Mach Dir mal einen richtigen Plan mit diesen Umlaufpuffern. Lies die >> Doku zur STI wie die das bei konkurrierenden Interrupts löst. > > Feste Priorisierung der 16 internen Interruptquellen mit getrennte > Vektoren. Die 8 externen Interrupt-Eingänge (IO Pins), 4 Timer, 4 > UART-Fälle. Für verschachtelte STI Interrupts muss man dessen "in > service" Register einschalten. Das "I" in STI steht für > Interrupt-Controller. > Naja, aus meiner Sicht ist das Ding ein ganzes Stück weit Krücke um andere nicht zum System gehörende Ics einzubinden. Wozu zum Teufel bräuchte man sonst in einem Z80 System einen Interrupt Controller? Ok, rotierende Prioritäten kann der IM2 Mode nicht, aber ein Atmega hat gar keine konfigurierbaren Prioritäten.Ich rotierende P. noch nie gebraucht. > Eigentlich sollte ich mich ja wundern, wie man aus dieser Mücke so einen > Elefanten machen kann, aber ... hmm... > > Synchron würde ich mit dem STI aber wirklich nicht machen wollen. > Bitsync kann er nicht, aber irgendeine nahezu undokumentierte Bytesync > Variation. Bei der hätte man wohl gute Chancen, der erste zu sein, der > das seit Erfindung des Bausteins ausprobiert. Jeder, der Sync im Auge > hatte, hat den SIO verwendet. :-) YMMD! Gaanz früher (Tm) als die Erde noch jung war und der Wind noch richtig aus Holz, da haben wir mal ein Magnetbandinterface mit SIO und SDLC gebastelt und immerhin 9600 Baud vom Band wieder runter bekommen... ...aber einem Kassettentonband trauere ich jetzt nicht wirklich nach.. Gruß, Holm
Holm Tiffe schrieb: > Wozu zum Teufel > bräuchte man sonst in einem Z80 System einen Interrupt Controller? Weil Zilog es sträflich unliess, Bausteine wie den Z80-FDC und den Z80-ADC zu entwickeln. Wenn man also Bausteine ausserhalb der Z80 Serie in den IM2 integrieren wollte und nicht zufällig noch einen passenden CTC- oder PIO-Eingang frei hatte, dann waren 8 Interrupt-Eingänge sicherlich sehr praktisch. Kurzum: Genau für solche Platinen wie seine, wo der ADC-Interrupt einen Anschluss sucht. Bereits bestehende Backplanes der 8080 Ära hatten auch keine IM2 Daisy Chain vorgesehen. > Ok, rotierende Prioritäten kann der IM2 Mode nicht, Der STI auch nicht, der integriert neben Timern und UART 8 klassische Interrupt-Anschlüsse in den IM2.
:
Bearbeitet durch User
A. K. schrieb: > Holm Tiffe schrieb: >> Wozu zum Teufel >> bräuchte man sonst in einem Z80 System einen Interrupt Controller? > > Weil Zilog es sträflich unliess, Bausteine wie den Z80-FDC und den > Z80-ADC zu entwickeln. Wenn man also Bausteine außerhalb der Z80 Serie > in den IM2 integrieren wollte und nicht zufällig noch einen passenden > CTC- oder PIO-Eingang frei hatte, dann waren 8 Interrupt-Eingänge > sicherlich sehr praktisch. Na das ist aber jetzt Quatsch ... Wenn man keinen Eingang frei hat muß man einen Interruptcontroller einsetzten der gleichzeitig Timer und Uart enthält? Die Begründung ist irgendwie "von hinten durch die Brust ins Auge"... Auf einem ADC Bord macht sich ein Timer und oder eine DMA nicht schlecht und die haben jeweils die entsprechenden Möglichkeiten. > > Kurzum: Genau für solche Platinen wie seine, wo der ADC-Interrupt einen > Anschluss sucht. Bereits bestehende Backplanes der 8080 Ära hatten auch > keine IM2 Daisy Chain vorgesehen. Für wie hoch hältst Du den potentiellen Markt für eine Umrüstung damals im Vergleich zu "Neubauten"? Soo viel besser performt ein Z80 nun auch nicht als ein 8080 und für die Rückwärtskompatibilität gabs IM0 und IM1, man ist also nicht auf IM2 angewiesen wenn man eine 8080 Backplane unbedingt benutzten möchte. Du ziehst ganz schön an den Haaren.. > >> Ok, rotierende Prioritäten kann der IM2 Mode nicht, > > Der STI auch nicht, der integriert neben Timern und UART 8 klassische > Interrupt-Anschlüsse in den IM2. Braucht kein Mensch sonst hätte Zilog das Ding gebaut. Statt dessen gabs dann SCC und CIO. Gruß, Holm
Hallo, ihr habt Sorgen um Dinge, die seit Äonen abgfrühstückt sind. Die Bitsync Funktion des MK3801 ist wirklich sehr interessant. Da sscheint eine Art Sync Wort gescchickt zu werden, auf die sich das Slave dann ein sycnrhonisieren kann. Einfach einen Takt und Bits dabei rein und raus war wohl zu einfach. Verschachtelte Ints sind kein Thema, einfach EI direkt am Einsprung einer ISR und schon kann das sich gegenseitig munter unterbrechen, wieder und immer wieder bis wir eine nie endende Rekursion haben und der Stack sich bedrohlich nahe dem Programm nähert und es dann "auffrisst". Für solche Konstrukte ist mir der ARM lieber mit seinen nested interrupts, da er einen sehr ausgeklügelten Interrupt Controller names VIC drin hat, Vektor Interrupt Controller :-) @Holm: Die Ints sind fest priorisiert in einer Tabelle. TX Empty niedriger als RX Full. Übrigens finde ich 9600 baud cool. Erinnert mich an die zeit wo ich mit dem C64 und einem 300 baud Akkustikooppler gesessen habe, eine Liste mit NUI's wo wir ins Datex P rein gingen :-) Glaube da ich ich 15 oder so.
Holm Tiffe schrieb: > Wenn man keinen Eingang frei hat muß man einen Interruptcontroller > einsetzten der gleichzeitig Timer und Uart enthält? Man muss nicht. Man kann. > Du ziehst ganz schön an den Haaren.. Den STI gab es, also hat sich damals jemand Chancen ausgerechnet. Für 68000 gab es m.W. einen ähnlichen Baustein. Warum du nun aber so aggressiv wirst ist mir unklar.
A. K. schrieb: > Warum du nun aber so aggressiv wirst ist mir unklar. Das hat er vom Röhrenforum, zu oft an die Anode gefasst .... :-) Der hies TS38230 für den 68000. 48 Pins a 1,27mm Raster.
Christian J. schrieb: > Die Bitsync Funktion des MK3801 ist wirklich sehr interessant. Scheint mir eher bytesychron zu sein. Bitsync wäre SDLC/HDLC, bytesync eher sowas in Richtung IBM BISYNC. Und die normale PC-Schnittstelle nicht taugt für keines davon. > ... bis wir eine nie endende Rekursion haben. Du unterschätzt den Interrupt Mechanismus der Z80. Verschachtelte Interrupts beim Z80 im IM2 arbeiten prinzipiell ähnlich wie dein ARM/CMx, d.h. nur höher priorisierte Interrupts können eine laufende ISR unterbrechen. Nur ist die Priorität innerhalb eines Bausteins nicht wählbar und die Priorität der Bausteine ergibt sich aus der Verdrahtung. Deshalb gibt es auch den RETI Befehl, der sich seitens der CPU nicht vom RET unterscheidet. Dieser Befehl wird von den Z80 Peripherie-Bausteinen dekodiert und gibt die Daisy Chain wieder frei. Deshalb hat der der STI ein optionales "in service" register, damit das auch innerhalb seiner 16 Interrupts funktionieren kann. > Für solche Konstrukte ist mir der ARM lieber mit seinen nested > interrupts, da er einen sehr ausgeklügelten Interrupt Controller names > VIC drin hat, Vektor Interrupt Controller :-) Vorsicht bei Vergleichen, sie könnten Rohrkrepierer sein ;-). Das Interrupt-System der ARM Prozessoren ist deren schwächere Seite, bevor die Cortex M kamen. Zumal die VICs separate Module waren und jeder Hersteller eigene Brötchen buk (Atmel und ST verwendete bei den ARM7/9 Controllern eigene Module, AD überhaupt keines). Der VIC von ARM ist zumindest in seiner ersten Ausprägung (PL190), zu finden in den LPC2100, keine echte Meisterleistung. Mit dem PL192 in den LPC2300 wurde es besser. Aber erst mit dem NVIC der Cortex M wurde es gut, weil erst da die CPU gut mit Nesting umgehen kann.
:
Bearbeitet durch User
A. K. schrieb: > Holm Tiffe schrieb: >> Wenn man keinen Eingang frei hat muß man einen Interruptcontroller >> einsetzten der gleichzeitig Timer und Uart enthält? > > Man muss nicht. Man kann. > >> Du ziehst ganz schön an den Haaren.. > Eben weil der Fall sehr selten Auftreten wird. Klar schlägt das Ding für kleine Rechner mehrere Fliegen mit einer Klappe für die man sonst mehrere Bausteine bräuchte. Dein Beispiel mit der 8080 Backplane geht aber nach hinten los, weil dieses System Peripherie hat die sowieso Systemfremd ist und mit den beiden "alten" Interruptmodi abgedeckt wird. > Den STI gab es, also hat sich damals jemand Chancen ausgerechnet. Für > 68000 gab es m.W. einen ähnlichen Baustein. > Keine Ahnung. Ich findeden 68k Klasse, habe aber keine Erfahrung damit bis auf die Bastelei mit dr KatCe die schon wieder wegen anderer Dinge in der Ecke liegt.. > Warum du nun aber so aggressiv wirst ist mir unklar. Ich bin doch nicht aggressiv.., calm down. Gruß, HOlm
A. K. schrieb: > Du unterschätzt den Interrupt Mechanismus der Z80. Verschachtelte > Interrupts beim Z80 im IM2 arbeiten prinzipiell ähnlich wie dein > ARM/CMx, d.h. nur höher priorisierte Interrupts können eine laufende ISR > unterbrechen. Moment, mal kurz einhaken. Ich habe keine Chain, weiss nur dass die Prio eben durch die Anordung kodiert ist. Wieso kann jetzt ein Int einen anderen nicht unterbrechen, wenn ich EI setze? Der STI hat die Bits "Interuppt liegt an" und "Pending Ints". Wann werden die gelöscht? Denn nur wenn es irgendeine Meldung gibt, dass ein Int abgearbeitet wurde kann verhindert werden, dass die sich gegenseitig kloppen. Ich habe mit dem LPC2368 mit dem VIC einiges gemacht, fand den sehr durchschaubar und gut zu handeln. Nicht ganz trivial aber noch machbar.
1 | /* Initialize the interrupt controller */ |
2 | /****************************************************************************** |
3 | ** Function name: init_VIC |
4 | ** |
5 | ** Descriptions: Initialize VIC interrupt controller. |
6 | ** parameters: None |
7 | ** Returned value: None |
8 | ** |
9 | ******************************************************************************/ |
10 | void Init_VIC(void) |
11 | { |
12 | uint32_t i = 0; |
13 | uint32_t *vect_addr, *vect_prio; |
14 | |
15 | /* initialize VIC*/ |
16 | VICIntEnClr = 0xffffffff; |
17 | VICVectAddr = 0; |
18 | VICIntSelect = 0; |
19 | |
20 | /* set all the vector and vector control register to 0 */ |
21 | for ( i = 0; i < VIC_SIZE; i++ ) |
22 | { |
23 | vect_addr = (uint32_t *)(VIC_BASE_ADDR + VECT_ADDR_INDEX + i*4); |
24 | vect_prio = (uint32_t *)(VIC_BASE_ADDR + VECT_PRIO_INDEX + i*4); |
25 | *vect_addr = 0x0; |
26 | *vect_prio = 0xF; |
27 | } |
28 | return; |
29 | } |
30 | |
31 | /****************************************************************************** |
32 | ** Function name: install_irq |
33 | ** |
34 | ** Descriptions: Install interrupt handler |
35 | ** parameters: Interrupt number, interrupt handler address, |
36 | ** interrupt priority |
37 | ** Returned value: true or false, return false if IntNum is out of range |
38 | ** |
39 | ******************************************************************************/ |
40 | unsigned long install_irq( uint32_t IntNumber, void *HandlerAddr, uint32_t Priority ) |
41 | { |
42 | uint32_t *vect_addr; |
43 | uint32_t *vect_prio; |
44 | |
45 | VICIntEnClr = 1 << IntNumber; /* Disable Interrupt */ |
46 | if ( IntNumber >= VIC_SIZE ) |
47 | { |
48 | return ( FALSE ); |
49 | } |
50 | else |
51 | { |
52 | /* find first un-assigned VIC address for the handler */ |
53 | vect_addr = (uint32_t *)(VIC_BASE_ADDR + VECT_ADDR_INDEX + IntNumber*4); |
54 | vect_prio = (uint32_t *)(VIC_BASE_ADDR + VECT_PRIO_INDEX + IntNumber*4); |
55 | *vect_addr = (uint32_t)HandlerAddr; /* set interrupt vector */ |
56 | *vect_prio = Priority; |
57 | VICIntEnable = 1 << IntNumber; /* Enable Interrupt */ |
58 | return( TRUE ); |
59 | } |
60 | } |
Christian J. schrieb: > Hallo, > > ihr habt Sorgen um Dinge, die seit Äonen abgfrühstückt sind. Die Bitsync > Funktion des MK3801 ist wirklich sehr interessant. Da sscheint eine Art > Sync Wort gescchickt zu werden, auf die sich das Slave dann ein > sycnrhonisieren kann. Einfach einen Takt und Bits dabei rein und raus > war wohl zu einfach. Die SIO unterstützt Asynchron mit verschiedenen Wortlängen sowie synchron Monosync und Bisync (und externe Synchronisation) sowie SDLC und HDLC. Für die, denen das zu komplex ist, gibts den Z80-Dart, eine kaputte SIO bei der irgendwas im Synchronblock kaputt ist :-) Die SIO ist komplexer als die CPU. Diene SIT hat offenscichtlich nun eine weitere Synchronbetriebsart die sonst keiner macht..wichtig wie ein drittes Knie, das ist was AK meinte. > > Verschachtelte Ints sind kein Thema, einfach EI direkt am Einsprung > einer ISR und schon kann das sich gegenseitig munter unterbrechen, > wieder und immer wieder bis wir eine nie endende Rekursion haben und der > Stack sich bedrohlich nahe dem Programm nähert und es dann "auffrisst". > Für solche Konstrukte ist mir der ARM lieber mit seinen nested > interrupts, da er einen sehr ausgeklügelten Interrupt Controller names > VIC drin hat, Vektor Interrupt Controller :-) > Ein "ARM" an sich hat keinen VIC, das haben allenfalls Implementationen der ARM Architektur. Du müßtest schon mal klar machen von welchem Du redest, sicher nicht Luminary Micro :-) > @Holm: Die Ints sind fest priorisiert in einer Tabelle. TX Empty > niedriger als RX Full. Wie ich mirs gedacht hatte. > > Übrigens finde ich 9600 baud cool. Erinnert mich an die zeit wo ich mit > dem C64 und einem 300 baud Akkustikooppler gesessen habe, eine Liste mit > NUI's wo wir ins Datex P rein gingen :-) Glaube da ich ich 15 oder so. Ich weniger, das kostet mich meine Zeit. Ich habe schon früher das machbare bevorzugt, wegen CTC als Taktgenerator und 2,5Mhz war das oft gerade mal 19200. Gruß, Holm
Holm Tiffe schrieb: > Die SIO ist komplexer als die CPU. Ich weiss..... darum habe ich sie auch nicht benutzt :-) 58 Seiten Handbuch für eine "Tür" mit 2 Drähten dran waren mir zuviel.
Christian J. schrieb: > Moment, mal kurz einhaken. Ich habe keine Chain, weiss nur dass die Prio > eben durch die Anordung kodiert ist. Logisch. Du hast ja auch nur einen entsprechenden Baustein. > Wieso kann jetzt ein Int einen > anderen nicht unterbrechen, wenn ich EI setze? Die Doku zum STI ist auch hier ein wenig maulfaul, aber sind dir die optionale ISRA/B nicht aufgefallen? Bissel was steht dazu sogar drin. Die ergeben nur dann Sinn, wenn damit Interrupts gleicher oder niedrigerer Priorität unterbunden werden, wenngleich das nicht explizit drinsteht. Immerhin ist der STI (auch) ein Interrupt Controller, von dem man so etwas erwarten sollte. > "Interuppt liegt an" und "Pending Ints". Wann werden die gelöscht? Steht in der Doku. Mit Aufruf des Handlers. Aber dann kommen dir ISRA/B ins Spiel und die werden erst mit dem dekodierten RETI Befehl gelöscht. > Ich habe mit dem LPC2368 mit dem VIC einiges gemacht, fand den sehr > durchschaubar und gut zu handeln. Nicht ganz trivial aber noch machbar. Der ist leidlich ok. Das Problem ist die CPU selbst, denn die ARM Cores vor den Cortex M haben sämtlich ein verbocktes Interrupt-System, wenn man Nesting jenseits des FIQ haben will Diese ARMs haben zwar einen partiell separaten Registerkontext und damit auch Stack für Interrupts (an sich eine gute Idee), aber der ist aufgrund eines Konstruktionsfehlers bei Nesting kaum zu gebrauchen. Die Return-Adresse eines Interrupts liegt in gleichen Register des Interrupt-Kontextes wie die Return-Adresse von Unterprogrammaufrufen. Um trotzdem Nesting zu ermöglichen muss man im Handler etwas Aufwand treiben und den Register-Kontext manuell wechseln. Das wirst du aber evtl. dank fertiger IDE nicht gemerkt haben. Entweder macht der Support-Code einen Wrapper um normale C Funktionen als Interrupt-Handler (so machte ich das), oder in den Handlern sind am Anfang und Ende entsprechende Makros mit ASM Befehlen darin.
:
Bearbeitet durch User
A. K. schrieb: > Um trotzdem Nesting zu ermöglichen muss man im Handler etwas Aufwand > treiben und den Register-Kontext manuell wechseln. Das wirst du aber > evtl. dank fertiger IDE nicht gemerkt haben. Entweder macht der > Support-Code einen Wrapper um normale C Funktionen als Interrupt-Handler > (so machte ich das), oder in den Handlern sind am Anfang und Ende > entsprechende Makros mit ASM Befehlen darin. Gibt es irgendwas was Du nicht weisst? Ich habe mich so tief damit gar nicht befasst sondern die von NXP empfohlenen Sourcen benutzt, die dieses Problem scheinbar umgehen. Die IDE hat damit nichts zu tun, die erzeugt mir nur den Startup Code je nach CPU Type.
Christian J. schrieb: > Gibt es irgendwas was Du nicht weisst? Ja. Die Antwort darauf. ;-)
:
Bearbeitet durch User
Aha :-) Ja, ab ddder Primce Cell 0192 haben die da was geändert. Damit musste ich mich mal rumschlagen, immer schön errate sheets lesen :-) The following list shows the functional differences between the PL192 and PL190 PrimeCell VICs: • VIC port fully supported, both in synchronous and asynchronous modes. • The programmers model is different between PL192 and PL190, so code is not backwards-compatible. • 16 standard interrupts replaced with vectored interrupts to give 32 vectored interrupts. • 16 software-programmable interrupt priority levels added, in addition to Aber das ist was anderes als Z80, ein paar Jahre liegen dazwischen.... und doch nur 0 und 1 und das ist einem immer komplizierter werdenden Zusammenhang. Nut mal als beispiel ein Anhang. Mit sowas habe ich nicht die geringste Lust mich damit zu befassen oder es gar verstehen zu wollen. Das Interface einer MMC karte an die PHY im Chip. Das soll einfach nur funktionieren und fertig.
Christian J. schrieb: > Aha :-) Ja, ab ddder Primce Cell 0192 haben die da was geändert. Yep, aber das hat nichts mit dem Problem der CPU zu tun. Aber die teilweise nichtvektorierten Interrupts der PL190 waren damit Geschichte. Wenn du ein wenig im Web suchst wirst du sowohl bei NXP als auch im Web einige hitzige Diskussionen zu "spurious interrupts" und "surprise interrupts" finden. Wobei die NXP Doku dazu nicht unbedingt der Stein der Weisen ist. Die "spurious interrupts" landen bei der PL190 im gleichen Vektor wie die nichtvektorierten, was viele Leute irritierte. Atmel war bei den SAM7 immerhin so klug, die "spurious interrupts" separat unterzubringen. Die "surprise interrupts" sind ein weiterer Konstruktionsfehler der Basisarchitektur der ARMs vor den Cortexen und können bei Verwendung von FIQs seltsame Blüten treiben.
Christian J. schrieb: > Nut mal als beispiel ein Anhang. Nesting kriegst du mit diesem Code aber nicht. Auch wenns der VIC kann, dein Code kann es nicht, denn wie auch bei der Z80 muss man die IRQs dazu explizit am Anfang des Handlers freigeben - und eben den erwähnten Hack fürs Nesting einbauen. Solange man kein Nesting braucht ist es daher auch besser, wenn man drauf verzichtet.
:
Bearbeitet durch User
A. K. schrieb: > Nesting kriegst du mit diesem Code aber nicht. Auch wenns der VIC kann, > dein Code kann es nicht, denn wie auch bei der Z80 muss man die IRQs > dazu explizit am Anfang des Handlers freigeben. Ahh..... nein, das war nur ein Beispiel wo MEINE Grenzen liegen, ok? Worüber sich hier einige aufregen. Das war nur mal für die SD karte, die ich auch innendrin kannte, zumindest das SPI Interface, nicht aber das MMC. Und das ist eine Adaption dieser Karte an eine PHY im LPC und um die schreiben zu können kann man sich 1 Monat damit auseinandersetzen wie die MMC Spec 3.0 funktioniert und dazu noch wie der ARM das unterstützt. Oder man nimmt .... eine fertige LIB die ca 20 API Funktionen hat, schliesst die an eigene Routinen an, verdrahtet die Ints und kümmert sich einen Shice darum wie die das macht.
Sowas hier macht Spass zu Programmieren :-) Mal sehen ob der Z80 damit auch klar kommt und mit wieviel Code.
1 | /////////////////////////////////////////////////////////////////////////////////// |
2 | /* |
3 | Funktion: CalcSonnenAufgang() |
4 | Modul : rtc_user.c |
5 | -------------------------------------------------------------------------------- |
6 | Beschreibung : Berechnet den Sonnenaufgang und Untergang |
7 | |
8 | Zeitgleichung: WOZ - MOZ = -0.171*sin(0.0337 * T + 0.465) - 0.1299*sin(0.01787 * T - 0.168) |
9 | Deklination = 0.4095*sin(0.016906*(T-80.086)) |
10 | Zeitdifferenz = 12*arccos((sin(h) - sin(B)*sin(Deklination)) / (cos(B)*cos(Deklination)))/pi; |
11 | Sonnenaufgang h=-50 Bogenminuten = -0.0145 |
12 | |
13 | Aufgang Ortszeit = 12 - Zeitdifferenz - Zeitgleichung |
14 | Untergang Ortszeit = 12 + Zeitdifferenz - Zeitgleichung |
15 | |
16 | Aufgang = Aufgang Ortszeit - geographische Länge /15 + Zeitzone |
17 | Untergang = Untergang Ortszeit - geographische Länge /15 + Zeitzone |
18 | |
19 | aufgerufene Funktionen : |
20 | Eingabeparameter : ptr (Zeiger auf aktuelle Zeit für Sommerzeit) |
21 | sonne (Zeiger auf Ergebnisstruktur |
22 | T (Tag des Jahres) |
23 | Rückgabe : - |
24 | veränderte Globals : SAG_Std,SAG_Min, SUG_Std,SUG_Min |
25 | öffentlich/private : öffentlich |
26 | |
27 | Autor: Christian J. |
28 | letzte Änderung: 20.2.2009 |
29 | */ |
30 | //////////////////////////////////////////////////////////////////////////////////// |
31 | |
32 | |
33 | uint8_t CalcSonnenAufgang(zeit_t *ptr, struct sonnenstand *sonne, uint16_t T) |
34 | { |
35 | #define hoehe -0.0145 // Sonnenhöhe in RAD |
36 | #define PI 3.141592654 |
37 | |
38 | float B, |
39 | Deklination, // Deklination der Sonne |
40 | Zeitdiff, // Zeitdifferenz |
41 | DIFF_WOZ_MOZ, |
42 | Aufgang_MOZ, // Aufgang mittlere Ortzeit |
43 | Untergang_MOZ, // Aufgang mittlere Ortszeit |
44 | Aufgang_WOZ, // Aufgang wahre Ortszeit |
45 | Untergang_WOZ; // Untergang wahre Ortszeit |
46 | |
47 | static uint16_t oldvalue = 0; |
48 | |
49 | |
50 | // Prüfen, ob Berechnungen für aktuellen Tag bereits vorliegen |
51 | |
52 | if (oldvalue == T) |
53 | return 1; |
54 | |
55 | oldvalue = T; |
56 | |
57 | // Berechnungen |
58 | B = PI *N_BREITE / 180; |
59 | Deklination = 0.4095*sin(0.016906*(T-80.086)); |
60 | Zeitdiff = 12*acos((sin(hoehe) - sin(B)*sin(Deklination)) / (cos(B)*cos(Deklination)))/PI; |
61 | DIFF_WOZ_MOZ = -0.171*sin(0.0337*T+0.465) - 0.1299*sin(0.01787*T-0.168); // WOZ-MOZ |
62 | |
63 | Aufgang_MOZ = 12 - Zeitdiff - DIFF_WOZ_MOZ; |
64 | Untergang_MOZ = 12 + Zeitdiff - DIFF_WOZ_MOZ; |
65 | |
66 | Aufgang_WOZ = Aufgang_MOZ + (15 - O_LAENGE)*(float)4/60; |
67 | Untergang_WOZ = Untergang_MOZ + (15 - O_LAENGE)*(float)4/60; |
68 | |
69 | |
70 | // Sommerzeit berücksichtigen |
71 | if (IsSommerzeit(ptr)) { |
72 | Aufgang_WOZ = Aufgang_WOZ + 1; |
73 | Untergang_WOZ = Untergang_WOZ + 1; |
74 | } |
75 | |
76 | // globale Float Werte setzen |
77 | sonne->f_SAG = Aufgang_WOZ; |
78 | sonne->f_SUG = Untergang_WOZ; |
79 | sonne->f_Tagdauer = sonne->f_SUG - sonne->f_SAG; |
80 | |
81 | // Umrechnung in Stunden/Minuten |
82 | |
83 | sonne->SAG_Std = floor(Aufgang_WOZ); // Sonnenaufgang |
84 | sonne->SAG_Min = (Aufgang_WOZ - (float)sonne->SAG_Std) * 60; |
85 | |
86 | sonne->SUG_Std = ceil(Untergang_WOZ)-1; // Sonnenuntergang |
87 | sonne->SUG_Min = (Untergang_WOZ - (float)sonne->SUG_Std) * 60; |
88 | |
89 | return 1; |
90 | } |
Christian J. schrieb: > Sowas hier macht Spass zu Programmieren :-) Ach herrje. Genau das hat mein Vater von einigen Jahren in BASIC programmiert. Da ging er schon auf die 80 zu. ;-)
:
Bearbeitet durch User
Stör mich jetzt nicht, ich arbeite ARM auf Z80 grad um.... das Rad wurde von mir ja schon vor 5 jahren erfunden und was sich am Porsche bei 200 km/h dreht wird es sicher auch am VW Käfer mit 80 km/h.....
Wenn ich sowas lese: Die Ausgabe von Zeichenketten im Hauptprogramm erfolgt mit sprintf(uart_buffer," Text 1......"); Uart_Write(); dann wundere ich mich, wie Du den darunterstehenden Code hinbekommen hast. Oder ist der abgekupfert? Das Monstrum sprintf() braucht man nur für formatierte Ausgabe. In dem obigen Beispiel wird aber überhaupt keine Formatierung enthalten. Hier reicht ein einfacher strcpy(), welcher um ein Vielfaches kleiner ist: strcpy(uart_buffer," Text 1......"); Also: Entweder ersetzt Du obiges Beispiel durch etwas komplexeres oder sprintf() durch strcpy(). ;-) P.S. Der größte Fehler von K&R war es, das allererste Hello-World-Programm mit einem printf() zu beginnen. Ein simpler Aufruf von puts() hätte es auch getan und wäre taktisch viel klüger gewesen. Aber so wurden direkt alle angehenden Programmierer "versaut".
:
Bearbeitet durch Moderator
Christian J. schrieb: > A. K. schrieb: > >> Warum du nun aber so aggressiv wirst ist mir unklar. > > Das hat er vom Röhrenforum, zu oft an die Anode gefasst .... :-) Das letzte mal das ich von irgend einer Anode eine gelatscht bekommen habe muß so ca. Mitte der 80er gewesen sein. > > Der hies TS38230 für den 68000. 48 Pins a 1,27mm Raster. Hieß er nicht. der 68230 hieß in erster Linie MC und TS nur als Nachbau von Toshiba, das ist der PIT. Er meint aber eigentlich den MC68901. Gruß, Holm
Frank M. schrieb: > Ein simpler Aufruf von puts() hätte es > auch getan und wäre taktisch viel klüger gewesen. Schlaue Compiler wissen das, und machen bei einem Aufruf von printf(), der nur den Formatstring hat, genau das. :)
Holm Tiffe schrieb: > Er meint aber eigentlich den MC68901. Der ist dermassen dicht am STI dann man dessen etwas bessere Doku wohl auch für den STI verwenden kann. Sogar den IM2 Modus hat er (eine IEI/IEO Chain).
A. K. schrieb: > Holm Tiffe schrieb: >> Er meint aber eigentlich den MC68901. > > Der ist dermassen dicht am STI dann man dessen etwas bessere Doku wohl > auch für den STI verwenden kann. Sogar den IM2 Modus hat er (eine > IEI/IEO Chain). Ja, ist irre für ein MC68K Peripheral. Auf so weitgehende Ähnlichkeit das man die Doku verwenden kann würde ich mich aber nicht verlassen wollen. Eine ähnliche Ähnlichkeit habe ich mal zwischen Z80-SIO und µPD7201 festgestellt, der µPD7201 ist eine SIO mit umgerüstetem Interrupt System für 8086 und Ähnliche CPUs wie es aussieht. Ich habe aber irgnendwo gelesen das die Leute auch nicht ganz so zufrieden mit dem Ding waren.. Gruß, Holm
Hallo Fans! Aktuel ist kleine Pause, da ich noch mit den Ringpuffern kämpfe, die sich bei genauem Hinschauen und "Wenn dann was?" Durchdenken doch ewas komplexer verhalten. Nicht wie sie sie ringeln, dazu reicht wr_ptr = (wr_ptr +1) % SIZE sondern die Sonderfälle und 1:1000000 Fälle, die auftreten können und die gegeneinander abgeriegelt werden müssten durch "Semaphore". Außerdem meldet sich TX int per Mode 2 nur wenn Buffer leer ist, muss aber zum Senden wieder angetriggert werden. TX und RX komplett beide in einer ISR jetzt. Das muss erstmal laufen und der Code fehlerfrei sein.... Bis später.... [code] // RX Empfangspuffer struct rx_type{ int8_t buf[RX_BUF_SIZE+1]; uint8_t rd_ptr; // Read Pointer, nur durch Hauptprogramm lesen uint8_t wr_ptr; // Write Pointer, nur durch Interrupt schreiben uint8_t f_buf_full; // flag:Es sind Zeichen da uint8_t f_buf_overflow; // flag:Overflow: WR Zeiger hat RD überholt: Buffer wertlos }; // TX Sendepuffer struct tx_type{ int8_t buf[TX_BUF_SIZE+1]; uint8_t rd_ptr; // Read Pointer, nur durch Hauptprogramm lesen uint8_t wr_ptr; // Write Pointer, nur durch Interrupt schreiben uint8_t f_buf_full; // Ringpuffer ist komplett voll uint8_t f_buf_empty; // Ringpuffer ist ganz leer uint8_t f_idle; // TX Hardware ist inaktiv }; /* Sonderfaelle des RX Receive Ringpuffers * 0......................END * ...rd->......wr->......... Normalfall * .......wr-> ....rd->...... Normalfall * rd/wr...................... Start oder Puffer leer * ........rd/wr.............. Puffer leer * */ char getchar() { register char ch; // Bei leerem Puffer 0 zurück liefern if (!rx.f_buf_full) return (0); // Ints aus, da Lesezugriff __asm di __endasm ; // Zeichen auslesen ch = rx.buf[rx.rd_ptr]; // Read Pointer am Array Ende zurück setzen rx.rd_ptr = (rx.rd_ptr +1) % RX_BUF_SIZE; // Alle Zeichen gelesen? rx.f_buf_full = (rx.rd_ptr == rx.wr_ptr) ? false : true; __asm ei __endasm ; return(ch); } ///////////////////////////////////////////////////////// // Zeichenausgabe für printf auf der STI mit 9600 Baud /* Sonderfaelle des TX Transfer Ringpuffers * 0......................END * ...rd->......wr->......... Normalfall * .......wr-> ....rd->...... Normalfall * wr/rd...................... Start oder Puffer voll * ........wr/rd.............. Puffer voll * */ void putchar(char c) { if (!tx.f_buf_full) { __asm di __endasm ; // Zeichen einschreiben tx.buf[tx.wr_ptr] = c; // wr+1 am Bufferende auf 0 zurücksetzen rx.wr_ptr = (rx.wr_ptr +1) % RX_BUF_SIZE; // Wurde Position ISR RD Zeiger erreicht? Dann voll. tx.f_buf_full = (tx.wr_ptr == tx.rd_ptr) ? true : false; // Wenn TX inaktiv muss ISR angestossen werden if (tx.f_idle) STI_UDR = tx.buf[tx.rd_ptr]; __asm ei __endasm ; } } void int_sti_receive_buffer_full(void) __interrupt { register uint8_t zeichen; zeichen = STI_UDR; // Zeichen abholen if (!rx.f_buf_overflow) { PIO8255_PORT_A = ~zeichen; // Zeichen auf LED // Zeichen in Ringpuffer schreiben rx.buf[rx.wr_ptr] = zeichen; // wr+1 Zeiger am Bufferende? Dann 0 setzen rx.wr_ptr = (rx.wr_ptr +1) % RX_BUF_SIZE; // WR >= RD : Buffer Overflow => Aktion erforderlich rx.f_buf_overflow = (rx.wr_ptr == rx.rd_ptr) ? true : false; // Meldung an Hauptprogramm: Zeichen ist da rx.f_buf_full = true; } __asm ei __endasm ; } //////////////////////////////////////////////// // ISR: Uart TX Sendepuffer ist leer // putchar() muss dafür sorgen, dass er wieder voll wird /* Sonderfaelle des TX Transfer Ringpuffers * 0......................END * ...rd->......wr->......... Normalfall * .......wr-> ....rd->...... Normalfall * wr/rd...................... Start oder Puffer voll * ........wr/rd.............. Puffer voll * */ void int_sti_transmit_buffer_empty(void) __interrupt { /* TX hat letztes Byte gesendet und muss nachschauen * ob weitere Bytes zu senden sind */ tx.f_idle = true; // TX Idle Flag, Uart inaktiv /* TX ISR muss extern angestossen werden, damit * diese Routine hier aufgerufen wird, wenn Puffer * leer ist */ // Sind noch Zeichen im TX Buffer? if (tx.rd_ptr < tx.wr_ptr) { tx.f_idle = false; // Flag TX aktiv tx.f_buf_full = false; // TX Full Flag zurücksetzen STI_UDR = tx.buf[tx.rd_ptr]; // Byte einschreiben tx.rd_ptr = (tx.rd_ptr +1) % RX_BUF_SIZE; // Read Pointer bei Überlauf auf 0 } else tx.f_buf_empty = true; __asm ei __endasm ; }
Machs nicht so kompliziert. Im Anhang sind getestete Routinen für AVR. Aus Performancegründen dürfen die Ringpuffer hier nur maximal 256 Byte groß sein, und die Größe muß eine 2-er Potenz sein. Der Hardwareteil sollte sich leicht auf STI umstricken lassen. Ansonsten - Die Funktion _write() und alles was damit zusammen hängt, rauswerfen. Dafür muß dann wahrscheinlich stdint.h rein - In serial.c die ersten 5 Includes rauswerfen. - Statt ATOMIC_BLOCK: di/ei - Die auskommentierte String-Ausgabefunktion ring_write() kann einen Deadlock produzieren. Da man die nicht unbedingt braucht, habe ich mich nicht weiter drum gekümmert. Also nicht benutzen. Das müßte es eigentlich gewesen sein. Wenn das so läuft, kann man noch optimieren.
Ich denke es kostet genauso viel Zeit einen Fremdcode anzupassen wie es Zeit dauert was eigenes zu schreiben was man dann auch komplett versteht. Nicht kompliziert, nur gibt es einige Sonderfälle zu betrachten und Fehler abzufangen, wenn da was nicht so läuft wie es soll. Das sausen ja 2 Zeiger drin herum, die sich kreuz und quer überholen können und was vonn außen kommt kann weder aufgehalten noch gebremst werden. AVR Code ja recht kurz aber andere UART, meine ist deutlich mehr Retro, da klappern noch die Relais im Chip :-) Denksport, soll ja Spass machen und schöner Code macht mir Spass :-) Die normale getchar() wartet glaube ich ewig bis was reinkommt? Timeout und Flags zur Anzeige sind da nicht vorgesehen.
> AVR Code ja recht kurz aber andere UART, meine ist deutlich mehr Retro, > da klappern noch die Relais im Chip :-) Der Code ist aber nicht wegen AVR so kurz. Allenfalls die Initialisierung ist da etwas kompakter. Er ist deshalb so kurz, weil er gut überlegt ist (*), und es die Sonder- und Fehlerfälle, wegen denen Du Dir Dein Hirn marterst, hier garnicht gibt. * Wenn beide Zeiger, bzw. Indexe gleich stehen, ist der Puffer leer. * Wenn der Lesezeiger eins hinter dem Schreibzeiger steht, ist der Puffer voll. * Counter braucht man dann nicht. Man kann nur ein Byte im Puffer nicht benutzen. * Durch die Limitierung der Pufferlänge auf 2-er Potenzen, reduziert die Prüfung eines Zeigers auf Pufferende und ggf. Zurücksetzen beim Weiterzählen auf eine einfache Maskierung. Das ist alles. (*) Nicht von mir. Das haben Generationen von Programmierern schon vorher so gemacht.
Den einzigen Unterschied zu meiner Lösung sehe ich nur hier: ep = (ep + 1) & ring->mask; Ich habe ep = (ep + 1) % SIZE; wobei % etwas mehr Code braucht als eine Maske, weil _modint aufgerufen werden muss und das jedesmal. und ich benutze globale Variablen, damit keine dynamischen erzeugt und Parameter übergeben werden müssen. that all. Macht schon was aus: a) driver.c:79: rx.rd_ptr = (rx.rd_ptr +1) % RX_BUF_SIZE; 0064 16 00 [ 7] 165 ld d,#0x00 0066 13 [ 6] 166 inc de 0067 C5 [11] 167 push bc 0068 21 80 00 [10] 168 ld hl,#0x0080 006B E5 [11] 169 push hl 006C D5 [11] 170 push de 006D CDr00r00 [17] 171 call __modsint 0070 F1 [10] 172 pop af 0071 F1 [10] 173 pop af 0072 C1 [10] 174 pop bc 0073 55 [ 4] 175 ld d,l 0074 21r08r01 [10] 176 ld hl,#(_rx + 0x0081) 0077 72 [ 7] 177 ld (hl),d b) 178 ;driver.c:80: rx.rd_ptr = (rx.rd_ptr +1) & rx.mask; 0078 14 [ 4] 179 inc d 0079 3Ar0Ar01 [13] 180 ld a, (#_rx + 131) 007C A2 [ 4] 181 and a, d 007D 57 [ 4] 182 ld d,a 007E 72 [ 7] 183 ld (hl),d
Christian J. schrieb: > Macht schon was aus: Es ist nicht nur die Zeilenanzahl-Differenz, sondern das hier ist richtig heftig: > 006D CDr00r00 [17] 171 call __modsint Da kommt noch einiges dazu.
:
Bearbeitet durch Moderator
Hi, ja, ich habe es umgeschrieben auf "Maske", recht simple Überlegung aber schon "pfiffig". Erinnert mich an das Zaks Buch Z80: Der erste Entwurf läuft aber es ist kein optimaler Entwurf. Im Buch wird eine 16 Bit Multiplikation optmiert, vom ersten Entwurf und dann dem Optimum, was 50% schneller läuft. Trotzdem läuft es noch nichr richtig. Zeicheneingabe ja, Ausgabe hakt noch, da verhaspelt er sich und es kommt Müll. Total vorbei ist es wenn ich vom Z80 dauernd sende und gleichzeitig vom PC Daten schicke so dass RX und TX aufgerufen werden. Es gibt nur einen "TX empty" Interrupt. D.h. der TX muss vom Hauptprogram getriggert werden durch STI_TX = zeichen, damit der nächste Int, wenn Zeichen raus ist dann in der ISR die weitere Verarbeitung des Puffers übernimmt. Wenn letztes Zeichen raus, dann bleibt TX stehen, der Int wird nicht mehr aufgerufen. Das Antriggern läuft noch nicht. Aktuell schreibe ich Testroutinen, die das simulieren sollen, Volllast usw. So einfach ist das nicht.
Christian J. schrieb: > Es gibt nur einen "TX empty" Interrupt. D.h. der TX muss vom > Hauptprogram getriggert werden durch STI_TX = zeichen, damit der nächste > Int, wenn Zeichen raus ist dann in der ISR die weitere Verarbeitung des > Puffers übernimmt. Wenn letztes Zeichen raus, dann bleibt TX stehen, der > Int wird nicht mehr aufgerufen. Das Antriggern läuft noch nicht. Schau Dir mal mcurses_phyio_putc() für den AVR an. Verfahren als Pseudocode:
1 | mcurses_phyio_putc (uint8_t ch) |
2 | {
|
3 | zeichen_in_ringbuffer_schreiben; |
4 | tx_empty_interrupt_aktivieren; |
5 | }
|
6 | |
7 | ISR(TX_EMPTY) |
8 | {
|
9 | if (ringbuffer_leer) |
10 | {
|
11 | tx_empty_interrupt_deaktivieren; |
12 | }
|
13 | else
|
14 | {
|
15 | ein_zeichen_aus_ringbuffer_lesen; |
16 | das_zeichen_auf_die_reise_schicken; |
17 | }
|
18 | }
|
> Wenn letztes Zeichen raus, dann bleibt TX stehen,
Der Witz ist, dass Du in dem Teil, wo Du ein Zeichen in den Ringbuffer
schreibst, danach auf jeden Fall den TX-Empty-Interrupt aktivieren
musst. Ohne wenn und aber.
:
Bearbeitet durch Moderator
Frank M. schrieb: > Der Witz ist, dass Du in dem Teil, wo Du ein Zeichen in den Ringbuffer > schreibst, danach auf jeden Fall den TX-Empty-Interrupt aktivieren > musst. Ohne wenn und aber Eben! und wie aktiviert man den? Obn so tricks funktionieren wie das Interrupt Flag der STI per Hand zu setzen weiss ich nicht. Der würde dann in genau dem Moment ausgelöst, wo der Schreib Befehl zu Ende ist. Es steht nicth dabei ob das register schreibbar ist. Die Flags werden von der hardware gesetzt. INT Empty wird normalerweise nur aufgerufen, wenn da das TX Schieberegister leer ist.
1 | void putchar(char c) |
2 | { |
3 | |
4 | while(tx.f_buf_full); // FIXXXME! |
5 | |
6 | __asm |
7 | di |
8 | __endasm ; |
9 | |
10 | tx.buf[tx.wr_ptr] = c; // Zeichen einschreiben |
11 | tx.wr_ptr = (tx.wr_ptr +1) & tx.mask; // Zeiger rollen |
12 | tx.f_buf_full = (tx.wr_ptr == tx.rd_ptr) ? true : false; // Buffer voll? |
13 | if (tx.f_idle) // Wenn TX inaktiv muss ISR angestossen werden |
14 | STI_UDR = tx.buf[tx.rd_ptr]; |
15 | |
16 | __asm |
17 | ei |
18 | __endasm ; |
19 | |
20 | |
21 | } |
Frank M. schrieb: > Der Witz ist, dass Du in dem Teil, wo Du ein Zeichen in den Ringbuffer > schreibst, danach auf jeden Fall den TX-Empty-Interrupt aktivieren > musst. Ohne wenn und aber. Wahrscheinlich hat Christian oben recht, und die Freigabe allein reicht nicht. kann sein, daß das Tx-Interrupt-Flag des STI nur gesetzt wird, wenn der Tx-Buffer leer wird, und nicht, wenn er leer ist. Wenn daß so ist, muß man beim Schreiben in den Sendefifo prüfen, ob der Tx-Interrupt enabled ist, und wenn nicht, das Zeichen in den STI, statt in den FIFO schreiben.
Leo C. schrieb: > Wenn daß so ist, muß man beim Schreiben in den Sendefifo prüfen, ob der > Tx-Interrupt enabled ist, und wenn nicht, das Zeichen in den STI, statt > in den FIFO schreiben Die TX ISR läuft nur an, nachdem ein Zeichen rausgeschoben wurde, was im Hauptprogramm in den STI Data geschoben wurde. Dann guckt die ISR nach ob weitere Zeichen vorliegen und stoppt sobald die Indexe sich decken. Das kann immer der Fall sein und schon ist "Schluss". Da muss ich mir was einfallen lassen...
Nachtrag: 2. Möglichkeit (wenn obiges zutrifft): Man braucht den STI-Interrupt in der Tx-Interrupt-Routine dann nicht zu sperren. In der Fifo-Schreibroutine dann prüfen, ob Fifo leer und STI-TxBuf leer, und Zeichen dann in STI schreiben. Edit: Wenn das Gestammel unverständlich ist, bitte nochmal nachfragen...
:
Bearbeitet durch User
So, mal streng nach Sherlock McCoder: 1. "TX empty" muss nur einmal eingeschaaltet werden und bleibt dann auch an. Gibt keinen Grund die abzuschalten. 2. "TX Empty ISR" setzt Flag: Ring ist leer, bin fertig!" Damit das kommt muss der Ring aber erstmal voll sein! Mindest 1 Zeichen. 3. putchar() guckt nach: Ist Ring leer? Dann wird es schwieriger: Muss das Zeichen in den Ringpuffer rein UND in das Data Register der TX? Die TX ISR wird nur laufen, wenn TX Data beschrieben wurde und beim nächstsen Aufruf würde sie das gleiche zeichen doppelt holen und senden. Henne oder Ei? Was war zuerst?
1 | void int_sti_transmit_buffer_empty(void) __interrupt |
2 | { |
3 | /* TX hat letztes Byte gesendet und muss nachschauen |
4 | * ob weitere Bytes zu senden sind */ |
5 | |
6 | /* TX ISR muss extern angestossen werden, damit |
7 | * diese Routine hier aufgerufen wird, wenn Puffer |
8 | * leer ist */ |
9 | |
10 | // Sind noch Zeichen im TX Buffer? |
11 | if (tx.rd_ptr != tx.wr_ptr) |
12 | { // ja... |
13 | tx.f_idle = false; // Flag TX aktiv |
14 | tx.f_buf_full = false; // TX Full Flag zurücksetzen |
15 | STI_UDR = tx.buf[tx.rd_ptr]; // Byte einschreiben |
16 | tx.rd_ptr = (tx.rd_ptr +1) & tx.mask; // Rotieren |
17 | } else |
18 | { |
19 | //nein... |
20 | tx.f_idle = true; // TX Idle Flag, Uart inaktiv |
21 | tx.f_buf_full = false; |
22 | } |
23 | __asm |
24 | ei |
25 | __endasm ; |
26 | } |
Leo C. schrieb: > Wahrscheinlich hat Christian oben recht, und die Freigabe allein reicht > nicht. kann sein, daß das Tx-Interrupt-Flag des STI nur gesetzt wird, > wenn der Tx-Buffer leer wird, und nicht, wenn er leer ist. Wenn dem tatsächlich so ist, dann kann man das mit folgendem PseudoCode erschlagen:
1 | if (ringbuffer_leer && STI_bereit_zum_senden) |
2 | {
|
3 | zeichen_an_sti_senden; |
4 | }
|
5 | else
|
6 | {
|
7 | zeichen_in_ringbuffer_ablegen
|
8 | }
|
9 | TX_EMPTY_interrupt aktivieren; |
Das erste Zeichen geht damit direkt an den STI und damit wird garantiert ein Interrupt erzeugt, sobald das zeichen auf den Weg geschickt wurde. Im Interrupts kann nun das nächste Zeichen an den STI geschickt werden - falls ein weiteres Zeichen bereits wartet.
Andere Herangehensweise:
Problem: putchar() kann ununterbrochen aufgerufen werden, kann ja sein
dass jede Menge Text zu schreiben ist. Der Puffer ist viel schneller
voll geschrieben als er von der ISR geleert wird. D.h. sobald eine
zeichen raus ist schon das nächste im Ring, der zeiger WRITE steht immer
DIREKT hinter READ bzw auf READ.
D.h. putchar MUSS warten! Oder es gehen zeichen verloren.
Es kann sein dass es keinen Unterschied macht ob man eine ISR verwendet
oder die Bytes per Hand reinschreibt und immer nachschiebt wenn es raus
ist.
>>TX_EMPTY_interrupt aktivieren;
Was heisst das? Den einschalten oder den "anspringen" lassen, was nicht
geht.
Frank M. schrieb: > TX_EMPTY_interrupt aktivieren; Die Zeile habe ich übersehen. Der Interrupt kann einmalig in der Initialisierung freigegeben werden. Da er nicht gesperrt wird, wenn der FIFO leer ist, reicht das.
Christian J. schrieb: > D.h. putchar MUSS warten! Oder es gehen zeichen verloren. Korrekt: Jeder Ringbuffer kann voll werden. Solange putchar immer noch unterbrechbar (zum Lesen von ankommenden Zeichen) ist, sollte das nicht tragisch sein. BTW: Als Z80-User hast Du ja den Komfort eines gigantisch großen RAMs (jedenfalls im Vergleich zu AVRs). Wie groß sind Deine TX- und RX-Buffer? > Was heisst das? Den einschalten oder den "anspringen" lassen, was nicht > geht. Den Einschalten. Anspringen wird er von selbst, nämlich dann, wenn das erste Zeichen raus ist.
:
Bearbeitet durch Moderator
1 | void putchar(char c) |
2 | { |
3 | char tx_empty; |
4 | _asm |
5 | di |
6 | __endasm ; |
7 | |
8 | tx_empty = STI_TSR & 0x80; |
9 | |
10 | // TX frei und Ring leer? |
11 | if (tx_empty && (tx.wr_ptr==tx.rd_ptr)) |
12 | STI_UDR = c; // Byte einschreiben |
13 | |
14 | else { |
15 | tx.buf[tx.wr_ptr] = c; // Zeichen einschreiben |
16 | tx.wr_ptr = (tx.wr_ptr +1) & tx.mask; // Zeiger rollen |
17 | tx.f_buf_full = (tx.wr_ptr == tx.rd_ptr) ? true : false; // Buffer voll? |
18 | } |
19 | __asm |
20 | ei |
21 | __endasm ; |
22 | |
23 | |
24 | } |
Leo C. schrieb: > Die Zeile habe ich übersehen. Der Interrupt kann einmalig in der > Initialisierung freigegeben werden. Da er nicht gesperrt wird, wenn der > FIFO leer ist, reicht das. Gut, wenn das einmalig reicht, weil man nur Interrupts bekommt, wenn der TX leer wird und nicht leer ist (Dauerfeuer wie beim AVR), dann haben wir ja jetzt die Lösung:
1 | init () |
2 | {
|
3 | TX_EMPTY_interrupt aktivieren; |
4 | }
|
5 | |
6 | putchar (uint8_t ch) |
7 | {
|
8 | if (ringbuffer_leer && STI_bereit_zum_senden) |
9 | {
|
10 | zeichen_an_sti_senden; |
11 | }
|
12 | else
|
13 | {
|
14 | zeichen_in_ringbuffer_ablegen
|
15 | }
|
16 | }
|
17 | |
18 | ISR(TX_EMPTY) |
19 | {
|
20 | if (! ringbuffer_leer) |
21 | {
|
22 | ein_zeichen_aus_ringbuffer_lesen; |
23 | das_zeichen_auf_die_reise_schicken; |
24 | }
|
25 | }
|
>>TX leer wird und nicht leer ist
das muss ich noch ausprobieren, genau weiss ich das nicht, ob der pegel
oder flankengetriggert ist. NMI ist pegelgetriggert, der steht dann auf
Dauerfeuer.
Christian J. schrieb: >
1 | > void putchar(char c) |
2 | > { |
3 | > char tx_empty; |
4 | > _asm |
5 | > di |
6 | > __endasm ; |
7 | > .... |
8 | > __asm |
9 | > ei |
10 | > __endasm ; |
11 | > } |
12 | > |
Durch "di" am Anfang und "ei" am Ende machst Du putchar ununterbrechbar. Kein Wunder, dass das nicht sauber funktioniert. Hatte ich nicht schon mehrfach geschrieben, dass putchar unterbrechbar sein muss, wenn es wartet? Apropos.... Wo wartest Du da eigentlich, wenn der Buffer voll ist? Du überschreibst ja den Buffer im Kreis ohne Rücksicht auf Verluste! Wo hast Du denn diese Sch...-Routinen gekupfert?!?
:
Bearbeitet durch Moderator
@Frank: meinst du vielleicht das hier? 1. Ring ist leer = gar nix drin oder 2. Im Ring ist noch Platz für 1 Zeichen ?
>>Apropos.... Wo wartest Du da eigentlich, wenn der Buffer voll ist? Du >>überschreibst ja den Buffer im Kreis ohne Rücksicht auf Verluste! Wo >>hast Du denn diese Sch...-Routinen gekupfert?!? Fraaaaaaaaaaaaaaaaaaaaaank! Das ist kein fertiger Code, sonder das was ich gerade auf dem Schirm habe! Der tut noch nicht. Brettert alles platt, wenn es da nichts ist was ihn aufhält.
Christian J. schrieb: > Das ist kein fertiger Code, sonder das was ich gerade auf dem Schirm > habe! Der tut noch nicht. Warum postest Du den dann? Warum nimmst Du nicht den Ringbuffer-Code aus mcurses? Der kommt mit minimalen volatile-Variablen aus und braucht auch keine Ringbuffer-Größe, welche eine Zweierpotenz ist. Zudem ist er absolut simpel und effizient.
Gabs alles schonmal hier: Beitrag "UART Sendepuffer" Ich benutze ungern Code, den ich nicht komplett verstanden habe. Und ein AVR ist kein Z80. Es geht nicht um das Prinzip von Ringpuffer, sondern daran wie der hier mit der Hardware verquickt wird. und das werde ich jetzt auf dem Balkon mit einem Kaffee durchdenken....
Christian J. schrieb: > Gabs alles schonmal hier: > > Beitrag "UART Sendepuffer" Was sollen denn diese Nebelkerzen?
Hallo! Habe gerade noch mal im Quelltext zu meinem CP/M-System nachgesehen: Beitrag "Re: Retro Fieber: Z80 oder 68000 ?" Ich nutze nur für den Empfang vom PC den RX-Interrupt der SIO. Damit wird der Ringpuffer gefüllt. Per Hardware-Handshake gibt es keinen Pufferüberlauf. Das Senden geht mit Polling. Dafür braucht es keinen INT. Für das Anzeigen am PC-Terminal muß es nicht mikrosekundengenau sein. Ich sehe in der putchar-Routine nach: ist das vorherige Zeichen weg, dann das nächste ins Senderegister und wieder raus.
Route 66 schrieb: > Das Senden geht mit Polling. Dafür braucht es keinen INT. Für das > Anzeigen am PC-Terminal muß es nicht mikrosekundengenau sein. > Ich sehe in der putchar-Routine nach: ist das vorherige Zeichen weg, > dann das nächste ins Senderegister und wieder raus. Genau das überlege ich mir auch grad ..... wobei man abkläören muss, ob zb während des Wartens, bis TX frei wird noch RX Ints zugelassen werden, damit das Ganze mehr "Duplex" wird. Aktuell wird alles rückwärts angezeigt..... d.h. ich nähere mich dem Ziel :-)
So, eine Routine while (1) putchar(getchar()); spielt mir bei cat main.c > /dev/ttyUSB0 genau das auf den Schirm. RX über Ints in Puffer, TX direkt in die Dose gehämmert. Und ich denke so bleibt es auch! denn putchatr muss sowieso warten, ob nach jedem zeichen oder erst wenn Buffer voll ist eigentlich egal.
Christian J. schrieb: > zb während des Wartens, bis TX frei wird > denn putchatr muss sowieso warten, ob > nach jedem zeichen Hier nochmal konkret: Nicht das Zeichen ins Senderegister und dann warten, bis es weg ist, sondern wenn Zeichen ins Senderegister geschrieben wurde, gleich wieder raus, und was Anderes machen. Beim nächsten Zeichen ist dann das Senderegister vielleicht schon leer. Also beim nächsten Zeichen nur kurz vergewissern und nur ggf. warten.
:
Bearbeitet durch User
Nichts anderes steht hier... void putchar(char c) { while ((STI_TSR & 0x80) == 0); STI_UDR = c; }
Christian J. schrieb: > wobei man abkläören muss, ob > zb während des Wartens, bis TX frei wird noch RX Ints zugelassen werden Da gibts überhaupt nichts zu klären. Frank weist schon die ganze Zeit darauf hin. Seine Routinen in mcurses (und meine in der gestern geposteten ring.zip) kommen völlig ohne Interrupt-Sperre aus.
So ein Monitor Programm ist ja auch eher einfach, da kann getchar() auch ewig warten, wie es definiert ist in C. Was sollte der Rechner auch machen, wenn ein Timeout kommt? Zwischendurch schon mal Geschirr spülen gehen? Solange keine Eingabe vom User kommt passiert auch nix. es ist ja nicht so dass während des Betriebes Kommandos von außen kommen können, die dann gesonders abgearbeitet werden. Es gibt siche eine pfiffige Lösung, dass in TX Buffer gschrieben werden kann, während im Hintergrund die Zeichen rausgehämmert werden. Trotzdem muss auch da immer gewartet werden, denn das Füllen geht immer schneller als das Senden.
Leo C. schrieb: > Da gibts überhaupt nichts zu klären. Frank weist schon die ganze Zeit > darauf hin. Seine Routinen in mcurses (und meine in der gestern > geposteten ring.zip) kommen völlig ohne Interrupt-Sperre aus. Defintiv nicht! Ohne geht es nicht! Eine Veränderung von globalen Variablen während die gelesen werden kann nicht akzeptiert werden. Da sind Semaphore nötig oder eine Sperre. Kann Framnk gern so machen, ich aber nicht. Zwischen Int Routinen und normalen grenze ich klar ab, vor allem wenn die auf gemeinsame Bereiche zugreifen. / Ints aus, da Lesezugriff __asm di __endasm ; ch = rx.buf[rx.rd_ptr]; rx.rd_ptr = (rx.rd_ptr +1) & rx.mask; rx.f_buf_full = (rx.rd_ptr == rx.wr_ptr) ? false : true; // Alle Zeichen gelesen? __asm ei __endasm ; return(ch); wr_ptr kann im Int verändert werden.
Leo C. schrieb: > Seine Routinen in mcurses (und meine in der gestern > geposteten ring.zip) kommen völlig ohne Interrupt-Sperre aus. So ist es. Das liegt daran, dass die Variablen tx_start und tx_stop voneinander unabhängig sind und in keiner Konkurrenz zueinander stehen. tx_stop ist static in der putchar()-Funktion und tx_start ist static in der TX-ISR(). Das einzige, was die beiden zusammenhält, ist die Variable tx_size. Diese ist die einzige (bis auf den buffer selbst), welche volatile sein muss. Dasselbe gilt für den RX-Ringbuffer - nur spiegelbildlich. rx_start ist static in getchar(), rx_stop ist static in der RX-ISR(). Für rx_size gilt dasselbe wie für tx_size. Der RX-Ringbuffer und der TX-Ringbuffer sind auch komplett voneinander entkoppelt, d.h. man kann damit Full-Duplex realisieren. Wenn der TX-Buffer volläuft, ist das überhaupt kein Problem. Dann wird halt gewartet. Kritischer ist es beim RX-Buffer. Wenn der volläuft, verliert man Zeichen. Daher sollte man im Zweifel den RX-Buffer größer dimensionieren als den TX-Buffer. Einfacher und effizienter gehts nicht.
:
Bearbeitet durch Moderator
Frank M. schrieb: > Dasselbe gilt für den RX-Ringbuffer - nur spiegelbildlich. rx_start ist > static in getchar(), rx_stop ist static in der RX-ISR(). Für rx_size > gilt dasselbe wie für tx_size. Diese entkopplung baue ich jetzt noch ein....
Christian J. schrieb: > Defintiv nicht! Ohne geht es nicht! Eine Veränderung von globalen > Variablen während die gelesen werden kann nicht akzeptiert werden. Da > sind Semaphore nötig oder eine Sperre. Quatsch. Wie gerade oben geschrieben, sind tx_start und tx_stop NICHT global. Das ist ja gerade der Witz! Einzig der Zugriff auf tx_size muss gesperrt werden und zwar nur genau dann, wenn geschrieben wird:
1 | cli(); |
2 | uart_txsize++; |
3 | sei(); |
Das ist die einzige Stelle!
Ich habe es jetzt an Frank Hex Editor ausprobiert. Einandfrei scrollt der durch auch mit Taste festhalten. Lässt man los scrollt der weiter bis alles abgearbeitet ist. Der "Absturz" kommt erst, wenn man nach unten schrollt und der ganze Bildschirm neu aufgebaut werden muss. irgendwan ist der Puffer voll gelaufen und dann müssen die Zeichen verworfen werden. Das muss ich noch abfangen. Frank, hast du schon die Weiterschaltung bei der Eingabe und auch Test ob ROM oder RAM? Aktuell lässt sich das ROM auhc beschreiben :-) PageUp UNd PageDown wäre auch nicht schlecht, ein goto Adresse vielleicht noch ... und (Sonderwunsch 1 )..... und (Sonderwunsch 2 ).....und.... :-)
Frank M. schrieb: > cli(); > uart_txsize++; > sei(); > > Das ist die einzige Stelle! Ups, die Stelle hatte ich übersehen. Meine Routinen kommen auch ohne die Füllstandszähler aus, und deshalb gibts da übehaupt keine Interrupt-Sperren. Auf CPUs, auf denen Interrupt-Sperren billig sind, (AVR, Z80) ist Deine Variante wahrscheinlich etwas effizienter. Auf ARMs sieht es etwas anders aus.
Christian J. schrieb: > Ich habe es jetzt an Frank Hex Editor ausprobiert. Einandfrei scrollt > der durch auch mit Taste festhalten. Lässt man los scrollt der weiter > bis alles abgearbeitet ist. Okay, das ist normales Verhalten. > Der "Absturz" kommt erst, wenn man nach unten schrollt und der ganze > Bildschirm neu aufgebaut werden muss. Der wird niemals neu aufgebaut. Wenn Du oben bzw. unten anschlägst, dann wird der Bildschirm mit einem Befehl nach oben/unten gescrollt und dann eine(!) Zeile hinterhergeschickt - mehr nicht. > Irgendwan ist der Puffer voll > gelaufen und dann müssen die Zeichen verworfen werden. Das muss ich noch > abfangen. Müsste dann der RX-Buffer sein. Wie groß ist der? Im Zweifel: Mach ihn größer. Ich schrieb ja eben schon, dass der RX-Buffer die einzige "Gefahr" bei der Sache ist. Wenn der TX-Buffer voll ist, macht das gar nichts. > Frank, hast du schon die Weiterschaltung bei der Eingabe und auch Test > ob ROM oder RAM? Aktuell lässt sich das ROM auhc beschreiben :-) Nö, ich weiß ja gar nicht, wo bei Deinem System die Grenze ist. Könnte man noch als Argument an hex_edit() runtergeben. > PageUp UNd PageDown wäre auch nicht schlecht, ein goto Adresse > vielleicht noch ... und..... und .....und :-) Ich habe in der Zwischenzeit noch Pos1 und Ende eingebaut. PageUp/Down wäre auch trivial. Und ein goto ist dank getnstr() nun auch nicht mehr schwierig. Okay, baue ich ein. Übrigens, ich habe da vor ein paar Tagen noch einen Fehler in mcurses_puti() gefunden. Ersetze die Funktion bitte mit:
1 | static void |
2 | mcurses_puti (uint8_t i) |
3 | {
|
4 | uint8_t ii; |
5 | |
6 | if (i >= 10) |
7 | {
|
8 | if (i >= 100) |
9 | {
|
10 | ii = i / 100; |
11 | mcurses_putc (ii + '0'); |
12 | i -= 100 * ii; |
13 | }
|
14 | |
15 | ii = i / 10; |
16 | mcurses_putc (ii + '0'); |
17 | i -= 10 * ii; |
18 | }
|
19 | |
20 | mcurses_putc (i + '0'); |
21 | }
|
Die alte hatte den Bug, dass Zahlen zwischen 101 und 109 nicht richtig umgerechnet wurden. Ein move(10,105) hatte dann dasselbe wie ein move(10,15) gemacht. Ein relativ unrealistischer Fall - gerade dann, wenn man sich auf 24x80 beschränkt - aber trotzdem. So passt es besser.
Frank M. schrieb: >> Frank, hast du schon die Weiterschaltung bei der Eingabe und auch Test >> ob ROM oder RAM? Aktuell lässt sich das ROM auhc beschreiben :-) > > Nö, ich weiß ja gar nicht, wo bei Deinem System die Grenze ist. Könnte > man noch als Argument an hex_edit() runtergeben. Bin auch der Meinung, daß der Anwender wissen sollte, was er tut. Ich habe mir nicht angesehen was der Editor genau macht. Aber wenn er das Geschriebene wieder zurückliest und die Anzeige (bei Änderung) aktualisiert, dann sieht man ja, obs ROM oder RAM ist.
Müsste dann der RX-Buffer sein. Wie groß ist der? Im Zweifel: Mach ihn größer leider muss das ein Vielfaches von 2 sein, also nur 64, 128 möglich. 256 wäre 0x00. Damit man die Maske benutzen kann. 128 sind es derzeit.
Die Routine ist ein Bisschen kurz und füllt wohl nicht mal die Puffer, schicke mal was Dickeres... Gruß, Holm
Leo C. schrieb: > Bin auch der Meinung, daß der Anwender wissen sollte, was er tut. Ich > habe mir nicht angesehen was der Editor genau macht. Aber wenn er das > Geschriebene wieder zurückliest und die Anzeige (bei Änderung) > aktualisiert, dann sieht man ja, obs ROM oder RAM ist. Nein, er liest den Wert nicht zurück. Die einzige Möglichkeit, festzustellen, ist, die geänderte Zeile einmal rausrollen zu lassen, um sie dann wieder reinzurollen. Aber danke für den Tipp, ich werde das mit dem sofortigen Zurücklesen einbauen.
@Frank: Früher oder später rennt der Puffer voll und dann kann es sein, dass da 2 x ESC gelesen wird und er aussteigt. Ich habe da ja keine Kontrolle, da es sich in hexedit abspielt.
Christian J. schrieb: > leider muss das ein Vielfaches von 2 sein, also nur 64, 128 möglich. 256 > wäre 0x00. Damit man die Maske benutzen kann. 128 sind es derzeit. Denk nochmal nach. Bei 256 ist die Maske 256-1, also 255 (0xFF). Bei einer 8-Bit Variablen kannst Du sie dann auch weg lassen. Eigentlich sollte das dann aber auch der Compiler erledigen. Also (erst mal) drin lassen.
Christian J. schrieb: > Früher oder später rennt der Puffer voll und dann kann es sein, dass da > 2 x ESC gelesen wird und er aussteigt. Ich habe da ja keine Kontrolle, > da es sich in hexedit abspielt. Natürlich hast Du da die Kontrolle! Jetzt zum ALLERLETZTEN MAL: hexedit | getch | mcurses_phyio_getch | getchar | DEINE FIFO-Routinen! Das kann doch nicht so schwer zu verstehen sein! Wenn Du den RX-Buffer größer machst, profitieren davon ALLE MCURSES-Funktionen! Die Frage zum Xten Mal: Wie groß ist Dein RX-Buffer? Wäre schön, wenn ich da endlich mal eine Antwort bekäme....
:
Bearbeitet durch Moderator
Anbei eine neue Version von hexedit. Neuigkeiten: - Pos1 und Home gehen an Anfang/Ende der Zeile - Bild-Tasten springen um eine Seite vor/zurück - STRG-G macht ein Goto: Abfrage Hex-Adresse und Sprung - Geschriebene Werte werden zwecks Prüfung wieder zurückgelesen (ROM) - Statuszeilen oben/unten in Farbe Viel Spaß!
:
Bearbeitet durch Moderator
Frank M. schrieb: > Anbei eine neue Version von hexedit. Sorry, da war noch ein Bug drin, wenn man die Bild-Tasten benutzt, während man in den ASCII-Spalten steht. Anbei der Fix.
:
Bearbeitet durch Moderator
Grad ausprobiert.... klappte nachdem ich da einige "static" wegnahm, weil ich sonst die Funtkionen nicht aus main.c haette sehen können, bzw aus irgendwelchen gründen (error: Old stycle C .-....) keinen prototypen in hexedit.h anlegen konnte. Jetzt kannich sogar den Stack sehen ;-) Nicht schlecht und mit 9600 baud echt Retro Gangnam style!
Christian J. schrieb: > driver.c:79: rx.rd_ptr = (rx.rd_ptr +1) % RX_BUF_SIZE; > > 0064 16 00 [ 7] 165 ld d,#0x00 > 0066 13 [ 6] 166 inc de > 0067 C5 [11] 167 push bc > 0068 21 80 00 [10] 168 ld hl,#0x0080 > 006B E5 [11] 169 push hl > 006C D5 [11] 170 push de > 006D CDr00r00 [17] 171 call __modsint Übrigens kann sdcc hier die Modulo-Op zu "& 0x7F" optimieren, wenn man die Zeile so schreibt:
1 | rx.rd_ptr = ++rx.rd_ptr % RX_BUF_SIZE; |
Christian J. schrieb: > Grad ausprobiert.... klappte nachdem ich da einige "static" wegnahm, > weil ich sonst die Funtkionen nicht aus main.c haette sehen können, bzw > aus irgendwelchen gründen (error: Old stycle C .-....) keinen prototypen > in hexedit.h anlegen konnte. Hm, ich weiß jetzt nicht, was für statics Du da wegnehmen musstest... vermutlich liegt es daran, dass Du nicht komplett alles über mcurses laufen lässt - was ich Dir immer noch empfehle. > Jetzt kannich sogar den Stack sehen ;-) Nicht schlecht und mit 9600 baud > echt Retro Gangnam style! Freut mich. Schaffst Du mit dem STI eigentlich auch 19200 Baud? Könnte vielleicht die RX-Buffer-Overflow-Problematik etwas entschärfen. Ich habe hier noch eine Verbesserung, die dafür sorgt, dass bei RX-Buffer-Überlauf nicht direkt jede Sondertaste als Doppel-ESCAPE erkannt wird: mcurses.c, Funktion getch(), alt:
1 | if (idx == MAX_KEYS) |
2 | {
|
3 | ch = KEY_ESCAPE; |
4 | }
|
Neu:
1 | if (idx == MAX_KEYS) |
2 | {
|
3 | ch = ERR; |
4 | }
|
So bleibst Du länger "im Spiel". ;-)
:
Bearbeitet durch Moderator
> Hm, ich weiß jetzt nicht, was für statics Du da wegnehmen musstest...
Das wird er selbst nicht so genau wissen, weil der Compiler bei ihm ja
nie konkrete Fehlermeldungen oder Warnungen ausgibt, sondern immer nur
"...", oder so...
if (value != value_read) { ====> move (line, FIRST_HEX_COL + 3 * byte); itoxx (value_read); } Warning: unreachable code Nur so: Damit ich das nutzen kann muss ja die Funktion hexedit bekannt gemacht werden :-) So um 1990 herum machte man das über Prtotypen in der #include Datei. darum habe ich Franks Code obenrum in eine solche verfrachtet und Prototypen angelegt, wobei ich include hexedit.h in mai.cn benutze. Vielleicht ist das ja im jahre 2014 anders.... außerdem habe ich Franks Code so um gefühlt 300 {} gestripped, so dass er 150 zeilen kürzer ist und "dichter".
Frank könnte jetzt hier im Wiki echt einen wirklich coolen Hex Editor präsentieren. Das Ding hat was! 19200 geht nicht, lässt sich kein Teiler für finden :-( Aber 2400 und 300 gehen... :-)
Christian J. schrieb: > if (value != value_read) > { > ====> move (line, FIRST_HEX_COL + 3 * byte); > itoxx (value_read); > } > > > Warning: unreachable code Da ist der SDCC doch schlauer als ich dachte. Er nimmt natürlich an, dass ein PEEK (siehe Macro in hexedit.c) exakt dasselbe ausliest, was der POKE vorher ins Memory geschrieben hat. Ein POKE auf eine ROM-Adresse macht ihm aber einen Strich durch die Rechnung. Ersetze bitte in hexedit.c:
1 | #define PEEK(x) *((unsigned char *) (x))
|
durch
1 | #define PEEK(x) (volatile) *((unsigned char *) (x))
|
Christian J. schrieb: > Frank könnte jetzt hier im Wiki echt einen wirklich coolen Hex Editor > präsentieren. Gibt es schon: http://www.mikrocontroller.net/articles/MCURSES#Beispielanwendung > 19200 geht nicht, lässt sich kein Teiler für finden :-( Schade. > Aber 2400 und 300 gehen... :-) 300 wäre dann natürlich dasselbe wie in den Science-Fiction-Spielfilmen, wo Meldungen auf dem Bildschirm heute noch mit 300Bd rausgeschrieben werden - untermalt von etwas Zirpen ;-)
Ups, Beitrag schon wieder weg. Ist eigentlich meine letzte Mail (vorgestern) mit dem Makefile Update nicht angekommen?
@Frank: wie kriegt man es hin, dass nach der Ausgabe diverser String der minieditor genau da steht, wo der letzte Buchstabe wa? Der Cursor steht nämlichn immer nochn in der ersten Zeile. Ich möchte ja einen fliessenden Buildschirm. // Bildschirm vorbereiten initscr (); clear(); move(0,1); for (i=0;i<12;i++) addstr (menu[i]); getnstr (inbuf, 20);
Leo C. schrieb: > Ups, Beitrag schon wieder weg. > Ist eigentlich meine letzte Mail (vorgestern) mit dem Makefile Update > nicht angekommen? Doch, ist da .... aber noch nicht eingebaut. Eines nach dem anderen. Danke!
@Frank: Etwas seltsam das verhalten von getstrng... der erste Buchstabe stimmt alle andere sind dann aber oben.... erst ein move(....) zwingt den Cursor in die richtige Zeile. Glaube der zähtl nicht richtig mit wo der Cursor steht nach einer Ausgabe. default: if (curlen < maxlen && (ch & 0x7F) >= 32 && (ch & 0x7F) < 127) // printable ascii 7bit or printable 8bit ISO8859 { for (i = curlen; i > curpos; i--) str[i] = str[i - 1]; insch (ch); str[curpos] = ch; curpos++; curlen++; } } move (starty, startx + curpos); Die beiden stimmen aber nach jedem Tastendruck:mcurses_curx,mcurses_curx Nur steht der Cursor nicht da. Das aber stimmt nicht, nach dem ersten Tastendruck ist bei startx eine 0 drin. move (starty, startx+curpos); schon der Startwert ist falsch nach einer Reihe von addstr. Die nächste Ausgabeposition liegt nicht direkt hinter dem letzten Zeichen. Ich habe \n\r als CR verwendet. Er vergisst die CR's als Erhöhung der y Koordinate mit zu zählen in static void mcurses_putc (uint8_t ch) { mcurses_phyio_putc (ch); }
@Frank: So stimmt es, nur ein Leerzeichen rutscht dazwischen. Ich habe für CR und LF den Zähler erhöht. Allerdings kriege ich das Leerzeichen nach dem ersten Buchstaben nicht weg. // ------------------------------------------------------------------------ ---------------------------------------------- // INTERN: put a character (raw // ------------------------------------------------------------------------ ---------------------------------------------- static void mcurses_putc (uint8_t ch) { mcurses_phyio_putc (ch); if (ch=='\n') mcurses_cury++; if (ch=='\r') mcurses_curx=0; } Key END erzeugt übrigens die Ausgabe "0F" im Minieditor. Hier meine Strings zum Testen, auch mit nur \r das gleiche Ergebnis. // Menu Ausgabe const char* const menu[] = { "\r\n---------------------------------", "\r\nZ80 System ist online.\r\n", // 0 "---------------------------------", // 1 "\r\n[load].......... .Lade User Program", // 2 "\r\n[start]...........Start User Program", // 3 "\r\n[clear]...........Loesche Memory", // 4 "\r\n[dump]........... Dump Memory", // 5 "\r\n[reset]...........Restart System", // 6 "\r\n[basic]...........Basic Interpreter", // 7 "\r\n---", // 8 "\r\nDeine Wahl?:" // 9 };
Und nochwas für Frank, wenn er mal wieder da ist: Da steht ab und zu was über rechts..... weiss aber nicht ob das nicht auch vielleicht an meinem Terminal liegt. es würde eh reichen nur Buchstaben und Zahlen anzuzeigen und keine Sonderzeichen.
Dafür kannst Du Dir doch schnell dieses Macro ändern:
1 | #define IS_PRINT(ch) (((ch) >= 32 && (ch) < 0x7F) || ((ch) >= 0xA0))
|
Schon gefunden. Aber mal was für Dich als sdcc Spezialisten und Coder. Guck mal den Dump an. Oben liegt der Stack von 0xffff abwärts und verdammt nah dran liegt "irgendwas" von dem ich nicht weiss wie es dahin kommt. Man sieht auch ein Wort was ich eingegeben hatte. Das Data Segment liegt nämlich schön brav bei 0x8000. Ist das so normal?
Christian J. schrieb: > Guck mal den Dump an. Oben liegt der Stack von 0xffff abwärts und Dein Stack liegt nicht von 0xfff an abwärts, sondern von 0xfffe an. Das hatte ich schon mal versucht, Dir zu erklären. > verdammt nah dran liegt "irgendwas" von dem ich nicht weiss wie es dahin > kommt. Seufz, wirst Du es jemals lernen? Ich sehe da kein "irgendwas" sondern nur ganz normale Bytes. Welche von denen sollen denn das "irgendwas" sein? > Man sieht auch ein Wort was ich eingegeben hatte. Das Data > Segment liegt nämlich schön brav bei 0x8000. Lokale Variable werden aber auf den Stack gelegt. Wahrscheinlich hat irgendeine Funktion ein character array. Z.B. die Eingabezeile. Das ist jetzt nur geraten. Ich habe nicht vor, in Dein Programm zu schauen. > Ist das so normal? Ja, deshalb habe ich auch schon mal geschrieben, daß 254 Byte Stack warhscheinlich etwas knapp ist.
Ok.... ich dachte nur die 00 würden eine Grenze bilden, dass der Stack sich nur so ca 32 Bytes ausgebreitet hätte. Hats du für das rprintf vielleicht mal die config.h Datei? Die fehlt da scheinbar. Auch alloca.h wird nicht gefunden.
rprintf? Meinst Du das hier? Beitrag "Re: Retro Fieber: Z80 oder 68000 ?" Das habe ich mir noch nicht angeschaut. > Auch alloca.h wird nicht gefunden. alloca() scheint es für sdcc nicht zu geben. Anscheinend hat es auch noch niemand vermißt. Kein Bug-Report/Feature-Request, nix auf den Mailinglisten.
Ok, ich versuche nur ein prinft zum Laufen zu kriegen. Allerdings fehlen mir einige C kenntnisse was recht komplexe Zeiger Geschichten angeht. Es gibt da noch mehr Sourcen aber die lassen sich nicht kompilieren.
Ist trotzdem schon irre....... das kann der stundenlang, gegen sich selbst spielen :-) Nur bei 23k wird es jetzt langsam eng im Speicher. Wäre gut, wenn man das Data Segment direkt hinter dem Codesegment plazieren könnte, automatisch.
> Wäre gut, wenn man das Data Segment direkt hinter dem Codesegment > plazieren könnte, automatisch. Anhang
> Ok, ich versuche nur ein prinft zum Laufen zu kriegen. Allerdings fehlen Wie wärs denn mit Chans xprintf: http://elm-chan.org/fsw_e.html
Hi, haeb chan installluert, kompiliert durch. Leider hast Du bei dem Makefile wohl nioch mehr geändert, ich sehe erstmal keine Meldungen mehr und das .bin File ist ein Image des ganzen Speichers, nicht mehr wie früher eines des Rams. Versuche grad da zu ändern aber weiss nicht genau wo ich das suchen soll. Zur Vedeutlichung: Vorher hatte ich ein Image, was ich direkt nach 2000 laden konnte. VOM Rom aus wurde dann nach 2100 gesprungen und es lief. Jetzt habe ich ein Image, was am Hex Editor ab 0x0000 beginnt und Luft bis 0x2000 hat, dort fängt der Code erst an. Das läuft natürlich nicht.
Christian J. schrieb: > Hats du für das rprintf vielleicht mal die config.h Datei? Die fehlt da > scheinbar. Auch alloca.h wird nicht gefunden. config.h ist eine zentrale Config meiner Projekte, hier irrelevant. alloca() kann durch einen lokalen oder globalen Puffer fester (maximaler) Länge ersetzt werden.
Kämpfe grad mit den Chan printf, die keine Ausgabe erzeugen. Wohin geht deren Ausgabe? Ein putchar ist nirgendwo zu finden. Beispiel ist leider falsch verlinkt. Ok, läuft... sehr nett. xdev_out(putchar); count = 1234; xprintf("Hallo Welt!"); xprintf("Teststring = %d",count); >config.h ist eine zentrale Config meiner Projekte, hier irrelevant. >alloca() kann durch einen lokalen oder globalen Puffer fester >(maximaler) Länge ersetzt werden. Dennoch entstehen leider viele Compilerfehler bei long long Auusdrücken, die ich nicht weiter verfolgt habe bei rprintf. Da die Chan Funktion deutlich kürzer ist und die elementaren Dinge abdeckt verwende ich die weiter. Hoffentlich steht Frank mal auf bald, damit seine Mcurses von dem Bug befreit wird. @Leo: Problem gefunden mit dem Image. Hat sich erledigt. Zeile für zeile durchgegangen und geändert.
Christian J. schrieb: > Leider hast Du bei dem > Makefile wohl nioch mehr geändert, ich sehe erstmal keine Meldungen mehr Meldungen sieht man wieder, wenn man "make V=1" eingibt. Ja, wenn man gar nichts mehr sieht, ist auch nicht optimal. Das ging gestern Abend aus Versehen raus. > und das .bin File ist ein Image des ganzen Speichers, nicht mehr wie > früher eines des Rams. Wenn Du für ROM und RAM eine Startadresse eingibst, sollte das Verhalten wie vorher sein. Wenn nicht, habe ich dafür jeztzt auch keine Erklärung. > Hoffentlich steht Frank mal auf bald, damit seine Mcurses von dem Bug > befreit wird. Manche Menschen haben außer Windmühlenkampf auch noch andere Hobbies. Ich werde die nächsten Tage auch keine Zeit haben. > @Leo: Problem gefunden mit dem Image. Hat sich erledigt. Zeile für zeile > durchgegangen und geändert. Und natürlich wird wieder nicht verraten, wo das Problem war...
:
Bearbeitet durch User
Leo C. schrieb: > Und natürlich wird wieder nicht verraten, wo das Problem war... crt0.s vergessen einzutragen. Ich habe den SP jetzt mal auf 0xfffe gesetzt, eine gerade Adresse. Hoffe das ist dann so richtig. Früher lief der Stack nach unten zu den niederen Adressen, hofffe das ist immer noch so. Ärgerlich ist dass sdcc unbenutzte Routinen nicht weg optimiert, der erste Compiler den ich kenne der das nicht macht. Man kann ja nicht alles auskommentieren aus Modulen, nur weil man es eben mal nicht braucht. Bin jetzt sowieso endgültig bei Wargames angekommen. Und werde auch mal etwas Pause machen. Nächste Woche sinf wichtige Termine und da muss ich durch Deutschland mal eben ganz durch. Lassen wir ihn mal spielen den Tag über, dann hat er was zu tun.
1 | 1 2 3 4 5 6 |
2 | +-+-+-+-+-+-+ |
3 | |O|#|#|#|O|#| |
4 | |O|O|O|#|#|O| |
5 | |#|#|#|O|O|#| |
6 | |O|O|O|#|#|O| |
7 | |O|#|#|O|#|O| |
8 | |#|#|#|O|O|O| |
9 | +-+-+-+-+-+-+ |
10 | 1 2 3 4 5 6 |
11 | |
12 | draw! no one won.. |
13 | Total remis: 2 |
14 | player #1: computer |
15 | player #2: computer |
16 | |
17 | 1 2 3 4 5 6 |
18 | +-+-+-+-+-+-+ |
19 | | | |O| | | | |
20 | | | |O| |#| | |
21 | |O|#|O|#|#|#| |
22 | |O|#|#|#|O|O| |
23 | |O|O|O|#|O|#| |
24 | |O|#|#|O|O|#| |
25 | +-+-+-+-+-+-+ |
26 | 1 2 3 4 5 6 |
27 | |
28 | player 1 (computer) won! |
29 | Total wins player 1: 10 |
30 | Total wins player 2: 7 |
31 | Total remis: 2 |
32 | player #1: computer |
33 | player #2: computer |
Christian J. schrieb: > Ich habe den SP jetzt mal auf 0xfffe gesetzt, eine gerade Adresse. Hoffe > das ist dann so richtig. Das ist genauso richtig oder falsch wie 0xffff. Nur verschenkst Du damit noch ein weiteres Byte RAM. Vielleicht versuchst Du in einer ruhigen Minute mal zu verstehen, was ich schon mal geschrieben hatte: ------------------------------------------------------------------ Wenn Du das letzte Byte RAM auch noch verwenden willst, wäre hier stack .equ 0 richtig, da der Stackpointer beim push zuerst dekrementiert wird, und beim pop werden die daten zuerst gelesen, und dann der sp inkrementiert. Hier kommt es auf das eine Byte sicher nicht an, aber an anderen Stellen muß man ggf. ganz genau wissen, wie der Stackpointer im Verhältnis zu den Daten steht. ------------------------------------------------------------------ > Früher lief der Stack nach unten zu den > niederen Adressen, hofffe das ist immer noch so. Allerdings, nur anders, als Du es Dir vorstellst. Der SP zeigt nicht auf die höchste freie Adresse, sondern auf die niedrigste, vom Stack belegte Adresse.
Leo C. schrieb: > Allerdings, nur anders, als Du es Dir vorstellst. Der SP zeigt nicht auf > die höchste freie Adresse, sondern auf die niedrigste, vom Stack belegte > Adresse. Zumindest oft, und auch bei Z80. Es gibt aber auch Prozessoren, bei denen SP auf die höchste freie Adresse zeigt, sowie welche mit aufwärts wachsenden Stacks.
Leo C. schrieb: > Vielleicht versuchst Du in einer ruhigen > Minute mal zu verstehen, was ich schon mal geschrieben hatte: Es ist eigentlich Jacke wie Hose ob der auf 0xffff steht oder 0x0000, was ja eine ROM Adresse ist. Da der erste Zugriff immer ein call oder pop sein wird, "wächst" er nach unten: 0xffff,0xfffe,0xfffd usw. Da ich aber nicht genau wusste, ob er 0x0000 auch beschreibt oder erst decrementiert setzte ich es auf 0xffff, was auch in vielen beispielen so ist, selbst in den sdcc Files wie crts.0. 0x0000 läuft genauso wie 0xffff. Das Thema, dass sdcc nicht klug genug ist, zu erkennen, ob ich eine Funktion benutze wird wohl ungelöst bleiben.
Das ist kein Problem vom Compiler sondern eines des Linkers. Versuche halt zu lesen was dokumentiert ist. Gruß, Holm
@Holm: Das nützt nichts. Der sdcc hat den sdld Linker, ein mit installiertes Programm. sdcc kann laut Manual nur ein Source File kompilieren, d.h man müsste alle durch includes zu einem zusammen ketten. So wie der CCS für PIC auch, mit dem ich fast 10 Jahre gearbeitet habe. Den besseren Umweg über compile+link geht man wohl mit Linker Skript und Makefile. Die sog "Dead code elimination" funktioniert nur lokal. Compiler wie der IAR oder Keil erstellen in 2 Durchläufen Aufruf-Abhängigkeitsbäume aller Funktionen und berechnen zb auch den Stack Bedarf und die Schachteltiefe. Dabei fliegen dann alle Funktionen raus, die nicht benutzt werden. Zb benutze ich von Fransk mcurses und der xprintf nur recht wenig, trotzdem wir alles mit eingebunden aber niemals durchlaufen. Das ist für einen Compiler, der für Mikrocomputer ausgelegt wurde nicht schön, es ist sogar ausgesprochen schlecht. Bei mir hier verdoppelt es die Codesize mal eben. Abhilde geht durch LÖibraries, die vorkompiliert sind und durch .h eingebunden werden. da holt er sich dann nur raus was er braucht. Habe noch nie was mit Libs gemacht und wie man die anlegt. Habe nur das hier gefunden und das ist Asbach: http://www.tensi.eu/thomas/programming/asxxx-linker/rev_sdcc_linker-documentation.pdf
Christian J. schrieb: > wie kriegt man es hin, dass nach der Ausgabe diverser String der > minieditor genau da steht, wo der letzte Buchstabe wa? > > Der Cursor steht nämlichn immer nochn in der ersten Zeile. Ich möchte ja > einen fliessenden Buildschirm. > > // Bildschirm vorbereiten > initscr (); > clear(); > move(0,1); > > for (i=0;i<12;i++) > addstr (menu[i]); > > getnstr (inbuf, 20); Wirf die '\n' aus den Menü-Strings raus! Positionierung machst Du mit move(), aber nicht wie oben, sondern so:
1 | initscr (); |
2 | clear(); |
3 | for (i=0;i<12;i++) |
4 | {
|
5 | move(i,1); |
6 | addstr (menu[i]); |
7 | }
|
8 | getnstr (inbuf, 20); |
Der move() muss also in die for-Schleife. Deine "\n" sind in mcurses nicht geeignet für Positionierung. mcurses hält in internen Variablen fest, wo der Cursor gerade steht. Ein \n bringt das durcheinander, denn je nach Einstellung des Terminals geht der Cursor dabei entweder nur eine Zeile nach unten, bleibt aber in derselben Spalte, ein andermal geht er auch noch an den Anfang der Zeile (Wagenrücklauf, implizites CR). Deine '\n' bringen damit die interne Cursor-Verwaltung durcheinander. Du musst immer mit move() positionieren. Das sollte auch Deine anderen Positionierungs-Probleme erklären - auch mit getnstr(). Einfach weil der interne virtuelle Cursor woanders steht als der reale! Denk bitte auch daran: Die erste Zeile/Spalte in mcurses beginnt mit 0, nicht mit 1. move (0, 0) ist die linke obere Ecke. Christian J. schrieb: > Da steht ab und zu was über rechts..... weiss aber nicht ob das nicht > auch vielleicht an meinem Terminal liegt. es würde eh reichen nur > Buchstaben und Zahlen anzuzeigen und keine Sonderzeichen. Ich schrieb ja: Dein Terminal muss auf ISO8859 eingestellt sein bei Darstellung der Sonderzeichen. Deines arbeitet offenbar mit UTF-8. Du kannst die Darstellung von 8-Bit-Zeichen ändern, wenn Du das Macro
1 | #define IS_PRINT(ch) (((ch) >= 32 && (ch) < 0x7F) || ((ch) >= 0xA0))
|
änderst in
1 | #define IS_PRINT(ch) (((ch) >= 32 && (ch) < 0x7F))
|
:
Bearbeitet durch Moderator
Leo C. schrieb: > […] > alloca() scheint es für sdcc nicht zu geben. Anscheinend hat es auch > noch niemand vermißt. Kein Bug-Report/Feature-Request, nix auf den > Mailinglisten. Es gibt ein RFE für VLAs. Philipp
Hallo Frank, tut mir leid aber dann kann ich damit nicht viel anfangen, da es unüblich ist absolut zu positionieren auf fliessenden Bildschirmen. Dafür gibt es seit der Erfonduing des Telex Sonderzeichen wie \n \r \b usw. Ich zähle da ja nicht die Koordinaten ab sondern nach jeder Zeile kommt die nächste unter drunter. Die verwendung von printf Formaten ist ja usus überall. Was super geht sind statische Bildschirme, wo laufen Zahlen usw rennen, also Masken. Ich habe bei dir ein wenig im Code gefummelt und die Steuerzeichen werden mit berücksichtigt. Aber Fliesstext wie eine Konsole.. Schade..... Er daddelt mir grad mal Primzahlen durch.... wüsste nicht wie ich sowas "einfach" ohne %6lu Format machen sollte, wenn ich absolut positioniere minicom kann das nicht: http://ubuntuforums.org/showthread.php?t=2063253
Christian da ist überhaupt Nichts schade. Curses dient dem Handling "statischer Screens" mit Cursor Positionierung, und der Eingabe in Masken wie man es z.B. in Menüsystemen und z.B. Hexeditoren braucht. Wenn Du einen scrollenden Console Modus willst, mußt Du da wieder raus und dieses handling "statischer Screens" abstellen. Guck Die mal Dein Linux an, funktioniert dort haargenau so. Entweder Console oder Editor. Wenn Du in einem Editor z.B. oben ein stehendes Feld und darunter ein scrollendes haben willst, mußt du das scrollen selber handeln. Das ist exakt die vorgesehene Funktionalität. Ich dachte Du hättest das indessen gerafft. Deine Vorlesung was woanders "Standard" ist, ist demzufolge ziemlicher Quatsch.... Gruß, Holm
Holm Tiffe schrieb: > Curses dient dem Handling "statischer Screens" mit Cursor > Positionierung, Genau das ist es. Und je nachdem was man will muss man das eine oder das andere nehmen :-) Mir fallen da zb einfache Spiele ein mit Grafikzeichen. Oder Masken die Berechnungen ausgeben. Schade dass der sdcc long long (64 bit) nicht vollständig unterstützt. Ich sehe schon, mein Z80 wird eine Revolution bei der Lösung der Riemann'schen Vermutung werden :-) Klappt aber sonst super! versuche nur noch die Ursache für zufällige Resets zu finden. Die gibt es leider :-( Übrigens portiere ich grad das Prinzip auf meinen ARM Rechner, damit der auch ein Terminal bekommt. Ist ja auch nur eine CPU ohne alles drumherum, aber immerhin einen Grafiklbildschirm hat er. War damals ein projekt hier, wo ich die Platinen fürs Forum machen liess, mit einem Benedikt war das glaube ich....
Christian J. schrieb: > tut mir leid aber dann kann ich damit nicht viel anfangen, da es > unüblich ist absolut zu positionieren auf fliessenden Bildschirmen. > Dafür gibt es seit der Erfonduing des Telex Sonderzeichen wie \n \r \b > usw. Holm hat da vollkommen recht: Entweder Console mit Fliesstext oder Anwendung mit mcurses. Ob Du Dein Menü mit oder ohne mcurses machst, bleibt Dir selbst überlassen. Mit mcurses steht das immer an derselben Stelle, ohne mcurses halt unter dem zuletzt ausgegebenen Text. Ist Geschmackssache. Ich persönlich würde da mcurses nutzen - gerade dann wenn das Menü umfangreicher wird. Wälht der User dann einen Punkt aus, verwendest Du je nach ausgewähltem Menüpunkt entweder mcurses oder die einfache Fließtext-Console.
Moin, aktuell wächst die ganze Sache, wobei der Spieltrieb noch etwas überwiegt. Ist eben was anderes einen PC mit fertiger Software zu bespielen, einen Arduino zu "programmieren" wo es einfach funktioniert oder einen peripherielose Rechner wo jede Leitung selbst gezogen wurde. Im dauerbetrieb, zb Berechnung von Primzahlen bis zur Grenze der 32 Bit traten nur "Seltsamkeiten" auf wie auf dem Screesnhot gezeigt. Ob da was mit dem Compiler nicht stimmt oder der Hardware muss noch erforscht werden. Aktuell rennt er daher seit Stunden über sein RAM und ROM und prüft ob sich die CRC16 Checksumme verändert. Das Thema Datenspeicher muss noch auf den Tisch, wobei ich fast schon an eine Datasette Mit "Hard-Bit-Rock" denke, müsste per Frequenzumtastung nicht zu schwer sein. Maximal 1200 baud leider. Oder doch eben ein "Arduino" (ich nutze nur die IDE und die Libs, plaziere die Chips aber einzeln), der ein Interface zu einem modernen Speicher wie SD Card herstellt mit vereinfachter API zb File 1,2.3,4 usw. also nur 64kb Sektoren als Ablage.
Macht dein C Compiler kompakten Code ? Wie Gross ist er im Vergleich mit ASM ? (Hello World)
@A.K. : Ich habe heute etwas an dem Erweiterungsboard gearbeitet und die Bus Leiste verdrahtet, die hinten aufgesteckt wird. Da ich dort auch ports brauche und gerne auch einen richtigen Timer ist die Wahl: 8254 (16 Bit!) und 8255 (3 Ports statt 2) oder CTC und PIO ? Obige sind interruptlos und intern "einfach", Z80 Teile sind Mode 2 fähig und etwas aufwendiger, die PIO kann vor allem Einzelports schalten. Bei dem STI ist im Mostek App Note die rede von einem Bug, der Daisy Chaining beeinflusst, so dass nichts da hinter geschaltet werden sollte. Ich habe den 3801 von ST in der Rev H. Hoff es gibt da keine Probleme wenn hinter den STI noch zwei Int erzeugende Bauteile kämen. Wie sähe das Prinzip dann aus? Meine Int-1 Tabelle liegt fix bei 0x2040, STI ist mit einem Vektor geladen, ebenso IM2 Register. Liessen sich die neuen Vektoren der Timer dann huckepack direkt auf die bestehende Tabelle plazieren?
Was ist deine "Int-1-Tabelle"? Im IM2 gibt es eine Tabelle aus bis zu 128 Vektoren. Die kannst du nach Laune belegen, jeder IM2 Baustein hat dazu ein Vektor-Basisregister. Was den Fehler angeht: Da steht, dass ab Ende 82 der Bug raus wäre. Das Datum deines Exemplars dürfte auf ihm draufstehen.
:
Bearbeitet durch User
Christian J. schrieb: > 8254 (16 Bit!) und 8255 (3 Ports statt 2) > oder > CTC und PIO ? Ich würde den Z8536 nehmen, den Nachfolger von PIO und CTC, aus der Z8000 Reihe, aber für Z80 Bus. Da gibts beides zusammen. Gibts bei ebay.
A. K. schrieb: > Was ist deine "Int-1-Tabelle"? Im IM2 gibt es eine Tabelle aus bis zu > 128 Vektoren. Die kannst du nach Laune belegen, jeder IM2 Baustein hat > dazu ein Vektor-Basisregister. Ok, dann werde ich das so machen und eine 2.te Uart kriegt er auch noch mit dem 65B20 Baustein, weil der höhere Baudraten erlaubt und einfach anzuflanschen ist. Es ist leider schn 5 Jahre her, dass ich hier mal eine Aktion laufen hatte mit Platinenbestellung und jemandem der sich Benedikt Kullmann nennt, einem Admin. Ich habe leider nur noch eine einzige dieser unbestückten Platinen und auch keinen AVR Code dazu, keine Beschreibung, nix mehr, auch das Eagle Layout ist weg, damals bei Datenunfall, wo 15 Jahre "Daten-Sammlung" bis 1996 sich in Luft auflösten. Denn das wäre ein schönes Display für den Z80 mit Uart Interface, Text und Grafik, allerdings komplett inkompatibel zu mcurses. habe das Ding grad mal angeworfen, nach 4 Jahren im Schrank nur die Uhr verstellt weil Batterie leer aber sonst läuft es prima.
Christian J. schrieb: > mit dem 65B20 Baustein, weil der höhere Baudraten erlaubt und einfach > anzuflanschen ist. Wenn du mit dem hohe Baudraten hinkriegst, dann Respekt. Der 6520 ist nämlich ein Portbaustein, identisch mit dem 6820. Und da die 65Axx beim Takt den 68Bxx entsprechen hat es m.W. nie eine 65Bxx Serie gegeben. ;-) Allerdings würde mich interessieren, wieso ein anderer Baustein aus gleichem Basistakt abgeleitet höhere Baudraten zulässt als der STI. Durch 16 teilen sie beide, und beide kriegen den 16x Takt aus einem Timer.
:
Bearbeitet durch User
Mit dem 68B50 (!) sind bei 3.964Mhz 56700 baud drin, abegleitet aus dem Quartz, da es keinen Timer als Vorteiler gibt, der mir 1/16 klaut. http://searle.hostei.com/grant/z80/SimpleZ80.html >>by changing the crystal to 3.6864MHz but the serial I/O speed is then also >>halved to 57600 baud. Ich habe ja lange überlegt das zu übernehmen, da der Baustein, den ich auch hier habe sehr einfach ist. Eine gepufferte TX Übertzragung habe ich neulich ums Verrecken nicht hin bekommen, egal wie ich den Code auch umschrieb. Das ging beim ARM deutlch einfacher durch mehr Int Quellen als nur Buffer Empty. CTC vs 8254: Der CTC benötigt den Z80 Clock als Basistakt für die Timer wie ich sehe, damit die Adressieung mit M1 usw. funktioniert.. Der 8254 kann einen beliebigen Clock anliegen haben und hat selbst keinen Input für einen Clock.
Christian J. schrieb: > Quartz, da es keinen Timer als Vorteiler gibt, der mir 1/16 klaut. Nur wenn man vorsichtshalber drauf vertraut, dass dieser Baustein sein Datasheet nicht gelesen hat und daher nicht weiss, dass darin an den Rx/Tx-Takteingängen bei 1,5MHz Ende der Fahnenstange ist.
:
Bearbeitet durch User
Christian J. schrieb: > Mit dem 68B50 (!) sind bei 3.964Mhz 56700 baud drin Bei dieser Frequenz kommt ein Teiler von 68 raus. Das geht asynchron überhaupt nicht. Ich nehme an, es sind 3,6864MHz.
Christian J. schrieb: > Das ging beim ARM > deutlch einfacher durch mehr Int Quellen als nur Buffer Empty. Mehr als das braucht man dazu normalerweise auch nicht. Welche hältst du noch zusätzlich für erforderlich? Ok, mein STI hatte die Tastatur dran hängen. Die ging nur in eine Richtung. Aber bei anderen Bausteinen hat mir das auch ausgereicht, wie beispielsweise beim SIO.
Was für einen Wert musst du denn ins Timer-Register des STI bisher reinschreiben, um auf deine 9600bd zu kommen?
....Also...Du bist Ratatui Koch..alles rein. Die Motorola Reihe hat Dir ja bis jetzt noch gefehlt.. Was gibts denn noch so.. F8? Wenn Du höhere Baudraten willst, solltest Du Dir Gedanken machen woher die Uart ihren Sendetakt beziehen könnte, IMHO sind die Baudraten die mit der Z80 SIO zu erzeugen sind nicht zu niedrig. Es ist eine Frage wie Du zu einem Baudratenkonformen Takt kommst, der innerhalb der Spezifikation der ICs liegt. Auch solltest Du mal erklären was Du mit einer höheren Baudrate eigentlich so anfangen möchtest. Wenn Du so eine Programmiererkoryphähe bist, stecke die Arbeit lieber in die Verbesserung des Compilers den Du benutzen willst oder besser erlne erst mal was das System mit seinem Assembler so kann. So viel ich weiß ist die kürzeste Taktperiode 400ns für Rx/TX Clock. das sind 2,5Mhz. Wenn ich mich richtig erinnere hattest Du einen Clock von 3,6864Mhz? Damit müßtest Du mit einem Vorteiler von 2 und Teilerfaktor 16 in einer Z80 SIO eine Baudrate von 115200 Baud erzeugen können, das reicht nicht? Das Problem ist dabei nicht das der SIO keine hohen Baudraten, sondern das ein üblicherweise als Baudratengernerator benutzter CTC nicht die erforderlichen Frequenzen erzeugen kann. Es steht Dir frei einen externen Baudratengenerator zu verwenden wie andere Bausteine den auch benötigen, Du kannst natürlich aber auch noch völlig andere beschissene ICs an Deine Platine knoten und weiterhin kein potentes Z80 System sondern einen Teller buntes Gemüse erzeugen. Ich hätte für dich auch noch einen russischen Schaltplan einer völlig in TTL Hardware gebauten PDP11 SLU, das ist etwa eine Doppeleuroplatine voller ICs. Es wurde Dir schon ein paar mal erzählt das Du Features verschenkst, Du wirst daraus scheinbar wirklich nicht schlauer sondern bildest Dir ein das Du es irgendwie eilig mit der seriellen Schnittstelle haben mußt? Das Z80 System war so verbreitet weil die Entwickler regelrecht genial damit waren mit ihrem Konzept kleine leistungsfähige Systeme mit wenigen ICs der Systemfamilie zu ermöglichen, nicht weil die CPU ein paar Register mehr hatte. Gruß, Holm
A. K. schrieb: > Bei dieser Frequenz kommt ein Teiler von 68 raus. Das geht asynchron > überhaupt nicht. Ich nehme an, es sind 3,6864MHz. Ja 3.6864, ich hatte dazu ja einen Link gepostet. 1,5 Mhz stehen im Datasheet aber scheinbar geht es ja auch mit mehr als der doppleten Frequenz. Dieser Grant ist ja nicht blöde und hat das alles aufgebaut. 1,16,64 ist der Teiler dann, der möglich ist. Hoffe nur dass das auch ohne CTS/RTS läuft, denn die habe ich nicht und brauche sie nicht. Der CTc fliegt aber raus, der 8254 ist moderner und kann zb mit 1Mhz geclocked werden statt mit dem krummen Baudraten Quarz. Ich habe es einfach nciht hingekriegt, wie ich den TX anstosse, damit er ab dann automatisch weiterläuft, solange zeichen da sind. Aber es geht ja auch so ganz gut, nur RX muss gebuffert werden. Zitat: 8K ROM 56K RAM (A version with 32K RAM is HERE) Z80 Processor (overclocked - all processors 4MHz+ (Z80B) that I have tried overclock to this with no issues) with a 7.3728MHz clock. You can halve this, ie. to stop the overclocking, by changing the crystal to 3.6864MHz but the serial I/O speed is then also halved to 57600 baud. 115200 Baud serial interface, RS232 specification voltage levels. Full interrupt driven input with buffer and hardware handshaking so no incoming data loss. Power consumption - approx 200mA A problem exists, however, as the /IORQ is also taken low during an interrupt acknowledge. If this was allowed, then the data/control values in the serial interface would be corrupted when the interrupt is acknowledged by the Z80. Interrupt acknowledge is identified by /IORQ and /M1 signals going low, so the 6850 is to be disabled if /M1 is low (the Z80 /M1 signal connected to the active-high CS0 of the 6850). This ensures that only real I/O triggers the serial interface. The /M1 signal is much wider than the /IORQ and totally masks the /IORQ signal. This ensures that there is no possibility of the ACK signal enabling a read or write. The remaining chip selects on the serial interface are connected to A7 and A6, so any I/O on address 10xxxxxx will select the serial chip. Finally, the register select on the serial interface is connected to A0, so the control register is addressed on port 80H and the data register is addressed on port 81H.
Holm Tiffe schrieb: > Was gibts denn noch so.. F8? F8 Peripherie an Z80, das wär mal wirklich spannend. Das Teil, also die ursprüngliche 385x Variante, hat einen sehr speziellen Bus. ;-) Den Z8536 hatte ich ihm ja schon vorgeschlagen. Viel besser gehts bei Parallel/Timer-Bausteinen nicht. > Wenn Du höhere Baudraten willst, solltest Du Dir Gedanken machen woher > die Uart ihren Sendetakt beziehen könnte, Yep. Kann er beim STI auch. CPU-Takt halbieren und an den STI ran um auf 115kbd zu kommen. Das ist natürlich mit Faktor 2 weit jenseits von dessen Limit. Aber wenn ich sehe, wie sein Web-Vorbild den 6850 mit 7,37MHz traktiert, obwohl der offiziell nur 1,5MHz kann, wärs doch beim STI auch einen Versuch wert.
A. K. schrieb: > Was für einen Wert musst du denn ins Timer-Register des STI bisher > reinschreiben, um auf deine 9600bd zu kommen? 3.
Holm Tiffe schrieb: > Es steht Dir frei einen > externen Baudratengenerator zu verwenden wie andere Bausteine den auch > benötigen, Du kannst natürlich aber auch noch völlig andere beschissene > ICs an Deine Platine knoten und weiterhin kein potentes Z80 System > sondern einen Teller buntes Gemüse erzeugen. Du hast absolut recht. Ich brauche eine zweite Uart und je länger ich drüber nachdenke umso wahrscheinlicher wird es, dass ein kleiner niedlicher ATTiny mit 8 Pins, der alles tutto kompletti innendrin hat incl einem Oszillator diese Aufgabe übernehmen könnte, statt einer 40 Pinner Oschi SIO, zu der ich dann noch 40 Leitungen ziehen muss, Baudrate usw. duckundwech :-)
Christian J. schrieb: > der 8254 ist moderner Ich finden den ja ziemlich schaurig. > Ich habe es einfach nciht hingekriegt, wie ich den TX anstosse, damit > er ab dann automatisch weiterläuft, solange zeichen da sind. Üblicherweise gibts 2 Möglichkeiten. Meist reicht es, den TXBE Interrupt freizugeben, weil der bei leerem Puffer sofort auslöst. Wenn der STI das nicht tut, dann schreibt man eben zusätzlich das erste Byte ins Datenregister. > geht ja auch so ganz gut, nur RX muss gebuffert werden. Eben.
Ist doch süss, oder? Mit ner SPI sogar dran! MISO, MOSI, SCK... Richtig zum Knuddeln der Kleine! Habe noch 5 Stück hier ... >Üblicherweise gibts 2 Möglichkeiten. Meist reicht es, den TXBE Interrupt >freizugeben, weil der bei leerem Puffer sofort auslöst. Probier ich aus, Ende nächste Woche wenn ich wieder zurück bin.
Wo du doch so gerne jemand zum Vorbild nimmst, der alles übertaktet was seine Kiste enthält, weshalb übertaktest nicht den Systemtakt auf 4,9152MHz und kriegst dann 38400 mit einem STI-Timerwert von 1?
A. K. schrieb: > Wo du doch so gerne jemand zum Vorbild nimmst, der alles übertaktet was > seine Kiste enthält, weshalb übertaktest nicht den Systemtakt auf > 4,9152MHz und kriegst dann 38400 mit einem STI-Timerwert von 1? Weil ich nicht glaube, dass die Fädelverdrahtung mit 10cm langen Taktleitungen, die mitten durch andere hochohmige Leitungen laufen zum STI das aushält. Der "hüpft" jetzt schon mal.... nach so einigen Stunden Lauf liegt er plötzlich im Reset. Hast du eigentlich mal Bilder von Deinem Projekt?
Christian J. schrieb: > A. K. schrieb: >> Bei dieser Frequenz kommt ein Teiler von 68 raus. Das geht asynchron >> überhaupt nicht. Ich nehme an, es sind 3,6864MHz. > > Ja 3.6864, ich hatte dazu ja einen Link gepostet. 1,5 Mhz stehen im > Datasheet Häh wo? >aber scheinbar geht es ja auch mit mehr als der doppleten > Frequenz. Dieser Grant ist ja nicht blöde und hat das alles aufgebaut. > 1,16,64 ist der Teiler dann, der möglich ist. Hoffe nur dass das auch > ohne CTS/RTS läuft, denn die habe ich nicht und brauche sie nicht. > > Der CTc fliegt aber raus, der 8254 ist moderner und kann zb mit 1Mhz > geclocked werden statt mit dem krummen Baudraten Quarz. > Ja klar, moderner. Der 8254 ist ein unwesentlich verbesserter 8253 (Taktfrequenzen: 8253 2Mz, 8253A 2,5Mhz, 8254 10Mhz) und der ist die Standardperipherie des allerersten 8080 den Du hier ausgelacht hast... Das Ding ist in keiner Weise in der Lage Interrupts auszulösen, Du muß irgend einen Ausgang über Draht mit einem Deiner INT Eingänge der STI verbinden...hochmodern.. > Ich habe es einfach nciht hingekriegt, wie ich den TX anstosse, damit > er ab dann automatisch weiterläuft, solange zeichen da sind. Aber es > geht ja auch so ganz gut, nur RX muss gebuffert werden. Bei anderen Leuten funktionierte das dann so das die SIO (!) einen Interrupt mit entspechendem Vector (Status Affects Vector) auslöste und die Serviceroutine so lange Bytes aus dem Buffer nachgelegt hat bis dieser alle war und dann den Int in der SIO ausgeschaltet, sowie diesen Status in einem Semaphor hinterlegt hat) Die serielle Sendroutine hat das nächste Byte dann nach Reset des Semaphors und Aktivierung des Ints in den TXBuffer der Sio geschrieben, weitere Zeichen bei inaktivem Sempahor dann wieder in den Buffer, Ausgabe über die Serviceroutine. Ich hatte Dir gesagt Du solltest Dir Gedanken um die Pufferei machen..da sind Deine Gedanken wohl nicht vorbei gekommen? Das Ganze ist wirklich easy in Assembler zu programmieren. Ich weiß aber nichts wirklich über diese STI. > > Zitat: > > 8K ROM 56K RAM (A version with 32K RAM is HERE) > Z80 Processor (overclocked - all processors 4MHz+ (Z80B) that I have > tried overclock to this with no issues) with a 7.3728MHz clock. You can > halve this, ie. to stop the overclocking, by changing the crystal to > 3.6864MHz but the serial I/O speed is then also halved to 57600 baud. > 115200 Baud serial interface, RS232 specification voltage levels. Full > interrupt driven input with buffer and hardware handshaking so no > incoming data loss. Power consumption - approx 200mA > > A problem exists, however, as the /IORQ is also taken low during an > interrupt acknowledge. If this was allowed, then the data/control values > in the serial interface would be corrupted when the interrupt is > acknowledged by the Z80. Interrupt acknowledge is identified by /IORQ > and /M1 signals going low, so the 6850 is to be disabled if /M1 is low > (the Z80 /M1 signal connected to the active-high CS0 of the 6850). This > ensures that only real I/O triggers the serial interface. The /M1 signal > is much wider than the /IORQ and totally masks the /IORQ signal. This > ensures that there is no possibility of the ACK signal enabling a read > or write. The remaining chip selects on the serial interface are > connected to A7 and A6, so any I/O on address 10xxxxxx will select the > serial chip. Finally, the register select on the serial interface is > connected to A0, so the control register is addressed on port 80H and > the data register is addressed on port 81H. Keine Ahnung was der da treibt. Halte Dich an die IO-Decodiererei die im Kieser-Meder zu finden ist, das Zeuch funktioniert. Irgendwer hatte mal festgestellt das es Differenzen zwischen Original-CTC und DDR-CTC gibt, die Ossis hatten wohl diesen BUG ausgebaut. Von der SIO sind mir solche Probleme nicht bekannt, das was ich gebastelt hatte ging jedenfalls auch mit den Originalen und ich hatte mich nach eben dieser OST-Bibel gerichtet. Einen Grund für eine beschissene synchrone Schnitte was Anderes als eine SIO einzusetzen hatte ich jedenfalls nie. Ich hhabe ins Datenblatt geguckt, da steht minimaler Taktzyklus für die RX-TX Takte 400ns. Wo hast Du die 1,5Mhz (666ns) her? ...aha, es gibt eine Note: Die Taktfrequenz muß das 4,5-fache der Baudrate sein. D.h. bei 115200 Baud muß die Systemtaktfrequenz am SIO mindestens 115200*4.5=0,5184 Mhz sein.. hmm... betreifft Dich wohl nicht. Gruß, Holm
Christian J. schrieb: > Ist doch süss, oder? Mit ner SPI sogar dran! MISO, MOSI, SCK... > Richtig zum Knuddeln der Kleine! Habe noch 5 Stück hier ... > >>Üblicherweise gibts 2 Möglichkeiten. Meist reicht es, den TXBE Interrupt >>freizugeben, weil der bei leerem Puffer sofort auslöst. > > Probier ich aus, Ende nächste Woche wenn ich wieder zurück bin. Ja, mach aber einen Neuen Thread auf.."Dummfug mit dem Z80..." Mit Retro hat das wohl nicht viel zu tun und es soll hier im Forum Leute geben die einen 8080 auf einem Atmega emulieren um darauf CP/M laufen zu lassen. (für ne Z80 hat der Atmega wohl zu kleine Hände womit Turbopascal ausfällt) Solche Leute bauen also Deine Ganzen Platinen in einem 40 Pinner. Gruß, Holm
Holm Tiffe schrieb: >> Ja 3.6864, ich hatte dazu ja einen Link gepostet. 1,5 Mhz stehen im >> Datasheet > > Häh wo? Beim MC68B50 als Höchstfrequenz der RxCLK/TxCLK Pins. Bei Grants MC6850 sind es sogar nur 0,8MHz, aber betrieben mit 7,37MHz. Davon können heutige Übertakter nur träumen. ;-)
Hallo Holm, habe mir deinen guten Beitrag mal ausgedruckt. Genauso habe ich es aber bei der STI gemacht. Semaphore hatte ich auch. Auf den Trick mit dem Abschalten der STI in der TX Service Routine bin ich aber nicht gekommen. Denn es ist wirklich so, dass man nur von außerhalb TX EN einschalten muss und dann rennt der TX Empty sofort los und schaut was man ihm ins Körbchen gelegt hat. Dann sieht es nämlich so aus: TX aus und noch Platz im Buffer? Zeichen rein und TX EN einschalten. Sofort danach kommt der TX Empty Int vorbei und sieht, dass der Zeiger eines weiter ist und schiebt das Byte raus. Ist dann wieder eines da gleiches Spiel, bis Körbchen leer, dann schaltet er sich ab indem er sein Enable Bit zurüpck setzt (und evtl Pending Ints auch noch). Allerdings ....... das Raushämmern von Bytes über die STI ohne Interrupt braucht genauso lange wie mit Int. Der einzige Vorteil ist, dass das Hauptprogramm mal eben 80 Bytes wegschreiben kann in den Buffer und sich danach nicht mehr drum kümmern muss, weil der TX Int die ins gegnerische Tor am PC spielt. >>Das Ganze ist wirklich easy in Assembler zu programmieren. Ich will aber nicht. Das ist so und bleibt so ;-) Hier gehts lang für "Du machst das so wie ich es dir sage!" :-) http://www.jogis-roehrenbude.de/forum/forum/forum.php
Christian J. schrieb: > Hallo Holm, [..] > > Allerdings ....... das Raushämmern von Bytes über die STI ohne Interrupt > braucht genauso lange wie mit Int. Der einzige Vorteil ist, dass das > Hauptprogramm mal eben 80 Bytes wegschreiben kann in den Buffer und > sich danach nicht mehr drum kümmern muss, weil der TX Int die ins > gegnerische Tor am PC spielt. Du hast eben gerade die Synchronisation langsamer Peripherie durch Interrupts entdeckt! Congrats... Um Dir zu zeigen was wirklich ein cleverer IO IC ist: Die SIO unterstützt einen weiteren Modus für zeitkritische Sachen wo bereits die Interruptlatenzzeiten stören: Die Synchronisation durch WAIT. Man kann mit OTIR einen Block zur Ausgabe auf die SIO ansetzen und sie ativiert die WAIT-Leitung der CPU so lange der Sendepuffer voll ist und gibt das Ding bei leerem Puffer wieder frei. schneller geht es dann nicht, das dürfte schneller sein als DMA. Ob das im Empfangsmodus auch geht weiß ich nicht mehr, müßte ich nachlesen. Gruß, Holm
Holm Tiffe schrieb: > Bei anderen Leuten funktionierte das dann so das die SIO (!) einen > Interrupt mit entspechendem Vector (Status Affects Vector) auslöste und > die Serviceroutine so lange Bytes aus dem Buffer nachgelegt hat bis > dieser alle war und dann den Int in der SIO ausgeschaltet, sowie diesen > Status in einem Semaphor hinterlegt hat) Die serielle Sendroutine hat > das nächste Byte dann nach Reset des Semaphors und Aktivierung des Ints > in den TXBuffer der Sio geschrieben, weitere Zeichen bei inaktivem > Sempahor dann wieder in den Buffer, Ausgabe über die Serviceroutine. Geht beim SIO noch einfacher. Man muss den Interrupt nicht abschalten, sondern bloss zurücksetzen. Siehe Beitrag "Re: Retro Fieber: Z80 oder 68000 ?" unter ivec$sioa$txbe: und putnw:.
Holm Tiffe schrieb: > Man kann mit OTIR einen Block zur Ausgabe auf die SIO ansetzen und sie > ativiert die WAIT-Leitung der CPU so lange der Sendepuffer voll ist und > gibt das Ding bei leerem Puffer wieder frei Nicht schlecht ..... aber das Thema SIO ist eigentlich duch, auch wenn du es bei jeder Gelegenheit hervorholst und noch 50 Stück davon hast, die herum oxidieren. Das hätte eher gemacht werden müssen, dann hätte ich auch 2 Uarts aber auf einer Euro Karte ist kein Platz mehr für eine SIO. Aber es wird ja noch das Projekt "Retro Z80 V2.0" geben, einen echten CP/M Rechner.... da werde ich dann darauf zurückgreifen, auch mit richtigen Platinen, Tastatur und Bildschirm.
A. K. schrieb: > Holm Tiffe schrieb: [..] > Geht beim SIO noch einfacher. Man muss den Interrupt nicht abschalten, > sondern bloss zurücksetzen. Siehe > Beitrag "Re: Retro Fieber: Z80 oder 68000 ?" > unter ivec$sioa$txbe: und putnw:. Ist ca 20 Jahre her das ich da wirklich Hand an eine SIO gelegt hätte, sorry, Sowas weiß ich nicht mehr so genau. Fakt ist aber, das mi die meisten integrierten Uarts in irgendwelchen µCs immer sehr "hausbacken" betreffs ihrer Möglichkeiten UND Bugs vorkommen.. :-) Gruß, Holm
Holm Tiffe schrieb: > Die SIO unterstützt einen weiteren Modus für zeitkritische Sachen wo > bereits die Interruptlatenzzeiten stören: Die Synchronisation durch > WAIT. Da werden die aber eher an schnelle synchrone Betriebsarten gedacht haben, nicht an asynchrone 9600bd. Und wer DRAM in der Kiste hat, der sollte dabei etwas aufpassen.
Christian J. schrieb: > Holm Tiffe schrieb: >> Man kann mit OTIR einen Block zur Ausgabe auf die SIO ansetzen und sie >> ativiert die WAIT-Leitung der CPU so lange der Sendepuffer voll ist und >> gibt das Ding bei leerem Puffer wieder frei > > Nicht schlecht ..... aber das Thema SIO ist eigentlich duch, auch wenn > du es bei jeder Gelegenheit hervorholst und noch 50 Stück davon hast, > die herum oxidieren. Das hätte eher gemacht werden müssen, dann hätte > ich auch 2 Uarts aber auf einer Euro Karte ist kein Platz mehr für eine > SIO. Aber es wird ja noch das Projekt "Retro Z80 V2.0" geben, einen > echten CP/M Rechner.... da werde ich dann darauf zurückgreifen, auch mit > richtigen Platinen, Tastatur und Bildschirm. Ich kann Dir aber nichts Anderes erzählen, ich habe zwar an einem 6809 auch schon einen 6850 programmiert, aber daran das der mich vom Sessel gerissen hätte kann ich mich nicht erinnern. Wie Du weißt kenne ich Dich ein Bisschen und Deine Art ist es Ratschläge wegen fehlendem Wissen erst mal in den Wind zu schlagen. Deine Platine sähe wenn es nach mir gegangen wäre anders aus: eine SIO und eine CTC mit einem Z80 einem EPROM und einem RAM inklusive Restelogik und V24 Treibern. Deine 2. Platine könnte jetzt 2 PIOs und z.B. ADC/DAC nebst sauberer IM2 Mimik bekommen. Du hättest Dir das nur nicht einreden lassen. Gruß, Holm
Holm Tiffe schrieb: > es soll hier im Forum Leute > geben die einen 8080 auf einem Atmega emulieren um darauf CP/M laufen zu > lassen. Ja mich zum Beispiel. > (für ne Z80 hat der Atmega wohl zu kleine Hände womit > Turbopascal ausfällt) Z80 ist da seit geraumer Weile drin (und damit auch TP3). Das hat mit dem ATmega nichts zu tun, sondern nur damit, das sich erst jemand finden musste (Leo?), der die restlichen Opcodes nachgebaut hat. Jens
A. K. schrieb: > Holm Tiffe schrieb: >> Die SIO unterstützt einen weiteren Modus für zeitkritische Sachen wo >> bereits die Interruptlatenzzeiten stören: Die Synchronisation durch >> WAIT. > > Da werden die aber eher an schnelle synchrone Betriebsarten gedacht > haben, nicht an asynchrone 9600bd. Und wer DRAM in der Kiste hat, der > sollte dabei etwas aufpassen. Freilich, aber sie haben die Möglichkeit geschaffen. Guck Dir doch mal die anderen Gurken die es gibt so an, CIO und SCC können wir mal außen vor lassen. Gruß, Holm
Holm Tiffe schrieb: > Fakt ist aber, das mi die meisten integrierten Uarts in irgendwelchen > µCs immer sehr "hausbacken" betreffs ihrer Möglichkeiten UND Bugs > vorkommen.. Yep, beispielsweise die 16c550er UARTs in den NXP ARMs und deren seltsame Interrupts. Wobei NXP mit dieser Wahl sowieso ins Klo griff, weil dieses Teil für einen bei RS485 recht praktischen 9-Bit Modus ziemlich um die Ecke greifen muss. Das kann die einfachere UART der AVRs besser.
Holm Tiffe schrieb: > Freilich, aber sie haben die Möglichkeit geschaffen. Guck Dir doch mal > die anderen Gurken die es gibt so an, CIO und SCC können wir mal außen > vor lassen. Auch nicht übel: TMS9902. Kein Luxusteil, aber wo gab es sonst schon eine asynchrone Schnittstelle in 18 Pins, einschliesslich integriertem Oszillator für Baudratenquarz. Bei 68000ern war der 68681 recht beliebt.
:
Bearbeitet durch User
So, zum Tagesschluss noch mal ne Frage... Der Thread hier steht kurz vor seinem Absinken in die Tiefen, da er nur noch von 3 Leuten am Leben gehalten wird und inzwischen alles soweit klar ist, dass ich als der TS allein weitermachen kann. War mal was Neues und hat Spass gemacht. Bleibt die Frage: Was damit machen? Bisher war die Kiste eine Programmierübung, 4 Gewinnt eingespielt, eine Primzahlzerlegung für Arme. Das Erweiterungsboard soll schon was "Sinnvolles" machen. Was kann man damit steuern was sich gut im Wohnzimmer macht? Mir fallen da spontan Dinge aus Fischertechnik ein, was ich noch komplett habe mit allen Elektronikbaukästen der später 70iger, Elektromagneten, Flipperkugeln, Wasserspiel mit Ventilen .... Lichterspiel?
Jens schrieb: > Holm Tiffe schrieb: >> es soll hier im Forum Leute >> geben die einen 8080 auf einem Atmega emulieren um darauf CP/M laufen zu >> lassen. > Ja mich zum Beispiel. > >> (für ne Z80 hat der Atmega wohl zu kleine Hände womit >> Turbopascal ausfällt) > Z80 ist da seit geraumer Weile drin (und damit auch TP3). Das hat mit > dem ATmega nichts zu tun, sondern nur damit, das sich erst jemand finden > musste (Leo?), der die restlichen Opcodes nachgebaut hat. > > Jens Ist recht Jens. Ich habe mal gelesen das das aber in das Ding nicht rein paßt, von wann der Stand war, weiß ich nicht. Ich habe das nur mit gemäßigtem Interesse gelesen da ich Emulationen maximals fürs Debugging mag. Ich habe Z80 CP/M Rechner hier, unter Anderem in einer Art Minitower zusammen mit einem Z8000. Auf der Kiste läuft CP/M, RIO und Zeus, bzw. deren Ost Benennungen OS/M,UDOS und WEGA, eine P8000 Compact. Emuliertes CP/M habe ich hier auch im Terminalfenster unter FreeBSD weswegen mich die Emulation auf einem AVR nicht vom Sessel reißt. Das ist aber meine persönliche Vorliebe. Hier gibts auch mit SIMH einen PDP11 und einen VAX Emulator, weiß nicht ob PA-RISC und MIPS auch gänge, dann hätte ich jeweils das Equivalent für meine PDP11/83 und die E60, die diversen MicroVaxen die SGI Indigo und die kleine HP9000/710 :-) Gruß, Holm
Christian J. schrieb: > So, zum Tagesschluss noch mal ne Frage... > > Der Thread hier steht kurz vor seinem Absinken in die Tiefen, da er nur > noch von 3 Leuten am Leben gehalten wird und inzwischen alles soweit > klar ist, dass ich als der TS allein weitermachen kann. War mal was > Neues und hat Spass gemacht. > > Bleibt die Frage: Was damit machen? > > Bisher war die Kiste eine Programmierübung, 4 Gewinnt eingespielt, eine > Primzahlzerlegung für Arme. Das Erweiterungsboard soll schon was > "Sinnvolles" machen. Was kann man damit steuern was sich gut im > Wohnzimmer macht? Mir fallen da spontan Dinge aus Fischertechnik ein, > was ich noch komplett habe mit allen Elektronikbaukästen der später > 70iger, Elektromagneten, Flipperkugeln, Wasserspiel mit Ventilen .... > Lichterspiel? Mir fällt nur Blödsinn ein. Man kann so ziemlich Alles damit machen, die DDR Industrie ist mit den Z80 bei Steuerungen sehr weit gekommen. Die Frage ist, ob das heute noch Sinnvoll ist. Ich habe ab und an mal das Problem das ich irgendwelche Speicher auslesen muß oder auch Daten konvertieren oder das Steuern einer Sequenz. Mit einem PC geht das heute eigentlich nicht mehr weil blos noch idiotische Interfaces dran sind, die zum Anschluß von irgendwas meist einen weiteren Controller benötigen (Ethernet oder USB [nicht das ich was gegen diese Schnittstellen hätte, aber sie berechtigen aus meiner Sicht nicht den Wegfall Anderer]). Wenn Du was Vernünftiges damit machen willst, dann stecke das Ding ein ein Europakartengehäuse, mach ein paar PIOs dran und führe die PINs über Buchsen nach außen, so das man was damit machen kann wenn mans braucht. Keine Ahnung ob Du Sowas brauchst. Gruß, Holm
Holm Tiffe schrieb: > Mir fällt nur Blödsinn ein. Das ist schon ganz ok. Und ein paar PIOs brauche ich nicht, dafür gibts Arduino. Der hat ganz viele "PIOs" dran. habe mir grad hier mal diesen CP/M Stick angeschaut, der hier als Projekt hinterlegt ist, einen Emulator auf Atmega88. So ganz trivial ist das ja nicht. CP/M habe ich mir noch nicht angeschaut, nur mal quer gelesen. War vor meiner Zeit. Wieso ist das so einfach zu emulieren? Das Ding ist doch sicherlich in Assembler geschrieben worden für eine spezielle Hardware? Also BIOS im EPROM, Floppys mit Userprogrammen, Ansteuerung eines Bildschirmes und Tastatur. Es gibt ja auch Software dafür, die geladen werden kann. Wie kriegt man sowas in einen Atmega Stick?
Christian J. schrieb: > Wieso ist das so einfach zu emulieren? Wo ist das Problem? CP/M unterscheidet zwischen dem portablen BDOS und dem hardwareabhängigen BIOS. Du musst für das CP/M nur den Befehlssatz einer 8080 CPU emulieren. Das ist überschaubar. Das BIOS dazu kann man selber stricken, weshalb man dafür keine echten I/O-Bausteine wie SIO nachbilden muss, sondern eine emulationsfreundliches eigenes Interface definieren kann. Das BIOS-Interface von PCs erinnert übrigens nicht zufällig an das BIOS von CP/M, ebenso wie der API von DOS an den vom BDOS erinnert.
:
Bearbeitet durch User
Ok, blicke ich zurück nach 1994 wo ich meinen ersten 386er bekam und dazu ein dickes Buch hatte: PC Intern! Das Ding was nachher vom vielen Nachschlagen in sich zerfiel und nur noch durch Klebeband zusammen gehalten wurde. Da stand alles drin was man wissen musste um in Asm den zu programmieren (auch wenn ich damals "nur" einen Virus schrieb. Die API waren Int 10h Int 13h für Bios, Int21h für DOS und viele andere, die man benutzen konnte, die ganze Floppy Kontrolle lief darüber, zumindest auf Sektorebene, keine Fat natürlich. D.h. Hardware <----> BIOS <-----> CP/M <-----> User Software Aha...
Hallo, glaube hier hat jemand sauber gemacht wie ich sehe :-) War aber auch nötig. Hoffe dennoch dass der ein oder andere hierhin zurück findet. Thema: externer Datenspeicher OHNE Retro. Herausgeführt aus dem Z80 ist nur der I/O Teil, Datenbus, Clock, Reset und sämtliche Decoderleitungen für Chip Selects. Ebenfalls sind 4 GPIO Pins vorhanden die getoggelt werden können. Ich überlege mir grad wie ich mit einem Arduino System, d.h. nur der IDE einen Datenspeicher aufbaue. Ich weiss nicht genau ob ein AVR mit 8 Mhz internem Oszillator schnell genug ist um direkt mit den Bus Leitungen des Z80 zu kommunizieren, d.h. ein Peripheriegerät simuliert. Ich habe noch einige Arduino Nanos hier, die mit 16Mhz Quarz arbeiten und einem Atmel 328 mit 32k Flash. Als Idee schwebt mir vor, dass der AVR einige Register in die I/O Map des Z80 einbringt (möglich sind 8 Bytes), die dann mit einem Protokoll dafür sorgen, dass eine angeschlossenen SD Card mit einem ganz einfachen Filesystem als Speicher dient. Falls es eine bessere Lösung gibt ..... bin da für alles offen.
Was spricht gegen Direktanschluss der SD-Card an Z80, statt Umweg über Arduino?
:
Bearbeitet durch User
A. K. schrieb: > Was spricht gegen Direktanschluss der SD-Card an Z80, statt Umweg über > Arduino? Ich kenne mich mit dem SD card Protokoll 4.0 recht gut aus, weil ich da mal Soft für geschrieben habe um Sektoren zu schreiben und zu lesen. Es wäre zu gross und gehört eigentlich nicht in den Z80, sondern in die "Floppy". Für den Arduino habe ich eine ganze fertige Lib mit FAT. Idee ist also AVR sitzt an Datenbus,RD,WR, IOREQ und Demuxer CS leitung I/O Map: 00 01 02 03 04 05 06 07 ..... CMD LO HI B1 B2 B3 B4 .... CMD = WRITE/READ/ERASE etc. LO/HI = Zielfile... 0,1,2,3,4,5,6...
Christian J. schrieb: > AVR als I/O Bus "Device", eingemapped mit fixere Adresse für maximal 32 > Bytes möglich. Mit welchem AVR geht das?
Nochmal....... Jeder ARDUINO den ich habe, hat genug IO um an einen Z80 Bus gehängt zu werden! Und ich habe Nanos, Einzelchips, Atmega32u usw. Wumpe, einer wird passen und alle haben das gleiche Programmiermodell wegen der IDE. Gibt es da ein problem? Nix anderes als wenn man in ein FPGA zb einen CTC Timer schreiben würde, so dass sich der FPGA wie ein CTC verhält. Kein Hexenwerk.
De AVR müsste nur dauernd an den Steuerleitungen horchen und sich genau wie ein Z80 Baustein verhalten. Ob er schnell genug ist weiss ich nicht. Ich müsste ja das ganze Timing des Z80 beachten.
Christian J. schrieb: > Gibt es da ein problem? Nur dass die AVRs weder Buslatch noch automatischen Handshake haben und die Reaktionszeit für Software leicht knackig ist. Oder machst dazu etwas Logik dazwischen, um mit WAIT zu arbeiten?
:
Bearbeitet durch User
Christian J. schrieb: > De AVR müsste nur dauernd an den Steuerleitungen horchen und sich genau > wie ein Z80 Baustein verhalten. Da bin ich mal gespannt.
Genau.... das wäre eine reine Softwarelösung ohne jede Harwareunterstützung. Wait ist bisher nicht rausgeführt, ginge aber. Der AVR sieht ja "nur" einen I/O Zugriff. IOREQ auf low, RD oder WR, Demuxer Leitung "0" ..... dazu muss ich ins Timing reinkriechen. Ein Latch rein ist absolut easy, so läuft die 7 Segment ja, die hat auch eine eigene Adresse. http://www.nathandumont.com/blog/giving-the-z80-a-good-boot "The Solution: A PIC and an SD card I've been looking at this problem since I stopped working on the first version of my Z80 homebrew system. A few months ago I came to the realisation that the PIC I was planning on using to interface an SD card to the system was under-utilised. SD cards are huge in storage and very cheap, plus you can interface to them via SPI which is easy to do. I'd built a file browser that ran on a PIC before that could cope with multiple partitions and FAT types, so knew that was well within the capabilities of a PIC to do. So the plan was to just use the PIC as an easy way to interface the storage to the Z80. The space requirement and cost of a PIC microcontroller is much lower than what would be needed for a 74xx logic solution, even if a parallel standard like IDE was used instead of SPI." CPLD habe ich leider nichts für und kann kein VHDL mehr nach fast 10 Jahren.....
Nett, dass du den Link gebracht hast. Dann muss ich dich nicht selber auf Microchip ansetzen - die haben nämlich in manchen Devices exakt das, was du hier benötigst: ein als Bus-Slave arbeitsfähiges Interface-Modul, das die Z80 direkt ansprechen könnte.
Nur daß Christian den Artikel nicht zu Ende gelesen hat. Der PIC macht nämlich genau daß, was Du oben vorgeschlagen hat: BUS-Master.
Das Timing wird easy, wenn du WAIT verwendest. Viel mehr als einen Bustreiber und ein RS-Flipflop brauchst du dann nicht. Zugriff der Z80 aktiviert WAIT, AVR deaktiviert.
A. K. schrieb: > ein als Bus-Slave arbeitsfähiges Interface-Modul, > das die Z80 direkt ansprechen könnte. Habe recht viele 18F877 hier, wo Port E als Bus Slave geschaltet werden kann inckl Steuerleitungen. Der CCS Compiler unterstützt das auch. Als Master geht nicht, kein Adressbus rausgeführt. Wozu Bustreiber? Wer soll wen treiben? Bidirektional, unidirektional? Der PIC oder AVR ist doch keine Last für die Datenleitungen. PSP Mode nennt sich das beim 18F877.... CS,RD,WR+8 Bits. Hardwarae gesteuert.
Christian J. schrieb: > Habe recht viele 18F877 hier, wo Port E als Bus Slave geschaltet werden > kann inckl Steuerleitungen. Na also. Dazu noch ein paar Portpins irgendeines Portbausteins auf Z80-Seite für Status&Control des Protokolls und fertig. > Wozu Bustreiber? Wer soll wen treiben? Ich hatte da zwei Lösungsvarianten verknotet. In der WAIT Variante brauchts den nicht.
:
Bearbeitet durch User
Genau das was ich brauche bei 16F877..... jeder Zugriff ist interruptgesteuert behandelbar. Allerdings habe ich für den PIC keine FAT für SD karten und auch nichts als Low Level Treiber. PORTD operates as an 8-bit wide Parallel Slave Port or microprocessor port when control bit PSPMODE (TRISE<4>) is set. In slave mode, it is asynchronously readable and writable by the external world through RD control input pin RE0/RD and WR control input pin RE1/WR. It can directly interface to an 8-bit microprocessor data bus. The external microprocessor can read or write the PORTD latch as an 8-bit latch. Setting bit PSPMODE enables port pin RE0/RD to be the RD input, RE1/WR to be the WR input and RE2/CS to be the CS (chip select) input. For this functionality, the corresponding data direction bits of the TRISE register (TRISE<2:0>) must be configured as inputs (set). The A/D port con- figuration bits PCFG3:PCFG0 (ADCON1<3:0>) must be set to configure pins RE2:RE0 as digital I/O. There are actually two 8-bit latches. One for data-out and one for data input. The user writes 8-bit data to the PORTD data latch and reads data from the port pin latch (note that they have the same address). In this mode, the TRISD register is ignored, since the micro- processor is controlling the direction of data flow.
Moin, nochmal zurück. Ich habe mich gegen den PIC entschieden, weil ich dafür keine Libs habe die SD Karte betreffend und der CCS Compiler bekannte Libs nicht kompiliert, habe eh nur eine 5 Jahre alte Version. Das Fass den sdcc dafür zu beutzen mache ich nicht mehr auf, zudem der sich in die MPLAB IDE integrieren müsste. Mein PIC KIT fliegt auch irgendwo rum, keine Ahnung wo. Also AVR. Nach einigem Lesen im Netz sind einige Lösungen zu finden ein IDE Interface auf eine CF abzubilden, damit CP/M laufen kann. Das ist aber zu aufgeblasen für diesen Minirechner, er hat ja auch keine Software für ein IDE Interface. Mannomann... welche Lösungen gibt es noch Speicher dran zu pappen ohne dafür ein neues Fass auf zu machen wie mit dem PIC oder IDE?
Christian J. schrieb: > Mannomann... welche Lösungen gibt es noch Speicher dran zu pappen ohne > dafür ein neues Fass auf zu machen wie mit dem PIC oder IDE? Wie man sich bettet, so liegt man. Wenn du unbedingt auf FAT bestehst, und darauf, vom PC aus ohne jeden irgendwie gearteten Aufwand dran zu kommen, dann hast du eben Arbeit im Z80-Rechner. Wenn du nicht so zwingend auf fix und fertiges Betanken durch den PC bestehst und folglich auch FAT nicht zwingend ist, dann wird es toteinfach. Aber das hatte ich früher schon beschrieben.
Christian J. schrieb: > Mannomann... welche Lösungen gibt es noch Speicher dran zu pappen ohne > dafür ein neues Fass auf zu machen wie mit dem PIC oder IDE? Deine Denkweise ist einfach falsch. Du suchst immer nur nach fertigen Lösungen. Wenn es diese nicht gibt, bist Du aufgeschmissen. Mach das einfach anders: Wenn es eine Lösung für ein bestimmtes Problem (noch) nicht gibt, dann schaffe sie! P.S. Ich sehe das genauso wie A.K. Du brauchst kein FAT.
:
Bearbeitet durch Moderator
Frank M. schrieb: > Wenn es eine Lösung für ein bestimmtes Problem (noch) nicht gibt, dann > schaffe sie! Frank, in diesem Fall gibt es sie! FAT etc brauche ich alles nicht. Es reicht ein 64kB Block Bytes, die nur geschrieben und gelesen werden müssen. Trotzdem muss das irgendwie an den I/O Bus dran und selbst diese Latch Geschichte hat ihre Tücken. Ohne I2C und SPI ist es einfach sch.....
Christian J. schrieb: > Ohne I2C und SPI ist es einfach sch..... Du traust dir nicht einmal SPI in Software zu? Das Protokoll eines Dataflash ist trivial.
:
Bearbeitet durch User
A. K. schrieb: > Du traust dir nicht einmal SPI in Software zu? Das Protokoll eines > Dataflash ist trivial. Natürlich! Auch CF karten sind bekannt, Paralleschnittstelle, bestens dokumentiert. Trotzdem muss da einiges an Bausteinen drumherum. Ideal wäre I2C EEPROM.... aber I2C kriegste mit den GPIO nicht hin. Der 8255 hat noch die blöde Eigenschaft bei jedem Mode Wechsel von RD auf WR seine Register zu resetten, so dass es Glitches gibt,
Christian J. schrieb: > Trotzdem muss da einiges an Bausteinen drumherum. Wüsste nicht, was ausser 4 Portpins und Pegelwandler für 3,3V SPI nötig wäre. Und weshalb bei unidirektionalen Leitungen Glitches auftreten müssen erschliesst sich mir nicht.
Christian J. schrieb: > Auch CF karten sind bekannt Den Aufwand von 16-Bit Parallel-IDE (aka CF) mit 1-Bit SPI zu vergleichen...
Christian J. schrieb: > Trotzdem muss da einiges an Bausteinen drumherum. Naja, so ein paar Widerstände als Pegelwandler für SPI sind natürlich hochkomplex... Schnapp Dir eine alte SD-Card und hänge sie an Deinen 8255 oder was Du sonst noch hast. Hier hast Du noch einen Link: http://elm-chan.org/docs/mmc/mmc_e.html Eigentlich reicht das schon, um die SC-Card am Z80 zum Laufen zu bekommen.
Er braucht auch nicht mal einen solchen Massenspeicher. Was zur Hölle soll denn da drauf? CP/M geht wohl mit der Architektur nicht recht wenn ich mich richtig erinnere, erfordert wohl zumindest Änderungen um lückenlose 64K Ram zu erzeugen. Woher also kommen die vielen Daten? Selbst entwickelte Programme? Eher unwahrscheinlich... Ich habe mal darüber nachgedacht einen mit AT89C2051 gebauten PS2 zu DDR Parallel-Tastaturanschluß den Jemand anders entworfen hatte zu Ende zu bauen, ging nicht, die IO-Zugriffe auf die der µC hätte reagieren müssen dauerten nur 800ns, nicht zu schaffen. Der in der originalen Tastatur rappelnde Z80 ohne RAM lief zwar nur mit 1Mhz, hatte aber externe Latches zur Hilfe (8212). Ein ATTINY mit Interrupt hätte es vielleicht gerade so geschafft..ich habe es dann gelassen. PIC ollte ich mir nicht antun und andere µC mit BUS fähigen Latches sind dünn gesäht. Eine PIO kann sowas, eine hornalte UPI 8042 auch. Gruß, Holm
Holm Tiffe schrieb: > PIC ollte ich mir nicht antun und andere µC mit > BUS fähigen Latches sind dünn gesäht. Hab ein paar alte Z8594 (Z8-UPC) rumliegen, mitsame 2K RAMs huckepack. Die haben mehr als bloss ein Latch, die haben ein mustergültiges Slave-Interface mit Dualport-Registern, Blocktransfer usw.
Den ganze Code für MMC habe ich schon mal geschrieben.... MMC karten gibt übrigens nicht mehr, nur noch SD. Und die sind leicht anders. Aber so könnte es gehen, der Code ist ja portierbar.
Christian J. schrieb: > Aber so könnte es gehen, der Code ist ja portierbar. Eben, Du musst doch nur SPIMMC() für den 8255 umschreiben.
Frank M. schrieb: > Christian J. schrieb: >> Aber so könnte es gehen, der Code ist ja portierbar. > > Eben, Du musst doch nur SPIMMC() für den 8255 umschreiben. Ich sagte ja vorhin schon eine Umsschaltung von Write auf Read beim 8255 einen kompletten Reset der internen Register erzeugt. Du musst danach alles neu einschreiben. Der 8255 ist zu blöde Einzelpins auf RD oder WR zu schalten, nur ganze Ports. Ich lass mir da mal was einfallen. Einen "8 Bit Ausgabe PORT" am Z80 kann man sehr einfach mit einem Latch erzeugen. Einen Eingabeport genauso, nur mit einem anderen Baustein.
Christian J. schrieb: > Ich sagte ja vorhin schon eine Umsschaltung von Write auf Read beim 8255 > einen kompletten Reset der internen Register erzeugt. Häh? Bei SPI brauchst Du gar nichts umzuschalten! Das bräuchtest Du höchstens bei I2C. Ist hier aber bei einer SD-Card nicht zielführend. P.S. Mich beschleicht das dumme Gefühl, dass Du von SPI keine Ahnung hast. Wie Du dafür ein Programm selber(!) schreiben konntest, ist mir schleierhaft.
:
Bearbeitet durch Moderator
Er hatte vmtl. nur das SPI-Interface des Controllers im Auge, und wie man das anspricht steht im Datasheet. Wie SPI hardwareseitig abgeht muss man dann ja nicht wissen, also muss man die begrenzte Anzahl grauer Zellen nicht mit unnötigem Wissen belasten. SPI in Software ist ungefähr das Zweiteinfachste, was man mit Ports tun kann, kommt direkt nach LED an/aus.
:
Bearbeitet durch User
Und was ist das hier? Eine komplette Komminikation per SPI mit mehreren Nodes, die um einiges komplxer ist. lasst gut sein, wir reden sonst aneinander vorbei. Mir fällt was ein...
1 | Funktion: SPI_SendFrame |
2 | Modul : port_cpu.c |
3 | -------------------------------------------------------------------------------- |
4 | Beschreibung : Verpackt den Datensatz und sendet ihn zum Slave |
5 | Erzeugt das Protokoll, um mit Slave zu kommunizieren |
6 | Es findet keine Auswertung statt, es werden nur rohe |
7 | Daten gesendet und empfangen. |
8 | |
9 | Diese Routine ist universell einsetzbar für SPI |
10 | Kommunikation |
11 | |
12 | Protokoll (ohne Checksumme) |
13 | |
14 | Sendung des Masters: |
15 | <MASTER_START> <Anzahl> <ssize> <...> <...> <MASTER_END> ... |
16 | |
17 | Slave antwortet mit: |
18 | a) ... <SLAVE_END> (wenn keine Sendedaten vorliegen) |
19 | b) ... <SLAVE_START> <rsize> <...> <...> <SLAVE_END> |
20 | |
21 | aufgerufene Funktionen : SPI |
22 | |
23 | enum chips {devIR,devLCD,devPORT......}; |
24 | |
25 | Eingabeparameter : dev Device (siehe enum chips) |
26 | *tosend Zeiger auf Quelldaten |
27 | ssize Anzahl zu sendender Daten |
28 | *receive Zeiger auf Empfangspuffer |
29 | *rsize Zeiger auf Puffer für Anzahl empf. Datenbyte |
30 | |
31 | Rückgabe : OK,FAIL |
32 | veränderte Globals : - |
33 | öffentlich/private : public |
34 | |
35 | |
36 | letzte Änderung: 28.3.2009 |
Christian J. schrieb: > Und was ist das hier? Eine komplette Komminikation per SPI mit mehreren > Nodes...... Na also, man muss dich nur etwas kitzeln, dann kommst du ganz von selber drauf. ;-)
Ist jetzt kein Witz aber manchmal glaube ich, dass seit meiner Kopfoperation Ende 2009, wo ein Tumor entfernt wurde einiges "weg" ist. Hatte zwar ne Reha 1/2 Jahr aber auch 5 Jahre später sind immer noch Lücken da...
Christian J. schrieb: > ein IDE Interface auf eine CF abzubilden Wesentlich primitiver als CF -> IDE -> Z80 Bus geht es kaum noch. Wenn du einen 8255 spendierst, hast du schon 90% der Miete. Das mit den Glitches ist bekannt und es gibt eine Lösung dafür. Der Text kommt als Anlage. Die Software, einen Sektor zu lesen / zu schreiben ist trivial, Sektor, Track, Head in das passende Register, Lesebefehl und dann Daten in aller Ruhe holen (es geht gut ohne DMA und der Z80 kann wunderbar Blöcke per IO transferieren). Wenn dir FAT zu umständlich ist, bietet sich ein Disk-Allocation-Vector Prinzip wie bei CP/M an. Auch dafür gibt es erprobte Software. Oder du nimmst gleich CP/M (was auch keine Großtat ist).
Georg G. schrieb: > Wenn dir FAT zu umständlich ist, bietet sich ein Disk-Allocation-Vector > Prinzip wie bei CP/M an. Auch dafür gibt es erprobte Software. Oder du > nimmst gleich CP/M (was auch keine Großtat ist). Doch, wenn man absolut keine Ahnung davon hat muss man sich in das ganze Thema einarbeiten, nicht nur einen Teil und CP/M ist nicht mein Ziel. es gibt ne Reihe Lösungen die an das BDOS des CPM angepasst sind, weiss ich. Den Text oben kenne ich auch schon. Ich belasse es bei einer SPI, da es eh nur individuell ist.
A. K. schrieb: > Holm Tiffe schrieb: >> PIC ollte ich mir nicht antun und andere µC mit >> BUS fähigen Latches sind dünn gesäht. > > Hab ein paar alte Z8594 (Z8-UPC) rumliegen, mitsame 2K RAMs huckepack. > Die haben mehr als bloss ein Latch, die haben ein mustergültiges > Slave-Interface mit Dualport-Registern, Blocktransfer usw. Nice, kannste bei mir abkippen :-) Ich habe nur irgend einen µPD75C-irgendwas 4 Bit Controlletti von NEC mit solch einem Gehäuse, den gabs wohl vor Urzeiten mal bei Polin? Mir ist es nie gelungen eine ordentliche Doku dafür zu finden, aber einen Assembler hatte ich schon mal angepaßt vor langer Zeit. Gruß, Holm
Mannomann ;-( Seit Stunden versuche ich den TX Buffer ans Laufen zu kriegen aber es kommt nur Zeichenmüll dabei raus. Einzelzeichen mit Pause laufen aber das schnelle Vollschreiben erzeugt nur Müll als Ausgabe. Das sieht alles absolut richtig aus aber es klappt nicht. Was funktioniert ist: - ISR wird aufgerufen, Int klappt also - Einzelzeichenausgabe Testsequenz: 1. String als Ganzes 2. Einzelzeichen Defintion
1 | // RX Empfangspuffer |
2 | struct rx_type{ |
3 | int8_t buf[BUF_SIZE+1]; |
4 | uint8_t rd_ptr; |
5 | uint8_t wr_ptr; |
6 | uint8_t mask; |
7 | uint8_t f_buf_full; // flag:Es sind Zeichen da |
8 | uint8_t f_buf_overflow; // flag:Overflow: WR Zeiger hat RD überholt: Buffer wertlos |
9 | }; |
10 | |
11 | // TX Sendepuffer |
12 | struct tx_type{ |
13 | int8_t buf[BUF_SIZE+1]; |
14 | uint8_t rd_ptr; |
15 | uint8_t wr_ptr; |
16 | uint8_t mask; |
17 | uint8_t f_idle; // TX Hardware ist inaktiv |
18 | uint8_t f_buf_full; // TX Buffer ist komplett voll |
19 | }; |
putchar....
1 | void putchar(char c) |
2 | { |
3 | static counter1 = 0; |
4 | |
5 | // Warte bis TX frei für neues Zeichen ist |
6 | //while ((STI_TSR & 0x80) == 0); |
7 | //STI_UDR = c; |
8 | |
9 | if (tx.f_idle) { |
10 | // TX ist leer und abgeschaltet |
11 | tx.f_idle = false; |
12 | STI_UDR = c; |
13 | SetDigit(counter1++); |
14 | // Int Enable |
15 | // CLI; |
16 | // STI_IMRA = STI_IMRA | TX_INT_MASK; // Int Mask |
17 | // STI_PVR = STI_IERA; |
18 | // STI_IDR = STI_IDR | TX_INT_MASK; |
19 | // STI_PVR = MODE2_VECTOR; |
20 | // EI; |
21 | } else |
22 | { |
23 | SetLedByte(counter1++); |
24 | // TX sendet noch..... |
25 | // Zeichen einschreiben, wenn Buffer nicht voll |
26 | if (!tx.f_buf_full) |
27 | { |
28 | tx.buf[tx.wr_ptr] = c; |
29 | // wr+1 am Bufferende auf 0 zurücksetzen |
30 | tx.wr_ptr = (tx.wr_ptr +1) & tx.mask; |
31 | // Wurde Position ISR RD Zeiger erreicht? Dann voll. |
32 | tx.f_buf_full = (tx.wr_ptr == tx.rd_ptr) ? true : false; |
33 | } |
34 | } |
35 | |
36 | } |
Interrupt Buffer Empty
1 | void int_sti_transmit_buffer_empty(void) __interrupt |
2 | { |
3 | static counter1 = 0; |
4 | static counter2 = 0; |
5 | |
6 | // Sind noch Zeichen im TX Buffer? |
7 | if (tx.rd_ptr != tx.wr_ptr) { // ja..... |
8 | //SetLedByte(counter1++); |
9 | tx.f_buf_full = false; // Buffer mindestens 1 Zeichen frei |
10 | tx.f_idle = false; // TX aus |
11 | STI_UDR = tx.buf[tx.rd_ptr]; // Byte einschreiben |
12 | tx.rd_ptr = (tx.rd_ptr +1) & tx.mask; // Read Pointer rollen |
13 | } |
14 | else |
15 | { // nein, letztes zeichen ging grad raus |
16 | //SetDigit(counter2++); |
17 | tx.f_idle = true; // TX aus |
18 | tx.f_buf_full = false; // Buffer mindestens 1 Zeichen frei |
19 | // TX Interrupt aus |
20 | // STI_PVR = STI_IERA; |
21 | // STI_IDR = STI_IDR & ~TX_INT_MASK; // Int TX aus |
22 | // STI_PVR = MODE2_VECTOR; // Vektor auf Mode 2 Tabelle |
23 | } |
24 | |
25 | EI; |
26 | |
27 | } |
(1) Race condition bei if (tx.f_idle) { // TX ist leer und abgeschaltet tx.f_idle = false; Da muss eine Interrupt-Sperre rein. (2) In putchar bei Pufferüberlauf Daten wegwerfen ist selten eine sinnvolle Strategie. Da macht man üblicherweise nur im Receiver-Interrupt, weil alternativlos.
if (!tx.f_buf_full) { tx.buf[tx.wr_ptr] = c; // wr+1 am Bufferende auf 0 zurücksetzen tx.wr_ptr = (tx.wr_ptr +1) & tx.mask; // Wurde Position ISR RD Zeiger erreicht? Dann voll. tx.f_buf_full = (tx.wr_ptr == tx.rd_ptr) ? true : false; } else while (tx.f_buf_full); Läuft trotzdem nicht.
(3) Ich denke nicht, dass das Register so richtig bedient wird: // STI_PVR = STI_IERA; // STI_PVR = MODE2_VECTOR; Auf diese Art schaltest du zwischendurch den IM2 Vektorbereich ab. Das wird meistens gut gehen - aber eben nur meistens.
:
Bearbeitet durch User
A. K. schrieb: > Ich denke nicht, dass das Register so richtig bedient wird: > // STI_PVR = STI_IERA; > // STI_PVR = MODE2_VECTOR; > Auf diese Art schaltest du zwischendurch den IM2 Vektorbereich ab. Das > wird meistens gut gehen - aber eben nur meistens. Geht nicht anders, da PVR benutzt wird für indirekte Adressierung und zum Schluss wieder auf Tabelle gesetzt wird. Ist aber auskommentiert, man muss keinen Int abschalten, Ergebnis mit und ohne gleich.
1 | // Schaltet die RX Line ab oder an |
2 | void rx_int_enable(char stat) |
3 | { |
4 | CLI; |
5 | if (stat) { // RX Buffer Interrupt ein |
6 | STI_RSR = STI_RSR | 0x01; // RX Hardware ein |
7 | STI_IMRA = STI_IMRA | RX_INT_MASK; |
8 | STI_PVR = STI_IERA; |
9 | STI_IDR = STI_IDR | RX_INT_MASK; |
10 | |
11 | } else { // RX Buffer Interrupt aus |
12 | STI_RSR = STI_RSR & ~0x01; // RX Hardware aus |
13 | STI_IMRA = STI_IMRA & ~RX_INT_MASK; // Maske aus |
14 | STI_PVR = STI_IERA; |
15 | STI_IDR = STI_IDR & ~RX_INT_MASK; // Enable aus |
16 | STI_IPRA = STI_IPRA & ~RX_INT_MASK; // Pending Ints löschen |
17 | } |
18 | |
19 | STI_PVR = MODE2_VECTOR; // Vektor auf Mode 2 Tabelle |
20 | EI; |
21 | } |
22 | |
23 | //////////////////////////////////////////////////////// |
24 | // Schaltet die TX Line ab oder an |
25 | void tx_int_enable(char stat) |
26 | { |
27 | CLI; |
28 | if (stat == true) |
29 | { // RX Buffer Interrupt ein |
30 | STI_TSR = STI_TSR | 0x01; // TX Hardware ein |
31 | STI_IMRA = STI_IMRA | TX_INT_MASK; // Int Mask |
32 | STI_PVR = STI_IERA; |
33 | STI_IDR = STI_IDR | TX_INT_MASK; // Int Enable |
34 | } else |
35 | { // TX Interrupt aus |
36 | STI_TSR = STI_TSR & ~0x01; |
37 | STI_IMRA = STI_IMRA & ~TX_INT_MASK; // Maske aus |
38 | STI_PVR = STI_IERA; |
39 | STI_IDR = STI_IDR & ~TX_INT_MASK; // Enable aus |
40 | STI_IPRA = STI_IPRA & ~TX_INT_MASK; // Pending Ints löschen |
41 | } |
42 | |
43 | STI_PVR = MODE2_VECTOR; // Vektor auf Mode 2 Tabelle |
44 | EI; |
45 | } |
Christian J. schrieb: > Läuft trotzdem nicht. Wundert mich nicht. (4) Vorher warten ob voll, dann reinschreiben. Nicht nachher warten und trotzdem wegwerfen, (5) Race condition rund um tx.f_buf_full. Dieses Flag ist ohnehin unnötig. Wenn man mit einem N+1 Puffer arbeitet, dann kann man diese Bedingung ohne Abschaltung von Interrupts feststellen, indem man die Indizes vergleicht, ohne ein Flag verwenden zu müssen.
:
Bearbeitet durch User
Christian J. schrieb: > Geht nicht anders, Das geht sehr wohl anders: STI_PVR = MODE2_VECTOR | STI_IERA; STI_IDR = STI_IDR | RX_INT_MASK;
A. K. schrieb: > (4) Vorher warten ob voll, dann reinschreiben. Nicht nachher warten und > trotzdem wegwerfen, Weisser Mann sprechen in Rätseln....
A. K. schrieb: > (5) Race condition rund um tx.f_buf_full. Dieses Flag ist ohnehin > unnötig. Wenn man mit einem N+1 Puffer arbeitet, dann kann man diese > Bedingung ohne Abschaltung von Interrupts feststellen, indem man die > Indizes vergleicht, ohne ein Flag verwenden zu müssen. Ok....
Christian J. schrieb: > Weisser Mann sprechen in Rätseln.... Da ist ein "s" zu viel. ;-) Was du machst: if (!full) reinschreiben; else while (full) und das führt nicht dazu, dass bei vollem Puffer das Byte irgendwo landet. Besser wäre das Prinzip while (full) ; reinschreiben;
A. K. schrieb: > Besser wäre das Prinzip > while (full) > ; > reinschreiben; Ah, Winnetou verstehen langsam was sein weißer Bruder ihm sagen will....
Christian J. schrieb: > Ah, Winnetou verstehen langsam was sein weißer Bruder ihm sagen will.... Na endlich. Ich habe mich schon lange gefragt, was alles passieren muss, bis du rot wirst. ;-)
Komt trotzdem der gleiche Müll bei raus:
1 | void putchar(char c) |
2 | { |
3 | |
4 | if (tx.f_idle) { |
5 | // TX ist leer und abgeschaltet |
6 | CLI; |
7 | tx.f_idle = false; |
8 | STI_UDR = c; |
9 | EI; |
10 | } else |
11 | { |
12 | // Zeichen einschreiben, wenn Buffer nicht voll |
13 | while (tx.wr_ptr != tx.rd_ptr) |
14 | { |
15 | tx.buf[tx.wr_ptr] = c; |
16 | // wr+1 am Bufferende auf 0 zurücksetzen |
17 | tx.wr_ptr = (tx.wr_ptr +1) & tx.mask; |
18 | } |
19 | } |
20 | |
21 | } |
Christian J. schrieb: > Komt trotzdem der gleiche Müll bei raus: > if (tx.f_idle) { > // TX ist leer und abgeschaltet > CLI; > tx.f_idle = false; > STI_UDR = c; > EI; Immer noch (1).
1 | //////////////////////////////////////////////// |
2 | // ISR: Uart TX Sendepuffer ist leer |
3 | // putchar() muss dafür sorgen, dass er wieder voll wird |
4 | // ISR sendet solange noch zeichen im Puffer sind |
5 | |
6 | void int_sti_transmit_buffer_empty(void) __interrupt |
7 | { |
8 | |
9 | // Sind noch Zeichen im TX Buffer? |
10 | if (tx.rd_ptr != tx.wr_ptr) { // ja..... |
11 | tx.f_idle = false; // TX aus |
12 | STI_UDR = tx.buf[tx.rd_ptr]; // Byte einschreiben |
13 | tx.rd_ptr = (tx.rd_ptr +1) & tx.mask; // Read Pointer rollen |
14 | } |
15 | else |
16 | { // nein, letztes zeichen ging grad raus |
17 | tx.f_idle = true; // TX aus |
18 | } |
19 | |
20 | EI; |
21 | |
22 | } |
#define CLI __asm di __endasm // Interrupts sperren/frei #define EI __asm ei __endasm Wieso? Ints sind aus.... auß0erdem verliert der auch so Zeichen, wenn Puffer voll mit der while Schleife.
Christian J. schrieb: > tx.wr_ptr = (tx.wr_ptr +1) & tx.mask; Kann man so machen, wenn BUFSIZE+1 eine Zweierpotenz ist. Sicherer ist aber wr = (wr <= BUFSIZE-1) ? wr + 1 : 0; weil davon unabhängig und kaum aufwändiger.
A. K. schrieb: >> if (tx.f_idle) { >> // TX ist leer und abgeschaltet >> CLI; >> tx.f_idle = false; >> STI_UDR = c; >> EI; > > Immer noch (1). Wenn Interrupt zwischen if() und CLI und darin das Flag gesetzt wird.
:
Bearbeitet durch User
So besser?
1 | void putchar(char c) |
2 | { |
3 | CLI; |
4 | if (tx.f_idle) { |
5 | // TX ist leer und abgeschaltet |
6 | tx.f_idle = false; |
7 | STI_UDR = c; |
8 | EI; |
9 | |
10 | } else |
11 | { |
12 | EI; |
13 | SetLedByte(counter1++); |
14 | // TX sendet noch. Warte bis Buffer frei..... |
15 | while (tx.wr_ptr == tx.rd_ptr); |
16 | tx.buf[tx.wr_ptr] = c; |
17 | // wr+1 am Bufferende auf 0 zurücksetzen |
18 | tx.wr_ptr = (tx.wr_ptr +1) & tx.mask; |
19 | |
20 | } |
21 | |
22 | } |
Christian J. schrieb: > So besser? Fast. Die race condition ist weg, ... > while (tx.wr_ptr == tx.rd_ptr); ... aber die Abfrage ist falsch. Diese Bedingung kann nicht gleichzeitig für voll und für leer stehen.
Leer braucht man nicht, alles was nicht voll ist ist garantiert "leer" bzw noch 1 Zeichen Platz. Er hängt sich aber auch genau da auf und bleibt ewig drin. Egal wie ich es auch drehe und wende, es kommt nur Müll bei raus und ich werde mir debug Funktionen schreiben müssen, damit ich weiss was Sache ist. wr und rd können ihre Positionen tauschen, je nachdem wer schnell läuft. rd kann aber wr nie "überholen", muss bei gleichheit stehen bleiben. Daher kann es nur die Abfrage == geben.
Christian J. schrieb: > Leer braucht man nicht, alles was nicht voll ist ist garantiert "leer" Meinst du nicht, dass sich da was beisst? // Sind noch Zeichen im TX Buffer? if (tx.rd_ptr != tx.wr_ptr) { // TX sendet noch. Warte bis Buffer frei..... while (tx.wr_ptr == tx.rd_ptr); > bzw noch 1 Zeichen Platz. Eben. Voll ist bei ((wr + 1) % N == rd).
:
Bearbeitet durch User
Hmm...... ISR guckt, ob Zeiger unterschiedlich sind. Wenj ja, wird Zeichen eingeschrieben und Zeiger +1. Beim nächsten Durchlauf sind Zeiger entwederr gleich oder es wurde schon was Neues eingeschrieben. Soo auf Anhieb sehe ich das jetzt nicht aber das ist meist so wenn man schon einige Stunden damit verbracht hat.
Entweder steht rd==wr für Puffer voll, oder es steht für Puffer leer. Aber es kann nicht sein, dass es für beides steht. Theoretischer Hintergrund: Das Prinzip besteht darin, dass man in einen Puffer von N Bytes nie mehr als N-1 Bytes reinschreibt. Andernfalls hätte man N+1 Füllungsgrade (0..N). Die Differenz der Indizes kann aber nur N Zustände darstellen. Also muss einer dran glauben, und das kann nur der Füllungsgrad N sein.
Ist mir klar aber #define BUF_SIZE 128 // RX Empfangspuffer struct rx_type{ int8_t buf[BUF_SIZE+1]; uint8_t rd_ptr; uint8_t wr_ptr; uint8_t mask; uint8_t f_buf_full; uint8_t f_buf_overflow; }; Puffer ist 1 groesser als der Index, ein Reservebyte. Weiss jetzt aber auch nicht weiter .....
Ich kann das problem jetzt nur so einkreisen, dass ich definierte Füllzustände erzeuge. zb 10 Zeichen in Puffer schreiben TX anstossen durch Direkteinschreiben des 1sten zeichens Warten ob ISR dann alle 10 Zeichen richtig ausgibt. ISR als Ok abhaken, weiter bei putchar() machen.- Ich werde mir nochmwas was durhclesen wie man diese beiden Fälle abfängt.
Christian J. schrieb: > Ist mir klar Offensichtlich nicht. > #define BUF_SIZE 128 > int8_t buf[BUF_SIZE+1]; Es reicht nicht, den Puffer eins grösser zu definieren. Du musst die "Puffer voll" Abfrage passend gestalten. Ausserdem bringt es nichts, den Puffer 129 Bytes gross zu machen, wenn du dank einer Maske von 0x7F grundsätzlich das letzte Bytes unbenutzt lässt. Entweder Du suchst im Internet nach diesem Verfahren und schreibst es passend ab, ohne unverstandendenen Code kreativ zu optimieren. Oder Du versuchst den Kram zu verstehen. Ja, man muss bei diesem Verfahren etwas nachdenken. Die intellektuell anspruchslosere Methode ist eine Variable, die angibt, wieviele Bytes im Puffer gefüllt sind. Die taugt an beiden Enden, also n==0 für "leer" und n==N für "voll". Ist aber nicht frei von race conditions, muss also mit Sperre arbeiten. Ausserdem gibts eine kleine Falle bei N==256.
:
Bearbeitet durch User
A. K. schrieb: > Die intellektuell > anspruchslosere Methode ist eine Variable, die angibt, wieviele Bytes im > Puffer gefüllt sind Das werde ich mal einbauen, da recht einfach. Der RX Buffer klappt übrigens einwandfrei, direkt von Anfang an. Aber der wird auch immer schneller gelesen als er beschrieben werden kann.
1 | char getchar() |
2 | { |
3 | register char ch; |
4 | |
5 | // Bei Überlauf alles resetten, Buffer wertlos |
6 | if (rx.f_buf_overflow) { |
7 | init_buffer(); |
8 | return (0); |
9 | } |
10 | |
11 | // Warte solange bis ein Zeichen im Buffer ist, auch ewig. |
12 | while (!rx.f_buf_full); |
13 | // Zeichen auslesen |
14 | ch = rx.buf[rx.rd_ptr]; |
15 | // Read Pointer am Array Ende zurück setzen |
16 | rx.rd_ptr = (rx.rd_ptr +1) & rx.mask; |
17 | // Alle Zeichen gelesen? |
18 | rx.f_buf_full = (rx.rd_ptr == rx.wr_ptr) ? false : true; |
19 | |
20 | return(ch); |
21 | } |
void int_sti_receive_buffer_full(void) __interrupt // geprüft = ok { register uint8_t zeichen; zeichen = STI_UDR; // Zeichen abholen if (!rx.f_buf_overflow) { SetLedByte(zeichen); // Zeichen auf LED rx.buf[rx.wr_ptr] = zeichen; rx.wr_ptr = (rx.wr_ptr +1) & rx.mask; // Rotieren rx.f_buf_overflow = (rx.wr_ptr == rx.rd_ptr) ? true : false; rx.f_buf_full = true; // Meldung } EI; } [code]
So klappt es einwandfrei im ersten Schuss
1 | void putchar(char c) |
2 | { |
3 | static counter1 = 0; |
4 | |
5 | // Warte bis TX frei für neues Zeichen ist |
6 | //while ((STI_TSR & 0x80) == 0); |
7 | //STI_UDR = c; |
8 | |
9 | CLI; |
10 | // TX Hardware ist leer |
11 | if (tx.f_idle) { |
12 | // Byte direkt einschreiben |
13 | tx.f_idle = false; |
14 | STI_UDR = c; |
15 | EI; |
16 | } else |
17 | { |
18 | // Byte muss in den Puffer rein... |
19 | EI; |
20 | SetLedByte(counter1++); |
21 | while (tx.bytes_to_send >= (BUF_SIZE-1)); // TX sendet noch. Warte bis Buffer frei..... |
22 | CLI; |
23 | tx.buf[tx.wr_ptr] = c; |
24 | tx.wr_ptr = (tx.wr_ptr +1) & tx.mask; // wr+1 am Bufferende auf 0 zurücksetzen |
25 | tx.bytes_to_send++; |
26 | } |
27 | |
28 | |
29 | |
30 | } |
1 | void int_sti_transmit_buffer_empty(void) __interrupt |
2 | { |
3 | static counter1 = 0; |
4 | static counter2 = 0; |
5 | |
6 | // Sind noch Zeichen im TX Buffer? |
7 | if (tx.bytes_to_send-- != 0) { // ja..... |
8 | SetLedByte(counter1++); |
9 | STI_UDR = tx.buf[tx.rd_ptr]; // Byte einschreiben |
10 | tx.f_idle = false; // TX aus |
11 | tx.rd_ptr = (tx.rd_ptr +1) & tx.mask; // Read Pointer rollen |
12 | } |
13 | else |
14 | { // nein, letztes zeichen ging grad raus |
15 | SetDigit(counter2++); |
16 | tx.f_idle = true; // TX aus |
17 | } |
18 | |
19 | EI; |
20 | |
21 | } |
Christian J. schrieb: > { > // Byte muss in den Puffer rein... > EI; ... > CLI; > tx.buf[tx.wr_ptr] = c; > tx.wr_ptr = (tx.wr_ptr +1) & tx.mask; // wr+1 am Bufferende > auf 0 zurücksetzen > tx.bytes_to_send++; > } Fehlt da nicht was?
:
Bearbeitet durch User
Christian J. schrieb: > if (tx.bytes_to_send-- != 0) { // ja..... ... > } > else > { // nein, letztes zeichen > ging grad raus > SetDigit(counter2++); > tx.f_idle = true; // TX aus > } Welchen Wert hat nun tx.bytes_to_send, wenn er vorher 0 war?
Du, hier ist grad alles im Ar...... ich kümmere mich da später drum. Bevor ich mir jetzt aber den Wolf suche werde ich die Version von gestern wieder einspielen aus dem Backup und das Neue draufsetzen.
Hi, nach so ca 2h lief es dann...... nachdem ich etwas gefunden hatte, was das Indianerauge übersah.... mich erst eine Debugausgabe der Variablen auf den Pfad brachte....wer findet den Unterschied?
1 | // Löscht den TX Buffer und setzt Zeiger auf 0 |
2 | void init_buffer() |
3 | { |
4 | // RX.... |
5 | rx.wr_ptr = 0; |
6 | rx.rd_ptr = 0; |
7 | rx.bytes_to_read = 0; |
8 | rx.f_buf_overflow = false; |
9 | rx.mask = (BUF_SIZE-1) & 0xff; |
10 | |
11 | // TX..... |
12 | tx.wr_ptr = 0; |
13 | tx.rd_ptr = 0; |
14 | tx.bytes_to_send = 0; |
15 | tx.f_idle = true; |
16 | tx.mask = (BUF_SIZE-1) & 0xff; |
17 | } |
1 | // Löscht den TX Buffer und setzt Zeiger auf 0 |
2 | void init_buffer() |
3 | { |
4 | // RX.... |
5 | rx.wr_ptr = 0; |
6 | rx.rd_ptr = 0; |
7 | rx.bytes_to_read = 0; |
8 | rx.f_buf_overflow = false; |
9 | rx.mask = (BUF_SIZE-1) & 0xff; |
10 | |
11 | // TX..... |
12 | tx.wr_ptr = 0; |
13 | tx.rd_ptr = 0; |
14 | tx.bytes_to_send = 0; |
15 | tx.f_idle = true; |
16 | rx.mask = (BUF_SIZE-1) & 0xff; |
17 | } |
Wenn man die bytes_to_send auf die LED Zeile abbildet kann man sehr schön sehen wieder Buffer beim Schreiben voll wird und sich durch den Interupt danach wieder leert.
1 | void int_sti_transmit_buffer_empty(void) __interrupt |
2 | { |
3 | // Sind noch Zeichen im TX Buffer? |
4 | if (tx.bytes_to_send > 0) { // ja..... |
5 | STI_UDR = tx.buf[tx.rd_ptr]; // Byte einschreiben |
6 | tx.rd_ptr = (tx.rd_ptr +1) & tx.mask; // Read Pointer rollen |
7 | tx.bytes_to_send--; |
8 | SetLedByte(tx.bytes_to_send); |
9 | tx.f_idle = false; |
10 | } |
11 | else |
12 | // nein, letztes Zeichen ging grad raus |
13 | tx.f_idle = true; |
14 | |
15 | EI; |
16 | |
17 | } |
@A.K.: Alles fertig .....Monitor komplett, EPROM randvoll mit mcurses und hexedit, weil der sdcc ja keinen dead code raus wirft. Andererseits muss der Monitor wirklich nicht gross sein, glaube meiner ist schon etwas überladen....
...na also geht doch. Unterschied ist rx.mask.. Wenn man den Basic Interpreter weg läßt hast Du einen durchaus üblichen Funktionsumfang. Die Frage ist, was dieser Hex-Monitor umfaßt. Gruß, Holm
Der Hex Dump stammt ja von Frank Mk hier und ist ganz nützlich wenn man mal schauen will wie das geladene Programm so liegt, wo der Stack und die Variablen etc. Volle Funktion eines Hex Editors eben. Den Basic Interpreter kriege ich natürlich nicht mehr rein, dann platzt das EPROM, was bis auf 300 Bytes jetzt auch voll ist. Der Monitor kann von einem Skript aus gesteuert werden wenn man echo -n- -e "...\r" verwendet. Das nutze ich um die Load Sequenz zu vereinfachen, die auch nicht unbedingt in Intel Hex vorliegen muss. Dateilaenge übertragen, Datei, "start" Befehl dazu und schon rennt es los. Ein druck auf die NMI Taste und er resettet sich wieder in den Monitor, sonst bewirkt Reset Neustart des RAM Programmes .... ja, ein bisschen Z80 Assembler habe ich ja gelernt :-)
1 | ld sp,#stack ;; Stack an Spitze des RAM legen |
2 | |
3 | ; Teste ob Userprogramm im RAM vorhanden (nur bei EPROM Version) |
4 | ;ld a, (ram_prog) ; Lade Start des RAM 0x2000 |
5 | ;cp #0xC3 ; vergleiche mit "C3" = JP Befehl |
6 | ;jp Z, ram_prog ; Ja, dann springe direkt ins Ram hinein |
7 | |
8 | ; Ram ausnullen (auskommentieren, wenn von PC Upload erfolgt) |
9 | ;xor a ; clear a and carry |
10 | ;ld bc,#0xdfff ; ram size left |
11 | ;ld hl,#0x2000 ; starting from 2000 |
12 | ;ld de,#0x2001 |
13 | ;ld (hl),a ; 0 -> (2000) |
14 | ;ldir ; (HL) -> (DE) |
Nettes Spielzeug das Ding und mit dem sdcc Compiler und einer kleinen HAL drüber lässt sich ne Menge machen. Übrigens ist der KC85 angekommen, mit Robotron Datasette und RAM Erweiterung..... gib mal Deine Adresse, dann geht er direkt durch....
Ein paar Worte zum Datenspeicher: Nachdem ich mir im Netz einiges über das XT/AT Computer IDE Interface durchgelesen habe stand für mich fest, dass das Thema sich erledigt hat. "Alles ganz easy...." >> Wesentlich primitiver als CF -> IDE -> Z80 Bus geht es kaum noch Wer mal einen Z80 Minirechner nachbaut sollte sich davon nicht einlullen lassen. Die IDE Register am Bus sind eine Sache und recht einfach zu mappen aber das IDE Protokoll an sich ist genug Lesestoff für eine Woche und dann ist noch immer keine Low Level Verwaltung für das Laufwerk geschrieben und erst recht keine High Level. Dann ist man nämlich recht schnell hier: http://www.retroleum.co.uk/z80-filesystem.html wo sich jemand aus lauter Not, weil FAT zum komplex ist ein eigenes Filesystem gestrickt hat. Wozu wenn es das alles schon als fertige Bausteine gibt? Ein in knapp einer Woche an einigen Abenden machbares Dateninterface um eine beliebige Reihe Binärdaten weg zu schreiben und wieder zurück zu lesen sieht bei mir jetzt so aus: - Atmega328 Controller - Arduino SD Library von Ardafruit mit 10 Basis Funktionen,ca 12 KB - SD Card Adapter mit CD4050 Level Shifter an SPI Bus des Atmega328 - Arduino IDE zur Codentwicklung auf einen nackten Atmega328 dessen ISP heraus geführt wurde. - RX/TX des 328er als Debug Interface Wenn man noch mehr Luxus haben will nimmt man einen Arduino Nano und steckt den wie ein IC in die Platine. Dann hat man gleich eine Debug Schnittstelle mit dabei und ein ISP. Anbindung an Z80 PIO über eine Software SPI (SDO, SDI, SCK, SS, WAIT). Da die Hardware SPI des Atmega bereits für die SD karte benutzt ist wird hier in Richtung Z80 PIO die Bitbang-Funktion "shiftin()" und shiftout() benutzt, zusammen mit dem SS Signal und einer extra WAIT Leitung für den Z80 SPI Master, da es aufwendiger ist eine Wait Funktion in Software zu machen. Die eigentliche Aufgabe besteht "nur" darin, die SD Library Funktionen welche man benötigt und das sind nur open, close, write, read, delete auf ein SPI Protokoll zu matchen. Dateinamen sind 1,2,3,4,5....viele. Ein Masterkommando vom Z80 sähe dann so aus: Master: <Write Command> <No of Data Bytes> <Data>.....<Data> <CRC> Master: <Read Command> <Filename> ........ Slave: <WAIT> ... <Data> <Data> ..... Master <get File Info> <File Name> Slave: <WAIT> ... <Data> <Data> ..... usw. Der AVR hat genug RAM Speicher (2K), um einen ganzen Datensatz vom Z80 in einem Rutsch zu übernehmen, um ihn dann als Ganzes wegzuschreiben, während er die Wait Leitung zieht. Eine Kenntnis des Atmega328 von innen ist nicht nötig, da die Arduino Lib die Hardware völlig abstrahiert, das Ganze ist nur durch Nutzug der High Level Funktionen machbar. Fangen wir mal an :-)
Das Standard OS das gerne Massenspeicher wie IDE Disks am Z80 hatte war CP/M und das realisierte das CP/M typische Dateisystem für logische Disks bis 8Mbyte, davon waren dann mehrere auf einer Platte möglich. Ich verstehe nicht, warum Du Dich ausgerechnet in der DOS Ecke herumtreibst und dort nach einem passenden FS suchst. Für CP/M gibts das Alles fertig und getestet (GIDE). Gru0, Holm
Christian J. schrieb: > (...) Die IDE Register am Bus sind eine Sache und recht einfach zu > mappen aber das IDE Protokoll an sich ist genug Lesestoff für eine Woche Was für ein Protokoll? Du beschreibst vier Register mit der Nummer des gewünschten Blocks, dann eins mit dem Kommando für lesen oder schreiben, und dann holst Du Dir 512 bytes Daten ab bzw schickst sie hin. Das ist wesentlich einfacher als das Gefummel mit einer SD-Karte oder einem NAND-Flash.
Zuerst habe ich mal ein Compilkerproblem gefunden, dass er seinen eigenen Code übeschreibt....
1 | ////////////////////////////////////////////// |
2 | // Ein Byte senden und empfangen |
3 | uint8_t spi_transmit(uint8_t data) |
4 | { |
5 | uint8_t mask,inbyte; |
6 | uint8_t i; |
7 | |
8 | STI_GPIP = STI_GPIP | SCLK; // Clock = HIGH |
9 | STI_GPIP = STI_GPIP & ~SS; // Slave Select LOW |
10 | //delay8(50); |
11 | |
12 | mask = 0b00000001; // Bit Maske, LSB zuerst |
13 | inbyte = 0; |
14 | ...... |
Kommentiert man das delay8(50) nämlich aus, was einwandfrei funktioniert passieren die tollsten Sachen, er killt entweder Daten oder programmcode.
1 | // Verzögerung |
2 | static void delay8(uint8_t cnt) { |
3 | volatile uint8_t k; |
4 | for (k=0;k<cnt;k++); |
5 | } |
Tja, also manchmal ist der sdcc etwas "seltsam". Stellt man dann etwas um, auch wenn es logisch das Gleiche wie vorher ist klappt es wieder. Schon einige Male solche "unerklärlichen Phänonomene" erlebt. In diesem Fall half es in die Warteschleife ein NOP in den Rumpf zu nehmen. Sieht schon ganz nett aus mit CPOL=1, CPHA=1 und 22 khz maximaler Rate.
Solche Fehler kenne ich auch von anderen Compilern und die haben i.A. nichts mit dem Compiler zu tun, sondern das der Stack nicht mehr stimmt weil Du irgendwas nicht aufgeräumt hast. Unter Unix gibts dann eine Speicherschutzverletzung.. Gruß, Holm
Moin, aktuell "Heavy Working on Project". Leider passt der Monitor nicht mehr in 8kb EPROM rein, mcurses haut sich leider zu viel weg und auch der Hexeditor frisst 1,8kb. Eine Kommunikation mit der SD karte haut nicht mehr hin, um von dort Anwenderprogramme zu laden. Abhilfe: 16KB EPROM und nur noch 48KB RAM. 48KB reicht auch finde ich. Schaltplan: Leitung A13 abklemmen. Input Pin 9 auf GND legen. 27128 EPROM, Leitung A13 zusätzlich an CPU Nur zur Sicherheit: Das wars doch? Wegen der Fädetechnik kann nichts umverdrahtet werden, nur abschneiden und neu legen. Sonst würde ich das ganze Gatter für A13, A14 herausnehmen und A14 und A15 auf das andere legen.
Ic würde mit an Deiner Stelle Gedanken um eine Urlademimik machen, die den gesamten ROM nach dem Reset in den RAM umlädt und diesen dann abschaltet. Damit ermöglichst Du Anwenderprogrammen den RAM der mit Monitorcode belegt ist nach Bedarf zu überschreiben, wenn das Programm beendet wird, ist nichts weiter nötig als den Urlademechanismus erneut anzustoßen und den Zustand vor dem Überschreiben des RAMs wieder her zu stellen. Auf diese Art und Weise funktionieren üblicherweise die meisten CP/M-fähigen Z80 Rechner, da die Anwenderprogramme auf eine Startadresse von 0x100 gebunden sind. der CCP und das BDOS sind nachladbare Programmteile und ganz oben im RAM residiert da BIOS und Systemvariablen wie Stack usw. Im Prinzip läßt sich das verwirklichen in dem nach Reset beim Lesen das ROM, beim Schreiben aber das RAM selektiert wird, nach erfolgtem Umladen des ROM Inhaltes wird dann ein Flipflop gekippt, das den ROM vollständig deselektiert und den RAM fest einschaltet. Ein Reset kippt die Mimik zurück. Ich weiß nicht ob Du das in Deinem Fitz noch unterbringen kannst, aber das hatte ich wohl schon mal "zeitig genug" erzählt.. RAM ist durch Nichts zu ersetzten, außer durch noch mehr RAM. Gruß, Holm
Das TDL-Basic gibt es auch als TDLBAS.REL. D.h. man kann es auf eine bestimmte Adresse relozieren. Ich habe mir einen "Reolzierer" in vb.net geschrieben. Das scheint (bin mal vorsichtig) zu funktionieren. Mein Basic liegt ab 4000h im ROM, RAM ist wie original (ab 100h). [[http://www.mikrocontroller.net/articles/ZAtmel:_ein_minimalistisches_Z80-System]]
Hi, da lässt sich nix mehr umverdrahten, das ist endgültig bei dem Brett. Nächster Wuirf vielleicht. Habe jetzt 16kb und das klappt ganz gut, mehr Platz für das OS.
Ein kompletter CPM rechner in dem fast 2 Jahre Arbeit stecken laut Autor ist hier dokumentiert: http://searle.hostei.com/grant/cpm/index.html Eine Unmenge an Anpassungen mussten da gemacht werden an das original BDOS. Wäre mal eine Sache den eingfach nur stur nachzubauen, 1-2 Wochen Einarbeitung müssten sicher reichen..
Da findest du in U7.C+D die mehrfach erwähnte ROM/RAM-Umschaltung. Allerdings komplizierter als nötig, die Adressdekodierung über U6.C+D wäre nicht nötig (ROM lesen / RAM schreiben reicht aus). Edit: Die Dekodierung ist sogar ungünstig. Wenn man sie weglässt, im ROM sofort unabhängig von der ROM-Grösse die gesamten(!) 64KB auf sich selbst kopiert und dann auf RAM umschaltet, dann landet das BIOS direkt aus dem ROM an passender Stelle im RAM und kann angesprungen werden.
:
Bearbeitet durch User
Steffen S. schrieb: > Das TDL-Basic gibt es auch als TDLBAS.REL. D.h. man kann es auf eine > bestimmte Adresse relozieren. Ich habe mir einen "Reolzierer" in vb.net > geschrieben. Den Begriff hab ich noch nie gehört. Beim aussprechen bricht man sich ja die Zunge. Erklär mal näher. Steffen S. schrieb: > Das scheint (bin mal vorsichtig) zu funktionieren. Mein Basic liegt ab > 4000h im ROM, RAM ist wie original (ab 100h). Das ist gleich ob ROM oder RAM. Wichtig ist die CP/M Sprungtabelle ab 100H.
Moin, nur kurz zum Verstehen: 1. Rechner startet aus dem Bios. Da Z80 immer bei 0x0000 anfängt muss bei 0x0000 ROM zu finden sein 2. Urlader zieht sich das OS rein ins RAM und springt dorthin. Er sieht entweder ROM oder RAM, d h. ein Kopiervorgang ins drunter liegende RAM ist so nicht mögllich, es sei denn dass jeder Schreibzugriff umgeleitet wird auf RAM indem die WR Leitung mit decodiert wird. Dann würde eine Kopierroutine das ROM ins RAM kopieren können, danach umschalten und fertig. Ok? Übrigens: Hat jemand eine Kauf Eagle Version? Ich würde den Z80 Rechner für CPM gerne auf richtiger Platine machen.
Christian J. schrieb: > nur kurz zum Verstehen: Das geht so: Startphase, Flipflop ausgelöst durch Cold Reset: Memory Read => ROM, adressunabhängig, Memory Write => RAM, adressunabhängig. Betriebsphase, Flipflop umgeschaltet per I/O Zugriff: Memory Read => RAM, adressunabhängig, Memory Write => RAM, adressunabhängig. Reset: Kopiere 64KB von Adresse 0 nach Adresse 0, damit wird also beim Cold Reset das ROM exakt 1:1 ins RAM kopiert und beim Warm Reset das RAM exakt 1:1 auf sich selbst. Schalte danach per IO-Zugriff auf Betriebsphase. Da im RAM die 1:1 Kopie vom ROM steht, ggf. mit ein paar gespiegelten Kopien, geht es im Code nahtlos weiter, nur kommt der nächste Befehl dann aus dem RAM statt aus dem ROM. Für CP/M setzt das voraus, dass 64KB RAM vorhanden sind. CP/M erwartet sein BIOS am oberen Ende des Adressraums. Dort liegt unabhängig von der Grösse des ROMs garantiert immer das hintere Ende vom ROM-Inhalt, sofern du nicht den Fehler machst, das ROM adressmässig einzuschränken. Wenn das BIOS also fertig entwickelt ist und ins ROM passt, dann ist nach diesem Blocktransfer nur noch ein Sprung an die entsprechende BIOS-Adresse nötig.
:
Bearbeitet durch User
Ok, verstanden. Die Decodierung hälst du also für unnötig? Irgendwie muss man ja aber umschalten. Ich habe mir diesen Rechner angeschaut, was mir etwas fehlt ist die peripherie, also Ports, Timer und andere Spielsachen. So ist das ja nur ein Rechner der Software verarbeiten kann aber nichts steuern. CPM kann damit sicher nichts anfangen. Es stellt sich dann auch die Frage wie man eigene programme entwickelt denn mit dem sdcc wird das wohl kaum mehr gehen. Die müssen ja "für CPM sein". Ist das also nur ein Spielzeug um mal wieder CPM Software zu fahren? Diese RAM Umschaltung hätte ich bei meinem auch machen sollen vorher. Wäre easy gewesen: 1: Monitor lädt Programm vom PC 2. Monitor kopiert Programm "unter sich" ab 0x0000 3. Monitor schaltet um um löst Soft reset für 0x0000 aus 4. User programm rennt los und hat 64k für sich.
Christian J. schrieb: > 1. Rechner startet aus dem Bios. Da Z80 immer bei 0x0000 anfängt muss > bei 0x0000 ROM zu finden sein Nicht zwingend. Beim KC85/3 und Konsorten, gibt es eine Bootstrap-Schaltung. Dort liegt das BIOS bei 0xE000. Bei Reset wird für ein paar M1-Zyklen dieser Bereich nach 0x0000 gemappt. Als erstes steht ein Jump in den 'richtigen' ROM. Das Mapping wird nach diesem Jump deaktiviert. Also ja und nein. Es wird bei 0x0000 angefangen, aber es muß nicht zwingend ein ROM dort sitzen. Es reicht, wenn die ersten Memread auf dem Bus 0xC3 0xll 0xhh vorfinden, um von einer anderen Adresse zu starten. > 2. Urlader zieht sich das OS rein ins RAM und springt dorthin. [...] Genau. > Übrigens: Hat jemand eine Kauf Eagle Version? Wenn es größer als 80 x 100 mm wird, verwende ich (privat) KiCad. Es ist zwar noch etwas kryptischer als Eagle zu bedienen, aber alles in allem recht brauchbar und nicht irgendwie limitiert. Jens
Christian J. schrieb: > Die Decodierung hälst du also für unnötig? Irgendwie muss man ja aber > umschalten. Durch einen passenden IO-Zugriff. Das kann auch ein Zugriff auf den ADC sein, wenn dein IO-Dekoder nichts mehr frei haben sollte. > 2. Monitor kopiert Programm "unter sich" ab 0x0000 Das setzt voraus, dass alle Schreibzugriffe im RAM landen. Auch die auf dem Adressbereich des ROM. Technisch kein Problem, Umbau ist einfach.
Christian J. schrieb: > So ist das > ja nur ein Rechner der Software verarbeiten kann aber nichts steuern. > CPM kann damit sicher nichts anfangen. Das hängt von den CP/M-Programmen ab. Es gibt relativ viele, nur das Minimalsystem (Console-IO und Disk-IO) brauchen: TurboPascal, WordStar, Microsoft Basic, dBase, Zork etc. pp. > Es stellt sich dann auch die > Frage wie man eigene programme entwickelt denn mit dem sdcc wird das > wohl kaum mehr gehen. Die müssen ja "für CPM sein". Richtig. Reichen Dir die Entwicklungswerkzeuge, die hier unter Programming aufgeführt sind?: http://pcsauro.altervista.org/CPM.PHP Jens
Christian J. schrieb: > Frage wie man eigene programme entwickelt denn mit dem sdcc wird das > wohl kaum mehr gehen. Kannst es mit PL/I versuchen. ;-) War ein recht bemerkenswertes Produkt. > Die müssen ja "für CPM sein". Nur wenn du auf dem Zielsystem entwickeln willst. Cross-Development auf dem PC mit sdcc geht natürlich immer noch.
Jens schrieb: > Beim KC85/3 und Konsorten, gibt es eine Bootstrap-Schaltung. Dort liegt > das BIOS bei 0xE000. Bei Reset wird für ein paar M1-Zyklen dieser > Bereich nach 0x0000 gemappt. Als erstes steht ein Jump in den > 'richtigen' ROM. Das Mapping wird nach diesem Jump deaktiviert Na, man will ja auch Software schreiben und wenn es kompliziert ist diese auf den Rechner zu kriegen, dann macht es keinen Spass. Ich frage mich auch grad wofür man CPM braucht wenn man keine Peripherie hat, keine Tastatur, keinen Monitor. Als ich so 16 war fing es mit dem Apple 2 an, da war das OS ein blinkender Cursor, es gab ein besch.... Basic und ein paar Format Befehle. Nichts was man wirklich damit machen konnte. Mehr als UCSD Pascal hat der 2e, den wir hatten nie gemacht und auf dem "Basis 108" lief ein Stundenplan Planungsprogram, was die Lehrer auf die Klassen aufteilte. Dauerte Tage bis das fertig war. Klar weiss ich, dass ich das alles besser und schöner mit einer IDE auf meinem ARM7 Board haben kann, Luxus Debugger, GCC, Crossworks IDE dabei und schneller, 80Mhz, mehr Ports, mehr Timer ..... aber das Z80 Minisystem macht mehr Spass und es ist überschaubarer, grünes Terminal, 9600 baud ..... eben Retro :-) fehlt nur noch das Fiepen für die 9600 baud. Zerbreche mir noch den Kopf wie ich 2 Software SPI miteinander verheiraten kann, die im Arduino und die auf dem Z80. Das könnte verdammt eng werden vom Timing her, der Slave (Ardu) muss deutlich schneller sein als der Z80 beim Datenempfang.
A. K. schrieb: > Technisch kein Problem, Umbau ist > einfach. Bei Fädeltechnik ist nix mehr mit Umbau :-) Bin froh, dass ich den 16kb ROM Umbau geschafft habe, 2 Drähte abknipsen, 3 neue verlegen. Ende. Kein draht geht mehr raus und nur noch wenige rein.
Christian J. schrieb: > keine Tastatur, keinen Monitor. CP/M funktioniert auch über die serielle Schnittstelle, und die ist in seinem Teil drin (mit SIO ;-). Der PC stellt Tastatur und Bildschirm.
A. K. schrieb: > CP/M funktioniert auch über die serielle Schnittstelle, und die ist in > seinem Teil drin (mit SIO ;-). Der PC stellt Tastatur und Bildschirm. habe mir grad die Softwaresammlung angechaut.....Wahnsinn. Turbo Pascal würde mich mal wieder reizen. Andererseits muss der Bau Zeitraum überschaubar bleiben. Wenn es erst ein halbes Jahr dauert, bis das System überhaupt Piep sagt lohnt es nicht. Dieser Searle hatr aber alles gut dokumentiert, d.h. Nachbau 1:1 dürfte möglich sein. Software läuft ja soweit wie ich das sehe. Er selbst hat 2 Jahre gebraucht wie er schrieb. Dummerweise finde ich die Eagle Files nirgendwo, müsste also abzeichnen.
@AK: Überlege die ganze zeit noch für eine sinnvolle SPI Übertragung wegen der SD Karte. Selten sowas benutzt bisher. Wie sind den Protokolle allgemein aufgebaut? Arbeiten die auch mit Start Token, warten auf Antwort usw? Es gibt unzählige Möglichkeiten. Ich tendiere fast dazu einen Header für den Datensatz in einen Struct zu packen, den Header dann stur zum Slave zu ballern und der sucht sich dann die Eckedaten heraus, wieviele Bytes kommen, Filenamen, File Descriptor (1,2,3....). Filenamen will ich schon haben, Catalog Funktion auch, Sichern und Laden. #define CMD_WR 'W' // Token für Daten schreiben #define CMD_RD 'R' // Token für Daten lesen #define CMD_HEAD 'H' // Token für Daten Header #define DUMMY 0xff #define RES_ACK 'A' // Response für "OK" #define RES_WAIT 'T' // Response für "Warte!" #define RES_ERR 'E' // Response für "Warte!" //////////////////////////////////////////////////////////// // sd_write_data // // Schreibt einen Datensatz auf die SD Karte // Eingabe: file = filenummer 1..255 // *filename = Zeiger auf Filename // *data = Zeiger auf Daten // len = Länge der Daten in Bytes // Rückgabe: 1 = ok, 0 = fehler char sd_write_data(char fileno, char* filename, char* data, uint16_t len) { uint16_t i,cnt; uint8_t resp; // Antwort des Slaves // Slave aktivieren sd_select(true); delay8(100); // Start Token senden spi_transmit(CMD_WR); delay8(100); // Filenummer und Länge des Datensatzes senden spi_transmit(CMD_HEAD); spi_transmit(fileno); spi_transmit(HIBYTE(len)); spi_transmit(LOBYTE(len)); delay8(100); // Ganzen Datensatz senden cnt = 0; for (i=0;i<len;i++) { while(spi_get_wait()); // WAIT vom Slave? SetLedByte(*data); resp = spi_transmit(*(data++)); // WAIT vom Slave? if (resp==RES_ERR) // Slave ok? return (0); } delay8(50); sd_select(false); return (1); }
A. K. schrieb: > Für CP/M setzt das voraus, dass 64KB RAM vorhanden sind. > CP/M erwartet sein BIOS am oberen Ende des Adressraums. Normalerweise definiert man die Speichergröße (MSIZE). Daraus ergeben sich dann das Ende des gültigen Adressraums und die Adressen von CCP, BDOS und BIOS. Bei mir lebt alles in nur 32 KB, die Mindestanforderung von CP/M 2.2 sind 20 KB. Ein Adressraum voller RAM macht Dinge natürlich trotzdem einfacher. Christian J. schrieb: > Die Decodierung hälst du also für unnötig? Irgendwie muss man ja aber > umschalten. Das kann im Zweifelsfall der allererste I/O-Zugriff sein, egal zu welcher Adresse, oder ein Gerät mit einem steuerbaren Pin (z.B. die serielle Schnittstelle - ein 16550 hat zwei Ausgänge). > Es stellt sich dann auch die Frage wie man eigene programme entwickelt > denn mit dem sdcc wird das wohl kaum mehr gehen. Die müssen ja "für CPM > sein". Warum sollte das nicht gehen? Ein CP/M-Programm ist ein an 0x100 gelinkter Haufen Bytes, der über eine festgelegte Schnittstelle (JMP auf fixe Adressen) mit dem Betriebssystem redet. Wenn du die entsprechenden Syscalls dem SDCC beibringst, kannst du auch mit dem arbeiten. Ansonsten gibt es die ganze Software von damals immernoch. > Ist das also nur ein Spielzeug um mal wieder CPM Software zu fahren? Davor schriebst du noch, das ginge ohne Ports oder Timer nicht ginge. Geht also doch. ;-) > Diese RAM Umschaltung hätte ich bei meinem auch machen sollen vorher. Ist ja nicht so, dass das jetzt eine neue Information wäre. Aber du hörst ja nie zu. Christian J. schrieb: > Wie sind den Protokolle allgemein aufgebaut? Arbeiten die auch mit Start > Token, warten auf Antwort usw? Es gibt unzählige Möglichkeiten. Das Protokoll zwischen Z80 und "SD-Karten-Controller"? Das kannst du dir beliebig aussuchen. Mir fallen da drei Möglichkeiten ein, wenn es um die SD-Karte geht: (a) Der Arduino ist eine SPI-Bridge. Dein Protokoll muss dann "read", "write" und Chipselect für jedes Gerät abbilden können. Auf dem Z80 kannst du dann jedes beliebige SPI-Gerät ansteuern, musst aber sowohl das SD-Protokoll als auch das Dateisystem auf dem Z80 implementieren. (b) Der Arduino spielt Block-Device. Dein Protokoll muss dann "read", "write" und "seek" abbilden können. Der Z80 muss dann nur das Dateisystem implementieren (CP/M bringt übrigens eins mit!) und kann über diese Schnittstelle auch nur auf SD-Karten zugreifen. FAT gibt's nur, wenn du auch FAT implementierst. (c) Der Arduino spielt File-Server. Dein Protokoll muss dann alle Dateisystemfunktionen abbilden können, die du möchtest (Datei oder Verzeichnis öffnen, schließen, lesen, schreiben, löschen, erstellen, ...) und der Z80 braucht dann diese Funktionen nur aufzurufen und die ganze Arbeit findet im Arduino statt. Für irgendwas davon musst du dich schon entscheiden. Über die Datenstrukturen nachzudenken bringt dich an der Stelle nicht wirklich weiter, solange du nicht weißt, was du brauchst und was nicht. Warum willst du dem Z80 überhaupt SPI in Software aufbürden? Der hat einen wunderbar schnellen, parallelen Bus mit genialen Zugriffsbefehlen. Übrigens wiederhole ich nochmal einen Vorschlag: Deine serielle Schnittstelle kann all das, was du willst, auch machen. Du musst dafür keine SD-Karte an dein System frickeln. Das Protokoll der Wahl dafür nennt sich ZMODEM.
S. R. schrieb: > Du musst dafür > keine SD-Karte an dein System frickeln. Das Protokoll der Wahl dafür > nennt sich ZMODEM. Hi, weiss ich aber ich implementiere kein ZMODEM auf dem Z80 Board, bzw schreibe ich sicherlich nicht selbst. Es wird ein Fileserver, der Ardu übernimmt alles, der Z80 hat nur 4 Befehle: write, read, seek, delete. Jede Datei hat vorne 64 Bytes "Header Infos" und danach die Daten. Header: - Dateityp (exe, dat) - Länge - Filenummer - Filename - File Description SPI Datentransfer ist auch 64 Bytes Header, danach justiert sich der Slave darauf, legt Datei an etc und nimmt Daten entgegen oder sendet sie. Arduino hat eine SD FAT light die nur ein Verzeichnis kennt und nur Basisfunktionen. Passt in 8k rein, der atmega328 hat 32k. Fiel mir so ein aber vielleicht gibt es ja sowas auch im "üblichen Rahmen". >Warum willst du dem Z80 überhaupt SPI in Software aufbürden? Der hat >einen wunderbar schnellen, parallelen Bus mit genialen >Zugriffsbefehlen. Hätte er...... wenn ich damals das wüsste was ich heute weiss.... der hat nämlich eine IDE on board quasi. CF Card direkt dran gepaoppt. Mein Bus ist s.o.
Habe mir das mal für zu hause geholt. Hoffe ich bereue es nicht: http://www.ebay.de/itm/271682004029
Christian J. schrieb: > Hoffe ich bereue es nicht: Da fehlen noch mindestens 8, besser 16 digitale Kanäle. Und selbst für analoges hab ich gern 4 statt 2.... ebay: 161313879775 oder: 181288566514 Beides zusammen gibt es sicher auch noch irgendwo. Jens
Christian J. schrieb: > wenn ich damals das wüsste was ich heute weiss Siehe: http://www.gutzitiert.de/zitat_autor_konfuzius_thema_handeln_zitat_1953.html
michael_ schrieb: > Den Begriff hab ich noch nie gehört. Beim aussprechen bricht man sich ja > die Zunge. Erklär mal näher. Sorry, habe mich vertippt. Meinte "relozieren" Macht normalerweiser ein Loader im Monitor. Da ich nur das TDL-Basic an eine andere Adresse haben wollte (nicht 300h sondern 4000h) habe ich ein kleines vb.net-Programm dafür geschrieben. Grundlage dafür: http://www.seasip.demon.co.uk/Cpm/rel.html
:
Bearbeitet durch User
Jens schrieb: > Christian J. schrieb: >> Hoffe ich bereue es nicht: > Da fehlen noch mindestens 8, besser 16 digitale Kanäle. > Und selbst für analoges hab ich gern 4 statt 2.... > > ebay: 161313879775 > oder: 181288566514 > > Beides zusammen gibt es sicher auch noch irgendwo. > > Jens Logic Analyser habe ich schon, einen für 25 Euro :-) Tuts aber. Nette Dinger aber Kohle fehlt für sowas.
@Leo: Sag mal, wie kommt es dass der sddc für eine einfache Zuweisung an eine Struct Variable dermassen ein Fass aufmacht? Der Compiler kennt doch die Adressen aller member? Structs sollen ja effizient sein aber hier eher das Gegenteil. Auch mit -> sieht es schlimm aus.
1 | Test normale Zuweisung, schön |
2 | |
3 | 302 ;sd.c:191: resp = fileno; |
4 | 46AE DD 7E 04 [19] 303 ld a,4 (ix) |
5 | 46B1 DD 77 B9 [19] 304 ld -71 (ix),a |
6 | |
7 | |
8 | Zuweisung von 8 Bit an Struct, waaaaas? |
9 | |
10 | 305 ;sd.c:192: file.no = fileno; // Filenummer |
11 | 46B4 21 03 00 [10] 306 ld hl,#0x0003 |
12 | 46B7 39 [11] 307 add hl,sp |
13 | 46B8 4D [ 4] 308 ld c,l |
14 | 46B9 44 [ 4] 309 ld b,h |
15 | 46BA 21 0A 00 [10] 310 ld hl,#0x000A |
16 | 46BD 09 [11] 311 add hl,bc |
17 | 46BE DD 56 04 [19] 312 ld d,4 (ix) |
18 | 46C1 DD 7E 04 [19] 313 ld a,4 (ix) |
19 | 46C4 17 [ 4] 314 rla |
20 | 46C5 9F [ 4] 315 sbc a, a |
21 | 46C6 5F [ 4] 316 ld e,a |
22 | 46C7 72 [ 7] 317 ld (hl),d |
23 | 46C8 23 [ 6] 318 inc hl |
24 | 46C9 73 [ 7] 319 ld (hl),e |
25 | 320 ;sd.c:193: file.len = len; // Datenlänge |
26 | 46CA 21 06 00 [10] 321 ld hl,#0x0006 |
27 | 46CD 09 [11] 322 add hl,bc |
28 | 46CE DD 7E 0B [19] 323 ld a,11 (ix) |
29 | 46D1 DD 77 FC [19] 324 ld -4 (ix),a |
30 | 46D4 DD 7E 0C [19] 325 ld a,12 (ix) |
31 | 46D7 DD 77 FD [19] 326 ld -3 (ix),a |
32 | 46DA DD 36 FE 00 [19] 327 ld -2 (ix),#0x00 |
33 | 46DE DD 36 FF 00 [19] 328 ld -1 (ix),#0x00 |
34 | 46E2 C5 [11] 329 push bc |
35 | 46E3 EB [ 4] 330 ex de,hl |
36 | 46E4 21 45 00 [10] 331 ld hl, #0x0045 |
37 | 46E7 39 [11] 332 add hl, sp |
38 | 46E8 01 04 00 [10] 333 ld bc, #0x0004 |
39 | 46EB ED B0 [21] 334 ldir |
40 | 46ED C1 [10] 335 pop bc |
Und noch eine Sache: Es ist leider so, dass gleiche Routinen sich sowohl im ROM als auch im Userprogramm finden, zb die Hardware Inits, Kommunikation usw. Gibt es mit einem C Compiler irgendeine Möglichkeit aus einem RAM Programm heraus Routinen im ROM anzuspringen? Der Variablenbereich des ROM ist unangetastet, der liegt unter der Decke bei B0000, 2K sind reserviert. Sowas wie function lala (char.....) @ ROM-Adresse Die Einsprünge kenne ich ja alle aus den .rst Files.
typedef int (*PtrToFunctionTakingCharReturningInt)(char); #define lala ((PtrToFunctionTakingCharReturningInt)0x1234)
> Gibt es mit einem C Compiler irgendeine Möglichkeit aus einem RAM > Programm heraus Routinen im ROM anzuspringen? Der Linker hat einen Schalter, mit dem das möglich sein sollte:
1 | -o Linked file/library object output enable (default) |
2 | -v Linked file/library object output disable |
3 | ... |
4 | The linker commands are explained in some more detail: |
5 | ... |
6 | 5. -o/-v Specifies that subsequent linked |
7 | files/libraries will generate object output (default) |
8 | or suppress object output. (if option -i, -s, or -t |
9 | was specified) |
Also erst das ROM-Programm normal compilieren und linken. Dann die Funktionen für RAM-Progamm compilieren, und beim Linken nach dem Schalter -v die Object-Dateien der referenzierten ROM-Teile listen.
Hi, klingt schwierig. ROM und RAM Programm sind zwei unterschiedliche Projekte, die nichts miteinander zu tun haben bisher. In Assembler wäre das kein Thema, wäre nur Register laden und JP dahin. Das RAM Programm müsste ja genau wissen wie es Parameter an eine ROM Funktion übergeben müsste, die es ja nicht kennt. zb: Monitor Programm hat: void delay(zeit) { ..... } Adresse ist bekannt und fix im EPROM, bzw lässt sich herausfinden. zb 0x1234 Das RAM Programm will nun diese Funktion nutzen.... und da scheiden sich die Geister.
@Leo: Ich lege das problem oben erstmal beiseite. Fällt Dir eine Mögliochkeit ein, wie man zur Laufzeit feststellen kann, wie gross ein Programm in Bytes ist? Oder wie man eine Kennung hinten am Code anbringt, so dass man aus dem laufenden Programm feststellen kann, wieviele Bytes man auf die SD sichern muss? Leider hat der Z80 keinen internen E2PROM wie die AVR, PIC, ARM usw :-(
> Fällt Dir eine Mögliochkeit > ein, wie man zur Laufzeit feststellen kann, wie gross ein Programm in > Bytes ist? Der Compiler generiert für jede Funktion Symbole in der Form _functionname_start und _functionname_end Also vielleicht sowas?
1 | #include <stdio.h> |
2 | |
3 | extern main_start(), main_end(); |
4 | |
5 | int main(void) |
6 | {
|
7 | printf("main start: %04x\n" |
8 | "main end: %04x\n" |
9 | "main size: %04x\n", |
10 | main, main_end, (void *) main_end - (void *) main); |
11 | |
12 | return 0; |
13 | }
|
main_start braucht man nicht, da es ja das gleiche wie main ist. Ich kanns nicht laufen lassen, aber das Ergebnis sieht ganz gut aus:
1 | 48 ; Function main |
2 | 49 ; --------------------------------- |
3 | 0113 50 _main_start:: |
4 | 0113 51 _main: |
5 | 52 ;hello.c:11: main, main_end , (void *) main_end - (void *) main); |
6 | 0113 21 34 01 [10] 53 ld hl,#_main_end |
7 | 0116 11 13 01 [10] 54 ld de,#_main |
8 | 0119 BF [ 4] 55 cp a, a |
9 | 011A ED 52 [15] 56 sbc hl, de |
10 | 57 ;hello.c:10: "main size: %04x\n", |
11 | 011C 11 34 01 [10] 58 ld de,#___str_0+0 |
12 | 011F E5 [11] 59 push hl |
13 | 0120 21 34 01 [10] 60 ld hl,#_main_end |
14 | 0123 E5 [11] 61 push hl |
15 | 0124 21 13 01 [10] 62 ld hl,#_main |
16 | 0127 E5 [11] 63 push hl |
17 | 0128 D5 [11] 64 push de |
18 | 0129 CD 94 01 [17] 65 call _printf |
19 | 012C F1 [10] 66 pop af |
20 | 012D F1 [10] 67 pop af |
21 | 012E F1 [10] 68 pop af |
22 | 012F F1 [10] 69 pop af |
23 | 70 ;hello.c:13: return 0; |
24 | 0130 21 00 00 [10] 71 ld hl,#0x0000 |
25 | 0133 C9 [10] 72 ret |
26 | 0134 73 _main_end:: |
Einfacher in der crt0.s :-) Muss man erstmal drauf kommen. gsinit: ; Initialisiere globale Variablen im RAM ld bc, #l__INITIALIZER ld a, b or a, c jr Z, weiter ld de, #s__INITIALIZED ld hl, #s__INITIALIZER ldir weiter: ; // Hier muss ein ret rein .area _GSFINAL ret ;Markiert das Ende des Programmes .ascii "FINAL" Das Wort FINAL steht direkt nach dem CODE Segment. Beim Start des Programmes suche ich danach. Jetzt würde nur noch ein Assemblerbefehl fehlen, der ein Alignment auf zb 16 Bytes vornimmt, damit ich den Suchlauf schneller machen kann, nämlich nur auf das erste von jeweils 16 Bytes auf F testen und dann gleich +16 Bytes weiter. SPI etc läuift schon im Trockendock..... tolles Maschinchen :-) Mit dem sdcc macht es erst richtig Spass.
> Einfacher :-) Na, Du wirst doch nicht behaupten, daß eine Suchschleife einfacher als die Subtraktion zweier Symbole ist. Und wenn die Code-size einer einzelnen Funktion nicht das Gewünschte ist, dann suchst Du dir halt die passenden Symbole aus der Mapfile raus. > Das Wort FINAL steht direkt nach dem CODE Segment. Beim Start des > Programmes suche ich danach. Aber nur, wenn Du es extra hinschreibst. Das braucht auch zusätzlichen Platz. Stattdessen kanns Du auch das Symbol "s__GSFINAL" nehmen. > Jetzt würde nur noch ein Assemblerbefehl fehlen, der ein Alignment auf > zb 16 Bytes vornimmt, damit ich den Suchlauf schneller machen kann, Dann brauchst Du Dir über sowas auch nicht den Kopf zu zerbrechen. Du hast sowieso andere Probleme, als die Geschwindigkeit so einer kleinen Schleife. :-)
Leo C. schrieb: > Na, Du wirst doch nicht behaupten, daß eine Suchschleife einfacher als > die Subtraktion zweier Symbole ist Ich weiss nicht was du da vorhast aber wo die Module stehen hängt nur davon ab in welcher Reihenfolge man sie linkt. Und die genannten Symbole erzeugen nur "kennt er nicht" Fehlermeldungen. ich brauche das in sd.c, da ist _main nicht bekannt.
Christian J. schrieb: > Alignment auf zb 16 Bytes Den SDCC Assembler kenne ich nicht. Meiner macht das mit org (($ & 0xfff0) + 0x10)
Hallo Leo, deine Methoden da funktionieren alle nicht. Die Symbole sind nicht bekannt in den einzelnen Modulen. Ob mit oder ohne Unterstrich. Nur das hier funktioniert einwandfrei:
1 | // Suche das Codeende |
2 | __at (RAM_START) uint8_t ram[RAM_SIZE]; // Bereich des RAM |
3 | uint16_t search_code_end() |
4 | { |
5 | _Bool hit; |
6 | uint16_t i; |
7 | |
8 | i = 0; |
9 | hit = false; |
10 | do { |
11 | if (ram[i]=='$') |
12 | if (ram[i+1]=='E') |
13 | if (ram[i+2]=='O') |
14 | if (ram[i+3]=='C') |
15 | hit = true; |
16 | i++; |
17 | } while (!hit || (i > 0xF000)); |
18 | |
19 | return(i+3+RAM_START); |
20 | |
21 | } |
> org (($ & 0xfff0) + 0x10)
Das funktioniert selten in relozierbaren Segmenten, und beim
SDCC-Assembler ist org in REL-Segmenten gleich ganz verboten.
Christian J. schrieb: > deine Methoden da funktionieren alle nicht. Die Symbole sind nicht > bekannt in den einzelnen Modulen. Ob mit oder ohne Unterstrich. Ich hatte ein vollständiges, auf Minimum reduziertes Beispiel gepostet, daß das Gegenteil beweist. Offensichtlich hast Du es nicht angesehen, zumindest die Zeile 3 nicht.
Leo C. schrieb: > Stattdessen kanns Du auch das Symbol "s__GSFINAL" nehmen. Ok, da habe ich leider übersehen, daß diesen Symbolen das fürhrende "_" fehlt. In C kann man die nicht referenzieren. Aber Statt einer Marke, die zusätzlich RAM belegt, und die Du suchen mußt, kannst Du Dir auch selber Symbole in den passenden Segmenten definieren (in crt0.s). crt0.s:
1 | .area _CODE |
2 | .globl _code_segment_start |
3 | _code_segment_start: |
4 | jp init |
5 | |
6 | ;... |
7 | .area _GSFINAL |
8 | ret |
9 | .globl _bis_hier_und_nicht_weiter |
10 | _bis_hier_und_nicht_weiter: |
C:
1 | #include <stdio.h> |
2 | |
3 | extern char code_segment_start[]; |
4 | extern char bis_hier_und_nicht_weiter[]; |
5 | |
6 | int main(void) |
7 | {
|
8 | printf("CODE start: %04x\n" |
9 | "End of GSFINAL: %04x\n" |
10 | "Length: %04x\n", |
11 | code_segment_start, bis_hier_und_nicht_weiter, |
12 | bis_hier_und_nicht_weiter - code_segment_start); |
13 | |
14 | return 0; |
15 | }
|
output:
1 | 0113 49 _main_start:: |
2 | 0113 50 _main: |
3 | 51 ;hello.c:13: bis_hier_und_nicht_weiter - code_segment_start); |
4 | 0113 11 79 0C [10] 52 ld de,#_bis_hier_und_nicht_weiter+0 |
5 | 0116 7B [ 4] 53 ld a,e |
6 | 0117 D6 00 [ 7] 54 sub a, #<(_code_segment_start) |
7 | 0119 4F [ 4] 55 ld c,a |
8 | 011A 7A [ 4] 56 ld a,d |
9 | 011B DE 01 [ 7] 57 sbc a, #>(_code_segment_start) |
10 | 011D 47 [ 4] 58 ld b,a |
11 | 59 ;hello.c:12: code_segment_start, bis_hier_und_nicht_weiter, |
12 | 60 ;hello.c:11: "Length: %04x\n", |
13 | 011E 21 33 01 [10] 61 ld hl,#___str_0 |
14 | 0121 C5 [11] 62 push bc |
15 | 0122 D5 [11] 63 push de |
16 | 0123 01 00 01 [10] 64 ld bc,#_code_segment_start |
17 | 0126 C5 [11] 65 push bc |
18 | 0127 E5 [11] 66 push hl |
19 | 0128 CD 93 01 [17] 67 call _printf |
20 | 012B F1 [10] 68 pop af |
21 | 012C F1 [10] 69 pop af |
22 | 012D F1 [10] 70 pop af |
23 | 012E F1 [10] 71 pop af |
24 | 72 ;hello.c:15: return 0; |
25 | 012F 21 00 00 [10] 73 ld hl,#0x0000 |
26 | 0132 C9 [10] 74 ret |
27 | 0133 75 _main_end:: |
Nachtrag: Im Anhang die vollständigen Dateien, incl. Map-Datei
:
Bearbeitet durch User
Leo C. schrieb: > extern char code_segment_start[]; > extern char bis_hier_und_nicht_weiter[]; Warum so etwas? Arrays?
Läuft nicht. Sobald ich das einbaue kriege ich jede Menge Fehler an anderen Stellen die vorher liefen. ASlink Warning_Undefined-Global "_main" refrence by module usw. ne ganze Latte. Vergessen wir es. Das hatte ich schonmal. PS: Nach realclean kompiliert es wieder. Mal sehen wie lange.
Geht nicht. Nach der nächsten Codeänderung völlig woanders kommen wieder reihenweise die asmlink Fehler.... Jetzt doch wieder.... nach "realclean".... au weia..... bloss nicht mehr anfassen den Konstrukt. Aber Ergebnis mit printf ist richtig.
Die Geheimnisse dieses Compilers ind unergründlich :-) Zuweisung der absoluten Werte und Umwandlung in Integerer code_start = (uint16_t)erste_code_adresse; code_end = (uint16_t)letzte_code_adresse; Das ham wa .... 4000 und 705D. Passt laut crts0.rst file
1 | 158 ;main.c:80: code_start = (uint16_t)erste_code_adresse; |
2 | 415E 3A 00 40 [13] 159 ld a,(#_erste_code_adresse + 0) |
3 | 4161 32 5D 70 [13] 160 ld (#_code_start + 0),a |
4 | 4164 3A 00 40 [13] 161 ld a,(#_erste_code_adresse + 0) |
5 | 4167 17 [ 4] 162 rla |
6 | 4168 9F [ 4] 163 sbc a, a |
7 | 4169 32 5E 70 [13] 164 ld (#_code_start + 1),a |
8 | 165 ;main.c:81: code_end = (uint16_t)letzte_code_adresse; |
9 | 416C 3A 5D 70 [13] 166 ld a,(#_letzte_code_adresse + 0) |
10 | 416F 32 5F 70 [13] 167 ld (#_code_end + 0),a |
11 | 4172 3A 5D 70 [13] 168 ld a,(#_letzte_code_adresse + 0) |
12 | 4175 17 [ 4] 169 rla |
13 | 4176 9F [ 4] 170 sbc a, a |
14 | 4177 32 60 70 [13] 171 ld (#_code_end + 1),a |
Und mit xprintf und printf gleichermassen gibt er aus Erste Codeadresse = ffc3 Letzte Codeadresse = ffc3 Verschieben wir die Zuweisung oben einfach etwas weiter nach oben im Main File, was eigentlich völlig egal ist erhalten wir: Erste Codeadresse = ffc3 Letzte Codeadresse = 7e5D <<<=== Hurra richtig! Fazit: Ich bin froh den sdcc zu haben (weil es nichts anderes Gescheites gibt) aber müsste ich damit beruflich arbeiten (solche Sachen habe ich mit dem Keil nie ...) würde ich das Ding zurückschicken und mir das Geld auszahlen lassen. Im industriellen Umfeld wäre der sdcc nicht "qualifizierbar" und in meiner Branche wo Source SIL 3 erfüllen muss auch "lebensgefährlich."
> code_start = (uint16_t)erste_code_adresse; > code_end = (uint16_t)letzte_code_adresse; Wie diese 4 Variablen deklariert sind, verrätst Du uns (natürlich mal wieder) nicht. Im Assembler-Code sieht man, daß "erste_code_adresse" und "letzte_code_adresse" statische oder globale, vorzeichenbehaftete 8-Bit Variablen sind. > 158 ;main.c:80: code_start = > (uint16_t)erste_code_adresse; > 415E 3A 00 40 [13] 159 ld a,(#_erste_code_adresse + 0) Lade Akku mit Inhalt von erste_code_adresse > 4161 32 5D 70 [13] 160 ld (#_code_start + 0),a Speichern in low(code_start) > 4164 3A 00 40 [13] 161 ld a,(#_erste_code_adresse + 0) Nochmal: (hier könnte optimiert werden) Lade Akku mit Inhalt von erste_code_adresse > 4167 17 [ 4] 162 rla > 4168 9F [ 4] 163 sbc a, a Vorzeichenerweiterung > 4169 32 5E 70 [13] 164 ld (#_code_start + 1),a Speichern in high(code_start) > Und mit xprintf und printf gleichermassen gibt er aus Garbage in garbage out.
A. K. schrieb: > Christian J. schrieb: >> Warum so etwas? Arrays? Wei Pointerarithmetik nur mit sinnvollen Datentypen richtig funktionieren kann. > Erspart den & Operator. Mit & hatte ich seltsame Ergebnisse. Da dürfre aber noch was anderes falsch deklariert gewesen sein.
Leo C. schrieb: > Mit & hatte ich seltsame Ergebnisse. Mit & geht es auch aber umständlicher. Ich musste a auf void* casten damit ich überhaupt kompilieren kann. Ich habe jetzt einfach mal wild rumprobiert, bis ich den Wert der Symbole hatte und nicht deren Inhalt. extern char erste_code_adresse[]; // Zeiger auf SDCC Globals extern char letzte_code_adresse[]; // Adressen für Start und Ende des Programms uint16_t code_start, code_end; // Sichere die Start- und Endadresse des Codes code_start = (uint16_t)erste_code_adresse; code_end = (uint16_t)letzte_code_adresse;
1 | 410C 98 _main: |
2 | 99 ;main.c:52: code_start = (uint16_t)erste_code_adresse; |
3 | 410C 21 00 40 [10] 100 ld hl,#_erste_code_adresse+0 |
4 | 410F 22 2E 65 [16] 101 ld (_code_start),hl |
5 | 102 ;main.c:53: code_end = (uint16_t)letzte_code_adresse; |
6 | 4112 21 2E 65 [10] 103 ld hl,#_letzte_code_adresse+0 |
7 | 4115 22 30 65 [16] 104 ld (_code_end),hl |
Möchte man unbedingt ein Kaufmanns UND verwenden geht es so: extern char erste_code_adresse; // Zeiger auf SDCC Globals extern char letzte_code_adresse; // Adressen für Start und Ende des Programms uint16_t *code_start, *code_end; // Sichere die Start- und Endadresse des Codes code_start = (void*)&erste_code_adresse; code_end = (void*)&letzte_code_adresse; ergibt: 99 ;main.c:52: code_start = (void*)&erste_code_adresse; 410C 21 00 40 [10] 100 ld hl,#_erste_code_adresse+0 410F 22 36 65 [16] 101 ld (_code_start),hl 102 ;main.c:53: code_end = (void*)&letzte_code_adresse; 4112 21 36 65 [10] 103 ld hl,#_letzte_code_adresse+0 4115 22 38 65 [16] 104 ld (_code_end),hl Das passiert alles meist dann, wenn man das normale Fahrwasser eines Compilers verlässt und seine Spezialfunktionen benutzt. Denn hier greift man ja schon tief in die Kiste der Tricks.
Christian J. schrieb: > // Adressen für Start und Ende des Programms > uint16_t *code_start, *code_end; Rechne hier mal die Differenz aus, und lass sie Dir ausgeben.
Leo C. schrieb: > Rechne hier mal die Differenz aus, und lass sie Dir ausgeben. Siehe Bild: sptr->len.
1 | // Header Infos zusammenbauen |
2 | sptr->cmd = CMD_WR; |
3 | sptr->type = TYPE_PROG; // Datentyp Programm |
4 | sptr->crc = crc; // Prüfsumme |
5 | |
6 | sptr->start_adress = code_start; // Startadresse |
7 | sptr->end_adress = code_end; // Endadresse |
8 | sptr->len = code_end-code_start; // Datenlänge |
9 | strcpy(sptr->name,filename); // Dateiname |
10 | strcpy(sptr->descr,filedescr); // Dateibeschreibung |
Passt, ist ja auch identischer Asm Code.
> Siehe Bild: sptr->len.
Das ist mit ziemlicher Sicherheit etwas anderes.
Nee, da kam das Gleiche bei raus. Siehste doch an dem Asm Code. Ausgabe mit xprintf. Ich vermeide call by ref sowieso wo es nur geht und auch nur selten Pointer, außer eben beim Heap. Du kannst dich damit ja gern weiter befassen, ich bin froh dass es mit [] läuft und fasse das Modul nicht mehr an. Allein schon die ganzen Asm Warnungen des Linkers vorher. ps: sehe grad dass ich im modul sd.c bei dem "extern uint16_t code_start" die * vergessen habe. kann sein dass da ein ungewollter typ cast über die Module hinweg stattgefunden hat.
Die nächste Zeit ist auch Arduino angesagt... da auf Z80 "blind" programmiert, ohne Testmöglichkeit, nur nach Logic Analyzer. Es wächst nämlich grad noch ein Platinchen heran.... mit 32 Bit Counter, SD, programmierbarem Taktteiler (4020 und 74151), Display und noch ein paar Ausgängen für die nächste Stufe... Es werden immer mehr :-)
Hallo, > Ich bin froh den sdcc zu haben (weil es nichts anderes Gescheites gibt) > aber müsste ich damit beruflich arbeiten (solche Sachen habe ich mit dem > Keil nie ...) würde ich das Ding zurückschicken und mir das Geld > auszahlen lassen. Die null Dollar, die du dafür bezahlt hast, kann sogar ich dir überweisen. Es gibt (gab) übrigens auch einen Keil-Compiler für den Z80, den ich allerdings nie gefunden habe. Der liefert aber vergleichbare bis bessere Ergebnisse als SDCC und dürfte auch zertifiziert sein. Alternativ gibt es auch noch den z88dk als C-Compiler, aber ob der bugfreier ist, weiß ich nicht. > Im industriellen Umfeld wäre der sdcc nicht "qualifizierbar" und in > meiner Branche wo Source SIL 3 erfüllen muss auch "lebensgefährlich." Dafür ist er auch nicht gebaut. Siehe Keil. > Die nächste Zeit ist auch Arduino angesagt... da auf Z80 "blind" > programmiert, ohne Testmöglichkeit, nur nach Logic Analyzer. Verstehe ich nicht. Ich hatte auf meinem System eine Turnaround-Zeit von vielleicht 15 Sekunden: "make all", Reset-Knopf drücken, Sende-Befehl des Terminals, Dateiname eingeben, paar Sekunden warten, Ergebnis gucken. Aber ich bin positiv überrascht, mit wieviel Wucht du immer wieder mit dem Kopf gegen die Wände rennst (Türen ignorierend) - und trotzdem durchkommst. Gruß, Svenska
S. R. schrieb: > Verstehe ich nicht. Ich hatte auf meinem System eine Turnaround-Zeit von > vielleicht 15 Sekunden: "make all", Reset-Knopf drücken, Sende-Befehl > des Terminals, Dateiname eingeben, paar Sekunden warten, Ergebnis > gucken. Glaubst du bei mir läuft das anders? 10s wenn es hoch kommt. NMI Reset für Laden, ./load Script aufrufen und das Ding rennt los. Aber das Extension Board ist noch nicht verdrahtet. https://www.youtube.com/watch?v=gSVBFNCqYeQ und https://www.youtube.com/watch?v=PpTISqDCT0c Das nächste Projekt steht schon in den Löchern.... Z80 mit Bildschirm und Tastatur, S100 Bus und CP/M :-) Aber keines dieser Kunstrgiff Systeme wie Atmega Emulator mit Z80 als Slave. ne eine richtige schöne Platine mit fetten Chips drauf und viel RAM :-) Wäre aber auch mal was, ne CPU ohne CPU: https://www.youtube.com/watch?v=GeSSkvwFDHs Bin in dem Zaks Buch inzwischen schon weiter ..... frage mich dennoch wie Menschen die Nerven hatten ganze OS damit zu schreiben. Allerdings hat der Jäger damals auch Stunde damit verbracht seine Pfeilspitzen zu schärfen, damit sie dann, wenn das Wild auftaucht scharf sind :-) Mal ne allgemeine Frage: Ich habe mir den Asm des sdcc ja nun oft genug angeschaut. Er ist clever genug aus einem strcpy oder memcpy eine LDIR Schleife zu bauen. Also die mächtigen Befehle zu nutzen, die mit Mikrocode abgearbeitet werden. Wie ist denn überhaupt die Nutzung des gesamten Befehlsvorrates? Gefühlt nutzt er nicht mehr als 20 Befehle. Ich vermute man könnte in Asm locker 30% Code einsparen.
Christian J. schrieb: [..] > Wie ist denn überhaupt die Nutzung des gesamten Befehlsvorrates? Gefühlt > nutzt er nicht mehr als 20 Befehle. Ich vermute man könnte in Asm locker > 30% Code einsparen. Du bist auf dem besten Wege herauszufinden warum RISC CPUs erfunden wurden. Ich denke nicht das das auf den Z80 zutrifft aber bei der VAX gab es komplexe Maschinenbefehle deren Ausführungszeiten länger waren als ihr Ersatz durch Befehlsfolgen einfacherer Befehle. Gruß, Holm
Holm Tiffe schrieb: > Du bist auf dem besten Wege herauszufinden warum RISC CPUs erfunden > wurden. http://www.cis.upenn.edu/~milom/cis501-Fall08/papers/cocke-RISC.pdf "There even were instances of code which, when compiled for the 801 and simulated on a System/370 Model 168, ran faster in real time than the same program run directly on a Model 168 when compiled by the PL/I compiler."
:
Bearbeitet durch User
Christian J. schrieb: > Im industriellen Umfeld wäre der sdcc nicht > "qualifizierbar" und in meiner Branche wo Source SIL 3 erfüllen muss > auch "lebensgefährlich." Sorry daß ich mich hier mal einmische und eurer Trialog störe. Aber obige Aussage von Christian, daß er beruflich was mit "SIL 3" zu tun hätte, und das in Verbindung mit seiner Arbeitsweise was hier auf inzwischen 1329 Beiträgen dokumentiert ist ... Das macht mir richtig Angst. Gruss
A. K. schrieb: > Holm Tiffe schrieb: >> Du bist auf dem besten Wege herauszufinden warum RISC CPUs erfunden >> wurden. > > http://www.cis.upenn.edu/~milom/cis501-Fall08/papers/cocke-RISC.pdf > > "There even were instances of code which, when compiled for the 801 and > simulated on a System/370 Model 168, ran faster in real time than the > same program run directly on a Model 168 when compiled by the PL/I > compiler." ...das ist ja schräg... allerdings lief emuliertes Linux bzw. Linux Programme auf einem FreeBSD eine Zeit lang auch schneller als auf Linux. Da war der Emulator aber mehr oder weniger ein system call wrapper und dadurch war das Ganze auch erklärbar. Bei dem VAX Beispiel, das ich von cctalk@classiccmp.org habe, frage ich mich allerdings was die Designer des Microcodes geraucht haben wenn sie es hinkriegen das eine Makrobefehlsfolge schneller ist als der spezialisierte Mikrocode auf der selben Maschine.. Ich weiß nicht viel über PL/1 aber IMHO sagt da schon was über die Qualität und Implementation des Compilers aus. Die DDR hat mal eine wenig kompatible und als langsamste geltende PDP11 gebaut, den Robotron K1630 mit asynchroner CPU. Für das Ding gabs Einschubplatinen um einen KRS4200 emulieren zu können um alte Programme ablaufen zu lassen. Wenn dieser Emulator lief, war der Rest der Maschine nicht für anderes verwendbar. Der Emulator aber seinerseits war deutlich schneller als der eigentliche KRS4200 (Honeywell 9000). Gruß, Holm
Holm Tiffe schrieb: > Bei dem VAX Beispiel, das ich von cctalk@classiccmp.org habe, frage ich > mich allerdings was die Designer des Microcodes geraucht haben wenn sie > es hinkriegen das eine Makrobefehlsfolge schneller ist als der > spezialisierte Mikrocode auf der selben Maschine.. Bekannt war diese Verhalten von den CALLx/RET Befehlen. Die waren als eierlegende Wollmilchsau so komplex geraten, dass viele auf die einfacheren und schnelleren JSB/RSB auswichen. Der Microcode eines komplexen Befehls muss alle möglichen Optionen des Befehls zur Laufzeit einzeln durchprobieren. Nur um meist festzustellen, dass es nichts zu tun gibt. Das kostet Zeit. Ein Compiler hingegen erzeugt einfach nur die Befehle, die wirklich benötigt werden.
:
Bearbeitet durch User
A. K. schrieb: [..] > Der Microcode eines komplexen Befehls muss alle möglichen Optionen des > Befehls zur Laufzeit einzeln durchprobieren. Nur um meist festzustellen, > dass es nichts zu tun gibt. Das kostet Zeit. Ein Compiler hingegen > erzeugt einfach nur die Befehle, die wirklich benötigt werden. ..nein, im konkreten Falle war das nicht der Call, ich glaube das war irgend ein String Befehl, wobei ich aber auch weiß das der Call auf VAX so ziemlich "Alles" macht.. Klar ist das die CPU immer ein "Interpreter" für die Maschinensprache ist der sich durchwursteln muß.Das ist aber beim Microcode zu einem Maschinenbefehl auch nicht anders und auch da kann man gut oder beschissen programmieren. Gruß, Holm
Erich schrieb: > Sorry daß ich mich hier mal einmische und eurer Trialog störe. > Aber obige Aussage von Christian, daß er beruflich was mit "SIL 3" zu > tun hätte, und das in Verbindung mit seiner Arbeitsweise was hier auf > inzwischen 1329 Beiträgen dokumentiert ist ... > > Das macht mir richtig Angst. > > Gruss Wahrscheinlich schlackerst du jetzt auch nicht mit den Ohren, wenn ich dir sage, dass einige Fachbeiträge über die 61508, 62061, 13849 und Co. in Fachzeitungen auf mein Konto gehen und ich sogar Schulungen gehalten habe, wie diese anzuwenden sind. Gefühlt so ca 500 Geräte mit SIL3 wurden von mir für den Markt zugelassen, mehrere davon in Kernkraftwerken (Reaktorabschaltung, Sicherheitsbereich E1). Du lebst ja noch, also scheinen sie zu funktionieren. Du verwechselst ARBEIT mit HOBBY! Wie viele hier leider.... Schönen Tag noch!
Holm Tiffe schrieb: > Du bist auf dem besten Wege herauszufinden warum RISC CPUs erfunden > wurden. Das frage ich mich auch, wenn ich mir den Befehlssatz einer Intel CPU heute anschaue..... ein PIC kommt mit 35 Befehlen aus...... für alles.
Holm Tiffe schrieb: > Das ist aber beim Microcode zu einem > Maschinenbefehl auch nicht anders und auch da kann man gut oder > beschissen programmieren. Auch Microcode kocht nur mit Wasser. Wenn für einen komplexen Befehl beispielsweise 20 Microinstructions benötigt werden, von denen die Hälfte nutzloser Code ist, der nicht zum Ergebnis beiträgt, dann kommt eine Ersatzsequenz vielleicht nur mit 10 Microinstructions aus. Und das liegt dann nicht daran, dass der Programmierer besoffen war, sondern dass der komplexe Befehl Teile enthält, die in diesem Fall nicht benötigt werden. Wenn du einen Befehl alles reinsteckst, was irgendwie mal gebraucht werden könnte, dann ist manches davon nur selten notwendig. Dieser Teil des Microcodes kostet beim Komplexbefehl trotzdem Takte, nur um festzustellen, dass ein Wert 0 ist. Der Compiler lässt das in der Ersatzsequenz aber von vorneherein weg. Als Beispiel Intels ENTER/LEAVE Befehle. Diese Befehle hatte Intel für Sprachen vom PASCAL Typ vorgesehen, die lokale Funktionen mit Zugriff auf die Variablen der umgebenden Funktion unterstützen. Dazu benötigt man einen viel komplexeren Stackframe als für C, weil ein Pointer-Array kopiert werden muss. In C lässt sich der ENTER Befehl auch nutzen, es wird dann aber nur ein Teil von dessen Funktion genutzt. Einer der Parameter des Befehls ist dann stets 0 (nesting level). Der Microcode des Befehls muss zur Laufzeit überprüfen, ob der Wert 0 ist, das kostet Zeit. Die Ersatzsequenz enthält diesen Teil nicht, das kostet also dann keine Laufzeit. Folglich waren bei Intel die 2-3 Ersatzbefehle schneller als Intels ENTER Befehl. Der folglich von kaum einem C Compiler verwendet wurde. Zweites Beispiel, wenn der Prozessor bei einem Speicherzugriffsfehler den Befehl abbricht, um ihn später erneut ausführen zu können. Meistens ist das so realisiert (m.W. auch bei den VAXen), nur die 68000 Familie arbeitete anders. Dann darf während der Laufzeit nichts geschehen, das dies verhindern könnte. Das kann Microcode deutlich komplizierter machen als eine exakt äquivalente Ersatzsequenz. So kann es bei Befehlen mit mehreren möglicherweise gleichen oder gar überlappenden Speicheradressen nötig werden, dass der Microcode zur Laufzeit die Speicheradressen vergleicht, um abhängig davon verschiedene Pfade einzuschlagen. In einer Ersatzsequenz aus einfachen Befehlen ist das einerseits oft unnötig, da sie zwischendrin unterbrochen werden kann. Andererseits kann der Compiler eigenes Wissen über die Beziehung der Operanden einbringen. Dieses Problem kann bereits bei einem scheinbar einfachen Befehl auftreten, der nur von Speicher zu Speicher addiert. Komplexe Befehle erzeugen also künstlich Probleme und Laufzeit, die man in Ersatzsequenzen aus einfachen Befehlen überhaupt nicht hat.
:
Bearbeitet durch User
Christian J. schrieb: > Gefühlt so ca 500 Geräte mit SIL3 > wurden von mir für den Markt zugelassen, mehrere davon in > Kernkraftwerken (Reaktorabschaltung, Sicherheitsbereich E1). Du lebst ja > noch, also scheinen sie zu funktionieren. Offensichtlich ist in diesen Geräten keine CPU drin. Oder sie wurde nicht von Dir programmiert... > Du verwechselst ARBEIT mit HOBBY! Hmm. Warum machst Du Dir die Methoden, die Du professionell nutzt, nicht auch privat zu eigen?
A. K. schrieb: > Komplexe Befehle erzeugen also künstlich Probleme und Laufzeit, die man > in Ersatzsequenzen aus einfachen Befehlen überhaupt nicht hat. Beeindruckend deine Kenntnisse über die Architektur! Enter und Leave habe ich damals auch nie gebraucht ca 1995 als ich viel Intel Asm machte, und auch viele andere nicht. Gehört zwar nicht hierhin aber als 1996 die PIC auftauchten war das wie eine Erlösung. Gestehe, dass ich niemals auch nur einen in Asm programmierte. Erst denr extrem buggy Byte Craft Compiler benutzt, dann den CCS ab 2000. Die Compiler waren allerdings limitiert und auch heute kennt der CCS als bekanntester Vertreter wohl noch kein char** ptr. Indizierte Adressierung kannten die PIC nicht, nur ein Destination Bit, was angab wo etwas zu speichern ist, W oder Speicherzelle. Da ist sicherlich viel Grips reingeflossen den absolut minimalen einen Befehlssatz zu erarbeiten, der ohne Microcode auskommt und daher sehr schnell ist, nämlich nur 1 Takt pro Befehl. Da die Programmierung eh "maschinennah" auch in C erfolgt ist der Code sehr kompakt
1 | .................... ////////////////////////////////////// |
2 | .................... // Die Bedeutung des Bytes rec_byte auswerten |
3 | .................... ////////////////////////////////////// |
4 | .................... |
5 | .................... // --- Byte 1: Startsignatur |
6 | .................... if (byte_counter == 1) { |
7 | 0027E: DECFSZ xE5,W |
8 | 00280: BRA 028E |
9 | .................... if (rec_byte != IRID) { |
10 | 00282: MOVF xE3,W |
11 | 00284: SUBLW 83 |
12 | 00286: BZ 028C |
13 | .................... ir_state = 0; |
14 | 00288: CLRF xE0 |
15 | .................... goto ende; |
16 | 0028A: BRA 0308 |
17 | .................... }} |
18 | .................... |
19 | .................... // --- Byte 2: Anzahl folgender Bytes |
20 | .................... else if (byte_counter == 2) { |
21 | 0028C: BRA 0306 |
22 | 0028E: MOVF xE5,W |
23 | 00290: SUBLW 02 |
24 | 00292: BNZ 029C |
25 | .................... no_bytes = rec_byte; // Empfangsgrenze setzen |
26 | 00294: MOVFF E3,E6 |
27 | .................... dat_cnt = 0; // Datenbytezähler rücksetzen |
28 | 00298: CLRF xE7 |
29 | .................... } |
30 | .................... |
31 | .................... // --- Byte 3: N Datenbytes empfangen |
32 | .................... else if ((byte_counter >=3 ) && (dat_cnt < no_bytes)) |
33 | 0029A: BRA 0306 |
34 | 0029C: MOVF xE5,W |
35 | 0029E: SUBLW 02 |
36 | 002A0: BC 02C0 |
37 | 002A2: MOVF xE6,W |
38 | 002A4: SUBWF xE7,W |
39 | 002A6: BC 02C0 |
40 | .................... { |
41 | .................... ir_rx_data[ir_rx_pointer++] = rec_byte; // Byte in Datenfeld schieben |
42 | 002A8: MOVF xDD,W |
43 | 002AA: INCF xDD,F |
44 | 002AC: CLRF 03 |
45 | 002AE: ADDLW 8C |
46 | 002B0: MOVWF FE9 |
47 | 002B2: MOVLW 00 |
48 | 002B4: ADDWFC 03,W |
49 | 002B6: MOVWF FEA |
50 | 002B8: MOVFF E3,FEF |
51 | .................... dat_cnt++; |
Christian J. schrieb: > Beeindruckend deine Kenntnisse über die Architektur! Enter und Leave > habe ich damals auch nie gebraucht ca 1995 als ich viel Intel Asm > machte, und auch viele andere nicht. Gehört zwar nicht hierhin aber als > 1996 die PIC auftauchten war das wie eine Erlösung. Intels x86 Architektur war zwar nie der Brüller, aber dass es wahrhaftig jemanden gibt, der die 8-Bit PICs als Erlösung gegenüber 386 betrachtet, das hätte ich nicht gedacht. ;-)
Das hasse ich an diesen Forum.... dieses "in den Mund legen" :-( PIC waren fürs Hobby wie eine Erlösung, nach dem 8051 Krampf, 8048 usw. Als der 16F84 rauskam habe ich Tage damit verbracht den auszureizen.
Christian J. schrieb: > Das hasse ich an diesen Forum.... dieses "in den Mund legen" :-( Sachte. Ich dachte mir zwar, dass du 8051 meintest, aber ENTER/LEAVE sind nun einmal x86 Befehle. So eine Vorlage darf man sich nicht entgehen lassen. ;-)
Und es ist nach wie vor "faszinierend", dass der kleine 14-Pinner in der Mitte zusammen mit einem Schieberegister in der Lage ist Sensoren auszulesen, Temperatur, Feuchte anzuzeigen, nebenbei noch eine Anzeige zu multiplexen ohne dass diese flackert (ok, ich lese im Umschaltmoment aus, da fällt es nicht auf :-) und alles was er macht auch noch über eine Uart auszugeben , Min Max im internen EEPROM speichert usw. usw. Mag sein das verwöhnte Bengels das heute alles als "normal" bezeichnen. Von sowas hätte ich als 18-20 Jähriger nur geträumt damals. Ne ähnliche Schaltung, die ich 1996 mit dem 8051 machte (ext. EPROM, NTC Widerstand) undderen Hartpapier Platte heute so schwarz braun statt hellbraun aussieht läuft aber heute auch noch, EPROMs schaffen also mindestens 20 Jahre :-)
So krampfig ist der 8051 doch auch nicht. Jedenfalls nicht schlimmer als diese krude PIC12-Architektur. :o
greg schrieb: > So krampfig ist der 8051 doch auch nicht. Jedenfalls nicht schlimmer als > diese krude PIC12-Architektur. :o Vielleicht meinte er auch 8048. Die war deutlich krampfiger als 8051. PIC12 ist ok, wenn man in Assembler programmiert und das Programm maximal 256 Worte umfasst. Für grössere Programme war diese Architektur - die übrigens die älteste noch genutzte µC Architektur ist - nie gedacht. Und als Ziel von Compilern schon garnicht.
:
Bearbeitet durch User
greg schrieb: > So krampfig ist der 8051 doch auch nicht. Jedenfalls nicht schlimmer als > diese krude PIC12-Architektur. :o Soso, 256 Byte Stack limiert.... ok, Keil Compiler damals gehabt. Immer ein EPROM mit dran was Pins kostete. Und 100 DM für einen 87C51 ausgegeben, der nach 3 Mal Brennen kaputt war :-( Ich warte noch auf die hier für Z80: http://en.wikipedia.org/wiki/MCU_8051_IDE#mediaviewer/File:MCU_8051_IDE_-_I.png
A. K. schrieb: > PIC12 ist ok, wenn man in Assembler programmiert und das Programm > maximal 256 Worte umfasst Das sind die im SOT-23 Gehäuse, 6 Pins, winzige Dinger, die aber reichen um zb eine IR Diode zu modulieren, TSOP zu decodieren usw. Nie gehabt, nur Asm, kein Debug Interface usw.
Christian J. schrieb: > Soso, 256 Byte Stack limiert.... ok, Nix Stack. Der Code. Notfalls 512 Worte, wenn man die Unterprogramme in die erste Hälfte davon legt. Bis dahin geht es ohne Banking ab. Mehr hatte der PIC1650A auch nicht. Dass dessen Architektur auch 4 Jahrzehnte später noch lebt hatte GI sicher nicht auf der Rechnung.
A. K. schrieb: > Mehr hatte der PIC1650A auch nicht. Der ist ja auch Steinzeit.... kein Mensch benutzt den mehr.
@Frank Meyer: Wäre es ohne weiteres für Dich möglich eine nützliche Option in den Minieditor getstrng einzubauen, nämlich dass er den Buffer in das Eingabefeld ausdruckt? Dieser müsste also leer sein wenn man ein leeres Feld haben will aber es wäre sehr nützlich um fehlerjafte Eingaben zu korrigieren ohne alles neu tippen zu müssen. Habe den Parser geschrieben, der die Kommandozeile zerlegt und da es jede Menge gibt, was ein User (auch wenn nur ich es bin) da verbrechen kann wäre eine "Back" Funktion sehr nützlich.
1 | do { |
2 | getnstr(cl.inbuf,CMDBUFSIZE-1); |
3 | while (strlen(cl.inbuf)==0); |
4 | |
5 | // String splitten |
6 | res = split_command(&cl) |
7 | } while (res != 1); |
8 | |
9 | ...... |
10 | |
11 | |
12 | char split_command(struct cl_type* ptr) |
13 | { |
14 | char cbuf[CMDBUFSIZE]; // Kopie Eingabepuffer |
15 | char* cptr; // Zeiger auf Eingabepuffer |
16 | char j,i; |
17 | |
18 | // Stringzerlegung (ok!) |
19 | strcpy(cbuf,ptr->inbuf); // String Kopie erzeugen |
20 | |
21 | j = 0; |
22 | cptr = strtok(cbuf," "); // Zeichentrenner und erster Abschnitt |
23 | strcpy(ptr->cmd,cptr); |
24 | while(cptr != 0 && (j < MAX_PARAMS)) |
25 | { |
26 | cptr = strtok(NULL," "); |
27 | if (cptr != NULL) { |
28 | if (strlen(cptr)<PARAM_LEN) |
29 | strcpy(ptr->param[j++],cptr); |
30 | else |
31 | return (2); |
32 | } |
33 | } |
34 | |
35 | ptr->no_params = j; |
36 | |
37 | #ifdef DEBUG_COMMAND |
38 | // Testweise Ausgabe der Zerlegung |
39 | xprintf("\rcmd: %s",ptr->cmd); |
40 | xprintf("\rParams: %d",j); |
41 | for (i=0;i < ptr->no_params;i++) |
42 | xprintf("\rParam %d : %s",i,ptr->param[i]); |
43 | #endif |
44 | |
45 | // 1 = ok |
46 | return (1); |
47 | } |
S. R. schrieb: > Übrigens wiederhole ich nochmal einen Vorschlag: Deine serielle > Schnittstelle kann all das, was du willst, auch machen. Du musst dafür > keine SD-Karte an dein System frickeln. Das Protokoll der Wahl dafür > nennt sich ZMODEM. Ich habe Dich "erhört" :-) Nur ist es nicht ZMODEM geworden, sondern wegen der kleineren Codegröße XMODEM. 10 Minuten einfügen, etwas umstellen, CRC mit rein nehmen, getchar und putchar einbauen, Kompilieren ohne Fehler und der Test war dann schnell gemacht, dass minicom Dateien entgegen nimmt und abspeichert und auch der Z80 sie von dort laden kann. Wie war das noch mit Boris Becker? "Bin ich schon drin?" :-) Schön, neben der SD Karte eine weitere Möglichkeit Programme einzuspielen und zu sichern. Damit haben wir a) Intel Hex Upload b) SD karte c) XMODEM und die 16kb sind leider auch bald voll :-(( http://www.menie.org/georges/embedded/xmodem.c
Christian J. schrieb: >> Das Protokoll der Wahl dafür nennt sich ZMODEM. > Ich habe Dich "erhört" :-) Nur ist es nicht ZMODEM geworden, sondern > wegen der kleineren Codegröße XMODEM. Naja, immerhin. Das ZMODEM hatte übrigens auch einen konkreten Hintergrund, denn es bietet dir drei relevante Vorteile gegenüber XMODEM: - ZMODEM überträgt Dateinamen - ZMODEM überträgt byte-exakte Dateigrößen (XMODEM paddet auf 128 Byte) - ZMODEM kann automatische Übertragungen (in beide Richtungen, wenn ich mich recht entsinne) anstoßen. Damit kannst du dir schon fast einen richtigen Fileserver bauen. Wenn dein Terminal gut genug ist, dann braucht der Z80 nur noch "gib mir TEST.TXT" sagen und bekommt die Datei, ohne dass du in deinem Terminal den Namen nochmal angeben müsstest. Gruß, Sebastian
Hi, naja, es klappt ja. Aber es soll ja eigentlich von ner Karte kommen. Der Z80 wird später mal nur an einen Raspi kommen, mit Monitor und Keyboard. PC als Stromfresser soll nur zur Entwicklung sein. Leider habe ich mir mit dem Intel Hex Decoder auch die doppelte Upload Zeit eingefangen wie vorher auf Binärebene. Aber es klappt auch und ist sehr einfach, wenn man vieles weglässt und auch keine Fehlerprüfungen mehr als die Prüfsumme einbaut. Interessieren würde mich mal woher die Z80er und Co. auf ebay etc derzeit noch kommen. Ist das NOS Ware? Oder wird der immer noch hergestellt? Habe einen von 1981 und andere von 1994 hier. Für den ders nachbauen will hier der Source. Lässt man die Prüfsumme auch noch weg wird es noch um 30% kürzer.
1 | ///////////////////////////////////////////////////////////////////// |
2 | // 1 Zeichen Hex -> Int konvertieren |
3 | // Eingabe: "C" = 0x43 |
4 | // Ausgabe: 0x0C |
5 | uint8_t xtoc (uint8_t ch) |
6 | { |
7 | uint8_t val; |
8 | |
9 | // Grossbuchstaben |
10 | if (ch >= 'A' && ch <= 'F') |
11 | val = (ch - 'A') + 10; |
12 | //Kleinbuchstaben |
13 | else if (ch >= 'a' && ch <= 'f') |
14 | val = (ch - 'a') + 10; |
15 | else |
16 | val = (ch - '0'); |
17 | |
18 | return val; |
19 | } |
20 | |
21 | // Intel Hex Decoder |
22 | |
23 | __at (ROM_START) unsigned char mem[0xffff]; // Kompletter Speicher |
24 | |
25 | char ihx_decode() |
26 | { |
27 | #define DATA_RECORD 0x00 |
28 | #define END_RECORD 0x01 |
29 | |
30 | struct ihx_data { |
31 | uint8_t len; |
32 | uint16_t adress; |
33 | uint8_t record; |
34 | uint8_t csum; |
35 | } ihx; |
36 | |
37 | uint8_t ch,i,lo,hi,k,data; |
38 | uint8_t check; |
39 | uint8_t p[4]; |
40 | |
41 | |
42 | k = 0; |
43 | do { |
44 | // warte auf Startzeichen |
45 | do ch = getchar(); |
46 | while (ch!=':'); |
47 | |
48 | ihx.csum = 0; |
49 | |
50 | // Hole Anzahl Zeichen des Satzes |
51 | hi = xtoc(getchar()); |
52 | lo = xtoc(getchar()); |
53 | ihx.len = (hi <<4 )+lo; |
54 | ihx.csum += ihx.len; |
55 | |
56 | // Hole Zieladresse des Satzes |
57 | for (i=0;i<4;i++) |
58 | p[3-i] = xtoc(getchar()); |
59 | |
60 | // Setze Adresse zusammen |
61 | ihx.adress = (p[3]<<12) | (p[2]<<8) | (p[1]<<4) | p[0]; |
62 | ihx.csum += (p[1]<<4) | p[0]; |
63 | ihx.csum += (p[3]<<4) | p[2]; |
64 | |
65 | // Hole Record Type |
66 | hi = xtoc(getchar()); |
67 | lo = xtoc(getchar()); |
68 | ihx.record = (hi<<4)+lo; |
69 | ihx.csum += ihx.record; |
70 | |
71 | // Record 0 = Daten |
72 | if (ihx.record == DATA_RECORD) { |
73 | // Hole Datenbytes ab |
74 | for (i=0;i<ihx.len;i++) |
75 | { |
76 | hi = xtoc(getchar()); |
77 | lo = xtoc(getchar()); |
78 | data = (hi <<4 )+lo; |
79 | mem[ihx.adress+i] = data; |
80 | ihx.csum += data; |
81 | SetLedByte((hi<<4)+lo); |
82 | } |
83 | |
84 | ihx.csum = (~ihx.csum) +1; |
85 | |
86 | // Prüfsumme holen |
87 | hi = xtoc(getchar()); |
88 | lo = xtoc(getchar()); |
89 | check = (hi<<4)+lo; |
90 | |
91 | // Prüfsumme überprüfen |
92 | if (check != ihx.csum) |
93 | return (0); |
94 | |
95 | SetDigit(k++); |
96 | } |
97 | |
98 | } while (ihx.record != END_RECORD); |
99 | |
100 | // Dateiende abwarten |
101 | do |
102 | ch = getchar(); |
103 | while (ch!=0x0a); |
104 | |
105 | return (1); |
106 | |
107 | } |
Der Programmcode 08.12.2014 12:02 erscheint mir wiederum sehr hobbymäßig, eher sogar mäßig bis ...mäßig. Jedenfalls nicht SIL3. Früher ---als es noch keine SIL Stufen gab--- da hat man schon erst das Zeugs dekodiert und erst in den Speicher geschrieben wenn alles ok war. Aber das war früher... Gruss
Erich schrieb: > Der Programmcode 08.12.2014 12:02 erscheint mir wiederum sehr > hobbymäßig, eher sogar mäßig bis ...mäßig. Jedenfalls nicht SIL3. Rede keinen Stuss und melde Dich erstmal an, bevor Du hier rumnörgelst. Code muss funktionieren und das tut er. Schönheitspreise braucht er nicht zu bekommen. SIL3 bei Z80? Gehts noch? Und bevor ich nicht von Dir etwas hier gesehen habe halt dich bitte mit Kommentaren zurück. Jedenfalls kam er heute an, gebraucht für 149 Ocken. Sehr nettes Teilchen!
Das Zeug daneben finde ich interessanter: Den nicht sehr erdbebenfest wirkenden und schon windschiefen Plattenstapel auf Platte. ;-) Der Rest ist leider nicht zu erkennen. Freiluft-Server?
:
Bearbeitet durch User
A. K. schrieb: > Freiluft-Server? Yep, ein 24/7 Server mit 6 TB, kleine Cubietruck "Fabrik"..... da drauf wird ja auch alles Z80 Zeug entwickelt, kompiliert, hochgeladen usw.
AK? Kann es sein, dass die 8254 Timer schweineheiss werden? Den hier kann man kaum länger anfassen. Pendelt sich bei 41 Grad ein. 1W Pv laut Datenblatt aber ich frage mich wo der die lässt. Gibt es die auch als CMOS? Oder den 8253? Der Stromverbrauch nähert sich den 500mA.....
Christian J. schrieb: > 1W Pv laut Datenblatt 170mA max, sagt mir das Datasheet. Yep, darf also warm werden. > Der Stromverbrauch nähert sich den 500mA..... Nur vom 8254? Das wären 2,5W und das wäre mehr als warm, mehr als schlappe 41°C würde ich meinen. CMOS wäre 82C54. Ganz dem Intel'schen Schema entsprechend.
:
Bearbeitet durch User
A. K. schrieb: > CMOS wäre 82C54. Ganz dem Intel'schen Schema entsprechend. 500mA alles zusammen inzwischen, beide Platinen. Der 8254 zieht sich 135ma aktuell rein. Und schon 82C54 "bestellt" in der Bucht..... geht nicht dass der hier die Bude aufheizt. Die 7805 sind auch an ihrer Grenze. Anbei die Peripherie, noch nicht ganz fertig aber frag bitte keiner nach dem "Sinn", es ist einfach nur etwas Elektronik, die sich konfigurieren lässt, mehr nicht. Das ist das Problem bei solchen Sachen.... eine echte Anwendung haben sie nicht :-(
Es wächst und wächst und falls mir noch was einfällt ist die nächste Leiste schon zur 3.ten Platine fertig :-) Bisher: 3 x 16 Bit Timer verkettet zu 32 Bit + 1 Interrupt Ausgang für Z80 1: 4 bis 1:14 Teilbarer 1Mhz Takgeber per Multiplexer SD Karten Interface mit Atmega 328 8 zusätzliche Inputs seriell 8 zusätzliches Output seriell 1 x Display mit Controller 1 x 8255 zur "Verwaltung" des Ganzen. Blöd, dass der 8255 sich nicht on the fly umschalten lässt an seinen Ports. Jede Änderung des Config Wortes resettet die anderen Register auch. Und wenn mal Langeweile ist, das ist der Original Schaltplan des Spiels PONG von Atari mit TTL Gattern....
Christian J. schrieb: > Es wächst und wächst und falls mir noch was einfällt ist die nächste > Leiste schon zur 3.ten Platine fertig :-) > > Bisher: > > 3 x 16 Bit Timer verkettet zu 32 Bit + 1 Interrupt Ausgang für Z80 > 1: 4 bis 1:14 Teilbarer 1Mhz Takgeber per Multiplexer > SD Karten Interface mit Atmega 328 > 8 zusätzliche Inputs seriell > 8 zusätzliches Output seriell > 1 x Display mit Controller > 1 x 8255 zur "Verwaltung" des Ganzen. > > Blöd, dass der 8255 sich nicht on the fly umschalten lässt an seinen > Ports. Jede Änderung des Config Wortes resettet die anderen Register > auch. Das wurde Dir doch aber vorher gesagt. Warum baust Du auch die schrottigen Intel Teile ein die es schon gab bevor der Z80 mit seiner Peripherie entwickelt wurde? Stelle Dein Oszi woanders hin sonst hast Du bei Zeiten Zinn Spritzer auf dem Display. Das Paket ist angekommen..THX. Gruß, Holm
Leo? Hast Du ne Erklärung dafür? Definiere ich das hier global struct ihx_data { uint8_t len; uint16_t datalength; uint16_t recordsets; uint16_t adress; uint8_t record; uint8_t csum; } ihx; kommt das bei raus: 195 ;tools.c:79: ihx.datalength = 0; 00A1 21 00 00 [10] 196 ld hl,#0x0000 00A4 22r01r00 [16] 197 ld ((_ihx + 0x0001)), hl Definere ich es aber in der Funktion, also "dynamisch" explodiert das zu
1 | 192 ;tools.c:80: ihx.datalength = 0; |
2 | 00A3 21 00 00 [10] 193 ld hl,#0x0000 |
3 | 00A6 39 [11] 194 add hl,sp |
4 | 00A7 DD 75 EF [19] 195 ld -17 (ix),l |
5 | 00AA DD 74 F0 [19] 196 ld -16 (ix),h |
6 | 00AD DD 7E EF [19] 197 ld a,-17 (ix) |
7 | 00B0 C6 01 [ 7] 198 add a, #0x01 |
8 | 00B2 DD 77 F9 [19] 199 ld -7 (ix),a |
9 | 00B5 DD 7E F0 [19] 200 ld a,-16 (ix) |
10 | 00B8 CE 00 [ 7] 201 adc a, #0x00 |
11 | 00BA DD 77 FA [19] 202 ld -6 (ix),a |
12 | 00BD DD 6E F9 [19] 203 ld l,-7 (ix) |
13 | 00C0 DD 66 FA [19] 204 ld h,-6 (ix) |
14 | 00C3 AF [ 4] 205 xor a, a |
15 | 00C4 77 [ 7] 206 ld (hl), a |
16 | 00C5 23 [ 6] 207 inc hl |
17 | 00C6 77 [ 7] 208 ld (hl), a |
Die ganze Routine betreffend, wo der struct zigmal angefasst wird sind das 500 (!!!) Bytes. Absolut ineffzienter Code. Solte man da nicht lieber fast alle global machen, bzw. quasi Universalvariablen einführen, statt dynamische zu verwenden? Lege ich den struct in den Heap sieht es ähnlich aus wie unten. :-( Irre!
1 | ;f.c:3: void f(void) |
2 | ; --------------------------------- |
3 | ; Function f |
4 | ; --------------------------------- |
5 | _f_start:: |
6 | _f: |
7 | ld hl,#-9 |
8 | add hl,sp |
9 | ld sp,hl |
10 | ;f.c:14: ihx.datalength = 0; |
11 | ld hl,#0x0001 |
12 | add hl,sp |
13 | xor a, a |
14 | ld (hl), a |
15 | inc hl |
16 | ld (hl), a |
17 | ld hl,#9 |
18 | add hl,sp |
19 | ld sp,hl |
20 | ret |
21 | _f_end:: |
22 | .area _CODE |
23 | .area _INITIALIZER |
24 | .area _CABS (ABS) |
Übersetzung: Er kann es nicht reproduzieren. Bei ihm kommt optimaler Code raus.
:
Bearbeitet durch User
Ah, der Dolmetscher... naja, ich kann es umso besser reproduzieren, da ich das an mehren Stellen ausprobiert habe. Globale Vars erzeugen erheblich weniger Code als dynamische. Ob die Knapserei mit dem RAM also Sinn macht sei mal dahingestellt. Der Heap ist sonst gern meine Rettung aber auch der wird über Zeiger angesprochen. Nochmal deutlich: Definiert man einen Struct IN einer Funktion, so dass er dynamisch angelegt wird, so explodiert die Codemenge. Legt man ihn nach außen, samt seiner Variablen, so ist es prima.
Christian J. schrieb: > Ja, bitte? Du meinst, wir hätten bessere Glaskugeln als Du? Mit den Codefetzen, die Du hier immer abwirfst, kann man jedenfalls auch nicht mehr anfangen. A. K. schrieb: > Übersetzung: Er kann es nicht reproduzieren. Bei ihm kommt optimaler > Code raus. Genau. Dabei habe ich alle Informationen, die Christian geliefert hat, für das Beispiel verwendet. Christian J. schrieb: > Nochmal deutlich: Definiert man einen Struct IN einer Funktion, so dass > er dynamisch angelegt wird, so explodiert die Codemenge. Das ist mal wieder so eine falsche Behauptung die Du nicht bewiesen hast. Mein Beispiel zeigt, daß das Gegenteil richtig ist. Jedenfalls in diesem Einzelfall. Inzwischen habe ich mir mal Deinen Kot-Brocken (tools.c) angeschaut. Zuerst habe ich alles auskommentiert, was ich nicht kompilieren kann. Die Funktion, um die es Dir offensichtlich geht, ihx_decode(), ist aber größtenteils noch drin. Kompiliert mit Standard-Optimierung (sdcc -mz80 --opt-code-size -c) zu 0x1fe Bytes. Dann habe ich etwas umorganisiert und das umständliche hin- und herkopieren zwischen Hilfsvariablen beseitigt. --> Größe ist auf 0x107 Bytes, also fast nur noch die Hälfte, implodiert. Man könnte auch sagen, die Codemenge explodiert durch ineffiziente Programmierung. Ich vermute, Sinn der "struct ihx_data" soll sein, daß die gesammelten Hex-Record-Daten an andere Programmteile weitergereicht werden können. Deshalb habe ich die struct nicht in der Funktion deklariert (wäre ja sinnlos), sondern ihr einen Pointer übergeben. Codegröße jetzt 0x223 Bytes, also mehr als verdoppelt. Aber der Compiler kann ja noch optimieren, in dem man dem Register Allocator mehr Zeit läßt. Und hier bringt das besonders viel. Mit "--max-allocs-per-node 70000" kommt 0x1bf raus.
Leo C. schrieb: > Das ist mal wieder so eine falsche Behauptung die Du nicht bewiesen > hast. Mein Beispiel zeigt, daß das Gegenteil richtig ist. Jedenfalls in > diesem Einzelfall. Ich lass es. Ich bin blind, ich habe keine Ahnung und ich schreibe Blödsinn, den ich nicht beweisen kann. Der Codefetzen da oben ist auch sicherlich nur ausgedacht. Die Zusammenfassung der Mehrfachaufrufe und die Prüfsummenauslagerung habe ich inzwischen auch gemacht, allerdings etwas anders. Die erste Lösung muss funktionieren, optimieren kann man immer noch. Trotzdem gute Ideen dabei, ich lerne was dazu. Optimierung ist aus, die hat mir nur Murks mal erzeugt. Code der ohne Opt läuft und mit nicht mehr kann ja nicht so richtig sein. Danke für die Mühe! Mit --max-allocs-per-node 70000 kompiliert er inzwischen seit 13 Minuten.....
Und noch weiter tot optimiert, da der struct nicht mehr extern gebraucht wird sieht es dann so aus, was dem profi hoffentlich auch gefällt :-)
Christian J. schrieb: > Optimierung ist aus, die hat mir nur Murks mal erzeugt. Hältst du das nicht für ziemlich frech? Optimierung abschalten und dann über unoptimierten Code meckern?
Großer Dank an Holm für seine "Wundertüte" !!! Und man glaubt es nicht...... "Sowjetiski 8255 brrrauchen mehrrr Strom, Towarisch aber wenn sie erstmal warm sind dann laufen sie auch". Gehäuse scheint entweder aus gepresstem Schwarzbrot zu bestehen oder Bakellit. Und auch DDR "Klon" im 2,5er Raster spielt (nachdem der Kessel-Dampfdruck hoch genug war) hatte wie gewünscht trotz Probleme mit der Beinfreiheit im Sockel .... allerdings liegt die Stromaufnahme gesamt inzwischen bei dramatischen 550mA für die vielen NMOS Chips und der 7805 gerät langsam ins Schwitzen ohne Kühlkörper.
Christian J. schrieb: > Und man glaubt es nicht...... "Sowjetiski 8255 brrrauchen mehrrr Strom, > Towarisch aber wenn sie erstmal warm sind dann laufen sie auch". Gehäuse > scheint entweder aus gepresstem Schwarzbrot zu bestehen oder Bakellit. Diese ICs waren doch teilweise lichtdurchlässig, was zur folge hatte daß sie im prallen Sonnenlicht nicht mehr zuverlässig funktionieren und resetten auch mit dem Blitzlicht (richtiges, nicht LED...) möglich ist. :-) Schon mal getestet??? Glaube der Effekt war seinerzeit beim ostzonalen Taschenrechner "Konkret600" öfter zu beobachten. Reperatur nur an dunklen Arbeitsplätzen möglich...
@Christian: ich habe dir extra die braunen 8255A geschickt weil die "besser" aussahen. Mit der Stromaufnahme von NMOS ICs mußt Du freilich klar kommen, wobei diese Teile da noch relativ genügsam sind, weitaus mehr Strom wurde damals (TM) in deren Umgebung durch TTL ICs verbraten. Z80 wuren in der DDR auch später als CMOS Versionen gebaut, bin mir aber nicht sicher ob ich da was da habe.. Über die seltsame Farbe der russischen Vergußmassen wird "ostzonal" (danke IGOR für diesen Begriff, Du mußt wohl westzonal sein, Zone aber auf jeden Fall) schon öfter gerätselt und ich habe den Verdacht das das Zeug auch mehr Wasser aufnimmt als die gewöhnliche schwarze Vergußmasse die auch in der DDR benutzt wurde. Die Farbe ging von kackbraun bis zu spinatfahl.. Was fürs Auge sind russische Keramik-ICs in Schweinchenrosa/Gold.. Hier mal ein Bild (1,1Mb!) einer russischen LSI11/03 CPU, die rosa Teile sind 4kx1 DRAMs kompatibel zu I2107: http://www.tiffe.de/Robotron/PDP-VAX/E60/E60-01.jpg Einen lichtempfindlichen Taschenrechner hatte ich auch schon, allerdings war der komplett russisch, ein Konkret 600 dürfte so selten gewesen sein das kaum Jemand das Vergnügen gehabt haben dürfte das Teil reparieren zu dürfen. Gruß, Holm
Hi, hauptsache sie spielen und das tun sie. Bevor ich wieder teuer bestellen muss aus China überlege ich mir, ob der MK3801-04 auch wohl 5Mhz an seinem Timer und Clock aushält oder ob ich doch auf den -06 wechseln muss, der sehr selten ist? Ich brauche höhere Baudraten und eine schnellere CPU und da wären 19600 die nächste durch Taktverdoppelung. -06 bisher nur in China gefundenm, das dauert wieder 6 Wochen bis der hier ist. Da ich an dem "Homebrew Z80" immer noch Spass habe, jedenfalls mehr als an einem fertigen ARM, AVR usw, wo eh alles funktioniert wächst der Monitor inzwischen beachtlich an. Kompletter Kommandoparser ist fertig und wird grad " Size optimiert", wobei die 16Kb Grenze das Limit des Machbaren darstellt. Dass der sdcc bei --max-allocs-per-node 50000 auch locker mal 1kB bei 13kb Code einspart war mir auch neu, nur dauert das eben locker 10min zu kompilieren, so dass es nur für den "relaese" in Frage kommt. Fuer Frank haette ich noch nette Funktionen, die ich mir zu mcurses dazugeschrieben habe aber er scheint ja weg zu sein.....
Holm Tiffe schrieb: > Hier mal ein Bild (1,1Mb!) einer russischen LSI11/03 CPU, die rosa Teile > sind 4kx1 DRAMs kompatibel zu I2107: Ist das Ding mal mit der Axt repariert worden?
A. K. schrieb: > Holm Tiffe schrieb: >> Hier mal ein Bild (1,1Mb!) einer russischen LSI11/03 CPU, die rosa Teile >> sind 4kx1 DRAMs kompatibel zu I2107: > > Ist das Ding mal mit der Axt repariert worden? Nee, aber wahrscheinlich mies transportiert (bei der Verschrottung). Der RAM funzt aber noch (also kein Grund zum tauschen ,,hätte aber Ersatz da), die ganze Platine bzw. der gesamte Rechner geht wieder und man kann darauf das Tetris-Original oder auch SpaceInvaders spielen. Der Rechner ist zwar groß, aber das dazugehörige Doppelfloppy ist größer. http://www.tiffe.de/Robotron/PDP-VAX/E60/CPU-oben.jpg Gruß, Holm
Holm Tiffe schrieb: > Nee, aber wahrscheinlich mies transportiert (bei der Verschrottung). Die Block-C's sehen aber auch schon schön "knusprig" aus .... gut gelagert sicher. Und die TTL sind wohl mit dem Hammer in Position gebracht worden? Ich frage mich grad so wie es in deinem Keller aussieht oder der Garage? Ist da noch Platz fur ein Auto? Und hat deine Frau noch keinen Wutanfall bekommen "SCHMEISS DEN MÜLL ENDLICH MAL WEG!" Jedenfalls merke ich grad schmerzlich, dass es besser gewesen wäre den ROM/RAM Switch einzubauen, damit alles RAm ist nach dem Booten :-( Fast alle fertige Software ist so konstruiert, dass sie nur aus einem RAM laufen kann.
IGOR schrieb: > Diese ICs waren doch teilweise lichtdurchlässig, was zur folge hatte daß > sie im prallen Sonnenlicht nicht mehr zuverlässig funktionieren Leider nicht nur Sonnenlicht oder intensives Blitzlicht. Eine normale Schreibtischlampe bei der Fehlersuche reichte aus um absolut irreguläres Verhalten zu erzeugen :-(
Christian J. schrieb: > Holm Tiffe schrieb: > >> Nee, aber wahrscheinlich mies transportiert (bei der Verschrottung). > > Die Block-C's sehen aber auch schon schön "knusprig" aus .... gut > gelagert sicher. Die sind nur oberflächlich angekratzt, kein Grund zur Aufregung. > > Ich frage mich grad so wie es in deinem Keller aussieht oder der Garage? > Ist da noch Platz fur ein Auto? Und hat deine Frau noch keinen Wutanfall > bekommen "SCHMEISS DEN MÜLL ENDLICH MAL WEG!" Die habe ich nach 14 Jahren wilder Ehe erst in diesem September geheiratet und das hätte ich kaum getan wenn sie ein Problem mit dieser Art Hobby gehabt hätte. War halt sorgfältiger Testbetrieb... :-) > > Jedenfalls merke ich grad schmerzlich, dass es besser gewesen wäre den > ROM/RAM Switch einzubauen, damit alles RAm ist nach dem Booten :-( Fast > alle fertige Software ist so konstruiert, dass sie nur aus einem RAM > laufen kann. Loriot: Ach? Lernen durch Schmerz ist ein bewährtes Verfahren Christian.. Schaue mal Deinen Thread hier durch wie viele Leute Dir das anempfohlen haben. Gruß, Holm
Holm Tiffe schrieb: > Lernen durch Schmerz ist ein bewährtes Verfahren Christian.. Ja... ich müsste so ca 150 Drähte wieder lösen aus den Fädelkämmen, die proppevoll sind, 2 ICs rausholen, eines noch dazu bauen .... und wenn ich fertig wäre, würde nichts mehr funktionieren und das Ding in hohem Bogen über Nachbars Zaun gefeuert werden.....
Aber nur mal theoretisch..... ... 0 0x4000 0xffff ROM ----------- RAM ###########|########################## Wenn man es so verschaltet, dass jeder Schreib Zugriff aufs RAM geht würde der Monitor das Userprogramm direkt ab 0x0000 laden können. Seine eigenen Variablen würden dann oberhalb liegen, zb ab 0xF000 Dann kommt der Moment des Umschaltens ...... dann müsste quasi glöeichzeitig noch ein Sprung auf 0x0000 ausgeführt werden, was aber nicht geht, da der erste Portzugriff sofort umschalten würde. Der JP start würde nicht mehr erreicht werden. Mit dem SDCC ist es nicht möglich Code zu erzeugen, der beliebig liegen kann, daher kann sich der Monitor nicht selbst hochkopieren und von dort weitermachen, das ginge nur mit Asm. Alternativ wäre das ROM oben ab 0xC000 und den Umschaltbefehl im Userprogramm liegen zu haben. Dann würde nur der obere Teil wegklappen und RAM frei werden. geht aber nicht weil bei 0x0000 ein JP liegen muss bei Coldstart. Wie wird es nun wirklich gemacht?
Christian J. schrieb: > Wenn man es so verschaltet, dass jeder Schreib Zugriff aufs RAM geht Yep. Wie ich oben schon schrieb. > würde der Monitor das Userprogramm direkt ab 0x0000 laden können. Wie ich oben auch schon schrieb: Kopier als erste Aktion den Monitor über sich selber und schalte einfach um. Von dem Moment an läuft der Monitor aus dem RAM, ohne dass die CPU einen Unterschied sieht, und du kannst dann tun und lassen was du willst.
A. K. schrieb: > Wie ich oben auch schon schrieb: Kopier als erste Aktion den Monitor > über sich selber und schalte einfach um. Von dem Moment an läuft der > Monitor aus dem RAM, ohne dass die CPU einen Unterschied sieht, und du > kannst dann tun und lassen was du willst. Ok, kein Problem.... die Umschalteschaltung habe ich schon. Einfach einen freien I/O Decoderausgang mit einem Flip Flop aus freien NANDs (2 sind eh übrig) verheiraten und die WR Leitung mit in den CS für das RAM mischen.
Christian J. schrieb: > und die WR Leitung mit in den CS für das RAM > mischen. Nicht ganz. Du musst das ROM abschalten, nicht das RAM.
A. K. schrieb: > Von dem Moment an läuft der > Monitor aus dem RAM, ohne dass die CPU einen Unterschied sieht, und du > kannst dann tun und lassen was du willst. >Nicht ganz. Du musst das ROM abschalten, nicht das RAM. Klar, über den OE des ROMs... Naja..... Es müsste erstmal das userprogramm geladen werden und das wurde auf einen fixe Adresse 0x0000 kompiliert. Der IHx8 Loader könnte es beim Laden auf einen 0x4000 Offset setzen, so dass es im RAM über dem Monitor liegt. Dann muss das Userprogramm aber dahin wo der Monitor liegt und das geht nicht, weil der ja läuft....
Christian J. schrieb: > ROM/RAM Switch einzubauen Wenn schon Retro, dann nimm ein GAL zwecks Umschaltung. das sortiert dir die /CE für RAM oben und unten und das Eprom. Und das Flipflop ist auch gleich drin. Wenn du möchtest, macht es dir (später) auch die Bankumschaltung für mehr als 64k RAM. Und noch ein Tipp: Nimm ein Flash Eprom als Boot Medium. Dann kannst du dir sogar deinen Monitor noch bequem ändern.
Es gibt mehrere Varianten, ROM lesen und RAM schreiben bis zum umkippen eines Flipflops (durch I/O Request) ist eine Variante. Sowas habe ich mal in einem GAL gemacht als ich einen Z80 Emuf aufgebohrt hatte. title EMUF Decoder pattern IODEC revision C author Tiffe date 22.01.2011 CHIP IODEC GAL16V8 ;pin 1 2 3 4 5 6 7 8 9 10 RESET MREQ IORQ RD A15 A7 A6 A5 A4 GND ; ;pin 11 12 13 14 15 16 17 18 19 20 GND P0CS P1CS CTCS SICS Q0 ROMCS RA0CS RA1CS VCC EQUATIONS /ROMCS = /A15 * /MREQ * /RD * /Q0 /RA0CS = /A15 * /MREQ * Q0 /RA1CS = A15 * /MREQ /P0CS = /A7 * /A6 * /A5 * /A4 * /IORQ /P1CS = /A7 * /A6 * /A5 A4 /IORQ /CTCS = /A7 * /A6 A5 /A4 * /IORQ /SICS = /A7 * /A6 A5 A4 * /IORQ ; /EXCS = /A7 A6 /A5 * /A4 * /IORQ Q0 = /RESET * Q0 + /RESET * /A7 A6 A5 A4 /IORQ ; end of IODEC Gruß, Holm
Also: FF = Flipflop: Boot: Lesen:ROM, Schreiben:RAM RAM: Lesen/Schreiben:RAM In ROM/RAM Dekodierung ist kein Adressbezug drin. Sinngemäss, unoptimiert: RAM:/CS1 = CPU:/MREQ RAM:CS2 = high RAM:/OE = FF=Boot ? high : CPU:/RD RAM:/WE = CPU:/WR ROM:/CS = FF=Boot ? high : CPU:/MREQ ROM:/OE = CPU:/RD
Ich erinnere mich ganz schwach an meine 486er ASM Zeiten.... da war es so dass ein EXE File eine Tabelle mitführte, wo im Code die absoluten Sprünge sind. Der DOS Lader patschte dann einzelne jede Adresse nach dem Laden des Code, damit dieser relokatibel wurde.
>> Wenn schon Retro, dann nimm ein GAL zwecks Umschaltung.
GAL programm habe ich, aber keine Ahnung von den Dingern und keine
Software die Gleichungen einzugeben. Wäre aber noch besorgbar, wenn es
nicht DOS ist, da ich kein Windows mehr habe.
Christian J. schrieb: > Dann muss das Userprogramm aber dahin wo der Monitor liegt und das geht > nicht, weil der ja läuft.... Dann kompilier den Monitor auf die Adresse 0xC000. Nur die ersten Paar Bytes vom Resetcode werden ab Adresse 0 ausgeführt, kopieren 0x0000:3FFF nach 0xC000, schalten auf RAM um und springen in den entsprechenden Entrypoint in den Monitor an 0xCxxx. Dann ist 0 frei.
Der Gal Code oben ist kaputt, ich hätte ein paar Code Tags drum herum bauen müssen..., naja denke sowieso nicht das Du mit einem GAL hantieren willst. Gruß, Holm
A. K. schrieb: > FF = Flipflop: > Boot: Lesen:ROM, Schreiben:RAM > RAM: Lesen/Schreiben:RAM > In ROM/RAM Dekodierung ist kein Adressbezug drin. http://searle.hostei.com/grant/cpm/CPMSchematic1.2.gif Das erklärt immer noch nicht wie das Userprogramm da hinkommen soll wo noch der Monitor läuft.....
Christian J. schrieb: > http://searle.hostei.com/grant/cpm/CPMSchematic1.2.gif Yep, das hatten wir auch schon mal, irgendwo in einer CP/M Diskussion. UC6:C/D sind unnötig wenn die Kopier/Umschaltaktion sofort nach dem Reset erfolgt. Solange gibts zwar kein lesbares RAM, aber dafür brauchst du auch keines.
A. K. schrieb: > Nur die ersten Paar Bytes vom Resetcode werden ab Adresse 0 ausgeführt, > kopieren 0x0000:3FFF nach 0xC000, schalten auf RAM um und springen in > den entsprechenden Entrypoint in den Monitor an 0xCxxx. Dann ist 0 frei. Das geht deshalb nicht weil der Monitor ein Startup Programm enthält und bei der Erzeugung des IHX8 Files dann alles zwischen 0x0000 und 0xC0000 mit Nullen gefüllt würde und das geht dann nicht mehr in EPROM rein. Denn der programmer erwartet, dass die Ladeadressen sich mit denen des Chip Raumes decken. Erstmal Kaffee machen....... kopf raucht.....
Wenn es dir nicht gelingt, aus dem Monitor einen Binärklumpen von der Grösse des EPROMs zu bauen und den ins EPROM zu brennen, unabhängig davon was in dem Binärklumpen steht, dann ist Hopfen und Malz verloren.
A. K. schrieb: > Wenn es dir nicht gelingt, aus dem Monitor einen Binärklumpen von der > Grösse des EPROMs zu bauen und den ins EPROM zu brennen, unabhängig > davon was in dem Binärklumpen steht, dann ist Hopfen und Malz verloren. Das mag sein .... aber um das in ein Projekt einzubetten müsste ein weiteres programm geschrieben werden was den Code patscht und das will ich vermeiden, da das aufwendig ist. Der SDCC kann keinen relokatiblen Code erzeugen der während der Laufzeit die Positon ändert und fertig. Und ohne Startup geht es auch nicht. Und genau aus einem ähnlichen Grund musste Microsoft damals den Umweg über die EXE Patch Tabelle gehen, was die bestimmt nicht gemacht hätten wenn das alles so einfach wäre.
Christian J. schrieb: > Software die Gleichungen einzugeben. PLANII gibt es (noch), ist Freeware und gut. Kann dein SDCC keine Assembler Ausgabe? Wenn ja: Der M80 ist nach wie vor frei zu haben und kennt ".PHASE". Ruckzuck ist ein REL-File gemacht, das du deinem Linker dann vorwerfen kannst. Musst dich nur von dem Gedanken an einen monolithischen Monitor frei machen. Deine Probleme haben andere schon vor Jahrzehnten gelöst. Und hier im Thread sind dir Lösungen x-mal angeboten worden.
Doch es geht! Objectcopy erzeugt ein BIN File aus dem HEX waas keine Adressbezüge mehr enthält. Der Brenner kann sich das BIN an beliebiger Stelle reinholen, er lädt es per default an 0x0000 aber das kann ich ändern..... Ok...
Christian J. schrieb: > Der SDCC kann keinen relokatiblen > Code erzeugen der während der Laufzeit die Positon ändert und fertig. Muss er dafür auch nicht. Es reicht, wenn er in der Lage ist, Code für den festen Adressbereich 0xE000 (ich war vorhin von 16K ausgegangen) zu erzeugen und du in der Lage bist, diese 8KB ins EPROM zu programmieren. > Und ohne Startup geht es auch nicht. Muss es auch nicht. Nur dass der Startup dann ab 0xE0xx läuft. Sinngemäss (8K ROM), übersetzt für Adressraum E000-FFFF, unter der Annahme, dass die RST Befehle vom Monitor nicht verwendet werden: reset: ld bc, 0x2000 ;8KB ld hp, 0x0000 ;von Quelle ld de, 0xE000 ;nach Ziel ldir ;kopieren out (flipflop),a ;FF umschalten jp startup ;absoluter Sprung nach 0xExxx startup: ..hier fängt dein bisheriger Startup Code an.. Der Reset führt das ROM zwar ab 0x0000 aus, aber die paar Bytes bis zum JP sind adressunabhängig.
:
Bearbeitet durch User
Georg G. schrieb: > Deine Probleme haben andere schon vor Jahrzehnten gelöst. Und hier im > Thread sind dir Lösungen x-mal angeboten worden. Nur zum Verständis... niemand hier im Thread kennt das System was ich aufgebaut habe, damit von einer Codeänderung zum Test alles schnell geht. Das geht vom Compiler über eine Umwandlung des Codes bis zum Laden in den Programmer und auch noch ein Ladeskript. Ebenso kennst du nicht die Werkzeuge die ich verwende. Einen M80 Assembler mit rein zu bringen wäre unsinn. Der SDCC hat einen drin, der gibt auch Asm aus aber der ist nicht kompatibel mit anderen, hat seine eigene Syntax. Die von AK vorgeschlagene Lösung ist ok, das Monitorprojekt muss auf 0xc000 kompiliert werden, dann kann ich es in adressloses BIN umwandeln und dieses kann gebrannt und direkt kopiert werden, die Kopierroutine bringt es im Startup Code mit.
A. K. schrieb: > Muss es auch nicht. Nur dass der Startup dann ab 0xE0xx läuft. Genau so !!!!! Anbei mal das projekt...... das ist schon etwas gwachsen und kann daher nicht ohne weiteres in was anderers portiert werden.
A. K. schrieb: > Muss er dafür auch nicht. Es reicht, wenn er in der Lage ist, Code für > den festen Adressbereich 0xE000 (ich war vorhin von 16K ausgegangen) zu > erzeugen und du in der Lage bist, diese 8KB ins EPROM zu programmieren Das geht aufgrund des Aufbaus eines IHX8 Files eben nur über den Umweg es zu einem BIN File (COM Datei aus DOS) zu machen, da dann jeder Adressbezug weg ist für den Brenner. IHX8 will er da sehen wo es hin soll, zumindest meine China Möhre hier.....
A. K. schrieb:
Korrektur:
reset: ld bc, 0xFFFF ;64KB
ld hp, 0x0001 ;von Quelle
ld de, 0x0001 ;nach Ziel
ldir ;kopieren
out (flipflop),a ;FF umschalten
jp startup ;absoluter Sprung nach 0xExxx
startup: ..hier fängt dein bisheriger Startup Code an..
Setzt voraus, dass im ROM keine Adressdekodierung drin ist. Der JP muss
aus dem RAM laufen können, also wird das ROM einfach 8x hintereinander
in den Adressraum kopiert.
:
Bearbeitet durch User
Es würden nur kopiert: 0x0000-0x4fff nach 0xC000-0xcfff Darüber muss Platz bleiben für Stack, Vars und Heap. D.h. ein userprogramm ist auch begrenzt und kann nur 48k gross sein.
Christian J. schrieb: > Es würden nur kopiert: 0x0000-0x4fff nach 0xC000-0xcfff > Darüber muss Platz bleiben für Stack, Vars und Heap. > D.h. ein userprogramm ist auch begrenzt und kann nur 48k gross sein. Oder du platzierst dieses RAM unterhalb des Monitors. Zumindest jenen Kram davon, den du bei laufendem Programm nicht mehr benötigst.
Ich sags mal so.... Die Entwicklung des Monitors macht man eh im RAM, habe ich bisher auch so gemacht. Danach kommt er ins ROM rein, man ändert einige Codebezüge vorher im Quelltext und für den letzten Schritt kann man auch mal im Hex Code des Brenners etwas rumpatchen, da es nur einmal ist und einen Sprung anpassen ist echt nicht die Welt. Der SDCC ist ein starkes Werkzeug aber er schafft auch Probleme, die man ohne ihn nicht hätte, denn Sonderlösungen sind in Asm einfacher.
Hallo, Willst du volle 64 k für deine Userprogramme zur Verfügung haben, so benötigst du ein spezielles Bankswiching incl. HW, welches 64K Ram dadurch ermöglicht das minimal 1 page für die Kopierroutine und die notwendigen Mapgingroutienen zum laden des Programmes in andere als die Ramadressen zur Laufzeit laden und später ummapen, verschieben (selbstentpacken) kann. Als letzen Akt muss dieses Programm einen Zyklus anstoßen welcher die 64 KB linear adressiert und einen NMI auslöst um dann das nun im RAM befindliche Userprogramm zu starten, welches komplett ohne OS auskommen muss. Über die Sinnhaftigkeit eine solchen Vorgehens darf nachgedacht werden. Ich hatte damals meinen Monitor von Hand readressiert(an diese Adresse kopiert dissasmbliert und alle Adressen umgeschrieben AXXX-->> 4XXX und Bxxx-->>5xxx), so dass der Monitor sowohl ab A000 als auch ab 4000 im Ram laufen konnte. So konnte ich den Monitor je nach Notwendigkeit von verschiedenen Speicheradressen laufen lassen. Zusätzlich habe ich in Page4 (Kasettenpuffer des Atari) Eine Datenschaufel und Mappingroutine untergebracht, mit welcher ich vor dem Start jeden Programmes beliebige Rammanipulationen vornehmen konnte. So konnte ich Bootdisketten nach dem Booten nur durch Manipulation des Einsprungvectors (Biosdefiniert) auf der Diskette (Diskeditor) da zu veranlssen nach dem Bootvorgang nicht zu starten sondern viel mehr meinen Monitor nach zu laden. Dabei wurde freilich ein Teil des Ram überschrieben aber ich habe alternierend beide Monitorversionen aufgerufen und konnte so das komplette binär Image des jeweiligen Programmes in ein Dosformat umwandeln. Egal wo im RAM es residierte. Namaste
:
Bearbeitet durch User
hallo, auch nicth schlecht. das der sdcc aber kein Mapping unterstützt müsste das auch wieder Sache des Monitors sein, wo dann endgültig die Frage nach Asm entstehen würde. und dann kommen wir auch zu meinem anderen hobby.... wenn ich einen 1.8l VW Motor auf 200PS bringen will, dann kann ich tausende dafür ausgegen seine Teile zu verändern, scharfe Nockenwelle, Kopf planen, Verdichtung erhöhen, Ladedruck ändern, Kanäle schleifen, Abgasdruck niedriger machen usw. Oder ich lass den Shice bau einfach einen G60 Motor ein mit 200PS... Sprich: Dann nehme ich keinen Z80 mehr sondern ARM...
Christian J. schrieb: > Oder ich lass den Shice bau einfach einen G60 Motor ein mit 200PS... > Sprich: Dann nehme ich keinen Z80 mehr sondern ARM... Dabei lernst du nur wie man den richtigen Chip / Motor auswählt. Aber nicht wie ein Motor/ Prozessor funktioniert. ASM ist Maschinenorientiertes Programmieren, nicht modern aber sehr lehrreich und der imho wesentliche Aspekt sich mit derart alter Technik zu befassen. egal ob Oltimerautomobil oder Oltimercomputer. Und über Geld und Zeit sollte man dabei schon gar nicht nachdenken. Es kann nur der persönlichen Kunst zugerechnet werden und die kommt von Können sonst hieße sie "Wunst". PS. Sehr langsam gewinnt auch mein Retroprojekt an Form UB8830D +128 KB SRAM (4*32)+2 *8 KB ROM. Ich weiss SRAM ist nicht wirklich Retro und auch das geplante GLCD/PS2 ist es nicht. Aber eine gepollte Tastatur, das habe ich schon mal gebastelt und ein (F)BAS Grafikausgang ... grr will ich nicht. Also lass ich dass. Namaste
:
Bearbeitet durch User
Ok, fnde ich gut. Und da Du ja sicher ein guter lehrer bist kanst du mir ja zum Üben mal diese Routine für die ich so ca 25 Minuten gebraucht habe in Asm codieren :-) Tick....tack.......Stoppuhr läuft...... ! Los !!!
1 | // Konvertiere Ints nach Hex Zeichen |
2 | void xtoa(uint16_t val, uint8_t *buf) |
3 | { |
4 | char *p; |
5 | char *first; |
6 | char temp; |
7 | unsigned dig; |
8 | |
9 | p = buf; |
10 | |
11 | firstdig = p; |
12 | do |
13 | { |
14 | dig = (unsigned) (val % 16); |
15 | val /= 16; |
16 | if (digl > 9) |
17 | *p++ = (char) (dig - 10 + 'a'); |
18 | else |
19 | *p++ = (char) (dig + '0'); |
20 | } while (val > 0); |
21 | |
22 | *p-- = '\0'; |
23 | do |
24 | { |
25 | temp = *p; |
26 | *p = *first; |
27 | *first = temp; |
28 | p--; |
29 | first++; |
30 | } while (first < p); |
31 | } |
1 | conv8 push af ; convert 8 bit in A to |
2 | and 0fh ; 2 ascii numbers in DE |
3 | add a,90h |
4 | daa |
5 | adc a,40h |
6 | daa |
7 | ld e,a |
8 | pop af |
9 | rrc a |
10 | rrc a |
11 | rrc a |
12 | rrc a |
13 | and 0fh |
14 | add a,90h |
15 | daa |
16 | adc a,40h |
17 | daa |
18 | ld d,a |
19 | ret |
..hilft das wirtschaften? Solche Routinen finden sich fertig in allerlei Literatur.. Gruß, Holm
@ Holm, perfect @Christian, von der und Grundstruktur wäre mein Ansatz der selbe gewesen, lediglich die Anwendung der Dezimalkorrektur kannte ich von der 6502 so nicht, was bei mir einen bedingten Sprung erfordert hätte falls nibble >09 ausfällt. eine step by step übersetzung von C ist hier freilich mit Spatzen auf Kanonen gesch.... ach nein andersrum. Fehlt noch eine Zählschleife und ein Ein- und ein Ausgabepuffer um auch größere (mehrstellige) Hexen zu konvertieren. Aber das kannst du ja schon selbst? ;)
:-) Habe ganz andere Sorgen derzeit nach .....moment.....10h Programmieren heute ohne Pausen. Der Monitor "DeLuxe" ist im ROM, gefühlt 50 EPROMs gelöscht und neu gebrannt heute, bzw war der Löscher nie aus und wurde immer wieder neu bestückt, da das im RAM nicht zu testen ging. Damit das geladene File nicht verloren geht, habe ich 2 Resets eingebaut, einen über NMI, der zurück in den Monitor führt aber das Programm jederzeit neu startbar ist und einen Normalreset der es sofort wieder startet. Allerdings bemerkt, dass ein Nicht-Nullen des RAMs vor dem Laden zu einem Programmabsturz des geladenen Programms führt. Intel Hex füllt ja nur dort auf, wo was ist. Ich vermute mal, dass es mit nicht initialisierten Vars zu tun hat. Je größer das Ganze wird umso heikler bei Änderungen, dass plötzlich auch was anderes nicht mehr funktioniert...... Theoretisch kann ich jetzt mehrere Programme laden und sie einzeln starten und wieder beenden. Leider gibt es keine virtuellen Memory Manager und eine MMU auf dem System, das würde einiges vereinfachen.
...Weshalb ich in meiner HW 2*8 KB EEPROM (statt EPRROM) beschreibbar sowie mit Dipschaltersreibschutz vorgesehen habe. Dazu (beliebig) mapbare 2* 2*32 KB RAM. So kann ich sowohl vom ROM als auch vom RAM je ein Backup halten. o.T. @ Holm Das "BM 200" befindet sich bereits in einem dieser EEPROMs. Nur bin ich noch an der MMU. Der TFT Maximite hat mir das BinFile in Pages geteilt an einen ATMEGA32 auf dem Brotbrett geschickt und dieser hat es Byteweise ins 28C256 kaligrafiert, inclusive Verifycation. Der TFT-Maximite wird mir auch als Serialterminal dienen.
Du hast mich da auf eine Idee gebracht..... lese mir grad den Abschnitt über den "Z80 DMA Controller" durch..... damit wäre es ohne weiteres möglich eine MMU aufzubauen, mehrere Pages zu haben usw. Allerdings würde das Ganze dann auch größenordnungen annehmen, die mit "Hobby" nicht mehr viel zu tun haben sondern mehr Richtung "Vollzeitbeschäftigung" gehen. Und Z80 mit S100 Bus gibt es ja schon in Form des N8VEM.
Holm Tiffe schrieb: > Einen lichtempfindlichen Taschenrechner hatte ich auch schon, allerdings > war der komplett russisch, ein Konkret 600 dürfte so selten gewesen sein > das kaum Jemand das Vergnügen gehabt haben dürfte das Teil reparieren zu > dürfen. Wir haben damals russische Taschenrechner in der Fa. gestellt bekommen. Solche mit Solarzelle. Ja, die Dinger waren lichtempfindlich. Kam jemand ins Zimmer, sagte "Warum habt ihr das Licht an, spart Strom!" und schaltete das Licht aus. In der Folge war das Ergebnis seitenlang eingetippter Listen weg. Wir haben da oft geflucht.
@Leo: Du hast auch keine Erklärung dafür, dass sich Bytes bei einem Programm während der Laufzeit überschreiben, je dichter das Datensegment am Code Segment liegt? Näher als 2kb, dann geht es los, dass sich "wahlos" Bytes überschreiben und den Absturz verursachten bzw chaotische Ausgaben auf dem Schirm?. Habe das sohar mit Checksummen überprüft nach dem Laden des programms und nach dem Starten. Keine Erklärung, Code siege gut aus aber je kleiner ich ihn mache (unbenutzte Teile mit einkompilieren), desto besser wird es. Unter 12kb ist es ganz weg und wenn man die Daten ab 0xc000 legt, wenn der code bei 0x8600 endet. Das sind s9 Dinge die dann Stunden dauern....... weil sie nicht erklärbar sind ohne genauen Debugger. Aber aufgetren ist es schon öfter mal, nur habe habe ich es am "Haken"
Christian so lange Du nicht sicher bist das Dein Code hinsichtlich memory allocation und deallocation alles richtig macht, würde ich sehr leise nachfragen.. Gruß, Holm
Holm Tiffe schrieb: > Christian so lange Du nicht sicher bist das Dein Code hinsichtlich > memory allocation und deallocation alles richtig macht, würde ich sehr > leise nachfragen. Ich habe derzeit keine dynamische Speicherallokation drin... aber die Interruptts mit ihren Ringpuffern....... PS: Es IST der TX Ringpuffer oder der TX Interrupt.... aber nur sporadisch. Da scheinen "kritische Zustände" zu entstehen.
A. K. schrieb: > Korrektur: > reset: ld bc, 0xFFFF ;64KB > ld hp, 0x0001 ;von Quelle > ld de, 0x0001 ;nach Ziel > ldir ;kopieren > out (flipflop),a ;FF umschalten > jp startup ;absoluter Sprung nach 0xExxx > startup: ..hier fängt dein bisheriger Startup Code an.. Unvollständig korrigiert! Das Doppelregister heißt HL. Bei der ersten Variante habe ich noch an einen Tippfehler geglaubt.
Route 66 schrieb: > Das Doppelregister heißt HL. Touché ;-) > Bei der ersten Variante habe ich noch an > einen Tippfehler geglaubt. War es auch. Ich schreib den Kram ja nicht komplett neu, bloss um ein paar Werte zu korrigieren.
Interessant....
1 | //////////////////////////////////////////////// |
2 | // ISR: Uart TX Sendepuffer ist leer |
3 | // putchar()füllt ihn wieder |
4 | // |
5 | // Veränderte globale Variablen: |
6 | // tx.bytes_to_send, tx.rd_ptr |
7 | |
8 | void int_sti_transmit_buffer_empty(void) __interrupt |
9 | { |
10 | // Sind noch Zeichen im TX Buffer? |
11 | if (tx.bytes_to_send > 0) { // ja..... |
12 | STI_UDR = tx.buf[tx.rd_ptr]; // Byte einschreiben |
13 | tx.rd_ptr = (tx.rd_ptr +1) & tx.mask; // Read Pointer rollen |
14 | tx.f_idle = false; |
15 | tx.bytes_to_send--; |
16 | } |
17 | else { |
18 | // nein, letztes Zeichen ging grad raus |
19 | tx.f_idle = true; |
20 | } |
21 | |
22 | if (tx.rd_ptr>(BUF_SIZE+5)) { |
23 | __asm |
24 | halt |
25 | __endasm; |
26 | } |
27 | |
28 | EI; |
29 | } |
Der HJALT dürgfte eigentlich nie erreicht werden. Hämmert man aber ordentlich auf den Tasten und lässt ihn viel Test ausgeben zb im DUMP Mode, so stürzt er sich doch in den HALT. Obwohl das die einzige Stelle ist wo diese Variable verändert wird..... Faszinierend.....
öhm Christian, programmierrter Absturz? "ASM halt" hält och wohl den Z80 an? wie soll es dann weitergehen? Hier wäre es doch wohl sinnvoller die aufrufenden Schicht rechtzeitig per Busy-flag darüber in Kenntnis zu setzen, dass sie den TX-Puffer nicht weiter befüllen sollte, bevor der Puffer nicht wieder genügend Kapazität aufweist. Idealerweise ist der Puffer etwas größer als der gröste Block, so kann man den Puffer auch blockweise füllen und warten bis das Busy-Flag wieder gelöcht wurde wenn der block draußen ist und muss nicht vor jedem Byte das Busyflag testen. Werden nur einzelne Bytes oder strings variabler länge übertrragen, so bleibt einem das allerdings nicht erspart. Für eine Blockweise Übertragung könnte man aber auch be leerem Puffer den Puffezeiger verbiegen und die Blocklänge angeben. So muss man nur das Busyflag setzen und nach der Übertragung selbiges zurücksetzen. Vorteil, du hast Kontrolle über den Speicher, der Puffer kann für die Einzelzeichen übertragung klein gehalten werden. und ein TX-bufferoverflow wird sicher vermieden. Achja und schneller gehts auch. ;)
Winfried J. schrieb: > wie soll es dann weitergehen? Soll es doch überhaupt nicht. Das ist der Exit für "dies hätte eigentlich nicht passieren dürfen". Das ist das Äquivalent zum assert() Makro, bei dem es im Fehlerfall auch nicht weitergeht.
Ich stehe etwas vor dem Unerklärlichen.... so ein Verhalten habe ich noch nie erlebt....... egal wie man es dreht..... er "spinnt". Lege ich das Datensegment schoen weit weg ist die Welt wieder in Ordung..... aber nicht über den Code, dann dreht er durch.
Christian J. schrieb: > Ich stehe etwas vor dem Unerklärlichen.... so ein Verhalten habe ich > noch nie erlebt....... egal wie man es dreht..... er "spinnt". Das ist normal. Der typische Zustand bei einem hartnäckigen Fehler. Nach der Erleuchtung bessert sich das wieder.
Hat mal jemand eine JTAG Schnittstelle für mich? Und einen Spource Level Debugger? Und wenn es geht auch bitte eine MMU mit Speicherschutz?
Das letzte Mal in diesen Zustand der Verzweifelung brachte mich der Cubietruck. Ewig Abstürze, 30 Minuten, dann wieder und dann immer öfter. Bis ich nach 3 Tagen Suchen mal die FEX durchging, das ist die Konfiguration für die CPU, die sie sich reinzieht und entdcekte dass CAS und RAS Time viel zu kurz sind, weil der Chinese da eine zu schwache Brille auf hatte. Und dann lief es, bis heute, seit 3 Monaten ohne Reset durch....
Hall0 Christian, Du wolltest Retro deine Weihnachtsmannwunschliste hast du vor geraumer Zeit... aber wir wollen ja nicht in ofenen Wunden rumstochern. Hat mal jemand Salz und Pfeffer? ich sollte noch ein bischen nachwürzen. jetzt nach dem ich mit meiner MMU eigentlich fast durch war kam heute ein Päckchen von segor mit darin 2 Stück 62C8128 (128KByte SRAM 70ns)darin. Juhu ich fang vor dem löten noch mal an zu zeichnenen das spart mir gefühlte 100 leitungen mit ebenso gefühlten 300 lötstellen und jede Menge Platz auf der Platine eue Konfiguration 2*8KB EEPROM und 2 *128 KB RAM Der gesparte Plat wird genutz die beim externen Speicher am UB8830D (4*2KB) nichtnutzbare RAM-Adressen 0-7FFF umzumappen dort könnten dann Puffer und Parameter zur Speicherverwaltung hin. Namaste
:
Bearbeitet durch User
@ Christian o.T. In meiner Lehrzeit ab 1977 haben wir Elektriker über die Blechkloper gelacht. Wenn die ihren ersten Versuch wieder begannen auseinderzureißen haben wir das Werkzeug ausgepackt, die 1-2 h davor haben wir mit nachdenken und diskutieren verbracht. Wir waren dann meist um 15 Uhr fertig und haben die Doppelkopfkarten ausgepackt, während die Blechklopper sich ranhalten musten ihren 3. Versuch bis Feierabend fertig zu bekommen. So ging das das gesammte erste Lehrjahr. Über welchen Berufsstand dürfen wir heute schmunzeln? Aber ich bewundere deine Ausdauer und Hartnäckigkeit. Namaste
:
Bearbeitet durch User
Christian J. schrieb: > und entdcekte dass CAS > und RAS Time viel zu kurz sind, weil der Chinese da eine zu schwache > Brille auf hatte. ne der hatte es eilig wie du ;) Mist schon wieder steckt mein Finger drin. Schnelllll wech hier.
:
Bearbeitet durch User
Was zur Hölle hat diese Routine damit zu tun dass das Programm entgleist und sich selbst zerstört? Kommentiere ich die aus vorne läuft es wieder.... Ich dreh noch ab.... !!!!! Sch.... Z80 ! Ähm.... schöner Z80 :-)
1 | // Einstellungen für SPI |
2 | void init_spi() |
3 | { |
4 | CLI; |
5 | // Interrupts ausschalten (Figure 8, MK3801 Manual, ind. IERB Register) |
6 | STI_PVR = MODE2_VECTOR | STI_IERB; |
7 | STI_IDR = STI_IDR & ~( (1<<1) | (1<<2) | (1<<3) | (1<<6) | (1<<7) ); |
8 | |
9 | // Data Direction einstellen (Figure 14, MK3801 Manual) |
10 | STI_PVR = MODE2_VECTOR | STI_DDR; |
11 | STI_IDR = STI_IDR | SDO | SCLK | SS; // 1 = SDO, SCLK, SS = Outputs |
12 | STI_IDR = STI_IDR & ~(SDI | WAIT); // 0 = SDI, WAIT = Inputs |
13 | |
14 | // Vektor zurückschreiben |
15 | STI_PVR = MODE2_VECTOR; |
16 | |
17 | // Voreinstellungen |
18 | STI_GPIP = STI_GPIP | SCLK; // Clock = HIGH |
19 | STI_GPIP = STI_GPIP | SS; // SS = HIGH |
20 | STI_GPIP = STI_GPIP & ~SDO; // SDO = 0 |
21 | EI; |
22 | } |
tja, cli... unterbindet deine rx tx IRQs erst nach ei (sei) kann es weitergehen nestet loop ?
Kann es sein, dass du mit dem abschliessenden EI deine geistige Gesundheit riskierst? Weil der Code die Interrupts zu diesem Zeitpunkt lieber noch nicht einschalten sollte?
:
Bearbeitet durch User
A. K. schrieb: > Kann es sein, dass du mit dem abschliessenden EI deine geistige > Gesundheit riskierst? Die Ints sind da schon an, alle..... die Tabellen initialisiert, der Vektor steht, Z80 Im2 ist gesetzt usw.....
nach halt erwarte die ZPU einen Interupt! ist dieser gesperrt durch cli cli+halt = end of work darum vor halt interupts erlauben ! hat mir gerade das Schlaue buch verrraten
Du, das hat damit nichts zu tun...... halt schaltet eine LED ein, wollte nur wissen wo der Code entgleist..... ohne gescheiten Debugger mit Breakpoints ist das eine Sache nach der Nadel im Heuhaufen. Eines habe ich schon gefunden: Hardware IO Zugriffe in einer ISR sollten unterbleiben, wenn der IO Port auch im Hauptprogramm öfter benuzt wird. UNd dieser MK3801 ist heimtükisch..... der hat indirekte register und wenn dir da ein INT zwischenhaut während gerade die beiden Befehle abgearbeitet werden, dann kann es sein dass der INT ins Nivana geht. STI_PVR muss immer auf 0x40 stehen, sonst zischt jeder INT irgendwo hin. Dummerweise braucht man STI_PVR auch für jede Adressierung, so dass ich 0x40 sicherheitshalber immeer wieder reinschreibe, auch wenn es zu viel sein sollte.
Hallo intressanter Thread. Ich habe jetzt nicht alles durchgelesen, ist schon etwas viel :-) mich würde eines interessieren. Wenn man so einen 68000er single board computer hat. Wie soll man da die Software drauf bringen, und vielleicht sogar debuggen können? Klar, der GCC kann Code für den 68k erzeugen, aber wie weiter? Ich hätte nämlich hier noch ein paar 68332 und zwei 68020. Könnte man auch mal wieder was machen damit (wäre eine interessante Nutzung der Festtage). Gruss Tobias
Tobias Plüss schrieb: > (wäre eine interessante Nutzung der > Festtage). Wohl eher eine des nächsten frühjahres.... habe 2 68000 hier in keramik, die sind noch deutlich komplexer als nur ein z80.
Ich sitze hier nur vor der Glaskugel und fange Fetzen auf, der Zusammenhang konnte ja durchaus gegeben sein. Ausschließen kannst nur du das. Wenn die LED dir ein Halt signalisiert bist du ja informiert. Aber wenn du vor Halt die Interrupts wieder erlaubst da ja, eh nichts anderes bearbeitet werden kann, so kannst du auch mit einem tx interupt halt wieder aufheben. wenn das Schubsregister der sio wieder leer ist. Trotzdem würde ich noch mal über eib Busy_Flag für die SIOTX nachdenken;) Halt von dauerhaft ine einer Pufferroutine zu benutzen ist keine Notbremse sondern ein Strick zum (dran) aufhängen kommt sowas in den Verkauf brauchst du weder einen neuen Verkäufer noch einen guten Anwalt. Es genügt der nächste Baum. SIl 3 o.k. aber was ist mit der Ausfallsicherheit?
Tobias Plüss schrieb: > Wie soll man da die Software drauf bringen, > und vielleicht sogar debuggen können? Genauso wie hier im Thread bei seiner Z80. Bootloader schreiben, der ein Programm von de Seriellen ins RAM läd und ausführt. Rest folgt dann. Debuggen: Triviales Ausgabemedium z.B. wie hier per LED-Anzeige.
Sodele, Das Problem scheint gelöst. Alles wieder zurück, 2 Ringpuffer usw. Ursache scheinen INT Konflikte gewesen zu sein, denn ein Codeumbau mit weniger Routinen und nur noch ganz wenig EI und CLI brachte dann das Ergebnis. Genau weiss ich es nicht aber manchmal hilft es etwas anders zu machen. Allerdings habe ich hier auch kein Vollduplex und das merkt man eben, bin das anders gewohnt. 680000 ist nicht mein Ding, eher ein Industrieprozessor, der zu viel drumherum braucht und wo es zu wenig für gibt.....
Hmm als triviales Ausgabemedium könnte man den UART nutzen, habe noch MC68681 hier, im violetten Keramikgehäuse mit Goldbeinen. Könnte man dafür verwenden :-)
Ja Ja diese Ressourcenprotzerei macht schlechte Gewohnheiten. Aber bescheidene Ressourcen erfordern Sparsamkeit und Disziplin. Und der Mangel an gewohnten Tools macht demütig. ;)
der 68000 ist einfacher zu handeln als ein Z80 dünkt mir so, der Proz ist zwar "komplexer" aber er ist regelmäßiger. Die Sache mit gcc auf MC68000 habe ich doch gerade erst gemacht (siehe Gcc-Thread). An einem 68681 im lila Gehäuse hätte ich Interesse, ich habe lila MC68010 auf den beiden KatCe Boards stecken...bräcuhte ich dann noch MC68230 in Keramik..vergeßt es.. Gruß, Holm
Hallo Holm einen violetten 68681 im Tausch gegen einen keramischen 68000? oder einen lila 68010? :-)
Christian J. schrieb: > Und einen Spource Level Debugger? Such Dir ein Stück Hardware, welches von Sigrok unterstützt wird. Und dann startest Du den Z80-Protokoll-Dekoder: http://sigrok.org/wiki/Protocol_decoder:Z80 Feine Sache, das! Jens
Tobias Plüss schrieb: > Hallo Holm > > einen violetten 68681 im Tausch gegen einen keramischen 68000? oder > einen lila 68010? :-) Nana....... violett? Also meiner hier, das ist ein Prachtbursche :-) Nen richtiger Frauenschwarm :-) Echt ADO, mit der Goldkante. Für den 68000 würdee ich ein uCLinux aufsetzen, sehr kleines Board mit wenig Chips aber es funktioniert: http://www.bigmessowires.com/2014/11/17/68-katy-68000-linux-on-a-solderless-breadboard/
A. K. schrieb: > Tobias Plüss schrieb: >> Wie soll man da die Software drauf bringen, >> und vielleicht sogar debuggen können? Hi, vielllicht erstmal überlegen, was du willst und vor allem wieviel zeit dabei draufgehen soll? Basteln abends und Frauchen beglücken geht selten zusammen. Wobei sich bei mir das Thema eh nicht stellt als Single :-) Echter Computer? Video, Audio, Keyboard, Speicher, Maus? ==> 1-2 Jahre Aufwand ohne Vorlagen Noch ein CP/M Abklatsch, der x.te? Oder sowas hier, was einfach nur zum Programmieren da ist? LEDs, Timer, eine Anzeige, SD Karten-Interface, ein paar TTL's zum Schalten und Takten? Terminal statt Monitor und Keyboard. Wahnsinnig intelligente Anwendungen wie 4 Gewinnt gegen sich selbst, Game of Life für 80x40 Display oder er berechnet eben primzahlen...kommt zwar nicht weit aber egal. Ich bin seit gut 2 1/2 Monaten dran von Null an und habe noch ein Extension Board dazu gebaut und inzwischen 3/4 verkabelt aber noch kein Programm für. Musst du wissen, der 68000 ist sicherlichn die bessere "C-Maschine". Ausrüstung: - Universal EPROMMER, ca 69 Euro und Löscher - EPROM und RAMS - Linux als Programmiersystem und Terminal (nix Windoofs!) - USB/RS232 Adapter für 2 Euro aus der Bucht und das übliche Lötgeraffels....
Last entry für heute: Ich habe die Ursache für das "seltsame Verhalten" gefunden. Da wird niemand drauf kommen und auch ich wäre es wohl nie, wenn ich nicht Holms Wundertüte mit den U880's ausprobiert hätte ..... Die NMOS CPU mit dem "schönsten Aufdruck in gelb" war im Ar.... ! Irgendwie spramng die so 1min nach warmwerden munter im Programmspeicher umher. Mit den U880 und den anderen NMOS und CMOS spielt es wieder einwandfrei. Arrrrrgghhhhhh !
ha! Das war damals nichts außergewönliches meist war ein Bonddraht abgerissen lag aber noch am Ship an. Wurde es dann wärmer ..... Übigens habe ich später soetwas bei LED wiedergesehen welche eigentlich nicht für den Blinkbetrieb gedacht waren.
@Tobias: Nee lass ma, ich lasse die Dinger in ihrer natürlichen Umgebung.. Gruß, Holm
Holm Tiffe schrieb: > @Tobias: Nee lass ma, ich lasse die Dinger in ihrer natürlichen > Umgebung.. Trotzdem würde ioch bei den Eproms mal die Jalousien runterlasssen, damit die Sonne nicht so rein scheint. Und auch mal Staub wischen auf den Fluren....
Mach Dir keine Gedanken, der Inhalt da ist eh nur temporär. Mehr als der Debug-Monitor FBUG ist da nicht drauf, übrigens in C geschrieben, von Motorola vor Jahrzehnten. Gruß, Holm
Hey Holm, woher hast du den FBUG? liegt der als Source vor? ich wär da interessiert.
Guck mal hier: http://www.tiffe.de/Robotron/Motorola/fbug das ist ein Arbeitsstand von vor 3 Monaten oder so :) Woher ich den habe? Keine Ahnung, früher mal ftp.funet.fi oder so... Die Anpassung für die Vektorbasisregister-Geschichte und Trap Stackframe für den 68010 habe ich da vor Jahren schon mal eingebaut, 68010 war zwar vorgesehen aber noch nicht fertig. Danach ging mit dem gcc kein Coff mehr und ich habe nochmal umgebaut. am gcc/ld ist da sicherlich noch viel Arbeit, aber der Kram funzt erst mal. Den letzten Stand müßte ich aber auch erst hoch laden, üb den Stand auf dem Server lief mal eine Problemdiskussion in diesem Forum, Abteilung gcc.. Gruß, Holm
Jadoch kenne ich, ist aber nur noch ein blasser Schatten seiner selbst. Den Finnen müssen da mal massenhaft Maschen runter gefallen sein. Gruß, Holm
Erinnerte mich an 1995 als das Internet noch von der gebildeten Schicht bevölkert war, es keine 10.000 Webseiten weltweit gab, das Usenet was noch keine Müllhalde war und einen anon.penet.fi mit dem man nette Sachen machen konnte.
Hi, weiss einer, wie man für einen Zufallszahlengenerator "zufällige" neue Startwerte erzeugen kann? Mist, ein Computer macht ja taktgenau jedesmal das Gleiche :-( Habe mir schon überlegt einen schnelllaufenden Timer anfangs auszulesen aber der Auslesewert ist auch immer der gleiche obwohl der mit 3,9 Mhz rennt.... wie der Rest eben auch, Takt für Takt :-(
Beim Z80 kannst das R-Register auslesen. Wenn das allerdings immer zur gleichen Zeit nach dem Reset erfolgt, bringt das auch nichts.
Jens schrieb: > Beim Z80 kannst das R-Register auslesen Rennt das automatisch los, bzw ist das eine Art Zaehler?
Christian J. schrieb: > Rennt das automatisch los, bzw ist das eine Art Zaehler? Ja. Zählt M1-Zyklen.
Yep, kommen immer andere Werte.... und da ich das Programm per Hand starte nie der gleiche zu Anfang :-) Nach Reset aber sind es immer die gleichen, Wert für Wert, nur dass der Rechner nich weiss, wann ich "start" eingebe hilft hier.
1 | for (k=0;k<20;k++) { |
2 | __asm |
3 | ld a,r |
4 | ld (_rreg),a |
5 | __endasm; |
6 | addstr(" "); addint(rreg); |
7 | } |
8 | press_return(); |
Christian J. schrieb: > weiss einer, wie man für einen Zufallszahlengenerator "zufällige" neue > Startwerte erzeugen kann? In dem Du beim Reset einen Zähler startest und beim ersten Tastendruck oder RS-232-Empfang ausliest. Ausgehend von der Annahme, dass Tastatur bzw Terminal von einem Menschen bedient werden, ist diese Zeitspanne nicht deterministisch. Heimcomputer haben hierzu die VSyncs gezählt.
Ja, danke! Schade, dass der Z80 nicht ein wenig fixer ist denn sonst würde diese Simulation hier deutlich flüssiger laufen. Und da ist schon vieles im Code optimiert worden..... jedenfalls ganz nett wie es "lebt" beim Game of Life :-) https://www.youtube.com/watch?v=0t41d-4tkYQ&feature=youtu.be
Moin und Frohe Weihnachten! Weiss jemand ob eine "normale" Z80 CPU (die 6mhz Varianten habe ich nicht) und vor allem der Mk3801-04 4.9 Mhz aushalten? Die 9600 baud sind einfach zu langsam und auch die CPU könnte etwas flotter unterwegs sein. Der Mk3801-06 ist kaum zu kriegen und wenn dann nur sehr teuer für über 25 Euro. Wenn mit 3.68Mhz 9600 sind sind, müssten mit 4.9Mhz 14.400 baud möglich sein. Schon nett... aber wird man etwas gaga wenn man da zu lange drauf schaut, was sich da so alles "entwickelt", trotz winziger Auflösung im Vergleich zu heutigen Computern, die das in Echtzeit simulieren. https://www.youtube.com/watch?v=R_dAzB3HNLg
Ich habe jetzt keine Lust mich durch das Datenblatt des STI durchzugraben (weil ich ja auch keinen besitze) aber eine SIo konnte relativ problemlos auch 19200 Baud (mit einem CTC Kanal als Baudratengenerator). Ich kann mir nur schwer vorstellen das 9600 die Grenze für die STI sein soll.. Probiere einfach aus was die 4Mhz Chips noch können, die werden nicht gleich kaputt gehen wenn Du sie übertaktest, Deine Programme werden einfach abstürzen. Ich denke aber schon das 5Mhz möglich sind, sicher aber nicht mit jedem IC. Gruß, Holm
Holm Tiffe schrieb: > Ich habe jetzt keine Lust mich durch das Datenblatt des STI > durchzugraben 4 Mhz..... natürlich schon nachgeschaut bevor ich hier was schreibe. Nicht ganz billig der kram, daher bevor ich den bestelle mal kurz gefragt. 9600 sind die Grenze (/16 und /4 Teiler leider davor), das steht auch in der App Note von Mostek drin. Mit dme -06er gehen 19200 bei 6 Mhz Baudratenquarz.
Holm Tiffe schrieb: > Ich kann mir nur schwer vorstellen das 9600 die > Grenze für die STI sein soll.. Er hat ein Problem mit der Baudratenerzeugung aus dem Systemtakt.
Wobei sich die Frage stellt ob man die /1 irgendwie aktivieren kann.... trotz "/16 only" Fussnote. Der Chip ist eh etwas "anders", schon die Sync Betriebsmodi sind anders als alles was ich je gesehen habe, mit Sync Bytes usw.
Die Sync-Modi werden nicht anders sein als die in der SIO auch (SDLC,HDLC,BiSync) nur Du mit mit der SPI gängiger Micros sicherlich völlig Anderes gewohnt. Die Sync-Protokolle gehören zur "frühen" Netzwerktechnik.. Holm
Holm Tiffe schrieb: > Die Sync-Modi werden nicht anders sein als die in der SIO auch > (SDLC,HDLC,BiSync) nur Du mit mit der SPI gängiger Micros sicherlich > völlig Anderes gewohnt. Bin da grad dran, habe noch einen App Note von Mostek aufgetrieben, einen Design Guide für alle Chipse von denen.....
Ich werde irre! 57600 laufen !!! Ich habe die Rev H Chip und bei der scheinen die den /1 Mode in Ordnung gebracht zu haben! Die App Note wo behauptet wurde das ginge nicht war veraltet...... ganz neue Geschwindigkeitsdimensionen, das Bild ist einfach sofort "da" und kriecht nicht mehr aus dem Bildschirm :-)
Interessant. USART asynchron mit /1 und dennoch Taktsynchronisation per Startbit? Das wär ne ziemliche Innovation. Mal sehen ob sich die Freude hält, denn der /16 Teiler ist für die Synchronisation bei Rx essentiell. Du also jetzt keine Taktsynchronisation mehr. Bei Tx macht die der PC, daher ist diese Richtung kein Problem. Bei Rx ist es Glücksache, also davon abhängig ob der Takt der PC-UART zufällig innerhalb deines Bitframes liegt oder an dessen Grenze. Wenn du jetzt also gelegentlich Ärger mit der Tastatur oder mit dem Bootloader hast... Poste doch bitte mal die komplette STI Config für 57600.
:
Bearbeitet durch User
Moment..... ich bin noch dran, da der Upload von Intel Hex nicht mehr läuft, der verschluckt sich jetzt ..... Da die Sync weg ist steht ja auch in der App Note von Mostek drin, die funktioniert nur bei 1/16. Ich melde mich sobald ich mehr weiss.... 38400 wären rechnerisch auch noch möglich.....
Christian J. schrieb: > Moment..... ich bin noch dran, da der Upload von Intel Hex nicht mehr > läuft, der verschluckt sich jetzt ..... Q.E.D. ;-) > Ich melde mich sobald ich mehr weiss.... Da kann ich dir helfen: Du brauchst nun eine externe Logik, die den STI Receiver mit einem synchronisierten Takt versieht.
Nein, es gibt Ärger mit der Eingabe... auch beim Tippen immer wieder mal "Murks". IHX8 Upload läuft nicht mehr, Checksum Fehler kommen immer mit rein..... also runter auf 38400 gehen, da dürfte der Frame vielleicht etwas besser passen. // STI konfigurieren für Uart Ausgabe STI_UCR = 0x08; // = 10001000 UART Control Register 8N1, DIV16 STI_RSR = 0x01; // RX Status - Enable RX STI_TSR = 0x05; // TX Status - TX High, TX enabled // Timer D... STI_PVR = STI_TDDR; // Zeiger PVR auf Timer D Data STI_IDR = 0x02; // Timer D Zeitkonstante STI_PVR = STI_TCDCR; // Zeiger auf Timer C,D Control Register STI_IDR = 0x8B; // Timer D DIV 16, C = Stop
Dein STI sampelt bei /1 das Rx Signal an zufälliger Stelle. Mal klappt das, weil innerhalb vom Bitframe, mal nicht. Weshalb das auch bei 300bd zwar statistisch besser wird, aber das grundlegende Problem nicht beseitigt.
:
Bearbeitet durch User
Alternative wäre 9600/57600 im Umschaltbetrieb aber leider macht das Terminal sowas nicht mit.... Klar, der macht nur 1 Sampel statt 16 wie vorher und wenn der nicht mittig sitzt, dann schiesst er daneben.....
Was du wirklich brauchst ist ein extern zugeführter Baudratentakt an den RC/TC Pins des STI. Ein Takt, der exakt das 16fache der gewünschten Baudrate darstellt. Bei Systemtakt/2 kriegst du 115kbd und bist etwas jenseits der Auslegung des STI, bei Systemtakt/4 57kbd. Fliegenden '74 versuchen.
:
Bearbeitet durch User
A. K. schrieb: > Was du wirklich brauchst ist ein extern zugeführter Baudratentakt an den > RC/TC Pins des STI. Schon mal die Platine angeschaut? Da geht nix mehr und ein Zusatzboard möchte ich nicht, damit sie läuft, auch wenn das machbar wäre..... derzeit sind TC/RC an den Timer angeschlossen. Was für einen Takt würdest du den vorschlagen an diesen Pins? Ich gehe von 19200 mallangsam hoch derzeit..... etwas aufwendig das ewig zu brennen und die Umschalterei im Terminal....
Christian J. schrieb: > Schon mal die Platine angeschaut? Deshalb schrieb ich ja auch "fliegend". Notfalls nimmst du die SMD-Version und versteckst das Teil unter dem STI Sockel, damit es echt aussieht. ;)
:
Bearbeitet durch User
Christian J. schrieb: > Was für einen Takt würdest du den vorschlagen an diesen Pins? Das hängt davon ab, welche Baudrate du gerne hättest und ob du bereit bist, den STI auf den RC/TC Leitungen versuchsweise zu übertakten. Aber eigentlich hatte ich das vorhin schon geschrieben. Lesen.
Da steht 4 Mhz und 3.6Mhz habe ich. Und das mit dem Übertakten ginge auch, wenn gleich die ganze Platine mit 5.9 bestückt würde, dann wäre der STI extrem, überdreht.
Mit Übertakten war der /16 Baudratenteiler des STI gemeint. Der ist beim -04 auf ca. 1MHz begrenzt, bei 115k landest du aber bei 1,8MHz. Also: Systemtakt/2 = 1,8MHz => 115kbd Systemtakt/4 = 0,9MHz => 57600bd 74HC74 als Teiler an den Systemtakt, Ausgang davon an RC/TC vom STI.
:
Bearbeitet durch User
Nix zu machen, selbst bei 19200 trifft er es nicht in die Mitte. War ja auch klar, da das Ganze sich auf jedem Baudbereich auswirkt, dürfte bei 300 auch nicht anders sein. 57600 taugen also nur zur Ausgabe über TX aber mit RX bin ich derzeit an die 9600 gefesselt.
A. K. schrieb: > Mit Übertakten war der /16 Baudratenteiler des STI gemeint. Der ist beim > -04 auf ca. 1MHz begrenzt, bei 115k landest du aber bei 1,8MHz. Es würden schon 57600 reichen. Ich habe auf der Erweiterungsplatine einen Osc drauf und einen 4020 Takteiler, der sich sogar einstellen lässt über einen Multiplexer. Allerdings wäre dann das hauptboard an diese Platine gebunden. Ergo ginghe es nur einen smd Oscillator unter die Platine zu frickeln und einen smd 4020 oder ...74 dazu. Unter dem IC witzlos, da keine Verbindung nach unten und unten drunter ist es verdammt eng.... Ich Depperl! Wozu habe ich denn einen 3.6864Mhz auf der Platine und noch 4024 Binärteiler in der Kiste womit 0,921600 Mhz erzeugbar sind? Dann läuft es auf jeden Fall synchron zum Systemtakt.
Bin ja mal gesspannt ob der A.K. (wie heisst er eigentlich mit Vornamnen) Recht hat.... die 900khz sind da.... auch wenn das IC nur noch 4 Füsse hat und der Rest abgesägt wurde mangels Platz. Erster Test: Ausgabe funktioniert mit ext. Clock aber IHX8 Decodierung kommt eindeutig nicht mehr hinter, 56700 sind zu schnell für den Code.
Christian J. schrieb: > 56700 sind zu schnell für den Code Dann bau eine Flusssteuerung ein. Entweder XON/XOFF-Protokoll (braucht keine Hardwareänderung) oder RTS/CTS. Jens
Jens schrieb: > Dann bau eine Flusssteuerung ein. > Entweder XON/XOFF-Protokoll (braucht keine Hardwareänderung) oder > RTS/CTS. Dann holst du dir aber die ganzen probleme damit rein, dass XOFF auch zeit zum Senden braucht und in der Zeit der winzige, nur 1 Byte große RX Puffer schon übergelaufen ist. Noch ne Baustelle aufmachen .. RTS(CTS hat nur der echte SIO (Hallo Holm....!) und der STI nicht, auch mein 2 Euro Usart/USB Interface nicht. Nee, ich habe schon die Lösung: Den Systemtakt hochn auf 4.915200 Mhz und daraus einen /2 /16 Takt ableiten, der dann 38400 Baud ergibt. Linux kennt kein 28.800 was ich derzeit noch haben könnte, weil das kein Standard ist. Also zwei Fliegen mit einer Klappe, die Kiste schneller machen und gleichzeitig die Baudrate auf 38.4 hoch, was absolut machbar sein müsste. Und wenn nicht kann der 4024 an dem Q2 Pin auch noch 19200 draus machen. Habe bloss den Osc verbummelt den ich mal hatte und musste grad einen neuen beim großen C bestellen für 10€ inkls Versandkosten.
Christian J. schrieb: > Dann holst du dir aber die ganzen probleme damit rein, dass XOFF auch > zeit zum Senden braucht und in der Zeit der winzige, nur 1 Byte große RX > Puffer schon übergelaufen ist. Immer halblang, du bist nicht der Erste, der sowas implementiert. Wichtig ist nur, dass der Receiver-Interrupt deutlich schneller ist als ein Byte dauert (*). Wenn die Interrupts priorisiert verschachtelbar sind (bei Z80 IM2 kein Problem), dann reicht das als Randbedingung aus. Musst ja den XOFF nicht erst senden, wenn der Puffer im RAM krachend voll ist. Beispiel für XON/XOFF gibts übrigens schon in diesem Thread. Zwar für SIO, aber am Prinzip ändert das nichts. *: Hier könnte C v. Assembler eine kleine Rolle spielen. Ich hatte im Rx-Interrupt zudem den zweiten Registersatz genutzt. > Noch ne Baustelle aufmachen .. RTS(CTS > hat nur der echte SIO Herrje! Das sind auch beim SIO letztlich nur 2 per Programm zu behandelnde Pins, denn einen Handshake-Automatismus hat auch der SIO nicht eingebaut.
:
Bearbeitet durch User
Alternativ: Gibt es beim stty Kommando irgendeine Möglichkeit nach dem Senden eines zeichens eine Pause ein zu stellen? Die Man Page ist erschlagend, verstehe nur die Hälfte was die UART alles kann aber sowas wäre genau das richtige, denn Laden ist ja nur einmal, danach sendet er ja meistens. >>Wichtig ist nur, dass der Receiver-Interrupt deutlich schneller ist als >>ein Byte dauert (*). habs mir angeschaut, was nach dem CRC Fehler im Speicher ist .... der RX Buffer fliegt über "voll" nach 128 Bytes. Das kriegt der Decoder nicht weg geschaufelt. Gerechnet bleiben für jedes Byte nur ca 600 Taktzyklen übrig, wenn 1 Byte 0,13ms braucht. Nicht machbar ohne "Bremse". => CPU schneller takten, anderer Quarz, auf 38400 gehen .... schätze mal 2. Januar sind die bestellten Teile da.
Du kannst ja XOFF schicken, wenn eine Zeile übertragen wurde und erstmal ausgewertet werden muss. Danach geht es mit XON weiter... Christian J. schrieb: > Gibt es beim stty Kommando irgendeine Möglichkeit nach dem Senden eines > zeichens eine Pause ein zu stellen? Bei stty ist mir nichts bekannt. Screen kennt den Befehl slowpaste
1 | <ctrl> a : readbuf <filename> |
2 | <ctrl> a : slowpaste 30 |
3 | <ctrl> a ] |
Oder man verwendet pv zum Verschicken:
1 | pv -qL 10 < intel.hex > /dev/ttyS0 |
Jens
Die Pausen zwischen den Zeichen gibts wohl nicht, Bei FreeBSD jedenfalls nicht, bei Linux weiß ich das nicht so genau. Ich habe mal mit einem alten Epromer gekämpft der bis 80386/25 noch arbeitete, bei allem schnelleren nicht mehr. Das Programm dafür war ein GWBasic Programm und auf dem Epromer werkelte eine 8048 CPU die ja keine serielle Schnittstelle hat (in Software implementiert). Das Ding ist bei schnelleren Rechnern nicht mehr dazu gekommen überhaupt mit RTS Anhalten zu rufen, der Müll wurde einfach über den Haufen geschoben. Da hätte ich mir solche Pausen gewünscht.. Der Promer war wohl mal von Conrad, Design by Auerswald... Gruß, Holm
Jens schrieb: >> Gibt es beim stty Kommando irgendeine Möglichkeit nach dem Senden eines >> zeichens eine Pause ein zu stellen? > Bei stty ist mir nichts bekannt. Im Manual gibts bei ein paar Steuerzeichen irgendwas mit Delays. Wahrscheinlich aus Unix, weil manche Teletypes der 70er nicht fix genug waren. Ich fürchte bloss, dass man dafür im Sourcecode von Linux graben muss, um rauszukriegen ob das überhaupt noch real existiert und was das genau bedeutet.
:
Bearbeitet durch User
Jens schrieb: > Du kannst ja XOFF schicken, wenn eine Zeile übertragen wurde und erstmal > ausgewertet werden muss. Danach geht es mit XON weiter... Hi, bevor ich jetzt die Kiste aus mache, weil ich mich 3 Tage damit befasst habe (vor meinem Umzugh in 2 Wochen, wo dann Ende ist) habe ich XON/XOFF eben ausprobiert. Buffer > 70% dann sende 0x13 Buffer < 30% dann sende 0x11 stty 57600 raw ixon ixoff ..... (natürlich gegeneinander verriegelt, d.h. ein XON wird nur gesendet wenn vorher ein XOFF da war und umgekehrt. Leider mit wenig Erfolg, da der PC da drauf nicht reagiert hat, den Buffer weiter voll schoss (rote LED), während ide gelbe LED am USB/RS232 Adapter zeigte, dass der Z80 dauernd mit XOFF "um Hilfe rief". Bzw auch nicht klar ist ob das Terminal nicht selbst diese Einstellung überschreibt oder nicht. Idealerweise hat man ei fertiges ZMODEM oder XMODEM auf dem Z80 und die passende Hardware dazu (echte SIO....), ich lade ja mit cat ....> /dev..... Der stty Befehl ist extrem mächtig und ein "RTFM" nützt da nichts, wenn man nicht grundlegende Kenntnisse der seriellen Datenübertragung hat. automatisches RTS/CTS ist die zuverlässigste, da Echtzeit. Die PrimeCell UART beim ARM hat die auch und die funktioniert auch, wie ich weiss, weil ich die mal benutzt habe. Ich mach erstmal Feierabend bis der 4.9 Mhz Osc ankommt, der über den 4024 Teiler, der ja schon drauf ist die 38400 ermöglicht und danach hat das schöne Leben "endlich mal Zeit für sich selbst zu haben" auch ein Ende, da ich die Bude hier einpacken muss. Danke auf jeden Fall all jenen, die hier so unermüdlich mit Rat und Tat da waren! Vielleicht kommt ja irgendwann mal der Nächste, der Z80 selbst bauen will und auch die Hartnäckigkeit hat da wirklich dran zu bleiben. Ein selbstgebauter "Computer", den man verfädelt hat, hat im Gegensatz zu den "funktioniert-alles" Arduinos und fertigen "Luxus-Software-Development" Microcontrollern ein gewisses Suchtpotential....
@A.K. Falls Du noch damit was machst... weiss ja nicht.: Die /1 Stufe beim MK3801 funktoniert nur beim Senden und einzelnen Tastendrücken. Ganz selten war da mal ein Murks Zeichen dabei. Sobald aber ein Datenstrom kommt entgleist die Sync nach kurzer zeit und man sieht nur noch Müll als Echo. Keine Ahnung wieso Mostek das überhaupt implementiert hat, wenn sie Sart und Stop Bit eh nicht mehr auswerten und darauf synchronisieren können. Die Mk3801-06 wollen sich einige wohl vergolden lassen.... http://www.ebay.co.uk/itm/MK3801N6-Integrated-Circuit-/400360957688?ssPageName=ADME:X:BOCOR:GB:1123
Christian J. schrieb: > Falls Du noch damit was machst... Das Ding steht seit 20 Jahren irgendwo in einem Keller rum. Schaltplan veschollen. ;-) > Die /1 Stufe beim MK3801 funktoniert nur beim Senden und einzelnen > Tastendrücken. Ganz selten war da mal ein Murks Zeichen dabei. Sobald > aber ein Datenstrom kommt entgleist die Sync nach kurzer zeit und man > sieht nur noch Müll als Echo. Jau. Exakt das hatte ich dir oben auch geweissagt. ;-) Beitrag "Re: Retro Fieber: Z80 oder 68000 ?" > Keine Ahnung wieso Mostek das überhaupt > implementiert hat, wenn sie Sart und Stop Bit eh nicht mehr auswerten > und darauf synchronisieren können. Das Startbit wird offenbar ausgewertet, aber eben nur als Startbit, nicht mehr zur Bitsynchronisation. Deshalb funktioniert ein einzelnen Bytes mit einer gewissen Wahrscheinlichkeit. Aber wenn genug Bytes zusammenkommen schlägt ebendiese Wahrscheinlichkeit dir ein Schnippchen. Sinn ergibt das nur in Zusammenhang mit externer Bitsynchronisation. Also wenn du beispielsweise einen Manchester-Codec extern anflanschst, der den Receiver-Takt aus dem Empfangssignal ableitet.
:
Bearbeitet durch User
A. K. schrieb: > Sinn ergibt das nur in Zusammenhang mit externer Bitsynchronisation. > Also wenn du beispielsweise einen Manchester-Codec extern anflanschst. Ich hätte es auch gleich "richtig" machen können und eine Z80 SIO verwenden und dazu noch eine ROM Umschaltung auf 64klb RAM...... allerdings sind alle Fallstricke immerhin selbst "erarbeitet" worden bzw "erlitten" .... bzw. stelle ich mir die Frage ob ich so belassen soll oder noch eine V2.0 bauen soll auf Platine. CP/M interessiert mich ehrlich gesagt nicht, weil das eh nur ein Spielzeug ist ("Oh, schön......CP/M läuft.... und was mach ich damit jetzt?"). Fürs "Programmieren" reicht es ja und die SD karte kriege ich auch noch ans Laufen, bevor die 16kb Monitor voll sind. Und irgendeine Anwendung, wo irgendwas schaltet und sich bewegt wird sich auch noch finden lassen. Etwas mit Elektromagneten und Flipper Kugeln schwirrt mir da im Kopf herum.... habe mal ein Demo Modell gebaut vor 10 Jahren auf Plexiglasplatte wo sich eine Solarzelle nach der Sonne mit bewegte mit Steppermotor. 2 grüne LED in Hülsen als Sensor (Blöd nur, dass die Sonne die offene Technik recht schnell ausgebleicht hat.) Sieht jedenfalls lustig aus, was sich da alles so "bildet".... nur fehlt mir noch ein Abruch Kriterium für endgültige Muster bzw "Blinker", dass er dann neu startet.
Christian J. schrieb: > Ich hätte es auch gleich "richtig" machen können und eine Z80 SIO > verwenden und dazu noch eine ROM Umschaltung auf 64klb RAM...... ;-) > schön......CP/M läuft.... und was mach ich damit jetzt?"). Und das ist jetzt anders? Ein Bekannter war mal über einen recht guten gebrauchten Joystick gestolpert. Passend für den ollen Flugsimulator. Da hat er dann etwas dran rumgebaut, nach und nach mehr und mehr, bis irgendwann ein Cockpit fertig wird, mit Instrumententafel, Schaltern und allem Gedöns. Sowas ist genau so lange interessant bis es fertig ist, plus maximal ein paar Wochen. Dann sieht es knorke raus, steht unbenutzt rum und die Frau hält einen für komplett bescheuert. ;-)
:
Bearbeitet durch User
A. K. schrieb: > Da hat er dann etwas > dran rumgebaut, nach und nach mehr und mehr, bis irgendwann ein Cockpit > fertig wird, mit Instrumententafel, Schaltern und allem Gedöns. Sowas > ist genau so lange interessant bis es fertig ist, plus maximal ein paar > Wochen. Hmmm...... meine Modelleisenbahn..... mein selbst restaurierter Fiat X1/9 ....... kommt mir sehr bekannt vor.... alss der nach 1 Jahr fertig war genau 1/2 Jahr gefahren und dann verkauft..... total unbequeme Klapperkiste.....ewig rappelte was...... aber das Basteln war schön :-) Hat mich auch wohl meine Ehe damals "gekostet" :-)
PS: Ich habe da schon ein "nächstes Projekt" im Auge..... wozu 5V wenn man auch 50 MegaVolt haben kann :-) https://www.youtube.com/watch?v=3FpjcOWwiI4
Holm Tiffe schrieb: > Die Pausen zwischen den Zeichen gibts wohl nicht, Bei FreeBSD jedenfalls > nicht, bei Linux weiß ich das nicht so genau. > > Ich habe mal mit einem alten Epromer gekämpft der bis 80386/25 noch > arbeitete, bei allem schnelleren nicht mehr. Das Programm dafür war ein > GWBasic Programm und auf dem Epromer werkelte eine 8048 CPU die ja keine > serielle Schnittstelle hat (in Software implementiert). Das Ding ist bei > schnelleren Rechnern nicht mehr dazu gekommen überhaupt mit RTS Anhalten > zu rufen, der Müll wurde einfach über den Haufen geschoben. Da hätte ich > mir solche Pausen gewünscht.. > > Der Promer war wohl mal von Conrad, Design by Auerswald... > > Gruß, > > Holm Das Problem habe ich gelöst in dem ich 2 Druckerports mit EP/PP verwendet habe und meinen Prommer Transistor, Relais Jumper selbst gestrickt und die SW in in Qbasic(ver. 1-7.1) geschrieben hatte (letere viel leider einem Systemabsturz zum Opfer) aber am MAXimite bekomme ich die sicher wieder zum laufen. ;) So ein universeller Basic-Zwerg mit genügend Ports ist recht vielseitig zu verwenden. Neue Anforderung---> neues Programm-gleiche HW Basis.
Christian J. schrieb: > Hat mich auch wohl meine Ehe damals "gekostet" :-) Dazu brauchte ich nicht mal 4 Räder. Das habe ich mit allein Programmiersessions am Atari auch so geschafft. Ein Hobby ist für eine Frau wie Fremdgehen die eine nimmt es hin, die andere nicht da ist ein Motorrad besser, falls sie gern selbst eines fährt. Namaste
Winfried J. schrieb: > Dazu brauchte ich nicht mal 4 Räder. Es waren zeitweise 20 Räder...... 2.8l Ford Capri, 2 x Scirocco II, 1 Fiat X1/9, 1 x 2.0 Ford Taunus Ghia
Christian J. schrieb: > Winfried J. schrieb: >> Dazu brauchte ich nicht mal 4 Räder. > > Es waren zeitweise 20 Räder...... 2.8l Ford Capri, 2 x Scirocco II, 1 > Fiat X1/9, 1 x 2.0 Ford Taunus Ghia Ein Auto wolltest Du wohl nicht.. Gruß, Holm
Holm Tiffe schrieb: > Ein Auto wolltest Du wohl nicht.. Doch, das hier war der Geilste...... schade dass ich ihn verkaufen musste :-( 16l/100km und "Schwarze Umweltplakette" hatten was
@Holm: Ich fühle mich bei Asm als wenn ich auf Eiern gehe, jedes Bisschen test kompilieren und Fehlermeldungen anschauen bei diesem ASXXXXX Assembler, wo nicht mal eine .define Anweidung funktioniert, ohne einen Fehler zuu erzeugen. Anleitung habe ich aber irgendwie macht er was anderes als da steht. Ausprobieren geht auch nicht da ich keinen Simulator habe bzw nicht weiss wie ich den Code, der als 1 Hex File da liegt da testen soll. Ich müsste entweder die eigene Adresse herausfinden, wo der Programmcode grad ist oder eben einen Schreibtest machen, ob er im Eprom oder Ram ist. Beim 6502 ging es, dass man die aktuelle PC (Program Counter) Adresse mit einem Befehl heraus fand, zb wäre die 0x00(00) für die Zeropage. Geht das mit dem Z80 Asm auch eleganter als mein Werk da unten? testvar .db 0x00 ; Sind wir grad im RAM oder EPROM? => Schreibtest ausführen ld a,#0xAF ld (rwtest),a ; 0x55->Testvariable ld a,(rwtest) ; Testvariable -> A cp #0xAF ; Schreiben erfolgreich? jp Z, init2 ; =Z, wir sind im RAM, dann überspringe ; Wir sind im EPROM, dann pruefe, ob ein Programm im RAM liegt ld a, (ram_prog) ; Lade Start des RAM 0x4000 cp #0xC3 ; vergleiche mit "C3" = JP Befehl jp Z, ram_prog ; Ja, dann springe direkt ins Ram hinein Noch zum SDCC: Die Option --max-allocs-per-node 200000 erzeugt zwar 20 Minuten Compilerlauf aber aus 13kb Code schafft er dann locker 12kb zu machen, der erzeugte Code sieht absolut "optimal" aus. Dank Leo, wusste ich vorher nicht, dass man eine Release Version erzeugen kann, auch wenn es 20 Mionuten dauert.....
call l1 l1: pop af ;A = high(PC) cp a,...
:
Bearbeitet durch User
A. K. schrieb: > call l1 > l1: pop af ;A = high(PC) > cp a,... Oh weh..... alle das war mal "da" vor 25 Jahren und muss nun wieder neu erlernt werden...... Warum .define SYMBOL nicht geht weisst du sicher auch nicht? Also auch das nicht. .ifdef SYMBOL lalala..... .endif
Christian J. schrieb: > Warum .define SYMBOL nicht geht weisst du sicher auch nicht? Kaum, da ich nie in deinem Assembler programmiert habe. > alle das war mal "da" vor 25 Jahren und muss nun wieder neu > erlernt werden...... Ist ein Kniff, den man bei heutigen CPUs der besseren Sorte auch keinesfalls anwenden sollte, weil bösartig bremsend.
:
Bearbeitet durch User
Christian J. schrieb: > Ich fühle mich bei Asm als wenn ich auf Eiern gehe, jedes Bisschen test > kompilieren und Fehlermeldungen anschauen bei diesem ASXXXXX Assembler, Also wenn ich mir das Bild ansehe, dann gehts wohl kaum noch einfacher: http://www.heise.de/download/z80-simulator-ide-1119083.html
:
Bearbeitet durch User
Nochmal zur "ROM Ausblendung" Habe da in "C" länger drüber nachgedacht, wie man das bewerkstelligen kann, weil es in Asm ja deutlichn einfacher ist, man nicht den sdcc drüber sitzen hat, der einem die Labels auf die kompilierte Adresse anpasst usw. Es ginge echt nur so: 1. Ur Lader (auf C000 kompiliert) und als adressloses BIN abgelegt. 2. Direkt die ersten Behle sind ..... LDIR mit der er sich selbst "hoch" kopiert, zb nach C000. 3. Sprung nach "oben" hinter Kopierroutine 4. ROM unten abschalten 5. Monitor starten 6 User Programm nach unten laden 7 Sprung ins User Programm Diese Kopierroutine muss notfalls als Einzelbytes abgelegt werden, da jeder "Bezug" oberhalb des eigenen Segment ein ungültiger Bezug für den Compiler ist. Anders geht es nicht.....
A. K. schrieb: > Also wenn ich mir das Bild ansehe, dann gehts wohl kaum noch einfacher: > http://www.heise.de/download/z80-simulator-ide-1119083.html Kenn ich schon. Läuft nach 7 Tagen ab und ist eingeschränkt.
Christian J. schrieb: > A. K. schrieb: > >> call l1 >> l1: pop af ;A = high(PC) >> cp a,... > Damit bekommt man raus ob der Stackpointer auf RAM zeigt. > Oh weh..... alle das war mal "da" vor 25 Jahren und muss nun wieder neu > erlernt werden...... > > Warum .define SYMBOL nicht geht weisst du sicher auch nicht? > > Also auch das nicht. > > .ifdef SYMBOL > > lalala..... > > .endif Naja Moment, die Assembler haben unterschiedliche Dialekte, gerade für solche Pseudoops. Ich weiß jetzt nicht was Dein ASXXXXX genau ist, ist das der Frankenstein-Assebmler? Wenn ja, dann gehen da Definistionen über EQU und das Festlegen von Bytes mit DB oder DS. IMHO kann der aber auch bedingte Assemblierung. A.1.1 Standard_Pseudo_Operation_Mnemonics End END File Inclusion INCL INCLUDE If IF Else ELSE End If ENDI Equate EQU Set SETEQU Org ORG Reserve Memory RESERVE RMB Define Byte Data BYTE DB FCB Define Word Data DW FDB WORD Define String Data FCC STRING Define Character Set Translation CHARSET Define Character Value CHARDEF CHD Use Character Translation CHARUSE Ich habe den SDCC mit seinem Assembler bisher nie benutzt. Das letzte war wohl dieser WLA-DX oder wie der heißt, der kann zwar Macros ist aber mit seiner Linkerei sehr "speziell".. Gruß, Holm
Christian J. schrieb: > Kenn ich schon. Läuft nach 7 Tagen ab und ist eingeschränkt. Ja. Kostet mörderische 25€.
Ich weiss nicht ob der das was der sdcc ausspuckt auch als Eingabe nimmt. Oft muss ja ja nur 1 Modul testen und nicht das ganze Programm. Müsste ich mal ausprobieren. Die Oberfläche ist nicht ganz so einfach weil man sehr viele Fenster hat, die "irgendwie" miteinander in Verbindung stehen.
Christian J. schrieb: > Anders geht es nicht..... Nicht nur ich frag mich manchmal, ob du ab und zu auch liest, was andere Leute schreiben. Weils schon recht interessant wirkt, wenn du als deine Erkenntnis präsentierst, was schon Äonen vorher hier geschrieben stand.
Christian J. schrieb: > Ich weiss nicht ob der das was der sdcc ausspuckt auch als Eingabe > nimmt. Das war grad eher als Anregung für etwas Übung mit Assembler-Befehlen gemeint. Nicht für komplette SDCC Programme. Bisschen Assembler geht darin recht elegant. Tief reingesehen habe ich auch nicht, nur grad mal ein paar Assembler Befehle ausprobiert. Die zig anderen Emulatoren habe ich mir auch nicht angesehen.
:
Bearbeitet durch User
A. K. schrieb: > Weils schon recht interessant wirkt, wenn du als deine > Erkenntnis präsentierst, was schon Äonen vorher hier geschrieben stand. Wieso, du wolltest doch den unter sich slebst kopieren und das macht eh keinen Sinn weil man da ja noch mal kopieren muss, damit Userprog nach 0x0000 kommt.
Christian J. schrieb: > Wieso, du wolltest doch den unter sich slebst kopieren Das war eine Variante. Wie das genau abzulaufen hat hängt davon ab, ob das RAM in der Startphase überhaupt irgendwo lesbar ist. Notwendig ist das nämlich nicht und man erspart sich so die Adressabhängigkeit der ROM/RAM Ansteuerung. Ohne Adressdekoder kann man 64KB über sich selbst kopieren, umschalten und dann nach oben springen. Oder erst nach oben springen und dann umschalten, das ist egal. Mit Adressdekoder kann man 8KB nach oben kopieren, dorthin springen und dann umschalten. Der Unterschied besteht in den für die Adressdekodierung nötigen Gattern. Die sich vielleicht anderweitig besser nutzen lassen.
:
Bearbeitet durch User
Christian J. schrieb: > Holm Tiffe schrieb: >> Ein Auto wolltest Du wohl nicht.. > > Doch, das hier war der Geilste...... schade dass ich ihn verkaufen > musste :-( 16l/100km und "Schwarze Umweltplakette" hatten was lechz ja für den würde ich auch .......,öhm such ich noch ;)
Holm Tiffe schrieb: > Damit bekommt man raus ob der Stackpointer auf RAM zeigt. Stackpointer ist ROM ist so ne Sache... Damit bekommt man mit vielen Takten raus, wo man grad unterwegs ist in der Speicherlandschaft..... Rücksprungadresse auf Stack, zurück nach A und F(lag) register, A ist 0x00 bei der Zeropage. Schon eingebaut, spielt.
@A.K. 4.9 Mhz Quarz kam heute an von Conrad: Riesenkarton und drin eine winzige Sachtel mit dem Quarz Oscillator. Eingelötet, Timer ab, Takt direkt drauf. 38400 eingestellt. 5 Minuten Arbeit. Spielte sofort, endlich Speed auf dem Schirm und eine spürbare fixere CPU :-) Codeänderung: keine. IHX8 Upload lief ohne Veränderungen, auch wenn er jede empfangene Zeile mit einem "." quittiert damit man auf dem Schirm etwas sieht. Supi :-)
:-))) Habe Kontakt zu Dr. Kieser bekommen (90% Autor Kieser/Meder "Mikorprozessortechnik"), er schreibt dass er sich gern an diese Zeit im FW Erfurt erinnert und ich könne auch gern Fragen zur U880 usw. stellen.
Hallo liebe RETROs,,, ganz kurz zu mir: hatte eigentlich die Bank durch, Sinclair ZX81, ORIC1, KWS-SAM68k, c´t EPAC 68008 - dazu hab ich auch ein eigenes Board in Eagle mal gemacht; allerdings Doppel-Euro und um einen Lattice ISP1032 erweitert, da wollte ich die GALs reinpacken und das Ding dann Schritt für Schritt verkleinern. Dann bin ich auf XILINX aufmerksam geworden, FPGAs mit Million-Gattern --> Software CPU gleich rein; siehe c´t Hacks Mini-Asteroids; die haben da einen 6502 bzw. kompletten C64 reingeschossen mit Video sogar. Alternativ mal was sau-einfaches: (noch mehr Retro) aber läuft... Eine 8085CPU mit PIO dazu, in der sind 256Byte RAM mit drin, dazu noch ein EPROM für den Code -- absolut easy. geht halt nur in ASM, aber für (fast nix) ist das OK und eben mal schnell auf Lochraster gestrickt. Noch ein Tipp (Retro): ZMD --> Zentrum Mikroelektronik Dresden Die bauen / bauten NV-SRAMS - ganz geckig, ohne Batterie mit einem Flash-Spiegel parallel. Ein 10uF Tantal als Stützkondensator reicht denen, beim Power-Fail das SRAM 1:1 ins Flash zu übertragen und beim Power-wieder-da das ganze umgekehrt. Aüßerlich ist das ein 6232..62256 SRAM rsp. deren DALLAS-Eqivalente. Ganz geckig an ZMD - hatte mir sehr imponiert!!! Die bauen, weil es ohnehin egal ist, eine 8080CPU mit auf den Wafer dazu - gratis - sozusagen. Muss ich auch mal reingoogeln demnächst... Bin auch am (wieder)Neustart mit dem Kram und auf der Suche nach simpel. Andreas Seck, Krämergasse 16, 35083 Wetter Ernst gemeinte Briefe herzlichst willkommen. Ich beantworte diese dann gerne und garantiert! Besser als im Netz zu versumpfen und sich tot zu suchen. Gruß A.S. 10.01.15
Hallo, auch wenn der Thread in der Versenkung gelandet ist .... mein kleines System wächst munter weiter und V2.0 ist in Planung. V2 soll auf einer Platine entstehen und nicht mit Fädeltechnik und einiges mehr bieten, zb einen Bus auf Messerleiste. Das wirft einige Fragen auf: 1. Ab wann muss ich Bustreiber wie den 74HCT245 (bi-direktional) und 74HCT244 (unidirectional) für Adress und Datenleitungen verwenden? Und mit welcher Leitung des Z80 bzw. externer Logik wird der Tri-State Zustand aktiviert? (Bisher habe ich am Datenbus 7 Bausteine hängen und er bricht immer noch nicht zusammen.) 2. Welches Bussystem ist das bekannteste? Wie läuft da die Sache mit den I/O Bausteinen? Chip Select Bausteine braucht man ja sicher immer noch. 3. Monitor / Tastatur: Ich plane ein Video Interface mit ein (Monochrom, 80x40 reicht aus, Pixell Grafik?) und einen Tastatur Adapter. Gibt es da was Fertiges? Sollte einfach nur funktionieren. CP/M ist nicht ausgeschlossen, daher muss mein V2 Board dafür schon vorbreitet sein. (Bank Switching, XT Interface, ROM Ausblendung usw.)
>auch wenn der Thread in der Versenkung gelandet ist Ja, das liegt u.a. auch daran, daß du dich bisher sehr bemüht hast, alle sinnvollen Ratschläge mäanderförmig zu umschiffen und dich möglichst viel auf inkompatiblen Nebenschauplätzen auszutoben. >einige Fragen 1. Habe nur praktische Antwort, die nicht "berechnet" ist: Intern auf der Platine keine Treiber am Adress-, Daten- oder Control-Bus. Jedoch (Bus-) Treiber auf allen Signalen die nach extern zur Steckerleiste gehen. Für die komplette des Bussteuerung bei voller DMA-Fähigkeit brauchte der Datenbustreiber mit seiner Richtungssteuerung 7 Produkttherme eines damaligen PALs. Nicht trivial. 2. In Deutschland war das wohl mal der ECB-Bus http://de.wikipedia.org/wiki/Europe_Card_Bus Freilich braucht man Chip-Selects; es muss ja eine Dekodierung geben. Und man hat i.d.R. auf jeder I/O Karte einstellbare Grundadresse für die dort befindliche Peripherie, also deren I/O-mapping. 3. Viele Möglichkeiten. Einfach und kompliziert. Einfach ist Textmode mit 6845. Komplexer ist z.B. Terminal-Nachbildung auf separater Europakarte, teils mit eigener CPU (komplettes Subsystem). Oder NEC7220, wem das zu einfach ist. Tastaturinterface keine einheitliche Norm, da es IBM-PC und dessen Tastaturschnittstelle (DIN- oder PS/2 MiniDIN Stecker) noch nicht gab. Wäre aber wohl inzwischen sinnvollste (wennauch nicht "retro") Möglichkeit. Gruss
Erich schrieb: >>auch wenn der Thread in der Versenkung gelandet ist > Ja, das liegt u.a. auch daran, daß du dich bisher sehr bemüht hast, alle > sinnvollen Ratschläge mäanderförmig zu umschiffen und dich möglichst > viel auf inkompatiblen Nebenschauplätzen auszutoben. Tja, der ROM/RAM Switch, der fehlt wirklich und die Baudrate von 38400 ist auch nur durch einen Trick entstanden. Aber da hat allein der A.K. schuld :-) Mit seinem MK3801 tip, dem Stromfresser mit den 8 Bit Krücken-Timern. stichel > Jedoch (Bus-) Treiber auf allen Signalen die nach extern zur > Steckerleiste gehen. Also kriegt jede Karte ihre eigene Entkopplung? Macht ganz schömn Chips, wenn man mal die Steuerleitungen mit dazu zählt. > Für die komplette des Bussteuerung bei voller DMA-Fähigkeit brauchte DMA lassen wir mal ..... ist mir zu kompliziert und nur für größere Systeme mit Massenspeichern und GraKa. > Datenbustreiber mit seiner Richtungssteuerung 7 Produkttherme eines > damaligen PALs. Nicht trivial. Mal ne dumme Frage: Gibt es eine Software, die einem das Gattergrab berechnet, wenn man zb Min und Max Term als Eingabe gibt? Ich erinnere mich schwach an sowas vor 20 Jahren, nannte sich Karnaugh Diagram zur Optimierung von Logik. Alledings fehlte ich da wohl in der Vorlesung. > In Deutschland war das wohl mal der ECB-Bus USA: S100? Ok. > Und man hat i.d.R. auf jeder I/O Karte einstellbare Grundadresse für die > dort befindliche Peripherie, also deren I/O-mapping. Ok. Gebongt. > Einfach und kompliziert. Einfach ist Textmode mit 6845. > Komplexer ist z.B. Terminal-Nachbildung auf separater Europakarte, teils > mit eigener CPU (komplettes Subsystem). Sollte auf jeden Fall VT102 oder besser sein. Kompletter Interpretation des Vt100 Standards. Sowas wie hier zb. Sehr schön. http://www.klichs.de/files/projekt-2.htm
Christian J. schrieb: > 3. Monitor / Tastatur: Ich plane ein Video Interface mit ein (Monochrom, > 80x40 reicht aus, Pixell Grafik?) und einen Tastatur Adapter. Gibt es da > was Fertiges? Sollte einfach nur funktionieren. Beitrag "VT100-Terminal (VGA+PS2)"
Joe G. schrieb: > Beitrag "VT100-Terminal (VGA+PS2)" Muss "Propeller" programmiert werden? (Kann ich nicht). Und kann ich Platine bei Dir kaufen?
Der Propeller wird über die USB Schnittstelle auf der Platine „programmiert“. Das geht mit den zugehörigen Software von Parallax. Die Platinenversion mit einem kleinen Hardwarefehler (Signalquellenumschaltung) gibt es umsonst gegen Erstattung des Portos. Die korrigierte Version braucht noch ein paar Tage. Die Software sowie die Doku gibt’s hier: http://www.mikrocontroller.net/svnbrowser/avr-cp-m/trunk/VT100/docs/?sortdir=down
Hi, ok, ich melde mich dann. Sollte zu schaffen sein. Für den es interessiert, anbei meine kleine Z80 Fabrik, die noch um eine Karte links ergänzt wird, wo Relais und Eingänge Platz finden. Nett warm die ganze Geschichte :-)
Hallo, > 1. Ab wann muss ich Bustreiber wie den 74HCT245 (bi-direktional) und > 74HCT244 (unidirectional) für Adress und Datenleitungen verwenden? Normalerweise, wenn du viele Bausteine und/oder lange Kabel dran hängen hast (parasitäre Kapazitäten). Ohne DMA musst du in CPU-Peripherie-Richtung die Steuer- und Adressleitungen, sowie die Datenleitungen bei Schreibzugriffen treiben, und in Peripherie-CPU-Richtung die Datenleitungen bei Lesezugriffen. Das hält sich in Grenzen. > Und mit welcher Leitung des Z80 bzw. externer Logik wird der Tri-State > Zustand aktiviert? (Bisher habe ich am Datenbus 7 Bausteine hängen und > er bricht immer noch nicht zusammen.) Wenn du /BUSREQ auf low legst, legt der Z80 /BUSACK auf low und geht in Tristate. Aber der tut dann überhaupt nichts mehr, bis du das wieder sein lässt... > 2. Welches Bussystem ist das bekannteste? Wie läuft da die Sache mit den > I/O Bausteinen? Chip Select Bausteine braucht man ja sicher immer noch. Denk' dir was eigenes aus, so schwer ist das nicht. Ansonsten kannst du dir mein System als Beispiel nehmen. ;-)
1 | Beachte: |
2 | - Slot 0 ist bei mir speziell, weil der /BUSREQ und so hat. ;-) |
3 | - Slot 1 hat /MREQ und /RFSH, weil dort der Speicher steckt, |
4 | alle anderen sind dort nicht verdrahtet. |
5 | - /INT und /SEL (Chip-Select) werden zentral dekodiert |
6 | und jeweils als eigene Leitung auf "ihren" Slot geführt. |
7 | - DMA fehlt. |
8 | - "daneben stecken" schadet nicht, weil neben Vcc und GND |
9 | nichts angeschlossen ist (außer auf Slot 1) |
10 | |
11 | Das Pinout (eine Reihe, 36 Pins) der Slots ist wie folgt: |
12 | +-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+ |
13 | | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | |
14 | | Vcc |/MREQ|/RFSH| GND | n/c | n/c | /RES|/WAIT| /SEL| /INT| /RD | /WR | |
15 | +-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+ |
16 | +-----+-----+-----+-----+-----+-----+-----+-----+ |
17 | | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | |
18 | | D0 | D1 | D2 | D3 | D4 | D5 | D6 | D7 | |
19 | +-----+-----+-----+-----+-----+-----+-----+-----+ |
20 | +-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+ |
21 | | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | |
22 | | A0 | A1 | A2 | A3 | A4 | A5 | A6 | A7 | A8 | A9 | A10 | A11 | A12 | A13 | A14 | A15 | |
23 | +-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+ |
> 3. Monitor / Tastatur: Ich plane ein Video Interface mit ein (Monochrom, > 80x40 reicht aus, Pixell Grafik?) und einen Tastatur Adapter. Für "echtes Retro" kannst du eine Tastaturmatrix an Schieberegister klemmen und VGA als Gattergrab implementieren, das ist machbar. Für "soll funktionieren" baust du dir am besten ein Terminal als separates Projekt und schließt das seriell an dein System an. Für Text nimmst du VT100, farbig mit VT220. Monochrome Vektorgrafik gibt's mit Tek40xx. Für Pixelgrafik ist mir kein Standard bekannt. Als Kompromiss kannst du Tastatur und VGA auch in einen Mikrocontroller stecken, die du an dein Bussystem anschließt. Es gibt PICs mit Slave-Bus-Interface, leider keine AVRs. Alle Versuche, PS/2 und VGA mit einem AVR zu machen, sind gescheitert - ein 32-Bitter sollte das aber schaffen. Ob ein AVR 80x40 kann, weiß ich nicht. Gruß, Svenska
Hi, für die VGA Darstellung gibt es mehrere Lösungen: Hier mit einem AVR, was zu gehen scheint: http://searle.hostei.com/grant/MonitorKeyboard/index.html Dann noch das hier dargestellte Board mit Propeller, was mich sehr interessiert und wenn man es ganz einfacha haben will kauft man sich für 20 Euro einen 14z Bildschirm (habe ich schon), klebt dahinter einen Raspberry Pi, der nur minicom einstellt und hochfährt und schließt an dessen USB Interface dann den Z80 mit FTDI Adapter an. Leider kein RTS/CTS, denn PC Adapter damit sind sehr selten. Ich habe einen, auch mit DTR etc aber noch nicht ausprobiert. Ohne RTS/CTS veschluckt er sich doch manchmal bei 56700 baud. Mit Tri-State meinte ich, dass die Bustreiber einen Enable haben, der irgendwie angeschlossen werden muss. Die CPU lässt ja die Adressleitungen nicht immer aktiv. Bei BUSREQ nimmt sie die hoch, sicherlich auch bei internen Vorgängen wenn grad kein Fetch anliegt. Ich weiss nicht ob da was rausgeführt ist (M1?), das man nutzen kann. Dein Bus sieht ja auch nicht anders aus als eben alle Pins rausführen :-) Dazu noch ein paar Select Leitungen, 8 habe ich. Das verpasst allen externen Karten dann eine fixe Adresse. Man sucht sich nur aus welchen SEL sie kriegen. Keyboard macht ja nur Sinn bei CP/M, da scheine ich wohl nicht drum herum zu kommen..... bzw kann ich da auch gleuch bei N8VEM weitermachen, denn da ist alles schon schön dokumentiert und fertig. Und drüber nachdenken, dass es das Ganze Platinengrab als einen einzigen Chip (Cortex...) gibt, der zudem noch 100 Mal schneller ist, mehr ROM, RAM etc hat darf man eh nicht. Bin da etwas von runter, denn wenn ich "voll retro mässig" alle Chips durch NMOS Typen ersetze dann brät er mir die 7805er weg und die beiden Trafos brechen zusammen wenn sie fast 550mA an 5V liefern sollen. Die russ. NMOS 8253 Timer werden bald derart heiss, dass man die Flossen verbrennt. Habe auch noch "Retro" 74er hier, die allerersten SN7400N, 50mA pro Baustein.... muss ja nicht sein.
VGA mit AVR geht. PS/2 mit AVR geht auch. Beides gleichzeitig mit einem AVR geht nicht. > Leider kein RTS/CTS, denn PC Adapter damit sind sehr selten. Ich > habe einen, auch mit DTR etc aber noch nicht ausprobiert. Ohne > RTS/CTS veschluckt er sich doch manchmal bei 56700 baud. Das kann ich mir nicht vorstellen. Entweder RTS/CTS oder DTR/DSR sollten die haben. Du bist dir sicher, dass sich der Adapter verschluckt und nicht der Z80? Handshaking funktioniert nicht mit Bytegrenzen und viele Systeme (auch PCs mit 16550) senden noch ihren FIFO leer, wenn RTS deaktiviert wird. Dein Z80 muss also noch bis zu 15 weitere Bytes verkraften, nachdem er die Gegenseite angehalten hat (mit XON/XOFF kann das auch noch mehr werden). > Mit Tri-State meinte ich, dass die Bustreiber einen Enable haben, der > irgendwie angeschlossen werden muss. Die CPU lässt ja die > Adressleitungen nicht immer aktiv. Die Synchronisation auf dem Bus geschieht durch die Steuerleitungen. Deine Enable-Signale musst du dir daraus schon selbst zusammenbasteln, je nachdem, was an deinem Bus hängt. Da ich für Peripherie nur I/O unterstütze, hängen die Enables für meine Steuer- und Adressleitungen auf Masse und für die Datenleitungen an /RD. Mit einem '138 erzeuge ich /SEL, dessen Enables hängen an /M1 und /IORQ. Ohne aktives /SEL haben die Geräte still zu sein. > Bei BUSREQ nimmt sie die hoch, > sicherlich auch bei internen Vorgängen wenn grad kein Fetch anliegt. Ich > weiss nicht ob da was rausgeführt ist (M1?), das man nutzen kann. Mit /BUSREQ nimmst du dem Z80 den Bus weg, damit ein anderer Master spielen kann (DMA), als Enable-Signal taugt das nix (und ist am Z80 sowieso ein Eingang). ;-) > Dein Bus sieht ja auch nicht anders aus als eben alle Pins rausführen > :-) Dazu noch ein paar Select Leitungen, 8 habe ich. Das verpasst allen > externen Karten dann eine fixe Adresse. Man sucht sich nur aus welchen > SEL sie kriegen. Ja. Und was ist da jetzt der Unterschied zu S-100 oder ECB? Außer, dass ich weniger Chips brauche, um das Zeug zu implementieren? ;-) Wenn du keine Hardware dafür hast, spielt dein Bussystem kein Rolle. > bzw kann ich da auch gleuch bei N8VEM weitermachen, > denn da ist alles schon schön dokumentiert und fertig. Seufz. Und wieder die alte Leier. > Und drüber nachdenken, dass es das Ganze Platinengrab als einen einzigen > Chip (Cortex...) gibt, der zudem noch 100 Mal schneller ist, mehr ROM, > RAM etc hat darf man eh nicht. Aber einen Cortex an den Z80 zu klemmen und ein VGA-Signal erzeugen zu lassen, ist wesentlich einfacher, als ein Gattergrab dafür zu bauen. Mit ein bisschen zusätzlichem Speicher kriegst du sogar Pixelgrafik hin. Oder dank höherer Rechenleistung eine höhere Auflösung im Textmodus, damit du nicht auf hässliche 8x8-Klötzchenbuchstaben starren musst.
S. R. schrieb: > - /INT und /SEL (Chip-Select) werden zentral dekodiert > und jeweils als eigene Leitung auf "ihren" Slot geführt. Ich würde dezentral dekodieren. Das schränk man sich nicht gleich von vornherein ein. Außerdem würde ich /NMI, /HALT und vor allem /IORQ mit auf die Leiste setzen. Sonst kann auf den Slaves nur Speicher bzw. memory-mapped-IO eingesetzt werden. Neben S100 und ECB gibt es auch noch diverse Abwandlungen des K1520-Standards... http://hc-ddr.hucki.net/wiki/doku.php/homecomputer:k1520 Jens
Christian J. schrieb: > Hi, > > ok, ich melde mich dann. Sollte zu schaffen sein. Für den es > interessiert, anbei meine kleine Z80 Fabrik, die noch um eine Karte > links ergänzt wird, wo Relais und Eingänge Platz finden. Nett warm die > ganze Geschichte :-) Hi! Schaut cool aus! Was mich wirklich interessieren würde wäre der Schaltplan und der komplette Quellcode...
Harald Nagy schrieb: > Schaut cool aus! Was mich wirklich interessieren würde wäre der > Schaltplan und der komplette Quellcode... Hier.... wobei ich jetzt nicht sagen will, dass die Extension was "Sinnvolles" macht. Das ist nur mein Werk ohne Anwendung dahinter. Extensionboard braucht noch Software für die SD karte, Z80 spielt die Daten bisher seriell dort ein, ein Header enthält alle Eckdaten (sd.c) und der AVR, der mit Arduino programmiert wird nimmt sie auf Software-SPI entgegen (hoffe das klappt) und ees werden open, write, read und close implementiert. Das ist aber alles noch nicht fertig. Bisher nur Timer, Shift Register.
Joe G. schrieb: > Ein weitere VT100 Lösung findest du hier: > http://geoffg.net/terminal.html Die ist ja Klasse! Mit Grafik ESC Sequencen. Nur schade, dass meine ncurses von Frank M. sowas nicht unterstützt, da wäre noch einiges zu machen. Ketzerische Frage: Die oder lieber deine bauen? :-) Die kommt mit PIC32 daher für den ich einen Programmer habe.
Harald Nagy schrieb: > Vielen Dank! Eagle Format, Freeware Version für Linux... ps: Diese Geoff Page hat echt schöne Projekte und alle sind komplett dokumentiert und mit Unterlagen, Layouts usw dabei. Der Mann hat Zeit als Rentner...
Christian J. schrieb: > Ketzerische Frage: Die oder lieber deine bauen? :- Da bin ich relativ schmerzfrei. Wie du magst :-)
Christian J. schrieb: > Ketzerische Frage: Die oder lieber deine bauen? :-) Die kommt mit PIC32 > daher für den ich einen Programmer habe. Also so'n Teil an Retro hängen lohnt doch irgendwie nicht. Da kannst du auch gleich einen RasPi dranhängen.
Christian J. schrieb: > Aber da hat allein der A.K. > schuld :-) Mit seinem MK3801 tip, dem Stromfresser mit den 8 Bit > Krücken-Timern. *stichel* Nachdem du den eigentlich sinnvollen SIO aufgrund schier übermenschlicher Komplexität abgelehnt hattest. ;-)
A. K. schrieb: > Also so'n Teil an Retro hängen lohnt doch irgendwie nicht. Da kannst du > auch gleich einen RasPi dranhängen. Meinste? Also meinen kleinen Himbeer Freund hier mit Tesa Krepp hinter den 14z Uralt Flachbildschirm pappen, das teure HDMI/DMI Konverter Kabel dafür verbreezen, einen 1 Euro FTDI RS 232 Konverter mit Heisskleber anpappen und dann die Himbeere so einstellen, dass die ein Terminal Programm im Autostart hochfährt? Ok, so ein 8 Euro Minikeyboard habe ich auch noch, mit Mäuseklaviertasten. Echt Retro.... ;-( Stimmt, die SIO ist echt Hammer, ohne Diplom im E-Technik kaum zu durchschauen. Da komme ich mit dem STM32F429 besser zurecht, der ist wirklich einfach dagegen.....
Jens schrieb: > S. R. schrieb: >> - /INT und /SEL (Chip-Select) werden zentral dekodiert >> und jeweils als eigene Leitung auf "ihren" Slot geführt. > Ich würde dezentral dekodieren. Das schränk man sich nicht gleich von > vornherein ein. Damit braucht man aber mindestens zwei zusätzliche ICs pro Hardware, und muss dann auch noch widerspruchsfreie Basisadressen konfigurieren können. Das war mir zu viel Aufwand. :-) 7 freie Bus-Steckplätze empfand ich als ausreichend, und wenn man will, kann man ja einen SPI- oder I2C-Bus zusätzlich anschließen. Oder man ersetzt zwei ICs ('138, '148) durch ihre 4-Bit-Pendants für 15 freie Steckplätze. Ich werde aber A8..A15 noch umbenennen. Auf dem Bus sind das ja keine Adressleitungen mehr, sondern zusätzliche, unidirektionale Datenleitungen. ;-) > Außerdem würde ich /NMI, /HALT und vor allem /IORQ mit auf die Leiste > setzen. Sonst kann auf den Slaves nur Speicher bzw. memory-mapped-IO > eingesetzt werden. /NMI ist ein Argument, wobei ich nicht weiß, wozu beliebige Hardware den auslösen können sollte. Bisher war der für die MMU reserviert (Zugriff auf nicht existenten Speicher), aber das funktioniert wohl nicht wie gedacht. /IORQ ohne /M1 ist fahrlässig (wegen Interrupt-Acknowledge-Zyklus), daher habe ich beide zusammen mit der Adressdekodierung in /SEL verwurstet. Wenn /SEL fällt, weiß die Hardware, dass sie für einen I/O-Zyklus angesprochen wurde. /HALT wird bei mir durch /WAIT bereitgestellt, was man auch präventiv ziehen kann. Beim nächsten I/O-Zyklus wartet der Z80 dann. Das hat den Vorteil, dass ein popeliger AVR dann auch mit einer ISR auf /SEL schnell genug reagieren kann. Der Vorteil bei mir ist, dass ich normale 36-Pin-Leisten nutzen kann. Die passen auf die kurze Seite meiner Lochrasterplatinen. ;-)
Hi, ich habe mir deinen Thread durchgelesen wo Du CP/M auf einem Board mit AVR und Slots zum Laufen kriegst. Diese AVR Geschichte wollte ich vermeiden, erstens " kann ich kein AVR" außer Arduino und habe keine Umgebung dafür, wohl aber eine für PICs und so einen Hilfsmotor wollte ich nicht auf dem Z80 Board haben. Über CPM gibt es tausend Seiten, alles scheinbar ganz easy - nur hat ein Grant Searle dafür 2 Jahre gebraucht und tausend Anpassungen. Ich wüsste derzeit nur nicht wie ich anfangen soll das in die Kiste zu kriegen. Mit Asm herumschlagen in dem CPM Source Code möchte ich nicht, eher ein Binary einladen und das läuft dann auch auf meiner Hardware. Gibt es denn ein gutes Beispiel für eine CPM kompatible Hardware, wo auch ein Massenspeicher angeschlossen ist? Ich habe weder Monitor, noch Floppy, noch Tastatur, müsste also rein über ein Terminal laufen. Ich bin drauf und dran das hier auf PLatine sauber nachzubauen, denn wie er es beschrieben hat, hat er jedes einzelnen CPM File anfassen müssen. http://searle.hostei.com/grant/cpm/index.html
Moin, ich frage mich grad wo der Unterschied zwischen einem 128k SRAM und einem 128k NVRAM liegt? Außer dass der eine das Format Sarg hat und der andere ein DIP 28 ist. Mit dem RAM läuft er, mit dem NVRAM startet er nicht mal. Pinning ist identisch. NVRAM im Top853 Tester lässt sich einwandfrei beschreiben, verifyen und auslesen. Daten werden auch gehalten. NVRAM ist also ok. Sieht der Z80 aber leider anders... Hatte eiegentlich vor auch das EPROM durch ein NVRAM zu ersetzen. Seltsam....
Schau doch ins Datenblatt. Da wird irgendein Timing nicht passen.
> Schau doch ins Datenblatt. Zu gefährlich. > Da wird irgendein Timing nicht passen. In dem Fall nicht.
Christian J. schrieb: > ich habe mir deinen Thread durchgelesen wo Du CP/M auf einem Board mit > AVR und Slots zum Laufen kriegst. Diese AVR Geschichte wollte ich > vermeiden, [...] Magst du mir bitte verraten, was ein AVR auf einer Platine mit dem Pinout des Bussystems zu tun hat? Irgendwie kann ich deinen Gedankengang nicht nachvollziehen. Mir geht es nicht darum, mein System nachzubauen. Ich habe dir eine aus meiner Sicht einfache Lösung gezeigt, wie du ein Businterface an dein System stricken kannst. Das "wegen Wettervorhersage" zu verwerfen, ist irgendwie uncool. Naja.
Frank K. schrieb: > Schau doch ins Datenblatt. Da wird irgendein Timing nicht passen. Bei so rund 30 "Timing Werten", die alle weit unterhalb des Kolbentaktes des Z80 liegen und ohne Logic Analyzer besserer Art schwierig. Es hat 2-3 Mal geklappt und dann nicht mehr. Da Kompatibilität im Datenblatt zu allen gängingen EPROMs und SRAMs (ASC6C1008) gewährleistet wird schon seltsam. Pins stehen allerdings senkrecht und nicht so wie bei einem normalen IC v-förmig. Kontaktproblem? Da die Dinger recht teuer sind (16 Euro) werde ich aber keinen zweiten mehr bestellen, um das auszuprobieren.
S. R. schrieb: > Magst du mir bitte verraten, was ein AVR auf einer Platine mit dem > Pinout des Bussystems zu tun hat? Irgendwie kann ich deinen Gedankengang > nicht nachvollziehen. Mir geht es nicht darum, mein System nachzubauen. Aneiander vorbei geredet. Ich habe deinen Busvorschlag bereits soweit umgesetzt. Mit der CPM Geschichte hat das aber nichts zu tun, das ist eine andere Baustelle.
> Da Kompatibilität im Datenblatt zu > allen gängingen EPROMs und SRAMs (ASC6C1008) Der Typ Deines NVRAMs ist aber weiter geheim? Der erst beste Typ, den ich mir gestern angeschaut hatte, hatte z.B. nicht die exakt gleiche Pinbelegung wie Dein RAM. Schau doch nochmal genauer hin.
M48Z128 http://www.st.com/web/en/resource/technical/document/datasheet/CD00000526.pdf CE2 ist NC aber das sehe ich schmerzfrei....
> CE2 ist NC aber das sehe ich schmerzfrei....
Dann schau doch nochmal in Deinen Schaltplan.
Leo C. schrieb: > Dann schau doch nochmal in Deinen Schaltplan. Yep !!! Vor lauter Bäumen keinen Wald? ich nutze ja CS2 als Chip Select und lege /CS# auf Masse :-( Musste ich ja für den Switch zwischen ROM/RAM. Also einen freien Inverter irgendwo anzapfen und das umverdrahten. Zumindest wenn der Delay durch den Inverter mir nicht andere Probs verursacht aber das sind nur 10ns. Das Nette am NVRAM ist ja, dass amn gewisse Daten wie ROM Prüfsumme bzw die des geladenen Programmes, Anzahl Starts, Betriebsdauer dauerhaft in einer unbenutzten Ecke ablegen kann. Der Stackpointer wird sicher nichts dagegen haben, wenn ich den auf 0xFFDF lege und die 16 Bytes drüber als geschützten Datenbereich verwende. Die Kiste hat im Dauerbetrieb 1 Woche bisher keine gekippten Bits gezeigt aber man weiss ja nie.
@Leo C. Ist zwar schon 'früh" aber "Tschibo Wild & Stark" macht es möglich um die Zeit noch zu programmieren. Die Umfrickelei der CS war erfolgreich, ein NVRAM sitzt im RAM Sockel und im EPROM Sockel ein DS1643 8k Timekeeper RAM. Die Kiste hat somit auch eine Uhr, die mitläuft. Ok, nicht mehr sooo ganz Retro-Style aber der Fortschritt der Technik macht auch auf dem Basteltisch nicht halt. Nett, dass das OS jetzt durch einen Loader aktualisiert werden kann, der sich selbst einfach nach oben kopiert und von dort aus Intel Hex einlaedt. Funktionen sind ja mit func_START und func_END als .globl gut erreichbar. Als Spezi für den SDCC weisst Du vielleicht auch, wie man ein zweites Datensegment anlegt? Denn das "EPROM" hat ungenutzten Speicher, der für Variablen genutzt werden könnte. Es gibt ja jede Menge Segmente wie HEADER1...10 usw. Könnte man Variablen durch einen Namens-Vorsatz, zu welchem Segment die gehören also in einen gesonderten Bereich packen?m Sowas wie idata und xdata beim MCS51? Aktuell kann ich das nur durch Tricksen mit #define RAM_SPECIAL 0x3400 __at RAM_SPECIAL struct system_type sys; Und alle Vars müssen im struct liegen. Nur suboptimal wie ich finde. Da der Speicher jetzt durchgehend aus 64k RAM besteht müsste CP/M jetzt auch möglich sein. Sperre ich mich aus, kann ich das NVRAM im Brenner ja neu "flashen".
@ LEEEEEEOOOOOOOOOOOOOOOOOOOOOOOOO !!!!!! wink *bruell* Hast Du irgendeine Idee, wie man dem SDCC klarmachen könnte dass eine Funktion nicht im aktuellen Code ist sondern eine fixe Adresse irgendwo hat? extern __at 0x2000 void myfunc(int,int); Damit müsste dem Compiler doch klar werden, wie der Stackframe beladen wird und wo er dann hinspringen soll bei myfunc(5,6); Klappt nur leider nicht, erzeugt einen Linker Fehler. Wäre ihm nicht bekannt. Geht nur mit Variablen derzeit. Zweck: Nutzung der ROM Routinen für RAM Programm damit Einsparung von viel Platz, da derzeit fast alles doppelt vorhanden ist.
Christian J. schrieb: > Hast Du irgendeine Idee, wie man dem SDCC klarmachen könnte dass eine > Funktion nicht im aktuellen Code ist sondern eine fixe Adresse irgendwo > hat? > > extern __at 0x2000 void myfunc(int,int); Bin zwar nicht Leo, aber gerüchteweise soll C so etwas wie Zeiger auf Funktionen kennen. Ich würde es mal damit versuchen... Grüßle, Volker.
Volker Bosch schrieb: > Bin zwar nicht Leo, aber gerüchteweise soll C so etwas wie Zeiger auf > Funktionen kennen. Ich würde es mal damit versuchen.. Ja.... aber nur auf Funktionen, die sich innerhalb der zum Projekt gehörigen Sourcen befinden. Ich weiss nur, dass "InitHardware" bei 0x7A3 liegt und ich es gern hätte, dass er eine virtuelle Funktion da drauf abildet, ohne dass die wirklich da ist. long hoch2(int n) { return n * n; } int main() { long (*rechne) (int); int zahl = 3; rechne = hoch2; int ergebnis = rechne(zahl); Das klappt. Aber wenn hoch2 außerhalb liegt und nur durch seine Adresse bekannt ist? typedef int (*IntFunc1) (void); typedef int (*IntFunc2) (int); kenne ich auch. IntFunc1 ist dann ein Zeiger auf Funktionen, die nichts zurückliefern. Der Compiler muss ja wissen wie er den Stackframe zusammen bauen muss. Das geht sicher irgendwie.....
Christian J. schrieb: >> Bin zwar nicht Leo, aber gerüchteweise soll C so etwas wie Zeiger auf >> Funktionen kennen. Ich würde es mal damit versuchen.. > > Ja.... aber nur auf Funktionen, die sich innerhalb der zum Projekt > gehörigen Sourcen befinden. Ich weiss nur, dass "InitHardware" bei > 0x7A3 liegt und ich es gern hätte, dass er eine virtuelle Funktion da > drauf abildet, ohne dass die wirklich da ist. Das kann ich mir jetzt nicht vorstellen. Um ein Hardware-Register aus C heraus anzusprechen, kann ich einen Zeiger auf dieses Register richten und dieses über ihn lesen und beschreiben. Warum sollte ich nicht auch einen Funktionszeiger anspringen können, den ich ins ROM zeigen lasse. Ohne es jetzt explizit ausprobiert zu haben, würde ich das ungefähr so machen: typedef int (*IntFunc2) (int); int main(void) { IntFunc2 RomFunction; int Val; RomFunction = (IntFunc2)0x1234; Val = (*RomFunction)(17); ... Oder noch kürzer und die Adress-Konstante direkt in den Funktionspointer casten. Zumindest auf dem 68k mit seinem linearen Adressraum sollte das funktionieren. Grüßle, Volker.
:
Bearbeitet durch User
Volker Bosch schrieb: > Ohne es jetzt explizit ausprobiert zu haben, schade > würde ich das ungefähr so machen:
1 | typedef int (*IntFunc2) (int); |
2 | |
3 | int main(void) { |
4 | IntFunc2 RomFunction; |
5 | int Val; |
6 | |
7 | RomFunction = (IntFunc2)0x1234; |
8 | Val = (*RomFunction)(17); |
9 | |
10 | return Val; |
11 | }
|
ergibt:
1 | leo@cb:/tmp$ sdcc -mz80 -S intfunc.c |
2 | Internal error: validateOpType failed in OP_SYMBOL(IC_LEFT (ic)) @ gen.c:4286: expected symbol, got value |
Leider ein Compiler-Bug.
Vorschlag: Linker-Option '-g' nutzen:
1 | 13. -g symbol=expression |
2 | (one definition per line in a linker command file.) |
3 | This specifies the value for the symbol where the ex- |
4 | pression may contain constants and/or defined symbols |
5 | from the linked files. |
c-code:
1 | extern long hoch_rom(int n); |
2 | int main() |
3 | {
|
4 | int ergebnis; |
5 | |
6 | ergebnis = hoch_rom(3); |
7 | return ergebnis; |
8 | }
|
Irgendwo im Makefile:
1 | ld_globals = -g _hoch_rom=0x1234 |
Und das link recipe erweitern:
1 | $(TARGET).ihx: $(CRT0) $(OBJS) |
2 | $(Q)$(LD) $(LDFLAGS) -i $@ \ |
3 | $(ld_segs) \ |
4 | $(ld_globals) \ |
5 | $(patsubst %,-k %,$(LIBDIRS)) \ |
6 | $(patsubst %,-l %,$(LDLIBS)) \ |
7 | $^ |
Die Adressen der ROM-Funktionen könnte man per Script aus dem Mapfile des ROM-Programms ziehen.
Volker Bosch schrieb: > Das kann ich mir jetzt nicht vorstellen. Um ein Hardware-Register aus C > heraus anzusprechen, kann ich einen Zeiger auf dieses Register richten > und dieses über ihn lesen und beschreiben. In Asm eigentlich kein Thema. Man kann das auch so machen wie beim guten alten DOS mit seinem Int21h, wo man viele Funktionen über ein Soft-Int aufrief oder die im Bios Bios mit Int 13h. Ging allerdings nur von Assembler aus damals meine ich. Wenn das ginge würde ich es aber komfortabel wollen, d.h. eine Liste aller Functionen im ROM, wo sie alle Namen kriegen und eine Adresse und dann nur noch aufrufen. Sonst braucht man zuviel Code für die Umwege. Mit Variablen und Registern alles ganz easy, hat jeder Mikro so eine -h Datei wo all seine register definiert werden aber mit Funktionen... tja..
Leo C. schrieb: > Irgendwo im Makefile:ld_globals = -g _hoch_rom=0x1234 Sieht kompliziert aus ... vor allem wenn man das ROM einmal ändert muss man alles neu machen. extern __at 0x1234 void func(int) erzeugt nämlich einen Linker Fehler, dass er das .globl _func nicht kennt und dem begegnet man ja mit der Defintion wie von Leo beschrieben.
Wobei ich erwähnen muss, dass das was ich möchte absolut nicht dem entspricht wie es damals wirklich gemacht wurde .... ausser dem DOS Int und Bios Int fällt mir nichts ein, wo ein User Pogramm sich der Routinen aus dem Monitor bediente.
> Sieht kompliziert aus ... Ich käme nie auf die Idee, Dir etwas kompliziertes vorzuschlagen. Ich verstehe auch nicht, was an der Zeile kompliziert sein soll. > vor allem wenn man das ROM einmal ändert muss > man alles neu machen. Das macht make natürlich vollautomatisch. Das Rezept dazu habe ich oben auch schon haarklein aufgeschrieben. Nur das Script, das die Adressen aus dem Mapfile holt, habe ich Dir als Übung überlassen.
Leo C. schrieb: > Das macht make natürlich vollautomatisch. Das Rezept dazu habe ich oben > auch schon haarklein aufgeschrieben. Nur das Script, das die Adressen > aus dem Mapfile holt, habe ich Dir als Übung überlassen. Du weisst dass ich Null Ahnung von Makefiles habe (was ich gedenke aber noch zu ändern...) und ganz sicher eine Woche brauche, um aus einem Text irgendwelche Teile heraus zu schneiden, die dann anderswo nachj irgendwelchen Regeln, die ich nicht kenne wieder eingesetzt würden. Wenn das nicht standardmässig geht lasse ich es bevor ich da anfange zu "frickeln" und damit in zig neue Probleme reinrenne, die ich vorher nicht hatte. Das Projekt für meine kleine Chip-Fabrik ist mit ca 18 .c Files inzwischen zu gross. Schade, hätte ja sein können dass es direkt gegangen wäre. ld_globals = -g _hoch_rom=0x1234 Und wenn es mehr werden? ld_globals = -g _func1=0x1234 _func2=0x4567 ... Warum kann ich die Globals nicht im crt0.s File definieren? Das geht ja mit den Interrupt Funktionen auch, die dort bekannt gemacht werden und meine Vektortabelle bilden. Er setzt brav die Adressen der ISR dann dort ein, die beim Linken ermittelt wurden. ; Interruptroutinen für den Mostek MK3801 Multi I/O Baustein ; Manual STI Baustein MK3801 Figure 7 .globl _int_sti_gpi_0 ; General Purpose Interrupt 0 .globl _int_sti_gpi_1 ; General Purpose Interrupt 1 .globl _int_sti_gpi_2 ; General Purpose Interrupt 2 und ;/////////////////////////////////////////////////////////// ; Tabelle der Mode 2 Int Vektoren auf die Handler Funktionen im C Modul ; Reihenfolge beachten !!! Siehe Manual Mostek 3801, Interrupt Tabelle .org adr_vec_table .dw (_int_sti_gpi_0) <=== hier kommt 0936 rein, s.u. .dw (_int_sti_gpi_1) .dw (_int_sti_gpi_2) .dw (_int_sti_gpi_3) .dw (_int_sti_timer_d) und aus dem int.c File mit gleichen Namen der Funktionen: 10 ; Public variables in this module 11 ;------------------------------------ 12 .globl _int_sti_receive_error 13 .globl _int_sti_transmit_error 14 .globl _int_sti_gpi_7 15 .globl _int_sti_gpi_6 16 .globl _int_sti_gpi_5 17 .globl _int_sti_gpi_4 18 .globl _int_sti_gpi_3 19 .globl _int_sti_gpi_2 20 .globl _int_sti_gpi_1 21 .globl _int_sti_timer_d 22 .globl _int_sti_timer_c 23 .globl _int_sti_timer_b 24 .globl _int_sti_gpi_0 25 .globl _int_sti_timer_a 27 .globl _int_sti_receive_buffer_full 28 .globl _nmi_vint 230 ; --------------------------------- 231 ; Function int_sti_gpi_0 232 ; --------------------------------- 0936 233 _int_sti_gpi_0_start:: 0936 234 _int_sti_gpi_0: 235 ;interrupt.c:111: EI_RETI; 0936 FB [ 4] 236 ei 0937 ED 4D [14] 237 reti 0939 238 _int_sti_gpi_0_end:: So ähnlich wäre das schon toll....
Heute Mittag habe ich mal was gebastelt. Das angehängte Makefile geht davon aus, daß Dein ROM- und Dein RAM-Programm 2 verschiedene Projekte im jeweils eigenen Verzeichnis sind. Es gibt es 2 neue Variablen.
1 | ROM_MAPFILE := ../rom/build/rom.map |
2 | ROM_FUNCS := _hoch_rom _nocheine_rom |
Im ROM-Projekt läßt Du ROM_MAPFILE einfach leer oder auskommentiert. Im RAM-Projekt gibst Du den Pfad (relativ oder absolut) des ROM-Mafiles an, und in der ROM_FUNCS-Zeile alle Funktionen, die im ROM-Projekt referenziert werden sollen.
Leo C. schrieb: > Heute Mittag habe ich mal was gebastelt. Cool! Danke! Wird morgen ausprobiert.... >> ROM_FUNCS := _hoch_rom _nocheine_rom Was kommt da genau hin? Beispiel? Wie man das lernen soll weiss ich echt nicht....
1 | ifneq ($(strip $(ROM_MAPFILE)),) |
2 | ld_globals = $(shell awk -v GLOBALS="$(ROM_FUNCS)" \ |
3 | 'BEGIN {$$0=GLOBALS; for (i = 1; i <= NF; i++) g_values[$$i] = ""} \ |
4 | END {for (x in g_values) if (g_values[x] != "")print "-g " x "=" g_values[x];}\ |
5 | { if ($$2 in g_values) g_values[$$2] = "0x"substr($$1, length($$1)-4+1)}\ |
6 | '\ |
7 | $(ROM_MAPFILE)) |
8 | endif |
> Was kommt da genau hin? Beispiel?
Die Namen der Funktionen, die im ROM liegen und auf die vom RAM-Programm
aus zugegriffen werden soll.
Also von void wasch_mein_auto(int politur, int wachs, int felgen); würde wasch_mein_auto eingetragen.
_wasch_mein_auto Nachtrag: ja, den führenden Unterstrich könnte man auch automatisch zufügen. Habe ich aus didaktischen Gründen weggelassen.
:
Bearbeitet durch User
Christian J. schrieb: > Wie man das lernen soll weiss ich echt nicht.... Den END-Block braucht man eigentlich nicht. Deshalb gehts auch noch eine Zeile kürzer:
1 | ifneq ($(strip $(ROM_MAPFILE)),) |
2 | ld_globals = $(shell awk -v GLOBALS="$(ROM_FUNCS)" \ |
3 | 'BEGIN {$$0=GLOBALS; for (i = 1; i <= NF; i++) g_symbols[$$i] = ""} \ |
4 | {if ($$2 in g_symbols) print "-g " $$2 "=0x" substr($$1,length($$1) - 4+1)} \ |
5 | '\ |
6 | $(ROM_MAPFILE)) |
7 | endif |
Da ist überhaupt nichts kompliziertes oder trickreiches dran. Lernen kann man daß, in dem man den kompakten Zeichenklotz systematisch in seine Einzelteile zerlegt, und dann das Handbuch zu Hilfe nimmt. [1,2] Dieser Teil ist Makefile-Syntax:
1 | ifneq ($(strip $(ROM_MAPFILE)),) |
2 | ld_globals = $(shell ... |
3 | ) |
4 | endif |
ifneq vergleicht die beiden (epandierten) Texte vor und hinter dem Komma. Innerhalb der ifneq-Klammer wird ggf. awk mit 3 Argumenten ausgeführt. 1. die awk-Variable 'GLOBALS' bekommt schon mal einen Wert zugewiesen. (-v...) 2. Das awk-Script/Programm, das ausgeführt werden soll. (Zwischen den '') 3. Die Datei, die awk lesen und filtern soll. ($(ROM_MAPFILE)) Wenn man awk mit Parameter -o aufruft, bekommt man eine "schön gedruckte" Ausgabe des Scripts:
1 | # gawk-Profil, erzeugt Tue Feb 10 13:07:36 2015 |
2 | |
3 | # BEGIN Blöcke |
4 | |
5 | BEGIN { |
6 | $0 = GLOBALS |
7 | for (i = 1; i <= NF; i++) { |
8 | g_symbols[$i] = "" |
9 | } |
10 | } |
11 | |
12 | # Regeln(s) |
13 | |
14 | { |
15 | if ($2 in g_symbols) { |
16 | print "-g " $2 "=0x" substr($1, length($1) - 4 + 1) |
17 | } |
18 | } |
Der BEGIN-Block zerlegt den übergebenen String in seine Einzelteile (also die zu suchenden Symbole), und legt ein (assoziatives) Array an, dessen Index aus den Symbolen besteht. Dies deshalb, weil man damit sehr bequem mit dem in-Operator suchen kann. Was unter Regeln steht, wird dann auf jede Zeile des Mapfiles angewendet. Wenn also auf 2. Position einer Zeile eines der von uns gesuchten Symbole steht, wird es (passend formatiert) zusammen mit der ersten Position, also dem Wert/der Adresse des Symbols, ausgegeben. [1] http://www.gnu.org/software/make/manual/make.html#index-ifneq [2] http://www.gnu.org/software/gawk/manual/gawk.html
Wieder was dazugelernt aber das ist (derzeit) noch zu kompliziert für jemanden, der wenig Script Erfahrung hat und der vor allem keine Anwendungen dafür hat, weil ich jobtechnisch woanders unterwegs bin, nämlich im Bereich "Maschinenrichtlinie", Functional Safety und der Zulassung von Maschinen und Systemen. Was aber scheinbar funktioniert ist: void(* resetFunc) (void) = 0x1234; Also ein Sprung nach 0x1234 ohne Parameter. ergibt: .area _INITIALIZED A97B 88 _resetFunc:: A97B 89 .ds 2 und 400 ;main.c:146: resetFunc(); 44ED 2A 7B A9 [16] 401 ld hl,(_resetFunc) 44F0 CD E1 7E [17] 402 call __sdcc_call_hl und 857B 453 __xinit__resetFunc: 857B 34 12 454 .dw #0x1234 455 .area _CABS (ABS) ----- Das klappt auch: void(* resetFunc) (int) = 0x1234; und Aufruf resetFunc(15); ergibt: 44EC F3 [ 4] 399 di 400 ;main.c:146: resetFunc(15); 44ED 21 0F 00 [10] 401 ld hl,#0x000F 44F0 E5 [11] 402 push hl 44F1 2A 80 A9 [16] 403 ld hl,(_resetFunc) 44F4 CD E6 7E [17] 404 call __sdcc_call_hl
Und das auch: int (* resetFunc) (int) = 0x1234; mit res = resetFunc(15); 400 ;main.c:146: res = resetFunc(15); 44ED 21 0F 00 [10] 401 ld hl,#0x000F 44F0 E5 [11] 402 push hl 44F1 2A 80 A9 [16] 403 ld hl,(_resetFunc) 44F4 CD E6 7E [17] 404 call __sdcc_call_hl 44F7 F1 [10] 405 pop af Heute keine Zeit mehr aber sieht so aus als ginge das auch ohne Umwege,....
@Leo: Leider war deine Arbeit umsonst :-( Es funktioniert auf die von mir gezeigte Weise aber nur bei Trivial Funktionen wie dem Setzen von LEDs und schon gar nicht bei Textausgabe usw. Ist auch klar, denn das Environment des Monitors ist ja nicht mehr da, wenn das Userprogramm läuft. Es laufen keine Ints, die ISR Routinen liegen woanders. Und das Data Segment muss so liegen, dass sich Userprog und Monitor nicht in die Quere kommen. Das klappt nur dann, wenn das Userprogramm kein Startup hat der die Int Vektoren ummodelt, keine Ints ändert usw. also rein als Call Aufruf läuft und konsequent nur die Subs des Monitors nutzt. Trotzdem interessant dass es auf die oben gezeigte Weise grundsätzlich geht.
Christian J. schrieb: > Das klappt nur dann, wenn das Userprogramm kein Startup hat der die Int > Vektoren ummodelt, keine Ints ändert usw. also rein als Call Aufruf > läuft und konsequent nur die Subs des Monitors nutzt. Was hattest Du denn erwartet? Natürlich musst Du die an die Konventionen des Monitors halten. Wenn der sich um Interrupts kümmert, dann darf man da nicht reinpfuschen. Jens
Was bei einem echten Computer noch sinn macht aber nicht bei einem kleinen Steuerrechner, wo man die Hardware ja braucht. wenn ich mal spass dran habe werde ich das umcodieren. ist ja platzverschwendung alle ncurses routinen doppelt zu haben. bei dos früher musste man ja auch ints wie 21h und 13h, wenn man sie umbog wieder zurück auf ihr eigentliches ziel leiten, sonst crashte er.
Hallo. Nimm doch einfach einen SEL Z80 Lehrcomputer. Da geht alles mit. Sogar Terminalfunktionalitat inkl. Assembler. Einfacher geht es nicht. http://petersieg.bplaced.net/?SEL_Z80_Trainer
>Aber die PIC's (vor allem die kleinen) sind eben gar nicht so doof, >sondern es haben davon einige genau diese Ports, mit denen man sie als >periphere IC's in größere Systeme einbinden kann. Im Prinzip sind das >alle, die einen PortD (für 8 Bit Daten I/O) und PortE (für die >Steuersignale) haben, PIC16F87x wenn ich mich recht erinnere. Damit >können diese Teile direkt an einen Systembus angeschlossen werden. und dieser PSP für tatsächlich "ein ganzes Byte" >Versuche mal sowas bei anderen µC zu finden. Für mehrere Bytes (>4) wohl nur über PLD oder mit MCU mit extBusInterface (über INT).
Ingo schrieb: > Hallo. Nimm doch einfach einen SEL Z80 Lehrcomputer. Da geht alles mit. Da jemand den Thread wieder ausgegraben hat... was soll ich mit so'ner Uralt-Sch...e? Programme auf Programmiertabelle schreiben? Handumrechnung der Mnemocnics und eintippen der Hex Zahlen? So habe ich 1984 angefangen, das Ding liegt sogar noch hier verstaubt, der "KEIL 8085 Lerncomputer" (ja, die KEIL's). Ich würde eher sagen "Da geht nix mit!". Zumindest nicht mehr als Blinki-LED und ein paar trivialste Anwendungen zum Verständnis der Funktionsweise einer CPU.
Holm T. schrieb: > Guck mal hier: > > http://www.tiffe.de/Robotron/Motorola/fbug > > das ist ein Arbeitsstand von vor 3 Monaten oder so :) > > Woher ich den habe? Keine Ahnung, früher mal ftp.funet.fi oder so... > Die Anpassung für die Vektorbasisregister-Geschichte und Trap Stackframe > für den 68010 habe ich da vor Jahren schon mal eingebaut, 68010 war zwar > vorgesehen aber noch nicht fertig. Danach ging mit dem gcc kein Coff > mehr > und ich habe nochmal umgebaut. am gcc/ld ist da sicherlich noch viel > Arbeit, aber der Kram funzt erst mal. > Den letzten Stand müßte ich aber auch erst hoch laden, üb den Stand auf > dem Server lief mal eine Problemdiskussion in diesem Forum, Abteilung > gcc.. > > Gruß, > > Holm Hallo Holm, ich habe deinen FBUG da ein wenig angeschaut. Ich möchte den gerne benutzen, doch weiss ich nicht so recht, was ich da alles brauche. Ist der Source, der da in dem Verzeichnis liegt, so lauffähig? was muss ich da alles beachten, wenn ich das auf meiner eigenen Hardware laufen lassen möchte? konkret habe ich eine Hardware mit MC68332. Einen DUART (68681) habe ich da nicht drauf, denn der '332 hat einen integrierten UART. Den möchte ich benutzen. Brauche ich noch was anderes, um den Monitor so benuzen zu können?
Ich würde Dir den Fbug für den 68332 nicht empfehlen, da wäre zu viel zu machen, angefangen von der anpassung des Codes für die Uart bis zum nicht passenden Stackframe bei Traps. Es gab aber IMHO einen CPU32bug von Motorola der als Binärblob ausgeliefert wurde, dazu ein Users Manual mit der Beschreibung der notwendigen Patches zur Anpassung an die Hardware. Ich habe das vor Jahrzehnten mal gemacht auch noch das User Manual auf totem Baum im Schrank. Ob ich den Monitor als Binrary noch habe weiß ich nicht, ich habe aber eine KatCe332 mit einem Erpom wo der drauf ist.. Suche erstmal ob Du das irgendwo zum Download noch bekommen kannst. Edit: ftp://gort.ludd.ltu.se/pub/misc/motorola/mcu332/ Die c32* Files enthalten den CPU32BUG, das Manual findest Du alleine.. Gruß, Holm
Da gibt's sogar noch was bei NXP (= ex Freescale (= ex MOTOROLA)): http://www.nxp.com/products/microcontrollers-and-processors/more-processors/coldfire-plus-coldfire-mcus-mpus/68kmpus-legacy/m683xx/32-bit-microcontroller:MC68332?fpsp=1&tab=Design_Tools_Tab
Hi Holm, danke dir für die Links. Habe da mal rein geguckt. Da sind zwar S-Records drin, aber den Source vom CPU32Bug scheint es wohl nirgends zu geben? das ist sehr schade. Ich weiss nicht wie man das zum Laufen kriegen soll, wenn man nur die compilierten S-Records hat. Aber danke trotzdem, ich werde mal ein wenig herum pröbeln.
Wie man das zum Laufen bekommt steht im Manual: http://www.ece.ualberta.ca/~cmpe401/docs/cpu32bug.pdf Quellen habe ich keine gefunden. Gruß, Holm
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.