Compare commits
13 Commits
06bc908b33
...
bf9a88805f
| Author | SHA1 | Date | |
|---|---|---|---|
| bf9a88805f | |||
| 188256b0ac | |||
| b1e7fde1a3 | |||
| 2ba1546dec | |||
| 3df5b28e4e | |||
| b0d57c1c96 | |||
| 806d87e0f1 | |||
| a4959782a8 | |||
| f707c394f0 | |||
| 0c0133b3c1 | |||
| 6a69215c90 | |||
| 59f49a232e | |||
| ce3ad9fa86 |
19
Makefile
19
Makefile
@@ -6,8 +6,8 @@ dev-image = 5150-dev
|
|||||||
crc16.s: crc16.c
|
crc16.s: crc16.c
|
||||||
ia16-elf-gcc -S -Os -o crc16.s crc16.c
|
ia16-elf-gcc -S -Os -o crc16.s crc16.c
|
||||||
|
|
||||||
crc16.bin: crc16.s crt0.c
|
crc16.bin: crc16.s
|
||||||
ia16-elf-gcc -o crc16.bin -Os -nostdlib crc16.s crt0.c
|
ia16-elf-gcc -o crc16.bin -Os -nostdlib crc16.s
|
||||||
|
|
||||||
CC = ia16-elf-gcc
|
CC = ia16-elf-gcc
|
||||||
CXX = ia16-elf-gcc
|
CXX = ia16-elf-gcc
|
||||||
@@ -31,11 +31,13 @@ fat12boot.elf: LDFLAGS += -T bootsect.ld
|
|||||||
|
|
||||||
fat12boot.bin: fat12boot.elf
|
fat12boot.bin: fat12boot.elf
|
||||||
|
|
||||||
|
stdlib.o: CFLAGS := $(filter-out -flto, $(CFLAGS))
|
||||||
|
|
||||||
polmon.elf: LDFLAGS += -T flat1000.ld
|
polmon.elf: LDFLAGS += -T flat1000.ld
|
||||||
polmon.elf: polmon.o stdlib.o
|
polmon.elf: polmon.o stdlib.o
|
||||||
|
|
||||||
polio.elf: LDFLAGS += -T flat0600.ld
|
polio.elf: LDFLAGS += -T flat0600.ld
|
||||||
polio.elf: polio.s fat12.o
|
polio.elf: polio-main.o polio.s fat12.o paracomm.o stdlib.o
|
||||||
|
|
||||||
wozmon.o: polmon.cc
|
wozmon.o: polmon.cc
|
||||||
wozmon.o: CPPFLAGS = -DWOZMON=1
|
wozmon.o: CPPFLAGS = -DWOZMON=1
|
||||||
@@ -51,12 +53,19 @@ wozmon.bin: wozmon.elf
|
|||||||
paracli.elf: LDFLAGS += -T doscom.ld
|
paracli.elf: LDFLAGS += -T doscom.ld
|
||||||
paracli.elf: paracli.s paracomm.o
|
paracli.elf: paracli.s paracomm.o
|
||||||
|
|
||||||
polos.img: fat12boot.bin polmon.com polio.com paracli.com
|
dos-programs = mushroom.elf hello.elf
|
||||||
|
$(dos-programs): LDFLAGS += -T doscom.ld
|
||||||
|
|
||||||
|
mushroom.elf: mushroom.s
|
||||||
|
hello.elf: hello.o stdlib.o crt0.s
|
||||||
|
|
||||||
|
polos.img: fat12boot.bin polmon.com polio.com mushroom.com hello.com
|
||||||
dd if=/dev/zero of=$@ bs=512 count=720
|
dd if=/dev/zero of=$@ bs=512 count=720
|
||||||
mformat -i $@ -t 40 -h 2 -s 9
|
mformat -i $@ -t 40 -h 2 -s 9
|
||||||
mcopy -i $@ polio.com ::/
|
mcopy -i $@ polio.com ::/
|
||||||
mcopy -i $@ polmon.com ::/
|
mcopy -i $@ polmon.com ::/
|
||||||
mcopy -i $@ paracli.com ::/
|
mcopy -i $@ mushroom.com ::/
|
||||||
|
mcopy -i $@ hello.com ::/
|
||||||
dd if=fat12boot.bin of=$@ conv=notrunc
|
dd if=fat12boot.bin of=$@ conv=notrunc
|
||||||
|
|
||||||
.PHONY: clean
|
.PHONY: clean
|
||||||
|
|||||||
@@ -14,13 +14,9 @@ void setup() {
|
|||||||
|
|
||||||
pc = ParaComms{
|
pc = ParaComms{
|
||||||
.mosi_cb =
|
.mosi_cb =
|
||||||
[](uint8_t *data, uint8_t len) {
|
[](uint8_t* data, uint8_t len) {
|
||||||
for (int i = 0; i < len; i++) {
|
for (int i = 0; i < len; i++) {
|
||||||
Serial.printf("%c", data[i]);
|
Serial.printf("%c", data[i]);
|
||||||
pc.SendByte(data[i]); // echo
|
|
||||||
if (data[i] == '\r') {
|
|
||||||
pc.SendByte('\n');
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
@@ -32,7 +28,7 @@ void loop() {
|
|||||||
static int led_counter = 0;
|
static int led_counter = 0;
|
||||||
static int led = HIGH;
|
static int led = HIGH;
|
||||||
|
|
||||||
static int mode = 0; // 0 = keyboard, 1 = parallel
|
static int mode = 0; // 0 = keyboard, 1 = parallel
|
||||||
|
|
||||||
if (led_counter > 400000) {
|
if (led_counter > 400000) {
|
||||||
led_counter = 0;
|
led_counter = 0;
|
||||||
@@ -41,7 +37,7 @@ void loop() {
|
|||||||
}
|
}
|
||||||
led_counter += 1;
|
led_counter += 1;
|
||||||
|
|
||||||
checkKbdReset();
|
// checkKbdReset();
|
||||||
|
|
||||||
uint8_t mosib;
|
uint8_t mosib;
|
||||||
if (strobeOccurred(mosib)) {
|
if (strobeOccurred(mosib)) {
|
||||||
@@ -52,6 +48,9 @@ void loop() {
|
|||||||
|
|
||||||
if (Serial.available() > 0) {
|
if (Serial.available() > 0) {
|
||||||
int c = Serial.read();
|
int c = Serial.read();
|
||||||
|
#if 1
|
||||||
|
pc.SendByte(c);
|
||||||
|
#else
|
||||||
if (c == 2) {
|
if (c == 2) {
|
||||||
mode = 0;
|
mode = 0;
|
||||||
} else if (c == 3) {
|
} else if (c == 3) {
|
||||||
@@ -63,5 +62,6 @@ void loop() {
|
|||||||
pc.SendByte(c);
|
pc.SendByte(c);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ SECTIONS {
|
|||||||
* (.bss)
|
* (.bss)
|
||||||
}
|
}
|
||||||
|
|
||||||
.data : {
|
.data (NOLOAD) : {
|
||||||
*(.data)
|
*(.data)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
5
crc16.s
5
crc16.s
@@ -3,6 +3,11 @@
|
|||||||
.att_syntax prefix
|
.att_syntax prefix
|
||||||
#NO_APP
|
#NO_APP
|
||||||
#APP
|
#APP
|
||||||
|
.section .text.init
|
||||||
|
.global _start
|
||||||
|
_start:
|
||||||
|
|
||||||
|
.section .text.main
|
||||||
.global main
|
.global main
|
||||||
main:
|
main:
|
||||||
push %bp
|
push %bp
|
||||||
|
|||||||
25
crt0.c
25
crt0.c
@@ -1,25 +0,0 @@
|
|||||||
#include <stdint.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
int main();
|
|
||||||
|
|
||||||
asm(".section .init \n"
|
|
||||||
".global _start \n"
|
|
||||||
"_start: \n\t"
|
|
||||||
"mov %cs, %ax \n\t"
|
|
||||||
"mov %ax, %ds \n\t"
|
|
||||||
"mov %ax, %es \n\t"
|
|
||||||
"cli \n\t"
|
|
||||||
"mov %ax, %ss \n\t"
|
|
||||||
"mov $0x1000, %ax \n\t"
|
|
||||||
"mov %ax, %sp \n\t"
|
|
||||||
"sti \n\t"
|
|
||||||
"jmp main");
|
|
||||||
|
|
||||||
void* memset(void* ptr, int val, size_t len) {
|
|
||||||
uint8_t* p = ptr;
|
|
||||||
while (len--) {
|
|
||||||
*p++ = val;
|
|
||||||
}
|
|
||||||
return ptr;
|
|
||||||
}
|
|
||||||
8
crt0.s
Normal file
8
crt0.s
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
.arch i8086,jumps
|
||||||
|
.code16
|
||||||
|
.intel_syntax noprefix
|
||||||
|
|
||||||
|
.section .init
|
||||||
|
.global _start
|
||||||
|
_start:
|
||||||
|
jmp main
|
||||||
@@ -14,7 +14,7 @@ SECTIONS {
|
|||||||
* (.bss)
|
* (.bss)
|
||||||
}
|
}
|
||||||
|
|
||||||
.data : {
|
.data (NOLOAD) : {
|
||||||
*(.data)
|
*(.data)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ SECTIONS {
|
|||||||
* (.bss)
|
* (.bss)
|
||||||
}
|
}
|
||||||
|
|
||||||
.data : {
|
.data (NOLOAD) : {
|
||||||
*(.data)
|
*(.data)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ SECTIONS {
|
|||||||
* (.bss)
|
* (.bss)
|
||||||
}
|
}
|
||||||
|
|
||||||
.data : {
|
.data (NOLOAD) : {
|
||||||
*(.data)
|
*(.data)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
48
ftp.asm
Normal file
48
ftp.asm
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
CPU 8086
|
||||||
|
|
||||||
|
chunksize equ 0x20
|
||||||
|
devicedelay equ 0x08
|
||||||
|
|
||||||
|
_start:
|
||||||
|
push bp
|
||||||
|
mov bp, sp
|
||||||
|
sub sp, 8
|
||||||
|
mov [bp-2], word chunksize ; recv size
|
||||||
|
mov [bp-4], word 0xf000 ; recv addr
|
||||||
|
mov [bp-6], word 0x0001 ; send size
|
||||||
|
mov [bp-8], word 0x7000 ; send addr
|
||||||
|
mov bx, [bp-8]
|
||||||
|
mov [bx], byte 0x42
|
||||||
|
l0:
|
||||||
|
cmp word [bp-4], 0xf600
|
||||||
|
jb l1
|
||||||
|
l2:
|
||||||
|
mov sp, bp
|
||||||
|
pop bp
|
||||||
|
ret
|
||||||
|
l1:
|
||||||
|
mov ah, 0x07
|
||||||
|
int 0x80
|
||||||
|
test al, al
|
||||||
|
jnz l1
|
||||||
|
push word [bp-2]
|
||||||
|
push word [bp-4]
|
||||||
|
mov ah, 0x05
|
||||||
|
int 0x80
|
||||||
|
test al, al
|
||||||
|
jz l2
|
||||||
|
mov ah, 0
|
||||||
|
add [bp-4], ax
|
||||||
|
push word [bp-6]
|
||||||
|
push word [bp-8]
|
||||||
|
mov ah, 0x06
|
||||||
|
int 0x80
|
||||||
|
add sp, 8
|
||||||
|
mov cx, devicedelay
|
||||||
|
l3:
|
||||||
|
mov ah, 0x07
|
||||||
|
push cx
|
||||||
|
int 0x80
|
||||||
|
pop cx
|
||||||
|
loop l3 ; give the device some time to answer
|
||||||
|
jmp l0
|
||||||
5
hello.c
Normal file
5
hello.c
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
puts("Hello, world!\r\n");
|
||||||
|
}
|
||||||
55
mrbridge.py
Normal file
55
mrbridge.py
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
import argparse
|
||||||
|
import serial
|
||||||
|
import threading
|
||||||
|
import time
|
||||||
|
import websocket
|
||||||
|
|
||||||
|
|
||||||
|
def parse_args():
|
||||||
|
parser = argparse.ArgumentParser(description="Bridge a serial port to a websocket")
|
||||||
|
parser.add_argument("port", help="path to the serial port")
|
||||||
|
parser.add_argument("--baudrate", default=115200)
|
||||||
|
parser.add_argument("--escape", action='store_true')
|
||||||
|
parser.add_argument("ws", help="URL of the websocket")
|
||||||
|
return parser.parse_args()
|
||||||
|
|
||||||
|
|
||||||
|
def device_thread(device, ws):
|
||||||
|
while True:
|
||||||
|
line = device.readline()
|
||||||
|
ws.send(line)
|
||||||
|
|
||||||
|
|
||||||
|
def slowwrite(device, data):
|
||||||
|
for b in data:
|
||||||
|
device.write([b])
|
||||||
|
time.sleep(0.01)
|
||||||
|
|
||||||
|
|
||||||
|
def ws_thread(device, ws):
|
||||||
|
while True:
|
||||||
|
data = ws.recv();
|
||||||
|
slowwrite(device, data.replace(b'\n', b'\r\n'))
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
args = parse_args()
|
||||||
|
device = serial.Serial(args.port, baudrate=args.baudrate)
|
||||||
|
ws = websocket.create_connection(args.ws)
|
||||||
|
|
||||||
|
wst = threading.Thread(target=ws_thread, args=(device, ws), daemon=True)
|
||||||
|
wst.start()
|
||||||
|
|
||||||
|
if args.escape:
|
||||||
|
device.write([0x03])
|
||||||
|
try:
|
||||||
|
device_thread(device, ws)
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
pass
|
||||||
|
finally:
|
||||||
|
if args.escape:
|
||||||
|
device.write([0x02])
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
261
mushroom.s
Normal file
261
mushroom.s
Normal file
@@ -0,0 +1,261 @@
|
|||||||
|
.arch i8086,jumps
|
||||||
|
.code16
|
||||||
|
.intel_syntax noprefix
|
||||||
|
|
||||||
|
.section .init
|
||||||
|
.global _start
|
||||||
|
_start:
|
||||||
|
mov ax, cs
|
||||||
|
mov ds, ax
|
||||||
|
mov es, ax
|
||||||
|
cli
|
||||||
|
mov ss, ax
|
||||||
|
mov sp, 0x100
|
||||||
|
sti
|
||||||
|
jmp main
|
||||||
|
|
||||||
|
.section .bss
|
||||||
|
kBufSize = 77
|
||||||
|
kDividerRow = 23
|
||||||
|
kRecvBufSize = 128
|
||||||
|
|
||||||
|
curpos: .word 0
|
||||||
|
inputsize: .byte 0
|
||||||
|
escaped: .byte 0
|
||||||
|
inputbuf: .zero kBufSize
|
||||||
|
recvbuf: .zero kRecvBufSize
|
||||||
|
|
||||||
|
# XXX: funky call
|
||||||
|
# inputs:
|
||||||
|
# si: string offset
|
||||||
|
# cl: string length
|
||||||
|
# clobbers: ax, bh, dx
|
||||||
|
.section .text.printn
|
||||||
|
printn:
|
||||||
|
push bx
|
||||||
|
push bp
|
||||||
|
mov bh, 0
|
||||||
|
1:
|
||||||
|
test cl, cl
|
||||||
|
jz 0f
|
||||||
|
mov al, [si]
|
||||||
|
cmpb escaped, 0
|
||||||
|
je 3f
|
||||||
|
cmp al, 'm'
|
||||||
|
jne 5f
|
||||||
|
movb escaped, 0
|
||||||
|
jmp 5f
|
||||||
|
3:
|
||||||
|
cmp al, 0x1b # ESC
|
||||||
|
jne 4f
|
||||||
|
movb escaped, 1
|
||||||
|
jmp 5f
|
||||||
|
4:
|
||||||
|
mov ah, 0x0e # write tty
|
||||||
|
int 0x10
|
||||||
|
push cx
|
||||||
|
mov ah, 0x03 # get cursor
|
||||||
|
int 0x10
|
||||||
|
cmp dh, kDividerRow
|
||||||
|
jb 2f
|
||||||
|
push dx
|
||||||
|
mov ah, 0x08 # read color
|
||||||
|
int 0x10
|
||||||
|
mov bh, ah
|
||||||
|
xor cx, cx
|
||||||
|
mov dx, 0x164f
|
||||||
|
mov ax, 0x0601 # scroll up, 1 line
|
||||||
|
int 0x10
|
||||||
|
pop dx
|
||||||
|
dec dh
|
||||||
|
mov bh, 0
|
||||||
|
mov ah, 0x02 # set cursor
|
||||||
|
int 0x10
|
||||||
|
2:
|
||||||
|
pop cx
|
||||||
|
5:
|
||||||
|
inc si
|
||||||
|
dec cl
|
||||||
|
jmp 1b
|
||||||
|
0:
|
||||||
|
pop bp
|
||||||
|
pop bx
|
||||||
|
ret
|
||||||
|
|
||||||
|
# XXX: funky call
|
||||||
|
# inputs:
|
||||||
|
# si: string offset
|
||||||
|
# cl: string length
|
||||||
|
# clobbers: ax, bh, dx
|
||||||
|
.section .text.addtext
|
||||||
|
addtext:
|
||||||
|
push di
|
||||||
|
push cx
|
||||||
|
mov bh, 0
|
||||||
|
mov ah, 0x03 # get cursor pos
|
||||||
|
int 0x10
|
||||||
|
pop cx
|
||||||
|
push dx
|
||||||
|
mov di, offset curpos
|
||||||
|
mov dx, [di]
|
||||||
|
mov ah, 0x02 # set cursor
|
||||||
|
int 0x10
|
||||||
|
call printn
|
||||||
|
mov ah, 0x03 # get cursor pos
|
||||||
|
int 0x10
|
||||||
|
mov [di], dx
|
||||||
|
pop dx
|
||||||
|
mov ah, 0x02 # set cursor
|
||||||
|
int 0x10
|
||||||
|
pop di
|
||||||
|
ret
|
||||||
|
|
||||||
|
.section .text.sendbuffer
|
||||||
|
sendbuffer:
|
||||||
|
push bp
|
||||||
|
mov bp, sp
|
||||||
|
sub sp, 2
|
||||||
|
mov al, inputsize
|
||||||
|
mov [bp-2], al
|
||||||
|
movb inputsize, 0
|
||||||
|
mov si, offset .l0
|
||||||
|
mov cl, 2
|
||||||
|
call addtext
|
||||||
|
mov si, offset inputbuf
|
||||||
|
mov cl, [bp-2]
|
||||||
|
call addtext
|
||||||
|
mov si, offset .l1
|
||||||
|
mov cl, 2
|
||||||
|
call addtext
|
||||||
|
mov si, offset inputbuf
|
||||||
|
mov cl, [bp-2]
|
||||||
|
call parasend
|
||||||
|
# XXX: should check cx in case not everything was sent
|
||||||
|
mov al, ' '
|
||||||
|
mov dx, 0x1802 # [24; 2]
|
||||||
|
call drawchar
|
||||||
|
mov ah, 0x02
|
||||||
|
int 0x10 # mov cursor back to start of line
|
||||||
|
add sp, 2
|
||||||
|
pop bp
|
||||||
|
ret
|
||||||
|
|
||||||
|
# draw until end of line
|
||||||
|
# al: char
|
||||||
|
# dh: row
|
||||||
|
# dl: start col
|
||||||
|
.section .text.drawchar
|
||||||
|
drawchar:
|
||||||
|
push ax
|
||||||
|
mov bh, 0
|
||||||
|
mov ah, 0x02 # set cursor
|
||||||
|
int 0x10
|
||||||
|
mov cx, 80
|
||||||
|
sub cl, dl
|
||||||
|
pop ax
|
||||||
|
mov ah, 0x0a
|
||||||
|
int 0x10
|
||||||
|
ret
|
||||||
|
|
||||||
|
.section .text.parasend
|
||||||
|
parasend:
|
||||||
|
mov ah, 0x06 # send parallel
|
||||||
|
push cx
|
||||||
|
push si
|
||||||
|
int 0x80
|
||||||
|
mov cx, 1
|
||||||
|
push cx
|
||||||
|
mov cx, offset .l1 + 1
|
||||||
|
push cx
|
||||||
|
mov ah, 0x06 # send parallel
|
||||||
|
int 0x80
|
||||||
|
add sp, 8
|
||||||
|
ret
|
||||||
|
|
||||||
|
prompt:
|
||||||
|
mov bh, 0
|
||||||
|
mov dx, 0x1800
|
||||||
|
mov ah, 0x02
|
||||||
|
int 0x10
|
||||||
|
mov ah, 0x0e
|
||||||
|
mov al, '>'
|
||||||
|
int 0x10
|
||||||
|
mov ah, 0x0e
|
||||||
|
mov al, ' '
|
||||||
|
int 0x10
|
||||||
|
ret
|
||||||
|
|
||||||
|
.section .rodata
|
||||||
|
.l0: .ascii "> "
|
||||||
|
.l1: .byte 0x0d, 0x0a
|
||||||
|
.l2: .ascii "MUSHRoom 8086 client 0.1\r\n"
|
||||||
|
l2len = . - offset .l2
|
||||||
|
|
||||||
|
.section .text.main
|
||||||
|
.global main
|
||||||
|
main:
|
||||||
|
movb inputsize, 0 # inputsize = 0
|
||||||
|
movw curpos, 0 # mov buffer cursor to [0;0]
|
||||||
|
movb escaped, 0
|
||||||
|
mov ax, 0x0002
|
||||||
|
int 0x10
|
||||||
|
mov si, offset .l2
|
||||||
|
mov cl, l2len
|
||||||
|
call addtext
|
||||||
|
mov dx, 0x1700 # [23; 0]
|
||||||
|
mov al, 0xc4 # horizontal box line
|
||||||
|
call drawchar
|
||||||
|
call prompt
|
||||||
|
0:
|
||||||
|
mov ah, 0x01
|
||||||
|
int 0x16 # check buffer
|
||||||
|
jz 1f # if empty, do a round of comms
|
||||||
|
mov ah, 0x00
|
||||||
|
int 0x16 # read 1 key
|
||||||
|
cmp al, 0x08 # backspace
|
||||||
|
je 5f
|
||||||
|
cmp al, 0x0d # CR
|
||||||
|
je 4f
|
||||||
|
mov di, offset inputbuf
|
||||||
|
mov si, offset inputsize
|
||||||
|
mov bh, 0
|
||||||
|
mov bl, [si]
|
||||||
|
cmp bl, kBufSize # stop accepting input at end of screen
|
||||||
|
jge 1f # do a round of comms
|
||||||
|
mov [di+bx], al # store character in buffer
|
||||||
|
incb [si] # increment buffer size
|
||||||
|
mov ah, 0x0e
|
||||||
|
mov bh, 0
|
||||||
|
int 0x10 # local echo
|
||||||
|
jmp 0b
|
||||||
|
5:
|
||||||
|
mov bl, inputsize
|
||||||
|
test bl, bl
|
||||||
|
jz 0b
|
||||||
|
decb inputsize
|
||||||
|
mov bh, 0
|
||||||
|
mov ah, 0x0e
|
||||||
|
int 0x10 # backspace
|
||||||
|
mov ax, 0x0e20
|
||||||
|
int 0x10
|
||||||
|
mov ax, 0x0e08
|
||||||
|
int 0x10
|
||||||
|
jmp 0b
|
||||||
|
4:
|
||||||
|
call sendbuffer # send input buffer
|
||||||
|
1:
|
||||||
|
mov ah, 0x07 # do parallel comms
|
||||||
|
int 0x80
|
||||||
|
mov ax, kRecvBufSize
|
||||||
|
push ax
|
||||||
|
mov ax, offset recvbuf
|
||||||
|
push ax
|
||||||
|
mov ah, 0x05 # recv
|
||||||
|
int 0x80
|
||||||
|
test al, al
|
||||||
|
mov cl, al
|
||||||
|
pop si
|
||||||
|
pop bx
|
||||||
|
jz 0b
|
||||||
|
call addtext
|
||||||
|
jmp 0b
|
||||||
26
paracomm.c
26
paracomm.c
@@ -1,6 +1,7 @@
|
|||||||
#include "paracomm.h"
|
#include "paracomm.h"
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
#define kMosiIdleByte 0x00
|
#define kMosiIdleByte 0x00
|
||||||
#define kMosiStartByte 0x42
|
#define kMosiStartByte 0x42
|
||||||
@@ -21,7 +22,6 @@ static uint8_t miso_recvbuf[256];
|
|||||||
static uint8_t miso_size;
|
static uint8_t miso_size;
|
||||||
static uint8_t miso_received_nibbles;
|
static uint8_t miso_received_nibbles;
|
||||||
static uint8_t miso_state;
|
static uint8_t miso_state;
|
||||||
static void (*miso_cb)(const uint8_t*, uint8_t);
|
|
||||||
|
|
||||||
static void swapbuffers() {
|
static void swapbuffers() {
|
||||||
mosi_sendbuf = mosi_workbuf[mosi_workbuf_idx];
|
mosi_sendbuf = mosi_workbuf[mosi_workbuf_idx];
|
||||||
@@ -92,23 +92,19 @@ void paracomm_feed(uint8_t n) {
|
|||||||
miso_received_nibbles += 1;
|
miso_received_nibbles += 1;
|
||||||
|
|
||||||
if (miso_received_nibbles == 2 * miso_size) {
|
if (miso_received_nibbles == 2 * miso_size) {
|
||||||
if (miso_cb != 0) {
|
|
||||||
miso_cb(miso_recvbuf, miso_size);
|
|
||||||
}
|
|
||||||
miso_state = 0;
|
miso_state = 0;
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void paracomm_init(miso_cb_t cb) {
|
void paracomm_init() {
|
||||||
mosi_size = 0;
|
mosi_size = 0;
|
||||||
mosi_workbuf_idx = 0;
|
mosi_workbuf_idx = 0;
|
||||||
mosi_workbuf_size = 0;
|
mosi_workbuf_size = 0;
|
||||||
mosi_state = 0;
|
mosi_state = 0;
|
||||||
|
|
||||||
miso_state = 0;
|
miso_state = 0;
|
||||||
miso_cb = cb;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int paracomm_send(uint8_t b) {
|
int paracomm_send(uint8_t b) {
|
||||||
@@ -122,3 +118,21 @@ int paracomm_send(uint8_t b) {
|
|||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint8_t paracomm_recv(uint8_t* buf, uint8_t size) {
|
||||||
|
if (miso_state != 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (size > miso_size) {
|
||||||
|
size = miso_size;
|
||||||
|
}
|
||||||
|
memcpy(buf, miso_recvbuf, size);
|
||||||
|
memcpy(miso_recvbuf, miso_recvbuf+size, miso_size - size);
|
||||||
|
miso_size -= size;
|
||||||
|
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t paracomm_busy() {
|
||||||
|
return mosi_state != 0 || miso_state != 0;
|
||||||
|
}
|
||||||
|
|||||||
12
paracomm.h
12
paracomm.h
@@ -2,18 +2,24 @@
|
|||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
typedef void (*miso_cb_t)(const uint8_t* buff, uint8_t size);
|
|
||||||
|
|
||||||
/** Must call first **/
|
/** Must call first **/
|
||||||
void paracomm_init(miso_cb_t miso_cb);
|
void paracomm_init();
|
||||||
|
|
||||||
/** Sends a single byte.
|
/** Sends a single byte.
|
||||||
* Returns: 0 if no error, non-0 otherwise.
|
* Returns: 0 if no error, non-0 otherwise.
|
||||||
*/
|
*/
|
||||||
int paracomm_send(uint8_t b);
|
int paracomm_send(uint8_t b);
|
||||||
|
|
||||||
|
/** Receive some bytes.
|
||||||
|
* Returns: number of bytes copied
|
||||||
|
*/
|
||||||
|
uint8_t paracomm_recv(uint8_t* buf, uint8_t size);
|
||||||
|
|
||||||
/** Call after reading a nibble from the port */
|
/** Call after reading a nibble from the port */
|
||||||
void paracomm_feed(uint8_t n);
|
void paracomm_feed(uint8_t n);
|
||||||
|
|
||||||
/** Yields the next byte to send out the port */
|
/** Yields the next byte to send out the port */
|
||||||
uint8_t paracomm_nextbyte();
|
uint8_t paracomm_nextbyte();
|
||||||
|
|
||||||
|
/** Returns non-zero if busy */
|
||||||
|
uint8_t paracomm_busy();
|
||||||
|
|||||||
93
polio-main.c
Normal file
93
polio-main.c
Normal file
@@ -0,0 +1,93 @@
|
|||||||
|
#include <stdint.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "fat12.h"
|
||||||
|
#include "paracomm.h"
|
||||||
|
|
||||||
|
#define kFatAddr ((void*)0x1a00)
|
||||||
|
#define kRootDirAddr ((void*)0x1c00)
|
||||||
|
#define kPolmonAddr ((void*)0x1000)
|
||||||
|
#define kInt80Vector ((uint16_t*)(0x80 * 4))
|
||||||
|
#define kParallelDataPort 0x3bc
|
||||||
|
#define kParallelStatusPort 0x3bd
|
||||||
|
#define kParallelControlPort 0x3be
|
||||||
|
#define kParaDelay 400
|
||||||
|
#define kRecvBufferSize 256
|
||||||
|
|
||||||
|
void dosdbt();
|
||||||
|
void int80h();
|
||||||
|
|
||||||
|
uint8_t parabuf[kRecvBufferSize];
|
||||||
|
uint8_t parasize;
|
||||||
|
|
||||||
|
static void paracb(const uint8_t* buf, uint8_t size) {
|
||||||
|
// we'll mercilessly erase old data with new data
|
||||||
|
memcpy(parabuf, buf, size);
|
||||||
|
parasize = size;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void die() {
|
||||||
|
while (1) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void __outb__(uint16_t port, uint8_t data) {
|
||||||
|
register uint16_t p asm("dx") = port;
|
||||||
|
register uint8_t d asm("al") = data;
|
||||||
|
asm volatile("outb %0, %1" ::"r"(d), "r"(p));
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint8_t __inb__(uint16_t port) {
|
||||||
|
register uint16_t p asm("dx") = port;
|
||||||
|
register uint8_t d asm("al");
|
||||||
|
asm volatile("inb %1, %0" : "=r"(d) : "r"(p));
|
||||||
|
return d;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void __delay__(int n) {
|
||||||
|
for (int i = 0; i < n; i++) {
|
||||||
|
asm volatile("");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t xferpara() {
|
||||||
|
uint8_t mosib = paracomm_nextbyte();
|
||||||
|
__outb__(kParallelDataPort, mosib);
|
||||||
|
__outb__(kParallelControlPort, 1);
|
||||||
|
__delay__(kParaDelay);
|
||||||
|
__outb__(kParallelControlPort, 0);
|
||||||
|
__delay__(kParaDelay);
|
||||||
|
uint8_t mison = __inb__(kParallelStatusPort) >> 4;
|
||||||
|
paracomm_feed(mison);
|
||||||
|
|
||||||
|
return paracomm_busy();
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t parasend(uint8_t* addr, uint8_t size) {
|
||||||
|
uint8_t i;
|
||||||
|
for (i = 0; i < size; i++) {
|
||||||
|
if (paracomm_send(addr[i])) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
dosdbt();
|
||||||
|
parasize = 0;
|
||||||
|
paracomm_init(paracb);
|
||||||
|
|
||||||
|
fat12_init(kFatAddr, kRootDirAddr);
|
||||||
|
|
||||||
|
uint16_t* int80v = kInt80Vector;
|
||||||
|
int80v[0] = (uint16_t)int80h;
|
||||||
|
int80v[1] = 0;
|
||||||
|
|
||||||
|
if (fat12_readfile("POLMON COM", kPolmonAddr)) {
|
||||||
|
die();
|
||||||
|
}
|
||||||
|
|
||||||
|
asm volatile("jmp *%0" ::"r"(kPolmonAddr));
|
||||||
|
}
|
||||||
84
polio.s
84
polio.s
@@ -5,6 +5,10 @@
|
|||||||
.section .init
|
.section .init
|
||||||
.global _start
|
.global _start
|
||||||
_start:
|
_start:
|
||||||
|
cli
|
||||||
|
mov ax, 0x2000 # stack address
|
||||||
|
mov sp, ax # ss should already be 0
|
||||||
|
sti
|
||||||
jmp main
|
jmp main
|
||||||
|
|
||||||
|
|
||||||
@@ -12,7 +16,7 @@ diskpointer = 0x1e*4
|
|||||||
dbtbase = 0x0500
|
dbtbase = 0x0500
|
||||||
|
|
||||||
.section .text.dosdbt
|
.section .text.dosdbt
|
||||||
.local dosdbt
|
.global dosdbt
|
||||||
dosdbt: # assumes es=0
|
dosdbt: # assumes es=0
|
||||||
push si
|
push si
|
||||||
push di
|
push di
|
||||||
@@ -36,8 +40,13 @@ dosdbt: # assumes es=0
|
|||||||
|
|
||||||
.section .text.int80stuff
|
.section .text.int80stuff
|
||||||
|
|
||||||
# near copy [param 2] bytes, es:[param 0] -> es:[param 1]
|
# near copy [param 2] bytes, ds:[param 0] -> ds:[param 1]
|
||||||
copy:
|
copy:
|
||||||
|
mov ax, [bp-14] # ds
|
||||||
|
mov es, ax
|
||||||
|
mov ds, ax
|
||||||
|
mov cl, 4
|
||||||
|
shl si, cl
|
||||||
mov si, [bp+0] # source
|
mov si, [bp+0] # source
|
||||||
mov di, [bp+2] # destination
|
mov di, [bp+2] # destination
|
||||||
mov cx, [bp+4] # length
|
mov cx, [bp+4] # length
|
||||||
@@ -103,51 +112,43 @@ formattrack:
|
|||||||
int 0x13
|
int 0x13
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
# params: ds:fname, ds:dest
|
||||||
readfile:
|
readfile:
|
||||||
|
mov si, [bp-14] # ds
|
||||||
|
mov cl, 4
|
||||||
|
shl si, cl
|
||||||
mov ax, [bp+0]
|
mov ax, [bp+0]
|
||||||
|
add ax, si
|
||||||
mov dx, [bp+2]
|
mov dx, [bp+2]
|
||||||
|
add dx, si
|
||||||
call fat12_readfile
|
call fat12_readfile
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
# params: ds:addr, size
|
||||||
|
sendpara:
|
||||||
|
mov si, [bp-14] # ds
|
||||||
|
mov cl, 4
|
||||||
|
shl si, cl
|
||||||
|
mov ax, [bp+0]
|
||||||
|
add ax, si
|
||||||
|
mov dx, [bp+2]
|
||||||
|
call parasend
|
||||||
|
ret
|
||||||
|
|
||||||
.section .rodata.polmon_str
|
# params: ds:addr, size
|
||||||
polmon_str: .ascii "POLMON COM"
|
recvpara:
|
||||||
polmon_addr = 0x1000
|
mov si, [bp-14] # ds
|
||||||
|
mov cl, 4
|
||||||
.section .text.main
|
shl si, cl
|
||||||
.global main
|
mov ax, [bp+0]
|
||||||
main:
|
add ax, si
|
||||||
cli
|
mov dx, [bp+2]
|
||||||
mov ax, 0x2000 # stack address
|
call paracomm_recv
|
||||||
mov sp, ax # ss should already be 0
|
ret
|
||||||
sti
|
|
||||||
call dosdbt
|
|
||||||
mov ax, 0x1a00 # first sector of first fat
|
|
||||||
mov dx, 0x1c00 # first sector of root dir
|
|
||||||
call fat12_init
|
|
||||||
|
|
||||||
mov si, 0x80*4
|
|
||||||
movw [si], offset int80h
|
|
||||||
movw [si+2], 0
|
|
||||||
|
|
||||||
mov ax, offset polmon_str
|
|
||||||
mov dx, polmon_addr
|
|
||||||
call fat12_readfile
|
|
||||||
test ax, ax
|
|
||||||
jnz 0f
|
|
||||||
|
|
||||||
jmp polmon_addr
|
|
||||||
0:
|
|
||||||
mov ax, 0x0e42
|
|
||||||
mov bh, 0
|
|
||||||
int 0x10
|
|
||||||
cli
|
|
||||||
hlt
|
|
||||||
|
|
||||||
.section .text.int80h
|
.section .text.int80h
|
||||||
|
.global int80h
|
||||||
int80h:
|
int80h:
|
||||||
push bx
|
|
||||||
push si
|
push si
|
||||||
push di
|
push di
|
||||||
push bp
|
push bp
|
||||||
@@ -163,8 +164,8 @@ int80h:
|
|||||||
xor ah, ah
|
xor ah, ah
|
||||||
mov si, ax
|
mov si, ax
|
||||||
mov bp, sp
|
mov bp, sp
|
||||||
lea bp, [bp + 18] # 12 for us, 6 for the interrupt
|
lea bp, [bp + 16] # 10 for us, 6 for the interrupt
|
||||||
call [int80h_table+si]
|
call cs:[int80h_table+si]
|
||||||
jmp 1f
|
jmp 1f
|
||||||
0:
|
0:
|
||||||
mov ax, -1
|
mov ax, -1
|
||||||
@@ -174,10 +175,8 @@ int80h:
|
|||||||
pop bp
|
pop bp
|
||||||
pop di
|
pop di
|
||||||
pop si
|
pop si
|
||||||
pop bx
|
|
||||||
iret
|
iret
|
||||||
|
|
||||||
|
|
||||||
.section .rodata.int80h
|
.section .rodata.int80h
|
||||||
int80h_table:
|
int80h_table:
|
||||||
.word offset copy # 0x00
|
.word offset copy # 0x00
|
||||||
@@ -185,5 +184,8 @@ int80h_table:
|
|||||||
.word offset writesector # 0x02
|
.word offset writesector # 0x02
|
||||||
.word offset formattrack # 0x03
|
.word offset formattrack # 0x03
|
||||||
.word offset readfile # 0x04
|
.word offset readfile # 0x04
|
||||||
|
.word offset recvpara # 0x05
|
||||||
|
.word offset sendpara # 0x06
|
||||||
|
.word offset xferpara # 0x07
|
||||||
|
|
||||||
int80h_entries = . - int80h_table
|
int80h_entries = . - int80h_table
|
||||||
|
|||||||
126
polmon.cc
126
polmon.cc
@@ -1,5 +1,6 @@
|
|||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
|
#include <cstring>
|
||||||
|
|
||||||
#ifndef WOZMON
|
#ifndef WOZMON
|
||||||
#define WOZMON 0
|
#define WOZMON 0
|
||||||
@@ -12,6 +13,8 @@
|
|||||||
#define INT80H 0
|
#define INT80H 0
|
||||||
#define SHOWTITLE 0
|
#define SHOWTITLE 0
|
||||||
#define BOOTSTRAP 0
|
#define BOOTSTRAP 0
|
||||||
|
#define LAUNCH 0
|
||||||
|
#define CTRLBREAK 0
|
||||||
#endif // WOZMON
|
#endif // WOZMON
|
||||||
|
|
||||||
#ifndef BACKSPACE
|
#ifndef BACKSPACE
|
||||||
@@ -38,6 +41,14 @@
|
|||||||
#define BOOTSTRAP 1
|
#define BOOTSTRAP 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef LAUNCH
|
||||||
|
#define LAUNCH 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef CTRLBREAK
|
||||||
|
#define CTRLBREAK 1
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
#if WOZMON
|
#if WOZMON
|
||||||
@@ -213,6 +224,97 @@ void Status(uint8_t status) {
|
|||||||
: "ax", "bh", "dx", "cx", "di", "cc");
|
: "ax", "bh", "dx", "cx", "di", "cc");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char toupper(char c) {
|
||||||
|
if (c >= 'a' && c <= 'z') {
|
||||||
|
return c - ('a' - 'A');
|
||||||
|
}
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
void tofatname(const char* name, char* fatname) {
|
||||||
|
for (int i = 0; i < 11; i++) {
|
||||||
|
if (*name == 0 || *name == '.') {
|
||||||
|
fatname[i] = ' ';
|
||||||
|
} else {
|
||||||
|
fatname[i] = toupper(*name++);
|
||||||
|
}
|
||||||
|
if (i == 7 && *name == '.') {
|
||||||
|
name++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void LaunchFile(const char* name) {
|
||||||
|
constexpr uint16_t kSegment = 0x200;
|
||||||
|
constexpr uint16_t kAddress = 0x100;
|
||||||
|
constexpr uint16_t kHeaderAddress = (kSegment << 4);
|
||||||
|
constexpr uint16_t kFlatAddress = (kSegment << 4) + kAddress;
|
||||||
|
constexpr uint8_t kTrampoline[] = { 0xe8, 0xfd, 0x00, 0xcb };
|
||||||
|
|
||||||
|
char fatname[11];
|
||||||
|
tofatname(name, fatname);
|
||||||
|
|
||||||
|
auto* ptr = reinterpret_cast<uint8_t*>(kHeaderAddress);
|
||||||
|
memcpy(ptr, kTrampoline, sizeof(kTrampoline));
|
||||||
|
|
||||||
|
asm volatile("mov %1, %%ax \n\t"
|
||||||
|
"push %%ax \n\t"
|
||||||
|
"mov %0, %%ax \n\t"
|
||||||
|
"push %%ax \n\t"
|
||||||
|
"mov $04, %%ah \n\t"
|
||||||
|
"int $0x80 \n\t"
|
||||||
|
"add $4, %%sp \n\t"
|
||||||
|
"mov %2, %%ax \n\t"
|
||||||
|
"mov %%ax, %%ds \n\t"
|
||||||
|
"mov %%ax, %%es \n\t"
|
||||||
|
"cli \n\t"
|
||||||
|
"mov %%ax, %%ss \n\t"
|
||||||
|
"mov %3, %%ax \n\t"
|
||||||
|
"xchg %%ax, %%sp \n\t"
|
||||||
|
"sti \n\t"
|
||||||
|
"push %%ax \n\t"
|
||||||
|
"lcall %2,$0 \n\t"
|
||||||
|
"xor %%ax, %%ax \n\t"
|
||||||
|
"mov %%ax, %%ds \n\t"
|
||||||
|
"mov %%ax, %%es \n\t"
|
||||||
|
"cli \n\t"
|
||||||
|
"pop %%sp \n\t"
|
||||||
|
"mov %%ax, %%ss \n\t"
|
||||||
|
"sti"
|
||||||
|
:: "rmi"(fatname),
|
||||||
|
"rmi"(kFlatAddress), "i"(kSegment), "i"(kHeaderAddress)
|
||||||
|
: "ax", "bx", "cx", "dx", "memory");
|
||||||
|
}
|
||||||
|
|
||||||
|
#if CTRLBREAK
|
||||||
|
|
||||||
|
constexpr uint16_t kCtrlBreakVector = (0x1b * 4);
|
||||||
|
|
||||||
|
extern "C" void cbreak();
|
||||||
|
asm(" .section .text.cbreak \n"
|
||||||
|
"cbreak: \n"
|
||||||
|
" xor %ax, %ax \n"
|
||||||
|
" mov %ds, %ax \n"
|
||||||
|
" cli \n"
|
||||||
|
" mov %ss, %ax \n"
|
||||||
|
" mov $0x2000, %sp \n"
|
||||||
|
" sti \n"
|
||||||
|
" pushf \n"
|
||||||
|
" push %ax \n"
|
||||||
|
" mov $0x1000, %ax \n"
|
||||||
|
" push %ax \n"
|
||||||
|
" mov $0x20, %al \n"
|
||||||
|
" out %al, $0x20 \n"
|
||||||
|
" iret \n");
|
||||||
|
|
||||||
|
void InstallCtrlBreak() {
|
||||||
|
auto vec = reinterpret_cast<void (**)()>(kCtrlBreakVector);
|
||||||
|
vec[0] = cbreak;
|
||||||
|
vec[1] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // CTRLBREAK
|
||||||
|
|
||||||
bool ParseCommand(const char* buf, uint16_t& cur_addr, uint16_t& cur_seg) {
|
bool ParseCommand(const char* buf, uint16_t& cur_addr, uint16_t& cur_seg) {
|
||||||
bool dump = true;
|
bool dump = true;
|
||||||
for (const char* ptr = buf; *ptr;) {
|
for (const char* ptr = buf; *ptr;) {
|
||||||
@@ -259,7 +361,20 @@ bool ParseCommand(const char* buf, uint16_t& cur_addr, uint16_t& cur_seg) {
|
|||||||
dump = false;
|
dump = false;
|
||||||
ClearScreen();
|
ClearScreen();
|
||||||
ptr++;
|
ptr++;
|
||||||
#endif
|
#endif // CLEARSCREENCMD
|
||||||
|
#if LAUNCH
|
||||||
|
} else if (*ptr == 'r') {
|
||||||
|
dump = false;
|
||||||
|
ptr++;
|
||||||
|
while (*ptr == ' ') {
|
||||||
|
ptr++;
|
||||||
|
}
|
||||||
|
int l = 0;
|
||||||
|
for (; ptr[l]; l++) {
|
||||||
|
}
|
||||||
|
LaunchFile(ptr);
|
||||||
|
ptr += l;
|
||||||
|
#endif // LAUNCH
|
||||||
} else if (*ptr == 'w') {
|
} else if (*ptr == 'w') {
|
||||||
dump = false;
|
dump = false;
|
||||||
uint16_t addr = cur_addr;
|
uint16_t addr = cur_addr;
|
||||||
@@ -296,7 +411,7 @@ void polmon() {
|
|||||||
|
|
||||||
ClearScreen();
|
ClearScreen();
|
||||||
#if SHOWTITLE
|
#if SHOWTITLE
|
||||||
puts("PolMon 0.2\r\n");
|
puts("PolMon for Workgroups 3.1\r\n");
|
||||||
#endif // SHOWTITLE
|
#endif // SHOWTITLE
|
||||||
DisplayPrompt();
|
DisplayPrompt();
|
||||||
|
|
||||||
@@ -339,7 +454,12 @@ void polmon() {
|
|||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
int main() { polmon(); }
|
int main() {
|
||||||
|
#if CTRLBREAK
|
||||||
|
InstallCtrlBreak();
|
||||||
|
#endif // CTRLBREAK
|
||||||
|
polmon();
|
||||||
|
}
|
||||||
|
|
||||||
#if BOOTSTRAP
|
#if BOOTSTRAP
|
||||||
__attribute__((section(".init"), noreturn, used)) void _start() {
|
__attribute__((section(".init"), noreturn, used)) void _start() {
|
||||||
|
|||||||
10
runcomm.asm
Normal file
10
runcomm.asm
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
CPU 8086
|
||||||
|
|
||||||
|
mov cx, 0x100
|
||||||
|
a:
|
||||||
|
mov ah, 0x07
|
||||||
|
int 0x80
|
||||||
|
test al, al
|
||||||
|
loopnz a
|
||||||
|
b:
|
||||||
|
ret
|
||||||
20
stdlib.c
20
stdlib.c
@@ -1,3 +1,6 @@
|
|||||||
|
#include <stdint.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
int getchar() {
|
int getchar() {
|
||||||
register char c asm("al");
|
register char c asm("al");
|
||||||
asm volatile("movb $0x00, %%ah\n\t"
|
asm volatile("movb $0x00, %%ah\n\t"
|
||||||
@@ -23,3 +26,20 @@ int puts(const char* s) {
|
|||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void* memcpy(void* dest, const void* src, size_t n) {
|
||||||
|
uint8_t* d = dest;
|
||||||
|
const uint8_t* s = src;
|
||||||
|
for (int i = 0; i < n; i++) {
|
||||||
|
d[i] = s[i];
|
||||||
|
}
|
||||||
|
return dest;
|
||||||
|
}
|
||||||
|
|
||||||
|
void* memset(void* ptr, int val, size_t len) {
|
||||||
|
uint8_t* p = ptr;
|
||||||
|
while (len--) {
|
||||||
|
*p++ = val;
|
||||||
|
}
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|||||||
13
trampoline.asm
Normal file
13
trampoline.asm
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
CPU 8086
|
||||||
|
|
||||||
|
src equ 0xf000
|
||||||
|
dest equ 0x0600
|
||||||
|
size equ 0x0600
|
||||||
|
|
||||||
|
_start:
|
||||||
|
mov cx, size
|
||||||
|
mov si, src
|
||||||
|
mov di, dest
|
||||||
|
rep movsb
|
||||||
|
mov ax, dest
|
||||||
|
jmp ax
|
||||||
Reference in New Issue
Block a user