Initial poc setup

This commit is contained in:
Willem Cazander 2020-12-23 18:55:56 +01:00
parent 0ce07185af
commit ad3f5e0bc4
22 changed files with 2696 additions and 2 deletions

371
Cargo.lock generated Normal file
View file

@ -0,0 +1,371 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
[[package]]
name = "alsa"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"alsa-sys 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"bitflags 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)",
"nix 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "alsa-sys"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"libc 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)",
"pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "ansi_term"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "atty"
version = "0.2.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"libc 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)",
"termion 1.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "bitflags"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "bitflags"
version = "0.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "bitflags"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "cfg-if"
version = "0.1.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "clap"
version = "2.33.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
"atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
"bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
"strsim 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
"textwrap 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
"unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
"vec_map 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "core-foundation"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"core-foundation-sys 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "core-foundation-sys"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"libc 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "coremidi"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"core-foundation 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
"core-foundation-sys 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
"coremidi-sys 2.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
"time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "coremidi-sys"
version = "2.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"core-foundation-sys 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "heck"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"unicode-segmentation 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "libc"
version = "0.2.51"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "memalloc"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "midir"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"alsa 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"bitflags 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
"coremidi 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)",
"memalloc 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"nix 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
"winmm-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "mmigate"
version = "0.0.1"
dependencies = [
"midir 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
"structopt 0.2.15 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "nix"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"bitflags 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
"cfg-if 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)",
"void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "numtoa"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "pkg-config"
version = "0.3.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "proc-macro2"
version = "0.4.28"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "quote"
version = "0.6.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"proc-macro2 0.4.28 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "redox_syscall"
version = "0.1.54"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "redox_termios"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"redox_syscall 0.1.54 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "strsim"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "structopt"
version = "0.2.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)",
"structopt-derive 0.2.15 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "structopt-derive"
version = "0.2.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"heck 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
"proc-macro2 0.4.28 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 0.15.32 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "syn"
version = "0.15.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"proc-macro2 0.4.28 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)",
"unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "termion"
version = "1.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"libc 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)",
"numtoa 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"redox_syscall 0.1.54 (registry+https://github.com/rust-lang/crates.io-index)",
"redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "textwrap"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "time"
version = "0.1.42"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"libc 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)",
"redox_syscall 0.1.54 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "unicode-segmentation"
version = "1.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "unicode-width"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "unicode-xid"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "vec_map"
version = "0.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "void"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "winapi"
version = "0.2.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "winapi"
version = "0.3.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "winapi-build"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "winapi-i686-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "winapi-x86_64-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "winmm-sys"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[metadata]
"checksum alsa 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8fd5a75e70d45a943d2a0a818277e71d6ff777e97358529d6b460d3d4c4d0745"
"checksum alsa-sys 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "b0edcbbf9ef68f15ae1b620f722180b82a98b6f0628d30baa6b8d2a5abc87d58"
"checksum ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b"
"checksum atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "9a7d5b8723950951411ee34d271d99dddcc2035a16ab25310ea2c8cfd4369652"
"checksum bitflags 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "32866f4d103c4e438b1db1158aa1b1a80ee078e5d77a59a2f906fd62a577389c"
"checksum bitflags 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4efd02e230a02e18f92fc2735f44597385ed02ad8f831e7c1c1156ee5e1ab3a5"
"checksum bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "228047a76f468627ca71776ecdebd732a3423081fcf5125585bcd7c49886ce12"
"checksum cfg-if 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "11d43355396e872eefb45ce6342e4374ed7bc2b3a502d1b28e36d6e23c05d1f4"
"checksum clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5067f5bb2d80ef5d68b4c87db81601f0b75bca627bc2ef76b141d7b846a3c6d9"
"checksum core-foundation 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "25bfd746d203017f7d5cbd31ee5d8e17f94b6521c7af77ece6c9e4b2d4b16c67"
"checksum core-foundation-sys 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "065a5d7ffdcbc8fa145d6f0746f3555025b9097a9e9cda59f7467abae670c78d"
"checksum coremidi 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ae2b8d4679b3a2a92b843d4c8e4a721be038ce49fce701c46296b2713f24c814"
"checksum coremidi-sys 2.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "07f05827cebb30dcd539ff1ac9bf6764f574a15fa147f8572f99d7617142f95e"
"checksum heck 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "20564e78d53d2bb135c343b3f47714a56af2061f1c928fdb541dc7b9fdd94205"
"checksum libc 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)" = "bedcc7a809076656486ffe045abeeac163da1b558e963a31e29fbfbeba916917"
"checksum memalloc 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "df39d232f5c40b0891c10216992c2f250c054105cb1e56f0fc9032db6203ecc1"
"checksum midir 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e653b919aca8b5f2697854f1819b33bfe49bcb3378abb0dbd834ce43ede9c7b1"
"checksum nix 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a2c5afeb0198ec7be8569d666644b574345aad2e95a53baf3a532da3e0f3fb32"
"checksum numtoa 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b8f8bdf33df195859076e54ab11ee78a1b208382d3a26ec40d142ffc1ecc49ef"
"checksum pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)" = "676e8eb2b1b4c9043511a9b7bea0915320d7e502b0a079fb03f9635a5252b18c"
"checksum proc-macro2 0.4.28 (registry+https://github.com/rust-lang/crates.io-index)" = "ba92c84f814b3f9a44c5cfca7d2ad77fa10710867d2bbb1b3d175ab5f47daa12"
"checksum quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)" = "faf4799c5d274f3868a4aae320a0a182cbd2baee377b378f080e16a23e9d80db"
"checksum redox_syscall 0.1.54 (registry+https://github.com/rust-lang/crates.io-index)" = "12229c14a0f65c4f1cb046a3b52047cdd9da1f4b30f8a39c5063c8bae515e252"
"checksum redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7e891cfe48e9100a70a3b6eb652fef28920c117d366339687bd5576160db0f76"
"checksum strsim 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a"
"checksum structopt 0.2.15 (registry+https://github.com/rust-lang/crates.io-index)" = "3d0760c312538987d363c36c42339b55f5ee176ea8808bbe4543d484a291c8d1"
"checksum structopt-derive 0.2.15 (registry+https://github.com/rust-lang/crates.io-index)" = "528aeb7351d042e6ffbc2a6fb76a86f9b622fdf7c25932798e7a82cb03bc94c6"
"checksum syn 0.15.32 (registry+https://github.com/rust-lang/crates.io-index)" = "846620ec526c1599c070eff393bfeeeb88a93afa2513fc3b49f1fea84cf7b0ed"
"checksum termion 1.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dde0593aeb8d47accea5392b39350015b5eccb12c0d98044d856983d89548dea"
"checksum textwrap 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060"
"checksum time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)" = "db8dcfca086c1143c9270ac42a2bbd8a7ee477b78ac8e45b19abfb0cbede4b6f"
"checksum unicode-segmentation 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "aa6024fc12ddfd1c6dbc14a80fa2324d4568849869b779f6bd37e5e4c03344d1"
"checksum unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "882386231c45df4700b275c7ff55b6f3698780a650026380e72dabe76fa46526"
"checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc"
"checksum vec_map 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "05c78687fb1a80548ae3250346c3db86a80a7cdd77bda190189f2d0a0987c81a"
"checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d"
"checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a"
"checksum winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "f10e386af2b13e47c89e7236a7a14a086791a2b88ebad6df9bf42040195cf770"
"checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc"
"checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
"checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
"checksum winmm-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "20a57a816b63ca4bf31aec70b4c334be13c4b73a30ab5b546135041627866035"

13
Cargo.toml Normal file
View file

@ -0,0 +1,13 @@
[package]
name = "mmigate"
description = "Msx Midi Internet Gateway"
version = "0.0.1"
authors = [ "Willem Cazander" ]
[dependencies]
structopt = "0.2"
midir = "0.5.0"
[[bin]]
name = "mmigate"
path = "src/mmigate/main.rs"

30
Makefile Normal file
View file

@ -0,0 +1,30 @@
#
# Top level makefile for tara
#
rwildcard = $(foreach d,$(wildcard $1*),$(call rwildcard,$d/,$2) $(filter $(subst *,%,$2),$d))
INC_MODS := $(call rwildcard, src, */0module.mk)
PATH_BIN := bin
PATH_SRC := src
BUILD_ALL := "Use 'make help' for possible targets."
BUILD_HELP := "Use one of the following build targets;"
MB_OPENMSX_EXTS += -ext FAC_MIDI_Interface
#MB_OPENMSX_EXTS += -ext Philips_NMS_1205
.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 $(PATH_MSXBUILD)/lib/make/msxbuild.mk
include $(INC_MODS)

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_OPENMSX ?= /opt/openMSX/bin/
#PATH_MSXBUILD ?= /opt/msxbuild

View file

@ -1,3 +1,24 @@
# mmigate
Msx Midi Internet Gateway
### MMIGATE
Msx Midi Internet Gateway
NOTE: Proof of concept no working code here...
## Running
make test-mmidrv
note: requires working openmsx with 8250+ide roms.
## Compile dist
make bin/dist.tar.gz
set prompt=on
set date=dd/mm/yy
set path=c:\;c:\msxdos;c:\utils;..;.
ntsc
doskey
ver

51
src/drivers/0module.mk Normal file
View file

@ -0,0 +1,51 @@
DRIVERS_NAME := drivers
DRIVERS_SRC := $(PATH_SRC)/$(DRIVERS_NAME)
DRIVERS_BIN := $(PATH_BIN)/$(DRIVERS_NAME)
DRIVERS_DEP := $(DRIVERS_SRC)/drv-unapi.asm $(DRIVERS_SRC)/drv-tcpip.asm $(DRIVERS_SRC)/drv-midi.asm
BUILD_HELP += \\n\\t* $(DRIVERS_BIN)/mmi-fac.dat\\n\\t* $(DRIVERS_BIN)/mmi-1205.dat\\n\\t* $(DRIVERS_BIN)/mmi-mint.dat\\n\\t* $(DRIVERS_BIN)/mmi-mext.dat
$(DRIVERS_BIN):
$(call mb_mkdir,$(DRIVERS_BIN))
$(DRIVERS_BIN)/mmi-fac.rel: $(DRIVERS_SRC)/mmi-fac.asm $(DRIVERS_DEP) | $(DRIVERS_BIN)
$(call mb_compile_asm,$@,$<)
$(DRIVERS_BIN)/mmi-fac.hex: $(DRIVERS_BIN)/mmi-fac.rel
$(call mb_link_asm_4000,$(DRIVERS_BIN)/mmi-fac.hex,$(DRIVERS_BIN)/mmi-fac.rel)
$(DRIVERS_BIN)/mmi-fac.dat: $(DRIVERS_BIN)/mmi-fac.hex
$(call mb_hex2dat,$(DRIVERS_BIN)/mmi-fac.hex,$(DRIVERS_BIN)/mmi-fac.dat)
$(DRIVERS_BIN)/mmi-1205.rel: $(DRIVERS_SRC)/mmi-1205.asm $(DRIVERS_DEP) | $(DRIVERS_BIN)
$(call mb_compile_asm,$@,$<)
$(DRIVERS_BIN)/mmi-1205.hex: $(DRIVERS_BIN)/mmi-1205.rel
$(call mb_link_asm_4000,$(DRIVERS_BIN)/mmi-1205.hex,$(DRIVERS_BIN)/mmi-1205.rel)
$(DRIVERS_BIN)/mmi-1205.dat: $(DRIVERS_BIN)/mmi-1205.hex
$(call mb_hex2dat,$(DRIVERS_BIN)/mmi-1205.hex,$(DRIVERS_BIN)/mmi-1205.dat)
$(DRIVERS_BIN)/mmi-mint.rel: $(DRIVERS_SRC)/mmi-mint.asm $(DRIVERS_DEP) | $(DRIVERS_BIN)
$(call mb_compile_asm,$@,$<)
$(DRIVERS_BIN)/mmi-mint.hex: $(DRIVERS_BIN)/mmi-mint.rel
$(call mb_link_asm_4000,$(DRIVERS_BIN)/mmi-mint.hex,$(DRIVERS_BIN)/mmi-mint.rel)
$(DRIVERS_BIN)/mmi-mint.dat: $(DRIVERS_BIN)/mmi-mint.hex
$(call mb_hex2dat,$(DRIVERS_BIN)/mmi-mint.hex,$(DRIVERS_BIN)/mmi-mint.dat)
$(DRIVERS_BIN)/mmi-mext.rel: $(DRIVERS_SRC)/mmi-mext.asm $(DRIVERS_DEP) | $(DRIVERS_BIN)
$(call mb_compile_asm,$@,$<)
$(DRIVERS_BIN)/mmi-mext.hex: $(DRIVERS_BIN)/mmi-mext.rel
$(call mb_link_asm_4000,$(DRIVERS_BIN)/mmi-mext.hex,$(DRIVERS_BIN)/mmi-mext.rel)
$(DRIVERS_BIN)/mmi-mext.dat: $(DRIVERS_BIN)/mmi-mext.hex
$(call mb_hex2dat,$(DRIVERS_BIN)/mmi-mext.hex,$(DRIVERS_BIN)/mmi-mext.dat)
# EOF

66
src/drivers/drv-midi.asm Normal file
View file

@ -0,0 +1,66 @@
;--- 3. Error codes
ERR_OK .equ 0 ; Operation completed successfully
ERR_NOT_IMP .equ 1 ; Capability not implemented
ERR_NO_NETWORK .equ 2 ; No network connection available
ERR_NO_DATA .equ 3 ; No incoming data available
ERR_INV_PARAM .equ 4 ; Invalid input parameter
ERR_QUERY_EXISTS .equ 5 ; Another query is already in progress
ERR_INV_IP .equ 6 ; Invalid IP address
ERR_NO_DNS .equ 7 ; No DNS servers are configured
ERR_DNS .equ 8 ; Error returned by DNS server
ERR_NO_FREE_CONN .equ 9 ; No free connections available
ERR_CONN_EXISTS .equ 10 ; Connection already exists
ERR_NO_CONN .equ 11 ; Connection does not exists
ERR_CONN_STATE .equ 12 ; Invalid connection state
ERR_BUFFER .equ 13 ; Insufficient output buffer space
ERR_LARGE_DGRAM .equ 14 ; Datagram is too large
ERR_INV_OPER .equ 15 ; Invalid operation
.macro RET_NO_IMPL
LD A,#ERR_NOT_IMP
RET
.endm
.macro MIDI_TX_START function_number
LD A,#0xF0 ; SystemExclusive
MIDI_TX
LD A,#0xF1 ; SOX Send data
MIDI_TX
LD A,#function_number
MIDI_TX; ; if a=0xF7 then send F7 + F0 + F2
.endm
.macro MIDI_TX_HL
LD A,H
MIDI_TX
LD A,L
MIDI_TX
.endm
.macro MIDI_TX_B
LD A,B
MIDI_TX
.endm
.macro MIDI_TX_END
LD A,#0xF7 ; End of SysEx
MIDI_TX
.endm
.macro MIDI_RX_START function_start
MIDI_RX
CP A
JR nz,#function_start
;CALL #function_start
.endm
.macro MIDI_RX_A_PUSH
MIDI_RX
PUSH AF
.endm
.macro MIDI_RX_B
MIDI_RX
LD B,A
.endm
.macro MIDI_RX_END_POP
POP AF
.endm

356
src/drivers/drv-tcpip.asm Normal file
View file

@ -0,0 +1,356 @@
;4.1.2. TCPIP_GET_CAPAB: Get information about the TCP/IP capabilities and features
;Input: A = 1
; B = Index of information block to retrieve:
; 1: Capabilities and features flags, link level protocol
; 2: Connection pool size and status
; 3: Maximum datagram size allowed
;Output: A = Error code
; When information block 1 requested:
; HL = Capabilities flags
; DE = Features flags
; B = Link level protocol used
; When information block 2 requested:
; B = Maximum simultaneous TCP connections supported
; C = Maximum simultaneous UDP connections supported
; D = Free TCP connections currently available
; E = Free UDP connections currently available
; H = Maximum simultaneous raw IP connections supported
; L = Free raw IP connections currently available
; When information block 3 requested:
; HL = Maximum incoming datagram size supported
; DE = Maximum outgoing datagram size supported
TCPIP_GET_CAPAB:
MIDI_TX_START 1
MIDI_TX_B
MIDI_TX_END
MIDI_RX_START #TCPIP_GET_CAPAB
MIDI_RX_A_PUSH
MIDI_RX_B
MIDI_RX_END_POP
RET
RET_NO_IMPL
;4.1.3. TCPIP_GET_IPINFO: Get IP address
;Input: A = 2
; B = Index of address to obtain:
; 1: Local IP address
; 2: Peer IP address
; 3: Subnet mask
; 4: Default gateway
; 5: Primary DNS server IP address
; 6: Secondary DNS server IP address
;Output: A = Error code
; L.H.E.D = Requested address
TCPIP_GET_IPINFO:
ret_no_impl
;4.1.4. TCPIP_NET_STATE: Get network state
;Input: A = 3
;Output: A = Error code
; B = Current network state:
; 0: Closed
; 1: Opening
; 2: Open
; 3: Closing
; 255: Unknown
TCPIP_NET_STATE:
ret_no_impl
;4.2.1. TCPIP_SEND_ECHO: Send ICMP echo message (PING)
;Input: A = 4
; HL = Address of echo parameters block
;Output: A = Error code
TCPIP_SEND_ECHO:
ret_no_impl
;4.2.2. TCPIP_RCV_ECHO: Retrieve ICMP echo response message
;Input: A = 5
; HL = Address for the echo parameters block
;Output: A = Error code
TCPIP_RCV_ECHO:
ret_no_impl
;4.3.1. TCPIP_DNS_Q: Start a host name resolution query
;Input: A = 6
; HL = Address of the host name to be resolved, zero terminated
; B = Flags, when set to 1 they instruct the resolver to:
; bit 0: Only abort the query currently in progress, if there is any
; (other flags and registers are then ignored)
; bit 1: Assume that the passed name is an IP address,
; and return an error if this is not true
; bit 2: If there is a query in progress already,
; do NOT abort it and return an error instead
;Output: A = Error code
; B = 0 if a query to a DNS server is in progress
; 1 if the name represented an IP address
; 2 if the name could be resolved locally
; L.H.E.D = Resolved IP address
; (only if no error occurred and B=1 or 2 is returned)
TCPIP_DNS_Q:
ret_no_impl
;4.3.2. TCPIP_DNS_S: Obtains the host name resolution process state and result
;Input: A = 7
; B = Flags, when set to 1 they instruct the resolver to:
; bit 0: Clear any existing result or error condition after the execution
; (except if there is a query in progress)
;Output: A = Error code
; B = DNS error code (when error is ERR_DNS)
; B = Current query status (when error is ERR_OK):
; 0: There is no query in progress, nor any result nor error code available
; 1: There is a query in progress
; 2: Query is complete
; C = Current query substatus (when error is ERR_OK and B=1):
; 0: Unknown
; 1: Querying the primary DNS server
; 2: Querying the secondary DNS server
; 3: Querying another DNS server
; C = Resolution proces type (when error is ERR_OK and B=2):
; 0: The name was obtained by querying a DNS server
; 1: The name was a direct representation of an IP address
; 2: The name was resolved locally
; L.H.E.D = Resolved IP address (when error is ERR_OK and B=2)
TCPIP_DNS_S:
ret_no_impl
;4.4.1. TCPIP_UDP_OPEN: Open a UDP connection
;Input: A = 8
; HL = Local port number (0FFFFh: random port)
; B = Intended connection lifetime:
; 0: Transient
; 1: Resident
;Output: A = Error code
; B = Connection number
TCPIP_UDP_OPEN:
MIDI_TX_START 8
MIDI_TX_HL
MIDI_TX_B
MIDI_TX_END
MIDI_RX_START #TCPIP_UDP_OPEN
MIDI_RX_A_PUSH
MIDI_RX_B
MIDI_RX_END_POP
RET
;4.4.2. TCPIP_UDP_CLOSE: Close a UDP connection
;Input: A = 9
; B = Connection number
; 0 to close all open transient UDP connections
;Output: A = Error code
TCPIP_UDP_CLOSE:
ret_no_impl
;4.4.3. TCPIP_UDP_STATE: Get the state of a UDP connection
;Input: A = 10
; B = Connection number
;Output: A = Error code
; HL = Local port number
; B = Number of pending incoming datagrams
; DE = Size of oldest pending incoming datagram (data part only)
TCPIP_UDP_STATE:
ret_no_impl
;4.4.4. TCPIP_UDP_SEND: Send an UDP datagram
;Input: A = 11
; B = Connection number
; HL = Address of datagram data
; DE = Address of parameters block
;Output: A = Error code
TCPIP_UDP_SEND:
ret_no_impl
;4.4.5. TCPIP_UDP_RCV: Retrieve an incoming UDP datagram
;Input: A = 12
; B = Connection number
; HL = Address for datagram data
; DE = Maximum data size to retrieve
;Output: A = Error code
; L.H.E.D = Source IP address
; IX = Source port
; BC = Actual received data size
TCPIP_UDP_RCV:
ret_no_impl
;4.5.1. TCPIP_TCP_OPEN: Open a TCP connection
;Input: A = 13
; HL = Address of parameters block
;Output: A = Error code
; B = Connection number
TCPIP_TCP_OPEN:
ret_no_impl
;4.5.2. TCPIP_TCP_CLOSE: Close a TCP connection
;Input: A = 14
; B = Connection number
; 0 to close all open transient TCP connections
;Output: A = Error code
TCPIP_TCP_CLOSE:
ret_no_impl
;4.5.3. TCPIP_TCP_ABORT: Abort a TCP connection
;Input: A = 15
; B = Connection number
; 0 to abort all open transient TCP connections
;Output: A = Error code
TCPIP_TCP_ABORT:
ret_no_impl
;4.5.4. TCPIP_TCP_STATE: Get the state of a TCP connection
;Input: A = 16
; B = Connection number
; HL = Pointer in TPA for connection information block
; (0 if not needed)
;Output: A = Error code
; B = Connection state
; C = Close reason (only if ERR_NO_CONN is returned)
; HL = Number of total available incoming bytes
; DE = Number of urgent available incoming bytes
; IX = Available free space in the output buffer
; (0FFFFh = infinite)
TCPIP_TCP_STATE:
ret_no_impl
;4.5.5. TCPIP_TCP_SEND: Send data a TCP connection
;Input: A = 17
; B = Connection number
; DE = Address of the data to be sent
; HL = Length of the data to be sent
; C = Flags:
; bit 0: Send the data PUSHed
; bit 1: The data is urgent
;Output: A = Error code
TCPIP_TCP_SEND:
ret_no_impl
;4.5.6. TCPIP_TCP_RCV: Receive data from a TCP connection
;Input: A = 18
; B = Connection number
; DE = Address for the retrieved data
; HL = Length of the data to be obtained
;Output: A = Error code
; BC = Total number of bytes that have been actually retrieved
; HL = Number of urgent data bytes that have been retrieved
; (placed at the beginning of the received data block)
TCPIP_TCP_RCV:
ret_no_impl
;4.5.7. TCPIP_TCP_FLUSH: Flush the output buffer of a TCP connection
;Input: A = 19
; B = Connection number
;Output: A = Error code
TCPIP_TCP_FLUSH:
ret_no_impl
;4.6.1. TCPIP_RAW_OPEN: Open a raw IP connection
;Input: A = 20
; B = Transport protocol code
; C = Intended connection lifetime:
; 0: Transient
; 1: Resident
;Output: A = Error code
; B = Connection number
TCPIP_RAW_OPEN:
ret_no_impl
;4.6.2. TCPIP_RAW_CLOSE: Close a raw IP connection
;Input: A = 21
; B = Connection number
; 0 to close all open transient UDP connections
;Output: A = Error code
TCPIP_RAW_CLOSE:
ret_no_impl
;4.6.3. TCPIP_RAW_STATE: Get the state of a raw IP connection
;Input: A = 22
; B = Connection number
;Output: A = Error code
; B = Associated protocol code
; HL = Number of pending incoming datagrams
; DE = Size of the oldest pending incoming datagram
TCPIP_RAW_STATE:
ret_no_impl
;4.6.4. TCPIP_RAW_SEND: Send a raw IP datagram
;Input: A = 23
; B = Connection number
; HL = Address of datagram data
; DE = Address of parameters block
;Output: A = Error code
TCPIP_RAW_SEND:
ret_no_impl
;4.6.5. TCPIP_RAW_RCV: Retrieve an incoming raw IP datagram
;Input: A = 24
; B = Connection number
; HL = Address for datagram data
; DE = Maximum data size to retrieve
;Output: A = Error code
; L.H.E.D = Source IP address
; BC = Actual received data size
TCPIP_RAW_RCV:
ret_no_impl
;4.7.1. TCPIP_CONFIG_AUTOIP: Enable or disable the automatic IP addresses retrieval
;Input: A = 25
; B = 0: Get current configuration
; 1: Set configuration
; C = Configuration to set (only if B=1):
; bit 0: Set to automatically retrieve
; local IP address, subnet mask and default gateway
; bit 1: Set to automatically retrieve DNS servers addresses
; bits 2-7: Unused, must be zero
;Output: A = Error code
; C = Configuration after the routine execution
; (same format as C at input)
TCPIP_CONFIG_AUTOIP:
ret_no_impl
;4.7.2. TCPIP_CONFIG_IP: Manually configure an IP address
;Input: A = 26
; B = Index of address to set:
; 1: Local IP address
; 2: Peer IP address
; 3: Subnet mask
; 4: Default gateway
; 5: Primary DNS server IP address
; 6: Secondary DNS server IP address
; L.H.E.D = Address value
;Output: A = Error code
TCPIP_CONFIG_IP:
ret_no_impl
;4.7.3. TCPIP_CONFIG_TTL: Get/set the value of TTL and TOS for outgoing datagrams
;Input: A = 27
; B = 0: Get current values
; 1: Set values
; D = New value for TTL (only if B=1)
; E = New value for ToS (only if B=1)
;Output: A = Error code
; D = Value of TTL after the routine execution
; E = Value of ToS after the routine execution
TCPIP_CONFIG_TTL:
ret_no_impl
;4.7.4. TCPIP_CONFIG_PING: Get/set the automatic PING reply flag
;Input: A = 28
; B = 0: Get current flag value
; 1: Set flag value
; C = New flag value (only if B=1):
; 0: Off
; 1: On
;Output: A = Error code
; C = Flag value after the routine execution
TCPIP_CONFIG_PING:
ret_no_impl
;4.8.1. TCPIP_WAIT: Wait for a processing step to run
;Input: A = 29
;Output: A = Error code
TCPIP_WAIT:
ret_no_impl

320
src/drivers/drv-unapi.asm Normal file
View file

@ -0,0 +1,320 @@
;
;
; 0x4000 - extbio unapi
; 0x5000 -
; 0x6000 -
; 0x7000 -
;
ARG .equ 0xF847
;--- API version and implementation version
API_V_P .equ 1
API_V_S .equ 0
ROM_V_P .equ 1
ROM_V_S .equ 1
;--- Maximum number of available standard and implementation-specific function numbers
;Must be 0 to 127
MAX_FN .equ 30+1
;Must be either zero (if no implementation-specific functions available), or #128 to 254
MAX_IMPFN .equ 127+3
;*********************************************
;*** CODE TO BE INSTALLED ON RAM SEGMENT ***
;*********************************************
;===============================
;=== EXTBIO hook execution ===
;===============================
;>>> Note that this code starts exactly at address 0x4000
; .ds 129
;.area CODE1 (ABS)
; .org 0H4400
DO_EXTBIO:
push hl
push bc
push af
ld a,d
cp #0x22
jr nz,JUMP_OLD
cp e
jr nz,JUMP_OLD
;Check API ID
ld hl,#UNAPI_ID
ld de,#ARG
LOOP: ld a,(de)
call TOUPPER
cp (hl)
jr nz,JUMP_OLD2
inc hl
inc de
or a
jr nz,LOOP
;A=255: Jump to old hook
pop af
push af
inc a
jr z,JUMP_OLD2
;A=0: B=B+1 and jump to old hook
pop af
pop bc
or a
jr nz,DO_EXTBIO2
inc b
pop hl
ld de,#0x2222
jp OLD_EXTBIO
DO_EXTBIO2:
;A=1: Return A=Slot, B=Segment, HL=UNAPI entry address
dec a
jr nz,DO_EXTBIO3
pop hl
ld a,(MY_SEG)
ld b,a
ld a,(MY_SLOT)
ld hl,#UNAPI_ENTRY
ld de,#0x2222
ret
;A>1: A=A-1, and jump to old hook
DO_EXTBIO3: ;A=A-1 already done
pop hl
ld de,#0x2222
jp OLD_EXTBIO
;--- Jump here to execute old EXTBIO code
JUMP_OLD2:
ld de,#0x2222
JUMP_OLD: ;Assumes "push hl,bc,af" done
pop af
pop bc
pop hl
;Old EXTBIO hook contents is here
;(it is setup at installation time)
OLD_EXTBIO:
.ds 5
;====================================
;=== Functions entry point code ===
;====================================
UNAPI_ENTRY:
push hl
push af
ld hl,#FN_TABLE
bit 7,a
jr z,IS_STANDARD
ld hl,#IMPFN_TABLE
and #0b01111111
cp #MAX_IMPFN-128
jr z,OK_FNUM
jr nc,UNDEFINED
IS_STANDARD:
cp #MAX_FN
jr z,OK_FNUM
jr nc,UNDEFINED
OK_FNUM:
add a,a
push de
ld e,a
ld d,#0
add hl,de
pop de
ld a,(hl)
inc hl
ld h,(hl)
ld l,a
pop af
ex (sp),hl
ret
;--- Undefined function: return with registers unmodified
UNDEFINED:
pop af
pop hl
ret
;--- Convert a character to upper-case if it is a lower-case letter
TOUPPER:
cp #"a"
ret c
cp #"z"+1
ret nc
and #0xDF
ret
;===================================
;=== Functions addresses table ===
;===================================
;--- Standard routines addresses table
FN_TABLE:
.dw UNAPI_GET_INFO
.dw TCPIP_GET_CAPAB
.dw TCPIP_GET_IPINFO
.dw TCPIP_NET_STATE
.dw TCPIP_SEND_ECHO
.dw TCPIP_RCV_ECHO
.dw TCPIP_DNS_Q
.dw TCPIP_DNS_S
.dw TCPIP_UDP_OPEN
.dw TCPIP_UDP_CLOSE
.dw TCPIP_UDP_STATE
.dw TCPIP_UDP_SEND
.dw TCPIP_UDP_RCV
.dw TCPIP_TCP_OPEN
.dw TCPIP_TCP_CLOSE
.dw TCPIP_TCP_ABORT
.dw TCPIP_TCP_STATE
.dw TCPIP_TCP_SEND
.dw TCPIP_TCP_RCV
.dw TCPIP_TCP_FLUSH
.dw TCPIP_RAW_OPEN
.dw TCPIP_RAW_CLOSE
.dw TCPIP_RAW_STATE
.dw TCPIP_RAW_SEND
.dw TCPIP_RAW_RCV
.dw TCPIP_CONFIG_AUTOIP
.dw TCPIP_CONFIG_IP
.dw TCPIP_CONFIG_TTL
.dw TCPIP_CONFIG_PING
.dw TCPIP_WAIT
.dw 0
;--- Implementation-specific routines addresses table
IMPFN_TABLE:
.dw UNAPIE_INIT
.dw UNAPIE_GET_JUMP
.dw DRV_INIT
.dw DRV_GET_INFO
;.dw TCPIPE_STATS
;.dw TCPIPE_RESET
.dw 0
;UNAPI_GET_INFO: Obtain the implementation name and version
;Input: A = 0
;Output: A = Error code
; HL = Address of the implementation name string
; DE = API specification version supported. D=primary, E=secondary.
; BC = API implementation version. B=primary, C=secondary.
UNAPI_GET_INFO:
LD BC,#256*ROM_V_P+ROM_V_S
LD DE,#256*API_V_P+API_V_S
LD HL,#APIINFO
XOR A
RET
;UNAPIE_INIT: Inits unapi jump code
;Input: A = 128
; HL = slot and segment ids
; BC = copy 5 bytes from this addres to OLD_EXTBIO
;Output:
; A = Error code
;
;The routines of the XXXX specification are intended to be called intensively, therefore being performance a concern. For this reason, a jump table is provided so that all the routines can be invoked directly in addition to using the standard UNAPI entry point. Routines are ordered by their UNAPI routine number, so that routine 0 is at (HL), routine 1 is at (HL+3), and so on.
UNAPIE_INIT:
LD (MY_SLOT),HL
LD H,B
LD L,C
LD DE,#OLD_EXTBIO
LD BC,#5
LDIR
RET
;UNAPIE_GET_JUMP: Get the routines jump table address
;Input: A = 129
;Output: HL = Address of the jump table (possibly in page 2)
;A = Segment of the jump table (#FF if ROM)
;
;The routines of the XXXX specification are intended to be called intensively, therefore being performance a concern. For this reason, a jump table is provided so that all the routines can be invoked directly in addition to using the standard UNAPI entry point. Routines are ordered by their UNAPI routine number, so that routine 0 is at (HL), routine 1 is at (HL+3), and so on.
UNAPIE_GET_JUMP:
LD HL,#FN_TABLE
LD A,(#MY_SEG)
RET
;DRV_INIT: Inits the implementation hardware.
;Input: A = 130
;Output: A = Error code
; HL = Address of the implementation name string
; DE = API specification version supported. D=primary, E=secondary.
; BC = API implementation version. B=primary, C=secondary.
DRV_INIT:
MIDI_INIT
XOR A
RET
;DRV_GET_INFO: Obtain the implementation gateway name and version
;Input: A = 131
;Output: A = Error code
; HL = Address of the implementation hostname string
; DE = Connected gateway version. D=primary, E=secondary.
DRV_GET_INFO:
MIDI_TX_START 131
MIDI_TX_END
MIDI_RX_START #DRV_GET_INFO
MIDI_RX_A_PUSH
;MIDI_RX_STR #DRV_HOSTNAME
;MIDI_RX_DE
MIDI_RX_END_POP
LD HL,#DRV_HOSTNAME
RET
DRV_HOSTNAME:
.str "hostname"
.str "$"
.ds 40
;============================
;=== UNAPI related data ===
;============================
;This data is setup at installation time
MY_SLOT: .db 0
MY_SEG: .db 0
;--- Specification identifier (up to 15 chars)
UNAPI_ID:
.str "TCP/IP"
.db 0
UNAPI_ID_END:
;--- Implementation name (up to 63 chars and zero terminated)
APIINFO:
.str "mmidrv-rpc"
.str "$"
.db 0

49
src/drivers/mmi-1205.asm Normal file
View file

@ -0,0 +1,49 @@
.module nms-1205.asm
.title driver for the NMS-1205 Music Module
;-----------------------------------------------------------------------------
; Motorola MC68B50
; #00-#01 Music Module MIDI, output ports (mirrored on ports #08-#09, #10-#11, #18-#19)
; #04-#05 Music Module MIDI, input ports (mirrored on ports #0C-#0D, #14-#15, #1C-#1D)
;IF INP(&H02)=255 AND INP(&HC0)=255 THEN CLS: PRINT"Geen FAC MIDI interface of Philips Music Module gevonden!!!":NEW
.macro MIDI_CMD_WAIT ?wait_loop
LD B,#4
wait_loop:
djnz #wait_loop
.endm
.macro MIDI_INIT ?wait_loop_1 ?wait_loop_2
LD A,#3 ; Reset first
OUT (#0),A
MIDI_CMD_WAIT
LD A,#21 ; enable x but no int
OUT (#0),A
MIDI_CMD_WAIT
.endm
.macro MIDI_TX ?wait_loop
PUSH AF
wait_loop:
IN A,(#4)
AND #2
JR Z,wait_loop
POP AF
OUT (#1),A
.endm
.macro MIDI_RX ?wait_loop
wait_loop:
IN A,(#4)
AND #1
JR Z,wait_loop
IN A,(#5)
.endm
.area _CODE
.include "drv-midi.asm"
.include "drv-unapi.asm"
.include "drv-tcpip.asm"
.area _DATA

71
src/drivers/mmi-fac.asm Normal file
View file

@ -0,0 +1,71 @@
.module mm-fac.asm
.title driver for the FAC midi interface
;-----------------------------------------------------------------------------
;
; #02-#03 FAC MIDI interface (i8251, mirrored on ports #00-#07)
;
;
UART_DATA .equ 0x02 ;8251 data
UART_CMD .equ 0x03 ;8251 command
.macro MIDI_CMD_WAIT ?wait_loop
LD B,#4
wait_loop:
djnz #wait_loop
.endm
.macro MIDI_INIT ?wait_loop_1 ?wait_loop_2
; Do chip reset
XOR A
;OUT (#UART_CMD),A
;MIDI_CMD_WAIT
;OUT (#UART_CMD),A
;MIDI_CMD_WAIT
;OUT (#UART_CMD),A
;MIDI_CMD_WAIT
;LD A,#0x40
;OUT (#UART_CMD),A
;MIDI_CMD_WAIT
; Init 8251 mode + command
LD A,#0b01001110
OUT (#UART_CMD),A
MIDI_CMD_WAIT
LD A,#0b00100101
OUT (#UART_CMD),A
.endm
.macro MIDI_TX_A register ?wait_loop
wait_loop:
IN A,(#UART_CMD)
AND #1
JR Z,wait_loop
LD A,#register
OUT (#UART_DATA),A
.endm
.macro MIDI_TX ?wait_loop
PUSH AF
wait_loop:
IN A,(#UART_CMD)
AND #1
JR Z,wait_loop
POP AF
OUT (#UART_DATA),A
.endm
.macro MIDI_RX ?wait_loop
wait_loop:
IN A,(#UART_CMD)
AND #2
JR Z,wait_loop
IN A,(#UART_DATA)
.endm
.area _CODE
.include "drv-midi.asm"
.include "drv-unapi.asm"
.include "drv-tcpip.asm"
.area _DATA

14
src/drivers/mmi-mext.asm Normal file
View file

@ -0,0 +1,14 @@
.module mm-fac.asm
.title driver for the FAC midi interface
;-----------------------------------------------------------------------------
; Intel i8251 + i8253 External MSX-MIDI
; #E0-#E2 External MSX-MIDI interface (µ·pack)
;
.area _CODE
.include "drv-midi.asm"
.include "drv-unapi.asm"
.include "drv-tcpip.asm"
.area _DATA

14
src/drivers/mmi-mint.asm Normal file
View file

@ -0,0 +1,14 @@
.module mm-fac.asm
.title driver for the FAC midi interface
;-----------------------------------------------------------------------------
; Intel i8251 + i8253 Internal MSX-MIDI
; #E8-#EF Internal MSX-MIDI interface (turboR GT)
;
.area _CODE
.include "drv-midi.asm"
.include "drv-unapi.asm"
.include "drv-tcpip.asm"
.area _DATA

57
src/mmidrv/0module.mk Normal file
View file

@ -0,0 +1,57 @@
MMIDRV_NAME := mmidrv
MMIDRV_TEST := test-$(MMIDRV_NAME)
MMIDRV_SRC := $(PATH_SRC)/$(MMIDRV_NAME)
MMIDRV_BIN := $(PATH_BIN)/$(MMIDRV_NAME)
MMIDRV_HEX := $(MMIDRV_BIN)/$(MMIDRV_NAME).hex
MMIDRV_COM := $(MMIDRV_BIN)/$(MMIDRV_NAME).com
MMIDRV_COM2 := $(MMIDRV_BIN)/$(MMIDRV_NAME)2.com
MMIDRV_RELS := $(MMIDRV_BIN)/$(MMIDRV_NAME).rel
MMIDRV_CODE := $(MMIDRV_SRC)/$(MMIDRV_NAME).asm
BUILD_HELP += \\n\\t* $(MMIDRV_COM) \\n\\t* $(MMIDRV_TEST)
$(MMIDRV_BIN):
$(call mb_mkdir,$(MMIDRV_BIN))
$(MMIDRV_BIN)/%.rel: $(MMIDRV_SRC)/%.asm | $(MMIDRV_BIN)
$(call mb_compile_asm,$@,$<)
$(MMIDRV_HEX): $(MMIDRV_RELS)
$(call mb_link_asm_dos,$(MMIDRV_HEX),$(MMIDRV_RELS))
$(MMIDRV_COM): $(MMIDRV_HEX)
$(call mb_hex2com,$(MMIDRV_HEX),$(MMIDRV_COM))
$(MMIDRV_COM2): $(MMIDRV_COM) $(PATH_BIN)/drivers/mmi-fac.dat $(PATH_BIN)/drivers/mmi-1205.dat
cp $< $@;
dd if=/dev/null of=$@ seek=1792 bs=1 count=0
dd if=$(PATH_BIN)/drivers/mmi-fac.dat of=$@ seek=1792 bs=1
$(MMIDRV_TEST): $(MMIDRV_COM2)
$(call mb_autoexec_open_gui_cmd,$(MMIDRV_BIN))
$(call mb_autoexec_append_cmd,$(MMIDRV_BIN),omsxctl set midi-out-logfilename /tmp/mm.out > NUL)
$(call mb_autoexec_append_cmd,$(MMIDRV_BIN),omsxctl plug FAC\ MIDI\ Interface\ MIDI-out midi-out-logger > NUL)
#$(call mb_autoexec_append_echo,$(MMIDRV_BIN),Plugging midi-out to mmigate.)
#$(call mb_autoexec_append_cmd,$(MMIDRV_BIN),omsxctl plug FAC\ MIDI\ Interface\ MIDI-out mmigate-in > NUL)
#$(call mb_autoexec_append_cmd,$(MMIDRV_BIN),omsxctl plug Philips\ Music\ Module\ MIDI-out mmigate-in > NUL)
#$(call mb_autoexec_append_echo,$(MMIDRV_BIN),Plugging midi-in to mmigate.)
#$(call mb_autoexec_append_cmd,$(MMIDRV_BIN),omsxctl plug FAC\ MIDI\ Interface\ MIDI-in mmigate-out > NUL)
#$(call mb_autoexec_append_cmd,$(MMIDRV_BIN),omsxctl plug Philips\ Music\ Module\ MIDI-in mmigate-out > NUL)
$(call mb_autoexec_append_echo,$(MMIDRV_BIN),Install ram helper.)
$(call mb_autoexec_append_cmd,$(MMIDRV_BIN),ramhelpr i autocont)
echo -n "" > $(MMIDRV_BIN)/autocont.bat
echo "echo Starting mmidrv.\r" >> $(MMIDRV_BIN)/autocont.bat
echo "echo SKIPPED.\r" >> $(MMIDRV_BIN)/autocont.bat
#echo "$(MMIDRV_NAME)\r" >> $(MMIDRV_BIN)/autocont.bat
#echo "echo Install InterNestor Lite.\r" >> $(MMIDRV_BIN)/autocont.bat
#echo "inl i\r" >> $(MMIDRV_BIN)/autocont.bat
$(call mb_copy,tmp/ramhelpr.com,$(MMIDRV_BIN))
$(call mb_copy,tmp/inl.com,$(MMIDRV_BIN))
$(call mb_copy,tmp/ping.com,$(MMIDRV_BIN))
$(call mb_copy,tmp/hget.com,$(MMIDRV_BIN))
$(call mb_openmsx_dos2,$(MMIDRV_BIN))

413
src/mmidrv/mmidrv.asm Normal file
View file

@ -0,0 +1,413 @@
;--- Sample RAM implementation of a MSX-UNAPI specification
; By Konami Man, 1-2010
;
; This code implements a sample mathematical specification, "SIMPLE_MATH"
; .db
; which has just two functions:
; Function 1: Returns HL = L + E
; Function 2: Returns HL = L * E
; The code installs on a mapped RAM segment.
; The RAM helper must have been previously installed.
;
; To create your own implementation:
; 1) In the "Constants" section, modify the API version and implementation version
; constants, as well as MAX_FN and MAX_IMPFN.
; 2) In the "Functions code" section, leave FN_INFO unmodified,
; and add your own functions.
; 3) Add an entry for each function in the "Functions addresses table" section.
; 4) In the "Data" section, modify the specification identifier
; and the implementation identifier.
;
; Optional improvements (up to you):
; - Install a RAM helper if none is detected.
; - Let the user choose the install segment in DOS 1.
; - Add code for uninstallation.
;*******************
;*** CONSTANTS ***
;*******************
;--- System variables and routines
_TERM0 .equ 0x00
_STROUT .equ 0x09
BDOS .equ 0x0005
ENASLT .equ 0x0024
EXTBIO .equ 0xFFCA
ARG .equ 0xF847
SEG_CODE .equ 0x0800
;***************************
;*** INSTALLATION CODE ***
;***************************
; org #100
.area _CODE
;--- Show welcome message
ld de,#WELCOME_S
ld c,#_STROUT
call #BDOS
;--- Locate the RAM helper, terminate with error if not installed
ld de,#0x2222
ld hl,#0
ld a,#0xFF
call EXTBIO
ld a,h
or l
jr nz,HELPER_OK
ld de,#NOHELPER_S
ld c,#_STROUT
call BDOS
ld c,#_TERM0
jp BDOS
HELPER_OK:
ld (HELPER_ADD),hl
ld (MAPTAB_ADD),bc
;--- Check if we are already installed.
; Do this by searching all the TCP/IP
; implementations installed, and comparing
; the implementation name of each one with
; our implementation name.
;* Copy the implementation identifier to ARG
ld hl,#UNAPI_ID
ld de,#ARG
ld bc,#UNAPI_ID_END-UNAPI_ID
ldir
;* Obtain the number of installed implementations
ld de,#0x2222
xor a
ld b,#0
call EXTBIO
ld a,b
or a
jr z,NOT_INST
;>>> The loop for each installed implementations
; starts here, with A=implementation index
IMPL_LOOP: push af
;* Obtain the slot, segment and entry point
; for the implementation
ld de,#0x2222
call EXTBIO
ld (ALLOC_SLOT),a
ld a,b
ld (ALLOC_SEG),a
ld (IMPLEM_ENTRY),hl
;* If the implementation is in page 3
; or in ROM, skip it
ld a,h
and #0b10000000
jr nz,NEXT_IMP
ld a,b
cp #0xFF
jr z,NEXT_IMP
;* Call the routine for obtaining
; the implementation information
ld a,(ALLOC_SLOT)
;ld iyh,a
.db 0xFD; iy
ld h,a
ld a,(ALLOC_SEG)
;ld iyl,a
.db 0xFD; iy
ld l,a
ld ix,(IMPLEM_ENTRY)
ld hl,(HELPER_ADD)
xor a
call CALL_HL ;Returns HL=name address
;* Compare the name of the implementation
; against our own name
ld a,(ALLOC_SEG)
ld b,a
ld de,#APIINFO ; -SEG_CODE_START+SEG_CODE
ld ix,(HELPER_ADD)
inc ix
inc ix
inc ix ;Now IX=helper routine to read from segment
NAME_LOOP: ld a,(ALLOC_SLOT)
push bc
push de
push hl
push ix
call CALL_IX
pop ix
pop hl
pop de
pop bc
ld c,a
ld a,(de)
cp c
jr nz,NEXT_IMP
or a
inc hl
inc de
jr nz,NAME_LOOP
;* The names match: already installed
ld de,#ALINST_S
ld c,#_STROUT
call 5
ld c,#_TERM0
jp 5
;* Names don't match: go to the next implementation
NEXT_IMP: pop af
dec a
jr nz,IMPL_LOOP
;* No more implementations:
; continue installation process
NOT_INST:
;--- Obtain the mapper support routines table, if available
xor a
ld de,#0x0402
call EXTBIO
or a
jr nz,ALLOC_DOS2
;--- DOS 1: Use the last segment on the primary mapper
ld hl,(MAPTAB_ADD)
ld b,(hl)
inc hl
ld a,(hl)
jr ALLOC_OK
;--- DOS 2: Allocate a segment using mapper support routines
ALLOC_DOS2:
ld a,b
ld (PRIM_SLOT),a
ld de,#ALL_SEG
ld bc,#15*3
ldir
ld a,(PRIM_SLOT)
or #0b00100000 ;Try primary mapper, then try others
ld b,a
ld a,#1 ;System segment
call ALL_SEG
jr nc,ALLOC_OK
ld de,#NOFREE_S ;Terminate if no free segments available
ld c,#_STROUT
call 5
ld c,#_TERM0
jp 5
ALLOC_OK:
ld (ALLOC_SEG),a
ld a,b
ld (ALLOC_SLOT),a
;--- Switch segment, copy code, and setup data
call GET_P1 ;Backup current segment
ld (P1_SEG),a
ld a,(ALLOC_SLOT) ;Switch slot and segment
ld h,#0x40
call ENASLT
ld a,(ALLOC_SEG)
call PUT_P1
ld hl,#0x4000 ;Clear the segment first
ld de,#0x4001
ld bc,#0x4000-1
ld (hl),#0x0
ldir
ld hl,#SEG_CODE ;Copy the code to the segment
ld de,#0x4000
ld bc,#0x4000 ; note use file lenth..
ldir
ld hl,(ALLOC_SLOT) ;Setup slot and segment information
;ld (MY_SLOT),hl
;* Now backup and #0xpatc the EXTBIO hook
; so that it calls address #4000 of the allocated segment
;ld hl,#EXTBIO
;ld de,#OLD_EXTBIO
;ld bc,#5
;ldir
LD a,#128 ; UNAPIE_INIT, hl=slot , DE=5b jump
LD BC,#EXTBIO
ld de,#0x2222
call 0x4000
;LD a,#0 ; UNAPI_GET_INFO
;ld de,#0x2222
;call 0x4000
;LD D,H
;LD E,L
;ld c,#_STROUT
;call BDOS
LD a,#130 ; DRV_INIT
ld de,#0x2222
call 0x4000
LD a,#131 ; DRV_GET_INFO
ld de,#0x2222
call 0x4000
LD D,H
LD E,L
ld c,#_STROUT
call BDOS
di
ld a,#0xCD ;Code for #"CALL"
ld (EXTBIO),a
ld hl,(HELPER_ADD)
ld bc,#6
add hl,bc ;Now HL points to segment call routine
ld (EXTBIO+1),hl
ld hl,(MAPTAB_ADD)
ld a,(ALLOC_SLOT)
ld d,a
ld e,#0 ;Index on mappers table
SRCHMAP:
ld a,(hl)
cp d
jr z,MAPFND
inc hl
inc hl ;Next table entry
inc e
jr SRCHMAP
MAPFND:
ld a,e ;A = Index of slot on mappers table
rrca
rrca
and #0b11000000 ;Entry point #4010 = index 0
ld (EXTBIO+3),a
ld a,(ALLOC_SEG)
ld (EXTBIO+4),a
ei
;--- Restore slot and segment, and terminate
ld a,(PRIM_SLOT)
ld h,#0x40
call ENASLT
ld a,(P1_SEG)
call PUT_P1
ld de,#OK_S
ld c,#_STROUT
call BDOS
ld c,#_TERM0
jp BDOS
;>>> Other auxiliary code
CALL_IX: jp (ix)
CALL_HL: jp (hl)
;****************************************************
;*** DATA AND STRINGS FOR THE INSTALLATION CODE ***
;****************************************************
;--- Variables
PRIM_SLOT: .db 0 ;Primary mapper slot number
P1_SEG: .db 0 ;Segment number for TPA on page 1
ALLOC_SLOT: .db 0 ;Slot for the allocated segment
ALLOC_SEG: .db 0 ;Allocated segment
HELPER_ADD: .dw 0 ;Address of the RAM helper jump table
MAPTAB_ADD: .dw 0 ;Address of the RAM helper mappers table
IMPLEM_ENTRY: .dw 0 ;Entry point for implementations
;--- DOS 2 mapper support routines
ALL_SEG: .ds 3
FRE_SEG: .ds 3
RD_SEG: .ds 3
WR_SEG: .ds 3
CAL_SEG: .ds 3
CALLS: .ds 3
PUT_PH: .ds 3
GET_PH: .ds 3
PUT_P0: .ds 3
GET_P0: .ds 3
PUT_P1: out (#0xFD),a
ret
GET_P1: in a,(#0xFD)
ret
PUT_P2: .ds 3
GET_P2: .ds 3
PUT_P3: .ds 3
;--- Strings
WELCOME_S:
.str "UNAPI TCP/IP over MIDI implementation 1.0"
.db 13,10
.str "(c) 2019 by Willem Cazander"
.db 13,10
;.db 13,10
.str "$"
NOHELPER_S:
.str "*** ERROR: No UNAPI RAM helper is installed"
.db 13,10,"$"
NOMAPPER_S:
.str "*** ERROR: No mapped RAM found"
.db 13,10,"$"
NOFREE_S:
.str "*** ERROR: Could not allocate any RAM segment"
.db 13,10,"$"
OK_S: .str "Installed. Have fun!"
.db 13,10,"$"
ALINST_S: .str "*** Already installed."
.db 13,10,"$"
UNAPI_ID:
.str "TCP/IP"
.db 0
UNAPI_ID_END:
APIINFO:
.str "mmidrv-rpc"
.db 0
APIINFO_END:
.area _DATA

630
src/mmidrv/mmidrv.asm.org Normal file
View file

@ -0,0 +1,630 @@
;--- Sample RAM implementation of a MSX-UNAPI specification
; By Konami Man, 1-2010
;
; This code implements a sample mathematical specification, "SIMPLE_MATH",
; which has just two functions:
; Function 1: Returns HL = L + E
; Function 2: Returns HL = L * E
; The code installs on a mapped RAM segment.
; The RAM helper must have been previously installed.
;
; To create your own implementation:
; 1) In the "Constants" section, modify the API version and implementation version
; constants, as well as MAX_FN and MAX_IMPFN.
; 2) In the "Functions code" section, leave FN_INFO unmodified,
; and add your own functions.
; 3) Add an entry for each function in the "Functions addresses table" section.
; 4) In the "Data" section, modify the specification identifier
; and the implementation identifier.
;
; Optional improvements (up to you):
; - Install a RAM helper if none is detected.
; - Let the user choose the install segment in DOS 1.
; - Add code for uninstallation.
;*******************
;*** CONSTANTS ***
;*******************
;--- System variables and routines
_TERM0: equ #00
_STROUT: equ #09
ENASLT: equ #0024
EXTBIO: equ #FFCA
ARG: equ #F847
;--- API version and implementation version
API_V_P: equ 1
API_V_S: equ 0
ROM_V_P: equ 1
ROM_V_S: equ 1
;--- Maximum number of available standard and implementation-specific function numbers
;Must be 0 to 127
MAX_FN: equ 2
;Must be either zero (if no implementation-specific functions available), or 128 to 254
MAX_IMPFN: equ 0
;***************************
;*** INSTALLATION CODE ***
;***************************
org #100
;--- Show welcome message
ld de,WELCOME_S
ld c,_STROUT
call 5
;--- Locate the RAM helper, terminate with error if not installed
ld de,#2222
ld hl,0
ld a,#FF
call EXTBIO
ld a,h
or l
jr nz,HELPER_OK
ld de,NOHELPER_S
ld c,_STROUT
call 5
ld c,_TERM0
jp 5
HELPER_OK:
ld (HELPER_ADD),hl
ld (MAPTAB_ADD),bc
;--- Check if we are already installed.
; Do this by searching all the SIMPLE_MATH
; implementations installed, and comparing
; the implementation name of each one with
; our implementation name.
;* Copy the implementation identifier to ARG
ld hl,UNAPI_ID-SEG_CODE_START+SEG_CODE
ld de,ARG
ld bc,UNAPI_ID_END-UNAPI_ID
ldir
;* Obtain the number of installed implementations
ld de,#2222
xor a
ld b,0
call EXTBIO
ld a,b
or a
jr z,NOT_INST
;>>> The loop for each installed implementations
; starts here, with A=implementation index
IMPL_LOOP: push af
;* Obtain the slot, segment and entry point
; for the implementation
ld de,#2222
call EXTBIO
ld (ALLOC_SLOT),a
ld a,b
ld (ALLOC_SEG),a
ld (IMPLEM_ENTRY),hl
;* If the implementation is in page 3
; or in ROM, skip it
ld a,h
and %10000000
jr nz,NEXT_IMP
ld a,b
cp #FF
jr z,NEXT_IMP
;* Call the routine for obtaining
; the implementation information
ld a,(ALLOC_SLOT)
ld iyh,a
ld a,(ALLOC_SEG)
ld iyl,a
ld ix,(IMPLEM_ENTRY)
ld hl,(HELPER_ADD)
xor a
call CALL_HL ;Returns HL=name address
;* Compare the name of the implementation
; against our own name
ld a,(ALLOC_SEG)
ld b,a
ld de,APIINFO-SEG_CODE_START+SEG_CODE
ld ix,(HELPER_ADD)
inc ix
inc ix
inc ix ;Now IX=helper routine to read from segment
NAME_LOOP: ld a,(ALLOC_SLOT)
push bc
push de
push hl
push ix
call CALL_IX
pop ix
pop hl
pop de
pop bc
ld c,a
ld a,(de)
cp c
jr nz,NEXT_IMP
or a
inc hl
inc de
jr nz,NAME_LOOP
;* The names match: already installed
ld de,ALINST_S
ld c,_STROUT
call 5
ld c,_TERM0
jp 5
;* Names don't match: go to the next implementation
NEXT_IMP: pop af
dec a
jr nz,IMPL_LOOP
;* No more implementations:
; continue installation process
NOT_INST:
;--- Obtain the mapper support routines table, if available
xor a
ld de,#0402
call EXTBIO
or a
jr nz,ALLOC_DOS2
;--- DOS 1: Use the last segment on the primary mapper
ld hl,(MAPTAB_ADD)
ld b,(hl)
inc hl
ld a,(hl)
jr ALLOC_OK
;--- DOS 2: Allocate a segment using mapper support routines
ALLOC_DOS2:
ld a,b
ld (PRIM_SLOT),a
ld de,ALL_SEG
ld bc,15*3
ldir
ld a,(PRIM_SLOT)
or %00100000 ;Try primary mapper, then try others
ld b,a
ld a,1 ;System segment
call ALL_SEG
jr nc,ALLOC_OK
ld de,NOFREE_S ;Terminate if no free segments available
ld c,_STROUT
call 5
ld c,_TERM0
jp 5
ALLOC_OK:
ld (ALLOC_SEG),a
ld a,b
ld (ALLOC_SLOT),a
;--- Switch segment, copy code, and setup data
call GET_P1 ;Backup current segment
ld (P1_SEG),a
ld a,(ALLOC_SLOT) ;Switch slot and segment
ld h,#40
call ENASLT
ld a,(ALLOC_SEG)
call PUT_P1
ld hl,#4000 ;Clear the segment first
ld de,#4001
ld bc,#4000-1
ld (hl),0
ldir
ld hl,SEG_CODE ;Copy the code to the segment
ld de,#4000
ld bc,SEG_CODE_END-SEG_CODE_START
ldir
ld hl,(ALLOC_SLOT) ;Setup slot and segment information
ld (MY_SLOT),hl
;* Now backup and patch the EXTBIO hook
; so that it calls address #4000 of the allocated segment
ld hl,EXTBIO
ld de,OLD_EXTBIO
ld bc,5
ldir
di
ld a,#CD ;Code for "CALL"
ld (EXTBIO),a
ld hl,(HELPER_ADD)
ld bc,6
add hl,bc ;Now HL points to segment call routine
ld (EXTBIO+1),hl
ld hl,(MAPTAB_ADD)
ld a,(ALLOC_SLOT)
ld d,a
ld e,0 ;Index on mappers table
SRCHMAP:
ld a,(hl)
cp d
jr z,MAPFND
inc hl
inc hl ;Next table entry
inc e
jr SRCHMAP
MAPFND:
ld a,e ;A = Index of slot on mappers table
rrca
rrca
and %11000000 ;Entry point #4010 = index 0
ld (EXTBIO+3),a
ld a,(ALLOC_SEG)
ld (EXTBIO+4),a
ei
;--- Restore slot and segment, and terminate
ld a,(PRIM_SLOT)
ld h,#40
call ENASLT
ld a,(P1_SEG)
call PUT_P1
ld de,OK_S
ld c,_STROUT
call 5
ld c,_TERM0
jp 5
;>>> Other auxiliary code
CALL_IX: jp (ix)
CALL_HL: jp (hl)
;****************************************************
;*** DATA AND STRINGS FOR THE INSTALLATION CODE ***
;****************************************************
;--- Variables
PRIM_SLOT: db 0 ;Primary mapper slot number
P1_SEG: db 0 ;Segment number for TPA on page 1
ALLOC_SLOT: db 0 ;Slot for the allocated segment
ALLOC_SEG: db 0 ;Allocated segment
HELPER_ADD: dw 0 ;Address of the RAM helper jump table
MAPTAB_ADD: dw 0 ;Address of the RAM helper mappers table
IMPLEM_ENTRY: dw 0 ;Entry point for implementations
;--- DOS 2 mapper support routines
ALL_SEG: ds 3
FRE_SEG: ds 3
RD_SEG: ds 3
WR_SEG: ds 3
CAL_SEG: ds 3
CALLS: ds 3
PUT_PH: ds 3
GET_PH: ds 3
PUT_P0: ds 3
GET_P0: ds 3
PUT_P1: out (#FD),a
ret
GET_P1: in a,(#FD)
ret
PUT_P2: ds 3
GET_P2: ds 3
PUT_P3: ds 3
;--- Strings
WELCOME_S:
db "UNAPI Sample RAM implementation 1.0 (SIMPLE_MATH)",13,10
db "(c) 2010 by Konamiman",13,10
db 13,10
db "$"
NOHELPER_S:
db "*** ERROR: No UNAPI RAM helper is installed",13,10,"$"
NOMAPPER_S:
db "*** ERROR: No mapped RAM found",13,10,"$"
NOFREE_S:
db "*** ERROR: Could not allocate any RAM segment",13,10,"$"
OK_S: db "Installed. Have fun!",13,10,"$"
ALINST_S: db "*** Already installed.",13,10,"$"
;*********************************************
;*** CODE TO BE INSTALLED ON RAM SEGMENT ***
;*********************************************
SEG_CODE:
org #4000
SEG_CODE_START:
;===============================
;=== EXTBIO hook execution ===
;===============================
;>>> Note that this code starts exactly at address #4000
DO_EXTBIO:
push hl
push bc
push af
ld a,d
cp #22
jr nz,JUMP_OLD
cp e
jr nz,JUMP_OLD
;Check API ID
ld hl,UNAPI_ID
ld de,ARG
LOOP: ld a,(de)
call TOUPPER
cp (hl)
jr nz,JUMP_OLD2
inc hl
inc de
or a
jr nz,LOOP
;A=255: Jump to old hook
pop af
push af
inc a
jr z,JUMP_OLD2
;A=0: B=B+1 and jump to old hook
pop af
pop bc
or a
jr nz,DO_EXTBIO2
inc b
pop hl
ld de,#2222
jp OLD_EXTBIO
DO_EXTBIO2:
;A=1: Return A=Slot, B=Segment, HL=UNAPI entry address
dec a
jr nz,DO_EXTBIO3
pop hl
ld a,(MY_SEG)
ld b,a
ld a,(MY_SLOT)
ld hl,UNAPI_ENTRY
ld de,#2222
ret
;A>1: A=A-1, and jump to old hook
DO_EXTBIO3: ;A=A-1 already done
pop hl
ld de,#2222
jp OLD_EXTBIO
;--- Jump here to execute old EXTBIO code
JUMP_OLD2:
ld de,#2222
JUMP_OLD: ;Assumes "push hl,bc,af" done
pop af
pop bc
pop hl
;Old EXTBIO hook contents is here
;(it is setup at installation time)
OLD_EXTBIO:
ds 5
;====================================
;=== Functions entry point code ===
;====================================
UNAPI_ENTRY:
push hl
push af
ld hl,FN_TABLE
bit 7,a
if MAX_IMPFN >= 128
jr z,IS_STANDARD
ld hl,IMPFN_TABLE
and %01111111
cp MAX_IMPFN-128
jr z,OK_FNUM
jr nc,UNDEFINED
IS_STANDARD:
else
jr nz,UNDEFINED
endif
cp MAX_FN
jr z,OK_FNUM
jr nc,UNDEFINED
OK_FNUM:
add a,a
push de
ld e,a
ld d,0
add hl,de
pop de
ld a,(hl)
inc hl
ld h,(hl)
ld l,a
pop af
ex (sp),hl
ret
;--- Undefined function: return with registers unmodified
UNDEFINED:
pop af
pop hl
ret
;===================================
;=== Functions addresses table ===
;===================================
;--- Standard routines addresses table
FN_TABLE:
FN_0: dw FN_INFO
FN_1: dw FN_ADD
FN_2: dw FN_MULT
;--- Implementation-specific routines addresses table
if MAX_IMPFN >= 128
IMPFN_TABLE:
FN_128: dw FN_DUMMY
endif
;========================
;=== Functions code ===
;========================
;--- Mandatory routine 0: return API information
; Input: A = 0
; Output: HL = Descriptive string for this implementation, on this slot, zero terminated
; DE = API version supported, D.E
; BC = This implementation version, B.C.
; A = 0 and Cy = 0
FN_INFO:
ld bc,256*ROM_V_P+ROM_V_S
ld de,256*API_V_P+API_V_S
ld hl,APIINFO
xor a
ret
;--- Sample routine 1: adds two 8-bit numbers
; Input: E, L = Numbers to add
; Output: HL = Result
FN_ADD:
ld h,0
ld d,0
add hl,de
ret
;--- Sample routine 2: multiplies two 8-bit numbers
; Input: E, L = Numbers to multiply
; Output: HL = Result
FN_MULT:
ld b,e
ld e,l
ld d,0
ld hl,0
MULT_LOOP:
add hl,de
djnz MULT_LOOP
ret
;============================
;=== Auxiliary routines ===
;============================
;--- Convert a character to upper-case if it is a lower-case letter
TOUPPER:
cp "a"
ret c
cp "z"+1
ret nc
and #DF
ret
;============================
;=== UNAPI related data ===
;============================
;This data is setup at installation time
MY_SLOT: db 0
MY_SEG: db 0
;--- Specification identifier (up to 15 chars)
UNAPI_ID:
db "SIMPLE_MATH",0
UNAPI_ID_END:
;--- Implementation name (up to 63 chars and zero terminated)
APIINFO:
db "Konamiman's RAM implementation of SIMPLE_MATH UNAPI",0
SEG_CODE_END:

10
src/mmigate/0module.mk Normal file
View file

@ -0,0 +1,10 @@
BUILD_HELP += \\n\\t* mmigate-build\\n\\t* mmigate-run-virtual
.PHONY: mmigate-build
mmigate-build:
cargo build
.PHONY: mmigate-run-virtual
mmigate-run-virtual:
cargo run virtual

200
src/mmigate/main.rs Normal file
View file

@ -0,0 +1,200 @@
extern crate midir;
//#[macro_use]
extern crate structopt;
use std::thread::sleep;
use std::time::Duration;
use std::io::{stdin, stdout, Write};
use std::error::Error;
use structopt::StructOpt;
use midir::{
MidiInput,
MidiOutput,
MidiInputConnection,
MidiOutputConnection
};
#[cfg(not(windows))]
use midir::os::unix::VirtualInput;
#[cfg(not(windows))]
use midir::os::unix::VirtualOutput;
const boot_logo: &str = "
Starting: _ _
_ __ ___ _ __ ___ (_) __ _ __ _| |_ ___
| '_ ` _ \\| '_ ` _ \\| |/ _` |/ _` | __/ _ \\
| | | | | | | | | | | | (_| | (_| | || __/
|_| |_| |_|_| |_| |_|_|\\__, |\\__,_|\\__\\___|
|___/
";
#[derive(StructOpt, Debug)]
#[structopt(name = "mmigate", rename_all = "kebab-case")]
struct Startup {
/// Enable debug mode.
#[structopt(short, long)]
debug: bool,
/// MIDI client name.
#[structopt(short, long, default_value = "mmigate")]
client_name: String,
#[structopt(subcommand)]
cmd: StartupCommand
}
#[derive(StructOpt, Debug)]
enum StartupCommand {
/// Proxy internet over virtual MIDI.
#[structopt(name = "virtual")]
VirtualProxy {
/// MIDI client name.
#[structopt(short, long, default_value = "rpc-tcp-unapi")]
port_name: String,
},
/// List all MIDI devices.
#[structopt(name = "hw-list")]
HardwareList {},
/// Proxy internet over MIDI devices.
#[structopt(name = "hw-proxy")]
HardwareProxy {
/// MIDI-In port
#[structopt(short = "i", long)]
midi_in: usize,
/// MIDI-Out port
#[structopt(short = "o", long)]
midi_out: usize,
},
}
fn main() {
match run(Startup::from_args()) {
Ok(_) => (),
Err(err) => println!("Error: {}", err.description())
}
}
//const MIDI_CLIENT_NAME: &str = "mmigate";
fn run(startup: Startup) -> Result<(), Box<Error>> {
println!("{}", boot_logo);
println!("version: {}", 123);
if startup.debug {
println!("{:?}", startup);
}
let midir_in = MidiInput::new(&(startup.client_name.to_string() + "-in"))?;
let midir_out = MidiOutput::new(&(startup.client_name.to_string() + "-out"))?;
match startup.cmd {
StartupCommand::HardwareList {} => {
//println!("Available MIDI-in ports:");
for i in 0..midir_in.port_count() {
println!("in_{}: {}", i, midir_in.port_name(i)?);
}
//println!("\nAvailable MIDI-out ports:");
for i in 0..midir_out.port_count() {
println!("out_{}: {}", i, midir_out.port_name(i)?);
}
return Ok(());
},
StartupCommand::VirtualProxy {port_name} => {
#[cfg(not(windows))] {
println!("mode: virtual");
println!("port_names: {}-in,{}-out", port_name, port_name);
let mut conn_out = midir_out.create_virtual(&(port_name.to_string() + "-out"))?;
let conn_in = midir_in.create_virtual(&(port_name.to_string() + "-in"), move |stamp, message, _| {
conn_out.send(message).unwrap_or_else(|_| println!("Error when forwarding message ..."));
println!("{}: {:?} (len = {})", stamp, message, message.len());
}, ())?;
//input.clear();
let mut input = String::new();
stdin().read_line(&mut input)?; // wait for next enter key press
println!("Closing connections");
return Ok(());
//return proxy();
}
//
#[cfg(windows)] {
return Error(("Virtual MIDI ports are not supported on Windows."));
}
}
StartupCommand::HardwareProxy {midi_in, midi_out} => {
// Get an output port (read from console if multiple are available)
let out_port = match midir_out.port_count() {
0 => return Err("no output port found".into()),
1 => {
println!("Choosing the only available output port: {}", midir_out.port_name(0).unwrap());
0
},
_ => {
println!("\nAvailable output ports:");
for i in 0..midir_out.port_count() {
println!("{}: {}", i, midir_out.port_name(i).unwrap());
}
print!("Please select output port: ");
stdout().flush()?;
let mut input = String::new();
stdin().read_line(&mut input)?;
input.trim().parse()?
}
};
println!("\nOpening connection");
let mut conn_out = midir_out.connect(out_port, "midir-test")?;
println!("Connection open. Listen!");
{
// Define a new scope in which the closure `play_note` borrows conn_out, so it can be called easily
let mut play_note = |note: u8, duration: u64| {
const NOTE_ON_MSG: u8 = 0x90;
const NOTE_OFF_MSG: u8 = 0x80;
const VELOCITY: u8 = 0x64;
// We're ignoring errors in here
let _ = conn_out.send(&[NOTE_ON_MSG, note, VELOCITY]);
sleep(Duration::from_millis(duration * 150));
let _ = conn_out.send(&[NOTE_OFF_MSG, note, VELOCITY]);
};
play_note(66, 4);
play_note(65, 3);
play_note(63, 1);
play_note(61, 6);
play_note(59, 2);
play_note(58, 4);
play_note(56, 4);
play_note(54, 4);
}
sleep(Duration::from_millis(150));
println!("\nClosing connection");
// This is optional, the connection would automatically be closed as soon as it goes out of scope
conn_out.close();
println!("Connection closed");
Ok(())
}
}
}
fn proxy<T>(startup: Startup, conn_in: MidiInputConnection<T>, conn_out: MidiOutputConnection) -> Result<(), Box<Error>> {
println!("Starting mmigate proxy");
sleep(Duration::from_millis(150));
println!("\nClosing connections");
conn_in.close();
conn_out.close();
println!("Connections closed");
Ok(())
}

BIN
tmp/hget.com Normal file

Binary file not shown.

BIN
tmp/inl.com Normal file

Binary file not shown.

BIN
tmp/ping.com Normal file

Binary file not shown.

BIN
tmp/ramhelpr.com Normal file

Binary file not shown.