Raspberry Pi Floppy emulator

A good friend passed on this link.  And what an amazing thing!

Floppy interface board

So basically a Raspberry Pi (which can be had for sub $50 USD), running a bare metal program can emulate the control signals of an Amiga floppy drive.  It reads disk files from a flash card, and serves them to the Amiga.  It can even kickstart an Amiga 1000.

I know that floppy emulators have been an on/off hot topic, but this is pretty interesting!

And of course it has a DIY angle to it as well.

Here is a video of it in action:

 

VIM the Virtual Machine debugger

I stumbled across this site a while back, but could never get it to run.  From the description VIM is:

..(vim) is a debugger, I can’t let a bad program take out the interrupt vectors, DOS, or whatever. Hence the “Virtual” in the name — VIM takes whatever memory it can get, and sets up the interpreter to use a “virtual” processor. So, when the interpreter uses Interrupts, DOS, etc, it’s using the virtual copy, so that a bad program destroying them won’t hurt VIM, the real DOS, real interrupt vectors, etc.

Which is very cool, unlike traditional debuggers which try to hide in memory, VIM executes outside of memory and is then invisible.  Unfortunately it is rather tied to ANCIENT hardware.  And executes better on an 8088/8086/80286 processor.  I thought I could run it on Qemu, but it’ll trap on the BIOS as it’ll have instructions outside of VIM’s understanding.  However using PCem’s 80286 emulation it’ll run fine.

VIM running MS-DOS

VIM running MS-DOS

Another interesting thing about VIM, is that it includes the full source code, which is built with Aztec/C, however it doesn’t build cleanly as you have to finagle some of the assembly.

Running this on PCem is quite nice, as you can set it for a FAST 80286 computer, so it won’t take 10 minutes to boot a virtual copy of MS-DOS.

Is this useful? Well maybe if you feel the need to write an MS-DOS device driver, VIM can debug it.. but otherwise, it is an interesting fossil.

Linux on the VAX

I don’t know how I missed this thing!

$ cat lvax
load -r ka655.bin
set rq0 ra92
att rq0 /tmp/vmlinux.dsk
att xq dummy0
boot cpu
$ ./vax lvax

MicroVAX 3900 simulator V4.0-0 Beta git commit id: 55c5d205

KA655-B V5.3, VMB 2.7
Performing normal system tests.
40..39..38..37..36..35..34..33..32..31..30..29..28..27..26..25..
24..23..22..21..20..19..18..17..16..15..14..13..12..11..10..09..
08..07..06..05..04..03..
Tests completed.
>>>show dev
UQSSP Disk Controller 0 (772150)
-DUA0 (RA92)
-DUA1 (RD54)
-DUA2 (RD54)
-DUA3 (RX50)

UQSSP Tape Controller 0 (774500)
-MUA0 (TK50)
-MUA1 (TK50)
-MUA2 (TK50)
-MUA3 (TK50)

RLV12 Controller 0 (774400)
-DLA0 (RL01)
-DLA1 (RL01)
-DLA2 (RL01)
-DLA3 (RL01)

Ethernet Adapter 0 (774440)
-XQA0 (08-00-2B-AA-BB-CC)
>>>boot dua0:
(BOOT/R5:0 DUA0

2..
-DUA0
1..0..

CPU type:
80004A04KA650
Boot Head.S loaded at address 00004A00
rpb/bootr5/ap/sp 00000000 00000000 00000344 00004800
relocated at phys address 00100307
CPU type: 0A000006 sidex: 01530302

Starting VM
Linux/VAX ([email protected])
KA650 sidex = 01530302
RPB info: l_pfncnt: 00007f98, .l_vmb_version: 0a000207 .l_badpgs: 00000000
Physical memory: 00007f98 HW pagelets, 00000ff3 pages (16332KB)
CPU type: KA650, SID: 00000000
VM: mapped physical from 80000000 to 80ff3000, iomap from 80ff3000
VM: vmalloc from 810f3000 to 814f3000
VM: ptemap from 814f4000 to 837f4000 for 64 processes
calling start_kernel…

Linux version 2.4.16 ([email protected]) (gcc version 2.95.2-linuxvax-dynamic-dev (CVS)) #28 Wed Feb 12 09:55:28 GMT 2003
kernel_cmd_line 80004a04
root=/dev/nfs ip=192.168.5.240:192.168.5.67:::vaxemu:eth0:none nfsroot=/mnt/redhat/vax_emu/vaxroot rw debug init=/bin/sh
VAXMM: Initialising mm layer for 64 tasks of size 64MB
VAXMM: system page table base 8020b800, length (bytes) 6fe80 length (ptes) 1bfa0
bootmap size = 00000200
calling free_bootmem(start=00001000, len=000ff000)
calling free_bootmem(start=0027c000, len=00d77000)
On node 0 totalpages: 4083
zone(0): 4083 pages.
zone(1): 0 pages.
zone(2): 0 pages.
Kernel command line: root=/dev/nfs ip=192.168.5.240:192.168.5.67:::vaxemu:eth0:none nfsroot=/mnt/redhat/vax_emu/vaxroot rw debug init=/bin/sh
Calibrating delay loop… 23.29 BogoMIPS
Memory: 14556k/16332k available
Dentry-cache hash table entries: 2048 (order: 2, 16384 bytes)
Inode-cache hash table entries: 1024 (order: 1, 8192 bytes)
Mount-cache hash table entries: 512 (order: 0, 4096 bytes)
Buffer-cache hash table entries: 1024 (order: 0, 4096 bytes)
Page-cache hash table entries: 4096 (order: 2, 16384 bytes)
POSIX conformance testing by UNIFIX
Linux NET4.0 for Linux 2.4
Based upon Swansea University Computer Society NET3.039
Starting kswapd
pty: 256 Unix98 ptys configured
Serial driver version 5.05c (2001-07-08) with no serial options enabled
block: 64 slots per queue, batch=16
RAMDISK driver initialized: 16 RAM disks of 4096K size 1024 blocksize
IO mapped phys addr 0x20088000, 0x0008 pages at virt 0x80ff3000 (IOMAP PTE index 0x0000)
ttyS0: Internal processor register console
IO mapped phys addr 0x20001000, 0x0001 pages at virt 0x80ffb000 (IOMAP PTE index 0x0008)
delqa qbus vector: 4 (0004, 0x0004)
Ethernet address in ROM: 08:00:2b:aa:bb:cc
NET4: Linux TCP/IP 1.0 for NET4.0
IP Protocols: ICMP, UDP, TCP
IP: routing cache hash table of 512 buckets, 4Kbytes
TCP: Hash tables configured (established 512 bind 512)
eth0: resetting DELQA… done
IP-Config: Guessing netmask 255.255.255.0
IP-Config: Complete:
device=eth0, addr=192.168.5.240, mask=255.255.255.0, gw=255.255.255.255,
host=vaxemu, domain=, nis-domain=(none),
bootserver=192.168.5.67, rootserver=192.168.5.67, rootpath=
NET4: Unix domain sockets 1.0/SMP for Linux NET4.0.
Looking up port of RPC 100003/2 on 192.168.5.67

I’m amazed that it runs this far under SIMH.  Sadly though disks are not supported on any of the SIMH models, as Linux relies on certain CPU models:

  • VAXstation 3100m76 (KA43 CPU)
  • VAXstation 3100m38 (KA42 CPU)

The project has moved from sourceforge, to a dedicated server.  Sadly it seems that it has been a few years between updates, but I guess someone could carry the torch….

QuakeWorld Clients

I thought Id’ take a few hours to update some builds based on the latest QWDOS source.

So I spent a few hours updating some QuakeWorld clients.. for reproducibility sakes, I built out the MS-DOS one and that worked fine.  The OS/2 one ‘works’ but the keyboard isn’t working.  Not so sure why not.  The Win32 version works fine, although I’m building with Visual C++ 4.0, and no assembly or DirectX.  Just straight GDI.

Next will be Linux with svgalib.

So my work is here.  I could go more into how to build, but I don’t know if anyone cares.

Emulating a Cray X-MP Supercomputer

I just saw this, and it looks incredibly awesome.  I didn’t know that early Cray’s were more in line with mainframes.  And the X-MP could reach speeds of 105Mhz with 16MB of ram back in 1982.

Talk about awesome!  Andras did an awesome job of recovering this lost gem of early supercomputing.

Building a super stock QuakeWorld server for Linux

I know this may sound silly, but I’m a silly person.  And yes, QuakeWorld used to build cleanly and fine on Linux.  However it doesn’t anymore, things have changed a *LOT* in the world of Linux, since the birth of QuakeWorld in 1996.  A different LIBC standard or two, and all kinds of other changes in the compiler.  Not to mention I have a x86_64 machine, and I want a pure 32bit binary, so the best way to go about that is to setup a 32bit virtual machine, and build from there.  I know I could cross compile, but on the otherhand I don’t want to install all this kind of crap on my server if I don’t have to.  So there is all kinds of reasons why you may want to build your own.  Not to mention if you are running Linux, but on a non x86 platform.  I guess the Raspberry Pi would be a good choice now that it is over two million units sold.

The first thing you need of course is the source code to Quake, from iD (my mirror).  Next you’ll need a more up to date Makefile.  I used the one from the LinuxGL-QuakeWorld-mini-HOWTO.  Don’t worry about the client stuff, it doesn’t matter the first thing it does anyways is build the server.

For the sake of preserving it, here is the makefile:

#
# QuakeWorld Makefile for Linux 2.0
#
# Apr '98 by Zoid <[email protected]>
#
# GNU Make required
#
# ELF only
#

MAINDIR=.

BUILD_RELEASE_DIR=bin
CLIENT_DIR=$(MAINDIR)/client
SERVER_DIR=$(MAINDIR)/server

CC=gcc
BASE_CFLAGS=-Wall -Dstricmp=strcasecmp -I$(CLIENT_DIR) -I$(SERVER_DIR)
RELEASE_CFLAGS=$(BASE_CFLAGS) -m486 -ffast-math -fexpensive-optimizations
GLCFLAGS=-DGLQUAKE -DGL_EXT_SHARED

LDFLAGS=-lm
XLDFLAGS=-L/usr/X11R6/lib -lX11 -lXext
GL_X11_LDFLAGS=-L/usr/X11R6/lib -lm -lGL -lX11 -lXext

DO_CC=$(CC) $(CFLAGS) -o $@ -c $<
DO_O_CC=$(CC) -O $(CFLAGS) -o $@ -c $<
DO_GL_CC=$(CC) $(CFLAGS) $(GLCFLAGS) -o $@ -c $<
DO_SERVER_CC=$(CC) -DSERVERONLY $(CFLAGS) -o $@ -c $<

DO_AS=$(CC) $(CFLAGS) -DELF -x assembler-with-cpp -o $@ -c $<
DO_GL_AS=$(CC) $(CFLAGS) $(GLCFLAGS) -DELF -x assembler-with-cpp -o $@ -c $<

#############################################################################
# SETUP AND BUILD
#############################################################################

TARGETS=$(BUILDDIR)/qwsv #$(BUILDDIR)/glqwcl.glx $(BUILDDIR)/qwcl.x11

build_release:
	@-mkdir $(BUILD_RELEASE_DIR) \
		$(BUILD_RELEASE_DIR)/client \
		$(BUILD_RELEASE_DIR)/glclient \
		$(BUILD_RELEASE_DIR)/server
	$(MAKE) targets BUILDDIR=$(BUILD_RELEASE_DIR) CFLAGS="$(RELEASE_CFLAGS)"

all: build_release

targets: $(TARGETS)

#############################################################################
# SERVER
#############################################################################

QWSV_OBJS = \
	 $(BUILDDIR)/server/pr_cmds.o \
	 $(BUILDDIR)/server/pr_edict.o \
	 $(BUILDDIR)/server/pr_exec.o \
	 $(BUILDDIR)/server/sv_init.o \
	 $(BUILDDIR)/server/sv_main.o \
	 $(BUILDDIR)/server/sv_nchan.o \
	 $(BUILDDIR)/server/sv_ents.o \
	 $(BUILDDIR)/server/sv_send.o \
	 $(BUILDDIR)/server/sv_move.o \
	 $(BUILDDIR)/server/sv_phys.o \
	 $(BUILDDIR)/server/sv_user.o \
	 $(BUILDDIR)/server/sv_ccmds.o \
	 $(BUILDDIR)/server/world.o \
	 $(BUILDDIR)/server/sys_unix.o \
	 $(BUILDDIR)/server/model.o \
	 $(BUILDDIR)/server/cmd.o \
	 $(BUILDDIR)/server/common.o \
	 $(BUILDDIR)/server/crc.o \
	 $(BUILDDIR)/server/cvar.o \
	 $(BUILDDIR)/server/mathlib.o \
	 $(BUILDDIR)/server/md4.o \
	 $(BUILDDIR)/server/zone.o \
	 $(BUILDDIR)/server/pmove.o \
	 $(BUILDDIR)/server/pmovetst.o \
	 $(BUILDDIR)/server/net_chan.o \
	 $(BUILDDIR)/server/net_udp.o

$(BUILDDIR)/qwsv : $(QWSV_OBJS)
	$(CC) $(CFLAGS) -o $@ $(QWSV_OBJS) $(LDFLAGS)

$(BUILDDIR)/server/pr_cmds.o :   $(SERVER_DIR)/pr_cmds.c
	$(DO_SERVER_CC)

$(BUILDDIR)/server/pr_edict.o :  $(SERVER_DIR)/pr_edict.c
	$(DO_SERVER_CC)

$(BUILDDIR)/server/pr_exec.o :   $(SERVER_DIR)/pr_exec.c
	$(DO_SERVER_CC)

$(BUILDDIR)/server/sv_init.o :   $(SERVER_DIR)/sv_init.c
	$(DO_SERVER_CC)

$(BUILDDIR)/server/sv_main.o :   $(SERVER_DIR)/sv_main.c
	$(DO_SERVER_CC)

$(BUILDDIR)/server/sv_nchan.o :  $(SERVER_DIR)/sv_nchan.c
	$(DO_SERVER_CC)

$(BUILDDIR)/server/sv_ents.o :   $(SERVER_DIR)/sv_ents.c
	$(DO_SERVER_CC)

$(BUILDDIR)/server/sv_send.o :   $(SERVER_DIR)/sv_send.c
	$(DO_SERVER_CC)

$(BUILDDIR)/server/sv_move.o :   $(SERVER_DIR)/sv_move.c
	$(DO_SERVER_CC)

$(BUILDDIR)/server/sv_phys.o :   $(SERVER_DIR)/sv_phys.c
	$(DO_SERVER_CC)

$(BUILDDIR)/server/sv_user.o :   $(SERVER_DIR)/sv_user.c
	$(DO_SERVER_CC)

$(BUILDDIR)/server/sv_ccmds.o :  $(SERVER_DIR)/sv_ccmds.c
	$(DO_SERVER_CC)

$(BUILDDIR)/server/world.o :     $(SERVER_DIR)/world.c
	$(DO_SERVER_CC)

$(BUILDDIR)/server/sys_unix.o :  $(SERVER_DIR)/sys_unix.c
	$(DO_SERVER_CC)

$(BUILDDIR)/server/model.o :     $(SERVER_DIR)/model.c
	$(DO_SERVER_CC)

$(BUILDDIR)/server/cmd.o :       $(CLIENT_DIR)/cmd.c
	$(DO_SERVER_CC)

$(BUILDDIR)/server/common.o :    $(CLIENT_DIR)/common.c
	$(DO_SERVER_CC)

$(BUILDDIR)/server/crc.o :       $(CLIENT_DIR)/crc.c
	$(DO_SERVER_CC)

$(BUILDDIR)/server/cvar.o :      $(CLIENT_DIR)/cvar.c
	$(DO_SERVER_CC)

$(BUILDDIR)/server/mathlib.o :   $(CLIENT_DIR)/mathlib.c
	$(DO_SERVER_CC)

$(BUILDDIR)/server/md4.o :       $(CLIENT_DIR)/md4.c
	$(DO_SERVER_CC)

$(BUILDDIR)/server/zone.o :      $(CLIENT_DIR)/zone.c
	$(DO_SERVER_CC)

$(BUILDDIR)/server/pmove.o :     $(CLIENT_DIR)/pmove.c
	$(DO_SERVER_CC)

$(BUILDDIR)/server/pmovetst.o :  $(CLIENT_DIR)/pmovetst.c
	$(DO_SERVER_CC)

$(BUILDDIR)/server/net_chan.o :  $(CLIENT_DIR)/net_chan.c
	$(DO_SERVER_CC)

$(BUILDDIR)/server/net_udp.o :   $(CLIENT_DIR)/net_udp.c
	$(DO_SERVER_CC)

#############################################################################
# CLIENT
#############################################################################

QWCL_OBJS = \
	$(BUILDDIR)/client/cl_demo.o \
	$(BUILDDIR)/client/cl_ents.o \
	$(BUILDDIR)/client/cl_input.o \
	$(BUILDDIR)/client/cl_main.o \
	$(BUILDDIR)/client/cl_parse.o \
	$(BUILDDIR)/client/cl_pred.o \
	$(BUILDDIR)/client/cl_tent.o \
	$(BUILDDIR)/client/cl_cam.o \
	$(BUILDDIR)/client/cmd.o \
	$(BUILDDIR)/client/common.o \
	$(BUILDDIR)/client/console.o \
	$(BUILDDIR)/client/crc.o \
	$(BUILDDIR)/client/cvar.o \
	$(BUILDDIR)/client/d_edge.o \
	$(BUILDDIR)/client/d_fill.o \
	$(BUILDDIR)/client/d_init.o \
	$(BUILDDIR)/client/d_modech.o \
	$(BUILDDIR)/client/d_part.o \
	$(BUILDDIR)/client/d_polyse.o \
	$(BUILDDIR)/client/d_scan.o \
	$(BUILDDIR)/client/d_sky.o \
	$(BUILDDIR)/client/d_sprite.o \
	$(BUILDDIR)/client/d_surf.o \
	$(BUILDDIR)/client/d_vars.o \
	$(BUILDDIR)/client/d_zpoint.o \
	$(BUILDDIR)/client/draw.o \
	$(BUILDDIR)/client/keys.o \
	$(BUILDDIR)/client/mathlib.o \
	$(BUILDDIR)/client/md4.o \
	$(BUILDDIR)/client/menu.o \
	$(BUILDDIR)/client/model.o \
	$(BUILDDIR)/client/net_chan.o \
	$(BUILDDIR)/client/net_udp.o \
	$(BUILDDIR)/client/nonintel.o \
	$(BUILDDIR)/client/pmove.o \
	$(BUILDDIR)/client/pmovetst.o \
	$(BUILDDIR)/client/r_aclip.o \
	$(BUILDDIR)/client/r_alias.o \
	$(BUILDDIR)/client/r_bsp.o \
	$(BUILDDIR)/client/r_draw.o \
	$(BUILDDIR)/client/r_edge.o \
	$(BUILDDIR)/client/r_efrag.o \
	$(BUILDDIR)/client/r_light.o \
	$(BUILDDIR)/client/r_main.o \
	$(BUILDDIR)/client/r_misc.o \
	$(BUILDDIR)/client/r_part.o \
	$(BUILDDIR)/client/r_sky.o \
	$(BUILDDIR)/client/r_sprite.o \
	$(BUILDDIR)/client/r_surf.o \
	$(BUILDDIR)/client/r_vars.o \
	$(BUILDDIR)/client/sbar.o \
	$(BUILDDIR)/client/screen.o \
	$(BUILDDIR)/client/skin.o \
	$(BUILDDIR)/client/snd_dma.o \
	$(BUILDDIR)/client/snd_mem.o \
	$(BUILDDIR)/client/snd_mix.o \
	$(BUILDDIR)/client/view.o \
	$(BUILDDIR)/client/wad.o \
	$(BUILDDIR)/client/zone.o \
	$(BUILDDIR)/client/cd_linux.o \
	$(BUILDDIR)/client/sys_linux.o \
	$(BUILDDIR)/client/snd_linux.o \

	QWCL_AS_OBJS = \
	$(BUILDDIR)/client/d_copy.o \
	$(BUILDDIR)/client/d_draw.o \
	$(BUILDDIR)/client/d_draw16.o \
	$(BUILDDIR)/client/d_parta.o \
	$(BUILDDIR)/client/d_polysa.o \
	$(BUILDDIR)/client/d_scana.o \
	$(BUILDDIR)/client/d_spr8.o \
	$(BUILDDIR)/client/d_varsa.o \
	$(BUILDDIR)/client/math.o \
	$(BUILDDIR)/client/r_aclipa.o \
	$(BUILDDIR)/client/r_aliasa.o \
	$(BUILDDIR)/client/r_drawa.o \
	$(BUILDDIR)/client/r_edgea.o \
	$(BUILDDIR)/client/r_varsa.o \
	$(BUILDDIR)/client/snd_mixa.o \
	$(BUILDDIR)/client/surf16.o \
	$(BUILDDIR)/client/surf8.o \
	$(BUILDDIR)/client/sys_dosa.o

QWCL_X11_OBJS = $(BUILDDIR)/client/vid_x.o

$(BUILDDIR)/qwcl.x11 : $(QWCL_OBJS) $(QWCL_AS_OBJS) $(QWCL_X11_OBJS)
	$(CC) $(CFLAGS) -o $@ $(QWCL_OBJS) $(QWCL_AS_OBJS) $(QWCL_X11_OBJS) \
		$(LDFLAGS) $(XLDFLAGS)

$(BUILDDIR)/client/cl_demo.o :        $(CLIENT_DIR)/cl_demo.c
	$(DO_CC)

$(BUILDDIR)/client/cl_ents.o :        $(CLIENT_DIR)/cl_ents.c
	$(DO_CC)

$(BUILDDIR)/client/cl_input.o :       $(CLIENT_DIR)/cl_input.c
	$(DO_CC)

$(BUILDDIR)/client/cl_main.o :        $(CLIENT_DIR)/cl_main.c
	$(DO_CC)

$(BUILDDIR)/client/cl_parse.o :       $(CLIENT_DIR)/cl_parse.c
	$(DO_CC)

$(BUILDDIR)/client/cl_pred.o :        $(CLIENT_DIR)/cl_pred.c
	$(DO_CC)

$(BUILDDIR)/client/cl_tent.o :        $(CLIENT_DIR)/cl_tent.c
	$(DO_CC)

$(BUILDDIR)/client/cl_cam.o :         $(CLIENT_DIR)/cl_cam.c
	$(DO_CC)

$(BUILDDIR)/client/cmd.o :            $(CLIENT_DIR)/cmd.c
	$(DO_CC)

$(BUILDDIR)/client/common.o :         $(CLIENT_DIR)/common.c
	$(DO_CC)

$(BUILDDIR)/client/console.o :        $(CLIENT_DIR)/console.c
	$(DO_CC)

$(BUILDDIR)/client/crc.o :            $(CLIENT_DIR)/crc.c
	$(DO_CC)

$(BUILDDIR)/client/cvar.o :           $(CLIENT_DIR)/cvar.c
	$(DO_CC)

$(BUILDDIR)/client/d_edge.o :         $(CLIENT_DIR)/d_edge.c
	$(DO_CC)

$(BUILDDIR)/client/d_fill.o :         $(CLIENT_DIR)/d_fill.c
	$(DO_CC)

$(BUILDDIR)/client/d_init.o :         $(CLIENT_DIR)/d_init.c
	$(DO_CC)

$(BUILDDIR)/client/d_modech.o :       $(CLIENT_DIR)/d_modech.c
	$(DO_CC)

$(BUILDDIR)/client/d_part.o :         $(CLIENT_DIR)/d_part.c
	$(DO_CC)

$(BUILDDIR)/client/d_polyse.o :       $(CLIENT_DIR)/d_polyse.c
	$(DO_CC)

$(BUILDDIR)/client/d_scan.o :         $(CLIENT_DIR)/d_scan.c
	$(DO_CC)

$(BUILDDIR)/client/d_sky.o :          $(CLIENT_DIR)/d_sky.c
	$(DO_CC)

$(BUILDDIR)/client/d_sprite.o :       $(CLIENT_DIR)/d_sprite.c
	$(DO_CC)

$(BUILDDIR)/client/d_surf.o :         $(CLIENT_DIR)/d_surf.c
	$(DO_CC)

$(BUILDDIR)/client/d_vars.o :         $(CLIENT_DIR)/d_vars.c
	$(DO_CC)

$(BUILDDIR)/client/d_zpoint.o :       $(CLIENT_DIR)/d_zpoint.c
	$(DO_CC)

$(BUILDDIR)/client/draw.o :           $(CLIENT_DIR)/draw.c
	$(DO_CC)

$(BUILDDIR)/client/keys.o :           $(CLIENT_DIR)/keys.c
	$(DO_CC)

$(BUILDDIR)/client/mathlib.o :        $(CLIENT_DIR)/mathlib.c
	$(DO_CC)

$(BUILDDIR)/client/md4.o :            $(CLIENT_DIR)/md4.c
	$(DO_CC)

$(BUILDDIR)/client/menu.o :           $(CLIENT_DIR)/menu.c
	$(DO_CC)

$(BUILDDIR)/client/model.o :          $(CLIENT_DIR)/model.c
	$(DO_CC)

$(BUILDDIR)/client/net_chan.o :       $(CLIENT_DIR)/net_chan.c
	$(DO_CC)

$(BUILDDIR)/client/net_udp.o :        $(CLIENT_DIR)/net_udp.c
	$(DO_CC)

$(BUILDDIR)/client/nonintel.o :       $(CLIENT_DIR)/nonintel.c
	$(DO_CC)

$(BUILDDIR)/client/pmove.o :          $(CLIENT_DIR)/pmove.c
	$(DO_CC)

$(BUILDDIR)/client/pmovetst.o :       $(CLIENT_DIR)/pmovetst.c
	$(DO_CC)

$(BUILDDIR)/client/r_aclip.o :        $(CLIENT_DIR)/r_aclip.c
	$(DO_CC)

$(BUILDDIR)/client/r_alias.o :        $(CLIENT_DIR)/r_alias.c
	$(DO_CC)

$(BUILDDIR)/client/r_bsp.o :          $(CLIENT_DIR)/r_bsp.c
	$(DO_CC)

$(BUILDDIR)/client/r_draw.o :         $(CLIENT_DIR)/r_draw.c
	$(DO_CC)

$(BUILDDIR)/client/r_edge.o :         $(CLIENT_DIR)/r_edge.c
	$(DO_CC)

$(BUILDDIR)/client/r_efrag.o :        $(CLIENT_DIR)/r_efrag.c
	$(DO_CC)

$(BUILDDIR)/client/r_light.o :        $(CLIENT_DIR)/r_light.c
	$(DO_CC)

$(BUILDDIR)/client/r_main.o :         $(CLIENT_DIR)/r_main.c
	$(DO_CC)

$(BUILDDIR)/client/r_misc.o :         $(CLIENT_DIR)/r_misc.c
	$(DO_CC)

$(BUILDDIR)/client/r_part.o :         $(CLIENT_DIR)/r_part.c
	$(DO_CC)

$(BUILDDIR)/client/r_sky.o :          $(CLIENT_DIR)/r_sky.c
	$(DO_CC)

$(BUILDDIR)/client/r_sprite.o :       $(CLIENT_DIR)/r_sprite.c
	$(DO_CC)

$(BUILDDIR)/client/r_surf.o :         $(CLIENT_DIR)/r_surf.c
	$(DO_CC)

$(BUILDDIR)/client/r_vars.o :         $(CLIENT_DIR)/r_vars.c
	$(DO_CC)

$(BUILDDIR)/client/sbar.o :           $(CLIENT_DIR)/sbar.c
	$(DO_CC)

$(BUILDDIR)/client/screen.o :         $(CLIENT_DIR)/screen.c
	$(DO_CC)

$(BUILDDIR)/client/skin.o :           $(CLIENT_DIR)/skin.c
	$(DO_CC)

$(BUILDDIR)/client/snd_dma.o :        $(CLIENT_DIR)/snd_dma.c
	$(DO_CC)

$(BUILDDIR)/client/snd_mem.o :        $(CLIENT_DIR)/snd_mem.c
	$(DO_CC)

$(BUILDDIR)/client/snd_mix.o :        $(CLIENT_DIR)/snd_mix.c
	$(DO_CC)

$(BUILDDIR)/client/view.o :           $(CLIENT_DIR)/view.c
	$(DO_CC)

$(BUILDDIR)/client/wad.o :            $(CLIENT_DIR)/wad.c
	$(DO_CC)

$(BUILDDIR)/client/zone.o :           $(CLIENT_DIR)/zone.c
	$(DO_CC)

$(BUILDDIR)/client/cd_linux.o :       $(CLIENT_DIR)/cd_linux.c
	$(DO_CC)

$(BUILDDIR)/client/sys_linux.o :      $(CLIENT_DIR)/sys_linux.c
	$(DO_CC)

$(BUILDDIR)/client/snd_linux.o :      $(CLIENT_DIR)/snd_linux.c
	$(DO_CC)

$(BUILDDIR)/client/d_copy.o :         $(CLIENT_DIR)/d_copy.s
	$(DO_AS)

$(BUILDDIR)/client/d_draw.o :         $(CLIENT_DIR)/d_draw.s
	$(DO_AS)

$(BUILDDIR)/client/d_draw16.o :       $(CLIENT_DIR)/d_draw16.s
	$(DO_AS)

$(BUILDDIR)/client/d_parta.o :        $(CLIENT_DIR)/d_parta.s
	$(DO_AS)

$(BUILDDIR)/client/d_polysa.o :       $(CLIENT_DIR)/d_polysa.s
	$(DO_AS)

$(BUILDDIR)/client/d_scana.o :        $(CLIENT_DIR)/d_scana.s
	$(DO_AS)

$(BUILDDIR)/client/d_spr8.o :         $(CLIENT_DIR)/d_spr8.s
	$(DO_AS)

$(BUILDDIR)/client/d_varsa.o :        $(CLIENT_DIR)/d_varsa.s
	$(DO_AS)

$(BUILDDIR)/client/math.o :           $(CLIENT_DIR)/math.s
	$(DO_AS)

$(BUILDDIR)/client/r_aclipa.o :       $(CLIENT_DIR)/r_aclipa.s
	$(DO_AS)

$(BUILDDIR)/client/r_aliasa.o :       $(CLIENT_DIR)/r_aliasa.s
	$(DO_AS)

$(BUILDDIR)/client/r_drawa.o :        $(CLIENT_DIR)/r_drawa.s
	$(DO_AS)

$(BUILDDIR)/client/r_edgea.o :        $(CLIENT_DIR)/r_edgea.s
	$(DO_AS)

$(BUILDDIR)/client/r_varsa.o :        $(CLIENT_DIR)/r_varsa.s
	$(DO_AS)

$(BUILDDIR)/client/snd_mixa.o :       $(CLIENT_DIR)/snd_mixa.s
	$(DO_AS)

$(BUILDDIR)/client/surf16.o :         $(CLIENT_DIR)/surf16.s
	$(DO_AS)

$(BUILDDIR)/client/surf8.o :          $(CLIENT_DIR)/surf8.s
	$(DO_AS)

$(BUILDDIR)/client/sys_dosa.o :       $(CLIENT_DIR)/sys_dosa.s
	$(DO_AS)

$(BUILDDIR)/client/vid_x.o : $(CLIENT_DIR)/vid_x.c
	$(DO_CC)

#############################################################################
# GL CLIENT
#############################################################################

GLQWCL_OBJS = \
	$(BUILDDIR)/glclient/cl_demo.o \
	$(BUILDDIR)/glclient/cl_ents.o \
	$(BUILDDIR)/glclient/cl_input.o \
	$(BUILDDIR)/glclient/cl_main.o \
	$(BUILDDIR)/glclient/cl_parse.o \
	$(BUILDDIR)/glclient/cl_pred.o \
	$(BUILDDIR)/glclient/cl_tent.o \
	$(BUILDDIR)/glclient/cl_cam.o \
	$(BUILDDIR)/glclient/cmd.o \
	$(BUILDDIR)/glclient/common.o \
	$(BUILDDIR)/glclient/console.o \
	$(BUILDDIR)/glclient/crc.o \
	$(BUILDDIR)/glclient/cvar.o \
	$(BUILDDIR)/glclient/keys.o \
	$(BUILDDIR)/glclient/mathlib.o \
	$(BUILDDIR)/glclient/md4.o \
	$(BUILDDIR)/glclient/menu.o \
	$(BUILDDIR)/glclient/net_chan.o \
	$(BUILDDIR)/glclient/net_udp.o \
	$(BUILDDIR)/glclient/nonintel.o \
	$(BUILDDIR)/glclient/pmove.o \
	$(BUILDDIR)/glclient/pmovetst.o \
	$(BUILDDIR)/glclient/r_part.o \
	$(BUILDDIR)/glclient/sbar.o \
	$(BUILDDIR)/glclient/skin.o \
	$(BUILDDIR)/glclient/snd_dma.o \
	$(BUILDDIR)/glclient/snd_mem.o \
	$(BUILDDIR)/glclient/snd_mix.o \
	$(BUILDDIR)/glclient/view.o \
	$(BUILDDIR)/glclient/wad.o \
	$(BUILDDIR)/glclient/zone.o \
	$(BUILDDIR)/glclient/cd_linux.o \
	$(BUILDDIR)/glclient/sys_linux.o \
	$(BUILDDIR)/glclient/snd_linux.o \
	\
	$(BUILDDIR)/glclient/gl_draw.o \
	$(BUILDDIR)/glclient/gl_mesh.o \
	$(BUILDDIR)/glclient/gl_model.o \
	$(BUILDDIR)/glclient/gl_ngraph.o \
	$(BUILDDIR)/glclient/gl_refrag.o \
	$(BUILDDIR)/glclient/gl_rlight.o \
	$(BUILDDIR)/glclient/gl_rmain.o \
	$(BUILDDIR)/glclient/gl_rmisc.o \
	$(BUILDDIR)/glclient/gl_rsurf.o \
	$(BUILDDIR)/glclient/gl_screen.o \
	$(BUILDDIR)/glclient/gl_warp.o \
	\
	$(BUILDDIR)/glclient/math.o \
	$(BUILDDIR)/glclient/snd_mixa.o \
	$(BUILDDIR)/glclient/sys_dosa.o

GLQWCL_X11_OBJS = $(BUILDDIR)/glclient/gl_vidlinuxglx.o

$(BUILDDIR)/glqwcl.glx : $(GLQWCL_OBJS) $(GLQWCL_X11_OBJS)
	$(CC) $(CFLAGS) -o $@ $(GLQWCL_OBJS) $(GLQWCL_X11_OBJS) $(LDFLAGS) $(GL_X11_LDFLAGS)

$(BUILDDIR)/glclient/cl_demo.o :       $(CLIENT_DIR)/cl_demo.c
	$(DO_GL_CC)

$(BUILDDIR)/glclient/cl_ents.o :       $(CLIENT_DIR)/cl_ents.c
	$(DO_GL_CC)

$(BUILDDIR)/glclient/cl_input.o :      $(CLIENT_DIR)/cl_input.c
	$(DO_GL_CC)

$(BUILDDIR)/glclient/cl_main.o :       $(CLIENT_DIR)/cl_main.c
	$(DO_GL_CC)

$(BUILDDIR)/glclient/cl_parse.o :      $(CLIENT_DIR)/cl_parse.c
	$(DO_GL_CC)

$(BUILDDIR)/glclient/cl_pred.o :       $(CLIENT_DIR)/cl_pred.c
	$(DO_GL_CC)

$(BUILDDIR)/glclient/cl_tent.o :       $(CLIENT_DIR)/cl_tent.c
	$(DO_GL_CC)

$(BUILDDIR)/glclient/cl_cam.o :        $(CLIENT_DIR)/cl_cam.c
	$(DO_GL_CC)

$(BUILDDIR)/glclient/cmd.o :           $(CLIENT_DIR)/cmd.c
	$(DO_GL_CC)

$(BUILDDIR)/glclient/common.o :        $(CLIENT_DIR)/common.c
	$(DO_GL_CC)

$(BUILDDIR)/glclient/console.o :       $(CLIENT_DIR)/console.c
	$(DO_GL_CC)

$(BUILDDIR)/glclient/crc.o :           $(CLIENT_DIR)/crc.c
	$(DO_GL_CC)

$(BUILDDIR)/glclient/cvar.o :          $(CLIENT_DIR)/cvar.c
	$(DO_GL_CC)

$(BUILDDIR)/glclient/keys.o :          $(CLIENT_DIR)/keys.c
	$(DO_GL_CC)

$(BUILDDIR)/glclient/mathlib.o :       $(CLIENT_DIR)/mathlib.c
	$(DO_GL_CC)

$(BUILDDIR)/glclient/md4.o :           $(CLIENT_DIR)/md4.c
	$(DO_GL_CC)

$(BUILDDIR)/glclient/menu.o :          $(CLIENT_DIR)/menu.c
	$(DO_GL_CC)

$(BUILDDIR)/glclient/net_chan.o :      $(CLIENT_DIR)/net_chan.c
	$(DO_GL_CC)

$(BUILDDIR)/glclient/net_udp.o :       $(CLIENT_DIR)/net_udp.c
	$(DO_GL_CC)

$(BUILDDIR)/glclient/nonintel.o :      $(CLIENT_DIR)/nonintel.c
	$(DO_GL_CC)

$(BUILDDIR)/glclient/pmove.o :         $(CLIENT_DIR)/pmove.c
	$(DO_GL_CC)

$(BUILDDIR)/glclient/pmovetst.o :      $(CLIENT_DIR)/pmovetst.c
	$(DO_GL_CC)

$(BUILDDIR)/glclient/r_part.o :        $(CLIENT_DIR)/r_part.c
	$(DO_GL_CC)

$(BUILDDIR)/glclient/sbar.o :          $(CLIENT_DIR)/sbar.c
	$(DO_GL_CC)

$(BUILDDIR)/glclient/screen.o :        $(CLIENT_DIR)/screen.c
	$(DO_GL_CC)

$(BUILDDIR)/glclient/skin.o :          $(CLIENT_DIR)/skin.c
	$(DO_GL_CC)

$(BUILDDIR)/glclient/snd_dma.o :       $(CLIENT_DIR)/snd_dma.c
	$(DO_GL_CC)

$(BUILDDIR)/glclient/snd_mem.o :       $(CLIENT_DIR)/snd_mem.c
	$(DO_GL_CC)

$(BUILDDIR)/glclient/snd_mix.o :       $(CLIENT_DIR)/snd_mix.c
	$(DO_GL_CC)

$(BUILDDIR)/glclient/view.o :          $(CLIENT_DIR)/view.c
	$(DO_GL_CC)

$(BUILDDIR)/glclient/wad.o :           $(CLIENT_DIR)/wad.c
	$(DO_GL_CC)

$(BUILDDIR)/glclient/zone.o :          $(CLIENT_DIR)/zone.c
	$(DO_GL_CC)

$(BUILDDIR)/glclient/cd_linux.o :      $(CLIENT_DIR)/cd_linux.c
	$(DO_GL_CC)

$(BUILDDIR)/glclient/sys_linux.o :     $(CLIENT_DIR)/sys_linux.c
	$(DO_GL_CC)

$(BUILDDIR)/glclient/snd_linux.o :     $(CLIENT_DIR)/snd_linux.c
	$(DO_GL_CC)

$(BUILDDIR)/glclient/gl_draw.o :       $(CLIENT_DIR)/gl_draw.c
	$(DO_GL_CC)

$(BUILDDIR)/glclient/gl_mesh.o :       $(CLIENT_DIR)/gl_mesh.c
	$(DO_GL_CC)

$(BUILDDIR)/glclient/gl_model.o :      $(CLIENT_DIR)/gl_model.c
	$(DO_GL_CC)

$(BUILDDIR)/glclient/gl_ngraph.o :     $(CLIENT_DIR)/gl_ngraph.c
	$(DO_GL_CC)

$(BUILDDIR)/glclient/gl_refrag.o :     $(CLIENT_DIR)/gl_refrag.c
	$(DO_GL_CC)

$(BUILDDIR)/glclient/gl_rlight.o :     $(CLIENT_DIR)/gl_rlight.c
	$(DO_GL_CC)

$(BUILDDIR)/glclient/gl_rmain.o :      $(CLIENT_DIR)/gl_rmain.c
	$(DO_GL_CC)

$(BUILDDIR)/glclient/gl_rmisc.o :      $(CLIENT_DIR)/gl_rmisc.c
	$(DO_GL_CC)

$(BUILDDIR)/glclient/gl_rsurf.o :      $(CLIENT_DIR)/gl_rsurf.c
	$(DO_GL_CC)

$(BUILDDIR)/glclient/gl_screen.o :     $(CLIENT_DIR)/gl_screen.c
	$(DO_GL_CC)

$(BUILDDIR)/glclient/gl_vidlinux.o :   $(CLIENT_DIR)/gl_vidlinux.c
	$(DO_GL_CC)

$(BUILDDIR)/glclient/gl_vidlinuxglx.o :   $(CLIENT_DIR)/gl_vidlinuxglx.c
	$(DO_GL_CC)

$(BUILDDIR)/glclient/gl_warp.o :       $(CLIENT_DIR)/gl_warp.c
	$(DO_GL_CC)

$(BUILDDIR)/glclient/math.o :          $(CLIENT_DIR)/math.s
	$(DO_GL_AS)

$(BUILDDIR)/glclient/snd_mixa.o :      $(CLIENT_DIR)/snd_mixa.s
	$(DO_GL_AS)

$(BUILDDIR)/glclient/sys_dosa.o :      $(CLIENT_DIR)/sys_dosa.s
	$(DO_GL_AS)

#############################################################################
# MISC
#############################################################################

clean:
	rm -fr bin/client
	rm -fr bin/glclient
	rm -fr bin/server

With that saved into a file, it is time to build.  Unzip the source code into a directory, and then from the QW directory run the new Makefile.  If your GCC is new enough it’ll complain about the -m486 directive.  Just remove that from the Makefile.  On my bare build system it compiles the server in a few seconds, but then fails to build the GLQuake client because I don’t have any OpenGL installed.  But again this is fine, I just want the server.

gcc -Wall -Dstricmp=strcasecmp -I./client -I./server -ffast-math -fexpensive-optimizations -o bin/qwsv bin/server/pr_cmds.o bin/server/pr_edict.o bin/server/pr_exec.o bin/server/sv_init.o bin/server/sv_main.o bin/server/sv_nchan.o bin/server/sv_ents.o bin/server/sv_send.o bin/server/sv_move.o bin/server/sv_phys.o bin/server/sv_user.o bin/server/sv_ccmds.o bin/server/world.o bin/server/sys_unix.o bin/server/model.o bin/server/cmd.o bin/server/common.o bin/server/crc.o bin/server/cvar.o bin/server/mathlib.o bin/server/md4.o bin/server/zone.o bin/server/pmove.o bin/server/pmovetst.o bin/server/net_chan.o bin/server/net_udp.o -lm
gcc -Wall -Dstricmp=strcasecmp -I./client -I./server -ffast-math -fexpensive-optimizations -DGLQUAKE -DGL_EXT_SHARED -o bin/glclient/cl_demo.o -c client/cl_demo.c
In file included from client/quakedef.h:76:0,
from client/cl_demo.c:21:
client/glquake.h:22:0: warning: ignoring #pragma warning [-Wunknown-pragmas]
client/glquake.h:23:0: warning: ignoring #pragma warning [-Wunknown-pragmas]
client/glquake.h:24:0: warning: ignoring #pragma warning [-Wunknown-pragmas]
client/glquake.h:30:19: fatal error: GL/gl.h: No such file or directory
compilation terminated.
make[1]: *** [bin/glclient/cl_demo.o] Error 1
make[1]: Leaving directory `/root/QW’
make: *** [build_release] Error 2
root@debx867:~/QW#

And to verify the server:

root@debx867:~/QW# file bin/qwsv
bin/qwsv: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.26, BuildID[sha1]=0xa074d1a1c7b941da5e3a774eebc70f969c3347c7, not stripped

Ok, all good!

Now for running the server, I place my qwsv binary into somewhere more ‘server’ like say /usr/local/quake

root@debx867:~/QW# mkdir /usr/local/quake
root@debx867:~/QW# cp bin/qwsv /usr/local/quake/

The next part is to copy in the pak0.pak & pak1.pak from your registered copy of Quake 1 into /usr/local/quake/id1.  You can always buy it on steam, although it is so old I’m sure you’ve already acquired a copy or two in the last few years.  Note that pak0.pak is the shareware portion of the datafile!  To be a server you require pak1.pak from the registered copy of Quake.  Although the source to the maps has been released, I’m pretty sure you will be missing all kinds of otherthings from pak1.pak.

Ok now with the pak’s in place, you need the QuakeWorld scripts in place.  Copy the ‘progs’ directory into the qw directory

root@debx867:/usr/local/quake# mkdir qw
root@debx867:/usr/local/quake# cp $HOME/QW/progs/* qw

Now with all of this in place it is enough to run the server!

root@debx867:/usr/local/quake# ./qwsv
Added packfile ./id1/pak0.pak (339 files)
Added packfile ./id1/pak1.pak (85 files)
PackFile: ./id1/pak1.pak : gfx/pop.lmp
Playing registered version.
IP address 127.0.1.1:27500
UDP Initialized
Exe: 20:05:14 Nov 18 2013
16.0 megabyte heap

Server Version 2.40 (Build 5451)

======== QuakeWorld Initialized ========
FindFile: can’t find server.cfg
couldn’t exec server.cfg
PackFile: ./id1/pak0.pak : maps/start.bsp
FindFile: ./qw/qwprogs.dat
PackFile: ./id1/pak0.pak : maps/start.bsp
Building PHS…
Average leafs visible / hearable / total: 111 / 239 / 1128
PackFile: ./id1/pak0.pak : progs/player.mdl
PackFile: ./id1/pak0.pak : progs/eyes.mdl
Updated needpass.

However you probably will want a server.cfg.  And incase the page goes offline here is a pretty basic config:

sv_gamedir qw
deathmatch 1
hostname  ”Your Quake DM Server”
serverinfo admin  ”[email protected]”
serverinfo url “http://www.yourwebsite.com”
rcon_password change_me
timelimit 10
fraglimit 20
pausable 0
samelevel 2
maxclients 16
map dm1
floodprot 4 8 30
floodprotmsg “You have activated the flood protection and will be silenced for 30 seconds”
maxspectators 2
allow_download 1
allow_download_skins 1
allow_download_models 1
allow_download_sounds 1
allow_download_maps 1

Naturally you may want to change things.  Save the config file into the id1 directory.

Now when it comes to running the server, the console will want to be interactive to the user.  If you nohup the process it’ll go bezerk. The best way to do this is with screen.  In my /etc/rc.local I add the following line:

screen -dmS quake /usr/local/quake/quake.sh

And of course the shell script is:

#!/bin/bash
cd /usr/local/quake
while true
do true
./qwsv
done

Very simple stuff.  If the server crashes or stops for any reason it’ll restart.

By default QuakeWorld will listen on UDP port 27500.  The next thing you’ll need is a client to test.  I’m kind of partial to the MS-DOS (qemu) and OS/2 clients.

QuakeWorld in action!

QuakeWorld in action!

And there we go, now you too can host your own QuakeWorld server.  And for those who can’t compiler, you can try my x86 binary here.

You may want to add your server to gametracker.com.  Or just join mine.

Moving servers again..

FragReady!

FragReady!

(EDITED)* So it seems that Fragready just knee jerks to bogus virus claims by fly by night idiots like  clean-mx.de because they are terrified of nethack on WindowsCE.  Yes really they deleted my server because of an old game on an old platform.

So here we go. again.  2013 seems to be the year of plenty of moves.  While cruising around LEB, I came across this special on Frag Ready.  So yeah I’m going to collapse all my VPS stuff (once it is finished copying) and move everything to a dedicated server.

What I’m hoping this will mean is that I can do far more neater things as now I don’t have to worry about CPU limitations, blowing my own quotas or being able to load whatever I want.  I think I’ll even go back to offering some kind of public UNIX thing, I just have to decide if I want a SIMH VAX running BSD 4.3 UWisc, or whatever.  I know I’ll certainly bring the Quake 1 server back, and maybe, just maybe hack enough to get a Doom dialup server going (if I can convince it to talk to my fake modems).

Another observation is that using the new ext4 filesystem means things are slower than ever.  I know this server is two years old but still my seven year old Mac Pro destroyes it running Qemu vs running KVM on this linux box.  I’ve found the two things help for performance some.

Convert disk images from sparse VMDK to QCOW2

# qemu-img convert -f vmdk -O qcow2 -o preallocation=metadata source.vmdk destination.qcow2

And changing KVM from ‘-hda disk.vmdk’ to

kvm -cpu pentium -m 256 -drive file=/usr/local/kvm/disk.qcow2,if=ide,index=0,media=disk,cache=none -vnc :0 -net nic,model=pcnet -net user

Next was to change the way the volume was mounted.  First a change in the filesystem

tune2fs -o journal_data_writeback /dev/sda1

Then changing the options to the following in fstab:

noatime,data=writeback,barrier=0,nobh,errors=remount-ro

So yeah, it feels a little better now.

Here we go, again with what is moved over so far:

Crossover version 13 released today!

Or so I think, I got my alert while running some highly productive software..

From their announcement:

The focus of CrossOver 13.0.0 is better performance for games.
CrossOver 13.0.0 includes our new Performance Enhanced Graphics.  With
Performance Enhanced Graphics, CrossOver creates a dedicated thread
for graphics commands, making better use of the CPU and GPU.  During
in-house testing we have seen some frame rates double what they were
with earlier versions of CrossOver.

CrossOver 13.0.0 also includes numerous other enhancements for your
favorite Windows applications.  This release includes a new version of
Wine – the open source Windows API layer that makes your Windows
applications run.  On the Mac, CrossOver 13.0.0 includes several fixes
to our Mac Driver.  On Linux, we are now shipping multiarch packages
on Debian-based distributions, which should make for smoother
installation of CrossOver.

A changelog for CrossOver 13.0.0 is shown below.

Mac customers with active support entitlements will be upgraded to
Crossover 13 the next time they launch Crossover. Linux users can
download the latest version from http://www.codeweavers.com/.

If Crossover asks for registration use your codeweavers.com email
address & password to register and unlock Crossover. Email
[email protected] if you need more help.

Thank you all for your support, and we hope you enjoy CrossOver 13.0.0!

Changelog:
==========
CrossOver 13.0.0 – 11/12/2013

* Games Support:

o CrossOver 13 has our new Performance Enhanced Graphics. Games will run
faster, with higher frame rates! This is a major overhaul of the 3D
graphics processing in CrossOver, and gives significant improvements in
many, many popular games.
o The launcher for Borderlands 2 is working.
o Both the Gem Store and mouse work with Guild Wars 2.
o The mouse pointer in Terraria is now accurate when the window is resized or
zoomed.
o Rendering bugs with RIFT on NVIDIA hardware are fixed.
o Multi-core rendering can now be enabled in Source games.
o Mirror’s Edge now runs under CrossOver.

* Mac OS X:

o Input Managers will no longer cause Windows applications
running under CrossOver to crash.
o When you Command-Tab out of a full-screen program and then back,
CrossOver will restore that program’s display resolution setting.
o CrossOver uses accelerated OpenGL in all cases.
o Added support for Mac-style full-screen windows.
o Enhanced the system tray icon support to handle right-clicks and
middle-clicks.
o Fix a bug which could cause CrossOver to display two mouse
cursors in some applications.
o Lots of window management fixes.
o Fixed scrolling going diagonal when it shouldn’t.
o Fixed certain programs (e.g. Quicken 2013) failing to launch when
using certain keyboard layouts (e.g. US International PC).
o Fixed a bug where the select-bottle section of the Software Installer
window would say Please Wait forever.
o Improved icon extraction from Windows executables.

* Linux:

o Architecture specifications have been removed from our package installer
filenames. That is, our package installers filenames no longer include the
‘i386’ specifier. This is purely a cosmetic change in the filenames we ship
– some customers were confused, believing they needed a different installer
for 64-bit machines, which is not true after the switch to multiarch.
o Files saved with Microsoft Office are no longer marked as ‘executable,’
meaning they can be opened by clicking on them in Nautilus or other file
browsers.

* Application Support:

o Project 2010 will run faster.
o Macros function much better in Microsoft Excel.
o Access 2000 user interaction is smoother on OS X.
o The system tray for QQ is functional now on OS X.
o Kayak Foundry will load files again.
o Fixed a crash in the Chinese version of Microsoft Office Home and Student
Edition.

 

I’m one of the people who ‘flocked the vote‘ back in the day for a free version, and now I get new versions for something like $30 USD a year.  I know I could probably build wine on its own, but honestly even back in 1994 building wine was a PITA, and I’m too old to care about doing it now.  I just kinda want it to work.

PCem 0.7 and beyond

Checking out that javascript PCe made me want to check out PCem.  And good reason too, as its latest version 0.7 can run OS/2!

At first I tried version 2.0 and it just reboots once it is going to start the installer, (I haven’t tried a pre-installed disk image yet) but for the heck of it I shoved in an OS/2 1.1 boot diskette, and it came up!  So all excited I tried 1.21 and it worked as well!  The caveat is that OS/2 cannot partition or format the disk.  I didn’t try giving it a HPFS volume, but rather setup for a DualBoot with MS-DOS, and that worked fine.

OS/2 1.21 on PCem 0.7

OS/2 1.21 on PCem 0.7

Some of the cool things about PCem is that it runs REAL firmware, so you get the real XT/286/386/486 experience.  Also it is cycle accurate so things are SLOW like they were back in the day.  I’ve noticed that disk IO is really slow.  Again just like it was back then.  Things like DOOM take forever to load on a 386.  Just like the real thing!

If you have the ROMs the CGA/EGA & SVGA emulation is pretty good.   Again this is largely from running the actual firmware.

Work has slowed on PCem, but there is a source repo here.  I haven’t tried to build it yet.

The only thing I’d say is missing is some kind of ethernet adapter.  It would be cool to get this onto the internet.  But at the same time I’ve got to say this is pretty cool, especially if you want to enjoy the PC experience from 20 years ago, this is the way to go!  Although after a few minutes of running a 286 at 6Mhz, you’ll want to push for the fastest 486 it can emulate!