From 118e11f2b4d82901f720484bfaab564c7e21959b Mon Sep 17 00:00:00 2001 From: Landon Curt Noll Date: Fri, 24 Mar 2023 00:11:44 -0700 Subject: [PATCH] fix Makefile and README.md for 2013/cable3 Fix #! line in rumme and make executable. --- 2013/cable3/Makefile | 286 ++++++++++++++++++++++++++++++------------ 2013/cable3/README.md | 92 ++++++-------- 2013/cable3/runme | 2 +- 3 files changed, 245 insertions(+), 135 deletions(-) mode change 100644 => 100755 2013/cable3/runme diff --git a/2013/cable3/Makefile b/2013/cable3/Makefile index 0c932f8d2..993d62724 100644 --- a/2013/cable3/Makefile +++ b/2013/cable3/Makefile @@ -1,102 +1,167 @@ #!/usr/bin/env make # -# 2013 makefile +# IOCCC 2013 winning entry - cable3 + +################################################################################ # -# This work by Landon Curt Noll, Simon Cooper, and Leonid A. Broukhis -# is licensed under: +# 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= bash -CP= cp -CPP= cpp -GUNZIP= gunzip -LD= ld -MAKE= make -RM= rm -SED= sed -TAR= tar -TRUE= true + +####################### +# common tool locations +####################### +# +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 # Set X11_INCLUDEDIR to the directory where the X11 include files reside # -X11_INCDIR= /usr/X11R6/include +#X11_INCDIR= /usr/X11R6/include +#X11_INCDIR= /usr/X11/include +X11_INCDIR= /opt/X11/include -# Compiler warnings +# Common C compiler warnings to silence # -#CWARN= -CWARN= -Wall -Wno-implicit-int -Wno-implicit-function-declaration \ - -Wno-return-type -Wno-unsequenced -Wno-shift-op-parentheses \ - -Wno-conditional-type-mismatch -Wno-parentheses \ - -Wno-incompatible-pointer-types -#CWARN= -Wall -pedantic +#CSILENCE= +CSILENCE= -Wno-bitwise-op-parentheses -Wno-bool-operation \ + -Wno-conditional-type-mismatch -Wno-error \ + -Wno-implicit-function-declaration -Wno-implicit-int \ + -Wno-incompatible-pointer-types -Wno-logical-not-parentheses \ + -Wno-logical-op-parentheses -Wno-parentheses -Wno-shift-op-parentheses \ + -Wno-sign-compare -Wno-unsequenced -Wno-unused-parameter -# compiler standard +# 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=c99 +CSTD= -std=gnu11 -# compiler bit architecture +# Compiler bit architecture # # Some entries require 32-bitness: # ARCH= -m32 # -# Some entries require 64-bitess: +# Some entries require 64-bitness: # ARCH= -m64 # # By default we assume nothing: # ARCH= -# optimization +# Defines that are needed to compile +# +#CDEFINE= +CDEFINE= -DKB='(kb=read(H(8),r+1190,1))&&H(7)' + +# 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 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= -O3 -fsigned-char +OPT= -O3 + +# Default flags for ANSI C compilation +# +CFLAGS= ${CSTD} ${CWARN} ${ARCH} ${CDEFINE} ${CINCLUDE} ${OPT} # Libraries needed to build # -LIBS=`sdl-config --cflags --libs` +#LIBS= +#LIBS= -lm +#LIBS= -L ${X11_LIBDIR} -lX11 +LIBS= `${SDL2_CONFIG} --libs` -# Defines -DEFS=-DKB='(kb=read(H(8),r+1190,1))&&H(7)' - -# default flags for ANSI C compilation -# -CFLAGS= ${CWARN} ${CSTD} ${ARCH} ${OPT} ${DEFS} - -# 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 #CC=clang -MAY_NEED_GCC= gcc +#CC=gcc + +# Compiler add-ons or replacements for clang only +# +ifeq ($(CC),clang) +# +CSILENCE+= -Wno-cast-align -Wno-comma -Wno-dollar-in-identifier-extension \ + -Wno-implicit-int-conversion -Wno-missing-prototypes \ + -Wno-missing-variable-declarations -Wno-padded -Wno-pedantic \ + -Wno-poison-system-directories -Wno-shadow -Wno-sign-conversion \ + -Wno-strict-prototypes +# +CWARN+= -Weverything +# +endif + +# Specific add-ons or replacements for gcc only +# +ifeq ($(CC),gcc) +# +#CSILENCE+= +# +#CWARN+= +# +endif ############################## @@ -104,24 +169,35 @@ MAY_NEED_GCC= gcc ############################## # ENTRY= cable3 -DATA= +PROG= ${ENTRY} +# +OBJ= ${PROG}.o +DATA= bios fd.img runme sc-ioccc.terminal screenshot_autocad.png \ + screenshot_flightsim4.png screenshot_lotus123.png screenshot_qbasic.png \ + screenshot_simcity.png screenshot_win3_on_macosx.png +TARGET= ${PROG} +# ALT_OBJ= -ALT_ENTRY= +ALT_TARGET= ################# # build the entry ################# # -all: ${ENTRY} ${DATA} +all: data ${TARGET} @${TRUE} -${ENTRY}: ${ENTRY}.c +.PHONY: all alt data everything clean clobber install \ + love haste waste maker easter_egg sandwich \ + supernova deep_magic magic charon pluto + +${PROG}: ${PROG}.c ${CC} ${CFLAGS} $< -o $@ ${LIBS} # alternative executable # -alt: ${ALT_ENTRY} +alt: data ${ALT_TARGET} @${TRUE} # data files @@ -129,33 +205,51 @@ alt: ${ALT_ENTRY} data: ${DATA} @${TRUE} +# both all and alt +# +everything: all alt + ############### # utility rules ############### # -everything: all alt - clean: - ${RM} -f ${ENTRY}.o ${ALT_OBJ} + ${RM} -f ${OBJ} ${ALT_OBJ} + @-if [ -f indent.c ]; then \ + echo ${RM} -f indent.c; \ + ${RM} -f indent.c; \ + fi clobber: clean - ${RM} -f ${ENTRY} ${ALT_ENTRY} - -nuke: clobber - @${TRUE} - -dist_clean: nuke - @${TRUE} + ${RM} -f ${TARGET} ${ALT_TARGET} + @-if [ -e sandwich ]; then \ + ${RM} -f sandwich; \ + echo 'ate sandwich'; \ + fi install: - @echo "Surely we are joking Dr. Lehmer!" + @echo "Dr. Spock says that is not logical!" @${TRUE} -# backwards compatibility +# you may be able to misunderstand the source by reading indent.c # -build: all - @${TRUE} +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 ################## @@ -174,35 +268,69 @@ waste: @echo 'haste' @${TRUE} +maker: + @echo 'Participate in a maker faire' + @${TRUE} + easter_egg: - @echo you expected to mis-understand this $${RANDOM} magic - @echo chongo '' "/\\oo/\\" - @echo Readers shall not be disallowed from being unable to not partly misunderstand this partocular final echo. + @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: nuke +supernova: sandwich @-if [ -r .code_anal ]; then \ - ${RM} -f .code_anal_v4; \ + ${RM} -f .code_anal_v6; \ else \ - echo "We are not expected to understand that"; \ + 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: +deep_magic: supernova @-if [ -r .code_anal ]; then \ - ccode_analysis --deep_magic 2ed3582ec5c094a093fea2a6bcb9f19439892873c9cc45ed1ceaafe08b7d52e1b2c7cd524be3b0b2 --FNV1a_hash 512-bit "${ENTRY}"; \ + ccode_analysis --deep_magic 7889066cdbdf09b0408021754586e895be641cc9be29e7eafd3ca65359541f17 \ + --FNV1a_hash_512_bit -v2 "${PROG}" "${PROG}.c"; \ else \ - echo "Park different"; \ + 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 --mode 391581 --level 216193 --FNV1a_hash 512-bit "${ENTRY}"; \ + ccode_analysis --level 20003 --mode 5717175 --FNV1a_hash_512_bit -v2 "${PROG}" "${PROG}.c"; \ else \ - echo "These aren't the primes you're looking for Paul Erdos!"; \ + 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/2013/cable3/README.md b/2013/cable3/README.md index db990bfd3..885a61e75 100644 --- a/2013/cable3/README.md +++ b/2013/cable3/README.md @@ -1,37 +1,41 @@ # Largest small system emulator -Adrian Cable - + Adrian Cable + +# To build: -## Judges' comments: -### To build: - - make cable3 +```sh +make +``` ### To run: - ./cable3 bios-image-file floppy-image-file [harddisk-image-file] +```sh +./cable3 bios-image-file floppy-image-file [harddisk-image-file] +``` ### Try: - ./runme +```sh +./runme +``` -### Selected Judges Remarks: +## Judges' comments: This entry weighs in at a magical 4043 bytes (8086 nibbles, 28,301 bits). It manages to implement most of the hardware in a 1980's era IBM-PC using a few hundred fewer bits than the total number of transistors used to implement the original 8086 CPU. -If you are using OS X, the included sc-ioccc.terminal configuration file will +If you are using macOS, the included sc-ioccc.terminal configuration file will correctly display console applications that use ANSI graphics. Update: This entry now has its own web page ## Author's comments: -A tiny but highly functional PC emulator/virtual machine -======================================================== + +### A tiny but highly functional PC emulator/virtual machine The author hereby presents, for the delectation (?) of the judges, a portable PC emulator/VM written specifically for the IOCCC which runs DOS, Windows 3.0, Excel, MS Flight Simulator, AutoCAD, Lotus 1-2-3 ... @@ -61,8 +65,7 @@ If you like living on the edge you can try building the emulator on a big endian */RULE 2 ABUSE DISCLAIMER* -Why is this entry obfuscated/interesting? ------------------------------------------ +### Why is this entry obfuscated/interesting? - First of all the 8086 is a nightmare processor to emulate. Instruction codings are complex and irregular in size and structure, with multiple addressing modes and no consistent memory placement for operands, very often multiple possible encodings for the same instruction, and the bizarre segment:offset memory model. In addition, the 8086 has a number of bugs (e.g. PUSH SP), undocumented behaviours and instructions (e.g. AAM/AAD + imm8, SALC, flag behaviour for MUL/DIV, etc. etc.), and archaic features (e.g. parity/auxiliary flags) which all need to be emulated properly. Here we emulate every feature of the CPU pretty exactly (in fact better than most commercial clones of the processor e.g. the NEC V30), with the exception of the trap flag which no real software uses except for debuggers (although support for the TF can be added if deemed important, without exceeding the IOCCC size limit). - In addition to the CPU we also emulate all the standard PC peripheral hardware. Parts of it are somewhat complete, much is rather dysfunctional (like the 8253/8259) but enough to support most real software. @@ -72,8 +75,7 @@ Why is this entry obfuscated/interesting? - This entry highlights the importance of comments in C. - This entry might result in an adjustment to the IOCCC size tool for the 2014 competition (see above). -Compiling on different platforms --------------------------------- +### Compiling on different platforms This entry has been tested on Windows (compiled with MS Visual Studio 2010 and 2013), Mac OS X (clang and gcc), and Linux (clang and gcc). The Makefile supplied is good for Mac OS X, Linux and probably other UNIXes. I have received reports that the emulator works on Raspberry Pi/Android/ARM (you will need to compile with -fsigned-char) and iOS. You will need to adjust the Makefile if your system lacks sdl-config to correctly point to the SDL libraries and header files. @@ -81,15 +83,13 @@ On UNIX-based systems we can get raw keystrokes using stty. However Windows has KB=(kb=H(8),kbhit())&&(r[1190]=getch(),H(7)) -POSIX portability note ----------------------- +### POSIX portability note The code as supplied uses implicit function declarations for POSIX file I/O and in doing so assumes that file offsets are the same bit width as your architecture. For some systems (e.g. 32-bit Mac OS X, which uses 64-bit file offsets) this is not the case, and to run successfully on these systems, you will need to explicitly declare these functions by adding the appropriate include to the top of the source: #include -Usage ------ +### Usage ./cable3 bios-image-file floppy-image-file [harddisk-image-file] @@ -99,8 +99,7 @@ PLEASE NOTE that under UNIXes the keyboard must be in raw mode for the emulator ./cable3 bios floppy.img harddisk.img stty cooked echo -To run the emulator - floppy mode only --------------------------------------- +### To run the emulator - floppy mode only The simplest use of the emulator is with a single floppy boot disk image, like the fd.img provided, which is a FreeDOS boot disk. @@ -110,8 +109,7 @@ Before running the emulator on a Unix-type system, stty needs to be used to put ./cable3 bios fd.img stty cooked echo -To run the emulator - floppy + HD mode --------------------------------------- +### To run the emulator - floppy + HD mode Easiest to start with is to try a ready-made 40MB hard disk image containing a whole bunch of software: @@ -125,8 +123,7 @@ For the more adventurous, you can start off with (for example) a blank 40MB imag Preparing the hard disk for use in the emulator is done just like a real PC. Boot the emulator, and use FDISK to partition the hard disk. When it's done FDISK will reboot the emulator. Then you can use FORMAT C: and you are done. The resulting disk image is in the right format to be mounted on a real Windows PC using e.g. OSFMount, on a Mac using hdiutil, or on Linux using mount, providing an easy way to copy files and programs to and from the disk image. Or, you can install programs from regular floppy disk images (see "Floppy disk support" below). -Keyboard emulation ------------------- +### Keyboard emulation The emulator simulates an XT-style keyboard controlled by an Intel 8042 chip on I/O port 0x60, generating IRQ1 and then interrupt 9 on each keypress. This is harder than it sounds because a real 8042 returns scan codes rather than the ASCII characters which the C standard I/O functions return. Rather than make the emulator less portable and use ioctl or platform-dependent equivalents to obtain real scan codes from the keyboard, the emulator BIOS does the reverse of a real PC BIOS and converts ASCII characters to scancodes, simulating press/release of the modifier keys (e.g. shift) as necessary to work like a "real" keyboard. The OS (DOS/Windows) then converts them back to ASCII characters and normally this process works seamlessly (although don't be surprised if there are issues, for example, with non-QWERTY e.g. international keyboards). @@ -138,8 +135,7 @@ To send an Fxx key, press Ctrl+F then a number key. For example, to get the F4 k To send a Page Down key, press Ctrl+F then O. To send a Page Up key, press Ctrl+F then E. Other key combinations are left for the discovery of the user. -Text mode support ------------------ +### Text mode support The emulator supports both text output via the standard BIOS interrupt 0x10 interface, and also direct video memory access (one page, 4KB video RAM at segment B800) in 80x25 CGA 16-color text mode. @@ -151,8 +147,7 @@ The regular PC character code page (437) includes various extended ASCII charact Occasionally a DOS application on exit will leave the video hardware in an odd state which confuses the emulator, resulting in subsequent text output being invisible. If this happens, just use the DOS CLS command to clear the screen and all will be well again. -Graphics mode support ---------------------- +### Graphics mode support Hercules 720x348 monochrome graphics mode emulation is implemented using SDL. Most Hercules features are supported via the normal I/O interface on ports 0x3B8 and 0x3BA including video memory bank switching (segments B000/B800), which some games use for double-buffered graphics. CGA graphics modes are not supported. @@ -160,20 +155,17 @@ When an application enters graphics mode, the emulator will open an SDL window ( On UNIXes, SDL will automatically output graphics via X11 if the DISPLAY environment variable is set up. -Dual graphics card support --------------------------- +### Dual graphics card support Some applications (e.g. AutoCAD) support a PC configuration with a CGA card and a Hercules card, for simultaneous text and graphics output on different displays. The emulator simulates this configuration, too, using separate windows for the (terminal) text and (SDL) graphics displays. -BIOS ----- +### BIOS Like a real PC, the emulator needs a BIOS to do anything useful. Here we use a custom BIOS, written from scratch specifically for the emulator. Source code for the BIOS (written in 8086 assembly language) which compiles with the freely-available NASM x86 assembler is available from the author on request. The BIOS implements the standard interrupt interfaces for video, disk, timer, clock and so on, much as a "real" PC BIOS does, and also a small timer-controlled video driver to convert video memory formatting into ANSI escape sequences when the emulator is in text mode. -CPU and memory emulation ------------------------- +### CPU and memory emulation Memory map is largely as per a real PC, with interrupt vector table at 0:0, BIOS data area including keyboard buffer at 40:0, CGA text video memory at B800:0, Hercules dual-bank graphics memory at B000/B800:0, and BIOS at F000:100. Unlike a real PC, in the emulator the CPU registers are memory-mapped (at F000:0), which enables considerable optimisation of the emulator's instruction execution unit by permitting the unification of memory and register operations, while remaining invisible to the running software. @@ -188,15 +180,13 @@ The CPU also implements some "special" two-byte opcodes to help the emulator tal Emulator exit is triggered if CS:IP == 0:0 (which would be nonsensical in real software since this is where the interrupt vector table lives). The supplied Dos6.22.img disk includes a small program QUITEMU.COM which contains a single JMP 0:0 instruction, to allow the user to easily quit the emulator without shutting down the terminal. -Floppy disk support -------------------- +### Floppy disk support Emulates a 3.5" high-density floppy drive. Can read, write and format 1.44MB disks (18 sectors per track, 2 heads) and 720KB disks (9 sectors per track, 2 heads). If you want to install your own software from floppy images (downloaded from e.g. Vetusware), the easiest way to "change disks" is to copy each disk image in turn over the floppy image file you specify on the command line. Don't forget to put your original boot disk back at the end! -Hard disk support ------------------ +### Hard disk support Supports up to 1023 cylinders, 63 sectors per track, 63 heads for disks up to 528MB. @@ -206,46 +196,38 @@ The emulator uses a particularly dumb algorithm to derive a simulated cylinder/s Note that unlike a real PC, the emulator cannot boot from a hard disk (image). Therefore, you will always need to use a bootable floppy image, even if after boot everything runs from the HD. -Mouse ------ +### Mouse No mouse is emulated. -Real-time clock ---------------- +### Real-time clock Reading the RTC (both time and date) is emulated via the standard BIOS clock interface, pulling the time/date from the host computer. Setting the time or date is not supported. -Timers ------- +### Timers A countdown timer on I/O port 0x40 is simulated in a broken way which is good enough for most software. On a real PC this has a default period of 55ms and is programmable. No programmability is supported in the emulator and the period may be about right or completely wrong depending on the actual speed of your computer. On a real PC, IRQ0 and interrupt 8 are fired every 55ms. The emulator tries to do the same but again, the delay period is uncalibrated so you get what you get. -PC speaker ----------- +### PC speaker Beeps only, through the console. -Software supported ------------------- +### Software supported The emulator will run practically any software a real PC (of the spec listed at the top of this file) can. The author has tested a number of OSes/GUIs (MS-DOS 6.22, FreeDOS 0.82pl3, Windows 3.0, DESQview 2.8), professional software (Lotus 1-2-3 2.4 and AsEasyAs 5.7 for DOS, Excel 2.1 for Windows, AutoCAD 2.5, WordStar 4), programming languages (QBASIC, GWBASIC, Turbo C++), games (Carrier Command, Police Quest, and a bunch of freeware Windows games), and diagnostic/benchmark software (Manifest, Microsoft MSD, InfoSpot, CheckIt) and all of them run well. Screenshots of some of these applications running (on Mac OS X) are provided for the impatient. -Compiler warnings ------------------ +### Compiler warnings A lot of compiler warnings are produced by clang. Missing type specifiers, control reaching the end of functions without returning values, incompatible pointer type assignments, and some precedence warnings, all necessary to keep the source size down. Other compilers are likely to produce similar warnings. +## Copyright: --------------------------------------------------------------------------------- - diff --git a/2013/cable3/runme b/2013/cable3/runme old mode 100644 new mode 100755 index 3b0f53e8d..05cacc120 --- a/2013/cable3/runme +++ b/2013/cable3/runme @@ -1,4 +1,4 @@ -#!/bin/sh +#!/usr/bin/env bash clear stty cbreak raw -echo min 0 if [ -f hd.img ]