Setting up a Nano Core War environment on a Asus Eee PC 701SD ============================================================= This notes file documents how I set up my 701SD to use to evolve warriors for the programming game Core War, where programs for a simplistic simulated processor battle one another. Much is written about Core War elsewhere, such as here: http://corewar.co.uk/ While the following info is specific to my 701SD and setup, the same general information should apply to any small x86 computer running Linux, particularly those with solid-state disks which can be damaged by repeated disk writes produced by core war evolvers and testing programs. This is not really a "how to" guide, it can be used that way but keep in mind every system is different and if blindly following "instructions" step by step without understanding, the process is likely to go wrong. Rather, this is to document my setup so that aspects can be applied to other setups, or in case I need to set it up again. The general idea is to minimize disk writes by running the evolver (such as rebs_nano.sh) on a ram disk, making sure all tools write temporary files to the temp file system which on the 701SD is in ram, and making sure the OS doesn't write excessively. Actually start with that first since that's important whether playing corewar or not. To minimize OS writes make sure the solid-state disk is mounted with the noatime option to avoid writing data every time a file is read, on my 701SD this meant sudo cp /etc/fstab /etc/fstab.was to make a backup, sudo nano /etc/fstab then changing options to options,noatime then saving the file (control-O) and exiting (control-X). The default might already be noatime but I want to make sure. Also on my system my .xsession-errors file was frequently being written to by everything that experienced the slightest GUI hiccup, plus is not humanly readable and not good for anything that I can tell, so I replaced it with a symlink to /dev/null by launching a terminal in my /home/user directory and entering rm .xsession-errors then: ln -s /dev/null .xsession-errors To keep the system from spiking the CPU and doing a disk write every few seconds I had to tell the network applet to not constantly poll for an ethernet connection. This doc assumes a regular KDE environment with repositories set so that Debian stable (etch) applications can be installed, that's an entirely different story with the 701SD as it comes with a "Easy Mode" shell that probably needs to be disabled to get much done (unless you like doing everything from a terminal and a single file manager window), and Asus doesn't exactly support the full KDE "Advanced" mode. On my system after doing an out-of-the-box update the required kicker and ksmserver packages were not in the default repositories, found them in the p701 section by surfing the repositories with a web browser, downloaded and installed the packages manually. After doing that the instructions on the Eee User Wiki (http://wiki.eeeuser.com/) worked for me, backed up and replaced /usr/bin/startfull.sh and /usr/bin/startsimple.sh with versions from the wiki, and in easy mode used Personalize to select full mode login. After that upon shutdown an option appears to boot to the full desktop, subsequent reboots boot to regular KDE. An Easy Mode icon appears on the KDE "Launch" menu but when I tried that (to set touchpad properties) it messed up the positions of all the icons on my desktop. Since then I ended up yanking out easy mode altogether after the system began complaining that asus-categories could not be set up... so I removed it (along with the easy mode program launcher - to get to the one thing I needed, the touchpad settings, I simply run gsynaptics from a menu entry I made). I used the wiki instructions to add repositories and edit the preferences file to "pin" the system-specific Asus versions, not all the repositories from the wiki worked, ended up using just... deb http://ftp.uk.debian.org/debian/ stable main contrib non-free ...plus the default repositories, kept the preferences settings intact. Newer Asus updates (like FireFox 3 / GTK 2.10) are not compatible with some Debian stable apps (like VLC that uses GTK 2.08). Yes, it's a mess but keep in mind Asus targets consumers and concentrates on making the supplied apps work, not supporting the whims of code hackers. To avoid issues I disabled updates altogether by uninstalling asus-updatesapplet and renaming /opt/xandros/bin/UpdateService to keep it from running. This is all on my system at one point in time, specifics will vary. In the end I have a very stable stripped down (fast) tiny GNU/Linux system on which I can do my thing just about anywhere, despite the work I absolutely love it. The default software is free, hack it into submission or install something else but despite dependency glitches the default Asus Xandros is very well integrated with the hardware and I tend to use older stuff anyway. Sometimes very old stuff. For my setup I use a lot of dos tools written in batch and QBasic to examine and test warrior code. Like I said I tend to use old stuff, and actually dos is modern compared to other stuff I run on my Eee PC. To handle line end conversions I installed "flip" so at the command line I can convert files to msdos format by entering flip -m filename or change to unix format using flip -u filename. Dos text files such as batch files need to be in msdos format, bash shell scripts and often data files (like warriors for REBS) need to be in unix format. The following text describes my setup, mostly copied from my raw notes mostly written 1/20/09. Some of the lines are long. ------- begin edited notes extract ------------------------------------------ [12/1/08] Setting up dosemu was pretty easy but still took the usual expected editing. Installed dosemu, dosemu-freedos and xfonts-dosemu, running xdosemu starts the system. By default the user home dir is the D: drive but I want all my dos stuff to be under its own dir with no access to the rest of the system, so added /home/user/dos and edited /usr/lib/freedos/autoexec.bat (or /etc/freedos/autoexec.bat) to this... ----- /etc/freedos/autoexec.bat (dos format) -------------- @echo off path c:\bin;c:\gnu;c:\dosemu set HELPPATH=c:\help set TEMP=c:\tmp set BLASTER=A220 I5 D1 H5 T6 prompt $P$G unix -s DOSDRIVE_D if "%DOSDRIVE_D%" == "" goto nodrived lredir d: linux\fs%DOSDRIVE_D%\dos :nodrived unix -s DOSTMP if "%DOSTMP%" == "" goto fidostmp if "%DOSDRIVE_D%" == "" goto dostmpd lredir e: linux\fs%DOSTMP% set TEMP=E:\ goto :fidostmp :dostmpd lredir d: linux\fs%DOSTMP% set TEMP=D:\ :fidostmp rem uncomment to load another bitmap font rem loadhi display con=(vga,437,2) rem mode con codepage prepare=((850) c:\cpi\ega.cpx) rem mode con codepage select 850 rem chcp 850 rem uncomment the following to load cdrom support rem shsucdx /d:mscd0001 unix -s DOSEMU_VERSION echo "Welcome to dosemu %DOSEMU_VERSION%!" d: call myauto.bat unix -e :: mods to this file... :: added \dos after %DOSDRIVE_D% :: added d: then call myauto.bat to add in custom commands :: put unix -e after call to myauto.bat so running commands :: via xdosemu "command" will search path set in myauto.bat ----- end of batch ---------------------------------------- [updated 1/24/09 to permit running batch files via xdosemu] BTW File Manager can't browse /usr /etc etc but only home and the underlying /.ro /.rw structures (unionfs) but Konqueror can go right to the logical dir names. [I made a shortcut to Konqueror on the desktop, with additional shortcuts that included a directory name to go to specific directories.] ..... This is for DosEmu 1.2.2, later DosEmu's do things differently using symbolic links to C: D: etc. ..... [1/20/09] Got my redcode scripts in place, at least for nano warriors. My FreeDos autoexec.bat wasn't right, couldn't run batches from the path. To fix moved the unix command to after a call to myauto.bat so the path would be set. Modified the testing and hill batches to use %temp% for temp files to keep them from writing to disk. The TEST benchmarker should be run on the ram disk so it'll write its temp files there. Here are the scripts and batch files I'm using and setup... DosEmu "D:" drive = /home/user/dos D:\EXEC (/home/user/dos/EXEC) in the PATH statement called by autoexec.bat /home/user/dos/args directory (D:\ARGS to dos) must exist (normally empty) Benchmark warriors in /home/user/dos/CWSTUFF/nanob2 (D:\CWSTUFF\NANOB2) Benchmark warriors in /home/user/dos/CWSTUFF/nanobm07 (D:\CWSTUFF\NANOBM07) Hill test warriors in /home/user/dos/CWSTUFF/hill80 (D:\CWSTUFF\HILL80) QBASIC.EXE, PMARS.EXE PMARSV.EXE and LIST.COM in /home/user/dos/EXEC TEST.EXE renamed to TEST.EX and put in /home/user/dos/CWSTUFF (to discourage from running on SSD, should only be run on ram disk) Linux binary for pmars in /usr/local/bin (version 0.8.6 or 0.9.2) Also have 0.8.6 pmarsv in /usr/local/bin but don't use it (yet). /home/user/rebs contains rebs_nano.sh (but don't run it there!) plus my working soups, notes, picks etc. REBS must be run from ram disk!!! Otherwise would quickly wear out the solid state disk as it writes roughly 50 blocks per second while evolving. Script to create ram disk... ----- /home/user/mkrd.sh ---------------------------------- #!/bin/bash if [ ! -e ~/rd/work ];then echo "Creating 25 meg (max) ramdisk with ~/rd/work directory" if [ ! -e ~/rd ];then mkdir ~/rd fi sudo mount -t ramfs none ~/rd -o maxsize=25000 && sudo mkdir ~/rd/work if [ -e ~/rd/work ];then sudo chmod 777 ~/rd/work sleep 2 else echo "Operation failed" echo "Press enter..." read nothing fi else echo "~/rd/work directory already exists" echo "Press enter..." read nothing fi ----- end of script --------------------------------------- A shortcut to this is on my desktop, set to run in a terminal. After running I put a symlink to /home/user/rd/work in my rebs dir for easy access to the ram disk for copying files soups etc back and forth, also put a symlink to /home/user/rd/work in /home/user/dos for easy access from dos for running the TEST benchmarker. Before shutting down un-mount the ram disk, I use this... ----- /home/user/unmountrd.sh ----------------------------- #!/bin/bash echo "" echo "This will remove the ram disk losing all contents" echo "Press enter to continue or control-c or close now" read nothing echo "Unmounting..." sudo umount ~/rd sleep 2 ----- end of script --------------------------------------- ...with a shortcut to it set to run in a terminal. Scripts to run the dos tools in DosEmu/FreeDos... ----- /usr/local/bin/pm80 --------------------------------- #!/bin/bash # older pmars used to support small coresize, -l and -d must be spec'd # to avoid segfault. 10 rounds to see what's happening (too fast). # linux version is still too fast... # pmarsv8 -l 5 -d 5 -s 80 -p 80 -c 800 -v 964 -r 10 $1 $2 $3 $4 $5 $6 $7 $8 # use dos version instead... w1=`basename "$1"` w2=`basename "$2"` w3=`basename "$3"` w4=`basename "$4"` w5=`basename "$5"` w6=`basename "$6"` w7=`basename "$7"` w8=`basename "$8"` cp -f $1 $2 $3 $4 $5 $6 $7 $8 ~/dos/args xdosemu "pmvnano $w1 $w2 $w3 $w4 $w5 $w6 $w7 $w8" rm -f ~/dos/args/*.red rm -f ~/dos/args/*.RED ----- end of script --------------------------------------- ----- /usr/local/bin/test80b2 ----------------------------- #!/bin/bash bn=`basename $1` cp -f $1 ~/dos/args xdosemu "test80b2 d:\\args\\$bn" rm -f ~/dos/args/$bn ----- end of script --------------------------------------- /usr/local/bin/testbm07 the same except for xdosemu call changed to: xdosemu "testbm07 d:\\args\\$bn" ----- /usr/local/bin/dohill80 ----------------------------- #!/bin/bash bn=`basename $1` if [ ! -e ~/dos/CWSTUFF/hill80/$bn ]; then cp $1 ~/dos/CWSTUFF/hill80 xdosemu "dohill80" rm -f ~/dos/CWSTUFF/hill80/$bn fi ----- end of script --------------------------------------- pm80, test80b2, testbm07 and dohill80 added to Launch menu using menu editor under Accessories, AssociateOnly, a new filetype added for Redcode files (text/x-redcode) *.red, pm80 test80b2 testbm07 dohill80 with Text Editor default associated with redcode type - found an icon that looks like corewar. These right clicks link to dos batch files... ----- /home/user/dos/EXEC/pmvnano.bat (dos format) -------- @echo off if .%1==. goto nowarriors if exist %1 goto runpmarsv D: cd \args if not exist %1 goto notfound :runpmarsv pmarsv -s 80 -p 80 -c 800 -l 5 -d 5 -r 10 -v 914 %1 %2 %3 %4 %5 %6 %7 %8 pause goto end :nowarriors echo no warrior(s) specified echo usage: %0 war1.red war2.red ... up to 8 total echo runs warriors in pmarsv, set for coresize 80 maxlength 5 goto end :notfound echo warrior not found :end ----- end of batch ---------------------------------------- ----- /home/user/dos/EXEC/test80b2.bat (dos format) ------- :: usage: testwar warrior [rounds] [outfile] :: charts warrior performance using qbasic :: coresize 80, processes 80, cycles 800 :: edit to specify test directory :: -f fixed sequence 1000 rounds :: 1/14/09 - use %temp% to write log/temps to ram :: 2/23/09 - formatted to permit more rounds, up to :: 2000 rounds looking nice, usable to 3333+ rounds @echo off if .%1==.Sub goto process if .%1==. echo no warrior specified if .%1==. goto end :: set to benchmark directory... set test=d:\cwstuff\nanob2 :: default rounds... set rnds=1000 if not .%2==. set rnds=%2 :: pmars command line... (for nano warriors, fixed sequence) set pmars=pmars -b -l 5 -d 5 -s 80 -p 80 -c 800 -r %rnds% -f :: rounds/pmars settings for nano's with -P option (pmars 0.9.2+) ::set rnds=142 ::set pmars=pmars092 -b -l 5 -d 5 -s 80 -p 80 -c 800 -r %rnds% -P :: listing program... (types if empty) set list=type50.bat if exist %1 goto fileok echo file not found goto end :fileok if exist %test%\*.red goto testok echo no test redcode goto end :testok echo Testing... rem>%temp%\battle$1.out for %%a in (%test%\*.red) do call %0 Sub %1 %%a del %temp%\score$$ ::echo>name.bat @echo off ::echo>>name.bat set name=%%1 find ";name"<%1>%temp%\getname$.bat call %temp%\getname$.bat del %temp%\getname$.bat ::del name.bat ::to avoid extra disk write add a fixed name.bat to a path dir... :: @echo off :: set name=%1 echo>%temp%\rank$.bas :on error goto X echo>>%temp%\rank$.bas open "%temp%\battle$1.out" for input as #1:open "%temp%\score$2" for output as #2 echo>>%temp%\rank$.bas ? #2, "Battle details for warrior %name%":? #2,"" echo>>%temp%\rank$.bas ? #2, "Opponent Scores Results Performance of %name%" echo>>%temp%\rank$.bas ? #2, "--------------- --------- ----------- ---------=---------=---------=---------=" echo>>%temp%\rank$.bas L:line input #1,a$:if instr(a$,"scores ")=0 goto L echo>>%temp%\rank$.bas line input #1,b$:line input #1,c$:if instr(a$,"%name%")=0 goto L echo>>%temp%\rank$.bas w$=left$(b$,instr(b$," by ")):w$=left$(w$+" ",15) echo>>%temp%\rank$.bas ms=val(right$(a$,len(a$)-instr(a$,"scores ")-6)):ts=ts+ms echo>>%temp%\rank$.bas os=val(right$(b$,len(b$)-instr(b$,"scores ")-6)):no=no+1 echo>>%temp%\rank$.bas ms$=left$(str$(ms)+" ",5):os$=left$(str$(os)+" ",5) echo>>%temp%\rank$.bas re$=right$(c$,len(c$)-8):re$=left$(re$+" ",13) echo>>%temp%\rank$.bas ? #2,w$;ms$;os$;re$;:if os+ms=0 or ms=0 goto N echo>>%temp%\rank$.bas ra=(ms/(%rnds%*3))*40:for z=1 to ra:? #2,"*";:next z echo>>%temp%\rank$.bas N:? #2,"":goto L echo>>%temp%\rank$.bas X:? #2,"--------------- --------- ----------- ---------=---------=---------=---------=" echo>>%temp%\rank$.bas if not no=0 then ? #2,"Adjusted Score:";int(((ts/no)/(%rnds%/100))*10)/10 echo>>%temp%\rank$.bas close #1:close #2:system qbasic /run %temp%\rank$.bas del %temp%\rank$.bas if not .%3==. copy score$2 %3>nul if not .%3==. goto notype if not .%list%==. call %list% %temp%\score$2 if not .%list%==. goto notype type %temp%\score$2|more pause :notype del %temp%\score$2 del %temp%\battle$1.out goto end :process >%temp%\score$$ %pmars% %2 %3 type %temp%\score$$ type %temp%\score$$>>%temp%\battle$1.out :end ----- end of batch ---------------------------------------- [updated 2/23/09 - list var is set to use batch below, good for benchmark sets of up to 40 or so warriors...] ----- /home/user/dos/EXEC/type50.bat (dos format) --------- @echo off mode con lines=50 cls type %1 pause ----- end of batch ---------------------------------------- /home/user/dos/EXEC/testbm07.bat the same except for bench dir, change to: set test=d:\cwstuff\nanobm07 and list program changed to list50.bat... ----- /home/user/dos/EXEC/list50.bat (dos format) --------- @echo off mode con lines=50 list %1 ----- end of batch ---------------------------------------- ----- /home/user/dos/EXEC/name.bat (dos format) ----------- @echo off set name=%1 ----- end of batch ---------------------------------------- ----- /home/user/dos/EXEC/dohill80.bat (dos format) ------- @echo off d: cd \CWSTUFF\hill80 hill80.bat ----- end of batch ---------------------------------------- ----- /home/user/dos/CWSTUFF/hill80/hill80.bat (dos format) :: run corewar hill - everyone plays everyone including self :: set to 200 rounds fixed sequence, 80-coresize specs :: operates on *.red files in current dir :: writes pmars score results to hill.out :: runs scorelog.bat to score results when done :: modified to use new scorelog 3rd parm to avoid :: over-scoring self battles :: 1/14/09 - modified to use %temp% to reduce writes on Eee PC @echo off if .%1==.sub goto %1%2 set pmarscl=pmars -b -l 5 -d 5 -s 80 -p 80 -c 800 -r 250 -f if exist %temp%\hill.out del %temp%\hill.out if exist %temp%\results.txt del %temp%\results.txt echo Running hill... do not press any keys... for %%a in (*.red) do call %0 sub 1 %%a del %temp%\battle.tmp call scorelog.bat %temp%\hill.out %temp%\results.txt x del %temp%\hill.out copy %temp%\results.txt scores.txt > nul list scores.txt goto end :sub1 for %%b in (*.red) do call %0 sub 2 %3 %%b goto end :sub2 %pmarscl% %3 %4 > %temp%\battle.tmp type %temp%\battle.tmp type %temp%\battle.tmp >> %temp%\hill.out :end ----- end of batch ---------------------------------------- ----- /home/user/dos/CWSTUFF/cptest.bat (dos format) ------ @echo off :: assumes \work points to ramdisk work dir if exist \work\test.exe goto change echo copying test.exe and benchmark sets to ramdisk \work md \work\nanobm07 md \work\nanob2 copy nanobm07\*.red \work\nanobm07 > nul copy nanob2\*.red \work\nanob2 > nul copy test.ex \work\test.exe > nul copy test.ini \work :change cd \work ----- end of batch ---------------------------------------- CPTEST copies the renamed TEST program and benchmark sets to the ramdisk (via symlink) to cut down on copying labor. Only rebs_nano.sh and the soup dir needs copying to evolve so I do that manually. The ramfs ramdisk always reports a size of 0 and causes KDE to complain but copies anyway after clicking the ignore button. After evolving interesting soups or warriors, changes to REBS etc are copied back to the rebs work dir. I didn't think it would before trying, but the 701SD makes a fine warrior evolution platform so long as disk writes can be minimized. After 3 days of use evolving and testing here's my stats... /home/user> uptime 14:38:36 up 3 days, 16:36, 1 user, load average: 0.02, 0.10, 0.05 /home/user> iostat Linux 2.6.21.4-eeepc (asus-71950145) 01/20/2009 avg-cpu: %user %nice %system %iowait %steal %idle 31.62 0.01 9.51 0.13 0.00 58.73 Device: tps Blk_read/s Blk_wrtn/s Blk_read Blk_wrtn sda 0.15 1.65 1.91 525536 609784 /home/user> df Filesystem 1K-blocks Used Available Use% Mounted on rootfs 4972972 3347340 1373012 71% / /dev/sda1 2766466 2627362 139104 95% /.ro /dev/sda2 4972972 3347340 1373012 71% /.rw none 4972972 3347340 1373012 71% / tmpfs 254120 12 254108 1% /dev/shm tmpfs 131072 2172 128900 2% /tmp /dev/sda1 2766466 2627362 139104 95% /ro /home/user> free total used free shared buffers cached Mem: 508240 388244 119996 0 97000 151812 -/+ buffers/cache: 139432 368808 Swap: 0 0 0 /home/user> Not bad. According to my flash life calculator... FLASH MEMORY LIFETIME CALCULATOR ENDURANCE RATING OF DEVICE ?10000 CAPACITY OF DRIVE IN GIGABYTES ?8 RESERVE CAPACITY IN PERCENT ?3 BLOCKS PER SECOND FROM IOSTAT ?1.91 FREE SPACE IN K FROM DF ?1373012 ESTIMATED LIFETIME IN YEARS: 67.4319 If that's even remotely close to right I have nothing to worry about. ----- end notes extract ----------------------------------------------------- 2/10/09 - I found out what was writing when running programs under DosEmu on my 701SD even when running on a ram disk, it was logging who knows to ~/.dosemu/boot.log whenever running TEST or other dos code that shells a lot. Fixed by doing... cd .dosemu mv boot.log boot.log.disabled ln -s /dev/null boot.log ...no more writes provided the app is running on a ram disk. . . . Hopefully this information is useful to some, however it is presented as-is and without warranty, use at your own risk. This file as a whole is copyright me, not for public duplication (in case I need to update it) but do whatever you want with my scripts in this file. The autoexec.bat file is a modified version of the file included with FreeDos package. This file last modified 2/23/09 Terry Newton (wtn90125@yahoo.com)