wok rev 25624

Add opendkim
author Pascal Bellard <pascal.bellard@slitaz.org>
date Wed Nov 08 16:45:57 2023 +0000 (5 months ago)
parents b5e0b1f0276d
children 114eed575c11
files emu2/receipt emu2/stuff/video.c opendkim-dev/receipt opendkim/receipt openvpn/stuff/usr/bin/make-ovpn zx0/receipt
line diff
     1.1 --- a/emu2/receipt	Fri Sep 29 10:56:02 2023 +0100
     1.2 +++ b/emu2/receipt	Wed Nov 08 16:45:57 2023 +0000
     1.3 @@ -23,6 +23,7 @@
     1.4  # Rules to configure and make the package.
     1.5  compile_rules()
     1.6  {
     1.7 +	cp $stuff/* src
     1.8  	mkdir obj
     1.9  	make CC=gcc-83 DESTDIR=$DESTDIR install
    1.10  }
     2.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.2 +++ b/emu2/stuff/video.c	Wed Nov 08 16:45:57 2023 +0000
     2.3 @@ -0,0 +1,751 @@
     2.4 +#include "video.h"
     2.5 +#include "codepage.h"
     2.6 +#include "dbg.h"
     2.7 +#include "emu.h"
     2.8 +
     2.9 +#include <errno.h>
    2.10 +#include <fcntl.h>
    2.11 +#include <stdio.h>
    2.12 +#include <stdlib.h>
    2.13 +#include <string.h>
    2.14 +#include <sys/ioctl.h>
    2.15 +#include <termios.h>
    2.16 +#include <unistd.h>
    2.17 +
    2.18 +// Simulated character screen.
    2.19 +// This is a copy of the currently displayed output in the terminal window.
    2.20 +// We have a max of 128 rows of up to 256 columns, total of 32KB.
    2.21 +static uint16_t term_screen[64][256];
    2.22 +// Current line in output, lines bellow this are not currently displayed.
    2.23 +// This allows using only part of the terminal.
    2.24 +static int output_row;
    2.25 +// Current cursor row/column position in the terminal.
    2.26 +static unsigned term_posx, term_posy, term_color, term_cursor;
    2.27 +// Current terminal sizes
    2.28 +static unsigned term_sx, term_sy;
    2.29 +// Current emulated video sizes and cursor position
    2.30 +static unsigned vid_posx[8], vid_posy[8], vid_cursor;
    2.31 +static unsigned vid_sx, vid_sy, vid_color, vid_page;
    2.32 +static unsigned vid_font_lines, vid_no_blank;
    2.33 +// Signals that the terminal size needs updating
    2.34 +static volatile int term_needs_update;
    2.35 +// Terminal FD, allows video output even with redirection.
    2.36 +static FILE *tty_file;
    2.37 +// Video is already initialized
    2.38 +static int video_initialized;
    2.39 +
    2.40 +// Forward
    2.41 +static void term_goto_xy(unsigned x, unsigned y);
    2.42 +
    2.43 +// Signal handler - terminal size changed
    2.44 +// TODO: not used yet.
    2.45 +#if 0
    2.46 +static void sigwinch_handler(int sig)
    2.47 +{
    2.48 +    //    term_needs_upodate = 1;
    2.49 +}
    2.50 +#endif
    2.51 +
    2.52 +static void term_get_size(void)
    2.53 +{
    2.54 +    struct winsize ws;
    2.55 +    if(ioctl(fileno(tty_file), TIOCGWINSZ, &ws) != -1)
    2.56 +    {
    2.57 +        // TODO: perhaps restrict to "known" values
    2.58 +        term_sx = ws.ws_col;
    2.59 +        term_sy = ws.ws_row;
    2.60 +        if(term_sx < 40)
    2.61 +            term_sx = 40;
    2.62 +        else if(term_sx > 240)
    2.63 +            term_sx = 240;
    2.64 +        if(term_sy < 25)
    2.65 +            term_sy = 25;
    2.66 +        else if(term_sy > 64)
    2.67 +            term_sy = 64;
    2.68 +    }
    2.69 +    else
    2.70 +    {
    2.71 +        term_sx = 80;
    2.72 +        term_sy = 25;
    2.73 +    }
    2.74 +}
    2.75 +
    2.76 +// Update posx/posy in BIOS memory
    2.77 +static void update_posxy(void)
    2.78 +{
    2.79 +    int vid_size = vid_sy > 25 ? 0x20 : 0x10;
    2.80 +    memory[0x44C] = 0x00;
    2.81 +    memory[0x44D] = vid_size;
    2.82 +    memory[0x44E] = 0x00;
    2.83 +    memory[0x44F] = (vid_size * vid_page) & 0x7F;
    2.84 +    for(int i = 0; i < 8; i++)
    2.85 +    {
    2.86 +        memory[0x450 + i * 2] = vid_posx[i];
    2.87 +        memory[0x451 + i * 2] = vid_posy[i];
    2.88 +    }
    2.89 +    memory[0x462] = vid_page;
    2.90 +}
    2.91 +
    2.92 +// Clears the terminal data - not the actual terminal screen
    2.93 +static void clear_terminal(void)
    2.94 +{
    2.95 +    debug(debug_video, "clear terminal shadow\n");
    2.96 +    // Clear screen terminal:
    2.97 +    for(int y = 0; y < 64; y++)
    2.98 +        for(int x = 0; x < 256; x++)
    2.99 +            term_screen[y][x] = 0x0720;
   2.100 +    output_row = -1;
   2.101 +    term_posx = 0;
   2.102 +    term_posy = 0;
   2.103 +    // Get current terminal size
   2.104 +    term_get_size();
   2.105 +    putc('\r', tty_file); // Go to column 0
   2.106 +}
   2.107 +
   2.108 +static void set_text_mode(int clear, int sx, int sy)
   2.109 +{
   2.110 +    debug(debug_video, "set text mode%s\n", clear ? " and clear" : "");
   2.111 +    // Clear video screen
   2.112 +    if(clear)
   2.113 +    {
   2.114 +        uint16_t *vm = (uint16_t *)(memory + 0xB8000);
   2.115 +        for(int i = 0; i < 16384; i++)
   2.116 +            vm[i] = 0x0720;
   2.117 +    }
   2.118 +    for(int i = 0; i < 8; i++)
   2.119 +    {
   2.120 +        vid_posx[i] = 0;
   2.121 +        vid_posy[i] = 0;
   2.122 +    }
   2.123 +    vid_page = 0;
   2.124 +    vid_color = 0x07;
   2.125 +    vid_cursor = 1;
   2.126 +    // TODO: support other video modes
   2.127 +    vid_sx = sx;
   2.128 +    vid_sy = sy;
   2.129 +    vid_font_lines = 16;
   2.130 +    memory[0x449] = 0x03; // video mode
   2.131 +    memory[0x44A] = vid_sx;
   2.132 +    memory[0x484] = vid_sy - 1;
   2.133 +    update_posxy();
   2.134 +}
   2.135 +
   2.136 +static unsigned get_last_used_row(void)
   2.137 +{
   2.138 +    unsigned max = 0;
   2.139 +    for(unsigned y = 0; y < vid_sy; y++)
   2.140 +        for(unsigned x = 0; x < vid_sx; x++)
   2.141 +            if(term_screen[y][x] != 0x700 && term_screen[y][x] != 0x720)
   2.142 +                max = y + 1;
   2.143 +    return max;
   2.144 +}
   2.145 +
   2.146 +static void exit_video(void)
   2.147 +{
   2.148 +    vid_cursor = 1;
   2.149 +    check_screen();
   2.150 +    unsigned max = get_last_used_row();
   2.151 +    term_goto_xy(0, max);
   2.152 +    fputs("\x1b[m", tty_file);
   2.153 +    fclose(tty_file);
   2.154 +    debug(debug_video, "exit video - row %d\n", max);
   2.155 +}
   2.156 +
   2.157 +static void init_video(void)
   2.158 +{
   2.159 +    debug(debug_video, "starting video emulation.\n");
   2.160 +    int tty_fd = open("/dev/tty", O_NOCTTY | O_WRONLY);
   2.161 +    if(tty_fd < 0)
   2.162 +    {
   2.163 +        print_error("error at open TTY, %s\n", strerror(errno));
   2.164 +        exit(1);
   2.165 +    }
   2.166 +    tty_file = fdopen(tty_fd, "w");
   2.167 +    atexit(exit_video);
   2.168 +    video_initialized = 1;
   2.169 +
   2.170 +    // Fill the functionality table
   2.171 +    memory[0xC0100] = 0x08; // Only mode 3 supported
   2.172 +    memory[0xC0101] = 0x00;
   2.173 +    memory[0xC0102] = 0x00;
   2.174 +    memory[0xC0107] = 0x07; // Support 300, 350 and 400 scanlines
   2.175 +    memory[0xC0108] = 0x00; // Active character blocks?
   2.176 +    memory[0xC0109] = 0x00; // MAximum character blocks?
   2.177 +    memory[0xC0108] = 0xFF; // Support functions
   2.178 +
   2.179 +    // Set video mode
   2.180 +    set_text_mode(1, 80, 25);
   2.181 +    clear_terminal();
   2.182 +    term_needs_update = 0;
   2.183 +    term_cursor = 1;
   2.184 +    term_color = 0x07;
   2.185 +}
   2.186 +
   2.187 +int video_active(void)
   2.188 +{
   2.189 +    return video_initialized;
   2.190 +}
   2.191 +
   2.192 +static void set_color(uint8_t c)
   2.193 +{
   2.194 +    if(term_color != c)
   2.195 +    {
   2.196 +        static char cn[8] = "04261537";
   2.197 +        fprintf(tty_file, (c & 0x80) ? "\x1b[%c;9%c;10%cm" : "\x1b[%c;3%c;4%cm", (c & 0x08) ? '1' : '0', cn[c & 7],
   2.198 +                cn[(c >> 4) & 7]);
   2.199 +        term_color = c;
   2.200 +    }
   2.201 +}
   2.202 +
   2.203 +// Writes a DOS character to the current terminal position
   2.204 +static void put_vc(uint8_t c)
   2.205 +{
   2.206 +    uint16_t uc = get_unicode(c);
   2.207 +    if(uc < 128)
   2.208 +        putc(uc, tty_file);
   2.209 +    else if(uc < 0x800)
   2.210 +    {
   2.211 +        putc(0xC0 | (uc >> 6), tty_file);
   2.212 +        putc(0x80 | (uc & 0x3F), tty_file);
   2.213 +    }
   2.214 +    else
   2.215 +    {
   2.216 +        putc(0xE0 | (uc >> 12), tty_file);
   2.217 +        putc(0x80 | ((uc >> 6) & 0x3F), tty_file);
   2.218 +        putc(0x80 | (uc & 0x3F), tty_file);
   2.219 +    }
   2.220 +}
   2.221 +
   2.222 +// Move terminal cursor to the position
   2.223 +static void term_goto_xy(unsigned x, unsigned y)
   2.224 +{
   2.225 +    if(term_posy < y && (int)term_posy < output_row)
   2.226 +    {
   2.227 +        int inc = (int)y < output_row ? y - term_posy : output_row - term_posy;
   2.228 +        fprintf(tty_file, "\x1b[%dB", inc);
   2.229 +        term_posy += inc;
   2.230 +    }
   2.231 +    if(term_posy < y)
   2.232 +    {
   2.233 +        putc('\r', tty_file);
   2.234 +        // Set background color to black, as some terminals insert lines with
   2.235 +        // the current background color.
   2.236 +        set_color(term_color & 0x0F);
   2.237 +        // TODO: Draw new line with background color from video screen
   2.238 +        for(unsigned i = term_posy; i < y; i++)
   2.239 +            putc('\n', tty_file);
   2.240 +        term_posx = 0;
   2.241 +        term_posy = y;
   2.242 +    }
   2.243 +    if(term_posy > y)
   2.244 +    {
   2.245 +        fprintf(tty_file, "\x1b[%dA", term_posy - y);
   2.246 +        term_posy = y;
   2.247 +    }
   2.248 +    if(x == 0 && term_posx != 0)
   2.249 +    {
   2.250 +        putc('\r', tty_file);
   2.251 +        term_posx = 0;
   2.252 +    }
   2.253 +    if(term_posx < x)
   2.254 +    {
   2.255 +        fprintf(tty_file, "\x1b[%dC", x - term_posx);
   2.256 +        term_posx = x;
   2.257 +    }
   2.258 +    if(term_posx > x)
   2.259 +    {
   2.260 +        fprintf(tty_file, "\x1b[%dD", term_posx - x);
   2.261 +        term_posx = x;
   2.262 +    }
   2.263 +}
   2.264 +
   2.265 +// Outputs a character with the given attributes at the given position
   2.266 +static void put_vc_xy(uint8_t vc, uint8_t color, unsigned x, unsigned y)
   2.267 +{
   2.268 +    term_goto_xy(x, y);
   2.269 +    set_color(color);
   2.270 +
   2.271 +    put_vc(vc);
   2.272 +    term_posx++;
   2.273 +    if(term_posx >= term_sx)
   2.274 +    {
   2.275 +        term_posx = 0;
   2.276 +        term_posy++;
   2.277 +    }
   2.278 +
   2.279 +    if(output_row < (int)term_posy)
   2.280 +        output_row = term_posy;
   2.281 +}
   2.282 +
   2.283 +// Compares current screen with memory data
   2.284 +void check_screen(void)
   2.285 +{
   2.286 +    // Exit if not in video mode
   2.287 +    if(!video_initialized)
   2.288 +        return;
   2.289 +
   2.290 +    uint16_t memp = (vid_page & 7) * (vid_sy > 25 ? 0x2000 : 0x1000);
   2.291 +    uint16_t *vm = (uint16_t *)(memory + 0xB8000 + memp);
   2.292 +    unsigned max = output_row + 1;
   2.293 +    for(unsigned y = output_row + 1; y < vid_sy; y++)
   2.294 +        for(unsigned x = 0; x < vid_sx; x++)
   2.295 +            if(vm[x + y * vid_sx] != term_screen[y][x])
   2.296 +                max = y + 1;
   2.297 +
   2.298 +    for(unsigned y = 0; y < max; y++)
   2.299 +        for(unsigned x = 0; x < vid_sx; x++)
   2.300 +        {
   2.301 +            int16_t vc = vm[x + y * vid_sx];
   2.302 +            if(vc != term_screen[y][x])
   2.303 +            {
   2.304 +                // Output character
   2.305 +                term_screen[y][x] = vc;
   2.306 +                put_vc_xy(vc & 0xFF, vc >> 8, x, y);
   2.307 +            }
   2.308 +        }
   2.309 +    if(term_cursor != vid_cursor)
   2.310 +    {
   2.311 +        term_cursor = vid_cursor;
   2.312 +        if(vid_cursor)
   2.313 +            fputs("\x1b[?25h", tty_file);
   2.314 +        else
   2.315 +            fputs("\x1b[?25l", tty_file);
   2.316 +    }
   2.317 +    if(term_cursor)
   2.318 +        // Move cursor
   2.319 +        term_goto_xy(vid_posx[vid_page], vid_posy[vid_page]);
   2.320 +    fflush(tty_file);
   2.321 +}
   2.322 +
   2.323 +static void vid_scroll_up(uint8_t x0, uint8_t y0, uint8_t x1, uint8_t y1, int n,
   2.324 +                          int page)
   2.325 +{
   2.326 +    debug(debug_video, "scroll up %d: (%d, %d) - (%d, %d)\n", n, x0, y0, x1, y1);
   2.327 +
   2.328 +    // Check parameters
   2.329 +    if(x1 >= vid_sx)
   2.330 +        x1 = vid_sx - 1;
   2.331 +    if(y1 >= vid_sy)
   2.332 +        y1 = vid_sy - 1;
   2.333 +    if(y0 > y1 || x0 > x1)
   2.334 +        return;
   2.335 +    if(n > y1 - y0 + 1 || !n)
   2.336 +        n = y1 + 1 - y0;
   2.337 +
   2.338 +    // Scroll TERMINAL if we are scrolling (almost) the entire screen
   2.339 +    if(y0 == 0 && y1 >= vid_sy - 2 && x0 < 2 && x1 >= vid_sx - 2)
   2.340 +    {
   2.341 +        // Update screen before
   2.342 +        check_screen();
   2.343 +        int m = n > output_row + 1 ? output_row + 1 : n;
   2.344 +        if(term_posy < m)
   2.345 +            term_goto_xy(0, m);
   2.346 +        output_row -= m;
   2.347 +        term_posy -= m;
   2.348 +        for(unsigned y = 0; y + m < term_sy; y++)
   2.349 +            for(unsigned x = 0; x < term_sx; x++)
   2.350 +                term_screen[y][x] = term_screen[y + m][x];
   2.351 +        for(unsigned y = term_sy - m; y < term_sy; y++)
   2.352 +            for(unsigned x = 0; x < term_sx; x++)
   2.353 +                term_screen[y][x] = 0x0720;
   2.354 +    }
   2.355 +
   2.356 +    // Scroll VIDEO
   2.357 +    uint16_t memp = (page & 7) * (vid_sy > 25 ? 0x2000 : 0x1000);
   2.358 +    uint16_t *vm = (uint16_t *)(memory + 0xB8000 + memp);
   2.359 +    for(unsigned y = y0; y + n <= y1; y++)
   2.360 +        for(unsigned x = x0; x <= x1; x++)
   2.361 +            vm[x + y * vid_sx] = vm[x + y * vid_sx + n * vid_sx];
   2.362 +    // Set last rows
   2.363 +    for(unsigned y = y1 - (n - 1); y <= y1; y++)
   2.364 +        for(unsigned x = x0; x <= x1; x++)
   2.365 +            vm[x + y * vid_sx] = (vid_color << 8) + 0x20;
   2.366 +}
   2.367 +
   2.368 +static void vid_scroll_dwn(uint8_t x0, uint8_t y0, uint8_t x1, uint8_t y1, unsigned n,
   2.369 +                           int page)
   2.370 +{
   2.371 +    debug(debug_video, "scroll down %d: (%d, %d) - (%d, %d)\n", n, x0, y0, x1, y1);
   2.372 +
   2.373 +    // Check parameters
   2.374 +    if(x1 >= vid_sx)
   2.375 +        x1 = vid_sx - 1;
   2.376 +    if(y1 >= vid_sy)
   2.377 +        y1 = vid_sy - 1;
   2.378 +    if(y0 > y1 || x0 > x1)
   2.379 +        return;
   2.380 +    if(n > y1 - y0 + 1 || !n)
   2.381 +        n = y1 + 1 - y0;
   2.382 +
   2.383 +    // TODO: try to scroll TERMINAL
   2.384 +
   2.385 +    // Scroll VIDEO
   2.386 +    uint16_t memp = (page & 7) * (vid_sy > 25 ? 0x2000 : 0x1000);
   2.387 +    uint16_t *vm = (uint16_t *)(memory + 0xB8000 + memp);
   2.388 +    for(unsigned y = y1; y >= y0 + n; y--)
   2.389 +        for(unsigned x = x0; x <= x1; x++)
   2.390 +            vm[x + y * vid_sx] = vm[x + y * vid_sx - n * vid_sx];
   2.391 +    // Set first rows
   2.392 +    for(unsigned y = y0; y < y0 + n; y++)
   2.393 +        for(unsigned x = x0; x <= x1; x++)
   2.394 +            vm[x + y * vid_sx] = (vid_color << 8) + 0x20;
   2.395 +}
   2.396 +
   2.397 +static void set_xy(unsigned x, unsigned y, uint16_t c, uint16_t mask, int page)
   2.398 +{
   2.399 +    uint16_t mem = (page & 7) * (vid_sy > 25 ? 0x2000 : 0x1000);
   2.400 +    uint16_t *vm = (uint16_t *)(memory + 0xB8000 + mem);
   2.401 +    vm[x + y * vid_sx] = (vm[x + y * vid_sx] & mask) | c;
   2.402 +}
   2.403 +
   2.404 +static uint16_t get_xy(unsigned x, unsigned y, int page)
   2.405 +{
   2.406 +    uint16_t mem = (page & 7) * (vid_sy > 25 ? 0x2000 : 0x1000);
   2.407 +    uint16_t *vm = (uint16_t *)(memory + 0xB8000 + mem);
   2.408 +    return vm[x + y * vid_sx];
   2.409 +}
   2.410 +
   2.411 +static void video_putchar(uint8_t ch, uint16_t at, int page)
   2.412 +{
   2.413 +    page = page & 7;
   2.414 +    if(ch == 0x0A)
   2.415 +    {
   2.416 +        vid_posy[page]++;
   2.417 +        while(vid_posy[page] >= vid_sy)
   2.418 +        {
   2.419 +            vid_posy[page] = vid_sy - 1;
   2.420 +            vid_scroll_up(0, 0, vid_sx - 1, vid_sy - 1, 1, page);
   2.421 +        }
   2.422 +    }
   2.423 +    else if(ch == 0x0D)
   2.424 +        vid_posx[page] = 0;
   2.425 +    else if(ch == 0x08)
   2.426 +    {
   2.427 +        if(vid_posx[page] > 0)
   2.428 +            vid_posx[page]--;
   2.429 +    }
   2.430 +    else
   2.431 +    {
   2.432 +        if(at & 0xFFFF)
   2.433 +            set_xy(vid_posx[page], vid_posy[page], ch, 0xFF00, page);
   2.434 +        else
   2.435 +            set_xy(vid_posx[page], vid_posy[page], ch + (at << 8), 0, page);
   2.436 +        vid_posx[page]++;
   2.437 +        if(vid_posx[page] >= vid_sx)
   2.438 +        {
   2.439 +            vid_posx[page] = 0;
   2.440 +            vid_posy[page]++;
   2.441 +            while(vid_posy[page] >= vid_sy)
   2.442 +            {
   2.443 +                vid_posy[page] = vid_sy - 1;
   2.444 +                vid_scroll_up(0, 0, vid_sx - 1, vid_sy - 1, 1, page);
   2.445 +            }
   2.446 +        }
   2.447 +    }
   2.448 +    update_posxy();
   2.449 +}
   2.450 +
   2.451 +void video_putch(char ch)
   2.452 +{
   2.453 +    debug(debug_video, "putchar %02x at (%d,%d)\n", ch & 0xFF, vid_posx[vid_page],
   2.454 +          vid_posy[vid_page]);
   2.455 +    video_putchar(ch, 0xFF00, vid_page);
   2.456 +}
   2.457 +
   2.458 +// VIDEO int
   2.459 +void int10()
   2.460 +{
   2.461 +    debug(debug_int, "V-10%04X: BX=%04X\n", cpuGetAX(), cpuGetBX());
   2.462 +    debug(debug_video, "V-10%04X: BX=%04X\n", cpuGetAX(), cpuGetBX());
   2.463 +    if(!video_initialized)
   2.464 +        init_video();
   2.465 +    unsigned ax = cpuGetAX();
   2.466 +    switch(ax >> 8)
   2.467 +    {
   2.468 +    case 0x00: // SET VIDEO MODE
   2.469 +        if((ax & 0x7F) > 3)
   2.470 +            debug(debug_video, "-> SET GRAPHICS MODE %x<-\n", ax & 0xFF);
   2.471 +        else
   2.472 +        {
   2.473 +            set_text_mode((ax & 0x80) == 0, (ax < 2) ? 40 : 80, 25);
   2.474 +            vid_no_blank = ax & 0x80;
   2.475 +        }
   2.476 +        break;
   2.477 +    case 0x01:                              // SET CURSOR SHAPE
   2.478 +        if((cpuGetCX() & 0x6000) == 0x2000) // Hide cursor
   2.479 +            vid_cursor = 0;
   2.480 +        else
   2.481 +            vid_cursor = 1;
   2.482 +        break;
   2.483 +    case 0x02: // SET CURSOR POS
   2.484 +    {
   2.485 +        int page = (cpuGetBX() >> 8) & 7;
   2.486 +        vid_posx[page] = cpuGetDX() & 0xFF;
   2.487 +        vid_posy[page] = cpuGetDX() >> 8;
   2.488 +        if(vid_posx[page] >= vid_sx)
   2.489 +            vid_posx[page] = vid_sx - 1;
   2.490 +        if(vid_posy[page] >= vid_sy)
   2.491 +            vid_posy[page] = vid_sy - 1;
   2.492 +        update_posxy();
   2.493 +        break;
   2.494 +    }
   2.495 +    case 0x03: // GET CURSOR POS
   2.496 +    {
   2.497 +        int page = (cpuGetBX() >> 8) & 7;
   2.498 +        cpuSetDX(vid_posx[page] + (vid_posy[page] << 8));
   2.499 +        cpuSetCX(0x0010);
   2.500 +        break;
   2.501 +    }
   2.502 +    case 0x05: // SELECT DISPLAY PAGE
   2.503 +        if((ax & 0xFF) > 7)
   2.504 +            debug(debug_video, "WARN: Select display page > 7!\n");
   2.505 +        else
   2.506 +        {
   2.507 +            vid_page = ax & 7;
   2.508 +            update_posxy();
   2.509 +        }
   2.510 +        break;
   2.511 +    case 0x06: // SCROLL UP WINDOW
   2.512 +    {
   2.513 +        uint16_t cx = cpuGetCX(), dx = cpuGetDX();
   2.514 +        vid_color = cpuGetBX() >> 8;
   2.515 +        vid_scroll_up(cx, cx >> 8, dx, dx >> 8, ax & 0xFF, vid_page);
   2.516 +        break;
   2.517 +    }
   2.518 +    case 0x07: // SCROLL DOWN WINDOW
   2.519 +    {
   2.520 +        uint16_t cx = cpuGetCX(), dx = cpuGetDX();
   2.521 +        vid_color = cpuGetBX() >> 8;
   2.522 +        vid_scroll_dwn(cx, cx >> 8, dx, dx >> 8, ax & 0xFF, vid_page);
   2.523 +        break;
   2.524 +    }
   2.525 +    case 0x08: // READ CHAR AT CURSOR
   2.526 +    {
   2.527 +        int page = (cpuGetBX() >> 8) & 7;
   2.528 +        cpuSetAX(get_xy(vid_posx[page], vid_posy[page], page));
   2.529 +        break;
   2.530 +    }
   2.531 +    case 0x09: // WRITE CHAR AT CURSOR
   2.532 +    case 0x0A: // WRITE CHAR ONLY AT CURSOR
   2.533 +    {
   2.534 +        int page = (cpuGetBX() >> 8) & 7;
   2.535 +        uint16_t px = vid_posx[page];
   2.536 +        uint16_t py = vid_posy[page];
   2.537 +        uint16_t mask = (ax & 0x0100) ? 0 : 0xFF00;
   2.538 +        uint16_t ch = ((ax & 0xFF) | (cpuGetBX() << 8)) & ~mask;
   2.539 +        for(int i = cpuGetCX(); i > 0; i--)
   2.540 +        {
   2.541 +            set_xy(px, py, ch, mask, page);
   2.542 +            px++;
   2.543 +            if(px >= vid_sx)
   2.544 +            {
   2.545 +                px = 0;
   2.546 +                py++;
   2.547 +                if(py >= vid_sy)
   2.548 +                    py = 0;
   2.549 +            }
   2.550 +        }
   2.551 +        break;
   2.552 +    }
   2.553 +    case 0x0E: // TELETYPE OUTPUT
   2.554 +        video_putchar(ax, 0xFF00, (cpuGetBX() >> 8) & 7);
   2.555 +        break;
   2.556 +    case 0x0F: // GET CURRENT VIDEO MODE
   2.557 +        cpuSetAX((vid_sx << 8) | 0x0003 | vid_no_blank); // 80x25 mode
   2.558 +        cpuSetBX((vid_page << 8) | (0xFF & cpuGetBX()));
   2.559 +        break;
   2.560 +    case 0x10:
   2.561 +        if(ax == 0x1002) // TODO: Set pallete registers - ignore
   2.562 +            break;
   2.563 +        else if(ax == 0x1003) // TODO: Set blinking state
   2.564 +            break;
   2.565 +        debug(debug_video, "UNHANDLED INT 10, AX=%04x\n", ax);
   2.566 +        break;
   2.567 +    case 0x11:
   2.568 +        if(ax == 0x1130)
   2.569 +        {
   2.570 +            cpuSetDX((vid_sy - 1) & 0xFF);
   2.571 +            cpuSetCX(vid_font_lines);
   2.572 +        }
   2.573 +        else if(ax == 0x1104 || ax == 0x1111 || ax == 0x1114)
   2.574 +        {
   2.575 +            // Clear end-of-screen
   2.576 +            unsigned max = get_last_used_row();
   2.577 +            debug(debug_video, "set 25 lines mode %d\n", max);
   2.578 +            if(max > 25)
   2.579 +            {
   2.580 +                term_goto_xy(0, 24);
   2.581 +                set_color(0x07);
   2.582 +                fputs("\x1b[J", tty_file);
   2.583 +                for(int y = 25; y < 64; y++)
   2.584 +                    for(int x = 0; x < 256; x++)
   2.585 +                        term_screen[y][x] = 0x0720;
   2.586 +                if(output_row > 24)
   2.587 +                    output_row = 24;
   2.588 +            }
   2.589 +            // Set 8x16 font - 80x25 mode:
   2.590 +            vid_sy = 25;
   2.591 +            vid_font_lines = 16;
   2.592 +            memory[0x484] = vid_sy - 1;
   2.593 +            update_posxy();
   2.594 +        }
   2.595 +        else if(ax == 0x1102 || ax == 0x1112)
   2.596 +        {
   2.597 +            // Set 8x8 font - 80x43 or 80x50 mode:
   2.598 +            debug(debug_video, "set 43/50 lines mode\n");
   2.599 +            // Hack - QBASIC.EXE assumes that the mode is always 50 lines on VGA,
   2.600 +            // and *sets* the height into the BIOS area!
   2.601 +            if(memory[0x484] > 42)
   2.602 +                vid_sy = 50;
   2.603 +            else
   2.604 +                vid_sy = 43;
   2.605 +            vid_font_lines = 8;
   2.606 +            memory[0x484] = vid_sy - 1;
   2.607 +            update_posxy();
   2.608 +        }
   2.609 +        break;
   2.610 +    case 0x12: // ALT FUNCTION SELECT
   2.611 +    {
   2.612 +        int bl = cpuGetBX() & 0xFF;
   2.613 +        if(bl == 0x10) // GET EGA INFO
   2.614 +        {
   2.615 +            cpuSetBX(0x0003);
   2.616 +            cpuSetCX(0x0000);
   2.617 +            cpuSetAX(0);
   2.618 +        }
   2.619 +        else if(bl == 0x30) // SET VERTICAL RESOLUTION
   2.620 +        {
   2.621 +            // TODO: select 25/28 lines
   2.622 +            cpuSetAX(0x1212);
   2.623 +        }
   2.624 +        else
   2.625 +            debug(debug_video, "UNHANDLED INT 10, AH=12 BL=%02x\n", bl);
   2.626 +    }
   2.627 +    break;
   2.628 +    case 0x13: // WRITE STRING
   2.629 +    {
   2.630 +        int page = (cpuGetBX() >> 8) & 7;
   2.631 +        vid_posx[page] = cpuGetDX() & 0xFF;
   2.632 +        vid_posy[page] = cpuGetDX() >> 8;
   2.633 +        if(vid_posx[page] >= vid_sx)
   2.634 +            vid_posx[page] = vid_sx - 1;
   2.635 +        if(vid_posy[page] >= vid_sy)
   2.636 +            vid_posy[page] = vid_sy - 1;
   2.637 +        int save_posx = vid_posx[page];
   2.638 +        int save_posy = vid_posy[page];
   2.639 +        int addr = cpuGetAddrES(cpuGetBP());
   2.640 +        int cnt = cpuGetCX();
   2.641 +        if(ax & 2)
   2.642 +        {
   2.643 +            while(cnt && addr < 0xFFFFF)
   2.644 +            {
   2.645 +                video_putchar(memory[addr], memory[addr + 1], page);
   2.646 +                addr += 2;
   2.647 +                cnt--;
   2.648 +            }
   2.649 +        }
   2.650 +        else
   2.651 +        {
   2.652 +            uint8_t at = cpuGetBX() >> 8;
   2.653 +            while(cnt && addr <= 0xFFFFF)
   2.654 +            {
   2.655 +                video_putchar(memory[addr], at, page);
   2.656 +                addr++;
   2.657 +                cnt--;
   2.658 +            }
   2.659 +        }
   2.660 +        if(!(ax & 1))
   2.661 +        {
   2.662 +            vid_posx[page] = save_posx;
   2.663 +            vid_posy[page] = save_posy;
   2.664 +        }
   2.665 +        update_posxy();
   2.666 +    }
   2.667 +    break;
   2.668 +    case 0x1A: // GET/SET DISPLAY COMBINATION CODE
   2.669 +        cpuSetAX(0x001A);
   2.670 +        cpuSetBX(0x0008); // VGA + analog color display
   2.671 +        break;
   2.672 +    case 0x1B: // STATE INFO
   2.673 +        if(cpuGetBX() == 0x0000)
   2.674 +        {
   2.675 +            int addr = cpuGetAddrES(cpuGetDI());
   2.676 +            if(addr < 0xFFF00)
   2.677 +            {
   2.678 +                // Store state information
   2.679 +                memset(memory + addr, 0, 64);
   2.680 +                memory[addr + 0] = 0x00;
   2.681 +                memory[addr + 1] = 0x01;
   2.682 +                memory[addr + 2] = 0x00;
   2.683 +                memory[addr + 3] = 0xC0; // static-func table at C000:0000
   2.684 +                memory[addr + 4] = 0x03; // Video mode
   2.685 +                memory[addr + 5] = vid_sx;
   2.686 +                memory[addr + 6] = vid_sx >> 8;
   2.687 +                for(int i = 0; i < 8; i++)
   2.688 +                {
   2.689 +                    memory[addr + 11 + i * 2] = vid_posx[i];
   2.690 +                    memory[addr + 12 + i * 2] = vid_posy[i];
   2.691 +                }
   2.692 +                memory[addr + 27] = vid_cursor * 6; // cursor start scanline
   2.693 +                memory[addr + 28] = vid_cursor * 7; // cursor end scanline
   2.694 +                memory[addr + 29] = 0;              // current page
   2.695 +                memory[addr + 30] = 0xD4;
   2.696 +                memory[addr + 31] = 0x03; // CRTC port: 03D4
   2.697 +                memory[addr + 34] = vid_sy;
   2.698 +                memory[addr + 35] = vid_font_lines;
   2.699 +                memory[addr + 36] = 0x00; // font lines: 0010
   2.700 +                memory[addr + 39] = 0x10;
   2.701 +                memory[addr + 40] = 0x00; // # of colors: 0010
   2.702 +                memory[addr + 41] = vid_sy > 25 ? 4 : 8; // # of pages
   2.703 +                memory[addr + 42] = 2;    // # of scan-lines - get from vid_sy
   2.704 +                memory[addr + 49] = 3;    // 256k memory
   2.705 +                cpuSetAX(0x1B1B);
   2.706 +            }
   2.707 +        }
   2.708 +        break;
   2.709 +    case 0xEF: // TEST MSHERC.COM DISPLAY TYPE
   2.710 +        // Ignored
   2.711 +        break;
   2.712 +    default:
   2.713 +        debug(debug_video, "UNHANDLED INT 10, AX=%04x\n", ax);
   2.714 +    }
   2.715 +}
   2.716 +
   2.717 +// CRTC port emulation, some software use it to fix "snow" in CGA modes.
   2.718 +static uint8_t crtc_port;
   2.719 +static uint16_t crtc_cursor_loc;
   2.720 +
   2.721 +uint8_t video_crtc_read(int port)
   2.722 +{
   2.723 +    if(port & 1)
   2.724 +    {
   2.725 +        if(crtc_port == 0x0E)
   2.726 +            return crtc_cursor_loc >> 8;
   2.727 +        if(crtc_port == 0x0F)
   2.728 +            return crtc_cursor_loc;
   2.729 +        else
   2.730 +            return 0;
   2.731 +    }
   2.732 +    else
   2.733 +        return crtc_port;
   2.734 +}
   2.735 +
   2.736 +void video_crtc_write(int port, uint8_t value)
   2.737 +{
   2.738 +    if(port & 1)
   2.739 +    {
   2.740 +        if(crtc_port == 0x0E)
   2.741 +            crtc_cursor_loc = (crtc_cursor_loc & 0xFF) | (value << 8);
   2.742 +        if(crtc_port == 0x0F)
   2.743 +            crtc_cursor_loc = (crtc_cursor_loc & 0xFF00) | (value);
   2.744 +        else
   2.745 +            debug(debug_video, "CRTC port write [%02x] <- %02x\n", crtc_port, value);
   2.746 +    }
   2.747 +    else
   2.748 +        crtc_port = value;
   2.749 +}
   2.750 +
   2.751 +int video_get_col(void)
   2.752 +{
   2.753 +    return vid_posx[vid_page];
   2.754 +}
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/opendkim-dev/receipt	Wed Nov 08 16:45:57 2023 +0000
     3.3 @@ -0,0 +1,21 @@
     3.4 +# SliTaz package receipt.
     3.5 +
     3.6 +PACKAGE="opendkim-dev"
     3.7 +VERSION="2.10.3"
     3.8 +CATEGORY="development"
     3.9 +SHORT_DESC="DKIM library, MTA filter implementation and associated tools, development files."
    3.10 +MAINTAINER="pascal.bellard@slitaz.org"
    3.11 +LICENSE="BSD"
    3.12 +WEB_SITE="http://www.opendkim.org/"
    3.13 +WANTED="opendkim"
    3.14 +
    3.15 +DEPENDS="opendkim pkg-config"
    3.16 +
    3.17 +# Rules to gen a SliTaz package suitable for Tazpkg.
    3.18 +genpkg_rules()
    3.19 +{
    3.20 +	mkdir -p $fs/usr/lib
    3.21 +	cp -a $install/usr/include		$fs/usr
    3.22 +	cp -a $install/usr/lib/*a		$fs/usr
    3.23 +	cp -a $install/usr/lib/pkgconfig	$fs/usr
    3.24 +}
     4.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.2 +++ b/opendkim/receipt	Wed Nov 08 16:45:57 2023 +0000
     4.3 @@ -0,0 +1,39 @@
     4.4 +# SliTaz package receipt.
     4.5 +
     4.6 +PACKAGE="opendkim"
     4.7 +VERSION="2.10.3"
     4.8 +CATEGORY="network"
     4.9 +SHORT_DESC="DKIM library, MTA filter implementation and associated tools."
    4.10 +MAINTAINER="pascal.bellard@slitaz.org"
    4.11 +LICENSE="BSD"
    4.12 +WEB_SITE="http://www.opendkim.org/"
    4.13 +
    4.14 +TARBALL="$PACKAGE-$VERSION.tar.gz"
    4.15 +WGET_URL="$SF_MIRROR/$PACKAGE/$TARBALL"
    4.16 +
    4.17 +DEPENDS="libbsd libssl"
    4.18 +BUILD_DEPENDS="libbsd openssl-dev"
    4.19 +
    4.20 +# What is the latest version available today?
    4.21 +current_version()
    4.22 +{
    4.23 +	wget -O - https://sourceforge.net/projects/opendkim/files/ 2>/dev/null | \
    4.24 +	sed '/scope="row/!d;/opendkim-/!d;s|.*dkim-||;s|.tar.*||;q'
    4.25 +}
    4.26 +
    4.27 +# Rules to configure and make the package.
    4.28 +compile_rules()
    4.29 +{
    4.30 +	# The default --enable-filer neads milter
    4.31 +	./configure --disable-filter $CONFIGURE_ARGS &&
    4.32 +	make &&
    4.33 +	make DESTDIR=$DESTDIR install
    4.34 +}
    4.35 +
    4.36 +# Rules to gen a SliTaz package suitable for Tazpkg.
    4.37 +genpkg_rules()
    4.38 +{
    4.39 +	mkdir -p $fs/usr/lib
    4.40 +	cp -a $install/usr/lib/lib*.so*	$fs/usr
    4.41 +	cp -a $install/usr/sbin	$fs/usr
    4.42 +}
     5.1 --- a/openvpn/stuff/usr/bin/make-ovpn	Fri Sep 29 10:56:02 2023 +0100
     5.2 +++ b/openvpn/stuff/usr/bin/make-ovpn	Wed Nov 08 16:45:57 2023 +0000
     5.3 @@ -132,8 +132,8 @@
     5.4  #duplicate-cn
     5.5  #push "redirect-gateway def1"
     5.6  
     5.7 -ifconfig $net.1 $net.3
     5.8 -ifconfig-pool $net.6 $net.254
     5.9 +ifconfig $net.1 $net.2
    5.10 +ifconfig-pool $net.5 $net.254
    5.11  route $net.0 255.255.255.0
    5.12  $(shift 3; for i in $net.0/255.255.255.0 $@; do
    5.13  	echo "push \"route ${i/\// }\""
     6.1 --- a/zx0/receipt	Fri Sep 29 10:56:02 2023 +0100
     6.2 +++ b/zx0/receipt	Wed Nov 08 16:45:57 2023 +0000
     6.3 @@ -15,7 +15,7 @@
     6.4  # What is the latest version available today?
     6.5  current_version()
     6.6  {
     6.7 -	wget -O - $WEB_SITE/commits/master 2>/dev/null | \
     6.8 +	wget -O - $WEB_SITE/commits/main 2>/dev/null | \
     6.9  	sed '/Commits on/!d;s|.*on |"|;s|<.*|"|;q' | xargs date +%Y%m%d -d
    6.10  }
    6.11