Initial files

This commit is contained in:
Willem Cazander 2020-12-23 18:14:13 +01:00
parent 2f34088fc3
commit a92a2b8dad
16 changed files with 755 additions and 2 deletions

38
.gitignore vendored Normal file
View file

@ -0,0 +1,38 @@
syntax: glob
# Project ignores
bin
bin/**
# Makefile ignores
Makelocal.mk
# File ignores
*.log
*.bak
*.zip
*.tar.gz
# Ignore some eclipse files
.settings
.project
# Ignore visual studio files
.vs/
# Ignore intellij files
*.iml
.idea
# Ignore netbeans directory
nbproject
# Ignore mac finder files
.DS_Store
# Ignore windows files.
Thumbs.db
Desktop.ini
# Ignore kde dolphin files
.directory

26
Makefile Normal file
View file

@ -0,0 +1,26 @@
rwildcard = $(foreach d,$(wildcard $1*),$(call rwildcard,$d/,$2) $(filter $(subst *,%,$2),$d))
INC_LIB := $(call rwildcard, lib, */0module.mk)
INC_TEST := $(call rwildcard, test, */0module.mk)
PATH_BIN := bin
BUILD_ALL := "Use 'make help' for possible targets."
BUILD_HELP := "Use one of the following build targets;"
.SUFFIXES:
.PHONY: all
all:
@echo $(BUILD_ALL)
BUILD_HELP += \\n\\t* help
.PHONY: help
help:
@echo $(BUILD_HELP)
.PHONY: clean
clean:
$(call mb_clean,$(PATH_BIN))
-include Makelocal.mk
include lib/make/msxbuild.mk
include $(INC_LIB)
include $(INC_TEST)

8
Makelocal.mk.tpl Normal file
View file

@ -0,0 +1,8 @@
# Local included makefile fragment.
# Save this file without tpl suffix and custumize it.
#
# Change to local installations if needed;
#PATH_SDCC ?= /usr/bin
#PATH_HEX2BIN ?= /usr/bin
#PATH_OPENMSX ?= /opt/openMSX/bin/

View file

@ -1,3 +1,39 @@
# msxbuild # MSXBUILD
Utils to use openMSX in build pipelines.
You can use these scripts as-is. But as always, feel free to extend it
for your specific needs or contribute a fix or feature.
## Makefile features
* SDCC msx build steps
* Headless openMSX buildpipe on max speed.
* openMSX safe exit failure guards.
* Automatic disk image import + export per build step.
* wgets resources from msxhub
## TCL Scripts
Tcl scripts for safe openMSX integrations as reliable build step
in compiling/packing/testing msx software natively.
But managed from external build tool like make or scripts.
This means that great care is given to make sure that openMSX
exits correctly.
The use this, pass the one or more scripts on the command line and
set the optional environment variables when executing openMSX:
FAIL_AFTER_BOOT=30 \
FAIL_AFTER_PATH=bin/myapp \
BOOT_HDD_PATH=bin/myapp/disk \
BOOT_HDD_IMAGE=bin/myapp/disk.img \
JOYPORTA=mouse \
openmsx \
-script <path-to>/boot_env.tcl \
-script <path-to>/boot_hdd.tcl \
-script <path-to>/fail_after.tcl \
-machine ...
Check the scripts source code for more (technical) details.
Utils to use openMSX in build pipelines.

33
lib/make/mb_assert.mk Normal file
View file

@ -0,0 +1,33 @@
define _mb_assert_success
@echo success: mb_assert_$(1)\; \'$(2)\'
endef
define _mb_assert_failure
@echo failure: mb_assert_$(1)\; \'$(2)\'
@exit 1
endef
define _mb_assert_if
$(if $(1),$(call _mb_assert_success,$(2),$(3)),$(call _mb_assert_failure,$(2),$(3)))
endef
define _mb_assert_if_not
$(if $(1),$(call _mb_assert_failure,$(2),$(3)),$(call _mb_assert_success,$(2),$(3)))
endef
# FIXME: Not stable
#define mb_assert_file_contains
# $(call _mb_assert_if,$(findstring $(2),$(file < $(1))),file_contains,$(2))
#endef
define mb_assert_file_equals
$(call _mb_assert_if_not,$(subst $(2),,$(file < $(1))),file_equals,$(2))
endef
# Assert that the variable(s) are set and doesn't have non-empty values.
# Params;
# 1. Variable name(s) to validate.
# 2. (optional) Error message to user.
define mb_assert_defined
$(strip $(foreach 1,$1,$(call _mb_assert_defined_error,$1,$(strip $(value 2)))))
endef
define _mb_assert_defined_error
$(if $(value $1),,$(error Undefined $1$(if $2, ($2))))
endef

68
lib/make/mb_autoexec.mk Normal file
View file

@ -0,0 +1,68 @@
MB_AUTOEXEC_BYSELF ?= true
MB_AUTOEXEC_BYSELF_MSG ?= Generated by msxbuild Makefile
MB_AUTOEXEC_TEXTMODE ?= 80
MB_AUTOEXEC_STARTUP_TIMEOUT ?= 60
MB_AUTOEXEC_STARTUP_EXITCODE ?= 124
MB_AUTOEXEC_TEST_TIMEOUT ?= 120
MB_AUTOEXEC_TEST_EXITCODE ?= 1
define mb_autoexec_append_cmd
echo "$(2)\r" >> $(1)/autoexec.bat
endef
define mb_autoexec_append_echo
$(call mb_autoexec_append_cmd,$(1),echo $(2))
endef
define mb_autoexec_append_rem
$(call mb_autoexec_append_cmd,$(1),rem $(2))
endef
define mb_autoexec_append_gui_mode
$(call mb_autoexec_append_echo,$(1),Enabling renderer.)
$(call mb_autoexec_append_cmd,$(1),omsxctl set renderer SDL > NUL)
$(call mb_autoexec_append_echo,$(1),Enabling throttling.)
$(call mb_autoexec_append_cmd,$(1),omsxctl set throttle on > NUL)
endef
define mb_autoexec_append_stop_fail
$(call mb_autoexec_append_echo,$(1),Disabling automatic failure.)
$(call mb_autoexec_append_cmd,$(1),omsxctl fail_after 0)
endef
define mb_autoexec_append_exit
$(call mb_autoexec_append_cmd,$(1),omsxctl exit 0)
endef
define mb_autoexec_write_default
echo -n "" > $(1)/autoexec.bat
$(if $(filter true,$(MB_AUTOEXEC_BYSELF)),$(call mb_autoexec_append_rem,$(1),$(MB_AUTOEXEC_BYSELF_MSG)))
$(call mb_autoexec_append_cmd,$(1),omsxctl fail_after $(MB_AUTOEXEC_STARTUP_TIMEOUT) seconds fail_after_init $(MB_AUTOEXEC_STARTUP_EXITCODE))
$(if $(filter 40,$(MB_AUTOEXEC_TEXTMODE)),$(call mb_autoexec_append_cmd,$(1),mode 40))
$(if $(filter 40,$(MB_AUTOEXEC_TEXTMODE)),$(call mb_autoexec_append_echo,$(1),Enabled mode 40.))
$(if $(filter 80,$(MB_AUTOEXEC_TEXTMODE)),$(call mb_autoexec_append_cmd,$(1),mode 80))
$(if $(filter 80,$(MB_AUTOEXEC_TEXTMODE)),$(call mb_autoexec_append_echo,$(1),Enabled mode 80.))
endef
define mb_autoexec_open_gui
@echo === Generating autoexec.bat for command with gui
$(call mb_autoexec_write_default,$(1))
$(call mb_autoexec_append_gui_mode,$(1))
$(call mb_autoexec_append_stop_fail,$(1))
$(call mb_autoexec_append_echo,$(1),Type 'omsxctl exit' to stop emulation.)
endef
define mb_autoexec_open_gui_cmd
$(call mb_autoexec_open_gui,$(1))
$(call mb_autoexec_append_echo,$(1),Running command '$(2)')
$(call mb_autoexec_append_cmd,$(1),$(2))
endef
define mb_autoexec_cmd
@echo === Generating autoexec.bat for command
$(call mb_autoexec_write_default,$(1))
$(call mb_autoexec_append_echo,$(1),Running command '$(2)')
$(call mb_autoexec_append_cmd,$(1),$(2))
$(call mb_autoexec_append_exit,$(1))
endef
define mb_autoexec_cmd_test
@echo === Generating autoexec.bat for command test
$(call mb_autoexec_write_default,$(1))
$(call mb_autoexec_append_cmd,$(1),omsxctl fail_after $(MB_AUTOEXEC_TEST_TIMEOUT) seconds fail_after_test $(MB_AUTOEXEC_TEST_EXITCODE))
$(call mb_autoexec_append_echo,$(1),Running test '$(2)')
$(call mb_autoexec_append_cmd,$(1),$(2))
$(call mb_autoexec_append_exit,$(1))
endef

44
lib/make/mb_base.mk Normal file
View file

@ -0,0 +1,44 @@
# TODO: clean up + make working for non-unix systems.
# OS cmds
ifeq ($(OS),Windows_NT)
MB_RM = del /F /Q
MB_RMDIR = RMDIR /S /Q
MB_MKDIR = mkdir
MB_COPY = copy
MB_ERRIGNORE = 2>NUL || true
MB_SEP=\\
else
MB_RM = rm -f
MB_RMDIR = rm -rf
MB_MKDIR = mkdir -p
MB_COPY = cp
MB_ERRIGNORE = 2>/dev/null
MB_SEP=/
endif
# Remove space after separator
MB_PSEP = $(strip $(MB_SEP))
define mb_clean
@echo === Cleaning build folder.
test $(1) && $(MB_RMDIR) $(1)
endef
define mb_mkdir
@echo === Create module build folder.
$(MB_MKDIR) $(1)
endef
define mb_delete
test $(1) && $(MB_RM) $(1)
endef
define mb_copy
$(MB_COPY) $(1) $(2)
endef
define mb_file_info
sha1sum $(1)
ls -lah $(1)
endef
define mb_create_dist
tar -czf $(1) -C $(2) `ls $(2)`
$(call mb_file_info,$(1))
endef

62
lib/make/mb_openmsx.mk Normal file
View file

@ -0,0 +1,62 @@
# TODO move to new msxhub native posix+win cmd tool
# + local userdir caching like ~/.cache/msxhub/repro/m/s/x/msxdos2
CMD_WGET ?= wget
PATH_OPENMSX ?= /usr/bin
# Define openmsx defaults
MB_OPENMSX_BOOT_TIMEOUT ?= 25
MB_OPENMSX_MACHINE ?= Philips_NMS_8250
MB_OPENMSX_JOYPORTA ?=
MB_OPENMSX_JOYPORTB ?=
# Workaround for include msxbuild.mk file and 'older' openmsx segfaults on relative settings path.
MB_OPENMSX_SETTING := $(if $(realpath $(PATH_MSXBUILD)),$(realpath $(PATH_MSXBUILD)),$(PATH_MSXBUILD))/lib/openmsx/boot_settings.xml
MB_OPENMSX_EXTS_ORG += -ext ide -ext ram4mb
MB_OPENMSX_ARGS = \
-setting $(MB_OPENMSX_SETTING) \
-machine $(MB_OPENMSX_MACHINE) \
-ext slotexpander $(MB_OPENMSX_EXTS_ORG) $(MB_OPENMSX_EXTS) \
-script $(PATH_MSXBUILD)/lib/openmsx/boot_env.tcl \
-script $(PATH_MSXBUILD)/lib/openmsx/boot_hdd.tcl \
-script $(PATH_MSXBUILD)/lib/openmsx/fail_after.tcl \
-script $(PATH_MSXBUILD)/bin/wget/omsxctl.tcl
# TODO: add run flag to disable xml output like "-control stdio-boot-only"
ifeq ($(OS),Windows_NT)
MB_OPENMSX_CMD = $(PATH_OPENMSX)/openmsx $(MB_OPENMSX_ARGS) -control stdio < $(PATH_MSXBUILD)/lib/openmsx/boot_stdio.xml
else
MB_OPENMSX_CMD = $(PATH_OPENMSX)/openmsx $(MB_OPENMSX_ARGS) -control stdio < $(PATH_MSXBUILD)/lib/openmsx/boot_stdio.xml | sed -n -e 's/.*>\(.*\)<.*/\1/p' | tail -n+3
endif
define _mb_openmsx_run
@echo === Running openmsx
test -f $(PATH_MSXBUILD)/bin/wget/omsxctl.tcl || $(CMD_WGET) -O $(PATH_MSXBUILD)/bin/wget/omsxctl.tcl https://msxhub.com/api/OMSXCTL/1.0-1/get/OMSXCTL/omsxctl.tcl
FAIL_AFTER_BOOT=$(MB_OPENMSX_BOOT_TIMEOUT) \
FAIL_AFTER_PATH=bin \
BOOT_HDD_PATH="$(1)" \
BOOT_HDD_IMAGE="$(1)/../dsk.img" \
JOYPORTA=$(MB_OPENMSX_JOYPORTA) \
JOYPORTB=$(MB_OPENMSX_JOYPORTB) \
$(MB_OPENMSX_CMD)
endef
define _mb_openmsx_run_dos
@echo === run openmsx
test -f $(PATH_MSXBUILD)/bin/wget/omsxctl.com || $(CMD_WGET) -O $(PATH_MSXBUILD)/bin/wget/omsxctl.com https://msxhub.com/api/OMSXCTL/1.0-1/get/OMSXCTL/omsxctl.com
$(call mb_copy,$(PATH_MSXBUILD)/bin/wget/omsxctl.com,$(1))
$(call _mb_openmsx_run,$(1))
endef
# TODO: add msx1+allversions of dos to https://github.com/fr3nd/msxhub-packages/issues/18
#define mb_openmsx_dos1
# @echo === Run openmsx_dos1
# cp build/msxdos1/* $(1)
# $(call _mb_openmsx_run_dos,$(1))
#endef
define mb_openmsx_dos2
@echo === Prepare openmsx run with dos2
test -f $(PATH_MSXBUILD)/bin/wget/msxdos2.sys || $(MB_MKDIR) $(PATH_MSXBUILD)/bin/wget
test -f $(PATH_MSXBUILD)/bin/wget/msxdos2.sys || $(CMD_WGET) -O $(PATH_MSXBUILD)/bin/wget/msxdos2.sys https://msxhub.com/api/MSXDOS2/2.20-1/get/MSXDOS2/MSXDOS2.SYS
test -f $(PATH_MSXBUILD)/bin/wget/command2.com || $(CMD_WGET) -O $(PATH_MSXBUILD)/bin/wget/command2.com https://msxhub.com/api/MSXDOS2/2.20-1/get/MSXDOS2/COMMAND2.COM
$(call mb_copy,$(PATH_MSXBUILD)/bin/wget/msxdos2.sys,$(1))
$(call mb_copy,$(PATH_MSXBUILD)/bin/wget/command2.com,$(1))
$(call _mb_openmsx_run_dos, $(1))
endef

74
lib/make/msxbuild.mk Normal file
View file

@ -0,0 +1,74 @@
# msxbuild.mk - Makefile helper to use with msx projects.
#
# note: this needs more work.
#
# Required tools paths
PATH_HEX2BIN ?= /usr/bin
PATH_SDCC ?= /usr/bin
PATH_MSXBUILD ?= $(dir $(lastword $(MAKEFILE_LIST)))../..
include $(PATH_MSXBUILD)/lib/make/mb_base.mk
include $(PATH_MSXBUILD)/lib/make/mb_autoexec.mk
include $(PATH_MSXBUILD)/lib/make/mb_openmsx.mk
include $(PATH_MSXBUILD)/lib/make/mb_assert.mk
CMD_H2B ?= $(PATH_HEX2BIN)/hex2bin
CMD_SDCC ?= $(PATH_SDCC)/sdcc
CMD_SDASM ?= $(PATH_SDCC)/sdasz80
CMD_SDAR ?= $(PATH_SDCC)/sdar
# Define build flags
MB_SDCC_FLAG_CPU ?= -mz80
MB_SDCC_FLAG_LD ?= --nostdinc
MB_SDASM_FLAGS ?= -g -l -c -o
MB_SDAR_FLAGS ?= -rc
#$(MB_SDASM) -I$(MB_LIBASM_SRC)/include
define mb_compile_asm
@echo === Compile module asm.
$(CMD_SDASM) $(MB_SDASM_FLAGS) $(1) $(2)
endef
define mb_link_asm_lib
@echo === Link module asm lib.
$(CMD_SDAR) $(MB_SDAR_FLAGS) $(1) $(2)
endef
define mb_link_asm
@echo === Link asm module at $(3)
$(CMD_SDCC) $(MB_SDCC_FLAG_CPU) --no-std-crt0 --code-loc $(3) -o $(1) $(2)
endef
define mb_link_asm_0000
$(call mb_link_asm,$(1),$(2),0x0000)
endef
define mb_link_asm_dos
$(call mb_link_asm,$(1),$(2),0x0100)
endef
define mb_link_asm_1000
$(call mb_link_asm,$(1),$(2),0x1000)
endef
define mb_link_asm_4000
$(call mb_link_asm,$(1),$(2),0x4000)
endef
define mb_link_asm_8000
$(call mb_link_asm,$(1),$(2),0x8000)
endef
define mb_link_asm_C000
$(call mb_link_asm,$(1),$(2),0xC000)
endef
#-l$(LIBASM_LINK)
define mb_hex2com
@echo === Convert to binary: $(notdir $(1)).com
cd $(dir $(1)) && $(CMD_H2B) -e com $(notdir $(1))
$(call mb_file_info,$(2))
@echo === Done $(notdir $(2))
endef
define mb_hex2dat
@echo === Convert to binary $(notdir $(1)).dat
cd $(dir $(1)) && $(CMD_H2B) -e dat $(notdir $(1))
$(call mb_file_info,$(2))
@echo === Done $(notdir $(2))
endef

65
lib/openmsx/boot_env.tcl Normal file
View file

@ -0,0 +1,65 @@
# boot_env -- Sets various openMSX settings based from environment variables.
#
# Typically used in automation tools which run openMSX without human interaction.
# Supported environment variables by this script;
#
# SAVE_SETTINGS_ON_EXIT=false
# Disables automatic settings saving.
#
# RENDERER=none
# Disables video output, to enable video use 'SDL' as argument.
#
# THROTTLE=off
# Disables msx speed emulation.
#
# SPEED=400
# Sets msx speed to 4x of original but only when throttle is on.
#
# JOYPORTA=mouse
# Inserts mouse in joyporta.
#
# JOYPORTB=mouse
# Inserts mouse in joyportb.
#
if {[info exists ::env(SAVE_SETTINGS_ON_EXIT)] && ([string trim $::env(SAVE_SETTINGS_ON_EXIT)] != "")} {
if {[catch {set save_settings_on_exit [string trim $::env(SAVE_SETTINGS_ON_EXIT)]} err_msg]} {
puts stderr "error: env.SAVE_SETTINGS_ON_EXIT value $err_msg"
exit 1
}
}
if {[info exists ::env(RENDERER)] && ([string trim $::env(RENDERER)] != "")} {
if {[catch {set renderer [string trim $::env(RENDERER)]} err_msg]} {
puts stderr "error: env.RENDERER value $err_msg"
exit 1
}
}
if {[info exists ::env(THROTTLE)] && ([string trim $::env(THROTTLE)] != "")} {
if {[catch {set throttle [string trim $::env(THROTTLE)]} err_msg]} {
puts stderr "error: env.THROTTLE value $err_msg"
exit 1
}
}
if {[info exists ::env(SPEED)] && ([string trim $::env(SPEED)] != "")} {
if {[catch {set speed [string trim $::env(SPEED)]} err_msg]} {
puts stderr "error: env.SPEED value $err_msg"
exit 1
}
}
if {[info exists ::env(JOYPORTA)] && ([string trim $::env(JOYPORTA)] != "")} {
if {[catch {plug joyporta [string trim $::env(JOYPORTA)]} err_msg]} {
puts stderr "error: env.JOYPORTA value $err_msg"
exit 1
}
}
if {[info exists ::env(JOYPORTB)] && ([string trim $::env(JOYPORTB)] != "")} {
if {[catch {plug joyportb [string trim $::env(JOYPORTB)]} err_msg]} {
puts stderr "error: env.JOYPORTB value $err_msg"
exit 1
}
}

130
lib/openmsx/boot_hdd.tcl Normal file
View file

@ -0,0 +1,130 @@
# boot_hdd -- Create import/export disk images to local folder.
#
# Typically used in automation tools which run openMSX without human interaction.
# This script is basicly is a bit more generic and safe way to run the following code;
#
# diskmanipulator create disk.img 32m 32m 32m 32m
# hda disk.img
# diskmanipulator import hda1 ./disk-in/
# after quit {diskmanipulator export hda1 ./disk-out/}
#
# Supported environment variables by this script;
#
# BOOT_HDD_SIZE=30m
# Sets the size of the created partitions, defaults to 15m.
#
# BOOT_HDD_IMAGE=bin/myapp/dsk.img
# Defaults to ./hdd.dsk
#
# BOOT_HDD_PATH=bin/myapp/dsk
# provides the default values for BOOT_HDD_PATH_IMPORT and BOOT_HDD_PATH_EXPORT
#
# BOOT_HDD_PATH_IMPORT=bin/myapp/dsk
# When set enables the import of all files into the first disk partition.
#
# BOOT_HDD_PATH_EXPORT=bin/myapp/dsk-result
# When set enables the export of all files back to the filesystem
#
# BOOT_HDD_EXPORT_PARTITION=2
# When set override the export from 'first' to 'given' partition number.
#
# BOOT_HDD_EXPORT_DIR=myout
# By default export does chdir to root of msx partition override to custom export directory.
#
# BOOT_HDD_PARTITIONS=2
# The number of partitions created in the disk image, defaults to 1.
#
# per default create msxdos1 compatible partition size.
set boot_hdd_size 15m
set boot_hdd_image hdd.dsk
set boot_hdd_path_import 0
set boot_hdd_path_export 0
set boot_hdd_export_partition 0
set boot_hdd_export_dir \\
set boot_hdd_partitions 1
# Parse env settings
if {[info exists ::env(BOOT_HDD_SIZE)] && ([string trim $::env(BOOT_HDD_SIZE)] != "")} {
set boot_hdd_size [string trim $::env(BOOT_HDD_SIZE)]
}
if {[info exists ::env(BOOT_HDD_IMAGE)] && ([string trim $::env(BOOT_HDD_IMAGE)] != "")} {
set boot_hdd_image [string trim $::env(BOOT_HDD_IMAGE)]
}
if {[info exists ::env(BOOT_HDD_PATH)] && ([string trim $::env(BOOT_HDD_PATH)] != "")} {
set boot_hdd_path_import [string trim $::env(BOOT_HDD_PATH)]
set boot_hdd_path_export [string trim $::env(BOOT_HDD_PATH)]
}
if {[info exists ::env(BOOT_HDD_PATH_IMPORT)] && ([string trim $::env(BOOT_HDD_PATH_IMPORT)] != "")} {
set boot_hdd_path_import [string trim $::env(BOOT_HDD_PATH_IMPORT)]
}
if {[info exists ::env(BOOT_HDD_PATH_EXPORT)] && ([string trim $::env(BOOT_HDD_PATH_EXPORT)] != "")} {
set boot_hdd_path_export [string trim $::env(BOOT_HDD_PATH_EXPORT)]
}
if {[info exists ::env(BOOT_HDD_EXPORT_PARTITION)] && ([string trim $::env(BOOT_HDD_EXPORT_PARTITION)] != "")} {
set boot_hdd_export_partition [string trim $::env(BOOT_HDD_EXPORT_PARTITION)]
}
if {[info exists ::env(BOOT_HDD_EXPORT_DIR)] && ([string trim $::env(BOOT_HDD_EXPORT_DIR)] != "")} {
set boot_hdd_export_dir [string trim $::env(BOOT_HDD_EXPORT_DIR)]
}
if {[info exists ::env(BOOT_HDD_PARTITIONS)] && ([string trim $::env(BOOT_HDD_PARTITIONS)] != "")} {
set boot_hdd_partitions [string trim $::env(BOOT_HDD_PARTITIONS)]
if {$boot_hdd_partitions == 0 || $boot_hdd_partitions > 4} {
puts stderr "error: Invalid env.BOOT_HDD_PARTITIONS value 1-4 allowed: $boot_hdd_partitions"
exit 1
}
}
if {$boot_hdd_path_import != 0} {
set boot_hdd_disk_partition "hda"
if {$boot_hdd_partitions == 1} {
if {[catch {diskmanipulator create $boot_hdd_image $boot_hdd_size} err_msg]} {
puts stderr "error: create1 $err_msg"
exit 1
}
}
if {$boot_hdd_partitions > 1} {
set boot_hdd_disk_partition "hda1"
if {$boot_hdd_partitions == 2} {
if {[catch {diskmanipulator create $boot_hdd_image $boot_hdd_size $boot_hdd_size} err_msg]} {
puts stderr "error: create2 $err_msg"
exit 1
}
}
if {$boot_hdd_partitions == 3} {
if {[catch {diskmanipulator create $boot_hdd_image $boot_hdd_size $boot_hdd_size $boot_hdd_size} err_msg]} {
puts stderr "error: create3 $err_msg"
exit 1
}
}
if {$boot_hdd_partitions == 4} {
if {[catch {diskmanipulator create $boot_hdd_image $boot_hdd_size $boot_hdd_size $boot_hdd_size $boot_hdd_size} err_msg]} {
puts stderr "error: create4 $err_msg"
exit 1
}
}
}
if {[catch {hda $boot_hdd_image} err_msg]} {
puts stderr "error: hda $err_msg"
exit 1
}
if {[catch {diskmanipulator import $boot_hdd_disk_partition $boot_hdd_path_import} err_msg]} {
puts stderr "error: import $err_msg"
exit 1
}
if {$boot_hdd_path_export != 0} {
if {$boot_hdd_export_partition != 0} {
set boot_hdd_disk_partition "hda$boot_hdd_export_partition"
}
after quit {
if {[catch {diskmanipulator chdir $boot_hdd_disk_partition $boot_hdd_export_dir} err_msg]} {
puts stderr "error: chdir $err_msg"
exit 1
}
if {[catch {diskmanipulator export $boot_hdd_disk_partition $boot_hdd_path_export} err_msg]} {
puts stderr "error: export $err_msg"
exit 1
}
}
}
}

View file

@ -0,0 +1,9 @@
<!DOCTYPE settings SYSTEM 'settings.dtd'>
<settings>
<settings>
<setting id="save_settings_on_exit">false</setting>
<setting id="scale_factor">3</setting>
<setting id="speed">333</setting>
</settings>
<bindings/>
</settings>

View file

@ -0,0 +1,8 @@
<openmsx-control>
<!--
When booting 'openmsx -control stdio < boot_stdio.xml'
It starts then in power off mode and without renderer for fast booting.
-->
<command>set power on</command>
<command>set throttle off</command>
</openmsx-control>

View file

@ -0,0 +1,77 @@
# fail_after -- exits openMSX after timeout.
#
# Typically used in combination with the MSX-DOS 'omsxctl.com' utility.
#
# Adds two environment variables and two commands to openMSX;
#
# 'fail_after timeout [timeunit] [fail_id] [fail_code]'
# Schedules an openMSX exit after the timeout.
# This can be canceled by requesting a timeout of 0 or new timeout.
# The timeunit can be selected between (msx)'time' and (host)'realtime'.
# The fail_id can be used to differentiate between multiple fail_after commands.
# The failure exit code can be given too.
#
# 'fail_after_exit [fail_id] [fail_code]'
# Exits openMSX with an failure exit code and if the FAIL_AFTER_PATH is
# set it also creates a screenshot named from the failure id.
#
# Supported environment variables by this script;
#
# FAIL_AFTER_PATH=.
# Enabled automatic screenshots saving in case of failures in the supplied path.
#
# FAIL_AFTER_BOOT=30
# Enables the boot watchdog timer which will exit openMSX after the timeout(in seconds).
# To cancel this timer give an `fail_after 0` or any new fail_after command.
#
proc fail_after_exit {{fail_id "fail_after_exit"} {fail_code 2}} {
global fail_after_path
if {$fail_after_path != 0} {
if {[catch {screenshot $fail_after_path/$fail_id.png} err_msg]} {
puts stderr "warning: $err_msg"
}
# maybe later add; if {is_text_mode} { [get_screen] ?> $fail_after_path/$fail_id.scr }
}
puts stderr "error: Failure request from $fail_id"
exit $fail_code
}
proc fail_after { timeout {time_unit "time"} {fail_id "fail_after"} {fail_code 2}} {
global fail_after_prev_timer
global fail_after_prev_id
set msg ""
if {$fail_after_prev_timer != 0} {
after cancel $fail_after_prev_timer
set msg "$fail_after_prev_id: Stopped attempt."
}
set fail_after_prev_id $fail_id
if {$time_unit != "time"} {
set time_unit "realtime"
}
if {$timeout != 0} {
if {[catch {set fail_after_prev_timer [after $time_unit $timeout "fail_after_exit $fail_id $fail_code"]} err_msg]} {
puts stderr "error: $err_msg"
fail_after_exit fail_after_timer_error 1
}
set msg "$msg\n$fail_id: Automatic failure in $timeout $time_unit seconds."
} else {
set fail_after_prev_timer 0
}
return $msg
}
# Globals
set fail_after_prev_timer 0
set fail_after_prev_id 0
set fail_after_path 0
# Parse screenshot path env setting
if {[info exists ::env(FAIL_AFTER_PATH)] && ([string trim $::env(FAIL_AFTER_PATH)] != "")} {
set fail_after_path [string trim $::env(FAIL_AFTER_PATH)]
}
# Enables boot watch dog timer when FAIL_AFTER_BOOT env has a value. (124 see `man timeout`)
if {[info exists ::env(FAIL_AFTER_BOOT)] && ([string trim $::env(FAIL_AFTER_BOOT)] != "")} {
fail_after [string trim $::env(FAIL_AFTER_BOOT)] realtime fail_after_boot 124
}

33
test/ahello/0module.mk Normal file
View file

@ -0,0 +1,33 @@
ASM_HELLO_NAME := ahello
ASM_HELLO_RUN := run-$(ASM_HELLO_NAME)
ASM_HELLO_TEST := test-$(ASM_HELLO_NAME)
ASM_HELLO_SRC := test/$(ASM_HELLO_NAME)
ASM_HELLO_BIN := $(PATH_BIN)/test/$(ASM_HELLO_NAME)
ASM_HELLO_HEX := $(ASM_HELLO_BIN)/$(ASM_HELLO_NAME).hex
ASM_HELLO_COM := $(ASM_HELLO_BIN)/$(ASM_HELLO_NAME).com
ASM_HELLO_RELS := $(ASM_HELLO_BIN)/$(ASM_HELLO_NAME).rel
ASM_HELLO_CODE := $(ASM_HELLO_SRC)/$(ASM_HELLO_NAME).asm
BUILD_HELP += \\n\\t* $(ASM_HELLO_COM)\\n\\t* $(ASM_HELLO_RUN)\\n\\t* $(ASM_HELLO_TEST) \(Change txt in hello.asm and run again\)
$(ASM_HELLO_BIN):
$(call mb_mkdir,$(ASM_HELLO_BIN))
$(ASM_HELLO_BIN)/%.rel: $(ASM_HELLO_SRC)/%.asm | $(ASM_HELLO_BIN)
$(call mb_compile_asm,$@,$<)
$(ASM_HELLO_HEX): $(ASM_HELLO_RELS)
$(call mb_link_asm_dos,$(ASM_HELLO_HEX),$(ASM_HELLO_RELS))
$(ASM_HELLO_COM): $(ASM_HELLO_HEX)
$(call mb_hex2com,$(ASM_HELLO_HEX),$(ASM_HELLO_COM))
$(ASM_HELLO_RUN): $(ASM_HELLO_COM)
$(call mb_autoexec_open_gui,$(ASM_HELLO_BIN))
$(call mb_openmsx_dos2,$(ASM_HELLO_BIN))
$(ASM_HELLO_TEST): $(ASM_HELLO_COM)
$(call mb_delete,$(ASM_HELLO_BIN)/test.out)
$(call mb_autoexec_cmd_test,$(ASM_HELLO_BIN),$(ASM_HELLO_NAME) > test.out)
$(call mb_openmsx_dos2,$(ASM_HELLO_BIN))
$(call mb_assert_file_equals,$(ASM_HELLO_BIN)/test.out,Hello world...from asm.)

42
test/ahello/ahello.asm Normal file
View file

@ -0,0 +1,42 @@
DOS .equ 0x5
_CONOUT .equ 0x02
.area _CODE
JP START
.db 0x0D ; type hello.com
.db 0x0D,0x0A
.str "Example hello world executable."
.db 0x0D,0x0A
.db 0x1A ; end txt
START:
LD HL,#TXT_HELLO
CALL PUT_TXT
LD HL,#TXT_HELLO_SRC
CALL PUT_TXT
RET
PUT_TXT:
LD A,(HL)
CP #0x1D
RET Z
LD E,A
LD C,#2
PUSH HL
CALL DOS
POP HL
INC HL
JR PUT_TXT
TXT_HELLO:
.str "Hello world..."
.db 0x1D
TXT_HELLO_SRC:
.str "from asm."
.db 0x0D,0x0A
.db 0x1D
.area _DATA