########################################################################
# auto.def - Configure file for the PiDP-8/I software build system,
#            based on autosetup.
#
# Copyright © 2016-2017 Warren Young
#
# Permission is hereby granted, free of charge, to any person obtaining
# a copy of this software and associated documentation files (the
# "Software"), to deal in the Software without restriction, including
# without limitation the rights to use, copy, modify, merge, publish,
# distribute, sublicense, and/or sell copies of the Software, and to
# permit persons to whom the Software is furnished to do so, subject to
# the following conditions:
#
# The above copyright notice and this permission notice shall be
# included in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
# IN NO EVENT SHALL THE AUTHORS LISTED ABOVE BE LIABLE FOR ANY CLAIM,
# DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT
# OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
# OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
# Except as contained in this notice, the names of the authors above
# shall not be used in advertising or otherwise to promote the sale,
# use or other dealings in this Software without prior written
# authorization from those authors.
########################################################################

define defaultprefix /opt/pidp8i

use cc
use cc-lib

options {
	debug-mode =>        "create a debug build (default is release)"
	no-lamp-simulator => "use simple LED driver instead of incandescent lamp simulator"
	serial-mod =>        "use GPIO drive scheme suitable for Oscar Vermeulen's serial mod method"
	alt-serial-mod =>    "use GPIO drive scheme suitable for James L-W's serial mod method"
	throttle:  =>        "override the throttle values in the boot scripts"
}

if {[opt-bool alt-serial-mod]} {
	msg-result "GPIO drive adjusted for James L-W's serial mods to the PiDP-8/I PCB."
	define PCB_SERIAL_MOD_JLW
	define PCB_SERIAL_MOD_ANY
}

if {[opt-bool serial-mod]} {
	msg-result "GPIO drive adjusted for O. Vermeulen's serial mods to the Pi & PiDP-8/I PCBs."
	define PCB_SERIAL_MOD_OV
	define PCB_SERIAL_MOD_ANY
}

if {[opt-bool debug-mode]} {
	msg-result "Creating a debuggable build."
	define BUILDMODE {-O0 -g}
} else {
	msg-result "Creating a release build."
	define BUILDMODE {-O2}
}

# High-level definitions
set builddir [get-define builddir]
set srcdir [get-define srcdir]
set cores [exec $srcdir/tools/corecount]

# Translate --throttle value to a SIMH command
set tv [opt-val throttle]
set tvsl [string length $tv]
if {($tvsl == 0 && $cores > 1) || $tv == "none"} {
	define SET_THROTTLE {set nothrottle}
	set tv "unlimited"
} else {
	# Rewrite symbolic values with values SIMH can understand.  See
	# README-throttle.md for the justification of these values.
	if {$tv == "single-core" || $tvsl == 0} {
		# Set throttle to the highest values we can achive on the single
        # core Pi boards with NLS without causing SIMH to claim the CPU
        # isn't fast enough and give up on throttling.
        set dtm "/proc/device-tree/model"
        if {[exec grep -q 'Raspberry Pi Zero' $dtm > /dev/null 2>&1]} {
            set tv "1250k"
        } else {
            set tv "850k"
        }
	} elseif {$tv == "pdp8e"} {
		set tv "416k"
	} elseif {$tv == "pdp8i" || $tv == "pdp8a"} {
		set tv "333k"
	} elseif {$tv == "pdp8l" || $tv == "pdp8"} {
		set tv "313k"
	} elseif {$tv == "ha6120"} {
		set tv "182k"
	} elseif {$tv == "im6100a"} {
		set tv "200k"
	} elseif {$tv == "im6100"} {
		set tv "100k"
	} elseif {$tv == "im6100c"} {
		set tv "83k"
	} elseif {$tv == "pdp8s"} {
		set tv "63k"
	} elseif {$tv == "human"} {
		set tv "10/1000"
	} elseif {$tv == "trace"} {
		set tv "1/1000"
	}
	# else, assume --throttle was given a legal SIMH throttle value
    
    if {[string first "/" $tv] > -1} {
        # Assume the ratio given will push us below 1 kIPS, where ILS
        # fails badly because of the simulator's sleeping behavior, so
        # disable the ILS feature if we were going to build it.
        set cores 1
    }

	define SET_THROTTLE "set throttle $tv"
}
msg-result "Simulator CPU throttle set to $tv IPS"

# Swap the incandescent lamp simulator feature out for the original LED
# driving method on single-core hosts.  The user can force this on
# multi-core hosts via --no-lamp-simulator.
if {($cores < 2) || [opt-bool no-lamp-simulator]} {
	msg-result "Driving PiDP-8/I front panel LEDs using low-CPU-usage method."
	define LED_DRIVER_MODULE n
	define ILS_MODE 0
} else {
	msg-result "Driving PiDP-8/I front panel LEDs using incandescent lamp simulator."
	define LED_DRIVER_MODULE i
	define ILS_MODE 1
}

# Check for headers, functions, etc. whose absence we can work around
cc-check-includes time.h
cc-check-functions clock_nanosleep nanosleep usleep
cc-check-functions sched_yield

# Ensure we have the libncurses development files installed here, else
# pidp8i-test won't build.
if {![cc-check-includes curses.h]} {
	user-error "Could not find curses.h.  Try installing libncurses-dev."
} elseif {![cc-check-function-in-lib initscr ncurses]} {
	user-error "Could not find initscr() in libncurses."
}

# We need to find an install(1) type program that supports -D.  The
# Raspberry Pi OSes typically used with the PiDB-8/I board do have this,
# but this package also runs on non-Linux OSes (e.g. for testing on a
# desktop Mac) so make sure we've got a suitable implementation.  The
# ginstall name is typical on non-Linux systems where GNU Coreutils was
# installed alongside the core OS utilities.
if {[cc-check-progs ginstall]} {
	define INSTALL ginstall
} elseif {[cc-check-progs install]} {
	if {[catch {exec install -D -d . >& /dev/null} result] == 0} {
		define INSTALL install
	} else {
		user-error "install(1) does not support -D; install GNU Coreutils."
	}
} else {
	user-error "No install(1) type program found; install GNU Coreutils."
}
msg-result "Found GNU install(1) program as [get-define INSTALL]."

# Also find GNU readlink in the same way
if {[cc-check-progs greadlink]} {
	set rlprg greadlink
} elseif {[cc-check-progs readlink]} {
	if {[catch {exec readlink -f . >& /dev/null} result] == 0} {
		set rlprg readlink
	} else {
		user-error "readlink(1) does not support -D; install GNU Coreutils."
	}
} else {
	user-error "No readlink(1) type program found; install GNU Coreutils."
}
msg-result "Found GNU readlink(1) as $rlprg."

# If we have cscope here, we'll use it in the "tags" target
define HAVE_PROG_CSCOPE [cc-check-progs cscope]

# Canonicalize some paths which may be relative and generate others from them
define ABSPREFIX [exec $rlprg -f [get-define prefix]]
define BOOTDIR  "[get-define ABSPREFIX]/share/boot"
define MEDIADIR "[get-define ABSPREFIX]/share/media"

# Remember the name and primary group of the user who installed this, since
# we want to give that group write privileges to some files when they're
# installed, and we want them to own the screen(1) session.
set instgrp [exec id -grn]
set instusr [exec id -urn]
if {$instusr == "root"} {
	msg-result "Error: This software will not install and run as root."
	user-error "Reconfigure without sudo!"
}
define INSTGRP $instgrp
define INSTUSR $instusr
msg-result "Install group for user-writeable files will be $instgrp."
msg-result "Owner of screen(1) session will be $instusr."

# Can we use any nonstandard flags here?  We don't bother including
# flags that both GCC and Clang support.  The ones inside the "if"
# block are those that Clang will accept in an autosetup test but
# then will yell about if you try to use them.  The test checks for
# an -f sub-option that Clang doesn't currently support even enough
# to fool autosetup.
cc-check-standards c99
if {![opt-bool debug-mode]} {
	cc-check-flags -fipa-cp-clone
	cc-check-flags -fno-strict-overflow
	cc-check-flags -fpredictive-commoning
	if ([get-define HAVE_CFLAG_FIPA_CP_CLONE]) {
		cc-check-flags -fgcse-after-reload
		cc-check-flags -finline-functions
		cc-check-flags -fno-unsafe-loop-optimizations
	}
}

# Embed this software's Fossil-based version string into gpio-common.c.
# Fail hard if we can't get this version string because all supported
# configurations require Fossil and work from a Fossil checkout.  Don't
# fall back on some lame "UNKNOWN" version string because that would
# mask a real problem that needs to be diagnosed.
set tool "tools/version"
set cmd "$srcdir/$tool"
set status [catch {exec $cmd} version]
if {$status != 0} {
    # The most likely cause for tools/version to fail is that the repo
    # file has become disassociated from the local checkout directory.
    set sql "select value from vvar where name=\"repository\""
    set cmd "fossil sql --no-repository $srcdir/.fslckout '$sql'"
    set status [catch {exec /bin/sh -c $cmd} path]
    if {$status != 0} {
        user-error "Fossil doesn't seem to work here.  Is it installed?\nCMD: $cmd"
    } elseif {[file exists $path]} {
        user-error "$tool failed to get checkout version from $path"
    } else {
        user-error "$tool failed: $path does not exist."
    }
}
define VERSION $version

# Build Deeper Thought if we find it here
if {[file exists "[get-define srcdir]/src/deeper.c"]} {
    set ls [string toupper "[get-define LED_DRIVER_MODULE]ls"]
	msg-result "Found Deeper Thought; building it against $ls GPIO module"
    define BUILD_DEEPER_THOUGHT 1
}

# Write outputs.
#
# NOTE: If you change the list of files here, change INFILES in
# Makefile.in, too.
make-config-header src/config.h \
	-auto {ENABLE_* HAVE_* PACKAGE_* SIZEOF_*} \
	-bare {ILS_MODE PCB_SERIAL_MOD_JLW PCB_SERIAL_MOD_OV}
make-template Makefile.in
make-template bin/pidp8i.in
make-template boot/0.script.in
make-template boot/2.script.in
make-template boot/3.script.in
make-template boot/4.script.in
make-template boot/6.script.in
make-template boot/7.script.in
make-template etc/pidp8i-init.in
make-template etc/sudoers.in
make-template examples/Makefile.in
make-template src/Makefile.in
make-template src/gpio-common.c.in
make-template src/PDP8/Makefile.in
make-template src/PDP8/pidp8i.c.in
make-template tools/simh-update.in
exec chmod +x "$builddir/tools/simh-update"
