Compare commits
3 commits
de71597d69
...
b3100175a8
Author | SHA1 | Date | |
---|---|---|---|
Willem Cazander | b3100175a8 | ||
Willem Cazander | 98a9d2d03f | ||
Willem Cazander | 60183a3690 |
38
.gitignore
vendored
Normal file
38
.gitignore
vendored
Normal 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
|
71
Makefile
Normal file
71
Makefile
Normal file
|
@ -0,0 +1,71 @@
|
||||||
|
-include Makelocal.mk
|
||||||
|
PATH_SDCC ?= /usr/bin
|
||||||
|
PATH_HEX2BIN ?= /usr/bin
|
||||||
|
PATH_BIN := bin
|
||||||
|
BUILD_ALL := "Use 'make help' for possible targets."
|
||||||
|
BUILD_HELP := "Use one of the following build targets;"
|
||||||
|
BUILD_VERSION ?= 1.0
|
||||||
|
BUILD_NAME := omsxctl-$(BUILD_VERSION)
|
||||||
|
.SUFFIXES:
|
||||||
|
|
||||||
|
.PHONY: all
|
||||||
|
all:
|
||||||
|
@echo $(BUILD_ALL)
|
||||||
|
|
||||||
|
BUILD_HELP += \\n\\t* help
|
||||||
|
.PHONY: help
|
||||||
|
help:
|
||||||
|
@echo $(BUILD_HELP)
|
||||||
|
|
||||||
|
BUILD_HELP += \\n\\t* clean
|
||||||
|
.PHONY: clean
|
||||||
|
clean:
|
||||||
|
rm bin -rf
|
||||||
|
|
||||||
|
bin/omsxctl:
|
||||||
|
mkdir -p bin/omsxctl
|
||||||
|
|
||||||
|
bin/omsxctl/%.rel: src/%.asm | bin/omsxctl
|
||||||
|
$(PATH_SDCC)/sdasz80 -g -l -c -o $@ $<
|
||||||
|
|
||||||
|
bin/omsxctl/omsxctl.hex: bin/omsxctl/omsxctl.rel
|
||||||
|
$(PATH_SDCC)/sdcc -mz80 --no-std-crt0 --code-loc 0x0100 -o $@ $<
|
||||||
|
|
||||||
|
BUILD_HELP += \\n\\t* bin/omsxctl/omsxctl.com
|
||||||
|
bin/omsxctl/omsxctl.com: bin/omsxctl/omsxctl.hex
|
||||||
|
cd bin/omsxctl && $(PATH_HEX2BIN)/hex2bin -e com omsxctl.hex
|
||||||
|
|
||||||
|
bin/dist:
|
||||||
|
mkdir -p bin/dist
|
||||||
|
|
||||||
|
bin/dist/$(BUILD_NAME): | bin/dist
|
||||||
|
mkdir -p bin/dist/$(BUILD_NAME)
|
||||||
|
|
||||||
|
bin/dist/$(BUILD_NAME)/omsxctl.com: bin/dist/$(BUILD_NAME) | bin/omsxctl/omsxctl.com
|
||||||
|
cp bin/omsxctl/omsxctl.com bin/dist/$(BUILD_NAME)/omsxctl.com
|
||||||
|
|
||||||
|
bin/dist/$(BUILD_NAME)/omsxctl.tcl: bin/dist/$(BUILD_NAME)
|
||||||
|
cp src/omsxctl.tcl bin/dist/$(BUILD_NAME)/omsxctl.tcl
|
||||||
|
|
||||||
|
bin/dist/$(BUILD_NAME)/omsxctl.asm: bin/dist/$(BUILD_NAME)
|
||||||
|
cp src/omsxctl.asm bin/dist/$(BUILD_NAME)/omsxctl.asm
|
||||||
|
|
||||||
|
bin/dist/$(BUILD_NAME)/usage.txt:
|
||||||
|
echo "# Usage\r" > $@
|
||||||
|
echo "\r" >> $@
|
||||||
|
echo "Pass the tcl script to openMSX on the command line:\r" >> $@
|
||||||
|
echo " openmsx -script <path-to>/omsxctl.tcl\r" >> $@
|
||||||
|
echo "\r" >> $@
|
||||||
|
echo "And then in MSX-DOS execute something like:\r" >> $@
|
||||||
|
echo " omsxctl set throttle off\r" >> $@
|
||||||
|
echo " ...\r" >> $@
|
||||||
|
echo " omsxctl exit\r" >> $@
|
||||||
|
echo "\r" >> $@
|
||||||
|
|
||||||
|
BUILD_HELP += \\n\\t* bin/dist/$(BUILD_NAME).tar.gz
|
||||||
|
bin/dist/$(BUILD_NAME).tar.gz: \
|
||||||
|
bin/dist/$(BUILD_NAME)/omsxctl.com \
|
||||||
|
bin/dist/$(BUILD_NAME)/omsxctl.tcl \
|
||||||
|
bin/dist/$(BUILD_NAME)/omsxctl.asm \
|
||||||
|
bin/dist/$(BUILD_NAME)/usage.txt
|
||||||
|
cd bin/dist && tar -czvf $(BUILD_NAME).tar.gz $(BUILD_NAME)
|
7
Makelocal.mk.tpl
Normal file
7
Makelocal.mk.tpl
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
# 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
|
25
README.md
25
README.md
|
@ -1,3 +1,26 @@
|
||||||
# omsxctl
|
# omsxctl
|
||||||
|
|
||||||
OpenMSXConTroL Utility and script
|
'OpenMSXConTroL' is an utility to send control commands to openMSX from within the emulated msx.
|
||||||
|
|
||||||
|
Original idea by 'immetoo' implemented with help from 'm9710797'
|
||||||
|
(see https://github.com/openMSX/openMSX/issues/1133)
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
Pass the tcl script to openMSX on the command line:
|
||||||
|
|
||||||
|
openmsx -script <path-to>/omsxctl.tcl
|
||||||
|
And then in MSX-DOS execute something like:
|
||||||
|
|
||||||
|
omsxctl set throttle off
|
||||||
|
...
|
||||||
|
omsxctl exit
|
||||||
|
|
||||||
|
## build
|
||||||
|
|
||||||
|
Copy Makelocal.mk.tpl to Makelocal.mk and setup your lib paths and type;
|
||||||
|
|
||||||
|
```
|
||||||
|
make help
|
||||||
|
|
||||||
|
```
|
||||||
|
|
132
src/omsxctl.asm
Normal file
132
src/omsxctl.asm
Normal file
|
@ -0,0 +1,132 @@
|
||||||
|
; MSX-DOS utility to execute openMSX commands from within the MSX.
|
||||||
|
;
|
||||||
|
; This can be used to e.g. integrate a MSX program in a build chain
|
||||||
|
; on the host computer.
|
||||||
|
;
|
||||||
|
; For example start openMSX from the command line like this:
|
||||||
|
; openmsx -script omsxctl.tcl -diska my_directory
|
||||||
|
;
|
||||||
|
; And inside my_directory/ put the a AUTOEXEC.BAT with content:
|
||||||
|
; omsxctl after time 100 "exit 1"
|
||||||
|
; my_tool my_data.in my_data.out
|
||||||
|
; omsxctl exit 0
|
||||||
|
|
||||||
|
bdos .equ 0x5
|
||||||
|
PutChr .equ 0x2
|
||||||
|
ArgSize .equ 0x0080
|
||||||
|
ArgData .equ 0x0081
|
||||||
|
ScriptPort .equ 0x2d
|
||||||
|
|
||||||
|
.area _CODE
|
||||||
|
; Detect whether the 'omsxctl.tcl' script is active.
|
||||||
|
ld hl,#ZeroStr ; empty command (doesn't produce output)
|
||||||
|
scf
|
||||||
|
out (ScriptPort),a ; script should change clear carry flag
|
||||||
|
jr c,ErrNoScript
|
||||||
|
|
||||||
|
; Process command line.
|
||||||
|
ld a,(ArgSize)
|
||||||
|
or a
|
||||||
|
jr z,ErrNoArgs
|
||||||
|
ld hl,#ArgData
|
||||||
|
add a,l
|
||||||
|
ld l,a
|
||||||
|
ld (hl),#0 ; write 0-terminator (needed for DOS1?)
|
||||||
|
|
||||||
|
; Execute command.
|
||||||
|
ld hl,#ArgData+1 ; skip first space
|
||||||
|
ld de,#ResultBuf
|
||||||
|
ld bc,#ResultBufSize
|
||||||
|
out (ScriptPort),a
|
||||||
|
|
||||||
|
; Did the command give an error?
|
||||||
|
jr nc,NoError
|
||||||
|
ld hl,#TxtCmdError
|
||||||
|
push bc
|
||||||
|
call Print
|
||||||
|
pop bc
|
||||||
|
NoError:
|
||||||
|
|
||||||
|
; Was the result string truncated?
|
||||||
|
ld a,b
|
||||||
|
and c
|
||||||
|
inc a ; BC == 0xffff ?
|
||||||
|
jr nz,NotTruncated
|
||||||
|
ld hl,#TxtTruncated
|
||||||
|
call Print
|
||||||
|
ld bc,#ResultBufSize
|
||||||
|
NotTruncated:
|
||||||
|
|
||||||
|
; Print the result string and translate \n to \r\n.
|
||||||
|
ld hl,#ResultBuf
|
||||||
|
ResultLoop:
|
||||||
|
ld a,b
|
||||||
|
or c
|
||||||
|
jr z,Done
|
||||||
|
push hl
|
||||||
|
push bc
|
||||||
|
ld a,(hl)
|
||||||
|
cp #10
|
||||||
|
jr nz,Not10
|
||||||
|
ld e,#13
|
||||||
|
ld c,#PutChr
|
||||||
|
call bdos
|
||||||
|
ld a,#10
|
||||||
|
Not10:
|
||||||
|
ld e,a
|
||||||
|
ld c,#PutChr
|
||||||
|
call bdos
|
||||||
|
pop bc
|
||||||
|
pop hl
|
||||||
|
inc hl
|
||||||
|
dec bc
|
||||||
|
jr ResultLoop
|
||||||
|
|
||||||
|
Done:
|
||||||
|
ld hl,#TxtNewLine
|
||||||
|
jr Print
|
||||||
|
|
||||||
|
ErrNoScript:
|
||||||
|
ld hl,#TxtErrNoScript
|
||||||
|
jr Print
|
||||||
|
|
||||||
|
ErrNoArgs:
|
||||||
|
ld hl,#TxtErrNoArgs
|
||||||
|
; print
|
||||||
|
|
||||||
|
Print:
|
||||||
|
ld a,(hl)
|
||||||
|
or a
|
||||||
|
ret z
|
||||||
|
ld e,a
|
||||||
|
ld c,#PutChr
|
||||||
|
push hl
|
||||||
|
call bdos
|
||||||
|
pop hl
|
||||||
|
inc hl
|
||||||
|
jr Print
|
||||||
|
|
||||||
|
|
||||||
|
TxtErrNoScript:
|
||||||
|
.str "The 'omsxctl.tcl' script is not active."
|
||||||
|
.db 0
|
||||||
|
|
||||||
|
TxtErrNoArgs:
|
||||||
|
.str "No arguments given."
|
||||||
|
.db 0
|
||||||
|
|
||||||
|
TxtCmdError:
|
||||||
|
.str "ERROR: "
|
||||||
|
.db 0
|
||||||
|
|
||||||
|
TxtTruncated:
|
||||||
|
.str "[truncated]"
|
||||||
|
TxtNewLine:
|
||||||
|
.db 13, 10
|
||||||
|
ZeroStr:
|
||||||
|
.db 0
|
||||||
|
|
||||||
|
ResultBuf:
|
||||||
|
ResultBufSize .equ 0x4000
|
||||||
|
|
||||||
|
.area _DATA
|
57
src/omsxctl.tcl
Normal file
57
src/omsxctl.tcl
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
# omsxctl -- execute openMSX commands from within an MSX program
|
||||||
|
#
|
||||||
|
# Typically used in combination with the MSX-DOS 'omsxctl.com' utility.
|
||||||
|
#
|
||||||
|
# But can also be used from any other MSX program with a code snippet like
|
||||||
|
# this:
|
||||||
|
# ld hl,command ; pointer to the to be executed command
|
||||||
|
# ld de,result ; the result of the command is written here
|
||||||
|
# ld bc,resultSize ; size of the result buffer (set to 0 if result is not needed)
|
||||||
|
# out (#2d),a ; the value of A doesn't matter
|
||||||
|
# jp c,error ; carry-flag set if there was an error executing the command
|
||||||
|
# ; BC is set to the actual length of the result string,
|
||||||
|
# ; or set to 0xffff when the result buffer was too small,
|
||||||
|
# ; in that case the result is still written to [DE] but truncated.
|
||||||
|
#
|
||||||
|
# Limitations:
|
||||||
|
# Strings containing characters >=128 are not handled well:
|
||||||
|
# - For passing the command string from the MSX to openMSX this could be
|
||||||
|
# fixed (but is it worth it?).
|
||||||
|
# - For passing the result from openMSX to the MSX I currently don't see a
|
||||||
|
# solution that handles both arbitrary utf-8 strings and binary data (e.g.
|
||||||
|
# created via the 'binary format' Tcl command). The current implementation
|
||||||
|
# chooses to handle binary data (and of course pure ASCII strings work fine
|
||||||
|
# as well).
|
||||||
|
|
||||||
|
proc trigger_omsxctl {} {
|
||||||
|
# Read the command string from memory.
|
||||||
|
set hl [reg HL]
|
||||||
|
set cmd ""
|
||||||
|
while 1 {
|
||||||
|
set c [peek $hl]
|
||||||
|
incr hl
|
||||||
|
if {$c == 0} break
|
||||||
|
append cmd [binary format c $c]
|
||||||
|
}
|
||||||
|
|
||||||
|
# Execute the command.
|
||||||
|
set err [catch [list uplevel #0 $cmd] result]
|
||||||
|
|
||||||
|
# Write the error status to the carry flag.
|
||||||
|
reg F [expr {([reg F] & 0xfe) | $err}]
|
||||||
|
|
||||||
|
# Write the result back to memory.
|
||||||
|
set len [string length $result]
|
||||||
|
set de [reg DE]
|
||||||
|
set bc [reg BC]
|
||||||
|
for {set i 0} {$i < $bc && $i < $len} {incr i} {
|
||||||
|
binary scan [string index $result $i] c c
|
||||||
|
poke [expr {$de + $i}] $c
|
||||||
|
}
|
||||||
|
|
||||||
|
# Write the actual result-length to BC.
|
||||||
|
reg BC [expr {($len <= $bc) ? $len : 0xffff}]
|
||||||
|
}
|
||||||
|
|
||||||
|
# Register callback on write to IO-port 0x2d.
|
||||||
|
debug set_watchpoint write_io 0x2d 1 trigger_omsxctl
|
Loading…
Reference in a new issue