Hallo,
ich bin auf
https://wikiti.brandonw.net/index.php?title=Z80_Routines:Math:Square_root
auf ein Assemblerprogramm zur Wurzelberechnung gestoßen. Dabei ist mir
Bytedefinitionen mitten im Programm aufgefallen, auf die ich mir keinen
Reim machen kann, hier ein kurzer Ausschnitt, das ganze Programm im
Anhang:
1
add a,d ; 4
2
jr nc,sq6 ; 12 / 7
3
res 5,d ; 8
4
db 254 ; 7
5
sq6:
6
sub d ; 4
7
sra d ; 8
Mann kann ja einen Befehl durchaus auch als Byte definieren, aber hier
macht das irgendwie keinen Sinn: 254 ist FEh und CMP n. "n" ist dann
"sub d", also 92h. Kann sich da jemand einen Reim drauf machen, ich
würde das gerne verstehen.
(Edit: code tags eingebaut - Mod.)
Das war früher so üblich, um die Codegröße zu reduzieren. Damit wird
"sub d" ignoriert (cp setzt nur die Flags) und man spart sich den Sprung
auf "sra d".
In lang sähe das so aus:
Nachtrag: Um zwei Bytes zu ignorieren wurde z.B. 01h (ld bc,n)
verwendet.
Es gab auch mal einen Assembler, bei dem konnte man das direkt
formulieren, das sah ungefähr so aus:
1
cp a, {sq6:sub d}
Ach ja, man spart auch (WIMRE, seitdem sind einige Jahrzehnte vergangen)
einen Taktzyklus gegenüber der Variante mit jp.
Zino schrieb:> Das war früher so üblich, um die Codegröße zu reduzieren
Also ob das so üblich war, weiß ich nicht. Es ist richtig "dreckig"
programmiert meiner Ansicht nach. Ich hab nie zu solch seltsamen
Methoden gegriffen (greifen müssen).
Gut lesbarer Code war mir damals mit Z80 Assembler auch schon wichtig.
Der oben gezeigte ist das definitiv nicht.
900ss schrieb:> Also ob das so üblich war, weiß ich nicht.
Kenne ich von 6502, da war das auch nicht so selten.
> Gut lesbarer Code war
... das mit einem Makro-Assembler. Notfalls schrieb man eben
db skip1byte
db skip2bytes
Eine andere Variante, bestens geeignet um Disassembler zu ärgern, waren
Parameter direkt hinter einem Unterprogrammaufruf. Sowas wie
call stringcompare
db 'word' - letztes Byte mit Bit 7 gesetzt
Ein 8 KB Zwerg-Compiler bestand fast nur aus sowas in der Art. Das
Unterprogramm hat sich den PC aus dem Stack geholt, inkrementell den
String abgegrast, und hinterher wieder zurück geschrieben. Bei 8080/Z80
konnte man die wichtigsten solchen Aufrufe um 2 Bytes kürzen, indem man
RST Opcodes an Stelle von CALL verwendete.
900ss schrieb:> Also ob das so üblich war, weiß ich nicht. Es ist richtig "dreckig"> programmiert meiner Ansicht nach. Ich hab nie zu solch seltsamen> Methoden gegriffen (greifen müssen).
du Glücklicher, ich wollte PC1500 relokatibel programmieren um es in
EEPROM in verschiedene Adressbereiche einbauen zu können.
Es gab aber kein jsr jump sub routine wo man mit ret/rts zurück kam!
Der aktuelle PC programm counter konnte auch nicht gelesen werden aber
man konnte ihn in Register schieben diese dann auslesen und mußte nur
noch vom Stack lesen und die Korrekturbytes am Stack manipulieren, waren
wohl 6 bytes und so konnte man mit jump branch vorwärts oder rückwärts
um x Byte springen um mit RTS oder RET genau da weiter zu machen von wo
man herkam.
(prx) A. K. schrieb:> das mit einem Makro-Assembler. Notfalls schrieb man eben> db skip1byte> db skip2bytes
Ja so wäre es schon deutlich besser wenn es denn sein muss zu solchen
Maßnahmen zu greifen.
Ein weiterer Grund für .DB-Anweisungen mitten im Code waren
etliche INOFFIZIELLE Befehle der Z80, die sich damit umsetzen ließen.
Natürlich war das brandgefährlich, da völlig unsicher war ob
jedes Derivat die auch unterstützte.
Bernd M. schrieb:> Danke, habs kapiert. Es geht also nur darum, sich das überspringen des> "sub d"-Befehls zu sparen. Very tricky.
Und wenn Du die Webseite, die Du verlinkt hattest, bis zum Ende gelesen
haettest, haettest Du die Webseite des Autors (John Metcalf,
http://www.retroprogramming.com) gefunden.
In seinem Blog-Eintrag
(http://www.retroprogramming.com/2017/07/a-fast-z80-integer-square-root.html)
findest Du die Herleitung des Algorithmus in C (Square-Root with
Bit-shifting, sehr schoenes Stueck Software) und die Erklaerung fuer die
Konstanten (fuer das Code-Overlapping):
Noch ein Grund war, zu verhindern, dass jede Nase sofort kapiert, was
der Code macht. Also zwischen Ende eines Unterprogramms und Anfang des
nächsten ein "db ErstesByteDreiByteBefehl" brachte damals noch den
Disassembler ins Schlittern.
Hallo!
Ich habe für einige kleine Z80-Systeme ganz ohne RAM Software
geschrieben und dennoch Unterprogramme trotz fehlendem Stack verwendet.
Für diese Funktion wurde ein Register (IX oder IY) missbraucht.
Also z.B.:
....
LD IX,lab100 ;Returnadresse
JMP up100 ;oder JR up100
lab100: LD a,xy... ;hier gehts nach der Subroutine up100 weiter
....
up100:
LD DE,para3...
....
JP (IX) ;statt RET
Es funktionierte problemlos in einem 8-fach EPROM-Programmer für 2716 in
der Serienproduktion zur Vervielfältigung aus einem Muster-2716.
Route_66 H. schrieb:> Ich habe für einige kleine Z80-Systeme ganz ohne RAM Software> geschrieben und dennoch Unterprogramme trotz fehlendem Stack verwendet.> Für diese Funktion wurde ein Register (IX oder IY) missbraucht.
RCA hat das auf die Spitze getrieben mit dem CDP1802 ("COSMAC"). Der
hatte 16 völlig gleichberechtigte Register, und jedes konnte
Programmzähler sein. Zum Springen hat man einfach das Register
umgeschaltet.
> So hard-core-Optimieren haette ich selbst in meiner Jugendzeit nicht> gemacht, weil man den Code ein Jahr spaeter nicht mehr versteht.
Ist halt die Frage, ob man das noch zum Algo optimieren zählen sollte,
oder eher unter die Rubrik "CPU-Architektur ausnutzen/"mißbrauchen".
Denn Architekturunabhängig ist so ein Code sicher nicht.
Nur bei so schmalen Datenbussen wie in der 8 bit Ära konnte man Code
überlappen, bei breiten Daten-Bussen geht das dann nicht mehr.
Mit Harvard Architektur hat man sogar getrennte Busse, kann also weiter
8 bit Daten schubsen mit bspw. 13 Bit Befehlscodebus (AVR?) .
IMHO lohn es sich eher die "mathematischen Tricks" (Numerik) zu
lernen/verstehen, um dann schnell eine ausreichend genaue Berechnung
runterzureissen; beispielsweise der Taschrechner von sinclair von 1973,
alle 4 Grundrechenarten aus gerade 320 ROM-Worten:
https://static.righto.com/calculator/sinclair_scientific_simulator.html
und ich frage mich heute noch wiese ein Mephisto Schachcomputer ohne
gross RAM ein PC-Schachprogramm auf 4 Mbyte schlagen konnte.
Bradward B. schrieb:> bei breiten Daten-Bussen geht das dann nicht mehr
Geht genauso, sofern die Befehle ein Byte–Stream sind, keine RISCs mit
fester Befehlslänge. Nur die Implementierung stolpert u.U. über die
eigenen Füsse und muss zeitraubend neu aufsetzen.
Disassembler ärgern kann man noch viel besser mit selbstmodifizierendem
Code, das habe ich noch auf dem x86 gerne gemacht. Für Assembler auf dem
Z80 oder 6502/10 bin ich zu jung.
Ben B. schrieb:> Disassembler ärgern kann man noch viel besser mit selbstmodifizierendem> Code,
Damit konnte man allerdings auch die Implementierer von Prozessoren ganz
böse ärgern.
(prx) A. K. schrieb:> Ben B. schrieb:>> Disassembler ärgern kann man noch viel besser mit selbstmodifizierendem>> Code,>> Damit konnte man allerdings auch die Implementierer von Prozessoren ganz> böse ärgern.
Naja, der Z80 oder 6502 hatten ja keinen Cache. Da konnte man sogar das
Byte nach dem gerade verarbeiteten Opcode überschreiben.
Ich kann mich lebhaft an einen Fall auf den 6510 (aka C64) erinnern, wo
der Code nur verschleiert war (EOR mit einem festen Byte). Ich habe da
lange gegrübelt wie der Prozessor die Schleife verläßt um den Code
anzuspringen. Dann fiel es mir wie Schuppen von den Augen: die
EOR-Schleife schloß sich mit einem relativen Sprung und verwendete auch
sonst selbstmodifizierenden Code um mehr als 256 Byte entschlüsseln zu
können. Sie lief allerdings rückwärts durch den RAM. So hat sie dann
irgendwann mal die Sprungdistanz des finalen BRAnches überschrieben. Und
das war der Moment wo die Schleife endete :)
Ich kenne es nur vom Hörensagen, aber die Geschichte ist zu schön, um
nicht erzählt zu werden.
Ein Kollege berichtete, daß sie früher auf der PDP (wahrscheinlich
PDP-11) einen kleinen Trick gemacht hätten, um den doch begrenzten
Speicher optimal zu nutzen.
In den Programmbefehlen gab es "ungenutze Bits", also solche, die für
den Programmablauf nicht benötigt wurden. Hier konnte man Daten
speichern - natürlich verteilt über mehrere Programmbefehle.
Also nicht nur selbstmodifizierender Code, sondern auch noch die
Vermischung von Daten und Programm...
Was aber genial an der PDP war, ist die Tatsache, daß sie vollständig
dokumentiert war. Ebenso die RS6000 von IBM. So habe ich damals ca. 30
Leitz-Ordner (es war natürlich eine andere Marke, die damals schon einen
Plastikeinband hatten, der fürchterlich gestunken hat) "geerbt", in den
massenweise Schaltpläne waren. Auch war jeder einzelne Befehl einzeln
haarklein dokumentiert mit allen Auswirkungen.
Und nein, die gibt es nicht mehr. Nachdem sie noch ein paar Jahre im
Serverraum herumstanden und ein Regal gefüllt haben, habe ich sie dann
entsorgt.
Svensson schrieb:> In den Programmbefehlen gab es "ungenutze Bits", also solche, die für> den Programmablauf nicht benötigt wurden. Hier konnte man Daten> speichern - natürlich verteilt über mehrere Programmbefehle.> Also nicht nur selbstmodifizierender Code, sondern auch noch die> Vermischung von Daten und Programm...
Das ging auch beim Motorola 68000 Prozessor. Der hatte 24
Adressleitungen für 16 MB, die Adressregister und der Adressteil der
Befehle war aber 32 bit lang. Also konnte man im oberen ungenutzten Byte
andere Informationen ablegen, z.B. zur Speicherverwaltung.
Es gab damals so eine Computerfirma in Cupertino, die haben das
ausgiebig genutzt. Da musste immer alles billig, billig sein, deshalb
sollte das 68k-System mit satten 128k Speicher auskommen und jedes Byte
war wertvoll. Später hat man dann gewaltig abgekotzt, um die Software
"32 bit clean" zu bekommen, so dass man auch den Adressraum eines
MC68030 jenseits der 16 MB ansprechen konnte.
(prx) A. K. schrieb:> Eine andere Variante, bestens geeignet um Disassembler zu ärgern, waren> Parameter direkt hinter einem Unterprogrammaufruf. Sowas wie> call stringcompare> db 'word' - letztes Byte mit Bit 7 gesetzt
Ich habe das sehr gerne beim 8051 gemacht. Es ärgerte mich, daß man in
Assembler nicht einfach die Argumente dort hinschreiben kann, wo man sie
im Ablauf brauchte. Die Texte und Daten standen also sonst wo, was das
Lesen und Ändern erschwerte. Obendrein mußte man vor den Aufrufen ein
Register mit der Adresse laden.
Beim 8051 geht das mit den Daten im Code sehr bequem, einfach den SP ins
DPTR laden. Und am Ende nach DPTR springen. Der Keil C51 benutzt das
z.B. bei switch/case.
Svensson schrieb:> In den Programmbefehlen gab es "ungenutze Bits", also solche, die für> den Programmablauf nicht benötigt wurden. Hier konnte man Daten> speichern - natürlich verteilt über mehrere Programmbefehle.
Braucht man dann nicht wieder immensen Programmcode um die Daten da
rauszuziehen?
Stelle ich mir nicht sehr effektiv vor.
Wer beim Z80 mal noch ein einzelnes Bit braucht, kann das MSB im
Refresh-Register verwenden...
Peter D. schrieb:> (prx) A. K. schrieb:>> Eine andere Variante, bestens geeignet um Disassembler zu ärgern, waren>> Parameter direkt hinter einem Unterprogrammaufruf. Sowas wie>> call stringcompare>> db 'word' - letztes Byte mit Bit 7 gesetzt>> Ich habe das sehr gerne beim 8051 gemacht
...
> Beim 8051 geht das mit den Daten im Code sehr bequem, einfach den SP ins> DPTR laden. Und am Ende nach DPTR springen.
Bei Z80 ging das auch gut, der hatte EX (SP),HL um die Adresse auf dem
Stack mit dem HL Register zu tauschen. Das sah dann so aus:
>> Disassembler ärgern kann man noch viel besser>> mit selbstmodifizierendem Code,> Damit konnte man allerdings auch die Implementierer> von Prozessoren ganz böse ärgern.
Ist korrekt, mindestens der 80486 merkt es nicht, wenn der Programmcode
bereits in den Cache geladen ist. Aber genau das kann man auch super
nutzen, um die böhsen Disassembler zu foppen. Man ruft über den
DOS-Interrupt irgend eine bedeutungslose Funktion auf (z.B. AH=30h Get
DOS Version) und ein paar Befehle vorher modifiziert man das MOV AH,30h
in MOV AH,4ch (Terminate Program). Der 486er führt den INT 21h dann
trotzdem mit AH=30h aus, im Debugger ändert sich der Code auf Terminate
Program und sorgt zumindest kurz für ein Fragezeichen im Gehirn.
Funktioniert leider nicht mehr mit neueren Prozessoren, der Pentium
merkt es bereits und lädt die Befehlswarteschlange neu (das Programm
beendet sich dann auch ohne Debugger). Wenn der Effekt beim 486er stört,
kann man nach dem Code modifizieren einen Sprungbefehl ausführen, dann
lädt der 486er die Befehlswarteschlange auch neu.
Das waren noch Zeiten... Rumspielen mit den "Trace"-Interrupts, Teile
des Programms im Bildschirmspeicher ausführen... dann kommt im Debugger
Freude auf.
Soul E. schrieb:> Das ging auch beim Motorola 68000 Prozessor. Der hatte 24> Adressleitungen für 16 MB, die Adressregister und der Adressteil der> Befehle war aber 32 bit lang. Also konnte man im oberen ungenutzten Byte> andere Informationen ablegen, z.B. zur Speicherverwaltung.>> Es gab damals so eine Computerfirma in Cupertino
Microsoft hat das auch beim original Amiga-Basic so gemacht. Mit einem
echten 32-Bitter lief das dann nicht mehr.
Gruß
Jobst
Jochen schrieb:> Ein weiterer Grund für .DB-Anweisungen mitten im Code waren> etliche INOFFIZIELLE Befehle der Z80, die sich damit umsetzen ließen.>> Natürlich war das brandgefährlich, da völlig unsicher war ob> jedes Derivat die auch unterstützte.
Welche Befehle soll es noch geben? Ich habe ein Buch über den U880, dort
ist im Befehlssatz keine Lücke.
Das kenne ich nur vom 6502/10, bei dem "illegale Opcodes" eine
Kombination aus mehreren Befehlen erlauben. Die meisten führen zum
Absturz des Prozessors, aber viele sind wirklich sinnvoll nutzbar - und
man könnte sagen, es ist sogar garantiert, daß sie auf jedem dieser
Prozessoren funktionieren. Da findet man sehr viel in der C64-Ecke, wo
solche Tricks regelmäßig benutzt wurden, ganz besonders in der
Demo-Szene. Ich glaube, als Commodore das Ding damals entworfen und
gebaut hat, war nicht mal denen klar, wozu diese Hardware fähig ist.
Hardy F. schrieb:> Welche Befehle soll es noch geben? Ich habe ein Buch über den U880, dort> ist im Befehlssatz keine Lücke.
Es handelt sich um die 2-Byte-Befehle bei denen das erste Byte DDh, EDh
und FDh ist, da ist bei dem 2. Byte noch genug frei. Besonders bei den
Indexbefehlen soll einiges gehen, aber ich habe mich damit noch nicht
befasst.
Hardy F. schrieb:> Warum? Der U880 war viel besser …> … bei mir zu bekommen.
Der hat die „erweiterten“ Befehle genauso gehabt wie der originale Z80.
Wurde seinerzeit auch in Zeitschriften diskutiert.
Übertrieben nützlich waren sie aber meist nicht, zumal es eben
langwierige Präfix-Befehle sind.
Hardy F. schrieb:> Zino schrieb:>> Hardy F. schrieb:>>> Welche Befehle soll es noch geben? Ich habe ein Buch über den U880, dort>>> ist im Befehlssatz keine Lücke.>>>> Falsches Buch. Versuche dieses:>> http://www.z80.info/zip/z80-documented.pdf>> Warum? Der U880 war viel besser …> … bei mir zu bekommen.
Es geht nicht um U880 vs Z80 sondern um die undokumentierten
Instruktionen. Offensichtlich hast Du keinen einzigen Blick in jenes
Dokument geworfen. Ich gebe zu, der Name ist etwas irreführend.
Herrliche Diskussion,da habe ich gleich mal mein Letztes Stück den LC80
eingeschaltet.
und er funktioniert noch....
War immer etwas schwieriger die Relativsprünge Fehlerfrei zu berechnen
und einzugeben.
Dafür hatte ich unter Anderen eine Berechnungsroutine in einen
Zusätzlichen E-Prom geschrieben.
MfG
ein alter 80 Jähriger aufmerksamer Knacker
Also, es heisst "undocumented" nicht "illeagl" und da dazu zählte man
auch "zweckfreie" Befehle, die in ihrer Funktion zum NOP identisch
waren.
Es ist halt so, das beim Auscodieren des Zustandsvector einer FSM auch
Bit-kombinationen gibt, die im Betrieb nicht witklich entstehen. Bspw.
kann man halt mit 4 FF 16 Zustände codieren, braucht weniger davon.
Dann codiert man die Zustände halt so, das man Logic per QuineMcClusky
o.ä. optimieren kann.
Edit:
Ich les grad, beim x86 gibt es die Exception 6 wenn die Befehlseinheit
auf einen Opcode stösst, dem kein Befehl zugeordnet werden kann. Ist
halt kein Z80 und wird daher hier nicht vertieft.
Die schönste Form ist von Zuse überliefert: "The Z1 (1938) and Z3 (1941)
computers built by Konrad Zuse contained illegal sequences of
instructions which damaged the hardware if executed by accident."
https://en.wikipedia.org/wiki/Halt_and_Catch_Fire_(computing)
>> Der LC80 hat keinen Z80.>> Nicht? Und was bitte ist ein U880?
Ein U880 ist ein U880 und kein Z80.
Kannst auch "faked Z80" dazu sagen.
Oder Raubkopie-Z80.
> Die schönste Form ist von Zuse überliefert: "The Z1 (1938) and Z3 (1941)> computers built by Konrad Zuse contained illegal sequences of> instructions which damaged the hardware if executed by accident."> https://en.wikipedia.org/wiki/Halt_and_Catch_Fire_(computing)
Halt (Elektro-)Mechanik-Rechner, bei "112" kommt die Feuerwehr ;-)
Wiedermal ein geiler Thread auf mikrocontroller.net!
Im Osten wurden Programme oftmals mit ner Sprungtabelle
am Anfang des Programmes mit Sprüngen auf die einzelnen
Funktionen implementiert.
War das damals ne Ost-Mode oder war soetwas auch
in den gebrauchten Ländern üblich?
mfg
Harald K. schrieb:> Bradward B. schrieb:>> Der LC80 hat keinen Z80.>> Nicht? Und was bitte ist ein U880?
Der U880 war dem Z80 funktional nachempfunden. Aber er war keine
abfotografierte 1:1 Kopie, wie in der Journaille oft behauptet, sondern
wurde an die vorhandenen Prozese angepasst neu implementiert. Einzelne
Schaltungsteile weichen in der Umsetzung ab. Daher können die
undokumenterten Funktionen des Z80 auch beim U880 vorhanden sein, sie
müssen es aber nicht.
Lotta . schrieb:> Im Osten wurden Programme oftmals mit ner Sprungtabelle> am Anfang des Programmes mit Sprüngen auf die einzelnen> Funktionen implementiert.>> War das damals ne Ost-Mode oder war soetwas auch> in den gebrauchten Ländern üblich?
Das war üblich, und zwar für Funktionen, die auch von extern benutzt
wurden. Der Sinn so einer Sprungtabelle war, für die externen Zugriffe
einheitliche Einsprungadressen bereitzustellen, die sich auch dann nicht
ändern, wenn die Funktionen mal neu geschrieben werden. So wie heutige
APIs und DLLs.
Das machte man auch, wenn die einzelnen Teile des Programmes von
verschiedenen Leuten geschrieben und später zusammengebaut wurden.
> Im Osten wurden Programme oftmals mit ner Sprungtabelle> am Anfang des Programmes mit Sprüngen auf die einzelnen> Funktionen implementiert.>> War das damals ne Ost-Mode oder war soetwas auch> in den gebrauchten Ländern üblich?
Da der Osten "gern" den Westen nachgebaut/kopiert hat ...
Wenn man es nicht so macht, kriegt man sowas wie das Monitor Programm
vom AIM65, dessen API mitten ins ROM springt. Sowas wie Adresse E123 für
Zeichenausgabe und FEDC für Druckfunktion. Bissel blöd, wenn man Fehler
darin korrigiert. Weshalb sich an dessen Ende ein paar Flicken fanden,
die von vorne angesprungen wurden und von dort wieder zurück sprangen,
weil sich die Einsprungadressen nicht mehr ändern durften.
Ich bin deshalb auch Systemen begegnet, die solche Einsprünge als
Sprungleiste vorneweg implementierten.
Lotta . schrieb:> Warum wurde es so gemacht, gibts da ein besonderen Grund?
z.B. damit relokalisierbarer Code Biosfunktionen erreichen oder gar
implementieren kann
Ähnlich: Softwareinterrupts
Soul E. schrieb:> Lotta . schrieb:>> Im Osten wurden Programme oftmals mit ner Sprungtabelle>> am Anfang des Programmes mit Sprüngen auf die einzelnen>> Funktionen implementiert.>>>> War das damals ne Ost-Mode oder war soetwas auch>> in den gebrauchten Ländern üblich?>> Das war üblich, und zwar für Funktionen, die auch von extern benutzt> wurden. Der Sinn so einer Sprungtabelle war, für die externen Zugriffe> einheitliche Einsprungadressen bereitzustellen, die sich auch dann nicht> ändern, wenn die Funktionen mal neu geschrieben werden. So wie heutige> APIs und DLLs.>> Das machte man auch, wenn die einzelnen Teile des Programmes von> verschiedenen Leuten geschrieben und später zusammengebaut wurden.
Quasi ne Public-Schnittstelle?
Nicht schlecht!
Ich hab mich nur gewundert, das die Tabelle nie in den RAM
geschrieben wurde, was ja ne interruptähnliche Verwendung
ermöglicht hätte...
Huch, da war schon einer schneller... :-P
mfg
Bradward B. schrieb:>> Da der Osten "gern" den Westen nachgebaut/kopiert hat ...
Und verbessert! Der 1057 von Robotron kam mit allen angeschlossen
Geräten klar. Auf der Seite https://www.eser-ddr.de ist allerdings das
Produktionsjahr des 1057 falsch, ich habe schon 1986/1987 an dieser
Maschine das Fehlersuchen gelernt.
Hardy F. schrieb:> Bradward B. schrieb:>>>> Da der Osten "gern" den Westen nachgebaut/kopiert hat ...>> Und verbessert! Der 1057 von Robotron kam mit allen angeschlossen> Geräten klar. Auf der Seite https://www.eser-ddr.de ist allerdings das> Produktionsjahr des 1057 falsch, ich habe schon 1986/1987 an dieser> Maschine das Fehlersuchen gelernt.
Ja,
Die Drogenszene des Westens hat ja auch zu ihrer Finanzierung
genug Quellcode in den Osten geliefert, warum sollte er nicht darauf
aufbauen?!? :-P
mfg
> Der U880 war dem Z80 funktional nachempfunden. Aber er war keine> abfotografierte 1:1 Kopie, wie in der Journaille oft behauptet, sondern> wurde an die vorhandenen Prozese angepasst neu implementiert. Einzelne> Schaltungsteile weichen in der Umsetzung ab.
Bspw. erinnere ich mich dunkel an unterschiedliches Verhalten der nM0
und nM1 Ausgangsleitungen bei IO-Zugriffen (nIOREQ = 'L'), was je nach
Verdrahtung auf dem Board bei der Ansteuerung der Peripherieschaltkreise
(PIO, CTC, ...) zu Problemen führen kann.
Und da Schaltungsteile (bspw. Register) als statische Speicher und nicht
in dynamischer TransferGate Technologie gebaut waren, reagieren Z80 und
seine Raubkopien unterschiedlich auf unterschiedliche Taktung bspw.
Unter-Taktung. Und das auch noch gern Temperaturabhängig. Das Vermögen
hohe kapazitiven Lasten bei langen leitungslängen/Fan-out zu treiben war
auch unterschiedlich.
Und es gab beim Nachbau eigene Design-Entscheidungen, ob man erkannte
"Logik-fehler" (gemeint sind wohl Diskrepanzen zum Z80-Datenblatt)
ausmerzt oder im Sinne der Export-Eignung 1:1 nachbaut ("It's not a bug,
it's a feature").
Thomas W. schrieb:> So hard-core-Optimieren haette ich selbst in meiner Jugendzeit nicht> gemacht, weil man den Code ein Jahr spaeter nicht mehr versteht.
Um Code auch nach längerer Zeit noch verstehen zu können, gab es auch
damals schon die Möglichkeit für Kommentare. Selber Schuld, wer das bei
solchen Tricksereien nicht nutzt.
> Die Drogenszene des Westens hat ja auch zu ihrer Finanzierung> genug Quellcode in den Osten geliefert, warum sollte er nicht darauf> aufbauen?!? :-P
Geliefert ist gut, die haben dem KGB den offenen Minix-Quellcode
verkaufen wollen - hat aber der KGB gemerkt. Oder einer der vom KGB in
Sibirien verknackten Wissenschaftler.
https://de.wikipedia.org/wiki/KGB-Hack> Um Code auch nach längerer Zeit noch verstehen zu können, gab es auch> damals schon die Möglichkeit für Kommentare. Selber Schuld, wer das bei> solchen Tricksereien nicht nutzt.
Naja, bei 16kb Arbeitsspeicher bietet der Editor nicht viel Platz für
Kommentare neben den Mnemonics. Und was für den einen "Tricksereien",
das für den anderen fachspezifische Allgemeinbildung für die man eine
mehrjährige Ausbildung erfolgreich absolviert hat.
Und "dokumentiert" wurde/wird gern mündlich -"Wenn Du Fragen hast,
kannste gern bei mir vorbeikommen ..."
Bradward B. schrieb:>> Die Drogenszene des Westens hat ja auch zu ihrer Finanzierung>> genug Quellcode in den Osten geliefert, warum sollte er nicht darauf>> aufbauen?!? :-P>> Geliefert ist gut, die haben dem KGB den offenen Minix-Quellcode> verkaufen wollen - hat aber der KGB gemerkt. Oder einer der vom KGB in> Sibirien verknackten Wissenschaftler.>> https://de.wikipedia.org/wiki/KGB-Hack
Naja, es gab auch noch mehr Leute als Hagbard Celline.
Und die haben sich besser angestellt. Immerhin hat
die Stasi die Telefongespräche über Scatting mitgehört,
und hatten auch die Hälfte der erpreßbaren Siemens-Mitarbeiter
unter Vertrag. ;-P
mfg
Bradward B. schrieb:> .... Und was für den einen "Tricksereien", das für den anderen> fachspezifische Allgemeinbildung für die man eine mehrjährige> Ausbildung erfolgreich absolviert hat.>> Und "dokumentiert" wurde/wird gern mündlich -"Wenn Du Fragen hast,> kannste gern bei mir vorbeikommen ..."
Was spielt das für eine Rolle, wenn es um ein und die selbe Person geht?
Thomas W. schrieb:> So hard-core-Optimieren haette ich selbst in meiner Jugendzeit nicht> gemacht, weil man den Code ein Jahr spaeter nicht mehr versteht.
Bradward B. schrieb:> Naja, bei 16kb Arbeitsspeicher bietet der Editor nicht viel Platz für> Kommentare neben den Mnemonics.
Es soll ja Gerüchten zufolge auch die Möglichkeit gegeben haben,
Quelltext in sogenannten Dateien auf Dateisystemen abzuspeichern. Und
die konnten dann auch größer werden als der dem Editor zugängliche
Arbeitsspeicher. Sowas war dann in der Handhabung ungeschickt, weil der
Editor bei Sprüngen im Quelltext immer wieder was nachladen musste, aber
sowas konnte einem auch gleich beibringen, Programme modular zu
gestalten, d.h. nicht alles in ein ellenlanges Assemblerlisting zu
stopfen.
Dabei konnten einem damals schon Programme wie Linker helfen.
Ok, wenn man das Pech hatte, an einem Computer zu arbeiten, der gar
keine Dateien kannte (sondern nur Dinge auf Cassettenrecorder speichern
konnte), dann hatte man natürlich die Arschkarte gezogen.
Mein allererster eigener Computer gehörte zu dieser Fraktion, allerdings
hatte der keine 16 kByte Arbeitsspeicher, sondern effektiv nur eines,
und das mit dem Kassettenrecorder war auch zum Abgewöhnen.
Der nächste, komplett selbstgebaute, hatte dafür zwei Diskettenlaufwerke
und eine kombinierte RAM- und ROM-Disk, in letzterer landeten die
meistbenutzen Programme (Editor, Assembler etc.), in ersterer lag der
Kram, der gerade bearbeitet wurde -- ich durfte nur nicht vergessen, die
Arbeit gelegentlich auf Disketten zu kopieren.
Der Arbeitsspeicher des Computers war 48 kB groß, die RAMdisk 256 kB und
die ROMdisk auch. Um Graphik hat sich das angeschlossene Graphikterminal
gekümmert (genauer, ein c't-Lötprojekt namens "Grip"
http://www.prof80.de/files/grip1.pdf).
Später nutzte ich ein selbstgebautes Textterminal mit 96 Zeichen pro
Zeile in 25 Zeilen (in einer 9x12-Pixelmatrix war das gerade noch auf
einen BAS-Monitor verwendbar).
Allerdings: Der einzige Z80, der da überhaupt verwendet wurde, steckte
im Graphikterminal.
Kann mich noch erinnern das mit dem LC80/U880/Z80 die nicht
dokumentierten Befehle getestet werden konnte.
Auch ein bekannter Fehler des Z80 wurde mit dem U880 behoben.
War natürlich alles damals sehr mühselig.
MfG
ein 80 jähriger aufmerksamer alter Knacker
Harald K. schrieb:> Textterminal mit 96 Zeichen pro> Zeile in 25 Zeilen (in einer 9x12-Pixelmatrix
Ne, da wird deine Erinnerung trügen.
Bei (Fernseh-) BAS und 15,625 kHz Zeilenfrequenz sind 768 x 576 Pixel
darstellbar.
25 Zeilen ja, aber nur 60 oder 64 Zeichen pro Zeile, und kleiner Matrix.
Erst später gab es PC Bildschirme mit 31 kHz aufwärts.
ist euch auch schon mal aufgefallen das seit dem Ersten "PC" immer eine
Programmiersprache mitgeliefert wurde,
Commodore Basic, apple basic, sinclair, pc1500, casio701, windows
basic.....
Seit win 10/11 nichts mehr, die Leute sollen heute nur noch Programme
kaufen und windows macht es einem sogar schwer alte Programmiersprachen
zu installieren!
Klaus F. schrieb:> Harald K. schrieb:>> Textterminal mit 96 Zeichen pro>> Zeile in 25 Zeilen (in einer 9x12-Pixelmatrix>> Ne, da wird deine Erinnerung trügen.> Bei (Fernseh-) BAS und 15,625 kHz Zeilenfrequenz sind 768 x 576 Pixel> darstellbar.> 25 Zeilen ja, aber nur 60 oder 64 Zeichen pro Zeile, und kleiner Matrix.
Gut dass Apple das nicht wusste. Bereits für den Apple IIplus von 1978
gab es eine "80 Zeichen-Karte", im wesentlichen ein Videoterminal mit
MC6845. Das Ding lieferte 80 Zeichen mal 24 Zeilen. Kurze Zeit später
kam die Videx Ultraterm mit 24x132, 32x128 und 48x80 Zeichen.
Natürlich brauchte man dafür einen vernünftigen BAS-Monitor mit 15,
besser 18 MHz Analogbandbreite. Z.B. einen Apple Monitor /// oder einen
AMDEK 200A. Mit einem NTSC-Fernseher mit 3 MHz Analogbandbreite war
nicht viel zu holen, und mit einem CVBS-HDMI-Wandler mit 13,5 MHz
Abtastrate ebensowenig.
Joachim B. schrieb:> ist euch auch schon mal aufgefallen das seit dem Ersten "PC" immer eine> Programmiersprache mitgeliefert wurde,
Die Programmiersprache war schon deshalb nötig, weil es zunächst ja kaum
Programme gab. Damit man also einen Computer nutzen konnte, mußte man
die Möglichkeit zur Programmierung haben.
Lange Zeit gaben die x86 beim Start die Fehlermeldung "no ROM Basic
found" aus; wenn kein Bootdevice gefunden wurde, dann wurde nach einem
ROM für den BASIC-Interpreter gesucht.
Soul E. schrieb:> Gut dass Apple das nicht wusste. Bereits für den Apple IIplus von 1978> gab es eine "80 Zeichen-Karte"
ich erinnere mich noch gut an meinem Colormonitor der mit RGB Karte kam
und den ich auf umschaltbar auf nur grün an die 80z Karte für CPMz80
anschließen konnte.
Taxan RGB Monitor und Colorgrafikkarte 1500,- DM zum Ende des Studiums
ab 1985. Der Monitor syncronisierte auch die 18kHz der 80z Karte.
Klaus F. schrieb:> Ne, da wird deine Erinnerung trügen.> Bei (Fernseh-) BAS und 15,625 kHz Zeilenfrequenz sind 768 x 576 Pixel> darstellbar.> 25 Zeilen ja, aber nur 60 oder 64 Zeichen pro Zeile, und kleiner Matrix.
Die Erinnerung trügt nicht. Das war eine 9x12-Matrix.
BAS-Monitor, nicht Fernseher. Und da ist die Horizontalauflösung nur vom
Pixeltakt abhängig (und natürlich der Bandbreite des Videoverstärkers im
Monitor).
Der Pixeltakt meines Selbstbauterminals betrug 16 MHz, damit ist ein
Pixel 62.5 nsec lang; ein Zeichen also 562.5 nsec, und 96 davon brauchen
54 µsec.
Das passt mit Austastlücke und Co. problemlos in die 64 µsec, die sich
aus der Zeilenfrequenz von 15.625 kHz ergeben.
Fernseher hatten nicht ansatzweise die nötige Videobandbreite, selbst
Schwarzweißfernseher nicht. Die kamen wegen des Tonträgers auf etwas
über 5 MHz.
Ich nutzte aber keinen Fernseher, sondern einen Monochrommonitor, und
der hatte keine Probleme mit den 16 MHz.
Allerdings sind auch mit einem Monitor bei 15.625 kHz Zeilenfrequenz
mehr als 300 Bildzeilen nur mit (meist unerträglichem, weil brutal
flackerndem) Interlace möglich.
Das konnte mein Selbstbauterminal auch, dann hatte das Ding 50
Textzeilen, aber das war nur mit einem Monitor mit sehr lange
nachleuchtendem Leuchtstoff erträglich.
So einen hatte ich, der wurde damals von Philips hergestellt und von
Vobis unter dem "Highscreen"-Label vertrieben.
Joachim B. schrieb:> ist euch auch schon mal aufgefallen das seit dem Ersten "PC" immer eine> Programmiersprache mitgeliefert wurde,> Commodore Basic, apple basic, sinclair, pc1500, casio701, windows> basic.....>> Seit win 10/11 nichts mehr, die Leute sollen heute nur noch Programme> kaufen und windows macht es einem sogar schwer alte Programmiersprachen> zu installieren!
Huch woher weißt Du das? ;-P
Ich hab gerad das Problem, den Borland jBuilder 7 auf
Win10 zu installieren, leider bricht das Installprogramm
kurz vor der Beendigung ab!
Ist das so, weil ich die 64 Bit Edition hab?
Muss ich da wirklich ne Win7 VM aufsetzen?
mfg
(prx) A. K. schrieb:> Lotta . schrieb:>> Muss ich da wirklich ne Win7 VM aufsetzen?>> Eine WinXP VM dürfte reichen.
Meinst Du, das es an den 64 Bit liegt?
So ne Ahnung hatte ich auch schon.
Gut, dann werd ich mal.
mfg
>> ist euch auch schon mal aufgefallen das seit dem Ersten "PC" immer eine>> Programmiersprache mitgeliefert wurde,>> Die Programmiersprache war schon deshalb nötig, weil es zunächst ja kaum> Programme gab. Damit man also einen Computer nutzen konnte, mußte man> die Möglichkeit zur Programmierung haben.
Bei der SUN hat man (als administrator) auch ab und zu den kernel oder
Teile davon kompilieren müßen bspw. bei Hinzufügung neuer
Hardware/Filesystem.
OK, SUN kam ja auch aus dem Universitären Bereich und wurde technisch
gesehen von einem deutschen Hacker voran getrieben. Der hatte "Mach es
selbst oder lass es sein" verinnerlicht. Und gehört nicht cc
spätetestens seit 1990 zum Unix (POSIX)-Mindestumfang ?!
Ach so, der TO spricht von PC's und nicht von workstations ;-) .
(prx) A. K. schrieb:> Ben B. schrieb:>> Disassembler ärgern kann man noch viel besser mit selbstmodifizierendem>> Code,>> Damit konnte man allerdings auch die Implementierer von Prozessoren ganz> böse ärgern.
Es sei denn Implementierer wie dieser Seymour Cray wollten das so. Ich
meine, wir hatten ja nix. Gar nix! Wir hatten nicht mal einen
Return-Stack in unserem alternden Super-Computer
https://en.wikipedia.org/wiki/CDC_7600
Ein Unterprogramm aufrufen? Ok, erste Aktion im Unterprogramm war die
Herkunftsadresse in eine Rücksprungadresse umwandeln. Damit modifizierte
sich das Unterprogramm selber in dem es einen Sprung zur
Rücksprungadresse ans eigene Ende schrieb.
Das war der offizielle Weg. Das funktionierte auch - meist. Aufgrund der
Architektur konnten sich keine zwei Aufrufe in die Quere kommen. Es sei
denn man versuchte sich an so neumodischem Kram wie Rekursion. Wobei der
Maschine selbstverständlich egal war ob man es mit einer direkten oder
indirekten Rekursion versuchte.
Hannes J. schrieb:> Es sei denn man versuchte sich an so neumodischem Kram wie Rekursion.
Nur hatte dieses Konzept noch keinen Einzug in die diese CDCs prägende
Programmiersprache gefunden: FORTRAN.
> Ich les grad, beim x86 gibt es die Exception 6 wenn die> Befehlseinheit auf einen Opcode stösst, dem kein Befehl> zugeordnet werden kann.
Der x86 schmeißt Dir einen Software-Interrupt, heißt direkt "illegal
opcode". Das hat man früher auch gebraucht, weil es z.B. viele CPUs gab,
die keine FPU enthielten (386SX/486SX, die mit FPU hießen DX). Wenn man
auf denen Code ausführen wollte, der z.B. für Fließkomma-Berechnungen
die FPU benutzt, dann crasht der auf solchen CPUs. Wenn man sich vorher
diesen Interrupt geschnappt hat, konnte man wenigstens noch eine
Fehlermeldung ausgeben und das Programm crashfrei beenden - oder wenn
man sich die Mühe gemacht hat, Code ohne FPU-Befehle benutzen.
Ben B. schrieb:>> Ich les grad, beim x86 gibt es die Exception 6 wenn die>> Befehlseinheit auf einen Opcode stösst, dem kein Befehl>> zugeordnet werden kann.> Der x86 schmeißt Dir einen Software-Interrupt, heißt direkt "illegal> opcode". Das hat man früher auch gebraucht, weil es z.B. viele CPUs gab,> die keine FPU enthielten (386SX/486SX, die mit FPU hießen DX). Wenn man> auf denen Code ausführen wollte, der z.B. für Fließkomma-Berechnungen> die FPU benutzt, dann crasht der auf solchen CPUs. Wenn man sich vorher> diesen Interrupt geschnappt hat, konnte man wenigstens noch eine> Fehlermeldung ausgeben und das Programm crashfrei beenden - oder wenn> man sich die Mühe gemacht hat, Code ohne FPU-Befehle benutzen.
Oder besser die FPU emulieren.
Bradward B. schrieb:> Exception 6Ben B. schrieb:> Software-Interrupt
Was eine Exception ist.
Zino schrieb:> Oder besser die FPU emulieren.
Was man beim Amiga (und vermutlich nicht nur dort) auch gemacht hat.
Ohne FPU gab es eine entsprechende Exception wodurch dann per IRQ die
Fließkommaberechnung in Software durchgeführt wurde.
Für die Software kein Unterschied, ob FPU vorhanden oder nicht.
Gruß
Jobst
Genau. Beim 80386 gab es beim Versuch, bei Abwesenheit einer FPU eine
FPU-Instruktion auszuführen, eine Device Not Available Exception. Also
eine andere Exception als bei wirklich undefinierten Instruktionen.
Ben B. schrieb:> Ist korrekt, mindestens der 80486 merkt es nicht, wenn der Programmcode> bereits in den Cache geladen ist.
Und eine frühe Version eines Prozessors aus der AMD K6 Familie erkannte
ab und zu auf self modifying code, obwohl es keiner war, und führte dann
u.U. einen Befehl zweimal aus.
> Ohne FPU gab es eine entsprechende Exception wodurch dann per> IRQ die Fließkommaberechnung in Software durchgeführt wurde.> Für die Software kein Unterschied, ob FPU vorhanden oder nicht.
Tricky... habe ich aber nie gebraucht, zumindest nicht für sinnvolle
Dinge.
Meine DOS-Testviren, mit deren hochprofessioneller Entwicklung und
Perfektionierung ich damals meine Freizeit verschwendet habe, waren
komplett für 32 Bit geschrieben und enthielten einen entsprechenden Test
falls sie doch mal auf einem 286er gestartet werden würden. Die gab es
damals vereinzelt noch. Dann wäre immerhin das infizierte Programm
selbst noch gelaufen, nur eben der Virus nicht.
Ben B. schrieb:>> Ich les grad, beim x86 gibt es die Exception 6 wenn die>> Befehlseinheit auf einen Opcode stösst, dem kein Befehl>> zugeordnet werden kann.> Der x86 schmeißt Dir einen Software-Interrupt, heißt direkt "illegal> opcode". Das hat man früher auch gebraucht, weil es z.B. viele CPUs gab,> die keine FPU enthielten (386SX/486SX, die mit FPU hießen DX). Wenn man> auf denen Code ausführen wollte, der z.B. für Fließkomma-Berechnungen> die FPU benutzt, dann crasht der auf solchen CPUs. Wenn man sich vorher> diesen Interrupt geschnappt hat, konnte man wenigstens noch eine> Fehlermeldung ausgeben und das Programm crashfrei beenden - oder wenn> man sich die Mühe gemacht hat, Code ohne FPU-Befehle benutzen.
Für all die Rechner, denen die FPU fehlte, gab es speicherresistente
Emulatoren. Die haben sich eben diesen Interrupt gegriffen und die
entsprechenden Befehle emuliert. War schnarchelangsam, aber notwendig,
wollte man z.B. mit AutoCAD arbeiten. Z.B.
https://www.qnx.com/developers/docs/qnx_4.25_docs/qnx4/utils/e/emu87.html
Joachim B. schrieb:> ist euch auch schon mal aufgefallen das seit dem Ersten "PC" immer eine> Programmiersprache mitgeliefert wurde,> Commodore Basic, apple basic, sinclair, pc1500, casio701, windows> basic.....>> Seit win 10/11 nichts mehr, die Leute sollen heute nur noch Programme> kaufen und windows macht es einem sogar schwer alte Programmiersprachen> zu installieren!
Dann schau Dir mal Deine Handtelefoniereinrichtung an. Bis Du da drauf
eigenen Code laufen lassen kannst, hast Du eher den C64 im Keller wieder
gefunden.
Flunder schrieb:> Bis Du da drauf eigenen Code laufen lassen kannst, hast Du eher den C64> im Keller wieder gefunden.
Ein Python dafür bekommst du ganz normal im Appstore, ist also nicht
mehr Aufwand zum Installieren als für jede andere App.
Aber mit Code-Verrenkungen auf einem Z80 hat das nichts mehr zu tun …
Hallo,
Jörg W. schrieb:> Aber mit Code-Verrenkungen auf einem Z80 hat das nichts mehr zu tun …
Stimmt, aber dafür hast du es jetzt mit "Fingerverrenkungen" zu tun um
den Quellcode einzugeben- :-))
rhf