RunCPM compile via DJGPP auf DOS/Win9x klappt nicht :(

  • Der RunCPM-Source nutzt

    _putch (putch) und

    _puts (puts)


    aber nach

    OSD: Putting text on the screen

    nutz DJGPP dabei nur BIOS Interrupts :(

    Zitat

    The putch() and cputs() functions may be good choices for text output in a 16-bit real-mode OS. Both the DJGPP and Turbo C versions use BIOS interrupts but not DOS interrupts.


    Bei diesen Befehlen gibt es bei puts auch kein Ende-Stringzeichen wie /0 oder $ da der String ja durch "" begrenzt uebergeben wird.


    Leider kann ich selbst kein Assembler um eine Inline-Routine zu basteln....kann ich irgendwo die genannte Borland-Variante sehen?


    Und: putch hat als Eingabe eher einen ASCII-Wert, weil ch (fuer chard) ein uint8 ist und kein char :(

  • clrscr ist als
    system ("CLS");

    definiert....


    Koennte man als Quick-Dirty Hack nicht das system (DOS-command) ECHO nehmen um Char/Zeichen oder String auszugeben.

    Ich wuesste nur nicht, wie ich die Variable des unit char oder string da rein bekomme


    Fuer den String geht es wohl unfefaehr so:

    char * command = "ls -l /non-existent";
    system( command );


    Also eine Variable fuer "ECHO " une eine fuer den String und diese dann vereint an system uebergeben


    Bei einem einzelnen Zeichen muesste man von ASCII auf String umwandeln.... und dies an "ECHO " anhaengen.


    Nur ob ECHO bei einzelnen Zeichen keinen CR oder LF macht?

  • In abstraction_posix.h wird einfach putchar genommen, gibt es natürlich auch bei DJGPP ...

    putch gibt es auch bei DJGPP
    Ich habe putchar getestet, aber der ist laut Doku eher verwandt mit den File-Command fputc (nach std-out)


    Sebst wenn ich putch gegen putchar tauschen koennte und der wuerde DOS Interrupts machen ist immer noch puts, der auch BIOS-Interrupts macht....


    Ich denke ohne passende Inline-ASM commands ist DJGPP dazu nicht in der Lage es als DOS-Interrupt auszugeben :(

  • Zitat

    The putch() and cputs() functions may be good choices for text output in a 16-bit real-mode OS. Both the DJGPP and Turbo C versions use BIOS interrupts but not DOS interrupts.

    Die abtract.h nutzt wie die abtraction_posix.h die conio.h - aber DJGPP verahelt sich wie Turbo C :(

    conio.h - Wikipedia


    Zitat

    The library functions declared by conio.h vary somewhat from compiler to compiler. As originally implemented in Lattice C, the various functions mapped directly to the first few DOS INT 21H functions. The library supplied with Borland's Turbo C did not use the DOS API but instead accessed video RAM directly for output and used BIOS interrupt calls.

  • In abstraction_posix.h findet sich kein conio.h, sonst wäre es ja nicht "POSIX" ... putch ist bei DJGPP in conio.h, aber putchar ist natürlich in stdio.h ... welche "platform" wird denn mit make build für den DJGPP benutzt?

    den make starte ich "natuerlich" mit

    make dos build


    Versuche ich unter DJGPP
    make build

    fragt er platform


    Mit

    make posix build

    klagt er natuerlich ueber viele fehlende "Librarys".


    Und ersetzen der conio durch stdio hilft leider auch nichts an der Ausgabe :(

  • Die FILE Ausgabefunktionen müssten doch aber nutzbar sein


    Deren Ausgabe kann man umleiten und die müssen deshalb durch DOS-Funktionen gehen.

    Sind dann halt minimal langsamer als speziell für das BIOS angepassten, dafür aber nicht portablen Versionen wie _putc etc.)


    Das sollte sich doch mit zwei Makros erledigen lassen?


    #define _putch(c) fputc(c,stdout)

    #define _puts(s) fputs(s,stdout)


    Falls der Preprozessor meckert, weil schon definiert, eventuell vorher noch

    #undefine _putch

    #undefine _puts


    Aufrufe von system(s) sollte man nur verwenden, wenn Programme gestartet werden sollen, für ein "clear screen" ist das ziemlich unwirtschaftlich.

    Es wird dabei ja jedes Mal ein kompletter Prozess gestartet und damit ist ohne Rechtsanwalt nicht zu spaßen.

    Wenn man schon ANSI Sequenzen verwendet ist es besser das auch mit einer Escape-Sequenz zu erledigen.

  • #define _putch(c) fputc(c,stdout)

    #define _puts(s) fputs(s,stdout)


    Das _putch habe ich in der abtract.h wie folgt definiert

    Code
    void _putch(uint8 ch) {
    // putchar(ch);
    fputc(ch,stdout);
    }

    putchar/fputc brachte leider bei der Ausgabe keinen Unterschied :(


    In der globals.h habe ich

    Code
    // extern void _puts(const char* str);
    #define _puts(s) fputs(s,stdout);

    eingetragen, aber das brachte leider nur folgenden Fehler beim compilieren:



    In der console.h gibt es noch

    aber die Befehle bauen auf der abtract.h auf wegen dem fuehrenden _ (Unterstrich)


    Irgendwo frage ich mich, ob ESC richtig umgegesetzt wird mit dem Pfeil nach LINKS,

    nicht da es da haengt und wir/ich falsch suche. Bei der Linux Version klappt die Umsetzung.

  • Auf die Schnelle sehe ich nur, dass in der #define Zeile kein ";" stehen darf

    Diese #defines sind ja nur Text-Ersetzungen durch den Preprozessor,


    #define _puts(s) fputs(s,stdout)

    soll dann

    ...

    _puts(aString);

    ...

    ersetzen durch

    ...

    fputs(aString,stdout);

    ...


    Und falls dann fputs nicht bekannt ist müsste noch die entsprechende header-Datei mit dem prototypen eingebunden werden.


    Aber im Prinzip (Hah!) sollte das alles auch ohne #defines funktionieren, wenn Du, wie offensichtlich schon gemacht, entsprechende Ersatzfunktionen in "C" schreibst.

  • MOMENT :) !!

    mit dem fput hatte ich nur unter der Win7 Eingabeaufforderung getestet :(


    Jetzt habe ich es nochmal auf meinem DOS-Rechner (DELL FX160 mit MSDOS 6.22) getestet,

    weil es stand ja im Internet die DOS-Interruts laufen auch nur unter echtem DOS (d.h. ich hatte zwar unter Win7 es mit ANSICON probiert - half da aber nichts)


    Der erste Versuch mit dem original ANSI.SYS in der CONFIG.SYS erwies sich als Anfang, denn Wordstar loeschte den Bildschirm, zeigte das Menue an....loeschte es ABER DANN WIDER :(

    Im leeren Bildschirm konnte man dann die Menue-Punkte zwar aufrufen, aber spaetestens im WS-Editor klappt das scrollen und Cursor-navigieren nicht.


    Erste Gegentests mit Alternativen ANSI wie ANSI.COM oder MYANSI.COM ergaben leider nur das selbe.


    ABER ich hatte nch einen 3ten Trumpf NNANSI.COM (v1.93) - den geladen (aus dem Gedaechtnis erstmal als NNANSI D - da sollte er mehr Moeglichkeiten haben und spaeter auch nur mit NNANSI fuer die "einfache" Variante)

    Und was soll ich sagen :) Wordstar wird sauber angezeigt, scrollt, Cursor klappt :)



  • Zum Testen der ANSI Sequenzen kannst Du auch http://www.z80.eu/downloads/TESTTERM101.ZIP bemühen, das habe ich ja mal extra für's Ausprobieren diverser Terminalemulationen geschrieben.


    P.S.: Statt VT100 via ANSI.SYS kannst Du auch VT52 testen, und zwar mit dem angehängten DOS-Gerätetreiber VT52.SYS (im ZIP).


    P.P.S.: Mit dem DOS Prompt Befehl kannst Du auch einfach die Funktion testen, bspw. mit "prompt $ep$p$g$eq" (damit wird nur das Prompt invers dargestellt, gesetzt der Fall VT52.SYS wird in der CONFIG.SYS geladen).

    Dateien

    "The biggest communication problem is we do not listen to understand. We listen to reply." - Stephen Covey


    Webseite und Blog ist immer noch - seit fast 20 Jahren - online.

    Einmal editiert, zuletzt von Peter z80.eu ()

  • Zum Testen der ANSI Sequenzen kannst Du auch http://www.z80.eu/downloads/TESTTERM101.ZIP bemühen, das habe ich ja mal extra für's Ausprobieren diverser Terminalemulationen geschrieben.


    P.S.: Statt VT100 via ANSI.SYS kannst Du auch VT52 testen, und zwar mit dem angehängten DOS-Gerätetreiber VT52.SYS (im ZIP).

    Leider verweigert sich mein DOS-Rechner dem TESTTERM - wenn ich es lade bleibt er am Eingabeprompt haengen :(


    Der VT52.SYS geht "soweit" - d.h. wenn man Wordstar auf VT52 umkonfiguriert (per WINSTALL) dann klappt die Bildschirmausgabe, allerdings fehlt dann das Attribut der Hervorhebung fuer die Menue-Punkte

    - ANSI ESC 1m fuer BRIGHT

    - ANSI ESC 0m fuer NORMAL

    aber immerhin besser in der Funktion als der ANSI.SYS und ANSI.COM/MYANSI.COM :)


    Der Vorteil beim NNANSI.COM ist dass er nachtraeglich (wenn gebraucht) geladen werden kann (NNANSI D) und nach Gebrauch auch wieder entladen werden kann (auch wenns nur ca. 4Kb sind).


    Im angehaengten Archiv sind 2 RunCPM-Versionen

    - RUNCPMFP.EXE fuer fput

    - RUNCPMPC.EXE fuer putchar


    Die beiden scheinen sich aber nichts zu geben ;)

    Zusaetzlich ist der CWSDPMI.EXE Extender dabei und NNANSI.COM in der v1.93


    Leider erkennt man die Helligkeitsunterschiede fuer die Menues auf den Fotos kaum, aber am Bildschirm erkennt man es ganz klar.




  • Aufrufe von system(s) sollte man nur verwenden, wenn Programme gestartet werden sollen, für ein "clear screen" ist das ziemlich unwirtschaftlich.

    Es wird dabei ja jedes Mal ein kompletter Prozess gestartet und damit ist ohne Rechtsanwalt nicht zu spaßen.

    Wenn man schon ANSI Sequenzen verwendet ist es besser das auch mit einer Escape-Sequenz zu erledigen.

    Habe ich mir nochmal durch den Kopf gehen lassen ;)

    1. es wird nur begrenzt genutzt (nicht aus Programmen heraus die eh ANSI-Sequenzen nutzen) sondern nur beim CLS an der Commandline und im RunCPM-Source der abgekapselt von den Programmen ist.

    2. bei diesen wenigen Zugriffen loescht es den Bildschirm unabhaengig von der genutzten Bildschirm-Emulation (also ANSI, VT52, ADM, Kaypro)


    Unter DOS gibt es kaum alternative Display-Driver (die ich kenne) aussder ANSI und nun VT52.


    Klar, wenn man sich auf ANSI festlegt, koennte man auch einen ANSI ClearScreen Code senden und haette es eleganter erledigt :)


    Aber wie geschrieben, tritt die Nutzung nicht innerhalb der CP/M Programme zu.

  • Der NNANSI scheint bei der Ausgabe etwas zu buffern, da beim durchlaufen des FRACTSL.BAS (egal ob interpretiert oder schon compiliert) die Ausgabe nur nach der kompletten Zeile kommt.


    Evtl. teste ich es nachher nochmal mit dem VT52.SYS und ganz ohne ANSI.

  • Der NNANSI scheint bei der Ausgabe etwas zu buffern, da beim durchlaufen des FRACTSL.BAS (egal ob interpretiert oder schon compiliert) die Ausgabe nur nach der kompletten Zeile kommt.

    Evtl. teste ich es nachher nochmal mit dem VT52.SYS und ganz ohne ANSI.

    Interessant ;) Nach der Umstellung auf fput/putchar die FRACTAL.BAS Ausgabe ist auch ohne ANSI-Driver auch "nur" nach jeder berechneten Zeile :(


    Also liegt es nicht an NANSI.COM/VT52.SYS

    In Worstar und dem Turbo Pascal Menue faellt es nicht auf und ein MBASIC-Listing wird zu schnell angezeigt, dass es auffaellt.


    DANKE an alle (in alphabetischer Reihenfolge) die mich unterstuetzt haben, die RunCPM-Bildschirmausgabe unter DOS zum laufen zu bekommen :)


    JenGun
    Danke fuer die Infos zu putchar und standard output
    Dies hat zusammen mit der Infos zu fput von Martin Hepperle mir das Verstaendnis naeher gebracht,

    dass stdio nicht ein File sein muss :)

    Martin Hepperle
    Danke fuer die Infos zu fputs :)
    und fuer ein CLS bei ANSI wurde ein print("\e[H\e[J"); langen.


    Peter z80.eu
    Danke fuer den Tipp zur Ausgabe per DOS-Interrupt
    Dadurch fand ich heraus, das DJGPP bei putc BIOS-Interrupts nutzt.

  • Nach der Umstellung auf fput/putchar die FRACTAL.BAS Ausgabe ist auch ohne ANSI-Driver auch "nur" nach jeder berechneten Zeile :(

    setbuf(stdout, NULL); sollte diese "Bufferung" für die Ausgabe ganz abschalten ... wird dann natürlich auch langsamer ... ;)

    Kann bei RunCPM in abstraction unter _console_init eingefügt werden, in abstraction_posix.h steht es so:

    Code
    setvbuf(stdout, (char*)NULL, _IONBF, 0); /* Disable stdout buffering */

    Einmal editiert, zuletzt von JenGun ()

  • setvbuf(stdout, NULL); sollte diese "Bufferung" für die Ausgabe ganz abschalten ... wird dann natürlich auch langsamer ... ;)

    JenGun
    WOW :) wie hast Du dies so schnell gefunden? Kannst den Source schon auswendig? ;)

    Ich kann sagen, dass es das war! PRIMA!!


    Ich habe mit dieser Einstellung nun

    - RUNCPMFB (fput ohne Buffer)

    - RUNCPMPB (putchar ohne Buffer)

    compiliert und nun wird beim FRACTAL.BAS auch wieder alles nach einem Zeichen ausgegeben :)


    Bei meinem 1.6GHz Atom (DELL FX160) faellt der Geschwindigkeitsverlust bei der Ausgabe nicht auf.

  • Nur etwas Erfahrung mit einem anderen Emulator, der ebenfalls in "C" geschrieben ist ... ;) putchar() und putc(.., stdout) (bzw. fputc(.., stdout) sind praktisch identisch, oder verwendest du nur fputs in RUNCPMFB?

    Eigentlich - da alle Ausgabe-Definitionen aufeinander aufbauen sollte RUNCPMFB nur mit fput laufen ;)

    (denk ich) - ist ja nicht wirklich "mein" Code. Ich pass den an und nenne es Fork/Port :)

  • Zum Testen der ANSI Sequenzen kannst Du auch http://www.z80.eu/downloads/TESTTERM101.ZIP bemühen, das habe ich ja mal extra für's Ausprobieren diverser Terminalemulationen geschrieben.


    P.S.: Statt VT100 via ANSI.SYS kannst Du auch VT52 testen, und zwar mit dem angehängten DOS-Gerätetreiber VT52.SYS (im ZIP).

    Leider verweigert sich mein DOS-Rechner dem TESTTERM - wenn ich es lade bleibt er am Eingabeprompt haengen :(

    [...]

    Lese ich erst jetzt ... TESTTERM ist doch ein CP/M- Programm, nix DOS :neinnein:


    Unter DOS würde ein Terminal-Testprogramm keinen Sinn ergeben, weil es offiziell eigentlich nur eine ANSI (=VT100) Emulation auf Kommandozeilenebene gibt. Unter CP/M hingegen waren verschiedene Terminal(emulationen) normal.

    "The biggest communication problem is we do not listen to understand. We listen to reply." - Stephen Covey


    Webseite und Blog ist immer noch - seit fast 20 Jahren - online.

    Einmal editiert, zuletzt von Peter z80.eu ()

  • Welches genau: fputc für "character" oder fputs für "string"? ;)

    Ist ja auch richtig so. :) Den Code schon irgendwo veröffentlicht?

    fputc für "character" weil in der console.h dann folgt:

    Code
    void _putcon(uint8 ch) // Puts a character
    {
    _putch(ch & mask8bit);
    }
    
    void _puts(const char* str) // Puts a \0 terminated string
    {
    while (*str)
    _putcon(*(str++));
    }

    denn in der abstract.h habe ich:

    Code
    void _putch(uint8 ch) {
    fputc(ch,stdout);
    // putchar(ch);
    }

    d.h es baut so auf: fputc -> _putch -> _putcon -> _puts

    Somit denke ich, dass alles fput (oder putchar ist - wenn man es umstellt)


    Veroeffentlicht ist der Source noch nicht, weil noch keiner fragte :)
    (OK - fuer Binary hat auch noch keiner gefragt...)


    Anbei der derzeitige Source ;)

  • Es gibt doch nochmal Geschwindigkeitsunterschiede wenn man RunCPM fuer DOS mit verschiedenen Optimierungs-Optionen compiliert.


    Bis jetzt waren RunCPMFB und RunCPMPB mit der Option -O0 compiliert (reduzierte Zeit fuer die Compilierung)

    und das ergibt 368KB


    Die Zeiten sehen aber schon ganz anders aus bei den Optionen

    -Os (Optimierung auf Binary-Size) - mit 423KB allerdings immer noch groesser als bei -O0

    -O3 (Optimierung auf Geschwindigkeit) - mit 560KB der groesste Brocken


    Die Versionen mit fput oder putchard geben sich bei den Optionen nicht mehr im Speed, deshalb bleibt beim compilieren einfach bei der fput-Variante

  • In der DOSBox-X ist RunCPMO3 langsamer als auf meinem 1.6GHz ATOM

    obwohl die DOSBox-X auf einem AMD Phenom II X4 mit 3GHz laeuft ;)


    In der Config-Datei braucht es ein ansi=false

    damit man den NNANSI nachladen kann, denn der DOXBox-X ANSI ist auch nicht besser als der vom MS-DOS :(