readme fix
[dosdemo] / README.md
1 Unnamed Mindlapse DOS demo for Pentium-era PCs
2 ----------------------------------------------
3 The demo uses VBE 320x240 16bpp. Some VBE implementations do not expose
4 double-scan video modes (240 lines), but can be made to work with a third-party
5 VBE TSR like `univbe` or `s3vbe`. Linear framebuffer (VBE 2.0) support is
6 recommended, but not necessary. The demo will fallback to VBE 1.2 banked modes
7 if LFB modes are not available.
8
9 Source structure
10 ----------------
11  - src/          cross-platform demo framework and miscellaneous utility code
12  - src/scr/      demo screens (parts) and effects support code
13  - src/dos/      DOS platform code
14  - src/glut/     GLUT platform code (windows/UNIX version)
15  - src/sdl/      SDL 1.x platform code (windows/UNIX version)
16  - libs/cgmath/  math library, header-file only
17  - libs/imago/   image loading library (includes libpng, zlib, libjpeg)
18  - libs/anim/    keyframe animation library
19
20 Building on DOS with Watcom
21 ---------------------------
22 Make sure you have Watcom or OpenWatcom installed, and the appropriate env-vars
23 set (the watcom installer automatically adds them to autoexec.bat by default).
24
25 Run wmake to build. Needs dos4gw.exe in current dir.
26
27 OpenWatcom cross-compilation on UNIX
28 ------------------------------------
29 source owdev script with contents (change WATCOM var as necessary):
30
31   export WATCOM=$HOME/devel/ow
32   export PATH=$WATCOM/binl:$PATH
33   export INCLUDE=$WATCOM/h:$INCLUDE
34
35 Run wmake to build. Needs dos4gw.exe and wstub.exe in current dir or PATH
36
37 Simply running ./demo.exe might invoke magic of the ancients to start wine,
38 which will in turn start dosbox, which will execute the DOS binary! If the gods
39 are slumbering in valhalla, just typing `dosbox demo.exe` should do the trick.
40
41 Building with DJGPP
42 -------------------
43 The DJGPP port of GCC is the recommended toolchain to use for building the demo,
44 either natively or cross-compiled on UNIX.
45
46 For native DOS builds add the DJGPP bin directory to the path (usually
47 `c:\djgpp\bin`) and set the DJGPP environment variable to point to the
48 `djgpp.env` file.
49
50 For cross-compiling on UNIX simply source the `setenv` file which comes with
51 DJGPP, which will set the `PATH` and `DJDIR` variables as necessary.
52
53 In both cases, run `make -f Makefile.dj` to build. To run the resulting
54 `demo.exe` you'll need to copy `cwsdpmi.exe` to the same directory. You can find
55 it here: ftp://ftp.fu-berlin.de/pc/languages/djgpp/current/v2misc/csdpmi7b.zip
56
57 When building natively on an old computer, and encounter a huge amount of disk
58 swapping, and corresponding ridiculously long compile times, make sure to
59 disable any memory managers and try again. `EMM386` may interfere with
60 `CWSDPMI`'s ability to use more than 32mb of RAM, and modern versions of GCC
61 need way more than that. Disable the memory manager with `emm386 off`, and
62 verify the amount of usable RAM with `go32-v2`.
63
64 Another problem is the MS-DOS version of `HIMEM.SYS` which only reports up to
65 64mb. To use more than that, which is necessary for modern versions of GCC, you
66 can either disable `HIMEM.SYS` completely, or use the `HIMEM.SYS` driver that
67 comes with Windows 9x (DOS >= 7). Here's a copy in case you need it:
68 http://mutantstargoat.com/~nuclear/tmp/d7himem.sys
69
70
71 Building and running with the SDL backend
72 -----------------------------------------
73 Run make to build (assuming make on your system is GNU make), or use the visual
74 studio 2013 project on Windows.
75
76 The SDL backend will scale the framebuffer up, by the factor specified in the
77 `FBSCALE` environment variable. So run the demo as: `FBSCALE=3 ./demo` for
78 a 3x scale factor, or just export the `FBSCALE` env var in the shell you are
79 going to use for running the demo. The default scale factor is 2x.
80
81 Datafiles
82 ---------
83 The demo datafiles are in their own subversion repo. To checkout the data files
84 run the following in the demo root directory:
85
86   svn co svn://mutantstargoat.com/datadirs/dosdemo data
87
88 Random optimization details about the Pentium1 (p54c)
89 -----------------------------------------------------
90 Use cround64 (util.h) for float -> integer conversions, instead of casts.
91
92 Performance measurement with RDTSC:
93     perf_start();
94     /* code under test */
95     perf_end(); /* result in perf_interval_count */
96
97 Cache organization (L1): 8kb data / 8kb instruction
98 128 sets of 2 cache lines, 32 bytes per cache line.
99
100 Addresses which are multiples of 4096 fall in the same set and can only have
101 two of them in cache at any time.
102
103 U/V pipe pairing rules:
104  - both instructions must be simple
105  - no read-after-write or write-after-write reg dependencies
106  - no displacement AND immediate in either instruction
107  - instr. with prefixes (except 0x0f) can only run on U pipe.
108  - prefixes are treated as separate 1-byte instructions (except 0x0f).
109  - branches can be paired if they are the second instr. of the pair only.
110
111 Simple instructions are:
112  - mov reg, reg/mem/imm
113  - mov mem, reg/imm
114  - alu reg, reg/mem/imm (alu: add/sub/cmp/and/or/xor)
115  - alu mem, reg/imm
116  - inc reg/mem
117  - dec reg/mem
118  - push reg/mem
119  - pop reg
120  - lea reg,mem
121  - jmp/call/jcc near
122  - nop
123  - test reg,reg/mem
124  - test acc,imm
125
126 U-only pairable instructions:
127  - adc, sbb
128  - shr, sar, shl, sal with immediate
129  - ror, rol, rcr, rcl with immediate=1
130
131 Notes about DJGPP & CWSDPMI
132 ---------------------------
133 Can't use the `hlt` instruction for waiting for interrupts, because we're
134 running in ring3 by default. I surrounded all the `hlt` instructions with a
135 `USE_HLT` conditional, which is undefined when building with DJGPP.
136
137 It's possible to arrange for our code to run on ring0 by changing the DPMI
138 provider from `cwsdpmi.exe` to `cwsdpr0.exe` by running:
139 `stubedit demo.exe dpmi=cwsdpr0.exe`, but I haven't tested under win9x to see if
140 it still works if we do that.
141
142 Our fucking segments don't start at 0 ... to access arbitrary parts of physical
143 memory we need to call `__djgpp_nearptr_enable()` and use the following macros I
144 defined in `cdpmi.h`:
145
146     #define virt_to_phys(v)     ((v) + __djgpp_base_address)
147     #define phys_to_virt(p)     ((p) - __djgpp_base_address)
148
149 Notes about moving code to/from a DOS computer
150 ----------------------------------------------
151 The easiest way to move code back and forth to a DOS computer, is to connect it
152 to the local network. For this you need a DOS packet driver for your NIC, which
153 thankfully most NIC vendors seem to provide, and a number of useful network
154 utilities which come with their own TCP/IP stack (mTCP and WATTCP). The
155 following are recommended:
156
157  - mTCP: http://www.brutman.com/mTCP
158  - WATTCP: http://www.watt-32.net
159  - ssh2dos: http://sshdos.sourceforge.net
160  - rsync: http://www.2net.co.uk/rsync.html
161
162 Here's an example batch file I'm using to set up the network:
163
164     @echo off
165     c:\net\rtspkt\rtspkt 0x61
166     set MTCPCFG=c:\net\mtcp\mtcp.cfg
167     set WATT_ROOT=c:\net\watt
168     set WATTCP.CFG=c:\net\watt\bin
169     set ETC=c:\net\watt\bin
170     set PATH=%PATH%;c:\net\mtcp;c:\net\watt\bin
171
172 The rtspkt program is the packet driver for my realtek NIC, and I'm instructing
173 it to use interrupt 61h. The rest are environment variables needed by mTCP and
174 WATTCP. If you run out of environment space you might need to increase it with
175 `SHELL=C:\DOS\COMMAND.COM /e:1024 /p` in `config.sys`, or just put all binaries
176 in a single place instead of adding multiple directories to the `PATH`.
177
178 ### mTCP configuration
179 The `mtcp.cfg` file configures the mTCP TCP/IP stack. Go through the file, which
180 comes with mTCP, and make any necessary changes. For instance I've set
181 `packetint 0x61` to match the packet driver interrupt, and I'm using static IP
182 assignments, so I've set it up like this:
183
184     ipaddr 192.168.0.21
185     netmask 255.255.0.0
186     gateway 192.168.1.1
187     nameserver 1.1.1.1
188
189 ### WATTCP configuration
190 The `wattcp.cfg` file is in the wattcp bin directory, and includes similar
191 configuration options:
192
193     my_ip = 192.168.0.21
194     hostname = "retrop1"
195     netmask = 255.255.0.0
196     nameserver = 1.1.1.1
197     gateway = 192.168.1.1
198     domain.suffix = localdomain
199     pkt.vector = 0x61
200     hosts = $(ETC)\hosts
201
202 ### Server-side configuration
203 The `pull.bat` file in the demo repo uses rsync to get the source code from the
204 git repo on my main GNU/Linux computer. To avoid having to type passwords all
205 the time, I've configures rsyncd to allow access to the demo directory in the
206 `/etc/rsyncd.conf` file:
207
208     [dosdemo]
209     path = /home/nuclear/code/demoscene/dosdemo
210     comment = DOS demo project
211
212 Since the DOS rsync utility is unfortunately read-only, the `push.bat` relies on
213 ssh2dos instead, which does require a password. The sshd on the server might
214 need to be configured to allow older encryption algorithms, depending on your
215 current setup.