dropped in the dos stuff master
authorJohn Tsiombikas <nuclear@mutantstargoat.com>
Tue, 18 Oct 2016 13:04:43 +0000 (16:04 +0300)
committerJohn Tsiombikas <nuclear@mutantstargoat.com>
Tue, 18 Oct 2016 13:04:43 +0000 (16:04 +0300)
.gitignore
Makefile.dos [new file with mode: 0644]
src/dos/main.c [new file with mode: 0644]
src/dos/serial.c [new file with mode: 0644]
src/unix/main.c

index a2793a8..714eb15 100644 (file)
@@ -1,4 +1,6 @@
 *.o
+*.obj
 *.swp
 *.d
 smouse
+*.exe
diff --git a/Makefile.dos b/Makefile.dos
new file mode 100644 (file)
index 0000000..44c1b2f
--- /dev/null
@@ -0,0 +1,24 @@
+obj = main.obj serial.obj device.obj dev_smag.obj vmath.obj
+bin = smouse.exe
+
+def = -dM_PI=3.141592653589793
+opt = -5 -fp5 -otexan -oh -oi -ei
+dbg = -d1
+
+incpath = -Isrc
+
+CC = wcc386
+CFLAGS = $(dbg) $(opt) $(def) -zq -bt=dos $(incpath)
+LD = wlink
+RM = del
+
+$(bin): $(obj)
+       *$(LD) debug all name $@ system dos4g file { $(obj) } $(LDFLAGS)
+
+.c: src;src/dos
+
+.c.obj: .autodepend
+       $(CC) -fo=$@ $(CFLAGS) $[*
+
+clean: .symbolic
+       $(RM) *.obj
diff --git a/src/dos/main.c b/src/dos/main.c
new file mode 100644 (file)
index 0000000..3945cd0
--- /dev/null
@@ -0,0 +1,97 @@
+#include <stdio.h>
+#include <math.h>
+#include <conio.h>
+#include "serial.h"
+#include "device.h"
+#include "vmath.h"
+
+void init_gfx(void);
+void destroy_gfx(void);
+int handle_dev_event(device_event *ev);
+
+vec3_t pos = {0, 0, -6};
+quat_t rot = {0, 0, 0, 1};     /* that's 1 + 0i + 0j + 0k */
+
+static struct device *dev;
+
+int main(void)
+{
+       int devfd;
+
+       register_all();
+       set_port("COM1");
+
+       if(!(dev = dev_init(0))) {
+               fprintf(stderr, "failed to initialize 6dof serial device at COM1\n");
+               return 1;
+       }
+       if((devfd = dev->start()) == -1) {
+               return 1;
+       }
+
+       init_gfx();
+
+       for(;;) {
+               device_event ev;
+
+               if(kbhit() && getch() == 27) {
+                       break;
+               }
+
+               while(dev->getevent(&ev)) {
+                       handle_dev_event(&ev);
+               }
+
+               /* redisplay */
+       }
+
+       dev->stop();
+       dev_destroy();
+       destroy_gfx();
+       return 0;
+}
+
+void init_gfx(void)
+{
+}
+
+void destroy_gfx(void)
+{
+}
+
+#define TX(ev) ((ev)->motion.motion[0])
+#define TY(ev) ((ev)->motion.motion[1])
+#define TZ(ev) ((ev)->motion.motion[2])
+#define RX(ev) ((ev)->motion.motion[3])
+#define RY(ev) ((ev)->motion.motion[4])
+#define RZ(ev) ((ev)->motion.motion[5])
+
+int handle_dev_event(device_event *ev)
+{
+       switch(ev->type) {
+       case DEV_EV_MOTION:
+               printf("t: %5d %5d %5d - r: %5d %5d %5d\n", TX(ev), TY(ev), TZ(ev),
+                               RX(ev), RY(ev), RZ(ev));
+               if(RX(ev) | RY(ev) | RZ(ev)) {
+                       float axis_len = sqrt(RX(ev) * RX(ev) + RY(ev) * RY(ev) + RZ(ev) * RZ(ev));
+                       if(axis_len != 0.0) {
+                               rot = quat_rotate(rot, axis_len * 0.001, -RX(ev) / axis_len,
+                                               -RY(ev) / axis_len, -RZ(ev) / axis_len);
+                       }
+               }
+
+               pos.x += TX(ev) * 0.001;
+               pos.y += TY(ev) * 0.001;
+               pos.z += TZ(ev) * 0.001;
+               break;
+
+       case DEV_EV_BUTTON:
+               if(ev->button.pressed) {
+                       pos = v3_cons(0, 0, -6);
+                       rot = quat_cons(1, 0, 0, 0);
+               }
+               break;
+       }
+
+       return 0;
+}
diff --git a/src/dos/serial.c b/src/dos/serial.c
new file mode 100644 (file)
index 0000000..55a863d
--- /dev/null
@@ -0,0 +1,363 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+#include <ctype.h>
+#include <dos.h>
+#include <conio.h>
+#include <i86.h>
+#include "serial.h"
+
+#define UART1_BASE     0x3f8
+#define UART2_BASE     0x2f8
+#define UART1_IRQ      4
+#define UART2_IRQ      3
+
+#define UART_DATA      0
+#define UART_INTR      1
+#define UART_DIVLO     0
+#define UART_DIVHI     1
+#define UART_FIFO      2
+#define UART_IID       2
+#define UART_LCTL      3
+#define UART_MCTL      4
+#define UART_LSTAT     5
+#define UART_MSTAT     6
+
+/* interrupt enable register bits */
+#define INTR_RECV      1
+#define INTR_SEND      2
+#define INTR_LSTAT     4
+#define INTR_DELTA     8
+
+/* fifo control register bits */
+#define FIFO_ENABLE            0x01
+#define FIFO_RECV_CLEAR        0x02
+#define FIFO_SEND_CLEAR        0x04
+#define FIFO_DMA               0x08
+#define FIFO_TRIG_4            0x40
+#define FIFO_TRIG_8            0x80
+#define FIFO_TRIG_14   0xc0
+
+/* interrupt id register bits */
+#define IID_PENDING            0x01
+#define IID_ID0                        0x02
+#define IID_ID1                        0x04
+#define IID_ID2                        0x08
+#define IID_FIFO_EN            0xc0
+
+#define IID_SOURCE             0xe
+
+#define IID_DELTA              0
+#define IID_SEND               0x2
+#define IID_RECV               0x4
+#define IID_FIFO               0xc
+#define IID_STATUS             0x6
+
+/* line control register bits */
+#define LCTL_BITS_8    0x03
+#define LCTL_STOP_2    0x04
+#define LCTL_DLAB      0x80
+#define LCTL_8N1       LCTL_BITS_8
+#define LCTL_8N2       (LCTL_BITS_8 | LCTL_STOP_2)
+
+/* modem control register bits */
+#define MCTL_DTR       0x01
+#define MCTL_RTS       0x02
+#define MCTL_OUT1      0x04
+#define MCTL_OUT2      0x08
+#define MCTL_LOOP      0x10
+
+/* line status register bits */
+#define LST_DRDY               0x01
+#define LST_ERR_OVER   0x02
+#define LST_ERR_PARITY 0x04
+#define LST_ERR_FRAME  0x08
+#define LST_ERR_BRK            0x10
+#define LST_TREG_EMPTY 0x20
+#define LST_TIDLE              0x40
+#define LST_ERROR              0x80
+
+/* modem status register bits */
+#define MST_DELTA_CTS  0x01
+#define MST_DELTA_DSR  0x02
+#define MST_TERI               0x04
+#define MST_DELTA_DCD  0x08
+#define MST_CTS                        0x10
+#define MST_DSR                        0x20
+#define MST_RING               0x40
+#define MST_DCD                        0x80
+
+/* interrupt controller stuff */
+#define PIC1_CMD_PORT  0x20
+#define PIC1_DATA_PORT 0x21
+#define PIC2_CMD_PORT  0xa0
+#define PIC2_DATA_PORT 0xa1
+#define OCW2_EOI               0x20
+
+#define COM_FMT_8N1            LCTL_8N1
+#define COM_FMT_8N2            LCTL_8N2
+
+struct serial_port {
+       int base, intr;
+       int blocking;
+
+       char inbuf[256];
+       int inbuf_ridx, inbuf_widx;
+};
+
+#define BNEXT(x)       (((x) + 1) & 0xff)
+#define BEMPTY(b)      (b##_ridx == b##_widx)
+
+static void ser_putc(int uart_base, char c);
+static void ser_puts(int uart_base, const char *s);
+static int ser_getc(int uart_base);
+static int have_recv(int base);
+static void __interrupt __far recv_intr(void);
+
+static struct serial_port ports[2];
+static int num_open;
+
+static int uart_base[] = {UART1_BASE, UART2_BASE};
+static int uart_irq[] = {UART1_IRQ, UART2_IRQ};
+
+static void (__interrupt __far *prev_recv_intr)(void);
+
+
+int ser_open(const char *port, int baud, unsigned int mode)
+{
+       unsigned char ctl;
+       unsigned short div = 115200 / baud;
+       int i, pidx, base, intr, fd;
+       unsigned int fmt;
+
+       if(toupper(port[0]) != 'C' || toupper(port[1]) != 'O' || toupper(port[2]) != 'M'
+                       || !isdigit(port[3])) {
+               fprintf(stderr, "ser_open: invalid com port: %s\n", port);
+               return -1;
+       }
+       pidx = port[3] - '0';
+       if(pidx < 1 || pidx > 2) {
+               fprintf(stderr, "ser_open: invalid com port: %d\n", pidx);
+               return -1;
+       }
+
+       if(ports[pidx].base) {
+               fprintf(stderr, "ser_open: port %d already open!\n", pidx);
+               return -1;
+       }
+       memset(ports + pidx, 0, sizeof ports[pidx]);
+
+       base = uart_base[pidx];
+       intr = uart_irq[pidx] | 8;
+
+       if(mode & SER_8N2) {
+               fmt = COM_FMT_8N2;
+       } else {
+               fmt = COM_FMT_8N1;
+       }
+
+       _disable();
+       if(!prev_recv_intr) {
+               prev_recv_intr = _dos_getvect(intr);
+               _dos_setvect(intr, recv_intr);
+       }
+       /* unmask the appropriate interrupt */
+       outp(PIC1_DATA_PORT, inp(PIC1_DATA_PORT) & ~(1 << uart_irq[pidx]));
+
+       outp(base + UART_LCTL, LCTL_DLAB);
+       outp(base + UART_DIVLO, div & 0xff);
+       outp(base + UART_DIVHI, (div >> 8) & 0xff);
+       outp(base + UART_LCTL, fmt);    /* fmt should be LCTL_8N1, LCTL_8N2 etc */
+       outp(base + UART_FIFO, FIFO_ENABLE | FIFO_SEND_CLEAR | FIFO_RECV_CLEAR);
+       outp(base + UART_MCTL, MCTL_DTR | MCTL_RTS | MCTL_OUT2);
+       outp(base + UART_INTR, INTR_RECV);
+
+       _enable();
+
+       ports[pidx].base = base;
+       ports[pidx].intr = intr;
+       ports[pidx].blocking = 1;
+       ++num_open;
+       return pidx;
+}
+
+void ser_close(int fd)
+{
+       if(--num_open == 0) {
+               _disable();
+               outp(ports[fd].base + UART_INTR, 0);
+               outp(ports[fd].base + UART_MCTL, 0);
+               _dos_setvect(ports[fd].intr, prev_recv_intr);
+               prev_recv_intr = 0;
+               _enable();
+       }
+
+       ports[fd].base = 0;
+}
+
+int ser_block(int fd)
+{
+       ports[fd].blocking = 1;
+       return 0;
+}
+
+int ser_nonblock(int fd)
+{
+       ports[fd].blocking = 0;
+       return 0;
+}
+
+int ser_pending(int fd)
+{
+       return !BEMPTY(ports[fd].inbuf);
+}
+
+/* if msec < 0: wait for ever */
+int ser_wait(int fd, long msec)
+{
+       int res;
+       while(!(res = ser_pending(fd))) {
+               delay(25);
+               if(msec >= 0) {
+                       if((msec -= 25) < 0) msec = 0;
+               }
+       }
+       return res;
+}
+
+static int can_send(int fd)
+{
+       int base = ports[fd].base;
+       return inp(base + UART_LSTAT) & LST_TREG_EMPTY;
+}
+
+static void ser_putc(int fd, char c)
+{
+       int base = ports[fd].base;
+       while(!can_send(fd));
+       while((inp(base + UART_MSTAT) & MST_CTS) == 0);
+       outp(base + UART_DATA, c);
+}
+
+static void ser_puts(int fd, const char *s)
+{
+       int base = ports[fd].base;
+       while(*s) {
+               ser_putc(fd, *s++);
+       }
+}
+
+static int ser_getc(int fd)
+{
+       struct serial_port *p = ports + fd;
+       int have, c = -1;
+
+       if(p->blocking) {
+               while(!(have = ser_pending(fd)));
+       } else {
+               have = ser_pending(fd);
+       }
+
+       if(have) {
+               c = p->inbuf[p->inbuf_ridx];
+               p->inbuf_ridx = BNEXT(p->inbuf_ridx);
+       }
+       return c;
+}
+
+int ser_write(int fd, const char *buf, int count)
+{
+       int n = count;
+       while(n--) {
+               ser_putc(fd, *buf++);
+       }
+       return count;
+}
+
+int ser_read(int fd, char *buf, int count)
+{
+       int c, n = 0;
+       while(n < count && (c = ser_getc(fd)) != -1) {
+               *buf++ = c;
+               ++n;
+       }
+       return n;
+}
+
+void ser_printf(int fd, const char *fmt, ...)
+{
+       static char buf[128];
+       va_list ap;
+
+       va_start(ap, fmt);
+       vsprintf(buf, fmt, ap);
+       va_end(ap);
+
+       ser_puts(fd, buf);
+}
+
+char *ser_getline(int fd, char *buf, int bsz)
+{
+       static char linebuf[512];
+       static int widx;
+       int i, rd, size, offs;
+
+       size = sizeof linebuf - widx;
+       while(size && (rd = ser_read(fd, linebuf + widx, size)) > 0) {
+               widx += rd;
+               size -= rd;
+       }
+
+       linebuf[widx] = 0;
+
+       for(i=0; i<widx; i++) {
+               if(linebuf[i] == '\r' || linebuf[i] == '\n') {
+                       size = i >= bsz ? bsz - 1 : i;
+                       memcpy(buf, linebuf, size);
+                       buf[size] = 0;
+
+                       offs = i + 1;
+                       memmove(linebuf, linebuf + offs, widx - offs);
+                       widx -= offs;
+                       return buf;
+               }
+       }
+       return 0;
+}
+
+static int have_recv(int base)
+{
+       unsigned short stat = inp(base + UART_LSTAT);
+       if(stat & LST_ERROR) {
+               fprintf(stderr, "receive error\n");
+               abort();
+       }
+       return stat & LST_DRDY;
+}
+
+static void __interrupt __far recv_intr()
+{
+       int i, idreg, c;
+
+       for(i=0; i<2; i++) {
+               int base = uart_base[i];
+               struct serial_port *p = ports + i;
+
+               while(((idreg = inp(base + UART_IID)) & IID_PENDING) == 0) {
+                       while(have_recv(base)) {
+                               c = inp(base + UART_DATA);
+
+                               p->inbuf[p->inbuf_widx] = inp(base + UART_DATA);
+                               p->inbuf_widx = BNEXT(p->inbuf_widx);
+
+                               if(p->inbuf_widx == p->inbuf_ridx) {
+                                       /* we overflowed, drop the oldest */
+                                       p->inbuf_ridx = BNEXT(p->inbuf_ridx);
+                               }
+                       }
+               }
+       }
+
+       outp(PIC1_CMD_PORT, OCW2_EOI);
+}
index a936a74..0e92c8e 100644 (file)
@@ -97,6 +97,8 @@ int main(void)
        }
 
 end:
+       dev->stop();
+       dev_destroy();
        destroy_gfx();
        XCloseDisplay(dpy);
        return 0;
@@ -154,7 +156,7 @@ int create_gfx(int xsz, int ysz)
 
        XSetWMProtocols(dpy, win, &wm_del_win, 1);
 
-       set_window_title("libspnav cube");
+       set_window_title("spacemouse cube");
 
        class_hint.res_name = "cube";
        class_hint.res_class = "cube";