Benutzer-Werkzeuge

Webseiten-Werkzeuge


start

Dies ist eine alte Version des Dokuments!


Füge global dazu:

static uint8 g_shift = 0;
static uint8 g_caps  = 0;


Und passe get_keycode_once() so an, dass Modifier-Tasten den Zustand setzen und nicht als Zeichen zurückkommen:

int get_keycode_once(uint8 *out_scancode)
{
  if (!kbd_has_data()) return 0;
  uint8 sc = kbd_read_data();

  if (sc == 0xE0) { e0_prefix = 1; return 0; }

  // Break (release)
  if (sc & 0x80) {
    uint8 make = sc & 0x7F;

    // Shift released?
    if (!e0_prefix && (make == 0x2A || make == 0x36)) g_shift = 0;

    if (!e0_prefix && make < 128) key_down[make] = 0;
    e0_prefix = 0;
    return 0;
  }

  // Make (press)
  if (!e0_prefix) {
    // Shift pressed?
    if (sc == 0x2A || sc == 0x36) { g_shift = 1; return 0; }

    // CapsLock toggled?
    if (sc == 0x3A) { g_caps ^= 1; return 0; }

    // suppress repeats
    if (sc < 128) {
      if (key_down[sc]) return 0;
      key_down[sc] = 1;
    }
  }

  e0_prefix = 0;
  *out_scancode = sc;
  return 1;
}

2) ASCII-Übersetzung mit Shift (US-Map als Basis)

Ersetze/ergänze deine get_ascii_char()-Logik durch eine Funktion, die Shift/Caps berücksichtigt:

static const char kbd_us[128] = {
  0,  27,'1','2','3','4','5','6','7','8','9','0','-','=',  '\b',
  '\t','q','w','e','r','t','y','u','i','o','p','[',']','\n', 0,
  'a','s','d','f','g','h','j','k','l',';','\'','`', 0,'\\',
  'z','x','c','v','b','n','m',',','.','/', 0,  '*', 0,' ',
  /* rest 0 */ 
};

static const char kbd_us_shift[128] = {
  0,  27,'!','@','#','$','%','^','&','*','(',')','_','+',  '\b',
  '\t','Q','W','E','R','T','Y','U','I','O','P','{','}','\n', 0,
  'A','S','D','F','G','H','J','K','L',':','"','~', 0,'|',
  'Z','X','C','V','B','N','M','<','>','?', 0,  '*', 0,' ',
};

static char get_ascii_char_ex(uint8 sc)
{
  if (sc >= 128) return 0;

  char c = g_shift ? kbd_us_shift[sc] : kbd_us[sc];

  // CapsLock nur für Buchstaben (und Shift invertiert Caps)
  if (c >= 'a' && c <= 'z') {
    if (g_caps ^ g_shift) c = (char)(c - 'a' + 'A');
  } else if (c >= 'A' && c <= 'Z') {
    if (g_caps ^ g_shift) c = (char)(c - 'A' + 'a');
  }

  return c;
}
// erlaubte Zeichen für Mini-BASIC
static int is_allowed_basic_char(char c) {
    if (c == ' ' || c == '.' || c == '"' || c == '=' || c == '+' || c == '-' ||
        c == '*' || c == '/' || c == '(' || c == ')' || c == '<' || c == '>' ||
        c == ',' ) return 1;

    if (c >= 'A' && c <= 'Z') return 1;
    if (c >= '0' && c <= '9') return 1;
    return 0;
}
// ===================== MINI BASIC (int-only) =====================

#define BASIC_MAX_LINES 64
#define BASIC_LINE_LEN  96

typedef struct {
    uint16 line_no;
    uint8  used;
    char   text[BASIC_LINE_LEN];
} BasicLine;

static BasicLine g_prog[BASIC_MAX_LINES];
static int g_vars[26]; // A..Z

static void basic_reset_program(void) {
    for (int i = 0; i < BASIC_MAX_LINES; i++) {
        g_prog[i].used = 0;
        g_prog[i].line_no = 0;
        g_prog[i].text[0] = 0;
    }
}

static void basic_reset_vars(void) {
    for (int i = 0; i < 26; i++) g_vars[i] = 0;
}

static int is_space(char c) { return c == ' ' || c == '\t'; }

static char up(char c) {
    if (c >= 'a' && c <= 'z') return (char)(c - 'a' + 'A');
    return c;
}

static void skip_spaces(const char **p) {
    while (**p && is_space(**p)) (*p)++;
}

static int is_digit(char c) { return (c >= '0' && c <= '9'); }
static int is_alpha(char c) { return (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z'); }

static int starts_with_kw(const char *s, const char *kw) {
    // case-insensitive, kw muss "Wortgrenze" haben (Ende oder Space)
    int i = 0;
    while (kw[i]) {
        if (up(s[i]) != kw[i]) return 0;
        i++;
    }
    char next = s[i];
    return (next == 0 || is_space(next));
}

static uint16 parse_u16(const char **p) {
    skip_spaces(p);
    uint16 v = 0;
    while (is_digit(**p)) {
        v = (uint16)(v * 10 + (**p - '0'));
        (*p)++;
    }
    return v;
}

static int parse_int(const char **p) {
    skip_spaces(p);
    int sign = 1;
    if (**p == '+') { (*p)++; }
    else if (**p == '-') { sign = -1; (*p)++; }

    int v = 0;
    while (is_digit(**p)) {
        v = v * 10 + (**p - '0');
        (*p)++;
    }
    return v * sign;
}

static int find_line_index(uint16 line_no) {
    for (int i = 0; i < BASIC_MAX_LINES; i++) {
        if (g_prog[i].used && g_prog[i].line_no == line_no) return i;
    }
    return -1;
}

static int find_free_slot(void) {
    for (int i = 0; i < BASIC_MAX_LINES; i++) {
        if (!g_prog[i].used) return i;
    }
    return -1;
}

static int find_next_line_sorted(uint16 last_line, uint16 *out_line, int *out_idx) {
    int found = 0;
    uint16 best = 0xFFFF;
    int best_i = -1;

    for (int i = 0; i < BASIC_MAX_LINES; i++) {
        if (!g_prog[i].used) continue;
        uint16 ln = g_prog[i].line_no;
        if (ln > last_line && ln < best) {
            best = ln;
            best_i = i;
            found = 1;
        }
    }

    if (!found) return 0;
    *out_line = best;
    *out_idx = best_i;
    return 1;
}

static void basic_store_line(uint16 line_no, const char *rest) {
    // rest: nach der Zeilennummer (inkl. leading spaces)
    // Wenn rest leer -> löschen
    const char *p = rest;
    skip_spaces(&p);

    int idx = find_line_index(line_no);

    if (*p == 0) {
        if (idx >= 0) g_prog[idx].used = 0;
        return;
    }

    if (idx < 0) {
        idx = find_free_slot();
        if (idx < 0) {
            print_new_line();
            print_string("BASIC: OUT OF PROGRAM SPACE");
            return;
        }
        g_prog[idx].used = 1;
        g_prog[idx].line_no = line_no;
    }

    // copy text, uppercase keywords funktionieren trotzdem case-insensitive
    int j = 0;
    while (*p && j < BASIC_LINE_LEN - 1) {
        g_prog[idx].text[j++] = *p++;
    }
    g_prog[idx].text[j] = 0;
}

static void basic_list(void) {
    uint16 last = 0;
    uint16 ln;
    int idx;

    while (find_next_line_sorted(last, &ln, &idx)) {
        print_new_line();
        print_int((int)ln);
        print_string(" ");
        print_string(g_prog[idx].text);
        last = ln;
    }
}

static void basic_error(const char *msg) {
    print_new_line();
    print_string("BASIC ERROR: ");
    print_string((char*)msg);
}

// ---------- Expression parser (recursive descent) ----------
static int parse_expr(const char **p); // forward

static int parse_factor(const char **p) {
    skip_spaces(p);

    // unary
    if (**p == '+') { (*p)++; return parse_factor(p); }
    if (**p == '-') { (*p)++; return -parse_factor(p); }

    if (**p == '(') {
        (*p)++;
        int v = parse_expr(p);
        skip_spaces(p);
        if (**p == ')') (*p)++;
        else basic_error("MISSING )");
        return v;
    }

    // variable
    if (is_alpha(**p)) {
        char c = up(**p);
        (*p)++;
        if (c >= 'A' && c <= 'Z') return g_vars[c - 'A'];
        return 0;
    }

    // number
    if (is_digit(**p)) {
        return parse_int(p);
    }

    basic_error("BAD FACTOR");
    return 0;
}

static int parse_term(const char **p) {
    int v = parse_factor(p);
    for (;;) {
        skip_spaces(p);
        if (**p == '*') { (*p)++; v = v * parse_factor(p); }
        else if (**p == '/') {
            (*p)++;
            int d = parse_factor(p);
            if (d == 0) { basic_error("DIV BY ZERO"); return 0; }
            v = v / d;
        } else break;
    }
    return v;
}

static int parse_expr(const char **p) {
    int v = parse_term(p);
    for (;;) {
        skip_spaces(p);
        if (**p == '+') { (*p)++; v = v + parse_term(p); }
        else if (**p == '-') { (*p)++; v = v - parse_term(p); }
        else break;
    }
    return v;
}

static int parse_relop(const char **p, const char **out_op) {
    skip_spaces(p);
    // supported: =, <, >, <=, >=, <>
    if (**p == '=') { *out_op = "="; (*p)++; return 1; }
    if (**p == '<') {
        (*p)++;
        if (**p == '=') { *out_op = "<="; (*p)++; return 1; }
        if (**p == '>') { *out_op = "<>"; (*p)++; return 1; }
        *out_op = "<"; return 1;
    }
    if (**p == '>') {
        (*p)++;
        if (**p == '=') { *out_op = ">="; (*p)++; return 1; }
        *out_op = ">"; return 1;
    }
    return 0;
}

static int eval_relation(int a, int b, const char *op) {
    if (op[0] == '=' && op[1] == 0) return a == b;
    if (op[0] == '<' && op[1] == 0) return a < b;
    if (op[0] == '>' && op[1] == 0) return a > b;
    if (op[0] == '<' && op[1] == '=') return a <= b;
    if (op[0] == '>' && op[1] == '=') return a >= b;
    if (op[0] == '<' && op[1] == '>') return a != b;
    return 0;
}

// ---------- Statement execution ----------
static int basic_exec_stmt(const char *line, uint16 *pc_line /*in/out*/, int *stop /*out*/) {
    const char *p = line;
    skip_spaces(&p);

    if (*p == 0) return 1;

    // REM
    if (starts_with_kw(p, "REM")) return 1;

    // END
    if (starts_with_kw(p, "END")) { *stop = 1; return 1; }

    // PRINT
    if (starts_with_kw(p, "PRINT")) {
        p += 5;
        skip_spaces(&p);

        // PRINT "TEXT"
        if (*p == '"') {
            p++;
            print_new_line();
            while (*p && *p != '"') {
                print_char(*p++);
            }
            if (*p == '"') p++;
            return 1;
        }

        // PRINT expr
        int v = parse_expr(&p);
        print_new_line();
        print_int(v);
        return 1;
    }

    // LET (optional)
    if (starts_with_kw(p, "LET")) {
        p += 3;
        skip_spaces(&p);
    }

    // IF expr rel expr THEN line
    if (starts_with_kw(p, "IF")) {
        p += 2;
        int left = parse_expr(&p);

        const char *op = 0;
        if (!parse_relop(&p, &op)) { basic_error("IF NEEDS RELOP"); return 0; }

        int right = parse_expr(&p);

        skip_spaces(&p);
        if (!starts_with_kw(p, "THEN")) { basic_error("IF NEEDS THEN"); return 0; }
        p += 4;

        uint16 target = parse_u16(&p);
        if (target == 0) { basic_error("BAD THEN LINE"); return 0; }

        if (eval_relation(left, right, op)) {
            *pc_line = (uint16)(target - 1); // Trick: RUN loop nimmt "next > pc_line"
        }
        return 1;
    }

    // GOTO line
    if (starts_with_kw(p, "GOTO")) {
        p += 4;
        uint16 target = parse_u16(&p);
        if (target == 0) { basic_error("BAD GOTO LINE"); return 0; }
        *pc_line = (uint16)(target - 1);
        return 1;
    }

    // Assignment: A = expr
    if (is_alpha(*p)) {
        char vname = up(*p++);
        if (vname < 'A' || vname > 'Z') { basic_error("BAD VAR"); return 0; }
        skip_spaces(&p);
        if (*p != '=') { basic_error("EXPECTED ="); return 0; }
        p++;
        int value = parse_expr(&p);
        g_vars[vname - 'A'] = value;
        return 1;
    }

    basic_error("UNKNOWN STATEMENT");
    return 0;
}

static void basic_run(void) {
    uint16 pc = 0;         // last executed line_no (for sorted iteration)
    int stop = 0;

    // Start at "before" first line:
    pc = 0;

    while (!stop) {
        uint16 ln;
        int idx;
        if (!find_next_line_sorted(pc, &ln, &idx)) break;

        // execute
        uint16 pc_before = ln;
        uint16 pc_line = ln;
        basic_exec_stmt(g_prog[idx].text, &pc_line, &stop);

        // pc_line may be changed by GOTO/IF
        pc = pc_line;

        // normal case: move to next after current
        if (pc == pc_before) pc = ln;
    }
}

// ---------- REPL line handler ----------
static void basic_repl_line(const char *input) {
    const char *p = input;
    skip_spaces(&p);
    if (*p == 0) return;

    // line starts with number? -> program line
    if (is_digit(*p)) {
        uint16 ln = parse_u16(&p);
        basic_store_line(ln, p);
        return;
    }

    // Immediate commands
    if (starts_with_kw(p, "LIST")) { basic_list(); return; }
    if (starts_with_kw(p, "RUN"))  { basic_run(); return; }
    if (starts_with_kw(p, "NEW"))  { basic_reset_program(); basic_reset_vars(); print_new_line(); print_string("OK"); return; }

    // keep your old shell commands too:
    if (starts_with_kw(p, "HELP")) {
        print_new_line();
        print_string("Available commands:");
        print_new_line();
        print_string("  HELP   - Prints this help");
        print_new_line();
        print_string("  REBOOT - Reboot the system");
        print_new_line();
        print_string("  NEW    - Clear BASIC program + vars");
        print_new_line();
        print_string("  LIST   - List BASIC program");
        print_new_line();
        print_string("  RUN    - Run BASIC program");
        print_new_line();
        print_string("BASIC examples:");
        print_new_line();
        print_string("  10 A=1+2*3");
        print_new_line();
        print_string("  20 PRINT A");
        print_new_line();
        print_string("  30 IF A=7 THEN 50");
        print_new_line();
        print_string("  40 GOTO 20");
        print_new_line();
        print_string("  50 END");
        return;
    }

    if (starts_with_kw(p, "REBOOT")) { do_reboot(); return; }

    // Otherwise: treat as immediate BASIC statement (PRINT/LET/A=.../IF/GOTO/END)
    uint16 dummy = 0;
    int stop = 0;
    basic_exec_stmt(p, &dummy, &stop);
}

Hallo Besucher! Willkommen in diesem kleinen Wiki rund um IT. Vieles ist noch unvollständig, unstrukturiert oder vielleicht sogar falsch bzw. irreführend.

Du kannst Artikel gerne ergänzen oder verbessern. Gerne mit so vielen Links wie nötig. Bitte keine Werbelinks und nur selbst verfasste oder lizenzfreie Texte! Copyright beachten!

Fehlende Verlinkungen

Eine Liste von Seiten die noch erstellt werden müssen.

# ID Links
1turn3 : Show backlinks
2a_stern_algorithmus3 : Show backlinks
3xml3 : Show backlinks
4netzwerkkarte2 : Show backlinks
5chef2 : Show backlinks
6bellman_ford_algorithmus2 : Show backlinks
7graylog2 : Show backlinks
8https2 : Show backlinks
9saslauthd2 : Show backlinks
10unix1 : Show backlinks
11tshark1 : Show backlinks
12ssd1 : Show backlinks
13networkd1 : Show backlinks
14srtp1 : Show backlinks
153des1 : Show backlinks
16sips1 : Show backlinks
17soundkarte1 : Show backlinks
18iax21 : Show backlinks
19breitensuche1 : Show backlinks
20hub1 : Show backlinks
21rpc1 : Show backlinks
22ice1 : Show backlinks
23creddump71 : Show backlinks
24eaphammer1 : Show backlinks
25prioritaetswarteschlange1 : Show backlinks
26webrtc1 : Show backlinks
27vnc1 : Show backlinks
28pcie1 : Show backlinks
29graphentheorie1 : Show backlinks
30ddos1 : Show backlinks
31sata1 : Show backlinks
32wifite1 : Show backlinks
33vmfs1 : Show backlinks
34courier1 : Show backlinks
35freepbx1 : Show backlinks
36realmd1 : Show backlinks
37base641 : Show backlinks
38pjsip1 : Show backlinks
39sctp1 : Show backlinks
40cuda1 : Show backlinks
41dnscat21 : Show backlinks
42dnsrecon1 : Show backlinks
43nvme1 : Show backlinks
44playground:playground1 : Show backlinks
45kuerzeste_wege1 : Show backlinks
46fierce1 : Show backlinks
47sendmail1 : Show backlinks
48iscsitarget1 : Show backlinks
49mailx1 : Show backlinks
50wpa31 : Show backlinks
51oakley1 : Show backlinks
start.1765039591.txt.gz · Zuletzt geändert: 2025/12/06 17:46 von jango