diff --git a/2004/gavin/.gitignore b/2004/gavin/.gitignore index c485d3bf1..4dcac4f64 100644 --- a/2004/gavin/.gitignore +++ b/2004/gavin/.gitignore @@ -1 +1,5 @@ +fs.tar gavin +kernel +sh +vi diff --git a/2004/gavin/Makefile b/2004/gavin/Makefile index 84ef098e4..df8860545 100644 --- a/2004/gavin/Makefile +++ b/2004/gavin/Makefile @@ -1,362 +1,356 @@ -#!/bin/make +#!/usr/bin/env make # -# 2004 makefile +# IOCCC 2004 winning entry - gavin + +################################################################################ # -# Copyright (C) 2004, Landon Curt Noll, Simon Cooper, Peter Seebach -# and Leonid A. Broukhis. All Rights Reserved. Permission for personal, -# educational or non-profit use is granted provided this copyright and -# notice are included in its entirety and remains unaltered. All other -# uses must receive prior permission from the contest judges. +# Regarding individual entries: +# +# IOCCC winning entry code may not work on your system. Even with standards, +# conditions and build environments change, especially when it comes to more +# extreme code such you might find in an IOCCC winner. Moreover, what was +# allowed and liked in one IOCCC contest may no longer be liked/allowed in +# later IOCCC years. +# +# Corrections on winning author and fixing typos in remarks are VERY WELCOME. +# +# GitHub pull requests are welcome: +# +# If you have a patch that might make running an entry work in modern Unix-like +# environments, please create a GitHub pull request for the IOCCC judges to +# consider. +# +# Suggestions and corrections regarding Makefiles, winning author information, +# fixing typos in remarks, and code patches are welcome via opening a GitHub +# issue or better yet, by creating a GitHub pull request for the IOCCC judges +# to consider. To form a GitHub issue or GitHub pull, please visit: +# +# https://github.com/ioccc-src/winner +# +################################################################################ + +# This work by Landon Curt Noll and Leonid A. Broukhis is licensed under: +# +# Creative Commons Attribution-ShareAlike 3.0 Unported License. +# +# See: http://creativecommons.org/licenses/by-sa/3.0/ -# tool locations +############################# +# shell used by this Makefile +############################# # -SHELL= /bin/sh -CP= cp -CPP= cpp -GUNZIP= gunzip -LD= ld -MAKE= make -RM= rm -SED= sed -TAR= tar -TRUE= true +SHELL= bash - -# Special flags for the gavin entry +####################### +# common tool locations +####################### # -# FYI: Older versions of GCC have a bug in -O2 optimization, hence -O1 -# -GAVIN_OPT= -O1 -GAVIN_FLAGS=\ - '-DY(m)=*((int*)(m))'\ - '-DE(f,a,b,c)=((G((*)))(f))(a,b,c)'\ - '-DM=for(D=0;D<786432;D++)'\ - '-DZ=int i=0,j=0,h,n,p=393728,s=26739,C,D'\ - '-DV=0x90200'\ - '-DK=0'\ - '-DR=while((C=E(V-8,100,0,0))&3&&(D=E(V-8,96,0,0))|3){'\ - '-DL(c,d)=E(V+8,100,c,0);R}E(V+8,96,d,0);R}' - +include ../../var.mk # Set X11_LIBDIR to the directory where the X11 library resides # -X11_LIBDIR= /usr/X11R6/lib +#X11_LIBDIR= /usr/X11R6/lib +#X11_LIBDIR= /usr/X11/lib +X11_LIBDIR= /opt/X11/lib -#CINCLUDE= -I ${HOMEBREW_PREFIX}/include/SDL2 +# Set X11_INCLUDEDIR to the directory where the X11 include files reside +# +#X11_INCDIR= /usr/X11R6/include +#X11_INCDIR= /usr/X11/include +X11_INCDIR= /opt/X11/include -# optimization +# Common C compiler warnings to silence +# +#CSILENCE= +CSILENCE= -Wno-bitwise-conditional-parentheses -Wno-bitwise-op-parentheses \ + -Wno-constant-conversion -Wno-error -Wno-implicit-function-declaration \ + -Wno-int-to-pointer-cast -Wno-parentheses -Wno-pointer-to-int-cast \ + -Wno-return-type -Wno-unused-parameter -Wno-unused-variable + +# Common C compiler warning flags +# +#CWARN= ${CSILENCE} +#CWARN= -Wall ${CSILENCE} +#CWARN= -Wall -Wextra ${CSILENCE} +CWARN= -Wall -Wextra -pedantic ${CSILENCE} + +# Compiler standard +# +#CSTD= +#CSTD= -ansi +CSTD= -std=gnu99 + +# Compiler bit architecture +# +# Some entries require 32-bitness: +# ARCH= -m32 +# +# Some entries require 64-bitness: +# ARCH= -m64 +# +# By default we assume nothing: +# +ARCH= + +# Defines that are needed to compile +# +#CDEFINE= +CDEFINE= '-DY(m)=*((int*)(m))' \ + '-DE(f,a,b,c)=((G((*)))(f))(a,b,c)' \ + '-DM=for(D=0;D<786432;D++)' \ + '-DZ=int i=0,j=0,h,n,p=393728,s=26739,C,D' \ + '-DV=0x90200' \ + '-DK=0' \ + '-DR=while((C=E(V-8,100,0,0))&3&&(D=E(V-8,96,0,0))|3){' \ + '-DL(c,d)=E(V+8,100,c,0);R}E(V+8,96,d,0);R}' + +# Include files that are needed to compile +# +CINCLUDE= +#CINCLUDE= -include stdlib.h +#CINCLUDE= -include stdio.h +#CINCLUDE= -include stdlib.h -include stdio.h +#CINCLUDE= -I ${X11_INCDIR} -I ${X11_INCDIR}/X11 +#CINCLUDE= `${SDL2_CONFIG} --cflags` + +# Optimization # # Most compiles will safely use -O2. Some can use only -O1 or -O. -# A few compilers have broken optimizers and thus you may -# not want anything. +# A few compilers have broken optimizers or this entry make break +# under those buggy optimizers and thus you may not want anything. +# Reasonable compilers will allow for -O3. # #OPT= #OPT= -O -#OPT= -O1 -OPT= -O2 +OPT= -O1 +#OPT= -O2 +#OPT= -O3 +# Default flags for ANSI C compilation +# +CFLAGS= ${CSTD} ${CWARN} ${ARCH} ${CDEFINE} ${CINCLUDE} ${OPT} -# flags for ANSI compiles +# Libraries needed to build # -# NOTE: Some ANSI compilers make use of -Xa to turn on ANSI mode, -# others such as gcc may want -ansi, others (Compaq Tru64 Unix) -# want -std1, and others may want nothing at all. -# Adjust the CFLAGS line as needed. -# -# NOTE: Some compilers cannot optimize, or optimize some entries -# incorrectly. You might want to turn on -O to see if your -# compiler can handle them. -# -# -#CFLAGS= -Xa ${OPT} -#CFLAGS= -std1 $(OPT) -CFLAGS= -ansi ${OPT} +LIBS= +#LIBS= -lm +#LIBS= -L ${X11_LIBDIR} -lX11 +#LIBS= `${SDL2_CONFIG} --libs` - -# ANSI compiler -# -# Set CC to the name of your ANSI compiler. -# -# Some entries seem to need gcc. If you have gcc, set -# both CC and MAY_NEED_GCC to gcc. -# -# If you do not have gcc, set CC to the name of your ANSI compiler, and -# set MAY_NEED_GCC to either ${CC} (and hope for the best) or to just : -# to disable such programs. +# C compiler to use # CC= cc -MAY_NEED_GCC= gcc +#CC=clang +#CC=gcc - -# 2004 winners +# Compiler add-ons or replacements for clang only # -WINNERS= anonymous arachnid burley gavare gavin hibachi hoyle jdalbec \ - kopczynski newbern omoikane schnitzi sds vik1 vik2 -CLEAN= anonymous_clean arachnid_clean burley_clean gavare_clean gavin_clean \ - hibachi_clean hoyle_clean jdalbec_clean kopczynski_clean \ - newbern_clean omoikane_clean schnitzi_clean sds_clean vik1_clean \ - vik2_clean -CLOBBER= anonymous_clobber arachnid_clobber burley_clobber gavare_clobber \ - gavin_clobber hibachi_clobber hoyle_clobber jdalbec_clobber \ - kopczynski_clobber newbern_clobber omoikane_clobber schnitzi_clobber \ - sds_clobber vik1_clobber vik2_clobber -ALT_NAMES= hoyle.orig kopczynski.orig -DATA_FILES= arachnid_files gavin_files hibachi_files kopczynski_files \ - newbern_files omoikane_files schnitzi_files - - -# default build +ifeq ($(CC),clang) # -all: ${WINNERS} - - -# Best use of "Precious" Lines +CSILENCE+= -Wno-comma -Wno-implicit-int-conversion -Wno-missing-prototypes \ + -Wno-poison-system-directories # -anonymous: anonymous.c - ${CC} anonymous.c -o anonymous - -anonymous_clean: - ${RM} -f anonymous.o - -anonymous_clobber: anonymous_clean - ${RM} -f anonymous - - -# Best use of Vision +CWARN+= -Weverything # -arachnid: arachnid.c - ${CC} -o arachnid -DL=LINES -DS=COLS \ - -DW=mvwaddch\(w,v,u,acs_map\[l\[m\[u arachnid.c -lncurses +endif -arachnid_clean: - ${RM} -f arachnid.o - -arachnid_clobber: arachnid_clean - ${RM} -f arachnid - -arachnid_files: arachnid.info - - -# Best Calculated Risk +# Specific add-ons or replacements for gcc only # -burley: burley.c - ${CC} -ansi burley.c -o burley - -burley_clean: - ${RM} -f burley.o - -burley_clobber: burley_clean - ${RM} -f burley - - -# Best Use of Light and Spheres +ifeq ($(CC),gcc) # -gavare: gavare.c - ${CC} -O3 gavare.c -o gavare - -gavare_clean: - ${RM} -f gavare.o - -gavare_clobber: gavare_clean - ${RM} -f gavare - - -# Best of Show +#CSILENCE+= # -gavin: gavin.c - ${CC} ${GAVIN_OPT} -o gavin ${GAVIN_FLAGS} gavin.c - ${RM} -f kernel - ./gavin > kernel - ${CC} ${GAVIN_OPT} -c ${GAVIN_FLAGS} -DB=_start '-Dputchar(a)=' gavin.c - ${RM} -f sh - ${LD} -s -o sh gavin.o - ${RM} -f vi - ${CP} sh vi - ${RM} -f fs.tar - ${TAR} -cvf fs.tar sh vi gavin.c gavin.hint prim - -gavin_clean: - ${RM} -f sh vi kernel gavin.o - -gavin_clobber: gavin_clean - ${RM} -f gavin fs.tar - -gavin_files: boot.b lilo.conf prim gavin_install.txt - - -# Best Abuse of the Guidelines +#CWARN+= # -hibachi: hibachi.tar.gz - ${RM} -f hibachi.tar - ${GUNZIP} < hibachi.tar.gz > hibachi.tar - ${TAR} -xvf hibachi.tar - ${RM} -f hibachi.tar - (cd hibachi && ${SHELL} ./configure) - ([ -f hibachi/makefile ] && cd hibachi && $(MAKE) -f makefile || true) - -hibachi_clean: - ${RM} -f hibachi/hibachi.o hibachi.tar - -hibachi_clobber: hibachi_clean - ${RM} -rf hibachi - -hibachi_files: hibachi.tar.gz +endif -# Most Functional Output +############################## +# Special flags for this entry +############################## # -hoyle: hoyle.c - ${CC} hoyle.c -o hoyle -lm - -hoyle.orig: hoyle.orig.c - ${CC} hoyle.orig.c -o hoyle.orig -lm - -hoyle_clean: - ${RM} -f hoyle.o hoyle.orig.o - -hoyle_clobber: hoyle_clean - ${RM} -f hoyle hoyle.orig - - -# Best Abuse of the Periodic Table +ENTRY= gavin +PROG= ${ENTRY} # -jdalbec: jdalbec.c - @${RM} -f jdalbec2.c - -${CC} -E jdalbec.c > jdalbec2.c - @${RM} -f jdalbec3.c - ${SED} -e 's/ (/(/g' < jdalbec2.c > jdalbec3.c - ${CC} -ansi jdalbec3.c -o jdalbec - -jdalbec_clean: - ${RM} -f jdalbec2.c jdalbec3.c jdalbec.o - -jdalbec_clobber: jdalbec_clean - ${RM} -f jdalbec - - -# Best one-liner +OBJ= ${PROG}.o +DATA= boot.b lilo.conf prim gavin_install.txt +TARGET= ${PROG} kernel sh vi fs.tar # -kopczynski: kopczynski.c - ${CC} -Dif=while kopczynski.c -o kopczynski - -kopczynski.orig: kopczynski.orig.c - ${CC} -Dif=while kopczynski.orig.c -o kopczynski.orig - -kopczynski_clean: - ${RM} -f kopczynski.o kopczynski.orig.o - -kopczynski_clobber: kopczynski_clean - ${RM} -f kopczynski kopczynski.orig - -kopczynski_files: kopczynski-10 kopczynski-11 kopczynski-8a kopczynski-8b \ - kopczynski-8c kopczynski-9 +ALT_OBJ= +ALT_TARGET= -# Best Font Engine +################# +# build the entry +################# # -newbern: newbern.c - ${CC} newbern.c -o newbern +all: data ${TARGET} + @${TRUE} -newbern_clean: - ${RM} -f newbern.o +.PHONY: all alt data everything clean clobber install \ + love haste waste maker easter_egg sandwich \ + supernova deep_magic magic charon pluto -newbern_clobber: newbern_clean - ${RM} -f newbern +${PROG}: ${PROG}.c + ${CC} ${CFLAGS} $< -o $@ ${LIBS} -newbern_files: newbern.dat +kernel: ${PROG} + ${RM} -f $@ + ./${PROG} > $@ +sh: ${PROG}.c + ${RM} -f ${PROG}.o + ${CC} ${CFLAGS} -DB=_start '-Dputchar(a)=' $< -c + ${RM} -f $@ + ${LD} -static -o $@ ${PROG}.o -# Best Utility +vi: sh + ${RM} -f $@ + ${CP} $< $@ + +fs.tar: sh vi gavin.c README.md prim + ${RM} -f $@ + ${TAR} -cvf $@ sh vi gavin.c README.md prim + +# alternative executable # -omoikane: omoikane.c - ${CC} -O omoikane.c -o omoikane +alt: data ${ALT_TARGET} + @${TRUE} -omoikane_clean: - ${RM} -f omoikane.o - -omoikane_clobber: omoikane_clean - ${RM} -f omoikane - -omoikane_files: omoikane.info - - -# Best Non-Use of Curses +# data files # -schnitzi: schnitzi.c - ${CC} schnitzi.c -o schnitzi +data: ${DATA} + @${TRUE} -schnitzi_clean: - ${RM} -f schnitzi.o - -schnitzi_clobber: schnitzi_clean - ${RM} -f schnitzi - -schnitzi_files: schnitzi.inp0 schnitzi.inp1 - - -# Best Abuse of Indentation +# both all and alt # -sds: sds.c - ${CC} -o sds sds.c - -sds_clean: - ${RM} -f sds_encoder.c sds_encoder.o sds.o - -sds_clobber: sds_clean - ${RM} -f sds sds_encoder - - -# Best X11 Game -# -vik1: vik1.c - ${CC} -ansi -O2 -o vik1 vik1.c -L${X11_LIBDIR} -lX11 - -vik1_clean: - ${RM} -f vik1.o - -vik1_clobber: vik1_clean - ${RM} -f vik1 - - -# Best Abuse of CPP -# -vik2: vik2.c - @${RM} -f vik2_1.c - ${CC} -E '-DSTOP=_5' '-DFNAME="vik2_1.c"' vik2.c > vik2_1.c - @${RM} -f vik2_2.c - ${CC} -E vik2_1.c > vik2_2.c - ${CC} -O vik2_2.c -o vik2 - -vik2_clean: - ${RM} -f vik2_1.c vik2_2.c vik2.o - -vik2_clobber: vik2_clean - ${RM} -f vik2 +everything: all alt +############### # utility rules +############### # -everything: ${WINNERS} ${ALT_NAMES} ${DATA_FILES} +clean: + ${RM} -f ${OBJ} ${ALT_OBJ} + ${RM} -f sh vi kernel gavin.o + @-if [ -f indent.c ]; then \ + echo ${RM} -f indent.c; \ + ${RM} -f indent.c; \ + fi +clobber: clean + ${RM} -f ${TARGET} ${ALT_TARGET} + ${RM} -f gavin fs.tar + @-if [ -e sandwich ]; then \ + ${RM} -f sandwich; \ + echo 'ate sandwich'; \ + fi + +install: + @echo "Dr. Spock says that is not logical!" + @${TRUE} + +# you may be able to misunderstand the source by reading indent.c +# +indent.c: ${PROG}.c + @if which "${GINDENT}" >/dev/null 2>&1; then \ + echo ${RM} -f $@; \ + ${RM} -f $@; \ + echo "${GINDENT} < $< > $@"; \ + ${GINDENT} < $< > $@; \ + elif which "${INDENT}" >/dev/null 2>&1; then \ + echo ${RM} -f $@; \ + ${RM} -f $@; \ + echo "${INDENT} < $< > $@"; \ + ${INDENT} < $< > $@; \ + else \ + echo "no intent tool found, ident $< yourself, sorry"; \ + echo "exit 1"; \ + exit 1; \ + fi + + +################## +# 133t hacker rulz +################## +# love: @echo 'not war?' + @${TRUE} haste: $(MAKE) waste - -waste: - @echo 'waste' - -clean: ${CLEAN} - ${RM} -f a.out core - -clobber: ${CLOBBER} - ${RM} -f ${WINNERS} - ${RM} -f ${ALT_NAMES} - -nuke: clobber @${TRUE} -install: all - ${CAT} ${WINNERS} ${ALT_NAMES} > /dev/null +waste: + @echo 'haste' + @${TRUE} + +maker: + @echo 'Participate in a maker faire' + @${TRUE} + +easter_egg: + @echo "you expected to often misunderstand this $${RANDOM} magic" + @echo "chongo '' /\\oo/\\" + @echo "Eggy" + +sandwich: easter_egg + @if [ `id -u` -eq 0 ]; then \ + echo 'Okay.'; \ + echo "$${RANDOM}`date +%s`$${RANDOM}" > $@; \ + else \ + echo 'What? Make it yourself.'; \ + exit 1; \ + fi + +# Understand the history of the Homebrew Computer Club +# as well as the West Coast Computer Faire and +# you might be confused different. :-) +# +supernova: sandwich + @-if [ -r .code_anal ]; then \ + ${RM} -f .code_anal_v6; \ + else \ + echo "planet deniers, like some members of the IAU, are so cute when they try to defend their logic"; \ + fi + @echo "A $@ helps ${MAKE} the elements that help form planets" + @${TRUE} + +deep_magic: supernova + @-if [ -r .code_anal ]; then \ + ccode_analysis --deep_magic 7889066cdbdf09b0408021754586e895be641cc9be29e7eafd3ca65359541f17 \ + --FNV1a_hash_512_bit -v2 "${PROG}" "${PROG}.c"; \ + else \ + echo "Wrong! Do it again!"; \ + sleep 2; \ + echo "Wrong! Do it again!"; \ + sleep 2; \ + echo "Wrong! Do it again!"; \ + fi + @${TRUE} + +magic: deep_magic + @-if [ -r .code_anal ]; then \ + ccode_analysis --level 20003 --mode 5717175 --FNV1a_hash_512_bit -v2 "${PROG}" "${PROG}.c"; \ + else \ + echo "If you don't eat yer meat, you can't have any pudding!"; \ + echo "How can you have any pudding if you don't eat yer meat?!"; \ + fi + @${TRUE} + +# The IOCCC resident astronomer states +# +charon: magic + @echo "$@ is a dwarf planet" + @echo "dwarf is a type of planet" + @echo "therefore IAU, $@ is a planet" + +pluto: charon + ${MAKE} charon + @echo "$@ is a dwarf planet" + @echo "dwarf is a type of planet" + @echo "therefore, $@ is a planet" + @echo "having lots of planets is good feature because supernovae can help ${MAKE} a lot of them" diff --git a/2004/gavin/README.md b/2004/gavin/README.md index 8d921cd09..14199951d 100644 --- a/2004/gavin/README.md +++ b/2004/gavin/README.md @@ -1,4 +1,4 @@ -Best of Show: +# Best of Show: Gavin Barraclough Flat 20, 83 Newton Street, @@ -7,134 +7,157 @@ Best of Show: U.K. -Judges' Comments: +# To build: - To build and run (on any platform, without root privileges): +```sh +make +``` - make gavin +### To run: - To enjoy the results (on a Linux/x86 machine): +```sh +./prog +``` - su +### Try: - # Make a floppy with an ext2 filesystem (mke2fs /dev/fd0), - # mount it under /mnt/floppy +To enjoy the results (on a Linux/x86 machine): - cp kernel fs.tar lilo.conf boot.b /mnt/floppy +```sh +su +``` - # If the version of your lilo is not 21.4, use the appropriate boot.b - # If your floppy drive is not /dev/fd0, edit lilo.conf appropriately - - lilo -C /mnt/floppy/lilo.conf - - # Boot from the floppy on an x86 machine with a PS/2 keyboard and mouse - # Move the window away from the corner - - vi gavin.c - - # Scroll the file with up-arrow and down-arrow - - sh - - # Can have several shell windows - - vi gavin.hint - prim - - # Press and hold any key - - Over the years, we've seen a program that dumps core - if executed on a "wrong" architecture immediately (1984/mullender), - or after a while (2001/bellard). This entry will happily compile and - execute on any architecture - the trick is that the result, to be useful, - must be produced (and can only be enjoyed) on a particular architecture. - We have not decided yet whether to disallow this for future contests. - - If you do not want to mess with a floppy and you use GRUB, see below - in the author's notes. - You can put additional text files in fs.tar for browsing with vi. - If you do not want to bother rebooting your computer at all, - see http://bellard.org/ for QEMU (Fabrice Bellard is an IOCCC 2001 winner), - but your experience will be limited (replace -DK=0 with -DK=1 in the Makefile, - and you will have to move the mouse to trigger the initial screen update). - - The judges were able to write a few more programs to run on this OS - What are the limitations for such programs? - What you can do and what you cannot do in such programs? - - The program called "prim", written by the judges, - computes and prints prime numbers. +Make a floppy with an ext2 filesystem (mke2fs /dev/fd0), mount it under /mnt/floppy. +Then: -Selected Author's Comments: +```sh +cp kernel fs.tar lilo.conf boot.b /mnt/floppy +``` - This is a 32-bit multitasking operating system for x86 computers, - with GUI and filesystem, support for loading and executing user - applications in elf binary format, with ps2 mouse and keyboard drivers, - and vesa graphics. And a command shell. And an application - - a simple text-file viewer. +NOTE: If the version of your lilo is not 21.4, use the appropriate boot.b file. - The OS has ended up as a traditional monolith with one entry point - for syscalls, with apps treated as cooperative-multitasking tasks - that can be sent different messages (e.g. 'initialize', 'key hit', - 'render to buffer') through their main entry point, and which will - return control to the OS having performed the necessary work. - Applications are are passed a pointer to their task structure, - which is partially defined by the OS, and partially for - the application's own use. +NOTE: If your floppy drive is not /dev/fd0, edit lilo.conf appropriately. - The program compiles into a tool to build a kernel image, - so having built the program, the makefile will run it, - piping the output into a file called 'kernel'. - The makefile will then proceed to build a root filesystem image. - This involves rebuilding the program with different compiler flags, - then building a tar file containing the resulting programs - (the filesystem format supported by the OS is the tar-file format). +```sh +lilo -C /mnt/floppy/lilo.conf +``` - For further usage information see 'gavin_install.txt'. +Boot from the floppy on an x86 machine with a PS/2 keyboard and mouse. +Move the window away from the corner. - The filenames 'vi' and 'sh' are significant, and should not be changed. +```sh +vi gavin.c +``` - Known 'features'. +Scroll the file with up-arrow and down-arrow - Known issues are really too plentiful to list. +```sh +sh +``` - If the mouse pointer goes off the left hand side of the screen - it will reappear on the right, and vice-versa. - If it goes off the top or bottom, it will go and corrupt some memory. +Can have several shell windows: - The file system is kinda optimistic about matching names, so, - for example if you type the command 'shell' into a command-line - it will execute the program 'sh' - close enough a match for it. +```sh +vi gavin.hint +./prim +``` - The elf binaries are not loaded at the correct address, - and their entry point must be the start address of the text segment. +Press and hold any key. - The keyboard driver can cope with the basic alpha-numeric keys, - but gets confused by fancy things like 'shift' or 'backspace'. +## Judges' comments: - In the text-file viewer, 'vi', the up/down and pgup/pgdn keys - scroll up or down by one line. There is nothing to stop you - [from] scrolling above the top of the file, and pressing any - other keys may have an undefined effect. +Over the years, we've seen a program that dumps core +if executed on a "wrong" architecture immediately (1984/mullender), +or after a while (2001/bellard). This entry will happily compile and +execute on any architecture - the trick is that the result, to be useful, +must be produced (and can only be enjoyed) on a particular architecture. +We have not decided yet whether to disallow this for future contests. - The x86 is bootstrapped into 32bit mode in 6 instructions, - with 4 more to set up data/stack segments and a stack-pointer - to allow C code to be run. On top of this there are also about - a dozen instructions to switch the video card into graphics mode. - All in all, a relatively tiny number of instructions next to - the size of the C program. Also, the string is mostly composed - of data - a Linux-esque kernel header for the bootloader, - protected mode descriptor tables, keyboard maps, etc. - (I should also mention that it contains mini functions - to perform an x86 'in' and 'out' instruction - to allow - the keyboard & mouse to be driven from C code). +If you do not want to mess with a floppy and you use GRUB, see below +in the author's notes. +You can put additional text files in fs.tar for browsing with vi. +If you do not want to bother rebooting your computer at all, +see http://bellard.org/ for QEMU (Fabrice Bellard is an IOCCC 2001 winner), +but your experience will be limited (replace -DK=0 with -DK=1 in the Makefile, +and you will have to move the mouse to trigger the initial screen update). - Porting to another architecture should be relatively easy* - - the string simply needs be replaced with one containing - data & code suitable for the new target platform. - Accesses to data in the string are made relative to the define 'V', - so these may need updating as appropriate (0x90200 is the address - at which a Linux bootloader loads an x86 kernel image). +The judges were able to write a few more programs to run on this OS +What are the limitations for such programs? +What you can do and what you cannot do in such programs? - * ;-) +The program called "prim", written by the judges, +computes and prints prime numbers. + +## Author's comments: + +This is a 32-bit multitasking operating system for x86 computers, +with GUI and filesystem, support for loading and executing user +applications in elf binary format, with ps2 mouse and keyboard drivers, +and vesa graphics. And a command shell. And an application - +a simple text-file viewer. + +The OS has ended up as a traditional monolith with one entry point +for syscalls, with apps treated as cooperative-multitasking tasks +that can be sent different messages (e.g. 'initialize', 'key hit', +'render to buffer') through their main entry point, and which will +return control to the OS having performed the necessary work. +Applications are are passed a pointer to their task structure, +which is partially defined by the OS, and partially for +the application's own use. + +The program compiles into a tool to build a kernel image, +so having built the program, the makefile will run it, +piping the output into a file called 'kernel'. +The makefile will then proceed to build a root filesystem image. +This involves rebuilding the program with different compiler flags, +then building a tar file containing the resulting programs +(the filesystem format supported by the OS is the tar-file format). + +For further usage information see 'gavin_install.txt'. + +The filenames 'vi' and 'sh' are significant, and should not be changed. + +### Known 'features' + +Known issues are really too plentiful to list. + +If the mouse pointer goes off the left hand side of the screen +it will reappear on the right, and vice-versa. +If it goes off the top or bottom, it will go and corrupt some memory. + +The file system is kinda optimistic about matching names, so, +for example if you type the command 'shell' into a command-line +it will execute the program 'sh' - close enough a match for it. + +The elf binaries are not loaded at the correct address, +and their entry point must be the start address of the text segment. + +The keyboard driver can cope with the basic alpha-numeric keys, +but gets confused by fancy things like 'shift' or 'backspace'. + +In the text-file viewer, 'vi', the up/down and pgup/pgdn keys +scroll up or down by one line. There is nothing to stop you +[from] scrolling above the top of the file, and pressing any +other keys may have an undefined effect. + +The x86 is bootstrapped into 32bit mode in 6 instructions, +with 4 more to set up data/stack segments and a stack-pointer +to allow C code to be run. On top of this there are also about +a dozen instructions to switch the video card into graphics mode. +All in all, a relatively tiny number of instructions next to +the size of the C program. Also, the string is mostly composed +of data - a Linux-esque kernel header for the bootloader, +protected mode descriptor tables, keyboard maps, etc. +(I should also mention that it contains mini functions +to perform an x86 'in' and 'out' instruction - to allow +the keyboard & mouse to be driven from C code). + +Porting to another architecture should be relatively easy* - +the string simply needs be replaced with one containing +data & code suitable for the new target platform. +Accesses to data in the string are made relative to the define 'V', +so these may need updating as appropriate (0x90200 is the address +at which a Linux bootloader loads an x86 kernel image). + +* ;-) diff --git a/2004/gavin/gavin.c b/2004/gavin/gavin.c index c967b7e57..2082b496a 100644 --- a/2004/gavin/gavin.c +++ b/2004/gavin/gavin.c @@ -1,8 +1,9 @@ +int main(int t, char **q, char **d) { return cain(t, (int)q, (int)d); } #define G(n) int n(int t, int q, int d) #define X(p,t,s) (p>=t&&p<(t+s)&&(p-(t)&1023)<(s&1023)) #define U(m) *((signed char *)(m)) #define F if(!--q){ -#define I(s) (int)main-(int)s +#define I(s) (int)cain-(int)s #define P(s,c,k) for(h=0; h>>14==0; h+=129)Y(16*c+h/1024+Y(V+36))&128>>(h&7)?U(s+(h&15367))=k:k G (B) @@ -52,7 +53,7 @@ else G (_); G (o); -G (main) +G (cain) { Z, k = K; if (!t) diff --git a/bugs.md b/bugs.md index a08d45387..27ccf5816 100644 --- a/bugs.md +++ b/bugs.md @@ -208,4 +208,100 @@ actually gcc if it looks like it's gcc (two different binaries). ## Entries that can compile but crash (sometimes or always) -.. entries to be added later .. +### [2004/gavin](2004/gavin/gavin.c) ([README.md](2004/gavin//README.md)) + +Segmentation fault occurs when running `gavin` to produce the kernel: + +```sh +./gavin > kernel +``` + +When trying to link `gavin.o` to produce `sh`, the linker generates: + +``` +Undefined symbols for architecture arm64: + "start", referenced from: + -u command line option + (maybe you meant: __start) +ld: symbol(s) not found for architecture arm64 +``` + +#### Recent for 2004/gavin mods: + +In case recent modification are part of the problem, here is a full disclosure +of what was changed: + +To compile on modern C compilers, the following patch was applied to `gavin.c`: + +```patch +diff --git a/2004/gavin/gavin.c b/2004/gavin/gavin.c +index c967b7e..2082b49 100644 +--- a/2004/gavin/gavin.c ++++ b/2004/gavin/gavin.c +@@ -1,8 +1,9 @@ ++int main(int t, char **q, char **d) { return cain(t, (int)q, (int)d); } + #define G(n) int n(int t, int q, int d) + #define X(p,t,s) (p>=t&&p<(t+s)&&(p-(t)&1023)<(s&1023)) + #define U(m) *((signed char *)(m)) + #define F if(!--q){ +-#define I(s) (int)main-(int)s ++#define I(s) (int)cain-(int)s + #define P(s,c,k) for(h=0; h>>14==0; h+=129)Y(16*c+h/1024+Y(V+36))&128>>(h&7)?U(s+(h&15367))=k:k + + G (B) +@@ -52,7 +53,7 @@ else + + G (_); + G (o); +-G (main) ++G (cain) + { + Z, k = K; + if (!t) +`` + +The original Makefile from 2004 had the following to say about this entry: + +```make +# Special flags for the gavin entry +# +# FYI: Older versions of GCC have a bug in -O2 optimization, hence -O1 +# +GAVIN_OPT= -O1 +GAVIN_FLAGS=\ + '-DY(m)=*((int*)(m))'\ + '-DE(f,a,b,c)=((G((*)))(f))(a,b,c)'\ + '-DM=for(D=0;D<786432;D++)'\ + '-DZ=int i=0,j=0,h,n,p=393728,s=26739,C,D'\ + '-DV=0x90200'\ + '-DK=0'\ + '-DR=while((C=E(V-8,100,0,0))&3&&(D=E(V-8,96,0,0))|3){'\ + '-DL(c,d)=E(V+8,100,c,0);R}E(V+8,96,d,0);R}' + +# ... + +# Best of Show +# +gavin: gavin.c + ${CC} ${GAVIN_OPT} -o gavin ${GAVIN_FLAGS} gavin.c + ${RM} -f kernel + ./gavin > kernel + ${CC} ${GAVIN_OPT} -c ${GAVIN_FLAGS} -DB=_start '-Dputchar(a)=' gavin.c + ${RM} -f sh + ${LD} -s -o sh gavin.o + ${RM} -f vi + ${CP} sh vi + ${RM} -f fs.tar + ${TAR} -cvf fs.tar sh vi gavin.c gavin.hint prim + +gavin_clean: + ${RM} -f sh vi kernel gavin.o + +gavin_clobber: gavin_clean + ${RM} -f gavin fs.tar + +gavin_files: boot.b lilo.conf prim gavin_install.txt +``` + +The current ([Makefile](2004/gavin/Makefile) was modified to try and +fit into the current IOCCC build environment.