Compare commits
No commits in common. "main" and "develop" have entirely different histories.
109 changed files with 14585 additions and 9616 deletions
31
.gitignore
vendored
31
.gitignore
vendored
|
@ -1,5 +1,4 @@
|
|||
src/*.o
|
||||
src/ui4x/*.o
|
||||
|
||||
dist/pack
|
||||
dist/saturn
|
||||
|
@ -19,18 +18,18 @@ docs/saturn.pdf
|
|||
docs/saturn.ps
|
||||
docs/saturn.log
|
||||
|
||||
src/libChf/docs/chf.tps
|
||||
src/libChf/docs/chf.tp
|
||||
src/libChf/docs/chf.toc
|
||||
src/libChf/docs/chf.pdf
|
||||
src/libChf/docs/chf.log
|
||||
src/libChf/docs/chf.info
|
||||
src/libChf/docs/chf.fns
|
||||
src/libChf/docs/chf.fn
|
||||
src/libChf/docs/chf.cps
|
||||
src/libChf/docs/chf.cp
|
||||
src/libChf/docs/chf.aux
|
||||
src/libChf/docs/chf.dvi
|
||||
src/libChf/docs/chf.ps
|
||||
src/libChf/libChf.a
|
||||
src/libChf/src/*.o
|
||||
libChf/docs/chf.tps
|
||||
libChf/docs/chf.tp
|
||||
libChf/docs/chf.toc
|
||||
libChf/docs/chf.pdf
|
||||
libChf/docs/chf.log
|
||||
libChf/docs/chf.info
|
||||
libChf/docs/chf.fns
|
||||
libChf/docs/chf.fn
|
||||
libChf/docs/chf.cps
|
||||
libChf/docs/chf.cp
|
||||
libChf/docs/chf.aux
|
||||
libChf/docs/chf.dvi
|
||||
libChf/docs/chf.ps
|
||||
libChf/libChf.a
|
||||
libChf/src/*.o
|
||||
|
|
147
Makefile
147
Makefile
|
@ -1,4 +1,4 @@
|
|||
# Simple Makefile to build saturn
|
||||
# Simple Makefile to build saturn_bertolotti
|
||||
#
|
||||
# The cc-option function and the C{,PP}FLAGS logic were copied from the
|
||||
# fsverity-utils project.
|
||||
|
@ -6,45 +6,35 @@
|
|||
# The governing license can be found in the LICENSE file or at
|
||||
# https://opensource.org/license/MIT.
|
||||
|
||||
NAME = saturn
|
||||
PREFIX = /usr
|
||||
DOCDIR = $(PREFIX)/doc/saturn
|
||||
|
||||
VERSION_MAJOR = 5
|
||||
VERSION_MINOR = 4
|
||||
VERSION_MAJOR = 0
|
||||
VERSION_MINOR = 0
|
||||
PATCHLEVEL = 0
|
||||
|
||||
PREFIX ?= /usr
|
||||
DOCDIR ?= $(PREFIX)/doc/$(NAME)
|
||||
INFODIR ?= $(PREFIX)/info
|
||||
|
||||
LUA_VERSION ?= lua
|
||||
PKG_CONFIG ?= pkg-config
|
||||
|
||||
OPTIM ?= 2
|
||||
|
||||
override CFLAGS := -O$(OPTIM) \
|
||||
CFLAGS ?= -O$(OPTIM) \
|
||||
-D_GNU_SOURCE=1 \
|
||||
-DVERSION_MAJOR=$(VERSION_MAJOR) \
|
||||
-DVERSION_MINOR=$(VERSION_MINOR) \
|
||||
-DPATCHLEVEL=$(PATCHLEVEL) \
|
||||
-I./src/ \
|
||||
-I./src/libChf/src/ \
|
||||
$(CFLAGS)
|
||||
-I./libChf/src/
|
||||
|
||||
LIBS = -L./src/libChf -lChf
|
||||
LIBS = -L./libChf -lChf
|
||||
|
||||
SDLCFLAGS = $(shell "$(PKG_CONFIG)" --cflags sdl2)
|
||||
SDLLIBS = $(shell "$(PKG_CONFIG)" --libs sdl2)
|
||||
SDLCFLAGS = $(shell pkg-config --cflags sdl2)
|
||||
SDLLIBS = $(shell pkg-config --libs sdl2)
|
||||
|
||||
NCURSESCFLAGS = $(shell "$(PKG_CONFIG)" --cflags ncursesw)
|
||||
NCURSESLIBS = $(shell "$(PKG_CONFIG)" --libs ncursesw)
|
||||
|
||||
### lua
|
||||
LUACFLAGS = $(shell "$(PKG_CONFIG)" --cflags $(LUA_VERSION))
|
||||
LUALIBS = $(shell "$(PKG_CONFIG)" --libs $(LUA_VERSION))
|
||||
NCURSESCFLAGS = $(shell pkg-config --cflags ncursesw)
|
||||
NCURSESLIBS = $(shell pkg-config --libs ncursesw)
|
||||
|
||||
FULL_WARNINGS = no
|
||||
|
||||
DOTOS = src/cpu.o \
|
||||
src/debug.o \
|
||||
src/dis.o \
|
||||
src/disk_io.o \
|
||||
src/disk_io_obj.o \
|
||||
|
@ -58,39 +48,26 @@ DOTOS = src/cpu.o \
|
|||
src/romram.o \
|
||||
src/romram49.o \
|
||||
src/serial.o \
|
||||
src/x_func.o \
|
||||
src/chf_messages.o \
|
||||
src/main.o
|
||||
src/x_func.o
|
||||
|
||||
DOTOS_UI4x = src/ui4x/config.o \
|
||||
src/ui4x/fonts.o \
|
||||
src/ui4x/48sx.o \
|
||||
src/ui4x/48gx.o \
|
||||
src/ui4x/49g.o \
|
||||
src/ui4x/common.o \
|
||||
src/ui4x/sdl2.o \
|
||||
src/ui4x/ncurses.o \
|
||||
src/ui4x/emulator.o
|
||||
DOTOS_UI48 = src/ui48_config.o \
|
||||
src/ui48_common.o \
|
||||
src/ui48_sdl2.o \
|
||||
src/ui48_ncurses.o \
|
||||
src/ui48_emulator.o \
|
||||
src/ui48_main.o
|
||||
|
||||
HEADERS = src/ui4x/bitmaps_misc.h \
|
||||
src/ui4x/common.h \
|
||||
src/ui4x/config.h \
|
||||
src/ui4x/ncurses.h \
|
||||
src/ui4x/sdl2.h \
|
||||
src/ui4x/inner.h \
|
||||
src/ui4x/emulator.h \
|
||||
src/disk_io.h \
|
||||
src/flash49.h \
|
||||
src/keyb.h \
|
||||
src/machdep.h \
|
||||
src/modules.h \
|
||||
src/monitor.h \
|
||||
src/serial.h \
|
||||
src/x_func.h \
|
||||
src/chf_messages.h \
|
||||
src/config.h \
|
||||
src/cpu.h \
|
||||
src/debug.h
|
||||
MSFS = src/MSFs/cpu.msf \
|
||||
src/MSFs/debug.msf \
|
||||
src/MSFs/disk_io.msf \
|
||||
src/MSFs/flash49.msf \
|
||||
src/MSFs/modules.msf \
|
||||
src/MSFs/saturn.msf \
|
||||
src/MSFs/serial.msf \
|
||||
src/MSFs/util.msf \
|
||||
src/MSFs/x11.msf \
|
||||
src/MSFs/x_func.msf \
|
||||
libChf/src/chf.msf
|
||||
|
||||
MAKEFLAGS +=-j$(NUM_CORES) -l$(NUM_CORES)
|
||||
|
||||
|
@ -130,7 +107,6 @@ override CFLAGS := -std=c11 \
|
|||
$(EXTRA_WARNING_FLAGS) \
|
||||
$(SDLCFLAGS) \
|
||||
$(NCURSESCFLAGS) \
|
||||
$(LUACFLAGS) \
|
||||
$(CFLAGS)
|
||||
|
||||
override CPPFLAGS := -I./src/ -D_GNU_SOURCE=1 \
|
||||
|
@ -138,79 +114,88 @@ override CPPFLAGS := -I./src/ -D_GNU_SOURCE=1 \
|
|||
|
||||
.PHONY: all clean clean-all pretty-code install mrproper get-roms install
|
||||
|
||||
all: src/libChf/libChf.a dist/$(NAME) docs
|
||||
all: libChf/libChf.a dist/saturn dist/saturn.cat docs
|
||||
|
||||
# Building
|
||||
src/libChf/libChf.a:
|
||||
make -C src/libChf #MT=yes
|
||||
libChf/libChf.a:
|
||||
make -C libChf
|
||||
|
||||
dist/$(NAME): $(DOTOS) $(DOTOS_UI4x) $(HEADERS) src/libChf/libChf.a
|
||||
$(CC) $(DOTOS) $(DOTOS_UI4x) src/libChf/libChf.a -o $@ $(CFLAGS) $(LIBS) $(SDLLIBS) $(NCURSESLIBS) $(LUALIBS)
|
||||
dist/saturn: $(DOTOS) $(DOTOS_UI48) libChf/libChf.a
|
||||
$(CC) $^ -o $@ $(CFLAGS) $(LIBS) $(SDLLIBS) $(NCURSESLIBS)
|
||||
|
||||
dist/pack: src/pack.o src/disk_io.o src/debug.o src/libChf/libChf.a
|
||||
dist/pack: src/pack.o src/disk_io.o src/debug.o libChf/libChf.a
|
||||
# UNUSED
|
||||
$(CC) $^ -o $@ $(CFLAGS) $(LIBS)
|
||||
|
||||
dist/saturn.cat: $(MSFS)
|
||||
for msf in $? ; \
|
||||
do gencat $@ $$msf ; \
|
||||
done
|
||||
|
||||
doc:
|
||||
make -C docs
|
||||
|
||||
# Cleaning
|
||||
clean:
|
||||
rm -f src/*.o
|
||||
make -C src/libChf clean
|
||||
make -C libChf clean
|
||||
make -C docs clean
|
||||
|
||||
mrproper: clean
|
||||
rm -f dist/$(NAME) dist/pack
|
||||
rm -f dist/saturn dist/saturn.cat dist/pack
|
||||
make -C dist/ROMs mrproper
|
||||
make -C src/libChf mrproper
|
||||
make -C libChf mrproper
|
||||
make -C docs mrproper
|
||||
|
||||
clean-all: mrproper
|
||||
|
||||
# Formatting
|
||||
pretty-code:
|
||||
clang-format -i src/*.c src/*.h src/ui4x/*.c src/ui4x/*.h
|
||||
make -C src/libChf pretty-code
|
||||
clang-format -i src/*.c src/*.h
|
||||
make -C libChf pretty-code
|
||||
|
||||
# Dependencies
|
||||
get-roms:
|
||||
make -C dist/ROMs get-roms
|
||||
|
||||
# Installation
|
||||
install: dist/$(NAME) doc
|
||||
install: dist/saturn dist/saturn.cat dist/Saturn.ad doc
|
||||
install -m 755 -d -- $(DESTDIR)$(PREFIX)/bin
|
||||
install -c -m 755 dist/$(NAME) $(DESTDIR)$(PREFIX)/bin/$(NAME)
|
||||
install -c -m 755 dist/saturn $(DESTDIR)$(PREFIX)/bin/saturn
|
||||
install -c -m 755 dist/saturn48gx $(DESTDIR)$(PREFIX)/bin/saturn48gx
|
||||
install -c -m 755 dist/saturn48sx $(DESTDIR)$(PREFIX)/bin/saturn48sx
|
||||
install -c -m 755 dist/saturn40g $(DESTDIR)$(PREFIX)/bin/saturn40g
|
||||
install -c -m 755 dist/saturn49g $(DESTDIR)$(PREFIX)/bin/saturn49g
|
||||
|
||||
install -m 755 -d -- $(DESTDIR)$(PREFIX)/share/$(NAME)
|
||||
install -c -m 644 dist/hplogo.png $(DESTDIR)$(PREFIX)/share/$(NAME)/hplogo.png
|
||||
cp -R dist/ROMs/ $(DESTDIR)$(PREFIX)/share/$(NAME)/
|
||||
install -c -m 644 dist/saturn.cat $(DESTDIR)$(PREFIX)/bin/saturn.cat #FIXME
|
||||
install -m 755 -d -- $(DESTDIR)$(PREFIX)/share/locale/C/LC_MESSAGES
|
||||
install -c -m 644 dist/saturn.cat $(DESTDIR)$(PREFIX)/share/locale/C/LC_MESSAGES/saturn.cat
|
||||
|
||||
install -m 755 -d -- $(DESTDIR)$(PREFIX)/share/saturn
|
||||
install -c -m 644 dist/saturn.cat $(DESTDIR)$(PREFIX)/share/saturn.cat #FIXME
|
||||
install -c -m 644 dist/hplogo.png $(DESTDIR)$(PREFIX)/share/saturn/hplogo.png
|
||||
cp -R dist/ROMs/ $(DESTDIR)$(PREFIX)/share/saturn/
|
||||
|
||||
install -m 755 -d -- $(DESTDIR)/etc/X11/app-defaults
|
||||
install -c -m 644 dist/Saturn.ad $(DESTDIR)/etc/X11/app-defaults/Saturn
|
||||
|
||||
install -m 755 -d -- $(DESTDIR)$(DOCDIR)
|
||||
cp -R COPYING LICENSE README* ./*.png docs-4.1.1.1 docs/*.{dvi,ps,pdf} $(DESTDIR)$(DOCDIR)
|
||||
|
||||
install -m 755 -d -- $(DESTDIR)$(INFODIR)
|
||||
cp docs/*.info $(DESTDIR)$(INFODIR)
|
||||
cp -R COPYING LICENSE README* docs* docs/ $(DESTDIR)$(DOCDIR)
|
||||
|
||||
install -m 755 -d -- $(DESTDIR)$(PREFIX)/share/applications
|
||||
sed "s|@PREFIX@|$(PREFIX)|g" dist/saturn48gx.desktop > $(DESTDIR)$(PREFIX)/share/applications/saturn48gx.desktop
|
||||
sed "s|@PREFIX@|$(PREFIX)|g" dist/saturn48sx.desktop > $(DESTDIR)$(PREFIX)/share/applications/saturn48sx.desktop
|
||||
sed "s|@PREFIX@|$(PREFIX)|g" dist/saturn49g.desktop > $(DESTDIR)$(PREFIX)/share/applications/saturn49g.desktop
|
||||
sed "s|@PREFIX@|$(PREFIX)|g" dist/saturn40g.desktop > $(DESTDIR)$(PREFIX)/share/applications/saturn40g.desktop
|
||||
|
||||
uninstall:
|
||||
rm -f $(DESTDIR)$(PREFIX)/bin/$(NAME)
|
||||
rm -f $(DESTDIR)$(PREFIX)/bin/saturn
|
||||
rm -f $(DESTDIR)$(PREFIX)/bin/saturn48gx
|
||||
rm -f $(DESTDIR)$(PREFIX)/bin/saturn48sx
|
||||
rm -f $(DESTDIR)$(PREFIX)/bin/saturn40g
|
||||
rm -f $(DESTDIR)$(PREFIX)/bin/saturn49g
|
||||
rm -fr $(DESTDIR)$(PREFIX)/share/$(NAME)
|
||||
rm -f $(DESTDIR)$(PREFIX)/bin/saturn.cat
|
||||
rm -f $(DESTDIR)$(PREFIX)/share/locale/C/LC_MESSAGES/saturn.cat
|
||||
rm -fr $(DESTDIR)$(PREFIX)/share/saturn
|
||||
rm -f $(DESTDIR)/etc/X11/app-defaults/Saturn
|
||||
rm -fr $(DESTDIR)$(DOCDIR)
|
||||
rm -f $(DESTDIR)$(PREFIX)/share/applications/saturn48gx.desktop
|
||||
rm -f $(DESTDIR)$(PREFIX)/share/applications/saturn48sx.desktop
|
||||
rm -f $(DESTDIR)$(PREFIX)/share/applications/saturn49g.desktop
|
||||
rm -f $(DESTDIR)$(PREFIX)/share/applications/saturn40g.desktop
|
||||
|
|
58
README.md
58
README.md
|
@ -1,24 +1,7 @@
|
|||
# Emulator of the HP 49G, HP 48 (GX & SX), and HP 40G
|
||||
|
||||
**This is a fork of saturn v4.1.1.1 originally by Ivan Cibrario Bertolotti.**
|
||||
|
||||
Original source are available at https://www.hpcalc.org/details/4382
|
||||
|
||||
The GUI has been replaced by a new one (taken from x48ng) in SDL2 and/or ncurses.
|
||||
|
||||
## Screenshots
|
||||
|
||||
![screenshot of saturn49g](./saturn49g.png?raw=true "screenshot of saturn49g")
|
||||
![screenshot of saturn48gx](./saturn48gx.png?raw=true "screenshot of saturn48gx")
|
||||
![screenshot of saturn48sx](./saturn48sx.png?raw=true "screenshot of saturn48sx")
|
||||
# Emulator of the HP 48GX, HP 49, and HP 40
|
||||
|
||||
## Building
|
||||
|
||||
Dependencies:
|
||||
- SDL2
|
||||
- ncursesw
|
||||
|
||||
|
||||
``` shell
|
||||
make
|
||||
```
|
||||
|
@ -29,24 +12,31 @@ make install DESTDIR=/
|
|||
```
|
||||
|
||||
## Using
|
||||
The main binary is `dist/saturn` with helpers/wrappers scripts available per model as:
|
||||
* `dist/saturn48gx`
|
||||
* `dist/saturn48sx`
|
||||
* `dist/saturn49g`
|
||||
* `dist/saturn40g` (not really functional (yet))
|
||||
|
||||
The local data are stored under `$XDG_CONFIG_HOME/saturn<model>/`.
|
||||
### locally
|
||||
``` shell
|
||||
./dist/run48.sh
|
||||
```
|
||||
|
||||
The scripts will take care of creating `$XDG_CONFIG_HOME/saturn<model>/`, download an appropriate ROM from hpcalc.org and create RAM cards (for 48gx and 48sx models.)
|
||||
### when installed
|
||||
``` shell
|
||||
saturn48gx
|
||||
```
|
||||
|
||||
|
||||
## Post-fork changelog
|
||||
- replaced the build system with a basic Makefile
|
||||
- updated license from GPL2-or-later to GPL3-or-later
|
||||
- moved binaries and their dependencies under ./dist/
|
||||
- new helper scripts run48.sh and run49.sh
|
||||
- ROMs helper Makefile
|
||||
|
||||
## Known bugs
|
||||
- some bugs in emulation:
|
||||
- 48gx: ON-D A can hang because it tries to write data in ROM space
|
||||
- 48gx: VERSION spouts messages in the console (hidden unless `--verbose`)
|
||||
- 49g: spouts messages in the console every second (hidden unless `--verbose`)
|
||||
- ncurses UI: becomes unresponsive (but still quits gracefully on F7)
|
||||
- I could get neither the 49 nor the 40 ROM running yet.
|
||||
|
||||
## Todo
|
||||
- fix emulation bugs
|
||||
- 49g: find a way to enable the bigger screen (131×80)
|
||||
- 40g: make emulation work
|
||||
|
||||
**This is a fork of saturn v4.1.1.1 originally by Ivan Cibrario Bertolotti.**
|
||||
|
||||
Original source are available at https://www.hpcalc.org/details/4382
|
||||
|
||||
Original documentation are kept in ./docs-4.1.1.1/ and ./manual/
|
||||
|
|
2
dist/ROMs/Makefile
vendored
2
dist/ROMs/Makefile
vendored
|
@ -31,7 +31,7 @@ gxrom-r:
|
|||
|
||||
# HP 49
|
||||
rom.49g:
|
||||
curl "https://www.hpcalc.org/hp49/pc/rom/hp4950emurom.zip" --output rom-49g.zip
|
||||
curl "https://www.hpcalc.org/hp49/pc/rom/beta1196.zip" --output rom-49g.zip
|
||||
unzip rom-49g.zip rom.49g
|
||||
rm rom-49g.zip
|
||||
|
||||
|
|
2422
dist/Saturn.ad
vendored
Normal file
2422
dist/Saturn.ad
vendored
Normal file
File diff suppressed because it is too large
Load diff
21
dist/run48.sh
vendored
Executable file
21
dist/run48.sh
vendored
Executable file
|
@ -0,0 +1,21 @@
|
|||
#!/bin/bash -eu
|
||||
|
||||
cd "$(dirname "$0")" ; CWD=$(pwd)
|
||||
|
||||
STATEDIR=$CWD/stateDir.48
|
||||
mkdir -p "$STATEDIR"
|
||||
|
||||
if [ ! -e "$STATEDIR"/gxrom-r ]; then
|
||||
make -C .. get-roms
|
||||
cp ROMs/gxrom-r "$STATEDIR"/gxrom-r
|
||||
fi
|
||||
|
||||
RAM=''
|
||||
if [ ! -e "$STATEDIR"/ram ]; then
|
||||
RAM=-reset
|
||||
fi
|
||||
|
||||
[ ! -e "$STATEDIR"/port1 ] && dd if=/dev/zero of="$STATEDIR"/port1 bs=1k count=128
|
||||
[ ! -e "$STATEDIR"/port2 ] && dd if=/dev/zero of="$STATEDIR"/port2 bs=1k count=4096
|
||||
|
||||
./run_saturn -face hp48 -hw hp48 -stateDir "$STATEDIR" -rom gxrom-r $RAM -port1 port1 -port2 port2
|
22
dist/run49.sh
vendored
Executable file
22
dist/run49.sh
vendored
Executable file
|
@ -0,0 +1,22 @@
|
|||
#!/bin/bash -eu
|
||||
|
||||
cd "$(dirname "$0")" ; CWD=$(pwd)
|
||||
|
||||
STATEDIR=$CWD/stateDir.49
|
||||
mkdir -p "$STATEDIR"
|
||||
|
||||
if [ ! -e "$STATEDIR"/rom.49g ]; then
|
||||
( cd "$STATEDIR"
|
||||
wget -c https://www.hpcalc.org/hp49/pc/rom/hp4950v210.zip -O rom.zip
|
||||
# wget -c https://www.hpcalc.org/hp49/pc/rom/beta1196.zip -O rom.zip
|
||||
unzip rom.zip
|
||||
rm rom.zip
|
||||
)
|
||||
fi
|
||||
|
||||
RAM=''
|
||||
if [ ! -e "$STATEDIR"/ram ]; then
|
||||
RAM=-reset
|
||||
fi
|
||||
|
||||
./run_saturn -face hp49 -hw hp49 -stateDir "$STATEDIR" -rom rom.49g $RAM "$@"
|
18
dist/run_saturn
vendored
Executable file
18
dist/run_saturn
vendored
Executable file
|
@ -0,0 +1,18 @@
|
|||
#!/bin/sh
|
||||
#
|
||||
# $Id: run_saturn,v 4.1 2000/12/11 09:54:19 cibrario Rel $
|
||||
#
|
||||
# This file allows you to run saturn directly from the build directory,
|
||||
# without installing it; regular use is discouraged.
|
||||
|
||||
if [ ! -r Saturn ]; then ln -s Saturn.ad Saturn; fi
|
||||
|
||||
# Be sure that XUSERFILESEARCHPATH does not supersede XAPPLRESDIR (IRIX)
|
||||
if [ "$XUSERFILESEARCHPATH" != "" ]; then
|
||||
XUSERFILESEARCHPATH=./%L/%N:./%l/%N:./%N:$XUSERFILESEARCHPATH;
|
||||
export XUSERFILESEARCHPATH;
|
||||
fi
|
||||
|
||||
XAPPLRESDIR=.; export XAPPLRESDIR # Take resources from here
|
||||
NLSPATH=./%N; export NLSPATH # Message catalog is here, too
|
||||
./saturn "$@"
|
46
dist/saturn40g
vendored
46
dist/saturn40g
vendored
|
@ -1,44 +1,28 @@
|
|||
#!/bin/bash -eu
|
||||
|
||||
cd "$(dirname "$0")" || exit 1
|
||||
#CWD=$(pwd)
|
||||
|
||||
BINNAME=$(basename "$0")
|
||||
STATE_HOME=${XDG_STATE_HOME:-$HOME/.local/state}
|
||||
|
||||
CONFIG_HOME=${XDG_CONFIG_HOME:-$HOME/.config}
|
||||
STATEDIR=$STATE_HOME/saturn/40g
|
||||
mkdir -p "$STATEDIR"
|
||||
|
||||
CONFIGDIR=${CONFIGDIR:-$CONFIG_HOME/$BINNAME}
|
||||
mkdir -p "$CONFIGDIR"
|
||||
|
||||
if [ ! -e "$CONFIGDIR"/rom ]; then
|
||||
if [ -d ../share/saturn/ROMs/ ]; then
|
||||
cp -R ../share/saturn/ROMs/ "$CONFIGDIR"/
|
||||
elif [ -d ./ROMs/ ]; then
|
||||
cp -R ./ROMs/ "$CONFIGDIR"/
|
||||
fi
|
||||
if [ ! -d "$CONFIGDIR"/ROMs ]; then
|
||||
if [ ! -e "$STATEDIR"/rom.39g ]; then
|
||||
if [ ! -d ../share/saturn/ROMs/ ]; then
|
||||
echo "Error: No ROMs/ dir found"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "The next step will download a ROM from https://hpcalc.org where \"HP graciously began allowing this to be downloaded in mid-2000.\""
|
||||
echo "You can hit Ctrl-C now if you do not wish to download them."
|
||||
read -r
|
||||
|
||||
make -C "$CONFIGDIR"/ROMs rom.39g
|
||||
cp "$CONFIGDIR"/ROMs/rom.39g "$CONFIGDIR"/rom
|
||||
if [ ! -d "$STATEDIR"/../ROMs ]; then
|
||||
cp -R ../share/saturn/ROMs/ "$STATEDIR"/../ROMs
|
||||
fi
|
||||
make -C "$STATEDIR"/../ROMs rom.39g
|
||||
cp "$STATEDIR"/../ROMs/rom.39g "$STATEDIR"/rom.39g
|
||||
fi
|
||||
|
||||
RESET=''
|
||||
if [ ! -e "$CONFIGDIR"/ram ]; then
|
||||
RESET=--reset
|
||||
RAM=''
|
||||
if [ ! -e "$STATEDIR"/ram ]; then
|
||||
RAM=-reset
|
||||
fi
|
||||
|
||||
if [ ! -e "$CONFIGDIR"/config.lua ]; then
|
||||
./saturn --40g --state-dir "$CONFIGDIR" --print-config > "$CONFIGDIR"/config.lua
|
||||
fi
|
||||
|
||||
if echo "$@" | grep -q "\--verbose"; then
|
||||
./saturn --40g --state-dir "$CONFIGDIR" "$RESET" "$@"
|
||||
else
|
||||
./saturn --40g --state-dir "$CONFIGDIR" "$RESET" "$@" 2> /dev/null
|
||||
fi
|
||||
./saturn --hw hp40 --40g --state-dir "$STATEDIR" --rom rom.39g "$RAM" --mod mod --cpu cpu --hdw hdw "$@"
|
||||
|
|
54
dist/saturn48gx
vendored
54
dist/saturn48gx
vendored
|
@ -1,47 +1,33 @@
|
|||
#!/bin/bash -eu
|
||||
|
||||
cd "$(dirname "$0")" || exit 1
|
||||
#CWD=$(pwd)
|
||||
|
||||
BINNAME=$(basename "$0")
|
||||
STATE_HOME=${XDG_STATE_HOME:-$HOME/.local/state}
|
||||
|
||||
CONFIG_HOME=${XDG_CONFIG_HOME:-$HOME/.config}
|
||||
STATEDIR=$STATE_HOME/saturn/48gx
|
||||
mkdir -p "$STATEDIR"
|
||||
|
||||
CONFIGDIR=${CONFIGDIR:-$CONFIG_HOME/$BINNAME}
|
||||
mkdir -p "$CONFIGDIR"
|
||||
|
||||
if [ ! -e "$CONFIGDIR"/rom ]; then
|
||||
if [ -d ../share/saturn/ROMs/ ]; then
|
||||
cp -R ../share/saturn/ROMs/ "$CONFIGDIR"/
|
||||
elif [ -d ./ROMs/ ]; then
|
||||
cp -R ./ROMs/ "$CONFIGDIR"/
|
||||
fi
|
||||
if [ ! -d "$CONFIGDIR"/ROMs ]; then
|
||||
if [ ! -e "$STATEDIR"/gxrom-r ]; then
|
||||
if [ ! -d ../share/saturn/ROMs/ ]; then
|
||||
echo "Error: No ROMs/ dir found"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "The next step will download a ROM from https://hpcalc.org where \"HP graciously began allowing this to be downloaded in mid-2000.\""
|
||||
echo "You can hit Ctrl-C now if you do not wish to download them."
|
||||
read -r
|
||||
|
||||
make -C "$CONFIGDIR"/ROMs gxrom-r
|
||||
cp "$CONFIGDIR"/ROMs/gxrom-r "$CONFIGDIR"/rom
|
||||
if [ ! -d "$STATEDIR"/../ROMs ]; then
|
||||
cp -R ../share/saturn/ROMs/ "$STATEDIR"/../ROMs
|
||||
fi
|
||||
make -C "$STATEDIR"/../ROMs gxrom-r
|
||||
cp "$STATEDIR"/../ROMs/gxrom-r "$STATEDIR"/gxrom-r
|
||||
fi
|
||||
|
||||
[ ! -e "$CONFIGDIR"/port1 ] && dd if=/dev/zero of="$CONFIGDIR"/port1 bs=1k count=128
|
||||
[ ! -e "$CONFIGDIR"/port2 ] && dd if=/dev/zero of="$CONFIGDIR"/port2 bs=1k count=4096
|
||||
|
||||
RESET=''
|
||||
if [ ! -e "$CONFIGDIR"/ram ]; then
|
||||
RESET=--reset
|
||||
fi
|
||||
|
||||
if [ ! -e "$CONFIGDIR"/config.lua ]; then
|
||||
./saturn --48gx --state-dir "$CONFIGDIR" --print-config > "$CONFIGDIR"/config.lua
|
||||
fi
|
||||
|
||||
if echo "$@" | grep -q "\--verbose"; then
|
||||
./saturn --48gx --state-dir "$CONFIGDIR" "$RESET" "$@"
|
||||
RAM=''
|
||||
if [ ! -e "$STATEDIR"/ram ]; then
|
||||
RAM=--reset
|
||||
else
|
||||
./saturn --48gx --state-dir "$CONFIGDIR" "$RESET" "$@" 2> /dev/null
|
||||
RAM="--ram ram"
|
||||
fi
|
||||
|
||||
[ ! -e "$STATEDIR"/port1 ] && dd if=/dev/zero of="$STATEDIR"/port1 bs=1k count=128
|
||||
[ ! -e "$STATEDIR"/port2 ] && dd if=/dev/zero of="$STATEDIR"/port2 bs=1k count=4096
|
||||
|
||||
./saturn --hw hp48 --48gx --state-dir "$STATEDIR" --rom gxrom-r "$RAM" --port1 port1 --port2 port2 --mod mod --cpu cpu --hdw hdw "$@"
|
||||
|
|
47
dist/saturn48sx
vendored
47
dist/saturn48sx
vendored
|
@ -1,47 +0,0 @@
|
|||
#!/bin/bash -eu
|
||||
|
||||
cd "$(dirname "$0")" || exit 1
|
||||
|
||||
BINNAME=$(basename "$0")
|
||||
|
||||
CONFIG_HOME=${XDG_CONFIG_HOME:-$HOME/.config}
|
||||
|
||||
CONFIGDIR=${CONFIGDIR:-$CONFIG_HOME/$BINNAME}
|
||||
mkdir -p "$CONFIGDIR"
|
||||
|
||||
if [ ! -e "$CONFIGDIR"/rom ]; then
|
||||
if [ -d ../share/saturn/ROMs/ ]; then
|
||||
cp -R ../share/saturn/ROMs/ "$CONFIGDIR"/
|
||||
elif [ -d ./ROMs/ ]; then
|
||||
cp -R ./ROMs/ "$CONFIGDIR"/
|
||||
fi
|
||||
if [ ! -d "$CONFIGDIR"/ROMs ]; then
|
||||
echo "Error: No ROMs/ dir found"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "The next step will download a ROM from https://hpcalc.org where \"HP graciously began allowing this to be downloaded in mid-2000.\""
|
||||
echo "You can hit Ctrl-C now if you do not wish to download them."
|
||||
read -r
|
||||
|
||||
make -C "$CONFIGDIR"/ROMs sxrom-j
|
||||
cp "$CONFIGDIR"/ROMs/sxrom-j "$CONFIGDIR"/rom
|
||||
fi
|
||||
|
||||
[ ! -e "$CONFIGDIR"/port1 ] && dd if=/dev/zero of="$CONFIGDIR"/port1 bs=1k count=128
|
||||
[ ! -e "$CONFIGDIR"/port2 ] && dd if=/dev/zero of="$CONFIGDIR"/port2 bs=1k count=128
|
||||
|
||||
RESET=''
|
||||
if [ ! -e "$CONFIGDIR"/ram ]; then
|
||||
RESET=--reset
|
||||
fi
|
||||
|
||||
if [ ! -e "$CONFIGDIR"/config.lua ]; then
|
||||
./saturn --48sx --state-dir "$CONFIGDIR" --print-config > "$CONFIGDIR"/config.lua
|
||||
fi
|
||||
|
||||
if echo "$@" | grep -q "\--verbose"; then
|
||||
./saturn --48sx --state-dir "$CONFIGDIR" "$RESET" "$@"
|
||||
else
|
||||
./saturn --48sx --state-dir "$CONFIGDIR" "$RESET" "$@" 2> /dev/null
|
||||
fi
|
9
dist/saturn48sx.desktop
vendored
9
dist/saturn48sx.desktop
vendored
|
@ -1,9 +0,0 @@
|
|||
[Desktop Entry]
|
||||
Encoding=UTF-8
|
||||
Version=1.0
|
||||
Type=Application
|
||||
Terminal=false
|
||||
Exec=@PREFIX@/bin/saturn48sx
|
||||
Name=saturn48sx
|
||||
Icon=@PREFIX@/share/saturn/hplogo.png
|
||||
Categories=Utility;
|
46
dist/saturn49g
vendored
46
dist/saturn49g
vendored
|
@ -1,44 +1,28 @@
|
|||
#!/bin/bash -eu
|
||||
|
||||
cd "$(dirname "$0")" || exit 1
|
||||
#CWD=$(pwd)
|
||||
|
||||
BINNAME=$(basename "$0")
|
||||
STATE_HOME=${XDG_STATE_HOME:-$HOME/.local/state}
|
||||
|
||||
CONFIG_HOME=${XDG_CONFIG_HOME:-$HOME/.config}
|
||||
STATEDIR=$STATE_HOME/saturn/49g
|
||||
mkdir -p "$STATEDIR"
|
||||
|
||||
CONFIGDIR=${CONFIGDIR:-$CONFIG_HOME/$BINNAME}
|
||||
mkdir -p "$CONFIGDIR"
|
||||
|
||||
if [ ! -e "$CONFIGDIR"/rom ]; then
|
||||
if [ -d ../share/saturn/ROMs/ ]; then
|
||||
cp -R ../share/saturn/ROMs/ "$CONFIGDIR"/
|
||||
elif [ -d ./ROMs/ ]; then
|
||||
cp -R ./ROMs/ "$CONFIGDIR"/
|
||||
fi
|
||||
if [ ! -d "$CONFIGDIR"/ROMs ]; then
|
||||
if [ ! -e "$STATEDIR"/rom.49g ]; then
|
||||
if [ ! -d ../share/saturn/ROMs/ ]; then
|
||||
echo "Error: No ROMs/ dir found"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "The next step will download a ROM from https://hpcalc.org where \"HP graciously began allowing this to be downloaded in mid-2000.\""
|
||||
echo "You can hit Ctrl-C now if you do not wish to download them."
|
||||
read -r
|
||||
|
||||
make -C "$CONFIGDIR"/ROMs rom.49g
|
||||
cp "$CONFIGDIR"/ROMs/rom.49g "$CONFIGDIR"/rom
|
||||
if [ ! -d "$STATEDIR"/../ROMs ]; then
|
||||
cp -R ../share/saturn/ROMs/ "$STATEDIR"/../ROMs
|
||||
fi
|
||||
make -C "$STATEDIR"/../ROMs rom.49g
|
||||
cp "$STATEDIR"/../ROMs/rom.49g "$STATEDIR"/rom.49g
|
||||
fi
|
||||
|
||||
RESET=''
|
||||
if [ ! -e "$CONFIGDIR"/ram ]; then
|
||||
RESET=--reset
|
||||
RAM=''
|
||||
if [ ! -e "$STATEDIR"/ram ]; then
|
||||
RAM=-reset
|
||||
fi
|
||||
|
||||
if [ ! -e "$CONFIGDIR"/config.lua ]; then
|
||||
./saturn --49g --state-dir "$CONFIGDIR" --print-config > "$CONFIGDIR"/config.lua
|
||||
fi
|
||||
|
||||
if echo "$@" | grep -q "\--verbose"; then
|
||||
./saturn --49g --state-dir "$CONFIGDIR" "$RESET" "$@"
|
||||
else
|
||||
./saturn --49g --state-dir "$CONFIGDIR" "$RESET" "$@" 2> /dev/null
|
||||
fi
|
||||
./saturn --hw hp49 --49g --state-dir "$STATEDIR" --rom rom.49g "$RAM" --mod mod --cpu cpu --hdw hdw "$@"
|
||||
|
|
|
@ -7,16 +7,14 @@ SRC = src/chf_init.c \
|
|||
src/chf_abrt.c \
|
||||
src/chf_hdlr.c \
|
||||
src/chf_msgc.c \
|
||||
src/chf_st.c
|
||||
src/chf_st.c \
|
||||
src/chf_top.c
|
||||
|
||||
#
|
||||
# Target object files
|
||||
#
|
||||
OBJS = $(SRC:.c=.o)
|
||||
|
||||
HEADERS = src/ChfPriv.h \
|
||||
src/Chf.h \
|
||||
|
||||
#
|
||||
# Other definitions
|
||||
#
|
||||
|
@ -48,8 +46,8 @@ mrproper: clean
|
|||
rm -f $(TARGET)
|
||||
make -C docs mrproper
|
||||
|
||||
$(TARGET): $(OBJS) $(HEADERS)
|
||||
$(AR) $(ARFLAGS) $@ $(OBJS)
|
||||
$(TARGET): $(OBJS)
|
||||
$(AR) $(ARFLAGS) $@ $?
|
||||
|
||||
# Formatting
|
||||
pretty-code:
|
|
@ -68,9 +68,10 @@ Condition generation and signal
|
|||
|
||||
Generating a condition
|
||||
|
||||
* CHF_Condition::
|
||||
* ChfCondition::
|
||||
* ChfEnd::
|
||||
* ChfSeverity::
|
||||
* ChfErrnoCondition::
|
||||
|
||||
Signaling a condition
|
||||
|
||||
|
@ -97,9 +98,9 @@ Structured condition handling
|
|||
|
||||
Chf behavior during structured condition handling
|
||||
|
||||
* CHF_Try::
|
||||
* CHF_Catch::
|
||||
* CHF_EndTry::
|
||||
* ChfTry::
|
||||
* ChfCatch::
|
||||
* ChfEndTry::
|
||||
|
||||
Message retrieval
|
||||
|
||||
|
@ -176,6 +177,9 @@ this change is transparent and the documentation does not reflect it.
|
|||
The reentrant flavor of the Chf library is not yet supported. Multithreaded
|
||||
application must serialize Chf accesses themselves.
|
||||
|
||||
@item
|
||||
The @code{ChfErrnoCondition} macro is not supported, and has no effect.
|
||||
|
||||
@item
|
||||
The default condition handler does not display the condition message
|
||||
on the standard error stream.
|
||||
|
@ -263,7 +267,7 @@ Moreover, each module using the Chf library must include the header file
|
|||
@node ChfInit(), ChfMsgcatInit(), Initialization and exit, Initialization and exit
|
||||
@section ChfInit()
|
||||
@cindex Initialization
|
||||
@deftypefn Function int ChfInit (const char *app_name, const int options, void *mrs_data, ChfMrsGet mrs_get, ChfMrsExit mrs_exit, const int condition_stack_size, const int handler_stack_size, const int exit_code)
|
||||
@deftypefn Function int ChfInit (const char *app_name, const ChfOptions options, void *mrs_data, ChfMrsGet mrs_get, ChfMrsExit mrs_exit, const int condition_stack_size, const int handler_stack_size, const int exit_code)
|
||||
|
||||
This function initializes the Chf library using a custom message retrieval
|
||||
subsystem, and returns to the caller a condition code; that code will be either
|
||||
|
@ -317,8 +321,8 @@ Size of the handler stack. This value determines the maximum number of
|
|||
active condition handlers the application can have. A condition handler is
|
||||
activated when a @code{ChfPushHandler()} is executed for it, and it is
|
||||
deactivated when the corresponding @code{ChfPopHandler()} completes.
|
||||
In addition, each execution of the @code{CHF_Try} macro also pushes
|
||||
a condition handler; the handler is removed when @code{CHF_EndTry}
|
||||
In addition, each execution of the @code{ChfTry} macro also pushes
|
||||
a condition handler; the handler is removed when @code{ChfEndTry}
|
||||
is executed.
|
||||
|
||||
@item exit_code
|
||||
|
@ -364,7 +368,7 @@ must be invoked only once before starting multithreaded operation.
|
|||
@section ChfMsgcatInit()
|
||||
@cindex Initialization
|
||||
@cindex Internationalization
|
||||
@deftypefn Function int ChfMsgcatInit (const char *app_name, const int options, const char *msgcat_name, const int condition_stack_size, const int handler_stack_size, const int exit_code)
|
||||
@deftypefn Function int ChfMsgcatInit (const char *app_name, const ChfOptions options, const char *msgcat_name, const int condition_stack_size, const int handler_stack_size, const int exit_code)
|
||||
|
||||
This function initializes the Chf library and activates the message retrieval
|
||||
subsystem based on @code{catgets()}, offering support for
|
||||
|
@ -420,7 +424,7 @@ before.
|
|||
@node ChfStaticInit(), ChfWin32Init(), ChfMsgcatInit(), Initialization and exit
|
||||
@section ChfStaticInit()
|
||||
@cindex Initialization
|
||||
@deftypefn Function int ChfStaticInit (const char *app_name, const int options, const ChfTable *table, const size_t table_size, const int condition_stack_size, const int handler_stack_size, const int exit_code)
|
||||
@deftypefn Function int ChfStaticInit (const char *app_name, const ChfOptions options, const ChfTable *table, const size_t table_size, const int condition_stack_size, const int handler_stack_size, const int exit_code)
|
||||
|
||||
This function initializes the Chf library and activates the static
|
||||
message retrieval subsystem using the message table @code{table},
|
||||
|
@ -482,7 +486,7 @@ The message fragment or template associated with
|
|||
@section ChfWin32Init()
|
||||
@cindex Initialization
|
||||
@cindex Internationalization
|
||||
@deftypefn Function int ChfWin32Init (const char *app_name, const int options, HINSTANCE instance, const int condition_stack_size, const int handler_stack_size, const int exit_code)
|
||||
@deftypefn Function int ChfWin32Init (const char *app_name, const ChfOptions options, HINSTANCE instance, const int condition_stack_size, const int handler_stack_size, const int exit_code)
|
||||
|
||||
This function initializes the Chf library and activates the message
|
||||
retrieval subsystem based on the Win32 function @code{LoadString()},
|
||||
|
@ -665,6 +669,12 @@ identifier. Even if this macro could in principle be redefined through the
|
|||
source, it is generally inconvenient to have functions belonging to different
|
||||
application's modules in the same source file, so it is discouraged.
|
||||
This definition is mandatory.
|
||||
|
||||
@item CHF_EXTENDED_INFO
|
||||
If this macro is set, all conditions generated by the source module
|
||||
will include the file name and the line number as additional information
|
||||
items. This can be useful for debugging purposes. This definition is
|
||||
optional.
|
||||
@end table
|
||||
|
||||
@strong{Win32:} The @code{tchar.h} system header must be included
|
||||
|
@ -687,14 +697,15 @@ When an unusual or noteworthy condition occurs, the application may generate
|
|||
a condition that describes it.
|
||||
|
||||
@menu
|
||||
* CHF_Condition::
|
||||
* ChfCondition::
|
||||
* ChfEnd::
|
||||
* ChfSeverity::
|
||||
* ChfErrnoCondition::
|
||||
@end menu
|
||||
|
||||
@node CHF_Condition, ChfEnd, Generating a condition, Generating a condition
|
||||
@subsection CHF_Condition
|
||||
@deftypefn Macro {} CHF_Condition {...}
|
||||
@node ChfCondition, ChfEnd, Generating a condition, Generating a condition
|
||||
@subsection ChfCondition
|
||||
@deftypefn Macro {} ChfCondition {...}
|
||||
|
||||
This macro starts the definition of a condition using the current
|
||||
application's module specifier @code{CHF_MODULE_ID}; it must be followed by
|
||||
|
@ -748,15 +759,15 @@ there was an attempt to generate a condition while the Chf condition
|
|||
@end deftypefn
|
||||
|
||||
|
||||
@node ChfEnd, ChfSeverity, CHF_Condition, Generating a condition
|
||||
@node ChfEnd, ChfSeverity, ChfCondition, Generating a condition
|
||||
@subsection ChfEnd
|
||||
@deftypefn Macro {} ChfEnd
|
||||
|
||||
This macro terminates the generation of the condition, started
|
||||
with @code{CHF_Condition}; it must be followed by @code{;}. For example:
|
||||
with @code{ChfCondition}; it must be followed by @code{;}. For example:
|
||||
|
||||
@example
|
||||
CHF_Condition
|
||||
ChfCondition
|
||||
<condition_code>, <severity>, <additional_info>
|
||||
ChfEnd;
|
||||
@end example
|
||||
|
@ -765,7 +776,7 @@ ChfEnd;
|
|||
|
||||
@c 2.1, cibrario, 26-May-2000
|
||||
@c Expanded description of severity codes
|
||||
@node ChfSeverity, ChfEnd, Generating a condition
|
||||
@node ChfSeverity, ChfErrnoCondition, ChfEnd, Generating a condition
|
||||
@subsection ChfSeverity
|
||||
@deftp {Data type} ChfSeverity
|
||||
The severity code of a condition is an enumerated type, and can assume one
|
||||
|
@ -811,6 +822,19 @@ call. It is usually signaled immediately after generation.
|
|||
@end table
|
||||
@end deftp
|
||||
|
||||
@node ChfErrnoCondition, , ChfSeverity, Generating a condition
|
||||
@subsection ChfErrnoCondition
|
||||
@deftypefn Macro {} ChfErrnoCondition
|
||||
|
||||
This macro generates a condition from the current value of the @code{errno}
|
||||
variable. The module identifier of the condition is set to the special
|
||||
value @code{CHF_ERRNO_SET}. The severity is always @code{CHF_ERROR}.
|
||||
|
||||
@strong{Win32:} This macro is not supported and has no effect when invoked.
|
||||
|
||||
@end deftypefn
|
||||
|
||||
|
||||
@node Signaling a condition, , Generating a condition, Condition generation and signal
|
||||
@section Signaling a condition
|
||||
@cindex Signaling a condition
|
||||
|
@ -952,7 +976,7 @@ typedef /* Condition handler */
|
|||
ChfAction (*ChfHandler)(
|
||||
const ChfDescriptor *,
|
||||
const ChfState,
|
||||
void*
|
||||
ChfPointer
|
||||
);
|
||||
@end example
|
||||
|
||||
|
@ -966,7 +990,7 @@ is a pointer to the condition group that is being signaled.
|
|||
@item const ChfState
|
||||
represents the current state of the condition handling facility.
|
||||
|
||||
@item void*
|
||||
@item ChfPointer
|
||||
is a copy of the @code{handler_context} pointer passed to the
|
||||
@code{ChfPushHandler()} invocation that established the condition
|
||||
handler.
|
||||
|
@ -1000,7 +1024,7 @@ of the new condition group allows it to do so.
|
|||
@subsection ChfPushHandler()
|
||||
@cindex Condition handlers
|
||||
@cindex Adding condition handlers
|
||||
@deftypefn Function void ChfPushHandler (ChfHandler new_handler, void *unwind_context, void* handler_context)
|
||||
@deftypefn Function void ChfPushHandler (ChfHandler new_handler, void *unwind_context, ChfPointer handler_context)
|
||||
|
||||
This function pushes the new condition handler @code{new_handler} with
|
||||
its associated @code{siglongjmp()} context, pointed by
|
||||
|
@ -1106,6 +1130,74 @@ the macros the Chf library provides for this purpose.
|
|||
|
||||
@end deftp
|
||||
|
||||
The following macros are provided to access a condition descriptor:
|
||||
|
||||
@deftypefn Macro {ChfDescriptor *} ChfGetNextDescriptor (Chf Descriptor *d)
|
||||
@cindex Next condition descriptor
|
||||
|
||||
Returns to the caller the condition descriptor that hierarchically
|
||||
follows @code{d} in the current condition group, or the special
|
||||
value @code{CHF_NULL_DESCRIPTOR} if @code{d} is the last descriptor of the
|
||||
group.
|
||||
|
||||
@end deftypefn
|
||||
|
||||
@deftypefn Macro int ChfGetModuleId (Chf Descriptor *d)
|
||||
@cindex Module identifier
|
||||
|
||||
Returns to the caller the identifier of the module that generated
|
||||
the condition @code{d}.
|
||||
|
||||
@end deftypefn
|
||||
|
||||
@deftypefn Macro int ChfGetConditionCode (Chf Descriptor *d)
|
||||
@cindex Condition Code
|
||||
|
||||
Returns to the caller the condition code of the condition @code{d}.
|
||||
|
||||
@end deftypefn
|
||||
|
||||
@deftypefn Macro ChfSeverity ChfGetSeverity (Chf Descriptor *d)
|
||||
@cindex Severity
|
||||
|
||||
Returns to the caller the severity level of the condition @code{d}.
|
||||
@xref{ChfSeverity}.
|
||||
|
||||
@end deftypefn
|
||||
|
||||
@deftypefn Macro int ChfGetLineNumber (Chf Descriptor *d)
|
||||
@cindex Line number
|
||||
|
||||
Returns to the caller the source line number where the condition @code{d}
|
||||
was generated. This piece of information is available only if the
|
||||
Chf compile-time option @code{CHF_EXTENDED_INFO} was set when the source
|
||||
file that generated the condition was compiled, otherwise the special
|
||||
value @code{CHF_UNKNOWN_LINE_NUMBER} is returned instead.
|
||||
|
||||
@end deftypefn
|
||||
|
||||
@deftypefn Macro {const char *} ChfGetFileName (Chf Descriptor *d)
|
||||
@cindex File name
|
||||
|
||||
Returns to the caller the file name where the condition @code{d}
|
||||
was generated. This piece of information is available only if the
|
||||
Chf compile-time option @code{CHF_EXTENDED_INFO} was set when the source
|
||||
file that generated the condition was compiled, otherwise the special
|
||||
value @code{CHF_UNKNOWN_FILE_NAME} is returned instead.
|
||||
|
||||
@end deftypefn
|
||||
|
||||
@deftypefn Macro {char *} ChfGetPartialMessage (Chf Descriptor *d)
|
||||
@cindex Partial condition message
|
||||
|
||||
Returns to the caller the partial condition message that was associated
|
||||
with the condition @code{d} when it was generated. The partial condition
|
||||
message contains the result of the execution of @code{sprintf()} using
|
||||
the message template associated with the condition as format, and the
|
||||
ancillary condition arguments as additional arguments.
|
||||
|
||||
@end deftypefn
|
||||
|
||||
|
||||
|
||||
@node Condition handling state, Handler actions, Condition descriptors, General condition handling
|
||||
|
@ -1250,19 +1342,19 @@ the structured condition handling is layered above the general one.
|
|||
The syntax establishing a structured condition handler is as follows:
|
||||
|
||||
@example
|
||||
CHF_Try
|
||||
ChfTry
|
||||
@{
|
||||
... body ...
|
||||
@}
|
||||
CHF_Catch
|
||||
ChfCatch
|
||||
@{
|
||||
const ChfDescriptor *exc = ChfGetTopCondition();
|
||||
... condition handler ...
|
||||
@}
|
||||
CHF_EndTry;
|
||||
ChfEndTry;
|
||||
@end example
|
||||
|
||||
The macros @code{CHF_Try}, @code{CHF_Catch} and @code{CHF_EndTry}
|
||||
The macros @code{ChfTry}, @code{ChfCatch} and @code{ChfEndTry}
|
||||
expand as follows:
|
||||
|
||||
@example
|
||||
|
@ -1300,7 +1392,7 @@ The @code{body} is either a statement or a block of statements (a block
|
|||
is shown in the example) to be protected. If an exception with severity
|
||||
equal to @code{CHF_FATAL} is signaled during the execution of
|
||||
@code{body}, control is transferred to the @code{condition handler}
|
||||
following @code{CHF_Catch}.
|
||||
following @code{ChfCatch}.
|
||||
|
||||
The handler can then retrieve the condition group associated with the
|
||||
exception using @code{ChfGetTopCondition()}, as shown in the example,
|
||||
|
@ -1311,12 +1403,12 @@ and must perform one of the following actions:
|
|||
Handle the exception; when the condition handler completes, that is, its
|
||||
last statement has been executed, the current condition group is
|
||||
automatically discarded and control is transferred to the code that
|
||||
follows @code{CHF_EndTry}.
|
||||
follows @code{ChfEndTry}.
|
||||
@item
|
||||
Resignal the exception, possibly after adding one or more conditions to
|
||||
it; in this case, the handler explicitly calls @code{ChfSignal()}.
|
||||
In response, Chf continues to search for a handler that actually
|
||||
handles the exception, in the @code{CHF_Try}/@code{CHF_Catch} blocks
|
||||
handles the exception, in the @code{ChfTry}/@code{ChfCatch} blocks
|
||||
enclosing the current one, in inner to outer order. The control
|
||||
will never be returned to the resignaling handler.
|
||||
@end itemize
|
||||
|
@ -1338,7 +1430,7 @@ automatically signaled immediately after generation and are not reported
|
|||
to the caller; they are informational conditions only, and they must not
|
||||
disrupt the normal control flow of the application. Accordingly, the
|
||||
structured condition handler is @strong{not} invoked when a
|
||||
success/informational condition is signaled in its @code{CHF_Try} body.
|
||||
success/informational condition is signaled in its @code{ChfTry} body.
|
||||
@item
|
||||
@code{CHF_WARNING} conditions generated by a module are usually not
|
||||
signaled immediately after generation, but are reported to the
|
||||
|
@ -1348,7 +1440,7 @@ has been at least partially successful; this usually means that
|
|||
the disruption of the control flow of the application can be kept to
|
||||
a minimum and handled locally. Accordingly, the structured condition
|
||||
handler is @strong{not} invoked when a warning condition
|
||||
is signaled in its @code{CHF_Try} body.
|
||||
is signaled in its @code{ChfTry} body.
|
||||
@item
|
||||
@code{CHF_ERROR} conditions generated by a module indicate that the
|
||||
module execution has been unsuccessful; they are usually reported to the
|
||||
|
@ -1357,7 +1449,7 @@ indicates that a significant disruption of the control flow of the
|
|||
application is required to recover, and that local handling is still
|
||||
possible but could not suffice. Accordingly, the structured condition
|
||||
handler is @strong{not} invoked when an error condition is signaled in
|
||||
its @code{CHF_Try} body. Notice also that if the @code{CHF_Try} body is
|
||||
its @code{ChfTry} body. Notice also that if the @code{ChfTry} body is
|
||||
not able to locally recover the condition, it can add a @code{CHF_FATAL}
|
||||
condition to the condition group and signal the modified group, thus
|
||||
triggering the invocation of the structured condition handler.
|
||||
|
@ -1365,7 +1457,7 @@ triggering the invocation of the structured condition handler.
|
|||
@code{CHF_FATAL} conditions are usually signaled immediately after
|
||||
generation and always require a global recovery action.
|
||||
Accordingly, the structured condition handler is
|
||||
invoked when a warning condition is signaled in its @code{CHF_Try} body.
|
||||
invoked when a warning condition is signaled in its @code{ChfTry} body.
|
||||
@end itemize
|
||||
|
||||
Notice also that control is transferred to the structured exception
|
||||
|
@ -1379,7 +1471,7 @@ detailed description of its operation.
|
|||
|
||||
If no exceptions are raised during the execution of @code{body},
|
||||
the @code{condition handler} is skipped and execution continues
|
||||
immediately after @code{CHF_EndTry}.
|
||||
immediately after @code{ChfEndTry}.
|
||||
|
||||
@node Chf behavior during structured condition handling, , Syntax of structured condition handlers, Structured condition handling
|
||||
@section Chf behavior during structured condition handling
|
||||
|
@ -1410,11 +1502,11 @@ immediately returns without doing anything, since Chf is now in state
|
|||
@item
|
||||
Chf transitions to the @code{CHF_IDLE} state and performs a non-local
|
||||
control transfer to the structured condition handler's unwind context;
|
||||
this corresponds to the code that follows @code{CHF_Catch}.
|
||||
this corresponds to the code that follows @code{ChfCatch}.
|
||||
The current condition group is not removed from the condition stack.
|
||||
@item
|
||||
Since the current condition group has not been removed from the
|
||||
condition stack, the code that follows @code{CHF_Catch} can freely
|
||||
condition stack, the code that follows @code{ChfCatch} can freely
|
||||
access the condition group using @code{ChfGetTopCondition()}
|
||||
and @code{ChfGetNextDescriptor()}.
|
||||
@item
|
||||
|
@ -1422,7 +1514,7 @@ If any new condition is generated in this phase, it is merged with the
|
|||
current condition group; the condition group can be re-signaled at will
|
||||
by invoking @code{ChfSignal()}.
|
||||
@item
|
||||
Immediately after the code that follows @code{CHF_Catch} completes,
|
||||
Immediately after the code that follows @code{ChfCatch} completes,
|
||||
@code{ChfDiscard()} is automatically invoked to remove the topmost
|
||||
condition group from the stack.
|
||||
@end itemize
|
||||
|
@ -1439,38 +1531,38 @@ In summary, the following structured condition handling macros
|
|||
are currently available:
|
||||
|
||||
@menu
|
||||
* CHF_Try::
|
||||
* CHF_Catch::
|
||||
* CHF_EndTry::
|
||||
* ChfTry::
|
||||
* ChfCatch::
|
||||
* ChfEndTry::
|
||||
@end menu
|
||||
|
||||
@node CHF_Try, CHF_Catch, Chf behavior during structured condition handling, Chf behavior during structured condition handling
|
||||
@subsection CHF_Try
|
||||
@deftypefn Macro {} CHF_Try {...}
|
||||
@node ChfTry, ChfCatch, Chf behavior during structured condition handling, Chf behavior during structured condition handling
|
||||
@subsection ChfTry
|
||||
@deftypefn Macro {} ChfTry {...}
|
||||
|
||||
This macro introduces a new structured condition handling body.
|
||||
The body is either a statement or a block of statements to be
|
||||
protected: if a @code{CHF_FATAL} exception is signaled during its
|
||||
execution, control is transferred to the condition handling code
|
||||
following @code{CHF_Catch}.
|
||||
following @code{ChfCatch}.
|
||||
|
||||
@end deftypefn
|
||||
|
||||
@node CHF_Catch, CHF_EndTry, CHF_Try, Chf behavior during structured condition handling
|
||||
@subsection CHF_Catch
|
||||
@deftypefn Macro {} CHF_Catch {...}
|
||||
@node ChfCatch, ChfEndTry, ChfTry, Chf behavior during structured condition handling
|
||||
@subsection ChfCatch
|
||||
@deftypefn Macro {} ChfCatch {...}
|
||||
|
||||
This macro must follow @code{CHF_Try} and introduces a new structured
|
||||
This macro must follow @code{ChfTry} and introduces a new structured
|
||||
condition handler following it; the handler can be either a statement or
|
||||
a block of statements. If a @code{CHF_FATAL} exception is signaled
|
||||
during the execution of the body protected by @code{CHF_Try}, control is
|
||||
transferred to the condition handling code following @code{CHF_Catch}.
|
||||
during the execution of the body protected by @code{ChfTry}, control is
|
||||
transferred to the condition handling code following @code{ChfCatch}.
|
||||
|
||||
@end deftypefn
|
||||
|
||||
@node CHF_EndTry, , CHF_Catch, Chf behavior during structured condition handling
|
||||
@subsection CHF_EndTry
|
||||
@deftypefn Macro {} CHF_EndTry
|
||||
@node ChfEndTry, , ChfCatch, Chf behavior during structured condition handling
|
||||
@subsection ChfEndTry
|
||||
@deftypefn Macro {} ChfEndTry
|
||||
|
||||
This macro marks the end of a body/condition handler pair.
|
||||
|
||||
|
@ -1818,6 +1910,36 @@ Contains the integer identifier of the message set containing the condition
|
|||
messages for @code{errno} codes. It has the value 3.
|
||||
@end deftypefn
|
||||
|
||||
@deftypefn Macro {} ChfChar
|
||||
This macro is used to make portable declarations of character variables,
|
||||
and is mapped into either @code{char} or @code{TCHAR} depending on the
|
||||
platform.
|
||||
@end deftypefn
|
||||
|
||||
@deftypefn Macro {} ChfText (x)
|
||||
This macro is used to make portable declarations of character strings,
|
||||
and is mapped into either @code{x} or @code{_T(x)} depending on the
|
||||
platform.
|
||||
@end deftypefn
|
||||
|
||||
@deftypefn Macro {} ChfSigjmp_buf
|
||||
This macro is mapped into either @code{sigjmp_buf} or @code{jmp_buf},
|
||||
depending on whether the platform supports @code{sigjmp_buf}
|
||||
contexts or not.
|
||||
@end deftypefn
|
||||
|
||||
@deftypefn Macro {} ChfSigsetjmp (x,y)
|
||||
This macro is mapped into either @code{sigsetjmp()} or @code{setjmp()},
|
||||
depending on whether the platform supports @code{sigjmp_buf}
|
||||
contexts or not. In the latter case argument @code{x} is ignored.
|
||||
@end deftypefn
|
||||
|
||||
@deftypefn Macro {} ChfSiglongjmp (x,y)
|
||||
This macro is mapped into either @code{siglongjmp()} or @code{longjmp()},
|
||||
depending on whether the platform supports @code{sigjmp_buf}
|
||||
contexts or not.
|
||||
@end deftypefn
|
||||
|
||||
@node Other useful functions, Changes since release 1, Other useful macro definitions, Top
|
||||
@chapter Other useful functions
|
||||
@cindex Other useful functions
|
271
libChf/src/Chf.h
Normal file
271
libChf/src/Chf.h
Normal file
|
@ -0,0 +1,271 @@
|
|||
/* .+
|
||||
|
||||
.identifier : $Id: Chf.h,v 2.2 2001/01/25 11:56:44 cibrario Exp $
|
||||
.context : CHF, Condition Handling Facility
|
||||
.title : $RCSfile: Chf.h,v $, main header
|
||||
.kind : C header
|
||||
.author : Ivan Cibrario B.
|
||||
.site : CSTV-CNR
|
||||
.creation : 2-May-1996
|
||||
.keywords : *
|
||||
.description :
|
||||
This is the main header of the Condition Handling Facility
|
||||
|
||||
.include : stdio.h setjmp.h (Win32: tchar.h)
|
||||
|
||||
.notes :
|
||||
$Log: Chf.h,v $
|
||||
Revision 2.2 2001/01/25 11:56:44 cibrario
|
||||
Added partial Win32 support (Windows CE only).
|
||||
|
||||
Revision 2.1 2000/05/26 14:10:08 cibrario
|
||||
- Revised unwind context passing mechanism; redefined CHF_NULL_CONTEXT
|
||||
- New macros: CHF_NULL_HANDLER, CHF_MAJOR_RELEASE_NUMBER,
|
||||
CHF_MINOR_RELEASE_NUMBER
|
||||
- New ChfAction value: CHF_UNWIND_KEEP; fixed spelling of ChfAction value:
|
||||
CHF_SIGNALLING -> CHF_SIGNALING
|
||||
- Added structured condition handling macros: ChfTry, ChfCatch, ChfEndTry
|
||||
|
||||
Revision 1.6 1997/01/15 13:41:20 cibrario
|
||||
Defined the new data type ChfPointer, a generic (void *) pointer. Each
|
||||
condition handler can have a private handler context pointer, of type
|
||||
ChfPointer, that the function ChfPushHandler() stores and that is passed
|
||||
to the handler when it's activated.
|
||||
Fixed a wrong adjustment of the condition handlers stack pointer after
|
||||
an unwind operation.
|
||||
|
||||
Revision 1.5 1996/10/04 09:45:30 cibrario
|
||||
Updated the condition message format in the private header ChfPriv.h to
|
||||
improve internationalization
|
||||
|
||||
Revision 1.4 1996/09/25 13:21:11 cibrario
|
||||
Added macro CHF_LIBRARY_ID; it contains the current ID of the CHF library.
|
||||
The module chf_init.o will contain it as a static char[] variable.
|
||||
|
||||
Revision 1.2 1996/06/11 13:02:10 cibrario
|
||||
Added prototype for ChfGetTopCondition()
|
||||
|
||||
Revision 1.1 1996/05/28 12:56:47 cibrario
|
||||
Initial revision
|
||||
|
||||
|
||||
.- */
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
Win32 & UNICODE support
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
#define ChfChar char
|
||||
#define ChfText( x ) x
|
||||
#define ChfSigjmp_buf sigjmp_buf
|
||||
#define ChfSigsetjmp( x, y ) sigsetjmp( x, y )
|
||||
#define ChfSiglongjmp( x, y ) siglongjmp( x, y )
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
CHF implementation limits and other symbolic constants
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
#define CHF_MAX_MESSAGE_LENGTH 256
|
||||
#define CHF_UNKNOWN_LINE_NUMBER ( -1 )
|
||||
#define CHF_UNKNOWN_FILE_NAME ( ChfChar* )NULL
|
||||
#define CHF_NULL_DESCRIPTOR ( ChfDescriptor* )NULL
|
||||
#define CHF_NULL_CONTEXT ( void* )NULL
|
||||
#define CHF_NULL_POINTER ( ChfPointer* )NULL
|
||||
#define CHF_NULL_HANDLER ( ChfHandler ) NULL
|
||||
#define CHF_LIBRARY_ID ChfText( "$Id: Chf.h,v 2.2 2001/01/25 11:56:44 cibrario Exp $" )
|
||||
|
||||
#define CHF_MAJOR_RELEASE_NUMBER 2
|
||||
#define CHF_MINOR_RELEASE_NUMBER 2
|
||||
|
||||
#define CHF_MODULE_NAMES_SET 1
|
||||
#define CHF_SET 2
|
||||
#define CHF_ERRNO_SET 3
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
Condition codes
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
#define CHF_S_OK 0
|
||||
#define CHF_F_COND_STACK_FULL 1 /* Condition stack is full */
|
||||
#define CHF_F_HDLR_STACK_FULL 2 /* Handler stack is full */
|
||||
#define CHF_F_HDLR_STACK_EMPTY 3 /* Handler stack is empty */
|
||||
#define CHF_F_BAD_STATE 4 /* Bad CHF state for req. operation */
|
||||
#define CHF_F_INVALID_ACTION 5 /* Invalid action from handler: %d */
|
||||
#define CHF_F_MALLOC 6 /* Dynamic memory allocation failed */
|
||||
#define CHF_F_NOT_AVAILABLE 7 /* Function not available */
|
||||
#define CHF_F_SETLOCALE 10 /* setlocale() failed */
|
||||
#define CHF_F_CATOPEN 11 /* catopen() failed */
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
Type definitions
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
typedef enum /* Condition severity codes */
|
||||
{ CHF_SUCCESS,
|
||||
CHF_INFO,
|
||||
CHF_WARNING,
|
||||
CHF_ERROR,
|
||||
CHF_FATAL } ChfSeverity;
|
||||
|
||||
typedef enum /* Condition handler action codes */
|
||||
{ CHF_CONTINUE, /* Continue application */
|
||||
CHF_RESIGNAL, /* Resignal to next handler */
|
||||
CHF_UNWIND, /* Stack unwind */
|
||||
CHF_UNWIND_KEEP /* Unwind, keep last cond. group */
|
||||
} ChfAction;
|
||||
|
||||
typedef int /* CHF options */
|
||||
ChfOptions;
|
||||
|
||||
#define CHF_DEFAULT 0x0000 /* default flags */
|
||||
#define CHF_ABORT 0x0001 /* use abort() instead of exit() */
|
||||
|
||||
typedef enum /* Current CHF state */
|
||||
{ CHF_UNKNOWN,
|
||||
CHF_IDLE,
|
||||
CHF_SIGNALING,
|
||||
CHF_UNWINDING,
|
||||
CHF_SIGNAL_UNWINDING } ChfState;
|
||||
|
||||
typedef struct ChfDescriptor_S /* Condition descriptor */
|
||||
{
|
||||
int module_id; /* Module identifier */
|
||||
int condition_code; /* Condition code */
|
||||
ChfSeverity severity; /* Severity */
|
||||
int line_number; /* Line # or CHF_UNK_LINE_NUMBER */
|
||||
const ChfChar* file_name; /* File name or CHF_UNK_FILE_NAME */
|
||||
ChfChar message[ CHF_MAX_MESSAGE_LENGTH ]; /* Partial message */
|
||||
struct ChfDescriptor_S* next; /* Link to next descriptor */
|
||||
} ChfDescriptor;
|
||||
|
||||
typedef struct ChfTable_S /* Standalone message table */
|
||||
{
|
||||
int module; /* Module identifier */
|
||||
int code; /* Condition code */
|
||||
ChfChar* msg_template; /* Message template */
|
||||
} ChfTable;
|
||||
|
||||
typedef /* Generic pointer */
|
||||
void* ChfPointer;
|
||||
|
||||
typedef /* Condition handler */
|
||||
ChfAction ( *ChfHandler )( const ChfDescriptor*, const ChfState, ChfPointer );
|
||||
|
||||
typedef /* Message retrieval 'get_message' function */
|
||||
const ChfChar* ( *ChfMrsGet )( void*, const int, const int, const ChfChar* default_message );
|
||||
|
||||
typedef /* Message retrieval 'exit' function */
|
||||
void ( *ChfMrsExit )( void* );
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
Condition generation macros
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
#if defined( CHF_EXTENDED_INFO )
|
||||
# define ChfCondition \
|
||||
ChfGenerate( \
|
||||
CHF_MODULE_ID, \
|
||||
ChfText(__FILE__), __LINE__,
|
||||
|
||||
# define ChfErrnoCondition ChfGenerate( CHF_ERRNO_SET, ChfText( __FILE__ ), __LINE__, errno, CHF_ERROR )
|
||||
|
||||
#else
|
||||
# define ChfCondition \
|
||||
ChfGenerate( \
|
||||
CHF_MODULE_ID, \
|
||||
CHF_UNKNOWN_FILE_NAME, CHF_UNKNOWN_LINE_NUMBER,
|
||||
|
||||
# define ChfErrnoCondition ChfGenerate( CHF_ERRNO_SET, CHF_UNKNOWN_FILE_NAME, CHF_UNKNOWN_LINE_NUMBER, errno, CHF_ERROR )
|
||||
|
||||
#endif
|
||||
|
||||
#define ChfEnd \
|
||||
)
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
Structured condition handling
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
#define ChfTry \
|
||||
{ \
|
||||
ChfSigjmp_buf _chf_sigjmp_buf; \
|
||||
if ( ChfSigsetjmp( _chf_sigjmp_buf, 1 ) == 0 ) { \
|
||||
ChfPushHandler( CHF_NULL_HANDLER, _chf_sigjmp_buf, CHF_NULL_POINTER );
|
||||
|
||||
#define ChfCatch \
|
||||
ChfPopHandler(); \
|
||||
} \
|
||||
else \
|
||||
{
|
||||
|
||||
#define ChfEndTry \
|
||||
ChfDiscard(); \
|
||||
} \
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
Other macros
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
#define ChfGetNextDescriptor( d ) ( d )->next
|
||||
#define ChfGetModuleId( d ) ( d )->module_id
|
||||
#define ChfGetConditionCode( d ) ( d )->condition_code
|
||||
#define ChfGetSeverity( d ) ( d )->severity
|
||||
#define ChfGetLineNumber( d ) ( d )->line_number
|
||||
#define ChfGetFileName( d ) ( d )->file_name
|
||||
#define ChfGetPartialMessage( d ) ( d )->message
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
Function prototypes
|
||||
------------------------------------------------------------------------- */
|
||||
/* Generic initialization */
|
||||
int ChfInit( const ChfChar* app_name, /* Application's name */
|
||||
const ChfOptions options, /* Options */
|
||||
void* mrs_data, /* Message retrieval private data */
|
||||
ChfMrsGet mrs_get, /* 'GetMessage' function */
|
||||
ChfMrsExit mrs_exit, /* 'Exit' function */
|
||||
const int condition_stack_size, /* Size of the condition stack */
|
||||
const int handler_stack_size, /* Size of the handler stack */
|
||||
const int exit_code /* Abnormal exit code */
|
||||
);
|
||||
/* Initialization with msgcat subsystem */
|
||||
int ChfMsgcatInit( const ChfChar* app_name, /* Application's name */
|
||||
const ChfOptions options, /* Options */
|
||||
const ChfChar* msgcat_name, /* Name of the message catalog */
|
||||
const int condition_stack_size, /* Size of the condition stack */
|
||||
const int handler_stack_size, /* Size of the handler stack */
|
||||
const int exit_code /* Abnormal exit code */
|
||||
);
|
||||
/* Initialization with static message tables */
|
||||
int ChfStaticInit( const ChfChar* app_name, /* Application's name */
|
||||
const ChfOptions options, /* Options */
|
||||
const ChfTable* table, /* Static message table */
|
||||
const size_t table_size, /* Size of the message table */
|
||||
const int condition_stack_size, /* Size of the condition stack */
|
||||
const int handler_stack_size, /* Size of the handler stack */
|
||||
const int exit_code /* Abnormal exit code */
|
||||
);
|
||||
/* Exit */
|
||||
void ChfExit( void );
|
||||
/* Abort application */
|
||||
void ChfAbort( const int abort_code );
|
||||
/* Push a new handler into the stack */
|
||||
void ChfPushHandler( ChfHandler new_handler, /* Handler to be added */
|
||||
void* unwind_context, /* Unwind context */
|
||||
ChfPointer handler_context /* Private handler context */
|
||||
);
|
||||
/* Pop a handler */
|
||||
void ChfPopHandler( void );
|
||||
/* Build a condition message */
|
||||
ChfChar* ChfBuildMessage( const ChfDescriptor* descriptor );
|
||||
/* Signal the current conditions */
|
||||
void ChfSignal( void );
|
||||
/* Discard the current conditions */
|
||||
void ChfDiscard( void );
|
||||
/* Generate a condition into the stack */
|
||||
void ChfGenerate( const int module_id, const ChfChar* file_name, const int line_number, const int condition_code,
|
||||
const ChfSeverity severity, ... );
|
||||
/* Retrieve a condition message */
|
||||
const ChfChar* ChfGetMessage( const int module_id, const int condition_code, const ChfChar* default_message );
|
||||
/* Retrieve top condition */
|
||||
const ChfDescriptor* ChfGetTopCondition( void );
|
|
@ -1,6 +1,3 @@
|
|||
#ifndef _CHF_PRIV_H
|
||||
#define _CHF_PRIV_H 1
|
||||
|
||||
/* .+
|
||||
|
||||
.identifier : $Id: ChfPriv.h,v 2.2 2001/01/25 11:57:57 cibrario Exp $
|
||||
|
@ -40,8 +37,6 @@
|
|||
|
||||
.- */
|
||||
|
||||
#include "Chf.h"
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
Macros
|
||||
------------------------------------------------------------------------- */
|
||||
|
@ -49,6 +44,16 @@
|
|||
#define CHF_MODULE_ID CHF_SET
|
||||
#define CHF_TMP_MESSAGE_LENGTH ( 2 * CHF_MAX_MESSAGE_LENGTH )
|
||||
#define CHF_DEF_MESSAGE_LENGTH 40
|
||||
#define CHF_DEF_PARTIAL_MSG_FMT ChfText( "Code <%d>d" )
|
||||
#define CHF_DEF_MID_MSG_FMT ChfText( "Mid <%d>d" )
|
||||
#define CHF_EXTENDED_INFO_FMT ChfText( "(%s,%d)" )
|
||||
#define CHF_SEVERITY_NAMES { ChfText( "S" ), ChfText( "I" ), ChfText( "W" ), ChfText( "E" ), ChfText( "F" ) }
|
||||
#define CHF_UNKNOWN_SEVERITY ChfText( "?" )
|
||||
#define CHF_MESSAGE_SEPARATOR ChfText( "-" )
|
||||
#define CHF_MESSAGE_TERMINATOR ChfText( "\n" )
|
||||
#define CHF_ABORT_HEADER ChfText( "ChfAbort-F-" )
|
||||
#define CHF_ABORT_BAD_CODE_FMT ChfText( "Bad abort code <%d>d\n" )
|
||||
#define CHF_ABORT_GOOD_CODE_FMT ChfText( "%s\n" )
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
Abort codes used with ChfAbort()
|
||||
|
@ -73,14 +78,14 @@
|
|||
typedef struct ChfHandlerDescriptor_S {
|
||||
ChfHandler handler;
|
||||
void* unwind_context;
|
||||
void* handler_context;
|
||||
ChfPointer handler_context;
|
||||
} ChfHandlerDescriptor;
|
||||
|
||||
/* CHF Context */
|
||||
typedef struct ChfContext_S {
|
||||
typedef struct ChfContext_S /* CHF Context */
|
||||
{
|
||||
ChfState state; /* Current CHF state */
|
||||
const char* app_name; /* Application's name */
|
||||
int options; /* Options */
|
||||
const ChfChar* app_name; /* Application's name */
|
||||
ChfOptions options; /* Options */
|
||||
void* mrs_data; /* Message retrieval private data */
|
||||
ChfMrsGet mrs_get; /* 'GetMessage' function */
|
||||
ChfMrsExit mrs_exit; /* 'Exit' function */
|
||||
|
@ -92,7 +97,7 @@ typedef struct ChfContext_S {
|
|||
ChfDescriptor* condition_sp; /* Current condition stack pointer */
|
||||
ChfHandlerDescriptor* handler_stack; /* Handler stack */
|
||||
ChfHandlerDescriptor* handler_sp; /* Current handler stack pointer */
|
||||
char* message_buffer; /* Message buffer */
|
||||
ChfChar* message_buffer; /* Message buffer */
|
||||
} ChfContext;
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
|
@ -117,24 +122,13 @@ extern ChfContext _chf_context; /* CHF Context */
|
|||
ChfContext* _ChfGetContext( void );
|
||||
#endif
|
||||
|
||||
/* Generic initialization */
|
||||
int ChfInit( const int module_id, const char* app_name, /* Application's name */
|
||||
const int options, /* Options */
|
||||
void* mrs_data, /* Message retrieval private data */
|
||||
ChfMrsGet mrs_get, /* 'GetMessage' function */
|
||||
ChfMrsExit mrs_exit, /* 'Exit' function */
|
||||
const int condition_stack_size, /* Size of the condition stack */
|
||||
const int handler_stack_size, /* Size of the handler stack */
|
||||
const int exit_code /* Abnormal exit code */
|
||||
);
|
||||
/* -------------------------------------------------------------------------
|
||||
Private redirection of stdlib functions needed by Win32
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
/* Abort application */
|
||||
void ChfAbort( const int abort_code );
|
||||
|
||||
/* Build a condition message */
|
||||
char* ChfBuildMessage( const ChfDescriptor* descriptor );
|
||||
|
||||
/* Retrieve a condition message */
|
||||
const char* ChfGetMessage( const int module_id, const int condition_code, const char* default_message );
|
||||
|
||||
#endif /*!_CHF_PRIV_H*/
|
||||
#define ChfStrlen strlen
|
||||
#define ChfStrcpy strcpy
|
||||
#define ChfStrcat strcat
|
||||
#define ChfStrncpy strncpy
|
||||
#define ChfSprintf sprintf
|
||||
#define ChfVsprintf vsprintf
|
|
@ -30,8 +30,14 @@
|
|||
|
||||
.- */
|
||||
|
||||
#ifndef lint
|
||||
static char rcs_id[] = "$Id: chf_abrt.c,v 2.2 2001/01/25 12:08:24 cibrario Exp $";
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <setjmp.h>
|
||||
|
||||
#include "Chf.h"
|
||||
#include "ChfPriv.h"
|
||||
|
@ -40,6 +46,23 @@
|
|||
# include <pthread.h>
|
||||
#endif
|
||||
|
||||
/* Abort codes message table; the relative position of the messages must
|
||||
match the numeric codes CHF_ABORT_xxxx defined in ChfPriv.h
|
||||
*/
|
||||
static const ChfChar* message_table[] = { ( const ChfChar* )NULL,
|
||||
ChfText( "Not initialized" ),
|
||||
ChfText( "Temporary message buffer overflow" ),
|
||||
ChfText( "Invalid action from last chance handler" ),
|
||||
ChfText( "Already initialized" ),
|
||||
ChfText( "Unwind request while unwinding" ),
|
||||
ChfText( "Improperly handled condition" ),
|
||||
ChfText( "Fatal condition while unwinding" ),
|
||||
ChfText( "Condition stack overflow" ),
|
||||
ChfText( "Can't prime a new Chf context" ),
|
||||
ChfText( "Pthread interaction failed" ) };
|
||||
|
||||
#define MESSAGE_TABLE_SIZE ( sizeof( message_table ) / sizeof( const ChfChar* ) )
|
||||
|
||||
/* .+
|
||||
|
||||
.title : ChfAbort
|
||||
|
@ -87,36 +110,22 @@
|
|||
- added Win32 support
|
||||
|
||||
.- */
|
||||
/* Abort application */
|
||||
void ChfAbort( const int abort_code )
|
||||
void ChfAbort( /* Abort application */
|
||||
const int abort_code )
|
||||
{
|
||||
|
||||
/* Abort codes message table; the relative position of the messages must
|
||||
match the numeric codes CHF_ABORT_xxxx defined in ChfPriv.h
|
||||
*/
|
||||
const char* message_table[] = { ( const char* )NULL,
|
||||
"Not initialized",
|
||||
"Temporary message buffer overflow",
|
||||
"Invalid action from last chance handler",
|
||||
"Already initialized",
|
||||
"Unwind request while unwinding",
|
||||
"Improperly handled condition",
|
||||
"Fatal condition while unwinding",
|
||||
"Condition stack overflow",
|
||||
"Can't prime a new Chf context",
|
||||
"Pthread interaction failed" };
|
||||
|
||||
if ( abort_code != CHF_ABORT_SILENT ) {
|
||||
fputs( "ChfAbort-F-", stderr );
|
||||
fputs( CHF_ABORT_HEADER, stderr );
|
||||
|
||||
if ( abort_code < 0 || abort_code >= ( int )MESSAGE_TABLE_SIZE )
|
||||
fprintf( stderr, CHF_ABORT_BAD_CODE_FMT, abort_code );
|
||||
|
||||
if ( abort_code < 0 || abort_code >= ( int )( sizeof( message_table ) / sizeof( const char* ) ) )
|
||||
fprintf( stderr, "Bad abort code <%d>d\n", abort_code );
|
||||
else
|
||||
fprintf( stderr, "%s\n", message_table[ abort_code ] );
|
||||
fprintf( stderr, CHF_ABORT_GOOD_CODE_FMT, message_table[ abort_code ] );
|
||||
}
|
||||
|
||||
if ( chf_context.state == CHF_UNKNOWN || chf_context.options & CHF_ABORT )
|
||||
abort();
|
||||
|
||||
else
|
||||
#ifndef _REENTRANT
|
||||
exit( chf_context.exit_code );
|
|
@ -24,7 +24,14 @@
|
|||
|
||||
.- */
|
||||
|
||||
#ifndef lint
|
||||
static char rcs_id[] = "$Id: chf_gen.c,v 2.2 2001/01/25 12:10:22 cibrario Exp $";
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <setjmp.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
|
||||
|
@ -76,9 +83,9 @@
|
|||
1.1, 3-May-1996, creation
|
||||
|
||||
.- */
|
||||
/* Generate a condition into the stack */
|
||||
void ChfGenerate( const int module_id, const char* file_name, const int line_number, const int condition_code, const ChfSeverity severity,
|
||||
... )
|
||||
void ChfGenerate( /* Generate a condition into the stack */
|
||||
const int module_id, const ChfChar* file_name, const int line_number, const int condition_code,
|
||||
const ChfSeverity severity, ... )
|
||||
{
|
||||
ChfDescriptor* new_descriptor;
|
||||
va_list aux_arg;
|
||||
|
@ -97,25 +104,30 @@ void ChfGenerate( const int module_id, const char* file_name, const int line_num
|
|||
otherwise abort the application.
|
||||
*/
|
||||
if ( new_descriptor - chf_context.condition_stack == chf_context.condition_stack_size ) {
|
||||
new_descriptor->module_id = module_id;
|
||||
new_descriptor->module_id = CHF_MODULE_ID;
|
||||
new_descriptor->condition_code = CHF_F_COND_STACK_FULL;
|
||||
new_descriptor->severity = CHF_FATAL;
|
||||
new_descriptor->line_number = CHF_UNKNOWN_LINE_NUMBER;
|
||||
new_descriptor->file_name = CHF_UNKNOWN_FILE_NAME;
|
||||
|
||||
strncpy( new_descriptor->message, ChfGetMessage( module_id, CHF_F_COND_STACK_FULL, "Condition stack is full" ),
|
||||
CHF_MAX_MESSAGE_LENGTH - 1 );
|
||||
ChfStrncpy( new_descriptor->message,
|
||||
ChfGetMessage( CHF_MODULE_ID, CHF_F_COND_STACK_FULL, ChfText( "Condition stack is full" ) ),
|
||||
CHF_MAX_MESSAGE_LENGTH - 1 );
|
||||
new_descriptor->message[ CHF_MAX_MESSAGE_LENGTH - 1 ] = '\0';
|
||||
|
||||
new_descriptor->next = CHF_NULL_DESCRIPTOR;
|
||||
chf_context.condition_sp++;
|
||||
|
||||
ChfSignal( module_id );
|
||||
} else
|
||||
ChfSignal();
|
||||
}
|
||||
|
||||
else
|
||||
ChfAbort( CHF_ABORT_COND_STACK_OVF );
|
||||
} else {
|
||||
char def_message[ CHF_DEF_MESSAGE_LENGTH ];
|
||||
char tmp_message[ CHF_TMP_MESSAGE_LENGTH ];
|
||||
}
|
||||
|
||||
else {
|
||||
ChfChar def_message[ CHF_DEF_MESSAGE_LENGTH ];
|
||||
ChfChar tmp_message[ CHF_TMP_MESSAGE_LENGTH ];
|
||||
|
||||
new_descriptor->module_id = module_id;
|
||||
new_descriptor->condition_code = condition_code;
|
||||
|
@ -124,16 +136,16 @@ void ChfGenerate( const int module_id, const char* file_name, const int line_num
|
|||
new_descriptor->file_name = file_name;
|
||||
|
||||
/* Generate the default message */
|
||||
sprintf( def_message, "Code <%d>d", condition_code );
|
||||
ChfSprintf( def_message, CHF_DEF_PARTIAL_MSG_FMT, condition_code );
|
||||
|
||||
/* Generate the partial message associated with the condition using a
|
||||
temporary area
|
||||
*/
|
||||
if ( vsprintf( tmp_message, ChfGetMessage( module_id, condition_code, def_message ), aux_arg ) >= CHF_TMP_MESSAGE_LENGTH )
|
||||
if ( ChfVsprintf( tmp_message, ChfGetMessage( module_id, condition_code, def_message ), aux_arg ) >= CHF_TMP_MESSAGE_LENGTH )
|
||||
ChfAbort( CHF_ABORT_MSG_OVF );
|
||||
|
||||
/* Copy the message into the condition descriptor */
|
||||
strncpy( new_descriptor->message, tmp_message, CHF_MAX_MESSAGE_LENGTH - 1 );
|
||||
ChfStrncpy( new_descriptor->message, tmp_message, CHF_MAX_MESSAGE_LENGTH - 1 );
|
||||
new_descriptor->message[ CHF_MAX_MESSAGE_LENGTH - 1 ] = '\0';
|
||||
|
||||
/* Link the new descriptor with the current descriptor list, if it
|
|
@ -37,6 +37,15 @@
|
|||
|
||||
.- */
|
||||
|
||||
#ifndef lint
|
||||
static char rcs_id[] = "$Id: chf_hdlr.c,v 2.2 2001/01/25 12:12:46 cibrario Exp $";
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <setjmp.h>
|
||||
|
||||
#include "Chf.h"
|
||||
#include "ChfPriv.h"
|
||||
|
||||
|
@ -73,12 +82,12 @@
|
|||
2.1, 19-May-2000, creation
|
||||
|
||||
.- */
|
||||
static ChfAction StructuredHelper( const ChfDescriptor* desc, const ChfState state, void* handler_context )
|
||||
static ChfAction StructuredHelper( const ChfDescriptor* desc, const ChfState state, ChfPointer handler_context )
|
||||
{
|
||||
ChfAction action;
|
||||
const ChfDescriptor* d;
|
||||
|
||||
return ( ( state == CHF_SIGNALING && desc->severity == CHF_FATAL ) ? CHF_UNWIND_KEEP : CHF_RESIGNAL );
|
||||
return ( ( state == CHF_SIGNALING && ChfGetSeverity( desc ) == CHF_FATAL ) ? CHF_UNWIND_KEEP : CHF_RESIGNAL );
|
||||
}
|
||||
|
||||
/* .+
|
||||
|
@ -123,7 +132,7 @@ static ChfAction StructuredHelper( const ChfDescriptor* desc, const ChfState sta
|
|||
.input :
|
||||
ChfHandler new_handler, new condition handler
|
||||
void *unwind_context, handler unwind context pointer
|
||||
void* handler_context, private handler context pointer
|
||||
ChfPointer handler_context, private handler context pointer
|
||||
.output :
|
||||
void
|
||||
.status_codes :
|
||||
|
@ -139,25 +148,89 @@ static ChfAction StructuredHelper( const ChfDescriptor* desc, const ChfState sta
|
|||
- added StructuredHelper handling
|
||||
|
||||
.- */
|
||||
/* Push a new handler into the stack */
|
||||
void ChfPushHandler( const int module_id, ChfHandler new_handler, void* unwind_context, void* handler_context )
|
||||
void ChfPushHandler( /* Push a new handler into the stack */
|
||||
ChfHandler new_handler, void* unwind_context, ChfPointer handler_context )
|
||||
{
|
||||
/* Make sure that CHF has been correctly initialized and is idle */
|
||||
if ( chf_context.state == CHF_UNKNOWN )
|
||||
ChfAbort( CHF_ABORT_INIT );
|
||||
|
||||
if ( chf_context.state != CHF_IDLE ) {
|
||||
ChfGenerate( module_id, __FILE__, __LINE__, CHF_F_BAD_STATE, CHF_FATAL );
|
||||
ChfSignal( module_id );
|
||||
} else
|
||||
/* Check if the handler stack is full */
|
||||
if ( chf_context.handler_sp - chf_context.handler_stack >= chf_context.handler_stack_size ) {
|
||||
ChfGenerate( module_id, __FILE__, __LINE__, CHF_F_HDLR_STACK_FULL, CHF_FATAL );
|
||||
ChfSignal( module_id );
|
||||
} else {
|
||||
chf_context.handler_sp->unwind_context = unwind_context;
|
||||
chf_context.handler_sp->handler_context = handler_context;
|
||||
chf_context.handler_sp->handler = ( ( new_handler == CHF_NULL_HANDLER ) ? StructuredHelper : new_handler );
|
||||
chf_context.handler_sp++;
|
||||
}
|
||||
ChfCondition CHF_F_BAD_STATE, CHF_FATAL ChfEnd;
|
||||
|
||||
ChfSignal();
|
||||
}
|
||||
|
||||
/* Check if the handler stack is full */
|
||||
else if ( chf_context.handler_sp - chf_context.handler_stack >= chf_context.handler_stack_size ) {
|
||||
ChfCondition CHF_F_HDLR_STACK_FULL, CHF_FATAL ChfEnd;
|
||||
|
||||
ChfSignal();
|
||||
}
|
||||
|
||||
else {
|
||||
chf_context.handler_sp->unwind_context = unwind_context;
|
||||
chf_context.handler_sp->handler_context = handler_context;
|
||||
chf_context.handler_sp->handler = ( ( new_handler == CHF_NULL_HANDLER ) ? StructuredHelper : new_handler );
|
||||
chf_context.handler_sp++;
|
||||
}
|
||||
}
|
||||
|
||||
/* .+
|
||||
|
||||
.title : ChfPopHandler
|
||||
.kind : C function
|
||||
.creation : 13-May-1996
|
||||
.description :
|
||||
This function pops the topmost condition handler from the handler stack and
|
||||
returns to the caller.
|
||||
|
||||
If some error occours during the execution, the function will generate
|
||||
and immediately signal one of the conditions listed below and marked with
|
||||
(*). The function will never return directly to the caller, since all
|
||||
conditions are CHF_FATAL.
|
||||
|
||||
NOTE: This function calls ChfAbort() with abort code CHF_ABORT_INIT if
|
||||
the CHF subsystem has not been initialized.
|
||||
|
||||
.call :
|
||||
ChfPopHandler();
|
||||
.input :
|
||||
void
|
||||
.output :
|
||||
void
|
||||
.status_codes :
|
||||
CHF_F_BAD_STATE, bad CHF state for requested operation
|
||||
CHF_F_HDLR_STACK_FULL, the handler stack is full
|
||||
.notes :
|
||||
1.1, 13-May-1996, creation
|
||||
1.6, 15-Jan-1997, update:
|
||||
- improved documentation
|
||||
2.1, 19-May-2000, update:
|
||||
- improved documentation
|
||||
|
||||
.- */
|
||||
void ChfPopHandler( /* Pop a handler */
|
||||
void )
|
||||
{
|
||||
/* Make sure that CHF has been correctly initialized and is idle */
|
||||
if ( chf_context.state == CHF_UNKNOWN )
|
||||
ChfAbort( CHF_ABORT_INIT );
|
||||
|
||||
if ( chf_context.state != CHF_IDLE ) {
|
||||
ChfCondition CHF_F_BAD_STATE, CHF_FATAL ChfEnd;
|
||||
|
||||
ChfSignal();
|
||||
}
|
||||
|
||||
/* Check if the handler stack is empty */
|
||||
else if ( chf_context.handler_sp == chf_context.handler_stack ) {
|
||||
ChfCondition CHF_F_HDLR_STACK_EMPTY, CHF_FATAL ChfEnd;
|
||||
|
||||
ChfSignal();
|
||||
}
|
||||
|
||||
/* Discard the topmost condition handler */
|
||||
else
|
||||
--chf_context.handler_sp;
|
||||
}
|
|
@ -47,8 +47,14 @@
|
|||
|
||||
.- */
|
||||
|
||||
#ifndef lint
|
||||
static char rcs_id[] = "$Id: chf_init.c,v 2.2 2001/01/25 14:05:23 cibrario Exp $";
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <setjmp.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "Chf.h"
|
||||
|
@ -58,12 +64,17 @@
|
|||
Global and static variables
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
/* Chf Library Id */
|
||||
#ifndef lint
|
||||
static ChfChar rcs_lib_id[] = CHF_LIBRARY_ID;
|
||||
#endif
|
||||
|
||||
/* CHF context */
|
||||
ChfContext _chf_context;
|
||||
|
||||
/* Message separator and severity names for ChfBuildMessage() */
|
||||
static const char separator[] = "-";
|
||||
static const char* severity_name[] = { "S", "I", "W", "E", "F" };
|
||||
static const ChfChar separator[] = CHF_MESSAGE_SEPARATOR;
|
||||
static const ChfChar* severity_name[] = CHF_SEVERITY_NAMES;
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
Multithreading support
|
||||
|
@ -148,7 +159,7 @@ static void DestroyContext( void* context )
|
|||
- added Win32 support
|
||||
|
||||
.- */
|
||||
static ChfAction DefaultHandler( const ChfDescriptor* desc, const ChfState state, void* handler_context )
|
||||
static ChfAction DefaultHandler( const ChfDescriptor* desc, const ChfState state, ChfPointer handler_context )
|
||||
{
|
||||
ChfAction action;
|
||||
const ChfDescriptor* d;
|
||||
|
@ -162,12 +173,12 @@ static ChfAction DefaultHandler( const ChfDescriptor* desc, const ChfState state
|
|||
is done atomically if multithreading support is enabled.
|
||||
In Win32, the default handler does not print anything.
|
||||
*/
|
||||
if ( desc->severity > CHF_SUCCESS ) {
|
||||
if ( ChfGetSeverity( desc ) > CHF_SUCCESS ) {
|
||||
#ifdef _REENTRANT
|
||||
if ( pthread_mutex_lock( &fputs_mutex ) )
|
||||
ChfAbort( CHF_ABORT_PTHREAD );
|
||||
#endif
|
||||
for ( d = desc; d != CHF_NULL_DESCRIPTOR; d = d->next )
|
||||
for ( d = desc; d != CHF_NULL_DESCRIPTOR; d = ChfGetNextDescriptor( d ) )
|
||||
fputs( ChfBuildMessage( d ), stderr );
|
||||
#ifdef _REENTRANT
|
||||
if ( pthread_mutex_unlock( &fputs_mutex ) )
|
||||
|
@ -176,7 +187,7 @@ static ChfAction DefaultHandler( const ChfDescriptor* desc, const ChfState state
|
|||
}
|
||||
|
||||
/* Determine the handler action */
|
||||
switch ( desc->severity ) {
|
||||
switch ( ChfGetSeverity( desc ) ) {
|
||||
case CHF_SUCCESS:
|
||||
case CHF_INFO:
|
||||
case CHF_WARNING:
|
||||
|
@ -226,18 +237,18 @@ static ChfAction DefaultHandler( const ChfDescriptor* desc, const ChfState state
|
|||
1.1, 16-May-1996, creation
|
||||
|
||||
.- */
|
||||
static char* scopy( char* p, const char* q, char* p_end )
|
||||
static ChfChar* scopy( ChfChar* p, const ChfChar* q, ChfChar* p_end )
|
||||
{
|
||||
size_t q_len = strlen( q );
|
||||
size_t q_len = ChfStrlen( q );
|
||||
size_t p_avail = p_end - p;
|
||||
|
||||
if ( q_len < p_avail ) {
|
||||
strcpy( p, q );
|
||||
ChfStrcpy( p, q );
|
||||
p += q_len;
|
||||
}
|
||||
|
||||
else if ( p_avail > 1 ) {
|
||||
strncpy( p, q, p_avail - 2 );
|
||||
ChfStrncpy( p, q, p_avail - 2 );
|
||||
p[ p_avail - 1 ] = '\0';
|
||||
p = p_end;
|
||||
}
|
||||
|
@ -289,10 +300,10 @@ static char* scopy( char* p, const char* q, char* p_end )
|
|||
- added Win32 support
|
||||
|
||||
.- */
|
||||
/* Retrieve a condition message */
|
||||
const char* ChfGetMessage( const int module_id, const int condition_code, const char* default_message )
|
||||
const ChfChar* ChfGetMessage( /* Retrieve a condition message */
|
||||
const int module_id, const int condition_code, const ChfChar* default_message )
|
||||
{
|
||||
const char* message;
|
||||
const ChfChar* message;
|
||||
|
||||
/* Check that CHF has been correctly initialized */
|
||||
if ( chf_context.state == CHF_UNKNOWN )
|
||||
|
@ -339,12 +350,12 @@ const char* ChfGetMessage( const int module_id, const int condition_code, const
|
|||
- added Win32 support
|
||||
|
||||
.- */
|
||||
/* Build a condition message */
|
||||
char* ChfBuildMessage( const ChfDescriptor* descriptor )
|
||||
ChfChar* ChfBuildMessage( /* Build a condition message */
|
||||
const ChfDescriptor* descriptor )
|
||||
{
|
||||
char* tmp_p;
|
||||
char* tmp_end;
|
||||
char def_message[ CHF_DEF_MESSAGE_LENGTH ];
|
||||
ChfChar* tmp_p;
|
||||
ChfChar* tmp_end;
|
||||
ChfChar def_message[ CHF_DEF_MESSAGE_LENGTH ];
|
||||
ChfSeverity severity;
|
||||
|
||||
/* Check that CHF has been correctly initialized */
|
||||
|
@ -364,18 +375,18 @@ char* ChfBuildMessage( const ChfDescriptor* descriptor )
|
|||
}
|
||||
|
||||
else
|
||||
tmp_p = scopy( tmp_p, "\t", tmp_end );
|
||||
tmp_p = scopy( tmp_p, ChfText( "\t" ), tmp_end );
|
||||
|
||||
/* The message continues with the module name */
|
||||
sprintf( def_message, "Mid <%d>d", descriptor->module_id );
|
||||
ChfSprintf( def_message, CHF_DEF_MID_MSG_FMT, ChfGetModuleId( descriptor ) );
|
||||
|
||||
tmp_p = scopy( tmp_p, ChfGetMessage( CHF_MODULE_NAMES_SET, descriptor->module_id, def_message ), tmp_end );
|
||||
tmp_p = scopy( tmp_p, ChfGetMessage( CHF_MODULE_NAMES_SET, ChfGetModuleId( descriptor ), def_message ), tmp_end );
|
||||
|
||||
/* Add also the extended information, if any */
|
||||
if ( descriptor->line_number != CHF_UNKNOWN_LINE_NUMBER ) {
|
||||
tmp_p = scopy( tmp_p, " ", tmp_end );
|
||||
if ( ChfGetLineNumber( descriptor ) != CHF_UNKNOWN_LINE_NUMBER ) {
|
||||
tmp_p = scopy( tmp_p, ChfText( " " ), tmp_end );
|
||||
|
||||
sprintf( def_message, "(%s:%i)", descriptor->file_name, descriptor->line_number );
|
||||
ChfSprintf( def_message, CHF_EXTENDED_INFO_FMT, ChfGetFileName( descriptor ), ChfGetLineNumber( descriptor ) );
|
||||
|
||||
tmp_p = scopy( tmp_p, def_message, tmp_end );
|
||||
}
|
||||
|
@ -383,14 +394,16 @@ char* ChfBuildMessage( const ChfDescriptor* descriptor )
|
|||
tmp_p = scopy( tmp_p, separator, tmp_end );
|
||||
|
||||
/* Add the severity code of the message */
|
||||
tmp_p = scopy( tmp_p, ( ( severity = descriptor->severity ) < CHF_SUCCESS || severity > CHF_FATAL ) ? "?" : severity_name[ severity ],
|
||||
tmp_p = scopy( tmp_p,
|
||||
( ( severity = ChfGetSeverity( descriptor ) ) < CHF_SUCCESS || severity > CHF_FATAL ) ? CHF_UNKNOWN_SEVERITY
|
||||
: severity_name[ severity ],
|
||||
tmp_end );
|
||||
|
||||
tmp_p = scopy( tmp_p, separator, tmp_end );
|
||||
|
||||
/* The message ends with the partial message from the descriptor */
|
||||
tmp_p = scopy( tmp_p, descriptor->message, tmp_end );
|
||||
( void )scopy( tmp_p, "\n", tmp_end );
|
||||
tmp_p = scopy( tmp_p, ChfGetPartialMessage( descriptor ), tmp_end );
|
||||
( void )scopy( tmp_p, CHF_MESSAGE_TERMINATOR, tmp_end );
|
||||
|
||||
return chf_context.message_buffer;
|
||||
}
|
||||
|
@ -421,7 +434,7 @@ char* ChfBuildMessage( const ChfDescriptor* descriptor )
|
|||
exit_code);
|
||||
.input :
|
||||
const char *app_name, Application's name
|
||||
const int options, Options
|
||||
const ChfOptions options, Options
|
||||
void *mrs_data, Message retrieval private data
|
||||
ChfMrsGet mrs_get, 'GetMessage' function
|
||||
ChfMrsExit mrs_exit, 'Exit' function
|
||||
|
@ -442,15 +455,15 @@ char* ChfBuildMessage( const ChfDescriptor* descriptor )
|
|||
- added Win32 support; a malloc() call was not portable.
|
||||
|
||||
.- */
|
||||
/* Generic initialization */
|
||||
int ChfInit( const int module_id, const char* app_name, /* Application's name */
|
||||
const int options, /* Options */
|
||||
void* mrs_data, /* Message retrieval private data */
|
||||
ChfMrsGet mrs_get, /* 'GetMessage' function */
|
||||
ChfMrsExit mrs_exit, /* 'Exit' function */
|
||||
const int condition_stack_size, /* Size of the condition stack */
|
||||
const int handler_stack_size, /* Size of the handler stack */
|
||||
const int exit_code /* Abnormal exit code */
|
||||
int ChfInit( /* Generic initialization */
|
||||
const ChfChar* app_name, /* Application's name */
|
||||
const ChfOptions options, /* Options */
|
||||
void* mrs_data, /* Message retrieval private data */
|
||||
ChfMrsGet mrs_get, /* 'GetMessage' function */
|
||||
ChfMrsExit mrs_exit, /* 'Exit' function */
|
||||
const int condition_stack_size, /* Size of the condition stack */
|
||||
const int handler_stack_size, /* Size of the handler stack */
|
||||
const int exit_code /* Abnormal exit code */
|
||||
)
|
||||
{
|
||||
int cc;
|
||||
|
@ -481,8 +494,8 @@ int ChfInit( const int module_id, const char* app_name, /* Application's name */
|
|||
cc = CHF_F_MALLOC;
|
||||
}
|
||||
|
||||
else if ( ( _chf_context.message_buffer = ( char* )malloc( ( size_t )( CHF_MAX_MESSAGE_LENGTH ) * sizeof( char ) ) ) ==
|
||||
( char* )NULL ) {
|
||||
else if ( ( _chf_context.message_buffer = ( ChfChar* )malloc( ( size_t )( CHF_MAX_MESSAGE_LENGTH ) * sizeof( ChfChar ) ) ) ==
|
||||
( ChfChar* )NULL ) {
|
||||
free( _chf_context.condition_stack );
|
||||
free( _chf_context.handler_stack );
|
||||
cc = CHF_F_MALLOC;
|
||||
|
@ -520,7 +533,7 @@ int ChfInit( const int module_id, const char* app_name, /* Application's name */
|
|||
/* Push the default handler; in the reentrant case, this will be
|
||||
done once per thread, when the thread-specific context is primed.
|
||||
*/
|
||||
ChfPushHandler( module_id, DefaultHandler, CHF_NULL_CONTEXT, CHF_NULL_POINTER );
|
||||
ChfPushHandler( DefaultHandler, CHF_NULL_CONTEXT, CHF_NULL_POINTER );
|
||||
#endif
|
||||
|
||||
cc = CHF_S_OK;
|
||||
|
@ -582,15 +595,15 @@ void ChfExit( void )
|
|||
}
|
||||
#endif
|
||||
|
||||
/* Destroy the context associated with this thread now; this is necessary
|
||||
to ensure that the context is actually destroyed when a single-threaded
|
||||
application links with the multithreaded version of Chf: in this case,
|
||||
pthread_exit() is called *after* ChfExit(), the Chf data key no longer
|
||||
exists when pthread_exit() is called and the destructor registered
|
||||
with pthread_key_create() does not take place.
|
||||
The data pointer associated with the Chf data key is set to NULL to
|
||||
avoid any subsequent reactivation of the destructor.
|
||||
*/
|
||||
/* Destroy the context associated with this thread now; this is necessary
|
||||
to ensure that the context is actually destroyed when a single-threaded
|
||||
application links with the multithreaded version of Chf: in this case,
|
||||
pthread_exit() is called *after* ChfExit(), the Chf data key no longer
|
||||
exists when pthread_exit() is called and the destructor registered
|
||||
with pthread_key_create() does not take place.
|
||||
The data pointer associated with the Chf data key is set to NULL to
|
||||
avoid any subsequent reactivation of the destructor.
|
||||
*/
|
||||
#ifdef _REENTRANT
|
||||
DestroyContext( &chf_context );
|
||||
if ( pthread_setspecific( data_key, ( void* )NULL ) ) {
|
||||
|
@ -694,7 +707,7 @@ ChfContext* _ChfGetContext( void )
|
|||
ChfAbort( CHF_ABORT_GET_CONTEXT );
|
||||
|
||||
/* Push the default handler */
|
||||
ChfPushHandler( module_id, DefaultHandler, CHF_NULL_CONTEXT, CHF_NULL_POINTER );
|
||||
ChfPushHandler( DefaultHandler, CHF_NULL_CONTEXT, CHF_NULL_POINTER );
|
||||
}
|
||||
|
||||
return context;
|
151
libChf/src/chf_msgc.c
Normal file
151
libChf/src/chf_msgc.c
Normal file
|
@ -0,0 +1,151 @@
|
|||
/* .+
|
||||
|
||||
.identifier : $Id: chf_msgc.c,v 2.2 2001/01/25 14:06:47 cibrario Exp $
|
||||
.context : CHF, Condition Handling Facility
|
||||
.title : $RCSfile: chf_msgc.c,v $, condition generation
|
||||
.kind : C source
|
||||
.author : Ivan Cibrario B.
|
||||
.site : CSTV-CNR
|
||||
.creation : 17-May-1996
|
||||
.keywords : *
|
||||
.description :
|
||||
This module contains the CHF initialization function ChfMsgcatInit()
|
||||
|
||||
.include : Chf.h
|
||||
|
||||
.notes :
|
||||
$Log: chf_msgc.c,v $
|
||||
Revision 2.2 2001/01/25 14:06:47 cibrario
|
||||
Added partial Win32 support (Windows CE only).
|
||||
|
||||
Revision 1.3 1996/06/21 14:19:22 cibrario
|
||||
Bug fix: the private context of the message retrieval facility was
|
||||
never freed by ExitMessage()
|
||||
|
||||
Revision 1.1 1996/05/28 12:55:15 cibrario
|
||||
Initial revision
|
||||
|
||||
|
||||
.- */
|
||||
|
||||
#ifndef lint
|
||||
static char rcs_id[] = "$Id: chf_msgc.c,v 2.2 2001/01/25 14:06:47 cibrario Exp $";
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <setjmp.h>
|
||||
#include <string.h>
|
||||
#include <locale.h>
|
||||
#include <nl_types.h>
|
||||
|
||||
#include "Chf.h"
|
||||
#include "ChfPriv.h"
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
Global and static variables
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
Private type definitions
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
typedef struct {
|
||||
nl_catd catalog; /* Message catalog descriptor */
|
||||
} ChfMsgcatContext;
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
Private functions
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
static const char* GetMessage( void* private_context, const int module_id, const int condition_code, const char* default_message )
|
||||
{
|
||||
return ( catgets( ( ( ChfMsgcatContext* )private_context )->catalog, module_id, condition_code, default_message ) );
|
||||
}
|
||||
|
||||
static void ExitMessage( void* private_context )
|
||||
{
|
||||
( void )catclose( ( ( ChfMsgcatContext* )private_context )->catalog );
|
||||
free( private_context );
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
Public functions
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
/* .+
|
||||
|
||||
.title : ChfMsgcatInit
|
||||
.kind : C function
|
||||
.creation : 17-May-1996
|
||||
.description :
|
||||
This function initializes CHF and returns to the caller a condition code;
|
||||
that code will be either CHF_S_OK if the initialization was succesful,
|
||||
or one of the other values listed below.
|
||||
|
||||
It's necessary to invoke succesfully either ChfMsgcatInit() or one of the
|
||||
other CHF initialization routines before using any other CHF function.
|
||||
|
||||
NOTE: This function will call ChfAbort() with abort code CHF_ABORT_DUP_INIT
|
||||
if CHF has already been initialized before.
|
||||
|
||||
WIN32:
|
||||
|
||||
- this function is not available due to lack of system support, and
|
||||
always returns CHF_F_NOT_AVAILABLE
|
||||
|
||||
.call :
|
||||
cc = ChfMsgcatInit(app_name, options,
|
||||
msgcat_name,
|
||||
condition_stack_size, handler_stack_size,
|
||||
exit_code);
|
||||
.input :
|
||||
const char *app_name, Application's name
|
||||
const ChfOptions options, Options
|
||||
const char *msgcat_name, Name of the message catalog
|
||||
const int condition_stack_size, Size of the condition stack
|
||||
const int handler_stack_size, Size of the handler stack
|
||||
const int exit_code, Abnormal exit code
|
||||
.output :
|
||||
int cc, condition code
|
||||
.status_codes :
|
||||
CHF_F_SETLOCALE, setlocale() failed
|
||||
CHF_F_CATOPEN, catopen() failed
|
||||
CHF_F_MALLOC, FATAL, memory allocation failed
|
||||
CHF_F_NOT_AVAILABLE, FATAL, function not available
|
||||
.notes :
|
||||
1.1, 17-May-1996, creation
|
||||
2.2, 22-Jan-2001, update:
|
||||
- added Win32 support
|
||||
|
||||
.- */
|
||||
int ChfMsgcatInit( /* Initialization with msgcat subsystem */
|
||||
const ChfChar* app_name, /* Application's name */
|
||||
const ChfOptions options, /* Options */
|
||||
const ChfChar* msgcat_name, /* Name of the message catalog */
|
||||
const int condition_stack_size, /* Size of the condition stack */
|
||||
const int handler_stack_size, /* Size of the handler stack */
|
||||
const int exit_code /* Abnormal exit code */
|
||||
)
|
||||
{
|
||||
ChfMsgcatContext* private_context;
|
||||
int cc;
|
||||
|
||||
if ( ( private_context = ( ChfMsgcatContext* )malloc( sizeof( ChfMsgcatContext ) ) ) == ( ChfMsgcatContext* )NULL )
|
||||
cc = CHF_F_MALLOC;
|
||||
else if ( setlocale( LC_ALL, "" ) == ( char* )NULL ) {
|
||||
free( private_context );
|
||||
cc = CHF_F_SETLOCALE;
|
||||
} else if ( ( private_context->catalog = catopen( msgcat_name, 0 ) ) == ( nl_catd )( -1 ) ) {
|
||||
free( private_context );
|
||||
cc = CHF_F_CATOPEN;
|
||||
} else if ( ( cc = ChfInit( app_name, options, ( void* )private_context, GetMessage, ExitMessage, condition_stack_size,
|
||||
handler_stack_size, exit_code ) ) != CHF_S_OK ) {
|
||||
( void )catclose( private_context->catalog );
|
||||
free( private_context );
|
||||
} else
|
||||
cc = CHF_S_OK;
|
||||
|
||||
return cc;
|
||||
}
|
|
@ -37,6 +37,13 @@
|
|||
|
||||
.- */
|
||||
|
||||
#ifndef lint
|
||||
static char rcs_id[] = "$Id: chf_sig.c,v 2.2 2001/01/25 14:07:42 cibrario Exp $";
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <setjmp.h>
|
||||
|
||||
#include "Chf.h"
|
||||
|
@ -84,7 +91,7 @@
|
|||
- added support for structured condition handling
|
||||
|
||||
.- */
|
||||
void ChfSignal( const int module_id )
|
||||
void ChfSignal( void )
|
||||
{
|
||||
ChfState saved_state;
|
||||
ChfDescriptor* saved_condition_base;
|
||||
|
@ -162,21 +169,23 @@ void ChfSignal( const int module_id )
|
|||
if ( chf_context.condition_sp > chf_context.condition_base ) {
|
||||
if ( chf_context.state == CHF_SIGNALING ) {
|
||||
/* Force the new severity to CHF_FATAL if necessary */
|
||||
if ( current_condition->severity == CHF_FATAL )
|
||||
( chf_context.condition_sp - 1 )->severity = CHF_FATAL;
|
||||
if ( ChfGetSeverity( current_condition ) == CHF_FATAL )
|
||||
ChfGetSeverity( chf_context.condition_sp - 1 ) = CHF_FATAL;
|
||||
|
||||
/* Link together the condition groups */
|
||||
chf_context.condition_base->next = current_condition;
|
||||
current_condition = chf_context.condition_sp - 1;
|
||||
chf_context.condition_base = chf_context.condition_sp;
|
||||
} else
|
||||
}
|
||||
|
||||
else
|
||||
chf_context.condition_sp = chf_context.condition_base;
|
||||
}
|
||||
|
||||
/* The action CHF_CONTINUE is not allowed if the current condition
|
||||
severity is CHF_FATAL; it's automatically changed to CHF_RESIGNAL
|
||||
*/
|
||||
if ( handler_result == CHF_CONTINUE && current_condition->severity == CHF_FATAL )
|
||||
if ( handler_result == CHF_CONTINUE && ChfGetSeverity( current_condition ) == CHF_FATAL )
|
||||
handler_result = CHF_RESIGNAL;
|
||||
}
|
||||
|
||||
|
@ -285,7 +294,7 @@ void ChfSignal( const int module_id )
|
|||
if ( unwind_handler->unwind_context == CHF_NULL_CONTEXT )
|
||||
ChfAbort( CHF_ABORT_SILENT );
|
||||
else
|
||||
siglongjmp( unwind_handler->unwind_context, 1 );
|
||||
ChfSiglongjmp( unwind_handler->unwind_context, 1 );
|
||||
}
|
||||
|
||||
break;
|
||||
|
@ -305,10 +314,12 @@ void ChfSignal( const int module_id )
|
|||
otherwise call ChfAbort()
|
||||
*/
|
||||
if ( chf_context.handler_sp > chf_context.handler_stack ) {
|
||||
ChfGenerate( module_id, __FILE__, __LINE__, CHF_F_INVALID_ACTION, CHF_FATAL, handler_result );
|
||||
ChfCondition CHF_F_INVALID_ACTION, CHF_FATAL, handler_result ChfEnd;
|
||||
|
||||
ChfSignal( module_id );
|
||||
} else
|
||||
ChfSignal();
|
||||
}
|
||||
|
||||
else
|
||||
ChfAbort( CHF_ABORT_INVALID_ACTION );
|
||||
|
||||
break;
|
||||
|
@ -319,3 +330,42 @@ void ChfSignal( const int module_id )
|
|||
/* Restore the old CHF state */
|
||||
chf_context.state = saved_state;
|
||||
}
|
||||
|
||||
/* .+
|
||||
|
||||
.title : ChfDiscard
|
||||
.kind : C function
|
||||
.creation : 17-May-1996
|
||||
.description :
|
||||
This function discards the topmost condition group currently in the
|
||||
condition stack, without signalling it. The function does nothing if
|
||||
the condition stack is empty.
|
||||
|
||||
NOTE: This function uses the CHF function 'ChfAbort()' to
|
||||
abort the application if either
|
||||
- CHF has not been initialized correctly (abort code CHF_ABORT_INIT)
|
||||
|
||||
.call :
|
||||
ChfDiscard();
|
||||
.input :
|
||||
void
|
||||
.output :
|
||||
void
|
||||
.status_codes :
|
||||
none
|
||||
.notes :
|
||||
1.1, 17-May-1996, creation
|
||||
|
||||
.- */
|
||||
void ChfDiscard( /* Discard the current conditions */
|
||||
void )
|
||||
{
|
||||
/* Check that CHF has been correctly initialized */
|
||||
if ( chf_context.state == CHF_UNKNOWN )
|
||||
ChfAbort( CHF_ABORT_INIT );
|
||||
|
||||
/* Reset the current condition stack pointer to the current condition
|
||||
stack base pointer
|
||||
*/
|
||||
chf_context.condition_sp = chf_context.condition_base;
|
||||
}
|
|
@ -24,13 +24,23 @@
|
|||
|
||||
.- */
|
||||
|
||||
#ifndef lint
|
||||
static char rcs_id[] = "$Id: chf_st.c,v 2.2 2001/01/25 14:08:45 cibrario Exp $";
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <setjmp.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "Chf.h"
|
||||
#include "ChfPriv.h"
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
Global and static variables
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
Private type definitions
|
||||
------------------------------------------------------------------------- */
|
||||
|
@ -52,17 +62,20 @@ static int Search( const void* l, const void* r )
|
|||
{
|
||||
if ( ( ( ChfTable* )l )->module > ( ( ChfTable* )r )->module )
|
||||
return ( GT );
|
||||
|
||||
else if ( ( ( ChfTable* )l )->module < ( ( ChfTable* )r )->module )
|
||||
return ( LT );
|
||||
|
||||
else if ( ( ( ChfTable* )l )->code > ( ( ChfTable* )r )->code )
|
||||
return ( GT );
|
||||
|
||||
else if ( ( ( ChfTable* )l )->code < ( ( ChfTable* )r )->code )
|
||||
return ( LT );
|
||||
|
||||
return ( EQ );
|
||||
}
|
||||
|
||||
static const char* StGetMessage( void* private_context, const int module_id, const int condition_code, const char* default_message )
|
||||
static const ChfChar* StGetMessage( void* private_context, const int module_id, const int condition_code, const ChfChar* default_message )
|
||||
{
|
||||
ChfTable key;
|
||||
ChfTable* res;
|
||||
|
@ -106,7 +119,7 @@ static void ExitMessage( void* private_context ) {}
|
|||
exit_code);
|
||||
.input :
|
||||
const char *app_name, Application's name
|
||||
const int options, Options
|
||||
const ChfOptions options, Options
|
||||
const ChfTable *table, pointer to the static message table
|
||||
const size_t table_size, size of the table (# of entries)
|
||||
const int condition_stack_size, Size of the condition stack
|
||||
|
@ -120,14 +133,14 @@ static void ExitMessage( void* private_context ) {}
|
|||
1.1, 27-May-1996, creation
|
||||
|
||||
.- */
|
||||
/* Initialization with static message tables */
|
||||
int ChfStaticInit( const int module_id, const char* app_name, /* Application's name */
|
||||
const int options, /* Options */
|
||||
const ChfTable* table, /* Static message table */
|
||||
const size_t table_size, /* Size of the message table */
|
||||
const int condition_stack_size, /* Size of the condition stack */
|
||||
const int handler_stack_size, /* Size of the handler stack */
|
||||
const int exit_code /* Abnormal exit code */
|
||||
int ChfStaticInit( /* Initialization with static message tables */
|
||||
const ChfChar* app_name, /* Application's name */
|
||||
const ChfOptions options, /* Options */
|
||||
const ChfTable* table, /* Static message table */
|
||||
const size_t table_size, /* Size of the message table */
|
||||
const int condition_stack_size, /* Size of the condition stack */
|
||||
const int handler_stack_size, /* Size of the handler stack */
|
||||
const int exit_code /* Abnormal exit code */
|
||||
)
|
||||
{
|
||||
ChfStaticContext* private_context;
|
||||
|
@ -135,7 +148,7 @@ int ChfStaticInit( const int module_id, const char* app_name, /* Application's n
|
|||
|
||||
if ( ( private_context = ( ChfStaticContext* )malloc( sizeof( ChfStaticContext ) ) ) == ( ChfStaticContext* )NULL )
|
||||
cc = CHF_F_MALLOC;
|
||||
else if ( ( cc = ChfInit( module_id, app_name, options, ( void* )private_context, StGetMessage, ExitMessage, condition_stack_size,
|
||||
else if ( ( cc = ChfInit( app_name, options, ( void* )private_context, StGetMessage, ExitMessage, condition_stack_size,
|
||||
handler_stack_size, exit_code ) ) != CHF_S_OK )
|
||||
free( private_context );
|
||||
else {
|
106
libChf/src/chf_top.c
Normal file
106
libChf/src/chf_top.c
Normal file
|
@ -0,0 +1,106 @@
|
|||
/* .+
|
||||
|
||||
.identifier : $Id: chf_top.c,v 2.2 2001/01/25 14:09:21 cibrario Exp $
|
||||
.context : CHF, Condition Handling Facility
|
||||
.title : $RCSfile: chf_top.c,v $
|
||||
.kind : C source
|
||||
.author : Ivan Cibrario B.
|
||||
.site : CSTV-CNR
|
||||
.creation : 5-Jun-1996
|
||||
.keywords : *
|
||||
.description :
|
||||
This module implements the CHF function ChfGetTopCondition()
|
||||
|
||||
.include : Chf.h
|
||||
|
||||
.notes :
|
||||
$Log: chf_top.c,v $
|
||||
Revision 2.2 2001/01/25 14:09:21 cibrario
|
||||
Added partial Win32 support (Windows CE only).
|
||||
|
||||
Revision 2.1 2000/05/26 14:23:33 cibrario
|
||||
ChfGetTopCondition() used to return a pointer to the wrong condition
|
||||
descriptor; fixed.
|
||||
|
||||
Revision 1.2 1996/06/11 12:47:17 cibrario
|
||||
file creation
|
||||
|
||||
|
||||
.- */
|
||||
|
||||
#ifndef lint
|
||||
static char rcs_id[] = "$Id: chf_top.c,v 2.2 2001/01/25 14:09:21 cibrario Exp $";
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <setjmp.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "Chf.h"
|
||||
#include "ChfPriv.h"
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
Public functions
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
/* .+
|
||||
|
||||
.title : ChfGetTopCondition
|
||||
.kind : C function
|
||||
.creation : 5-Jun-1996
|
||||
.description :
|
||||
This function returns to the caller a pointer to the top condition of
|
||||
the current condition group. It generates and immediately signals the
|
||||
condition CHF_F_BAD_STATE if the current condition group is empty.
|
||||
|
||||
|
||||
NOTE: During condition signalling, CHF creates a new, empty, condition group
|
||||
immediately before starting the invocation sequence of the condition
|
||||
handlers, as described in the documentation. Therefore
|
||||
ChfGetTopCondition(), if called from a condition handler, will return
|
||||
a pointer to the top condition generated during the handling ONLY, and
|
||||
NOT to the top condition of the condition group being signalled. The
|
||||
latter pointer is directly available, as an argument, to the condition
|
||||
handlers.
|
||||
|
||||
NOTE: This function will call ChfAbort() with abort code CHF_ABORT_INIT
|
||||
if CHF hasn't been correctly initialized.
|
||||
|
||||
NOTE: The returned pointer is no longer valid when any other CHF function
|
||||
is called after ChfGetTopCondition().
|
||||
|
||||
.call :
|
||||
d = ChfGetTopCondition();
|
||||
.input :
|
||||
void
|
||||
.output :
|
||||
const ChfDescriptor *d, condition descriptor
|
||||
.status_codes :
|
||||
|
||||
.notes :
|
||||
1.2, 17-May-1996, creation
|
||||
2.1, 24-May-2000, bug fix:
|
||||
- condition stack referenced incorrectly
|
||||
|
||||
.- */
|
||||
const ChfDescriptor* ChfGetTopCondition( /* Retrieve top condition */
|
||||
void )
|
||||
{
|
||||
ChfDescriptor* d;
|
||||
|
||||
/* Check that CHF has been correctly initialized */
|
||||
if ( chf_context.state == CHF_UNKNOWN )
|
||||
ChfAbort( CHF_ABORT_INIT );
|
||||
|
||||
if ( ( d = chf_context.condition_sp ) == chf_context.condition_base ) {
|
||||
ChfCondition CHF_F_BAD_STATE, CHF_FATAL ChfEnd;
|
||||
ChfSignal();
|
||||
}
|
||||
|
||||
/* The top element of the condition group is the element immediately
|
||||
below the stack pointer.
|
||||
*/
|
||||
return d - 1;
|
||||
}
|
15
libChf/src/resource.h
Normal file
15
libChf/src/resource.h
Normal file
|
@ -0,0 +1,15 @@
|
|||
//{{NO_DEPENDENCIES}}
|
||||
// Microsoft Developer Studio generated include file.
|
||||
// Used by chf.rc
|
||||
//
|
||||
|
||||
// Next default values for new objects
|
||||
//
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
# ifndef APSTUDIO_READONLY_SYMBOLS
|
||||
# define _APS_NEXT_RESOURCE_VALUE 101
|
||||
# define _APS_NEXT_COMMAND_VALUE 40001
|
||||
# define _APS_NEXT_CONTROL_VALUE 1000
|
||||
# define _APS_NEXT_SYMED_VALUE 101
|
||||
# endif
|
||||
#endif
|
40
libChf/tests/chf.msf
Normal file
40
libChf/tests/chf.msf
Normal file
|
@ -0,0 +1,40 @@
|
|||
$ .+
|
||||
$ .
|
||||
$ .identifier : $Id: chf.msf,v 2.2 2001/01/25 12:00:19 cibrario Exp $
|
||||
$ .context :
|
||||
$ .title : $RCSfile: chf.msf,v $
|
||||
$ .kind : Makefile
|
||||
$ .author : Ivan Cibrario B.
|
||||
$ .site : CSTV-CNR
|
||||
$ .creation : 27-May-1996
|
||||
$ .keywords : *
|
||||
$ .description :
|
||||
$ . Message source file for the CHF conditions
|
||||
$ .notes :
|
||||
$ . $Log: chf.msf,v $
|
||||
$ . Revision 2.2 2001/01/25 12:00:19 cibrario
|
||||
$ . Added partial Win32 support (Windows CE only).
|
||||
$ .
|
||||
$ . Revision 2.1 2000/05/26 14:17:21 cibrario
|
||||
$ . Updated documentation block and RCS log message header to prevent
|
||||
$ . gencat warnings on Linux boxes
|
||||
$ .
|
||||
$ . Revision 1.1 1996/05/28 12:57:06 cibrario
|
||||
$ . Initial revision
|
||||
$ .
|
||||
$ .-
|
||||
|
||||
$set 1
|
||||
2 Chf
|
||||
3 Errno
|
||||
|
||||
$set 2
|
||||
1 Condition stack is full
|
||||
2 Handler stack is full
|
||||
3 Handler stack is empty
|
||||
4 Wrong Chf state for requested operation
|
||||
5 Invalid action code from handler (code=<%d>d)
|
||||
6 Dynamic memory allocation failed
|
||||
7 Function not implemented
|
||||
10 setlocale() failed
|
||||
11 catopen() failed
|
|
@ -16,7 +16,7 @@
|
|||
|
||||
#define CHF_MODULE_ID 255
|
||||
#define CHF_EXTENDED_INFO
|
||||
#include "../src/Chf.h"
|
||||
#include "Chf.h"
|
||||
|
||||
int main( int argc, char* argv[] )
|
||||
{
|
||||
|
@ -44,7 +44,7 @@ int main( int argc, char* argv[] )
|
|||
exit( EXIT_FAILURE );
|
||||
|
||||
/* Generate a condition and check descriptor; this is line 46 */
|
||||
CHF_Condition 3, CHF_WARNING, 456 ChfEnd;
|
||||
ChfCondition 3, CHF_WARNING, 456 ChfEnd;
|
||||
|
||||
if ( ( d = ChfGetTopCondition() ) == NULL )
|
||||
exit( EXIT_FAILURE );
|
||||
|
@ -53,7 +53,7 @@ int main( int argc, char* argv[] )
|
|||
exit( EXIT_FAILURE );
|
||||
|
||||
/* Generate another condition and check; this is line 60 */
|
||||
CHF_Condition 4, CHF_INFO, "arg" ChfEnd;
|
||||
ChfCondition 4, CHF_INFO, "arg" ChfEnd;
|
||||
|
||||
if ( ( e = ChfGetTopCondition() ) == NULL )
|
||||
exit( EXIT_FAILURE );
|
||||
|
@ -65,7 +65,7 @@ int main( int argc, char* argv[] )
|
|||
ChfDiscard();
|
||||
|
||||
/* This is line 77 */
|
||||
CHF_Condition 5, CHF_ERROR, 456, 789 ChfEnd;
|
||||
ChfCondition 5, CHF_ERROR, 456, 789 ChfEnd;
|
||||
|
||||
if ( ( d = ChfGetTopCondition() ) == NULL )
|
||||
exit( EXIT_FAILURE );
|
|
@ -16,7 +16,7 @@
|
|||
|
||||
#define CHF_MODULE_ID 255
|
||||
#define CHF_EXTENDED_INFO
|
||||
#include "../src/Chf.h"
|
||||
#include "Chf.h"
|
||||
|
||||
void* task( void* arg )
|
||||
{
|
||||
|
@ -34,7 +34,7 @@ void* task( void* arg )
|
|||
exit( EXIT_FAILURE );
|
||||
|
||||
/* Generate a condition and check descriptor; this is line 36 */
|
||||
CHF_Condition 3, CHF_WARNING, 456 ChfEnd;
|
||||
ChfCondition 3, CHF_WARNING, 456 ChfEnd;
|
||||
|
||||
if ( ( d = ChfGetTopCondition() ) == NULL )
|
||||
exit( EXIT_FAILURE );
|
||||
|
@ -43,7 +43,7 @@ void* task( void* arg )
|
|||
exit( EXIT_FAILURE );
|
||||
|
||||
/* Generate another condition and check; this is line 50 */
|
||||
CHF_Condition 4, CHF_INFO, "arg" ChfEnd;
|
||||
ChfCondition 4, CHF_INFO, "arg" ChfEnd;
|
||||
|
||||
if ( ( e = ChfGetTopCondition() ) == NULL )
|
||||
exit( EXIT_FAILURE );
|
||||
|
@ -55,7 +55,7 @@ void* task( void* arg )
|
|||
ChfDiscard();
|
||||
|
||||
/* This is line 67 */
|
||||
CHF_Condition 5, CHF_ERROR, 456, 789 ChfEnd;
|
||||
ChfCondition 5, CHF_ERROR, 456, 789 ChfEnd;
|
||||
|
||||
if ( ( d = ChfGetTopCondition() ) == NULL )
|
||||
exit( EXIT_FAILURE );
|
|
@ -19,7 +19,7 @@
|
|||
|
||||
#define CHF_MODULE_ID 255
|
||||
#define CHF_EXTENDED_INFO
|
||||
#include "../src/Chf.h"
|
||||
#include "Chf.h"
|
||||
|
||||
void* task( void* arg )
|
||||
{
|
||||
|
@ -32,11 +32,11 @@ void* task( void* arg )
|
|||
printf( "\tThread %d\n", ( int )arg );
|
||||
|
||||
/* Generate a condition group and signal it */
|
||||
CHF_Condition 6, CHF_INFO, ( int )arg ChfEnd;
|
||||
CHF_Condition 6, CHF_INFO, ( int )arg ChfEnd;
|
||||
CHF_Condition 6, CHF_INFO, ( int )arg ChfEnd;
|
||||
CHF_Condition 6, CHF_INFO, ( int )arg ChfEnd;
|
||||
CHF_Condition 7, CHF_INFO, ( int )arg ChfEnd;
|
||||
ChfCondition 6, CHF_INFO, ( int )arg ChfEnd;
|
||||
ChfCondition 6, CHF_INFO, ( int )arg ChfEnd;
|
||||
ChfCondition 6, CHF_INFO, ( int )arg ChfEnd;
|
||||
ChfCondition 6, CHF_INFO, ( int )arg ChfEnd;
|
||||
ChfCondition 7, CHF_INFO, ( int )arg ChfEnd;
|
||||
|
||||
/* The sleep() is here to increase contention between threads */
|
||||
sleep( 1 );
|
|
@ -19,20 +19,20 @@
|
|||
|
||||
#define CHF_MODULE_ID 255
|
||||
#define CHF_EXTENDED_INFO
|
||||
#include "../src/Chf.h"
|
||||
#include "Chf.h"
|
||||
|
||||
struct tdata_s {
|
||||
const ChfDescriptor *d, *e;
|
||||
int phase;
|
||||
};
|
||||
|
||||
ChfAction h1( const ChfDescriptor* c, const ChfState s, void* p )
|
||||
ChfAction h1( const ChfDescriptor* c, const ChfState s, ChfPointer p )
|
||||
{
|
||||
struct tdata_s* tdata_p = ( struct tdata_s* )p;
|
||||
ChfAction action;
|
||||
|
||||
if ( c != tdata_p->e || ChfGetNextDescriptor( c ) != tdata_p->d ) {
|
||||
CHF_Condition 10, CHF_FATAL ChfEnd;
|
||||
ChfCondition 10, CHF_FATAL ChfEnd;
|
||||
action = CHF_RESIGNAL;
|
||||
}
|
||||
|
||||
|
@ -42,7 +42,7 @@ ChfAction h1( const ChfDescriptor* c, const ChfState s, void* p )
|
|||
return action;
|
||||
}
|
||||
|
||||
ChfAction h2( const ChfDescriptor* c, const ChfState s, void* p )
|
||||
ChfAction h2( const ChfDescriptor* c, const ChfState s, ChfPointer p )
|
||||
{
|
||||
struct tdata_s* tdata_p = ( struct tdata_s* )p;
|
||||
ChfAction action;
|
||||
|
@ -51,7 +51,7 @@ ChfAction h2( const ChfDescriptor* c, const ChfState s, void* p )
|
|||
case CHF_SIGNALING:
|
||||
{
|
||||
if ( c != tdata_p->e || ChfGetNextDescriptor( c ) != tdata_p->d || ( tdata_p->phase != 2 && tdata_p->phase != 4 ) ) {
|
||||
CHF_Condition 10, CHF_FATAL ChfEnd;
|
||||
ChfCondition 10, CHF_FATAL ChfEnd;
|
||||
action = CHF_RESIGNAL;
|
||||
}
|
||||
|
||||
|
@ -76,7 +76,7 @@ ChfAction h2( const ChfDescriptor* c, const ChfState s, void* p )
|
|||
return action;
|
||||
}
|
||||
|
||||
ChfAction h3( const ChfDescriptor* c, const ChfState s, void* p )
|
||||
ChfAction h3( const ChfDescriptor* c, const ChfState s, ChfPointer p )
|
||||
{
|
||||
struct tdata_s* tdata_p = ( struct tdata_s* )p;
|
||||
ChfAction action;
|
||||
|
@ -106,7 +106,7 @@ ChfAction h3( const ChfDescriptor* c, const ChfState s, void* p )
|
|||
return action;
|
||||
}
|
||||
|
||||
ChfAction h4( const ChfDescriptor* c, const ChfState s, void* p )
|
||||
ChfAction h4( const ChfDescriptor* c, const ChfState s, ChfPointer p )
|
||||
{
|
||||
struct tdata_s* tdata_p = ( struct tdata_s* )p;
|
||||
ChfAction action;
|
||||
|
@ -119,14 +119,14 @@ ChfAction h4( const ChfDescriptor* c, const ChfState s, void* p )
|
|||
case CHF_SIGNALING:
|
||||
{
|
||||
if ( c != tdata_p->e || ChfGetNextDescriptor( c ) != tdata_p->d ) {
|
||||
CHF_Condition 10, CHF_FATAL ChfEnd;
|
||||
ChfCondition 10, CHF_FATAL ChfEnd;
|
||||
action = CHF_RESIGNAL;
|
||||
}
|
||||
|
||||
else {
|
||||
/* This generates a new group and signals it */
|
||||
tdata_p->phase = 3;
|
||||
CHF_Condition 9, CHF_INFO ChfEnd;
|
||||
ChfCondition 9, CHF_INFO ChfEnd;
|
||||
ChfSignal();
|
||||
|
||||
if ( tdata_p->phase != 4 )
|
||||
|
@ -134,7 +134,7 @@ ChfAction h4( const ChfDescriptor* c, const ChfState s, void* p )
|
|||
tdata_p->phase = 5;
|
||||
|
||||
if ( c != tdata_p->e || ChfGetNextDescriptor( c ) != tdata_p->d ) {
|
||||
CHF_Condition 10, CHF_FATAL ChfEnd;
|
||||
ChfCondition 10, CHF_FATAL ChfEnd;
|
||||
action = CHF_RESIGNAL;
|
||||
} else
|
||||
action = CHF_CONTINUE;
|
||||
|
@ -159,12 +159,12 @@ void* task( void* arg )
|
|||
printf( "\tThread %d\n", ( int )arg );
|
||||
|
||||
/* Push the handler */
|
||||
ChfPushHandler( h1, NULL, ( void* )( &tdata ) );
|
||||
ChfPushHandler( h1, NULL, ( ChfPointer )( &tdata ) );
|
||||
|
||||
/* Generate a condition group and signal it */
|
||||
CHF_Condition 6, CHF_INFO, ( int )arg ChfEnd;
|
||||
ChfCondition 6, CHF_INFO, ( int )arg ChfEnd;
|
||||
tdata.d = ChfGetTopCondition();
|
||||
CHF_Condition 7, CHF_INFO, ( int )arg ChfEnd;
|
||||
ChfCondition 7, CHF_INFO, ( int )arg ChfEnd;
|
||||
tdata.e = ChfGetTopCondition();
|
||||
|
||||
/* The sleep() is here to increase contention between threads */
|
||||
|
@ -178,9 +178,9 @@ void* task( void* arg )
|
|||
and signal it; this checks that the handler has actually been
|
||||
removed.
|
||||
*/
|
||||
CHF_Condition 6, CHF_INFO, ( int )arg ChfEnd;
|
||||
ChfCondition 6, CHF_INFO, ( int )arg ChfEnd;
|
||||
tdata.d = NULL;
|
||||
CHF_Condition 7, CHF_INFO, ( int )arg ChfEnd;
|
||||
ChfCondition 7, CHF_INFO, ( int )arg ChfEnd;
|
||||
tdata.e = NULL;
|
||||
ChfSignal();
|
||||
|
||||
|
@ -190,13 +190,13 @@ void* task( void* arg )
|
|||
|
||||
tdata.phase = 0;
|
||||
if ( setjmp( jb ) == 0 ) {
|
||||
ChfPushHandler( h2, jb, ( void* )( &tdata ) );
|
||||
ChfPushHandler( h2, jb, ( ChfPointer )( &tdata ) );
|
||||
|
||||
/* Generate a condition group and signal it */
|
||||
tdata.phase = 1;
|
||||
CHF_Condition 6, CHF_INFO, ( int )arg ChfEnd;
|
||||
ChfCondition 6, CHF_INFO, ( int )arg ChfEnd;
|
||||
tdata.d = ChfGetTopCondition();
|
||||
CHF_Condition 7, CHF_INFO, ( int )arg ChfEnd;
|
||||
ChfCondition 7, CHF_INFO, ( int )arg ChfEnd;
|
||||
tdata.e = ChfGetTopCondition();
|
||||
|
||||
/* This does not trigger an unwind */
|
||||
|
@ -204,9 +204,9 @@ void* task( void* arg )
|
|||
ChfSignal();
|
||||
|
||||
tdata.phase = 3;
|
||||
CHF_Condition 6, CHF_INFO, ( int )arg ChfEnd;
|
||||
ChfCondition 6, CHF_INFO, ( int )arg ChfEnd;
|
||||
tdata.d = ChfGetTopCondition();
|
||||
CHF_Condition 8, CHF_INFO, ( int )arg ChfEnd;
|
||||
ChfCondition 8, CHF_INFO, ( int )arg ChfEnd;
|
||||
tdata.e = ChfGetTopCondition();
|
||||
|
||||
/* This MUST trigger an unwind */
|
||||
|
@ -230,13 +230,13 @@ void* task( void* arg )
|
|||
{
|
||||
tdata.phase = 0;
|
||||
|
||||
ChfPushHandler( h3, NULL, ( void* )&tdata );
|
||||
ChfPushHandler( h4, NULL, ( void* )&tdata );
|
||||
ChfPushHandler( h3, NULL, ( ChfPointer )&tdata );
|
||||
ChfPushHandler( h4, NULL, ( ChfPointer )&tdata );
|
||||
|
||||
tdata.phase = 1;
|
||||
CHF_Condition 6, CHF_INFO, ( int )arg ChfEnd;
|
||||
ChfCondition 6, CHF_INFO, ( int )arg ChfEnd;
|
||||
tdata.d = ChfGetTopCondition();
|
||||
CHF_Condition 7, CHF_INFO, ( int )arg ChfEnd;
|
||||
ChfCondition 7, CHF_INFO, ( int )arg ChfEnd;
|
||||
tdata.e = ChfGetTopCondition();
|
||||
|
||||
tdata.phase = 2;
|
|
@ -19,7 +19,7 @@
|
|||
|
||||
#define CHF_MODULE_ID 255
|
||||
#define CHF_EXTENDED_INFO
|
||||
#include "../src/Chf.h"
|
||||
#include "Chf.h"
|
||||
|
||||
#define H_STACK_SIZE 10
|
||||
#define C_STACK_SIZE 30
|
||||
|
@ -27,14 +27,14 @@
|
|||
/* Dummy handler; pushed only to verify that the handler stack overflow
|
||||
checks are correct.
|
||||
*/
|
||||
ChfAction h1( const ChfDescriptor* c, const ChfState s, void* p ) { return CHF_RESIGNAL; }
|
||||
ChfAction h1( const ChfDescriptor* c, const ChfState s, ChfPointer p ) { return CHF_RESIGNAL; }
|
||||
|
||||
/* Overflow check handler; it unwinds if the CHF_F_HDLR_STACK_FULL
|
||||
condition is signalled exactly after H_STACK_SIZE-2 invocations
|
||||
of ChfPushHandler(), it resignals a modified condition if the
|
||||
condition is signalled too early
|
||||
*/
|
||||
ChfAction h2( const ChfDescriptor* c, const ChfState s, void* p )
|
||||
ChfAction h2( const ChfDescriptor* c, const ChfState s, ChfPointer p )
|
||||
{
|
||||
int push_count = *( ( int* )p );
|
||||
ChfAction action;
|
||||
|
@ -45,7 +45,7 @@ ChfAction h2( const ChfDescriptor* c, const ChfState s, void* p )
|
|||
if ( push_count == H_STACK_SIZE - 2 && ChfGetNextDescriptor( c ) == NULL && ChfGetSeverity( c ) == CHF_FATAL )
|
||||
action = CHF_UNWIND;
|
||||
else {
|
||||
CHF_Condition 11, CHF_FATAL, push_count, H_STACK_SIZE - 2 ChfEnd;
|
||||
ChfCondition 11, CHF_FATAL, push_count, H_STACK_SIZE - 2 ChfEnd;
|
||||
action = CHF_RESIGNAL;
|
||||
}
|
||||
}
|
||||
|
@ -59,10 +59,10 @@ ChfAction h2( const ChfDescriptor* c, const ChfState s, void* p )
|
|||
|
||||
/* Overflow check handler; it unwinds if the CHF_F_COND_STACK_FULL
|
||||
condition is signalled exactly after C_STACK_SIZE invocations
|
||||
of CHF_Condition, it resignals a modified condition if the
|
||||
of ChfCondition, it resignals a modified condition if the
|
||||
condition is signalled too early
|
||||
*/
|
||||
ChfAction h3( const ChfDescriptor* c, const ChfState s, void* p )
|
||||
ChfAction h3( const ChfDescriptor* c, const ChfState s, ChfPointer p )
|
||||
{
|
||||
int push_count = *( ( int* )p );
|
||||
ChfAction action;
|
||||
|
@ -73,7 +73,7 @@ ChfAction h3( const ChfDescriptor* c, const ChfState s, void* p )
|
|||
if ( push_count == C_STACK_SIZE && ChfGetNextDescriptor( c ) == NULL && ChfGetSeverity( c ) == CHF_FATAL )
|
||||
action = CHF_UNWIND;
|
||||
else {
|
||||
CHF_Condition 12, CHF_FATAL, push_count, C_STACK_SIZE ChfEnd;
|
||||
ChfCondition 12, CHF_FATAL, push_count, C_STACK_SIZE ChfEnd;
|
||||
action = CHF_RESIGNAL;
|
||||
}
|
||||
}
|
||||
|
@ -100,7 +100,7 @@ void* task( void* arg )
|
|||
int i;
|
||||
|
||||
/* Push the handler */
|
||||
ChfPushHandler( h2, jb, ( void* )( &push_count ) );
|
||||
ChfPushHandler( h2, jb, ( ChfPointer )( &push_count ) );
|
||||
|
||||
/* The sleep() is here to increase contention between threads */
|
||||
sleep( 1 );
|
||||
|
@ -122,14 +122,14 @@ void* task( void* arg )
|
|||
int i;
|
||||
|
||||
/* Push the handler */
|
||||
ChfPushHandler( h3, jb, ( void* )( &push_count ) );
|
||||
ChfPushHandler( h3, jb, ( ChfPointer )( &push_count ) );
|
||||
|
||||
/* The sleep() is here to increase contention between threads */
|
||||
sleep( 1 );
|
||||
|
||||
/* Push dummy conditions until an error should occur */
|
||||
for ( ; push_count <= C_STACK_SIZE; push_count++ )
|
||||
CHF_Condition 1, CHF_INFO ChfEnd;
|
||||
ChfCondition 1, CHF_INFO ChfEnd;
|
||||
|
||||
/* No error? Bad! */
|
||||
return ( void* )EXIT_FAILURE;
|
||||
|
@ -145,14 +145,14 @@ void* task( void* arg )
|
|||
int i;
|
||||
|
||||
/* Push the handler */
|
||||
ChfPushHandler( h3, jb, ( void* )( &push_count ) );
|
||||
ChfPushHandler( h3, jb, ( ChfPointer )( &push_count ) );
|
||||
|
||||
/* The sleep() is here to increase contention between threads */
|
||||
sleep( 1 );
|
||||
|
||||
/* Push dummy conditions until an error should occur */
|
||||
for ( ; push_count <= C_STACK_SIZE; push_count++ )
|
||||
CHF_Condition 1, CHF_INFO ChfEnd;
|
||||
ChfCondition 1, CHF_INFO ChfEnd;
|
||||
|
||||
/* No error? Bad! */
|
||||
return ( void* )EXIT_FAILURE;
|
|
@ -19,7 +19,7 @@
|
|||
|
||||
#define CHF_MODULE_ID 255
|
||||
#define CHF_EXTENDED_INFO
|
||||
#include "../src/Chf.h"
|
||||
#include "Chf.h"
|
||||
|
||||
#define H_STACK_SIZE 10
|
||||
#define C_STACK_SIZE 30
|
||||
|
@ -28,50 +28,50 @@ void* task( void* arg )
|
|||
{
|
||||
volatile int phase = 0;
|
||||
|
||||
CHF_Try
|
||||
ChfTry
|
||||
{
|
||||
phase = 1;
|
||||
CHF_Condition 20, CHF_SUCCESS ChfEnd;
|
||||
ChfCondition 20, CHF_SUCCESS ChfEnd;
|
||||
ChfSignal();
|
||||
|
||||
phase = 2;
|
||||
CHF_Condition 20, CHF_INFO ChfEnd;
|
||||
ChfCondition 20, CHF_INFO ChfEnd;
|
||||
ChfSignal();
|
||||
|
||||
phase = 3;
|
||||
CHF_Condition 20, CHF_WARNING ChfEnd;
|
||||
ChfCondition 20, CHF_WARNING ChfEnd;
|
||||
ChfSignal();
|
||||
|
||||
phase = 4;
|
||||
CHF_Condition 20, CHF_ERROR ChfEnd;
|
||||
ChfCondition 20, CHF_ERROR ChfEnd;
|
||||
ChfSignal();
|
||||
|
||||
phase = 5;
|
||||
CHF_Condition 20, CHF_FATAL ChfEnd;
|
||||
ChfCondition 20, CHF_FATAL ChfEnd;
|
||||
ChfSignal();
|
||||
|
||||
/* Should not be reached */
|
||||
return ( void* )EXIT_FAILURE;
|
||||
}
|
||||
CHF_Catch
|
||||
ChfCatch
|
||||
{
|
||||
/* Catched an exception; check descriptor */
|
||||
const ChfDescriptor* d = ChfGetTopCondition();
|
||||
if ( d == NULL || ChfGetNextDescriptor( d ) != NULL || ChfGetModuleId( d ) != CHF_MODULE_ID || ChfGetConditionCode( d ) != 20 )
|
||||
return ( void* )EXIT_FAILURE;
|
||||
}
|
||||
CHF_EndTry;
|
||||
ChfEndTry;
|
||||
|
||||
/* Check that the condition stack actually is empty after catch */
|
||||
CHF_Try { const volatile ChfDescriptor* e = ChfGetTopCondition(); }
|
||||
CHF_Catch
|
||||
ChfTry { const volatile ChfDescriptor* e = ChfGetTopCondition(); }
|
||||
ChfCatch
|
||||
{
|
||||
const ChfDescriptor* d = ChfGetTopCondition();
|
||||
if ( d == NULL || ChfGetNextDescriptor( d ) != NULL || ChfGetModuleId( d ) != CHF_SET ||
|
||||
ChfGetConditionCode( d ) != CHF_F_BAD_STATE )
|
||||
return ( void* )EXIT_FAILURE;
|
||||
}
|
||||
CHF_EndTry;
|
||||
ChfEndTry;
|
||||
|
||||
return ( void* )EXIT_SUCCESS;
|
||||
}
|
|
@ -16,7 +16,7 @@
|
|||
|
||||
#define CHF_MODULE_ID 255
|
||||
#define CHF_EXTENDED_INFO
|
||||
#include "../src/Chf.h"
|
||||
#include "Chf.h"
|
||||
|
||||
extern ChfTable message_table[];
|
||||
extern size_t message_table_size;
|
||||
|
@ -44,7 +44,7 @@ int main( int argc, char* argv[] )
|
|||
exit( EXIT_FAILURE );
|
||||
|
||||
/* Generate a condition and check descriptor; this is line 46 */
|
||||
CHF_Condition 3, CHF_WARNING, 456 ChfEnd;
|
||||
ChfCondition 3, CHF_WARNING, 456 ChfEnd;
|
||||
|
||||
if ( ( d = ChfGetTopCondition() ) == NULL )
|
||||
exit( EXIT_FAILURE );
|
||||
|
@ -53,7 +53,7 @@ int main( int argc, char* argv[] )
|
|||
exit( EXIT_FAILURE );
|
||||
|
||||
/* Generate another condition and check; this is line 60 */
|
||||
CHF_Condition 4, CHF_INFO, "arg" ChfEnd;
|
||||
ChfCondition 4, CHF_INFO, "arg" ChfEnd;
|
||||
|
||||
if ( ( e = ChfGetTopCondition() ) == NULL )
|
||||
exit( EXIT_FAILURE );
|
||||
|
@ -65,7 +65,7 @@ int main( int argc, char* argv[] )
|
|||
ChfDiscard();
|
||||
|
||||
/* This is line 77 */
|
||||
CHF_Condition 5, CHF_ERROR, 456, 789 ChfEnd;
|
||||
ChfCondition 5, CHF_ERROR, 456, 789 ChfEnd;
|
||||
|
||||
if ( ( d = ChfGetTopCondition() ) == NULL )
|
||||
exit( EXIT_FAILURE );
|
BIN
saturn48gx.png
BIN
saturn48gx.png
Binary file not shown.
Before Width: | Height: | Size: 12 KiB |
BIN
saturn48sx.png
BIN
saturn48sx.png
Binary file not shown.
Before Width: | Height: | Size: 12 KiB |
BIN
saturn49g.png
BIN
saturn49g.png
Binary file not shown.
Before Width: | Height: | Size: 18 KiB |
64
src/MSFs/cpu.msf
Normal file
64
src/MSFs/cpu.msf
Normal file
|
@ -0,0 +1,64 @@
|
|||
$ .+
|
||||
$ .identifier : $Id: cpu.msf,v 4.1 2000/12/11 09:54:19 cibrario Rel $
|
||||
$ .context : SATURN, Saturn CPU / HP48 emulator
|
||||
$ .title : $RCSfile: cpu.msf,v $
|
||||
$ .kind : Message catalog source
|
||||
$ .author : Ivan Cibrario B.
|
||||
$ .site : CSTV-CNR
|
||||
$ .creation : 13-Feb-1998
|
||||
$ .keywords : *
|
||||
$ .description :
|
||||
$ Message catalog source file for the CPU emulation modules.
|
||||
$ .notes :
|
||||
$ . $Log: cpu.msf,v $
|
||||
$ . Revision 4.1 2000/12/11 09:54:19 cibrario
|
||||
$ . Public release.
|
||||
$ .
|
||||
$ . Revision 3.13 2000/11/09 11:27:48 cibrario
|
||||
$ . Revised to add file selection box GUI element, CPU halt/run
|
||||
$ . requests and emulator's extended functions:
|
||||
$ .
|
||||
$ . - New messages: 118, 119, 303
|
||||
$ .
|
||||
$ . Revision 3.8 2000/10/19 14:56:52 cibrario
|
||||
$ . Bug fix:
|
||||
$ . Removed lines with empty directives
|
||||
$ .
|
||||
$ Revision 3.1 2000/09/20 13:44:30 cibrario
|
||||
$ Revised to implement passive CPU shutdown:
|
||||
$ - new messages 114, 115, 116, 117
|
||||
$ .
|
||||
$ Revision 1.1 1998/02/18 11:50:36 cibrario
|
||||
$ Initial revision
|
||||
$ .-
|
||||
|
||||
$set 1
|
||||
11 Cpu
|
||||
|
||||
$set 11
|
||||
101 Function [%s] called
|
||||
102 Executing @ PC[%05X]
|
||||
103 CPU shutdown executed
|
||||
104 CPU wake-up executed
|
||||
105 %s request accepted
|
||||
106 %s request pending
|
||||
107 RTI loop to service %s
|
||||
108 RTI returning
|
||||
109 INTON servicing %s
|
||||
110 CPU emulator [%s]
|
||||
111 Timer1 expired CTRL[%01X]
|
||||
112 Timer2 expired CTRL[%01X]
|
||||
113 Emulator interrupt request detected
|
||||
114 Timer[%s] Ctrl[%01X] Val[%08X]
|
||||
115 Timer[%s] expires in [%d]d ms
|
||||
116 Starting idle loop, timeout [%d]d ms
|
||||
117 Spooling up after [%d]d us in idle loop
|
||||
118 CPU halted by CpuHaltRequest()
|
||||
119 CPU awoken by CpuRunRequest()
|
||||
201 Can't restore CPU status from disk; resetting CPU
|
||||
202 Monitor command syntax error [%s]
|
||||
301 Bad opcode @ PC[%05X], N[%01X]
|
||||
302 Can't save CPU status to disk
|
||||
303 Halt/Run requests not allowed; #undef CPU_SPIN_SHUTDN
|
||||
401 Internal error [%s]
|
||||
402 Unexpected CPU shutdown
|
29
src/MSFs/debug.msf
Normal file
29
src/MSFs/debug.msf
Normal file
|
@ -0,0 +1,29 @@
|
|||
$ .+
|
||||
$ .identifier : $Id: debug.msf,v 4.1 2000/12/11 09:54:19 cibrario Rel $
|
||||
$ .context : SATURN, Saturn CPU / HP48 emulator
|
||||
$ .title : $RCSfile: debug.msf,v $
|
||||
$ .kind : Message catalog source
|
||||
$ .author : Ivan Cibrario B.
|
||||
$ .site : CSTV-CNR
|
||||
$ .creation : 13-Feb-1998
|
||||
$ .keywords : *
|
||||
$ .description :
|
||||
$ Message catalog source file for the debugging support modules.
|
||||
$ .notes :
|
||||
$ . $Log: debug.msf,v $
|
||||
$ . Revision 4.1 2000/12/11 09:54:19 cibrario
|
||||
$ . Public release.
|
||||
$ .
|
||||
$ . Revision 3.8 2000/10/19 14:55:10 cibrario
|
||||
$ . Bug fix:
|
||||
$ . Removed lines with empty directives
|
||||
$ .
|
||||
$ Revision 1.1 1998/02/18 11:54:02 cibrario
|
||||
$ Initial revision
|
||||
$ .-
|
||||
|
||||
$set 1
|
||||
30 Debug
|
||||
|
||||
$set 30
|
||||
201 Debug not supported; Rebuild with -DDEBUG
|
44
src/MSFs/disk_io.msf
Normal file
44
src/MSFs/disk_io.msf
Normal file
|
@ -0,0 +1,44 @@
|
|||
$ .+
|
||||
$ .identifier : $Id: disk_io.msf,v 4.1 2000/12/11 09:54:19 cibrario Rel $
|
||||
$ .context : SATURN, Saturn CPU / HP48 emulator
|
||||
$ .title : $RCSfile: disk_io.msf,v $
|
||||
$ .kind : Message catalog source
|
||||
$ .author : Ivan Cibrario B.
|
||||
$ .site : CSTV-CNR
|
||||
$ .creation : 13-Feb-1998
|
||||
$ .keywords : *
|
||||
$ .description :
|
||||
$ Message catalog source file for the disk I/O functions.
|
||||
$ .notes :
|
||||
$ . $Log: disk_io.msf,v $
|
||||
$ . Revision 4.1 2000/12/11 09:54:19 cibrario
|
||||
$ . Public release.
|
||||
$ .
|
||||
$ . Revision 3.14 2000/11/13 10:32:24 cibrario
|
||||
$ . Implemented fast load/save; improved keyboard interface emulation at
|
||||
$ . high emulated CPU speed:
|
||||
$ .
|
||||
$ . - Fixed spelling error in message 405
|
||||
$ . - Added new messages: 407, 408
|
||||
$ .
|
||||
$ . Revision 3.8 2000/10/19 14:58:41 cibrario
|
||||
$ . Bug fix:
|
||||
$ . Removed lines with empty directives
|
||||
$ .
|
||||
$ Revision 1.1 1998/02/17 11:54:49 cibrario
|
||||
$ Initial revision
|
||||
$ .-
|
||||
|
||||
$set 1
|
||||
13 Disk_IO
|
||||
|
||||
$set 13
|
||||
101 Function [%s] called
|
||||
401 Can't open file [%s]
|
||||
402 getc() failed reading file [%s]
|
||||
403 putc() failed writing file [%s]
|
||||
404 fread() failed reading file [%s]
|
||||
405 fwrite() failed writing file [%s]
|
||||
406 Close file [%s] failed
|
||||
407 File [%s] has a bad header
|
||||
408 File [%s] is too large
|
38
src/MSFs/flash49.msf
Normal file
38
src/MSFs/flash49.msf
Normal file
|
@ -0,0 +1,38 @@
|
|||
$ .+
|
||||
$ .identifier : $Id: flash49.msf,v 4.1 2000/12/11 09:54:19 cibrario Rel $
|
||||
$ .context : SATURN, Saturn CPU / HPxx emulator
|
||||
$ .title : $RCSfile: flash49.msf,v $
|
||||
$ .kind : Message catalog source
|
||||
$ .author : Ivan Cibrario B.
|
||||
$ .site : CSTV-CNR
|
||||
$ .creation : 25-Sep-2000
|
||||
$ .keywords : *
|
||||
$ .description :
|
||||
$ Message catalog source file for the flash rom emulator.
|
||||
$ .notes :
|
||||
$ . $Log: flash49.msf,v $
|
||||
$ . Revision 4.1 2000/12/11 09:54:19 cibrario
|
||||
$ . Public release.
|
||||
$ .
|
||||
$ . Revision 3.8 2000/10/19 15:00:41 cibrario
|
||||
$ . Bug fix:
|
||||
$ . Removed lines with empty directives
|
||||
$ .
|
||||
$ Revision 3.3 2000/09/26 15:30:28 cibrario
|
||||
$ *** empty log message ***
|
||||
$ .-
|
||||
|
||||
$set 1
|
||||
16 Flash
|
||||
|
||||
$set 16
|
||||
101 Read (Nibble) A[%08X] D[%01X]
|
||||
102 Write (Nibble) A[%08X] D[%01X]
|
||||
103 FSM STATE[%d] CYCLE[%d]
|
||||
104 \tFSM Args: (Byte)A[%08X] D[%02X]
|
||||
105 \tFSM Next: STATE[%d] RESULT[%02X]
|
||||
106 \tFSM Operation: [%s]
|
||||
201 Command unknown/not implemented - FSM Info:\n\
|
||||
\tSTATE[%d] CYCLE[%d] A[%08X] D[%02X]
|
||||
202 Invalid address in Write to Buffer - FSM Info:\n\
|
||||
\tSTATE[%d] CYCLE[%d] A[%08X] D[%02X]
|
103
src/MSFs/modules.msf
Normal file
103
src/MSFs/modules.msf
Normal file
|
@ -0,0 +1,103 @@
|
|||
$ .+
|
||||
$ .identifier : $Id: modules.msf,v 4.1 2000/12/11 09:54:19 cibrario Rel $
|
||||
$ .context : SATURN, Saturn CPU / HP48 emulator
|
||||
$ .title : $RCSfile: modules.msf,v $
|
||||
$ .kind : Message catalog source
|
||||
$ .author : Ivan Cibrario B.
|
||||
$ .site : CSTV-CNR
|
||||
$ .creation : 13-Feb-1998
|
||||
$ .keywords : *
|
||||
$ .description :
|
||||
$ Message catalog source file for the peripheral modules emulator.
|
||||
$ .notes :
|
||||
$ . $Log: modules.msf,v $
|
||||
$ . Revision 4.1 2000/12/11 09:54:19 cibrario
|
||||
$ . Public release.
|
||||
$ .
|
||||
$ . Revision 3.8 2000/10/19 14:58:01 cibrario
|
||||
$ . Bug fix:
|
||||
$ . Removed lines with empty directives
|
||||
$ .
|
||||
$ Revision 3.3 2000/09/26 15:05:33 cibrario
|
||||
$ Revised to implement Flash ROM write access:
|
||||
$ - Added message 312
|
||||
$ .
|
||||
$ Revision 3.2 2000/09/22 14:07:04 cibrario
|
||||
$ Implemented preliminary support of HP49 hw architecture:
|
||||
$ - added new messages: 311, 407, 408
|
||||
$ .
|
||||
$ Revision 2.7 2000/09/19 11:13:12 cibrario
|
||||
$ Deeply revised to implement config/unconfig cache.
|
||||
$ .
|
||||
$ Revision 2.4 2000/09/12 15:48:57 cibrario
|
||||
$ Added messages 112, 113, 114, 211, 212, 306, 307, 308, 309, 310
|
||||
$ .
|
||||
$ Revision 2.1 2000/09/08 15:22:17 cibrario
|
||||
$ Updated message 209; added message 210. Both updates reflect the
|
||||
$ changes made to the keyboard emulation module in order to
|
||||
$ accommodate the new GUI.
|
||||
$ .
|
||||
$ Revision 1.1 1998/02/17 14:53:53 cibrario
|
||||
$ Initial revision
|
||||
$ .-
|
||||
|
||||
$set 1
|
||||
12 Modules
|
||||
|
||||
$set 12
|
||||
101 Function [%s] called
|
||||
102 Initializing module [%s]
|
||||
103 Resetting module [%s]
|
||||
106 ModGetID -> [%05X]
|
||||
107 CONFIG M[%s] A[%05X] S[%05X]
|
||||
108 UNCNFG M[%s] A[%05X] S[%05X]
|
||||
109 Saving module [%s]
|
||||
110 Function [%s] not implemented
|
||||
111 Modules emulator: [%s]
|
||||
112 Bank Switcher F/F set to A[%05X]
|
||||
113 Port 1 has been write-protected
|
||||
114 Port 2 has been write-protected
|
||||
115 >>> PerfCtr [%s]=[%d]
|
||||
116 Cached UNCNFG completed
|
||||
117 Cached CONFIG A[%05X] completed
|
||||
118 Late UNCNFG cache hit
|
||||
119 Late UNCNFG cache miss
|
||||
202 Bad ModConfig [%05X] ignored
|
||||
203 Bad ModUnconfig [%05X] ignored
|
||||
204 Bad HdwWrite A[%05X] N[%01X]
|
||||
205 Bad HdwRead A[%05X]
|
||||
206 Resetting all modules
|
||||
207 Can't initialize internal RAM from disk
|
||||
208 Can't initialize HDW from disk
|
||||
209 Bad key [%s] ignored
|
||||
210 Bad out_bit [%x] ignored
|
||||
211 Can't initialize Port 1 from disk
|
||||
212 Can't initialize Port 2 from disk
|
||||
213 Unable to find CONFIG cache victim; flushing cache
|
||||
301 Read from unmapped A[%05X]
|
||||
302 Write to unmapped A[%05X] N[%01X]
|
||||
303 Write into ROM A[%05X] D[%01X]
|
||||
304 Can't save internal RAM status to disk
|
||||
305 Can't save HDW status to disk
|
||||
306 Can't save Port 1 status to disk
|
||||
307 Write into CE1 A[%05X] D[%01X]
|
||||
308 Can't save Port 1 status to disk
|
||||
309 Read from NCE3 A[%05X] when Port 2 is not present
|
||||
310 Write into NCE3 A[%05X] D[%01X] when Port 2 is not present
|
||||
311 Hardware configuration [%s] not supported
|
||||
312 Can't save Flash ROM status to disk
|
||||
401 Can't save module mapping info
|
||||
402 Can't initialize internal ROM
|
||||
403 Dynamic allocation of ModMap failed
|
||||
404 Bad alloc_c [%d] after FlushCache()
|
||||
405 Cached struct ModMap chain corrupted; freeing unlinked entry
|
||||
406 Unable to find CONFIG cache victim after cache flush
|
||||
407 Allocation of ModStatus_xx failed ([%d]d bytes needed)
|
||||
408 ModInit() invoked without registering a ModDescription first
|
||||
501 A[%05X] -> *Not Mapped*
|
||||
502 A[%05X] -> M[%s] R[%05X]
|
||||
503 Device\t\t\tAddress\tSize\tStatus
|
||||
504 %s\t%05X\t%05X\t%s
|
||||
505 Configured
|
||||
506 Size_configured
|
||||
507 *Unconfigured*
|
33
src/MSFs/saturn.msf
Normal file
33
src/MSFs/saturn.msf
Normal file
|
@ -0,0 +1,33 @@
|
|||
$ .+
|
||||
$ .identifier : $Id: saturn.msf,v 4.1 2000/12/11 09:54:19 cibrario Rel $
|
||||
$ .context : SATURN, Saturn CPU / HP48 emulator
|
||||
$ .title : $RCSfile: saturn.msf,v $
|
||||
$ .kind : Message catalog source
|
||||
$ .author : Ivan Cibrario B.
|
||||
$ .site : CSTV-CNR
|
||||
$ .creation : 8-Sep-2000
|
||||
$ .keywords : *
|
||||
$ .description :
|
||||
$ Message catalog source file for the main program.
|
||||
$ .notes :
|
||||
$ . $Log: saturn.msf,v $
|
||||
$ . Revision 4.1 2000/12/11 09:54:19 cibrario
|
||||
$ . Public release.
|
||||
$ .
|
||||
$ . Revision 3.9 2000/10/24 16:11:48 cibrario
|
||||
$ . Added messages 10/501 and 10/502 as suggested by GPL
|
||||
$ .
|
||||
$ . Revision 3.8 2000/10/19 15:01:20 cibrario
|
||||
$ . Bug fix:
|
||||
$ . Removed lines with empty directives
|
||||
$ .
|
||||
$ Revision 2.1 2000/09/08 15:35:43 cibrario
|
||||
$ *** empty log message ***
|
||||
$ .-
|
||||
|
||||
$set 1
|
||||
10 Main
|
||||
|
||||
$set 10
|
||||
501 saturn %s - A poor-man's emulator of HP48GX, HP49, HP39/40\nCopyright (C) 1998-2000 Ivan Cibrario Bertolotti\n
|
||||
502 This program is free software, and comes with ABSOLUTELY NO WARRANTY;\nfor details see the accompanying documentation.\n\n
|
62
src/MSFs/serial.msf
Normal file
62
src/MSFs/serial.msf
Normal file
|
@ -0,0 +1,62 @@
|
|||
$ .+
|
||||
$ .identifier : $Id: serial.msf,v 4.1 2000/12/11 09:54:19 cibrario Rel $
|
||||
$ .context : SATURN, Saturn CPU / HP48 emulator
|
||||
$ .title : $RCSfile: serial.msf,v $
|
||||
$ .kind : Message catalog source
|
||||
$ .author : Ivan Cibrario B.
|
||||
$ .site : CSTV-CNR
|
||||
$ .creation : 13-Sep-2000
|
||||
$ .keywords : *
|
||||
$ .description :
|
||||
$ Message catalog source file for the serial port emulator.
|
||||
$ .notes :
|
||||
$ . $Log: serial.msf,v $
|
||||
$ . Revision 4.1 2000/12/11 09:54:19 cibrario
|
||||
$ . Public release.
|
||||
$ .
|
||||
$ . Revision 3.16 2000/11/21 16:42:18 cibrario
|
||||
$ . Ultrix/IRIX support:
|
||||
$ . - New message: 203
|
||||
$ .
|
||||
$ . Revision 3.8 2000/10/19 15:00:10 cibrario
|
||||
$ . Bug fix:
|
||||
$ . Removed lines with empty directives
|
||||
$ .
|
||||
$ Revision 3.2 2000/09/22 14:38:08 cibrario
|
||||
$ Implemented preliminary support of HP49 hw architecture:
|
||||
$ - New messages: 408, 409
|
||||
$ .
|
||||
$ Revision 2.6 2000/09/15 09:26:18 cibrario
|
||||
$ Added new messages: 403, 404, 405, 406, 407,
|
||||
$ needed by the implementation of USE_STREAMSPTY
|
||||
$ .
|
||||
$ Revision 2.5 2000/09/14 15:44:49 cibrario
|
||||
$ *** empty log message ***
|
||||
$ .-
|
||||
|
||||
$set 1
|
||||
15 Serial
|
||||
|
||||
$set 15
|
||||
101 Function [%s] called
|
||||
102 Serial port emulator: [%s]
|
||||
103 Read [%s]; value [%01X]
|
||||
104 Write [%s]; value [%01X](old) -> [%01X](new)
|
||||
105 Read RBR; value [%02X]
|
||||
106 Write TBR; value [%02X]
|
||||
107 Pseudo-terminal name is [%s]
|
||||
201 Read from empty receiver buffer, rcs [%01X]
|
||||
202 Write into full transmitter buffer, tcs [%01X]
|
||||
203 Pseudo-terminals not supported
|
||||
301 Error draining transmitter buffer
|
||||
302 Error charging receiver buffer
|
||||
303 Error shutting down pseudo-terminal
|
||||
401 openpty() failed on master pty
|
||||
402 fcntl() failed on master pty
|
||||
403 Can't open() pty master [%s]
|
||||
404 grantpt() failed on master pty
|
||||
405 unlockpt() failed on master pty
|
||||
406 Can't open() pty slave [%s]
|
||||
407 ioctl(I_PUSH,[%s]) failed on slave pty
|
||||
408 tcgetattr() failed on master pty
|
||||
409 tcsetattr() failed on master pty
|
38
src/MSFs/util.msf
Normal file
38
src/MSFs/util.msf
Normal file
|
@ -0,0 +1,38 @@
|
|||
$ .+
|
||||
$ .identifier : $Id: util.msf,v 4.1 2000/12/11 09:54:19 cibrario Rel $
|
||||
$ .context : SATURN, Saturn CPU / HPxx emulator
|
||||
$ .title : $RCSfile: util.msf,v $
|
||||
$ .kind : Message catalog source
|
||||
$ .author : Ivan Cibrario B.
|
||||
$ .site : CSTV-CNR
|
||||
$ .creation : 2-Oct-2000
|
||||
$ .keywords : *
|
||||
$ .description :
|
||||
$ Message catalog source file for the utility programs.
|
||||
$ .notes :
|
||||
$ . $Log: util.msf,v $
|
||||
$ . Revision 4.1 2000/12/11 09:54:19 cibrario
|
||||
$ . Public release.
|
||||
$ .
|
||||
$ . Revision 3.8 2000/10/19 15:01:43 cibrario
|
||||
$ . Bug fix:
|
||||
$ . Removed lines with empty directives
|
||||
$ .
|
||||
$ Revision 3.6 2000/10/02 13:59:02 cibrario
|
||||
$ *** empty log message ***
|
||||
$ .-
|
||||
|
||||
$set 1
|
||||
17 Utilities
|
||||
|
||||
$set 17
|
||||
1 Usage:\n\
|
||||
pack <emu48_source_rom> <saturn_dest_rom>
|
||||
|
||||
2 Command line syntax error
|
||||
3 stat(%s) failed
|
||||
4 Invalid source file size: %d
|
||||
5 malloc(%d) failed
|
||||
6 open(%s) failed
|
||||
7 read(%s) failed
|
||||
8 WriteNibblesToFile() failed
|
77
src/MSFs/x11.msf
Normal file
77
src/MSFs/x11.msf
Normal file
|
@ -0,0 +1,77 @@
|
|||
$ .+
|
||||
$ .identifier : $Id: x11.msf,v 4.1 2000/12/11 09:54:19 cibrario Rel $
|
||||
$ .context : SATURN, Saturn CPU / HP48 emulator
|
||||
$ .title : $RCSfile: x11.msf,v $
|
||||
$ .kind : Message catalog source
|
||||
$ .author : Ivan Cibrario B.
|
||||
$ .site : CSTV-CNR
|
||||
$ .creation : 13-Feb-1998
|
||||
$ .keywords : *
|
||||
$ .description :
|
||||
$ Message catalog source file for the X11 interface modules and main program.
|
||||
$ .notes :
|
||||
$ . $Log: x11.msf,v $
|
||||
$ . Revision 4.1 2000/12/11 09:54:19 cibrario
|
||||
$ . Public release.
|
||||
$ .
|
||||
$ . Revision 3.17 2000/11/23 17:03:52 cibrario
|
||||
$ . Implemented sutil library and assorted bug fixes:
|
||||
$ . - Added ending newline
|
||||
$ .
|
||||
$ . Revision 3.16 2000/11/21 16:43:40 cibrario
|
||||
$ . Ultrix/IRIX support:
|
||||
$ . - Removed single quote from message 402
|
||||
$ .
|
||||
$ . Revision 3.15 2000/11/15 14:16:14 cibrario
|
||||
$ . GUI enhancements and assorted bug fixes:
|
||||
$ . - Revised message 108 to list the new command-line option -batchXfer
|
||||
$ . - Added new messages 204 and 402
|
||||
$ .
|
||||
$ . Revision 3.13 2000/11/09 11:39:18 cibrario
|
||||
$ . Revised to add file selection box GUI element, CPU halt/run
|
||||
$ . requests and emulator's extended functions:
|
||||
$ .
|
||||
$ . - New messages: 113, 114, 203, 303
|
||||
$ .
|
||||
$ . Revision 3.9 2000/10/24 16:12:25 cibrario
|
||||
$ . Revised messages 108 (updated command-line options) and 301
|
||||
$ .
|
||||
$ . Revision 3.8 2000/10/19 14:59:23 cibrario
|
||||
$ . Bug fix:
|
||||
$ . Removed lines with empty directives
|
||||
$ .
|
||||
$ Revision 2.1 2000/09/08 15:31:18 cibrario
|
||||
$ - Updated messages 104, 105, 108
|
||||
$ - Removed message 106
|
||||
$ - New messages 109, 110, 111, 112, 201, 202, 302
|
||||
$ .
|
||||
$ Revision 1.1 1998/02/19 12:01:14 cibrario
|
||||
$ Initial revision
|
||||
$ .-
|
||||
|
||||
$set 1
|
||||
14 X11
|
||||
|
||||
$set 14
|
||||
101 Function [%s] called
|
||||
102 LCD Parameter [%s]: [%05X]
|
||||
103 X Expose event LCD window, count=%d
|
||||
104 Pressed key [%s]
|
||||
105 Released key [%s]
|
||||
107 X11 Interface [%s]
|
||||
108 Usage:\n\t%s [-reset] [-monitor] [-batchXfer] [-stateDir <>]\n\t\t[-face <>] [-hw <>]\n\t\t[-cpu <>] [-mod <>] [-hdw <>]\n\t\t[-rom <>] [-ram <>] [-port1 <>] [-port2 <>]
|
||||
109 Selected GUI face [%s]
|
||||
110 Active GUI face has [%d] keys
|
||||
111 Created key [%d], inOut [%s]
|
||||
112 Found compoundString for widget [%s], value [%s]
|
||||
113 Traversing widget [%s]
|
||||
114 Current widget has [%d] children
|
||||
201 Xt action called with wrong argc: [%d]
|
||||
202 X Atom [%s] unknown
|
||||
203 FSB continuation procedure not set
|
||||
204 Too many messages not yet acknowledged (> [%d]).\n\tGUI logging temporarily suspended
|
||||
301 Invalid option [%s] ignored
|
||||
302 WM_COMMAND property bad or not set
|
||||
303 No text segment found in a FSB XmString
|
||||
401 X Window System fatal error
|
||||
402 Face [%s] has no keys; the application resource\n\tfile probably is missing, corrupt, or unreachable
|
46
src/MSFs/x_func.msf
Normal file
46
src/MSFs/x_func.msf
Normal file
|
@ -0,0 +1,46 @@
|
|||
$ .+
|
||||
$ .identifier : $Id: x_func.msf,v 4.1 2000/12/11 09:54:19 cibrario Rel $
|
||||
$ .context : SATURN, Saturn CPU / HPxx emulator
|
||||
$ .title : $RCSfile: x_func.msf,v $
|
||||
$ .kind : Message catalog source
|
||||
$ .author : Ivan Cibrario B.
|
||||
$ .site : CSTV-CNR
|
||||
$ .creation : 3-Nov-2000
|
||||
$ .keywords : *
|
||||
$ .description :
|
||||
$ Message catalog source file for the emulator's extended functions.
|
||||
$ .notes :
|
||||
$ . $Log: x_func.msf,v $
|
||||
$ . Revision 4.1 2000/12/11 09:54:19 cibrario
|
||||
$ . Public release.
|
||||
$ .
|
||||
$ . Revision 3.14 2000/11/13 11:14:19 cibrario
|
||||
$ . Implemented fast load/save; improved keyboard interface emulation at
|
||||
$ . high emulated CPU speed:
|
||||
$ .
|
||||
$ . - Added new messages: 105, 106, 107, 202, 203, 303, 501, 502
|
||||
$ .
|
||||
$ . Revision 3.13 2000/11/09 11:42:22 cibrario
|
||||
$ . *** empty log message ***
|
||||
$ .
|
||||
$ .-
|
||||
|
||||
$set 1
|
||||
18 X_Func
|
||||
|
||||
$set 18
|
||||
101 Function [%s] called
|
||||
102 Emulator's extended function #[%01X]
|
||||
103 Emulator speed set to [%d]MHz
|
||||
104 Emulator at maximum speed
|
||||
105 Transferring [%s]
|
||||
106 Kget START[%05X] END[%05X] HDR[%s]
|
||||
107 Send START[%05X] END[%05X] HDR[%s]
|
||||
201 Invalid function code #[%01X] ignored
|
||||
202 Operation aborted by user
|
||||
203 Operation failed
|
||||
301 Cpu Halt requests not allowed.\n\tRebuild with CPU_SPIN_SHUTDN undefined in config.h
|
||||
302 Cpu speed control not available.\n\tRebuild with REAL_CPU_SPEED defined in config.h
|
||||
303 Can't determine binary header for hw [%s]
|
||||
501 Load object from disk...
|
||||
502 Save object to disk...
|
534
src/___x11_lcd.c
Normal file
534
src/___x11_lcd.c
Normal file
|
@ -0,0 +1,534 @@
|
|||
/* -------------------------------------------------------------------------
|
||||
saturn - A poor-man's emulator of some HP calculators
|
||||
Copyright (C) 1998-2000 Ivan Cibrario Bertolotti
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with the documentation of this program; if not, write to
|
||||
the Free Software Foundation, Inc.,
|
||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
For more information, please contact the author, preferably by email,
|
||||
at the following address:
|
||||
|
||||
Ivan Cibrario Bertolotti
|
||||
IRITI - National Research Council
|
||||
c/o IEN "Galileo Ferraris"
|
||||
Strada delle Cacce, 91
|
||||
10135 - Torino (ITALY)
|
||||
|
||||
email: cibrario@iriti.cnr.it
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
/* +-+ */
|
||||
|
||||
/* .+
|
||||
|
||||
.identifier : $Id: display.c,v 4.1.1.1 2002/11/11 16:12:46 cibrario Exp $
|
||||
.context : SATURN, Saturn CPU / HP48 emulator
|
||||
.title : $RCSfile: display.c,v $
|
||||
.kind : C source
|
||||
.author : Ivan Cibrario B.
|
||||
.site : CSTV-CNR
|
||||
.creation : 29-Jan-1998
|
||||
.keywords : *
|
||||
.description :
|
||||
This source module emulates the Lcd driver of the Yorke chip.
|
||||
|
||||
References:
|
||||
|
||||
SASM.DOC by HP (HORN disk 4)
|
||||
Guide to the Saturn Processor Rev. 0.00f by Matthew Mastracci
|
||||
entries.srt by Mika Heiskanen (mheiskan@vipunen.hut.fi)
|
||||
x48 source code by Eddie C. Dost (ecd@dressler.de)
|
||||
|
||||
NOTE: In the current (r1.1) implementation, the control fields
|
||||
mod_status.hdw.lcd_offset and mod_status.hdw.lcd_contrast are
|
||||
not supported. Therefore, the emulation accuracy is sometimes
|
||||
poor; for example, the Equation Writer does not work well with
|
||||
large equations.
|
||||
|
||||
.include : config.h, machdep.h, cpu.h, modules.h, display.h
|
||||
|
||||
.notes :
|
||||
$Log: display.c,v $
|
||||
Revision 4.1.1.1 2002/11/11 16:12:46 cibrario
|
||||
Small screen support; preliminary
|
||||
|
||||
Revision 4.1 2000/12/11 09:54:19 cibrario
|
||||
Public release.
|
||||
|
||||
Revision 3.10 2000/10/24 16:14:37 cibrario
|
||||
Added/Replaced GPL header
|
||||
|
||||
Revision 3.8 2000/10/23 13:15:36 cibrario
|
||||
Bug fix:
|
||||
In InitLcd(), added a clip rectangle to GC, to avoid drawing non-existent
|
||||
pixels, that is, pixels that *do* exist in the frame buffer, but should
|
||||
never be viewed on screen.
|
||||
|
||||
Revision 3.5 2000/10/02 09:44:42 cibrario
|
||||
Linux support:
|
||||
- gcc does not like array subscripts with type 'char', and it is right.
|
||||
|
||||
Revision 3.1 2000/09/20 13:47:58 cibrario
|
||||
Minor updates and fixes to avoid gcc compiler warnings on Solaris
|
||||
when -ansi -pedantic -Wall options are selected.
|
||||
|
||||
* Revision 1.1 1998/02/17 14:14:39 cibrario
|
||||
* Initial revision
|
||||
*
|
||||
|
||||
.- */
|
||||
|
||||
#ifndef lint
|
||||
static char rcs_id[] = "$Id: display.c,v 4.1.1.1 2002/11/11 16:12:46 cibrario Exp $";
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <setjmp.h>
|
||||
#include <string.h> /* 3.1: memset() */
|
||||
|
||||
#include <X11/Xlib.h>
|
||||
|
||||
#include "config.h"
|
||||
#include "machdep.h"
|
||||
#include "cpu.h"
|
||||
#include "modules.h"
|
||||
#include "x11_lcd.h"
|
||||
#include "x11.h"
|
||||
#include "debug.h"
|
||||
|
||||
#define CHF_MODULE_ID X11_CHF_MODULE_ID
|
||||
#include <Chf.h>
|
||||
|
||||
#ifndef LCD_MAG
|
||||
# define LCD_MAG 2 /* 4.1.1.1: Compat. default */
|
||||
#endif
|
||||
|
||||
#define NIBBLES_PER_ROW 34 /* 136 pixel total */
|
||||
#define MAX_ROWS 64 /* 64 rows total */
|
||||
#define N_ANN 6 /* # of annunciators */
|
||||
#define LCD_X_ORIGIN 1 + 4 * ( LCD_MAG - 1 ) /* x origin */
|
||||
|
||||
#if LCD_MAG == 1
|
||||
# define LCD_Y_ORIGIN 14 /* y origin */
|
||||
#else
|
||||
# define LCD_Y_ORIGIN 20 /* y origin */
|
||||
#endif
|
||||
|
||||
/* 3.8: Origin and size of clip rectangle */
|
||||
#define LCD_CLIP_X_ORIGIN LCD_X_ORIGIN
|
||||
#define LCD_CLIP_Y_ORIGIN 0 /* Don't clip annunciators */
|
||||
#define LCD_CLIP_WIDTH 131 * LCD_MAG
|
||||
#define LCD_CLIP_HEIGHT LCD_Y_ORIGIN + 64 * LCD_MAG
|
||||
|
||||
#define MASK_ANN_LEFT 0x81 /* Annunciator's bit masks */
|
||||
#define MASK_ANN_RIGHT 0x82
|
||||
#define MASK_ANN_ALPHA 0x84
|
||||
#define MASK_ANN_BATTERY 0x88
|
||||
#define MASK_ANN_BUSY 0x90
|
||||
#define MASK_ANN_IO 0xA0
|
||||
|
||||
/*---------------------------------------------------------------------------
|
||||
Static/Global variables
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
static /*const*/ unsigned char nibble_bitmap_data[ NIBBLE_VALUES ][ LCD_MAG ] = {
|
||||
#if LCD_MAG == 1
|
||||
{ 0x00 }, /* ---- */
|
||||
{ 0x01 }, /* *--- */
|
||||
{ 0x02 }, /* -*-- */
|
||||
{ 0x03 }, /* **-- */
|
||||
{ 0x04 }, /* --*- */
|
||||
{ 0x05 }, /* *-*- */
|
||||
{ 0x06 }, /* -**- */
|
||||
{ 0x07 }, /* ***- */
|
||||
{ 0x08 }, /* ---* */
|
||||
{ 0x09 }, /* *--* */
|
||||
{ 0x0a }, /* -*-* */
|
||||
{ 0x0b }, /* **-* */
|
||||
{ 0x0c }, /* --** */
|
||||
{ 0x0d }, /* *-** */
|
||||
{ 0x0e }, /* -*** */
|
||||
{ 0x0f } /* **** */
|
||||
#elif LCD_MAG == 2
|
||||
{ 0x00, 0x00 }, /* ---- */
|
||||
{ 0x03, 0x03 }, /* *--- */
|
||||
{ 0x0c, 0x0c }, /* -*-- */
|
||||
{ 0x0f, 0x0f }, /* **-- */
|
||||
{ 0x30, 0x30 }, /* --*- */
|
||||
{ 0x33, 0x33 }, /* *-*- */
|
||||
{ 0x3c, 0x3c }, /* -**- */
|
||||
{ 0x3f, 0x3f }, /* ***- */
|
||||
{ 0xc0, 0xc0 }, /* ---* */
|
||||
{ 0xc3, 0xc3 }, /* *--* */
|
||||
{ 0xcc, 0xcc }, /* -*-* */
|
||||
{ 0xcf, 0xcf }, /* **-* */
|
||||
{ 0xf0, 0xf0 }, /* --** */
|
||||
{ 0xf3, 0xf3 }, /* *-** */
|
||||
{ 0xfc, 0xfc }, /* -*** */
|
||||
{ 0xff, 0xff } /* **** */
|
||||
#else
|
||||
# error "Bad LCD_MAG; supported values are 1 and 2"
|
||||
#endif
|
||||
};
|
||||
|
||||
#define ANN_X( i ) ( 8 * LCD_MAG + ( 22 * LCD_MAG + 1 ) * i )
|
||||
#define ANN_Y( i ) ( 1 + 3 * ( LCD_MAG - 1 ) )
|
||||
static /*const*/ struct {
|
||||
int mask; /* Bit mask */
|
||||
int x, y; /* Position */
|
||||
int w, h; /* Width, Height */
|
||||
unsigned char bitmap_data[ 24 ]; /* Bitmap data */
|
||||
} ann_data[ N_ANN ] = {
|
||||
{MASK_ANN_LEFT, ANN_X( 0 ), ANN_Y( 0 ), 15, 12, { 0xfe, 0x3f, 0xff, 0x7f, 0x9f, 0x7f, 0xcf, 0x7f, 0xe7, 0x7f, 0x03, 0x78,
|
||||
0x03, 0x70, 0xe7, 0x73, 0xcf, 0x73, 0x9f, 0x73, 0xff, 0x73, 0xfe, 0x33 } },
|
||||
{MASK_ANN_RIGHT, ANN_X( 1 ), ANN_Y( 1 ), 15, 12, { 0xfe, 0x3f, 0xff, 0x7f, 0xff, 0x7c, 0xff, 0x79, 0xff, 0x73, 0x0f, 0x60,
|
||||
0x07, 0x60, 0xe7, 0x73, 0xe7, 0x79, 0xe7, 0x7c, 0xe7, 0x7f, 0xe6, 0x3f } },
|
||||
{MASK_ANN_ALPHA, ANN_X( 2 ), ANN_Y( 2 ), 15, 12, { 0xe0, 0x03, 0x18, 0x44, 0x0c, 0x4c, 0x06, 0x2c, 0x07, 0x2c, 0x07, 0x1c,
|
||||
0x07, 0x0c, 0x07, 0x0c, 0x07, 0x0e, 0x0e, 0x4d, 0xf8, 0x38, 0x00, 0x00 } },
|
||||
{MASK_ANN_BATTERY, ANN_X( 3 ), ANN_Y( 3 ), 15, 12, { 0x04, 0x10, 0x02, 0x20, 0x12, 0x24, 0x09, 0x48, 0xc9, 0x49, 0xc9, 0x49,
|
||||
0xc9, 0x49, 0x09, 0x48, 0x12, 0x24, 0x02, 0x20, 0x04, 0x10, 0x00, 0x00 }},
|
||||
{MASK_ANN_BUSY, ANN_X( 4 ), ANN_Y( 4 ), 15, 12, { 0xfc, 0x1f, 0x08, 0x08, 0x08, 0x08, 0xf0, 0x07, 0xe0, 0x03, 0xc0, 0x01,
|
||||
0x40, 0x01, 0x20, 0x02, 0x10, 0x04, 0xc8, 0x09, 0xe8, 0x0b, 0xfc, 0x1f } },
|
||||
{MASK_ANN_IO, ANN_X( 5 ), ANN_Y( 5 ), 15, 12, { 0x0c, 0x00, 0x1e, 0x00, 0x33, 0x0c, 0x61, 0x18, 0xcc, 0x30, 0xfe, 0x7f,
|
||||
0xfe, 0x7f, 0xcc, 0x30, 0x61, 0x18, 0x33, 0x0c, 0x1e, 0x00, 0x0c, 0x00 } }
|
||||
};
|
||||
|
||||
static Nibble lcd_buffer[ MAX_ROWS ][ NIBBLES_PER_ROW ];
|
||||
static int ann_buffer;
|
||||
static int clean;
|
||||
|
||||
static Display* display;
|
||||
static Window window;
|
||||
static GC gc;
|
||||
static unsigned long fg_pixel, bg_pixel;
|
||||
static unsigned int depth;
|
||||
|
||||
static Pixmap nibble_pixmap[ NIBBLE_VALUES ];
|
||||
static Pixmap ann_pixmap[ N_ANN ];
|
||||
|
||||
/*---------------------------------------------------------------------------
|
||||
Private functions
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
/* .+
|
||||
|
||||
.title : InitPixmaps
|
||||
.kind : C function
|
||||
.creation : 29-Jan-1998
|
||||
.description :
|
||||
This function initializes the pixmaps for the Lcd screen elements and
|
||||
stores them into the appropriate global variables.
|
||||
|
||||
.call :
|
||||
InitPixmaps();
|
||||
.input :
|
||||
void
|
||||
.output :
|
||||
void
|
||||
.status_codes :
|
||||
X11_I_CALLED
|
||||
X11_F_X_ERROR
|
||||
.notes :
|
||||
1.1, 29-Jan-1998, creation
|
||||
|
||||
.- */
|
||||
static void InitPixmaps( void )
|
||||
{
|
||||
int i;
|
||||
|
||||
debug1( DEBUG_C_TRACE, X11_I_CALLED, "InitPixmaps" );
|
||||
|
||||
/* Initialize nibble_pixmap */
|
||||
for ( i = 0; i < NIBBLE_VALUES; i++ ) {
|
||||
if ( ( nibble_pixmap[ i ] = XCreatePixmapFromBitmapData( display, window, ( char* )nibble_bitmap_data[ i ], 4 * LCD_MAG, LCD_MAG,
|
||||
fg_pixel, bg_pixel, depth ) ) == None ) {
|
||||
ChfCondition X11_F_X_ERROR, CHF_FATAL ChfEnd;
|
||||
ChfSignal();
|
||||
}
|
||||
}
|
||||
|
||||
/* Initialize ann_pixmap */
|
||||
for ( i = 0; i < N_ANN; i++ ) {
|
||||
if ( ( ann_pixmap[ i ] = XCreatePixmapFromBitmapData( display, window, ( char* )ann_data[ i ].bitmap_data, ann_data[ i ].w,
|
||||
ann_data[ i ].h, fg_pixel, bg_pixel, depth ) ) == None ) {
|
||||
ChfCondition X11_F_X_ERROR, CHF_FATAL ChfEnd;
|
||||
ChfSignal();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* .+
|
||||
|
||||
.title : ClearLcd
|
||||
.kind : C function
|
||||
.creation : 29-Jan-1998
|
||||
.description :
|
||||
This function clears the Lcd screen
|
||||
|
||||
.call :
|
||||
ClearLcd();
|
||||
.input :
|
||||
void
|
||||
.output :
|
||||
void
|
||||
.status_codes :
|
||||
X11_I_CALLED
|
||||
.notes :
|
||||
1.1, 29-Jan-1998, creation
|
||||
|
||||
.- */
|
||||
static void ClearLcd( void )
|
||||
{
|
||||
debug1( DEBUG_C_TRACE, X11_I_CALLED, "ClearLcd" );
|
||||
|
||||
/* Clear Lcd display */
|
||||
( void )memset( ( void* )lcd_buffer, 0, sizeof( lcd_buffer ) );
|
||||
ann_buffer = 0;
|
||||
|
||||
XClearWindow( display, window );
|
||||
XFlush( display );
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------
|
||||
Public funcitons
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
/* .+
|
||||
|
||||
.title : InitLcd
|
||||
.kind : C function
|
||||
.creation : 29-Jan-1998
|
||||
.description :
|
||||
This function initializes the Lcd driver emulator and prepares it for use.
|
||||
The LCD screen is initially cleared.
|
||||
|
||||
.call :
|
||||
InitLcd(lcd_display, lcd_window, lcd_fg_pixel, lcd_bg_pixel);
|
||||
.input :
|
||||
Display *lcd_display, X display
|
||||
Window lcd_window, X window to be used for display
|
||||
unsigned long lcd_fg_pixel, foreground color to be used
|
||||
unsigned long lcd_bg_pixel, background color to be used
|
||||
.output :
|
||||
void
|
||||
.status_codes :
|
||||
X11_I_CALLED
|
||||
X11_F_X_ERROR
|
||||
.notes :
|
||||
1.1, 29-Jan-1998, creation
|
||||
3.8, 23-Oct-2000, bug fix:
|
||||
- added clip rectangle to GC, to avoid drawing non-existent pixels.
|
||||
|
||||
.- */
|
||||
void InitLcd( Display* lcd_display, Window lcd_window, unsigned long lcd_fg_pixel, unsigned long lcd_bg_pixel )
|
||||
{
|
||||
XWindowAttributes xwa;
|
||||
XGCValues gc_values;
|
||||
|
||||
debug1( DEBUG_C_TRACE, X11_I_CALLED, "InitLcdWindow" );
|
||||
|
||||
display = lcd_display;
|
||||
window = lcd_window;
|
||||
fg_pixel = lcd_fg_pixel;
|
||||
bg_pixel = lcd_bg_pixel;
|
||||
|
||||
/* Get window attributes and initialize window depth */
|
||||
if ( XGetWindowAttributes( display, window, &xwa ) == 0 ) {
|
||||
ChfCondition X11_F_X_ERROR, CHF_FATAL ChfEnd;
|
||||
ChfSignal();
|
||||
}
|
||||
|
||||
depth = xwa.depth;
|
||||
|
||||
/* Create GC */
|
||||
gc_values.function = GXcopy;
|
||||
gc_values.plane_mask = AllPlanes;
|
||||
gc_values.subwindow_mode = IncludeInferiors;
|
||||
gc_values.foreground = lcd_fg_pixel;
|
||||
gc_values.background = lcd_bg_pixel;
|
||||
gc_values.graphics_exposures = False;
|
||||
|
||||
gc = XCreateGC( display, window, GCFunction | GCPlaneMask | GCForeground | GCBackground | GCSubwindowMode | GCGraphicsExposures,
|
||||
&gc_values );
|
||||
|
||||
{
|
||||
/* 3.8: This clip rectangle prevents XCopyArea() (in DrawLcd()) from
|
||||
drawing non-visible pixels
|
||||
*/
|
||||
XRectangle rect[ 1 ];
|
||||
|
||||
rect[ 0 ].x = LCD_CLIP_X_ORIGIN; /* This is the clip rectangle */
|
||||
rect[ 0 ].y = LCD_CLIP_Y_ORIGIN;
|
||||
rect[ 0 ].width = LCD_CLIP_WIDTH;
|
||||
rect[ 0 ].height = LCD_CLIP_HEIGHT;
|
||||
|
||||
XSetClipRectangles( display, gc, 0, 0, /* Alsolute clip X,Y origin */
|
||||
rect, 1, YXBanded );
|
||||
}
|
||||
|
||||
/* Initialize Pixmaps */
|
||||
InitPixmaps();
|
||||
|
||||
/* Clear screen and initialize the static memory areas */
|
||||
ClearLcd();
|
||||
|
||||
/* Set the 'display is clean' flag */
|
||||
clean = 1;
|
||||
}
|
||||
|
||||
/* .+
|
||||
|
||||
.title : DrawLcd
|
||||
.kind : C function
|
||||
.creation : 29-Jan-1998
|
||||
.description :
|
||||
This function redraws the Lcd screen from the information contained in
|
||||
the mod_status.hdw structure.
|
||||
|
||||
.call :
|
||||
DrawLcd();
|
||||
.input :
|
||||
void
|
||||
.output :
|
||||
void
|
||||
.status_codes :
|
||||
X11_I_CALLED
|
||||
X11_I_LCD_PAR
|
||||
.notes :
|
||||
1.1, 29-Jan-1998, creation
|
||||
|
||||
.- */
|
||||
void DrawLcd( void )
|
||||
{
|
||||
Address addr = mod_status.hdw.lcd_base_addr;
|
||||
int y, x;
|
||||
Nibble v;
|
||||
|
||||
debug1( DEBUG_C_TRACE, X11_I_CALLED, "DrawLcd" );
|
||||
|
||||
/* If the debug class DEBUG_C_DISPLAY is enabled, print the display
|
||||
parameters
|
||||
*/
|
||||
debug2( DEBUG_C_DISPLAY, X11_I_LCD_PAR, "_base_addr", ( int )mod_status.hdw.lcd_base_addr );
|
||||
|
||||
debug2( DEBUG_C_DISPLAY, X11_I_LCD_PAR, "_on", ( int )mod_status.hdw.lcd_on );
|
||||
|
||||
debug2( DEBUG_C_DISPLAY, X11_I_LCD_PAR, "_contrast", ( int )mod_status.hdw.lcd_contrast );
|
||||
|
||||
debug2( DEBUG_C_DISPLAY, X11_I_LCD_PAR, "_vlc", ( int )mod_status.hdw.lcd_vlc );
|
||||
|
||||
debug2( DEBUG_C_DISPLAY, X11_I_LCD_PAR, "_offset", ( int )mod_status.hdw.lcd_offset );
|
||||
|
||||
debug2( DEBUG_C_DISPLAY, X11_I_LCD_PAR, "_line_offset", ( int )mod_status.hdw.lcd_line_offset );
|
||||
|
||||
debug2( DEBUG_C_DISPLAY, X11_I_LCD_PAR, "_menu_addr", ( int )mod_status.hdw.lcd_menu_addr );
|
||||
|
||||
debug2( DEBUG_C_DISPLAY, X11_I_LCD_PAR, "_ann", ( int )mod_status.hdw.lcd_ann );
|
||||
|
||||
/* Check if display is on */
|
||||
if ( !mod_status.hdw.lcd_on ) {
|
||||
/* Display is off; clear lcd if necessary */
|
||||
if ( !clean ) {
|
||||
/* Set the 'display is clean' flag and clear the screen */
|
||||
clean = 1;
|
||||
ClearLcd();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/* The display is on and will be no longer clean */
|
||||
clean = 0;
|
||||
|
||||
/* Scan active display rows */
|
||||
for ( y = 0; y <= mod_status.hdw.lcd_vlc; y++ ) {
|
||||
/* Scan columns */
|
||||
for ( x = 0; x < NIBBLES_PER_ROW; x++ ) {
|
||||
v = FetchNibble( addr++ );
|
||||
if ( v != lcd_buffer[ y ][ x ] ) {
|
||||
lcd_buffer[ y ][ x ] = v;
|
||||
|
||||
XCopyArea( display, nibble_pixmap[ ( int )v ], window, gc, 0, 0, /* src_x, src_y */
|
||||
4 * LCD_MAG, LCD_MAG, /* width, height */
|
||||
x * 4 * LCD_MAG + LCD_X_ORIGIN, y * LCD_MAG + LCD_Y_ORIGIN );
|
||||
}
|
||||
}
|
||||
|
||||
addr += mod_status.hdw.lcd_line_offset;
|
||||
}
|
||||
|
||||
/* Scan menu display rows */
|
||||
addr = mod_status.hdw.lcd_menu_addr;
|
||||
for ( ; y < MAX_ROWS; y++ ) {
|
||||
/* Scan columns */
|
||||
for ( x = 0; x < NIBBLES_PER_ROW; x++ ) {
|
||||
v = FetchNibble( addr++ );
|
||||
if ( v != lcd_buffer[ y ][ x ] ) {
|
||||
lcd_buffer[ y ][ x ] = v;
|
||||
|
||||
XCopyArea( display, nibble_pixmap[ ( int )v ], window, gc, 0, 0, /* src_x, src_y */
|
||||
4 * LCD_MAG, LCD_MAG, /* width, height */
|
||||
x * 4 * LCD_MAG + LCD_X_ORIGIN, y * LCD_MAG + LCD_Y_ORIGIN );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Scan annunciators */
|
||||
if ( mod_status.hdw.lcd_ann != ann_buffer ) {
|
||||
ann_buffer = mod_status.hdw.lcd_ann;
|
||||
|
||||
for ( y = 0; y < N_ANN; y++ ) {
|
||||
if ( ( ann_buffer & ann_data[ y ].mask ) == ann_data[ y ].mask ) {
|
||||
XCopyArea( display, ann_pixmap[ y ], window, gc, 0, 0, /* src_x, src_y */
|
||||
ann_data[ y ].w, ann_data[ y ].h, /* width, height */
|
||||
ann_data[ y ].x, ann_data[ y ].y );
|
||||
} else {
|
||||
XClearArea( display, window, ann_data[ y ].x, ann_data[ y ].y, ann_data[ y ].w, ann_data[ y ].h, False /* No exposures */
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Flush display */
|
||||
XFlush( display );
|
||||
}
|
||||
|
||||
/* .+
|
||||
|
||||
.title : RefreshLcd
|
||||
.kind : C function
|
||||
.creation : 17-Feb-1998
|
||||
.description :
|
||||
This function refreshes the Lcd screen after a X Window Expose event.
|
||||
|
||||
.call :
|
||||
RefreshLcd();
|
||||
.input :
|
||||
void
|
||||
.output :
|
||||
void
|
||||
.status_codes :
|
||||
X11_I_CALLED
|
||||
.notes :
|
||||
1.1, 17-Feb-1998, creation
|
||||
|
||||
.- */
|
||||
void RefreshLcd( void )
|
||||
{
|
||||
debug1( DEBUG_C_TRACE, X11_I_CALLED, "RefreshLcd" );
|
||||
|
||||
ClearLcd();
|
||||
DrawLcd();
|
||||
}
|
95
src/___x11_lcd.h
Normal file
95
src/___x11_lcd.h
Normal file
|
@ -0,0 +1,95 @@
|
|||
#ifndef _DISPLAY_H
|
||||
#define _DISPLAY_H 1
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
saturn - A poor-man's emulator of some HP calculators
|
||||
Copyright (C) 1998-2000 Ivan Cibrario Bertolotti
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with the documentation of this program; if not, write to
|
||||
the Free Software Foundation, Inc.,
|
||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
For more information, please contact the author, preferably by email,
|
||||
at the following address:
|
||||
|
||||
Ivan Cibrario Bertolotti
|
||||
IRITI - National Research Council
|
||||
c/o IEN "Galileo Ferraris"
|
||||
Strada delle Cacce, 91
|
||||
10135 - Torino (ITALY)
|
||||
|
||||
email: cibrario@iriti.cnr.it
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
/* +-+ */
|
||||
|
||||
/* .+
|
||||
|
||||
.identifier : $Id: display.h,v 4.1 2000/12/11 09:54:19 cibrario Rel $
|
||||
.context : SATURN, Saturn CPU / HP48 emulator
|
||||
.title : $RCSfile: display.h,v $
|
||||
.kind : C header
|
||||
.author : Ivan Cibrario B.
|
||||
.site : CSTV-CNR
|
||||
.creation : 28-Jan-1998
|
||||
.keywords : *
|
||||
.description :
|
||||
This header contains all definitions and declarations related to the
|
||||
HP48's LCD display emulator. References:
|
||||
|
||||
SASM.DOC by HP (HORN disk 4)
|
||||
Guide to the Saturn Processor Rev. 0.00f by Matthew Mastracci
|
||||
entries.srt by Mika Heiskanen (mheiskan@vipunen.hut.fi)
|
||||
x48 source code by Eddie C. Dost (ecd@dressler.de)
|
||||
|
||||
.include : config.h, machdep.h, cpu.h, modules.h, X11/Xlib.h
|
||||
|
||||
.notes :
|
||||
$Log: display.h,v $
|
||||
Revision 4.1 2000/12/11 09:54:19 cibrario
|
||||
Public release.
|
||||
|
||||
Revision 3.10 2000/10/24 16:14:38 cibrario
|
||||
Added/Replaced GPL header
|
||||
|
||||
Revision 1.1 1998/02/17 11:51:31 cibrario
|
||||
Initial revision
|
||||
|
||||
|
||||
.- */
|
||||
|
||||
#include <X11/Xlib.h> /* for InitLcd ( Display* ; Window ) */
|
||||
|
||||
/*---------------------------------------------------------------------------
|
||||
Data type definitions - require config.h, machdep.h, cpu.h
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
/*---------------------------------------------------------------------------
|
||||
Macros
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
/*---------------------------------------------------------------------------
|
||||
Global variables
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
/*---------------------------------------------------------------------------
|
||||
Function prototypes
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
void InitLcd( Display* lcd_display, Window lcd_window, unsigned long lcd_fg_pixel, unsigned long lcd_bg_pixel ); /* used in x11.c */
|
||||
|
||||
void DrawLcd( void ); /* used in emulator.c */
|
||||
void RefreshLcd( void ); /* used in x11.c */
|
||||
|
||||
#endif /*!_DISPLAY_H*/
|
286
src/___x11_main.c
Normal file
286
src/___x11_main.c
Normal file
|
@ -0,0 +1,286 @@
|
|||
/* -------------------------------------------------------------------------
|
||||
saturn - A poor-man's emulator of some HP calculators
|
||||
Copyright (C) 1998-2000 Ivan Cibrario Bertolotti
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with the documentation of this program; if not, write to
|
||||
the Free Software Foundation, Inc.,
|
||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
For more information, please contact the author, preferably by email,
|
||||
at the following address:
|
||||
|
||||
Ivan Cibrario Bertolotti
|
||||
IRITI - National Research Council
|
||||
c/o IEN "Galileo Ferraris"
|
||||
Strada delle Cacce, 91
|
||||
10135 - Torino (ITALY)
|
||||
|
||||
email: cibrario@iriti.cnr.it
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
/* +-+ */
|
||||
|
||||
/* .+
|
||||
|
||||
.identifier : $Id: saturn.c,v 4.1 2000/12/11 09:54:19 cibrario Rel $
|
||||
.context : SATURN, Saturn CPU / HP48 emulator
|
||||
.title : $RCSfile: saturn.c,v $
|
||||
.kind : C source
|
||||
.author : Ivan Cibrario B.
|
||||
.site : CSTV-CNR
|
||||
.creation : 8-Sep-2000
|
||||
.keywords : *
|
||||
.description :
|
||||
This file contains the main program of the Saturn CPU / HP4x emulator
|
||||
|
||||
.include : *
|
||||
|
||||
.notes :
|
||||
$Log: saturn.c,v $
|
||||
Revision 4.1 2000/12/11 09:54:19 cibrario
|
||||
Public release.
|
||||
|
||||
Revision 3.15 2000/11/15 14:07:53 cibrario
|
||||
GUI enhancements and assorted bug fixes:
|
||||
|
||||
- made Chf initialization more robust with respect to incorrect
|
||||
locale settings
|
||||
|
||||
- made stand-alone messages conforming to Chf standard format
|
||||
|
||||
- the copyright notice is now output through the GUI, too, if stdout
|
||||
is not a tty
|
||||
|
||||
Revision 3.14 2000/11/13 11:31:16 cibrario
|
||||
Implemented fast load/save; improved keyboard interface emulation at
|
||||
high emulated CPU speed:
|
||||
|
||||
- Revision number bump with no changes
|
||||
|
||||
Revision 3.11 2000/10/25 11:14:35 cibrario
|
||||
*** empty log message ***
|
||||
|
||||
Revision 3.10 2000/10/24 16:14:56 cibrario
|
||||
Added/Replaced GPL header
|
||||
|
||||
Revision 3.9 2000/10/24 16:11:20 cibrario
|
||||
The main program now has its own set of condition codes;
|
||||
added printf of MAIN_M_COPYRIGHT and MAIN_M_LICENSE as suggested by GPL
|
||||
|
||||
Revision 3.8 2000/10/23 13:16:49 cibrario
|
||||
Bug fix:
|
||||
Improper use of sizeof() in main() could give a segmentation fault.
|
||||
|
||||
Revision 3.1 2000/09/20 13:58:41 cibrario
|
||||
Minor updates and fixes to avoid gcc compiler warnings on Solaris
|
||||
when -ansi -pedantic -Wall options are selected.
|
||||
|
||||
* Revision 2.5 2000/09/14 15:32:07 cibrario
|
||||
* Added invotation of SerialInit() in main program, to initialize
|
||||
* the serial port emulation module.
|
||||
*
|
||||
* Revision 2.1 2000/09/08 15:46:02 cibrario
|
||||
* *** empty log message ***
|
||||
*
|
||||
|
||||
.- */
|
||||
|
||||
#ifndef lint
|
||||
static char rcs_id[] = "$Id: saturn.c,v 4.1 2000/12/11 09:54:19 cibrario Rel $";
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
// #include <setjmp.h>
|
||||
#include <string.h> /* 3.1: strcpy(), strcat() */
|
||||
#include <unistd.h> /* isatty() */
|
||||
|
||||
#include "config.h"
|
||||
#include "machdep.h"
|
||||
#include "cpu.h"
|
||||
#include "x11.h"
|
||||
#include "serial.h"
|
||||
#include "debug.h"
|
||||
#include "monitor.h"
|
||||
|
||||
/* Chf condition codes (main program only) */
|
||||
|
||||
#define CHF_MODULE_ID MAIN_CHF_MODULE_ID
|
||||
#include <Chf.h>
|
||||
|
||||
#define MAIN_M_COPYRIGHT 501
|
||||
#define MAIN_M_LICENSE 502
|
||||
|
||||
/*---------------------------------------------------------------------------
|
||||
Chf parameters - Do not change.
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
#define CONDITION_STACK_SIZE 16
|
||||
#define HANDLER_STACK_SIZE 8
|
||||
|
||||
/* Conditional prefix and mandatory suffix to make a message catalog
|
||||
name from argv[0]
|
||||
*/
|
||||
static const char cat_prefix[] = "./";
|
||||
static const char cat_suffix[] = ".cat";
|
||||
|
||||
#define CAT_PREFIX_LEN ( sizeof( cat_prefix ) + 1 )
|
||||
#define CAT_SUFFIX_LEN ( sizeof( cat_suffix ) + 1 )
|
||||
|
||||
static void adjust_setlocale( void )
|
||||
{
|
||||
fprintf( stderr, "saturn-W-locale probably bad; reverting to C locale\n" );
|
||||
|
||||
putenv( "LC_ALL=C" );
|
||||
putenv( "LC_COLLATE=C" );
|
||||
putenv( "LC_CTYPE=C" );
|
||||
putenv( "LC_MESSAGES=C" );
|
||||
putenv( "LC_MONETARY=C" );
|
||||
putenv( "LC_NUMERIC=C" );
|
||||
putenv( "LC_TIME=C" );
|
||||
putenv( "LANG=C" );
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------
|
||||
Public functions
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
/* .+
|
||||
|
||||
.title : main
|
||||
.kind : C function
|
||||
.creation : 8-Sep-2000
|
||||
.description :
|
||||
Main program.
|
||||
|
||||
.notes :
|
||||
2.1, 6-Sep-2000, creation
|
||||
2.5, 14-Sep-2000, update
|
||||
- added invotation of SerialInit().
|
||||
3.9, 23-Oct-2000, update
|
||||
- main() now has its own set of condition codes
|
||||
3.15, 15-Nov-2000, update
|
||||
- made Chf initialization more robust with respect to bad locales
|
||||
|
||||
.- */
|
||||
int main( int argc, char* argv[] )
|
||||
{
|
||||
char* cat_name;
|
||||
int st;
|
||||
int retry = 0;
|
||||
|
||||
if ( ( cat_name = malloc( strlen( argv[ 0 ] ) + CAT_PREFIX_LEN + CAT_SUFFIX_LEN + 1 ) ) == NULL ) {
|
||||
fprintf( stderr, "saturn-E-cat_name initialization failed\n" );
|
||||
exit( EXIT_FAILURE );
|
||||
}
|
||||
|
||||
/* Generate catalog name, without optional prefix */
|
||||
strcpy( cat_name, argv[ 0 ] );
|
||||
strcat( cat_name, cat_suffix );
|
||||
|
||||
/* 3.15: Retry the initialization steps below two times; before trying
|
||||
the second time, adjust the setlocale() environment variables
|
||||
with adjust_setlocale()
|
||||
*/
|
||||
while ( retry < 2 ) {
|
||||
/* Chf initialization with msgcat subsystem; notice that on
|
||||
some systems (e.g. Digital UNIX) catopen() can succeed even
|
||||
if it was not able to open the right message catalog;
|
||||
better try it now.
|
||||
*/
|
||||
if ( ( st = ChfMsgcatInit( argv[ 0 ], /* Application's name */
|
||||
CHF_DEFAULT, /* Options */
|
||||
cat_name, /* Name of the message catalog */
|
||||
CONDITION_STACK_SIZE, /* Size of the condition stack */
|
||||
HANDLER_STACK_SIZE, /* Size of the handler stack */
|
||||
EXIT_FAILURE /* Abnormal exit code */
|
||||
) ) != CHF_S_OK ||
|
||||
ChfGetMessage( CHF_MODULE_ID, MAIN_M_COPYRIGHT, NULL ) == NULL )
|
||||
fprintf( stderr, "saturn-E-Primary Chf initialization failed (%d)\n", st );
|
||||
else
|
||||
break;
|
||||
|
||||
/* Bring down Chf before initializing it again */
|
||||
if ( st == CHF_S_OK )
|
||||
ChfExit();
|
||||
|
||||
/* Try alternate message catalog name (with prefix) */
|
||||
strcpy( cat_name, cat_prefix );
|
||||
strcat( cat_name, argv[ 0 ] );
|
||||
strcat( cat_name, cat_suffix );
|
||||
|
||||
if ( ( st = ChfMsgcatInit( argv[ 0 ], /* Application's name */
|
||||
CHF_DEFAULT, /* Options */
|
||||
cat_name, /* Name of the message catalog */
|
||||
CONDITION_STACK_SIZE, /* Size of the condition stack */
|
||||
HANDLER_STACK_SIZE, /* Size of the handler stack */
|
||||
EXIT_FAILURE /* Abnormal exit code */
|
||||
) ) != CHF_S_OK ||
|
||||
ChfGetMessage( CHF_MODULE_ID, MAIN_M_COPYRIGHT, NULL ) == NULL )
|
||||
fprintf( stderr, "saturn-E-Alternate Chf initialization failed (%d)\n", st );
|
||||
else
|
||||
break;
|
||||
|
||||
/* Bring down Chf before initializing it again */
|
||||
if ( st == CHF_S_OK )
|
||||
ChfExit();
|
||||
|
||||
/* Attempt to adjust setlocale() environment variables */
|
||||
if ( retry++ == 0 )
|
||||
adjust_setlocale();
|
||||
}
|
||||
|
||||
if ( retry == 2 ) {
|
||||
fprintf( stderr, "saturn-F-Application aborted\n" );
|
||||
exit( EXIT_FAILURE );
|
||||
}
|
||||
|
||||
/* cat_name no longer needed */
|
||||
free( cat_name );
|
||||
|
||||
/* 3.9: Print out MAIN_M_COPYRIGHT and MAIN_M_LICENSE on stdout now */
|
||||
fprintf( stdout, ChfGetMessage( CHF_MODULE_ID, MAIN_M_COPYRIGHT, "" ), "$Revision: 4.1 $" );
|
||||
/* fprintf( stdout, ChfGetMessage( CHF_MODULE_ID, MAIN_M_LICENSE, "" ) ); */
|
||||
|
||||
/* Initialize GUI and associated lcd display emulation module */
|
||||
InitializeGui( argc, argv );
|
||||
|
||||
/* Initialize serial port emulation.
|
||||
This function returns the name of the slave side of the pty;
|
||||
it is unused here, because the GUI condition handler intercepts
|
||||
a condition containing the same information and displays the pty name
|
||||
on the main emulator's window.
|
||||
*/
|
||||
( void )SerialInit();
|
||||
|
||||
/* Initialize emulator proper */
|
||||
EmulatorInit();
|
||||
|
||||
/* 3.15: Repeat copyright message on GUI if stdout is not a tty */
|
||||
if ( !isatty( fileno( stdout ) ) ) {
|
||||
ChfCondition MAIN_M_LICENSE, CHF_INFO ChfEnd;
|
||||
ChfCondition MAIN_M_COPYRIGHT, CHF_INFO, "$Revision: 4.1 $" ChfEnd;
|
||||
|
||||
ChfSignal();
|
||||
}
|
||||
|
||||
if ( args.monitor )
|
||||
/* Invoke Monitor */
|
||||
Monitor();
|
||||
else
|
||||
/* Call Emulator directly */
|
||||
Emulator();
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
|
@ -1,178 +0,0 @@
|
|||
#include "libChf/src/Chf.h"
|
||||
#include "chf_messages.h"
|
||||
|
||||
ChfTable message_table[] = {
|
||||
{CHF_MODULE_NAMES_SET, CHF_SET, "Chf" },
|
||||
{CHF_MODULE_NAMES_SET, MAIN_CHF_MODULE_ID, "MAIN" },
|
||||
{CHF_MODULE_NAMES_SET, CPU_CHF_MODULE_ID, "CPU" },
|
||||
{CHF_MODULE_NAMES_SET, MOD_CHF_MODULE_ID, "MOD" },
|
||||
{CHF_MODULE_NAMES_SET, DISK_IO_CHF_MODULE_ID, "DISK_IO" },
|
||||
{CHF_MODULE_NAMES_SET, X11_CHF_MODULE_ID, "X11" },
|
||||
{CHF_MODULE_NAMES_SET, SERIAL_CHF_MODULE_ID, "SERIAL" },
|
||||
{CHF_MODULE_NAMES_SET, FLASH_CHF_MODULE_ID, "FLASH" },
|
||||
{CHF_MODULE_NAMES_SET, UTIL_CHF_MODULE_ID, "UTIL" },
|
||||
{CHF_MODULE_NAMES_SET, X_FUNC_CHF_MODULE_ID, "X_FUNC" },
|
||||
{CHF_MODULE_NAMES_SET, DEBUG_CHF_MODULE_ID, "DEBUG" },
|
||||
|
||||
{CHF_SET, CHF_S_OK, "" },
|
||||
{CHF_SET, CHF_F_COND_STACK_FULL, "Condition stack is full" },
|
||||
{CHF_SET, CHF_F_HDLR_STACK_FULL, "Handler stack is full" },
|
||||
{CHF_SET, CHF_F_HDLR_STACK_EMPTY, "Handler stack is empty" },
|
||||
{CHF_SET, CHF_F_BAD_STATE, "Wrong Chf state for requested operation" },
|
||||
{CHF_SET, CHF_F_INVALID_ACTION, "Invalid action code from handler (code=<%d>d)" },
|
||||
{CHF_SET, CHF_F_MALLOC, "Dynamic memory allocation failed" },
|
||||
{CHF_SET, CHF_F_NOT_AVAILABLE, "Function not implemented" },
|
||||
{CHF_SET, CHF_F_SETLOCALE, "setlocale() failed" },
|
||||
{CHF_SET, CHF_F_CATOPEN, "catopen() failed" },
|
||||
|
||||
{CPU_CHF_MODULE_ID, CPU_I_CALLED, "Function [%s] called" },
|
||||
{CPU_CHF_MODULE_ID, CPU_I_EXECUTING, "Executing @ PC[%05X]" },
|
||||
{CPU_CHF_MODULE_ID, CPU_I_SHUTDN, "CPU shutdown executed" },
|
||||
{CPU_CHF_MODULE_ID, CPU_I_WAKE, "CPU wake-up executed" },
|
||||
{CPU_CHF_MODULE_ID, CPU_I_INT, "%s request accepted" },
|
||||
{CPU_CHF_MODULE_ID, CPU_I_INT_PENDING, "%s request pending" },
|
||||
{CPU_CHF_MODULE_ID, CPU_I_RTI_LOOP, "RTI loop to service %s" },
|
||||
{CPU_CHF_MODULE_ID, CPU_I_RTI_END, "RTI returning" },
|
||||
{CPU_CHF_MODULE_ID, CPU_I_INTON, "INTON servicing %s" },
|
||||
{CPU_CHF_MODULE_ID, CPU_I_REVISION, "CPU emulator [%s]" },
|
||||
{CPU_CHF_MODULE_ID, CPU_I_TIMER1_EX, "Timer1 expired CTRL[%01X]" },
|
||||
{CPU_CHF_MODULE_ID, CPU_I_TIMER2_EX, "Timer2 expired CTRL[%01X]" },
|
||||
{CPU_CHF_MODULE_ID, CPU_I_EMULATOR_INT, "Emulator interrupt request detected" },
|
||||
{CPU_CHF_MODULE_ID, CPU_I_TIMER_ST, "Timer[%s] Ctrl[%01X] Val[%08X]" },
|
||||
{CPU_CHF_MODULE_ID, CPU_I_TIMER_EXP, "Timer[%s] expires in [%d]d ms" },
|
||||
{CPU_CHF_MODULE_ID, CPU_I_IDLE_X_LOOP, "Starting idle loop, timeout [%d]d ms" },
|
||||
{CPU_CHF_MODULE_ID, CPU_I_ELAPSED, "Spooling up after [%d]d us in idle loop" },
|
||||
{CPU_CHF_MODULE_ID, CPU_I_HALT, "CPU halted by CpuHaltRequest()" },
|
||||
{CPU_CHF_MODULE_ID, CPU_I_RUN, "CPU awoken by CpuRunRequest()" },
|
||||
{CPU_CHF_MODULE_ID, CPU_W_RESETTING, "Can't restore CPU status from disk; resetting CPU" },
|
||||
{CPU_CHF_MODULE_ID, CPU_W_BAD_MONITOR_CMD, "Monitor command syntax error [%s]" },
|
||||
{CPU_CHF_MODULE_ID, CPU_E_BAD_OPCODE, "Bad opcode @ PC[%05X], N[%01X]" },
|
||||
{CPU_CHF_MODULE_ID, CPU_E_SAVE, "Can't save CPU status to disk" },
|
||||
{CPU_CHF_MODULE_ID, CPU_E_NO_HALT, "Halt/Run requests not allowed; #undef CPU_SPIN_SHUTDN" },
|
||||
{CPU_CHF_MODULE_ID, CPU_F_INTERR, "Internal error [%s]" },
|
||||
{CPU_CHF_MODULE_ID, CPU_F_BAD_SHUTDN, "Unexpected CPU shutdown" },
|
||||
|
||||
{DEBUG_CHF_MODULE_ID, DEBUG_W_NOT_SUPPORTED, "Debug not supported; Rebuild with -DDEBUG" },
|
||||
{DEBUG_CHF_MODULE_ID, DEBUG_W_BAD_CMD, "Debug: Invalid command" },
|
||||
|
||||
{DISK_IO_CHF_MODULE_ID, DISK_IO_S_OK, "Disk IO: OK" },
|
||||
{DISK_IO_CHF_MODULE_ID, DISK_IO_I_CALLED, "Function [%s] called" },
|
||||
{DISK_IO_CHF_MODULE_ID, DISK_IO_E_OPEN, "Can't open file [%s]" },
|
||||
{DISK_IO_CHF_MODULE_ID, DISK_IO_E_GETC, "getc() failed reading file [%s]" },
|
||||
{DISK_IO_CHF_MODULE_ID, DISK_IO_E_PUTC, "putc() failed writing file [%s]" },
|
||||
{DISK_IO_CHF_MODULE_ID, DISK_IO_E_READ, "fread() failed reading file [%s]" },
|
||||
{DISK_IO_CHF_MODULE_ID, DISK_IO_E_WRITE, "fwrite() failed writing file [%s]" },
|
||||
{DISK_IO_CHF_MODULE_ID, DISK_IO_E_CLOSE, "Close file [%s] failed" },
|
||||
{DISK_IO_CHF_MODULE_ID, DISK_IO_E_BAD_HDR, "File [%s] has a bad header" },
|
||||
{DISK_IO_CHF_MODULE_ID, DISK_IO_E_SIZE, "File [%s] is too large" },
|
||||
|
||||
{FLASH_CHF_MODULE_ID, FLASH_I_READ, "Read (Nibble) A[%08X] D[%01X]" },
|
||||
{FLASH_CHF_MODULE_ID, FLASH_I_WRITE, "Write (Nibble) A[%08X] D[%01X]" },
|
||||
{FLASH_CHF_MODULE_ID, FLASH_I_FSM, "FSM STATE[%d] CYCLE[%d]" },
|
||||
{FLASH_CHF_MODULE_ID, FLASH_I_FSM_AD, "\tFSM Args: (Byte)A[%08X] D[%02X]" },
|
||||
{FLASH_CHF_MODULE_ID, FLASH_I_FSM_RESULT, "\tFSM Next: STATE[%d] RESULT[%02X]" },
|
||||
{FLASH_CHF_MODULE_ID, FLASH_I_FSM_OP, "\tFSM Operation: [%s]" },
|
||||
{FLASH_CHF_MODULE_ID, FLASH_W_BAD_CMD, "Command unknown/not implemented - FSM Info:\n\\tSTATE[%d] CYCLE[%d] A[%08X] D[%02X]" },
|
||||
{FLASH_CHF_MODULE_ID, FLASH_W_BAD_ADDRESS, "Invalid address in Write to Buffer - FSM Info:\n\\tSTATE[%d] CYCLE[%d] A[%08X] D[%02X]"},
|
||||
{FLASH_CHF_MODULE_ID, FLASH_E_xxx, "FLASH_E_xxx" },
|
||||
{FLASH_CHF_MODULE_ID, FLASH_F_xxx, "FLASH_F_xxx" },
|
||||
|
||||
{MOD_CHF_MODULE_ID, MOD_I_CALLED, "Function [%s] called" },
|
||||
{MOD_CHF_MODULE_ID, MOD_I_INITIALIZING, "Initializing module [%s]" },
|
||||
{MOD_CHF_MODULE_ID, MOD_I_RESETTING, "Resetting module [%s]" },
|
||||
{MOD_CHF_MODULE_ID, MOD_I_GET_ID, "ModGetID -> [%05X]" },
|
||||
{MOD_CHF_MODULE_ID, MOD_I_CONFIG, "CONFIG M[%s] A[%05X] S[%05X]" },
|
||||
{MOD_CHF_MODULE_ID, MOD_I_UNCONFIG, "UNCNFG M[%s] A[%05X] S[%05X]" },
|
||||
{MOD_CHF_MODULE_ID, MOD_I_SAVING, "Saving module [%s]" },
|
||||
{MOD_CHF_MODULE_ID, MOD_I_NOT_IMPLEMENTED, "Function [%s] not implemented" },
|
||||
{MOD_CHF_MODULE_ID, MOD_I_REVISION, "Modules emulator: [%s]" },
|
||||
{MOD_CHF_MODULE_ID, MOD_I_BS_ADDRESS, "Bank Switcher F/F set to A[%05X]" },
|
||||
{MOD_CHF_MODULE_ID, MOD_I_PORT_1_WP, "Port 1 has been write-protected" },
|
||||
{MOD_CHF_MODULE_ID, MOD_I_PORT_2_WP, "Port 2 has been write-protected" },
|
||||
{MOD_CHF_MODULE_ID, MOD_I_PERF_CTR, ">>> PerfCtr [%s]=[%d]" },
|
||||
{MOD_CHF_MODULE_ID, MOD_I_CACHED_UNCONFIG, "Cached UNCNFG completed" },
|
||||
{MOD_CHF_MODULE_ID, MOD_I_CACHED_CONFIG, "Cached CONFIG A[%05X] completed" },
|
||||
{MOD_CHF_MODULE_ID, MOD_I_UNCONFIG_L_HIT, "Late UNCNFG cache hit" },
|
||||
{MOD_CHF_MODULE_ID, MOD_I_UNCONFIG_L_MISS, "Late UNCNFG cache miss" },
|
||||
{MOD_CHF_MODULE_ID, MOD_W_BAD_CONFIG, "Bad ModConfig [%05X] ignored" },
|
||||
{MOD_CHF_MODULE_ID, MOD_W_BAD_UNCONFIG, "Bad ModUnconfig [%05X] ignored" },
|
||||
{MOD_CHF_MODULE_ID, MOD_W_HDW_WRITE, "Bad HdwWrite A[%05X] N[%01X]" },
|
||||
{MOD_CHF_MODULE_ID, MOD_W_HDW_READ, "Bad HdwRead A[%05X]" },
|
||||
{MOD_CHF_MODULE_ID, MOD_W_RESETTING_ALL, "Resetting all modules" },
|
||||
{MOD_CHF_MODULE_ID, MOD_W_RAM_INIT, "Can't initialize internal RAM from disk" },
|
||||
{MOD_CHF_MODULE_ID, MOD_W_HDW_INIT, "Can't initialize HDW from disk" },
|
||||
{MOD_CHF_MODULE_ID, MOD_W_BAD_KEY, "Bad key [%s] ignored" },
|
||||
{MOD_CHF_MODULE_ID, MOD_W_BAD_OUT_BIT, "Bad out_bit [%x] ignored" },
|
||||
{MOD_CHF_MODULE_ID, MOD_W_PORT_1_INIT, "Can't initialize Port 1 from disk" },
|
||||
{MOD_CHF_MODULE_ID, MOD_W_PORT_2_INIT, "Can't initialize Port 2 from disk" },
|
||||
{MOD_CHF_MODULE_ID, MOD_W_NO_VICTIM, "Unable to find CONFIG cache victim; flushing cache" },
|
||||
{MOD_CHF_MODULE_ID, MOD_E_BAD_READ, "Read from unmapped A[%05X]" },
|
||||
{MOD_CHF_MODULE_ID, MOD_E_BAD_WRITE, "Write to unmapped A[%05X] N[%01X]" },
|
||||
{MOD_CHF_MODULE_ID, MOD_E_ROM_WRITE, "Write into ROM A[%05X] D[%01X]" },
|
||||
{MOD_CHF_MODULE_ID, MOD_E_RAM_SAVE, "Can't save internal RAM status to disk" },
|
||||
{MOD_CHF_MODULE_ID, MOD_E_HDW_SAVE, "Can't save HDW status to disk" },
|
||||
{MOD_CHF_MODULE_ID, MOD_E_PORT_1_SAVE, "Can't save Port 1 status to disk" },
|
||||
{MOD_CHF_MODULE_ID, MOD_E_CE1_WRITE, "Write into CE1 A[%05X] D[%01X]" },
|
||||
{MOD_CHF_MODULE_ID, MOD_E_PORT_2_SAVE, "Can't save Port 1 status to disk" },
|
||||
{MOD_CHF_MODULE_ID, MOD_E_NCE3_READ, "Read from NCE3 A[%05X] when Port 2 is not present" },
|
||||
{MOD_CHF_MODULE_ID, MOD_E_NCE3_WRITE, "Write into NCE3 A[%05X] D[%01X] when Port 2 is not present" },
|
||||
{MOD_CHF_MODULE_ID, MOD_E_NO_MATCH, "Hardware configuration [%s] not supported" },
|
||||
{MOD_CHF_MODULE_ID, MOD_E_ROM_SAVE, "Can't save Flash ROM status to disk" },
|
||||
{MOD_CHF_MODULE_ID, MOD_F_MAP_SAVE, "Can't save module mapping info" },
|
||||
{MOD_CHF_MODULE_ID, MOD_F_ROM_INIT, "Can't initialize internal ROM" },
|
||||
{MOD_CHF_MODULE_ID, MOD_F_MAP_ALLOC, "Dynamic allocation of ModMap failed" },
|
||||
{MOD_CHF_MODULE_ID, MOD_F_BAD_ALLOC_C, "Bad alloc_c [%d] after FlushCache()" },
|
||||
{MOD_CHF_MODULE_ID, MOD_F_CHAIN_CORRUPTED, "Cached struct ModMap chain corrupted; freeing unlinked entry" },
|
||||
{MOD_CHF_MODULE_ID, MOD_F_NO_VICTIM, "Unable to find CONFIG cache victim after cache flush" },
|
||||
{MOD_CHF_MODULE_ID, MOD_F_MOD_STATUS_ALLOC, "Allocation of ModStatus_xx failed ([%d]d bytes needed)" },
|
||||
{MOD_CHF_MODULE_ID, MOD_F_NO_DESCRIPTION, "ModInit() invoked without registering a ModDescription first" },
|
||||
{MOD_CHF_MODULE_ID, MOD_M_NOT_MAPPED, "A[%05X] -> *Not Mapped*" },
|
||||
{MOD_CHF_MODULE_ID, MOD_M_MAPPED, "A[%05X] -> M[%s] R[%05X]" },
|
||||
{MOD_CHF_MODULE_ID, MOD_M_MAP_TABLE_TITLE, "Device\t\t\tAddress\tSize\tStatus" },
|
||||
{MOD_CHF_MODULE_ID, MOD_M_MAP_TABLE_ROW, "%s\t%05X\t%05X\t%s" },
|
||||
{MOD_CHF_MODULE_ID, MOD_M_MAP_CONFIGURED, "Configured" },
|
||||
{MOD_CHF_MODULE_ID, MOD_M_MAP_SZ_CONFIGURED, "Size_configured" },
|
||||
{MOD_CHF_MODULE_ID, MOD_M_MAP_UNCONFIGURED, "*Unconfigured*" },
|
||||
|
||||
{SERIAL_CHF_MODULE_ID, SERIAL_I_CALLED, "Function [%s] called" },
|
||||
{SERIAL_CHF_MODULE_ID, SERIAL_I_REVISION, "Serial port emulator: [%s]" },
|
||||
{SERIAL_CHF_MODULE_ID, SERIAL_I_READ, "Read [%s]; value [%01X]" },
|
||||
{SERIAL_CHF_MODULE_ID, SERIAL_I_WRITE, "Write [%s]; value [%01X](old) -> [%01X](new)" },
|
||||
{SERIAL_CHF_MODULE_ID, SERIAL_I_RBR, "Read RBR; value [%02X]" },
|
||||
{SERIAL_CHF_MODULE_ID, SERIAL_I_TBR, "Write TBR; value [%02X]" },
|
||||
{SERIAL_CHF_MODULE_ID, SERIAL_I_PTY_NAME, "Pseudo-terminal name is [%s]" },
|
||||
{SERIAL_CHF_MODULE_ID, SERIAL_W_EMPTY_RRB, "Read from empty receiver buffer, rcs [%01X]" },
|
||||
{SERIAL_CHF_MODULE_ID, SERIAL_W_FULL_TRB, "Write into full transmitter buffer, tcs [%01X]" },
|
||||
{SERIAL_CHF_MODULE_ID, SERIAL_W_NOPTY, "Pseudo-terminals not supported" },
|
||||
{SERIAL_CHF_MODULE_ID, SERIAL_E_TRB_DRAIN, "Error draining transmitter buffer" },
|
||||
{SERIAL_CHF_MODULE_ID, SERIAL_E_RRB_CHARGE, "Error charging receiver buffer" },
|
||||
{SERIAL_CHF_MODULE_ID, SERIAL_E_PTY_CLOSE, "Error shutting down pseudo-terminal" },
|
||||
{SERIAL_CHF_MODULE_ID, SERIAL_F_OPENPTY, "openpty() failed on master pty" },
|
||||
{SERIAL_CHF_MODULE_ID, SERIAL_F_FCNTL, "fcntl() failed on master pty" },
|
||||
{SERIAL_CHF_MODULE_ID, SERIAL_F_OPEN_MASTER, "Can't open() pty master [%s]" },
|
||||
{SERIAL_CHF_MODULE_ID, SERIAL_F_GRANTPT, "grantpt() failed on master pty" },
|
||||
{SERIAL_CHF_MODULE_ID, SERIAL_F_UNLOCKPT, "unlockpt() failed on master pty" },
|
||||
{SERIAL_CHF_MODULE_ID, SERIAL_F_OPEN_SLAVE, "Can't open() pty slave [%s]" },
|
||||
{SERIAL_CHF_MODULE_ID, SERIAL_F_PUSH, "ioctl(I_PUSH,[%s]) failed on slave pty" },
|
||||
{SERIAL_CHF_MODULE_ID, SERIAL_F_TCGETATTR, "tcgetattr() failed on master pty" },
|
||||
{SERIAL_CHF_MODULE_ID, SERIAL_F_TCSETATTR, "tcsetattr() failed on master pty" },
|
||||
|
||||
{X_FUNC_CHF_MODULE_ID, X_FUNC_I_CALLED, "Function [%s] called" },
|
||||
{X_FUNC_CHF_MODULE_ID, X_FUNC_I_CODE, "Emulator's extended function #[%01X]" },
|
||||
{X_FUNC_CHF_MODULE_ID, X_FUNC_I_SET_SPEED, "Emulator speed set to [%d]MHz" },
|
||||
{X_FUNC_CHF_MODULE_ID, X_FUNC_I_MAX_SPEED, "Emulator at maximum speed" },
|
||||
{X_FUNC_CHF_MODULE_ID, X_FUNC_I_FILE_NAME, "Transferring [%s]" },
|
||||
{X_FUNC_CHF_MODULE_ID, X_FUNC_I_KGET, "Kget START[%05X] END[%05X] HDR[%s]" },
|
||||
{X_FUNC_CHF_MODULE_ID, X_FUNC_I_SEND, "Send START[%05X] END[%05X] HDR[%s]" },
|
||||
{X_FUNC_CHF_MODULE_ID, X_FUNC_W_BAD_CODE, "Invalid function code #[%01X] ignored" },
|
||||
{X_FUNC_CHF_MODULE_ID, X_FUNC_W_ABORTED, "Operation aborted by user" },
|
||||
{X_FUNC_CHF_MODULE_ID, X_FUNC_W_FAILED, "Operation failed" },
|
||||
{X_FUNC_CHF_MODULE_ID, X_FUNC_E_NO_HALT, "Cpu Halt requests not allowed.\n\tRebuild with CPU_SPIN_SHUTDN undefined in config.h" },
|
||||
{X_FUNC_CHF_MODULE_ID, X_FUNC_E_NO_SPEED, "Cpu speed control not available.\n\tRebuild with REAL_CPU_SPEED defined in config.h" },
|
||||
{X_FUNC_CHF_MODULE_ID, X_FUNC_E_NO_BIN_HDR, "Can't determine binary header for hw [%s]" },
|
||||
{X_FUNC_CHF_MODULE_ID, X_FUNC_F_xxx, "X_FUNC_F_xxx" },
|
||||
{X_FUNC_CHF_MODULE_ID, X_FUNC_M_KGET, "Load object from disk..." },
|
||||
{X_FUNC_CHF_MODULE_ID, X_FUNC_M_SEND, "Save object to disk..." },
|
||||
};
|
||||
|
||||
size_t message_table_size = sizeof( message_table ) / sizeof( message_table[ 0 ] );
|
|
@ -1,20 +0,0 @@
|
|||
#ifndef _CHF_MESSAGES_H
|
||||
#define _CHF_MESSAGES_H 1
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "libChf/src/Chf.h"
|
||||
|
||||
#include "config.h"
|
||||
#include "cpu.h"
|
||||
#include "debug.h"
|
||||
#include "disk_io.h"
|
||||
#include "flash49.h"
|
||||
#include "modules.h"
|
||||
#include "serial.h"
|
||||
#include "x_func.h"
|
||||
|
||||
extern ChfTable message_table[];
|
||||
extern size_t message_table_size;
|
||||
|
||||
#endif /*!_CHF_MESSAGES_H*/
|
124
src/config.h
124
src/config.h
|
@ -124,7 +124,43 @@
|
|||
|
||||
.- */
|
||||
|
||||
#include "ui4x/config.h"
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "ui48_config.h"
|
||||
|
||||
/* CHF_EXTENDED_INFO:
|
||||
Define this symbol if extended information is desired during condition
|
||||
handling; this is usually useful only for debugging purposes.
|
||||
*/
|
||||
/* #define CHF_EXTENDED_INFO */
|
||||
|
||||
/* DEBUG:
|
||||
Define this symbol to include the debugging code for all source modules
|
||||
in the executable image.
|
||||
|
||||
At run-time, the debug level can be set using the function SetDebugLevel();
|
||||
the initial debug level is set to the value of the symbol DEBUG_LEVEL,
|
||||
if it is defined, otherwise it is set to zero.
|
||||
*/
|
||||
/* #define DEBUG */
|
||||
|
||||
/* DEBUG_LEVEL:
|
||||
When this symbol is defined and the debugging code has been included
|
||||
in the executable image (DEBUG symbol set), the initial debug level
|
||||
is set to its value.
|
||||
|
||||
The value must be the bitwise OR of zero or more of the symbols
|
||||
DEBUG_C_<> defined in debug.h; each of them corresponds to a class
|
||||
of debugging conditions that can be individually enabled or disabled.
|
||||
*/
|
||||
#define DEBUG_LEVEL DEBUG_C_REVISION
|
||||
|
||||
/* 2.1: FORCE_NONMODAL
|
||||
If this symbol is defined, nonmodal navigation is forced in the
|
||||
OSF/Motif GUI, by setting navigationType to XmNONE and traversalOn
|
||||
to False at the source code level.
|
||||
*/
|
||||
/* #define FORCE_NONMODAL */
|
||||
|
||||
/* 2.4: N_PORT_2_BANK
|
||||
This symbol is used to dimension the HP48GX Port_2: it denotes the
|
||||
|
@ -132,7 +168,6 @@
|
|||
between 1 and 32, inclusive. When undefined, Port_2 is not emulated at all.
|
||||
The default value is 8, that is, Port_2 is emulated and its size is 1Mbyte.
|
||||
*/
|
||||
// #define N_PORT_2_BANK ( config.model == MODEL_48GX ? 32 : 1 )
|
||||
#define N_PORT_2_BANK 32
|
||||
|
||||
/* 2.5: SERIAL_FORCE_OPENPTY, SERIAL_FORCE_STREAMSPTY
|
||||
|
@ -144,6 +179,20 @@
|
|||
/* #define SERIAL_FORCE_OPENPTY */
|
||||
/* #define SERIAL_FORCE_STREAMSPTY */
|
||||
|
||||
/* 3.2: HP49_SUPPORT
|
||||
Define this symbol to enable HP49-specific support code in the
|
||||
emulator; it does not harm if this symbol is defined when emulating
|
||||
a HP48, too, since all changed should be backward-compatible.
|
||||
*/
|
||||
#define HP49_SUPPORT
|
||||
|
||||
/* 3.13: REAL_CPU_SPEED
|
||||
Define this symbol (recommended) to force the emulated CPU to run
|
||||
no faster than a software-controlled limit; by default, the limit
|
||||
is close to the real CPU speed.
|
||||
*/
|
||||
#define REAL_CPU_SPEED
|
||||
|
||||
/* 3.14: CPU_SLOW_IN
|
||||
Define this symbol (recommended) to slow down the A=IN and C=IN
|
||||
instructions depending on the current emulated CPU speed.
|
||||
|
@ -153,6 +202,14 @@
|
|||
*/
|
||||
#define CPU_SLOW_IN 16
|
||||
|
||||
/* 4.1.1.1: LCD_MAG
|
||||
This symbol represents the magnification ratio of the emulated LCD pixels
|
||||
when drawn on the emulated display; supported values are 1 and 2; 2 is the
|
||||
default. Currently, the value cannot be set at runtime for performance
|
||||
reasons.
|
||||
*/
|
||||
#define LCD_MAG 2
|
||||
|
||||
/* 4.1.1.1: When defined, this symbol represents the threshold of the long
|
||||
key pression. When the mouse button is kept pressed on a calculator's key
|
||||
for more than LONG_PRESS_THR milliseconds, the key stays pressed after
|
||||
|
@ -175,9 +232,70 @@
|
|||
#define X_FUNC_CHF_MODULE_ID 18 /* 3.13 */
|
||||
#define DEBUG_CHF_MODULE_ID 30
|
||||
|
||||
/* .+
|
||||
|
||||
.identifier : $Id: args.h,v 4.1 2000/12/11 09:54:19 cibrario Rel $
|
||||
.context : SATURN, Saturn CPU / HP48 emulator
|
||||
.title : $RCSfile: args.h,v $
|
||||
.kind : C header
|
||||
.author : Ivan Cibrario B.
|
||||
.site : CSTV-CNR
|
||||
.creation : 19-Jan-1998
|
||||
.keywords : *
|
||||
.description :
|
||||
This header declares a global data structure containing the emulator
|
||||
invocation arguments; this data structure is initialized before startup,
|
||||
either by means of argc/argv or in other ways.
|
||||
|
||||
.include : config.h
|
||||
|
||||
.notes :
|
||||
$Log: args.h,v $
|
||||
Revision 4.1 2000/12/11 09:54:19 cibrario
|
||||
Public release.
|
||||
|
||||
Revision 3.15 2000/11/15 14:03:06 cibrario
|
||||
GUI enhancements and assorted bug fixes:
|
||||
- added .batchXfer boolean (corresponding to command-line option
|
||||
-batchXfer) to struct Args
|
||||
|
||||
Revision 3.10 2000/10/24 16:14:25 cibrario
|
||||
Added/Replaced GPL header
|
||||
|
||||
Revision 2.1 2000/09/08 14:45:06 cibrario
|
||||
Added the following fields to 'struct Args': reset, monitor, hw.
|
||||
The latter mimes the setting of the -hw command line option and
|
||||
of the *hw top-level application resource; the former two have
|
||||
been added to export them cleanly from the GUI modules.
|
||||
|
||||
* Revision 1.1 1998/02/17 11:58:37 cibrario
|
||||
* Initial revision
|
||||
*
|
||||
|
||||
.- */
|
||||
|
||||
/*---------------------------------------------------------------------------
|
||||
Data type definitions - require config.h
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
struct Args {
|
||||
bool reset; /* 2.1: Force emulator reset */
|
||||
bool monitor; /* 2.1: Call monitor() on startup */
|
||||
bool batchXfer; /* 3.15: Non-interactive file transfers */
|
||||
char* mod_file_name;
|
||||
char* cpu_file_name;
|
||||
char* hdw_file_name;
|
||||
char* rom_file_name;
|
||||
char* ram_file_name;
|
||||
char* port_1_file_name;
|
||||
char* port_2_file_name;
|
||||
char* hw; /* 2.1: Hardware configuration (unused) */
|
||||
};
|
||||
|
||||
/*---------------------------------------------------------------------------
|
||||
Global variables
|
||||
---------------------------------------------------------------------------*/
|
||||
extern config_t config;
|
||||
|
||||
extern struct Args args;
|
||||
|
||||
#endif /*!_CONFIG_H*/
|
||||
|
|
54
src/cpu.h
54
src/cpu.h
|
@ -108,8 +108,6 @@
|
|||
|
||||
.- */
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
/*---------------------------------------------------------------------------
|
||||
Macro/Data type definitions - require machdep.h
|
||||
|
||||
|
@ -136,48 +134,48 @@
|
|||
#define CPU_RCS_INFO "$Revision: 4.1 $ $State: Rel $"
|
||||
|
||||
/* Instruction opcode access macros:
|
||||
GET_FS(f) returns the short field-selector value from the
|
||||
GetFS(f) returns the short field-selector value from the
|
||||
given nibble (bits 2..0)
|
||||
|
||||
GET_IMMEDIATE_FS_FLAG(f) returns the immediate-field-selector flag from the
|
||||
GetImmFS(f) returns the immediate-field-selector flag from the
|
||||
given nibble (bit 3)
|
||||
=0: regular field selector
|
||||
!=0: immediate field selector
|
||||
|
||||
GET_OC_1(o) returns the short operation code from the given
|
||||
GetOC_1(o) returns the short operation code from the given
|
||||
nibble (bits 3..2 >>2)
|
||||
|
||||
GET_OC_2(f, o) returns the long operation code from the given
|
||||
GetOC_2(f, o) returns the long operation code from the given
|
||||
nibbles (f bit 3, o bits 3..2)
|
||||
|
||||
GET_OC_3b(o) returns the long operation code from the given
|
||||
GetOC_3b(o) returns the long operation code from the given
|
||||
nibble (bits 2..0)
|
||||
|
||||
GET_RP(o) returns the register-pair identifier from the given
|
||||
GetRP(o) returns the register-pair identifier from the given
|
||||
nibble (bits 1..0)
|
||||
|
||||
GET_Rn(r) returns the R register index from the given nibble
|
||||
GetRn(r) returns the R register index from the given nibble
|
||||
(bits 2..0)
|
||||
|
||||
GET_AC(r) returns the A/C register flag from the given nibble
|
||||
GetAC(r) returns the A/C register flag from the given nibble
|
||||
(bit 3)
|
||||
=0: register A
|
||||
!=0: register C
|
||||
|
||||
GET_AS(r) returns the add/subtract flag from the given nibble
|
||||
GetAS(r) returns the add/subtract flag from the given nibble
|
||||
(bit 3)
|
||||
=0: add
|
||||
!=0: subtract
|
||||
*/
|
||||
#define GET_FS( f ) ( ( f ) & 0x7 )
|
||||
#define GET_IMMEDIATE_FS_FLAG( o ) ( ( o ) & 0x8 )
|
||||
#define GET_OC_1( o ) ( ( ( o ) & 0xC ) >> 2 )
|
||||
#define GET_OC_2( f, o ) ( ( ( ( f ) & 0x8 ) >> 1 ) | ( ( ( o ) & 0xC ) >> 2 ) )
|
||||
#define GET_OC_3b( o ) ( ( o ) & 0x7 )
|
||||
#define GET_RP( o ) ( ( o ) & 0x3 )
|
||||
#define GET_Rn( r ) ( ( r ) & 0x7 )
|
||||
#define GET_AC( r ) ( ( r ) & 0x8 )
|
||||
#define GET_AS( r ) ( ( r ) & 0x8 )
|
||||
#define GetFS( f ) ( ( f ) & 0x7 )
|
||||
#define GetImmFS( o ) ( ( o ) & 0x8 )
|
||||
#define GetOC_1( o ) ( ( ( o ) & 0xC ) >> 2 )
|
||||
#define GetOC_2( f, o ) ( ( ( ( f ) & 0x8 ) >> 1 ) | ( ( ( o ) & 0xC ) >> 2 ) )
|
||||
#define GetOC_3b( o ) ( ( o ) & 0x7 )
|
||||
#define GetRP( o ) ( ( o ) & 0x3 )
|
||||
#define GetRn( r ) ( ( r ) & 0x7 )
|
||||
#define GetAC( r ) ( ( r ) & 0x8 )
|
||||
#define GetAS( r ) ( ( r ) & 0x8 )
|
||||
|
||||
/* Field selector codes */
|
||||
#define FS_P 0
|
||||
|
@ -254,12 +252,12 @@ struct CpuStatus {
|
|||
|
||||
int fs_idx_lo[ N_FS ];
|
||||
int fs_idx_hi[ N_FS ];
|
||||
bool hexmode; /* DEC/HEX mode */
|
||||
bool carry; /* Carry bit */
|
||||
bool shutdn; /* SHUTDN flag */
|
||||
bool halt; /* Halt flag */
|
||||
bool int_enable; /* Int. enable */
|
||||
bool int_service; /* Int. service */
|
||||
int hexmode; /* DEC/HEX mode, 1=HEX */
|
||||
int carry; /* Carry bit 1=set */
|
||||
int shutdn; /* SHUTDN flag, 1=executed */
|
||||
int halt; /* 3.13: # of pending Halt */
|
||||
int int_enable; /* Int. enable, 1=enabled */
|
||||
int int_service; /* Int. service, 1=service */
|
||||
enum IntRequest int_pending; /* Pending interrupt request */
|
||||
|
||||
/* 3.13: inner_loop_max gives the upper limit of the CPU speed if the
|
||||
|
@ -333,9 +331,9 @@ void EmulatorInit( void ); /* 2.1 */
|
|||
void EmulatorExit( enum ExitOption opt ); /* 2.1 */
|
||||
int CpuHaltRequest( void ); /* 3.13 */
|
||||
int CpuRunRequest( void ); /* 3.13 */
|
||||
bool CpuHaltAllowed( void ); /* 3.13 */
|
||||
int CpuHaltAllowed( void ); /* 3.13 */
|
||||
|
||||
Address Disassemble( Address pc, char ob[ DISASSEMBLE_OB_SIZE ] ); /* dis.c */
|
||||
Address Disassemble( Address pc, char ob[ DISASSEMBLE_OB_SIZE ] );
|
||||
void DumpCpuStatus( char ob[ DUMP_CPU_STATUS_OB_SIZE ] );
|
||||
|
||||
#endif /*!_CPU_H*/
|
||||
|
|
125
src/debug.c
Normal file
125
src/debug.c
Normal file
|
@ -0,0 +1,125 @@
|
|||
/* -------------------------------------------------------------------------
|
||||
saturn - A poor-man's emulator of some HP calculators
|
||||
Copyright (C) 1998-2000 Ivan Cibrario Bertolotti
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with the documentation of this program; if not, write to
|
||||
the Free Software Foundation, Inc.,
|
||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
For more information, please contact the author, preferably by email,
|
||||
at the following address:
|
||||
|
||||
Ivan Cibrario Bertolotti
|
||||
IRITI - National Research Council
|
||||
c/o IEN "Galileo Ferraris"
|
||||
Strada delle Cacce, 91
|
||||
10135 - Torino (ITALY)
|
||||
|
||||
email: cibrario@iriti.cnr.it
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
/* +-+ */
|
||||
|
||||
/* .+
|
||||
|
||||
.identifier : $Id: debug.c,v 4.1 2000/12/11 09:54:19 cibrario Rel $
|
||||
.context : SATURN, Saturn CPU / HP48 emulator
|
||||
.title : $RCSfile: debug.c,v $
|
||||
.kind : C source
|
||||
.author : Ivan Cibrario B.
|
||||
.site : CSTV-CNR
|
||||
.creation : 28-Jan-1998
|
||||
.keywords : *
|
||||
.description :
|
||||
Debugging support.
|
||||
|
||||
.include : debug.h
|
||||
|
||||
.notes :
|
||||
$Log: debug.c,v $
|
||||
Revision 4.1 2000/12/11 09:54:19 cibrario
|
||||
Public release.
|
||||
|
||||
Revision 3.10 2000/10/24 16:14:32 cibrario
|
||||
Added/Replaced GPL header
|
||||
|
||||
Revision 1.1 1998/02/17 11:42:30 cibrario
|
||||
Initial revision
|
||||
|
||||
|
||||
.- */
|
||||
|
||||
#ifndef lint
|
||||
static char rcs_id[] = "$Id: debug.c,v 4.1 2000/12/11 09:54:19 cibrario Rel $";
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <setjmp.h>
|
||||
|
||||
#include "config.h"
|
||||
#include "machdep.h"
|
||||
#include "cpu.h"
|
||||
#include "debug.h"
|
||||
|
||||
#define CHF_MODULE_ID DEBUG_CHF_MODULE_ID
|
||||
#include <Chf.h>
|
||||
|
||||
/*---------------------------------------------------------------------------
|
||||
Static/Global variables
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
#ifdef DEBUG
|
||||
# ifdef DEBUG_LEVEL
|
||||
int debug_level = DEBUG_LEVEL;
|
||||
# else
|
||||
int debug_level = 0;
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/*---------------------------------------------------------------------------
|
||||
Public functions
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
/* .+
|
||||
|
||||
.title : SetDebugLevel
|
||||
.kind : C function
|
||||
.creation : 28-Jan-1998
|
||||
.description :
|
||||
If runtime debug support is enabled (symbol DEBUG defined during executable
|
||||
image build) this function updates the 'debug_level' flag, otherwise
|
||||
it signals a condition and does nothing more.
|
||||
|
||||
.call :
|
||||
SetDebugLevel(new_level)
|
||||
.input :
|
||||
int new_level, new value of the debug_level flag
|
||||
.output :
|
||||
void
|
||||
.status_codes :
|
||||
DEBUG_W_NOT_SUPPORTED
|
||||
.notes :
|
||||
1.1, 28-Jan-1998, creation
|
||||
|
||||
.- */
|
||||
void SetDebugLevel( int new_level )
|
||||
{
|
||||
#ifdef DEBUG
|
||||
debug_level = new_level;
|
||||
#else
|
||||
ChfCondition DEBUG_W_NOT_SUPPORTED, CHF_WARNING ChfEnd;
|
||||
ChfSignal();
|
||||
#endif
|
||||
}
|
56
src/debug.h
56
src/debug.h
|
@ -102,22 +102,37 @@
|
|||
|
||||
.- */
|
||||
|
||||
#define debug_preamble( module_id, debug_class, condition_code ) \
|
||||
{ \
|
||||
if ( config.debug_level & ( debug_class ) ) { ChfGenerate( module_id, __FILE__, __LINE__, condition_code, CHF_INFO
|
||||
#define debug_postamble( module_id ) ); \
|
||||
ChfSignal( module_id ); \
|
||||
} \
|
||||
}
|
||||
#ifdef DEBUG
|
||||
|
||||
#define debug0( module_id, debug_class, condition_code ) \
|
||||
debug_preamble( module_id, debug_class, condition_code ) debug_postamble( module_id )
|
||||
#define debug1( module_id, debug_class, condition_code, arg_1 ) \
|
||||
debug_preamble( module_id, debug_class, condition_code ), arg_1 debug_postamble( module_id )
|
||||
#define debug2( module_id, debug_class, condition_code, arg_1, arg_2 ) \
|
||||
debug_preamble( module_id, debug_class, condition_code ), arg_1, arg_2 debug_postamble( module_id )
|
||||
#define debug3( module_id, debug_class, condition_code, arg_1, arg_2, arg_3 ) \
|
||||
debug_preamble( module_id, debug_class, condition_code ), arg_1, arg_2, arg_3 debug_postamble( module_id )
|
||||
# define debug_preamble( debug_class, condition_code ) \
|
||||
{ \
|
||||
extern int debug_level; \
|
||||
if ( debug_level & ( debug_class ) ) { \
|
||||
ChfCondition( condition_code ), CHF_INFO
|
||||
|
||||
# define debug_postamble \
|
||||
ChfEnd; \
|
||||
ChfSignal(); \
|
||||
} \
|
||||
}
|
||||
|
||||
# define debug0( debug_class, condition_code ) debug_preamble( debug_class, condition_code ) debug_postamble
|
||||
|
||||
# define debug1( debug_class, condition_code, arg_1 ) debug_preamble( debug_class, condition_code ), arg_1 debug_postamble
|
||||
|
||||
# define debug2( debug_class, condition_code, arg_1, arg_2 ) debug_preamble( debug_class, condition_code ), arg_1, arg_2 debug_postamble
|
||||
|
||||
# define debug3( debug_class, condition_code, arg_1, arg_2, arg_3 ) \
|
||||
debug_preamble( debug_class, condition_code ), arg_1, arg_2, arg_3 debug_postamble
|
||||
|
||||
#else
|
||||
|
||||
# define debug0( debug_class, condition_code )
|
||||
# define debug1( debug_class, condition_code, arg_1 )
|
||||
# define debug2( debug_class, condition_code, arg_1, arg_2 )
|
||||
# define debug3( debug_class, condition_code, arg_1, arg_2, arg_3 )
|
||||
|
||||
#endif
|
||||
|
||||
/*---------------------------------------------------------------------------
|
||||
Debug classes
|
||||
|
@ -133,9 +148,8 @@
|
|||
#define DEBUG_C_IMPLEMENTATION 0x0100 /* Feature implementation */
|
||||
#define DEBUG_C_FLASH 0x0080 /* 3.3: Flash ROM */
|
||||
#define DEBUG_C_X_FUNC 0x0040 /* 3.13: Extended functions */
|
||||
#define DEBUG_C_XX 0x0010
|
||||
#define DEBUG_C_OPCODES 0x0001 /* OpCodes */
|
||||
#define DEBUG_C_NONE 0
|
||||
#define DEBUG_C_REVISION 0x0010 /* Revision information */
|
||||
#define DEBUG_C_X11 0x0001 /* X11 Interface */
|
||||
|
||||
/*---------------------------------------------------------------------------
|
||||
Chf condition codes
|
||||
|
@ -144,4 +158,10 @@
|
|||
#define DEBUG_W_NOT_SUPPORTED 201 /* Debug not supported */
|
||||
#define DEBUG_W_BAD_CMD 202 /* Invalid command */
|
||||
|
||||
/*---------------------------------------------------------------------------
|
||||
Function prototypes
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
void SetDebugLevel( int new_level );
|
||||
|
||||
#endif /*!_DEBUG_H*/
|
||||
|
|
|
@ -61,10 +61,14 @@
|
|||
|
||||
.- */
|
||||
|
||||
#ifndef lint
|
||||
static char rcs_id[] = "$Id: disk_io.c,v 4.1 2000/12/11 09:54:19 cibrario Rel $";
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "libChf/src/Chf.h"
|
||||
#include <setjmp.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "config.h"
|
||||
#include "machdep.h"
|
||||
|
@ -72,6 +76,9 @@
|
|||
#include "disk_io.h"
|
||||
#include "debug.h"
|
||||
|
||||
#define CHF_MODULE_ID DISK_IO_CHF_MODULE_ID
|
||||
#include <Chf.h>
|
||||
|
||||
/* .+
|
||||
|
||||
.title : ReadNibblesFromFile
|
||||
|
@ -105,18 +112,18 @@ int ReadNibblesFromFile( const char* name, int size, Nibble* dest )
|
|||
int by;
|
||||
int st = DISK_IO_S_OK;
|
||||
|
||||
debug1( DISK_IO_CHF_MODULE_ID, DEBUG_C_TRACE, DISK_IO_I_CALLED, "ReadNibblesFromFile" );
|
||||
debug1( DEBUG_C_TRACE, DISK_IO_I_CALLED, "ReadNibblesFromFile" );
|
||||
|
||||
if ( ( f = fopen( name, "rb" ) ) == ( FILE* )NULL ) {
|
||||
ChfGenerate( CHF_ERRNO_SET, __FILE__, __LINE__, errno, CHF_ERROR );
|
||||
ChfGenerate( DISK_IO_CHF_MODULE_ID, __FILE__, __LINE__, st = DISK_IO_E_OPEN, CHF_ERROR, name );
|
||||
ChfErrnoCondition;
|
||||
ChfCondition st = DISK_IO_E_OPEN, CHF_ERROR, name ChfEnd;
|
||||
} else {
|
||||
for ( i = 0; i < size; ) {
|
||||
by = getc( f );
|
||||
|
||||
if ( by == -1 ) {
|
||||
ChfGenerate( CHF_ERRNO_SET, __FILE__, __LINE__, errno, CHF_ERROR );
|
||||
ChfGenerate( DISK_IO_CHF_MODULE_ID, __FILE__, __LINE__, st = DISK_IO_E_GETC, CHF_ERROR, name );
|
||||
ChfErrnoCondition;
|
||||
ChfCondition st = DISK_IO_E_GETC, CHF_ERROR, name ChfEnd;
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -163,26 +170,26 @@ int WriteNibblesToFile( const Nibble* src, int size, const char* name )
|
|||
int by;
|
||||
int st = DISK_IO_S_OK;
|
||||
|
||||
debug1( DISK_IO_CHF_MODULE_ID, DEBUG_C_TRACE, DISK_IO_I_CALLED, "WriteNibblesToFile" );
|
||||
debug1( DEBUG_C_TRACE, DISK_IO_I_CALLED, "WriteNibblesToFile" );
|
||||
|
||||
if ( ( f = fopen( name, "wb" ) ) == ( FILE* )NULL ) {
|
||||
ChfGenerate( CHF_ERRNO_SET, __FILE__, __LINE__, errno, CHF_ERROR );
|
||||
ChfGenerate( DISK_IO_CHF_MODULE_ID, __FILE__, __LINE__, st = DISK_IO_E_OPEN, CHF_ERROR, name );
|
||||
ChfErrnoCondition;
|
||||
ChfCondition st = DISK_IO_E_OPEN, CHF_ERROR, name ChfEnd;
|
||||
} else {
|
||||
for ( i = 0; i < size; ) {
|
||||
by = ( int )src[ i++ ];
|
||||
by |= ( int )src[ i++ ] << 4;
|
||||
|
||||
if ( putc( by, f ) == EOF ) {
|
||||
ChfGenerate( CHF_ERRNO_SET, __FILE__, __LINE__, errno, CHF_ERROR );
|
||||
ChfGenerate( DISK_IO_CHF_MODULE_ID, __FILE__, __LINE__, st = DISK_IO_E_PUTC, CHF_ERROR, name );
|
||||
ChfErrnoCondition;
|
||||
ChfCondition st = DISK_IO_E_PUTC, CHF_ERROR, name ChfEnd;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( fclose( f ) == EOF ) {
|
||||
ChfGenerate( CHF_ERRNO_SET, __FILE__, __LINE__, errno, CHF_ERROR );
|
||||
ChfGenerate( DISK_IO_CHF_MODULE_ID, __FILE__, __LINE__, st = DISK_IO_E_CLOSE, CHF_ERROR, name );
|
||||
ChfErrnoCondition;
|
||||
ChfCondition st = DISK_IO_E_CLOSE, CHF_ERROR, name ChfEnd;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -218,15 +225,15 @@ int ReadStructFromFile( const char* name, size_t s_size, void* s )
|
|||
FILE* f;
|
||||
int st = DISK_IO_S_OK;
|
||||
|
||||
debug1( DISK_IO_CHF_MODULE_ID, DEBUG_C_TRACE, DISK_IO_I_CALLED, "ReadStructFromFile" );
|
||||
debug1( DEBUG_C_TRACE, DISK_IO_I_CALLED, "ReadStructFromFile" );
|
||||
|
||||
if ( ( f = fopen( name, "rb" ) ) == ( FILE* )NULL ) {
|
||||
ChfGenerate( CHF_ERRNO_SET, __FILE__, __LINE__, errno, CHF_ERROR );
|
||||
ChfGenerate( DISK_IO_CHF_MODULE_ID, __FILE__, __LINE__, st = DISK_IO_E_OPEN, CHF_ERROR, name );
|
||||
ChfErrnoCondition;
|
||||
ChfCondition st = DISK_IO_E_OPEN, CHF_ERROR, name ChfEnd;
|
||||
} else {
|
||||
if ( fread( s, s_size, ( size_t )1, f ) != 1 ) {
|
||||
ChfGenerate( CHF_ERRNO_SET, __FILE__, __LINE__, errno, CHF_ERROR );
|
||||
ChfGenerate( DISK_IO_CHF_MODULE_ID, __FILE__, __LINE__, st = DISK_IO_E_READ, CHF_ERROR, name );
|
||||
ChfErrnoCondition;
|
||||
ChfCondition st = DISK_IO_E_READ, CHF_ERROR, name ChfEnd;
|
||||
}
|
||||
|
||||
( void )fclose( f );
|
||||
|
@ -266,20 +273,20 @@ int WriteStructToFile( const void* s, size_t s_size, const char* name )
|
|||
FILE* f;
|
||||
int st = DISK_IO_S_OK;
|
||||
|
||||
debug1( DISK_IO_CHF_MODULE_ID, DEBUG_C_TRACE, DISK_IO_I_CALLED, "WriteStructToFile" );
|
||||
debug1( DEBUG_C_TRACE, DISK_IO_I_CALLED, "WriteStructToFile" );
|
||||
|
||||
if ( ( f = fopen( name, "wb" ) ) == ( FILE* )NULL ) {
|
||||
ChfGenerate( CHF_ERRNO_SET, __FILE__, __LINE__, errno, CHF_ERROR );
|
||||
ChfGenerate( DISK_IO_CHF_MODULE_ID, __FILE__, __LINE__, st = DISK_IO_E_OPEN, CHF_ERROR, name );
|
||||
ChfErrnoCondition;
|
||||
ChfCondition st = DISK_IO_E_OPEN, CHF_ERROR, name ChfEnd;
|
||||
} else {
|
||||
if ( fwrite( s, s_size, ( size_t )1, f ) != 1 ) {
|
||||
ChfGenerate( CHF_ERRNO_SET, __FILE__, __LINE__, errno, CHF_ERROR );
|
||||
ChfGenerate( DISK_IO_CHF_MODULE_ID, __FILE__, __LINE__, st = DISK_IO_E_WRITE, CHF_ERROR, name );
|
||||
ChfErrnoCondition;
|
||||
ChfCondition st = DISK_IO_E_WRITE, CHF_ERROR, name ChfEnd;
|
||||
}
|
||||
|
||||
if ( fclose( f ) == EOF ) {
|
||||
ChfGenerate( CHF_ERRNO_SET, __FILE__, __LINE__, errno, CHF_ERROR );
|
||||
ChfGenerate( DISK_IO_CHF_MODULE_ID, __FILE__, __LINE__, st = DISK_IO_E_CLOSE, CHF_ERROR, name );
|
||||
ChfErrnoCondition;
|
||||
ChfCondition st = DISK_IO_E_CLOSE, CHF_ERROR, name ChfEnd;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -58,12 +58,16 @@
|
|||
|
||||
.- */
|
||||
|
||||
#ifndef lint
|
||||
static char rcs_id[] = "$Id: disk_io_obj.c,v 4.1 2000/12/11 09:54:19 cibrario Rel $";
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <setjmp.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "libChf/src/Chf.h"
|
||||
|
||||
#include "config.h"
|
||||
#include "machdep.h"
|
||||
#include "cpu.h"
|
||||
|
@ -71,6 +75,9 @@
|
|||
#include "disk_io.h"
|
||||
#include "debug.h"
|
||||
|
||||
#define CHF_MODULE_ID DISK_IO_CHF_MODULE_ID
|
||||
#include <Chf.h>
|
||||
|
||||
/* .+
|
||||
|
||||
.title : ReadObjectFromFile
|
||||
|
@ -128,26 +135,26 @@ int ReadObjectFromFile( const char* name, const char* hdr, Address start, Addres
|
|||
|
||||
int st = DISK_IO_S_OK;
|
||||
|
||||
debug1( DISK_IO_CHF_MODULE_ID, DEBUG_C_TRACE, DISK_IO_I_CALLED, "ReadObjectFromFile" );
|
||||
debug1( DEBUG_C_TRACE, DISK_IO_I_CALLED, "ReadObjectFromFile" );
|
||||
|
||||
/* Save first nibbles of target space into save_area */
|
||||
for ( cur = start, i = 0; cur < end && i < N_SAVE_AREA; cur++, i++ )
|
||||
save_area[ i ] = ReadNibble( cur );
|
||||
|
||||
if ( ( f = fopen( name, "rb" ) ) == ( FILE* )NULL ) {
|
||||
ChfGenerate( CHF_ERRNO_SET, __FILE__, __LINE__, errno, CHF_ERROR );
|
||||
ChfGenerate( DISK_IO_CHF_MODULE_ID, __FILE__, __LINE__, st = DISK_IO_E_OPEN, CHF_ERROR, name );
|
||||
ChfErrnoCondition;
|
||||
ChfCondition st = DISK_IO_E_OPEN, CHF_ERROR, name ChfEnd;
|
||||
} else {
|
||||
/* Check and skip header */
|
||||
for ( i = 0; i < ( int )hdr_len; i++ ) {
|
||||
by = getc( f );
|
||||
|
||||
if ( by == EOF ) {
|
||||
ChfGenerate( CHF_ERRNO_SET, __FILE__, __LINE__, errno, CHF_ERROR );
|
||||
ChfGenerate( DISK_IO_CHF_MODULE_ID, __FILE__, __LINE__, st = DISK_IO_E_GETC, CHF_ERROR, name );
|
||||
ChfErrnoCondition;
|
||||
ChfCondition st = DISK_IO_E_GETC, CHF_ERROR, name ChfEnd;
|
||||
break;
|
||||
} else if ( hdr[ i ] != '?' && by != hdr[ i ] ) {
|
||||
ChfGenerate( DISK_IO_CHF_MODULE_ID, __FILE__, __LINE__, st = DISK_IO_E_BAD_HDR, CHF_ERROR, name );
|
||||
ChfCondition st = DISK_IO_E_BAD_HDR, CHF_ERROR, name ChfEnd;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -159,7 +166,7 @@ int ReadObjectFromFile( const char* name, const char* hdr, Address start, Addres
|
|||
while ( ( by = getc( f ) ) != EOF ) {
|
||||
/* Next byte available in by; check available space */
|
||||
if ( cur >= end - 1 ) {
|
||||
ChfGenerate( DISK_IO_CHF_MODULE_ID, __FILE__, __LINE__, st = DISK_IO_E_SIZE, CHF_ERROR, name );
|
||||
ChfCondition st = DISK_IO_E_SIZE, CHF_ERROR, name ChfEnd;
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -170,8 +177,8 @@ int ReadObjectFromFile( const char* name, const char* hdr, Address start, Addres
|
|||
|
||||
/* Check why getc() failed */
|
||||
if ( ferror( f ) && !feof( f ) ) {
|
||||
ChfGenerate( CHF_ERRNO_SET, __FILE__, __LINE__, errno, CHF_ERROR );
|
||||
ChfGenerate( DISK_IO_CHF_MODULE_ID, __FILE__, __LINE__, st = DISK_IO_E_GETC, CHF_ERROR, name );
|
||||
ChfErrnoCondition;
|
||||
ChfCondition st = DISK_IO_E_GETC, CHF_ERROR, name ChfEnd;
|
||||
}
|
||||
|
||||
/* Recover from save_area if transfer failed */
|
||||
|
@ -229,17 +236,17 @@ int WriteObjectToFile( Address start, Address end, const char* hdr, const char*
|
|||
|
||||
int st = DISK_IO_S_OK;
|
||||
|
||||
debug1( DISK_IO_CHF_MODULE_ID, DEBUG_C_TRACE, DISK_IO_I_CALLED, "WriteObjectFromFile" );
|
||||
debug1( DEBUG_C_TRACE, DISK_IO_I_CALLED, "WriteObjectFromFile" );
|
||||
|
||||
if ( ( f = fopen( name, "wb" ) ) == ( FILE* )NULL ) {
|
||||
ChfGenerate( CHF_ERRNO_SET, __FILE__, __LINE__, errno, CHF_ERROR );
|
||||
ChfGenerate( DISK_IO_CHF_MODULE_ID, __FILE__, __LINE__, st = DISK_IO_E_OPEN, CHF_ERROR, name );
|
||||
ChfErrnoCondition;
|
||||
ChfCondition st = DISK_IO_E_OPEN, CHF_ERROR, name ChfEnd;
|
||||
} else {
|
||||
/* Write header; replace wildcard character '?' with 'S' */
|
||||
for ( i = 0; i < ( int )hdr_len; i++ ) {
|
||||
if ( putc( hdr[ i ] == '?' ? 'S' : hdr[ i ], f ) == EOF ) {
|
||||
ChfGenerate( CHF_ERRNO_SET, __FILE__, __LINE__, errno, CHF_ERROR );
|
||||
ChfGenerate( DISK_IO_CHF_MODULE_ID, __FILE__, __LINE__, st = DISK_IO_E_PUTC, CHF_ERROR, name );
|
||||
ChfErrnoCondition;
|
||||
ChfCondition st = DISK_IO_E_PUTC, CHF_ERROR, name ChfEnd;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -253,8 +260,8 @@ int WriteObjectToFile( Address start, Address end, const char* hdr, const char*
|
|||
by |= ( int )ReadNibble( cur++ ) << 4;
|
||||
|
||||
if ( putc( by, f ) == EOF ) {
|
||||
ChfGenerate( CHF_ERRNO_SET, __FILE__, __LINE__, errno, CHF_ERROR );
|
||||
ChfGenerate( DISK_IO_CHF_MODULE_ID, __FILE__, __LINE__, st = DISK_IO_E_PUTC, CHF_ERROR, name );
|
||||
ChfErrnoCondition;
|
||||
ChfCondition st = DISK_IO_E_PUTC, CHF_ERROR, name ChfEnd;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -264,16 +271,16 @@ int WriteObjectToFile( Address start, Address end, const char* hdr, const char*
|
|||
by = ( int )ReadNibble( cur++ );
|
||||
|
||||
if ( putc( by, f ) == EOF ) {
|
||||
ChfGenerate( CHF_ERRNO_SET, __FILE__, __LINE__, errno, CHF_ERROR );
|
||||
ChfGenerate( DISK_IO_CHF_MODULE_ID, __FILE__, __LINE__, st = DISK_IO_E_PUTC, CHF_ERROR, name );
|
||||
ChfErrnoCondition;
|
||||
ChfCondition st = DISK_IO_E_PUTC, CHF_ERROR, name ChfEnd;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Close the output file anyway */
|
||||
if ( fclose( f ) == EOF ) {
|
||||
ChfGenerate( CHF_ERRNO_SET, __FILE__, __LINE__, errno, CHF_ERROR );
|
||||
ChfGenerate( DISK_IO_CHF_MODULE_ID, __FILE__, __LINE__, st = DISK_IO_E_CLOSE, CHF_ERROR, name );
|
||||
ChfErrnoCondition;
|
||||
ChfCondition st = DISK_IO_E_CLOSE, CHF_ERROR, name ChfEnd;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
456
src/emulator.c
456
src/emulator.c
|
@ -107,6 +107,10 @@
|
|||
|
||||
.- */
|
||||
|
||||
#ifndef lint
|
||||
static char rcs_id[] = "$Id: emulator.c,v 4.1 2000/12/11 09:54:19 cibrario Rel $";
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <setjmp.h>
|
||||
|
@ -114,15 +118,18 @@
|
|||
#include <unistd.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#include "libChf/src/Chf.h"
|
||||
|
||||
#include "config.h"
|
||||
#include "machdep.h"
|
||||
#include "cpu.h"
|
||||
#include "modules.h"
|
||||
#include "x11_lcd.h"
|
||||
#include "x11.h"
|
||||
#include "serial.h"
|
||||
#include "debug.h"
|
||||
|
||||
#define CHF_MODULE_ID CPU_CHF_MODULE_ID
|
||||
#include <Chf.h>
|
||||
|
||||
/*---------------------------------------------------------------------------
|
||||
Private macros / variables / functions
|
||||
---------------------------------------------------------------------------*/
|
||||
|
@ -154,7 +161,7 @@
|
|||
#define LCD_T1_MASK 0x3 /* LCD refresh timing mask */
|
||||
#define INT_T1_MASK 0xF /* Int. req. timing mask */
|
||||
|
||||
static bool emulator_int_req = false; /* Interrupt request flag */
|
||||
static int emulator_int_req = 0; /* Interrupt request flag */
|
||||
|
||||
/* This function contains the main emulator loop; under normal conditions,
|
||||
it never returns to the caller. The only way to exit this function is
|
||||
|
@ -166,26 +173,27 @@ static void EmulatorLoop( void )
|
|||
int ela;
|
||||
int inner_loop = cpu_status.inner_loop;
|
||||
int t1_count = 0;
|
||||
int i, j;
|
||||
|
||||
debug1( CPU_CHF_MODULE_ID, DEBUG_C_TRACE, CPU_I_CALLED, "EmulatorLoop" );
|
||||
debug1( DEBUG_C_TRACE, CPU_I_CALLED, "EmulatorLoop" );
|
||||
|
||||
/* Ignore past interrupt requests */
|
||||
emulator_int_req = false;
|
||||
emulator_int_req = 0;
|
||||
|
||||
/* Get current time of day */
|
||||
gettimeofday( &old_t, NULL );
|
||||
|
||||
while ( true ) {
|
||||
while ( 1 ) {
|
||||
/* T1 loop */
|
||||
for ( int j = 0; j < T1_MULTIPLIER; j++ ) {
|
||||
for ( j = 0; j < T1_MULTIPLIER; j++ ) {
|
||||
/* Inner loop */
|
||||
for ( int i = 0; i < inner_loop; i++ )
|
||||
for ( i = 0; i < inner_loop; i++ )
|
||||
OneStep();
|
||||
|
||||
/* T2 update */
|
||||
if ( mod_status.hdw.t2_ctrl & T2_CTRL_TRUN ) {
|
||||
if ( --mod_status.hdw.t2_val == ( int )0xFFFFFFFF ) {
|
||||
debug1( CPU_CHF_MODULE_ID, DEBUG_C_TIMERS, CPU_I_TIMER2_EX, mod_status.hdw.t2_ctrl );
|
||||
debug1( DEBUG_C_TIMERS, CPU_I_TIMER2_EX, mod_status.hdw.t2_ctrl );
|
||||
|
||||
mod_status.hdw.t2_ctrl |= T2_CTRL_SREQ;
|
||||
|
||||
|
@ -201,7 +209,7 @@ static void EmulatorLoop( void )
|
|||
/* T1 update */
|
||||
mod_status.hdw.t1_val = ( mod_status.hdw.t1_val - 1 ) & NIBBLE_MASK;
|
||||
if ( mod_status.hdw.t1_val == 0xF ) {
|
||||
debug1( CPU_CHF_MODULE_ID, DEBUG_C_TIMERS, CPU_I_TIMER1_EX, mod_status.hdw.t1_ctrl );
|
||||
debug1( DEBUG_C_TIMERS, CPU_I_TIMER1_EX, mod_status.hdw.t1_ctrl );
|
||||
|
||||
mod_status.hdw.t1_ctrl |= T1_CTRL_SREQ;
|
||||
|
||||
|
@ -217,13 +225,13 @@ static void EmulatorLoop( void )
|
|||
/* DrawLcd(); */
|
||||
|
||||
/* Emulator Interrupt Request */
|
||||
if ( ( t1_count++ & INT_T1_MASK ) == 0 && emulator_int_req ) {
|
||||
ChfGenerate( CPU_CHF_MODULE_ID, __FILE__, __LINE__, CPU_I_EMULATOR_INT, CHF_INFO );
|
||||
ChfSignal( CPU_CHF_MODULE_ID );
|
||||
if ( ( t1_count & INT_T1_MASK ) == 0 && emulator_int_req ) {
|
||||
ChfCondition CPU_I_EMULATOR_INT, CHF_INFO ChfEnd;
|
||||
ChfSignal();
|
||||
}
|
||||
|
||||
/* UI Events handling */
|
||||
// ui_get_event();
|
||||
/* X Events handling */
|
||||
/* HandleXEvents(); */
|
||||
|
||||
/* Handle serial port */
|
||||
HandleSerial();
|
||||
|
@ -237,237 +245,236 @@ static void EmulatorLoop( void )
|
|||
if ( inner_loop < INNER_LOOP_MIN )
|
||||
inner_loop = INNER_LOOP_MIN;
|
||||
|
||||
/* 3.13: Force an upper limit to the CPU speed if the run-time option
|
||||
config.throttle is defined: inner_loop is limited to
|
||||
#ifdef REAL_CPU_SPEED
|
||||
/* 3.13: Force an upper limit to the CPU speed if the compile-time option
|
||||
REAL_CPU_SPEED is defined: inner_loop is limited to
|
||||
cpu_status.inner_loop_max
|
||||
and the excess time, if any, is spent sleeping; usleep() is
|
||||
BSD 4.3-specific, but most recent systems should offer it anyway,
|
||||
well, I hope.
|
||||
The special value cpu_status.inner_loop_max==0 gives maximum speed.
|
||||
*/
|
||||
if ( config.throttle )
|
||||
if ( cpu_status.inner_loop_max != 0 && inner_loop >= cpu_status.inner_loop_max ) {
|
||||
inner_loop = cpu_status.inner_loop_max;
|
||||
if ( T1_INTERVAL > ela )
|
||||
usleep( T1_INTERVAL - ela );
|
||||
}
|
||||
if ( cpu_status.inner_loop_max != 0 && inner_loop >= cpu_status.inner_loop_max ) {
|
||||
inner_loop = cpu_status.inner_loop_max;
|
||||
if ( T1_INTERVAL > ela )
|
||||
usleep( T1_INTERVAL - ela );
|
||||
}
|
||||
#endif
|
||||
|
||||
cpu_status.inner_loop = inner_loop;
|
||||
old_t = cur_t;
|
||||
}
|
||||
}
|
||||
|
||||
static ChfAction do_SHUTDN( void )
|
||||
{
|
||||
/* 3.1: CPU_SPIN_SHUTDN is not defined, and the cpu emulator
|
||||
has just executed a shutdown instruction.
|
||||
Let's do something a little tricky here:
|
||||
|
||||
//1- redraw the LCD
|
||||
|
||||
2- handle serial port activities
|
||||
|
||||
3- determine which timer will expire first, and
|
||||
compute an approximate value of the maximum duration
|
||||
of the shutdown --> ms
|
||||
|
||||
4- handle serial port activities
|
||||
|
||||
5- enter the inner idle loop; it breaks when either an
|
||||
X Event occurred (possibly clearing the shutdown) or
|
||||
the shutdown timeout elapses
|
||||
|
||||
6- determine the actual time we spend in the idle loop
|
||||
(X timeouts are not accurate enough for this purpose)
|
||||
|
||||
7- update T1 and T2, check their state and wake/interrupt
|
||||
the CPU if necessary
|
||||
|
||||
Activities 3-7 above are enclosed in an outer loop because we
|
||||
cannot be absolutely sure of the actual time spent
|
||||
in the idle loop; moreover, not all X Events actually
|
||||
spool up the CPU. The outer loop breaks when the CPU is
|
||||
actually brought out of shutdown.
|
||||
|
||||
frac_t1 and frac_t2 contain the number of microseconds
|
||||
not accounted for in the last T1/T2 update, respectively;
|
||||
they help minimize the cumulative timing error induced
|
||||
by executing the outer idle loop more than once.
|
||||
*/
|
||||
struct timeval start_idle, end_idle;
|
||||
int frac_t1 = 0, frac_t2 = 0;
|
||||
|
||||
gettimeofday( &start_idle, NULL );
|
||||
|
||||
/* Redraw the LCD immediately before entering idle loop;
|
||||
this ensures that the latest LCD updated actually
|
||||
get to the screen.
|
||||
*/
|
||||
// ui_update_display();
|
||||
|
||||
/* Handle serial port activity before entering the outer idle
|
||||
loop, because this could possibly bring the cpu out of
|
||||
shutdown right now.
|
||||
*/
|
||||
HandleSerial();
|
||||
|
||||
/* XXX
|
||||
If either timer has a pending service request,
|
||||
process it immediately. It is not clear why it was
|
||||
not processed *before* shutdown, though.
|
||||
*/
|
||||
if ( mod_status.hdw.t1_ctrl & T1_CTRL_SREQ ) {
|
||||
if ( mod_status.hdw.t1_ctrl & T1_CTRL_WAKE )
|
||||
CpuWake();
|
||||
|
||||
if ( mod_status.hdw.t1_ctrl & T1_CTRL_INT )
|
||||
CpuIntRequest( INT_REQUEST_IRQ );
|
||||
}
|
||||
|
||||
if ( mod_status.hdw.t2_ctrl & T2_CTRL_SREQ ) {
|
||||
if ( mod_status.hdw.t2_ctrl & T2_CTRL_WAKE )
|
||||
CpuWake();
|
||||
|
||||
if ( mod_status.hdw.t2_ctrl & T2_CTRL_INT )
|
||||
CpuIntRequest( INT_REQUEST_IRQ );
|
||||
}
|
||||
|
||||
while ( cpu_status.shutdn ) {
|
||||
unsigned long ms = MAX_IDLE_X_LOOP_TIMEOUT;
|
||||
unsigned long mst;
|
||||
int ela;
|
||||
int ela_ticks;
|
||||
|
||||
debug3( CPU_CHF_MODULE_ID, DEBUG_C_TIMERS, CPU_I_TIMER_ST, "T1 (during SHUTDN)", mod_status.hdw.t1_ctrl, mod_status.hdw.t1_val );
|
||||
debug3( CPU_CHF_MODULE_ID, DEBUG_C_TIMERS, CPU_I_TIMER_ST, "T2 (during SHUTDN)", mod_status.hdw.t2_ctrl, mod_status.hdw.t2_val );
|
||||
|
||||
/* Determine which timer will expire first */
|
||||
if ( mod_status.hdw.t1_ctrl & ( T1_CTRL_INT | T1_CTRL_WAKE ) ) {
|
||||
/* T1 will do something on expiration */
|
||||
mst = ( ( unsigned long )mod_status.hdw.t1_val + 1 ) * T1_MS_MULTIPLIER;
|
||||
|
||||
debug2( CPU_CHF_MODULE_ID, DEBUG_C_TIMERS, CPU_I_TIMER_EXP, "T1", mst );
|
||||
|
||||
if ( mst < ms )
|
||||
ms = mst;
|
||||
}
|
||||
|
||||
if ( ( mod_status.hdw.t2_ctrl & T2_CTRL_TRUN ) && ( mod_status.hdw.t2_ctrl & ( T2_CTRL_INT | T2_CTRL_WAKE ) ) ) {
|
||||
/* T2 is running and will do something on expiration */
|
||||
mst = ( ( unsigned long )mod_status.hdw.t2_val + 1 ) / T2_MS_DIVISOR;
|
||||
|
||||
debug2( CPU_CHF_MODULE_ID, DEBUG_C_TIMERS, CPU_I_TIMER_EXP, "T2", mst );
|
||||
|
||||
if ( mst < ms )
|
||||
ms = mst;
|
||||
}
|
||||
|
||||
/* Handle serial port activities at each iteration of
|
||||
the outer idle loop; this ensures that the serial
|
||||
port emulation will not starve.
|
||||
*/
|
||||
HandleSerial();
|
||||
|
||||
/* Enter idle loop, possibly with timeout;
|
||||
The loop breaks when:
|
||||
- any X Event occurs (possibly clearing the shutdown)
|
||||
- the given timeout expires
|
||||
*/
|
||||
debug1( CPU_CHF_MODULE_ID, DEBUG_C_TIMERS, CPU_I_IDLE_X_LOOP, ms );
|
||||
// IdleXLoop( ms );
|
||||
usleep( ms );
|
||||
|
||||
/* End of idle loop; compute actual elapsed time */
|
||||
gettimeofday( &end_idle, NULL );
|
||||
|
||||
ela = ( end_idle.tv_sec - start_idle.tv_sec ) * 1000000 + ( end_idle.tv_usec - start_idle.tv_usec );
|
||||
|
||||
/* Update start_idle here to contain lag */
|
||||
start_idle = end_idle;
|
||||
|
||||
debug1( CPU_CHF_MODULE_ID, DEBUG_C_TIMERS, CPU_I_ELAPSED, ela );
|
||||
|
||||
/* Update timers and act accordingly */
|
||||
ela_ticks = ( ( ela + frac_t1 ) + T1_INTERVAL / 2 ) / T1_INTERVAL;
|
||||
frac_t1 = ( ela + frac_t1 ) - ela_ticks * T1_INTERVAL;
|
||||
|
||||
if ( ela_ticks > mod_status.hdw.t1_val ) {
|
||||
debug1( CPU_CHF_MODULE_ID, DEBUG_C_TIMERS, CPU_I_TIMER1_EX, mod_status.hdw.t1_ctrl );
|
||||
|
||||
mod_status.hdw.t1_ctrl |= T1_CTRL_SREQ;
|
||||
|
||||
if ( mod_status.hdw.t1_ctrl & T1_CTRL_WAKE )
|
||||
CpuWake();
|
||||
|
||||
if ( mod_status.hdw.t1_ctrl & T1_CTRL_INT )
|
||||
CpuIntRequest( INT_REQUEST_IRQ );
|
||||
}
|
||||
|
||||
mod_status.hdw.t1_val = ( mod_status.hdw.t1_val - ela_ticks ) & T1_OVF_MASK;
|
||||
|
||||
if ( mod_status.hdw.t2_ctrl & T2_CTRL_TRUN ) {
|
||||
ela_ticks = ( ( ela + frac_t2 ) + T2_INTERVAL / 2 ) / T2_INTERVAL;
|
||||
frac_t2 = ( ela + frac_t2 ) - ela_ticks * T2_INTERVAL;
|
||||
|
||||
if ( ela_ticks > mod_status.hdw.t2_val ) {
|
||||
debug1( CPU_CHF_MODULE_ID, DEBUG_C_TIMERS, CPU_I_TIMER2_EX, mod_status.hdw.t2_ctrl );
|
||||
|
||||
mod_status.hdw.t2_ctrl |= T2_CTRL_SREQ;
|
||||
|
||||
if ( mod_status.hdw.t2_ctrl & T2_CTRL_WAKE )
|
||||
CpuWake();
|
||||
|
||||
if ( mod_status.hdw.t2_ctrl & T2_CTRL_INT )
|
||||
CpuIntRequest( INT_REQUEST_IRQ );
|
||||
}
|
||||
|
||||
mod_status.hdw.t2_val = ( mod_status.hdw.t2_val - ela_ticks ) & T2_OVF_MASK;
|
||||
}
|
||||
}
|
||||
|
||||
debug3( CPU_CHF_MODULE_ID, DEBUG_C_TIMERS, CPU_I_TIMER_ST, "T1 (after SHUTDN)", mod_status.hdw.t1_ctrl, mod_status.hdw.t1_val );
|
||||
debug3( CPU_CHF_MODULE_ID, DEBUG_C_TIMERS, CPU_I_TIMER_ST, "T2 (after SHUTDN)", mod_status.hdw.t2_ctrl, mod_status.hdw.t2_val );
|
||||
|
||||
return CHF_CONTINUE;
|
||||
}
|
||||
|
||||
/* Condition handler for the EmulatorLoop */
|
||||
static ChfAction EmulatorLoopHandler( const ChfDescriptor* descriptor, const ChfState state, void* _ctx )
|
||||
static ChfAction EmulatorLoopHandler( const ChfDescriptor* d, const ChfState s, ChfPointer ctx )
|
||||
{
|
||||
ChfAction act;
|
||||
|
||||
/* Check Chf state */
|
||||
switch ( state ) {
|
||||
switch ( s ) {
|
||||
/* 2.1: Chf release 2 fixed the spelling of 'SIGNALING' */
|
||||
case CHF_SIGNALING:
|
||||
/* ChfSignal() in progress */
|
||||
switch ( descriptor->module_id ) {
|
||||
case CPU_CHF_MODULE_ID:
|
||||
/* Condition from CPU modules; check Condition Code */
|
||||
switch ( descriptor->condition_code ) {
|
||||
case CPU_I_SHUTDN:
|
||||
act = do_SHUTDN();
|
||||
break;
|
||||
if ( ChfGetModuleId( d ) == CPU_CHF_MODULE_ID ) {
|
||||
/* Condition from CPU modules; check Condition Code */
|
||||
switch ( ChfGetConditionCode( d ) ) {
|
||||
case CPU_I_SHUTDN:
|
||||
{
|
||||
/* 3.1: CPU_SPIN_SHUTDN is not defined, and the cpu emulator
|
||||
has just executed a shutdown instruction.
|
||||
Let's do something a little tricky here:
|
||||
|
||||
case CPU_I_EMULATOR_INT:
|
||||
/* Emulator interrupt; unwind */
|
||||
act = CHF_UNWIND;
|
||||
break;
|
||||
1- redraw the LCD
|
||||
|
||||
2- handle serial port activities
|
||||
|
||||
3- determine which timer will expire first, and
|
||||
compute an approximate value of the maximum duration
|
||||
of the shutdown --> ms
|
||||
|
||||
4- handle serial port activities
|
||||
|
||||
5- enter the inner idle loop; it breaks when either an
|
||||
X Event occurred (possibly clearing the shutdown) or
|
||||
the shutdown timeout elapses
|
||||
|
||||
6- determine the actual time we spend in the idle loop
|
||||
(X timeouts are not accurate enough for this purpose)
|
||||
|
||||
7- update T1 and T2, check their state and wake/interrupt
|
||||
the CPU if necessary
|
||||
|
||||
Activities 3-7 above are enclosed in an outer loop because we
|
||||
cannot be absolutely sure of the actual time spent
|
||||
in the idle loop; moreover, not all X Events actually
|
||||
spool up the CPU. The outer loop breaks when the CPU is
|
||||
actually brought out of shutdown.
|
||||
|
||||
frac_t1 and frac_t2 contain the number of microseconds
|
||||
not accounted for in the last T1/T2 update, respectively;
|
||||
they help minimize the cumulative timing error induced
|
||||
by executing the outer idle loop more than once.
|
||||
*/
|
||||
struct timeval start_idle, end_idle;
|
||||
int frac_t1 = 0, frac_t2 = 0;
|
||||
|
||||
gettimeofday( &start_idle, NULL );
|
||||
|
||||
/* Redraw the LCD immediately before entering idle loop;
|
||||
this ensures that the latest LCD updated actually
|
||||
get to the screen.
|
||||
*/
|
||||
// DrawLcd();
|
||||
|
||||
/* Handle serial port activity before entering the outer idle
|
||||
loop, because this could possibly bring the cpu out of
|
||||
shutdown right now.
|
||||
*/
|
||||
HandleSerial();
|
||||
|
||||
/* XXX
|
||||
If either timer has a pending service request,
|
||||
process it immediately. It is not clear why it was
|
||||
not processed *before* shutdown, though.
|
||||
*/
|
||||
if ( mod_status.hdw.t1_ctrl & T1_CTRL_SREQ ) {
|
||||
if ( mod_status.hdw.t1_ctrl & T1_CTRL_WAKE )
|
||||
CpuWake();
|
||||
|
||||
if ( mod_status.hdw.t1_ctrl & T1_CTRL_INT )
|
||||
CpuIntRequest( INT_REQUEST_IRQ );
|
||||
}
|
||||
|
||||
if ( mod_status.hdw.t2_ctrl & T2_CTRL_SREQ ) {
|
||||
if ( mod_status.hdw.t2_ctrl & T2_CTRL_WAKE )
|
||||
CpuWake();
|
||||
|
||||
if ( mod_status.hdw.t2_ctrl & T2_CTRL_INT )
|
||||
CpuIntRequest( INT_REQUEST_IRQ );
|
||||
}
|
||||
|
||||
while ( cpu_status.shutdn ) {
|
||||
unsigned long ms = MAX_IDLE_X_LOOP_TIMEOUT;
|
||||
unsigned long mst;
|
||||
int ela;
|
||||
int ela_ticks;
|
||||
|
||||
debug3( DEBUG_C_TIMERS, CPU_I_TIMER_ST, "T1 (during SHUTDN)", mod_status.hdw.t1_ctrl,
|
||||
mod_status.hdw.t1_val );
|
||||
debug3( DEBUG_C_TIMERS, CPU_I_TIMER_ST, "T2 (during SHUTDN)", mod_status.hdw.t2_ctrl,
|
||||
mod_status.hdw.t2_val );
|
||||
|
||||
/* Determine which timer will expire first */
|
||||
if ( mod_status.hdw.t1_ctrl & ( T1_CTRL_INT | T1_CTRL_WAKE ) ) {
|
||||
/* T1 will do something on expiration */
|
||||
mst = ( ( unsigned long )mod_status.hdw.t1_val + 1 ) * T1_MS_MULTIPLIER;
|
||||
|
||||
debug2( DEBUG_C_TIMERS, CPU_I_TIMER_EXP, "T1", mst );
|
||||
|
||||
if ( mst < ms )
|
||||
ms = mst;
|
||||
}
|
||||
|
||||
if ( ( mod_status.hdw.t2_ctrl & T2_CTRL_TRUN ) &&
|
||||
( mod_status.hdw.t2_ctrl & ( T2_CTRL_INT | T2_CTRL_WAKE ) ) ) {
|
||||
/* T2 is running and will do something on expiration */
|
||||
mst = ( ( unsigned long )mod_status.hdw.t2_val + 1 ) / T2_MS_DIVISOR;
|
||||
|
||||
debug2( DEBUG_C_TIMERS, CPU_I_TIMER_EXP, "T2", mst );
|
||||
|
||||
if ( mst < ms )
|
||||
ms = mst;
|
||||
}
|
||||
|
||||
/* Handle serial port activities at each iteration of
|
||||
the outer idle loop; this ensures that the serial
|
||||
port emulation will not starve.
|
||||
*/
|
||||
HandleSerial();
|
||||
|
||||
/* Enter idle loop, possibly with timeout;
|
||||
The loop breaks when:
|
||||
- any X Event occurs (possibly clearing the shutdown)
|
||||
- the given timeout expires
|
||||
*/
|
||||
debug1( DEBUG_C_TIMERS, CPU_I_IDLE_X_LOOP, ms );
|
||||
// IdleXLoop( ms );
|
||||
|
||||
/* End of idle loop; compute actual elapsed time */
|
||||
gettimeofday( &end_idle, NULL );
|
||||
|
||||
ela = ( end_idle.tv_sec - start_idle.tv_sec ) * 1000000 + ( end_idle.tv_usec - start_idle.tv_usec );
|
||||
|
||||
/* Update start_idle here to contain lag */
|
||||
start_idle = end_idle;
|
||||
|
||||
debug1( DEBUG_C_TIMERS, CPU_I_ELAPSED, ela );
|
||||
|
||||
/* Update timers and act accordingly */
|
||||
ela_ticks = ( ( ela + frac_t1 ) + T1_INTERVAL / 2 ) / T1_INTERVAL;
|
||||
frac_t1 = ( ela + frac_t1 ) - ela_ticks * T1_INTERVAL;
|
||||
|
||||
if ( ela_ticks > mod_status.hdw.t1_val ) {
|
||||
debug1( DEBUG_C_TIMERS, CPU_I_TIMER1_EX, mod_status.hdw.t1_ctrl );
|
||||
|
||||
mod_status.hdw.t1_ctrl |= T1_CTRL_SREQ;
|
||||
|
||||
if ( mod_status.hdw.t1_ctrl & T1_CTRL_WAKE )
|
||||
CpuWake();
|
||||
|
||||
if ( mod_status.hdw.t1_ctrl & T1_CTRL_INT )
|
||||
CpuIntRequest( INT_REQUEST_IRQ );
|
||||
}
|
||||
|
||||
mod_status.hdw.t1_val = ( mod_status.hdw.t1_val - ela_ticks ) & T1_OVF_MASK;
|
||||
|
||||
if ( mod_status.hdw.t2_ctrl & T2_CTRL_TRUN ) {
|
||||
ela_ticks = ( ( ela + frac_t2 ) + T2_INTERVAL / 2 ) / T2_INTERVAL;
|
||||
frac_t2 = ( ela + frac_t2 ) - ela_ticks * T2_INTERVAL;
|
||||
|
||||
if ( ela_ticks > mod_status.hdw.t2_val ) {
|
||||
debug1( DEBUG_C_TIMERS, CPU_I_TIMER2_EX, mod_status.hdw.t2_ctrl );
|
||||
|
||||
mod_status.hdw.t2_ctrl |= T2_CTRL_SREQ;
|
||||
|
||||
if ( mod_status.hdw.t2_ctrl & T2_CTRL_WAKE )
|
||||
CpuWake();
|
||||
|
||||
if ( mod_status.hdw.t2_ctrl & T2_CTRL_INT )
|
||||
CpuIntRequest( INT_REQUEST_IRQ );
|
||||
}
|
||||
|
||||
mod_status.hdw.t2_val = ( mod_status.hdw.t2_val - ela_ticks ) & T2_OVF_MASK;
|
||||
}
|
||||
}
|
||||
|
||||
debug3( DEBUG_C_TIMERS, CPU_I_TIMER_ST, "T1 (after SHUTDN)", mod_status.hdw.t1_ctrl, mod_status.hdw.t1_val );
|
||||
debug3( DEBUG_C_TIMERS, CPU_I_TIMER_ST, "T2 (after SHUTDN)", mod_status.hdw.t2_ctrl, mod_status.hdw.t2_val );
|
||||
|
||||
act = CHF_CONTINUE;
|
||||
}
|
||||
break;
|
||||
|
||||
case CPU_I_EMULATOR_INT:
|
||||
/* Emulator interrupt; unwind */
|
||||
act = CHF_UNWIND;
|
||||
break;
|
||||
|
||||
default:
|
||||
/* Condition Code not handled; resignal */
|
||||
act = CHF_RESIGNAL;
|
||||
}
|
||||
} else
|
||||
/* Condition from other modules; resignal */
|
||||
act = CHF_RESIGNAL;
|
||||
|
||||
default:
|
||||
/* Condition Code not handled; resignal */
|
||||
act = CHF_RESIGNAL;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
/* Condition from other modules; resignal */
|
||||
act = CHF_RESIGNAL;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
/* Other states; resignal the condition */
|
||||
act = CHF_RESIGNAL;
|
||||
break;
|
||||
}
|
||||
|
||||
return act;
|
||||
|
@ -510,12 +517,12 @@ void Emulator( void )
|
|||
{
|
||||
jmp_buf unwind_context;
|
||||
|
||||
debug1( CPU_CHF_MODULE_ID, DEBUG_C_TRACE, CPU_I_CALLED, "Emulator" );
|
||||
debug1( DEBUG_C_TRACE, CPU_I_CALLED, "Emulator" );
|
||||
|
||||
/* Setup unwind_context */
|
||||
if ( setjmp( unwind_context ) == 0 ) {
|
||||
/* Push condition handler, with NULL context */
|
||||
ChfPushHandler( CPU_CHF_MODULE_ID, EmulatorLoopHandler, &unwind_context, ( void* )NULL );
|
||||
ChfPushHandler( EmulatorLoopHandler, &unwind_context, ( ChfPointer )NULL );
|
||||
|
||||
/* Activate emulator loop */
|
||||
EmulatorLoop();
|
||||
|
@ -546,7 +553,7 @@ void Emulator( void )
|
|||
1.1, 18-Feb-1998, creation
|
||||
|
||||
.- */
|
||||
void EmulatorIntRequest( void ) { emulator_int_req = true; }
|
||||
void EmulatorIntRequest( void ) { emulator_int_req = 1; }
|
||||
|
||||
/* .+
|
||||
|
||||
|
@ -581,14 +588,14 @@ void EmulatorIntRequest( void ) { emulator_int_req = true; }
|
|||
void EmulatorInit( void )
|
||||
{
|
||||
/* Select a module description table */
|
||||
ModSelectDescription( config.model );
|
||||
ModSelectDescription( args.hw );
|
||||
|
||||
/* Initialize cpu and modules subsystems */
|
||||
CpuInit();
|
||||
ModInit();
|
||||
|
||||
/* Reset if appropriate */
|
||||
if ( config.reset ) {
|
||||
if ( args.reset ) {
|
||||
CpuReset();
|
||||
ModReset();
|
||||
}
|
||||
|
@ -630,5 +637,4 @@ void EmulatorExit( enum ExitOption opt )
|
|||
/* Default behavior; do nothing */
|
||||
break;
|
||||
}
|
||||
ChfExit();
|
||||
}
|
||||
|
|
|
@ -69,7 +69,14 @@
|
|||
|
||||
.- */
|
||||
|
||||
#include "libChf/src/Chf.h"
|
||||
#ifndef lint
|
||||
static char rcs_id[] = "$Id: flash49.c,v 4.1 2000/12/11 09:54:19 cibrario Rel $";
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <setjmp.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "config.h"
|
||||
#include "machdep.h"
|
||||
|
@ -78,6 +85,9 @@
|
|||
#include "flash49.h"
|
||||
#include "debug.h"
|
||||
|
||||
#define CHF_MODULE_ID FLASH_CHF_MODULE_ID
|
||||
#include <Chf.h>
|
||||
|
||||
/*---------------------------------------------------------------------------
|
||||
Private Macro/Data type definitions
|
||||
---------------------------------------------------------------------------*/
|
||||
|
@ -131,8 +141,8 @@ static int wb[ WB_SIZE ]; /* Write buffer */
|
|||
static int BadCommand( enum FlashState* state, enum FlashCycle cycle, XAddress address, int data )
|
||||
{
|
||||
/* Unknown command: signal and reset state to FLASH_ST_READ_ARRAY */
|
||||
ChfGenerate( FLASH_CHF_MODULE_ID, __FILE__, __LINE__, FLASH_W_BAD_CMD, CHF_WARNING, *state, cycle, address, data );
|
||||
ChfSignal( FLASH_CHF_MODULE_ID );
|
||||
ChfCondition FLASH_W_BAD_CMD, CHF_WARNING, *state, cycle, address, data ChfEnd;
|
||||
ChfSignal();
|
||||
|
||||
*state = FLASH_ST_READ_ARRAY;
|
||||
return 0; /* Dummy result */
|
||||
|
@ -151,7 +161,7 @@ static int ParseCommand( enum FlashState* state, enum FlashCycle cycle, XAddress
|
|||
switch ( data ) {
|
||||
case FLASH_CMD_READ_ARRAY:
|
||||
/* Transition to FLASH_ST_READ_ARRAY state */
|
||||
debug1( FLASH_CHF_MODULE_ID, DEBUG_C_FLASH, FLASH_I_FSM_OP, "Read Array" );
|
||||
debug1( DEBUG_C_FLASH, FLASH_I_FSM_OP, "Read Array" );
|
||||
*state = FLASH_ST_READ_ARRAY;
|
||||
break;
|
||||
|
||||
|
@ -160,14 +170,14 @@ static int ParseCommand( enum FlashState* state, enum FlashCycle cycle, XAddress
|
|||
The current implementation does nothing, because
|
||||
the value of the status register is fixed. No state transitions.
|
||||
*/
|
||||
debug1( FLASH_CHF_MODULE_ID, DEBUG_C_FLASH, FLASH_I_FSM_OP, "Clear Status" );
|
||||
debug1( DEBUG_C_FLASH, FLASH_I_FSM_OP, "Clear Status" );
|
||||
break;
|
||||
|
||||
case FLASH_CMD_WRITE_BUFFER:
|
||||
/* Write to Buffer; section 4.8 on Data Sheet.
|
||||
Transition to FLASH_ST_READ_XSR state.
|
||||
*/
|
||||
debug1( FLASH_CHF_MODULE_ID, DEBUG_C_FLASH, FLASH_I_FSM_OP, "Write to Buffer (start)" );
|
||||
debug1( DEBUG_C_FLASH, FLASH_I_FSM_OP, "Write to Buffer (start)" );
|
||||
*state = FLASH_ST_READ_XSR;
|
||||
break;
|
||||
|
||||
|
@ -175,7 +185,7 @@ static int ParseCommand( enum FlashState* state, enum FlashCycle cycle, XAddress
|
|||
/* Read Status; section 4.4 on Data Sheet.
|
||||
Transition to FLASH_ST_READ_SR state.
|
||||
*/
|
||||
debug1( FLASH_CHF_MODULE_ID, DEBUG_C_FLASH, FLASH_I_FSM_OP, "Read Status" );
|
||||
debug1( DEBUG_C_FLASH, FLASH_I_FSM_OP, "Read Status" );
|
||||
*state = FLASH_ST_READ_SR;
|
||||
break;
|
||||
|
||||
|
@ -184,14 +194,14 @@ static int ParseCommand( enum FlashState* state, enum FlashCycle cycle, XAddress
|
|||
Transition to FLASH_ST_BL_ERASE state.
|
||||
Consistency of block addresses is not checked.
|
||||
*/
|
||||
debug1( FLASH_CHF_MODULE_ID, DEBUG_C_FLASH, FLASH_I_FSM_OP, "Erase Block (start)" );
|
||||
debug1( DEBUG_C_FLASH, FLASH_I_FSM_OP, "Erase Block (start)" );
|
||||
*state = FLASH_ST_BL_ERASE;
|
||||
break;
|
||||
|
||||
default:
|
||||
/* Unknown command; signal, ignore, keep current state. */
|
||||
ChfGenerate( FLASH_CHF_MODULE_ID, __FILE__, __LINE__, FLASH_W_BAD_CMD, CHF_WARNING, *state, cycle, address, data );
|
||||
ChfSignal( FLASH_CHF_MODULE_ID );
|
||||
ChfCondition FLASH_W_BAD_CMD, CHF_WARNING, *state, cycle, address, data ChfEnd;
|
||||
ChfSignal();
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -204,7 +214,7 @@ static int ReadXSR( enum FlashState* state, enum FlashCycle cycle, XAddress addr
|
|||
/* Return XSR status; a buffer is always available in the current
|
||||
emulation scheme. Keep current state.
|
||||
*/
|
||||
debug1( FLASH_CHF_MODULE_ID, DEBUG_C_FLASH, FLASH_I_FSM_OP, "Read XSR" );
|
||||
debug1( DEBUG_C_FLASH, FLASH_I_FSM_OP, "Read XSR" );
|
||||
return FLASH_XSR_WBS;
|
||||
}
|
||||
|
||||
|
@ -214,7 +224,7 @@ static int ReadSR( enum FlashState* state, enum FlashCycle cycle, XAddress addre
|
|||
/* Return SR status; the WSM executes in zero time in the current
|
||||
emulation scheme. Keep current state.
|
||||
*/
|
||||
debug1( FLASH_CHF_MODULE_ID, DEBUG_C_FLASH, FLASH_I_FSM_OP, "Read SR" );
|
||||
debug1( DEBUG_C_FLASH, FLASH_I_FSM_OP, "Read SR" );
|
||||
return FLASH_SR_WSMS;
|
||||
}
|
||||
|
||||
|
@ -226,7 +236,7 @@ static int ReadSR( enum FlashState* state, enum FlashCycle cycle, XAddress addre
|
|||
static int StoreCount( enum FlashState* state, enum FlashCycle cycle, XAddress address, int data )
|
||||
{
|
||||
/* Store WRITE_BUFFER count; next state is FLASH_ST_WRITE_DATA */
|
||||
debug1( FLASH_CHF_MODULE_ID, DEBUG_C_FLASH, FLASH_I_FSM_OP, "Write to Buffer (count)" );
|
||||
debug1( DEBUG_C_FLASH, FLASH_I_FSM_OP, "Write to Buffer (count)" );
|
||||
wb_count = wb_cdown = data & WB_COUNT_MASK;
|
||||
|
||||
*state = FLASH_ST_WRITE_DATA_1;
|
||||
|
@ -242,7 +252,7 @@ static int StoreData( enum FlashState* state, enum FlashCycle cycle, XAddress ad
|
|||
{
|
||||
int index;
|
||||
|
||||
debug1( FLASH_CHF_MODULE_ID, DEBUG_C_FLASH, FLASH_I_FSM_OP, "Write to Buffer (data)" );
|
||||
debug1( DEBUG_C_FLASH, FLASH_I_FSM_OP, "Write to Buffer (data)" );
|
||||
|
||||
/* Store WRITE_BUFFER data; the first write also stores the
|
||||
buffer starting address.
|
||||
|
@ -258,8 +268,8 @@ static int StoreData( enum FlashState* state, enum FlashCycle cycle, XAddress ad
|
|||
case FLASH_ST_WRITE_DATA_N:
|
||||
index = address - wb_start;
|
||||
if ( index < 0 || index >= WB_SIZE ) {
|
||||
ChfGenerate( FLASH_CHF_MODULE_ID, __FILE__, __LINE__, FLASH_W_BAD_ADDRESS, CHF_WARNING, *state, cycle, address, data );
|
||||
ChfSignal( FLASH_CHF_MODULE_ID );
|
||||
ChfCondition FLASH_W_BAD_ADDRESS, CHF_WARNING, *state, cycle, address, data ChfEnd;
|
||||
ChfSignal();
|
||||
} else
|
||||
wb[ index ] = data;
|
||||
break;
|
||||
|
@ -282,7 +292,7 @@ static int StoreData( enum FlashState* state, enum FlashCycle cycle, XAddress ad
|
|||
*/
|
||||
static int WriteConfirm( enum FlashState* state, enum FlashCycle cycle, XAddress address, int data )
|
||||
{
|
||||
debug1( FLASH_CHF_MODULE_ID, DEBUG_C_FLASH, FLASH_I_FSM_OP, "Write to Buffer (end)" );
|
||||
debug1( DEBUG_C_FLASH, FLASH_I_FSM_OP, "Write to Buffer (end)" );
|
||||
|
||||
/* Expect Write to Buffer confirmation code */
|
||||
if ( data == FLASH_CMD_WRITE_BUFFER_2 ) {
|
||||
|
@ -308,7 +318,7 @@ static int WriteConfirm( enum FlashState* state, enum FlashCycle cycle, XAddress
|
|||
*/
|
||||
static int BlockErase( enum FlashState* state, enum FlashCycle cycle, XAddress address, int data )
|
||||
{
|
||||
debug1( FLASH_CHF_MODULE_ID, DEBUG_C_FLASH, FLASH_I_FSM_OP, "Block Erase (end)" );
|
||||
debug1( DEBUG_C_FLASH, FLASH_I_FSM_OP, "Block Erase (end)" );
|
||||
|
||||
/* Expect Write to Buffer confirmation code */
|
||||
if ( data == FLASH_CMD_BL_ERASE_2 ) {
|
||||
|
@ -354,12 +364,12 @@ static int FSM( enum FlashCycle cycle, XAddress address, int data )
|
|||
{
|
||||
int result;
|
||||
|
||||
debug2( FLASH_CHF_MODULE_ID, DEBUG_C_FLASH, FLASH_I_FSM, fsm_state, cycle );
|
||||
debug2( FLASH_CHF_MODULE_ID, DEBUG_C_FLASH, FLASH_I_FSM_AD, address, data );
|
||||
debug2( DEBUG_C_FLASH, FLASH_I_FSM, fsm_state, cycle );
|
||||
debug2( DEBUG_C_FLASH, FLASH_I_FSM_AD, address, data );
|
||||
|
||||
result = F[ fsm_state ][ cycle ]( &fsm_state, cycle, address, data );
|
||||
|
||||
debug2( FLASH_CHF_MODULE_ID, DEBUG_C_FLASH, FLASH_I_FSM_RESULT, fsm_state, result );
|
||||
debug2( DEBUG_C_FLASH, FLASH_I_FSM_RESULT, fsm_state, result );
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -406,7 +416,7 @@ Nibble FlashRead49( XAddress address )
|
|||
result = LowNibble( r_buffer );
|
||||
}
|
||||
|
||||
debug2( FLASH_CHF_MODULE_ID, DEBUG_C_TRACE | DEBUG_C_FLASH, FLASH_I_READ, address, result );
|
||||
debug2( DEBUG_C_TRACE | DEBUG_C_FLASH, FLASH_I_READ, address, result );
|
||||
|
||||
return result;
|
||||
}
|
||||
|
@ -440,7 +450,7 @@ Nibble FlashRead49( XAddress address )
|
|||
.- */
|
||||
void FlashWrite49( XAddress address, Nibble datum )
|
||||
{
|
||||
debug2( FLASH_CHF_MODULE_ID, DEBUG_C_TRACE | DEBUG_C_FLASH, FLASH_I_WRITE, address, datum );
|
||||
debug2( DEBUG_C_TRACE | DEBUG_C_FLASH, FLASH_I_WRITE, address, datum );
|
||||
|
||||
if ( IsOdd( address ) )
|
||||
/* Odd address, invoke FSM; ignore result */
|
||||
|
|
45
src/hdw.c
45
src/hdw.c
|
@ -74,7 +74,7 @@
|
|||
Revision 3.2 2000/09/22 13:46:30 cibrario
|
||||
Implemented preliminary support of HP49 hw architecture:
|
||||
- The HP49 firmware (1.19-4) reads a nibble from 0x30 for unknown reasons;
|
||||
enabled reads from relative
|
||||
conditionally (#ifdef HP49_SUPPORT) enabled reads from relative
|
||||
addresses 0x30..0x34 without signaling a warning.
|
||||
|
||||
* Revision 3.1 2000/09/20 13:48:52 cibrario
|
||||
|
@ -99,9 +99,15 @@
|
|||
|
||||
.- */
|
||||
|
||||
#include <string.h> /* 3.1: memset() */
|
||||
#ifndef lint
|
||||
static char rcs_id[] = "$Id: hdw.c,v 4.1 2000/12/11 09:54:19 cibrario Rel $";
|
||||
#endif
|
||||
|
||||
#include "libChf/src/Chf.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <setjmp.h>
|
||||
#include <string.h> /* 3.1: memset() */
|
||||
#include <errno.h>
|
||||
|
||||
#include "config.h"
|
||||
#include "machdep.h"
|
||||
|
@ -112,6 +118,9 @@
|
|||
#include "x_func.h" /* 3.13: Extended emulator functions */
|
||||
#include "debug.h"
|
||||
|
||||
#define CHF_MODULE_ID MOD_CHF_MODULE_ID
|
||||
#include <Chf.h>
|
||||
|
||||
static const int addr_mask[] = { 0x0000F, 0x000F0, 0x00F00, 0x0F000, 0xF0000 };
|
||||
|
||||
static const int32 int32_mask[] = { 0x0000000F, 0x000000F0, 0x00000F00, 0x0000F000, 0x000F0000, 0x00F00000, 0x0F000000, 0xF0000000 };
|
||||
|
@ -142,11 +151,11 @@ static const int32 int32_mask[] = { 0x0000000F, 0x000000F0, 0x00000F00, 0x0000F0
|
|||
.- */
|
||||
void HdwInit( void )
|
||||
{
|
||||
debug1( MOD_CHF_MODULE_ID, DEBUG_C_TRACE, MOD_I_CALLED, "HdwInit" );
|
||||
debug1( DEBUG_C_TRACE, MOD_I_CALLED, "HdwInit" );
|
||||
|
||||
if ( ReadStructFromFile( config.hdw_file_name, sizeof( mod_status.hdw ), &mod_status.hdw ) ) {
|
||||
ChfGenerate( MOD_CHF_MODULE_ID, __FILE__, __LINE__, MOD_W_HDW_INIT, CHF_WARNING );
|
||||
ChfSignal( MOD_CHF_MODULE_ID );
|
||||
if ( ReadStructFromFile( args.hdw_file_name, sizeof( mod_status.hdw ), &mod_status.hdw ) ) {
|
||||
ChfCondition MOD_W_HDW_INIT, CHF_WARNING ChfEnd;
|
||||
ChfSignal();
|
||||
|
||||
( void )memset( &mod_status.hdw, 0, sizeof( mod_status.hdw ) );
|
||||
}
|
||||
|
@ -176,11 +185,11 @@ void HdwInit( void )
|
|||
.- */
|
||||
void HdwSave( void )
|
||||
{
|
||||
debug1( MOD_CHF_MODULE_ID, DEBUG_C_TRACE, MOD_I_CALLED, "HdwSave" );
|
||||
debug1( DEBUG_C_TRACE, MOD_I_CALLED, "HdwSave" );
|
||||
|
||||
if ( WriteStructToFile( &mod_status.hdw, sizeof( mod_status.hdw ), config.hdw_file_name ) ) {
|
||||
ChfGenerate( MOD_CHF_MODULE_ID, __FILE__, __LINE__, MOD_E_HDW_SAVE, CHF_ERROR );
|
||||
ChfSignal( MOD_CHF_MODULE_ID );
|
||||
if ( WriteStructToFile( &mod_status.hdw, sizeof( mod_status.hdw ), args.hdw_file_name ) ) {
|
||||
ChfCondition MOD_E_HDW_SAVE, CHF_ERROR ChfEnd;
|
||||
ChfSignal();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -213,7 +222,7 @@ void HdwSave( void )
|
|||
.- */
|
||||
Nibble HdwRead( Address rel_address )
|
||||
{
|
||||
debug1( MOD_CHF_MODULE_ID, DEBUG_C_TRACE, MOD_I_CALLED, "HdwRead" );
|
||||
debug1( DEBUG_C_TRACE, MOD_I_CALLED, "HdwRead" );
|
||||
|
||||
/* In the following switch, each case corresponds to one hdw register.
|
||||
If the register must be read from the shadow space mod_status.hdw.hdw[],
|
||||
|
@ -299,6 +308,7 @@ Nibble HdwRead( Address rel_address )
|
|||
case 0x2F: /* Timer 2 Control */
|
||||
return mod_status.hdw.t2_ctrl;
|
||||
|
||||
#ifdef HP49_SUPPORT
|
||||
/* 3.2: The HP49 firmware (1.19-4) reads a nibble from 0x30 */
|
||||
case 0x30:
|
||||
case 0x31:
|
||||
|
@ -306,6 +316,7 @@ Nibble HdwRead( Address rel_address )
|
|||
case 0x33:
|
||||
case 0x34:
|
||||
return ( Nibble )0x0;
|
||||
#endif
|
||||
|
||||
case 0x37: /* Timer 1 value */
|
||||
return mod_status.hdw.t1_val;
|
||||
|
@ -321,8 +332,8 @@ Nibble HdwRead( Address rel_address )
|
|||
return ( Nibble )( ( mod_status.hdw.t2_val >> ( ( rel_address - 0x38 ) * 4 ) ) & 0x0F );
|
||||
|
||||
default:
|
||||
ChfGenerate( MOD_CHF_MODULE_ID, __FILE__, __LINE__, MOD_W_HDW_READ, CHF_WARNING, rel_address );
|
||||
ChfSignal( MOD_CHF_MODULE_ID );
|
||||
ChfCondition MOD_W_HDW_READ, CHF_WARNING, rel_address ChfEnd;
|
||||
ChfSignal();
|
||||
return ( Nibble )0xF;
|
||||
}
|
||||
|
||||
|
@ -356,7 +367,7 @@ Nibble HdwRead( Address rel_address )
|
|||
.- */
|
||||
void HdwWrite( Address rel_address, Nibble data )
|
||||
{
|
||||
debug1( MOD_CHF_MODULE_ID, DEBUG_C_TRACE, MOD_I_CALLED, "HdwWrite" );
|
||||
debug1( DEBUG_C_TRACE, MOD_I_CALLED, "HdwWrite" );
|
||||
|
||||
/* This switch has a case for each 'known' hdw register. The code inside the
|
||||
case performs the actions specific for that register; the code following
|
||||
|
@ -528,8 +539,8 @@ void HdwWrite( Address rel_address, Nibble data )
|
|||
break;
|
||||
|
||||
default:
|
||||
ChfGenerate( MOD_CHF_MODULE_ID, __FILE__, __LINE__, MOD_W_HDW_WRITE, CHF_WARNING, rel_address, ( int )data );
|
||||
ChfSignal( MOD_CHF_MODULE_ID );
|
||||
ChfCondition MOD_W_HDW_WRITE, CHF_WARNING, rel_address, ( int )data ChfEnd;
|
||||
ChfSignal();
|
||||
}
|
||||
|
||||
/* Save copy into hdw register array */
|
||||
|
|
|
@ -72,7 +72,14 @@
|
|||
|
||||
.- */
|
||||
|
||||
#include "libChf/src/Chf.h"
|
||||
#ifndef lint
|
||||
static char rcs_id[] = "$Id: hw_config.c,v 4.1 2000/12/11 09:54:19 cibrario Rel $";
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <setjmp.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "config.h"
|
||||
#include "machdep.h"
|
||||
|
@ -80,6 +87,9 @@
|
|||
#include "modules.h"
|
||||
#include "debug.h"
|
||||
|
||||
#define CHF_MODULE_ID MOD_CHF_MODULE_ID
|
||||
#include <Chf.h>
|
||||
|
||||
/*---------------------------------------------------------------------------
|
||||
Module description tables
|
||||
---------------------------------------------------------------------------*/
|
||||
|
@ -140,23 +150,30 @@ extern void Ce1Write49( Address, Nibble );
|
|||
extern void Ce2Write49( Address, Nibble );
|
||||
extern void NCe3Write49( Address, Nibble );
|
||||
|
||||
static const ModDescription hw48_description = {
|
||||
{"ROM (ROM)", 0x00, 0, RomInit, RomSave, RomRead, RomWrite, MOD_CONFIGURED, 0x00000, 0xFFFFF, 0},
|
||||
{"Hardware Regs. (HDW)", 0x19, 5, HdwInit, HdwSave, HdwRead, HdwWrite, MOD_SIZE_CONFIGURED, 0x00000, 0x00040, 0},
|
||||
{"Internal RAM (RAM)", 0x03, 4, RamInit, RamSave, RamRead, RamWrite, MOD_UNCONFIGURED, 0, 0, 0},
|
||||
{"Bank Select (CE1)", 0x05, 2, Ce1Init, Ce1Save, Ce1Read, Ce1Write, MOD_UNCONFIGURED, 0, 0, 0},
|
||||
{"Port 1 Control (CE2)", 0x07, 3, Ce2Init, Ce2Save, Ce2Read, Ce2Write, MOD_UNCONFIGURED, 0, 0, 0},
|
||||
{"Port 2 Control (NCE3)", 0x01, 1, NCe3Init, NCe3Save, NCe3Read, NCe3Write, MOD_UNCONFIGURED, 0, 0, 0}
|
||||
};
|
||||
static const ModDescription hw49_description = {
|
||||
{"ROM (ROM)", 0x00, 0, RomInit49, RomSave49, RomRead49, RomWrite49, MOD_CONFIGURED, 0x00000, 0xFFFFF, 0 },
|
||||
{"Hardware Regs. (HDW)", 0x19, 5, HdwInit, HdwSave, HdwRead, HdwWrite, MOD_SIZE_CONFIGURED, 0x00000, 0x00040, 0 },
|
||||
{"IRAM (RAM)", 0x03, 4, RamInit49, RamSave49, RamRead49, RamWrite49, MOD_UNCONFIGURED, 0, 0, 0 },
|
||||
{"Bank Select (CE1)", 0x05, 2, Ce1Init49, Ce1Save49, Ce1Read49, Ce1Write49, MOD_UNCONFIGURED, 0, 0, 0 },
|
||||
{"ERAM Bank 0 (CE2)", 0x07, 3, Ce2Init49, Ce2Save49, Ce2Read49, Ce2Write49, MOD_UNCONFIGURED, 0, 0, 0 },
|
||||
{"ERAM Bank 1 (NCE3)", 0x01, 1, NCe3Init49, NCe3Save49, NCe3Read49, NCe3Write49, MOD_UNCONFIGURED, 0, 0, MOD_MAP_FLAGS_ABS}
|
||||
static const struct {
|
||||
const char* hw;
|
||||
ModDescription description;
|
||||
} table[] = {
|
||||
{"hp48",
|
||||
{ { "ROM (ROM)", 0x00, 0, RomInit, RomSave, RomRead, RomWrite, MOD_CONFIGURED, 0x00000, 0xFFFFF, 0 },
|
||||
{ "Hardware Regs. (HDW)", 0x19, 5, HdwInit, HdwSave, HdwRead, HdwWrite, MOD_SIZE_CONFIGURED, 0x00000, 0x00040, 0 },
|
||||
{ "Internal RAM (RAM)", 0x03, 4, RamInit, RamSave, RamRead, RamWrite, MOD_UNCONFIGURED, 0, 0, 0 },
|
||||
{ "Bank Select (CE1)", 0x05, 2, Ce1Init, Ce1Save, Ce1Read, Ce1Write, MOD_UNCONFIGURED, 0, 0, 0 },
|
||||
{ "Port 1 Control (CE2)", 0x07, 3, Ce2Init, Ce2Save, Ce2Read, Ce2Write, MOD_UNCONFIGURED, 0, 0, 0 },
|
||||
{ "Port 2 Control (NCE3)", 0x01, 1, NCe3Init, NCe3Save, NCe3Read, NCe3Write, MOD_UNCONFIGURED, 0, 0, 0 } }},
|
||||
|
||||
{"hp49",
|
||||
{ { "ROM (ROM)", 0x00, 0, RomInit49, RomSave49, RomRead49, RomWrite49, MOD_CONFIGURED, 0x00000, 0xFFFFF, 0 },
|
||||
{ "Hardware Regs. (HDW)", 0x19, 5, HdwInit, HdwSave, HdwRead, HdwWrite, MOD_SIZE_CONFIGURED, 0x00000, 0x00040, 0 },
|
||||
{ "IRAM (RAM)", 0x03, 4, RamInit49, RamSave49, RamRead49, RamWrite49, MOD_UNCONFIGURED, 0, 0, 0 },
|
||||
{ "Bank Select (CE1)", 0x05, 2, Ce1Init49, Ce1Save49, Ce1Read49, Ce1Write49, MOD_UNCONFIGURED, 0, 0, 0 },
|
||||
{ "ERAM Bank 0 (CE2)", 0x07, 3, Ce2Init49, Ce2Save49, Ce2Read49, Ce2Write49, MOD_UNCONFIGURED, 0, 0, 0 },
|
||||
{ "ERAM Bank 1 (NCE3)", 0x01, 1, NCe3Init49, NCe3Save49, NCe3Read49, NCe3Write49, MOD_UNCONFIGURED, 0, 0,
|
||||
MOD_MAP_FLAGS_ABS } } }
|
||||
};
|
||||
|
||||
#define N_DESCRIPTIONS ( int )( sizeof( table ) / sizeof( table[ 0 ] ) )
|
||||
|
||||
/*---------------------------------------------------------------------------
|
||||
Public functions
|
||||
---------------------------------------------------------------------------*/
|
||||
|
@ -184,22 +201,18 @@ static const ModDescription hw49_description = {
|
|||
1.1, 28-Jan-1998, creation
|
||||
|
||||
.- */
|
||||
void ModSelectDescription( int model )
|
||||
void ModSelectDescription( const char* hw )
|
||||
{
|
||||
debug1( MOD_CHF_MODULE_ID, DEBUG_C_TRACE, MOD_I_CALLED, "ModSelectDescription" );
|
||||
int i;
|
||||
|
||||
switch ( model ) {
|
||||
case MODEL_48SX:
|
||||
case MODEL_48GX:
|
||||
ModRegisterDescription( hw48_description );
|
||||
break;
|
||||
case MODEL_40G:
|
||||
case MODEL_49G:
|
||||
ModRegisterDescription( hw49_description );
|
||||
break;
|
||||
default:
|
||||
ChfGenerate( MOD_CHF_MODULE_ID, __FILE__, __LINE__, MOD_E_NO_MATCH, CHF_ERROR, "Unknown model" );
|
||||
ChfSignal( MOD_CHF_MODULE_ID );
|
||||
exit( EXIT_FAILURE );
|
||||
}
|
||||
debug1( DEBUG_C_TRACE, MOD_I_CALLED, "ModSelectDescription" );
|
||||
|
||||
for ( i = 0; i < N_DESCRIPTIONS && strcmp( hw, table[ i ].hw ); i++ )
|
||||
;
|
||||
|
||||
if ( i == N_DESCRIPTIONS ) {
|
||||
ChfCondition MOD_E_NO_MATCH, CHF_ERROR, hw ChfEnd;
|
||||
ChfSignal();
|
||||
} else
|
||||
ModRegisterDescription( table[ i ].description );
|
||||
}
|
||||
|
|
41
src/keyb.c
41
src/keyb.c
|
@ -81,16 +81,24 @@
|
|||
|
||||
.- */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#ifndef lint
|
||||
static char rcs_id[] = "$Id: keyb.c,v 4.1 2000/12/11 09:54:19 cibrario Rel $";
|
||||
#endif
|
||||
|
||||
#include "libChf/src/Chf.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <setjmp.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "config.h"
|
||||
#include "machdep.h"
|
||||
#include "cpu.h"
|
||||
#include "modules.h"
|
||||
#include "keyb.h"
|
||||
#include "debug.h"
|
||||
|
||||
#define CHF_MODULE_ID MOD_CHF_MODULE_ID
|
||||
#include <Chf.h>
|
||||
|
||||
#define OUT_BITS 12
|
||||
|
||||
|
@ -159,11 +167,12 @@ InputRegister KeybIN( OutputRegister out )
|
|||
{
|
||||
/* Compute the current value of the IN register */
|
||||
InputRegister in = ( InputRegister )0;
|
||||
int bit;
|
||||
|
||||
/* For each bit set in the 'out' register, OR the corresponding IN register
|
||||
value into 'in'
|
||||
*/
|
||||
for ( int bit = 0; bit < OUT_BITS; bit++ ) {
|
||||
for ( bit = 0; bit < OUT_BITS; bit++ ) {
|
||||
if ( out & 0x01 )
|
||||
in |= cur_in[ bit ];
|
||||
out >>= 1;
|
||||
|
@ -201,8 +210,10 @@ void KeybPress( const char* key )
|
|||
{
|
||||
if ( strcmp( key, "*" ) == 0 ) {
|
||||
/* This is the ON key */
|
||||
int i;
|
||||
|
||||
/* Set all 0x8000 lines */
|
||||
for ( int i = 0; i < OUT_BITS; i++ )
|
||||
for ( i = 0; i < OUT_BITS; i++ )
|
||||
cur_in[ i ] |= 0x8000;
|
||||
|
||||
/* Post an interrupt request to the CPU */
|
||||
|
@ -211,11 +222,11 @@ void KeybPress( const char* key )
|
|||
unsigned int in_val, out_bit;
|
||||
|
||||
if ( sscanf( key, "%x/%x", &out_bit, &in_val ) != 2 ) {
|
||||
ChfGenerate( MOD_CHF_MODULE_ID, __FILE__, __LINE__, MOD_W_BAD_KEY, CHF_WARNING, key );
|
||||
ChfSignal( MOD_CHF_MODULE_ID );
|
||||
ChfCondition MOD_W_BAD_KEY, CHF_WARNING, key ChfEnd;
|
||||
ChfSignal();
|
||||
/* } else if ( out_bit < 0 || out_bit >= OUT_BITS ) { */
|
||||
/* ChfGenerate( MOD_CHF_MODULE_ID, __FILE__, __LINE__, MOD_W_BAD_OUT_BIT, CHF_WARNING, out_bit ); */
|
||||
/* ChfSignal( MOD_CHF_MODULE_ID ); */
|
||||
/* ChfCondition MOD_W_BAD_OUT_BIT, CHF_WARNING, out_bit ChfEnd; */
|
||||
/* ChfSignal(); */
|
||||
} else {
|
||||
/* Update the cur_in array */
|
||||
cur_in[ out_bit ] |= in_val;
|
||||
|
@ -254,18 +265,20 @@ void KeybRelease( const char* key )
|
|||
{
|
||||
if ( strcmp( key, "*" ) == 0 ) {
|
||||
/* This is the ON key */
|
||||
int i;
|
||||
|
||||
/* Reset all 0x8000 lines */
|
||||
for ( int i = 0; i < OUT_BITS; i++ )
|
||||
for ( i = 0; i < OUT_BITS; i++ )
|
||||
cur_in[ i ] &= 0x7FFF;
|
||||
} else {
|
||||
unsigned int in_val, out_bit;
|
||||
|
||||
if ( sscanf( key, "%x/%x", &out_bit, &in_val ) != 2 ) {
|
||||
ChfGenerate( MOD_CHF_MODULE_ID, __FILE__, __LINE__, MOD_W_BAD_KEY, CHF_WARNING, key );
|
||||
ChfSignal( MOD_CHF_MODULE_ID );
|
||||
ChfCondition MOD_W_BAD_KEY, CHF_WARNING, key ChfEnd;
|
||||
ChfSignal();
|
||||
/* } else if ( out_bit < 0 || out_bit >= OUT_BITS ) { */
|
||||
/* ChfGenerate( MOD_CHF_MODULE_ID, __FILE__, __LINE__, MOD_W_BAD_OUT_BIT, CHF_WARNING, out_bit ); */
|
||||
/* ChfSignal( MOD_CHF_MODULE_ID ); */
|
||||
/* ChfCondition MOD_W_BAD_OUT_BIT, CHF_WARNING, out_bit ChfEnd; */
|
||||
/* ChfSignal(); */
|
||||
} else {
|
||||
/* Update the cur_in array */
|
||||
cur_in[ out_bit ] &= ~in_val;
|
||||
|
|
|
@ -1,171 +0,0 @@
|
|||
#ifndef _CHF_H
|
||||
#define _CHF_H 1
|
||||
|
||||
/* .+
|
||||
|
||||
.identifier : $Id: Chf.h,v 2.2 2001/01/25 11:56:44 cibrario Exp $
|
||||
.context : CHF, Condition Handling Facility
|
||||
.title : $RCSfile: Chf.h,v $, main header
|
||||
.kind : C header
|
||||
.author : Ivan Cibrario B.
|
||||
.site : CSTV-CNR
|
||||
.creation : 2-May-1996
|
||||
.keywords : *
|
||||
.description :
|
||||
This is the main header of the Condition Handling Facility
|
||||
|
||||
.include : stdio.h setjmp.h (Win32: tchar.h)
|
||||
|
||||
.notes :
|
||||
$Log: Chf.h,v $
|
||||
Revision 2.2 2001/01/25 11:56:44 cibrario
|
||||
Added partial Win32 support (Windows CE only).
|
||||
|
||||
Revision 2.1 2000/05/26 14:10:08 cibrario
|
||||
- Revised unwind context passing mechanism; redefined CHF_NULL_CONTEXT
|
||||
- New macros: CHF_NULL_HANDLER, CHF_MAJOR_RELEASE_NUMBER,
|
||||
CHF_MINOR_RELEASE_NUMBER
|
||||
- New ChfAction value: CHF_UNWIND_KEEP; fixed spelling of ChfAction value:
|
||||
CHF_SIGNALLING -> CHF_SIGNALING
|
||||
- Added structured condition handling macros: CHF_Try, CHF_Catch, CHF_EndTry
|
||||
|
||||
Revision 1.6 1997/01/15 13:41:20 cibrario
|
||||
Defined the new data type void*, a generic (void *) pointer. Each
|
||||
condition handler can have a private handler context pointer, of type
|
||||
void*, that the function ChfPushHandler() stores and that is passed
|
||||
to the handler when it's activated.
|
||||
Fixed a wrong adjustment of the condition handlers stack pointer after
|
||||
an unwind operation.
|
||||
|
||||
Revision 1.5 1996/10/04 09:45:30 cibrario
|
||||
Updated the condition message format in the private header ChfPriv.h to
|
||||
improve internationalization
|
||||
|
||||
Revision 1.4 1996/09/25 13:21:11 cibrario
|
||||
Added macro CHF_LIBRARY_ID; it contains the current ID of the CHF library.
|
||||
The module chf_init.o will contain it as a static char[] variable.
|
||||
|
||||
Revision 1.2 1996/06/11 13:02:10 cibrario
|
||||
Added prototype for ChfGetTopCondition()
|
||||
|
||||
Revision 1.1 1996/05/28 12:56:47 cibrario
|
||||
Initial revision
|
||||
|
||||
|
||||
.- */
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
CHF implementation limits and other symbolic constants
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
#define CHF_MAX_MESSAGE_LENGTH 256
|
||||
#define CHF_UNKNOWN_LINE_NUMBER ( -1 )
|
||||
#define CHF_UNKNOWN_FILE_NAME ( char* )NULL
|
||||
#define CHF_NULL_DESCRIPTOR ( ChfDescriptor* )NULL
|
||||
#define CHF_NULL_CONTEXT ( void* )NULL
|
||||
#define CHF_NULL_POINTER ( void** )NULL
|
||||
#define CHF_NULL_HANDLER ( ChfHandler ) NULL
|
||||
|
||||
#define CHF_MODULE_NAMES_SET 1
|
||||
#define CHF_SET 2
|
||||
#define CHF_ERRNO_SET 3
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
Condition codes
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
#define CHF_S_OK 0
|
||||
#define CHF_F_COND_STACK_FULL 1 /* Condition stack is full */
|
||||
#define CHF_F_HDLR_STACK_FULL 2 /* Handler stack is full */
|
||||
#define CHF_F_HDLR_STACK_EMPTY 3 /* Handler stack is empty */
|
||||
#define CHF_F_BAD_STATE 4 /* Bad CHF state for req. operation */
|
||||
#define CHF_F_INVALID_ACTION 5 /* Invalid action from handler: %d */
|
||||
#define CHF_F_MALLOC 6 /* Dynamic memory allocation failed */
|
||||
#define CHF_F_NOT_AVAILABLE 7 /* Function not available */
|
||||
#define CHF_F_SETLOCALE 10 /* setlocale() failed */
|
||||
#define CHF_F_CATOPEN 11 /* catopen() failed */
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
Type definitions
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
/* Condition severity codes */
|
||||
typedef enum { CHF_SUCCESS, CHF_INFO, CHF_WARNING, CHF_ERROR, CHF_FATAL } ChfSeverity;
|
||||
|
||||
/* Condition handler action codes */
|
||||
typedef enum {
|
||||
CHF_CONTINUE, /* Continue application */
|
||||
CHF_RESIGNAL, /* Resignal to next handler */
|
||||
CHF_UNWIND, /* Stack unwind */
|
||||
CHF_UNWIND_KEEP /* Unwind, keep last cond. group */
|
||||
} ChfAction;
|
||||
|
||||
#define CHF_DEFAULT 0x0000 /* default flags */
|
||||
#define CHF_ABORT 0x0001 /* use abort() instead of exit() */
|
||||
|
||||
/* Current CHF state */
|
||||
typedef enum { CHF_UNKNOWN, CHF_IDLE, CHF_SIGNALING, CHF_UNWINDING, CHF_SIGNAL_UNWINDING } ChfState;
|
||||
|
||||
/* Condition descriptor */
|
||||
typedef struct ChfDescriptor_S {
|
||||
int module_id; /* Module identifier */
|
||||
int condition_code; /* Condition code */
|
||||
ChfSeverity severity; /* Severity */
|
||||
int line_number; /* Line # or CHF_UNK_LINE_NUMBER */
|
||||
const char* file_name; /* File name or CHF_UNK_FILE_NAME */
|
||||
char message[ CHF_MAX_MESSAGE_LENGTH ]; /* Partial message */
|
||||
struct ChfDescriptor_S* next; /* Link to next descriptor */
|
||||
} ChfDescriptor;
|
||||
|
||||
/* Standalone message table */
|
||||
typedef struct ChfTable_S {
|
||||
int module; /* Module identifier */
|
||||
int code; /* Condition code */
|
||||
const char* msg_template; /* Message template */
|
||||
} ChfTable;
|
||||
|
||||
/* Condition handler */
|
||||
typedef ChfAction ( *ChfHandler )( const ChfDescriptor*, const ChfState, void* );
|
||||
|
||||
/* Message retrieval 'get_message' function */
|
||||
typedef const char* ( *ChfMrsGet )( void*, const int, const int, const char* default_message );
|
||||
|
||||
/* Message retrieval 'exit' function */
|
||||
typedef void ( *ChfMrsExit )( void* );
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
Function prototypes
|
||||
------------------------------------------------------------------------- */
|
||||
/* Generate a condition into the stack */
|
||||
void ChfGenerate( const int module_id, const char* file_name, const int line_number, const int condition_code, const ChfSeverity severity,
|
||||
... );
|
||||
|
||||
/******************/
|
||||
/* used in saturn */
|
||||
/******************/
|
||||
/* Initialization with static message tables */
|
||||
int ChfStaticInit( const int module_id, const char* app_name, /* Application's name */
|
||||
const int options, /* Options */
|
||||
const ChfTable* table, /* Static message table */
|
||||
const size_t table_size, /* Size of the message table */
|
||||
const int condition_stack_size, /* Size of the condition stack */
|
||||
const int handler_stack_size, /* Size of the handler stack */
|
||||
const int exit_code /* Abnormal exit code */
|
||||
);
|
||||
|
||||
/* Push a new handler into the stack */
|
||||
void ChfPushHandler( const int module_id, ChfHandler new_handler, /* Handler to be added */
|
||||
void* unwind_context, /* Unwind context */
|
||||
void* handler_context /* Private handler context */
|
||||
);
|
||||
|
||||
/* Signal the current conditions */
|
||||
void ChfSignal( const int module_id );
|
||||
|
||||
/* Exit */
|
||||
void ChfExit( void );
|
||||
|
||||
#endif /*!_CHF_H*/
|
|
@ -1,61 +0,0 @@
|
|||
/* .+
|
||||
|
||||
.identifier : $Id: chf_msgc.c,v 2.2 2001/01/25 14:06:47 cibrario Exp $
|
||||
.context : CHF, Condition Handling Facility
|
||||
.title : $RCSfile: chf_msgc.c,v $, condition generation
|
||||
.kind : C source
|
||||
.author : Ivan Cibrario B.
|
||||
.site : CSTV-CNR
|
||||
.creation : 17-May-1996
|
||||
.keywords : *
|
||||
.description :
|
||||
This module contains the CHF initialization function ChfMsgcatInit()
|
||||
|
||||
.include : Chf.h
|
||||
|
||||
.notes :
|
||||
$Log: chf_msgc.c,v $
|
||||
Revision 2.2 2001/01/25 14:06:47 cibrario
|
||||
Added partial Win32 support (Windows CE only).
|
||||
|
||||
Revision 1.3 1996/06/21 14:19:22 cibrario
|
||||
Bug fix: the private context of the message retrieval facility was
|
||||
never freed by ExitMessage()
|
||||
|
||||
Revision 1.1 1996/05/28 12:55:15 cibrario
|
||||
Initial revision
|
||||
|
||||
|
||||
.- */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <locale.h>
|
||||
#include <nl_types.h>
|
||||
|
||||
#include "Chf.h"
|
||||
#include "ChfPriv.h"
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
Private type definitions
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
typedef struct {
|
||||
nl_catd catalog; /* Message catalog descriptor */
|
||||
} ChfMsgcatContext;
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
Private functions
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
static const char* GetMessage( void* private_context, const int module_id, const int condition_code, const char* default_message )
|
||||
{
|
||||
return ( catgets( ( ( ChfMsgcatContext* )private_context )->catalog, module_id, condition_code, default_message ) );
|
||||
}
|
||||
|
||||
static void ExitMessage( void* private_context )
|
||||
{
|
||||
( void )catclose( ( ( ChfMsgcatContext* )private_context )->catalog );
|
||||
free( private_context );
|
||||
}
|
117
src/main.c
117
src/main.c
|
@ -1,117 +0,0 @@
|
|||
#include <signal.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#include "ui4x/config.h"
|
||||
#include "ui4x/emulator.h"
|
||||
#include "ui4x/common.h"
|
||||
|
||||
#include "config.h"
|
||||
#include "cpu.h"
|
||||
#include "monitor.h"
|
||||
#include "chf_messages.h"
|
||||
|
||||
#define UI_REFRESH_RATE_Hz 64
|
||||
|
||||
#define CONDITION_STACK_SIZE 16
|
||||
#define HANDLER_STACK_SIZE 8
|
||||
|
||||
#define QUERY_EVENTS_EVERY_X_FRAME 4
|
||||
|
||||
void signal_handler( int sig )
|
||||
{
|
||||
static int nb_refreshes_since_last_checking_events = 0;
|
||||
|
||||
switch ( sig ) {
|
||||
/* case SIGINT: /\* Ctrl-C *\/ */
|
||||
/* enter_debugger |= USER_INTERRUPT; */
|
||||
/* break; */
|
||||
case SIGALRM:
|
||||
if ( nb_refreshes_since_last_checking_events > QUERY_EVENTS_EVERY_X_FRAME ) {
|
||||
nb_refreshes_since_last_checking_events = 0;
|
||||
ui_get_event();
|
||||
}
|
||||
|
||||
ui_update_display();
|
||||
|
||||
nb_refreshes_since_last_checking_events++;
|
||||
break;
|
||||
|
||||
case SIGPIPE:
|
||||
ui_stop();
|
||||
exit_emulator();
|
||||
exit( EXIT_SUCCESS );
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int main( int argc, char** argv )
|
||||
{
|
||||
config = *config_init( argc, argv );
|
||||
|
||||
/* Chf initialization with msgcat subsystem
|
||||
*/
|
||||
if ( ( ChfStaticInit( MAIN_CHF_MODULE_ID, config.progname, /* Application's name */
|
||||
CHF_DEFAULT, /* Options */
|
||||
message_table, /* Name of the message catalog */
|
||||
message_table_size, /* message catalog size */
|
||||
CONDITION_STACK_SIZE, /* Size of the condition stack */
|
||||
HANDLER_STACK_SIZE, /* Size of the handler stack */
|
||||
EXIT_FAILURE /* Abnormal exit code */
|
||||
) ) != CHF_S_OK ) {
|
||||
fprintf( stderr, "saturn-E-Primary Chf initialization failed\n" );
|
||||
exit( EXIT_FAILURE );
|
||||
}
|
||||
|
||||
/* 3.9: Print out MAIN_M_COPYRIGHT and MAIN_M_LICENSE on stdout now */
|
||||
fprintf( stdout,
|
||||
"%s %i.%i.%i - A poor-man's emulator of HP48GX/SX, HP49, HP39/40\nCopyright (C) 1998-2000 Ivan Cibrario "
|
||||
"Bertolotti\nCopyright (C) Gwenhael Le Moine\n",
|
||||
config.progname, VERSION_MAJOR, VERSION_MINOR, PATCHLEVEL );
|
||||
fprintf( stdout,
|
||||
"This program is free software, and comes with ABSOLUTELY NO WARRANTY;\nfor details see the accompanying documentation.\n\n" );
|
||||
|
||||
init_emulator( &config );
|
||||
|
||||
/* (G)UI */
|
||||
setup_ui( &config );
|
||||
ui_start( &config );
|
||||
|
||||
sigset_t set;
|
||||
struct sigaction sa;
|
||||
sigemptyset( &set );
|
||||
sigaddset( &set, SIGALRM );
|
||||
sa.sa_handler = signal_handler;
|
||||
sa.sa_mask = set;
|
||||
#ifdef SA_RESTART
|
||||
sa.sa_flags = SA_RESTART;
|
||||
#endif
|
||||
sigaction( SIGALRM, &sa, ( struct sigaction* )0 );
|
||||
|
||||
/************************************/
|
||||
/* set the real time interval timer */
|
||||
/************************************/
|
||||
/*
|
||||
Every <interval>µs setitimer will trigger a SIGALRM
|
||||
which will getUI events and refresh UI in signal_handler
|
||||
*/
|
||||
struct itimerval it;
|
||||
it.it_interval.tv_sec = 0;
|
||||
it.it_interval.tv_usec = 1000000 / UI_REFRESH_RATE_Hz;
|
||||
it.it_value.tv_sec = it.it_interval.tv_sec;
|
||||
it.it_value.tv_usec = it.it_interval.tv_usec;
|
||||
setitimer( ITIMER_REAL, &it, ( struct itimerval* )0 );
|
||||
|
||||
if ( config.monitor )
|
||||
/* Invoke Monitor */
|
||||
Monitor();
|
||||
else
|
||||
/* Call Emulator directly */
|
||||
Emulator();
|
||||
|
||||
/* never reached */
|
||||
return EXIT_SUCCESS;
|
||||
}
|
272
src/modules.c
272
src/modules.c
|
@ -94,7 +94,7 @@
|
|||
* description table dynamically.
|
||||
* - ModInit() now refuses to work if no module description table has
|
||||
* been registered yet.
|
||||
* - enabled forced alignment of
|
||||
* - Conditionally (#ifdef HP49_SUPPORT) enabled forced alignment of
|
||||
* module configuration sizes and addresses in ModConfig()
|
||||
*
|
||||
* Revision 3.1 2000/09/20 14:00:02 cibrario
|
||||
|
@ -110,11 +110,15 @@
|
|||
|
||||
.- */
|
||||
|
||||
#ifndef lint
|
||||
static char rcs_id[] = "$Id: modules.c,v 4.1 2000/12/11 09:54:19 cibrario Rel $";
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "libChf/src/Chf.h"
|
||||
#include <errno.h>
|
||||
#include <setjmp.h>
|
||||
|
||||
#include "config.h"
|
||||
#include "machdep.h"
|
||||
|
@ -123,6 +127,9 @@
|
|||
#include "disk_io.h"
|
||||
#include "debug.h"
|
||||
|
||||
#define CHF_MODULE_ID MOD_CHF_MODULE_ID
|
||||
#include <Chf.h>
|
||||
|
||||
/*---------------------------------------------------------------------------
|
||||
Static/Global variables
|
||||
---------------------------------------------------------------------------*/
|
||||
|
@ -136,7 +143,7 @@ struct ModStatus mod_status; /* Status information - global */
|
|||
points to it.
|
||||
*/
|
||||
static struct ModMap* mod_map_ptr; /* Module mapping information */
|
||||
#define MOD_MAP ( *mod_map_ptr )
|
||||
#define mod_map ( *mod_map_ptr )
|
||||
|
||||
/* 2.7: All dynamically-allocated module mapping structures are linked
|
||||
together; cache_head points to the head of the list. The list
|
||||
|
@ -165,7 +172,7 @@ static int repl_c = 0; /* Entry replacement counter */
|
|||
|
||||
# define IncPerfCtr( x ) x++
|
||||
# define DecPerfCtr( x ) x--
|
||||
# define PrintPerfCtr( x ) debug2( MOD_CHF_MODULE_ID, DEBUG_C_MOD_CACHE, MOD_I_PERF_CTR, #x, x )
|
||||
# define PrintPerfCtr( x ) debug2( DEBUG_C_MOD_CACHE, MOD_I_PERF_CTR, #x, x )
|
||||
|
||||
# define PrintCacheStats \
|
||||
{ \
|
||||
|
@ -218,8 +225,8 @@ static int repl_c = 0; /* Entry replacement counter */
|
|||
.- */
|
||||
static Nibble BadRead( Address addr )
|
||||
{
|
||||
ChfGenerate( MOD_CHF_MODULE_ID, __FILE__, __LINE__, MOD_E_BAD_READ, CHF_ERROR, addr );
|
||||
ChfSignal( MOD_CHF_MODULE_ID );
|
||||
ChfCondition MOD_E_BAD_READ, CHF_ERROR, addr ChfEnd;
|
||||
ChfSignal();
|
||||
|
||||
return ( Nibble )0x0;
|
||||
}
|
||||
|
@ -250,8 +257,8 @@ static Nibble BadRead( Address addr )
|
|||
.- */
|
||||
static void BadWrite( Address addr, Nibble datum )
|
||||
{
|
||||
ChfGenerate( MOD_CHF_MODULE_ID, __FILE__, __LINE__, MOD_E_BAD_WRITE, CHF_ERROR, addr, datum );
|
||||
ChfSignal( MOD_CHF_MODULE_ID );
|
||||
ChfCondition MOD_E_BAD_WRITE, CHF_ERROR, addr, datum ChfEnd;
|
||||
ChfSignal();
|
||||
}
|
||||
|
||||
/* .+
|
||||
|
@ -262,7 +269,7 @@ static void BadWrite( Address addr, Nibble datum )
|
|||
.description :
|
||||
This function rebuilds the module page table from page 'lo' to page 'hi',
|
||||
inclusive, using the information contained in the current module
|
||||
mapping structure (MOD_MAP.map_info).
|
||||
mapping structure (mod_map.map_info).
|
||||
|
||||
.call :
|
||||
RebuildPageTable(lo, hi);
|
||||
|
@ -286,14 +293,17 @@ static void BadWrite( Address addr, Nibble datum )
|
|||
.- */
|
||||
static void RebuildPageTable( int lo, int hi )
|
||||
{
|
||||
int page;
|
||||
int mod;
|
||||
|
||||
Address page_addr;
|
||||
int prio;
|
||||
int winner = -1;
|
||||
|
||||
debug1( MOD_CHF_MODULE_ID, DEBUG_C_TRACE, MOD_I_CALLED, "RebuildPageTable" );
|
||||
debug1( DEBUG_C_TRACE, MOD_I_CALLED, "RebuildPageTable" );
|
||||
|
||||
/* Scan all pages in the [lo, hi] range */
|
||||
for ( int page = lo; page <= hi; page++ ) {
|
||||
for ( page = lo; page <= hi; page++ ) {
|
||||
/* Calculate the base page address for the current page */
|
||||
page_addr = ModAddress( page );
|
||||
|
||||
|
@ -304,9 +314,9 @@ static void RebuildPageTable( int lo, int hi )
|
|||
to MOD_MIN_ACCESS_PRIO.
|
||||
*/
|
||||
prio = MOD_MIN_ACCESS_PRIO;
|
||||
for ( int mod = 0; mod < N_MOD; mod++ ) {
|
||||
if ( MOD_MAP.map_info[ mod ].config == MOD_CONFIGURED && page_addr >= MOD_MAP.map_info[ mod ].abs_base_addr &&
|
||||
page_addr < MOD_MAP.map_info[ mod ].abs_base_addr + MOD_MAP.map_info[ mod ].size &&
|
||||
for ( mod = 0; mod < N_MOD; mod++ ) {
|
||||
if ( mod_map.map_info[ mod ].config == MOD_CONFIGURED && page_addr >= mod_map.map_info[ mod ].abs_base_addr &&
|
||||
page_addr < mod_map.map_info[ mod ].abs_base_addr + mod_map.map_info[ mod ].size &&
|
||||
prio < mod_description[ mod ].access_prio ) {
|
||||
winner = mod;
|
||||
prio = mod_description[ mod ].access_prio;
|
||||
|
@ -319,10 +329,10 @@ static void RebuildPageTable( int lo, int hi )
|
|||
read/write functions to BadRead/BadWrite, to catch accesses to
|
||||
unmapped addresses.
|
||||
*/
|
||||
MOD_MAP.page_table[ page ].index = MOD_NO_MOD_INDEX;
|
||||
MOD_MAP.page_table[ page ].rel_base_addr = 0x00000;
|
||||
MOD_MAP.page_table[ page ].read = BadRead;
|
||||
MOD_MAP.page_table[ page ].write = BadWrite;
|
||||
mod_map.page_table[ page ].index = MOD_NO_MOD_INDEX;
|
||||
mod_map.page_table[ page ].rel_base_addr = 0x00000;
|
||||
mod_map.page_table[ page ].read = BadRead;
|
||||
mod_map.page_table[ page ].write = BadWrite;
|
||||
} else {
|
||||
/* The page is mapped
|
||||
3.3: If the MOD_MAP_FLAGS_ABS is set in the winner's module
|
||||
|
@ -330,13 +340,12 @@ static void RebuildPageTable( int lo, int hi )
|
|||
absolute address; this way, the module read/write functions
|
||||
will receive absolute addresses instead of relative ones.
|
||||
*/
|
||||
MOD_MAP.page_table[ page ].index = winner;
|
||||
MOD_MAP.page_table[ page ].rel_base_addr = ( mod_description[ winner ].map_flags & MOD_MAP_FLAGS_ABS )
|
||||
mod_map.page_table[ page ].index = winner;
|
||||
mod_map.page_table[ page ].rel_base_addr = ( mod_description[ winner ].map_flags & MOD_MAP_FLAGS_ABS )
|
||||
? page_addr
|
||||
: page_addr - MOD_MAP.map_info[ winner ].abs_base_addr;
|
||||
MOD_MAP.page_table[ page ].read = mod_description[ winner ].read;
|
||||
// FIXME: 48gx VERSION bug: This is the place where the RomWrite fonction is set. Should we avoid ROM being able to win?
|
||||
MOD_MAP.page_table[ page ].write = mod_description[ winner ].write;
|
||||
: page_addr - mod_map.map_info[ winner ].abs_base_addr;
|
||||
mod_map.page_table[ page ].read = mod_description[ winner ].read;
|
||||
mod_map.page_table[ page ].write = mod_description[ winner ].write;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -369,7 +378,7 @@ static struct ModMap* ClearCachingInfo( struct ModMap* d )
|
|||
|
||||
int i;
|
||||
|
||||
debug1( MOD_CHF_MODULE_ID, DEBUG_C_TRACE, MOD_I_CALLED, "ClearCachingInfo" );
|
||||
debug1( DEBUG_C_TRACE, MOD_I_CALLED, "ClearCachingInfo" );
|
||||
|
||||
for ( i = 0; i < N_MOD_CACHE_ENTRIES; i++ )
|
||||
d->cache.config[ i ] = empty;
|
||||
|
@ -417,12 +426,12 @@ static struct ModMap* NewModMap( void )
|
|||
{
|
||||
struct ModMap* new;
|
||||
|
||||
debug1( MOD_CHF_MODULE_ID, DEBUG_C_TRACE, MOD_I_CALLED, "NewModMap" );
|
||||
debug1( DEBUG_C_TRACE, MOD_I_CALLED, "NewModMap" );
|
||||
|
||||
if ( ( new = ( struct ModMap* )malloc( sizeof( struct ModMap ) ) ) == ( struct ModMap* )NULL ) {
|
||||
ChfGenerate( CHF_ERRNO_SET, __FILE__, __LINE__, errno, CHF_ERROR );
|
||||
ChfGenerate( MOD_CHF_MODULE_ID, __FILE__, __LINE__, MOD_F_MAP_ALLOC, CHF_FATAL );
|
||||
ChfSignal( MOD_CHF_MODULE_ID );
|
||||
ChfErrnoCondition;
|
||||
ChfCondition MOD_F_MAP_ALLOC, CHF_FATAL ChfEnd;
|
||||
ChfSignal();
|
||||
}
|
||||
|
||||
/* Link new structure to the cache list */
|
||||
|
@ -464,7 +473,7 @@ static struct ModMap* CopyModMap( struct ModMap* d, const struct ModMap* s )
|
|||
{
|
||||
struct ModMap* link = d->cache.link; /* Save .link of dest. */
|
||||
|
||||
debug1( MOD_CHF_MODULE_ID, DEBUG_C_TRACE, MOD_I_CALLED, "CopyModMap" );
|
||||
debug1( DEBUG_C_TRACE, MOD_I_CALLED, "CopyModMap" );
|
||||
|
||||
*d = *s;
|
||||
d->cache.link = link; /* Restore .link */
|
||||
|
@ -507,7 +516,7 @@ static struct ModMap* CopyModMap( struct ModMap* d, const struct ModMap* s )
|
|||
.- */
|
||||
static void ReplaceModMap( struct ModMap** d, const struct ModMap* s )
|
||||
{
|
||||
debug1( MOD_CHF_MODULE_ID, DEBUG_C_TRACE, MOD_I_CALLED, "ReplaceModMap" );
|
||||
debug1( DEBUG_C_TRACE, MOD_I_CALLED, "ReplaceModMap" );
|
||||
|
||||
if ( *d == ( struct ModMap* )NULL )
|
||||
/* Allocation needed; cache cleared after allocation */
|
||||
|
@ -546,7 +555,7 @@ static void FlushCache( struct ModMap* save )
|
|||
{
|
||||
struct ModMap *p, *n;
|
||||
|
||||
debug1( MOD_CHF_MODULE_ID, DEBUG_C_TRACE, MOD_I_CALLED, "FlushCache" );
|
||||
debug1( DEBUG_C_TRACE, MOD_I_CALLED, "FlushCache" );
|
||||
|
||||
/* Scan the cache list; free all elements except that pointed by 'save' */
|
||||
p = cache_head;
|
||||
|
@ -574,8 +583,8 @@ static void FlushCache( struct ModMap* save )
|
|||
#ifdef DEBUG
|
||||
/* The alloc_c performance counter must be exactly 1 now */
|
||||
if ( alloc_c != 1 ) {
|
||||
ChfGenerate( MOD_CHF_MODULE_ID, __FILE__, __LINE__, MOD_F_BAD_ALLOC_C, CHF_ERROR, alloc_c );
|
||||
ChfSignal( MOD_CHF_MODULE_ID );
|
||||
ChfCondition MOD_F_BAD_ALLOC_C, CHF_ERROR, alloc_c ChfEnd;
|
||||
ChfSignal();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
@ -607,11 +616,11 @@ static struct ModMap* AccessConfigCache( Address tag )
|
|||
{
|
||||
int i;
|
||||
|
||||
debug1( MOD_CHF_MODULE_ID, DEBUG_C_TRACE, MOD_I_CALLED, "AccessConfigCache" );
|
||||
debug1( DEBUG_C_TRACE, MOD_I_CALLED, "AccessConfigCache" );
|
||||
|
||||
for ( i = 0; i < N_MOD_CACHE_ENTRIES; i++ )
|
||||
if ( MOD_MAP.cache.config[ i ].tag == tag )
|
||||
return MOD_MAP.cache.config[ i ].map_ptr;
|
||||
if ( mod_map.cache.config[ i ].tag == tag )
|
||||
return mod_map.cache.config[ i ].map_ptr;
|
||||
|
||||
return ( struct ModMap* )NULL;
|
||||
}
|
||||
|
@ -645,9 +654,9 @@ static struct ModMap* AccessUnconfigCache( int i )
|
|||
{
|
||||
struct ModMap* p;
|
||||
|
||||
debug1( MOD_CHF_MODULE_ID, DEBUG_C_TRACE, MOD_I_CALLED, "AccessUnconfigCache" );
|
||||
debug1( DEBUG_C_TRACE, MOD_I_CALLED, "AccessUnconfigCache" );
|
||||
|
||||
p = MOD_MAP.cache.unconfig[ i ];
|
||||
p = mod_map.cache.unconfig[ i ];
|
||||
|
||||
while ( p != ( struct ModMap* )NULL && !p->cache.config_point )
|
||||
p = p->cache.unconfig[ i ];
|
||||
|
@ -691,10 +700,10 @@ static struct ModMap* AccessUnconfigCache( int i )
|
|||
.- */
|
||||
struct ModCacheTableEntry* SelectConfigVictim( int retry )
|
||||
{
|
||||
int v = MOD_MAP.cache.victim;
|
||||
int v = mod_map.cache.victim;
|
||||
struct ModCacheTableEntry* victim = ( struct ModCacheTableEntry* )NULL;
|
||||
|
||||
debug1( MOD_CHF_MODULE_ID, DEBUG_C_TRACE, MOD_I_CALLED, "AccessUnconfigCache" );
|
||||
debug1( DEBUG_C_TRACE, MOD_I_CALLED, "AccessUnconfigCache" );
|
||||
|
||||
/* Scan the config cache entries, starting at .cache.victim,
|
||||
until a suitable one is found or the index loops around
|
||||
|
@ -704,29 +713,29 @@ struct ModCacheTableEntry* SelectConfigVictim( int retry )
|
|||
- it is empty (map_ptr == NULL)
|
||||
- or the reference count of the associated map is 0
|
||||
*/
|
||||
if ( ( MOD_MAP.cache.config[ v ].map_ptr == ( struct ModMap* )NULL ) || MOD_MAP.cache.config[ v ].map_ptr->cache.ref_count == 0 )
|
||||
victim = &( MOD_MAP.cache.config[ v ] );
|
||||
if ( ( mod_map.cache.config[ v ].map_ptr == ( struct ModMap* )NULL ) || mod_map.cache.config[ v ].map_ptr->cache.ref_count == 0 )
|
||||
victim = &( mod_map.cache.config[ v ] );
|
||||
|
||||
v = ( v + 1 ) % N_MOD_CACHE_ENTRIES;
|
||||
} while ( victim == ( struct ModCacheTableEntry* )NULL && v != MOD_MAP.cache.victim );
|
||||
} while ( victim == ( struct ModCacheTableEntry* )NULL && v != mod_map.cache.victim );
|
||||
|
||||
if ( victim == ( struct ModCacheTableEntry* )NULL ) {
|
||||
if ( retry ) {
|
||||
/* Unable to find a victim; flush the cache and retry */
|
||||
ChfGenerate( MOD_CHF_MODULE_ID, __FILE__, __LINE__, MOD_W_NO_VICTIM, CHF_WARNING );
|
||||
ChfSignal( MOD_CHF_MODULE_ID );
|
||||
ChfCondition MOD_W_NO_VICTIM, CHF_WARNING ChfEnd;
|
||||
ChfSignal();
|
||||
|
||||
FlushCache( mod_map_ptr );
|
||||
|
||||
victim = SelectConfigVictim( 0 );
|
||||
} else {
|
||||
/* Unable to find a victim; retry is not an option; give up */
|
||||
ChfGenerate( MOD_CHF_MODULE_ID, __FILE__, __LINE__, MOD_F_NO_VICTIM, CHF_FATAL );
|
||||
ChfSignal( MOD_CHF_MODULE_ID );
|
||||
ChfCondition MOD_F_NO_VICTIM, CHF_FATAL ChfEnd;
|
||||
ChfSignal();
|
||||
}
|
||||
} else
|
||||
/* Found a victim; update next-victim index */
|
||||
MOD_MAP.cache.victim = v;
|
||||
mod_map.cache.victim = v;
|
||||
|
||||
return victim;
|
||||
}
|
||||
|
@ -764,7 +773,7 @@ static struct ModMap* CheckForLateHit( void )
|
|||
struct ModMap* p;
|
||||
int i;
|
||||
|
||||
debug1( MOD_CHF_MODULE_ID, DEBUG_C_TRACE, MOD_I_CALLED, "AccessUnconfigCache" );
|
||||
debug1( DEBUG_C_TRACE, MOD_I_CALLED, "AccessUnconfigCache" );
|
||||
|
||||
p = cache_head;
|
||||
|
||||
|
@ -824,7 +833,7 @@ static void FreeModMap( struct ModMap* p )
|
|||
{
|
||||
struct ModMap* n;
|
||||
|
||||
debug1( MOD_CHF_MODULE_ID, DEBUG_C_TRACE, MOD_I_CALLED, "FreeModMap" );
|
||||
debug1( DEBUG_C_TRACE, MOD_I_CALLED, "FreeModMap" );
|
||||
|
||||
/* Free the struct ModMap pointed by p, preserving the linkage of
|
||||
other entries. The caller must ensure that the entry is not
|
||||
|
@ -845,8 +854,8 @@ static void FreeModMap( struct ModMap* p )
|
|||
|
||||
/* Should never happen */
|
||||
if ( n == ( struct ModMap* )NULL ) {
|
||||
ChfGenerate( MOD_CHF_MODULE_ID, __FILE__, __LINE__, MOD_F_CHAIN_CORRUPTED, CHF_FATAL );
|
||||
ChfSignal( MOD_CHF_MODULE_ID );
|
||||
ChfCondition MOD_F_CHAIN_CORRUPTED, CHF_FATAL ChfEnd;
|
||||
ChfSignal();
|
||||
}
|
||||
|
||||
/* Bypass element pointed by p and free it */
|
||||
|
@ -891,7 +900,7 @@ static void FreeModMap( struct ModMap* p )
|
|||
.- */
|
||||
void ModRegisterDescription( ModDescription p )
|
||||
{
|
||||
debug1( MOD_CHF_MODULE_ID, DEBUG_C_TRACE, MOD_I_CALLED, "ModRegisterDescription" );
|
||||
debug1( DEBUG_C_TRACE, MOD_I_CALLED, "ModRegisterDescription" );
|
||||
mod_description = p;
|
||||
}
|
||||
|
||||
|
@ -939,40 +948,42 @@ void ModInit( void )
|
|||
{
|
||||
int mod;
|
||||
|
||||
debug1( MOD_CHF_MODULE_ID, DEBUG_C_TRACE, MOD_I_CALLED, "ModInit" );
|
||||
debug1( DEBUG_C_TRACE, MOD_I_CALLED, "ModInit" );
|
||||
debug1( DEBUG_C_REVISION, MOD_I_REVISION, MOD_RCS_INFO );
|
||||
|
||||
/* First, a little sanity check on mod_description: ensure that
|
||||
ModRegisterDescription() has been called at least once with a
|
||||
non-NULL argument.
|
||||
*/
|
||||
if ( mod_description == NULL ) {
|
||||
ChfGenerate( MOD_CHF_MODULE_ID, __FILE__, __LINE__, MOD_F_NO_DESCRIPTION, CHF_FATAL );
|
||||
ChfSignal( MOD_CHF_MODULE_ID );
|
||||
ChfCondition MOD_F_NO_DESCRIPTION, CHF_FATAL ChfEnd;
|
||||
ChfSignal();
|
||||
}
|
||||
|
||||
/* Scan the mod_description table, initializing all modules */
|
||||
for ( mod = 0; mod < N_MOD; mod++ ) {
|
||||
debug1( MOD_CHF_MODULE_ID, DEBUG_C_MODULES, MOD_I_INITIALIZING, mod_description[ mod ].name );
|
||||
debug1( DEBUG_C_MODULES, MOD_I_INITIALIZING, mod_description[ mod ].name );
|
||||
mod_description[ mod ].init();
|
||||
}
|
||||
|
||||
/* Allocate the root struct ModMap and set it as the current one;
|
||||
the structure can be accessed using either mod_map_ptr or MOD_MAP.
|
||||
the structure can be accessed using either mod_map_ptr or mod_map.
|
||||
*/
|
||||
mod_map_ptr = ClearCachingInfo( NewModMap() );
|
||||
|
||||
/* Attempt to restore the mod_map from file; reset modules if the read
|
||||
fails.
|
||||
*/
|
||||
if ( ReadStructFromFile( config.mod_file_name, sizeof( MOD_MAP.map_info ), &MOD_MAP.map_info ) ) {
|
||||
ChfGenerate( MOD_CHF_MODULE_ID, __FILE__, __LINE__, MOD_W_RESETTING_ALL, CHF_WARNING );
|
||||
ChfSignal( MOD_CHF_MODULE_ID );
|
||||
if ( ReadStructFromFile( args.mod_file_name, sizeof( mod_map.map_info ), &mod_map.map_info ) ) {
|
||||
ChfCondition MOD_W_RESETTING_ALL, CHF_WARNING ChfEnd;
|
||||
ChfSignal();
|
||||
|
||||
/* Reset all modules */
|
||||
ModReset();
|
||||
} else
|
||||
} else {
|
||||
/* Rebuild page table (not saved on disk) */
|
||||
RebuildPageTable( 0, N_PAGE_TABLE_ENTRIES - 1 );
|
||||
}
|
||||
}
|
||||
|
||||
/* .+
|
||||
|
@ -1009,18 +1020,18 @@ void ModSave( void )
|
|||
{
|
||||
int mod;
|
||||
|
||||
debug1( MOD_CHF_MODULE_ID, DEBUG_C_TRACE, MOD_I_CALLED, "ModSave" );
|
||||
debug1( DEBUG_C_TRACE, MOD_I_CALLED, "ModSave" );
|
||||
|
||||
/* Scan the mod_description table, initializing all modules */
|
||||
for ( mod = 0; mod < N_MOD; mod++ ) {
|
||||
debug1( MOD_CHF_MODULE_ID, DEBUG_C_MODULES, MOD_I_SAVING, mod_description[ mod ].name );
|
||||
debug1( DEBUG_C_MODULES, MOD_I_SAVING, mod_description[ mod ].name );
|
||||
mod_description[ mod ].save();
|
||||
}
|
||||
|
||||
/* Attempt to save the mod_map from file */
|
||||
if ( WriteStructToFile( &MOD_MAP.map_info, sizeof( MOD_MAP.map_info ), config.mod_file_name ) ) {
|
||||
ChfGenerate( MOD_CHF_MODULE_ID, __FILE__, __LINE__, MOD_F_MAP_SAVE, CHF_FATAL );
|
||||
ChfSignal( MOD_CHF_MODULE_ID );
|
||||
if ( WriteStructToFile( &mod_map.map_info, sizeof( mod_map.map_info ), args.mod_file_name ) ) {
|
||||
ChfCondition MOD_F_MAP_SAVE, CHF_FATAL ChfEnd;
|
||||
ChfSignal();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1065,12 +1076,12 @@ Address ModGetID( void )
|
|||
int mod;
|
||||
Address id;
|
||||
|
||||
debug1( MOD_CHF_MODULE_ID, DEBUG_C_TRACE, MOD_I_CALLED, "ModGetID" );
|
||||
debug1( DEBUG_C_TRACE, MOD_I_CALLED, "ModGetID" );
|
||||
|
||||
/* Scan the module information table searching for either an unconfigured
|
||||
or a partially configured module
|
||||
*/
|
||||
for ( mod = 0; mod < N_MOD && MOD_MAP.map_info[ mod ].config == MOD_CONFIGURED; mod++ )
|
||||
for ( mod = 0; mod < N_MOD && mod_map.map_info[ mod ].config == MOD_CONFIGURED; mod++ )
|
||||
;
|
||||
|
||||
if ( mod == N_MOD )
|
||||
|
@ -1078,11 +1089,11 @@ Address ModGetID( void )
|
|||
id = ( Address )0x00000;
|
||||
else
|
||||
/* Build the module id */
|
||||
id = ( MOD_MAP.map_info[ mod ].abs_base_addr & 0xFFF00 ) |
|
||||
( MOD_MAP.map_info[ mod ].config == MOD_UNCONFIGURED ? 0x00000 : 0x000F0 ) |
|
||||
( mod_description[ mod ].id + ( MOD_MAP.map_info[ mod ].config == MOD_UNCONFIGURED ? 0 : 1 ) );
|
||||
id = ( mod_map.map_info[ mod ].abs_base_addr & 0xFFF00 ) |
|
||||
( mod_map.map_info[ mod ].config == MOD_UNCONFIGURED ? 0x00000 : 0x000F0 ) |
|
||||
( mod_description[ mod ].id + ( mod_map.map_info[ mod ].config == MOD_UNCONFIGURED ? 0 : 1 ) );
|
||||
|
||||
debug1( MOD_CHF_MODULE_ID, DEBUG_C_MODULES, MOD_I_GET_ID, id );
|
||||
debug1( DEBUG_C_MODULES, MOD_I_GET_ID, id );
|
||||
return id;
|
||||
}
|
||||
|
||||
|
@ -1115,18 +1126,18 @@ void ModReset( void )
|
|||
{
|
||||
int mod;
|
||||
|
||||
debug1( MOD_CHF_MODULE_ID, DEBUG_C_TRACE, MOD_I_CALLED, "ModReset" );
|
||||
debug1( DEBUG_C_TRACE, MOD_I_CALLED, "ModReset" );
|
||||
|
||||
/* Scan the mod_description table, initializing the module
|
||||
mapping information MOD_MAP.map_info.
|
||||
mapping information mod_map.map_info.
|
||||
*/
|
||||
for ( mod = 0; mod < N_MOD; mod++ ) {
|
||||
debug1( MOD_CHF_MODULE_ID, DEBUG_C_MODULES, MOD_I_RESETTING, mod_description[ mod ].name );
|
||||
debug1( DEBUG_C_MODULES, MOD_I_RESETTING, mod_description[ mod ].name );
|
||||
|
||||
/* Set the module configuration status */
|
||||
MOD_MAP.map_info[ mod ].config = mod_description[ mod ].r_config;
|
||||
MOD_MAP.map_info[ mod ].abs_base_addr = mod_description[ mod ].r_abs_base_addr;
|
||||
MOD_MAP.map_info[ mod ].size = mod_description[ mod ].r_size;
|
||||
mod_map.map_info[ mod ].config = mod_description[ mod ].r_config;
|
||||
mod_map.map_info[ mod ].abs_base_addr = mod_description[ mod ].r_abs_base_addr;
|
||||
mod_map.map_info[ mod ].size = mod_description[ mod ].r_size;
|
||||
}
|
||||
|
||||
/* Rebuild the module page table */
|
||||
|
@ -1139,7 +1150,7 @@ void ModReset( void )
|
|||
this flag is used by the unconfig cache code to correctly
|
||||
undo the last config
|
||||
*/
|
||||
MOD_MAP.cache.config_point = 1;
|
||||
mod_map.cache.config_point = 1;
|
||||
}
|
||||
|
||||
/* .+
|
||||
|
@ -1151,7 +1162,7 @@ void ModReset( void )
|
|||
This function configures a module, using the given 'config_info'.
|
||||
|
||||
The target module will be the first unconfigured or partially configured
|
||||
module found in the MOD_MAP.map_info table.
|
||||
module found in the mod_map.map_info table.
|
||||
|
||||
If the target module is unconfigured, ModConfig sets the size of its
|
||||
address space to 0x100000 - 'config_info'; the module then becomes
|
||||
|
@ -1183,7 +1194,7 @@ void ModReset( void )
|
|||
2.7, 15-Sep-2000, update
|
||||
- implemented module config/unconfig cache
|
||||
3.2, 22-Sep-2000, update
|
||||
- enabled forced alignment
|
||||
- conditionally (#ifdef HP49_SUPPORT) enabled forced alignment
|
||||
of config_info
|
||||
.- */
|
||||
void ModConfig( Address config_info )
|
||||
|
@ -1193,13 +1204,15 @@ void ModConfig( Address config_info )
|
|||
|
||||
int mod;
|
||||
|
||||
debug1( MOD_CHF_MODULE_ID, DEBUG_C_TRACE, MOD_I_CALLED, "ModConfig" );
|
||||
debug1( DEBUG_C_TRACE, MOD_I_CALLED, "ModConfig" );
|
||||
|
||||
#ifdef HP49_SUPPORT
|
||||
/* 3.2: The HP49 firmware (1.19-4) can generate misaligned config
|
||||
addresses, that is, addresses that are not a multiple of 0x100;
|
||||
silently align them here.
|
||||
*/
|
||||
config_info &= ~0xFF;
|
||||
#endif
|
||||
|
||||
/* ACCESS CONFIG CACHE */
|
||||
if ( ( nxt = AccessConfigCache( config_info ) ) != ( struct ModMap* )NULL ) {
|
||||
|
@ -1208,7 +1221,7 @@ void ModConfig( Address config_info )
|
|||
|
||||
IncPerfCtr( hit_c );
|
||||
|
||||
debug1( MOD_CHF_MODULE_ID, DEBUG_C_MOD_CACHE, MOD_I_CACHED_CONFIG, config_info );
|
||||
debug1( DEBUG_C_MOD_CACHE, MOD_I_CACHED_CONFIG, config_info );
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1240,43 +1253,42 @@ void ModConfig( Address config_info )
|
|||
/* Scan the module information table searching for either an unconfigured
|
||||
or a partially configured module
|
||||
*/
|
||||
for ( mod = 0; mod < N_MOD && MOD_MAP.map_info[ mod ].config == MOD_CONFIGURED; mod++ )
|
||||
for ( mod = 0; mod < N_MOD && mod_map.map_info[ mod ].config == MOD_CONFIGURED; mod++ )
|
||||
;
|
||||
|
||||
if ( mod == N_MOD ) {
|
||||
/* All modules are configured - Signal a warning */
|
||||
// FIXME: 48gx bugs here when running VERSION
|
||||
ChfGenerate( MOD_CHF_MODULE_ID, __FILE__, __LINE__, MOD_W_BAD_CONFIG, CHF_WARNING, config_info );
|
||||
ChfSignal( MOD_CHF_MODULE_ID );
|
||||
ChfCondition MOD_W_BAD_CONFIG, CHF_WARNING, config_info ChfEnd;
|
||||
ChfSignal();
|
||||
} else {
|
||||
if ( MOD_MAP.map_info[ mod ].config == MOD_UNCONFIGURED ) {
|
||||
if ( mod_map.map_info[ mod ].config == MOD_UNCONFIGURED ) {
|
||||
/* The module was unconfigured; configure its size */
|
||||
MOD_MAP.map_info[ mod ].size = 0x100000 - config_info;
|
||||
MOD_MAP.map_info[ mod ].config = MOD_SIZE_CONFIGURED;
|
||||
mod_map.map_info[ mod ].size = 0x100000 - config_info;
|
||||
mod_map.map_info[ mod ].config = MOD_SIZE_CONFIGURED;
|
||||
} else {
|
||||
/* The module size was already configured; configure its base address */
|
||||
MOD_MAP.map_info[ mod ].abs_base_addr = config_info;
|
||||
MOD_MAP.map_info[ mod ].config = MOD_CONFIGURED;
|
||||
mod_map.map_info[ mod ].abs_base_addr = config_info;
|
||||
mod_map.map_info[ mod ].config = MOD_CONFIGURED;
|
||||
|
||||
/* Rebuild the page table */
|
||||
RebuildPageTable( ModPage( MOD_MAP.map_info[ mod ].abs_base_addr ),
|
||||
ModPage( MOD_MAP.map_info[ mod ].abs_base_addr + MOD_MAP.map_info[ mod ].size - 1 ) );
|
||||
RebuildPageTable( ModPage( mod_map.map_info[ mod ].abs_base_addr ),
|
||||
ModPage( mod_map.map_info[ mod ].abs_base_addr + mod_map.map_info[ mod ].size - 1 ) );
|
||||
|
||||
/* Mark the current struct ModMap to be a configuration point;
|
||||
this flag is used by the unconfig cache code to correctly
|
||||
undo the last config
|
||||
*/
|
||||
MOD_MAP.cache.config_point = 1;
|
||||
mod_map.cache.config_point = 1;
|
||||
|
||||
debug3( MOD_CHF_MODULE_ID, DEBUG_C_MODULES | DEBUG_C_MOD_CACHE, MOD_I_CONFIG, mod_description[ mod ].name,
|
||||
MOD_MAP.map_info[ mod ].abs_base_addr, MOD_MAP.map_info[ mod ].size );
|
||||
debug3( DEBUG_C_MODULES | DEBUG_C_MOD_CACHE, MOD_I_CONFIG, mod_description[ mod ].name, mod_map.map_info[ mod ].abs_base_addr,
|
||||
mod_map.map_info[ mod ].size );
|
||||
}
|
||||
|
||||
/* Set the unconfig cache pointer of module 'mod' to the old ModMap,
|
||||
and increment its reference counter, to avoid freeing it
|
||||
improperly.
|
||||
*/
|
||||
MOD_MAP.cache.unconfig[ mod ] = old;
|
||||
mod_map.cache.unconfig[ mod ] = old;
|
||||
old->cache.ref_count++;
|
||||
}
|
||||
}
|
||||
|
@ -1318,15 +1330,15 @@ void ModUnconfig( Address unconfig_info )
|
|||
struct ModMap *nxt, *old;
|
||||
int mod;
|
||||
|
||||
debug1( MOD_CHF_MODULE_ID, DEBUG_C_TRACE, MOD_I_CALLED, "ModUnconfig" );
|
||||
debug1( DEBUG_C_TRACE, MOD_I_CALLED, "ModUnconfig" );
|
||||
|
||||
/* Determine the module to unconfigure */
|
||||
if ( ( mod = MOD_MAP.page_table[ ModPage( unconfig_info ) ].index ) == MOD_NO_MOD_INDEX ) {
|
||||
if ( ( mod = mod_map.page_table[ ModPage( unconfig_info ) ].index ) == MOD_NO_MOD_INDEX ) {
|
||||
/* There isn't any module configured at the given address -
|
||||
Signal a warning
|
||||
*/
|
||||
ChfGenerate( MOD_CHF_MODULE_ID, __FILE__, __LINE__, MOD_W_BAD_UNCONFIG, CHF_WARNING, unconfig_info );
|
||||
ChfSignal( MOD_CHF_MODULE_ID );
|
||||
ChfCondition MOD_W_BAD_UNCONFIG, CHF_WARNING, unconfig_info ChfEnd;
|
||||
ChfSignal();
|
||||
} else if ( mod_description[ mod ].r_config == MOD_CONFIGURED ) {
|
||||
/* The module is automatically configured after reset; it can never
|
||||
be unconfigured.
|
||||
|
@ -1339,7 +1351,7 @@ void ModUnconfig( Address unconfig_info )
|
|||
|
||||
IncPerfCtr( hit_c );
|
||||
|
||||
debug0( MOD_CHF_MODULE_ID, DEBUG_C_MOD_CACHE, MOD_I_CACHED_UNCONFIG );
|
||||
debug0( DEBUG_C_MOD_CACHE, MOD_I_CACHED_UNCONFIG );
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1365,18 +1377,18 @@ void ModUnconfig( Address unconfig_info )
|
|||
mod_map_ptr = CopyModMap( NewModMap(), mod_map_ptr );
|
||||
|
||||
/* Update the mapping information table */
|
||||
MOD_MAP.map_info[ mod ].config = mod_description[ mod ].r_config;
|
||||
mod_map.map_info[ mod ].config = mod_description[ mod ].r_config;
|
||||
|
||||
/* Rebuild the page table */
|
||||
RebuildPageTable( ModPage( MOD_MAP.map_info[ mod ].abs_base_addr ),
|
||||
ModPage( MOD_MAP.map_info[ mod ].abs_base_addr + MOD_MAP.map_info[ mod ].size - 1 ) );
|
||||
RebuildPageTable( ModPage( mod_map.map_info[ mod ].abs_base_addr ),
|
||||
ModPage( mod_map.map_info[ mod ].abs_base_addr + mod_map.map_info[ mod ].size - 1 ) );
|
||||
|
||||
/* Reset the module configuration status; the abs_base_addr of the module
|
||||
is not reset because its old value is still needed by ModGetId()
|
||||
The size is reset for the modules that are already MOD_SIZE_CONFIGURED
|
||||
immediately after reset.
|
||||
*/
|
||||
MOD_MAP.map_info[ mod ].size = mod_description[ mod ].r_size;
|
||||
mod_map.map_info[ mod ].size = mod_description[ mod ].r_size;
|
||||
|
||||
if ( ( nxt = CheckForLateHit() ) != ( struct ModMap* )NULL ) {
|
||||
/* Update pointer from the old map to the new one, and increment
|
||||
|
@ -1390,7 +1402,7 @@ void ModUnconfig( Address unconfig_info )
|
|||
mod_map_ptr = nxt;
|
||||
|
||||
IncPerfCtr( lhit_c );
|
||||
debug0( MOD_CHF_MODULE_ID, DEBUG_C_MOD_CACHE, MOD_I_UNCONFIG_L_HIT );
|
||||
debug0( DEBUG_C_MOD_CACHE, MOD_I_UNCONFIG_L_HIT );
|
||||
} else {
|
||||
/* Continue to use the new map with no caching information,
|
||||
and hope that further configuration activities will link it
|
||||
|
@ -1401,14 +1413,14 @@ void ModUnconfig( Address unconfig_info )
|
|||
this flag is used by the unconfig cache code to correctly
|
||||
undo the last config
|
||||
*/
|
||||
MOD_MAP.cache.config_point = 1;
|
||||
mod_map.cache.config_point = 1;
|
||||
|
||||
IncPerfCtr( miss_c );
|
||||
|
||||
debug0( MOD_CHF_MODULE_ID, DEBUG_C_MOD_CACHE, MOD_I_UNCONFIG_L_MISS );
|
||||
debug0( DEBUG_C_MOD_CACHE, MOD_I_UNCONFIG_L_MISS );
|
||||
|
||||
debug3( MOD_CHF_MODULE_ID, DEBUG_C_MODULES | DEBUG_C_MOD_CACHE, MOD_I_UNCONFIG, mod_description[ mod ].name,
|
||||
MOD_MAP.map_info[ mod ].abs_base_addr, MOD_MAP.map_info[ mod ].size );
|
||||
debug3( DEBUG_C_MODULES | DEBUG_C_MOD_CACHE, MOD_I_UNCONFIG, mod_description[ mod ].name, mod_map.map_info[ mod ].abs_base_addr,
|
||||
mod_map.map_info[ mod ].size );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1440,7 +1452,7 @@ Nibble FetchNibble( Address addr )
|
|||
{
|
||||
register int page = ModPage( addr );
|
||||
|
||||
return MOD_MAP.page_table[ page ].read( MOD_MAP.page_table[ page ].rel_base_addr | ModOffset( addr ) );
|
||||
return mod_map.page_table[ page ].read( mod_map.page_table[ page ].rel_base_addr | ModOffset( addr ) );
|
||||
}
|
||||
|
||||
/* .+
|
||||
|
@ -1476,10 +1488,10 @@ Nibble ReadNibble( Address addr )
|
|||
register Nibble d;
|
||||
|
||||
/* Read the nibble from the peripheral module */
|
||||
d = MOD_MAP.page_table[ page ].read( MOD_MAP.page_table[ page ].rel_base_addr | ModOffset( addr ) );
|
||||
d = mod_map.page_table[ page ].read( mod_map.page_table[ page ].rel_base_addr | ModOffset( addr ) );
|
||||
|
||||
/* Update the crc register, if appropriate */
|
||||
if ( MOD_MAP.page_table[ page ].index != MOD_HDW_INDEX )
|
||||
if ( mod_map.page_table[ page ].index != MOD_HDW_INDEX )
|
||||
mod_status.hdw.crc = ( mod_status.hdw.crc >> 4 ) ^ ( ( ( mod_status.hdw.crc ^ d ) & 0x0F ) * 0x1081 );
|
||||
|
||||
/* Return to the caller */
|
||||
|
@ -1514,7 +1526,7 @@ void WriteNibble( Address addr, Nibble datum )
|
|||
{
|
||||
register int page = ModPage( addr );
|
||||
|
||||
MOD_MAP.page_table[ page ].write( MOD_MAP.page_table[ page ].rel_base_addr | ModOffset( addr ), datum );
|
||||
mod_map.page_table[ page ].write( mod_map.page_table[ page ].rel_base_addr | ModOffset( addr ), datum );
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------
|
||||
|
@ -1551,16 +1563,16 @@ void ModMapCheck( Address addr, char ob[ MOD_MAP_CHECK_OB_SIZE ] )
|
|||
page = ModPage( addr );
|
||||
offset = ModOffset( addr );
|
||||
|
||||
if ( ( mod = MOD_MAP.page_table[ page ].index ) == MOD_NO_MOD_INDEX )
|
||||
sprintf( ob, "A[%05X] -> *Not Mapped*", addr );
|
||||
if ( ( mod = mod_map.page_table[ page ].index ) == MOD_NO_MOD_INDEX )
|
||||
sprintf( ob, ChfGetMessage( CHF_MODULE_ID, MOD_M_NOT_MAPPED, "" ), addr );
|
||||
else {
|
||||
Address rel_addr;
|
||||
rel_addr = MOD_MAP.page_table[ page ].rel_base_addr | offset;
|
||||
rel_addr = mod_map.page_table[ page ].rel_base_addr | offset;
|
||||
|
||||
sprintf( ob, "A[%05X] -> M[%s] R[%05X]", addr, mod_description[ mod ].name, rel_addr );
|
||||
sprintf( ob, ChfGetMessage( CHF_MODULE_ID, MOD_M_MAPPED, "" ), addr, mod_description[ mod ].name, rel_addr );
|
||||
}
|
||||
|
||||
ChfSignal( MOD_CHF_MODULE_ID );
|
||||
ChfSignal();
|
||||
}
|
||||
|
||||
/* .+
|
||||
|
@ -1588,14 +1600,16 @@ void ModMapTable( char ob[ MOD_MAP_TABLE_OB_SIZE ] )
|
|||
{
|
||||
int mod;
|
||||
|
||||
sprintf( ob, "%s\n", "Device\t\t\tAddress\tSize\tStatus" );
|
||||
sprintf( ob, "%s\n", ChfGetMessage( CHF_MODULE_ID, MOD_M_MAP_TABLE_TITLE, "" ) );
|
||||
ob += strlen( ob );
|
||||
|
||||
for ( mod = 0; mod < N_MOD; mod++ ) {
|
||||
sprintf( ob, "%s\t%05X\t%05X\t%s", mod_description[ mod ].name, MOD_MAP.map_info[ mod ].abs_base_addr, MOD_MAP.map_info[ mod ].size,
|
||||
MOD_MAP.map_info[ mod ].config == MOD_CONFIGURED
|
||||
? "Configured"
|
||||
: ( MOD_MAP.map_info[ mod ].config == MOD_SIZE_CONFIGURED ? "Size_configured" : "*Unconfigured*" ) );
|
||||
sprintf( ob, ChfGetMessage( CHF_MODULE_ID, MOD_M_MAP_TABLE_ROW, "" ), mod_description[ mod ].name,
|
||||
mod_map.map_info[ mod ].abs_base_addr, mod_map.map_info[ mod ].size,
|
||||
mod_map.map_info[ mod ].config == MOD_CONFIGURED ? ChfGetMessage( CHF_MODULE_ID, MOD_M_MAP_CONFIGURED, "C" )
|
||||
: ( mod_map.map_info[ mod ].config == MOD_SIZE_CONFIGURED
|
||||
? ChfGetMessage( CHF_MODULE_ID, MOD_M_MAP_SZ_CONFIGURED, "S" )
|
||||
: ChfGetMessage( CHF_MODULE_ID, MOD_M_MAP_UNCONFIGURED, "U" ) ) );
|
||||
|
||||
strcat( ob, "\n" );
|
||||
ob += strlen( ob );
|
||||
|
|
|
@ -229,7 +229,7 @@ typedef void ( *ModWriteFunction )( Address rel_addr, Nibble data );
|
|||
enum ModConfig { MOD_UNCONFIGURED, MOD_SIZE_CONFIGURED, MOD_CONFIGURED };
|
||||
|
||||
struct ModDescriptionEntry {
|
||||
const char* name;
|
||||
char* name;
|
||||
Address id;
|
||||
int access_prio;
|
||||
#define MOD_MIN_ACCESS_PRIO ( -1 )
|
||||
|
@ -570,7 +570,7 @@ extern struct ModStatus mod_status;
|
|||
---------------------------------------------------------------------------*/
|
||||
|
||||
/* Initialization */
|
||||
void ModSelectDescription( int model );
|
||||
void ModSelectDescription( const char* hw );
|
||||
void ModRegisterDescription( ModDescription p );
|
||||
void ModInit( void );
|
||||
void ModSave( void );
|
||||
|
|
|
@ -65,17 +65,25 @@
|
|||
|
||||
.- */
|
||||
|
||||
#ifndef lint
|
||||
static char rcs_id[] = "$Id: monitor.c,v 4.1 2000/12/11 09:54:19 cibrario Rel $";
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <setjmp.h>
|
||||
#include <string.h>
|
||||
#include <signal.h>
|
||||
|
||||
#include "libChf/src/Chf.h"
|
||||
#include <errno.h>
|
||||
|
||||
#include "config.h"
|
||||
#include "machdep.h"
|
||||
#include "cpu.h"
|
||||
#include "modules.h"
|
||||
#include "debug.h"
|
||||
|
||||
#define CHF_MODULE_ID CPU_CHF_MODULE_ID
|
||||
#include <Chf.h>
|
||||
|
||||
/*---------------------------------------------------------------------------
|
||||
Macro & Data type definitions
|
||||
|
@ -136,7 +144,7 @@ static int debug( void )
|
|||
Address addr;
|
||||
if ( ReadHexAddress( &addr ) )
|
||||
return FAILED;
|
||||
config.debug_level |= ( int )addr;
|
||||
SetDebugLevel( ( int )addr );
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
@ -248,12 +256,12 @@ static int mon_quit( void )
|
|||
---------------------------------------------------------------------------*/
|
||||
|
||||
struct TEntry {
|
||||
const char* name;
|
||||
const char* desc;
|
||||
char* name;
|
||||
char* desc;
|
||||
int ( *function )( void );
|
||||
};
|
||||
|
||||
#define TABLE_SIZE( t ) ( sizeof( t ) / sizeof( struct TEntry ) )
|
||||
#define TableSize( t ) ( sizeof( t ) / sizeof( struct TEntry ) )
|
||||
|
||||
/* Forward declaration for the Help funcion */
|
||||
static int Help( void );
|
||||
|
@ -277,15 +285,16 @@ static const struct TEntry table[] = {
|
|||
static int InvokeCommand( char* tk )
|
||||
{
|
||||
int i;
|
||||
for ( i = 0; i < ( int )TABLE_SIZE( table ) && strcmp( tk, table[ i ].name ); i++ )
|
||||
for ( i = 0; i < ( int )TableSize( table ) && strcmp( tk, table[ i ].name ); i++ )
|
||||
;
|
||||
return i == TABLE_SIZE( table ) ? FAILED : table[ i ].function();
|
||||
return i == TableSize( table ) ? FAILED : table[ i ].function();
|
||||
}
|
||||
|
||||
/* Print help information */
|
||||
static int Help( void )
|
||||
{
|
||||
for ( int i = 0; i < ( int )TABLE_SIZE( table ); i++ )
|
||||
int i;
|
||||
for ( i = 0; i < ( int )TableSize( table ); i++ )
|
||||
printf( "%s\t\t%s\n", table[ i ].name, table[ i ].desc );
|
||||
|
||||
return OK;
|
||||
|
@ -332,7 +341,7 @@ void Monitor( void )
|
|||
signal( SIGINT, sigint_handler );
|
||||
|
||||
/* Infinite loop; it's exited only when a condition is signalled */
|
||||
while ( true ) {
|
||||
while ( 1 ) {
|
||||
/* Write prompt */
|
||||
fputs( PROMPT, stdout );
|
||||
fflush( stdout );
|
||||
|
@ -341,16 +350,16 @@ void Monitor( void )
|
|||
/* New command empty; try old command */
|
||||
if ( ( tk = strtok( old_cmd, TOK_DELIMITERS ) ) != ( char* )NULL )
|
||||
if ( InvokeCommand( tk ) )
|
||||
ChfGenerate( CPU_CHF_MODULE_ID, __FILE__, __LINE__, CPU_W_BAD_MONITOR_CMD, CHF_WARNING, tk );
|
||||
ChfSignal( CPU_CHF_MODULE_ID );
|
||||
ChfCondition CPU_W_BAD_MONITOR_CMD, CHF_WARNING, tk ChfEnd;
|
||||
ChfSignal();
|
||||
} else {
|
||||
/* Save command */
|
||||
strcpy( old_cmd, cmd );
|
||||
|
||||
/* New command */
|
||||
if ( InvokeCommand( tk ) ) {
|
||||
ChfGenerate( CPU_CHF_MODULE_ID, __FILE__, __LINE__, CPU_W_BAD_MONITOR_CMD, CHF_WARNING, tk );
|
||||
ChfSignal( CPU_CHF_MODULE_ID );
|
||||
ChfCondition CPU_W_BAD_MONITOR_CMD, CHF_WARNING, tk ChfEnd;
|
||||
ChfSignal();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
148
src/pack.c
148
src/pack.c
|
@ -64,32 +64,27 @@
|
|||
|
||||
.- */
|
||||
|
||||
#ifndef lint
|
||||
static char rcs_id[] = "$Id";
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <setjmp.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#include "libChf/src/Chf.h"
|
||||
#include <errno.h>
|
||||
|
||||
#include "config.h"
|
||||
#include "machdep.h"
|
||||
#include "cpu.h"
|
||||
#include "disk_io.h"
|
||||
|
||||
/* Condition codes used by this utility */
|
||||
#define UTIL_CHF_MODULE_ID 17
|
||||
|
||||
#define UTIL_I_PACK_USAGE 1
|
||||
#define UTIL_F_PACK_CMD_LINE 2
|
||||
#define UTIL_F_PACK_STAT 3
|
||||
#define UTIL_F_PACK_SRC_SIZE 4
|
||||
#define UTIL_F_PACK_MALLOC 5
|
||||
#define UTIL_F_PACK_OPEN 6
|
||||
#define UTIL_F_PACK_READ 7
|
||||
#define UTIL_F_PACK_WRITE_NIBBLES 8
|
||||
#define CHF_MODULE_ID UTIL_CHF_MODULE_ID
|
||||
#include <Chf.h>
|
||||
|
||||
/* Maximum size of source ROM (bytes) handled by this utility; set to
|
||||
a reasonable value
|
||||
|
@ -106,20 +101,24 @@
|
|||
/* Conditional prefix and mandatory suffix to make a message catalog
|
||||
name from cat_base_name.
|
||||
*/
|
||||
/* Message catalog */
|
||||
static const char cat_base_name[] = "saturn";
|
||||
ChfTable message_table[] = {
|
||||
{UTIL_CHF_MODULE_ID, UTIL_I_PACK_USAGE, "Usage:\n pack <emu48_source_rom> <saturn_dest_rom>"},
|
||||
{UTIL_CHF_MODULE_ID, UTIL_F_PACK_CMD_LINE, "Command line syntax error" },
|
||||
{UTIL_CHF_MODULE_ID, UTIL_F_PACK_STAT, "stat(%s) failed" },
|
||||
{UTIL_CHF_MODULE_ID, UTIL_F_PACK_SRC_SIZE, "Invalid source file size: %d" },
|
||||
{UTIL_CHF_MODULE_ID, UTIL_F_PACK_MALLOC, "malloc(%d) failed" },
|
||||
{UTIL_CHF_MODULE_ID, UTIL_F_PACK_OPEN, "open(%s) failed" },
|
||||
{UTIL_CHF_MODULE_ID, UTIL_F_PACK_READ, "read(%s) failed" },
|
||||
{UTIL_CHF_MODULE_ID, UTIL_F_PACK_WRITE_NIBBLES, "WriteNibblesToFile() failed" },
|
||||
};
|
||||
static const char cat_prefix[] = "./";
|
||||
static const char cat_suffix[] = ".cat";
|
||||
|
||||
size_t message_table_size = sizeof( message_table ) / sizeof( message_table[ 0 ] );
|
||||
#define CAT_PREFIX_LEN ( sizeof( cat_prefix ) + 1 )
|
||||
#define CAT_SUFFIX_LEN ( sizeof( cat_suffix ) + 1 )
|
||||
|
||||
/* Message catalog base_name */
|
||||
static const char cat_base_name[] = "saturn";
|
||||
|
||||
/* Condition codes used by this utility */
|
||||
#define UTIL_I_PACK_USAGE 1
|
||||
#define UTIL_F_PACK_CMD_LINE 2
|
||||
#define UTIL_F_PACK_STAT 3
|
||||
#define UTIL_F_PACK_SRC_SIZE 4
|
||||
#define UTIL_F_PACK_MALLOC 5
|
||||
#define UTIL_F_PACK_OPEN 6
|
||||
#define UTIL_F_PACK_READ 7
|
||||
#define UTIL_F_PACK_WRITE_NIBBLES 8
|
||||
|
||||
/*---------------------------------------------------------------------------
|
||||
Public functions
|
||||
|
@ -139,73 +138,112 @@ size_t message_table_size = sizeof( message_table ) / sizeof( message_table[ 0 ]
|
|||
.- */
|
||||
int main( int argc, char* argv[] )
|
||||
{
|
||||
char* cat_name; /* Message catalog name */
|
||||
struct stat statb; /* stat() buffer on source file */
|
||||
char* b; /* Source buffer */
|
||||
Nibble* nb; /* Nibble buffer */
|
||||
int d; /* Source file descriptor */
|
||||
int i;
|
||||
int st;
|
||||
|
||||
if ( ( cat_name = malloc( sizeof( cat_base_name ) + CAT_PREFIX_LEN + CAT_SUFFIX_LEN + 1 ) ) == NULL ) {
|
||||
fprintf( stderr, "Cat_name initialization failed\n" );
|
||||
exit( EXIT_FAILURE );
|
||||
}
|
||||
|
||||
/* Generate catalog name, without optional prefix */
|
||||
strcpy( cat_name, cat_base_name );
|
||||
strcat( cat_name, cat_suffix );
|
||||
|
||||
/* Chf initialization with msgcat subsystem;
|
||||
notice that on some systems (e.g. Digital UNIX) catopen() can succeed
|
||||
even if it was not able to open the right message catalog; better
|
||||
try it now.
|
||||
*/
|
||||
if ( ChfStaticInit( argv[ 0 ], /* Application's name */
|
||||
CHF_DEFAULT, /* Options */
|
||||
message_table, /* message catalog */
|
||||
message_table_size, /* message catalog size */
|
||||
CONDITION_STACK_SIZE, /* Size of the condition stack */
|
||||
HANDLER_STACK_SIZE, /* Size of the handler stack */
|
||||
EXIT_FAILURE /* Abnormal exit code */
|
||||
) != CHF_S_OK ) {
|
||||
fprintf( stderr, "Chf initialization failed\n" );
|
||||
exit( EXIT_FAILURE );
|
||||
if ( ( st = ChfMsgcatInit( argv[ 0 ], /* Application's name */
|
||||
CHF_DEFAULT, /* Options */
|
||||
cat_name, /* Name of the message catalog */
|
||||
CONDITION_STACK_SIZE, /* Size of the condition stack */
|
||||
HANDLER_STACK_SIZE, /* Size of the handler stack */
|
||||
EXIT_FAILURE /* Abnormal exit code */
|
||||
) ) != CHF_S_OK ||
|
||||
ChfGetMessage( CHF_MODULE_ID, UTIL_I_PACK_USAGE, NULL ) == NULL ) {
|
||||
if ( st != CHF_S_OK && st != CHF_F_CATOPEN ) {
|
||||
fprintf( stderr, "Chf initialization failed\n" );
|
||||
exit( EXIT_FAILURE );
|
||||
} else {
|
||||
fprintf( stderr, "Default message catalog open failed; trying alternate\n" );
|
||||
|
||||
/* Bring down Chf before initializing it again */
|
||||
if ( st == CHF_S_OK )
|
||||
ChfExit();
|
||||
|
||||
/* Try alternate message catalog name (with prefix) */
|
||||
strcpy( cat_name, cat_prefix );
|
||||
strcat( cat_name, cat_base_name );
|
||||
strcat( cat_name, cat_suffix );
|
||||
|
||||
if ( ( st = ChfMsgcatInit( argv[ 0 ], /* Application's name */
|
||||
CHF_DEFAULT, /* Options */
|
||||
cat_name, /* Name of the message catalog */
|
||||
CONDITION_STACK_SIZE, /* Size of the condition stack */
|
||||
HANDLER_STACK_SIZE, /* Size of the handler stack */
|
||||
EXIT_FAILURE /* Abnormal exit code */
|
||||
) ) != CHF_S_OK ||
|
||||
ChfGetMessage( CHF_MODULE_ID, UTIL_I_PACK_USAGE, NULL ) == NULL ) {
|
||||
fprintf( stderr, "Alternate Chf initialization failed\n" );
|
||||
exit( EXIT_FAILURE );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* cat_name no longer needed */
|
||||
free( cat_name );
|
||||
|
||||
/* Now, do some useful work; pack argv[1] into argv[2] */
|
||||
if ( argc != 3 ) {
|
||||
ChfGenerate( UTIL_CHF_MODULE_ID, __FILE__, __LINE__, UTIL_I_PACK_USAGE, CHF_INFO );
|
||||
ChfGenerate( UTIL_CHF_MODULE_ID, __FILE__, __LINE__, UTIL_F_PACK_CMD_LINE, CHF_FATAL );
|
||||
ChfSignal( UTIL_CHF_MODULE_ID );
|
||||
ChfCondition UTIL_I_PACK_USAGE, CHF_INFO ChfEnd;
|
||||
ChfCondition UTIL_F_PACK_CMD_LINE, CHF_FATAL ChfEnd;
|
||||
ChfSignal();
|
||||
}
|
||||
|
||||
/* Get the size of the source file */
|
||||
if ( stat( argv[ 1 ], &statb ) ) {
|
||||
ChfGenerate( CHF_ERRNO_SET, __FILE__, __LINE__, errno, CHF_ERROR );
|
||||
ChfGenerate( UTIL_CHF_MODULE_ID, __FILE__, __LINE__, UTIL_F_PACK_STAT, CHF_FATAL, argv[ 1 ] );
|
||||
ChfSignal( UTIL_CHF_MODULE_ID );
|
||||
ChfErrnoCondition;
|
||||
ChfCondition UTIL_F_PACK_STAT, CHF_FATAL, argv[ 1 ] ChfEnd;
|
||||
ChfSignal();
|
||||
}
|
||||
|
||||
/* Check that actual size is reasonable */
|
||||
if ( statb.st_size > MAX_SRC_SIZE ) {
|
||||
ChfGenerate( UTIL_CHF_MODULE_ID, __FILE__, __LINE__, UTIL_F_PACK_SRC_SIZE, CHF_FATAL, statb.st_size );
|
||||
ChfSignal( UTIL_CHF_MODULE_ID );
|
||||
ChfCondition UTIL_F_PACK_SRC_SIZE, CHF_FATAL, statb.st_size ChfEnd;
|
||||
ChfSignal();
|
||||
}
|
||||
|
||||
/* Allocate source buffer */
|
||||
if ( ( b = ( char* )malloc( statb.st_size ) ) == ( char* )NULL ||
|
||||
( nb = ( Nibble* )malloc( sizeof( Nibble ) * statb.st_size ) ) == ( Nibble* )NULL ) {
|
||||
ChfGenerate( CHF_ERRNO_SET, __FILE__, __LINE__, errno, CHF_ERROR );
|
||||
ChfGenerate( UTIL_CHF_MODULE_ID, __FILE__, __LINE__, UTIL_F_PACK_MALLOC, CHF_FATAL, statb.st_size );
|
||||
ChfSignal( UTIL_CHF_MODULE_ID );
|
||||
ChfErrnoCondition;
|
||||
ChfCondition UTIL_F_PACK_MALLOC, CHF_FATAL, statb.st_size ChfEnd;
|
||||
ChfSignal();
|
||||
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
/* open/read/close */
|
||||
if ( ( d = open( argv[ 1 ], O_RDONLY ) ) == -1 ) {
|
||||
ChfGenerate( CHF_ERRNO_SET, __FILE__, __LINE__, errno, CHF_ERROR );
|
||||
ChfGenerate( UTIL_CHF_MODULE_ID, __FILE__, __LINE__, UTIL_F_PACK_OPEN, CHF_FATAL, argv[ 1 ] );
|
||||
ChfSignal( UTIL_CHF_MODULE_ID );
|
||||
ChfErrnoCondition;
|
||||
ChfCondition UTIL_F_PACK_OPEN, CHF_FATAL, argv[ 1 ] ChfEnd;
|
||||
ChfSignal();
|
||||
}
|
||||
|
||||
if ( read( d, b, statb.st_size ) != statb.st_size ) {
|
||||
ChfGenerate( CHF_ERRNO_SET, __FILE__, __LINE__, errno, CHF_ERROR );
|
||||
ChfErrnoCondition;
|
||||
|
||||
( void )close( d );
|
||||
|
||||
ChfGenerate( UTIL_CHF_MODULE_ID, __FILE__, __LINE__, UTIL_F_PACK_READ, CHF_FATAL, argv[ 1 ] );
|
||||
ChfSignal( UTIL_CHF_MODULE_ID );
|
||||
ChfCondition UTIL_F_PACK_READ, CHF_FATAL, argv[ 1 ] ChfEnd;
|
||||
ChfSignal();
|
||||
}
|
||||
|
||||
( void )close( d );
|
||||
|
@ -219,8 +257,8 @@ int main( int argc, char* argv[] )
|
|||
|
||||
/* Write */
|
||||
if ( WriteNibblesToFile( nb, statb.st_size, argv[ 2 ] ) ) {
|
||||
ChfGenerate( UTIL_CHF_MODULE_ID, __FILE__, __LINE__, UTIL_F_PACK_WRITE_NIBBLES, CHF_FATAL );
|
||||
ChfSignal( UTIL_CHF_MODULE_ID );
|
||||
ChfCondition UTIL_F_PACK_WRITE_NIBBLES, CHF_FATAL ChfEnd;
|
||||
ChfSignal();
|
||||
}
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
|
|
146
src/romram.c
146
src/romram.c
|
@ -78,12 +78,16 @@
|
|||
|
||||
.- */
|
||||
|
||||
#ifndef lint
|
||||
static char rcs_id[] = "$Id: romram.c,v 4.1 2000/12/11 09:54:19 cibrario Rel $";
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <setjmp.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h> /* access() */
|
||||
|
||||
#include "libChf/src/Chf.h"
|
||||
#include <errno.h>
|
||||
|
||||
#include "config.h"
|
||||
#include "machdep.h"
|
||||
|
@ -92,6 +96,9 @@
|
|||
#include "disk_io.h"
|
||||
#include "debug.h"
|
||||
|
||||
#define CHF_MODULE_ID MOD_CHF_MODULE_ID
|
||||
#include <Chf.h>
|
||||
|
||||
/* 3.2: The rom/ram storage areas are now dynamically allocated in
|
||||
a private struct ModStatus_48. The dynamic allocation is performed during
|
||||
Rom initialization, and the following macro allows us to reuse the
|
||||
|
@ -134,20 +141,17 @@ static struct ModStatus_48* mod_status_48;
|
|||
.- */
|
||||
void RomInit( void )
|
||||
{
|
||||
debug1( MOD_CHF_MODULE_ID, DEBUG_C_TRACE, MOD_I_CALLED, "RomInit" );
|
||||
debug1( DEBUG_C_TRACE, MOD_I_CALLED, "RomInit" );
|
||||
|
||||
if ( ( mod_status_48 = ( struct ModStatus_48* )malloc( sizeof( struct ModStatus_48 ) ) ) == ( struct ModStatus_48* )NULL ) {
|
||||
ChfGenerate( CHF_ERRNO_SET, __FILE__, __LINE__, errno, CHF_ERROR );
|
||||
ChfGenerate( MOD_CHF_MODULE_ID, __FILE__, __LINE__, MOD_F_MOD_STATUS_ALLOC, CHF_FATAL, sizeof( struct ModStatus_48 ) );
|
||||
ChfSignal( MOD_CHF_MODULE_ID );
|
||||
ChfErrnoCondition;
|
||||
ChfCondition MOD_F_MOD_STATUS_ALLOC, CHF_FATAL, sizeof( struct ModStatus_48 ) ChfEnd;
|
||||
ChfSignal();
|
||||
}
|
||||
|
||||
if ( ReadNibblesFromFile( config.rom_file_name, N_ROM_SIZE, mod_status_rom ) ) {
|
||||
// To load 48SX ROM, try again with half the size this time.
|
||||
if ( ReadNibblesFromFile( config.rom_file_name, N_ROM_SIZE / 2, mod_status_rom ) ) {
|
||||
ChfGenerate( MOD_CHF_MODULE_ID, __FILE__, __LINE__, MOD_F_ROM_INIT, CHF_FATAL );
|
||||
ChfSignal( MOD_CHF_MODULE_ID );
|
||||
}
|
||||
if ( ReadNibblesFromFile( args.rom_file_name, N_ROM_SIZE, mod_status_rom ) ) {
|
||||
ChfCondition MOD_F_ROM_INIT, CHF_FATAL ChfEnd;
|
||||
ChfSignal();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -172,7 +176,7 @@ void RomInit( void )
|
|||
1.1, 11-Feb-1998, creation
|
||||
|
||||
.- */
|
||||
void RomSave( void ) { debug1( MOD_CHF_MODULE_ID, DEBUG_C_TRACE, MOD_I_CALLED, "RomSave" ); }
|
||||
void RomSave( void ) { debug1( DEBUG_C_TRACE, MOD_I_CALLED, "RomSave" ); }
|
||||
|
||||
/* .+
|
||||
|
||||
|
@ -197,7 +201,7 @@ void RomSave( void ) { debug1( MOD_CHF_MODULE_ID, DEBUG_C_TRACE, MOD_I_CALLED, "
|
|||
.- */
|
||||
Nibble RomRead( Address rel_address )
|
||||
{
|
||||
debug1( MOD_CHF_MODULE_ID, DEBUG_C_TRACE, MOD_I_CALLED, "RomRead" );
|
||||
debug1( DEBUG_C_TRACE, MOD_I_CALLED, "RomRead" );
|
||||
|
||||
return mod_status_rom[ rel_address ];
|
||||
}
|
||||
|
@ -227,11 +231,10 @@ Nibble RomRead( Address rel_address )
|
|||
.- */
|
||||
void RomWrite( Address rel_address, Nibble datum )
|
||||
{
|
||||
debug1( MOD_CHF_MODULE_ID, DEBUG_C_TRACE, MOD_I_CALLED, "RomWrite" );
|
||||
debug1( DEBUG_C_TRACE, MOD_I_CALLED, "RomWrite" );
|
||||
|
||||
// FIXME: 48gx: saturn48gx-Mid <12>d (src/romram.c,235)-E-Write into ROM A[1B632] D[9]
|
||||
ChfGenerate( MOD_CHF_MODULE_ID, __FILE__, __LINE__, MOD_E_ROM_WRITE, CHF_ERROR, rel_address, datum );
|
||||
ChfSignal( MOD_CHF_MODULE_ID );
|
||||
ChfCondition MOD_E_ROM_WRITE, CHF_ERROR, rel_address, datum ChfEnd;
|
||||
ChfSignal();
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------
|
||||
|
@ -261,11 +264,11 @@ void RomWrite( Address rel_address, Nibble datum )
|
|||
.- */
|
||||
void RamInit( void )
|
||||
{
|
||||
debug1( MOD_CHF_MODULE_ID, DEBUG_C_TRACE, MOD_I_CALLED, "RamInit" );
|
||||
debug1( DEBUG_C_TRACE, MOD_I_CALLED, "RamInit" );
|
||||
|
||||
if ( ReadNibblesFromFile( config.ram_file_name, N_RAM_SIZE, mod_status_ram ) ) {
|
||||
ChfGenerate( MOD_CHF_MODULE_ID, __FILE__, __LINE__, MOD_W_RAM_INIT, CHF_WARNING );
|
||||
ChfSignal( MOD_CHF_MODULE_ID );
|
||||
if ( ReadNibblesFromFile( args.ram_file_name, N_RAM_SIZE, mod_status_ram ) ) {
|
||||
ChfCondition MOD_W_RAM_INIT, CHF_WARNING ChfEnd;
|
||||
ChfSignal();
|
||||
|
||||
( void )memset( mod_status_ram, 0, sizeof( mod_status_ram ) );
|
||||
}
|
||||
|
@ -291,17 +294,17 @@ void RamInit( void )
|
|||
.notes :
|
||||
1.1, 11-Feb-1998, creation
|
||||
2.4, 12-Sep-2000, update
|
||||
- upon failure, added push of ChfGenerate( CHF_ERRNO_SET, __FILE__, __LINE__, errno, CHF_ERROR ) to condition stack.
|
||||
- upon failure, added push of ChfErrnoCondition to condition stack.
|
||||
|
||||
.- */
|
||||
void RamSave( void )
|
||||
{
|
||||
debug1( MOD_CHF_MODULE_ID, DEBUG_C_TRACE, MOD_I_CALLED, "RamSave" );
|
||||
debug1( DEBUG_C_TRACE, MOD_I_CALLED, "RamSave" );
|
||||
|
||||
if ( WriteNibblesToFile( mod_status_ram, N_RAM_SIZE, config.ram_file_name ) ) {
|
||||
ChfGenerate( CHF_ERRNO_SET, __FILE__, __LINE__, errno, CHF_ERROR );
|
||||
ChfGenerate( MOD_CHF_MODULE_ID, __FILE__, __LINE__, MOD_E_RAM_SAVE, CHF_ERROR );
|
||||
ChfSignal( MOD_CHF_MODULE_ID );
|
||||
if ( WriteNibblesToFile( mod_status_ram, N_RAM_SIZE, args.ram_file_name ) ) {
|
||||
ChfErrnoCondition;
|
||||
ChfCondition MOD_E_RAM_SAVE, CHF_ERROR ChfEnd;
|
||||
ChfSignal();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -328,7 +331,7 @@ void RamSave( void )
|
|||
.- */
|
||||
Nibble RamRead( Address rel_address )
|
||||
{
|
||||
debug1( MOD_CHF_MODULE_ID, DEBUG_C_TRACE, MOD_I_CALLED, "RamRead" );
|
||||
debug1( DEBUG_C_TRACE, MOD_I_CALLED, "RamRead" );
|
||||
|
||||
return mod_status_ram[ rel_address ];
|
||||
}
|
||||
|
@ -357,7 +360,7 @@ Nibble RamRead( Address rel_address )
|
|||
.- */
|
||||
void RamWrite( Address rel_address, Nibble datum )
|
||||
{
|
||||
debug1( MOD_CHF_MODULE_ID, DEBUG_C_TRACE, MOD_I_CALLED, "RamWrite" );
|
||||
debug1( DEBUG_C_TRACE, MOD_I_CALLED, "RamWrite" );
|
||||
|
||||
mod_status_ram[ rel_address ] = datum;
|
||||
}
|
||||
|
@ -390,7 +393,7 @@ void RamWrite( Address rel_address, Nibble datum )
|
|||
.- */
|
||||
void Ce1Init( void )
|
||||
{
|
||||
debug1( MOD_CHF_MODULE_ID, DEBUG_C_TRACE, MOD_I_CALLED, "Ce1Init" );
|
||||
debug1( DEBUG_C_TRACE, MOD_I_CALLED, "Ce1Init" );
|
||||
|
||||
/* Check if bank-switcher accelerators are valid; if not, initialize
|
||||
them to a reasonable value (that is, select Port_2 bank 0).
|
||||
|
@ -424,7 +427,7 @@ void Ce1Init( void )
|
|||
.- */
|
||||
void Ce1Save( void )
|
||||
{
|
||||
debug1( MOD_CHF_MODULE_ID, DEBUG_C_TRACE, MOD_I_CALLED, "Ce1Save" );
|
||||
debug1( DEBUG_C_TRACE, MOD_I_CALLED, "Ce1Save" );
|
||||
|
||||
/* Nothing to be done herel the bank-switcher accelerators are saved
|
||||
by the hdw modules
|
||||
|
@ -458,8 +461,8 @@ void Ce1Save( void )
|
|||
.- */
|
||||
Nibble Ce1Read( Address rel_address )
|
||||
{
|
||||
debug1( MOD_CHF_MODULE_ID, DEBUG_C_TRACE, MOD_I_CALLED, "Ce1Read" );
|
||||
debug1( MOD_CHF_MODULE_ID, DEBUG_C_MODULES, MOD_I_BS_ADDRESS, rel_address );
|
||||
debug1( DEBUG_C_TRACE, MOD_I_CALLED, "Ce1Read" );
|
||||
debug1( DEBUG_C_MODULES, MOD_I_BS_ADDRESS, rel_address );
|
||||
|
||||
/* Save the read address into the hdw accelerators.
|
||||
bs_address can be directly or-ed with a relative port address to
|
||||
|
@ -499,10 +502,10 @@ Nibble Ce1Read( Address rel_address )
|
|||
.- */
|
||||
void Ce1Write( Address rel_address, Nibble datum )
|
||||
{
|
||||
debug1( MOD_CHF_MODULE_ID, DEBUG_C_TRACE, MOD_I_CALLED, "Ce1Write" );
|
||||
debug1( DEBUG_C_TRACE, MOD_I_CALLED, "Ce1Write" );
|
||||
|
||||
ChfGenerate( MOD_CHF_MODULE_ID, __FILE__, __LINE__, MOD_E_CE1_WRITE, CHF_ERROR, rel_address, datum );
|
||||
ChfSignal( MOD_CHF_MODULE_ID );
|
||||
ChfCondition MOD_E_CE1_WRITE, CHF_ERROR, rel_address, datum ChfEnd;
|
||||
ChfSignal();
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------
|
||||
|
@ -536,11 +539,11 @@ void Ce2Init( void )
|
|||
{
|
||||
Nibble new_status;
|
||||
|
||||
debug1( MOD_CHF_MODULE_ID, DEBUG_C_TRACE, MOD_I_CALLED, "Ce2Init" );
|
||||
debug1( DEBUG_C_TRACE, MOD_I_CALLED, "Ce2Init" );
|
||||
|
||||
if ( ReadNibblesFromFile( config.port_1_file_name, N_PORT_1_SIZE, mod_status_port_1 ) ) {
|
||||
ChfGenerate( MOD_CHF_MODULE_ID, __FILE__, __LINE__, MOD_W_PORT_1_INIT, CHF_WARNING );
|
||||
ChfSignal( MOD_CHF_MODULE_ID );
|
||||
if ( ReadNibblesFromFile( args.port_1_file_name, N_PORT_1_SIZE, mod_status_port_1 ) ) {
|
||||
ChfCondition MOD_W_PORT_1_INIT, CHF_WARNING ChfEnd;
|
||||
ChfSignal();
|
||||
|
||||
( void )memset( mod_status_port_1, 0, sizeof( mod_status_port_1 ) );
|
||||
|
||||
|
@ -549,14 +552,14 @@ void Ce2Init( void )
|
|||
/* Card present; check write protection */
|
||||
new_status = mod_status_hdw.card_status | CE2_CARD_PRESENT;
|
||||
|
||||
if ( access( config.port_1_file_name, W_OK ) == 0 )
|
||||
if ( access( args.port_1_file_name, W_OK ) == 0 )
|
||||
new_status |= CE2_CARD_WE;
|
||||
else {
|
||||
new_status &= ~CE2_CARD_WE;
|
||||
|
||||
ChfGenerate( CHF_ERRNO_SET, __FILE__, __LINE__, errno, CHF_ERROR );
|
||||
ChfGenerate( MOD_CHF_MODULE_ID, __FILE__, __LINE__, MOD_I_PORT_1_WP, CHF_INFO );
|
||||
ChfSignal( MOD_CHF_MODULE_ID );
|
||||
ChfErrnoCondition;
|
||||
ChfCondition MOD_I_PORT_1_WP, CHF_INFO ChfEnd;
|
||||
ChfSignal();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -595,13 +598,13 @@ void Ce2Init( void )
|
|||
.- */
|
||||
void Ce2Save( void )
|
||||
{
|
||||
debug1( MOD_CHF_MODULE_ID, DEBUG_C_TRACE, MOD_I_CALLED, "Ce2Save" );
|
||||
debug1( DEBUG_C_TRACE, MOD_I_CALLED, "Ce2Save" );
|
||||
|
||||
/* Attempt to save only if port is write-enabled */
|
||||
if ( ( mod_status_hdw.card_status & CE2_CARD_WE ) && WriteNibblesToFile( mod_status_port_1, N_PORT_1_SIZE, config.port_1_file_name ) ) {
|
||||
ChfGenerate( CHF_ERRNO_SET, __FILE__, __LINE__, errno, CHF_ERROR );
|
||||
ChfGenerate( MOD_CHF_MODULE_ID, __FILE__, __LINE__, MOD_E_PORT_1_SAVE, CHF_ERROR );
|
||||
ChfSignal( MOD_CHF_MODULE_ID );
|
||||
if ( ( mod_status_hdw.card_status & CE2_CARD_WE ) && WriteNibblesToFile( mod_status_port_1, N_PORT_1_SIZE, args.port_1_file_name ) ) {
|
||||
ChfErrnoCondition;
|
||||
ChfCondition MOD_E_PORT_1_SAVE, CHF_ERROR ChfEnd;
|
||||
ChfSignal();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -628,7 +631,7 @@ void Ce2Save( void )
|
|||
.- */
|
||||
Nibble Ce2Read( Address rel_address )
|
||||
{
|
||||
debug1( MOD_CHF_MODULE_ID, DEBUG_C_TRACE, MOD_I_CALLED, "Ce2Read" );
|
||||
debug1( DEBUG_C_TRACE, MOD_I_CALLED, "Ce2Read" );
|
||||
|
||||
return mod_status_port_1[ rel_address ];
|
||||
}
|
||||
|
@ -657,7 +660,7 @@ Nibble Ce2Read( Address rel_address )
|
|||
.- */
|
||||
void Ce2Write( Address rel_address, Nibble datum )
|
||||
{
|
||||
debug1( MOD_CHF_MODULE_ID, DEBUG_C_TRACE, MOD_I_CALLED, "Ce2Write" );
|
||||
debug1( DEBUG_C_TRACE, MOD_I_CALLED, "Ce2Write" );
|
||||
|
||||
mod_status_port_1[ rel_address ] = datum;
|
||||
}
|
||||
|
@ -694,12 +697,12 @@ void NCe3Init( void )
|
|||
{
|
||||
Nibble new_status;
|
||||
|
||||
debug1( MOD_CHF_MODULE_ID, DEBUG_C_TRACE, MOD_I_CALLED, "NCe3Init" );
|
||||
debug1( DEBUG_C_TRACE, MOD_I_CALLED, "NCe3Init" );
|
||||
|
||||
#ifdef N_PORT_2_BANK
|
||||
if ( ReadNibblesFromFile( config.port_2_file_name, N_PORT_2_SIZE, mod_status_port_2 ) ) {
|
||||
ChfGenerate( MOD_CHF_MODULE_ID, __FILE__, __LINE__, MOD_W_PORT_2_INIT, CHF_WARNING );
|
||||
ChfSignal( MOD_CHF_MODULE_ID );
|
||||
if ( ReadNibblesFromFile( args.port_2_file_name, N_PORT_2_SIZE, mod_status_port_2 ) ) {
|
||||
ChfCondition MOD_W_PORT_2_INIT, CHF_WARNING ChfEnd;
|
||||
ChfSignal();
|
||||
|
||||
( void )memset( mod_status_port_2, 0, sizeof( mod_status_port_2 ) );
|
||||
|
||||
|
@ -708,14 +711,14 @@ void NCe3Init( void )
|
|||
/* Card present; check write protection */
|
||||
new_status = mod_status_hdw.card_status | NCE3_CARD_PRESENT;
|
||||
|
||||
if ( access( config.port_2_file_name, W_OK ) == 0 )
|
||||
if ( access( args.port_2_file_name, W_OK ) == 0 )
|
||||
new_status |= NCE3_CARD_WE;
|
||||
else {
|
||||
new_status &= ~NCE3_CARD_WE;
|
||||
|
||||
ChfGenerate( CHF_ERRNO_SET, __FILE__, __LINE__, errno, CHF_ERROR );
|
||||
ChfGenerate( MOD_CHF_MODULE_ID, __FILE__, __LINE__, MOD_I_PORT_2_WP, CHF_INFO );
|
||||
ChfSignal( MOD_CHF_MODULE_ID );
|
||||
ChfErrnoCondition;
|
||||
ChfCondition MOD_I_PORT_2_WP, CHF_INFO ChfEnd;
|
||||
ChfSignal();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -759,15 +762,14 @@ void NCe3Init( void )
|
|||
.- */
|
||||
void NCe3Save( void )
|
||||
{
|
||||
debug1( MOD_CHF_MODULE_ID, DEBUG_C_TRACE, MOD_I_CALLED, "NCe3Save" );
|
||||
debug1( DEBUG_C_TRACE, MOD_I_CALLED, "NCe3Save" );
|
||||
|
||||
#ifdef N_PORT_2_BANK
|
||||
/* Attempt to save only if port is write-enabled */
|
||||
if ( ( mod_status_hdw.card_status & NCE3_CARD_WE ) &&
|
||||
WriteNibblesToFile( mod_status_port_2, N_PORT_2_SIZE, config.port_2_file_name ) ) {
|
||||
ChfGenerate( CHF_ERRNO_SET, __FILE__, __LINE__, errno, CHF_ERROR );
|
||||
ChfGenerate( MOD_CHF_MODULE_ID, __FILE__, __LINE__, MOD_E_PORT_2_SAVE, CHF_ERROR );
|
||||
ChfSignal( MOD_CHF_MODULE_ID );
|
||||
if ( ( mod_status_hdw.card_status & NCE3_CARD_WE ) && WriteNibblesToFile( mod_status_port_2, N_PORT_2_SIZE, args.port_2_file_name ) ) {
|
||||
ChfErrnoCondition;
|
||||
ChfCondition MOD_E_PORT_2_SAVE, CHF_ERROR ChfEnd;
|
||||
ChfSignal();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
@ -797,14 +799,14 @@ void NCe3Save( void )
|
|||
.- */
|
||||
Nibble NCe3Read( Address rel_address )
|
||||
{
|
||||
debug1( MOD_CHF_MODULE_ID, DEBUG_C_TRACE, MOD_I_CALLED, "NCe3Read" );
|
||||
debug1( DEBUG_C_TRACE, MOD_I_CALLED, "NCe3Read" );
|
||||
|
||||
#ifdef N_PORT_2_BANK
|
||||
return mod_status_port_2[ rel_address | mod_status_hdw.accel.a48.bs_address ];
|
||||
|
||||
#else
|
||||
ChfGenerate( MOD_CHF_MODULE_ID, __FILE__, __LINE__, MOD_E_NCE3_READ, CHF_ERROR, rel_address );
|
||||
ChfSignal( MOD_CHF_MODULE_ID );
|
||||
ChfCondition MOD_E_NCE3_READ, CHF_ERROR, rel_address ChfEnd;
|
||||
ChfSignal();
|
||||
return ( Nibble )0;
|
||||
|
||||
#endif
|
||||
|
@ -837,14 +839,14 @@ Nibble NCe3Read( Address rel_address )
|
|||
.- */
|
||||
void NCe3Write( Address rel_address, Nibble datum )
|
||||
{
|
||||
debug1( MOD_CHF_MODULE_ID, DEBUG_C_TRACE, MOD_I_CALLED, "NCe3Write" );
|
||||
debug1( DEBUG_C_TRACE, MOD_I_CALLED, "NCe3Write" );
|
||||
|
||||
#ifdef N_PORT_2_BANK
|
||||
mod_status_port_2[ rel_address | mod_status_hdw.accel.a48.bs_address ] = datum;
|
||||
|
||||
#else
|
||||
ChfGenerate( MOD_CHF_MODULE_ID, __FILE__, __LINE__, MOD_E_NCE3_WRITE, CHF_ERROR, rel_address, datum );
|
||||
ChfSignal( MOD_CHF_MODULE_ID );
|
||||
ChfCondition MOD_E_NCE3_WRITE, CHF_ERROR, rel_address, datum ChfEnd;
|
||||
ChfSignal();
|
||||
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -90,12 +90,16 @@
|
|||
|
||||
.- */
|
||||
|
||||
#ifndef lint
|
||||
static char rcs_id[] = "$Id: romram49.c,v 4.1 2000/12/11 09:54:19 cibrario Rel $";
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <setjmp.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h> /* access() */
|
||||
|
||||
#include "libChf/src/Chf.h"
|
||||
#include <errno.h>
|
||||
|
||||
#include "config.h"
|
||||
#include "machdep.h"
|
||||
|
@ -105,6 +109,9 @@
|
|||
#include "disk_io.h"
|
||||
#include "debug.h"
|
||||
|
||||
#define CHF_MODULE_ID MOD_CHF_MODULE_ID
|
||||
#include <Chf.h>
|
||||
|
||||
#define FLASH_VIEW_SELECTOR 0x40000
|
||||
#define FLASH_BANK_MASK 0x3FFFF
|
||||
|
||||
|
@ -149,17 +156,17 @@ struct ModStatus_49* mod_status_49;
|
|||
.- */
|
||||
void RomInit49( void )
|
||||
{
|
||||
debug1( MOD_CHF_MODULE_ID, DEBUG_C_TRACE, MOD_I_CALLED, "RomInit49" );
|
||||
debug1( DEBUG_C_TRACE, MOD_I_CALLED, "RomInit49" );
|
||||
|
||||
if ( ( mod_status_49 = ( struct ModStatus_49* )malloc( sizeof( struct ModStatus_49 ) ) ) == ( struct ModStatus_49* )NULL ) {
|
||||
ChfGenerate( CHF_ERRNO_SET, __FILE__, __LINE__, errno, CHF_ERROR );
|
||||
ChfGenerate( MOD_CHF_MODULE_ID, __FILE__, __LINE__, MOD_F_MOD_STATUS_ALLOC, CHF_FATAL, sizeof( struct ModStatus_49 ) );
|
||||
ChfSignal( MOD_CHF_MODULE_ID );
|
||||
ChfErrnoCondition;
|
||||
ChfCondition MOD_F_MOD_STATUS_ALLOC, CHF_FATAL, sizeof( struct ModStatus_49 ) ChfEnd;
|
||||
ChfSignal();
|
||||
}
|
||||
|
||||
if ( ReadNibblesFromFile( config.rom_file_name, N_FLASH_SIZE_49, mod_status_49->flash ) ) {
|
||||
ChfGenerate( MOD_CHF_MODULE_ID, __FILE__, __LINE__, MOD_F_ROM_INIT, CHF_FATAL );
|
||||
ChfSignal( MOD_CHF_MODULE_ID );
|
||||
if ( ReadNibblesFromFile( args.rom_file_name, N_FLASH_SIZE_49, mod_status_49->flash ) ) {
|
||||
ChfCondition MOD_F_ROM_INIT, CHF_FATAL ChfEnd;
|
||||
ChfSignal();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -187,12 +194,12 @@ void RomInit49( void )
|
|||
.- */
|
||||
void RomSave49( void )
|
||||
{
|
||||
debug1( MOD_CHF_MODULE_ID, DEBUG_C_TRACE, MOD_I_CALLED, "RomSave49" );
|
||||
debug1( DEBUG_C_TRACE, MOD_I_CALLED, "RomSave49" );
|
||||
|
||||
if ( WriteNibblesToFile( mod_status_49->flash, N_FLASH_SIZE_49, config.rom_file_name ) ) {
|
||||
ChfGenerate( CHF_ERRNO_SET, __FILE__, __LINE__, errno, CHF_ERROR );
|
||||
ChfGenerate( MOD_CHF_MODULE_ID, __FILE__, __LINE__, MOD_E_ROM_SAVE, CHF_ERROR );
|
||||
ChfSignal( MOD_CHF_MODULE_ID );
|
||||
if ( WriteNibblesToFile( mod_status_49->flash, N_FLASH_SIZE_49, args.rom_file_name ) ) {
|
||||
ChfErrnoCondition;
|
||||
ChfCondition MOD_E_ROM_SAVE, CHF_ERROR ChfEnd;
|
||||
ChfSignal();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -221,7 +228,7 @@ Nibble RomRead49( Address rel_address )
|
|||
{
|
||||
register XAddress view;
|
||||
|
||||
debug1( MOD_CHF_MODULE_ID, DEBUG_C_TRACE, MOD_I_CALLED, "RomRead49" );
|
||||
debug1( DEBUG_C_TRACE, MOD_I_CALLED, "RomRead49" );
|
||||
|
||||
view = mod_status.hdw.accel.a49.view[ ( rel_address & FLASH_VIEW_SELECTOR ) != 0 ];
|
||||
|
||||
|
@ -258,7 +265,7 @@ Nibble RomRead49( Address rel_address )
|
|||
.- */
|
||||
void RomWrite49( Address rel_address, Nibble datum )
|
||||
{
|
||||
debug1( MOD_CHF_MODULE_ID, DEBUG_C_TRACE, MOD_I_CALLED, "RomWrite49" );
|
||||
debug1( DEBUG_C_TRACE, MOD_I_CALLED, "RomWrite49" );
|
||||
|
||||
/* Ignore write cycles through ROM controller; HP49 ROM 1.19-4
|
||||
can do this when to ON key is pressed.
|
||||
|
@ -292,11 +299,11 @@ void RomWrite49( Address rel_address, Nibble datum )
|
|||
.- */
|
||||
void RamInit49( void )
|
||||
{
|
||||
debug1( MOD_CHF_MODULE_ID, DEBUG_C_TRACE, MOD_I_CALLED, "RamInit49" );
|
||||
debug1( DEBUG_C_TRACE, MOD_I_CALLED, "RamInit49" );
|
||||
|
||||
if ( ReadNibblesFromFile( config.ram_file_name, N_RAM_SIZE_49, mod_status_49->ram ) ) {
|
||||
ChfGenerate( MOD_CHF_MODULE_ID, __FILE__, __LINE__, MOD_W_RAM_INIT, CHF_WARNING );
|
||||
ChfSignal( MOD_CHF_MODULE_ID );
|
||||
if ( ReadNibblesFromFile( args.ram_file_name, N_RAM_SIZE_49, mod_status_49->ram ) ) {
|
||||
ChfCondition MOD_W_RAM_INIT, CHF_WARNING ChfEnd;
|
||||
ChfSignal();
|
||||
|
||||
( void )memset( mod_status_49->ram, 0, sizeof( mod_status_49->ram ) );
|
||||
}
|
||||
|
@ -325,12 +332,12 @@ void RamInit49( void )
|
|||
.- */
|
||||
void RamSave49( void )
|
||||
{
|
||||
debug1( MOD_CHF_MODULE_ID, DEBUG_C_TRACE, MOD_I_CALLED, "RamSave49" );
|
||||
debug1( DEBUG_C_TRACE, MOD_I_CALLED, "RamSave49" );
|
||||
|
||||
if ( WriteNibblesToFile( mod_status_49->ram, N_RAM_SIZE_49, config.ram_file_name ) ) {
|
||||
ChfGenerate( CHF_ERRNO_SET, __FILE__, __LINE__, errno, CHF_ERROR );
|
||||
ChfGenerate( MOD_CHF_MODULE_ID, __FILE__, __LINE__, MOD_E_RAM_SAVE, CHF_ERROR );
|
||||
ChfSignal( MOD_CHF_MODULE_ID );
|
||||
if ( WriteNibblesToFile( mod_status_49->ram, N_RAM_SIZE_49, args.ram_file_name ) ) {
|
||||
ChfErrnoCondition;
|
||||
ChfCondition MOD_E_RAM_SAVE, CHF_ERROR ChfEnd;
|
||||
ChfSignal();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -357,7 +364,7 @@ void RamSave49( void )
|
|||
.- */
|
||||
Nibble RamRead49( Address rel_address )
|
||||
{
|
||||
debug1( MOD_CHF_MODULE_ID, DEBUG_C_TRACE, MOD_I_CALLED, "RamRead49" );
|
||||
debug1( DEBUG_C_TRACE, MOD_I_CALLED, "RamRead49" );
|
||||
|
||||
return mod_status_49->ram[ rel_address ];
|
||||
}
|
||||
|
@ -386,7 +393,7 @@ Nibble RamRead49( Address rel_address )
|
|||
.- */
|
||||
void RamWrite49( Address rel_address, Nibble datum )
|
||||
{
|
||||
debug1( MOD_CHF_MODULE_ID, DEBUG_C_TRACE, MOD_I_CALLED, "RamWrite49" );
|
||||
debug1( DEBUG_C_TRACE, MOD_I_CALLED, "RamWrite49" );
|
||||
|
||||
mod_status_49->ram[ rel_address ] = datum;
|
||||
}
|
||||
|
@ -418,7 +425,7 @@ void RamWrite49( Address rel_address, Nibble datum )
|
|||
.- */
|
||||
void Ce1Init49( void )
|
||||
{
|
||||
debug1( MOD_CHF_MODULE_ID, DEBUG_C_TRACE, MOD_I_CALLED, "Ce1Init49" );
|
||||
debug1( DEBUG_C_TRACE, MOD_I_CALLED, "Ce1Init49" );
|
||||
|
||||
/* Check if bank-switcher accelerators are valid; if not, initialize
|
||||
them to a reasonable value (that is, select Flash Rom bank 0 for
|
||||
|
@ -452,7 +459,7 @@ void Ce1Init49( void )
|
|||
.- */
|
||||
void Ce1Save49( void )
|
||||
{
|
||||
debug1( MOD_CHF_MODULE_ID, DEBUG_C_TRACE, MOD_I_CALLED, "Ce1Save49" );
|
||||
debug1( DEBUG_C_TRACE, MOD_I_CALLED, "Ce1Save49" );
|
||||
|
||||
/* Nothing to be done here; the bank-switcher accelerators are saved
|
||||
by the hdw modules
|
||||
|
@ -497,8 +504,8 @@ void Ce1Save49( void )
|
|||
.- */
|
||||
Nibble Ce1Read49( Address rel_address )
|
||||
{
|
||||
debug1( MOD_CHF_MODULE_ID, DEBUG_C_TRACE, MOD_I_CALLED, "Ce1Read49" );
|
||||
debug1( MOD_CHF_MODULE_ID, DEBUG_C_MODULES, MOD_I_BS_ADDRESS, rel_address );
|
||||
debug1( DEBUG_C_TRACE, MOD_I_CALLED, "Ce1Read49" );
|
||||
debug1( DEBUG_C_MODULES, MOD_I_BS_ADDRESS, rel_address );
|
||||
|
||||
/* Save the ROM view base addresses address into the hdw accelerators.
|
||||
view[] can be directly or-ed with a relative port address to
|
||||
|
@ -537,8 +544,8 @@ Nibble Ce1Read49( Address rel_address )
|
|||
.- */
|
||||
void Ce1Write49( Address rel_address, Nibble datum )
|
||||
{
|
||||
debug1( MOD_CHF_MODULE_ID, DEBUG_C_TRACE, MOD_I_CALLED, "Ce1Write49" );
|
||||
debug1( MOD_CHF_MODULE_ID, DEBUG_C_MODULES, MOD_I_BS_ADDRESS, rel_address );
|
||||
debug1( DEBUG_C_TRACE, MOD_I_CALLED, "Ce1Write49" );
|
||||
debug1( DEBUG_C_MODULES, MOD_I_BS_ADDRESS, rel_address );
|
||||
|
||||
/* Save the ROM view base addresses address into the hdw accelerators.
|
||||
view[] can be directly or-ed with a relative port address to
|
||||
|
@ -577,7 +584,7 @@ void Ce1Write49( Address rel_address, Nibble datum )
|
|||
.- */
|
||||
void Ce2Init49( void )
|
||||
{
|
||||
debug1( MOD_CHF_MODULE_ID, DEBUG_C_TRACE, MOD_I_CALLED, "Ce2Init49" );
|
||||
debug1( DEBUG_C_TRACE, MOD_I_CALLED, "Ce2Init49" );
|
||||
|
||||
/* Set base of ce2 area */
|
||||
mod_status_49->ce2 = mod_status_49->ram + CE2_RAM_OFFSET;
|
||||
|
@ -616,7 +623,7 @@ void Ce2Init49( void )
|
|||
.- */
|
||||
void Ce2Save49( void )
|
||||
{
|
||||
debug1( MOD_CHF_MODULE_ID, DEBUG_C_TRACE, MOD_I_CALLED, "Ce2Save49" );
|
||||
debug1( DEBUG_C_TRACE, MOD_I_CALLED, "Ce2Save49" );
|
||||
|
||||
/* Do nothing; the whole RAM is saved by RamSave49() */
|
||||
}
|
||||
|
@ -643,7 +650,7 @@ void Ce2Save49( void )
|
|||
.- */
|
||||
Nibble Ce2Read49( Address rel_address )
|
||||
{
|
||||
debug1( MOD_CHF_MODULE_ID, DEBUG_C_TRACE, MOD_I_CALLED, "Ce2Read49" );
|
||||
debug1( DEBUG_C_TRACE, MOD_I_CALLED, "Ce2Read49" );
|
||||
|
||||
return mod_status_49->ce2[ rel_address ];
|
||||
}
|
||||
|
@ -671,7 +678,7 @@ Nibble Ce2Read49( Address rel_address )
|
|||
.- */
|
||||
void Ce2Write49( Address rel_address, Nibble datum )
|
||||
{
|
||||
debug1( MOD_CHF_MODULE_ID, DEBUG_C_TRACE, MOD_I_CALLED, "Ce2Write49" );
|
||||
debug1( DEBUG_C_TRACE, MOD_I_CALLED, "Ce2Write49" );
|
||||
|
||||
mod_status_49->ce2[ rel_address ] = datum;
|
||||
}
|
||||
|
@ -706,7 +713,7 @@ void Ce2Write49( Address rel_address, Nibble datum )
|
|||
.- */
|
||||
void NCe3Init49( void )
|
||||
{
|
||||
debug1( MOD_CHF_MODULE_ID, DEBUG_C_TRACE, MOD_I_CALLED, "NCe3Init49" );
|
||||
debug1( DEBUG_C_TRACE, MOD_I_CALLED, "NCe3Init49" );
|
||||
|
||||
/* Set base of nce3 area */
|
||||
mod_status_49->nce3 = mod_status_49->ram + NCE3_RAM_OFFSET;
|
||||
|
@ -745,7 +752,7 @@ void NCe3Init49( void )
|
|||
.- */
|
||||
void NCe3Save49( void )
|
||||
{
|
||||
debug1( MOD_CHF_MODULE_ID, DEBUG_C_TRACE, MOD_I_CALLED, "NCe3Save49" );
|
||||
debug1( DEBUG_C_TRACE, MOD_I_CALLED, "NCe3Save49" );
|
||||
|
||||
/* Do nothing; the whole RAM is saved by RamSave49() */
|
||||
}
|
||||
|
@ -782,7 +789,7 @@ void NCe3Save49( void )
|
|||
.- */
|
||||
Nibble NCe3Read49( Address rel_address )
|
||||
{
|
||||
debug1( MOD_CHF_MODULE_ID, DEBUG_C_TRACE, MOD_I_CALLED, "NCe3Read49" );
|
||||
debug1( DEBUG_C_TRACE, MOD_I_CALLED, "NCe3Read49" );
|
||||
|
||||
return ( mod_status.hdw.hdw[ HDW_LCR_OFFSET ] & LCR_LED )
|
||||
? FlashRead49( mod_status.hdw.accel.a49.view[ ( rel_address & FLASH_VIEW_SELECTOR ) != 0 ] |
|
||||
|
@ -824,7 +831,7 @@ Nibble NCe3Read49( Address rel_address )
|
|||
.- */
|
||||
void NCe3Write49( Address rel_address, Nibble datum )
|
||||
{
|
||||
debug1( MOD_CHF_MODULE_ID, DEBUG_C_TRACE, MOD_I_CALLED, "NCe3Write49" );
|
||||
debug1( DEBUG_C_TRACE, MOD_I_CALLED, "NCe3Write49" );
|
||||
|
||||
if ( mod_status.hdw.hdw[ HDW_LCR_OFFSET ] & LCR_LED )
|
||||
FlashWrite49( mod_status.hdw.accel.a49.view[ ( rel_address & FLASH_VIEW_SELECTOR ) != 0 ] | ( rel_address & FLASH_BANK_MASK ),
|
||||
|
|
192
src/serial.c
192
src/serial.c
|
@ -79,13 +79,13 @@
|
|||
|
||||
Revision 3.2 2000/09/22 14:34:55 cibrario
|
||||
Implemented preliminary support of HP49 hw architecture:
|
||||
- simplified handling of
|
||||
- Conditionally (#ifdef HP49_SUPPORT) simplified handling of
|
||||
RCS_RBZ and RCS_RBF bits of RCS register.
|
||||
- disabled local ECHO on master
|
||||
- Conditionally (#ifdef HP49_SUPPORT) disabled local ECHO on master
|
||||
pty when USE_OPENPTY is in effect; this avoid spurious rx
|
||||
when no process is connected to the slave pty yet. Apparently,
|
||||
USE_STREAMSPTY does not suffer from this.
|
||||
- removed warning message
|
||||
- Conditionally (#ifdef HP49_SUPPORT) removed warning message
|
||||
when reading from an empty RRB.
|
||||
|
||||
* Revision 2.6 2000/09/15 09:23:02 cibrario
|
||||
|
@ -100,18 +100,24 @@
|
|||
|
||||
.- */
|
||||
|
||||
#ifndef lint
|
||||
static char rcs_id[] = "$Id: serial.c,v 4.1 2000/12/11 09:54:19 cibrario Rel $";
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <setjmp.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "libChf/src/Chf.h"
|
||||
|
||||
#include "config.h"
|
||||
#include "machdep.h"
|
||||
#include "cpu.h"
|
||||
#include "serial.h" /* 2.5: Serial port emulation module */
|
||||
#include "debug.h"
|
||||
|
||||
#define CHF_MODULE_ID SERIAL_CHF_MODULE_ID
|
||||
#include <Chf.h>
|
||||
|
||||
/*---------------------------------------------------------------------------
|
||||
Determine pty implementation
|
||||
|
||||
|
@ -415,7 +421,7 @@ static int slave_pty; /* File descriptor of pty's slave side */
|
|||
- if the receiver ring buffer is empty,
|
||||
RCS_RBZ and RCS_RBF are both reset
|
||||
|
||||
3.2: the RCS_RBZ bit is
|
||||
3.2: If HP49_SUPPORT is enabled, the RCS_RBZ bit is
|
||||
always left clear and only RCS_RBF is updated;
|
||||
this is simpler and works well on the 48, too.
|
||||
|
||||
|
@ -435,12 +441,24 @@ static int slave_pty; /* File descriptor of pty's slave side */
|
|||
( ( ioc & IOC_ERBZ ) && ( rcs & RCS_RBZ ) ) ) ) \
|
||||
CpuIntRequest( INT_REQUEST_IRQ )
|
||||
|
||||
#define UpdateRCS \
|
||||
if ( FullSlots( rrb ) > 0 ) { \
|
||||
rcs |= RCS_RBF; \
|
||||
} else { \
|
||||
rcs &= ~( RCS_RBF ); \
|
||||
}
|
||||
#ifdef HP49_SUPPORT
|
||||
# define UpdateRCS \
|
||||
if ( FullSlots( rrb ) > 0 ) { \
|
||||
rcs |= RCS_RBF; \
|
||||
} else { \
|
||||
rcs &= ~( RCS_RBF ); \
|
||||
}
|
||||
#else
|
||||
# define UpdateRCS \
|
||||
if ( FullSlots( rrb ) > 1 ) { \
|
||||
rcs |= ( RCS_RBF | RCS_RBZ ); \
|
||||
} else if ( FullSlots( rrb ) > 0 ) { \
|
||||
rcs |= RCS_RBF; \
|
||||
rcs &= ~RCS_RBZ; \
|
||||
} else { \
|
||||
rcs &= ~( RCS_RBF | RCS_RBZ ); \
|
||||
}
|
||||
#endif
|
||||
|
||||
#define UpdateTCS \
|
||||
if ( EmptySlots( trb ) > 1 ) { \
|
||||
|
@ -494,7 +512,7 @@ static int slave_pty; /* File descriptor of pty's slave side */
|
|||
2.6, 15-Sep-2000, update
|
||||
- implemented USE_STREAMSPTY
|
||||
3.2, 22-Sep-2000, update
|
||||
- disabled local ECHO on master
|
||||
- conditionally (#ifdef HP49_SUPPORT) disabled local ECHO on master
|
||||
pty when USE_OPENPTY is in effect; this avoid spurious rx
|
||||
when no process is connected to the slave pty yet.
|
||||
3.16, 16-Nov-2000, update
|
||||
|
@ -505,7 +523,7 @@ static int slave_pty; /* File descriptor of pty's slave side */
|
|||
.- */
|
||||
const char* SerialInit( void )
|
||||
{
|
||||
debug1( SERIAL_CHF_MODULE_ID, DEBUG_C_TRACE, SERIAL_I_CALLED, "SerialInit" );
|
||||
debug1( DEBUG_C_TRACE, SERIAL_I_CALLED, "SerialInit" );
|
||||
|
||||
/* Initialize ring buffers */
|
||||
InitRingBuffer( rrb );
|
||||
|
@ -519,9 +537,9 @@ const char* SerialInit( void )
|
|||
if ( openpty( &master_pty, &slave_pty, NULL, NULL, NULL ) ) {
|
||||
pty_name = ( char* )NULL;
|
||||
|
||||
ChfGenerate( CHF_ERRNO_SET, __FILE__, __LINE__, errno, CHF_ERROR );
|
||||
ChfGenerate( SERIAL_CHF_MODULE_ID, __FILE__, __LINE__, SERIAL_F_OPENPTY, CHF_FATAL );
|
||||
ChfSignal( SERIAL_CHF_MODULE_ID );
|
||||
ChfErrnoCondition;
|
||||
ChfCondition SERIAL_F_OPENPTY, CHF_FATAL ChfEnd;
|
||||
ChfSignal();
|
||||
} else {
|
||||
int cur_flags;
|
||||
|
||||
|
@ -532,9 +550,9 @@ const char* SerialInit( void )
|
|||
|
||||
/* Set O_NONBLOCK on master_pty */
|
||||
if ( ( cur_flags = fcntl( master_pty, F_GETFL, 0 ) ) < 0 || fcntl( master_pty, F_SETFL, cur_flags | O_NONBLOCK ) < 0 ) {
|
||||
ChfGenerate( CHF_ERRNO_SET, __FILE__, __LINE__, errno, CHF_ERROR );
|
||||
ChfGenerate( SERIAL_CHF_MODULE_ID, __FILE__, __LINE__, SERIAL_F_FCNTL, CHF_FATAL );
|
||||
ChfSignal( SERIAL_CHF_MODULE_ID );
|
||||
ChfErrnoCondition;
|
||||
ChfCondition SERIAL_F_FCNTL, CHF_FATAL ChfEnd;
|
||||
ChfSignal();
|
||||
}
|
||||
}
|
||||
# endif
|
||||
|
@ -544,30 +562,30 @@ const char* SerialInit( void )
|
|||
if ( ( master_pty = open( PTY_MASTER, O_RDWR | O_NONBLOCK ) ) < 0 ) {
|
||||
pty_name = ( char* )NULL;
|
||||
|
||||
ChfGenerate( CHF_ERRNO_SET, __FILE__, __LINE__, errno, CHF_ERROR );
|
||||
ChfGenerate( SERIAL_CHF_MODULE_ID, __FILE__, __LINE__, SERIAL_F_OPEN_MASTER, CHF_FATAL, PTY_MASTER );
|
||||
ChfSignal( SERIAL_CHF_MODULE_ID );
|
||||
ChfErrnoCondition;
|
||||
ChfCondition SERIAL_F_OPEN_MASTER, CHF_FATAL, PTY_MASTER ChfEnd;
|
||||
ChfSignal();
|
||||
} else {
|
||||
/* Master side opened ok; change permissions and unlock slave side */
|
||||
|
||||
if ( grantpt( master_pty ) < 0 ) {
|
||||
/* close() may modify errno; save it first */
|
||||
ChfGenerate( CHF_ERRNO_SET, __FILE__, __LINE__, errno, CHF_ERROR );
|
||||
ChfErrnoCondition;
|
||||
|
||||
( void )close( master_pty );
|
||||
|
||||
ChfGenerate( SERIAL_CHF_MODULE_ID, __FILE__, __LINE__, SERIAL_F_GRANTPT, CHF_FATAL );
|
||||
ChfSignal( SERIAL_CHF_MODULE_ID );
|
||||
ChfCondition SERIAL_F_GRANTPT, CHF_FATAL ChfEnd;
|
||||
ChfSignal();
|
||||
}
|
||||
|
||||
if ( unlockpt( master_pty ) < 0 ) {
|
||||
/* close() may modify errno; save it first */
|
||||
ChfGenerate( CHF_ERRNO_SET, __FILE__, __LINE__, errno, CHF_ERROR );
|
||||
ChfErrnoCondition;
|
||||
|
||||
( void )close( master_pty );
|
||||
|
||||
ChfGenerate( SERIAL_CHF_MODULE_ID, __FILE__, __LINE__, SERIAL_F_UNLOCKPT, CHF_FATAL );
|
||||
ChfSignal( SERIAL_CHF_MODULE_ID );
|
||||
ChfCondition SERIAL_F_UNLOCKPT, CHF_FATAL ChfEnd;
|
||||
ChfSignal();
|
||||
}
|
||||
|
||||
/* Get name of slave side; this must be done on the *master* side */
|
||||
|
@ -576,12 +594,12 @@ const char* SerialInit( void )
|
|||
/* Open slave in nonblocking mode */
|
||||
if ( ( slave_pty = open( pty_name, O_RDWR | O_NONBLOCK ) ) < 0 ) {
|
||||
/* close() may modify errno; save it first */
|
||||
ChfGenerate( CHF_ERRNO_SET, __FILE__, __LINE__, errno, CHF_ERROR );
|
||||
ChfErrnoCondition;
|
||||
|
||||
( void )close( master_pty );
|
||||
|
||||
ChfGenerate( SERIAL_CHF_MODULE_ID, __FILE__, __LINE__, SERIAL_F_OPEN_SLAVE, CHF_FATAL, pty_name );
|
||||
ChfSignal( SERIAL_CHF_MODULE_ID );
|
||||
ChfCondition SERIAL_F_OPEN_SLAVE, CHF_FATAL, pty_name ChfEnd;
|
||||
ChfSignal();
|
||||
}
|
||||
|
||||
/* Remember: close the pty before exiting */
|
||||
|
@ -592,19 +610,20 @@ const char* SerialInit( void )
|
|||
indistinguishable from a real terminal.
|
||||
*/
|
||||
if ( ioctl( slave_pty, I_PUSH, "ptem" ) == -1 ) {
|
||||
ChfGenerate( CHF_ERRNO_SET, __FILE__, __LINE__, errno, CHF_ERROR );
|
||||
ChfGenerate( SERIAL_CHF_MODULE_ID, __FILE__, __LINE__, SERIAL_F_PUSH, CHF_FATAL, "ptem" );
|
||||
ChfSignal( SERIAL_CHF_MODULE_ID );
|
||||
ChfErrnoCondition;
|
||||
ChfCondition SERIAL_F_PUSH, CHF_FATAL, "ptem" ChfEnd;
|
||||
ChfSignal();
|
||||
}
|
||||
|
||||
if ( ioctl( slave_pty, I_PUSH, "ldterm" ) == -1 ) {
|
||||
ChfGenerate( CHF_ERRNO_SET, __FILE__, __LINE__, errno, CHF_ERROR );
|
||||
ChfGenerate( SERIAL_CHF_MODULE_ID, __FILE__, __LINE__, SERIAL_F_PUSH, CHF_FATAL, "ldterm" );
|
||||
ChfSignal( SERIAL_CHF_MODULE_ID );
|
||||
ChfErrnoCondition;
|
||||
ChfCondition SERIAL_F_PUSH, CHF_FATAL, "ldterm" ChfEnd;
|
||||
ChfSignal();
|
||||
}
|
||||
}
|
||||
# endif
|
||||
|
||||
# ifdef HP49_SUPPORT
|
||||
/* 3.17: Ensure that the pty is fully trasparent by default.
|
||||
This allows to use most non-terminal-aware applications (such as od)
|
||||
on the pty directly.
|
||||
|
@ -613,9 +632,9 @@ const char* SerialInit( void )
|
|||
struct termios tios;
|
||||
|
||||
if ( tcgetattr( slave_pty, &tios ) ) {
|
||||
ChfGenerate( CHF_ERRNO_SET, __FILE__, __LINE__, errno, CHF_ERROR );
|
||||
ChfGenerate( SERIAL_CHF_MODULE_ID, __FILE__, __LINE__, SERIAL_F_TCGETATTR, CHF_FATAL );
|
||||
ChfSignal( SERIAL_CHF_MODULE_ID );
|
||||
ChfErrnoCondition;
|
||||
ChfCondition SERIAL_F_TCGETATTR, CHF_FATAL ChfEnd;
|
||||
ChfSignal();
|
||||
}
|
||||
|
||||
tios.c_iflag &= ~( BRKINT | IGNPAR | PARMRK | INPCK | ISTRIP | INLCR | IGNCR | ICRNL | IUCLC | IXON | IXANY | IXOFF | IMAXBEL );
|
||||
|
@ -638,24 +657,23 @@ const char* SerialInit( void )
|
|||
tios.c_cc[ VTIME ] = 0;
|
||||
|
||||
if ( tcsetattr( slave_pty, TCSANOW, &tios ) ) {
|
||||
ChfGenerate( CHF_ERRNO_SET, __FILE__, __LINE__, errno, CHF_ERROR );
|
||||
ChfGenerate( SERIAL_CHF_MODULE_ID, __FILE__, __LINE__, SERIAL_F_TCSETATTR, CHF_FATAL );
|
||||
ChfSignal( SERIAL_CHF_MODULE_ID );
|
||||
ChfErrnoCondition;
|
||||
ChfCondition SERIAL_F_TCSETATTR, CHF_FATAL ChfEnd;
|
||||
ChfSignal();
|
||||
}
|
||||
}
|
||||
# endif
|
||||
|
||||
/* Publish pty name */
|
||||
if ( config.verbose ) {
|
||||
ChfGenerate( SERIAL_CHF_MODULE_ID, __FILE__, __LINE__, SERIAL_I_PTY_NAME, CHF_INFO, pty_name );
|
||||
ChfSignal( SERIAL_CHF_MODULE_ID );
|
||||
}
|
||||
ChfCondition SERIAL_I_PTY_NAME, CHF_INFO, pty_name ChfEnd;
|
||||
ChfSignal();
|
||||
|
||||
#else
|
||||
/* Dummy implementation; do nothing */
|
||||
pty_name = "";
|
||||
|
||||
ChfGenerate( SERIAL_CHF_MODULE_ID, __FILE__, __LINE__, SERIAL_W_NOPTY, CHF_WARNING );
|
||||
ChfSignal( SERIAL_CHF_MODULE_ID );
|
||||
ChfCondition SERIAL_W_NOPTY, CHF_WARNING ChfEnd;
|
||||
ChfSignal();
|
||||
#endif
|
||||
|
||||
return pty_name;
|
||||
|
@ -691,12 +709,12 @@ const char* SerialInit( void )
|
|||
.- */
|
||||
void SerialClose( void )
|
||||
{
|
||||
debug1( SERIAL_CHF_MODULE_ID, DEBUG_C_TRACE, SERIAL_I_CALLED, "SerialClose" );
|
||||
debug1( DEBUG_C_TRACE, SERIAL_I_CALLED, "SerialClose" );
|
||||
|
||||
if ( close( slave_pty ) || close( master_pty ) ) {
|
||||
ChfGenerate( CHF_ERRNO_SET, __FILE__, __LINE__, errno, CHF_ERROR );
|
||||
ChfGenerate( SERIAL_CHF_MODULE_ID, __FILE__, __LINE__, SERIAL_E_PTY_CLOSE, CHF_ERROR );
|
||||
ChfSignal( SERIAL_CHF_MODULE_ID );
|
||||
ChfErrnoCondition;
|
||||
ChfCondition SERIAL_E_PTY_CLOSE, CHF_ERROR ChfEnd;
|
||||
ChfSignal();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -728,7 +746,7 @@ void SerialClose( void )
|
|||
.- */
|
||||
const char* SerialPtyName( void )
|
||||
{
|
||||
debug1( SERIAL_CHF_MODULE_ID, DEBUG_C_TRACE, SERIAL_I_CALLED, "SerialPtyName" );
|
||||
debug1( DEBUG_C_TRACE, SERIAL_I_CALLED, "SerialPtyName" );
|
||||
|
||||
return pty_name;
|
||||
}
|
||||
|
@ -760,8 +778,8 @@ const char* SerialPtyName( void )
|
|||
.- */
|
||||
Nibble Serial_IOC_Read( void )
|
||||
{
|
||||
debug1( SERIAL_CHF_MODULE_ID, DEBUG_C_TRACE, SERIAL_I_CALLED, "Serial_IOC_Read" );
|
||||
debug2( SERIAL_CHF_MODULE_ID, DEBUG_C_SERIAL, SERIAL_I_READ, "IOC", ioc );
|
||||
debug1( DEBUG_C_TRACE, SERIAL_I_CALLED, "Serial_IOC_Read" );
|
||||
debug2( DEBUG_C_SERIAL, SERIAL_I_READ, "IOC", ioc );
|
||||
|
||||
return ioc;
|
||||
}
|
||||
|
@ -793,8 +811,8 @@ Nibble Serial_IOC_Read( void )
|
|||
.- */
|
||||
Nibble Serial_RCS_Read( void )
|
||||
{
|
||||
debug1( SERIAL_CHF_MODULE_ID, DEBUG_C_TRACE, SERIAL_I_CALLED, "Serial_RCS_Read" );
|
||||
debug2( SERIAL_CHF_MODULE_ID, DEBUG_C_SERIAL, SERIAL_I_READ, "RCS", rcs );
|
||||
debug1( DEBUG_C_TRACE, SERIAL_I_CALLED, "Serial_RCS_Read" );
|
||||
debug2( DEBUG_C_SERIAL, SERIAL_I_READ, "RCS", rcs );
|
||||
|
||||
return rcs;
|
||||
}
|
||||
|
@ -826,8 +844,8 @@ Nibble Serial_RCS_Read( void )
|
|||
.- */
|
||||
Nibble Serial_TCS_Read( void )
|
||||
{
|
||||
debug1( SERIAL_CHF_MODULE_ID, DEBUG_C_TRACE, SERIAL_I_CALLED, "Serial_TCS_Read" );
|
||||
debug2( SERIAL_CHF_MODULE_ID, DEBUG_C_SERIAL, SERIAL_I_READ, "TCS", tcs );
|
||||
debug1( DEBUG_C_TRACE, SERIAL_I_CALLED, "Serial_TCS_Read" );
|
||||
debug2( DEBUG_C_SERIAL, SERIAL_I_READ, "TCS", tcs );
|
||||
|
||||
return tcs;
|
||||
}
|
||||
|
@ -859,14 +877,14 @@ Nibble Serial_TCS_Read( void )
|
|||
.notes :
|
||||
2.5, 13-Sep-2000, creation
|
||||
3.2, 22-Sep-2000, update
|
||||
- removed warning message
|
||||
- conditionally (#ifdef HP49_SUPPORT) removed warning message
|
||||
when reading from an empty RRB.
|
||||
.- */
|
||||
int8 Serial_RBR_Read( void )
|
||||
{
|
||||
int8 rx;
|
||||
|
||||
debug1( SERIAL_CHF_MODULE_ID, DEBUG_C_TRACE, SERIAL_I_CALLED, "Serial_RBR_Read" );
|
||||
debug1( DEBUG_C_TRACE, SERIAL_I_CALLED, "Serial_RBR_Read" );
|
||||
|
||||
/* Pull one character from rbr, if not empty */
|
||||
if ( FullSlots( rrb ) > 0 ) {
|
||||
|
@ -874,6 +892,14 @@ int8 Serial_RBR_Read( void )
|
|||
} else {
|
||||
/* rrb is empty */
|
||||
|
||||
#ifndef HP49_SUPPORT
|
||||
/* 3.2: The HP49 firmware (1.19-4) can read from an empty RRB;
|
||||
this is not harmful, and this warning can be removed.
|
||||
*/
|
||||
ChfCondition SERIAL_W_EMPTY_RRB, CHF_WARNING, rcs ChfEnd;
|
||||
ChfSignal();
|
||||
#endif
|
||||
|
||||
rx = ( int8 )0xFF;
|
||||
}
|
||||
|
||||
|
@ -883,7 +909,7 @@ int8 Serial_RBR_Read( void )
|
|||
/* Post a new IRQ if necessary */
|
||||
CheckIRQ;
|
||||
|
||||
debug1( SERIAL_CHF_MODULE_ID, DEBUG_C_SERIAL, SERIAL_I_RBR, rx );
|
||||
debug1( DEBUG_C_SERIAL, SERIAL_I_RBR, rx );
|
||||
return rx;
|
||||
}
|
||||
|
||||
|
@ -915,8 +941,8 @@ int8 Serial_RBR_Read( void )
|
|||
.- */
|
||||
void Serial_IOC_Write( Nibble n )
|
||||
{
|
||||
debug1( SERIAL_CHF_MODULE_ID, DEBUG_C_TRACE, SERIAL_I_CALLED, "Serial_IOC_Write" );
|
||||
debug3( SERIAL_CHF_MODULE_ID, DEBUG_C_SERIAL, SERIAL_I_WRITE, "IOC", ioc, n );
|
||||
debug1( DEBUG_C_TRACE, SERIAL_I_CALLED, "Serial_IOC_Write" );
|
||||
debug3( DEBUG_C_SERIAL, SERIAL_I_WRITE, "IOC", ioc, n );
|
||||
|
||||
ioc = n;
|
||||
|
||||
|
@ -950,8 +976,8 @@ void Serial_IOC_Write( Nibble n )
|
|||
.- */
|
||||
void Serial_RCS_Write( Nibble n )
|
||||
{
|
||||
debug1( SERIAL_CHF_MODULE_ID, DEBUG_C_TRACE, SERIAL_I_CALLED, "Serial_RCS_Write" );
|
||||
debug3( SERIAL_CHF_MODULE_ID, DEBUG_C_SERIAL, SERIAL_I_WRITE, "RCS", rcs, n );
|
||||
debug1( DEBUG_C_TRACE, SERIAL_I_CALLED, "Serial_RCS_Write" );
|
||||
debug3( DEBUG_C_SERIAL, SERIAL_I_WRITE, "RCS", rcs, n );
|
||||
|
||||
rcs = n;
|
||||
}
|
||||
|
@ -983,8 +1009,8 @@ void Serial_RCS_Write( Nibble n )
|
|||
.- */
|
||||
void Serial_TCS_Write( Nibble n )
|
||||
{
|
||||
debug1( SERIAL_CHF_MODULE_ID, DEBUG_C_TRACE, SERIAL_I_CALLED, "Serial_TCS_Write" );
|
||||
debug3( SERIAL_CHF_MODULE_ID, DEBUG_C_SERIAL, SERIAL_I_WRITE, "TCS", tcs, n );
|
||||
debug1( DEBUG_C_TRACE, SERIAL_I_CALLED, "Serial_TCS_Write" );
|
||||
debug3( DEBUG_C_SERIAL, SERIAL_I_WRITE, "TCS", tcs, n );
|
||||
|
||||
tcs = n;
|
||||
}
|
||||
|
@ -1015,8 +1041,8 @@ void Serial_TCS_Write( Nibble n )
|
|||
.- */
|
||||
void Serial_CRER_Write( Nibble n )
|
||||
{
|
||||
debug1( SERIAL_CHF_MODULE_ID, DEBUG_C_TRACE, SERIAL_I_CALLED, "Serial_CRER_Write" );
|
||||
debug3( SERIAL_CHF_MODULE_ID, DEBUG_C_SERIAL, SERIAL_I_WRITE, "CRER", 0, n );
|
||||
debug1( DEBUG_C_TRACE, SERIAL_I_CALLED, "Serial_CRER_Write" );
|
||||
debug3( DEBUG_C_SERIAL, SERIAL_I_WRITE, "CRER", 0, n );
|
||||
|
||||
rcs &= ~RCS_RER;
|
||||
}
|
||||
|
@ -1051,16 +1077,16 @@ void Serial_CRER_Write( Nibble n )
|
|||
.- */
|
||||
void Serial_TBR_Write( int8 d )
|
||||
{
|
||||
debug1( SERIAL_CHF_MODULE_ID, DEBUG_C_TRACE, SERIAL_I_CALLED, "Serial_TBR_Write" );
|
||||
debug1( SERIAL_CHF_MODULE_ID, DEBUG_C_SERIAL, SERIAL_I_TBR, d );
|
||||
debug1( DEBUG_C_TRACE, SERIAL_I_CALLED, "Serial_TBR_Write" );
|
||||
debug1( DEBUG_C_SERIAL, SERIAL_I_TBR, d );
|
||||
|
||||
/* Pull one character from rbr, if not empty */
|
||||
if ( EmptySlots( trb ) > 0 ) {
|
||||
Push( trb, d );
|
||||
} else {
|
||||
/* trb is full; discard character */
|
||||
ChfGenerate( SERIAL_CHF_MODULE_ID, __FILE__, __LINE__, SERIAL_W_FULL_TRB, CHF_WARNING, tcs );
|
||||
ChfSignal( SERIAL_CHF_MODULE_ID );
|
||||
ChfCondition SERIAL_W_FULL_TRB, CHF_WARNING, tcs ChfEnd;
|
||||
ChfSignal();
|
||||
}
|
||||
|
||||
/* Update transmitter status */
|
||||
|
@ -1112,7 +1138,7 @@ void HandleSerial( void )
|
|||
{
|
||||
int result;
|
||||
|
||||
debug1( SERIAL_CHF_MODULE_ID, DEBUG_C_TRACE, SERIAL_I_CALLED, "HandleSerial" );
|
||||
debug1( DEBUG_C_TRACE, SERIAL_I_CALLED, "HandleSerial" );
|
||||
|
||||
#ifndef USE_NOPTY
|
||||
/* Attempt to drain transmitter buffer even if serial port is closed */
|
||||
|
@ -1120,9 +1146,9 @@ void HandleSerial( void )
|
|||
|
||||
/* Signal a condition upon failure */
|
||||
if ( result < 0 ) {
|
||||
ChfGenerate( CHF_ERRNO_SET, __FILE__, __LINE__, errno, CHF_ERROR );
|
||||
ChfGenerate( SERIAL_CHF_MODULE_ID, __FILE__, __LINE__, SERIAL_E_TRB_DRAIN, CHF_ERROR );
|
||||
ChfSignal( SERIAL_CHF_MODULE_ID );
|
||||
ChfErrnoCondition;
|
||||
ChfCondition SERIAL_E_TRB_DRAIN, CHF_ERROR ChfEnd;
|
||||
ChfSignal();
|
||||
}
|
||||
|
||||
/* Update tcs */
|
||||
|
@ -1134,9 +1160,9 @@ void HandleSerial( void )
|
|||
|
||||
/* Signal a condition upon failure */
|
||||
if ( result < 0 ) {
|
||||
ChfGenerate( CHF_ERRNO_SET, __FILE__, __LINE__, errno, CHF_ERROR );
|
||||
ChfGenerate( SERIAL_CHF_MODULE_ID, __FILE__, __LINE__, SERIAL_E_RRB_CHARGE, CHF_ERROR );
|
||||
ChfSignal( SERIAL_CHF_MODULE_ID );
|
||||
ChfErrnoCondition;
|
||||
ChfCondition SERIAL_E_RRB_CHARGE, CHF_ERROR ChfEnd;
|
||||
ChfSignal();
|
||||
}
|
||||
|
||||
/* Update receiver status */
|
||||
|
|
172
src/ui48_bitmaps_big_font.h
Normal file
172
src/ui48_bitmaps_big_font.h
Normal file
|
@ -0,0 +1,172 @@
|
|||
#ifndef _UI48_BITMAPS_BIG_FONT_H
|
||||
#define _UI48_BITMAPS_BIG_FONT_H 1
|
||||
|
||||
#define big_font_dot_width 8
|
||||
#define big_font_dot_height 13
|
||||
static unsigned char big_font_dot_bits[] = {
|
||||
0, 0, 0, 0, 0, 0, 0, 24, 24, 0, 0, 0, 0,
|
||||
};
|
||||
|
||||
#define big_font_0_width 8
|
||||
#define big_font_0_height 13
|
||||
static unsigned char big_font_0_bits[] = {
|
||||
24, 60, 102, 102, 195, 195, 195, 195, 195, 102, 102, 60, 24,
|
||||
};
|
||||
|
||||
#define big_font_1_width 8
|
||||
#define big_font_1_height 13
|
||||
static unsigned char big_font_1_bits[] = {
|
||||
24, 28, 30, 27, 24, 24, 24, 24, 24, 24, 24, 24, 255,
|
||||
};
|
||||
|
||||
#define big_font_2_width 8
|
||||
#define big_font_2_height 13
|
||||
static unsigned char big_font_2_bits[] = {
|
||||
60, 102, 195, 195, 192, 192, 96, 56, 12, 6, 3, 3, 255,
|
||||
};
|
||||
|
||||
#define big_font_3_width 8
|
||||
#define big_font_3_height 13
|
||||
static unsigned char big_font_3_bits[] = {
|
||||
60, 102, 195, 195, 192, 96, 56, 96, 192, 195, 195, 102, 60,
|
||||
};
|
||||
|
||||
#define big_font_4_width 8
|
||||
#define big_font_4_height 13
|
||||
static unsigned char big_font_4_bits[] = {
|
||||
96, 112, 120, 108, 102, 99, 99, 255, 96, 96, 96, 96, 96,
|
||||
};
|
||||
|
||||
#define big_font_5_width 8
|
||||
#define big_font_5_height 13
|
||||
static unsigned char big_font_5_bits[] = {
|
||||
255, 3, 3, 3, 3, 59, 103, 192, 192, 192, 195, 102, 60,
|
||||
};
|
||||
|
||||
#define big_font_6_width 8
|
||||
#define big_font_6_height 13
|
||||
static unsigned char big_font_6_bits[] = {
|
||||
60, 102, 67, 3, 3, 59, 103, 195, 195, 195, 195, 102, 60,
|
||||
};
|
||||
|
||||
#define big_font_7_width 8
|
||||
#define big_font_7_height 13
|
||||
static unsigned char big_font_7_bits[] = {
|
||||
255, 192, 192, 96, 96, 48, 48, 24, 24, 12, 12, 6, 6,
|
||||
};
|
||||
|
||||
#define big_font_8_width 8
|
||||
#define big_font_8_height 13
|
||||
static unsigned char big_font_8_bits[] = {
|
||||
60, 102, 195, 195, 195, 102, 60, 102, 195, 195, 195, 102, 60,
|
||||
};
|
||||
|
||||
#define big_font_9_width 8
|
||||
#define big_font_9_height 13
|
||||
static unsigned char big_font_9_bits[] = {
|
||||
62, 195, 195, 195, 195, 195, 230, 220, 192, 192, 194, 102, 60,
|
||||
};
|
||||
|
||||
#define big_font_A_width 8
|
||||
#define big_font_A_height 10
|
||||
static unsigned char big_font_A_bits[] = {
|
||||
30, 51, 51, 51, 51, 51, 63, 51, 51, 51,
|
||||
};
|
||||
|
||||
#define big_font_C_width 8
|
||||
#define big_font_C_height 10
|
||||
static unsigned char big_font_C_bits[] = {
|
||||
30, 51, 51, 3, 3, 3, 3, 51, 51, 30,
|
||||
};
|
||||
|
||||
#define big_font_D_width 8
|
||||
#define big_font_D_height 10
|
||||
static unsigned char big_font_D_bits[] = {
|
||||
15, 27, 51, 51, 51, 51, 51, 51, 27, 15,
|
||||
};
|
||||
|
||||
#define big_font_E_width 8
|
||||
#define big_font_E_height 10
|
||||
static unsigned char big_font_E_bits[] = {
|
||||
63, 3, 3, 3, 31, 3, 3, 3, 3, 63,
|
||||
};
|
||||
|
||||
#define big_font_G_width 8
|
||||
#define big_font_G_height 10
|
||||
static unsigned char big_font_G_bits[] = {
|
||||
30, 51, 51, 3, 3, 59, 51, 51, 51, 30,
|
||||
};
|
||||
|
||||
#define big_font_H_width 8
|
||||
#define big_font_H_height 10
|
||||
static unsigned char big_font_H_bits[] = {
|
||||
51, 51, 51, 51, 63, 51, 51, 51, 51, 51,
|
||||
};
|
||||
|
||||
#define big_font_I_width 8
|
||||
#define big_font_I_height 10
|
||||
static unsigned char big_font_I_bits[] = {
|
||||
63, 12, 12, 12, 12, 12, 12, 12, 12, 63,
|
||||
};
|
||||
|
||||
#define big_font_L_width 8
|
||||
#define big_font_L_height 10
|
||||
static unsigned char big_font_L_bits[] = {
|
||||
3, 3, 3, 3, 3, 3, 3, 3, 3, 63,
|
||||
};
|
||||
|
||||
#define big_font_M_width 8
|
||||
#define big_font_M_height 10
|
||||
static unsigned char big_font_M_bits[] = {
|
||||
33, 51, 51, 63, 63, 51, 51, 51, 51, 51,
|
||||
};
|
||||
|
||||
#define big_font_N_width 8
|
||||
#define big_font_N_height 10
|
||||
static unsigned char big_font_N_bits[] = {
|
||||
51, 51, 55, 55, 55, 59, 59, 59, 51, 51,
|
||||
};
|
||||
|
||||
#define big_font_O_width 8
|
||||
#define big_font_O_height 10
|
||||
static unsigned char big_font_O_bits[] = {
|
||||
30, 51, 51, 51, 51, 51, 51, 51, 51, 30,
|
||||
};
|
||||
|
||||
#define big_font_P_width 8
|
||||
#define big_font_P_height 10
|
||||
static unsigned char big_font_P_bits[] = {
|
||||
31, 51, 51, 51, 51, 31, 3, 3, 3, 3,
|
||||
};
|
||||
|
||||
#define big_font_R_width 8
|
||||
#define big_font_R_height 10
|
||||
static unsigned char big_font_R_bits[] = {
|
||||
31, 51, 51, 51, 31, 27, 51, 51, 51, 51,
|
||||
};
|
||||
|
||||
#define big_font_S_width 8
|
||||
#define big_font_S_height 10
|
||||
static unsigned char big_font_S_bits[] = {
|
||||
30, 51, 51, 6, 12, 12, 24, 51, 51, 30,
|
||||
};
|
||||
|
||||
#define big_font_T_width 8
|
||||
#define big_font_T_height 10
|
||||
static unsigned char big_font_T_bits[] = {
|
||||
63, 12, 12, 12, 12, 12, 12, 12, 12, 12,
|
||||
};
|
||||
|
||||
#define big_font_V_width 8
|
||||
#define big_font_V_height 10
|
||||
static unsigned char big_font_V_bits[] = {
|
||||
51, 51, 51, 51, 51, 51, 51, 30, 30, 12,
|
||||
};
|
||||
|
||||
#define big_font_X_width 8
|
||||
#define big_font_X_height 10
|
||||
static unsigned char big_font_X_bits[] = {
|
||||
51, 51, 30, 30, 12, 12, 30, 30, 51, 51,
|
||||
};
|
||||
|
||||
#endif /* _UI48_BITMAPS_BIG_FONT_H 1 */
|
|
@ -1,5 +1,5 @@
|
|||
#ifndef _UI4x_BITMAPS_MISC_H
|
||||
#define _UI4x_BITMAPS_MISC_H 1
|
||||
#ifndef _UI48_BITMAPS_MISC_H
|
||||
#define _UI48_BITMAPS_MISC_H 1
|
||||
|
||||
#define hp_width 96
|
||||
#define hp_height 24
|
||||
|
@ -221,4 +221,4 @@ static unsigned char last_bitmap[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
|
|||
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x29, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
|
||||
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0xc9, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80 };
|
||||
|
||||
#endif /* _UI4x_BITMAPS_MISC_H 1 */
|
||||
#endif /* _UI48_BITMAPS_MISC_H 1 */
|
423
src/ui48_bitmaps_small_font.h
Normal file
423
src/ui48_bitmaps_small_font.h
Normal file
|
@ -0,0 +1,423 @@
|
|||
#ifndef _UI48_BITMAPS_SMALL_FONT_H
|
||||
#define _UI48_BITMAPS_SMALL_FONT_H 1
|
||||
|
||||
#define blank_width 4
|
||||
#define blank_height 7
|
||||
static unsigned char blank_bits[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
||||
|
||||
#define hash_width 5
|
||||
#define hash_height 7
|
||||
static unsigned char hash_bits[] = { 0x00, 0x0a, 0x1f, 0x0a, 0x0a, 0x1f, 0x0a };
|
||||
|
||||
#define lbrace_width 3
|
||||
#define lbrace_height 7
|
||||
static unsigned char lbrace_bits[] = { 0x04, 0x02, 0x01, 0x01, 0x01, 0x02, 0x04 };
|
||||
|
||||
#define rbrace_width 3
|
||||
#define rbrace_height 7
|
||||
static unsigned char rbrace_bits[] = { 0x01, 0x02, 0x04, 0x04, 0x04, 0x02, 0x01 };
|
||||
|
||||
#define comma_width 3
|
||||
#define comma_height 7
|
||||
static unsigned char comma_bits[] = { 0x00, 0x00, 0x00, 0x00, 0x06, 0x06, 0x03 };
|
||||
|
||||
#define slash_width 3
|
||||
#define slash_height 7
|
||||
static unsigned char slash_bits[] = { 0x04, 0x04, 0x02, 0x02, 0x02, 0x01, 0x01 };
|
||||
|
||||
#define zero_width 5
|
||||
#define zero_height 7
|
||||
static unsigned char zero_bits[] = {
|
||||
14, 17, 25, 21, 19, 17, 14,
|
||||
};
|
||||
|
||||
#define one_width 5
|
||||
#define one_height 7
|
||||
static unsigned char one_bits[] = {
|
||||
4, 6, 5, 4, 4, 4, 31,
|
||||
};
|
||||
|
||||
#define two_width 5
|
||||
#define two_height 7
|
||||
static unsigned char two_bits[] = { 0x0e, 0x11, 0x10, 0x08, 0x04, 0x02, 0x1f };
|
||||
|
||||
#define three_width 5
|
||||
#define three_height 7
|
||||
static unsigned char three_bits[] = { 0x0e, 0x11, 0x10, 0x0c, 0x10, 0x11, 0x0e };
|
||||
|
||||
#define four_width 5
|
||||
#define four_height 7
|
||||
static unsigned char four_bits[] = {
|
||||
8, 12, 10, 9, 31, 8, 8,
|
||||
};
|
||||
|
||||
#define five_width 5
|
||||
#define five_height 7
|
||||
static unsigned char five_bits[] = {
|
||||
31, 1, 1, 15, 16, 16, 15,
|
||||
};
|
||||
|
||||
#define six_width 5
|
||||
#define six_height 7
|
||||
static unsigned char six_bits[] = {
|
||||
14, 17, 1, 15, 17, 17, 14,
|
||||
};
|
||||
|
||||
#define seven_width 5
|
||||
#define seven_height 7
|
||||
static unsigned char seven_bits[] = {
|
||||
31, 16, 8, 4, 2, 1, 1,
|
||||
};
|
||||
|
||||
#define eight_width 5
|
||||
#define eight_height 7
|
||||
static unsigned char eight_bits[] = {
|
||||
14, 17, 17, 14, 17, 17, 14,
|
||||
};
|
||||
|
||||
#define nine_width 5
|
||||
#define nine_height 7
|
||||
static unsigned char nine_bits[] = {
|
||||
14, 17, 17, 30, 16, 17, 14,
|
||||
};
|
||||
|
||||
#define small_colon_width 2
|
||||
#define small_colon_height 7
|
||||
static unsigned char small_colon_bits[] = { 0x00, 0x03, 0x03, 0x00, 0x03, 0x03, 0x00 };
|
||||
|
||||
#define d_width 5
|
||||
#define d_height 7
|
||||
static unsigned char d_bits[] = {
|
||||
16, 16, 30, 17, 17, 30, 0,
|
||||
};
|
||||
|
||||
#define e_width 5
|
||||
#define e_height 7
|
||||
static unsigned char e_bits[] = {
|
||||
0, 14, 17, 15, 1, 14, 0,
|
||||
};
|
||||
|
||||
#define i_width 5
|
||||
#define i_height 7
|
||||
static unsigned char i_bits[] = {
|
||||
4, 0, 6, 4, 4, 14, 0,
|
||||
};
|
||||
|
||||
#define p_width 5
|
||||
#define p_height 7
|
||||
static unsigned char p_bits[] = {
|
||||
0, 15, 17, 17, 15, 1, 1,
|
||||
};
|
||||
|
||||
#define r_width 5
|
||||
#define r_height 7
|
||||
static unsigned char r_bits[] = {
|
||||
0, 29, 3, 1, 1, 1, 0,
|
||||
};
|
||||
|
||||
#define s_width 5
|
||||
#define s_height 7
|
||||
static unsigned char s_bits[] = {
|
||||
0, 30, 1, 14, 16, 15, 0,
|
||||
};
|
||||
|
||||
#define t_width 5
|
||||
#define t_height 7
|
||||
static unsigned char t_bits[] = {
|
||||
2, 15, 2, 2, 2, 12, 0,
|
||||
};
|
||||
|
||||
#define v_width 5
|
||||
#define v_height 7
|
||||
static unsigned char v_bits[] = {
|
||||
0, 17, 17, 10, 10, 4, 0,
|
||||
};
|
||||
|
||||
#define w_width 5
|
||||
#define w_height 7
|
||||
static unsigned char w_bits[] = {
|
||||
0, 17, 17, 21, 21, 10, 0,
|
||||
};
|
||||
|
||||
#define y_width 5
|
||||
#define y_height 7
|
||||
static unsigned char y_bits[] = {
|
||||
0, 0, 17, 17, 30, 16, 15,
|
||||
};
|
||||
|
||||
#define A_width 5
|
||||
#define A_height 7
|
||||
static unsigned char A_bits[] = { 0x0e, 0x11, 0x11, 0x1f, 0x11, 0x11, 0x11 };
|
||||
|
||||
#define B_width 5
|
||||
#define B_height 7
|
||||
static unsigned char B_bits[] = { 0x0f, 0x11, 0x11, 0x0f, 0x11, 0x11, 0x0f };
|
||||
|
||||
#define C_width 5
|
||||
#define C_height 7
|
||||
static unsigned char C_bits[] = { 0x0e, 0x11, 0x01, 0x01, 0x01, 0x11, 0x0e };
|
||||
|
||||
#define D_width 5
|
||||
#define D_height 7
|
||||
static unsigned char D_bits[] = { 0x0f, 0x11, 0x11, 0x11, 0x11, 0x11, 0x0f };
|
||||
|
||||
#define E_width 5
|
||||
#define E_height 7
|
||||
static unsigned char E_bits[] = { 0x1f, 0x01, 0x01, 0x0f, 0x01, 0x01, 0x1f };
|
||||
|
||||
#define F_width 5
|
||||
#define F_height 7
|
||||
static unsigned char F_bits[] = { 0x1f, 0x01, 0x01, 0x0f, 0x01, 0x01, 0x01 };
|
||||
|
||||
#define G_width 5
|
||||
#define G_height 7
|
||||
static unsigned char G_bits[] = { 0x0e, 0x11, 0x01, 0x01, 0x19, 0x11, 0x0e };
|
||||
|
||||
#define H_width 5
|
||||
#define H_height 7
|
||||
static unsigned char H_bits[] = { 0x11, 0x11, 0x11, 0x1f, 0x11, 0x11, 0x11 };
|
||||
|
||||
#define I_width 1
|
||||
#define I_height 7
|
||||
static unsigned char I_bits[] = { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 };
|
||||
|
||||
#define J_width 4
|
||||
#define J_height 7
|
||||
static unsigned char J_bits[] = { 0x08, 0x08, 0x08, 0x08, 0x08, 0x09, 0x06 };
|
||||
|
||||
#define K_width 5
|
||||
#define K_height 7
|
||||
static unsigned char K_bits[] = { 0x11, 0x09, 0x05, 0x03, 0x05, 0x09, 0x11 };
|
||||
|
||||
#define L_width 4
|
||||
#define L_height 7
|
||||
static unsigned char L_bits[] = { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x0f };
|
||||
|
||||
#define M_width 5
|
||||
#define M_height 7
|
||||
static unsigned char M_bits[] = { 0x11, 0x1b, 0x15, 0x11, 0x11, 0x11, 0x11 };
|
||||
|
||||
#define N_width 5
|
||||
#define N_height 7
|
||||
static unsigned char N_bits[] = { 0x11, 0x11, 0x13, 0x15, 0x19, 0x11, 0x11 };
|
||||
|
||||
#define O_width 5
|
||||
#define O_height 7
|
||||
static unsigned char O_bits[] = { 0x0e, 0x11, 0x11, 0x11, 0x11, 0x11, 0x0e };
|
||||
|
||||
#define P_width 5
|
||||
#define P_height 7
|
||||
static unsigned char P_bits[] = { 0x0f, 0x11, 0x11, 0x0f, 0x01, 0x01, 0x01 };
|
||||
|
||||
#define Q_width 5
|
||||
#define Q_height 7
|
||||
static unsigned char Q_bits[] = { 0x0e, 0x11, 0x11, 0x11, 0x15, 0x09, 0x16 };
|
||||
|
||||
#define R_width 5
|
||||
#define R_height 7
|
||||
static unsigned char R_bits[] = { 0x0f, 0x11, 0x11, 0x0f, 0x05, 0x09, 0x11 };
|
||||
|
||||
#define S_width 5
|
||||
#define S_height 7
|
||||
static unsigned char S_bits[] = { 0x0e, 0x11, 0x01, 0x0e, 0x10, 0x11, 0x0e };
|
||||
|
||||
#define T_width 5
|
||||
#define T_height 7
|
||||
static unsigned char T_bits[] = { 0x1f, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04 };
|
||||
|
||||
#define U_width 5
|
||||
#define U_height 7
|
||||
static unsigned char U_bits[] = { 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x0e };
|
||||
|
||||
#define V_width 5
|
||||
#define V_height 7
|
||||
static unsigned char V_bits[] = { 0x11, 0x11, 0x11, 0x11, 0x0a, 0x0a, 0x04 };
|
||||
|
||||
#define W_width 5
|
||||
#define W_height 7
|
||||
static unsigned char W_bits[] = { 0x11, 0x11, 0x11, 0x11, 0x15, 0x1b, 0x11 };
|
||||
|
||||
#define X_width 5
|
||||
#define X_height 7
|
||||
static unsigned char X_bits[] = { 0x11, 0x11, 0x0a, 0x04, 0x0a, 0x11, 0x11 };
|
||||
|
||||
#define Y_width 5
|
||||
#define Y_height 7
|
||||
static unsigned char Y_bits[] = { 0x11, 0x11, 0x0a, 0x04, 0x04, 0x04, 0x04 };
|
||||
|
||||
#define Z_width 5
|
||||
#define Z_height 7
|
||||
static unsigned char Z_bits[] = { 0x1f, 0x10, 0x08, 0x04, 0x02, 0x01, 0x1f };
|
||||
|
||||
#define lbracket_width 3
|
||||
#define lbracket_height 7
|
||||
static unsigned char lbracket_bits[] = { 0x07, 0x01, 0x01, 0x01, 0x01, 0x01, 0x07 };
|
||||
|
||||
#define rbracket_width 3
|
||||
#define rbracket_height 7
|
||||
static unsigned char rbracket_bits[] = { 0x07, 0x04, 0x04, 0x04, 0x04, 0x04, 0x07 };
|
||||
|
||||
#define arrow_width 7
|
||||
#define arrow_height 7
|
||||
static unsigned char arrow_bits[] = { 0x00, 0x08, 0x18, 0x3f, 0x18, 0x08, 0x00 };
|
||||
|
||||
#define diff_width 5
|
||||
#define diff_height 7
|
||||
static unsigned char diff_bits[] = { 0x0e, 0x10, 0x10, 0x1e, 0x11, 0x11, 0x0e };
|
||||
|
||||
#define integral_width 5
|
||||
#define integral_height 8
|
||||
static unsigned char integral_bits[] = { 0x0c, 0x12, 0x02, 0x04, 0x04, 0x08, 0x09, 0x06 };
|
||||
|
||||
#define sigma_width 6
|
||||
#define sigma_height 9
|
||||
static unsigned char sigma_bits[] = { 0x3f, 0x21, 0x02, 0x04, 0x08, 0x04, 0x02, 0x21, 0x3f };
|
||||
|
||||
#define sqr_width 11
|
||||
#define sqr_height 10
|
||||
static unsigned char sqr_bits[] = { 0x00, 0x03, 0x80, 0x04, 0x00, 0x04, 0x00, 0x02, 0x26, 0x01,
|
||||
0x94, 0x07, 0x08, 0x00, 0x14, 0x00, 0x53, 0x00, 0x21, 0x00 };
|
||||
|
||||
#define root_width 18
|
||||
#define root_height 13
|
||||
static unsigned char root_bits[] = { 0x26, 0x00, 0x00, 0x14, 0x00, 0x00, 0x08, 0xfe, 0x03, 0x14, 0x02, 0x02, 0x53,
|
||||
0x02, 0x00, 0x21, 0x99, 0x00, 0x00, 0x91, 0x00, 0x10, 0x91, 0x00, 0xa0, 0x50,
|
||||
0x00, 0xc0, 0x60, 0x00, 0x80, 0x20, 0x00, 0x00, 0x14, 0x00, 0x00, 0x0c, 0x00 };
|
||||
|
||||
#define pow10_width 13
|
||||
#define pow10_height 9
|
||||
static unsigned char pow10_bits[] = { 0x00, 0x12, 0x00, 0x0c, 0x32, 0x04, 0x4b, 0x0a, 0x4a,
|
||||
0x09, 0x4a, 0x00, 0x4a, 0x00, 0x4a, 0x00, 0x32, 0x00 };
|
||||
|
||||
#define exp_width 11
|
||||
#define exp_height 9
|
||||
static unsigned char exp_bits[] = { 0x80, 0x04, 0x00, 0x03, 0x00, 0x01, 0x8c, 0x02, 0x52,
|
||||
0x02, 0x09, 0x00, 0x07, 0x00, 0x21, 0x00, 0x1e, 0x00 };
|
||||
|
||||
#define under_width 6
|
||||
#define under_height 7
|
||||
static unsigned char under_bits[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f };
|
||||
|
||||
#define prog_width 16
|
||||
#define prog_height 7
|
||||
static unsigned char prog_bits[] = { 0x48, 0x12, 0x24, 0x24, 0x12, 0x48, 0x09, 0x90, 0x12, 0x48, 0x24, 0x24, 0x48, 0x12 };
|
||||
|
||||
#define string_width 10
|
||||
#define string_height 7
|
||||
static unsigned char string_bits[] = { 0x85, 0x02, 0x85, 0x02, 0x85, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
||||
|
||||
#define equal_width 5
|
||||
#define equal_height 7
|
||||
static unsigned char equal_bits[] = { 0x00, 0x1f, 0x00, 0x00, 0x1f, 0x00, 0x00 };
|
||||
|
||||
#define nl_width 8
|
||||
#define nl_height 7
|
||||
static unsigned char nl_bits[] = { 0x00, 0x84, 0x86, 0xff, 0x06, 0x04, 0x00 };
|
||||
|
||||
#define pi_width 6
|
||||
#define pi_height 7
|
||||
static unsigned char pi_bits[] = { 0x20, 0x1f, 0x12, 0x12, 0x12, 0x12, 0x12 };
|
||||
|
||||
#define angle_width 8
|
||||
#define angle_height 7
|
||||
static unsigned char angle_bits[] = { 0x40, 0x20, 0x10, 0x28, 0x44, 0x42, 0xff };
|
||||
|
||||
#define lcurly_width 5
|
||||
#define lcurly_height 7
|
||||
static unsigned char lcurly_bits[] = { 0x18, 0x04, 0x04, 0x02, 0x04, 0x04, 0x18 };
|
||||
|
||||
#define rcurly_width 5
|
||||
#define rcurly_height 7
|
||||
static unsigned char rcurly_bits[] = { 0x03, 0x04, 0x04, 0x08, 0x04, 0x04, 0x03 };
|
||||
|
||||
#define sqr_gx_width 11
|
||||
#define sqr_gx_height 13
|
||||
static unsigned char sqr_gx_bits[] = { 0x00, 0x03, 0x80, 0x04, 0x00, 0x04, 0x00, 0x02, 0x00, 0x01, 0x80, 0x07, 0x00,
|
||||
0x00, 0x66, 0x00, 0x14, 0x00, 0x08, 0x00, 0x14, 0x00, 0x53, 0x00, 0x21, 0x00 };
|
||||
|
||||
#define root_gx_width 18
|
||||
#define root_gx_height 15
|
||||
static unsigned char root_gx_bits[] = { 0x66, 0x00, 0x00, 0x14, 0x00, 0x00, 0x08, 0x00, 0x00, 0x14, 0x00, 0x00, 0x53, 0xfe, 0x03,
|
||||
0x21, 0x02, 0x02, 0x00, 0x02, 0x00, 0x00, 0x99, 0x00, 0x00, 0x91, 0x00, 0x10, 0x91, 0x00,
|
||||
0xa0, 0x50, 0x00, 0xc0, 0x60, 0x00, 0x80, 0x20, 0x00, 0x00, 0x14, 0x00, 0x00, 0x0c, 0x00 };
|
||||
|
||||
#define pow10_gx_width 13
|
||||
#define pow10_gx_height 12
|
||||
static unsigned char pow10_gx_bits[] = { 0x00, 0x12, 0x00, 0x0c, 0x00, 0x04, 0x00, 0x0a, 0x00, 0x09, 0x32, 0x00,
|
||||
0x4b, 0x00, 0x4a, 0x00, 0x4a, 0x00, 0x4a, 0x00, 0x4a, 0x00, 0x32, 0x00 };
|
||||
|
||||
#define exp_gx_width 13
|
||||
#define exp_gx_height 12
|
||||
static unsigned char exp_gx_bits[] = { 0x00, 0xfb, 0x00, 0xf6, 0x00, 0xe6, 0x00, 0xf6, 0x80, 0xed, 0x18, 0xe0,
|
||||
0x36, 0xe0, 0x36, 0xe0, 0x1f, 0xe0, 0x03, 0xe0, 0x13, 0xe0, 0x0e, 0xe0 };
|
||||
#define parens_gx_width 20
|
||||
#define parens_gx_height 12
|
||||
static unsigned char parens_gx_bits[] = { 0x0c, 0x00, 0x03, 0x06, 0x00, 0x06, 0x06, 0x00, 0x06, 0x03, 0x00, 0x0c,
|
||||
0x03, 0x00, 0x0c, 0x03, 0x00, 0x0c, 0x03, 0x00, 0x0c, 0x03, 0x00, 0x0c,
|
||||
0x03, 0x00, 0x0c, 0x06, 0x00, 0x06, 0x06, 0x00, 0x06, 0x0c, 0x00, 0x03 };
|
||||
|
||||
#define hash_gx_width 8
|
||||
#define hash_gx_height 12
|
||||
static unsigned char hash_gx_bits[] = { 0x00, 0x00, 0x48, 0x48, 0xfe, 0x24, 0x24, 0x7f, 0x12, 0x12, 0x00, 0x00 };
|
||||
|
||||
#define bracket_gx_width 12
|
||||
#define bracket_gx_height 12
|
||||
static unsigned char bracket_gx_bits[] = { 0x0f, 0x0f, 0x03, 0x0c, 0x03, 0x0c, 0x03, 0x0c, 0x03, 0x0c, 0x03, 0x0c,
|
||||
0x03, 0x0c, 0x03, 0x0c, 0x03, 0x0c, 0x03, 0x0c, 0x03, 0x0c, 0x0f, 0x0f };
|
||||
|
||||
#define under_gx_width 10
|
||||
#define under_gx_height 12
|
||||
static unsigned char under_gx_bits[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x03, 0xff, 0x03 };
|
||||
|
||||
#define prog_gx_width 24
|
||||
#define prog_gx_height 12
|
||||
static unsigned char prog_gx_bits[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xc3, 0x18,
|
||||
0x8c, 0x81, 0x31, 0xc6, 0x00, 0x63, 0x63, 0x00, 0xc6, 0xc6, 0x00, 0x63,
|
||||
0x8c, 0x81, 0x31, 0x18, 0xc3, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
||||
|
||||
#define quote_gx_width 12
|
||||
#define quote_gx_height 12
|
||||
static unsigned char quote_gx_bits[] = { 0x05, 0x0a, 0x05, 0x0a, 0x05, 0x0a, 0x05, 0x0a, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
||||
|
||||
#define curly_gx_width 14
|
||||
#define curly_gx_height 12
|
||||
static unsigned char curly_gx_bits[] = { 0x0c, 0x0c, 0x06, 0x18, 0x06, 0x18, 0x06, 0x18, 0x06, 0x18, 0x03, 0x30,
|
||||
0x06, 0x18, 0x06, 0x18, 0x06, 0x18, 0x06, 0x18, 0x06, 0x18, 0x0c, 0x0c };
|
||||
|
||||
#define colon_gx_width 8
|
||||
#define colon_gx_height 12
|
||||
static unsigned char colon_gx_bits[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xc3, 0x00, 0x00, 0xc3, 0xc3, 0x00 };
|
||||
|
||||
#define angle_gx_width 12
|
||||
#define angle_gx_height 12
|
||||
static unsigned char angle_gx_bits[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x80, 0x01, 0xc0, 0x00, 0xe0, 0x01,
|
||||
0xb0, 0x03, 0x18, 0x03, 0x0c, 0x03, 0x06, 0x03, 0xff, 0x0f, 0xff, 0x0f };
|
||||
|
||||
#define pi_gx_width 10
|
||||
#define pi_gx_height 12
|
||||
static unsigned char pi_gx_bits[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xfe, 0x03, 0xff, 0x01,
|
||||
0xcc, 0x00, 0xcc, 0x00, 0xcc, 0x00, 0xcc, 0x00, 0xcc, 0x00, 0xcc, 0x00 };
|
||||
|
||||
#define nl_gx_width 18
|
||||
#define nl_gx_height 12
|
||||
static unsigned char nl_gx_bits[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xc0, 0x00, 0x03, 0xf0, 0x00, 0x03,
|
||||
0xfc, 0x00, 0x03, 0xff, 0xff, 0x03, 0xff, 0xff, 0x03, 0xfc, 0x00, 0x00,
|
||||
0xf0, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
||||
|
||||
#define comma_gx_width 3
|
||||
#define comma_gx_height 12
|
||||
static unsigned char comma_gx_bits[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x07, 0x07, 0x04, 0x04, 0x02 };
|
||||
|
||||
#define arrow_gx_width 18
|
||||
#define arrow_gx_height 12
|
||||
static unsigned char arrow_gx_bits[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x3c, 0x00,
|
||||
0x00, 0xfc, 0x00, 0xff, 0xff, 0x03, 0xff, 0xff, 0x03, 0x00, 0xfc, 0x00,
|
||||
0x00, 0x3c, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
||||
|
||||
#define equal_gx_width 8
|
||||
#define equal_gx_height 12
|
||||
static unsigned char equal_gx_bits[] = { 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00 };
|
||||
|
||||
#endif /* _UI48_BITMAPS_SMALL_FONT_H 1 */
|
2291
src/ui48_common.c
Normal file
2291
src/ui48_common.c
Normal file
File diff suppressed because it is too large
Load diff
|
@ -1,7 +1,7 @@
|
|||
#ifndef _UI4x_COMMON_H
|
||||
#define _UI4x_COMMON_H 1
|
||||
#ifndef _UI48_COMMON_H
|
||||
#define _UI48_COMMON_H 1
|
||||
|
||||
#include "config.h"
|
||||
#include "ui48_config.h"
|
||||
|
||||
/*************************************************/
|
||||
/* public API: if it's there it's used elsewhere */
|
||||
|
@ -15,4 +15,4 @@ extern void ( *ui_stop )( void );
|
|||
extern void setup_ui( config_t* config );
|
||||
extern void close_and_exit( void );
|
||||
|
||||
#endif /* !_UI4x_COMMON_H */
|
||||
#endif /* !_UI48_COMMON_H */
|
271
src/ui48_config.c
Normal file
271
src/ui48_config.c
Normal file
|
@ -0,0 +1,271 @@
|
|||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <pwd.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <getopt.h>
|
||||
|
||||
#include "ui48_config.h"
|
||||
|
||||
static config_t config = {
|
||||
.progname = ( char* )"ui48",
|
||||
|
||||
.model = MODEL_48GX,
|
||||
.verbose = false,
|
||||
.shiftless = false,
|
||||
|
||||
.frontend = FRONTEND_SDL,
|
||||
|
||||
.mono = false,
|
||||
.gray = false,
|
||||
|
||||
.chromeless = false,
|
||||
.fullscreen = false,
|
||||
.scale = 1.0,
|
||||
|
||||
.tiny = false,
|
||||
.small = false,
|
||||
|
||||
.wire_name = ( char* )"/dev/wire",
|
||||
.ir_name = ( char* )"/dev/ir",
|
||||
|
||||
/* from args.h */
|
||||
.reset = false,
|
||||
.monitor = false,
|
||||
.batchXfer = false,
|
||||
.state_dir_path = ( char* )".",
|
||||
.mod_file_name = ( char* )"mod",
|
||||
.cpu_file_name = ( char* )"cpu",
|
||||
.hdw_file_name = ( char* )"hdw",
|
||||
.rom_file_name = ( char* )"rom",
|
||||
.ram_file_name = ( char* )"ram",
|
||||
.port_1_file_name = ( char* )"port1",
|
||||
.port_2_file_name = ( char* )"port2",
|
||||
.hw = ( char* )"hp48", /* 2.1: Hardware configuration (unused) */
|
||||
|
||||
};
|
||||
|
||||
/* Path/name dynamic allocator */
|
||||
/* static char* GetPathname( char* path, char* name ) */
|
||||
/* { */
|
||||
/* char* s = malloc( strlen( path ) + strlen( name ) + 2 ); */
|
||||
|
||||
/* strcpy( s, path ); */
|
||||
/* strcat( s, "/" ); */
|
||||
/* strcat( s, name ); */
|
||||
|
||||
/* return s; */
|
||||
/* } */
|
||||
|
||||
config_t* config_init( int argc, char* argv[] )
|
||||
{
|
||||
int option_index;
|
||||
int c = '?';
|
||||
|
||||
int clopt_model = -1;
|
||||
int clopt_verbose = -1;
|
||||
int clopt_shiftless = -1;
|
||||
int clopt_frontend = -1;
|
||||
int clopt_mono = -1;
|
||||
int clopt_gray = -1;
|
||||
int clopt_chromeless = -1;
|
||||
int clopt_fullscreen = -1;
|
||||
double clopt_scale = -1.0;
|
||||
|
||||
int clopt_tiny = -1;
|
||||
int clopt_small = -1;
|
||||
|
||||
int clopt_reset = -1;
|
||||
int clopt_monitor = -1;
|
||||
int clopt_batchXfer = -1;
|
||||
char* clopt_state_dir_path;
|
||||
char* clopt_mod_file_name;
|
||||
char* clopt_cpu_file_name;
|
||||
char* clopt_hdw_file_name;
|
||||
char* clopt_rom_file_name;
|
||||
char* clopt_ram_file_name;
|
||||
char* clopt_port_1_file_name;
|
||||
char* clopt_port_2_file_name;
|
||||
char* clopt_hw;
|
||||
|
||||
const char* optstring = "h";
|
||||
struct option long_options[] = {
|
||||
{"help", no_argument, NULL, 'h' },
|
||||
|
||||
{"48sx", no_argument, &clopt_model, MODEL_48SX },
|
||||
{"48gx", no_argument, &clopt_model, MODEL_48GX },
|
||||
{"40g", no_argument, &clopt_model, MODEL_40G },
|
||||
{"49g", no_argument, &clopt_model, MODEL_49G },
|
||||
{"verbose", no_argument, &clopt_verbose, true },
|
||||
{"shiftless", no_argument, &clopt_shiftless, true },
|
||||
{"gui", no_argument, &clopt_frontend, FRONTEND_SDL },
|
||||
{"tui", no_argument, &clopt_frontend, FRONTEND_NCURSES},
|
||||
{"tui-small", no_argument, NULL, 6110 },
|
||||
{"tui-tiny", no_argument, NULL, 6120 },
|
||||
{"mono", no_argument, &clopt_mono, true },
|
||||
{"gray", no_argument, &clopt_gray, true },
|
||||
{"chromeless", no_argument, &clopt_chromeless, true },
|
||||
{"fullscreen", no_argument, &clopt_fullscreen, true },
|
||||
{"scale", required_argument, NULL, 7110 },
|
||||
|
||||
{"reset", no_argument, &clopt_reset, true },
|
||||
{"monitor", no_argument, &clopt_monitor, true },
|
||||
{"batchXfer", no_argument, &clopt_batchXfer, true },
|
||||
{"state-dir", required_argument, NULL, 8999 },
|
||||
{"mod", required_argument, NULL, 8000 },
|
||||
{"cpu", required_argument, NULL, 8010 },
|
||||
{"hdw", required_argument, NULL, 8020 },
|
||||
{"rom", required_argument, NULL, 8030 },
|
||||
{"ram", required_argument, NULL, 8040 },
|
||||
{"port1", required_argument, NULL, 8050 },
|
||||
{"port2", required_argument, NULL, 8060 },
|
||||
{"hw", required_argument, NULL, 8070 },
|
||||
|
||||
{0, 0, 0, 0 }
|
||||
};
|
||||
|
||||
const char* help_text = "usage: %s [options]\n"
|
||||
"options:\n"
|
||||
" -h --help what you are reading\n"
|
||||
" --gui graphical (SDL2) front-end (default: true)\n"
|
||||
" --tui text front-end (default: false)\n"
|
||||
" --tui-small text small front-end (2×2 pixels per character) (default: "
|
||||
"false)\n"
|
||||
" --tui-tiny text tiny front-end (2×4 pixels per character) (default: "
|
||||
"false)\n"
|
||||
" --chromeless only show display (default: "
|
||||
"false)\n"
|
||||
" --fullscreen make the UI fullscreen "
|
||||
"(default: false)\n"
|
||||
" --scale=<n> make the UI scale <n> times "
|
||||
"(default: 1.0)\n"
|
||||
" --mono make the UI monochrome (default: "
|
||||
"false)\n"
|
||||
" --gray make the UI grayscale (default: "
|
||||
"false)\n"
|
||||
" --48gx make the GUI looks like a HP 48GX (default: "
|
||||
"auto)\n"
|
||||
" --48sx make the GUI looks like a HP 48SX (default: "
|
||||
"auto)\n"
|
||||
" --shiftless don't map the shift keys to let them free for numbers (default: "
|
||||
"false)\n";
|
||||
|
||||
while ( c != EOF ) {
|
||||
c = getopt_long( argc, argv, optstring, long_options, &option_index );
|
||||
|
||||
switch ( c ) {
|
||||
case 'h':
|
||||
fprintf( stderr, help_text, config.progname );
|
||||
exit( 0 );
|
||||
break;
|
||||
case 6110:
|
||||
clopt_frontend = FRONTEND_NCURSES;
|
||||
clopt_small = true;
|
||||
break;
|
||||
case 6120:
|
||||
clopt_frontend = FRONTEND_NCURSES;
|
||||
clopt_tiny = true;
|
||||
break;
|
||||
case 7110:
|
||||
clopt_scale = atof( optarg );
|
||||
break;
|
||||
case 8999:
|
||||
clopt_state_dir_path = optarg;
|
||||
break;
|
||||
case 8000:
|
||||
clopt_mod_file_name = optarg;
|
||||
break;
|
||||
case 8010:
|
||||
clopt_cpu_file_name = optarg;
|
||||
break;
|
||||
case 8020:
|
||||
clopt_hdw_file_name = optarg;
|
||||
break;
|
||||
case 8030:
|
||||
clopt_rom_file_name = optarg;
|
||||
break;
|
||||
case 8040:
|
||||
clopt_ram_file_name = optarg;
|
||||
break;
|
||||
case 8050:
|
||||
clopt_port_1_file_name = optarg;
|
||||
break;
|
||||
case 8060:
|
||||
clopt_port_2_file_name = optarg;
|
||||
break;
|
||||
case 8070:
|
||||
clopt_hw = optarg;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( optind < argc ) {
|
||||
fprintf( stderr, "Invalid arguments : " );
|
||||
while ( optind < argc )
|
||||
fprintf( stderr, "%s\n", argv[ optind++ ] );
|
||||
fprintf( stderr, "\n" );
|
||||
}
|
||||
|
||||
/****************************************************/
|
||||
/* 2. treat command-line params which have priority */
|
||||
/****************************************************/
|
||||
if ( clopt_verbose != -1 )
|
||||
config.verbose = clopt_verbose == true;
|
||||
if ( clopt_model != -1 )
|
||||
config.model = clopt_model;
|
||||
if ( clopt_frontend != -1 )
|
||||
config.frontend = clopt_frontend;
|
||||
if ( clopt_chromeless != -1 )
|
||||
config.chromeless = clopt_chromeless == true;
|
||||
if ( clopt_fullscreen != -1 )
|
||||
config.fullscreen = clopt_fullscreen == true;
|
||||
if ( clopt_scale > 0.0 )
|
||||
config.scale = clopt_scale;
|
||||
if ( clopt_mono != -1 )
|
||||
config.mono = clopt_mono == true;
|
||||
if ( clopt_small != -1 )
|
||||
config.small = clopt_small == true;
|
||||
if ( clopt_tiny != -1 )
|
||||
config.tiny = clopt_tiny == true;
|
||||
if ( clopt_gray != -1 )
|
||||
config.gray = clopt_gray == true;
|
||||
if ( clopt_shiftless != -1 )
|
||||
config.shiftless = clopt_shiftless == true;
|
||||
|
||||
if ( clopt_reset != -1 )
|
||||
config.reset = clopt_reset;
|
||||
if ( clopt_monitor != -1 )
|
||||
config.monitor = clopt_monitor;
|
||||
if ( clopt_batchXfer != -1 )
|
||||
config.batchXfer = clopt_batchXfer;
|
||||
if ( clopt_state_dir_path != NULL )
|
||||
config.state_dir_path = strdup( clopt_state_dir_path );
|
||||
if ( clopt_mod_file_name != NULL )
|
||||
config.mod_file_name = strdup( clopt_mod_file_name );
|
||||
if ( clopt_cpu_file_name != NULL )
|
||||
config.cpu_file_name = strdup( clopt_cpu_file_name );
|
||||
if ( clopt_hdw_file_name != NULL )
|
||||
config.hdw_file_name = strdup( clopt_hdw_file_name );
|
||||
if ( clopt_rom_file_name != NULL )
|
||||
config.rom_file_name = strdup( clopt_rom_file_name );
|
||||
if ( clopt_ram_file_name != NULL )
|
||||
config.ram_file_name = strdup( clopt_ram_file_name );
|
||||
if ( clopt_port_1_file_name != NULL )
|
||||
config.port_1_file_name = strdup( clopt_port_1_file_name );
|
||||
if ( clopt_port_2_file_name != NULL )
|
||||
config.port_2_file_name = strdup( clopt_port_2_file_name );
|
||||
if ( clopt_hw != NULL )
|
||||
config.hw = strdup( clopt_hw );
|
||||
|
||||
fprintf( stderr, "config.chromeless = %s\n\n", config.chromeless ? "true" : "false" );
|
||||
|
||||
return &config;
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
#ifndef _UI4x_CONFIG_H
|
||||
#define _UI4x_CONFIG_H 1
|
||||
#ifndef _UI48_CONFIG_H
|
||||
#define _UI48_CONFIG_H 1
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
|
@ -15,11 +15,8 @@ typedef struct {
|
|||
char* progname;
|
||||
|
||||
int model;
|
||||
bool throttle;
|
||||
bool verbose;
|
||||
bool shiftless;
|
||||
bool big_screen;
|
||||
bool black_lcd;
|
||||
|
||||
int frontend;
|
||||
bool mono;
|
||||
|
@ -40,8 +37,6 @@ typedef struct {
|
|||
bool monitor; /* 2.1: Call monitor() on startup */
|
||||
bool batchXfer; /* 3.15: Non-interactive file transfers */
|
||||
char* state_dir_path;
|
||||
char* config_file_name;
|
||||
|
||||
char* mod_file_name;
|
||||
char* cpu_file_name;
|
||||
char* hdw_file_name;
|
||||
|
@ -49,9 +44,7 @@ typedef struct {
|
|||
char* ram_file_name;
|
||||
char* port_1_file_name;
|
||||
char* port_2_file_name;
|
||||
|
||||
int debug_level;
|
||||
bool enable_BUSCC;
|
||||
char* hw; /* 2.1: Hardware configuration (unused) */
|
||||
} config_t;
|
||||
|
||||
/*************/
|
||||
|
@ -59,4 +52,4 @@ typedef struct {
|
|||
/*************/
|
||||
extern config_t* config_init( int argc, char* argv[] );
|
||||
|
||||
#endif /* !_UI4x_CONFIG_H */
|
||||
#endif /* !_UI48_CONFIG_H */
|
|
@ -2,18 +2,14 @@
|
|||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "ui48_config.h"
|
||||
#include "ui48_emulator.h"
|
||||
|
||||
#include "config.h"
|
||||
#include "emulator.h"
|
||||
#include "keyb.h"
|
||||
#include "modules.h"
|
||||
|
||||
#include "../config.h"
|
||||
#include "../keyb.h"
|
||||
#include "../modules.h"
|
||||
#include "../serial.h"
|
||||
|
||||
#define KEYBOARD ( config.model == MODEL_48GX || config.model == MODEL_48SX ? keyboard48 : keyboard49 )
|
||||
#define NB_KEYS ( config.model == MODEL_48GX || config.model == MODEL_48SX ? NB_HP48_KEYS : NB_HP49_KEYS )
|
||||
|
||||
config_t config;
|
||||
static config_t config;
|
||||
|
||||
typedef struct hpkey_t {
|
||||
int code;
|
||||
|
@ -21,7 +17,7 @@ typedef struct hpkey_t {
|
|||
char* inOut;
|
||||
} hpkey_t;
|
||||
|
||||
static hpkey_t keyboard48[ NB_HP48_KEYS ] = {
|
||||
static hpkey_t keyboard48[ NB_KEYS ] = {
|
||||
/* From top left to bottom right */
|
||||
{0x14, false, "1/10"},
|
||||
{0x84, false, "8/10"},
|
||||
|
@ -82,104 +78,29 @@ static hpkey_t keyboard48[ NB_HP48_KEYS ] = {
|
|||
{0x00, false, "0/01"},
|
||||
};
|
||||
|
||||
static hpkey_t keyboard49[ NB_HP49_KEYS ] = {
|
||||
/* From top left to bottom right */
|
||||
{0x50, false, "5/01"},
|
||||
{0x51, false, "5/02"},
|
||||
{0x52, false, "5/04"},
|
||||
{0x53, false, "5/08"},
|
||||
{0x54, false, "5/10"},
|
||||
{0x55, false, "5/20"},
|
||||
|
||||
{0x57, false, "5/80"},
|
||||
{0x47, false, "4/80"},
|
||||
{0x37, false, "3/80"},
|
||||
|
||||
{0x27, false, "2/80"},
|
||||
{0x17, false, "1/80"},
|
||||
{0x07, false, "0/80"},
|
||||
|
||||
{0x62, false, "6/04"},
|
||||
{0x63, false, "6/08"},
|
||||
{0x60, false, "6/01"},
|
||||
{0x61, false, "6/02"},
|
||||
|
||||
{0x46, false, "4/40"},
|
||||
{0x36, false, "3/40"},
|
||||
{0x26, false, "2/40"},
|
||||
{0x16, false, "1/40"},
|
||||
{0x06, false, "0/40"},
|
||||
|
||||
{0x45, false, "4/20"},
|
||||
{0x35, false, "3/20"},
|
||||
{0x25, false, "2/20"},
|
||||
{0x15, false, "1/20"},
|
||||
{0x05, false, "0/20"},
|
||||
|
||||
{0x44, false, "4/10"},
|
||||
{0x34, false, "3/10"},
|
||||
{0x24, false, "2/10"},
|
||||
{0x14, false, "1/10"},
|
||||
{0x04, false, "0/10"},
|
||||
|
||||
{0x73, false, "7/08"},
|
||||
{0x33, false, "3/08"},
|
||||
{0x23, false, "2/08"},
|
||||
{0x13, false, "1/08"},
|
||||
{0x03, false, "0/08"},
|
||||
|
||||
{0x72, false, "7/04"},
|
||||
{0x32, false, "3/04"},
|
||||
{0x22, false, "2/04"},
|
||||
{0x12, false, "1/04"},
|
||||
{0x02, false, "0/04"},
|
||||
|
||||
{0x71, false, "7/02"},
|
||||
{0x31, false, "3/02"},
|
||||
{0x21, false, "2/02"},
|
||||
{0x11, false, "1/02"},
|
||||
{0x01, false, "0/02"},
|
||||
|
||||
{0x8000, false, "*" },
|
||||
{0x30, false, "3/01"},
|
||||
{0x20, false, "2/01"},
|
||||
{0x10, false, "1/01"},
|
||||
{0x00, false, "0/01"},
|
||||
};
|
||||
|
||||
void press_key( int hpkey )
|
||||
{
|
||||
if ( hpkey < 0 || hpkey > NB_KEYS )
|
||||
return;
|
||||
// Check not already pressed (may be important: avoids a useless do_kbd_int)
|
||||
if ( KEYBOARD[ hpkey ].pressed )
|
||||
if ( keyboard48[ hpkey ].pressed )
|
||||
return;
|
||||
|
||||
KEYBOARD[ hpkey ].pressed = true;
|
||||
keyboard48[ hpkey ].pressed = true;
|
||||
|
||||
KeybPress( KEYBOARD[ hpkey ].inOut );
|
||||
KeybPress( keyboard48[ hpkey ].inOut );
|
||||
}
|
||||
|
||||
void release_key( int hpkey )
|
||||
{
|
||||
if ( hpkey < 0 || hpkey > NB_KEYS )
|
||||
return;
|
||||
// Check not already released (not critical)
|
||||
if ( !KEYBOARD[ hpkey ].pressed )
|
||||
if ( !keyboard48[ hpkey ].pressed )
|
||||
return;
|
||||
|
||||
KEYBOARD[ hpkey ].pressed = false;
|
||||
keyboard48[ hpkey ].pressed = false;
|
||||
|
||||
KeybRelease( KEYBOARD[ hpkey ].inOut );
|
||||
KeybRelease( keyboard48[ hpkey ].inOut );
|
||||
}
|
||||
|
||||
bool is_key_pressed( int hpkey )
|
||||
{
|
||||
if ( hpkey < 0 || hpkey > NB_KEYS )
|
||||
return false;
|
||||
|
||||
return KEYBOARD[ hpkey ].pressed;
|
||||
}
|
||||
bool is_key_pressed( int hpkey ) { return keyboard48[ hpkey ].pressed; }
|
||||
|
||||
unsigned char get_annunciators( void ) { return mod_status.hdw.lcd_ann; }
|
||||
|
||||
|
@ -197,9 +118,8 @@ void get_lcd_buffer( int* target )
|
|||
for ( x = 0; x < NIBBLES_PER_ROW; x++ ) {
|
||||
v = FetchNibble( addr++ );
|
||||
|
||||
// split nibble
|
||||
for ( int nx = 0; nx < 4; nx++ )
|
||||
target[ ( y * LCD_WIDTH ) + ( x * 4 ) + nx ] = v & ( 1 << ( nx & 3 ) );
|
||||
target[ ( y * 131 ) + ( x * 4 ) + nx ] = v & ( 1 << ( nx & 3 ) );
|
||||
}
|
||||
|
||||
addr += mod_status.hdw.lcd_line_offset;
|
||||
|
@ -207,27 +127,52 @@ void get_lcd_buffer( int* target )
|
|||
|
||||
/* Scan menu display rows */
|
||||
addr = mod_status.hdw.lcd_menu_addr;
|
||||
for ( ; y < LCD_HEIGHT; y++ ) {
|
||||
#define MAX_ROWS 64
|
||||
for ( ; y < MAX_ROWS; y++ ) {
|
||||
/* Scan columns */
|
||||
for ( x = 0; x < NIBBLES_PER_ROW; x++ ) {
|
||||
v = FetchNibble( addr++ );
|
||||
|
||||
// split nibble
|
||||
for ( int nx = 0; nx < 4; nx++ )
|
||||
target[ ( y * LCD_WIDTH ) + ( x * 4 ) + nx ] = v & ( 1 << ( nx & 3 ) );
|
||||
target[ ( y * 131 ) + ( x * 4 ) + nx ] = v & ( 1 << ( nx & 3 ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int get_contrast( void ) { return mod_status.hdw.lcd_contrast - 6; }
|
||||
int get_contrast( void ) { return mod_status.hdw.lcd_contrast; }
|
||||
|
||||
struct Args args;
|
||||
|
||||
/* Path/name dynamic allocator */
|
||||
static char* GetPathname( char* path, char* name )
|
||||
{
|
||||
char* s = malloc( strlen( path ) + strlen( name ) + 2 );
|
||||
|
||||
strcpy( s, path );
|
||||
strcat( s, "/" );
|
||||
strcat( s, name );
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
void init_emulator( config_t* conf )
|
||||
{
|
||||
config = *conf;
|
||||
|
||||
EmulatorInit();
|
||||
/* Fill the emulator options data structure. */
|
||||
args.reset = config.reset;
|
||||
args.monitor = config.monitor;
|
||||
args.batchXfer = config.batchXfer;
|
||||
args.mod_file_name = GetPathname( config.state_dir_path, config.mod_file_name );
|
||||
args.cpu_file_name = GetPathname( config.state_dir_path, config.cpu_file_name );
|
||||
args.hdw_file_name = GetPathname( config.state_dir_path, config.hdw_file_name );
|
||||
args.rom_file_name = GetPathname( config.state_dir_path, config.rom_file_name );
|
||||
args.ram_file_name = GetPathname( config.state_dir_path, config.ram_file_name );
|
||||
args.port_1_file_name = GetPathname( config.state_dir_path, config.port_1_file_name );
|
||||
args.port_2_file_name = GetPathname( config.state_dir_path, config.port_2_file_name );
|
||||
args.hw = config.hw;
|
||||
|
||||
conf->wire_name = ( char* )SerialInit();
|
||||
EmulatorInit();
|
||||
}
|
||||
|
||||
void exit_emulator( void ) { EmulatorExit( SAVE_AND_EXIT ); }
|
103
src/ui48_emulator.h
Normal file
103
src/ui48_emulator.h
Normal file
|
@ -0,0 +1,103 @@
|
|||
#ifndef _UI48_EMULATOR_H
|
||||
#define _UI48_EMULATOR_H 1
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "ui48_config.h"
|
||||
|
||||
// Keys
|
||||
#define HPKEY_A 0
|
||||
#define HPKEY_B 1
|
||||
#define HPKEY_C 2
|
||||
#define HPKEY_D 3
|
||||
#define HPKEY_E 4
|
||||
#define HPKEY_F 5
|
||||
|
||||
#define HPKEY_MTH 6
|
||||
#define HPKEY_PRG 7
|
||||
#define HPKEY_CST 8
|
||||
#define HPKEY_VAR 9
|
||||
#define HPKEY_UP 10
|
||||
#define HPKEY_NXT 11
|
||||
|
||||
#define HPKEY_QUOTE 12
|
||||
#define HPKEY_STO 13
|
||||
#define HPKEY_EVAL 14
|
||||
#define HPKEY_LEFT 15
|
||||
#define HPKEY_DOWN 16
|
||||
#define HPKEY_RIGHT 17
|
||||
|
||||
#define HPKEY_SIN 18
|
||||
#define HPKEY_COS 19
|
||||
#define HPKEY_TAN 20
|
||||
#define HPKEY_SQRT 21
|
||||
#define HPKEY_POWER 22
|
||||
#define HPKEY_INV 23
|
||||
|
||||
#define HPKEY_ENTER 24
|
||||
#define HPKEY_NEG 25
|
||||
#define HPKEY_EEX 26
|
||||
#define HPKEY_DEL 27
|
||||
#define HPKEY_BS 28
|
||||
|
||||
#define HPKEY_ALPHA 29
|
||||
#define HPKEY_7 30
|
||||
#define HPKEY_8 31
|
||||
#define HPKEY_9 32
|
||||
#define HPKEY_DIV 33
|
||||
|
||||
#define HPKEY_SHL 34
|
||||
#define HPKEY_4 35
|
||||
#define HPKEY_5 36
|
||||
#define HPKEY_6 37
|
||||
#define HPKEY_MUL 38
|
||||
|
||||
#define HPKEY_SHR 39
|
||||
#define HPKEY_1 40
|
||||
#define HPKEY_2 41
|
||||
#define HPKEY_3 42
|
||||
#define HPKEY_MINUS 43
|
||||
|
||||
#define HPKEY_ON 44
|
||||
#define HPKEY_0 45
|
||||
#define HPKEY_PERIOD 46
|
||||
#define HPKEY_SPC 47
|
||||
#define HPKEY_PLUS 48
|
||||
|
||||
#define FIRST_HPKEY HPKEY_A
|
||||
#define LAST_HPKEY HPKEY_PLUS
|
||||
#define NB_KEYS ( LAST_HPKEY + 1 )
|
||||
|
||||
#define KEYS_BUFFER_SIZE 9
|
||||
|
||||
// Annunciators
|
||||
#define NB_ANNUNCIATORS 6
|
||||
|
||||
#define ANN_LEFT 0x81
|
||||
#define ANN_RIGHT 0x82
|
||||
#define ANN_ALPHA 0x84
|
||||
#define ANN_BATTERY 0x88
|
||||
#define ANN_BUSY 0x90
|
||||
#define ANN_IO 0xa0
|
||||
|
||||
// LCD
|
||||
#define NIBBLES_PER_ROW 34
|
||||
#define LCD_WIDTH 131
|
||||
#define LCD_HEIGHT 64
|
||||
|
||||
/*************************************************/
|
||||
/* public API: if it's there it's used elsewhere */
|
||||
/*************************************************/
|
||||
extern void press_key( int hpkey );
|
||||
extern void release_key( int hpkey );
|
||||
extern bool is_key_pressed( int hpkey );
|
||||
|
||||
extern void init_emulator( config_t* conf );
|
||||
extern void exit_emulator( void );
|
||||
|
||||
extern unsigned char get_annunciators( void );
|
||||
extern bool get_display_state( void );
|
||||
extern void get_lcd_buffer( int* target );
|
||||
extern int get_contrast( void );
|
||||
|
||||
#endif /* !_UI48_EMULATOR_H */
|
93
src/ui48_inner.h
Normal file
93
src/ui48_inner.h
Normal file
|
@ -0,0 +1,93 @@
|
|||
#ifndef _UI48_INNER_H
|
||||
#define _UI48_INNER_H 1
|
||||
|
||||
#include "ui48_emulator.h"
|
||||
|
||||
#include "ui48_bitmaps_misc.h"
|
||||
#include "ui48_bitmaps_small_font.h"
|
||||
#include "ui48_bitmaps_big_font.h"
|
||||
|
||||
// Colors
|
||||
/* SX GX */
|
||||
#define WHITE 0 /* #ffffff #ffffff */
|
||||
#define LEFT 1 /* #ffa600 #ffbaff */
|
||||
#define RIGHT 2 /* #00d2ff #00ffcc */
|
||||
#define BUT_TOP 3 /* #6d5d5d #646464 */
|
||||
#define BUTTON 4 /* #5a4d4d #585858 */
|
||||
#define BUT_BOT 5 /* #4c4141 #4a4a4a */
|
||||
#define LCD 6 /* #cadd5c #cadd5c */
|
||||
#define PIXEL 7 /* #000080 #000080 */
|
||||
#define PAD_TOP 8 /* #6d4e4e #585858 */
|
||||
#define PAD 9 /* #5a4040 #4a4a4a */
|
||||
#define PAD_BOT 10 /* #4c3636 #404040 */
|
||||
#define DISP_PAD_TOP 11 /* #9b7654 #808080 */
|
||||
#define DISP_PAD 12 /* #7c5e43 #68686e */
|
||||
#define DISP_PAD_BOT 13 /* #644b35 #54545a */
|
||||
#define LOGO 14 /* #cca96b #b0b0b8 */
|
||||
#define LOGO_BACK 15 /* #404040 #68686e */
|
||||
#define LABEL 16 /* #cab890 #f0f0f0 */
|
||||
#define FRAME 17 /* #000000 #000000 */
|
||||
#define UNDERLAY 18 /* #3c2a2a #68686e */
|
||||
#define BLACK 19 /* #000000 #000000 */
|
||||
|
||||
#define FIRST_COLOR WHITE
|
||||
#define LAST_COLOR BLACK
|
||||
#define NB_COLORS ( LAST_COLOR + 1 )
|
||||
|
||||
/***********/
|
||||
/* typedef */
|
||||
/***********/
|
||||
typedef struct letter_t {
|
||||
unsigned int w, h;
|
||||
unsigned char* bits;
|
||||
} letter_t;
|
||||
|
||||
typedef struct color_t {
|
||||
const char* name;
|
||||
int r, g, b, a;
|
||||
int mono_rgb;
|
||||
int gray_rgb;
|
||||
} color_t;
|
||||
|
||||
typedef struct button_t {
|
||||
const char* name;
|
||||
|
||||
int x, y;
|
||||
int w, h;
|
||||
|
||||
int lc;
|
||||
const char* label;
|
||||
short font_size;
|
||||
unsigned int lw, lh;
|
||||
unsigned char* lb;
|
||||
|
||||
const char* letter;
|
||||
|
||||
const char* left;
|
||||
short is_menu;
|
||||
const char* right;
|
||||
const char* sub;
|
||||
} button_t;
|
||||
|
||||
/*************/
|
||||
/* variables */
|
||||
/*************/
|
||||
extern letter_t small_font[ 128 ];
|
||||
extern letter_t big_font[ 128 ];
|
||||
|
||||
extern color_t colors_sx[ NB_COLORS ];
|
||||
extern color_t colors_gx[ NB_COLORS ];
|
||||
|
||||
extern button_t buttons_sx[ NB_KEYS ];
|
||||
extern button_t buttons_gx[ NB_KEYS ];
|
||||
|
||||
#define small_ascent 8
|
||||
#define small_descent 4
|
||||
|
||||
/*************/
|
||||
/* functions */
|
||||
/*************/
|
||||
extern int SmallTextWidth( const char* string, unsigned int length );
|
||||
extern int BigTextWidth( const char* string, unsigned int length );
|
||||
|
||||
#endif /* _UI48_INNER_H */
|
196
src/ui48_main.c
Normal file
196
src/ui48_main.c
Normal file
|
@ -0,0 +1,196 @@
|
|||
#include <signal.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#include "ui48_config.h"
|
||||
#include "ui48_emulator.h"
|
||||
#include "ui48_common.h"
|
||||
|
||||
#include "config.h"
|
||||
#include "cpu.h"
|
||||
#include "monitor.h"
|
||||
|
||||
#define SPEED_HZ_UI 64
|
||||
|
||||
/* Chf condition codes (main program only) */
|
||||
|
||||
#define CHF_MODULE_ID MAIN_CHF_MODULE_ID
|
||||
#include <Chf.h>
|
||||
|
||||
#define MAIN_M_COPYRIGHT 501
|
||||
#define MAIN_M_LICENSE 502
|
||||
|
||||
/*---------------------------------------------------------------------------
|
||||
Chf parameters - Do not change.
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
#define CONDITION_STACK_SIZE 16
|
||||
#define HANDLER_STACK_SIZE 8
|
||||
|
||||
/* Conditional prefix and mandatory suffix to make a message catalog
|
||||
name from argv[0]
|
||||
*/
|
||||
static const char cat_prefix[] = "./";
|
||||
static const char cat_suffix[] = ".cat";
|
||||
|
||||
#define CAT_PREFIX_LEN ( sizeof( cat_prefix ) + 1 )
|
||||
#define CAT_SUFFIX_LEN ( sizeof( cat_suffix ) + 1 )
|
||||
|
||||
static void adjust_setlocale( void )
|
||||
{
|
||||
fprintf( stderr, "saturn-W-locale probably bad; reverting to C locale\n" );
|
||||
|
||||
putenv( "LC_ALL=C" );
|
||||
putenv( "LC_COLLATE=C" );
|
||||
putenv( "LC_CTYPE=C" );
|
||||
putenv( "LC_MESSAGES=C" );
|
||||
putenv( "LC_MONETARY=C" );
|
||||
putenv( "LC_NUMERIC=C" );
|
||||
putenv( "LC_TIME=C" );
|
||||
putenv( "LANG=C" );
|
||||
}
|
||||
|
||||
void signal_handler( int sig )
|
||||
{
|
||||
switch ( sig ) {
|
||||
/* case SIGINT: /\* Ctrl-C *\/ */
|
||||
/* enter_debugger |= USER_INTERRUPT; */
|
||||
/* break; */
|
||||
case SIGALRM:
|
||||
ui_get_event();
|
||||
ui_update_display();
|
||||
break;
|
||||
case SIGPIPE:
|
||||
ui_stop();
|
||||
exit_emulator();
|
||||
exit( 0 );
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int main( int argc, char** argv )
|
||||
{
|
||||
config_t* config = config_init( argc, argv );
|
||||
char* cat_name;
|
||||
int st;
|
||||
int retry = 0;
|
||||
|
||||
if ( ( cat_name = malloc( strlen( argv[ 0 ] ) + CAT_PREFIX_LEN + CAT_SUFFIX_LEN + 1 ) ) == NULL ) {
|
||||
fprintf( stderr, "saturn-E-cat_name initialization failed\n" );
|
||||
exit( EXIT_FAILURE );
|
||||
}
|
||||
|
||||
/* Generate catalog name, without optional prefix */
|
||||
strcpy( cat_name, argv[ 0 ] );
|
||||
strcat( cat_name, cat_suffix );
|
||||
|
||||
/* 3.15: Retry the initialization steps below two times; before trying
|
||||
the second time, adjust the setlocale() environment variables
|
||||
with adjust_setlocale()
|
||||
*/
|
||||
while ( retry < 2 ) {
|
||||
/* Chf initialization with msgcat subsystem; notice that on
|
||||
some systems (e.g. Digital UNIX) catopen() can succeed even
|
||||
if it was not able to open the right message catalog;
|
||||
better try it now.
|
||||
*/
|
||||
if ( ( st = ChfMsgcatInit( argv[ 0 ], /* Application's name */
|
||||
CHF_DEFAULT, /* Options */
|
||||
cat_name, /* Name of the message catalog */
|
||||
CONDITION_STACK_SIZE, /* Size of the condition stack */
|
||||
HANDLER_STACK_SIZE, /* Size of the handler stack */
|
||||
EXIT_FAILURE /* Abnormal exit code */
|
||||
) ) != CHF_S_OK ||
|
||||
ChfGetMessage( CHF_MODULE_ID, MAIN_M_COPYRIGHT, NULL ) == NULL )
|
||||
fprintf( stderr, "saturn-E-Primary Chf initialization failed (%d)\n", st );
|
||||
else
|
||||
break;
|
||||
|
||||
/* Bring down Chf before initializing it again */
|
||||
if ( st == CHF_S_OK )
|
||||
ChfExit();
|
||||
|
||||
/* Try alternate message catalog name (with prefix) */
|
||||
strcpy( cat_name, cat_prefix );
|
||||
strcat( cat_name, argv[ 0 ] );
|
||||
strcat( cat_name, cat_suffix );
|
||||
|
||||
if ( ( st = ChfMsgcatInit( argv[ 0 ], /* Application's name */
|
||||
CHF_DEFAULT, /* Options */
|
||||
cat_name, /* Name of the message catalog */
|
||||
CONDITION_STACK_SIZE, /* Size of the condition stack */
|
||||
HANDLER_STACK_SIZE, /* Size of the handler stack */
|
||||
EXIT_FAILURE /* Abnormal exit code */
|
||||
) ) != CHF_S_OK ||
|
||||
ChfGetMessage( CHF_MODULE_ID, MAIN_M_COPYRIGHT, NULL ) == NULL )
|
||||
fprintf( stderr, "saturn-E-Alternate Chf initialization failed (%d)\n", st );
|
||||
else
|
||||
break;
|
||||
|
||||
/* Bring down Chf before initializing it again */
|
||||
if ( st == CHF_S_OK )
|
||||
ChfExit();
|
||||
|
||||
/* Attempt to adjust setlocale() environment variables */
|
||||
if ( retry++ == 0 )
|
||||
adjust_setlocale();
|
||||
}
|
||||
|
||||
if ( retry == 2 ) {
|
||||
fprintf( stderr, "saturn-F-Application aborted\n" );
|
||||
exit( EXIT_FAILURE );
|
||||
}
|
||||
|
||||
/* cat_name no longer needed */
|
||||
free( cat_name );
|
||||
|
||||
/* 3.9: Print out MAIN_M_COPYRIGHT and MAIN_M_LICENSE on stdout now */
|
||||
fprintf( stdout, ChfGetMessage( CHF_MODULE_ID, MAIN_M_COPYRIGHT, "" ), "$Revision: 4.1 $" );
|
||||
/* fprintf( stdout, ChfGetMessage( CHF_MODULE_ID, MAIN_M_LICENSE, "" ) ); */
|
||||
|
||||
init_emulator( config );
|
||||
|
||||
/* (G)UI */
|
||||
setup_ui( config );
|
||||
ui_start( config );
|
||||
|
||||
sigset_t set;
|
||||
struct sigaction sa;
|
||||
sigemptyset( &set );
|
||||
sigaddset( &set, SIGALRM );
|
||||
sa.sa_handler = signal_handler;
|
||||
sa.sa_mask = set;
|
||||
#ifdef SA_RESTART
|
||||
sa.sa_flags = SA_RESTART;
|
||||
#endif
|
||||
sigaction( SIGALRM, &sa, ( struct sigaction* )0 );
|
||||
|
||||
/************************************/
|
||||
/* set the real time interval timer */
|
||||
/************************************/
|
||||
/*
|
||||
Every <interval>µs setitimer will trigger a SIGALRM
|
||||
which will getUI events and refresh UI in signal_handler
|
||||
*/
|
||||
struct itimerval it;
|
||||
it.it_interval.tv_sec = 0;
|
||||
it.it_interval.tv_usec = 1000000 / SPEED_HZ_UI;
|
||||
it.it_value.tv_sec = 0;
|
||||
it.it_value.tv_usec = 1000000 / SPEED_HZ_UI;
|
||||
setitimer( ITIMER_REAL, &it, ( struct itimerval* )0 );
|
||||
|
||||
if ( config->monitor )
|
||||
/* Invoke Monitor */
|
||||
Monitor();
|
||||
else
|
||||
/* Call Emulator directly */
|
||||
Emulator();
|
||||
|
||||
/* never reached */
|
||||
return EXIT_SUCCESS;
|
||||
}
|
|
@ -14,13 +14,13 @@
|
|||
|
||||
#include <curses.h>
|
||||
|
||||
#include "config.h"
|
||||
#include "emulator.h"
|
||||
#include "common.h"
|
||||
#include "inner.h"
|
||||
#include "ui48_config.h"
|
||||
#include "ui48_emulator.h"
|
||||
#include "ui48_common.h"
|
||||
#include "ui48_inner.h"
|
||||
|
||||
#define COLORS ( config.model == MODEL_48GX ? colors_48gx : ( config.model == MODEL_49G ? colors_49g : colors_48sx ) )
|
||||
#define BUTTONS ( config.model == MODEL_48GX ? buttons_48gx : ( config.model == MODEL_49G ? buttons_49g : buttons_48sx ) )
|
||||
#define COLORS ( config.model == MODEL_48GX ? colors_gx : colors_sx )
|
||||
#define BUTTONS ( config.model == MODEL_48GX ? buttons_gx : buttons_sx )
|
||||
|
||||
#define LCD_OFFSET_X 1
|
||||
#define LCD_OFFSET_Y 1
|
||||
|
@ -38,7 +38,7 @@
|
|||
/* variables */
|
||||
/*************/
|
||||
static config_t config;
|
||||
static int lcd_pixels_buffer[ LCD_WIDTH * 80 ];
|
||||
static int lcd_pixels_buffer[ LCD_WIDTH * LCD_HEIGHT ];
|
||||
static int last_annunciators = -1;
|
||||
// static int last_contrast = -1;
|
||||
|
||||
|
@ -259,179 +259,170 @@ void ui_get_event_ncurses( void )
|
|||
|
||||
switch ( k ) {
|
||||
case '0':
|
||||
hpkey = ( config.model == MODEL_49G ? HP49_KEY_0 : HP48_KEY_0 );
|
||||
hpkey = HPKEY_0;
|
||||
break;
|
||||
case '1':
|
||||
hpkey = ( config.model == MODEL_49G ? HP49_KEY_1 : HP48_KEY_1 );
|
||||
hpkey = HPKEY_1;
|
||||
break;
|
||||
case '2':
|
||||
hpkey = ( config.model == MODEL_49G ? HP49_KEY_2 : HP48_KEY_2 );
|
||||
hpkey = HPKEY_2;
|
||||
break;
|
||||
case '3':
|
||||
hpkey = ( config.model == MODEL_49G ? HP49_KEY_3 : HP48_KEY_3 );
|
||||
hpkey = HPKEY_3;
|
||||
break;
|
||||
case '4':
|
||||
hpkey = ( config.model == MODEL_49G ? HP49_KEY_4 : HP48_KEY_4 );
|
||||
hpkey = HPKEY_4;
|
||||
break;
|
||||
case '5':
|
||||
hpkey = ( config.model == MODEL_49G ? HP49_KEY_5 : HP48_KEY_5 );
|
||||
hpkey = HPKEY_5;
|
||||
break;
|
||||
case '6':
|
||||
hpkey = ( config.model == MODEL_49G ? HP49_KEY_6 : HP48_KEY_6 );
|
||||
hpkey = HPKEY_6;
|
||||
break;
|
||||
case '7':
|
||||
hpkey = ( config.model == MODEL_49G ? HP49_KEY_7 : HP48_KEY_7 );
|
||||
hpkey = HPKEY_7;
|
||||
break;
|
||||
case '8':
|
||||
hpkey = ( config.model == MODEL_49G ? HP49_KEY_8 : HP48_KEY_8 );
|
||||
hpkey = HPKEY_8;
|
||||
break;
|
||||
case '9':
|
||||
hpkey = ( config.model == MODEL_49G ? HP49_KEY_9 : HP48_KEY_9 );
|
||||
hpkey = HPKEY_9;
|
||||
break;
|
||||
case 'a':
|
||||
hpkey = ( config.model == MODEL_49G ? HP49_KEY_A : HP48_KEY_A );
|
||||
hpkey = HPKEY_A;
|
||||
break;
|
||||
case 'b':
|
||||
hpkey = ( config.model == MODEL_49G ? HP49_KEY_B : HP48_KEY_B );
|
||||
hpkey = HPKEY_B;
|
||||
break;
|
||||
case 'c':
|
||||
hpkey = ( config.model == MODEL_49G ? HP49_KEY_C : HP48_KEY_C );
|
||||
hpkey = HPKEY_C;
|
||||
break;
|
||||
case 'd':
|
||||
hpkey = ( config.model == MODEL_49G ? HP49_KEY_D : HP48_KEY_D );
|
||||
hpkey = HPKEY_D;
|
||||
break;
|
||||
case 'e':
|
||||
hpkey = ( config.model == MODEL_49G ? HP49_KEY_E : HP48_KEY_E );
|
||||
hpkey = HPKEY_E;
|
||||
break;
|
||||
case 'f':
|
||||
hpkey = ( config.model == MODEL_49G ? HP49_KEY_F : HP48_KEY_F );
|
||||
hpkey = HPKEY_F;
|
||||
break;
|
||||
case 'g':
|
||||
hpkey = ( config.model == MODEL_49G ? HP49_KEY_APPS : HP48_KEY_MTH );
|
||||
hpkey = HPKEY_MTH;
|
||||
break;
|
||||
case 'h':
|
||||
hpkey = ( config.model == MODEL_49G ? HP49_KEY_MODE : HP48_KEY_PRG );
|
||||
hpkey = HPKEY_PRG;
|
||||
break;
|
||||
case 'i':
|
||||
hpkey = ( config.model == MODEL_49G ? HP49_KEY_TOOL : HP48_KEY_CST );
|
||||
hpkey = HPKEY_CST;
|
||||
break;
|
||||
case 'j':
|
||||
hpkey = ( config.model == MODEL_49G ? HP49_KEY_VAR : HP48_KEY_VAR );
|
||||
hpkey = HPKEY_VAR;
|
||||
break;
|
||||
case 'k':
|
||||
hpkey = ( config.model == MODEL_49G ? HP49_KEY_STO : HP48_KEY_UP );
|
||||
break;
|
||||
case KEY_UP:
|
||||
hpkey = ( config.model == MODEL_49G ? HP49_KEY_UP : HP48_KEY_UP );
|
||||
hpkey = HPKEY_UP;
|
||||
break;
|
||||
case 'l':
|
||||
hpkey = ( config.model == MODEL_49G ? HP49_KEY_NXT : HP48_KEY_NXT );
|
||||
hpkey = HPKEY_NXT;
|
||||
break;
|
||||
case 'm':
|
||||
hpkey = ( config.model == MODEL_49G ? HP49_KEY_HIST : HP48_KEY_QUOTE );
|
||||
hpkey = HPKEY_QUOTE;
|
||||
break;
|
||||
case 'n':
|
||||
hpkey = ( config.model == MODEL_49G ? HP49_KEY_CAT : HP48_KEY_STO );
|
||||
hpkey = HPKEY_STO;
|
||||
break;
|
||||
case 'o':
|
||||
hpkey = ( config.model == MODEL_49G ? HP49_KEY_EQW : HP48_KEY_EVAL );
|
||||
hpkey = HPKEY_EVAL;
|
||||
break;
|
||||
case 'p':
|
||||
hpkey = ( config.model == MODEL_49G ? HP49_KEY_SYMB : HP48_KEY_LEFT );
|
||||
break;
|
||||
case KEY_LEFT:
|
||||
hpkey = ( config.model == MODEL_49G ? HP49_KEY_LEFT : HP48_KEY_LEFT );
|
||||
hpkey = HPKEY_LEFT;
|
||||
break;
|
||||
case 'q':
|
||||
hpkey = ( config.model == MODEL_49G ? HP49_KEY_POWER : HP48_KEY_DOWN );
|
||||
break;
|
||||
case KEY_DOWN:
|
||||
hpkey = ( config.model == MODEL_49G ? HP49_KEY_DOWN : HP48_KEY_DOWN );
|
||||
hpkey = HPKEY_DOWN;
|
||||
break;
|
||||
case 'r':
|
||||
hpkey = ( config.model == MODEL_49G ? HP49_KEY_SQRT : HP48_KEY_RIGHT );
|
||||
break;
|
||||
case KEY_RIGHT:
|
||||
hpkey = ( config.model == MODEL_49G ? HP49_KEY_RIGHT : HP48_KEY_RIGHT );
|
||||
hpkey = HPKEY_RIGHT;
|
||||
break;
|
||||
case 's':
|
||||
hpkey = ( config.model == MODEL_49G ? HP49_KEY_SIN : HP48_KEY_SIN );
|
||||
hpkey = HPKEY_SIN;
|
||||
break;
|
||||
case 't':
|
||||
hpkey = ( config.model == MODEL_49G ? HP49_KEY_COS : HP48_KEY_COS );
|
||||
hpkey = HPKEY_COS;
|
||||
break;
|
||||
case 'u':
|
||||
hpkey = ( config.model == MODEL_49G ? HP49_KEY_TAN : HP48_KEY_TAN );
|
||||
hpkey = HPKEY_TAN;
|
||||
break;
|
||||
case 'v':
|
||||
hpkey = ( config.model == MODEL_49G ? HP49_KEY_EEX : HP48_KEY_SQRT );
|
||||
hpkey = HPKEY_SQRT;
|
||||
break;
|
||||
case 'w':
|
||||
hpkey = ( config.model == MODEL_49G ? HP49_KEY_NEG : HP48_KEY_POWER );
|
||||
hpkey = HPKEY_POWER;
|
||||
break;
|
||||
case 'x':
|
||||
hpkey = ( config.model == MODEL_49G ? HP49_KEY_X : HP48_KEY_INV );
|
||||
hpkey = HPKEY_INV;
|
||||
break;
|
||||
case 'y':
|
||||
hpkey = ( config.model == MODEL_49G ? HP49_KEY_INV : HP48_KEY_NEG );
|
||||
hpkey = HPKEY_NEG;
|
||||
break;
|
||||
case 'z':
|
||||
hpkey = ( config.model == MODEL_49G ? HP49_KEY_DIV : HP48_KEY_EEX );
|
||||
hpkey = HPKEY_EEX;
|
||||
break;
|
||||
case ' ':
|
||||
hpkey = ( config.model == MODEL_49G ? HP49_KEY_SPC : HP48_KEY_SPC );
|
||||
hpkey = HPKEY_SPC;
|
||||
break;
|
||||
case KEY_DC:
|
||||
hpkey = ( config.model == MODEL_49G ? -1 : HP48_KEY_DEL );
|
||||
hpkey = HPKEY_DEL;
|
||||
break;
|
||||
case '.':
|
||||
hpkey = ( config.model == MODEL_49G ? HP49_KEY_PERIOD : HP48_KEY_PERIOD );
|
||||
hpkey = HPKEY_PERIOD;
|
||||
break;
|
||||
case '+':
|
||||
hpkey = ( config.model == MODEL_49G ? HP49_KEY_PLUS : HP48_KEY_PLUS );
|
||||
hpkey = HPKEY_PLUS;
|
||||
break;
|
||||
case '-':
|
||||
hpkey = ( config.model == MODEL_49G ? HP49_KEY_MINUS : HP48_KEY_MINUS );
|
||||
hpkey = HPKEY_MINUS;
|
||||
break;
|
||||
case '*':
|
||||
hpkey = ( config.model == MODEL_49G ? HP49_KEY_MUL : HP48_KEY_MUL );
|
||||
hpkey = HPKEY_MUL;
|
||||
break;
|
||||
case '/':
|
||||
hpkey = ( config.model == MODEL_49G ? HP49_KEY_DIV : HP48_KEY_DIV );
|
||||
hpkey = HPKEY_DIV;
|
||||
break;
|
||||
|
||||
case KEY_F( 1 ):
|
||||
case KEY_ENTER:
|
||||
case '\n':
|
||||
case ',':
|
||||
case 13:
|
||||
hpkey = ( config.model == MODEL_49G ? HP49_KEY_ENTER : HP48_KEY_ENTER );
|
||||
hpkey = HPKEY_ENTER;
|
||||
break;
|
||||
case KEY_BACKSPACE:
|
||||
case 127:
|
||||
case '\b':
|
||||
hpkey = ( config.model == MODEL_49G ? HP49_KEY_BS : HP48_KEY_BS );
|
||||
hpkey = HPKEY_BS;
|
||||
break;
|
||||
case KEY_F( 2 ):
|
||||
case '[':
|
||||
case 339: /* PgUp */
|
||||
hpkey = ( config.model == MODEL_49G ? HP49_KEY_SHL : HP48_KEY_SHL );
|
||||
hpkey = HPKEY_SHL;
|
||||
break;
|
||||
case KEY_F( 3 ):
|
||||
case ']':
|
||||
case 338: /* PgDn */
|
||||
hpkey = ( config.model == MODEL_49G ? HP49_KEY_SHR : HP48_KEY_SHR );
|
||||
hpkey = HPKEY_SHR;
|
||||
break;
|
||||
case KEY_F( 4 ):
|
||||
case ';':
|
||||
case KEY_IC: /* Ins */
|
||||
hpkey = ( config.model == MODEL_49G ? HP49_KEY_ALPHA : HP48_KEY_ALPHA );
|
||||
hpkey = HPKEY_ALPHA;
|
||||
break;
|
||||
case KEY_F( 5 ):
|
||||
case '\\':
|
||||
case 27: /* Esc */
|
||||
case 262: /* Home */
|
||||
hpkey = ( config.model == MODEL_49G ? HP49_KEY_ON : HP48_KEY_ON );
|
||||
hpkey = HPKEY_ON;
|
||||
break;
|
||||
|
||||
case KEY_F( 7 ):
|
||||
|
@ -443,7 +434,7 @@ void ui_get_event_ncurses( void )
|
|||
break;
|
||||
}
|
||||
|
||||
if ( hpkey > 0 && !is_key_pressed( hpkey ) )
|
||||
if ( !is_key_pressed( hpkey ) )
|
||||
press_key( hpkey );
|
||||
}
|
||||
}
|
||||
|
@ -457,6 +448,9 @@ void ui_stop_ncurses( void )
|
|||
|
||||
void ui_start_ncurses( config_t* conf )
|
||||
{
|
||||
if ( config.verbose )
|
||||
fprintf( stderr, "UI is ncurses\n" );
|
||||
|
||||
config = *conf;
|
||||
|
||||
setlocale( LC_ALL, "" );
|
||||
|
@ -472,15 +466,11 @@ void ui_start_ncurses( config_t* conf )
|
|||
start_color();
|
||||
|
||||
if ( config.gray ) {
|
||||
init_color( LCD_COLOR_BG, COLORS[ UI4X_COLOR_PIXEL_OFF ].gray_rgb, COLORS[ UI4X_COLOR_PIXEL_OFF ].gray_rgb,
|
||||
COLORS[ UI4X_COLOR_PIXEL_OFF ].gray_rgb );
|
||||
init_color( LCD_COLOR_FG, COLORS[ UI4X_COLOR_PIXEL_ON ].gray_rgb, COLORS[ UI4X_COLOR_PIXEL_ON ].gray_rgb,
|
||||
COLORS[ UI4X_COLOR_PIXEL_ON ].gray_rgb );
|
||||
init_color( LCD_COLOR_BG, COLORS[ LCD ].gray_rgb, COLORS[ LCD ].gray_rgb, COLORS[ LCD ].gray_rgb );
|
||||
init_color( LCD_COLOR_FG, COLORS[ PIXEL ].gray_rgb, COLORS[ PIXEL ].gray_rgb, COLORS[ PIXEL ].gray_rgb );
|
||||
} else {
|
||||
init_color( LCD_COLOR_BG, ( COLORS[ UI4X_COLOR_PIXEL_OFF ].rgb >> 16 ) & 0xff,
|
||||
( COLORS[ UI4X_COLOR_PIXEL_OFF ].rgb >> 8 ) & 0xff, COLORS[ UI4X_COLOR_PIXEL_OFF ].rgb & 0xff );
|
||||
init_color( LCD_COLOR_BG, ( COLORS[ UI4X_COLOR_PIXEL_ON ].rgb >> 16 ) & 0xff, ( COLORS[ UI4X_COLOR_PIXEL_ON ].rgb >> 8 ) & 0xff,
|
||||
COLORS[ UI4X_COLOR_PIXEL_ON ].rgb & 0xff );
|
||||
init_color( LCD_COLOR_BG, COLORS[ LCD ].r, COLORS[ LCD ].g, COLORS[ LCD ].b );
|
||||
init_color( LCD_COLOR_FG, COLORS[ PIXEL ].r, COLORS[ PIXEL ].g, COLORS[ PIXEL ].b );
|
||||
}
|
||||
|
||||
init_pair( LCD_PIXEL_OFF, LCD_COLOR_BG, LCD_COLOR_BG );
|
6
src/ui48_ncurses.h
Normal file
6
src/ui48_ncurses.h
Normal file
|
@ -0,0 +1,6 @@
|
|||
#ifndef _UI48_NCURSES_H
|
||||
#define _UI48_NCURSES_H 1
|
||||
|
||||
extern void setup_frontend_ncurses( void );
|
||||
|
||||
#endif /* _UI48_NCURSES_H */
|
1110
src/ui48_sdl2.c
Normal file
1110
src/ui48_sdl2.c
Normal file
File diff suppressed because it is too large
Load diff
6
src/ui48_sdl2.h
Normal file
6
src/ui48_sdl2.h
Normal file
|
@ -0,0 +1,6 @@
|
|||
#ifndef _UI48_SDL2_H
|
||||
#define _UI48_SDL2_H 1
|
||||
|
||||
extern void setup_frontend_sdl( void );
|
||||
|
||||
#endif /* _UI48_SDL2_H */
|
908
src/ui4x/48gx.c
908
src/ui4x/48gx.c
|
@ -1,908 +0,0 @@
|
|||
#include "inner.h"
|
||||
|
||||
color_t colors_48gx[ NB_COLORS ] = {
|
||||
/* UI4X_COLOR_HP_LOGO */
|
||||
{
|
||||
.a = 0xFF,
|
||||
.mono_rgb = 0xFF,
|
||||
.gray_rgb = 0xB0,
|
||||
.rgb = 0xB0B0B8,
|
||||
},
|
||||
/* UI4X_COLOR_HP_LOGO_BG */
|
||||
{
|
||||
.a = 0xFF,
|
||||
.mono_rgb = 0x0,
|
||||
.gray_rgb = 0x68,
|
||||
.rgb = 0x68686E,
|
||||
},
|
||||
/* UI4X_COLOR_48GX_128K_RAM */
|
||||
{
|
||||
.a = 0xFF,
|
||||
.mono_rgb = 0xFF,
|
||||
.gray_rgb = 0xF0,
|
||||
.rgb = 0xF0F0F0,
|
||||
},
|
||||
/* UI4X_COLOR_FRAME */
|
||||
{
|
||||
.a = 0xFF,
|
||||
.mono_rgb = 0xFF,
|
||||
.gray_rgb = 0x0,
|
||||
.rgb = 0x000000,
|
||||
},
|
||||
/* UI4X_COLOR_UPPER_FACEPLATE_EDGE_TOP */
|
||||
{
|
||||
.a = 0xFF,
|
||||
.mono_rgb = 0x0,
|
||||
.gray_rgb = 0x80,
|
||||
.rgb = 0x80808A,
|
||||
},
|
||||
/* UI4X_COLOR_UPPER_FACEPLATE */
|
||||
{
|
||||
.a = 0xFF,
|
||||
.mono_rgb = 0x0,
|
||||
.gray_rgb = 0x68,
|
||||
.rgb = 0x68686E,
|
||||
},
|
||||
/* UI4X_COLOR_UPPER_FACEPLATE_EDGE_BOTTOM */
|
||||
{
|
||||
.a = 0xFF,
|
||||
.mono_rgb = 0x0,
|
||||
.gray_rgb = 0x54,
|
||||
.rgb = 0x54545A,
|
||||
},
|
||||
/* UI4X_COLOR_FACEPLATE_EDGE_TOP */
|
||||
{
|
||||
.a = 0xFF,
|
||||
.mono_rgb = 0x0,
|
||||
.gray_rgb = 0x58,
|
||||
.rgb = 0x585858,
|
||||
},
|
||||
/* UI4X_COLOR_FACEPLATE */
|
||||
{
|
||||
.a = 0xFF,
|
||||
.mono_rgb = 0x0,
|
||||
.gray_rgb = 0x4A,
|
||||
.rgb = 0x4A4A4A,
|
||||
},
|
||||
/* UI4X_COLOR_FACEPLATE_EDGE_BOTTOM */
|
||||
{
|
||||
.a = 0xFF,
|
||||
.mono_rgb = 0x0,
|
||||
.gray_rgb = 0x40,
|
||||
.rgb = 0x404040,
|
||||
},
|
||||
/* UI4X_COLOR_KEYPAD_HIGHLIGHT */
|
||||
{
|
||||
.a = 0xFF,
|
||||
.mono_rgb = 0x0,
|
||||
.gray_rgb = 0x68,
|
||||
.rgb = 0x68686E,
|
||||
},
|
||||
/* UI4X_COLOR_BUTTON_EDGE_TOP */
|
||||
{
|
||||
.a = 0xFF,
|
||||
.mono_rgb = 0x0,
|
||||
.gray_rgb = 0x68,
|
||||
.rgb = 0x686868,
|
||||
},
|
||||
/* UI4X_COLOR_BUTTON */
|
||||
{
|
||||
.a = 0xFF,
|
||||
.mono_rgb = 0x0,
|
||||
.gray_rgb = 0x58,
|
||||
.rgb = 0x585858,
|
||||
},
|
||||
/* UI4X_COLOR_BUTTON_EDGE_BOTTOM */
|
||||
{
|
||||
.a = 0xFF,
|
||||
.mono_rgb = 0x0,
|
||||
.gray_rgb = 0x4A,
|
||||
.rgb = 0x4A4A4A,
|
||||
},
|
||||
/* UI4X_COLOR_PIXEL_OFF */
|
||||
{
|
||||
.a = 0xFF,
|
||||
.mono_rgb = 0xFF,
|
||||
.gray_rgb = 0xCD,
|
||||
.rgb = 0xCADD5C,
|
||||
},
|
||||
/* UI4X_COLOR_PIXEL_ON */
|
||||
{
|
||||
.a = 0xFF,
|
||||
.mono_rgb = 0x0,
|
||||
.gray_rgb = 0x14,
|
||||
.rgb = 0x000080,
|
||||
},
|
||||
/* UI4X_COLOR_BLACK_PIXEL_OFF */
|
||||
{
|
||||
.a = 0xFF,
|
||||
.mono_rgb = 0xFF,
|
||||
.gray_rgb = 0xCD,
|
||||
.rgb = 0xf5f5f5,
|
||||
},
|
||||
/* UI4X_COLOR_BLACK_PIXEL_ON */
|
||||
{
|
||||
.a = 0xFF,
|
||||
.mono_rgb = 0x0,
|
||||
.gray_rgb = 0x14,
|
||||
.rgb = 0x000000,
|
||||
},
|
||||
/* UI4X_COLOR_LABEL */
|
||||
{
|
||||
.a = 0xFF,
|
||||
.mono_rgb = 0xFF,
|
||||
.gray_rgb = 0xFF,
|
||||
.rgb = 0xFFFFFF,
|
||||
},
|
||||
/* UI4X_COLOR_ALPHA */
|
||||
{
|
||||
.a = 0xFF,
|
||||
.mono_rgb = 0xFF,
|
||||
.gray_rgb = 0xFF,
|
||||
.rgb = 0xFFFFFF,
|
||||
},
|
||||
/* UI4X_COLOR_SHIFT_LEFT */
|
||||
{
|
||||
.a = 0xFF,
|
||||
.mono_rgb = 0xFF,
|
||||
.gray_rgb = 0xDC,
|
||||
.rgb = 0xFFBAFF,
|
||||
},
|
||||
/* UI4X_COLOR_SHIFT_RIGHT */
|
||||
{
|
||||
.a = 0xFF,
|
||||
.mono_rgb = 0xFF,
|
||||
.gray_rgb = 0xA9,
|
||||
.rgb = 0x00FFCC,
|
||||
},
|
||||
};
|
||||
|
||||
#define KB_LINE_HEIGHT 50
|
||||
#define KB_COLUMN_WIDTH_6_KEYS 50
|
||||
#define KB_COLUMN_WIDTH_5_KEYS 60
|
||||
|
||||
button_t buttons_48gx[ NB_HP48_KEYS ] = {
|
||||
{.x = 0,
|
||||
.y = 0,
|
||||
.w = 36,
|
||||
.h = 23,
|
||||
.label_color = UI4X_COLOR_LABEL,
|
||||
.label_text = 0,
|
||||
.font_size = 0,
|
||||
.label_graphic_w = menu_label_width,
|
||||
.label_graphic_h = menu_label_height,
|
||||
.label_graphic = menu_label_bitmap,
|
||||
.letter = "A",
|
||||
.left = 0,
|
||||
.highlight = false,
|
||||
.right = 0,
|
||||
.sub = 0 },
|
||||
{.x = KB_COLUMN_WIDTH_6_KEYS,
|
||||
.y = 0,
|
||||
.w = 36,
|
||||
.h = 23,
|
||||
.label_color = UI4X_COLOR_LABEL,
|
||||
.label_text = 0,
|
||||
.font_size = 0,
|
||||
.label_graphic_w = menu_label_width,
|
||||
.label_graphic_h = menu_label_height,
|
||||
.label_graphic = menu_label_bitmap,
|
||||
.letter = "B",
|
||||
.left = 0,
|
||||
.highlight = false,
|
||||
.right = 0,
|
||||
.sub = 0 },
|
||||
{.x = 2 * KB_COLUMN_WIDTH_6_KEYS,
|
||||
.y = 0,
|
||||
.w = 36,
|
||||
.h = 23,
|
||||
.label_color = UI4X_COLOR_LABEL,
|
||||
.label_text = 0,
|
||||
.font_size = 0,
|
||||
.label_graphic_w = menu_label_width,
|
||||
.label_graphic_h = menu_label_height,
|
||||
.label_graphic = menu_label_bitmap,
|
||||
.letter = "C",
|
||||
.left = 0,
|
||||
.highlight = false,
|
||||
.right = 0,
|
||||
.sub = 0 },
|
||||
{.x = 3 * KB_COLUMN_WIDTH_6_KEYS,
|
||||
.y = 0,
|
||||
.w = 36,
|
||||
.h = 23,
|
||||
.label_color = UI4X_COLOR_LABEL,
|
||||
.label_text = 0,
|
||||
.font_size = 0,
|
||||
.label_graphic_w = menu_label_width,
|
||||
.label_graphic_h = menu_label_height,
|
||||
.label_graphic = menu_label_bitmap,
|
||||
.letter = "D",
|
||||
.left = 0,
|
||||
.highlight = false,
|
||||
.right = 0,
|
||||
.sub = 0 },
|
||||
{.x = 4 * KB_COLUMN_WIDTH_6_KEYS,
|
||||
.y = 0,
|
||||
.w = 36,
|
||||
.h = 23,
|
||||
.label_color = UI4X_COLOR_LABEL,
|
||||
.label_text = 0,
|
||||
.font_size = 0,
|
||||
.label_graphic_w = menu_label_width,
|
||||
.label_graphic_h = menu_label_height,
|
||||
.label_graphic = menu_label_bitmap,
|
||||
.letter = "E",
|
||||
.left = 0,
|
||||
.highlight = false,
|
||||
.right = 0,
|
||||
.sub = 0 },
|
||||
{.x = 5 * KB_COLUMN_WIDTH_6_KEYS,
|
||||
.y = 0,
|
||||
.w = 36,
|
||||
.h = 23,
|
||||
.label_color = UI4X_COLOR_LABEL,
|
||||
.label_text = 0,
|
||||
.font_size = 0,
|
||||
.label_graphic_w = menu_label_width,
|
||||
.label_graphic_h = menu_label_height,
|
||||
.label_graphic = menu_label_bitmap,
|
||||
.letter = "F",
|
||||
.left = 0,
|
||||
.highlight = false,
|
||||
.right = 0,
|
||||
.sub = 0 },
|
||||
|
||||
{.x = 0,
|
||||
.y = KB_LINE_HEIGHT,
|
||||
.w = 36,
|
||||
.h = 26,
|
||||
.label_color = UI4X_COLOR_LABEL,
|
||||
.label_text = "MTH",
|
||||
.font_size = 0,
|
||||
.label_graphic_w = 0,
|
||||
.label_graphic_h = 0,
|
||||
.label_graphic = 0,
|
||||
.letter = "G",
|
||||
.left = "RAD",
|
||||
.highlight = false,
|
||||
.right = "POLAR",
|
||||
.sub = 0 },
|
||||
{.x = KB_COLUMN_WIDTH_6_KEYS,
|
||||
.y = KB_LINE_HEIGHT,
|
||||
.w = 36,
|
||||
.h = 26,
|
||||
.label_color = UI4X_COLOR_LABEL,
|
||||
.label_text = "PRG",
|
||||
.font_size = 0,
|
||||
.label_graphic_w = 0,
|
||||
.label_graphic_h = 0,
|
||||
.label_graphic = 0,
|
||||
.letter = "H",
|
||||
.left = "CHARS",
|
||||
.highlight = false,
|
||||
.right = 0,
|
||||
.sub = 0 },
|
||||
{.x = 2 * KB_COLUMN_WIDTH_6_KEYS,
|
||||
.y = KB_LINE_HEIGHT,
|
||||
.w = 36,
|
||||
.h = 26,
|
||||
.label_color = UI4X_COLOR_LABEL,
|
||||
.label_text = "CST",
|
||||
.font_size = 0,
|
||||
.label_graphic_w = 0,
|
||||
.label_graphic_h = 0,
|
||||
.label_graphic = 0,
|
||||
.letter = "I",
|
||||
.left = "MODES",
|
||||
.highlight = false,
|
||||
.right = 0,
|
||||
.sub = 0 },
|
||||
{.x = 3 * KB_COLUMN_WIDTH_6_KEYS,
|
||||
.y = KB_LINE_HEIGHT,
|
||||
.w = 36,
|
||||
.h = 26,
|
||||
.label_color = UI4X_COLOR_LABEL,
|
||||
.label_text = "VAR",
|
||||
.font_size = 0,
|
||||
.label_graphic_w = 0,
|
||||
.label_graphic_h = 0,
|
||||
.label_graphic = 0,
|
||||
.letter = "J",
|
||||
.left = "MEMORY",
|
||||
.highlight = false,
|
||||
.right = 0,
|
||||
.sub = 0 },
|
||||
{.x = 4 * KB_COLUMN_WIDTH_6_KEYS,
|
||||
.y = KB_LINE_HEIGHT,
|
||||
.w = 36,
|
||||
.h = 26,
|
||||
.label_color = UI4X_COLOR_LABEL,
|
||||
.label_text = 0,
|
||||
.font_size = 0,
|
||||
.label_graphic_w = up_width,
|
||||
.label_graphic_h = up_height,
|
||||
.label_graphic = up_bitmap,
|
||||
.letter = "K",
|
||||
.left = "STACK",
|
||||
.highlight = false,
|
||||
.right = 0,
|
||||
.sub = 0 },
|
||||
{.x = 5 * KB_COLUMN_WIDTH_6_KEYS,
|
||||
.y = KB_LINE_HEIGHT,
|
||||
.w = 36,
|
||||
.h = 26,
|
||||
.label_color = UI4X_COLOR_LABEL,
|
||||
.label_text = "NXT",
|
||||
.font_size = 0,
|
||||
.label_graphic_w = 0,
|
||||
.label_graphic_h = 0,
|
||||
.label_graphic = 0,
|
||||
.letter = "L",
|
||||
.left = "PREV",
|
||||
.highlight = false,
|
||||
.right = "MENU",
|
||||
.sub = 0 },
|
||||
|
||||
{.x = 0,
|
||||
.y = 2 * KB_LINE_HEIGHT,
|
||||
.w = 36,
|
||||
.h = 26,
|
||||
.label_color = UI4X_COLOR_LABEL,
|
||||
.label_text = 0,
|
||||
.font_size = 0,
|
||||
.label_graphic_w = quote_width,
|
||||
.label_graphic_h = quote_height,
|
||||
.label_graphic = quote_bitmap,
|
||||
.letter = "M",
|
||||
.left = "UP",
|
||||
.highlight = false,
|
||||
.right = "HOME",
|
||||
.sub = 0 },
|
||||
{.x = KB_COLUMN_WIDTH_6_KEYS,
|
||||
.y = 2 * KB_LINE_HEIGHT,
|
||||
.w = 36,
|
||||
.h = 26,
|
||||
.label_color = UI4X_COLOR_LABEL,
|
||||
.label_text = "STO",
|
||||
.font_size = 0,
|
||||
.label_graphic_w = 0,
|
||||
.label_graphic_h = 0,
|
||||
.label_graphic = 0,
|
||||
.letter = "N",
|
||||
.left = "DEF",
|
||||
.highlight = false,
|
||||
.right = "RCL",
|
||||
.sub = 0 },
|
||||
{.x = 2 * KB_COLUMN_WIDTH_6_KEYS,
|
||||
.y = 2 * KB_LINE_HEIGHT,
|
||||
.w = 36,
|
||||
.h = 26,
|
||||
.label_color = UI4X_COLOR_LABEL,
|
||||
.label_text = "EVAL",
|
||||
.font_size = 0,
|
||||
.label_graphic_w = 0,
|
||||
.label_graphic_h = 0,
|
||||
.label_graphic = 0,
|
||||
.letter = "O",
|
||||
.left = "\x06NUM",
|
||||
.highlight = false,
|
||||
.right = "UNDO",
|
||||
.sub = 0 },
|
||||
{.x = 3 * KB_COLUMN_WIDTH_6_KEYS,
|
||||
.y = 2 * KB_LINE_HEIGHT,
|
||||
.w = 36,
|
||||
.h = 26,
|
||||
.label_color = UI4X_COLOR_LABEL,
|
||||
.label_text = 0,
|
||||
.font_size = 0,
|
||||
.label_graphic_w = left_width,
|
||||
.label_graphic_h = left_height,
|
||||
.label_graphic = left_bitmap,
|
||||
.letter = "P",
|
||||
.left = "PICTURE",
|
||||
.highlight = false,
|
||||
.right = 0,
|
||||
.sub = 0 },
|
||||
{.x = 4 * KB_COLUMN_WIDTH_6_KEYS,
|
||||
.y = 2 * KB_LINE_HEIGHT,
|
||||
.w = 36,
|
||||
.h = 26,
|
||||
.label_color = UI4X_COLOR_LABEL,
|
||||
.label_text = 0,
|
||||
.font_size = 0,
|
||||
.label_graphic_w = down_width,
|
||||
.label_graphic_h = down_height,
|
||||
.label_graphic = down_bitmap,
|
||||
.letter = "Q",
|
||||
.left = "VIEW",
|
||||
.highlight = false,
|
||||
.right = 0,
|
||||
.sub = 0 },
|
||||
{.x = 5 * KB_COLUMN_WIDTH_6_KEYS,
|
||||
.y = 2 * KB_LINE_HEIGHT,
|
||||
.w = 36,
|
||||
.h = 26,
|
||||
.label_color = UI4X_COLOR_LABEL,
|
||||
.label_text = 0,
|
||||
.font_size = 0,
|
||||
.label_graphic_w = right_width,
|
||||
.label_graphic_h = right_height,
|
||||
.label_graphic = right_bitmap,
|
||||
.letter = "R",
|
||||
.left = "SWAP",
|
||||
.highlight = false,
|
||||
.right = 0,
|
||||
.sub = 0 },
|
||||
|
||||
{.x = 0,
|
||||
.y = 3 * KB_LINE_HEIGHT,
|
||||
.w = 36,
|
||||
.h = 26,
|
||||
.label_color = UI4X_COLOR_LABEL,
|
||||
.label_text = "SIN",
|
||||
.font_size = 0,
|
||||
.label_graphic_w = 0,
|
||||
.label_graphic_h = 0,
|
||||
.label_graphic = 0,
|
||||
.letter = "S",
|
||||
.left = "ASIN",
|
||||
.highlight = false,
|
||||
.right = "\x07",
|
||||
.sub = 0 },
|
||||
{.x = KB_COLUMN_WIDTH_6_KEYS,
|
||||
.y = 3 * KB_LINE_HEIGHT,
|
||||
.w = 36,
|
||||
.h = 26,
|
||||
.label_color = UI4X_COLOR_LABEL,
|
||||
.label_text = "COS",
|
||||
.font_size = 0,
|
||||
.label_graphic_w = 0,
|
||||
.label_graphic_h = 0,
|
||||
.label_graphic = 0,
|
||||
.letter = "T",
|
||||
.left = "ACOS",
|
||||
.highlight = false,
|
||||
.right = "\x08",
|
||||
.sub = 0 },
|
||||
{.x = 2 * KB_COLUMN_WIDTH_6_KEYS,
|
||||
.y = 3 * KB_LINE_HEIGHT,
|
||||
.w = 36,
|
||||
.h = 26,
|
||||
.label_color = UI4X_COLOR_LABEL,
|
||||
.label_text = "TAN",
|
||||
.font_size = 0,
|
||||
.label_graphic_w = 0,
|
||||
.label_graphic_h = 0,
|
||||
.label_graphic = 0,
|
||||
.letter = "U",
|
||||
.left = "ATAN",
|
||||
.highlight = false,
|
||||
.right = "\x09",
|
||||
.sub = 0 },
|
||||
{.x = 3 * KB_COLUMN_WIDTH_6_KEYS,
|
||||
.y = 3 * KB_LINE_HEIGHT,
|
||||
.w = 36,
|
||||
.h = 26,
|
||||
.label_color = UI4X_COLOR_LABEL,
|
||||
.label_text = 0,
|
||||
.font_size = 0,
|
||||
.label_graphic_w = sqrt_width,
|
||||
.label_graphic_h = sqrt_height,
|
||||
.label_graphic = sqrt_bitmap,
|
||||
.letter = "V",
|
||||
.left = "\x13",
|
||||
.highlight = false,
|
||||
.right = "\x14",
|
||||
.sub = 0 },
|
||||
{.x = 4 * KB_COLUMN_WIDTH_6_KEYS,
|
||||
.y = 3 * KB_LINE_HEIGHT,
|
||||
.w = 36,
|
||||
.h = 26,
|
||||
.label_color = UI4X_COLOR_LABEL,
|
||||
.label_text = 0,
|
||||
.font_size = 0,
|
||||
.label_graphic_w = power_width,
|
||||
.label_graphic_h = power_height,
|
||||
.label_graphic = power_bitmap,
|
||||
.letter = "W",
|
||||
.left = "\x15",
|
||||
.highlight = false,
|
||||
.right = "LOG",
|
||||
.sub = 0 },
|
||||
{.x = 5 * KB_COLUMN_WIDTH_6_KEYS,
|
||||
.y = 3 * KB_LINE_HEIGHT,
|
||||
.w = 36,
|
||||
.h = 26,
|
||||
.label_color = UI4X_COLOR_LABEL,
|
||||
.label_text = 0,
|
||||
.font_size = 0,
|
||||
.label_graphic_w = inv_width,
|
||||
.label_graphic_h = inv_height,
|
||||
.label_graphic = inv_bitmap,
|
||||
.letter = "X",
|
||||
.left = "\x16",
|
||||
.highlight = false,
|
||||
.right = "LN",
|
||||
.sub = 0 },
|
||||
|
||||
{.x = 0,
|
||||
.y = 4 * KB_LINE_HEIGHT,
|
||||
.w = 86,
|
||||
.h = 26,
|
||||
.label_color = UI4X_COLOR_LABEL,
|
||||
.label_text = "ENTER",
|
||||
.font_size = 2,
|
||||
.label_graphic_w = 0,
|
||||
.label_graphic_h = 0,
|
||||
.label_graphic = 0,
|
||||
.letter = 0,
|
||||
.left = "EQUATION",
|
||||
.highlight = false,
|
||||
.right = "MATRIX",
|
||||
.sub = 0 },
|
||||
{.x = 2 * KB_COLUMN_WIDTH_6_KEYS,
|
||||
.y = 4 * KB_LINE_HEIGHT,
|
||||
.w = 36,
|
||||
.h = 26,
|
||||
.label_color = UI4X_COLOR_LABEL,
|
||||
.label_text = 0,
|
||||
.font_size = 0,
|
||||
.label_graphic_w = neg_width,
|
||||
.label_graphic_h = neg_height,
|
||||
.label_graphic = neg_bitmap,
|
||||
.letter = "Y",
|
||||
.left = "EDIT",
|
||||
.highlight = false,
|
||||
.right = "CMD",
|
||||
.sub = 0 },
|
||||
{.x = 3 * KB_COLUMN_WIDTH_6_KEYS,
|
||||
.y = 4 * KB_LINE_HEIGHT,
|
||||
.w = 36,
|
||||
.h = 26,
|
||||
.label_color = UI4X_COLOR_LABEL,
|
||||
.label_text = "EEX",
|
||||
.font_size = 0,
|
||||
.label_graphic_w = 0,
|
||||
.label_graphic_h = 0,
|
||||
.label_graphic = 0,
|
||||
.letter = "Z",
|
||||
.left = "PURG",
|
||||
.highlight = false,
|
||||
.right = "ARG",
|
||||
.sub = 0 },
|
||||
{.x = 4 * KB_COLUMN_WIDTH_6_KEYS,
|
||||
.y = 4 * KB_LINE_HEIGHT,
|
||||
.w = 36,
|
||||
.h = 26,
|
||||
.label_color = UI4X_COLOR_LABEL,
|
||||
.label_text = "DEL",
|
||||
.font_size = 0,
|
||||
.label_graphic_w = 0,
|
||||
.label_graphic_h = 0,
|
||||
.label_graphic = 0,
|
||||
.letter = 0,
|
||||
.left = "CLEAR",
|
||||
.highlight = false,
|
||||
.right = 0,
|
||||
.sub = 0 },
|
||||
{.x = 5 * KB_COLUMN_WIDTH_6_KEYS,
|
||||
.y = 4 * KB_LINE_HEIGHT,
|
||||
.w = 36,
|
||||
.h = 26,
|
||||
.label_color = UI4X_COLOR_LABEL,
|
||||
.label_text = 0,
|
||||
.font_size = 0,
|
||||
.label_graphic_w = bs_width,
|
||||
.label_graphic_h = bs_height,
|
||||
.label_graphic = bs_bitmap,
|
||||
.letter = 0,
|
||||
.left = "DROP",
|
||||
.highlight = false,
|
||||
.right = 0,
|
||||
.sub = 0 },
|
||||
|
||||
{.x = 0,
|
||||
.y = 5 * KB_LINE_HEIGHT,
|
||||
.w = 36,
|
||||
.h = 26,
|
||||
.label_color = UI4X_COLOR_LABEL,
|
||||
.label_text = 0,
|
||||
.font_size = 0,
|
||||
.label_graphic_w = alpha_width,
|
||||
.label_graphic_h = alpha_height,
|
||||
.label_graphic = alpha_bitmap,
|
||||
.letter = 0,
|
||||
.left = "USER",
|
||||
.highlight = false,
|
||||
.right = "ENTRY",
|
||||
.sub = 0 },
|
||||
{.x = KB_COLUMN_WIDTH_5_KEYS,
|
||||
.y = 5 * KB_LINE_HEIGHT,
|
||||
.w = 46,
|
||||
.h = 26,
|
||||
.label_color = UI4X_COLOR_LABEL,
|
||||
.label_text = "7",
|
||||
.font_size = 1,
|
||||
.label_graphic_w = 0,
|
||||
.label_graphic_h = 0,
|
||||
.label_graphic = 0,
|
||||
.letter = 0,
|
||||
.left = "SOLVE",
|
||||
.highlight = true,
|
||||
.right = 0,
|
||||
.sub = 0 },
|
||||
{.x = 2 * KB_COLUMN_WIDTH_5_KEYS,
|
||||
.y = 5 * KB_LINE_HEIGHT,
|
||||
.w = 46,
|
||||
.h = 26,
|
||||
.label_color = UI4X_COLOR_LABEL,
|
||||
.label_text = "8",
|
||||
.font_size = 1,
|
||||
.label_graphic_w = 0,
|
||||
.label_graphic_h = 0,
|
||||
.label_graphic = 0,
|
||||
.letter = 0,
|
||||
.left = "PLOT",
|
||||
.highlight = true,
|
||||
.right = 0,
|
||||
.sub = 0 },
|
||||
{.x = 3 * KB_COLUMN_WIDTH_5_KEYS,
|
||||
.y = 5 * KB_LINE_HEIGHT,
|
||||
.w = 46,
|
||||
.h = 26,
|
||||
.label_color = UI4X_COLOR_LABEL,
|
||||
.label_text = "9",
|
||||
.font_size = 1,
|
||||
.label_graphic_w = 0,
|
||||
.label_graphic_h = 0,
|
||||
.label_graphic = 0,
|
||||
.letter = 0,
|
||||
.left = "SYMBOLIC",
|
||||
.highlight = true,
|
||||
.right = 0,
|
||||
.sub = 0 },
|
||||
{.x = 4 * KB_COLUMN_WIDTH_5_KEYS,
|
||||
.y = 5 * KB_LINE_HEIGHT,
|
||||
.w = 46,
|
||||
.h = 26,
|
||||
.label_color = UI4X_COLOR_LABEL,
|
||||
.label_text = 0,
|
||||
.font_size = 0,
|
||||
.label_graphic_w = div_width,
|
||||
.label_graphic_h = div_height,
|
||||
.label_graphic = div_bitmap,
|
||||
.letter = 0,
|
||||
.left = "\x17 ",
|
||||
.highlight = false,
|
||||
.right = "\x18",
|
||||
.sub = 0 },
|
||||
|
||||
{.x = 0,
|
||||
.y = 6 * KB_LINE_HEIGHT,
|
||||
.w = 36,
|
||||
.h = 26,
|
||||
.label_color = UI4X_COLOR_SHIFT_LEFT,
|
||||
.label_text = 0,
|
||||
.font_size = 0,
|
||||
.label_graphic_w = shl_width,
|
||||
.label_graphic_h = shl_height,
|
||||
.label_graphic = shl_bitmap,
|
||||
.letter = 0,
|
||||
.left = 0,
|
||||
.highlight = false,
|
||||
.right = 0,
|
||||
.sub = 0 },
|
||||
{.x = KB_COLUMN_WIDTH_5_KEYS,
|
||||
.y = 6 * KB_LINE_HEIGHT,
|
||||
.w = 46,
|
||||
.h = 26,
|
||||
.label_color = UI4X_COLOR_LABEL,
|
||||
.label_text = "4",
|
||||
.font_size = 1,
|
||||
.label_graphic_w = 0,
|
||||
.label_graphic_h = 0,
|
||||
.label_graphic = 0,
|
||||
.letter = 0,
|
||||
.left = "TIME",
|
||||
.highlight = true,
|
||||
.right = 0,
|
||||
.sub = 0 },
|
||||
{.x = 2 * KB_COLUMN_WIDTH_5_KEYS,
|
||||
.y = 6 * KB_LINE_HEIGHT,
|
||||
.w = 46,
|
||||
.h = 26,
|
||||
.label_color = UI4X_COLOR_LABEL,
|
||||
.label_text = "5",
|
||||
.font_size = 1,
|
||||
.label_graphic_w = 0,
|
||||
.label_graphic_h = 0,
|
||||
.label_graphic = 0,
|
||||
.letter = 0,
|
||||
.left = "STAT",
|
||||
.highlight = true,
|
||||
.right = 0,
|
||||
.sub = 0 },
|
||||
{.x = 3 * KB_COLUMN_WIDTH_5_KEYS,
|
||||
.y = 6 * KB_LINE_HEIGHT,
|
||||
.w = 46,
|
||||
.h = 26,
|
||||
.label_color = UI4X_COLOR_LABEL,
|
||||
.label_text = "6",
|
||||
.font_size = 1,
|
||||
.label_graphic_w = 0,
|
||||
.label_graphic_h = 0,
|
||||
.label_graphic = 0,
|
||||
.letter = 0,
|
||||
.left = "UNITS",
|
||||
.highlight = true,
|
||||
.right = 0,
|
||||
.sub = 0 },
|
||||
{.x = 4 * KB_COLUMN_WIDTH_5_KEYS,
|
||||
.y = 6 * KB_LINE_HEIGHT,
|
||||
.w = 46,
|
||||
.h = 26,
|
||||
.label_color = UI4X_COLOR_LABEL,
|
||||
.label_text = 0,
|
||||
.font_size = 0,
|
||||
.label_graphic_w = mul_width,
|
||||
.label_graphic_h = mul_height,
|
||||
.label_graphic = mul_bitmap,
|
||||
.letter = 0,
|
||||
.left = "\x19 ",
|
||||
.highlight = false,
|
||||
.right = "\x1a",
|
||||
.sub = 0 },
|
||||
|
||||
{.x = 0,
|
||||
.y = 7 * KB_LINE_HEIGHT,
|
||||
.w = 36,
|
||||
.h = 26,
|
||||
.label_color = UI4X_COLOR_SHIFT_RIGHT,
|
||||
.label_text = 0,
|
||||
.font_size = 0,
|
||||
.label_graphic_w = shr_width,
|
||||
.label_graphic_h = shr_height,
|
||||
.label_graphic = shr_bitmap,
|
||||
.letter = 0,
|
||||
.left = 0,
|
||||
.highlight = true,
|
||||
.right = 0,
|
||||
.sub = 0 },
|
||||
{.x = KB_COLUMN_WIDTH_5_KEYS,
|
||||
.y = 7 * KB_LINE_HEIGHT,
|
||||
.w = 46,
|
||||
.h = 26,
|
||||
.label_color = UI4X_COLOR_LABEL,
|
||||
.label_text = "1",
|
||||
.font_size = 1,
|
||||
.label_graphic_w = 0,
|
||||
.label_graphic_h = 0,
|
||||
.label_graphic = 0,
|
||||
.letter = 0,
|
||||
.left = "I/O",
|
||||
.highlight = true,
|
||||
.right = 0,
|
||||
.sub = 0 },
|
||||
{.x = 2 * KB_COLUMN_WIDTH_5_KEYS,
|
||||
.y = 7 * KB_LINE_HEIGHT,
|
||||
.w = 46,
|
||||
.h = 26,
|
||||
.label_color = UI4X_COLOR_LABEL,
|
||||
.label_text = "2",
|
||||
.font_size = 1,
|
||||
.label_graphic_w = 0,
|
||||
.label_graphic_h = 0,
|
||||
.label_graphic = 0,
|
||||
.letter = 0,
|
||||
.left = "LIBRARY",
|
||||
.highlight = true,
|
||||
.right = 0,
|
||||
.sub = 0 },
|
||||
{.x = 3 * KB_COLUMN_WIDTH_5_KEYS,
|
||||
.y = 7 * KB_LINE_HEIGHT,
|
||||
.w = 46,
|
||||
.h = 26,
|
||||
.label_color = UI4X_COLOR_LABEL,
|
||||
.label_text = "3",
|
||||
.font_size = 1,
|
||||
.label_graphic_w = 0,
|
||||
.label_graphic_h = 0,
|
||||
.label_graphic = 0,
|
||||
.letter = 0,
|
||||
.left = "EQ LIB",
|
||||
.highlight = true,
|
||||
.right = 0,
|
||||
.sub = 0 },
|
||||
{.x = 4 * KB_COLUMN_WIDTH_5_KEYS,
|
||||
.y = 7 * KB_LINE_HEIGHT,
|
||||
.w = 46,
|
||||
.h = 26,
|
||||
.label_color = UI4X_COLOR_LABEL,
|
||||
.label_text = 0,
|
||||
.font_size = 0,
|
||||
.label_graphic_w = minus_width,
|
||||
.label_graphic_h = minus_height,
|
||||
.label_graphic = minus_bitmap,
|
||||
.letter = 0,
|
||||
.left = "\x1b ",
|
||||
.highlight = false,
|
||||
.right = "\x1c",
|
||||
.sub = 0 },
|
||||
|
||||
{.x = 0,
|
||||
.y = 8 * KB_LINE_HEIGHT,
|
||||
.w = 36,
|
||||
.h = 26,
|
||||
.label_color = UI4X_COLOR_LABEL,
|
||||
.label_text = "ON",
|
||||
.font_size = 0,
|
||||
.label_graphic_w = 0,
|
||||
.label_graphic_h = 0,
|
||||
.label_graphic = 0,
|
||||
.letter = 0,
|
||||
.left = "CONT",
|
||||
.highlight = false,
|
||||
.right = "OFF",
|
||||
.sub = "CANCEL"},
|
||||
{.x = KB_COLUMN_WIDTH_5_KEYS,
|
||||
.y = 8 * KB_LINE_HEIGHT,
|
||||
.w = 46,
|
||||
.h = 26,
|
||||
.label_color = UI4X_COLOR_LABEL,
|
||||
.label_text = "0",
|
||||
.font_size = 1,
|
||||
.label_graphic_w = 0,
|
||||
.label_graphic_h = 0,
|
||||
.label_graphic = 0,
|
||||
.letter = 0,
|
||||
.left = "\x04 ",
|
||||
.highlight = false,
|
||||
.right = "\x03",
|
||||
.sub = 0 },
|
||||
{.x = 2 * KB_COLUMN_WIDTH_5_KEYS,
|
||||
.y = 8 * KB_LINE_HEIGHT,
|
||||
.w = 46,
|
||||
.h = 26,
|
||||
.label_color = UI4X_COLOR_LABEL,
|
||||
.label_text = ".",
|
||||
.font_size = 1,
|
||||
.label_graphic_w = 0,
|
||||
.label_graphic_h = 0,
|
||||
.label_graphic = 0,
|
||||
.letter = 0,
|
||||
.left = "\x02 ",
|
||||
.highlight = false,
|
||||
.right = "\x01",
|
||||
.sub = 0 },
|
||||
{.x = 3 * KB_COLUMN_WIDTH_5_KEYS,
|
||||
.y = 8 * KB_LINE_HEIGHT,
|
||||
.w = 46,
|
||||
.h = 26,
|
||||
.label_color = UI4X_COLOR_LABEL,
|
||||
.label_text = "SPC",
|
||||
.font_size = 0,
|
||||
.label_graphic_w = 0,
|
||||
.label_graphic_h = 0,
|
||||
.label_graphic = 0,
|
||||
.letter = 0,
|
||||
.left = "\x05 ",
|
||||
.highlight = false,
|
||||
.right = "\x1f",
|
||||
.sub = 0 },
|
||||
{.x = 4 * KB_COLUMN_WIDTH_5_KEYS,
|
||||
.y = 8 * KB_LINE_HEIGHT,
|
||||
.w = 46,
|
||||
.h = 26,
|
||||
.label_color = UI4X_COLOR_LABEL,
|
||||
.label_text = 0,
|
||||
.font_size = 0,
|
||||
.label_graphic_w = plus_width,
|
||||
.label_graphic_h = plus_height,
|
||||
.label_graphic = plus_bitmap,
|
||||
.letter = 0,
|
||||
.left = "\x1d ",
|
||||
.highlight = false,
|
||||
.right = "\x1e",
|
||||
.sub = 0 },
|
||||
};
|
908
src/ui4x/48sx.c
908
src/ui4x/48sx.c
|
@ -1,908 +0,0 @@
|
|||
#include "inner.h"
|
||||
|
||||
color_t colors_48sx[ NB_COLORS ] = {
|
||||
/* UI4X_COLOR_HP_LOGO */
|
||||
{
|
||||
.a = 0xFF,
|
||||
.mono_rgb = 0xFF,
|
||||
.gray_rgb = 0xAC,
|
||||
.rgb = 0xCCA96B,
|
||||
},
|
||||
/* UI4X_COLOR_HP_LOGO_BG */
|
||||
{
|
||||
.a = 0xFF,
|
||||
.mono_rgb = 0x00,
|
||||
.gray_rgb = 0x41,
|
||||
.rgb = 0x404040,
|
||||
},
|
||||
/* UI4X_COLOR_48GX_128K_RAM */
|
||||
{
|
||||
.a = 0xFF,
|
||||
.mono_rgb = 0xFF,
|
||||
.gray_rgb = 0xB9,
|
||||
.rgb = 0xCAB890,
|
||||
},
|
||||
/* UI4X_COLOR_FRAME */
|
||||
{
|
||||
.a = 0xFF,
|
||||
.mono_rgb = 0xFF,
|
||||
.gray_rgb = 0x00,
|
||||
.rgb = 0x000000,
|
||||
},
|
||||
/* UI4X_COLOR_UPPER_FACEPLATE_EDGE_TOP */
|
||||
{
|
||||
.a = 0xFF,
|
||||
.mono_rgb = 0x00,
|
||||
.gray_rgb = 0x7C,
|
||||
.rgb = 0x9B7654,
|
||||
},
|
||||
/* UI4X_COLOR_UPPER_FACEPLATE */
|
||||
{
|
||||
.a = 0xFF,
|
||||
.mono_rgb = 0x00,
|
||||
.gray_rgb = 0x63,
|
||||
.rgb = 0x7C5E43,
|
||||
},
|
||||
/* UI4X_COLOR_UPPER_FACEPLATE_EDGE_BOTTOM */
|
||||
{
|
||||
.a = 0xFF,
|
||||
.mono_rgb = 0x00,
|
||||
.gray_rgb = 0x4F,
|
||||
.rgb = 0x644B35,
|
||||
},
|
||||
/* UI4X_COLOR_FACEPLATE_EDGE_TOP */
|
||||
{
|
||||
.a = 0xFF,
|
||||
.mono_rgb = 0x00,
|
||||
.gray_rgb = 0x58,
|
||||
.rgb = 0x6D4E4E,
|
||||
},
|
||||
/* UI4X_COLOR_FACEPLATE */
|
||||
{
|
||||
.a = 0xFF,
|
||||
.mono_rgb = 0x00,
|
||||
.gray_rgb = 0x49,
|
||||
.rgb = 0x5A4040,
|
||||
},
|
||||
/* UI4X_COLOR_FACEPLATE_EDGE_BOTTOM */
|
||||
{
|
||||
.a = 0xFF,
|
||||
.mono_rgb = 0x00,
|
||||
.gray_rgb = 0x3C,
|
||||
.rgb = 0x4C3636,
|
||||
},
|
||||
/* UI4X_COLOR_KEYPAD_HIGHLIGHT */
|
||||
{
|
||||
.a = 0xFF,
|
||||
.mono_rgb = 0x00,
|
||||
.gray_rgb = 0x30,
|
||||
.rgb = 0x3C2A2A,
|
||||
},
|
||||
/* UI4X_COLOR_BUTTON_EDGE_TOP */
|
||||
{
|
||||
.a = 0xFF,
|
||||
.mono_rgb = 0x00,
|
||||
.gray_rgb = 0x5B,
|
||||
.rgb = 0x6D5D5D,
|
||||
},
|
||||
/* UI4X_COLOR_BUTTON */
|
||||
{
|
||||
.a = 0xFF,
|
||||
.mono_rgb = 0x00,
|
||||
.gray_rgb = 0x51,
|
||||
.rgb = 0x5A4D4D,
|
||||
},
|
||||
/* UI4X_COLOR_BUTTON_EDGE_BOTTOM */
|
||||
{
|
||||
.a = 0xFF,
|
||||
.mono_rgb = 0x00,
|
||||
.gray_rgb = 0x45,
|
||||
.rgb = 0x4C4141,
|
||||
},
|
||||
/* UI4X_COLOR_PIXEL_OFF */
|
||||
{
|
||||
.a = 0xFF,
|
||||
.mono_rgb = 0xFF,
|
||||
.gray_rgb = 0xCD,
|
||||
.rgb = 0xCADD5C,
|
||||
},
|
||||
/* UI4X_COLOR_PIXEL_ON */
|
||||
{
|
||||
.a = 0xFF,
|
||||
.mono_rgb = 0x00,
|
||||
.gray_rgb = 0x14,
|
||||
.rgb = 0x000080,
|
||||
},
|
||||
/* UI4X_COLOR_BLACK_PIXEL_OFF */
|
||||
{
|
||||
.a = 0xFF,
|
||||
.mono_rgb = 0xFF,
|
||||
.gray_rgb = 0xCD,
|
||||
.rgb = 0xf5f5f5,
|
||||
},
|
||||
/* UI4X_COLOR_BLACK_PIXEL_ON */
|
||||
{
|
||||
.a = 0xFF,
|
||||
.mono_rgb = 0x00,
|
||||
.gray_rgb = 0x14,
|
||||
.rgb = 0x000000,
|
||||
},
|
||||
/* UI4X_COLOR_LABEL */
|
||||
{
|
||||
.a = 0xFF,
|
||||
.mono_rgb = 0xFF,
|
||||
.gray_rgb = 0xFF,
|
||||
.rgb = 0xFFFFFF,
|
||||
},
|
||||
/* UI4X_COLOR_ALPHA */
|
||||
{
|
||||
.a = 0xFF,
|
||||
.mono_rgb = 0xFF,
|
||||
.gray_rgb = 0xFF,
|
||||
.rgb = 0xFFFFFF,
|
||||
},
|
||||
/* UI4X_COLOR_SHIFT_LEFT */
|
||||
{
|
||||
.a = 0xFF,
|
||||
.mono_rgb = 0xFF,
|
||||
.gray_rgb = 0xE6,
|
||||
.rgb = 0xFFA600,
|
||||
},
|
||||
/* UI4X_COLOR_SHIFT_RIGHT */
|
||||
{
|
||||
.a = 0xFF,
|
||||
.mono_rgb = 0xFF,
|
||||
.gray_rgb = 0xA9,
|
||||
.rgb = 0x00D2FF,
|
||||
},
|
||||
};
|
||||
|
||||
#define KB_LINE_HEIGHT 50
|
||||
#define KB_COLUMN_WIDTH_6_KEYS 50
|
||||
#define KB_COLUMN_WIDTH_5_KEYS 60
|
||||
|
||||
button_t buttons_48sx[ NB_HP48_KEYS ] = {
|
||||
{.x = 0,
|
||||
.y = 0,
|
||||
.w = 36,
|
||||
.h = 23,
|
||||
.label_color = UI4X_COLOR_LABEL,
|
||||
.label_text = 0,
|
||||
.font_size = 0,
|
||||
.label_graphic_w = menu_label_width,
|
||||
.label_graphic_h = menu_label_height,
|
||||
.label_graphic = menu_label_bitmap,
|
||||
.letter = "A",
|
||||
.left = 0,
|
||||
.highlight = false,
|
||||
.right = 0,
|
||||
.sub = 0 },
|
||||
{.x = KB_COLUMN_WIDTH_6_KEYS,
|
||||
.y = 0,
|
||||
.w = 36,
|
||||
.h = 23,
|
||||
.label_color = UI4X_COLOR_LABEL,
|
||||
.label_text = 0,
|
||||
.font_size = 0,
|
||||
.label_graphic_w = menu_label_width,
|
||||
.label_graphic_h = menu_label_height,
|
||||
.label_graphic = menu_label_bitmap,
|
||||
.letter = "B",
|
||||
.left = 0,
|
||||
.highlight = false,
|
||||
.right = 0,
|
||||
.sub = 0 },
|
||||
{.x = 2 * KB_COLUMN_WIDTH_6_KEYS,
|
||||
.y = 0,
|
||||
.w = 36,
|
||||
.h = 23,
|
||||
.label_color = UI4X_COLOR_LABEL,
|
||||
.label_text = 0,
|
||||
.font_size = 0,
|
||||
.label_graphic_w = menu_label_width,
|
||||
.label_graphic_h = menu_label_height,
|
||||
.label_graphic = menu_label_bitmap,
|
||||
.letter = "C",
|
||||
.left = 0,
|
||||
.highlight = false,
|
||||
.right = 0,
|
||||
.sub = 0 },
|
||||
{.x = 3 * KB_COLUMN_WIDTH_6_KEYS,
|
||||
.y = 0,
|
||||
.w = 36,
|
||||
.h = 23,
|
||||
.label_color = UI4X_COLOR_LABEL,
|
||||
.label_text = 0,
|
||||
.font_size = 0,
|
||||
.label_graphic_w = menu_label_width,
|
||||
.label_graphic_h = menu_label_height,
|
||||
.label_graphic = menu_label_bitmap,
|
||||
.letter = "D",
|
||||
.left = 0,
|
||||
.highlight = false,
|
||||
.right = 0,
|
||||
.sub = 0 },
|
||||
{.x = 4 * KB_COLUMN_WIDTH_6_KEYS,
|
||||
.y = 0,
|
||||
.w = 36,
|
||||
.h = 23,
|
||||
.label_color = UI4X_COLOR_LABEL,
|
||||
.label_text = 0,
|
||||
.font_size = 0,
|
||||
.label_graphic_w = menu_label_width,
|
||||
.label_graphic_h = menu_label_height,
|
||||
.label_graphic = menu_label_bitmap,
|
||||
.letter = "E",
|
||||
.left = 0,
|
||||
.highlight = false,
|
||||
.right = 0,
|
||||
.sub = 0 },
|
||||
{.x = 5 * KB_COLUMN_WIDTH_6_KEYS,
|
||||
.y = 0,
|
||||
.w = 36,
|
||||
.h = 23,
|
||||
.label_color = UI4X_COLOR_LABEL,
|
||||
.label_text = 0,
|
||||
.font_size = 0,
|
||||
.label_graphic_w = menu_label_width,
|
||||
.label_graphic_h = menu_label_height,
|
||||
.label_graphic = menu_label_bitmap,
|
||||
.letter = "F",
|
||||
.left = 0,
|
||||
.highlight = false,
|
||||
.right = 0,
|
||||
.sub = 0 },
|
||||
|
||||
{.x = 0,
|
||||
.y = KB_LINE_HEIGHT,
|
||||
.w = 36,
|
||||
.h = 26,
|
||||
.label_color = UI4X_COLOR_LABEL,
|
||||
.label_text = "MTH",
|
||||
.font_size = 0,
|
||||
.label_graphic_w = 0,
|
||||
.label_graphic_h = 0,
|
||||
.label_graphic = 0,
|
||||
.letter = "G",
|
||||
.left = "PRINT",
|
||||
.highlight = true,
|
||||
.right = 0,
|
||||
.sub = 0 },
|
||||
{.x = KB_COLUMN_WIDTH_6_KEYS,
|
||||
.y = KB_LINE_HEIGHT,
|
||||
.w = 36,
|
||||
.h = 26,
|
||||
.label_color = UI4X_COLOR_LABEL,
|
||||
.label_text = "PRG",
|
||||
.font_size = 0,
|
||||
.label_graphic_w = 0,
|
||||
.label_graphic_h = 0,
|
||||
.label_graphic = 0,
|
||||
.letter = "H",
|
||||
.left = "I/O",
|
||||
.highlight = true,
|
||||
.right = 0,
|
||||
.sub = 0 },
|
||||
{.x = 2 * KB_COLUMN_WIDTH_6_KEYS,
|
||||
.y = KB_LINE_HEIGHT,
|
||||
.w = 36,
|
||||
.h = 26,
|
||||
.label_color = UI4X_COLOR_LABEL,
|
||||
.label_text = "CST",
|
||||
.font_size = 0,
|
||||
.label_graphic_w = 0,
|
||||
.label_graphic_h = 0,
|
||||
.label_graphic = 0,
|
||||
.letter = "I",
|
||||
.left = "MODES",
|
||||
.highlight = true,
|
||||
.right = 0,
|
||||
.sub = 0 },
|
||||
{.x = 3 * KB_COLUMN_WIDTH_6_KEYS,
|
||||
.y = KB_LINE_HEIGHT,
|
||||
.w = 36,
|
||||
.h = 26,
|
||||
.label_color = UI4X_COLOR_LABEL,
|
||||
.label_text = "VAR",
|
||||
.font_size = 0,
|
||||
.label_graphic_w = 0,
|
||||
.label_graphic_h = 0,
|
||||
.label_graphic = 0,
|
||||
.letter = "J",
|
||||
.left = "MEMORY",
|
||||
.highlight = true,
|
||||
.right = 0,
|
||||
.sub = 0 },
|
||||
{.x = 4 * KB_COLUMN_WIDTH_6_KEYS,
|
||||
.y = KB_LINE_HEIGHT,
|
||||
.w = 36,
|
||||
.h = 26,
|
||||
.label_color = UI4X_COLOR_LABEL,
|
||||
.label_text = 0,
|
||||
.font_size = 0,
|
||||
.label_graphic_w = up_width,
|
||||
.label_graphic_h = up_height,
|
||||
.label_graphic = up_bitmap,
|
||||
.letter = "K",
|
||||
.left = "LIBRARY",
|
||||
.highlight = true,
|
||||
.right = 0,
|
||||
.sub = 0 },
|
||||
{.x = 5 * KB_COLUMN_WIDTH_6_KEYS,
|
||||
.y = KB_LINE_HEIGHT,
|
||||
.w = 36,
|
||||
.h = 26,
|
||||
.label_color = UI4X_COLOR_LABEL,
|
||||
.label_text = "NXT",
|
||||
.font_size = 0,
|
||||
.label_graphic_w = 0,
|
||||
.label_graphic_h = 0,
|
||||
.label_graphic = 0,
|
||||
.letter = "L",
|
||||
.left = "PREV",
|
||||
.highlight = false,
|
||||
.right = 0,
|
||||
.sub = 0 },
|
||||
|
||||
{.x = 0,
|
||||
.y = 2 * KB_LINE_HEIGHT,
|
||||
.w = 36,
|
||||
.h = 26,
|
||||
.label_color = UI4X_COLOR_LABEL,
|
||||
.label_text = 0,
|
||||
.font_size = 0,
|
||||
.label_graphic_w = quote_width,
|
||||
.label_graphic_h = quote_height,
|
||||
.label_graphic = quote_bitmap,
|
||||
.letter = "M",
|
||||
.left = "UP",
|
||||
.highlight = false,
|
||||
.right = "HOME",
|
||||
.sub = 0 },
|
||||
{.x = KB_COLUMN_WIDTH_6_KEYS,
|
||||
.y = 2 * KB_LINE_HEIGHT,
|
||||
.w = 36,
|
||||
.h = 26,
|
||||
.label_color = UI4X_COLOR_LABEL,
|
||||
.label_text = "STO",
|
||||
.font_size = 0,
|
||||
.label_graphic_w = 0,
|
||||
.label_graphic_h = 0,
|
||||
.label_graphic = 0,
|
||||
.letter = "N",
|
||||
.left = "DEF",
|
||||
.highlight = false,
|
||||
.right = "RCL",
|
||||
.sub = 0 },
|
||||
{.x = 2 * KB_COLUMN_WIDTH_6_KEYS,
|
||||
.y = 2 * KB_LINE_HEIGHT,
|
||||
.w = 36,
|
||||
.h = 26,
|
||||
.label_color = UI4X_COLOR_LABEL,
|
||||
.label_text = "EVAL",
|
||||
.font_size = 0,
|
||||
.label_graphic_w = 0,
|
||||
.label_graphic_h = 0,
|
||||
.label_graphic = 0,
|
||||
.letter = "O",
|
||||
.left = "\x80Q",
|
||||
.highlight = false,
|
||||
.right = "\x80NUM",
|
||||
.sub = 0 },
|
||||
{.x = 3 * KB_COLUMN_WIDTH_6_KEYS,
|
||||
.y = 2 * KB_LINE_HEIGHT,
|
||||
.w = 36,
|
||||
.h = 26,
|
||||
.label_color = UI4X_COLOR_LABEL,
|
||||
.label_text = 0,
|
||||
.font_size = 0,
|
||||
.label_graphic_w = left_width,
|
||||
.label_graphic_h = left_height,
|
||||
.label_graphic = left_bitmap,
|
||||
.letter = "P",
|
||||
.left = "GRAPH",
|
||||
.highlight = false,
|
||||
.right = 0,
|
||||
.sub = 0 },
|
||||
{.x = 4 * KB_COLUMN_WIDTH_6_KEYS,
|
||||
.y = 2 * KB_LINE_HEIGHT,
|
||||
.w = 36,
|
||||
.h = 26,
|
||||
.label_color = UI4X_COLOR_LABEL,
|
||||
.label_text = 0,
|
||||
.font_size = 0,
|
||||
.label_graphic_w = down_width,
|
||||
.label_graphic_h = down_height,
|
||||
.label_graphic = down_bitmap,
|
||||
.letter = "Q",
|
||||
.left = "REVIEW",
|
||||
.highlight = false,
|
||||
.right = 0,
|
||||
.sub = 0 },
|
||||
{.x = 5 * KB_COLUMN_WIDTH_6_KEYS,
|
||||
.y = 2 * KB_LINE_HEIGHT,
|
||||
.w = 36,
|
||||
.h = 26,
|
||||
.label_color = UI4X_COLOR_LABEL,
|
||||
.label_text = 0,
|
||||
.font_size = 0,
|
||||
.label_graphic_w = right_width,
|
||||
.label_graphic_h = right_height,
|
||||
.label_graphic = right_bitmap,
|
||||
.letter = "R",
|
||||
.left = "SWAP",
|
||||
.highlight = false,
|
||||
.right = 0,
|
||||
.sub = 0 },
|
||||
|
||||
{.x = 0,
|
||||
.y = 3 * KB_LINE_HEIGHT,
|
||||
.w = 36,
|
||||
.h = 26,
|
||||
.label_color = UI4X_COLOR_LABEL,
|
||||
.label_text = "SIN",
|
||||
.font_size = 0,
|
||||
.label_graphic_w = 0,
|
||||
.label_graphic_h = 0,
|
||||
.label_graphic = 0,
|
||||
.letter = "S",
|
||||
.left = "ASIN",
|
||||
.highlight = false,
|
||||
.right = "\x07",
|
||||
.sub = 0 },
|
||||
{.x = KB_COLUMN_WIDTH_6_KEYS,
|
||||
.y = 3 * KB_LINE_HEIGHT,
|
||||
.w = 36,
|
||||
.h = 26,
|
||||
.label_color = UI4X_COLOR_LABEL,
|
||||
.label_text = "COS",
|
||||
.font_size = 0,
|
||||
.label_graphic_w = 0,
|
||||
.label_graphic_h = 0,
|
||||
.label_graphic = 0,
|
||||
.letter = "T",
|
||||
.left = "ACOS",
|
||||
.highlight = false,
|
||||
.right = "\x08",
|
||||
.sub = 0 },
|
||||
{.x = 2 * KB_COLUMN_WIDTH_6_KEYS,
|
||||
.y = 3 * KB_LINE_HEIGHT,
|
||||
.w = 36,
|
||||
.h = 26,
|
||||
.label_color = UI4X_COLOR_LABEL,
|
||||
.label_text = "TAN",
|
||||
.font_size = 0,
|
||||
.label_graphic_w = 0,
|
||||
.label_graphic_h = 0,
|
||||
.label_graphic = 0,
|
||||
.letter = "U",
|
||||
.left = "ATAN",
|
||||
.highlight = false,
|
||||
.right = "\x09",
|
||||
.sub = 0 },
|
||||
{.x = 3 * KB_COLUMN_WIDTH_6_KEYS,
|
||||
.y = 3 * KB_LINE_HEIGHT,
|
||||
.w = 36,
|
||||
.h = 26,
|
||||
.label_color = UI4X_COLOR_LABEL,
|
||||
.label_text = 0,
|
||||
.font_size = 0,
|
||||
.label_graphic_w = sqrt_width,
|
||||
.label_graphic_h = sqrt_height,
|
||||
.label_graphic = sqrt_bitmap,
|
||||
.letter = "V",
|
||||
.left = "\x0a",
|
||||
.highlight = false,
|
||||
.right = "\x0b",
|
||||
.sub = 0 },
|
||||
{.x = 4 * KB_COLUMN_WIDTH_6_KEYS,
|
||||
.y = 3 * KB_LINE_HEIGHT,
|
||||
.w = 36,
|
||||
.h = 26,
|
||||
.label_color = UI4X_COLOR_LABEL,
|
||||
.label_text = 0,
|
||||
.font_size = 0,
|
||||
.label_graphic_w = power_width,
|
||||
.label_graphic_h = power_height,
|
||||
.label_graphic = power_bitmap,
|
||||
.letter = "W",
|
||||
.left = "\x0c",
|
||||
.highlight = false,
|
||||
.right = "LOG",
|
||||
.sub = 0 },
|
||||
{.x = 5 * KB_COLUMN_WIDTH_6_KEYS,
|
||||
.y = 3 * KB_LINE_HEIGHT,
|
||||
.w = 36,
|
||||
.h = 26,
|
||||
.label_color = UI4X_COLOR_LABEL,
|
||||
.label_text = 0,
|
||||
.font_size = 0,
|
||||
.label_graphic_w = inv_width,
|
||||
.label_graphic_h = inv_height,
|
||||
.label_graphic = inv_bitmap,
|
||||
.letter = "X",
|
||||
.left = "\x0d",
|
||||
.highlight = false,
|
||||
.right = "LN",
|
||||
.sub = 0 },
|
||||
|
||||
{.x = 0,
|
||||
.y = 4 * KB_LINE_HEIGHT,
|
||||
.w = 86,
|
||||
.h = 26,
|
||||
.label_color = UI4X_COLOR_LABEL,
|
||||
.label_text = "ENTER",
|
||||
.font_size = 2,
|
||||
.label_graphic_w = 0,
|
||||
.label_graphic_h = 0,
|
||||
.label_graphic = 0,
|
||||
.letter = 0,
|
||||
.left = "EQUATION",
|
||||
.highlight = false,
|
||||
.right = "MATRIX",
|
||||
.sub = 0 },
|
||||
{.x = 2 * KB_COLUMN_WIDTH_6_KEYS,
|
||||
.y = 4 * KB_LINE_HEIGHT,
|
||||
.w = 36,
|
||||
.h = 26,
|
||||
.label_color = UI4X_COLOR_LABEL,
|
||||
.label_text = 0,
|
||||
.font_size = 0,
|
||||
.label_graphic_w = neg_width,
|
||||
.label_graphic_h = neg_height,
|
||||
.label_graphic = neg_bitmap,
|
||||
.letter = "Y",
|
||||
.left = "EDIT",
|
||||
.highlight = false,
|
||||
.right = "VISIT",
|
||||
.sub = 0 },
|
||||
{.x = 3 * KB_COLUMN_WIDTH_6_KEYS,
|
||||
.y = 4 * KB_LINE_HEIGHT,
|
||||
.w = 36,
|
||||
.h = 26,
|
||||
.label_color = UI4X_COLOR_LABEL,
|
||||
.label_text = "EEX",
|
||||
.font_size = 0,
|
||||
.label_graphic_w = 0,
|
||||
.label_graphic_h = 0,
|
||||
.label_graphic = 0,
|
||||
.letter = "Z",
|
||||
.left = "2D",
|
||||
.highlight = false,
|
||||
.right = "3D",
|
||||
.sub = 0 },
|
||||
{.x = 4 * KB_COLUMN_WIDTH_6_KEYS,
|
||||
.y = 4 * KB_LINE_HEIGHT,
|
||||
.w = 36,
|
||||
.h = 26,
|
||||
.label_color = UI4X_COLOR_LABEL,
|
||||
.label_text = "DEL",
|
||||
.font_size = 0,
|
||||
.label_graphic_w = 0,
|
||||
.label_graphic_h = 0,
|
||||
.label_graphic = 0,
|
||||
.letter = 0,
|
||||
.left = "PURGE",
|
||||
.highlight = false,
|
||||
.right = 0,
|
||||
.sub = 0 },
|
||||
{.x = 5 * KB_COLUMN_WIDTH_6_KEYS,
|
||||
.y = 4 * KB_LINE_HEIGHT,
|
||||
.w = 36,
|
||||
.h = 26,
|
||||
.label_color = UI4X_COLOR_LABEL,
|
||||
.label_text = 0,
|
||||
.font_size = 0,
|
||||
.label_graphic_w = bs_width,
|
||||
.label_graphic_h = bs_height,
|
||||
.label_graphic = bs_bitmap,
|
||||
.letter = 0,
|
||||
.left = "DROP",
|
||||
.highlight = false,
|
||||
.right = "CLR",
|
||||
.sub = 0 },
|
||||
|
||||
{.x = 0,
|
||||
.y = 5 * KB_LINE_HEIGHT,
|
||||
.w = 36,
|
||||
.h = 26,
|
||||
.label_color = UI4X_COLOR_LABEL,
|
||||
.label_text = 0,
|
||||
.font_size = 0,
|
||||
.label_graphic_w = alpha_width,
|
||||
.label_graphic_h = alpha_height,
|
||||
.label_graphic = alpha_bitmap,
|
||||
.letter = 0,
|
||||
.left = "USR",
|
||||
.highlight = false,
|
||||
.right = "ENTRY",
|
||||
.sub = 0 },
|
||||
{.x = KB_COLUMN_WIDTH_5_KEYS,
|
||||
.y = 5 * KB_LINE_HEIGHT,
|
||||
.w = 46,
|
||||
.h = 26,
|
||||
.label_color = UI4X_COLOR_LABEL,
|
||||
.label_text = "7",
|
||||
.font_size = 1,
|
||||
.label_graphic_w = 0,
|
||||
.label_graphic_h = 0,
|
||||
.label_graphic = 0,
|
||||
.letter = 0,
|
||||
.left = "SOLVE",
|
||||
.highlight = true,
|
||||
.right = 0,
|
||||
.sub = 0 },
|
||||
{.x = 2 * KB_COLUMN_WIDTH_5_KEYS,
|
||||
.y = 5 * KB_LINE_HEIGHT,
|
||||
.w = 46,
|
||||
.h = 26,
|
||||
.label_color = UI4X_COLOR_LABEL,
|
||||
.label_text = "8",
|
||||
.font_size = 1,
|
||||
.label_graphic_w = 0,
|
||||
.label_graphic_h = 0,
|
||||
.label_graphic = 0,
|
||||
.letter = 0,
|
||||
.left = "PLOT",
|
||||
.highlight = true,
|
||||
.right = 0,
|
||||
.sub = 0 },
|
||||
{.x = 3 * KB_COLUMN_WIDTH_5_KEYS,
|
||||
.y = 5 * KB_LINE_HEIGHT,
|
||||
.w = 46,
|
||||
.h = 26,
|
||||
.label_color = UI4X_COLOR_LABEL,
|
||||
.label_text = "9",
|
||||
.font_size = 1,
|
||||
.label_graphic_w = 0,
|
||||
.label_graphic_h = 0,
|
||||
.label_graphic = 0,
|
||||
.letter = 0,
|
||||
.left = "ALGEBRA",
|
||||
.highlight = true,
|
||||
.right = 0,
|
||||
.sub = 0 },
|
||||
{.x = 4 * KB_COLUMN_WIDTH_5_KEYS,
|
||||
.y = 5 * KB_LINE_HEIGHT,
|
||||
.w = 46,
|
||||
.h = 26,
|
||||
.label_color = UI4X_COLOR_LABEL,
|
||||
.label_text = 0,
|
||||
.font_size = 0,
|
||||
.label_graphic_w = div_width,
|
||||
.label_graphic_h = div_height,
|
||||
.label_graphic = div_bitmap,
|
||||
.letter = 0,
|
||||
.left = "( )",
|
||||
.highlight = false,
|
||||
.right = "#",
|
||||
.sub = 0 },
|
||||
|
||||
{.x = 0,
|
||||
.y = 6 * KB_LINE_HEIGHT,
|
||||
.w = 36,
|
||||
.h = 26,
|
||||
.label_color = UI4X_COLOR_SHIFT_LEFT,
|
||||
.label_text = 0,
|
||||
.font_size = 0,
|
||||
.label_graphic_w = shl_width,
|
||||
.label_graphic_h = shl_height,
|
||||
.label_graphic = shl_bitmap,
|
||||
.letter = 0,
|
||||
.left = 0,
|
||||
.highlight = false,
|
||||
.right = 0,
|
||||
.sub = 0 },
|
||||
{.x = KB_COLUMN_WIDTH_5_KEYS,
|
||||
.y = 6 * KB_LINE_HEIGHT,
|
||||
.w = 46,
|
||||
.h = 26,
|
||||
.label_color = UI4X_COLOR_LABEL,
|
||||
.label_text = "4",
|
||||
.font_size = 1,
|
||||
.label_graphic_w = 0,
|
||||
.label_graphic_h = 0,
|
||||
.label_graphic = 0,
|
||||
.letter = 0,
|
||||
.left = "TIME",
|
||||
.highlight = true,
|
||||
.right = 0,
|
||||
.sub = 0 },
|
||||
{.x = 2 * KB_COLUMN_WIDTH_5_KEYS,
|
||||
.y = 6 * KB_LINE_HEIGHT,
|
||||
.w = 46,
|
||||
.h = 26,
|
||||
.label_color = UI4X_COLOR_LABEL,
|
||||
.label_text = "5",
|
||||
.font_size = 1,
|
||||
.label_graphic_w = 0,
|
||||
.label_graphic_h = 0,
|
||||
.label_graphic = 0,
|
||||
.letter = 0,
|
||||
.left = "STAT",
|
||||
.highlight = true,
|
||||
.right = 0,
|
||||
.sub = 0 },
|
||||
{.x = 3 * KB_COLUMN_WIDTH_5_KEYS,
|
||||
.y = 6 * KB_LINE_HEIGHT,
|
||||
.w = 46,
|
||||
.h = 26,
|
||||
.label_color = UI4X_COLOR_LABEL,
|
||||
.label_text = "6",
|
||||
.font_size = 1,
|
||||
.label_graphic_w = 0,
|
||||
.label_graphic_h = 0,
|
||||
.label_graphic = 0,
|
||||
.letter = 0,
|
||||
.left = "UNITS",
|
||||
.highlight = true,
|
||||
.right = 0,
|
||||
.sub = 0 },
|
||||
{.x = 4 * KB_COLUMN_WIDTH_5_KEYS,
|
||||
.y = 6 * KB_LINE_HEIGHT,
|
||||
.w = 46,
|
||||
.h = 26,
|
||||
.label_color = UI4X_COLOR_LABEL,
|
||||
.label_text = 0,
|
||||
.font_size = 0,
|
||||
.label_graphic_w = mul_width,
|
||||
.label_graphic_h = mul_height,
|
||||
.label_graphic = mul_bitmap,
|
||||
.letter = 0,
|
||||
.left = "[ ]",
|
||||
.highlight = false,
|
||||
.right = "_",
|
||||
.sub = 0 },
|
||||
|
||||
{.x = 0,
|
||||
.y = 7 * KB_LINE_HEIGHT,
|
||||
.w = 36,
|
||||
.h = 26,
|
||||
.label_color = UI4X_COLOR_SHIFT_RIGHT,
|
||||
.label_text = 0,
|
||||
.font_size = 0,
|
||||
.label_graphic_w = shr_width,
|
||||
.label_graphic_h = shr_height,
|
||||
.label_graphic = shr_bitmap,
|
||||
.letter = 0,
|
||||
.left = 0,
|
||||
.highlight = false,
|
||||
.right = 0,
|
||||
.sub = 0 },
|
||||
{.x = KB_COLUMN_WIDTH_5_KEYS,
|
||||
.y = 7 * KB_LINE_HEIGHT,
|
||||
.w = 46,
|
||||
.h = 26,
|
||||
.label_color = UI4X_COLOR_LABEL,
|
||||
.label_text = "1",
|
||||
.font_size = 1,
|
||||
.label_graphic_w = 0,
|
||||
.label_graphic_h = 0,
|
||||
.label_graphic = 0,
|
||||
.letter = 0,
|
||||
.left = "RAD",
|
||||
.highlight = false,
|
||||
.right = "POLAR",
|
||||
.sub = 0 },
|
||||
{.x = 2 * KB_COLUMN_WIDTH_5_KEYS,
|
||||
.y = 7 * KB_LINE_HEIGHT,
|
||||
.w = 46,
|
||||
.h = 26,
|
||||
.label_color = UI4X_COLOR_LABEL,
|
||||
.label_text = "2",
|
||||
.font_size = 1,
|
||||
.label_graphic_w = 0,
|
||||
.label_graphic_h = 0,
|
||||
.label_graphic = 0,
|
||||
.letter = 0,
|
||||
.left = "STACK",
|
||||
.highlight = false,
|
||||
.right = "ARG",
|
||||
.sub = 0 },
|
||||
{.x = 3 * KB_COLUMN_WIDTH_5_KEYS,
|
||||
.y = 7 * KB_LINE_HEIGHT,
|
||||
.w = 46,
|
||||
.h = 26,
|
||||
.label_color = UI4X_COLOR_LABEL,
|
||||
.label_text = "3",
|
||||
.font_size = 1,
|
||||
.label_graphic_w = 0,
|
||||
.label_graphic_h = 0,
|
||||
.label_graphic = 0,
|
||||
.letter = 0,
|
||||
.left = "CMD",
|
||||
.highlight = false,
|
||||
.right = "MENU",
|
||||
.sub = 0 },
|
||||
{.x = 4 * KB_COLUMN_WIDTH_5_KEYS,
|
||||
.y = 7 * KB_LINE_HEIGHT,
|
||||
.w = 46,
|
||||
.h = 26,
|
||||
.label_color = UI4X_COLOR_LABEL,
|
||||
.label_text = 0,
|
||||
.font_size = 0,
|
||||
.label_graphic_w = minus_width,
|
||||
.label_graphic_h = minus_height,
|
||||
.label_graphic = minus_bitmap,
|
||||
.letter = 0,
|
||||
.left = "\x0e",
|
||||
.highlight = false,
|
||||
.right = "\x0f",
|
||||
.sub = 0 },
|
||||
|
||||
{.x = 0,
|
||||
.y = 8 * KB_LINE_HEIGHT,
|
||||
.w = 36,
|
||||
.h = 26,
|
||||
.label_color = UI4X_COLOR_LABEL,
|
||||
.label_text = "ON",
|
||||
.font_size = 0,
|
||||
.label_graphic_w = 0,
|
||||
.label_graphic_h = 0,
|
||||
.label_graphic = 0,
|
||||
.letter = 0,
|
||||
.left = "CONT",
|
||||
.highlight = false,
|
||||
.right = "OFF",
|
||||
.sub = "ATTN"},
|
||||
{.x = KB_COLUMN_WIDTH_5_KEYS,
|
||||
.y = 8 * KB_LINE_HEIGHT,
|
||||
.w = 46,
|
||||
.h = 26,
|
||||
.label_color = UI4X_COLOR_LABEL,
|
||||
.label_text = "0",
|
||||
.font_size = 1,
|
||||
.label_graphic_w = 0,
|
||||
.label_graphic_h = 0,
|
||||
.label_graphic = 0,
|
||||
.letter = 0,
|
||||
.left = "= ",
|
||||
.highlight = false,
|
||||
.right = " \x80",
|
||||
.sub = 0 },
|
||||
{.x = 2 * KB_COLUMN_WIDTH_5_KEYS,
|
||||
.y = 8 * KB_LINE_HEIGHT,
|
||||
.w = 46,
|
||||
.h = 26,
|
||||
.label_color = UI4X_COLOR_LABEL,
|
||||
.label_text = ".",
|
||||
.font_size = 1,
|
||||
.label_graphic_w = 0,
|
||||
.label_graphic_h = 0,
|
||||
.label_graphic = 0,
|
||||
.letter = 0,
|
||||
.left = ",",
|
||||
.highlight = false,
|
||||
.right = " \x10",
|
||||
.sub = 0 },
|
||||
{.x = 3 * KB_COLUMN_WIDTH_5_KEYS,
|
||||
.y = 8 * KB_LINE_HEIGHT,
|
||||
.w = 46,
|
||||
.h = 26,
|
||||
.label_color = UI4X_COLOR_LABEL,
|
||||
.label_text = "SPC",
|
||||
.font_size = 0,
|
||||
.label_graphic_w = 0,
|
||||
.label_graphic_h = 0,
|
||||
.label_graphic = 0,
|
||||
.letter = 0,
|
||||
.left = "\x11 ",
|
||||
.highlight = false,
|
||||
.right = " \x12",
|
||||
.sub = 0 },
|
||||
{.x = 4 * KB_COLUMN_WIDTH_5_KEYS,
|
||||
.y = 8 * KB_LINE_HEIGHT,
|
||||
.w = 46,
|
||||
.h = 26,
|
||||
.label_color = UI4X_COLOR_LABEL,
|
||||
.label_text = 0,
|
||||
.font_size = 0,
|
||||
.label_graphic_w = plus_width,
|
||||
.label_graphic_h = plus_height,
|
||||
.label_graphic = plus_bitmap,
|
||||
.letter = 0,
|
||||
.left = "{ }",
|
||||
.highlight = false,
|
||||
.right = ": :",
|
||||
.sub = 0 },
|
||||
};
|
940
src/ui4x/49g.c
940
src/ui4x/49g.c
|
@ -1,940 +0,0 @@
|
|||
#include "inner.h"
|
||||
|
||||
color_t colors_49g[ NB_COLORS ] = {
|
||||
/* UI4X_COLOR_HP_LOGO */
|
||||
{
|
||||
.a = 0xff,
|
||||
.mono_rgb = 0xff,
|
||||
.gray_rgb = 0xB0,
|
||||
.rgb = 0xB0B0B8,
|
||||
},
|
||||
/* UI4X_COLOR_HP_LOGO_BG */
|
||||
{
|
||||
.a = 0xff,
|
||||
.mono_rgb = 0x00,
|
||||
.gray_rgb = 0x68,
|
||||
.rgb = 0x131313,
|
||||
},
|
||||
/* UI4X_COLOR_48GX_128K_RAM */
|
||||
{
|
||||
.a = 0xff,
|
||||
.mono_rgb = 0xff,
|
||||
.gray_rgb = 0xF0,
|
||||
.rgb = 0xF0F0F0,
|
||||
},
|
||||
/* UI4X_COLOR_FRAME */
|
||||
{
|
||||
.a = 0xff,
|
||||
.mono_rgb = 0xff,
|
||||
.gray_rgb = 0x00,
|
||||
.rgb = 0x000000,
|
||||
},
|
||||
/* UI4X_COLOR_UPPER_FACEPLATE_EDGE_TOP */
|
||||
{
|
||||
.a = 0xff,
|
||||
.mono_rgb = 0x00,
|
||||
.gray_rgb = 0x80,
|
||||
.rgb = 0x000000,
|
||||
},
|
||||
/* UI4X_COLOR_UPPER_FACEPLATE */
|
||||
{
|
||||
.a = 0xff,
|
||||
.mono_rgb = 0x00,
|
||||
.gray_rgb = 0x68,
|
||||
.rgb = 0x262626,
|
||||
},
|
||||
/* UI4X_COLOR_UPPER_FACEPLATE_EDGE_BOTTOM */
|
||||
{
|
||||
.a = 0xff,
|
||||
.mono_rgb = 0x00,
|
||||
.gray_rgb = 0x54,
|
||||
.rgb = 0x000000,
|
||||
},
|
||||
/* UI4X_COLOR_FACEPLATE_EDGE_TOP */
|
||||
{
|
||||
.a = 0xff,
|
||||
.mono_rgb = 0x00,
|
||||
.gray_rgb = 0x58,
|
||||
.rgb = 0x585858,
|
||||
},
|
||||
/* UI4X_COLOR_FACEPLATE */
|
||||
{
|
||||
.a = 0xff,
|
||||
.mono_rgb = 0x00,
|
||||
.gray_rgb = 0x4A,
|
||||
.rgb = 0x272727,
|
||||
},
|
||||
/* UI4X_COLOR_FACEPLATE_EDGE_BOTTOM */
|
||||
{
|
||||
.a = 0xff,
|
||||
.mono_rgb = 0x00,
|
||||
.gray_rgb = 0x40,
|
||||
.rgb = 0x404040,
|
||||
},
|
||||
/* UI4X_COLOR_KEYPAD_HIGHLIGHT */
|
||||
{
|
||||
.a = 0xff,
|
||||
.mono_rgb = 0x00,
|
||||
.gray_rgb = 0x68,
|
||||
.rgb = 0x4f6165,
|
||||
},
|
||||
/* UI4X_COLOR_BUTTON_EDGE_TOP */
|
||||
{
|
||||
.a = 0xff,
|
||||
.mono_rgb = 0x00,
|
||||
.gray_rgb = 0x68,
|
||||
.rgb = 0x4b4b4b,
|
||||
},
|
||||
/* UI4X_COLOR_BUTTON */
|
||||
{
|
||||
.a = 0xff,
|
||||
.mono_rgb = 0x00,
|
||||
.gray_rgb = 0x58,
|
||||
.rgb = 0x3f3f3f,
|
||||
},
|
||||
/* UI4X_COLOR_BUTTON_EDGE_BOTTOM */
|
||||
{
|
||||
.a = 0xff,
|
||||
.mono_rgb = 0x00,
|
||||
.gray_rgb = 0x4A,
|
||||
.rgb = 0x3d3d3d,
|
||||
},
|
||||
/* UI4X_COLOR_PIXEL_OFF */
|
||||
{
|
||||
.a = 0xff,
|
||||
.mono_rgb = 0xff,
|
||||
.gray_rgb = 0xCD,
|
||||
.rgb = 0xcdcdcd,
|
||||
},
|
||||
/* UI4X_COLOR_PIXEL_ON */
|
||||
{
|
||||
.a = 0xff,
|
||||
.mono_rgb = 0x00,
|
||||
.gray_rgb = 0x14,
|
||||
.rgb = 0x000000,
|
||||
},
|
||||
/* UI4X_COLOR_BLACK_PIXEL_OFF */
|
||||
{
|
||||
.a = 0xFF,
|
||||
.mono_rgb = 0xFF,
|
||||
.gray_rgb = 0xCD,
|
||||
.rgb = 0xf5f5f5,
|
||||
},
|
||||
/* UI4X_COLOR_BLACK_PIXEL_ON */
|
||||
{
|
||||
.a = 0xFF,
|
||||
.mono_rgb = 0x0,
|
||||
.gray_rgb = 0x14,
|
||||
.rgb = 0x000000,
|
||||
},
|
||||
/* UI4X_COLOR_LABEL */
|
||||
{
|
||||
.a = 0xff,
|
||||
.mono_rgb = 0xff,
|
||||
.gray_rgb = 0xff,
|
||||
.rgb = 0xffffff,
|
||||
},
|
||||
/* UI4X_COLOR_ALPHA */
|
||||
{
|
||||
.a = 0xff,
|
||||
.mono_rgb = 0xff,
|
||||
.gray_rgb = 0xDC,
|
||||
.rgb = 0x67c184,
|
||||
},
|
||||
/* UI4X_COLOR_SHIFT_LEFT */
|
||||
{
|
||||
.a = 0xff,
|
||||
.mono_rgb = 0xff,
|
||||
.gray_rgb = 0xDC,
|
||||
.rgb = 0x82b1ff,
|
||||
},
|
||||
/* UI4X_COLOR_SHIFT_RIGHT */
|
||||
{
|
||||
.a = 0xff,
|
||||
.mono_rgb = 0xff,
|
||||
.gray_rgb = 0xA9,
|
||||
.rgb = 0xff8a80,
|
||||
},
|
||||
};
|
||||
|
||||
#define KB_LINE_HEIGHT 48
|
||||
#define KB_COLUMN_WIDTH_6_KEYS 50
|
||||
#define KB_COLUMN_WIDTH_5_KEYS 60
|
||||
|
||||
button_t buttons_49g[ NB_HP49_KEYS ] = {
|
||||
{.x = 0,
|
||||
.y = 0,
|
||||
.w = 36,
|
||||
.h = 26,
|
||||
.label_color = UI4X_COLOR_LABEL,
|
||||
.label_text = "F1",
|
||||
.font_size = 0,
|
||||
.label_graphic_w = 0,
|
||||
.label_graphic_h = 0,
|
||||
.label_graphic = 0,
|
||||
.letter = "A",
|
||||
.left = "Y=",
|
||||
.highlight = false,
|
||||
.right = 0,
|
||||
.sub = 0 },
|
||||
{.x = KB_COLUMN_WIDTH_6_KEYS,
|
||||
.y = 0,
|
||||
.w = 36,
|
||||
.h = 26,
|
||||
.label_color = UI4X_COLOR_LABEL,
|
||||
.label_text = "F2",
|
||||
.font_size = 0,
|
||||
.label_graphic_w = 0,
|
||||
.label_graphic_h = 0,
|
||||
.label_graphic = 0,
|
||||
.letter = "B",
|
||||
.left = "WIN",
|
||||
.highlight = false,
|
||||
.right = 0,
|
||||
.sub = 0 },
|
||||
{.x = 2 * KB_COLUMN_WIDTH_6_KEYS,
|
||||
.y = 0,
|
||||
.w = 36,
|
||||
.h = 26,
|
||||
.label_color = UI4X_COLOR_LABEL,
|
||||
.label_text = "F3",
|
||||
.font_size = 0,
|
||||
.label_graphic_w = 0,
|
||||
.label_graphic_h = 0,
|
||||
.label_graphic = 0,
|
||||
.letter = "C",
|
||||
.left = "GRAPH",
|
||||
.highlight = false,
|
||||
.right = 0,
|
||||
.sub = 0 },
|
||||
{.x = 3 * KB_COLUMN_WIDTH_6_KEYS,
|
||||
.y = 0,
|
||||
.w = 36,
|
||||
.h = 26,
|
||||
.label_color = UI4X_COLOR_LABEL,
|
||||
.label_text = "F4",
|
||||
.font_size = 0,
|
||||
.label_graphic_w = 0,
|
||||
.label_graphic_h = 0,
|
||||
.label_graphic = 0,
|
||||
.letter = "D",
|
||||
.left = "2D/3D",
|
||||
.highlight = false,
|
||||
.right = 0,
|
||||
.sub = 0 },
|
||||
{.x = 4 * KB_COLUMN_WIDTH_6_KEYS,
|
||||
.y = 0,
|
||||
.w = 36,
|
||||
.h = 26,
|
||||
.label_color = UI4X_COLOR_LABEL,
|
||||
.label_text = "F5",
|
||||
.font_size = 0,
|
||||
.label_graphic_w = 0,
|
||||
.label_graphic_h = 0,
|
||||
.label_graphic = 0,
|
||||
.letter = "E",
|
||||
.left = "TBLSET",
|
||||
.highlight = false,
|
||||
.right = 0,
|
||||
.sub = 0 },
|
||||
{.x = 5 * KB_COLUMN_WIDTH_6_KEYS,
|
||||
.y = 0,
|
||||
.w = 36,
|
||||
.h = 26,
|
||||
.label_color = UI4X_COLOR_LABEL,
|
||||
.label_text = "F6",
|
||||
.font_size = 0,
|
||||
.label_graphic_w = 0,
|
||||
.label_graphic_h = 0,
|
||||
.label_graphic = 0,
|
||||
.letter = "F",
|
||||
.left = "TABLE",
|
||||
.highlight = false,
|
||||
.right = 0,
|
||||
.sub = 0 },
|
||||
|
||||
{.x = 0,
|
||||
.y = 1 * KB_LINE_HEIGHT,
|
||||
.w = 46,
|
||||
.h = 26,
|
||||
.label_color = UI4X_COLOR_LABEL,
|
||||
.label_text = "APPS",
|
||||
.font_size = 0,
|
||||
.label_graphic_w = 0,
|
||||
.label_graphic_h = 0,
|
||||
.label_graphic = 0,
|
||||
.letter = "G",
|
||||
.left = "FILES",
|
||||
.highlight = false,
|
||||
.right = "BEGIN",
|
||||
.sub = 0 },
|
||||
{.x = KB_COLUMN_WIDTH_5_KEYS,
|
||||
.y = 1 * KB_LINE_HEIGHT,
|
||||
.w = 46,
|
||||
.h = 26,
|
||||
.label_color = UI4X_COLOR_LABEL,
|
||||
.label_text = "MODE",
|
||||
.font_size = 0,
|
||||
.label_graphic_w = 0,
|
||||
.label_graphic_h = 0,
|
||||
.label_graphic = 0,
|
||||
.letter = "H",
|
||||
.left = "CUSTOM",
|
||||
.highlight = false,
|
||||
.right = "END",
|
||||
.sub = 0 },
|
||||
{.x = 2 * KB_COLUMN_WIDTH_5_KEYS,
|
||||
.y = 1 * KB_LINE_HEIGHT,
|
||||
.w = 46,
|
||||
.h = 26,
|
||||
.label_color = UI4X_COLOR_LABEL,
|
||||
.label_text = "TOOL",
|
||||
.font_size = 0,
|
||||
.label_graphic_w = 0,
|
||||
.label_graphic_h = 0,
|
||||
.label_graphic = 0,
|
||||
.letter = "I",
|
||||
.left = "i",
|
||||
.highlight = false,
|
||||
.right = "I",
|
||||
.sub = 0 },
|
||||
|
||||
{.x = 0,
|
||||
.y = 2 * KB_LINE_HEIGHT,
|
||||
.w = 46,
|
||||
.h = 26,
|
||||
.label_color = UI4X_COLOR_LABEL,
|
||||
.label_text = "VAR",
|
||||
.font_size = 0,
|
||||
.label_graphic_w = 0,
|
||||
.label_graphic_h = 0,
|
||||
.label_graphic = 0,
|
||||
.letter = "J",
|
||||
.left = "UPDIR",
|
||||
.highlight = false,
|
||||
.right = "COPY",
|
||||
.sub = 0 },
|
||||
{.x = KB_COLUMN_WIDTH_5_KEYS,
|
||||
.y = 2 * KB_LINE_HEIGHT,
|
||||
.w = 46,
|
||||
.h = 26,
|
||||
.label_color = UI4X_COLOR_LABEL,
|
||||
.label_text = "STO",
|
||||
.font_size = 0,
|
||||
.label_graphic_w = 0,
|
||||
.label_graphic_h = 0,
|
||||
.label_graphic = 0,
|
||||
.letter = "K",
|
||||
.left = "RCL",
|
||||
.highlight = false,
|
||||
.right = "CUT",
|
||||
.sub = 0 },
|
||||
{.x = 2 * KB_COLUMN_WIDTH_5_KEYS,
|
||||
.y = 2 * KB_LINE_HEIGHT,
|
||||
.w = 46,
|
||||
.h = 26,
|
||||
.label_color = UI4X_COLOR_LABEL,
|
||||
.label_text = "NXT",
|
||||
.font_size = 0,
|
||||
.label_graphic_w = 0,
|
||||
.label_graphic_h = 0,
|
||||
.label_graphic = 0,
|
||||
.letter = "L",
|
||||
.left = "PREV",
|
||||
.highlight = false,
|
||||
.right = "PASTE",
|
||||
.sub = 0 },
|
||||
|
||||
{.x = 3 * KB_COLUMN_WIDTH_5_KEYS,
|
||||
.y = 1.4 * KB_LINE_HEIGHT,
|
||||
.w = 46,
|
||||
.h = 26,
|
||||
.label_color = UI4X_COLOR_LABEL,
|
||||
.label_text = 0,
|
||||
.font_size = 0,
|
||||
.label_graphic_w = left_width,
|
||||
.label_graphic_h = left_height,
|
||||
.label_graphic = left_bitmap,
|
||||
.letter = 0,
|
||||
.left = 0,
|
||||
.highlight = false,
|
||||
.right = 0,
|
||||
.sub = 0 },
|
||||
{.x = 210,
|
||||
.y = 0.75 * KB_LINE_HEIGHT,
|
||||
.w = 46,
|
||||
.h = 26,
|
||||
.label_color = UI4X_COLOR_LABEL,
|
||||
.label_text = 0,
|
||||
.font_size = 0,
|
||||
.label_graphic_w = up_width,
|
||||
.label_graphic_h = up_height,
|
||||
.label_graphic = up_bitmap,
|
||||
.letter = 0,
|
||||
.left = 0,
|
||||
.highlight = false,
|
||||
.right = 0,
|
||||
.sub = 0 },
|
||||
{.x = 4 * KB_COLUMN_WIDTH_5_KEYS,
|
||||
.y = 1.4 * KB_LINE_HEIGHT,
|
||||
.w = 46,
|
||||
.h = 26,
|
||||
.label_color = UI4X_COLOR_LABEL,
|
||||
.label_text = 0,
|
||||
.font_size = 0,
|
||||
.label_graphic_w = right_width,
|
||||
.label_graphic_h = right_height,
|
||||
.label_graphic = right_bitmap,
|
||||
.letter = 0,
|
||||
.left = 0,
|
||||
.highlight = false,
|
||||
.right = 0,
|
||||
.sub = 0 },
|
||||
{.x = 210,
|
||||
.y = 2 * KB_LINE_HEIGHT,
|
||||
.w = 46,
|
||||
.h = 26,
|
||||
.label_color = UI4X_COLOR_LABEL,
|
||||
.label_text = 0,
|
||||
.font_size = 0,
|
||||
.label_graphic_w = down_width,
|
||||
.label_graphic_h = down_height,
|
||||
.label_graphic = down_bitmap,
|
||||
.letter = 0,
|
||||
.left = 0,
|
||||
.highlight = false,
|
||||
.right = 0,
|
||||
.sub = 0 },
|
||||
|
||||
{.x = 0,
|
||||
.y = 3 * KB_LINE_HEIGHT,
|
||||
.w = 46,
|
||||
.h = 26,
|
||||
.label_color = UI4X_COLOR_LABEL,
|
||||
.label_text = "HIST",
|
||||
.font_size = 0,
|
||||
.label_graphic_w = 0,
|
||||
.label_graphic_h = 0,
|
||||
.label_graphic = 0,
|
||||
.letter = "M",
|
||||
.left = "CMD",
|
||||
.highlight = false,
|
||||
.right = "UNDO",
|
||||
.sub = 0 },
|
||||
{.x = KB_COLUMN_WIDTH_5_KEYS,
|
||||
.y = 3 * KB_LINE_HEIGHT,
|
||||
.w = 46,
|
||||
.h = 26,
|
||||
.label_color = UI4X_COLOR_LABEL,
|
||||
.label_text = "CAT",
|
||||
.font_size = 0,
|
||||
.label_graphic_w = 0,
|
||||
.label_graphic_h = 0,
|
||||
.label_graphic = 0,
|
||||
.letter = "N",
|
||||
.left = "PRG",
|
||||
.highlight = false,
|
||||
.right = "CHARS",
|
||||
.sub = 0 },
|
||||
{.x = 2 * KB_COLUMN_WIDTH_5_KEYS,
|
||||
.y = 3 * KB_LINE_HEIGHT,
|
||||
.w = 46,
|
||||
.h = 26,
|
||||
.label_color = UI4X_COLOR_LABEL,
|
||||
.label_text = "EQW",
|
||||
.font_size = 0,
|
||||
.label_graphic_w = 0,
|
||||
.label_graphic_h = 0,
|
||||
.label_graphic = 0,
|
||||
.letter = "O",
|
||||
.left = "MTRW",
|
||||
.highlight = false,
|
||||
.right = "\x27",
|
||||
.sub = 0 },
|
||||
{.x = 3 * KB_COLUMN_WIDTH_5_KEYS,
|
||||
.y = 3 * KB_LINE_HEIGHT,
|
||||
.w = 46,
|
||||
.h = 26,
|
||||
.label_color = UI4X_COLOR_LABEL,
|
||||
.label_text = "SYMB",
|
||||
.font_size = 0,
|
||||
.label_graphic_w = 0,
|
||||
.label_graphic_h = 0,
|
||||
.label_graphic = 0,
|
||||
.letter = "P",
|
||||
.left = "MTH",
|
||||
.highlight = false,
|
||||
.right = "EVAL",
|
||||
.sub = 0 },
|
||||
{.x = 4 * KB_COLUMN_WIDTH_5_KEYS,
|
||||
.y = 3 * KB_LINE_HEIGHT,
|
||||
.w = 46,
|
||||
.h = 26,
|
||||
.label_color = UI4X_COLOR_LABEL,
|
||||
.label_text = 0,
|
||||
.font_size = 0,
|
||||
.label_graphic_w = bs_width,
|
||||
.label_graphic_h = bs_height,
|
||||
.label_graphic = bs_bitmap,
|
||||
.letter = 0,
|
||||
.left = "DEL",
|
||||
.highlight = false,
|
||||
.right = "CLEAR",
|
||||
.sub = 0 },
|
||||
|
||||
{.x = 0,
|
||||
.y = 4 * KB_LINE_HEIGHT,
|
||||
.w = 46,
|
||||
.h = 26,
|
||||
.label_color = UI4X_COLOR_LABEL,
|
||||
.label_text = 0,
|
||||
.font_size = 0,
|
||||
.label_graphic_w = power_width,
|
||||
.label_graphic_h = power_height,
|
||||
.label_graphic = power_bitmap,
|
||||
.letter = "Q",
|
||||
.left = "\x16",
|
||||
.highlight = false,
|
||||
.right = "LN",
|
||||
.sub = 0 },
|
||||
{.x = KB_COLUMN_WIDTH_5_KEYS,
|
||||
.y = 4 * KB_LINE_HEIGHT,
|
||||
.w = 46,
|
||||
.h = 26,
|
||||
.label_color = UI4X_COLOR_LABEL,
|
||||
.label_text = 0,
|
||||
.font_size = 0,
|
||||
.label_graphic_w = sqrt_width,
|
||||
.label_graphic_h = sqrt_height,
|
||||
.label_graphic = sqrt_bitmap,
|
||||
.letter = "R",
|
||||
.left = "\x13",
|
||||
.highlight = false,
|
||||
.right = "\x14",
|
||||
.sub = 0 },
|
||||
{.x = 2 * KB_COLUMN_WIDTH_5_KEYS,
|
||||
.y = 4 * KB_LINE_HEIGHT,
|
||||
.w = 46,
|
||||
.h = 26,
|
||||
.label_color = UI4X_COLOR_LABEL,
|
||||
.label_text = "SIN",
|
||||
.font_size = 0,
|
||||
.label_graphic_w = 0,
|
||||
.label_graphic_h = 0,
|
||||
.label_graphic = 0,
|
||||
.letter = "S",
|
||||
.left = "ASIN",
|
||||
.highlight = false,
|
||||
.right = "\x09",
|
||||
.sub = 0 },
|
||||
{.x = 3 * KB_COLUMN_WIDTH_5_KEYS,
|
||||
.y = 4 * KB_LINE_HEIGHT,
|
||||
.w = 46,
|
||||
.h = 26,
|
||||
.label_color = UI4X_COLOR_LABEL,
|
||||
.label_text = "COS",
|
||||
.font_size = 2,
|
||||
.label_graphic_w = 0,
|
||||
.label_graphic_h = 0,
|
||||
.label_graphic = 0,
|
||||
.letter = "T",
|
||||
.left = "ACOS",
|
||||
.highlight = false,
|
||||
.right = "\x07",
|
||||
.sub = 0 },
|
||||
{.x = 4 * KB_COLUMN_WIDTH_5_KEYS,
|
||||
.y = 4 * KB_LINE_HEIGHT,
|
||||
.w = 46,
|
||||
.h = 26,
|
||||
.label_color = UI4X_COLOR_LABEL,
|
||||
.label_text = "TAN",
|
||||
.font_size = 0,
|
||||
.label_graphic_w = 0,
|
||||
.label_graphic_h = 0,
|
||||
.label_graphic = 0,
|
||||
.letter = "U",
|
||||
.left = "ATAN",
|
||||
.highlight = false,
|
||||
.right = "\x08",
|
||||
.sub = 0 },
|
||||
|
||||
{.x = 0,
|
||||
.y = 5 * KB_LINE_HEIGHT,
|
||||
.w = 46,
|
||||
.h = 26,
|
||||
.label_color = UI4X_COLOR_LABEL,
|
||||
.label_text = "EEX",
|
||||
.font_size = 0,
|
||||
.label_graphic_w = 0,
|
||||
.label_graphic_h = 0,
|
||||
.label_graphic = 0,
|
||||
.letter = "V",
|
||||
.left = "\x15",
|
||||
.highlight = false,
|
||||
.right = "LOG",
|
||||
.sub = 0 },
|
||||
{.x = KB_COLUMN_WIDTH_5_KEYS,
|
||||
.y = 5 * KB_LINE_HEIGHT,
|
||||
.w = 46,
|
||||
.h = 26,
|
||||
.label_color = UI4X_COLOR_LABEL,
|
||||
.label_text = 0,
|
||||
.font_size = 0,
|
||||
.label_graphic_w = neg_width,
|
||||
.label_graphic_h = neg_height,
|
||||
.label_graphic = neg_bitmap,
|
||||
.letter = "W",
|
||||
.left = "\x60",
|
||||
.highlight = false,
|
||||
.right = "=",
|
||||
.sub = 0 },
|
||||
{.x = 2 * KB_COLUMN_WIDTH_5_KEYS,
|
||||
.y = 5 * KB_LINE_HEIGHT,
|
||||
.w = 46,
|
||||
.h = 26,
|
||||
.label_color = UI4X_COLOR_LABEL,
|
||||
.label_text = "X",
|
||||
.font_size = 0,
|
||||
.label_graphic_w = 0,
|
||||
.label_graphic_h = 0,
|
||||
.label_graphic = 0,
|
||||
.letter = "X",
|
||||
.left = "\x3b",
|
||||
.highlight = false,
|
||||
.right = "\x3c",
|
||||
.sub = 0 },
|
||||
{.x = 3 * KB_COLUMN_WIDTH_5_KEYS,
|
||||
.y = 5 * KB_LINE_HEIGHT,
|
||||
.w = 46,
|
||||
.h = 26,
|
||||
.label_color = UI4X_COLOR_LABEL,
|
||||
.label_text = 0,
|
||||
.font_size = 0,
|
||||
.label_graphic_w = inv_width,
|
||||
.label_graphic_h = inv_height,
|
||||
.label_graphic = inv_bitmap,
|
||||
.letter = "Y",
|
||||
.left = "\x3f",
|
||||
.highlight = false,
|
||||
.right = "\x3e",
|
||||
.sub = 0 },
|
||||
{.x = 4 * KB_COLUMN_WIDTH_5_KEYS,
|
||||
.y = 5 * KB_LINE_HEIGHT,
|
||||
.w = 46,
|
||||
.h = 26,
|
||||
.label_color = UI4X_COLOR_LABEL,
|
||||
.label_text = 0,
|
||||
.font_size = 0,
|
||||
.label_graphic_w = div_width,
|
||||
.label_graphic_h = div_height,
|
||||
.label_graphic = div_bitmap,
|
||||
.letter = "Z",
|
||||
.left = "ABS ",
|
||||
.highlight = false,
|
||||
.right = "ARG",
|
||||
.sub = 0 },
|
||||
|
||||
{.x = 0,
|
||||
.y = 6 * KB_LINE_HEIGHT,
|
||||
.w = 46,
|
||||
.h = 26,
|
||||
.label_color = UI4X_COLOR_ALPHA,
|
||||
.label_text = 0,
|
||||
.font_size = 0,
|
||||
.label_graphic_w = alpha_width,
|
||||
.label_graphic_h = alpha_height,
|
||||
.label_graphic = alpha_bitmap,
|
||||
.letter = 0,
|
||||
.left = "USER",
|
||||
.highlight = false,
|
||||
.right = "ENTRY",
|
||||
.sub = 0 },
|
||||
{.x = KB_COLUMN_WIDTH_5_KEYS,
|
||||
.y = 6 * KB_LINE_HEIGHT,
|
||||
.w = 46,
|
||||
.h = 26,
|
||||
.label_color = UI4X_COLOR_LABEL,
|
||||
.label_text = "7",
|
||||
.font_size = 1,
|
||||
.label_graphic_w = 0,
|
||||
.label_graphic_h = 0,
|
||||
.label_graphic = 0,
|
||||
.letter = 0,
|
||||
.left = "S.SLV",
|
||||
.highlight = false,
|
||||
.right = "N.SLV", //"NUM.SLV",
|
||||
.sub = 0},
|
||||
{.x = 2 * KB_COLUMN_WIDTH_5_KEYS,
|
||||
.y = 6 * KB_LINE_HEIGHT,
|
||||
.w = 46,
|
||||
.h = 26,
|
||||
.label_color = UI4X_COLOR_LABEL,
|
||||
.label_text = "8",
|
||||
.font_size = 1,
|
||||
.label_graphic_w = 0,
|
||||
.label_graphic_h = 0,
|
||||
.label_graphic = 0,
|
||||
.letter = 0,
|
||||
.left = "EXP", //"EXP&LN",
|
||||
.highlight = false,
|
||||
.right = "TRIG",
|
||||
.sub = 0 },
|
||||
{.x = 3 * KB_COLUMN_WIDTH_5_KEYS,
|
||||
.y = 6 * KB_LINE_HEIGHT,
|
||||
.w = 46,
|
||||
.h = 26,
|
||||
.label_color = UI4X_COLOR_LABEL,
|
||||
.label_text = "9",
|
||||
.font_size = 1,
|
||||
.label_graphic_w = 0,
|
||||
.label_graphic_h = 0,
|
||||
.label_graphic = 0,
|
||||
.letter = 0,
|
||||
.left = "FIN.", //"FINANCE",
|
||||
.highlight = false,
|
||||
.right = "TIME",
|
||||
.sub = 0 },
|
||||
{.x = 4 * KB_COLUMN_WIDTH_5_KEYS,
|
||||
.y = 6 * KB_LINE_HEIGHT,
|
||||
.w = 46,
|
||||
.h = 26,
|
||||
.label_color = UI4X_COLOR_LABEL,
|
||||
.label_text = 0,
|
||||
.font_size = 0,
|
||||
.label_graphic_w = mul_width,
|
||||
.label_graphic_h = mul_height,
|
||||
.label_graphic = mul_bitmap,
|
||||
.letter = 0,
|
||||
.left = "\x19 ",
|
||||
.highlight = false,
|
||||
.right = "\x1c",
|
||||
.sub = 0 },
|
||||
|
||||
{.x = 0,
|
||||
.y = 7 * KB_LINE_HEIGHT,
|
||||
.w = 46,
|
||||
.h = 26,
|
||||
.label_color = UI4X_COLOR_SHIFT_LEFT,
|
||||
.label_text = 0,
|
||||
.font_size = 0,
|
||||
.label_graphic_w = shl_width,
|
||||
.label_graphic_h = shl_height,
|
||||
.label_graphic = shl_bitmap,
|
||||
.letter = 0,
|
||||
.left = 0,
|
||||
.highlight = false,
|
||||
.right = 0,
|
||||
.sub = 0 },
|
||||
{.x = KB_COLUMN_WIDTH_5_KEYS,
|
||||
.y = 7 * KB_LINE_HEIGHT,
|
||||
.w = 46,
|
||||
.h = 26,
|
||||
.label_color = UI4X_COLOR_LABEL,
|
||||
.label_text = "4",
|
||||
.font_size = 1,
|
||||
.label_graphic_w = 0,
|
||||
.label_graphic_h = 0,
|
||||
.label_graphic = 0,
|
||||
.letter = 0,
|
||||
.left = "CALC",
|
||||
.highlight = false,
|
||||
.right = "ALG",
|
||||
.sub = 0 },
|
||||
{.x = 2 * KB_COLUMN_WIDTH_5_KEYS,
|
||||
.y = 7 * KB_LINE_HEIGHT,
|
||||
.w = 46,
|
||||
.h = 26,
|
||||
.label_color = UI4X_COLOR_LABEL,
|
||||
.label_text = "5",
|
||||
.font_size = 1,
|
||||
.label_graphic_w = 0,
|
||||
.label_graphic_h = 0,
|
||||
.label_graphic = 0,
|
||||
.letter = 0,
|
||||
.left = "MATR.", //"MATRICES",
|
||||
.highlight = false,
|
||||
.right = "STAT",
|
||||
.sub = 0 },
|
||||
{.x = 3 * KB_COLUMN_WIDTH_5_KEYS,
|
||||
.y = 7 * KB_LINE_HEIGHT,
|
||||
.w = 46,
|
||||
.h = 26,
|
||||
.label_color = UI4X_COLOR_LABEL,
|
||||
.label_text = "6",
|
||||
.font_size = 1,
|
||||
.label_graphic_w = 0,
|
||||
.label_graphic_h = 0,
|
||||
.label_graphic = 0,
|
||||
.letter = 0,
|
||||
.left = "CNVRT", //"CONVERT",
|
||||
.highlight = false,
|
||||
.right = "UNITS",
|
||||
.sub = 0 },
|
||||
{.x = 4 * KB_COLUMN_WIDTH_5_KEYS,
|
||||
.y = 7 * KB_LINE_HEIGHT,
|
||||
.w = 46,
|
||||
.h = 26,
|
||||
.label_color = UI4X_COLOR_LABEL,
|
||||
.label_text = 0,
|
||||
.font_size = 0,
|
||||
.label_graphic_w = minus_width,
|
||||
.label_graphic_h = minus_height,
|
||||
.label_graphic = minus_bitmap,
|
||||
.letter = 0,
|
||||
.left = "\x17 ",
|
||||
.highlight = false,
|
||||
.right = "\x1a",
|
||||
.sub = 0 },
|
||||
|
||||
{.x = 0,
|
||||
.y = 8 * KB_LINE_HEIGHT,
|
||||
.w = 46,
|
||||
.h = 26,
|
||||
.label_color = UI4X_COLOR_SHIFT_RIGHT,
|
||||
.label_text = 0,
|
||||
.font_size = 0,
|
||||
.label_graphic_w = shr_width,
|
||||
.label_graphic_h = shr_height,
|
||||
.label_graphic = shr_bitmap,
|
||||
.letter = 0,
|
||||
.left = 0,
|
||||
.highlight = false,
|
||||
.right = 0,
|
||||
.sub = 0 },
|
||||
{.x = KB_COLUMN_WIDTH_5_KEYS,
|
||||
.y = 8 * KB_LINE_HEIGHT,
|
||||
.w = 46,
|
||||
.h = 26,
|
||||
.label_color = UI4X_COLOR_LABEL,
|
||||
.label_text = "1",
|
||||
.font_size = 1,
|
||||
.label_graphic_w = 0,
|
||||
.label_graphic_h = 0,
|
||||
.label_graphic = 0,
|
||||
.letter = 0,
|
||||
.left = "ARITH",
|
||||
.highlight = false,
|
||||
.right = "CMPLX",
|
||||
.sub = 0 },
|
||||
{.x = 2 * KB_COLUMN_WIDTH_5_KEYS,
|
||||
.y = 8 * KB_LINE_HEIGHT,
|
||||
.w = 46,
|
||||
.h = 26,
|
||||
.label_color = UI4X_COLOR_LABEL,
|
||||
.label_text = "2",
|
||||
.font_size = 1,
|
||||
.label_graphic_w = 0,
|
||||
.label_graphic_h = 0,
|
||||
.label_graphic = 0,
|
||||
.letter = 0,
|
||||
.left = "DEF",
|
||||
.highlight = false,
|
||||
.right = "LIB",
|
||||
.sub = 0 },
|
||||
{.x = 3 * KB_COLUMN_WIDTH_5_KEYS,
|
||||
.y = 8 * KB_LINE_HEIGHT,
|
||||
.w = 46,
|
||||
.h = 26,
|
||||
.label_color = UI4X_COLOR_LABEL,
|
||||
.label_text = "3",
|
||||
.font_size = 1,
|
||||
.label_graphic_w = 0,
|
||||
.label_graphic_h = 0,
|
||||
.label_graphic = 0,
|
||||
.letter = 0,
|
||||
.left = "\x23",
|
||||
.highlight = false,
|
||||
.right = "BASE",
|
||||
.sub = 0 },
|
||||
{.x = 4 * KB_COLUMN_WIDTH_5_KEYS,
|
||||
.y = 8 * KB_LINE_HEIGHT,
|
||||
.w = 46,
|
||||
.h = 26,
|
||||
.label_color = UI4X_COLOR_LABEL,
|
||||
.label_text = 0,
|
||||
.font_size = 0,
|
||||
.label_graphic_w = plus_width,
|
||||
.label_graphic_h = plus_height,
|
||||
.label_graphic = plus_bitmap,
|
||||
.letter = 0,
|
||||
.left = "\x1d ",
|
||||
.highlight = false,
|
||||
.right = "\x1b",
|
||||
.sub = 0 },
|
||||
|
||||
{.x = 0,
|
||||
.y = 9 * KB_LINE_HEIGHT,
|
||||
.w = 46,
|
||||
.h = 26,
|
||||
.label_color = UI4X_COLOR_LABEL,
|
||||
.label_text = "ON",
|
||||
.font_size = 0,
|
||||
.label_graphic_w = 0,
|
||||
.label_graphic_h = 0,
|
||||
.label_graphic = 0,
|
||||
.letter = 0,
|
||||
.left = "CONT",
|
||||
.highlight = false,
|
||||
.right = "OFF",
|
||||
.sub = "CANCEL" },
|
||||
{.x = KB_COLUMN_WIDTH_5_KEYS,
|
||||
.y = 9 * KB_LINE_HEIGHT,
|
||||
.w = 46,
|
||||
.h = 26,
|
||||
.label_color = UI4X_COLOR_LABEL,
|
||||
.label_text = "0",
|
||||
.font_size = 1,
|
||||
.label_graphic_w = 0,
|
||||
.label_graphic_h = 0,
|
||||
.label_graphic = 0,
|
||||
.letter = 0,
|
||||
.left = "\x7e",
|
||||
.highlight = false,
|
||||
.right = "\x03",
|
||||
.sub = 0 },
|
||||
{.x = 2 * KB_COLUMN_WIDTH_5_KEYS,
|
||||
.y = 9 * KB_LINE_HEIGHT,
|
||||
.w = 46,
|
||||
.h = 26,
|
||||
.label_color = UI4X_COLOR_LABEL,
|
||||
.label_text = ".",
|
||||
.font_size = 1,
|
||||
.label_graphic_w = 0,
|
||||
.label_graphic_h = 0,
|
||||
.label_graphic = 0,
|
||||
.letter = 0,
|
||||
.left = "\x1e",
|
||||
.highlight = false,
|
||||
.right = "\x01",
|
||||
.sub = 0 },
|
||||
{.x = 3 * KB_COLUMN_WIDTH_5_KEYS,
|
||||
.y = 9 * KB_LINE_HEIGHT,
|
||||
.w = 46,
|
||||
.h = 26,
|
||||
.label_color = UI4X_COLOR_LABEL,
|
||||
.label_text = "SPC",
|
||||
.font_size = 0,
|
||||
.label_graphic_w = 0,
|
||||
.label_graphic_h = 0,
|
||||
.label_graphic = 0,
|
||||
.letter = 0,
|
||||
.left = "\x05 ",
|
||||
.highlight = false,
|
||||
.right = "\x02",
|
||||
.sub = 0 },
|
||||
{.x = 4 * KB_COLUMN_WIDTH_5_KEYS,
|
||||
.y = 9 * KB_LINE_HEIGHT,
|
||||
.w = 46,
|
||||
.h = 26,
|
||||
.label_color = UI4X_COLOR_LABEL,
|
||||
.label_text = "ENTER",
|
||||
.font_size = 0,
|
||||
.label_graphic_w = 0,
|
||||
.label_graphic_h = 0,
|
||||
.label_graphic = 0,
|
||||
.letter = 0,
|
||||
.left = "ANS ",
|
||||
.highlight = false,
|
||||
.right = "\x06NUM",
|
||||
.sub = 0 },
|
||||
};
|
|
@ -1,33 +0,0 @@
|
|||
#include <stdlib.h>
|
||||
|
||||
#include "common.h"
|
||||
#include "inner.h"
|
||||
#include "sdl2.h"
|
||||
#include "ncurses.h"
|
||||
|
||||
void ( *ui_get_event )( void );
|
||||
void ( *ui_update_display )( void );
|
||||
void ( *ui_start )( config_t* config );
|
||||
void ( *ui_stop )( void );
|
||||
|
||||
void setup_ui( config_t* config )
|
||||
{
|
||||
switch ( config->frontend ) {
|
||||
case FRONTEND_NCURSES:
|
||||
setup_frontend_ncurses();
|
||||
break;
|
||||
case FRONTEND_SDL:
|
||||
default:
|
||||
setup_frontend_sdl();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void close_and_exit( void )
|
||||
{
|
||||
exit_emulator();
|
||||
|
||||
ui_stop();
|
||||
|
||||
exit( 0 );
|
||||
}
|
|
@ -1,567 +0,0 @@
|
|||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <pwd.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#include <libgen.h>
|
||||
|
||||
#include <getopt.h>
|
||||
|
||||
#include <lua.h>
|
||||
#include <lauxlib.h>
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "../debug.h"
|
||||
|
||||
#ifndef LUA_OK
|
||||
# define LUA_OK 0
|
||||
#endif
|
||||
|
||||
static config_t config = {
|
||||
.progname = ( char* )"saturn4xxx",
|
||||
|
||||
.model = MODEL_48GX,
|
||||
.throttle = false,
|
||||
.verbose = false,
|
||||
.shiftless = false,
|
||||
.big_screen = false,
|
||||
.black_lcd = false,
|
||||
|
||||
.frontend = FRONTEND_SDL,
|
||||
|
||||
.mono = false,
|
||||
.gray = false,
|
||||
|
||||
.chromeless = false,
|
||||
.fullscreen = false,
|
||||
.scale = 1.0,
|
||||
|
||||
.tiny = false,
|
||||
.small = false,
|
||||
|
||||
/* from args.h */
|
||||
.reset = false,
|
||||
.monitor = false,
|
||||
.batchXfer = false,
|
||||
.state_dir_path = ( char* )".",
|
||||
|
||||
.debug_level = DEBUG_C_NONE,
|
||||
.enable_BUSCC = false,
|
||||
};
|
||||
|
||||
lua_State* config_lua_values;
|
||||
|
||||
static inline bool config_read( const char* filename )
|
||||
{
|
||||
int rc;
|
||||
|
||||
assert( filename != NULL );
|
||||
|
||||
/*---------------------------------------------------
|
||||
; Create the Lua state, which includes NO predefined
|
||||
; functions or values. This is literally an empty
|
||||
; slate.
|
||||
;----------------------------------------------------*/
|
||||
config_lua_values = luaL_newstate();
|
||||
if ( config_lua_values == NULL ) {
|
||||
fprintf( stderr, "cannot create Lua state\n" );
|
||||
return false;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------
|
||||
; For the truly paranoid about sandboxing, enable the
|
||||
; following code, which removes the string library,
|
||||
; which some people find problematic to leave un-sand-
|
||||
; boxed. But in my opinion, if you are worried about
|
||||
; such attacks in a configuration file, you have bigger
|
||||
; security issues to worry about than this.
|
||||
;------------------------------------------------------*/
|
||||
#ifdef PARANOID
|
||||
lua_pushliteral( config_lua_values, "x" );
|
||||
lua_pushnil( config_lua_values );
|
||||
lua_setmetatable( config_lua_values, -2 );
|
||||
lua_pop( config_lua_values, 1 );
|
||||
#endif
|
||||
|
||||
/*-----------------------------------------------------
|
||||
; Lua 5.2+ can restrict scripts to being text only,
|
||||
; to avoid a potential problem with loading pre-compiled
|
||||
; Lua scripts that may have malformed Lua VM code that
|
||||
; could possibly lead to an exploit, but again, if you
|
||||
; have to worry about that, you have bigger security
|
||||
; issues to worry about. But in any case, here I'm
|
||||
; restricting the file to "text" only.
|
||||
;------------------------------------------------------*/
|
||||
rc = luaL_loadfile( config_lua_values, filename );
|
||||
if ( rc != LUA_OK ) {
|
||||
fprintf( stderr, "Lua error: (%d) %s\n", rc, lua_tostring( config_lua_values, -1 ) );
|
||||
return false;
|
||||
}
|
||||
|
||||
rc = lua_pcall( config_lua_values, 0, 0, 0 );
|
||||
if ( rc != LUA_OK ) {
|
||||
fprintf( stderr, "Lua error: (%d) %s\n", rc, lua_tostring( config_lua_values, -1 ) );
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void print_config( void )
|
||||
{
|
||||
fprintf( stdout, "--------------------------------------------------------------------------------\n" );
|
||||
fprintf( stdout, "-- Configuration file for saturnng\n" );
|
||||
fprintf( stdout, "-- This is a comment\n" );
|
||||
|
||||
fprintf( stdout, "model = \"" );
|
||||
switch ( config.model ) {
|
||||
case MODEL_48GX:
|
||||
fprintf( stdout, "48gx" );
|
||||
break;
|
||||
case MODEL_48SX:
|
||||
fprintf( stdout, "48sx" );
|
||||
break;
|
||||
case MODEL_40G:
|
||||
fprintf( stdout, "40g" );
|
||||
break;
|
||||
case MODEL_49G:
|
||||
fprintf( stdout, "49g" );
|
||||
break;
|
||||
}
|
||||
fprintf( stdout, "\" -- possible values: \"48gx\", \"48sx\", \"40g\", \"49g\"\n" );
|
||||
fprintf( stdout, "\n" );
|
||||
|
||||
fprintf( stdout, "verbose = %s\n", config.verbose ? "true" : "false" );
|
||||
fprintf( stdout, "throttle = %s\n", config.throttle ? "true" : "false" );
|
||||
fprintf( stdout, "\n" );
|
||||
fprintf( stdout, "monitor = %s\n", config.monitor ? "true" : "false" );
|
||||
fprintf( stdout, "\n" );
|
||||
|
||||
fprintf( stdout, "--------------------\n" );
|
||||
fprintf( stdout, "-- User Interface --\n" );
|
||||
fprintf( stdout, "--------------------\n" );
|
||||
fprintf( stdout, "frontend = \"" );
|
||||
switch ( config.frontend ) {
|
||||
case FRONTEND_SDL:
|
||||
fprintf( stdout, "sdl" );
|
||||
break;
|
||||
case FRONTEND_NCURSES:
|
||||
fprintf( stdout, "tui" );
|
||||
if ( config.small )
|
||||
fprintf( stdout, "-small" );
|
||||
else if ( config.tiny )
|
||||
fprintf( stdout, "-tiny" );
|
||||
break;
|
||||
}
|
||||
fprintf( stdout, "\" -- possible values: \"sdl\", \"tui\", \"tui-small\", \"tui-tiny\"\n" );
|
||||
fprintf( stdout, "\n" );
|
||||
|
||||
fprintf( stdout, "gray = %s\n", config.gray ? "true" : "false" );
|
||||
fprintf( stdout, "mono = %s\n", config.mono ? "true" : "false" );
|
||||
|
||||
fprintf( stdout, "\n" );
|
||||
fprintf( stdout, " -- Following options are specific to sdl frontend\n" );
|
||||
fprintf( stdout, "big_screen = %s\n", config.big_screen ? "true" : "false" );
|
||||
fprintf( stdout, "black_lcd = %s\n", config.black_lcd ? "true" : "false" );
|
||||
fprintf( stdout, "chromeless = %s\n", config.chromeless ? "true" : "false" );
|
||||
fprintf( stdout, "fullscreen = %s\n", config.fullscreen ? "true" : "false" );
|
||||
fprintf( stdout, "scale = %f\n", config.scale );
|
||||
fprintf( stdout, "shiftless = %s\n", config.shiftless ? "true" : "false" );
|
||||
|
||||
fprintf( stdout, "\n" );
|
||||
fprintf( stdout, "--- End of saturnng configuration ----------------------------------------------\n" );
|
||||
}
|
||||
|
||||
/* Path/name dynamic allocator */
|
||||
static char* normalize_filename( char* path, char* name )
|
||||
{
|
||||
char* s = malloc( strlen( path ) + strlen( name ) + 2 );
|
||||
|
||||
strcpy( s, path );
|
||||
strcat( s, "/" );
|
||||
strcat( s, name );
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
config_t* config_init( int argc, char* argv[] )
|
||||
{
|
||||
int option_index;
|
||||
int c = '?';
|
||||
|
||||
char* config_file_name = ( char* )"config.lua";
|
||||
char* mod_file_name = ( char* )"mod";
|
||||
char* cpu_file_name = ( char* )"cpu";
|
||||
char* hdw_file_name = ( char* )"hdw";
|
||||
char* rom_file_name = ( char* )"rom";
|
||||
char* ram_file_name = ( char* )"ram";
|
||||
char* port_1_file_name = ( char* )"port1";
|
||||
char* port_2_file_name = ( char* )"port2";
|
||||
|
||||
int print_config_and_exit = false;
|
||||
|
||||
int clopt_model = -1;
|
||||
int clopt_verbose = -1;
|
||||
int clopt_big_screen = -1;
|
||||
int clopt_black_lcd = -1;
|
||||
int clopt_throttle = -1;
|
||||
int clopt_shiftless = -1;
|
||||
int clopt_frontend = -1;
|
||||
int clopt_mono = -1;
|
||||
int clopt_gray = -1;
|
||||
int clopt_chromeless = -1;
|
||||
int clopt_fullscreen = -1;
|
||||
double clopt_scale = -1.0;
|
||||
|
||||
int clopt_tiny = -1;
|
||||
int clopt_small = -1;
|
||||
|
||||
int clopt_reset = -1;
|
||||
int clopt_monitor = -1;
|
||||
/* int clopt_batchXfer = -1; */
|
||||
int clopt_enable_BUSCC = -1;
|
||||
|
||||
char* clopt_state_dir_path = ( char* )".";
|
||||
|
||||
const char* optstring = "h";
|
||||
struct option long_options[] = {
|
||||
{"help", no_argument, NULL, 'h' },
|
||||
{"verbose", no_argument, &clopt_verbose, true },
|
||||
{"print-config", no_argument, &print_config_and_exit, true },
|
||||
|
||||
{"throttle", no_argument, &clopt_throttle, true },
|
||||
{"big-screen", no_argument, &clopt_big_screen, true },
|
||||
{"black-lcd", no_argument, &clopt_black_lcd, true },
|
||||
|
||||
{"48sx", no_argument, &clopt_model, MODEL_48SX },
|
||||
{"48gx", no_argument, &clopt_model, MODEL_48GX },
|
||||
{"40g", no_argument, &clopt_model, MODEL_40G },
|
||||
{"49g", no_argument, &clopt_model, MODEL_49G },
|
||||
|
||||
{"reset", no_argument, &clopt_reset, true },
|
||||
{"monitor", no_argument, &clopt_monitor, true },
|
||||
/* {"batchXfer", no_argument, &clopt_batchXfer, true }, */
|
||||
{"state-dir", required_argument, NULL, 8999 },
|
||||
|
||||
{"shiftless", no_argument, &clopt_shiftless, true },
|
||||
|
||||
{"gui", no_argument, &clopt_frontend, FRONTEND_SDL },
|
||||
{"chromeless", no_argument, &clopt_chromeless, true },
|
||||
{"fullscreen", no_argument, &clopt_fullscreen, true },
|
||||
{"scale", required_argument, NULL, 7110 },
|
||||
|
||||
{"tui", no_argument, &clopt_frontend, FRONTEND_NCURSES},
|
||||
{"tui-small", no_argument, NULL, 6110 },
|
||||
{"tui-tiny", no_argument, NULL, 6120 },
|
||||
|
||||
{"mono", no_argument, &clopt_mono, true },
|
||||
{"gray", no_argument, &clopt_gray, true },
|
||||
|
||||
{"debug-opcodes", no_argument, NULL, 38601 },
|
||||
/* {"debug-xx", no_argument, NULL, 38602 }, */
|
||||
{"debug-x-func", no_argument, NULL, 38603 },
|
||||
{"debug-flash", no_argument, NULL, 38604 },
|
||||
{"debug-implementation", no_argument, NULL, 38605 },
|
||||
{"debug-mod-cache", no_argument, NULL, 38606 },
|
||||
{"debug-serial", no_argument, NULL, 38607 },
|
||||
{"debug-timers", no_argument, NULL, 38608 },
|
||||
{"debug-interruptions", no_argument, NULL, 38609 },
|
||||
{"debug-display", no_argument, NULL, 38610 },
|
||||
{"debug-modules", no_argument, NULL, 38611 },
|
||||
{"debug-trace", no_argument, NULL, 38612 },
|
||||
|
||||
{"implement-BUSCC", no_argument, &clopt_enable_BUSCC, true },
|
||||
|
||||
{0, 0, 0, 0 }
|
||||
};
|
||||
|
||||
const char* help_text = "usage: %s [options]\n"
|
||||
"options:\n"
|
||||
" -h --help what you are reading\n"
|
||||
" --print-config output current configuration to stdout and exit (in config.lua formatting)\n"
|
||||
" --verbose display more informations\n"
|
||||
" --throttle throttle CPU speed\n"
|
||||
" --big-screen 131×80 screen (default: false)\n"
|
||||
" --black-lcd (default: false)\n"
|
||||
" --48gx emulate a HP 48GX\n"
|
||||
" --48sx emulate a HP 48SX\n"
|
||||
" --40g emulate a HP 40G\n"
|
||||
" --49g emulate a HP 49G\n"
|
||||
" --state-dir=<path> use a different data directory "
|
||||
"(default: ~/.config/saturnMODEL/)\n"
|
||||
" --gui graphical (SDL2) front-end (default: true)\n"
|
||||
" --tui text front-end (default: false)\n"
|
||||
" --tui-small text small front-end (2×2 pixels per character) (default: "
|
||||
"false)\n"
|
||||
" --tui-tiny text tiny front-end (2×4 pixels per character) (default: "
|
||||
"false)\n"
|
||||
" --chromeless only show display (default: "
|
||||
"false)\n"
|
||||
" --fullscreen make the UI fullscreen "
|
||||
"(default: false)\n"
|
||||
" --scale=<n> make the UI scale <n> times "
|
||||
"(default: 1.0)\n"
|
||||
" --mono make the UI monochrome (default: "
|
||||
"false)\n"
|
||||
" --gray make the UI grayscale (default: "
|
||||
"false)\n"
|
||||
" --shiftless don't map the shift keys to let them free for numbers (default: "
|
||||
"false)\n"
|
||||
" --reset force a reset\n"
|
||||
" --monitor start with monitor (default: no)\n"
|
||||
"\n"
|
||||
" --debug-opcodes enables debugging opcodes (default: no)\n"
|
||||
/* " --debug- enables debugging something (default: no)\n" */
|
||||
" --debug-x-func enables debugging extended functions (default: no)\n"
|
||||
" --debug-flash enables debugging flash (default: no)\n"
|
||||
" --debug-implementation enables debugging implementation (default: no) (UNUSED)\n"
|
||||
" --debug-mod-cache enables debugging mod cache (default: no)\n"
|
||||
" --debug-serial enables debugging serial (default: no)\n"
|
||||
" --debug-timers enables debugging timers (default: no)\n"
|
||||
" --debug-interruptions enables debugging interruptions (default: no)\n"
|
||||
" --debug-display enables debugging display (default: no) (UNUSED)\n"
|
||||
" --debug-modules enables debugging modules (default: no)\n"
|
||||
" --debug-trace enables debugging trace (default: no)\n";
|
||||
|
||||
while ( c != EOF ) {
|
||||
c = getopt_long( argc, argv, optstring, long_options, &option_index );
|
||||
|
||||
switch ( c ) {
|
||||
case 'h':
|
||||
fprintf( stdout, help_text, config.progname );
|
||||
exit( EXIT_SUCCESS );
|
||||
break;
|
||||
case 6110:
|
||||
clopt_frontend = FRONTEND_NCURSES;
|
||||
clopt_small = true;
|
||||
break;
|
||||
case 6120:
|
||||
clopt_frontend = FRONTEND_NCURSES;
|
||||
clopt_tiny = true;
|
||||
break;
|
||||
case 7110:
|
||||
clopt_scale = atof( optarg );
|
||||
break;
|
||||
case 8999:
|
||||
clopt_state_dir_path = optarg;
|
||||
break;
|
||||
|
||||
case 38601:
|
||||
config.debug_level |= DEBUG_C_OPCODES;
|
||||
break;
|
||||
/* case 38602: */
|
||||
/* config.debug_level |= DEBUG_C_XX; */
|
||||
/* break; */
|
||||
case 38603:
|
||||
config.debug_level |= DEBUG_C_X_FUNC;
|
||||
break;
|
||||
case 38604:
|
||||
config.debug_level |= DEBUG_C_FLASH;
|
||||
break;
|
||||
case 38605:
|
||||
config.debug_level |= DEBUG_C_IMPLEMENTATION;
|
||||
break;
|
||||
case 38606:
|
||||
config.debug_level |= DEBUG_C_MOD_CACHE;
|
||||
break;
|
||||
case 38607:
|
||||
config.debug_level |= DEBUG_C_SERIAL;
|
||||
break;
|
||||
case 38608:
|
||||
config.debug_level |= DEBUG_C_TIMERS;
|
||||
break;
|
||||
case 38609:
|
||||
config.debug_level |= DEBUG_C_INT;
|
||||
break;
|
||||
case 38610:
|
||||
config.debug_level |= DEBUG_C_DISPLAY;
|
||||
break;
|
||||
case 38611:
|
||||
config.debug_level |= DEBUG_C_MODULES;
|
||||
break;
|
||||
case 38612:
|
||||
config.debug_level |= DEBUG_C_TRACE;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( clopt_state_dir_path != NULL )
|
||||
config.state_dir_path = strdup( clopt_state_dir_path );
|
||||
|
||||
config.config_file_name = normalize_filename( config.state_dir_path, config_file_name );
|
||||
config.mod_file_name = normalize_filename( config.state_dir_path, mod_file_name );
|
||||
config.cpu_file_name = normalize_filename( config.state_dir_path, cpu_file_name );
|
||||
config.hdw_file_name = normalize_filename( config.state_dir_path, hdw_file_name );
|
||||
config.rom_file_name = normalize_filename( config.state_dir_path, rom_file_name );
|
||||
config.ram_file_name = normalize_filename( config.state_dir_path, ram_file_name );
|
||||
config.port_1_file_name = normalize_filename( config.state_dir_path, port_1_file_name );
|
||||
config.port_2_file_name = normalize_filename( config.state_dir_path, port_2_file_name );
|
||||
|
||||
/**********************/
|
||||
/* 1. read config.lua */
|
||||
/**********************/
|
||||
bool haz_config_file = config_read( config.config_file_name );
|
||||
if ( haz_config_file ) {
|
||||
lua_getglobal( config_lua_values, "verbose" );
|
||||
config.verbose = lua_toboolean( config_lua_values, -1 );
|
||||
|
||||
lua_getglobal( config_lua_values, "throttle" );
|
||||
config.throttle = lua_toboolean( config_lua_values, -1 );
|
||||
|
||||
lua_getglobal( config_lua_values, "big_screen" );
|
||||
config.big_screen = lua_toboolean( config_lua_values, -1 );
|
||||
|
||||
lua_getglobal( config_lua_values, "black_lcd" );
|
||||
config.black_lcd = lua_toboolean( config_lua_values, -1 );
|
||||
|
||||
lua_getglobal( config_lua_values, "chromeless" );
|
||||
config.chromeless = lua_toboolean( config_lua_values, -1 );
|
||||
|
||||
lua_getglobal( config_lua_values, "fullscreen" );
|
||||
config.fullscreen = lua_toboolean( config_lua_values, -1 );
|
||||
|
||||
lua_getglobal( config_lua_values, "gray" );
|
||||
config.gray = lua_toboolean( config_lua_values, -1 );
|
||||
|
||||
lua_getglobal( config_lua_values, "mono" );
|
||||
config.mono = lua_toboolean( config_lua_values, -1 );
|
||||
|
||||
lua_getglobal( config_lua_values, "shiftless" );
|
||||
config.shiftless = lua_toboolean( config_lua_values, -1 );
|
||||
|
||||
lua_getglobal( config_lua_values, "monitor" );
|
||||
config.monitor = lua_toboolean( config_lua_values, -1 );
|
||||
|
||||
lua_getglobal( config_lua_values, "model" );
|
||||
const char* svalue_model = luaL_optstring( config_lua_values, -1, "49g" );
|
||||
if ( svalue_model != NULL ) {
|
||||
if ( strcmp( svalue_model, "49g" ) == 0 )
|
||||
config.model = MODEL_49G;
|
||||
if ( strcmp( svalue_model, "40g" ) == 0 )
|
||||
config.model = MODEL_40G;
|
||||
if ( strcmp( svalue_model, "48gx" ) == 0 )
|
||||
config.model = MODEL_48GX;
|
||||
if ( strcmp( svalue_model, "48sx" ) == 0 )
|
||||
config.model = MODEL_48SX;
|
||||
}
|
||||
|
||||
lua_getglobal( config_lua_values, "frontend" );
|
||||
const char* svalue = luaL_optstring( config_lua_values, -1, "sdl" );
|
||||
if ( svalue != NULL ) {
|
||||
if ( strcmp( svalue, "sdl" ) == 0 )
|
||||
config.frontend = FRONTEND_SDL;
|
||||
if ( strcmp( svalue, "tui" ) == 0 ) {
|
||||
config.frontend = FRONTEND_NCURSES;
|
||||
config.small = false;
|
||||
config.tiny = false;
|
||||
}
|
||||
if ( strcmp( svalue, "tui-small" ) == 0 ) {
|
||||
config.frontend = FRONTEND_NCURSES;
|
||||
config.small = true;
|
||||
config.tiny = false;
|
||||
}
|
||||
if ( strcmp( svalue, "tui-tiny" ) == 0 ) {
|
||||
config.frontend = FRONTEND_NCURSES;
|
||||
config.small = false;
|
||||
config.tiny = true;
|
||||
}
|
||||
}
|
||||
|
||||
lua_getglobal( config_lua_values, "scale" );
|
||||
config.scale = luaL_optnumber( config_lua_values, -1, 1.0 );
|
||||
}
|
||||
|
||||
/****************************************************/
|
||||
/* 2. treat command-line params which have priority */
|
||||
/****************************************************/
|
||||
if ( clopt_verbose != -1 )
|
||||
config.verbose = clopt_verbose == true;
|
||||
if ( clopt_model != -1 )
|
||||
config.model = clopt_model;
|
||||
if ( clopt_throttle != -1 )
|
||||
config.throttle = clopt_throttle == true;
|
||||
if ( clopt_big_screen != -1 )
|
||||
config.big_screen = clopt_big_screen == true;
|
||||
if ( clopt_black_lcd != -1 )
|
||||
config.black_lcd = clopt_black_lcd == true;
|
||||
if ( clopt_frontend != -1 )
|
||||
config.frontend = clopt_frontend;
|
||||
if ( clopt_chromeless != -1 )
|
||||
config.chromeless = clopt_chromeless == true;
|
||||
if ( clopt_fullscreen != -1 )
|
||||
config.fullscreen = clopt_fullscreen == true;
|
||||
if ( clopt_scale > 0.0 )
|
||||
config.scale = clopt_scale;
|
||||
if ( clopt_mono != -1 )
|
||||
config.mono = clopt_mono == true;
|
||||
if ( clopt_small != -1 )
|
||||
config.small = clopt_small == true;
|
||||
if ( clopt_tiny != -1 )
|
||||
config.tiny = clopt_tiny == true;
|
||||
if ( clopt_gray != -1 )
|
||||
config.gray = clopt_gray == true;
|
||||
if ( clopt_shiftless != -1 )
|
||||
config.shiftless = clopt_shiftless == true;
|
||||
|
||||
if ( clopt_reset != -1 )
|
||||
config.reset = clopt_reset;
|
||||
if ( clopt_monitor != -1 )
|
||||
config.monitor = clopt_monitor;
|
||||
/* if ( clopt_batchXfer != -1 ) */
|
||||
/* config.batchXfer = clopt_batchXfer; */
|
||||
if ( clopt_enable_BUSCC != -1 )
|
||||
config.enable_BUSCC = clopt_enable_BUSCC;
|
||||
|
||||
if ( config.model == MODEL_49G )
|
||||
config.black_lcd = true;
|
||||
|
||||
config.progname = basename( strdup( argv[ 0 ] ) );
|
||||
switch ( config.model ) {
|
||||
case MODEL_48GX:
|
||||
strcat( config.progname, "48gx" );
|
||||
break;
|
||||
case MODEL_48SX:
|
||||
strcat( config.progname, "48sx" );
|
||||
break;
|
||||
case MODEL_49G:
|
||||
strcat( config.progname, "49g" );
|
||||
break;
|
||||
case MODEL_40G:
|
||||
strcat( config.progname, "40g" );
|
||||
break;
|
||||
}
|
||||
|
||||
if ( config.verbose ) {
|
||||
if ( !print_config_and_exit )
|
||||
print_config();
|
||||
|
||||
if ( optind < argc ) {
|
||||
fprintf( stderr, "%i invalid arguments : ", argc - optind );
|
||||
while ( optind < argc )
|
||||
fprintf( stderr, "%s\n", argv[ optind++ ] );
|
||||
fprintf( stderr, "\n" );
|
||||
}
|
||||
}
|
||||
|
||||
if ( print_config_and_exit ) {
|
||||
print_config();
|
||||
exit( EXIT_SUCCESS );
|
||||
}
|
||||
|
||||
if ( !haz_config_file ) {
|
||||
fprintf( stdout, "\nConfiguration file %s doesn't seem to exist or is invalid!\n", config.config_file_name );
|
||||
|
||||
fprintf( stdout, "You can solve this by running `mkdir -p %s && %s --print-config >> %s`\n\n", config.state_dir_path,
|
||||
config.progname, config.config_file_name );
|
||||
}
|
||||
|
||||
return &config;
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue