diff --git a/bios/GLABIOS.ROM b/bios/GLABIOS.ROM index f1088618..cc78bf42 100644 Binary files a/bios/GLABIOS.ROM and b/bios/GLABIOS.ROM differ diff --git a/bios/GLABIOS640.ROM b/bios/GLABIOS640.ROM index eb41f3fd..89e1fd07 100644 Binary files a/bios/GLABIOS640.ROM and b/bios/GLABIOS640.ROM differ diff --git a/boot/freedos_hd.img b/boot/freedos_hd.img index 05cea626..25fdf5e4 100644 Binary files a/boot/freedos_hd.img and b/boot/freedos_hd.img differ diff --git a/lib/vxt/exec.inl b/lib/vxt/exec.inl index 3b0587df..744a1c19 100644 --- a/lib/vxt/exec.inl +++ b/lib/vxt/exec.inl @@ -782,23 +782,24 @@ static void mov_C7(CONSTSP(cpu) p, INST(inst)) { } static void enter_C8(CONSTSP(cpu) p, INST(inst)) { - UNUSED(inst); - vxt_word size = read_opcode16(p); - vxt_byte level = read_opcode8(p); - - push(p, p->regs.bp); - vxt_word sp = p->regs.sp; - - if (level) { - for (vxt_byte i = 0; i < level; i++) { - p->regs.bp -= 2; - push(p, p->regs.bp); - } - push(p, p->regs.sp); - } + UNUSED(inst); + vxt_word size = read_opcode16(p); + vxt_byte level = read_opcode8(p) & 0x1F; + + push(p, p->regs.bp); + vxt_word bp = p->regs.bp; + vxt_word sp = p->regs.sp; + + if (level > 0) { + while (--level) { + bp -= 2; + push(p, cpu_segment_read_word(p, p->regs.ss, bp)); + } + push(p, sp); + } - p->regs.bp = sp; - p->regs.sp -= size; + p->regs.sp -= size; + p->regs.bp = sp; } static void leave_C9(CONSTSP(cpu) p, INST(inst)) { diff --git a/modules/network/network.c b/modules/network/network.c index 28173a0f..759581fe 100644 --- a/modules/network/network.c +++ b/modules/network/network.c @@ -35,12 +35,18 @@ #include #endif +// This is hardcoded in the driver extension. +#define MAX_PACKET_SIZE 0x3F00 + struct network { pcap_t *handle; bool can_recv; - int pkg_len; char nif[128]; - vxt_byte buffer[0x10000]; + + int pkg_len; + vxt_byte buffer[MAX_PACKET_SIZE]; + vxt_word buf_seg; + vxt_word buf_offset; }; static vxt_byte in(struct network *n, vxt_word port) { @@ -50,7 +56,8 @@ static vxt_byte in(struct network *n, vxt_word port) { static void out(struct network *n, vxt_word port, vxt_byte data) { /* - This is the API of Fake86's packet driver. + This is the API of Fake86's packet driver + with the VirtualXT extension. References: http://crynwr.com/packet_driver.html @@ -66,6 +73,11 @@ static void out(struct network *n, vxt_word port, vxt_byte data) { n->can_recv = true; break; case 1: // Send packet of CX at DS:SI + if (r->cx > MAX_PACKET_SIZE) { + VXT_LOG("Can't send! Invalid package size."); + break; + } + for (int i = 0; i < (int)r->cx; i++) n->buffer[i] = vxt_system_read_byte(s, VXT_POINTER(r->ds, r->si + i)); @@ -73,23 +85,29 @@ static void out(struct network *n, vxt_word port, vxt_byte data) { VXT_LOG("Could not send packet!"); break; case 2: // Return packet info (packet buffer in DS:SI, length in CX) - r->ds = 0xD000; - r->si = 0; + r->ds = n->buf_seg; + r->si = n->buf_offset; r->cx = (vxt_word)n->pkg_len; break; case 3: // Copy packet to final destination (given in ES:DI) for (int i = 0; i < (int)r->cx; i++) - vxt_system_write_byte(s, VXT_POINTER(r->es, r->di + i), vxt_system_read_byte(s, VXT_POINTER(0xD000, i))); + vxt_system_write_byte(s, VXT_POINTER(r->es, r->di + i), vxt_system_read_byte(s, VXT_POINTER(n->buf_seg, n->buf_offset + i))); break; case 4: // Disable packet reception n->can_recv = false; break; + case 0xFF: // Setup packet buffer + n->buf_seg = r->cs; + n->buf_offset = r->dx; + VXT_LOG("Packet buffer is located at %04X:%04X", r->cs, r->dx); + break; } } static vxt_error reset(struct network *n) { n->can_recv = false; n->pkg_len = 0; + n->buf_seg = n->buf_offset = 0; return VXT_NO_ERROR; } @@ -101,7 +119,7 @@ static vxt_error timer(struct network *n, vxt_timer_id id, int cycles) { (void)id; (void)cycles; vxt_system *s = VXT_GET_SYSTEM(n); - if (!n->can_recv) + if (!n->can_recv || !n->buf_seg) return VXT_NO_ERROR; const vxt_byte *data = NULL; @@ -110,14 +128,16 @@ static vxt_error timer(struct network *n, vxt_timer_id id, int cycles) { if (pcap_next_ex(n->handle, &header, &data) <= 0) return VXT_NO_ERROR; - if (header->len > sizeof(n->buffer)) + if (header->len > MAX_PACKET_SIZE) { + VXT_LOG("Invalid package size!"); return VXT_NO_ERROR; + } n->can_recv = false; n->pkg_len = header->len; for (int i = 0; i < n->pkg_len; i++) - vxt_system_write_byte(s, VXT_POINTER(0xD000, i), data[i]); + vxt_system_write_byte(s, VXT_POINTER(n->buf_seg, n->buf_offset + i), data[i]); vxt_system_interrupt(s, 6); return VXT_NO_ERROR; @@ -149,7 +169,7 @@ static pcap_t *init_pcap(struct network *n) { return NULL; } - if (!(handle = pcap_open_live(dev->name, 0xFFFF, PCAP_OPENFLAG_PROMISCUOUS, -1, buffer))) { + if (!(handle = pcap_open_live(dev->name, 0xFFFF, PCAP_OPENFLAG_PROMISCUOUS, 1, buffer))) { VXT_LOG("pcap error: %s", buffer); pcap_freealldevs(devs); return NULL; diff --git a/modules/post/post.c b/modules/post/post.c new file mode 100644 index 00000000..ebbb93e1 --- /dev/null +++ b/modules/post/post.c @@ -0,0 +1,62 @@ +// Copyright (c) 2019-2024 Andreas T Jonsson +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software in +// a product, an acknowledgment (see the following) in the product +// documentation is required. +// +// This product make use of the VirtualXT software emulator. +// Visit https://virtualxt.org for more information. +// +// 2. Altered source versions must be plainly marked as such, and must not be +// misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source distribution. + +#include + +struct post { + int code; +}; + +static vxt_byte in(struct post *c, vxt_word port) { + (void)port; + return c->code; +} + +static void out(struct post *c, vxt_word port, vxt_byte data) { + (void)port; + c->code = data; + VXT_LOG("0x%01X", data); +} + +static vxt_error install(struct post *c, vxt_system *s) { + struct vxt_pirepheral *p = VXT_GET_PIREPHERAL(c); + vxt_system_install_io_at(s, p, 0x80); + return VXT_NO_ERROR; +} + +static vxt_error reset(struct post *c) { + c->code = 0; + return VXT_NO_ERROR; +} + +static const char *name(struct post *c) { + (void)c; return "Post Card"; +} + +VXTU_MODULE_CREATE(post, { + PIREPHERAL->install = &install; + PIREPHERAL->reset = &reset; + PIREPHERAL->name = &name; + PIREPHERAL->io.in = ∈ + PIREPHERAL->io.out = &out; +}) diff --git a/modules/post/premake5.lua b/modules/post/premake5.lua new file mode 100644 index 00000000..88d46ad3 --- /dev/null +++ b/modules/post/premake5.lua @@ -0,0 +1 @@ +files "post.c" diff --git a/tools/checksum/update_bios_checksum.py b/tools/checksum/update_bios_checksum.py new file mode 100755 index 00000000..f89caee7 --- /dev/null +++ b/tools/checksum/update_bios_checksum.py @@ -0,0 +1,25 @@ +#!/usr/bin/env python3 + +import os +import sys +import struct + +size = 0 +sum = 0 + +with open(sys.argv[1], "rb") as f: + f.seek(0, os.SEEK_END) + size = f.tell() + f.seek(0, os.SEEK_SET) + + num = size + while num > 1: + sum += int(struct.unpack("B", f.read(1))[0]) + num -= 1 + +sum = (256 - (sum & 0xFF)) & 0xFF +print("BIOS Checksum: 0x{:02X}".format(sum)) + +with open(sys.argv[1], "rb+") as f: + f.seek(size - 1, os.SEEK_SET) + f.write(struct.pack("B", sum)) diff --git a/tools/vxtpkt/vxtpkt.asm b/tools/vxtpkt/vxtpkt.asm new file mode 100644 index 00000000..b927749f --- /dev/null +++ b/tools/vxtpkt/vxtpkt.asm @@ -0,0 +1,82 @@ +; Copyright (c) 2019-2024 Andreas T Jonsson +; +; This software is provided 'as-is', without any express or implied +; warranty. In no event will the authors be held liable for any damages +; arising from the use of this software. +; +; Permission is granted to anyone to use this software for any purpose, +; including commercial applications, and to alter it and redistribute it +; freely, subject to the following restrictions: +; +; 1. The origin of this software must not be misrepresented; you must not +; claim that you wrote the original software. If you use this software in +; a product, an acknowledgment (see the following) in the product +; documentation is required. +; +; This product make use of the VirtualXT software emulator. +; Visit https://virtualxt.org for more information. +; +; 2. Altered source versions must be plainly marked as such, and must not be +; misrepresented as being the original software. +; +; 3. This notice may not be removed or altered from any source distribution. + +cpu 8086 +org 256 + +start: + jmp init + +intFC_handler: + out 0xB2, al + iret + +packet_buffer: + times 0x3F00 dd 0 + +end_of_resident: + +init: + lea dx, init_msg + mov ax, 0x900 + int 0x21 + + in al, 0xB2 + cmp al, 0 + jne .no_network + + ; Setup buffer + lea dx, [cs:packet_buffer] + mov ah, 0xFF + out 0xB2, al + + mov ax, 0x25FC + mov dx, intFC_handler + int 0x21 + + lea dx, installed_msg + mov ax, 0x900 + int 0x21 + + mov ax, 0x3100 ; Terminate and stay resident. + mov dx, (end_of_resident - start + 256 + 15) >> 4 + int 0x21 + +.no_network: + lea dx, not_network_msg + mov ax, 0x900 + int 0x21 + + ; DOS "terminate" function. + mov al, -1 + mov ah, 0x4C + int 0x21 + +init_msg: + db 'VirtualXT extension for Fake86 packet driver', 0xA, 0xD, '$' + +installed_msg: + db 'Driver installed!', 0xA, 0xD, '$' + +not_network_msg: + db 'No network module! Driver not installed.', 0xA, 0xD, '$'