Erweiterter USB-Treiber + neues User Interface

ZX-Team Forum
Benutzeravatar
siggi
User
Beiträge: 2450
Registriert: 06.12.2005, 08:34
Wohnort: D, Hessen, tiefste Werreraa
Kontaktdaten:

Erweiterter USB-Treiber + neues User Interface

Beitrag von siggi » 06.11.2011, 10:23

Ich habe mal den USB-Treiber von Joachim (für PIO-Interface) noch etwas aufgebohrt:
Neben einer fehlenden Hilfezeile (Löschen eines Files fehlte in der Hilfe) versteht der Treiber (Verson 1.23) nun das Kommando
"D,xxxx"
Damit wird das XXXX.te File (und nur dieses) im aktuellen Verzeichnis auf den Bildschirm ausgegeben. Wie üblich ist XXXX vierstellig und Hex., also z. b: "D,0003"

Und wozu braucht man das?

Damit man programmgesteuert (man ist ja tippfaul 8) ) mit einem BASIC-Programm sich durch ein Verzeichnis des USB-Sticks wühlen kann, um dann diese Dateien per Programm zu bearbeiten.
Hintergrund ist, daß ich viele PT3-Dateien vom Stick lesen und unter MEFISDOS abspeichern wollte. Und das geht nun automatisch :D

Dazu wird der Einsprung 8195 in den Treiber benutzt (statt 8192). Wie bekannt, liefert der Treiber dann den Erfolg (oder auch nicht) eines Kommandos über die Systemvariable "SEED" (16434) an BASIC zurück (0: kein Fehler), wodurch das BASIC-Programm dann ggf. auf Fehler reagieren kann.

Diese Schnittstelle habe ich noch etwas erweitert: wird eine Datei vom Stick geladen, dann wird deren Länge nun in der Systemvariable COORDS (16438/9) abgelegt, damit man weiß, wie viele Bytes ggf. zu bearbeiten sind.

Und dann habe ich gleich ein Programm MOVEALL gebastelt, das diese neue Funktionalität nutzt:
es schaufelt alle Dateien aus dem aktuellen Verzeichnis des USB-Sticks in ein zuvor eingegebenes MEFISDOS verzeichnis (die Dateien werden vom USB-Stick gelöscht).
Dabei wird vorausgesetzt, daß der USB-Treiber auf der Adresse 8192 geladen ist (bei mir wird diese Seite mit POKE 0,4 eingeblendet) und daß MEFISDOS auch auf 8192 liegt (bei mir wird diese Seite mit POKE 0,2 eingeblendet).
Das Programm bricht bei Fehler ab, ebenso wenn ein Unterverzeichnis gefunden wird.
Die Dateinamen werden auf MEFIDOS-Konventionen geändert: keine Extension, Namenslänge max. 8 Zeichen. Vorhandene Dateien gleichen Namens werden ggf. überschrieben.
moveall.p
(3.01 KiB) 173-mal heruntergeladen
Und hier ist der Treiber (als ASDIS-Source):
USB123.P
(9.29 KiB) 172-mal heruntergeladen
Die wesentliche Funktion ist ab Label DIRM eingebaut:
dirm.jpg
dirm.jpg (27.81 KiB) 10616 mal betrachtet
Eine kleine Unschönheit ist allerdings dabei: wenn so ein BASIC-Programm nach MEFISDOS verschoben wird, dann landet es dort als Datenfile auf Adresse 32768 (es fehlt in MEFISDOS leider die Option "SAVE AS", um einen Datenblock explizit als BASIC-Programm abzuspeichern). Man muß es also manuell beim Laden in den Basic-Bereich holen und kann es dann von dort dann neu abspeichern.
Vorzugsweise eignet sich MOVEALL also zum Verschieben von Daten, z. B. PT3-Dateien.

Gruß und noch fröhliches Basteln

Siggi

PS: Habe festgestellt, daß der Treiber bei Dateinamen mit '_' im Namen nicht auf die Datei zugreifen kann. Da ist wohl noch ein Problemchen im Treiber ...
Zuletzt geändert von siggi am 13.11.2011, 13:48, insgesamt 1-mal geändert.

Benutzeravatar
Joachim
User
Beiträge: 1038
Registriert: 06.11.2004, 20:21

Re: Erweiterter USB-Treiber

Beitrag von Joachim » 06.11.2011, 12:12

Hallo Siggi,
großartig!
So ein MOVEALL für die PT3-Files habe ich mir auch schon gebastelt. Du hast natürlich die Mercedes-Version. Hab's mir schon runtergeladen.
Die Treibererweiterungen sind sehr sinnvoll. Ich habe vor einiger Zeit begonnen, dein TREECOPY so umzubauen, dass man damit von und nach USB-Stick/Mefisdos kopieren kann. Da kam ich auch auf das Problem, Directories durchzunudeln, bin dann hängen geblieben. Das dürfte mit dem jetzigen Treiber leichter sein. Muss ich gleich mal ausprobieren.
Grüße
Joachim
Viele Grüße!
Joachim


ZX80, ZX81, ZX-Spectrum, ZX96, ZX2000, ZXmore, ZX81NU, Blauer Engel, AX81

Benutzeravatar
siggi
User
Beiträge: 2450
Registriert: 06.12.2005, 08:34
Wohnort: D, Hessen, tiefste Werreraa
Kontaktdaten:

Re: Erweiterter USB-Treiber

Beitrag von siggi » 06.11.2011, 16:38

Hallo Joachim,
das mit Treecopy läßt sich damit ja auch machen, ist nur etwas schwieriger als be MOVEALL: da ich damit die kopierte Datei auf dem Stick lösche, wandern alle nachfolgenden Dateien "nach oben" und ich brauche immer nur konstant auf die 3. (im Unterverzeichnis) bzw. 1. Datei (im Root-Verzeichnis) zuzugreifen. Wenn die Dateien nicht gelöscht werden, muß man sie halt einzeln durchzählen. Da dies aber mit Hex-Zahlen passiert, muß der Zeddy da halt hex zählen lernen. Dez. wäre da einfacher ...
Aber man könnte den Treiber ja auch auf dez. Rechnerei (mit variabler Zahlenlänge, wie im MEFISDOS auch) umschreiben ...

Siggi

Benutzeravatar
Joachim
User
Beiträge: 1038
Registriert: 06.11.2004, 20:21

Re: Erweiterter USB-Treiber

Beitrag von Joachim » 06.11.2011, 17:12

Hallo Siggi,
ja, dez. wäre nicht schlecht. Hab' mir's schon öfters angeschaut. Ist nicht ganz trivial. Vorläufig habe ich es so gelöst. X = Eingangswert, X$(1) ist Ergebnis.

2000 REM usb-adr aufbereiten
2001 FAST
2005 FOR I=4 TO 1 STEP -1
2010 LET X$(1,I TO I)=CHR$ (CODE "0"+X-16*INT (X/16))
2020 LET X=INT (X/16)
2030 NEXT I

Grüße
Joachim
Viele Grüße!
Joachim


ZX80, ZX81, ZX-Spectrum, ZX96, ZX2000, ZXmore, ZX81NU, Blauer Engel, AX81

Benutzeravatar
siggi
User
Beiträge: 2450
Registriert: 06.12.2005, 08:34
Wohnort: D, Hessen, tiefste Werreraa
Kontaktdaten:

Re: Erweiterter USB-Treiber

Beitrag von siggi » 08.11.2011, 18:51

So, da ich anscheinend nicht der einzige bin, der lieber dezimal als hex zählt, habe ich dem Treiber nun mal Dezimalzahlen beigebracht. Ab der Version 1.2.5 sind alle numerischen Parameter nun Dezimalzahlen variabler Länge.
Hier ist die Routine, die ab (HL) eine Dezimalzahl in BC einliest und beim ersten nicht-numerischen Zeichen abbricht:
getbc.jpg
getbc.jpg (15.46 KiB) 10551 mal betrachtet
Und um die Bedienung mehr an MEFISDOS anzulehnen, habe ich dann noch folgende Änderungen vorgenommen:
- als Trennzeichen im Kommando ist nun auch ein Leerzeichen erlaubt (nicht nur ',' wie bisher)
- beim Speichern von Datenblöcken ist der 2. Parameter nun die Länge des Datenblocks (nicht mehr die Endadresse)
Die Hilfe habe ich entsprechend angepaßt und es wird nun auch die Version des Treibers angezeigt.

Und da ich den Treiber wieder auf der Werkbank hatte, habe ich gleich noch in den USB-READB/SENDB-Routinen rumgerührt und habe da diverse Taktzyklen einsparen können. Zum Laden eines 16K Speicherblocks werden nun ca. 5 Sekunden verbraten, bisher waren es 7

Hier ist die zeitoptimerte READB-Routine (der CALL RE1 und die Rechnerei dort wurden ersetzt durch ein paar Bitpopeleien):
readb.jpg
readb.jpg (23.99 KiB) 10551 mal betrachtet
Und schließlich habe ich einen weiteren Einsprung vorgesehen: bei 8198 kann man nur von M/C aus einspringen. Fehlerausgabe ist dann abgeschaltet und der Treiber kehrt mit RET zum aufrufenden Maschinenprogramm zurück. Der Kommandostring wird im Druckerpuffer (ab Adresse 16444) erwartet, beginnend mit dem Kommandobuchstaben und abgeschlossen mit ".
Achtung: dieser Einsprung ist von mir nur minimal getestet. Da können noch Probleme drin sein!

Einsprünge sind nun also (wenn der Treiber bei 8K liegt)
8192: für direkte Kommandos mit Fehlerausgabe auf Bildschirm
8195: für Basic-Programm mit Fehlerbehandlung durch Programm
8198: für M/C mit Fehlerbehandlung durch Programm

Um den Einsprung "mittenrein" (bei 8888 oder so?) habe ich mich nicht gekümmert, der dürfte nicht mehr klappen.

Gruß und fröhliches Basteln
Siggi
USB125.P
(9.84 KiB) 138-mal heruntergeladen

Benutzeravatar
Joachim
User
Beiträge: 1038
Registriert: 06.11.2004, 20:21

Re: Erweiterter USB-Treiber

Beitrag von Joachim » 08.11.2011, 20:48

Hallo Siggi,
ich weiß ja nicht, wie weit es von Fürth zu dir ist, aber auf jeden Fall reichen deine telepathischen Fähigkeiten aus und zu wissen, was ich alles vermißt habe und 'schon immer mal' einbauen wollte.
Der MC-Aufruf war mir ebenso wichtig, wie die Dezimaleingabe und die Längenangabe. Vielen Dank, dass du das so schnell erledigt hast. Werde mir das Listing zu Gemüte führen und sicher wieder was dabei von dir lernen.
Auch werde ich den MC-Aufruf testen.

vielen Dank nochmals und viele Grüße
Joachim
Viele Grüße!
Joachim


ZX80, ZX81, ZX-Spectrum, ZX96, ZX2000, ZXmore, ZX81NU, Blauer Engel, AX81

Benutzeravatar
siggi
User
Beiträge: 2450
Registriert: 06.12.2005, 08:34
Wohnort: D, Hessen, tiefste Werreraa
Kontaktdaten:

Re: Erweiterter USB-Treiber

Beitrag von siggi » 09.11.2011, 19:10

Hallo Joachim,
falls die Telepathieverbindung nicht gestört ist, dann vermute ich mal, Du hättest auch Verwendung für einen USB-Treiber, der auch ein BREAK eingebaut hat (falls mal der Stick während des Zugriffs gezogen wird).
Hier ist der Treiber Version 126, der das macht: durch Drücken der A-Taste kann der Treiberaufruf abgebrochen werden und kehrt mit Fehler 8 zurück. Anders als Oliver habe ich dafür die A-Taste gewählt (nicht SPACE), damit man nicht auch versehentlich gleich das BASIC-Programm mit abbricht.
USB126.P
(10.43 KiB) 156-mal heruntergeladen
Gruß
Siggi

PS: Habe aus der SENDB-Routine auch noch ein paar überflüssige T-States entnommen :wink:

Und hier noch das Listing des Treibers:
usb126.zip
(116.75 KiB) 157-mal heruntergeladen

Benutzeravatar
Joachim
User
Beiträge: 1038
Registriert: 06.11.2004, 20:21

Re: Erweiterter USB-Treiber

Beitrag von Joachim » 09.11.2011, 20:32

Hallo Siggi,
das ist echt genial. Besonders bei Programmierversuchen in BASIC sehr hilfreich.
Hier noch das Listing in Textform.
usb126.txt
(39.4 KiB) 153-mal heruntergeladen
viele Grüße
Joachim
Viele Grüße!
Joachim


ZX80, ZX81, ZX-Spectrum, ZX96, ZX2000, ZXmore, ZX81NU, Blauer Engel, AX81

Benutzeravatar
siggi
User
Beiträge: 2450
Registriert: 06.12.2005, 08:34
Wohnort: D, Hessen, tiefste Werreraa
Kontaktdaten:

Re: Erweiterter USB-Treiber

Beitrag von siggi » 10.11.2011, 14:07

Hallo Joachim,
habe noch 'nen Bug in der 126 gefunden: Update kommt demnächst ..

Siggi

Benutzeravatar
siggi
User
Beiträge: 2450
Registriert: 06.12.2005, 08:34
Wohnort: D, Hessen, tiefste Werreraa
Kontaktdaten:

Re: Erweiterter USB-Treiber

Beitrag von siggi » 10.11.2011, 19:14

So, nächster Versuch.

Der Fehler im Unterprogramm INIT ist behoben: dort wurde im Fehlerfalle einfach mit JP ERROR rausgesprungen, wodurch auf dem Stack die alte Return-Adresse verblieb und dann Ärger machte. Das ist nun behoben.

Ich habe dann an anderer Stelle (ERASE, RMDIR) gleich noch fehlendes Errorhandling ergänzt. Und weil die Firmware auch ein RENAME-Kommando kann, habe ich das auch gleich noch eingebaut.

Und weil ich primär mit MEFIDOS schaffe, wollte ich mir nicht unbedingt beim USB-Stick eine ganz andere Kommandosyntax antun. Und so habe ich noch kurzerhand die Kommandos (soweit möglich) an die MEFISDOS-Kommandos angepaßt :D

Das sieht nun so aus:
USB130-H.jpg
USB130-H.jpg (70.59 KiB) 10488 mal betrachtet
Und weil die Syntax nun anders ist, heißt er jetzt V1.3.0:
USB130.P
(10.64 KiB) 141-mal heruntergeladen
So, ich hoffe, daß da nun keine Fehler mehr drin sind ... :lol:

Gruß
Siggi

Benutzeravatar
siggi
User
Beiträge: 2450
Registriert: 06.12.2005, 08:34
Wohnort: D, Hessen, tiefste Werreraa
Kontaktdaten:

Re: Erweiterter USB-Treiber

Beitrag von siggi » 11.11.2011, 21:46

Zu früh gefreut: mit dem Einbau der BREAK-Funktion ist ein Problem reigekommen, das ich erst jetzt bemerkt habe: das "I"-Kommando (Info vom Stick) hat nur noch Müll geliefert. Anscheinend ist das Timing da so kritisch, daß der Einbau der Prüfung auf BREAK den Informationsfluß vom Stick durcheinanderbringt. Nun habe ich dort (und nur dort) die BREAK-Prüfung wieder ausgebaut, und schon geht "I" wieder. :D

Jetzt gibt's also die 1.3.1 Version.
Eigentlich hatte ich die mit einer kleinen Verbesserung schon in Arbeit: bei dieser Version wird nun beim Kommando "D VERZEICHNIS" ins Unterverzeichnis gewechselt UND ZUSÄTZLICH WIRD DAS NEUE VERZEICHNIS GLEICH ANGEZEIGT (allerdings nur im interaktiven Modus bei Einsprung auf 8192, nicht bei 8195 oder 8198).
So ist das Verhalten am ähnlichsten zu MEFISDOS, wo ein "D D:VERZEICHNIS/" ja auch das Verzeichnis anzeigt.

Hier also der neueste Source:
USB131.P
(10.65 KiB) 158-mal heruntergeladen
Und hier gleich als assemblierte Version für Laufadresse 8192: Programm starten (ggf. das POKE 0 zum Einblenden von RAM bei 8K anpassen) und mit "R"(Restore) den M/C auf Adresse 8192 kopieren:
U131-8k.P
(13.03 KiB) 149-mal heruntergeladen
Gruß
Siggi

Benutzeravatar
siggi
User
Beiträge: 2450
Registriert: 06.12.2005, 08:34
Wohnort: D, Hessen, tiefste Werreraa
Kontaktdaten:

Re: Erweiterter USB-Treiber: mit neuem User Interface

Beitrag von siggi » 12.11.2011, 11:31

Heureka, die M/C-Schnittstelle des Treibers funktioniert auch (obwohl noch ein kleiner Fehler drin ist bei Rückgabe des Fehlercodes beim Laden von Dateien).

Testweise habe ich ein Userinterface in C gebastelt, mit dem man sich (bei nach 8192 geladenem Treiber) mit dem Cursortasten durch die Verzeichnisstruktur des Sticks hangeln kann (wie man es von MEFISDOS gewohnt ist):
Mit 6 und 7 kann man durch die Einträge navigieren, mit 8, L oder RETURN lädt man das aktuelle File oder wechselt ins Unterverzeichnis. Ist man mit dem Balken auf einem leeren Eintrag, wird einfach ein DIR ausgeführt. Raus kommt man mit X

Hier ist das ausführbare Programm, das nach 32768 geladen und dort gestartet wird (USB-Treiber ab V130 muß bei 8K geladen sein).
ui.zip
(1.96 KiB) 172-mal heruntergeladen
Und hier ist der Source

Code: Alles auswählen

//zcc +zx81 -startup=2 -create-app -vn -o ui.bin ui.c
#include <stdio.h>
#include <string.h>
#include <input.h>
#include <conio.h>
#include <zx81.h>

unsigned int DFILE @ 16396;
unsigned char ERRNO @ 16434;
unsigned char PRBUF[33] @ 16444;

unsigned char exec(char * cmd)
{
    int i;
    for (i=0; i < strlen(cmd); i++)
        PRBUF[i] = ascii_zx(cmd[i]);
    PRBUF[i++] = 11; /* terminating " */
    for (; i < 32; i++)
        PRBUF[i] = 0;
#asm
    XREF restore81
    call restore81
    call $A2A
    call 8198
#endasm
    zx_slow();
    return ERRNO;
}

unsigned char * invert_line(int no)
{
    unsigned char * pos;
    int i;
    pos = (unsigned char *) (DFILE + 1 + no * 33);
    for (i=0; i < 32; i++)
    {
        *pos ^= 0x80;
        pos++;
    }
    return DFILE + 1 + no * 33;
}

int getline(unsigned char * pos, char * buffer)
{
    char ch;
    int i = 0;

    do
    {
        ch = zx_ascii((*pos++) & 0x7F);
        *buffer++ = ch;
    }
    while (ch != ' ');
    *(--buffer) = '\0';
    if (zx_ascii((*pos) & 0x7F) == 'D')
        return 1;
    else
        return 0;
}

void main()
{
   int loop = 1;
   int line = 0;
   char key;
   unsigned char* screen_pos;
   char cmd[32];
   char name[32];
   char is_dir;

   exec("D");

   screen_pos = invert_line(line);
   do
   {   in_Wait(20);
       key = getk();
       switch (key)
       {
           case '7':
                 if (line > 0)
                 {
                    invert_line(line);
                    line--;
                    screen_pos = invert_line(line);
                 }
                 break;

           case '6':
                 if (line < 23)
                 {
                    invert_line(line);
                    line++;
                    screen_pos = invert_line(line);
                 }
                 break;
           case 13:
           case 'L':
           case '8':
               is_dir = getline(screen_pos, name);
               if (!strlen(name))
               {
                  is_dir = 1;
                  strcpy(cmd, "\0");
               }
               else
               {
                   if (is_dir)
                   {
                      strcpy(cmd, "D ");
                   }
                   else
                      strcpy(cmd, "L ");
                   strcat(cmd, name);
               }
               if (strlen(cmd))
               {
                    if (exec(cmd))
                        printf("ERROR\n");
                    else
                        printf("OK\n");
               }

               if (is_dir)
               {
                  putchar(12);
                  exec("D");
                  line = 0;
                  screen_pos = invert_line(line);
                  in_WaitForNoKey();
               }
               break;

           case 'X':
                loop = 0;
               break;
       }
    }
    while(loop);
}

Fröhliches Wochenende
Siggi

Benutzeravatar
Joachim
User
Beiträge: 1038
Registriert: 06.11.2004, 20:21

Re: Erweiterter USB-Treiber

Beitrag von Joachim » 12.11.2011, 11:39

Hallo Siggi,
mir fehlen die Worte. Vorallem, weil du das so schnell hinkriegst. Ich komme gar nicht nach, die Versionen auszuprobieren. Bin auch froh, dass du das alles in ASDIS machst. So ist es wirklich am einfachsten und schnellsten, eine Version für den jeweiligen ZX81 anzupassen (PIO-Adressen, Laufadresse).
Die Idee, die Befehlskürzel anzupassen, finde ich sehr gut, weil auch ich zu tief in Mefisdos drin stecke und immer überlegen muss, wie das Kommando abgekürzt wird.
Fehlt nur noch, dass man im angezeigten Directory mit dem Cursor das gewünschte File anwählen und laden kann ;)

Vielen Dank und viele Grüße
Joachim


12.11.2011/11:40 Uhr
Das gibts doch nicht: während ich die obigen Zeilen geschrieben habe, hast du schon gepostet, was ich (scherzhaft) vorgeschlagen habe. Also doch Telepathie!

Nochmals Grüße
Joachim
Viele Grüße!
Joachim


ZX80, ZX81, ZX-Spectrum, ZX96, ZX2000, ZXmore, ZX81NU, Blauer Engel, AX81

Benutzeravatar
Joachim
User
Beiträge: 1038
Registriert: 06.11.2004, 20:21

Re: Erweiterter USB-Treiber

Beitrag von Joachim » 12.11.2011, 14:32

Hallo Siggi,
das UI funktioniert auch bei mir mit V1.3.1.
Ist das richtig: Das UI bezieht sich nur auf eine Directory-Seite. D.h., wenn ich soviele Files auf einer Card habe, dass ich durch das Dir. blättern muss, kann ich erst und nur bei der letzten Seite ein File zum Laden auswählen - oder mache ich da einen Bedienungsfehler?

Grüße
Joachim

Hab's gefunden: Ist man auf der Seite, auf der man den Cursor benützen will, muss man 'A' eingeben.
Joachim
Viele Grüße!
Joachim


ZX80, ZX81, ZX-Spectrum, ZX96, ZX2000, ZXmore, ZX81NU, Blauer Engel, AX81

Benutzeravatar
siggi
User
Beiträge: 2450
Registriert: 06.12.2005, 08:34
Wohnort: D, Hessen, tiefste Werreraa
Kontaktdaten:

Re: Erweiterter USB-Treiber: Neues User Interface

Beitrag von siggi » 12.11.2011, 16:37

Ja genau. Solange das Directory Listing durchläuft, hat ja der Treiber die Oberhoheit über Tastatur und Bildschirm. Also kann man da mit A den Treiber abbrechen und der Bildinhalt bleibt erhalten. Darauf kann auch anschließend das C-Programm wieder darauf zugreifen und die aktuellen Namen auslesen.

Gruß
Siggi
Zuletzt geändert von siggi am 13.11.2011, 13:32, insgesamt 1-mal geändert.

Benutzeravatar
siggi
User
Beiträge: 2450
Registriert: 06.12.2005, 08:34
Wohnort: D, Hessen, tiefste Werreraa
Kontaktdaten:

Re: Erweiterter USB-Treiber: Neues User Interface

Beitrag von siggi » 13.11.2011, 13:11

So, es gibt nun eine neue UI-Version, die nun alle Features des Treiber unterstützt:
ui.zip
(2.46 KiB) 142-mal heruntergeladen
mit V,R,K,8,Return kann man Verzeichnisse anlegen, umbenennen, löschen, reinwechseln
mit L,R,E,Return kann man Dateien laden, umbenennen, löschen
mit C kann man manuell ein Treiberkommando eingeben (dann wird auf Taste RETURN gewartet)
mit X kommt man raus

Fehlende Parameter (Ladeadresse, neuer Name) werden ggf. erfragt.
Programm läuft wieder auf 32K,Treiber wird bei 8K erwartet.

Die Größe ist ca. 4K, man könnte es also zusammen mit dem Treiber (ca. 2800 Byte) in einen 8K-Block packen (z. B. beider oberhalb 32K, erst Treiber, danach UI) und zusammen mit MEFIDOS abspeichern und laden.

Irgendwelche Wünsche, wo das Programm liegen soll?

Gruß
Siggi

Code: Alles auswählen

//zcc +zx81 -startup=2 -create-app -vn -o ui.bin ui.c
#include <stdio.h>
#include <string.h>
#include <input.h>
#include <conio.h>
#include <zx81.h>

unsigned int DFILE @ 16396;
unsigned char ERRNO @ 16434;
unsigned char PRBUF[33] @ 16444;

unsigned char exec(char * cmd)
{
    int i;
    for (i=0; i < strlen(cmd); i++)
        PRBUF[i] = ascii_zx(cmd[i]);
    PRBUF[i++] = 11; /* terminating " */
    for (; i < 32; i++)
        PRBUF[i] = 0;
#if 1
#asm
    XREF restore81
    call restore81
    call $A2A
    call 8198
#endasm
#else
    printf("exec=%s\nlen=%d\n",cmd, strlen(cmd));
#endif
    zx_slow();
    return ERRNO;
}

void cls(void)
{
    putchar(12);
}

unsigned char * invert_line(int no)
{
    unsigned char * pos;
    int i;
    pos = (unsigned char *) (DFILE + 1 + no * 33);
    for (i=0; i < 32; i++)
    {
        *pos ^= 0x80;
        pos++;
    }
    return DFILE + 1 + no * 33;
}

int getline(unsigned char * pos, char * buffer)
{
    char ch;
    int i = 0;

    do
    {
        ch = zx_ascii((*pos++) & 0x7F);
        *buffer++ = ch;
    }
    while (ch != ' ');
    *(--buffer) = '\0';
    if (zx_ascii((*pos) & 0x7F) == 'D')
        return 1;
    else
        return 0;
}

void main()
{
   int loop = 1;
   int line = 0;
   char key;
   unsigned char* screen_pos;
   char cmd[33];
   char name[33];
   char answer[33];
   char is_dir, is_prog, show_dir;
   int name_len;


   exec("D");

   screen_pos = invert_line(line);
   do
   {
       in_Wait(20);
       key = getk();

       switch (key)
       {
           case '7':
                 if (line > 0)
                 {
                    invert_line(line);
                    line--;
                    screen_pos = invert_line(line);
                 }
                 break;

           case '6':
                 if (line < 23)
                 {
                    invert_line(line);
                    line++;
                    screen_pos = invert_line(line);
                 }
                 break;
           case 13:
           case 'L':
           case '8':
           case 'K':
           case 'V':
           case 'R':
           case 'E':
           case 'C':
               show_dir = 1;
               is_dir = getline(screen_pos, name);
               name_len = strlen(name);
               cmd[0] =0;
               answer[0] =0;
               is_prog = 0;

               if (key == 'C')
               {
                   cls();
                   printf("Kommando=");
                   fgets_cons(answer, 33);
                   if (answer[0] > ' ')
                   {
                       answer[strlen(answer) - 1] = 0; /* overwrite CR */
                       strcpy(cmd, answer);
                       show_dir = 0;
                   }
               }
               else
               if (key == 'V')
               {
                   cls();
                   printf("Neues Verz.=");
                   fgets_cons(answer, 33);
                   if (answer[0] > ' ')
                   {
                       answer[strlen(answer) - 1] = 0; /* overwrite CR */
                       strcpy(cmd, "V ");
                       strcat(cmd, answer);
                   }
               }
               else
               if (name_len)
               {
                    cls();
                    /* name is given: check for program */
                    if (name_len > 2)
                       is_prog = !(strcmp(&name[name_len - 2], ".P"));

                    if (key == 'R')
                    {
                        printf("Neuer Name=");
                        fgets_cons(answer, 33);
                        if (answer[0] > ' ')
                        {
                            answer[strlen(answer) - 1] = 0; /* overwrite CR */
                            strcpy(cmd, "R ");
                            strcat(cmd, name);
                            strcat(cmd, " ");
                            strcat(cmd, answer);
                        }
                        else
                            cmd[0] = 0;
                    }

                    /* directory command */
                    if (is_dir)
                    {
                        if (key == 'K')
                        {
                            printf("Verz. loeschen(J/N)?");
                            fgets_cons(answer, 33);
                            if (answer[0] == 'J')
                            {
                                strcpy(cmd, "K ");
                                strcat(cmd, name);
                            }
                        }
                        else
                        if ((key == '8') || (key == 13))
                        {
                            strcpy(cmd, "D ");
                            strcat(cmd, name);
                        }
                    }
                    else
                    {
                        if ((key == 'L') || (key == 13))
                        {
                            strcpy(cmd, "L ");
                            strcat(cmd, name);
                            if (!is_prog)
                            {
                                printf("Adresse=");
                                fgets_cons(answer, 33);
                                if (answer[0] > ' ')
                                {
                                    answer[strlen(answer) - 1] = 0; /* overwrite CR */
                                    strcat(cmd, ",");
                                    strcat(cmd, answer);
                                }
                                else
                                    cmd[0] = 0;
                            }
                        }
                        else
                        if (key == 'E')
                        {
                            printf("Datei loeschen(J/N)?");
                            fgets_cons(answer, 33);
                            if (answer[0] == 'J')
                            {
                                strcpy(cmd, "E ");
                                strcat(cmd, name);
                            }
                        }
                    }
               }


               if (strlen(cmd))
                   if (exec(cmd))
                   {
                       printf("ERROR\n");
                       in_Wait(1000);
                   }

               in_WaitForNoKey();

               if (!show_dir)
               {
                   printf("\n<return>\n");
                   fgets_cons(answer, 33);
                   in_WaitForNoKey();
               }
               cls();
               exec("D");
               line = 0;
               screen_pos = invert_line(line);
               break;

           case 'X':
               loop = 0;
               in_WaitForNoKey();
               break;
       }
    }
    while(loop);
}

Benutzeravatar
Joachim
User
Beiträge: 1038
Registriert: 06.11.2004, 20:21

Re: Erweiterter USB-Treiber + neues User Interface

Beitrag von Joachim » 13.11.2011, 14:00

Hallo Siggi! Wahnsinn!
Also wenn man sich's aussuchen darf, dann für Startadresse 12288, 36864 und 40960. Dann könnte man sich, wie du verschlägst, entsprechende Blöcke mit USB131 sowie der UI in Mefisdos speichern.
vielen Dank und viele Grüße
Joachim
Viele Grüße!
Joachim


ZX80, ZX81, ZX-Spectrum, ZX96, ZX2000, ZXmore, ZX81NU, Blauer Engel, AX81

Benutzeravatar
Joachim
User
Beiträge: 1038
Registriert: 06.11.2004, 20:21

Re: Erweiterter USB-Treiber + neues User Interface

Beitrag von Joachim » 13.11.2011, 19:28

Hallo Siggi,
habe die neue Version von UI eben ausprobiert: aller erste Sahne! Dass es so komfortabel ist, hätte ich nicht erwartet!

Joachim
Viele Grüße!
Joachim


ZX80, ZX81, ZX-Spectrum, ZX96, ZX2000, ZXmore, ZX81NU, Blauer Engel, AX81

Benutzeravatar
siggi
User
Beiträge: 2450
Registriert: 06.12.2005, 08:34
Wohnort: D, Hessen, tiefste Werreraa
Kontaktdaten:

Re: Erweiterter USB-Treiber + neues User Interface

Beitrag von siggi » 13.11.2011, 19:42

Hallo Joachim,
noch 'ne neuere Version:
habe nun versucht, den Bildschirm möglichst lange zu erhalten, damit er nicht immer neu per DIR aufgebaut werden muß. Ist leider sehr umständlich, weil Bildschirmposition von C-Konsole und Treiber (BASIC-Systemvariablen) auseinanderlaufen UND in dem kleinen (platzsparenden) Konsole-Treiber des Z88DK keine Cursorpositionierung drin ist. Deshalb habe ich mit vielen Backspaces schaffen müssen, was etwas zäh geht, aber es geht und man spart immer noch Zeit :mrgreen:

Dieses UI kann nun auch Dateien speichern (hatte ich vorher vergessen).
S auf leeren Bildschirmzeile fragt neuen Namen für P-File ab
S auf einem P-file fragt ab, ob P-File überschrieben werden soll.
Datenblöcke können nur mit explizitem Kommando (per C) abgespeichert werden.

Erstmal hier noch die Version für 32K Laufadresse. Wenn die soweit bugfrei ist, mache ich die anderen.
ui.zip
(2.63 KiB) 150-mal heruntergeladen
Demnächst gibt's dann noch 'nen neuer Treiber, weil da ja noch ein kleiner Fehler drin ist.

Gruß
Siggi

Code: Alles auswählen

//zcc +zx81 -startup=2 -create-app -vn -o ui.bin ui.c
#include <stdio.h>
#include <string.h>
#include <input.h>
#include <conio.h>
#include <zx81.h>

unsigned int DFILE @ 16396;
unsigned char ERRNO @ 16434;
unsigned char PRBUF[33] @ 16444;

void cls(void)
{
    putchar(12);
}

void home(void)
{
    int i;
    for (i=0; i < 300; i++)
       putchar(8);

}

unsigned char exec(char * cmd, char del_screen)
{
    int i;
    for (i=0; i < strlen(cmd); i++)
        PRBUF[i] = ascii_zx(cmd[i]);
    PRBUF[i++] = 11; /* terminating " */
    for (; i < 32; i++)
        PRBUF[i] = 0;
    if (del_screen)
    {
        cls();
#if 1
#asm
    XREF restore81
    call restore81
    call $A2A
    call 8198
#endasm
    }
    else
    {
#asm
    call restore81
    call 8198
#endasm
    }
#else
    }
    printf("exec=%s\nlen=%d\n",cmd, strlen(cmd));
#endif
    zx_slow();
    return ERRNO;
}


unsigned char * invert_line(int no)
{
    unsigned char * pos;
    int i;
    pos = (unsigned char *) (DFILE + 1 + no * 33);
    for (i=0; i < 32; i++)
    {
        *pos |= 0x80;
        pos++;
    }
    return DFILE + 1 + no * 33;
}

unsigned char * reset_line(int no)
{
    unsigned char * pos;
    int i;
    pos = (unsigned char *) (DFILE + 1 + no * 33);
    for (i=0; i < 32; i++)
    {
        *pos &= 0x7F;
        pos++;
    }
    return DFILE + 1 + no * 33;
}

int getline(unsigned char * pos, char * buffer)
{
    char ch;
    int i = 0;

    do
    {
        ch = zx_ascii((*pos++) & 0x7F);
        *buffer++ = ch;
    }
    while (ch != ' ');
    *(--buffer) = '\0';
    if (zx_ascii((*pos) & 0x7F) == 'D')
        return 1;
    else
        return 0;
}

void main()
{
   int loop = 1;
   int line = 0;
   char key;
   unsigned char* screen_pos;
   char cmd[33];
   char name[33];
   char answer[33];
   char is_dir, is_prog, wait_for_return, show_dir;
   int name_len;


   exec("D", 1);

   screen_pos = invert_line(line);
   do
   {
       in_Wait(20);
       key = getk();

       switch (key)
       {
           case '7':
                 if (line > 0)
                 {
                    reset_line(line);
                    line--;
                    screen_pos = invert_line(line);
                 }
                 break;

           case '6':
                 if (line < 19)
                 {
                    reset_line(line);
                    line++;
                    screen_pos = invert_line(line);
                 }
                 break;
           case 13:
           case 'L':
           case '8':
           case 'K':
           case 'V':
           case 'R':
           case 'E':
           case 'C':
           case 'S':
               wait_for_return = 0;
               is_dir = getline(screen_pos, name);
               name_len = strlen(name);
               cmd[0] =0;
               answer[0] =0;
               is_prog = 0;
               show_dir = 0;

               if (key == 'C')
               {
                   home();
                   printf("Kommando=");
                   fgets_cons(answer, 33);
                   if (answer[0] > ' ')
                   {
                       answer[strlen(answer) - 1] = 0; /* overwrite CR */
                       strcpy(cmd, answer);
                       wait_for_return = 1;
                       show_dir = 1;
                   }
                   home();
               }
               else
               if (key == 'V')
               {
                   home();
                   printf("Neues Verz.=");
                   fgets_cons(answer, 33);
                   if (answer[0] > ' ')
                   {
                       answer[strlen(answer) - 1] = 0; /* overwrite CR */
                       strcpy(cmd, "V ");
                       strcat(cmd, answer);
                   }
                   home();
               }
               else
               if (name_len)
               {
                    home();
                    /* name is given: check for program */
                    if (name_len > 2)
                       is_prog = !(strcmp(&name[name_len - 2], ".P"));

                    if (key == 'R')
                    {
                        printf("Neuer Name=");
                        fgets_cons(answer, 33);
                        if (answer[0] > ' ')
                        {
                            answer[strlen(answer) - 1] = 0; /* overwrite CR */
                            strcpy(cmd, "R ");
                            strcat(cmd, name);
                            strcat(cmd, " ");
                            strcat(cmd, answer);
                        }
                        else
                            cmd[0] = 0;
                    }

                    /* directory command */
                    if (is_dir)
                    {
                        if (key == 'K')
                        {
                            printf("Verz. loeschen(J/N)?");
                            fgets_cons(answer, 33);
                            if (answer[0] == 'J')
                            {
                                strcpy(cmd, "K ");
                                strcat(cmd, name);
                            }
                        }
                        else
                        if ((key == '8') || (key == 13))
                        {
                            strcpy(cmd, "D ");
                            strcat(cmd, name);
                            show_dir = 1;
                        }
                    }
                    else
                    {
                        if ((key == 'L') || (key == 13))
                        {
                            strcpy(cmd, "L ");
                            strcat(cmd, name);
                            if (!is_prog)
                            {
                                printf("Adresse=");
                                fgets_cons(answer, 33);
                                if (answer[0] > ' ')
                                {
                                    answer[strlen(answer) - 1] = 0; /* overwrite CR */
                                    strcat(cmd, ",");
                                    strcat(cmd, answer);
                                }
                                else
                                    cmd[0] = 0;
                            }
                        }
                        else
                        if (key == 'E')
                        {
                            printf("Datei loeschen(J/N)?");
                            fgets_cons(answer, 33);
                            if (answer[0] == 'J')
                            {
                                strcpy(cmd, "E ");
                                strcat(cmd, name);
                            }
                        }
                        else
                        if (key == 'S')
                        {
                            if (is_prog)
                            {
                                printf("Programm ueberschreiben(J/N)?");
                                fgets_cons(answer, 33);
                                if (answer[0] == 'J')
                                {
                                    strcpy(cmd, "S ");
                                    strcat(cmd, name);
                                }
                            }
                        }
                    }
                    home();
               }
               else
               if (key == 'S')
               {
                   home();
                   printf("Name P-File=");
                   fgets_cons(answer, 33);
                   if (answer[0] > ' ')
                   {
                       answer[strlen(answer) - 1] = 0; /* overwrite CR */
                       strcpy(cmd, "S ");
                       strcat(cmd, answer);
                   }
                   home();
              }


               if (strlen(cmd))
               {
                   if (exec(cmd, 0))
                   {
                       home();
                       printf("Fehler\n");
                       in_Wait(1000);
                       home();
                   }
               }
               else
                   show_dir = 1;

               in_WaitForNoKey();

               if (wait_for_return)
               {
                   home();
                   printf("\n<return>\n");
                   fgets_cons(answer, 33);
                   home();
                   in_WaitForNoKey();
               }
               if (show_dir)
               {
                   exec("D", 1);
                   line = 0;
                   screen_pos = invert_line(line);
               }
               break;

           case 'X':
               loop = 0;
               in_WaitForNoKey();
               break;
       }
    }
    while(loop);
}

Benutzeravatar
siggi
User
Beiträge: 2450
Registriert: 06.12.2005, 08:34
Wohnort: D, Hessen, tiefste Werreraa
Kontaktdaten:

Re: Erweiterter USB-Treiber + neues User Interface

Beitrag von siggi » 14.11.2011, 23:08

Ebbes geht immer noch :D

Ich habe ins UI, das jetzt "USB FILE MANAGER V1.0" heißt, noch 2 Gimmicks reingepackt, die auch schon in meinem FAT32-Programm zum Lesen/Schreiben von FAT32 MMC-Karten implementiert hatte.

Mit Tasten
M
landet man direkt im MEFISDOS (so man eines hat, das sich bei 8192 befindet und sich reinPOKEn läßt). Und so kann man unter Umgehung des BASIC ein AUTOSTART-Programm kopieren, ohne daß es losrennt und sich vielleicht selbst modifiziert oder nicht mehr abspeichern lassen will.
Beendet man MEFISDOS, landet man wieder im UFM.

Und mit Taste
-
wird schließlich beim im Speicher (nicht auf dem Stick!) liegenden Programm (das man z. B. zuvor geladen hatte) die AUTOSTART-Information gelöscht, sodaß man in Ruhe das Programm von BASIC aus auseinandernehmen kann, ohne daß es losrennt.

Das ist der Startbildschirm, der zeitgesteuer oder per Tastendruck verschwindet:
UFM.jpg
UFM.jpg (87.4 KiB) 10344 mal betrachtet
Und hier ist der UFM V1.0 (wieder für 32K compiliert)
ufm.zip
(3.06 KiB) 144-mal heruntergeladen
Und hier ist noch der um 1 Fehler ärmere Treiber V1.3.2:
USB132.P
(10.68 KiB) 148-mal heruntergeladen
Und noch der Source:

Code: Alles auswählen

//zcc +zx81 -startup=2 -create-app -vn -o ufm.bin ufm.c

#define MEFISDOS

#include <stdio.h>
#include <string.h>
#include <input.h>
#include <conio.h>
#include <zx81.h>

unsigned int DFILE @ 16396;
unsigned char ERRNO @ 16434;
unsigned char PRBUF[33] @ 16444;
unsigned int NXTLIN @ 16425;

void zx_cls(void)
{
   putchar(12);  /* clears C screen and resets C print postion to home */
#asm
   XREF restore81
   call restore81
   call $A2A
#endasm
}

void home(void)
{
    int i;
    for (i=0; i < 70; i++)
       putchar(8);
}

unsigned char exec(char * cmd, char del_screen)
{
    int i;
    for (i=0; i < strlen(cmd); i++)
        PRBUF[i] = ascii_zx(cmd[i]);
    PRBUF[i++] = 11; /* terminating " */
    if (del_screen)
    {
        zx_cls();
    }
#if 1
#asm
    call restore81
    call 8198
#endasm
#else
    printf("exec=>%s< len=%d\n",cmd, strlen(cmd));
#endif
    zx_slow();
    return ERRNO;
}

/* assembler defines */
#define EPSEL 0x7F
#define FRET  0xF65F
#define SELRB 0x3C7A
#define MEFISDOSENTRY 8198
#define WORKPAGE 13
#define FILEPAGE 14

void exec_mefisdos(void)
{
#asm
     call restore81
     ld a,2
     out (EPSEL),a    ; enable MEFISDOS EEPROM and setup program environment
     ld a,WORKPAGE
     ld (8),a       ; POKE 8,13 for ZX96
     ld a,WORKPAGE  ; select work page
     call SELRB
     xor a
     ld (FRET),a    ; set "return to m/c"
     call MEFISDOSENTRY  ; call MEFIDOS
     ld a,4         ; enable ram
     out (EPSEL),a
#endasm
}

unsigned char * invert_line(int no)
{
    unsigned char * pos;
    int i;
    pos = (unsigned char *) (DFILE + 1 + no * 33);
    for (i=0; i < 32; i++)
    {
        *pos |= 0x80;
        pos++;
    }
    return DFILE + 1 + no * 33;
}

unsigned char * reset_line(int no)
{
    unsigned char * pos;
    int i;
    pos = (unsigned char *) (DFILE + 1 + no * 33);
    for (i=0; i < 32; i++)
    {
        *pos &= 0x7F;
        pos++;
    }
    return DFILE + 1 + no * 33;
}

int getline(unsigned char * pos, char * buffer)
{
    char ch;
    int i = 0;

    do
    {
        ch = zx_ascii((*pos++) & 0x7F);
        *buffer++ = ch;
    }
    while (ch != ' ');
    *(--buffer) = '\0';
    if (zx_ascii((*pos) & 0x7F) == 'D')
        return 1;
    else
        return 0;
}

void main()
{
   int loop = 1;
   int line = 0;
   char key;
   unsigned char* screen_pos;
   char cmd[33];
   char name[33];
   char answer[33];
   char is_dir, is_prog, wait_for_return, show_dir;
   int name_len;

   zx_cls();

   printf("  ZX81 USB FILE MANAGER V1.0   \n");
   invert_line(0);
   printf("\n");
   printf("Tasten fuer Dateien:\n");
   printf("L,CR:   Laden\n");
   printf("S:      SPEICHERN\n");
   printf("E:      LOESCHEN\n");
   printf("-:      AUTOSTART LOESCHEN\n\n");
   printf("FUER VERZEICHNISSE\n");
   printf("V:      ANLEGEN\n");
   printf("K:      LOESCHEN\n");
   printf("5,8,CR: WECHSELN ZU\n\n");
   printf("GEMEINSAM:\n");
   printf("R:      UMBENENNEN\n\n");
   printf("SONSTIGES:\n");
   printf("6,7:    NAVIGIEREN\n");
   printf("C:      TREIBER-KOMMANDO\n");
   printf("A:      TREIBER-ABBRUCH\n");
#ifdef MEFISDOS
   printf("M:      MEFISDOS STARTEN\n");
#endif
   printf("X:      ENDE\n");
   in_Pause(5000);

   exec("D", 1);

   screen_pos = invert_line(line);
   do
   {
       in_Wait(20);
       key = getk();

       switch (key)
       {
           case '7':
                 if (line > 0)
                 {
                    reset_line(line);
                    line--;
                    screen_pos = invert_line(line);
                 }
                 break;

           case '6':
                 if (line < 19)
                 {
                    reset_line(line);
                    line++;
                    screen_pos = invert_line(line);
                 }
                 break;
           case 13:
           case 'L':
           case '8':
           case '5':
           case 'K':
           case 'V':
           case 'R':
           case 'E':
           case 'C':
           case 'S':
#ifdef MEFISDOS
           case 'M':
#endif
           case '-':
               wait_for_return = 0;
               is_dir = getline(screen_pos, name);
               name_len = strlen(name);
               cmd[0] =0;
               answer[0] =0;
               is_prog = 0;
               show_dir = 0;

#ifdef MEFISDOS
               if (key == 'M')
               {
                  zx_cls();
                  exec_mefisdos();
                  wait_for_return = 1;
               }
               else
#endif
               if (key == 'C')
               {
                   printf("Kommando=");
                   gets(answer);
                   if (answer[0] > ' ')
                   {
                       strcpy(cmd, answer);
                       wait_for_return = 1;
                       zx_cls();
                   }
                   home();
               }
               else
               if (key == '-')
               {
                   printf("AUTOSTART AUS (J/N)?");
                   gets(answer);
                   if (answer[0] == 'J')
                   {
                       NXTLIN = DFILE;
                   }
                   home();
               }
               else
               if (key == 'V')
               {
                   printf("Neues Verz.=");
                   gets(answer);
                   if (answer[0] > ' ')
                   {
                       strcpy(cmd, "V ");
                       strcat(cmd, answer);
                   }
                   home();
               }
               else
               if (name_len)
               {
                    /* name is given: check for program */
                    if (name_len > 2)
                       is_prog = !(strcmp(&name[name_len - 2], ".P"));

                    if (key == 'R')
                    {
                        printf("Neuer Name=");
                        gets(answer);
                        if (answer[0] > ' ')
                        {
                            strcpy(cmd, "R ");
                            strcat(cmd, name);
                            strcat(cmd, " ");
                            strcat(cmd, answer);
                        }
                        else
                            cmd[0] = 0;
                        home();
                    }

                    /* directory command */
                    if (is_dir)
                    {
                        if (key == 'K')
                        {
                            printf("Verz. loeschen(J/N)?");
                            gets(answer);
                            if (answer[0] == 'J')
                            {
                                strcpy(cmd, "K ");
                                strcat(cmd, name);
                            }
                            home();
                        }
                        else
                        if ((key == '5') || (key == '8') || (key == 13))
                        {
                            strcpy(cmd, "D ");
                            strcat(cmd, name);
                            show_dir = 1;
                        }
                    }
                    else
                    {
                        if ((key == 'L') || (key == 13))
                        {
                            strcpy(cmd, "L ");
                            strcat(cmd, name);
                            if (!is_prog)
                            {
                                printf("Adresse=");
                                gets(answer);
                                if (answer[0] > ' ')
                                {
                                    strcat(cmd, ",");
                                    strcat(cmd, answer);
                                }
                                else
                                    cmd[0] = 0;
                            }
                            show_dir = 1;
                        }
                        else
                        if (key == 'E')
                        {
                            printf("Datei loeschen(J/N)?");
                            gets(answer);
                            if (answer[0] == 'J')
                            {
                                strcpy(cmd, "E ");
                                strcat(cmd, name);
                            }
                        }
                        else
                        if (key == 'S')
                        {
                            if (is_prog)
                            {
                                printf("Programm ueberschreiben(J/N)?");
                                gets(answer);
                                if (answer[0] == 'J')
                                {
                                    strcpy(cmd, "S ");
                                    strcat(cmd, name);
                                }
                            }
                        }
                    }
                    home();
               }
               else
               if (key == 'S')
               {
                   do
                   {
                       home();
                       printf("Name P-File=");
                       gets(answer);
                       if (answer[0] > ' ')
                       {
                           strcpy(cmd, "S ");
                           strcat(cmd, answer);
                       }
                   }
                   while (!strstr(answer, ".P"));
                   home();
               }

               if (strlen(cmd))
               {
                   if (exec(cmd, 0))
                   {
                       printf(">>> Fehler Code %d <<<\n", ERRNO);
                       wait_for_return = 1;
                   }
               }
               else
                   show_dir = 1;

               in_WaitForNoKey();

               if (wait_for_return)
               {
                   printf("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n");
                   printf("<RETURN>");
                   gets(answer);
                   zx_cls();
                   in_WaitForNoKey();
                   show_dir = 1;
               }
               if (show_dir)
               {
                   exec("D", 1);
                   line = 0;
                   screen_pos = invert_line(line);
               }
               break;

           case 'X':
               loop = 0;
               in_WaitForNoKey();
               break;
       }
    }
    while(loop);
    #asm
    rst 8
    DEFB $FF
    #endasm
}
Gruß und viel Spaß
Siggi

Benutzeravatar
siggi
User
Beiträge: 2450
Registriert: 06.12.2005, 08:34
Wohnort: D, Hessen, tiefste Werreraa
Kontaktdaten:

Re: Erweiterter USB-Treiber + neues User Interface

Beitrag von siggi » 15.11.2011, 22:44

Ich habe noch ein paar Kleinigkeiten im UFM geändert (der Startbildschirm ist nun auch über H als Hilfe vorhanden, Mefisdos kann man nur auf leerem Feld starten (aus Sicherheitsgründen, falls man kein MEFISDOS bei 8K hat), Taste '-' durch '0' ersetzt) und das Programm ist nun ca. 5100 Bytes lang (Joachim: paßt also nicht mehr in einen 4K Block).

Ich habe das Programm deshalb für folgende Adressen compiliert:
8192 + 3000 = 11192
32768 + 3000 = 35768

Die Lücke von 3000 Bytes am Anfang ist für den Treiber vorgesehen, der ca. 2800 Bytes braucht. Ich habe dann bei mir im Treiber den ersten Einsprung (z.B. bei 32768) auf die Adresse des UFM (35768) geändert und den gesamten Block 32K-40K abgespeichert. So komme ich dann mit USR 32768 gleich in den UFM.

Hier sind die für 11192 und 35768 compilierten Dateien:
ufm_8_32K.zip
(6.25 KiB) 145-mal heruntergeladen
Diese erwarten den Treiber jeweils auf den Adressen 8192 bzw. 32768.
Also Treiber dahin assemblieren und entsprechenden UFM...BIN-Datei auf ihre Adresse laden und dann alles zusammen abspeichern (ein 8K Block).

Die 8K-Version enthält keinen MEFISDOS-Aufruf, damit sich der UFM nicht den Boden unter den Füßen wegpoken kann. EDIT: Ist inzwischen getestet und läuft.

Und hier der neueste Source Code (ist nun auch etwas übersichtlicher geworden):

Code: Alles auswählen

// ZX81 USB FILE MANAGER
// for usage with USB Driver 1.3.0 ...
//
// V1.0
// Made by Siggi, Nov. 2011
//
//zcc +zx81 -startup=2 -create-app -DDRIVER=8192 -vn -o ufm.bin ufm.c

/* wegnehmen, wenn kein MEFISDOS vorhanden ist */
#define MEFISDOS

#include <stdio.h>
#include <string.h>
#include <input.h>
#include <conio.h>
#include <zx81.h>

unsigned int DFILE @ 16396;
unsigned char ERRNO @ 16434;
unsigned char PRBUF[33] @ 16444;
unsigned int NXTLIN @ 16425;

void zx_cls(void)
{
   putchar(12);  /* clears C screen and resets C print postion to home */
#asm
   XREF restore81
   call restore81
   call $A2A
#endasm
}

void home(void)
{
    int i;
    for (i=0; i < 70; i++)
       putchar(8);
}

void exec(char * cmd, char del_screen)
{
    int i;
    for (i=0; i < strlen(cmd); i++)
        PRBUF[i] = ascii_zx(cmd[i]);
    PRBUF[i++] = 11; /* terminating " */
    if (del_screen)
    {
        zx_cls();
    }
#if 1
#asm
    call restore81
    call DRIVER+6
#endasm
#else
    printf("exec=>%s< len=%d\n",cmd, strlen(cmd));
#endif
    zx_slow();
}

/* assembler defines */
#define EPSEL 0x7F
#define FRET  0xF65F
#define SELRB 0x3C7A
#define MEFISDOSENTRY 8198
#define WORKPAGE 13
#define FILEPAGE 14

void exec_mefisdos(void)
{
#asm
     call restore81
     ld a,2
     out (EPSEL),a    ; enable MEFISDOS EEPROM and setup program environment
     ld a,WORKPAGE
     ld (8),a       ; POKE 8,13 for ZX96
     ld a,WORKPAGE  ; select work page
     call SELRB
     xor a
     ld (FRET),a    ; set "return to m/c"
     call MEFISDOSENTRY  ; call MEFISDOS
#endasm
}

unsigned char * invert_line(int no)
{
    unsigned char * pos;
    unsigned char * ret;
    int i;
    ret = pos = (unsigned char *) (DFILE + 1 + no * 33);
    for (i=0; i < 32; i++)
    {
        if (*pos != 0x76)
            *pos |= 0x80;
        pos++;
    }
    return ret;
}

void reset_line(int no)
{
    unsigned char * pos;
    int i;
    pos = (unsigned char *) (DFILE + 1 + no * 33);
    for (i=0; i < 32; i++)
    {
        *pos &= 0x7F;
        pos++;
    }
}
/* returns 1, if name is a directory */
int getline(unsigned char * pos, char * buffer)
{
    char ch;
    int i = 0;

    do
    {
        ch = zx_ascii((*pos++) & 0x7F);
        *buffer++ = ch;
    }
    while (ch != ' ');
    *(--buffer) = '\0';
    if (zx_ascii((*pos) & 0x7F) == 'D')
        return 1;
    else
        return 0;
}

void show_help(void)
{
   zx_cls();
   printf("   ZX81 USB FILE MANAGER V1.0\n");
   invert_line(0);
   printf("\nDatei\n");
   printf("L,CR: Laden\n");
   printf("S:    SPEICHERN\n");
   printf("E:    LOESCHEN\n");
   printf("R:    UMBENENNEN\n");
   printf("\nVERZEICHNIS\n");
   printf("5,8:  WECHSELN\n");
   printf("V:    ANLEGEN\n");
   printf("K:    LOESCHEN\n");
   printf("R:    UMBENENNEN\n");
   printf("\nSONSTIGES\n");
   printf("6,7:  NAVIGIEREN\n");
   printf("C:    TREIBER-KOMMANDO\n");
   printf("A:    ABBRUCH\n");
   printf("0:    AUTOSTART LOESCHEN\n");
#ifdef MEFISDOS
   printf("M:    MEFISDOS\n");
#endif
   printf("H:    HILFE\n");
   printf("X:    ENDE\n");
   in_Pause(5000);
}
void main()
{
   int line = 0;
   char key;
   unsigned char* screen_pos;
   char cmd[33];
   char name[33];
   char answer[33];
   char is_dir, is_prog, wait_for_return, show_dir, wait_for_key_released;
   int name_len;

   show_help();
   show_dir = 1;

   do
   {
        if (show_dir)
        {
            exec("D", 1);
            line = 0;
            screen_pos = invert_line(line);
        }

        is_dir = getline(screen_pos, name);
        name_len = strlen(name);
        is_prog = (char) strstr(name, ".P");

        cmd[0] = 0;
        answer[0] = 0;
        show_dir = 0;
        wait_for_return = 0;
        wait_for_key_released = 1;

        in_Wait(20);
        key = in_Inkey();

        switch (key)
        {
            default:
                  break;

            case '7':
                  if (line > 0)
                  {
                      reset_line(line);
                      line--;
                      screen_pos = invert_line(line);
                      wait_for_key_released = 0;
                  }
                  break;

            case'6':
                  if (line < 20)
                  {
                      reset_line(line);
                      line++;
                      screen_pos = invert_line(line);
                      wait_for_key_released = 0;
                  }
                  break;

            case 'H':
                  show_help();
                  show_dir = 1;
                  break;

            case 'C':
                  printf("Kommando=");
                  gets(answer);
                  if (answer[0] > ' ')
                  {
                      strcpy(cmd, answer);
                      wait_for_return = 1;
                      zx_cls();
                  }
                  home();
                  break;

            case '0':
                  printf("AUTOSTART AUS (J/N)?");
                  gets(answer);
                  if (answer[0] == 'J')
                  {
                      NXTLIN = DFILE;
                  }
                  home();
                  break;

            case 'V':
                  printf("Neues Verz.=");
                  gets(answer);
                  if (answer[0] > ' ')
                  {
                      strcpy(cmd, "V ");
                      strcat(cmd, answer);
                  }
                  home();
                  break;

            case 'R':
                  if (name_len)
                  {
                      printf("Neuer Name=");
                      gets(answer);
                      if (answer[0] > ' ')
                      {
                          strcpy(cmd, "R ");
                          strcat(cmd, name);
                          strcat(cmd, " ");
                          strcat(cmd, answer);
                      }
                      home();
                  }
                  break;

            case 'K':
                  if (is_dir && name_len)
                  {
                      printf("Verz. loeschen(J/N)?");
                      gets(answer);
                      if (answer[0] == 'J')
                      {
                          strcpy(cmd, "K ");
                          strcat(cmd, name);
                      }
                      home();
                  }
                  break;

            case '5':
            case '8':
                  if (is_dir && name_len)
                  {
                      strcpy(cmd, "D ");
                      strcat(cmd, name);
                      show_dir = 1;
                  }
                  break;

            case 13:
                  if (!name_len)
                      show_dir = 1;
                  /* no break */
            case 'L':
                  if (!is_dir && name_len)
                  {
                      strcpy(cmd, "L ");
                      strcat(cmd, name);
                      if (!is_prog)
                      {
                          printf("Adresse=");
                          gets(answer);
                          if (answer[0] > ' ')
                          {
                              strcat(cmd, ",");
                              strcat(cmd, answer);
                          }
                          else
                              cmd[0] = 0;
                      }
                      home();
                      show_dir = 1;
                  }
                  break;

            case'E':
                  if (!is_dir && name_len)
                  {
                      printf("Datei loeschen(J/N)?");
                      gets(answer);
                      if (answer[0] == 'J')
                      {
                          strcpy(cmd, "E ");
                          strcat(cmd, name);
                      }
                      home();
                  }
                  break;

            case 'S':
                  if (!is_dir && name_len && is_prog)
                  {
                      printf("Ueberschreiben(J/N)?");
                      gets(answer);
                      if (answer[0] == 'J')
                      {
                          strcpy(cmd, "S ");
                          strcat(cmd, name);
                      }
                      home();
                  }
                  if (!name_len)
                  {
                      printf("Name P-File=");
                      gets(answer);
                      if (answer[0] > ' ')
                      {
                          strcpy(cmd, "S ");
                          strcat(cmd, answer);
                          if (!strstr(answer, ".P"))
                              strcat(cmd, ".P");
                      }
                      home();
                  }
                  break;

#ifdef MEFISDOS
            case 'M':
                  if (!name_len)
                  {
                     zx_cls();
                     exec_mefisdos();
                     wait_for_return = 1;
                  }
                  break;
#endif
        }

        /* anything to do? */
        if (cmd[0])
        {
            exec(cmd, 0);
            if (ERRNO)
            {
                printf("> Fehler Code %d <\n", ERRNO);
                wait_for_return = 1;
            }
        }

        if (wait_for_key_released)
            in_WaitForNoKey();

        if (wait_for_return)
        {
            printf("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n");
            printf("<RETURN>");
            gets(answer);
            show_dir = 1;
        }
    }
    while(key != 'X');
    #asm
    rst 8
    DEFB $FF
    #endasm
}
@Joachim: zur Adresse 40960: wo soll denn da der Treiber liegen? Bei 8k?

Gruß und viel Spaß
Siggi
Zuletzt geändert von siggi am 16.11.2011, 13:46, insgesamt 1-mal geändert.

Benutzeravatar
siggi
User
Beiträge: 2450
Registriert: 06.12.2005, 08:34
Wohnort: D, Hessen, tiefste Werreraa
Kontaktdaten:

Re: Erweiterter USB-Treiber + neues User Interface

Beitrag von siggi » 16.11.2011, 09:52

Noch ein paar Hinweise zur Bedienung des UFM:
die meisten Tasten werden ja kontextabhängig (Inhalt der markierten Zeile) ausgewertet. Und was bei manchen Tasten von sich aus klar ist (z. B. L oder CR lädt aktuelle Datei, K löscht aktuelles Verzeichnis), ist es bei anderen nicht unmittelbar. Deshalb hier ein paar Sonderfälle:

S (Speichern) auf einem markieren P-File führt (nach Rückfrage) zum Überschreiben dieses P-Files
S auf einem leeren Feld (oberste leere Zeile markiert) führt zum Abspeichern eines neuen P-Files (nach Abfrage des Namens). Dabei wird eine Extension ".P" an den Namen angebabbt, falls er diese nicht schon hat. Es wird aber vom UFM nicht geprüft, ob der neu eingegeben Name nicht schon als P-Datei auf dem Stick existiert (man könnte also dennoch eine vorhandene P-Datei damit überschreiben).
Datenfiles, die eine Adresse und Länge als Parameter zum Abspeichern brauchen, können nur über ein direktes Treiberkommando (mittels C) gespeichert werden.

CR (Return) lädt ein markiertes P-File direkt. Bei einem Datenfile wird noch die Zieladresse abgefragt.
CR auf einem leeren Feld (oberste Zeile) schickt aber ein DIR-Kommando an den Treiber. Damit kann man also das aktuelle Verzeichnis auf den Bildschirm "wiederholen", wenn es nach einem Fehler (z. B. USB-Stick nicht gesteckt) verloren gegangen ist (leerer Bildschirm, in dem man keine Verzeichnisse mehr markieren kann, um z.B. zum Root-Verzeichnis zu gelangen).

M (Mefisdos Einsprung) wird nur auf einem leeren Feld (oberste Zeile) ausgeführt, wodurch die versehentliche Bedienung erschwert wird( sinnvoll, wenn kein MEFISDOS bei 8K vorhanden ist).

'0' zum Löschen der AUTOSTART-Information des geladenen Programmes bezieht sich ja nicht auf den Stick und wird immer (unabhängig von der Markierung) akzeptiert.

'A' (Abbruch) wirkt nur auf den Treiberaufruf. Wenn man im UFM selbst ein Kommando abbrechen will, kann man dies durch eine leere Eingabe (z. B. bei Abfrage des Dateinamens) erreichen.

Fast alle Tasten (außer 6 und 7) müssen nach Betätigung losgelassen werden, damit nicht (quer durch Treiber, Directories, UFM und Fehlermeldungen) durch "Dauerfeuer" eine unerwünschte Aktion losgetreten wird. Das kann man sich aber zunutze machen, wenn man ein Bild (z. B. Hilfetext) länger auf dem Schirm haben möchte: dann einfach die Taste (z. B. H für die Hilfe) gedrückt halten ....

Gruß
Siggi

Nachtrag: Hier der aktuelle Start/Hilfe Screen
UFM-H.jpg
UFM-H.jpg (115.12 KiB) 10301 mal betrachtet

Benutzeravatar
Joachim
User
Beiträge: 1038
Registriert: 06.11.2004, 20:21

Re: Erweiterter USB-Treiber + neues User Interface

Beitrag von Joachim » 21.11.2011, 11:31

Hallo Siggi,
war mal kurz weg, darum die Antwort etwas verspätet: Mit 40960 habe ich mich vertan. Das wäre die Adresse des USB-Treibers. Nach der neuen Konvention bitte die Adresse auf 40960 + 3000 = 43960 legen. Den USB-Treiber lege ich dann auf Adresse 40960. Weil ich einiges im Bereich ab 32768 laufen lasse (Druckertreiber für Listings etc.) und auch der Bereich ab 8192 sehr begehrt ist, kann ich mir dann auch einen Block auf diese Adresse legen.
Danke und viele Grüße
Joachim
Viele Grüße!
Joachim


ZX80, ZX81, ZX-Spectrum, ZX96, ZX2000, ZXmore, ZX81NU, Blauer Engel, AX81

Benutzeravatar
siggi
User
Beiträge: 2450
Registriert: 06.12.2005, 08:34
Wohnort: D, Hessen, tiefste Werreraa
Kontaktdaten:

Re: Erweiterter USB-Treiber + neues User Interface

Beitrag von siggi » 21.11.2011, 18:55

Hallo Joachim (und andere)

ich habe die Zwischenzeit genutzt und noch ein bißchen was an Treiber und UFM verbessert:
der Treiber V1.3.3 enthält nun als ersten den Sprung zum Label UFM, das man entsprechend setzen muß, wo der UFM liegt. Der ursprünglichen Einsprung nach USB1 ist nun der 4. Einsprung (so man den noch nutzen will).
Und der Treiber ermöglich nun auch ein BREAK mit der Taste "6". So kann man schon im Treiber "Anlauf nehmen", wenn man im UFM mit dem Balken zu der heißersehnten Datei sich vorarbeiten will: 6 im Treiber macht BREAK und man kann (ohne von der Taste zu gehen) gleich im UFM nach unten navigieren.

Der UFM heißt nun V 1.1 und hat folgende Änderungen:

- die Taste "5" schickt ein "D .." an den Stick, sodaß man überall direkt ein Verzeichnis "nach oben" wandern kann, ohne bis zum Eintrag ".." navigieren zu müssen. Das klappt natürlich nicht mehr im Root-Verzeichnis: da gibt's 'nen Fehler.

- 8 und CR auf einem Verzeichnis wechselns ins Verzeichnis
- L und CR auf einer Datei laden die Datei, wobei nach CR der UFM beendet wird und man gleich wieder im Basic ist. Nach L bleibt man im UFM, wo man die geladene Datei dann ggf. manipulieren ("0") oder z. B. nach MEFISDOS schaufeln kann.

Ich habe den UFM für 8, 32 und 40K (mit 3000 Byte Offset) compiliert (sind alle im ZIP-File drin).
Zusätzlich gibt's eine Datei UFM-R.bin für die Unentschlossenen: die kann man auf jede Adresse (z. B. 4711) laden und dort starten, denn sie ist "relokierbar".
Wenn sie dort z. B. mit RAND USR 4711 gestartet wird, dann "patcht" sich die Datei selbst, damit sie auf 4711 läuft. Dann fragt das Programm die Treiberadresse ab.
Wenn man nach Beendigung des UFM dann diesen Datenbereich ab 4711 abspeichert, dann bleibt auch die Treiberadresse gespeichert. Beim nächsten Start wird aber nicht mehr "selbstgepatcht", dann läuft das Programm nur noch auf dieser Adresse.
Der relokierbare UFM ist etwas größer, da er ja zusätzlich die Tabelle zum Selbstpatch enthält. Ich habe deshalb dort die Hilfe-Seite großteils weggelassen, damit er nicht zu groß wird. Man kann ihn aber immer noch mit dem Treiber in einen 8K-Block pressen, aber der OFFSET 3000 muß verkleinert werden.

Und hier sind die Dateien:

Gelöscht, weil da beim compilieren was schief ging :cry:

Und hier nochmal der Source

Code: Alles auswählen

// ZX81 USB FILE MANAGER
// for usage with USB Driver 1.3.0 ...
//
// V1.1
// Made by Siggi, Nov. 2011
//
// Use compiler option -DDRIVER=xxxx to define the driver's address.
// Otherwise it will be asked for at start of program.
// Use -DNO_HELP to have a smaller program without help screen
// Use -DNO_MEFISDOS to disable calls to MEFISDOS at 8k
//
//To make a .P file (no fixed driver address):
//zcc +zx81 -startup=2 -create-app -vn -o ufm.bin ufm-driver.c
// or for other location (32768) with driver at 8K
//zcc +zx81 -startup=2 -zorg=32768 -vn -DDRIVER=8192 -o ufm-32768.bin ufm-driver.c
// or for other location (11192) with driver at 8K, without MEFIDOS
//zcc +zx81 -startup=2 -zorg=11192 -vn -DNO_MEFISDOS -DDRIVER=8192 -o ufm-11192.bin ufm-driver.c
// or for other location (35768) with driver at 32K
//zcc +zx81 -startup=2 -zorg=35768 -vn -DDRIVER=32768 -o ufm-35768.bin ufm-driver.c
// or for other location (43960) with driver at 40K
//zcc +zx81 -startup=2 -zorg=43960 -vn -DDRIVER=40960 -o ufm-43960.bin ufm-driver.c
// or for relocatable code (no HELP screen, no fixed driver address)
//zcc +zx81 -startup=2 -Ca-R -vn -DNO_HELP -o ufm-R.bin ufm-driver.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <input.h>
#include <conio.h>
#include <zx81.h>

unsigned int DFILE @ 16396;
unsigned char ERRNO @ 16434;
unsigned char PRBUF[33] @ 16444;
unsigned int NXTLIN @ 16425;
unsigned char DF_SZ @ 16418;

static unsigned int driver_addr = 0;

void zx_cls(void)
{
    putchar(12);
}

void zx_print_at(unsigned char line, unsigned char column)
{
#asm
    XREF restore81
    call restore81
    pop hl; address
    pop bc; column into C
    pop de; line
    push de
    push bc
    push hl
    ld b,e; line into B
    jp 0x8F5
#endasm
}

void del_line(char line)
{
    memset(DFILE + 1 + 33 * line, 0, 32); /* clear line */
}

void home(void)
{
    zx_print_at(0, 0);
    del_line(0);
}

void exec(char * cmd, char del_screen)
{
    int i;
    for (i=0; i < strlen(cmd); i++)
        PRBUF[i] = ascii_zx(cmd[i]);
    PRBUF[i++] = 11; /* terminating " */
    if (del_screen)
    {
        zx_cls();
    }
#asm
    XREF l_dcal
    call restore81
    ld HL,(_driver_addr)
    ld BC,6
    add HL,BC
    call l_dcal
#endasm
    zx_slow();
    home();
//    printf("exec=>%s< len=%d\n",cmd, strlen(cmd));
}

#ifndef NO_MEFISDOS

/* assembler defines */
#define EPSEL 0x7F
#define FRET  0xF65F
#define SELRB 0x3C7A
#define MEFISDOSENTRY 8198
#define WORKPAGE 13
#define FILEPAGE 14

void exec_mefisdos(void)
{
#asm
     call restore81
     ld a,2
     out (EPSEL),a    ; enable MEFISDOS EEPROM and setup program environment
     ld a,WORKPAGE
     ld (8),a       ; POKE 8,13 for ZX96
     ld a,WORKPAGE  ; select work page
     call SELRB
     xor a
     ld (FRET),a    ; set "return to m/c"
     call MEFISDOSENTRY  ; call MEFISDOS
     ld a,4
     out (EPSEL),a
#endasm
     zx_slow();
}
#endif

unsigned char * invert_line(int no)
{
    unsigned char * pos;
    unsigned char * ret;
    int i;
    ret = pos = (unsigned char *) (DFILE + 1 + no * 33);
    for (i=0; i < 32; i++)
    {
        if (*pos != 0x76)
            *pos |= 0x80;
        pos++;
    }
    return ret;
}

void reset_line(int no)
{
    unsigned char * pos;
    int i;
    pos = (unsigned char *) (DFILE + 1 + no * 33);
    for (i=0; i < 32; i++)
    {
        *pos &= 0x7F;
        pos++;
    }
}
/* returns 1, if name is a directory */
int getline(unsigned char * pos, char * buffer)
{
    char ch;
    int i = 0;

    do
    {
        ch = zx_ascii((*pos++) & 0x7F);
        *buffer++ = ch;
    }
    while (ch != ' ');
    *(--buffer) = '\0';
    if (zx_ascii((*pos) & 0x7F) == 'D')
        return 1;
    else
        return 0;
}
void show_help(void)
{
   zx_cls();
   printf("   ZX81 USB FILE MANAGER V1.1\n");
   invert_line(0);
#ifndef NO_HELP
   printf("\nDatei\n");
   printf("L,CR: Laden/X\n");
   printf("S:    SPEICHERN\n");
   printf("E:    LOESCHEN\n");
   printf("R:    UMBENENNEN\n");
   printf("\nVERZEICHNIS\n");
   printf("5:    ZURUECK\n");
   printf("8,CR: HINEIN\n");
   printf("V:    ANLEGEN\n");
   printf("K:    LOESCHEN\n");
   printf("R:    UMBENENNEN\n");
   printf("\nSONSTIGES\n");
   printf("6,7:  NAVIGIEREN\n");
   printf("0:    AUTOSTART LOESCHEN\n");
   printf("T:    TREIBER-KOMMANDO (%u)\n", driver_addr);
   printf("A:    ABBRUCH\n");
#ifndef NO_MEFISDOS
   printf("M:    MEFISDOS\n");
#endif
   printf("H:    HILFE\n");
   printf("X:    ENDE\n");
#else
   printf("\nTREIBER: %u\n", driver_addr);
#endif

   in_Pause(5000);
}


void main()
{
   int line = 0;
   char key;
   unsigned char* screen_pos;
   char cmd[33];
   char name[33];
   char answer[33];
   char is_dir, is_prog, wait_for_return, show_dir, wait_for_key_released;
   int name_len;

   DF_SZ = 0;   /* use full screen: 24 lines */

#ifdef DRIVER
   driver_addr = DRIVER;
#else
   if (!driver_addr)
   {
       printf("Treiber-Adresse=");
       gets(answer);
       driver_addr = atoi(answer);
   }
#endif

   show_help();

   show_dir = 1;

   do
   {
        if (show_dir)
        {
            exec("D", 1);
            line = 0;
            screen_pos = invert_line(line);
        }

        is_dir = getline(screen_pos, name);
        name_len = strlen(name);
        is_prog = (char) strstr(name, ".P");

        cmd[0] = 0;
        answer[0] = 0;
        show_dir = 0;
        wait_for_return = 0;
        wait_for_key_released = 1;

        in_Wait(20);
        key = in_Inkey();

        switch (key)
        {
            default:
                  break;

            case '7':
                  if (line > 0)
                  {
                      reset_line(line);
                      line--;
                      screen_pos = invert_line(line);
                      wait_for_key_released = 0;
                  }
                  break;

            case'6':
                  if (line < 20)
                  {
                      reset_line(line);
                      line++;
                      screen_pos = invert_line(line);
                      wait_for_key_released = 0;
                  }
                  break;

            case 'H':
                  show_help();
                  show_dir = 1;
                  break;

            case 'T':
                  printf("Kommando=");
                  gets(answer);
                  if (answer[0] > ' ')
                  {
                      strcpy(cmd, answer);
                      wait_for_return = 1;
                      zx_cls();
                  }
                  home();
                  break;

            case '0':
                  printf("AUTOSTART AUS (J/N)?");
                  gets(answer);
                  if (answer[0] == 'J')
                  {
                      NXTLIN = DFILE;
                  }
                  home();
                  break;

            case 'V':
                  printf("Neues Verz.=");
                  gets(answer);
                  if (answer[0] > ' ')
                  {
                      strcpy(cmd, "V ");
                      strcat(cmd, answer);
                  }
                  home();
                  break;

            case 'R':
                  if (name_len)
                  {
                      printf("Neuer Name=");
                      gets(answer);
                      if (answer[0] > ' ')
                      {
                          strcpy(cmd, "R ");
                          strcat(cmd, name);
                          strcat(cmd, " ");
                          strcat(cmd, answer);
                      }
                      home();
                  }
                  break;

            case 'K':
                  if (is_dir)
                  {
                      printf("Verz. loeschen(J/N)?");
                      gets(answer);
                      if (answer[0] == 'J')
                      {
                          strcpy(cmd, "K ");
                          strcat(cmd, name);
                          del_line(line);
                      }
                      home();
                  }
                  break;

            case '5':
                  strcpy(cmd, "D ..");
                  show_dir = 1;
                  break;

            case 13:
            case '8':
                  show_dir = 1; /* screen will be destroyed, so restore DIR in any case */
                  if (is_dir)
                  {
                      strcpy(cmd, "D ");
                      strcat(cmd, name);
                      break;
                  }
                  if (is_prog)
                      key = 'X'; /* terminate after LOAD */
                  /* no break */
            case 'L':
                  if (!is_dir && name_len)
                  {
                      strcpy(cmd, "L ");
                      strcat(cmd, name);
                      if (!is_prog)
                      {
                          printf("Adresse=");
                          gets(answer);
                          if (answer[0] > ' ')
                          {
                              strcat(cmd, ",");
                              strcat(cmd, answer);
                          }
                          else
                              cmd[0] = 0;
                      }
                      home();
                      show_dir = 1;
                  }
                  break;

            case'E':
                  if (!is_dir && name_len)
                  {
                      printf("Datei loeschen(J/N)?");
                      gets(answer);
                      if (answer[0] == 'J')
                      {
                          strcpy(cmd, "E ");
                          strcat(cmd, name);
                          del_line(line);
                      }
                      home();
                  }
                  break;

            case 'S':
                  if (is_prog)
                  {
                      printf("Ueberschreiben(J/N)?");
                      gets(answer);
                      if (answer[0] == 'J')
                      {
                          strcpy(cmd, "S ");
                          strcat(cmd, name);
                      }
                      home();
                  }
                  if (!name_len)
                  {
                      printf("Name P-File=");
                      gets(answer);
                      if (answer[0] > ' ')
                      {
                          strcpy(cmd, "S ");
                          strcat(cmd, answer);
                          if (!strstr(answer, ".P"))
                              strcat(cmd, ".P");
                      }
                      home();
                  }
                  break;

#ifndef NO_MEFISDOS
            case 'M':
                  if (!name_len)
                  {
                     zx_cls();
                     exec_mefisdos();
                     wait_for_return = 1;
                  }
                  break;
#endif
        }

        /* anything to do? */
        if (cmd[0])
        {
            exec(cmd, 0);
            if (ERRNO)
            {
                home();
                printf("> Fehler %d <\n", ERRNO);
                wait_for_return = 1;
            }
        }

        if (wait_for_key_released)
            in_WaitForNoKey();

        if (wait_for_return)
        {
            zx_print_at(23, 0);
            printf("<UFM: RETURN>");
            gets(answer);
            show_dir = 1;
        }
    }
    while(key != 'X');
    #asm
    rst 8
    DEFB $FF
    #endasm
}
Gruß und viel Spaß
Siggi
Zuletzt geändert von siggi am 21.11.2011, 22:45, insgesamt 1-mal geändert.

Benutzeravatar
Joachim
User
Beiträge: 1038
Registriert: 06.11.2004, 20:21

Re: Erweiterter USB-Treiber + neues User Interface

Beitrag von Joachim » 21.11.2011, 19:50

Super Service! Hab's schon runtergeladen und bin beim Ausprobieren.
Grüße
Joachim
Viele Grüße!
Joachim


ZX80, ZX81, ZX-Spectrum, ZX96, ZX2000, ZXmore, ZX81NU, Blauer Engel, AX81

Antworten