On behalf of: 3298 - Applied 23 patches by 3298:

Misc changes, mostly fixes:
- fix ./newconfig systems other than OSX (broke in c8b823f)
- fix palette usage in 2-bit color mode (was broken ever since grayscale was implemented in 18e1003 and its improperly attributed copy f7913eb)
- fix continuing from breakpoints in the debugger (never worked, was exposed when the debugger was enabled in 9c1f2ed)
- restore the printf statements commented out in 9c1f2ed and hide them with #ifdefs instead
- close the server socket after accepting a debugger connection to allow another simultaneous debug session to be started using the same TCP port
- use the symbolic constant DEFAULT_GDBSTUB_PORT (already defined in gdb_stub.h as 1234) when starting the gdb server in main.c in place of the raw number 1234
- change Makefile to read the name of the firmware file from the file update.scp instead of hardcoding it; this allows users to switch to another firmware
by simply pasting it along with its accompanying update.scp into the x49gp directory

- Enhance port G (keyboard) handling to remember the value of output bits across periods with these bits configured as input
This fixes interaction with HPGCC3 keyboard routines, and it also fixes keys with eint==7 (assuming the stock firmware is in use)
needing a double-tap to work unless pressed very shortly after another keypress (the latter broke in b5f93ed)
- Get rid of the deprecated function warning by switching from gdk_pixbuf_new_from_inline to gdk_pixbuf_new_from_data (based on code by chwdt)
- Delete remaining now-redundant CVS files
- Don't release all buttons anymore if there are still physical keys and/or the left mouse button are holding some down
On the other hand, forcibly release all buttons when losing focus to avoid getting stuck in a state with buttons down
when they are not held down by anything; this would happen due to missed events while not in focus
- Add a context menu to the screen, containing only "Reset" and "Quit" items for now
- Ensure that the files backing flash, sram, and s3c2410-sram exist and have the correct size when opening them
Note that if the flash file does not exist, this will not fill it with the code that's supposed to be in there, obviously causing the calculator to crash. That's an improvement for later.
- Allow the config system to fill not only numbers, but also strings (including filenames) with default values
basename is excluded, but it's planned to be dropped entirely.
- Add an "install" target to the Makefile
- Implement a more generic command-line parser for substantially improved flexibility
- Also adds a proper help option, though the manual referenced in the corresponding output (a manpage, hopefully) does not exist yet.
- Drop the "basename" config property in favor of interpreting relative paths in the config as relative to the config file's location
- Retire the "image" config property in favor of simply loading the image from next to the binary or from the install directory
- Split the UI name property into name (affecting only the window title) and type (affecting the UI image and in the future also the default bootcode) properties
- Change the default calculator type to the 50g everywhere, which probably matches today's user expectations better than the 49g+.
- Create a flash file from the calculator model's appropriate boot file if it does not exist, relying on the bootcode to detect the absence of a firmware
  The bootcode will complain about the missing firmware and enter update mode, so the user needs to supply their favorite firmware version and point the bootcode's updater to it.
  The easiest way is probably pointing the emulated SD card at a directory containing the firmware and its accompanying update.scp file, and then starting the SD-based update.
- Add SD mount / unmount options to the right-click / menu-key popup menu
- Remove most of the old script-based config-generating system since the binary now has these capabilities as well
- Add an applications menu item for installing
- Keep some debug output on stderr and a huge vvfat.log file from showing up when not debugging x49gp itself
- Allow (re-)connecting a debugger to a running session
  This is done through the right-click / menu-key popup menu.
  To avoid confusion due to the accidental clicks leading to an unresponsive interface (caused by waiting for the debugger to connect),
  this option is hidden unless option -d or its new companion -D (same as -d, but does not start the debug interface right away) is present.
- Improved support for hardware keyboards
- Update README.md, add manpage, rename other README files to TODO to reflect their contents
This commit is contained in:
claudiol 2018-05-07 17:32:14 -04:00
parent 91d85c5aec
commit c61f11cff2
55 changed files with 1302 additions and 773 deletions

8
.gitignore vendored
View file

@ -1,18 +1,10 @@
sim/CVS*
*.svn/*
*.DS_Store/*
.DS_Store
.depend
*.o
*.d
config
flash-49g+
flash-50g
flash-noboot
sdcard
sram
x49gp
s3c2410-sram
qemu/qemu-git/arm-softmmu
qemu/qemu-git/libhw32
qemu/qemu-git/libhw64

100
Makefile
View file

@ -29,24 +29,16 @@ X49GP_DEBUG = \
-DDEBUG_X49GP_TIMER_IDLE \
-DDEBUG_X49GP_ARM_IDLE \
-DDEBUG_X49GP_ENABLE_IRQ \
-DDEBUG_X49GP_BLOCK \
-DDEBUG_X49GP_MAIN \
-DDEBUG_X49GP_UI
DEBUG = -g # -pg
#2.09
#FIRMWARE = 4950_92.bin
#HPGCC3 (copy HPGCC3 ROM first)
#FIRMWARE = 49_hpgcc.bin
#2.15
#FIRMWARE = 4950_215.bin
#2.15full
FIRMWARE = 2MB_215f.bin
BOOT49GP = boot-49g+.bin
BOOT50G = boot-50g.bin
SERIAL49GP = DE00000001
SERIAL50G = DEA0000001
COPYRIGHT = Kinposhcopyright
IMAGE49GP = hp49g+.png
IMAGE50G = hp50g.png
QEMU_DEFINES = -DTARGET_ARM -DX49GP \
-D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE \
@ -90,6 +82,13 @@ X49GP_INCLUDES = -Iinclude -Ibitmaps $(QEMU_INC)
INCLUDES = $(GDB_INCLUDES) $(X49GP_INCLUDES)
INSTALL_PREFIX = /usr/local
INSTALL_BINARY_DIR = "$(INSTALL_PREFIX)"/bin
INSTALL_DATA_DIR = "$(INSTALL_PREFIX)"/share/$(TARGET)
INSTALL_MENU_DIR = "$(INSTALL_PREFIX)"/share/applications
INSTALL_MAN_DIR = "$(INSTALL_PREFIX)/share/man/man1"
DEFINES += -DX49GP_DATADIR=\"$(INSTALL_DATA_DIR)\"
ifdef QEMU_OLD
CC = $(shell if [ "`uname -s`" = "Darwin" ]; then echo "gcc"; else echo "gcc-3.4"; fi)
else
@ -103,7 +102,7 @@ CC += $(shell if [ "`uname -m`" = "sparc64" -o "`uname -m`" = "sun4u" ]; then ec
COCOA_LIBS=$(shell if [ "`uname -s`" = "Darwin" ]; then echo "-F/System/Library/Frameworks -framework Cocoa -framework IOKit"; fi)
CFLAGS = -O2 -Wall -Werror $(DEBUG) $(INCLUDES) $(DEFINES) -Wno-error=deprecated-declarations
CFLAGS = -O2 -Wall -Werror $(DEBUG) $(INCLUDES) $(DEFINES)
LDFLAGS = $(DEBUG) $(X49GP_LDFLAGS) $(GDB_LDFLAGS)
LDLIBS = $(X49GP_LIBS) $(GDB_LIBS) $(COCOA_LIBS)
@ -158,12 +157,13 @@ VVFATOBJS += $(QEMU_DIR)/cutils.o
endif
TARGET = x49gp
TARGET_ALLCAPS = X49GP
all: do-it-all
ifeq (.depend,$(wildcard .depend))
include .depend
do-it-all: $(QEMU) $(TARGET) flash-49g+ flash-50g sram s3c2410-sram
do-it-all: $(QEMU) $(TARGET)
else
do-it-all: depend-and-build
endif
@ -176,59 +176,20 @@ $(TARGET): $(OBJS) $(VVFATOBJS) $(QEMU_OBJS)
$(CC) $(LDFLAGS) -o $@ $(OBJS) $(VVFATOBJS) $(LDLIBS)
endif
flash-49g+: $(BOOT49GP) flash-noboot
@cp flash-noboot $@
@/bin/echo -n "$@: Copy boot loader \"$(BOOT49GP)\" to "; echo "0"
@dd if=$(BOOT49GP) of=$@ bs=16 seek=0 conv=notrunc 2>/dev/null
@/bin/echo -n "$@: Set serial number \"$(SERIAL49GP)\" at "; expr 16 \* 1023
@/bin/echo -n "$(SERIAL49GP)" >serialno
@dd if=serialno of=$@ bs=16 seek=1023 conv=notrunc 2>/dev/null
@rm -f serialno
install: all $(TARGET).desktop $(TARGET).man
install -D -m 755 $(TARGET) "$(INSTALL_BINARY_DIR)/$(TARGET)"
install -D -m 644 $(BOOT49GP) "$(INSTALL_DATA_DIR)/$(BOOT49GP)"
install -D -m 644 $(BOOT50G) "$(INSTALL_DATA_DIR)/$(BOOT50G)"
install -D -m 644 $(IMAGE49GP) "$(INSTALL_DATA_DIR)/$(IMAGE49GP)"
install -D -m 644 $(IMAGE50G) "$(INSTALL_DATA_DIR)/$(IMAGE50G)"
install -D -m 644 $(TARGET).desktop "$(INSTALL_MENU_DIR)/$(TARGET).desktop"
install -D -m 644 $(TARGET).man "$(INSTALL_MAN_DIR)/$(TARGET).1"
flash-50g: $(BOOT50G) flash-noboot
@cp flash-noboot $@
@/bin/echo -n "$@: Copy boot loader \"$(BOOT50G)\" to "; echo "0"
@dd if=$(BOOT50G) of=$@ bs=16 seek=0 conv=notrunc 2>/dev/null
@/bin/echo -n "$@: Set serial number \"$(SERIAL50G)\" at "; expr 16 \* 1023
@/bin/echo -n "$(SERIAL50G)" >serialno
@dd if=serialno of=$@ bs=16 seek=1023 conv=notrunc 2>/dev/null
@rm -f serialno
$(TARGET).desktop: x49gp.desktop.in
perl -p -e "s!TARGET!$(TARGET)!" <x49gp.desktop.in >$@
flash-noboot: $(FIRMWARE)
@/bin/echo -n "$@: Fill ff: 0 "
@/bin/echo -ne "\377" >one
@COUNT=0; \
SIZE=1; \
while [ $${COUNT} -le 20 ]; do \
cat one one >one2; \
mv one2 one; \
COUNT=`expr $${COUNT} + 1`; \
SIZE=`expr $${SIZE} + $${SIZE}`; \
/bin/echo -n "."; \
done; \
echo " $${SIZE}"
@mv one $@
@/bin/echo -n "$@: Mark blocks:"
@OFFSET=524544; \
for block in 02 03 04 05 06 07 10 11 12 13 14 15; do \
/bin/echo -ne "\360\0$${block}\000\000\000" >header; \
dd if=header of=$@ bs=1 seek=$${OFFSET} conv=notrunc 2>/dev/null; \
/bin/echo -n " $${OFFSET}"; \
OFFSET=`expr $${OFFSET} + 131072`; \
done; \
echo ""
@/bin/echo -n "$@: Copy firmware \"$(FIRMWARE)\" to "; expr 16 \* 1024
@dd if=$(FIRMWARE) of=$@ bs=16 seek=1024 conv=notrunc 2>/dev/null
@/bin/echo -n "$@: Set copyright \"$(COPYRIGHT)\" at "; expr 16 \* 1024
@/bin/echo -n "$(COPYRIGHT)" >copyright
@dd if=copyright of=$@ bs=16 seek=1024 conv=notrunc 2>/dev/null
@rm -f one one2 header copyright
sram:
dd if=/dev/zero of=$@ bs=1024 count=512
s3c2410-sram:
dd if=/dev/zero of=$@ bs=1024 count=4
$(TARGET).man: x49gp.man.in
perl -p -e "s!TARGET_ALLCAPS!$(TARGET_ALLCAPS)!;" -e "s!TARGET!$(TARGET)!" <x49gp.man.in >$@
sdcard:
ifeq ($(shell uname),Darwin)
@ -238,9 +199,6 @@ else
/sbin/mkdosfs -v -C -S 512 -f 2 -F 16 -r 512 -R 2 -n "x49gp" $@ 65536
endif
config:
./newconfig
sim: dummy
$(MAKE) -C $@
@ -285,8 +243,7 @@ clean: clean-libs
distclean: clean
rm -rf $(QEMU)
rm -f $(TARGET) flash-49g+ flash-50g flash-noboot sram s3c2410-sram
rm -f config
rm -f $(TARGET) $(TARGET).desktop $(TARGET).man $(TARGET).man
depend-and-build: depend
$(MAKE) -C . all
@ -311,8 +268,7 @@ clean: clean-qemu
distclean: clean
$(MAKE) -C $(QEMU) -f Makefile-small distclean
rm -f $(TARGET) flash-49g+ flash-50g flash-noboot sram s3c2410-sram
rm -f config
rm -f $(TARGET) $(TARGET).desktop $(TARGET).man $(TARGET).man
depend-libs: $(QEMU)/config-host.h

63
README
View file

@ -1,63 +0,0 @@
Next steps:
- Verify Locks needed
- Audit Keyboard <-> IO Port Interaction
- Add remote gdb interface
Registers to check access to:
IO PORT MISCCR
MMU FSR
MMU FAR
MMU Alignment Checks in general
MMU r7: Wait for Interrupt
File Manager:
Read from 0x08080000: Probe memory size???
-> Add mirrored mapping of SRAM?
Annunciators:
Bits set in Column 132 of the LCD screen memory:
Row 0: Transmit
Row 1: Left Shift
Row 2: Right Shift
Row 3: Alpha
Row 4: Battery
Row 5: Busy
IRQ Branch Table:
08000020: IRQ reads 08000020 + (IRQOFFSET << 2), branches there
IRQ returns with "subs pc, lr, #4"
The speed of the emulator is an issue...
It is running about 20 times SLOWER than the original calculator at the moment
on my 400 MHz UltraSparc. There will be quite some speedup running on a modern
PC or workstation with faster processor. Also, at the moment I have a lot of debugging
enabled, which slows down the emulator.
Getting the full 75 MHz out of the emulated ARM core will be hard work, I have not
looked into the potential optimizations that can be done in the core emulator, but
there are some things done during every instruction that we don't need for this
machine.
There are generally two options to speed up or use the emulator:
1. Emulate the hardware as closely as possible to help debug programms digging
into the s3c2410.
2. Emulate the saturn part to make it a usable calculator. Here one could implement
some of the most often used KOS syscalls directly in the emulator without doing
these on the emulated ARM core. This would speed up the calculator significantly.
Optimally there will be a runtime option to switch between these two modes.

View file

@ -1 +0,0 @@
Fix ldX_le/stX_le on sparc: use ASI_LE

View file

@ -1,11 +0,0 @@
[x49gp]
basename=.x49gp
[x49gp]
name=hp49g+
image=hp49g+.png
[flash]
filename=flash
[sram]
filename=sram
[s3c2410-sram]
filename=s3c2410-sram

138
README.md
View file

@ -29,6 +29,12 @@ Prereqs:
sudo yum install git gtk2-devel
```
* Arch:
```
sudo pacman -S git gtk2
```
------------------------------------------------------------------------
Start up X11 and use xterm
@ -43,71 +49,19 @@ git clone https://github.com/chwdt/x49gp.git
------------------------------------------------------------------------
Edit FIRMWARE (optional):
The default firmware will be 4950_92.bin, for HPGCC3 development copy
49_hpgcc.bin in to x49gp and change FIRMWARE in the Makefile.
------------------------------------------------------------------------
Build:
```
cd x49gp
make
make sdcard
make config
```
------------------------------------------------------------------------
Mount SD card:
OS/X:
Install (optional):
```
open sdcard.dmg
```
Linux:
```
sudo mkdir -p /Volumes/X49GP/
sudo mount -o loop sdcard /Volumes/X49GP
```
------------------------------------------------------------------------
Put stuff in SD, e.g.:
OS/X:
```
cp BACKUP /Volumes/X49GP/
```
Linux:
```
sudo cp BACKUP /Volumes/X49GP/
```
NOTE: If using HPGCC2 don't forget the ARMToolbox.
------------------------------------------------------------------------
Eject SD:
OS/X:
```
hdiutil detach $(df | grep -i x49gp | head -1 | awk '{print $1}')
```
Linux:
```
sudo umount /Volumes/X49GP
make install
```
------------------------------------------------------------------------
@ -115,9 +69,46 @@ sudo umount /Volumes/X49GP
Run:
```
./x49gp config
./x49gp
```
When installed, there should be an applications menu entry to run x49gp.
Installing also enables running it from the terminal in any directory:
```
x49gp
```
------------------------------------------------------------------------
First launch setup
On the first launch, the calculator will be missing a firmware, forcing
the bootloader to complain and demand a fresh one.
HP's official firmwares can be found at e.g.:
https://www.hpcalc.org/hp49/pc/rom/
Some of the most popular of these are also included in x49gp's source
directory.
Alternatively, the most up-to-date version of NewRPL can be found at:
https://hpgcc3.org/downloads/newrplfw.bin
Pick a firmware to use and store it in any directory along with its
update.scp file. The update.scp file only contains the filename of the
firmware (when renaming the firmware, make sure the new name fits into
a DOS-style 8.3 naming scheme) followed by a DOS-style linebreak, so a
missing update.scp can be rectified easily.
Right click on the screen, or press the menu key on a physical keyboard,
to open the menu, and click on "Mount SD folder".
Select the directory containing the firmware. Then, select the SD option
from the bootloader's update source menu by clicking on the virtual key
labeled "2" or by pressing the "2" key on a physical keyboard.
Now the bootloader is installing the firmware; wait until it finishes
printing hex numbers to the virtual display, then follow its prompt to
press Reset ( = F12 or the Reset entry in the menu) or Enter.
The calculator should be fully usable after this procedure.
------------------------------------------------------------------------
Do stuff, e.g.:
@ -147,7 +138,14 @@ EVAL
To Exit Emulator
* ctrl-c to exit (from launch window)
Use any of:
* Press Alt-F4 or your system's equivalent key combination
* Open the menu using a right click on the screen or the menu key, then
choose "Quit"
* Press Ctrl-C in the launch terminal
------------------------------------------------------------------------
@ -156,15 +154,26 @@ Start Over:
* clean slate?
```
rm -f flash-49g+ flash-50g flash-noboot sram s3c2410-sram
make flash-49g+ flash-50g flash-noboot sram s3c2410-sram
./newconfig
rm -r ~/.x49gp
```
* soft reset only?
With x49gp running, press F12, or right click on the screen and select
"Reset" from the menu.
------------------------------------------------------------------------
Debugging with x49gp
There is a GDB interface for debugging ARM programs, e.g. HPGCC2/3
applications or replacement firmwares. To use it, start x49gp from a
terminal with the -d option, and start arm-none-eabi-gdb with an
appropriate ELF file in another terminal. To connect to x49gp, type in
the GDB console:
```
./newconfig
target remote :1234
```
------------------------------------------------------------------------
@ -177,12 +186,3 @@ Known Limitations:
- `f*` calls stable (HPGCC3)
------------------------------------------------------------------------
Change Log:
Additional note: August 22, 2013
Updated this so that it'll compile on Ubuntu 12.04.
--Nicholas Kirchner

View file

@ -1,91 +0,0 @@
/ann_alpha.xbm/1.4/Thu Dec 11 12:14:08 2008//
/ann_battery.xbm/1.4/Thu Dec 11 12:14:08 2008//
/ann_busy.xbm/1.4/Thu Dec 11 12:14:08 2008//
/ann_io.xbm/1.4/Thu Dec 11 12:14:08 2008//
/ann_left.xbm/1.4/Thu Dec 11 12:14:08 2008//
/ann_right.xbm/1.4/Thu Dec 11 12:14:08 2008//
/button_large.xbm/1.4/Thu Dec 11 12:14:08 2008//
/button_normal.xbm/1.4/Thu Dec 11 12:14:08 2008//
/button_round.pix/1.1/Wed Jul 12 11:30:39 2006//
/button_round.xbm/1.4/Thu Dec 11 12:14:08 2008//
/button_small.xbm/1.4/Thu Dec 11 12:14:08 2008//
/button_tiny.xbm/1.4/Thu Dec 11 12:14:08 2008//
/tiny_A.xbm/1.4/Thu Dec 11 12:14:08 2008//
/tiny_B.xbm/1.4/Thu Dec 11 12:14:08 2008//
/tiny_C.xbm/1.4/Thu Dec 11 12:14:08 2008//
/tiny_D.xbm/1.4/Thu Dec 11 12:14:08 2008//
/tiny_E.xbm/1.4/Thu Dec 11 12:14:08 2008//
/tiny_F.xbm/1.4/Thu Dec 11 12:14:08 2008//
/tiny_G.xbm/1.4/Thu Dec 11 12:14:08 2008//
/tiny_H.xbm/1.4/Thu Dec 11 12:14:08 2008//
/tiny_I.xbm/1.4/Thu Dec 11 12:14:08 2008//
/tiny_J.xbm/1.4/Thu Dec 11 12:14:08 2008//
/tiny_K.xbm/1.4/Thu Dec 11 12:14:08 2008//
/tiny_L.xbm/1.4/Thu Dec 11 12:14:08 2008//
/tiny_M.xbm/1.4/Thu Dec 11 12:14:08 2008//
/tiny_N.xbm/1.4/Thu Dec 11 12:14:08 2008//
/tiny_O.xbm/1.4/Thu Dec 11 12:14:08 2008//
/tiny_P.xbm/1.4/Thu Dec 11 12:14:08 2008//
/tiny_Q.xbm/1.4/Thu Dec 11 12:14:08 2008//
/tiny_R.xbm/1.4/Thu Dec 11 12:14:08 2008//
/tiny_S.xbm/1.4/Thu Dec 11 12:14:08 2008//
/tiny_T.xbm/1.4/Thu Dec 11 12:14:08 2008//
/tiny_U.xbm/1.4/Thu Dec 11 12:14:08 2008//
/tiny_V.xbm/1.4/Thu Dec 11 12:14:08 2008//
/tiny_W.xbm/1.4/Thu Dec 11 12:14:08 2008//
/tiny_X.xbm/1.4/Thu Dec 11 12:14:08 2008//
/tiny_Y.xbm/1.4/Thu Dec 11 12:14:08 2008//
/tiny_Z.xbm/1.4/Thu Dec 11 12:14:08 2008//
/tiny__i.xbm/1.1/Thu Dec 11 12:19:15 2008//
/tiny_ampersand.xbm/1.4/Thu Dec 11 12:14:08 2008//
/tiny_arrowleft.xbm/1.4/Thu Dec 11 12:14:08 2008//
/tiny_arrowright.xbm/1.4/Thu Dec 11 12:14:08 2008//
/tiny_braceleft.xbm/1.5/Thu Dec 11 12:14:08 2008//
/tiny_braceright.xbm/1.5/Thu Dec 11 12:14:08 2008//
/tiny_bracketleft.xbm/1.4/Thu Dec 11 12:14:08 2008//
/tiny_bracketright.xbm/1.4/Thu Dec 11 12:14:08 2008//
/tiny_colon.xbm/1.4/Thu Dec 11 12:14:08 2008//
/tiny_comma.xbm/1.4/Thu Dec 11 12:14:08 2008//
/tiny_equal.xbm/1.5/Thu Dec 11 12:14:08 2008//
/tiny_greater.xbm/1.4/Thu Dec 11 12:14:08 2008//
/tiny_guillemotleft.xbm/1.4/Thu Dec 11 12:14:08 2008//
/tiny_guillemotright.xbm/1.4/Thu Dec 11 12:14:08 2008//
/tiny_hyphen.xbm/1.4/Thu Dec 11 12:14:08 2008//
/tiny_large_comma.xbm/1.4/Thu Dec 11 12:14:08 2008//
/tiny_less.xbm/1.4/Thu Dec 11 12:14:08 2008//
/tiny_math_arrowleft.xbm/1.4/Thu Dec 11 12:14:08 2008//
/tiny_math_arrowright.xbm/1.4/Thu Dec 11 12:14:08 2008//
/tiny_math_downarrowleft.xbm/1.4/Thu Dec 11 12:14:08 2008//
/tiny_math_downarrowright.xbm/1.4/Thu Dec 11 12:14:08 2008//
/tiny_math_e.xbm/1.4/Thu Dec 11 12:14:08 2008//
/tiny_math_equal.xbm/1.4/Thu Dec 11 12:14:08 2008//
/tiny_math_greater.xbm/1.4/Thu Dec 11 12:14:08 2008//
/tiny_math_greaterequal.xbm/1.4/Thu Dec 11 12:14:08 2008//
/tiny_math_infinity.xbm/1.4/Thu Dec 11 12:14:08 2008//
/tiny_math_integral.xbm/1.4/Thu Dec 11 12:14:08 2008//
/tiny_math_less.xbm/1.4/Thu Dec 11 12:14:08 2008//
/tiny_math_lessequal.xbm/1.4/Thu Dec 11 12:14:08 2008//
/tiny_math_notequal.xbm/1.4/Thu Dec 11 12:14:08 2008//
/tiny_math_numbersign.xbm/1.4/Thu Dec 11 12:14:08 2008//
/tiny_math_partialdiff.xbm/1.4/Thu Dec 11 12:14:08 2008//
/tiny_math_pi.xbm/1.4/Thu Dec 11 12:14:08 2008//
/tiny_math_radical.xbm/1.4/Thu Dec 11 12:14:08 2008//
/tiny_math_summation.xbm/1.4/Thu Dec 11 12:14:08 2008//
/tiny_math_x.xbm/1.4/Thu Dec 11 12:14:08 2008//
/tiny_math_y.xbm/1.5/Thu Dec 11 12:14:08 2008//
/tiny_notdef.xbm/1.4/Thu Dec 11 12:14:08 2008//
/tiny_numbersign.xbm/1.4/Thu Dec 11 12:14:08 2008//
/tiny_one.xbm/1.4/Thu Dec 11 12:14:08 2008//
/tiny_overscore.xbm/1.5/Thu Dec 11 12:14:08 2008//
/tiny_parenleft.xbm/1.5/Thu Dec 11 12:14:08 2008//
/tiny_parenright.xbm/1.5/Thu Dec 11 12:14:08 2008//
/tiny_period.xbm/1.4/Thu Dec 11 12:14:08 2008//
/tiny_quotedbl.xbm/1.4/Thu Dec 11 12:14:08 2008//
/tiny_slash.xbm/1.4/Thu Dec 11 12:14:08 2008//
/tiny_three.xbm/1.4/Thu Dec 11 12:14:08 2008//
/tiny_two.xbm/1.4/Thu Dec 11 12:14:08 2008//
/tiny_twosuperior.xbm/1.4/Thu Dec 11 12:14:08 2008//
/tiny_underscore.xbm/1.5/Thu Dec 11 12:14:08 2008//
/tiny_xsuperior.xbm/1.4/Thu Dec 11 12:14:08 2008//
/tiny_zero.xbm/1.4/Thu Dec 11 12:14:08 2008//
D

View file

@ -1 +0,0 @@
x49gp/bitmaps

View file

@ -1 +0,0 @@
:pserver:anonymous@x49gp.cvs.sourceforge.net:/cvsroot/x49gp

View file

@ -47,7 +47,7 @@
file system (test if the boot sector still relies on that fact)! */
/* MAYBE TODO: write block-visofs.c */
#define DEBUG
//#define DEBUG
#undef DEBUG_SECTORS
#ifdef DEBUG

80
block.c
View file

@ -156,14 +156,24 @@ find_protocol(const char *filename)
memcpy(protocol, filename, len);
protocol[len] = '\0';
for(drv1 = first_drv; drv1 != NULL; drv1 = drv1->next) {
fprintf(stderr, "%s:%u: protocol '%s', drv->protocol_name '%s'\n", __FUNCTION__, __LINE__, protocol, drv1->protocol_name);
#ifdef DEBUG_X49GP_BLOCK
fprintf(stderr,
"%s:%u: protocol '%s', drv->protocol_name '%s'\n",
__FUNCTION__, __LINE__, protocol, drv1->protocol_name);
#endif
if (drv1->protocol_name &&
!strcmp(drv1->protocol_name, protocol)) {
fprintf(stderr, "%s:%u: protocol '%s', drv %p\n", __FUNCTION__, __LINE__, protocol, drv1);
#ifdef DEBUG_X49GP_BLOCK
fprintf(stderr, "%s:%u: protocol '%s', drv %p\n",
__FUNCTION__, __LINE__, protocol, drv1);
#endif
return drv1;
}
}
fprintf(stderr, "%s:%u: protocol '%s', NULL\n", __FUNCTION__, __LINE__, protocol);
#ifdef DEBUG_X49GP_BLOCK
fprintf(stderr, "%s:%u: protocol '%s', NULL\n",
__FUNCTION__, __LINE__, protocol);
#endif
return NULL;
}
@ -276,8 +286,10 @@ bdrv_file_open(BlockDriverState **pbs, const char *filename, int flags)
{
BlockDriverState *bs;
int ret;
fprintf(stderr, "%s:%u: filename '%s'\n", __FUNCTION__, __LINE__, filename);
#ifdef DEBUG_X49GP_BLOCK
fprintf(stderr, "%s:%u: filename '%s'\n",
__FUNCTION__, __LINE__, filename);
#endif
bs = bdrv_new("");
if (!bs)
@ -285,11 +297,16 @@ fprintf(stderr, "%s:%u: filename '%s'\n", __FUNCTION__, __LINE__, filename);
ret = bdrv_open(bs, filename, flags | BDRV_O_FILE);
if (ret < 0) {
bdrv_delete(bs);
fprintf(stderr, "%s:%u: '%s': %d\n", __FUNCTION__, __LINE__, filename, ret);
#ifdef DEBUG_X49GP_BLOCK
fprintf(stderr, "%s:%u: '%s': %d\n",
__FUNCTION__, __LINE__, filename, ret);
#endif
return ret;
}
*pbs = bs;
#ifdef DEBUG_X49GP_BLOCK
fprintf(stderr, "%s:%u: return 0\n", __FUNCTION__, __LINE__);
#endif
return 0;
}
@ -300,7 +317,10 @@ bdrv_open(BlockDriverState *bs, const char *filename, int flags)
char backing_filename[1024];
BlockDriver *drv = NULL;
fprintf(stderr, "%s:%u: filename '%s'\n", __FUNCTION__, __LINE__, filename);
#ifdef DEBUG_X49GP_BLOCK
fprintf(stderr, "%s:%u: filename '%s'\n",
__FUNCTION__, __LINE__, filename);
#endif
bs->read_only = 0;
bs->is_temporary = 0;
@ -310,24 +330,34 @@ fprintf(stderr, "%s:%u: filename '%s'\n", __FUNCTION__, __LINE__, filename);
if (flags & BDRV_O_FILE) {
drv = find_protocol(filename);
if (!drv) {
fprintf(stderr, "%s:%u: drv: %p\n", __FUNCTION__, __LINE__, drv);
#ifdef DEBUG_X49GP_BLOCK
f printf(stderr, "%s:%u: drv: %p\n",
__FUNCTION__, __LINE__, drv);
#endif
return -ENOENT;
}
} else {
if (!drv) {
drv = find_image_format(filename);
if (!drv) {
fprintf(stderr, "%s:%u: drv: %p\n", __FUNCTION__, __LINE__, drv);
#ifdef DEBUG_X49GP_BLOCK
fprintf(stderr, "%s:%u: drv: %p\n",
__FUNCTION__, __LINE__, drv);
#endif
return -1;
}
}
}
#ifdef DEBUG_X49GP_BLOCK
fprintf(stderr, "%s:%u: drv: %p\n", __FUNCTION__, __LINE__, drv);
#endif
bs->drv = drv;
bs->opaque = qemu_mallocz(drv->instance_size);
if (bs->opaque == NULL && drv->instance_size > 0) {
#ifdef DEBUG_X49GP_BLOCK
fprintf(stderr, "%s:%u: no opaque\n", __FUNCTION__, __LINE__);
#endif
return -1;
}
/* Note: for compatibility, we open disk image files as RDWR, and
@ -337,7 +367,10 @@ fprintf(stderr, "%s:%u: no opaque\n", __FUNCTION__, __LINE__);
else
open_flags = flags & ~(BDRV_O_FILE);
ret = drv->bdrv_open(bs, filename, open_flags);
fprintf(stderr, "%s:%u: drv->bdrv_open: %d\n", __FUNCTION__, __LINE__, ret);
#ifdef DEBUG_X49GP_BLOCK
fprintf(stderr, "%s:%u: drv->bdrv_open: %d\n",
__FUNCTION__, __LINE__, ret);
#endif
if (ret == -EACCES && !(flags & BDRV_O_FILE)) {
ret = drv->bdrv_open(bs, filename, BDRV_O_RDONLY);
bs->read_only = 1;
@ -346,7 +379,10 @@ fprintf(stderr, "%s:%u: drv->bdrv_open: %d\n", __FUNCTION__, __LINE__, ret);
qemu_free(bs->opaque);
bs->opaque = NULL;
bs->drv = NULL;
fprintf(stderr, "%s:%u: return %d\n", __FUNCTION__, __LINE__, ret);
#ifdef DEBUG_X49GP_BLOCK
fprintf(stderr, "%s:%u: return %d\n",
__FUNCTION__, __LINE__, ret);
#endif
return ret;
}
if (drv->bdrv_getlength) {
@ -363,15 +399,27 @@ fprintf(stderr, "%s:%u: return %d\n", __FUNCTION__, __LINE__, ret);
if (!bs->backing_hd) {
fail:
bdrv_close(bs);
fprintf(stderr, "%s:%u: return -ENOMEM\n", __FUNCTION__, __LINE__);
#ifdef DEBUG_X49GP_BLOCK
fprintf(stderr, "%s:%u: return -ENOMEM\n",
__FUNCTION__, __LINE__);
#endif
return -ENOMEM;
}
fprintf(stderr, "%s:%u: combine '%s' '%s'\n", __FUNCTION__, __LINE__, filename, bs->backing_file);
#ifdef DEBUG_X49GP_BLOCK
fprintf(stderr, "%s:%u: combine '%s' '%s'\n",
__FUNCTION__, __LINE__, filename, bs->backing_file);
#endif
path_combine(backing_filename, sizeof(backing_filename),
filename, bs->backing_file);
fprintf(stderr, "%s:%u: combine: '%s'\n", __FUNCTION__, __LINE__, backing_filename);
#ifdef DEBUG_X49GP_BLOCK
fprintf(stderr, "%s:%u: combine: '%s'\n",
__FUNCTION__, __LINE__, backing_filename);
#endif
if (bdrv_open(bs->backing_hd, backing_filename, 0) < 0) {
fprintf(stderr, "%s:%u: backing fail\n", __FUNCTION__, __LINE__);
#ifdef DEBUG_X49GP_BLOCK
fprintf(stderr, "%s:%u: backing fail\n",
__FUNCTION__, __LINE__);
#endif
goto fail;
}
}
@ -381,7 +429,9 @@ fprintf(stderr, "%s:%u: backing fail\n", __FUNCTION__, __LINE__);
if (bs->change_cb)
bs->change_cb(bs->change_opaque);
#ifdef DEBUG_X49GP_BLOCK
fprintf(stderr, "%s:%u: return 0\n", __FUNCTION__, __LINE__);
#endif
return 0;
}

View file

@ -1,13 +0,0 @@
[x49gp]
basename=
[gui]
name=hp50g
image=hp50g.png
[flash]
filename=flash-50g
[sram]
filename=sram
[s3c2410-sram]
filename=s3c2410-sram
[s3c2410-sdi]
filename=sdcard.dmg

101
flash.c
View file

@ -9,7 +9,12 @@
#include <sys/mman.h>
#include <errno.h>
#include <gtk/gtk.h>
#include <glib.h>
#include <cairo.h>
#include <x49gp.h>
#include <x49gp_ui.h>
#include <memory.h>
#include <byteorder.h>
@ -40,6 +45,7 @@ typedef struct {
uint32_t cfi_size;
uint32_t sector_size;
uint32_t block_size;
char *filename;
int fd;
size_t size;
@ -54,6 +60,8 @@ typedef struct {
#define SST29VF160_BLOCK_SIZE 0x00010000
#define SST29VF160_SIZE 0x00200000
#define BOOT_SIZE 0x00004000
static const unsigned short sst29vf160_cfi_data[] =
{
[0x10] = 0x0051,
@ -460,48 +468,113 @@ static int
flash_load(x49gp_module_t *module, GKeyFile *key)
{
x49gp_flash_t *flash = module->user_data;
x49gp_t *x49gp = module->x49gp;
x49gp_ui_t *ui = x49gp->ui;
int calc = ui->calculator;
char *filename;
struct stat st;
char *bootfile;
int bootfd;
int error;
#ifdef DEBUG_X49GP_MODULES
printf("%s: %s:%u\n", module->name, __FUNCTION__, __LINE__);
#endif
filename = x49gp_module_get_filename(module, key, "filename");
if (NULL == filename) {
fprintf(stderr, "%s: %s:%u: key \"filename\" not found\n",
module->name, __FUNCTION__, __LINE__);
return -1;
}
error = x49gp_module_get_filename(module, key, "filename", "flash",
&(flash->filename), &filename);
flash->fd = open(filename, O_RDWR);
flash->fd = open(filename, O_RDWR | O_CREAT, 0644);
if (flash->fd < 0) {
error = -errno;
fprintf(stderr, "%s: %s:%u: open %s: %s\n",
module->name, __FUNCTION__, __LINE__,
filename, strerror(errno));
g_free(filename);
return -1;
return error;
}
flash->data = mmap(phys_ram_base + flash->offset, SST29VF160_SIZE,
flash->size = SST29VF160_SIZE;
if (fstat(flash->fd, &st) < 0) {
error = -errno;
fprintf(stderr, "%s: %s:%u: fstat %s: %s\n",
module->name, __FUNCTION__, __LINE__,
filename, strerror(errno));
g_free(filename);
close(flash->fd);
flash->fd = -1;
return error;
}
if (ftruncate(flash->fd, flash->size) < 0) {
error = -errno;
fprintf(stderr, "%s: %s:%u: ftruncate %s: %s\n",
module->name, __FUNCTION__, __LINE__,
filename, strerror(errno));
g_free(filename);
close(flash->fd);
flash->fd = -1;
return error;
}
flash->data = mmap(phys_ram_base + flash->offset, flash->size,
PROT_READ | PROT_WRITE, MAP_SHARED | MAP_FIXED,
flash->fd, 0);
if (flash->data == (void *) -1) {
error = -errno;
fprintf(stderr, "%s: %s:%u: mmap %s: %s\n",
module->name, __FUNCTION__, __LINE__,
filename, strerror(errno));
g_free(filename);
close(flash->fd);
flash->fd = -1;
return -1;
return error;
}
flash->size = SST29VF160_SIZE;
g_free(filename);
return 0;
if (flash->size > st.st_size) {
fprintf(stderr, "Flash too small, rebuilding\n");
memset(phys_ram_base + flash->offset + st.st_size,
0xFF, flash->size - st.st_size);
bootfd = x49gp_module_open_rodata(module,
calc == UI_CALCULATOR_HP49GP ?
"boot-49g+.bin" :
"boot-50g.bin",
&bootfile);
if (bootfd < 0) {
g_free(filename);
close(flash->fd);
flash->fd = -1;
return bootfd;
}
if (read(bootfd, phys_ram_base + flash->offset,
BOOT_SIZE) < 0) {
error = -errno;
fprintf(stderr, "%s: %s:%u: read %s: %s\n",
module->name, __FUNCTION__, __LINE__,
filename, strerror(errno));
g_free(bootfile);
close(bootfd);
close(flash->fd);
flash->fd = -1;
return error;
}
close(bootfd);
g_free(bootfile);
}
return error;
}
static int
flash_save(x49gp_module_t *module, GKeyFile *config)
flash_save(x49gp_module_t *module, GKeyFile *key)
{
x49gp_flash_t *flash = module->user_data;
int error;
@ -510,6 +583,8 @@ flash_save(x49gp_module_t *module, GKeyFile *config)
printf("%s: %s:%u\n", module->name, __FUNCTION__, __LINE__);
#endif
x49gp_module_set_filename(module, key, "filename", flash->filename);
error = msync(flash->data, flash->size, MS_ASYNC);
if (error) {
fprintf(stderr, "%s:%u: msync: %s\n",

View file

@ -455,8 +455,10 @@ static void gdb_read_byte(GDBState *s, int ch)
int i, csum;
char reply[1];
//printf("%s: state %u, byte %02x (%c)\n", __FUNCTION__, s->state, ch, ch);
#ifdef DEBUG_GDB
printf("%s: state %u, byte %02x (%c)\n", __FUNCTION__, s->state, ch, ch);
fflush(stdout);
#endif
switch(s->state) {
case RS_IDLE:
@ -515,8 +517,10 @@ gdb_handlesig (CPUState *env, int sig)
s = &gdbserver_state;
//printf("%s: sig: %u\n", __FUNCTION__, sig);
#ifdef DEBUG_GDB
printf("%s: sig: %u\n", __FUNCTION__, sig);
fflush(stdout);
#endif
/* disable single step if it was enabled */
cpu_single_step(env, 0);
@ -537,8 +541,10 @@ fflush(stdout);
{
int i;
//printf("%s: read: %d\n", __FUNCTION__, n);
#ifdef DEBUG_GDB
printf("%s: read: %d\n", __FUNCTION__, n);
fflush(stdout);
#endif
for (i = 0; i < n; i++)
gdb_read_byte (s, buf[i]);
@ -547,6 +553,7 @@ fflush(stdout);
{
/* XXX: Connection closed. Should probably wait for annother
connection before continuing. */
gdbserver_fd = -1;
return sig;
}
}
@ -573,8 +580,10 @@ gdb_poll (CPUState *env)
return 0;
}
//printf("%s: revents: %08x\n", __FUNCTION__, pfd.revents);
#ifdef DEBUG_GDB
printf("%s: revents: %08x\n", __FUNCTION__, pfd.revents);
fflush(stdout);
#endif
if (pfd.revents & (POLLIN | POLLHUP))
return 1;
@ -628,6 +637,10 @@ static void gdb_accept(void *opaque)
gdb_syscall_state = s;
fcntl(fd, F_SETFL, O_NONBLOCK);
/* When the debugger is connected, stop accepting connections */
/* to free the port up for other concurrent instances. */
close(gdbserver_fd);
}
static int gdbserver_open(int port)
@ -663,6 +676,9 @@ static int gdbserver_open(int port)
int gdbserver_start(int port)
{
if (gdbserver_fd >= 0)
return -1;
gdbserver_fd = gdbserver_open(port);
if (gdbserver_fd < 0)
return -1;
@ -670,3 +686,8 @@ int gdbserver_start(int port)
gdb_accept (NULL);
return 0;
}
int gdbserver_isactive()
{
return (gdbserver_fd >= 0);
}

View file

@ -15,4 +15,6 @@ int gdb_handlesig (CPUState *, int);
void gdb_exit(CPUState *, int);
int gdbserver_start(int);
int gdbserver_isactive();
#endif

View file

@ -1,18 +0,0 @@
/bitmap_font.h/1.5/Thu Dec 11 12:18:17 2008//
/bitmaps.h/1.9/Thu Dec 11 12:18:17 2008//
/block.h/1.1/Thu Dec 11 12:18:17 2008//
/byteorder.h/1.5/Thu Dec 11 12:18:17 2008//
/glyphname.h/1.3/Thu Dec 11 12:18:17 2008//
/list.h/1.5/Thu Dec 11 12:18:17 2008//
/s3c2410.h/1.18/Thu Dec 11 12:18:17 2008//
/s3c2410_intc.h/1.3/Thu Dec 11 12:18:17 2008//
/s3c2410_mmu.h/1.3/Thu Dec 11 12:18:17 2008//
/s3c2410_power.h/1.3/Thu Dec 11 12:18:17 2008//
/s3c2410_timer.h/1.3/Thu Dec 11 12:18:17 2008//
/saturn.h/1.1/Thu Dec 11 12:18:17 2008//
/symbol.h/1.4/Thu Dec 11 12:18:17 2008//
/x49gp.h/1.15/Thu Dec 11 12:18:17 2008//
/x49gp_timer.h/1.3/Thu Dec 11 12:18:17 2008//
/x49gp_types.h/1.5/Thu Dec 11 12:18:17 2008//
/x49gp_ui.h/1.14/Thu Dec 11 12:18:17 2008//
D

View file

@ -1 +0,0 @@
x49gp/include

View file

@ -1 +0,0 @@
:pserver:anonymous@x49gp.cvs.sourceforge.net:/cvsroot/x49gp

View file

@ -336,7 +336,7 @@ extern int x49gp_s3c2410_adc_init(x49gp_t *x49gp);
extern int x49gp_s3c2410_spi_init(x49gp_t *x49gp);
extern int x49gp_s3c2410_sdi_init(x49gp_t *x49gp);
extern void s3c2410_io_port_g_update(x49gp_t *x49gp);
extern void s3c2410_io_port_g_update(x49gp_t *x49gp, int column, int row, unsigned char columnbit, unsigned char rowbit, uint32_t new_state);
extern void s3c2410_io_port_f_set_bit(x49gp_t *x49gp, int n, uint32_t set);
extern void x49gp_schedule_lcd_update(x49gp_t *x49gp);

View file

@ -67,6 +67,7 @@ struct __x49gp_s__ {
void *s3c2410_watchdog;
void *s3c2410_intc;
void *s3c2410_io_port;
void *s3c2410_sdi;
void *timer;
uint8_t *sram;
@ -95,6 +96,9 @@ struct __x49gp_s__ {
GKeyFile *config;
const char *progname;
const char *progpath;
const char *basename;
int debug_port;
};
extern void x49gp_set_idle(x49gp_t *, x49gp_arm_idle_t idle);
@ -110,8 +114,11 @@ extern int x49gp_module_init(x49gp_t *x49gp, const char *name,
extern int x49gp_module_register(x49gp_module_t *module);
extern int x49gp_module_unregister(x49gp_module_t *module);
extern char *x49gp_module_get_filename(x49gp_module_t *module, GKeyFile *,
const char *key);
extern int x49gp_module_get_filename(x49gp_module_t *module, GKeyFile *,
const char *, char *, char **,
char **);
extern int x49gp_module_set_filename(x49gp_module_t *module, GKeyFile *,
const char *, const char *);
extern int x49gp_module_get_int(x49gp_module_t *module, GKeyFile *,
const char *, int, int *);
extern int x49gp_module_set_int(x49gp_module_t *module, GKeyFile *,
@ -131,6 +138,15 @@ extern int x49gp_module_set_u64(x49gp_module_t *module, GKeyFile *,
const char *, uint64_t);
extern int x49gp_module_get_string(x49gp_module_t *module, GKeyFile *,
const char *, char *, char **);
extern int x49gp_module_set_string(x49gp_module_t *module, GKeyFile *,
const char *, const char *);
extern int x49gp_module_open_rodata(x49gp_module_t *module,
const char *name,
char **path);
extern void s3c2410_sdi_unmount(x49gp_t *x49gp);
extern int s3c2410_sdi_mount(x49gp_t *x49gp, char *filename);
extern int s3c2410_sdi_is_mounted(x49gp_t *x49gp);
extern int x49gp_modules_init(x49gp_t *);
extern int x49gp_modules_exit(x49gp_t *);

View file

@ -93,6 +93,9 @@ typedef struct {
struct __x49gp_ui_s__ {
GtkWidget *window;
GtkWidget *fixed;
GtkWidget *menu;
GtkWidget *menu_unmount;
GtkWidget *menu_debug;
GdkPixbuf *bg_pixbuf;
GdkPixmap *bg_pixmap;
@ -105,6 +108,9 @@ struct __x49gp_ui_s__ {
x49gp_ui_button_t *buttons;
unsigned int nr_buttons;
unsigned int buttons_down;
char *name;
GtkWidget *lcd_canvas;
GdkPixmap *lcd_pixmap;

308
main.c
View file

@ -25,14 +25,6 @@
#include "gdbstub.h"
static void *oom_check(void *ptr)
{
if (ptr == NULL) {
abort();
}
return ptr;
}
static x49gp_t *x49gp;
#ifdef QEMU_OLD // LD TEMPO HACK
@ -51,6 +43,16 @@ ram_addr_t ram_size = 0x80000; // LD ???
/* vl.c */
int singlestep;
#if !(defined(__APPLE__) || defined(_POSIX_C_SOURCE) && !defined(__sun__))
static void *oom_check(void *ptr)
{
if (ptr == NULL) {
abort();
}
return ptr;
}
#endif
void *qemu_memalign(size_t alignment, size_t size)
{
#if defined(__APPLE__) || defined(_POSIX_C_SOURCE) && !defined(__sun__)
@ -293,12 +295,252 @@ x49gp_lcd_timer(void *data)
x49gp_mod_timer(x49gp->lcd_timer, expires);
}
struct options {
char *config;
int debug_port;
int start_debugger;
int more_options;
};
struct option_def;
typedef int (*option_action)(struct options *opt, struct option_def *match,
char *this_opt, char *param, char *progname);
struct option_def {
option_action action;
char *longname;
char shortname;
};
static int action_help(struct options *opt, struct option_def *match,
char *this_opt, char *param, char *progname);
static int action_debuglater(struct options *opt, struct option_def *match,
char *this_opt, char *param, char *progname);
static int action_debug(struct options *opt, struct option_def *match,
char *this_opt, char *param, char *progname);
static int action_unknown_with_param(struct options *opt,
struct option_def *match, char *this_opt,
char *param, char *progname);
static int action_longopt(struct options *opt, struct option_def *match,
char *this_opt, char *param, char *progname);
static int action_endopt(struct options *opt, struct option_def *match,
char *this_opt, char *param, char *progname);
struct option_def option_defs[] = {
{ action_help, "help", 'h' },
{ action_debuglater, "enable-debug", 'D' },
{ action_debug, "debug", 'd' },
{ action_longopt, NULL, '-' },
{ action_unknown_with_param, NULL, '=' },
{ action_endopt, "", '\0' }
};
static void
usage(const char *progname)
warn_unneeded_param(struct option_def *match, char *this_opt)
{
fprintf(stderr, "usage: %s <config-file>\n",
progname);
exit(1);
if (this_opt[1] == '-') {
fprintf(stderr, "The option \"--%s\" does not support"
" parameters\n", match->longname);
} else
fprintf(stderr, "The option '-%c' does not support parameters\n",
match->shortname);
}
static int
action_help(struct options *opt, struct option_def *match, char *this_opt,
char *param, char *progname)
{
if (param != NULL)
warn_unneeded_param(match, this_opt);
fprintf(stderr, "Emulator for HP 49G+ / 50G calculators\n"
"Usage: %s [<options>] [<config-file>]\n"
"Valid options:\n"
" -D, --enable-debug[=<port] enable the debugger interface\n"
" (default port: %u)\n"
" -d, --debug[=<port>] like -D, but also start the"
" debugger immediately\n"
" -h, --help print this message and exit\n"
"The config file is formatted as INI file and contains the"
" settings for which\n"
"persistence makes sense, like calculator model, CPU"
" registers, etc.\n"
"If the config file is omitted, ~/.%s/config is used.\n"
"Please consult the manual for more details on config file"
" settings.\n", progname, DEFAULT_GDBSTUB_PORT, progname);
exit(0);
}
static int
action_debuglater(struct options *opt, struct option_def *match, char *this_opt,
char *param, char *progname)
{
char *end;
int port;
if (param == NULL) {
if (opt->debug_port == 0)
opt->debug_port = DEFAULT_GDBSTUB_PORT;
return FALSE;
}
port = strtoul(param, &end, 0);
if ((end == param) || (*end != '\0')) {
fprintf(stderr, "Invalid port \"%s\", using default\n", param);
if (opt->debug_port == 0)
opt->debug_port = DEFAULT_GDBSTUB_PORT;
return TRUE;
}
if (opt->debug_port != 0 && opt->debug_port != DEFAULT_GDBSTUB_PORT)
fprintf(stderr, "Additional debug port \"%s\" specified,"
" overriding\n", param);
opt->debug_port = port;
return TRUE;
}
static int
action_debug(struct options *opt, struct option_def *match, char *this_opt,
char *param, char *progname)
{
opt->start_debugger = TRUE;
return action_debuglater(opt, match, this_opt, param, progname);
}
static int
action_longopt(struct options *opt, struct option_def *match, char *this_opt,
char *param, char *progname)
{
int i;
char *test_str, *option_str;
if (this_opt[1] != '-' || param != NULL) {
fprintf(stderr, "Unrecognized option '-', ignoring\n");
return FALSE;
}
for (i = 0; i < sizeof(option_defs) / sizeof(option_defs[0]); i++) {
if (option_defs[i].longname == NULL)
continue;
test_str = option_defs[i].longname;
option_str = this_opt + 2;
while (*test_str != '\0' && *test_str == *option_str) {
test_str++;
option_str++;
}
if (*test_str != '\0') continue;
switch (*option_str) {
case '\0':
(option_defs[i].action)(opt, option_defs + i, this_opt,
NULL, progname);
return TRUE;
case '=':
(option_defs[i].action)(opt, option_defs + i, this_opt,
option_str+2, progname);
return TRUE;
}
}
fprintf(stderr, "Unrecognized option \"%s\", ignoring\n", this_opt + 2);
return TRUE;
}
static int
action_unknown_with_param(struct options *opt, struct option_def *match,
char *this_opt, char *param, char *progname)
{
return TRUE;
}
static int
action_endopt(struct options *opt, struct option_def *match, char *this_opt,
char *param, char *progname)
{
opt->more_options = FALSE;
return TRUE;
}
static void
parse_shortopt(struct options *opt, char *this_opt, char *progname)
{
char *option = this_opt + 1;
char *param;
int i;
if (*option == '\0') {
fprintf(stderr,
"Empty option present, ignoring\n");
return;
}
do {
for (i = 0; i < sizeof(option_defs) / sizeof(option_defs[0]);
i++) {
if (*option == option_defs[i].shortname) {
if (*(option + 1) == '=') {
param = option + 2;
} else {
param = NULL;
}
if ((option_defs[i].action)(opt, option_defs + i,
this_opt, param,
progname))
return;
break;
}
}
if (i == sizeof(option_defs) / sizeof(option_defs[0]))
fprintf(stderr,
"Unrecognized option '%c', ignoring\n",
*option);
option++;
} while (*option != '\0');
}
static void
parse_options(struct options *opt, int argc, char **argv, char *progname)
{
opt->more_options = TRUE;
while (argc > 1) {
switch (argv[1][0]) {
case '\0':
break;
break;
case '-':
if (opt->more_options) {
parse_shortopt(opt, argv[1], progname);
break;
}
/* FALL THROUGH */
default:
if (opt->config != NULL) {
fprintf(stderr,
"Additional config file \"%s\""
" specified, overriding\n",
argv[1]);
}
opt->config = argv[1];
}
argc--;
argv++;
}
}
void
@ -321,22 +563,23 @@ ui_sighnd(int sig)
int
main(int argc, char **argv)
{
char *progname;
char *progname, *progpath;
int error;
struct options opt;
const char *home;
progname = strrchr(argv[0], '/');
if (progname)
progname++;
else
progname = argv[0];
progname = g_path_get_basename(argv[0]);
progpath = g_path_get_dirname(argv[0]);
gtk_init(&argc, &argv);
if (argc < 2)
usage(progname);
opt.config = NULL;
opt.debug_port = 0;
opt.start_debugger = FALSE;
parse_options(&opt, argc, argv, progname);
x49gp = malloc(sizeof(x49gp_t));
if (NULL == x49gp) {
@ -346,14 +589,17 @@ main(int argc, char **argv)
}
memset(x49gp, 0, sizeof(x49gp_t));
#ifdef DEBUG_X49GP_MAIN
fprintf(stderr, "_SC_PAGE_SIZE: %08lx\n", sysconf(_SC_PAGE_SIZE));
printf("%s:%u: x49gp: %p\n", __FUNCTION__, __LINE__, x49gp);
#endif
INIT_LIST_HEAD(&x49gp->modules);
x49gp->progname = progname;
x49gp->progpath = progpath;
x49gp->clk_tck = sysconf(_SC_CLK_TCK);
x49gp->emulator_fclk = 75000000;
@ -391,7 +637,19 @@ printf("%s:%u: x49gp: %p\n", __FUNCTION__, __LINE__, x49gp);
exit(1);
}
error = x49gp_modules_load(x49gp, argv[argc-1]);
if (opt.config == NULL) {
char config_dir[strlen(progname) + 2];
home = g_get_home_dir();
sprintf(config_dir, ".%s", progname);
opt.config = g_build_filename(home, config_dir,
"config", NULL);
}
x49gp->basename = g_path_get_dirname(opt.config);
x49gp->debug_port = opt.debug_port;
error = x49gp_modules_load(x49gp, opt.config);
if (error) {
if (error != -EAGAIN) {
exit(1);
@ -416,17 +674,15 @@ printf("%s:%u: x49gp: %p\n", __FUNCTION__, __LINE__, x49gp);
x49gp_mod_timer(x49gp->lcd_timer, x49gp_get_clock());
if(argc>=3) {
if((argv[1][0]=='-')&&(argv[1][1]=='d')&&(argv[1][2]==0)) {
gdbserver_start(1234);
if(opt.debug_port != 0 && opt.start_debugger) {
gdbserver_start(opt.debug_port);
gdb_handlesig(x49gp->env, 0);
}
}
x49gp_main_loop(x49gp);
x49gp_modules_save(x49gp, argv[argc-1]);
x49gp_modules_save(x49gp, opt.config);
x49gp_modules_exit(x49gp);

131
module.c
View file

@ -37,7 +37,9 @@ x49gp_modules_init(x49gp_t *x49gp)
exit(1);
}
#ifdef DEBUG_X49GP_MODULES
printf("%s: phys_ram_base: %p\n", __FUNCTION__, phys_ram_base);
#endif
phys_ram_dirty = qemu_vmalloc(phys_ram_size >> TARGET_PAGE_BITS);
memset(phys_ram_dirty, 0xff, phys_ram_size >> TARGET_PAGE_BITS);
@ -103,6 +105,13 @@ x49gp_modules_load(x49gp_t *x49gp, const char *filename)
printf("%s:%u:\n", __FUNCTION__, __LINE__);
#endif
if (g_mkdir_with_parents(x49gp->basename, 0755)) {
error = -errno;
fprintf(stderr, "%s:%u: g_mkdir_with_parents: %s\n",
__FUNCTION__, __LINE__, strerror(errno));
return error;
}
x49gp->config = g_key_file_new();
if (NULL == x49gp->config) {
fprintf(stderr, "%s:%u: g_key_file_new: Out of memory\n",
@ -110,7 +119,9 @@ x49gp_modules_load(x49gp_t *x49gp, const char *filename)
return -ENOMEM;
}
if (! g_key_file_load_from_file(x49gp->config, filename, 0, &gerror)) {
if (! g_key_file_load_from_file(x49gp->config, filename,
G_KEY_FILE_KEEP_COMMENTS, &gerror)
&& ! g_error_matches(gerror, G_FILE_ERROR, G_FILE_ERROR_NOENT)) {
fprintf(stderr, "%s:%u: g_key_file_load_from_file: %s\n",
__FUNCTION__, __LINE__, gerror->message);
g_key_file_free(x49gp->config);
@ -133,6 +144,7 @@ x49gp_modules_load(x49gp_t *x49gp, const char *filename)
{
extern unsigned char *phys_ram_base;
#ifdef DEBUG_X49GP_MODULES
printf("%s: phys_ram_base: %p\n", __FUNCTION__, phys_ram_base);
printf("\t%02x %02x %02x %02x %02x %02x %02x %02x\n",
phys_ram_base[0],
@ -143,6 +155,7 @@ printf("\t%02x %02x %02x %02x %02x %02x %02x %02x\n",
phys_ram_base[5],
phys_ram_base[6],
phys_ram_base[7]);
#endif
}
return result;
@ -176,7 +189,7 @@ x49gp_modules_save(x49gp_t *x49gp, const char *filename)
return -ENOMEM;
}
fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0666);
fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0644);
if (fd < 0) {
error = -errno;
fprintf(stderr, "%s:%u: open %s: %s\n",
@ -227,60 +240,45 @@ x49gp_module_unregister(x49gp_module_t *module)
return 0;
}
char *
int
x49gp_module_get_filename(x49gp_module_t *module, GKeyFile *key,
const char *name)
const char *name, char *reset, char **valuep,
char **path)
{
char *filename;
char *basename;
const char *home;
char *path;
x49gp_t *x49gp = module->x49gp;
int error;
filename = g_key_file_get_string(key, module->name, name, NULL);
if (NULL == filename) {
fprintf(stderr, "%s: %s:%u: key \"%s\" not found\n",
module->name, __FUNCTION__, __LINE__, name);
return NULL;
error = x49gp_module_get_string(module, key, name, reset, valuep);
if (g_path_is_absolute(*valuep)) {
*path = g_strdup(*valuep);
return error;
}
if (g_path_is_absolute(filename)) {
return filename;
}
home = g_get_home_dir();
basename = g_key_file_get_string(key, "x49gp", "basename", NULL);
if (NULL == basename) {
fprintf(stderr, "%s: %s:%u: key \"basename\" not found\n",
"x49gp", __FUNCTION__, __LINE__);
g_free(filename);
return NULL;
}
path = g_build_filename(home, basename, filename, NULL);
*path = g_build_filename(x49gp->basename, *valuep, NULL);
if (NULL == path) {
fprintf(stderr, "%s: %s:%u: Out of memory\n",
module->name, __FUNCTION__, __LINE__);
g_free(*valuep);
*valuep = NULL;
}
g_free(filename);
g_free(basename);
return error;
}
return path;
int
x49gp_module_set_filename(x49gp_module_t *module, GKeyFile *key,
const char *name, const char *value)
{
return x49gp_module_set_string(module, key, name, value);
}
int
x49gp_module_get_int(x49gp_module_t *module, GKeyFile *key, const char *name,
int reset, int *valuep)
{
uint32_t value;
int error;
error = x49gp_module_get_u32(module, key, name, reset, &value);
if (0 == error) {
*valuep = value;
}
return error;
return x49gp_module_get_u32(module, key, name, reset,
(uint32_t *) valuep);
}
int
@ -411,7 +409,7 @@ x49gp_module_get_string(x49gp_module_t *module, GKeyFile *key,
if (NULL == data) {
fprintf(stderr, "%s: %s:%u: key \"%s\" not found\n",
module->name, __FUNCTION__, __LINE__, name);
*valuep = strdup(reset);
*valuep = g_strdup(reset);
return -EAGAIN;
}
@ -419,6 +417,59 @@ x49gp_module_get_string(x49gp_module_t *module, GKeyFile *key,
return 0;
}
int x49gp_module_set_string(x49gp_module_t *module, GKeyFile *key,
const char *name, const char *value)
{
g_key_file_set_value(key, module->name, name, value);
return 0;
}
int
x49gp_module_open_rodata(x49gp_module_t *module, const char *name,
char **path)
{
x49gp_t *x49gp = module->x49gp;
int fd;
int error;
*path = g_build_filename(x49gp->progpath, name, NULL);
if (NULL == *path) {
fprintf(stderr, "%s: %s:%u: Out of memory\n",
module->name, __FUNCTION__, __LINE__);
return -ENOMEM;
}
fd = open(*path, O_RDONLY);
#ifdef X49GP_DATADIR
if (fd < 0 && (errno == EACCES || errno == ENOENT)) {
g_free(*path);
*path = g_build_filename(X49GP_DATADIR, name, NULL);
if (NULL == *path) {
fprintf(stderr, "%s: %s:%u: Out of memory\n",
module->name, __FUNCTION__, __LINE__);
return -ENOMEM;
}
fd = open(*path, O_RDONLY);
}
#endif
if (fd < 0) {
error = -errno;
fprintf(stderr, "%s: %s:%u: open %s: %s\n",
module->name, __FUNCTION__, __LINE__,
*path, strerror(errno));
g_free(*path);
*path = NULL;
return error;
}
return fd;
}
int
x49gp_module_init(x49gp_t *x49gp, const char *name,
int (*init)(x49gp_module_t *),

View file

@ -1,18 +0,0 @@
#!/bin/bash
if [ ! -r "config.tmpl" ]
then
echo "Cannot read config.tmpl" >&2
exit 1
fi
B=${PWD##$HOME/}
perl -p -e "s!^(basename=).*!\1$B!" <config.tmpl >config
if [ "$(uname -s)" = "Linux" ]
then
perl -p -e "s!^(filename=sdcard).dmg!\1!" config
fi
echo "New config created"
exit 0

View file

@ -1 +0,0 @@
qemu

View file

@ -1,4 +0,0 @@
/.cvsignore/1.1/Thu Dec 11 12:22:06 2008//
/prepare.sh/1.1/Thu Dec 11 12:14:08 2008//
/qemu-0.9.0.tar.gz/1.1/Thu Dec 11 12:14:08 2008//
D/patches////

View file

@ -1 +0,0 @@
x49gp/qemu

View file

@ -1 +0,0 @@
:pserver:anonymous@x49gp.cvs.sourceforge.net:/cvsroot/x49gp

View file

@ -1,27 +0,0 @@
/q_block.c_hdled_1.diff/1.1/Thu Dec 11 12:14:08 2008//
/q_block_int.h_hdled_1.diff/1.1/Thu Dec 11 12:14:08 2008//
/q_host-cocoa_02.diff/1.1/Thu Dec 11 12:14:08 2008//
/q_vga.c_02.diff/1.1/Thu Dec 11 12:14:08 2008//
/qemu-0.7.2-dyngen-check-stack-clobbers.patch/1.1/Thu Dec 11 12:14:08 2008//
/qemu-0.7.2-gcc4-opts.patch/1.1/Thu Dec 11 12:14:08 2008//
/qemu-0.8.0-gcc4-hacks.patch/1.1/Thu Dec 11 12:14:08 2008//
/qemu-0.8.0-osx-bugfix.patch/1.1/Thu Dec 11 12:14:08 2008//
/qemu-0.9.0-arm-shift.patch/1.1/Thu Dec 11 12:14:08 2008//
/qemu-0.9.0-enforce-16byte-stack-boundary.patch/1.1/Thu Dec 11 12:14:08 2008//
/qemu-0.9.0-gcc4.patch/1.1/Thu Dec 11 12:14:08 2008//
/qemu-0.9.0-i386-FORCE_RET.patch/1.1/Thu Dec 11 12:14:08 2008//
/qemu-0.9.0-osx-intel-port.patch/1.1/Thu Dec 11 12:14:09 2008//
/qemu-0.9.0-qcow2.diff/1.1/Thu Dec 11 12:14:09 2008//
/qemu-0.9.0-sparc-clobber.patch/1.1/Thu Dec 11 12:14:09 2008//
/qemu-0.9.0-sparc-compile-flags.patch/1.1/Thu Dec 11 12:14:09 2008//
/qemu-0.9.0-sparc-load-store-le.patch/1.1/Thu Dec 11 12:14:09 2008//
/qemu-0.9.0-sparc-register.patch/1.1/Thu Dec 11 12:14:09 2008//
/qemu-0.9.0-x49gp-arm-dump-state.patch/1.1/Thu Dec 11 12:14:09 2008//
/qemu-0.9.0-x49gp-arm-mmu.patch/1.1/Thu Dec 11 12:14:09 2008//
/qemu-0.9.0-x49gp-arm-semihosting.patch/1.1/Thu Dec 11 12:14:09 2008//
/qemu-0.9.0-x49gp-block.patch/1.1/Thu Dec 11 12:14:09 2008//
/qemu-0.9.0-x49gp-build-libqemu.patch/1.1/Thu Dec 11 12:14:09 2008//
/qemu-0.9.0-x49gp-debug-unassigned.patch/1.1/Thu Dec 11 12:14:09 2008//
/qemu-0.9.0-x49gp-phys_ram_dirty.patch/1.1/Thu Dec 11 12:14:09 2008//
/qemu-2ndbootdevice_04.diff/1.1/Thu Dec 11 12:14:09 2008//
D

View file

@ -1 +0,0 @@
x49gp/qemu/patches

View file

@ -1 +0,0 @@
:pserver:anonymous@x49gp.cvs.sourceforge.net:/cvsroot/x49gp

View file

@ -223,7 +223,9 @@ s3c2410_adc_init(x49gp_module_t *module)
iotype = cpu_register_io_memory(s3c2410_adc_readfn,
s3c2410_adc_writefn, adc);
#endif
#ifdef DEBUG_S3C2410_ADC
printf("%s: iotype %08x\n", __FUNCTION__, iotype);
#endif
cpu_register_physical_memory(S3C2410_ADC_BASE, S3C2410_MAP_SIZE, iotype);
return 0;

View file

@ -707,7 +707,9 @@ s3c2410_intc_init(x49gp_module_t *module)
iotype = cpu_register_io_memory(s3c2410_intc_readfn,
s3c2410_intc_writefn, intc);
#endif
#ifdef DEBUG_S3C2410_INTC
printf("%s: iotype %08x\n", __FUNCTION__, iotype);
#endif
cpu_register_physical_memory(S3C2410_INTC_BASE, S3C2410_MAP_SIZE, iotype);
return 0;
}

View file

@ -248,8 +248,7 @@ s3c2410_io_port_read(void *opaque, target_phys_addr_t offset)
break;
case S3C2410_IO_PORT_GPGDAT:
*(reg->datap) = s3c2410_scan_keys(io->x49gp, io->gpgcon, *(reg->datap));
break;
return s3c2410_scan_keys(io->x49gp, io->gpgcon, io->gpgdat);
case S3C2410_IO_PORT_GPHDAT:
if (0 == ((io->gphcon >> 14) & 3)) {
@ -356,16 +355,25 @@ static uint32_t lcd_data = 0;
}
void
s3c2410_io_port_g_update(x49gp_t *x49gp)
s3c2410_io_port_g_update(x49gp_t *x49gp, int column, int row, unsigned char columnbit, unsigned char rowbit, uint32_t new_state)
{
s3c2410_io_port_t *io = x49gp->s3c2410_io_port;
uint32_t oldvalue, change;
uint32_t oldvalue, newvalue, change;
int n;
oldvalue=io->gpgdat;
io->gpgdat = s3c2410_scan_keys(x49gp, io->gpgcon, io->gpgdat);
oldvalue = s3c2410_scan_keys(x49gp, io->gpgcon, io->gpgdat);
change=io->gpgdat^oldvalue;
if (new_state) {
x49gp->keybycol[column] |= rowbit;
x49gp->keybyrow[row] |= columnbit;
} else {
x49gp->keybycol[column] &= ~rowbit;
x49gp->keybyrow[row] &= ~columnbit;
}
newvalue = s3c2410_scan_keys(x49gp, io->gpgcon, io->gpgdat);
change=newvalue^oldvalue;
for(n=0;n<15;++n) {
@ -374,11 +382,12 @@ s3c2410_io_port_g_update(x49gp_t *x49gp)
case 2: /* Interrupt */
{
if(n+8<=15) {
// EINT 8-15
switch ((io->extint1 >> (4 * n)) & 7) {
switch (n+8<=15 ?
(io->extint1 >> (4 * n)) & 7 : // EINT 8-15
(io->extint2 >> (4 * (n-8))) & 7 // EINT 16-23
) {
case 0: /* Low Level */
if (!(io->gpgdat & (1 << n)))
if (!(newvalue & (1 << n)))
{
io->eintpend |= 1 << (n + 8);
if (io->eintpend & ~(io->eintmask))
@ -386,7 +395,7 @@ s3c2410_io_port_g_update(x49gp_t *x49gp)
}
break;
case 1: /* High Level */
if (io->gpgdat & (1 << n)) {
if (newvalue & (1 << n)) {
io->eintpend |= 1 << (n + 8);
if (io->eintpend & ~(io->eintmask))
s3c2410_intc_assert(x49gp, EINT8_23, 1);
@ -394,7 +403,7 @@ s3c2410_io_port_g_update(x49gp_t *x49gp)
break;
case 2: /* Falling Edge */
case 3:
if ((change & (1 << n)) && !(io->gpgdat & (1 << n))) {
if ((change & (1 << n)) && !(newvalue & (1 << n))) {
io->eintpend |= 1 << (n + 8);
if (io->eintpend & ~(io->eintmask))
s3c2410_intc_assert(x49gp, EINT8_23, 1);
@ -402,7 +411,7 @@ s3c2410_io_port_g_update(x49gp_t *x49gp)
break;
case 4: /* Rising Edge */
case 5:
if ((change & (1 << n)) && (io->gpgdat & (1 << n))) {
if ((change & (1 << n)) && (newvalue & (1 << n))) {
io->eintpend |= 1 << (n + 8);
if (io->eintpend & ~(io->eintmask))
s3c2410_intc_assert(x49gp, EINT8_23, 1);
@ -416,53 +425,6 @@ s3c2410_io_port_g_update(x49gp_t *x49gp)
s3c2410_intc_assert(x49gp, EINT8_23, 1);
}
break;
}
}
else {
// EINT 16-23
switch ((io->extint2 >> (4 * (n-8))) & 7) {
case 0: /* Low Level */
if (!(io->gpgdat & (1 << n)))
{
io->eintpend |= 1 << (n + 8);
if (io->eintpend & ~(io->eintmask))
s3c2410_intc_assert(x49gp, EINT8_23, 1);
}
break;
case 1: /* High Level */
if (io->gpgdat & (1 << n)) {
io->eintpend |= 1 << (n + 8);
if (io->eintpend & ~(io->eintmask))
s3c2410_intc_assert(x49gp, EINT8_23, 1);
}
break;
case 2: /* Falling Edge */
case 3:
if ((change & (1 << n)) && !(io->gpgdat & (1 << n))) {
io->eintpend |= 1 << (n + 8);
if (io->eintpend & ~(io->eintmask))
s3c2410_intc_assert(x49gp, EINT8_23, 1);
}
break;
case 4: /* Rising Edge */
case 5:
if ((change & (1 << n)) && (io->gpgdat & (1 << n))) {
io->eintpend |= 1 << (n + 8);
if (io->eintpend & ~(io->eintmask))
s3c2410_intc_assert(x49gp, EINT8_23, 1);
}
break;
case 6: /* Any Edge */
case 7:
if (change & (1 << n)) {
io->eintpend |= 1 << (n + 8);
if (io->eintpend & ~(io->eintmask))
s3c2410_intc_assert(x49gp, EINT8_23, 1);
}
break;
}
}
}
@ -701,7 +663,9 @@ s3c2410_io_port_init(x49gp_module_t *module)
iotype = cpu_register_io_memory(s3c2410_io_port_readfn,
s3c2410_io_port_writefn, io);
#endif
#ifdef DEBUG_S3C2410_IO_PORT
printf("%s: iotype %08x\n", __FUNCTION__, iotype);
#endif
cpu_register_physical_memory(S3C2410_IO_PORT_BASE, S3C2410_MAP_SIZE, iotype);
return 0;
}

View file

@ -110,7 +110,7 @@ x49gp_get_pixel_color(s3c2410_lcd_t *lcd, int x, int y)
case 1:
return 15 * data;
case 2:
return 15 & (lcd->bluelut >> (2 * data));
return 15 & (lcd->bluelut >> (4 * data));
default:
return data;
}
@ -375,7 +375,9 @@ s3c2410_lcd_init(x49gp_module_t *module)
iotype = cpu_register_io_memory(s3c2410_lcd_readfn,
s3c2410_lcd_writefn, lcd);
#endif
#ifdef DEBUG_S3C2410_LCD
printf("%s: iotype %08x\n", __FUNCTION__, iotype);
#endif
cpu_register_physical_memory(S3C2410_LCD_BASE, S3C2410_MAP_SIZE, iotype);
return 0;
}

View file

@ -237,7 +237,9 @@ s3c2410_memc_init(x49gp_module_t *module)
iotype = cpu_register_io_memory(s3c2410_memc_readfn,
s3c2410_memc_writefn, memc);
#endif
#ifdef DEBUG_S3C2410_MEMC
printf("%s: iotype %08x\n", __FUNCTION__, iotype);
#endif
cpu_register_physical_memory(S3C2410_MEMC_BASE, S3C2410_MAP_SIZE, iotype);
return 0;
}

View file

@ -218,7 +218,9 @@ s3c2410_nand_init(x49gp_module_t *module)
iotype = cpu_register_io_memory(s3c2410_nand_readfn,
s3c2410_nand_writefn, nand);
#endif
#ifdef DEBUG_S3C2410_NAND
printf("%s: iotype %08x\n", __FUNCTION__, iotype);
#endif
cpu_register_physical_memory(S3C2410_NAND_BASE, S3C2410_MAP_SIZE, iotype);
return 0;
}

View file

@ -329,7 +329,9 @@ s3c2410_power_init(x49gp_module_t *module)
iotype = cpu_register_io_memory(s3c2410_power_readfn,
s3c2410_power_writefn, power);
#endif
#ifdef DEBUG_S3C2410_POWER
printf("%s: iotype %08x\n", __FUNCTION__, iotype);
#endif
cpu_register_physical_memory(S3C2410_POWER_BASE, S3C2410_MAP_SIZE, iotype);
return 0;
}

View file

@ -465,7 +465,9 @@ s3c2410_rtc_init(x49gp_module_t *module)
iotype = cpu_register_io_memory(s3c2410_rtc_readfn,
s3c2410_rtc_writefn, rtc);
#endif
#ifdef DEBUG_S3C2410_RTC
printf("%s: iotype %08x\n", __FUNCTION__, iotype);
#endif
cpu_register_physical_memory(S3C2410_RTC_BASE, S3C2410_MAP_SIZE, iotype);
return 0;

View file

@ -39,6 +39,7 @@ typedef struct {
x49gp_t *x49gp;
char *filename;
BlockDriverState *bs;
int fd;
@ -525,15 +526,89 @@ s3c2410_sdi_write(void *opaque, target_phys_addr_t offset, uint32_t data)
}
}
void
s3c2410_sdi_unmount(x49gp_t *x49gp)
{
s3c2410_sdi_t *sdi = x49gp->s3c2410_sdi;
if (sdi->bs) {
bdrv_delete(sdi->bs);
sdi->bs = NULL;
}
if (sdi->fd >= 0) {
close(sdi->fd);
sdi->fd = -1;
}
g_free(sdi->filename);
sdi->filename = g_strdup("");
s3c2410_io_port_f_set_bit(x49gp, 3, 0);
}
int
s3c2410_sdi_mount(x49gp_t *x49gp, char *filename)
{
s3c2410_sdi_t *sdi = x49gp->s3c2410_sdi;
struct stat st;
char vvfat_name[1024];
int error = 0;
s3c2410_sdi_unmount(x49gp);
g_free(sdi->filename);
sdi->filename = filename;
if (strcmp(filename, "") && (stat(filename, &st) == 0)) {
if (S_ISDIR(st.st_mode)) {
sprintf(vvfat_name, "fat:rw:16:%s", filename);
sdi->bs = bdrv_new("");
if (sdi->bs) {
error = bdrv_open(sdi->bs, vvfat_name, 0);
if (error != 0) {
fprintf(stderr,
"%s:%u: bdrv_open %s: %d\n",
__FUNCTION__, __LINE__,
vvfat_name, error);
bdrv_delete(sdi->bs);
sdi->bs = NULL;
}
}
} else {
sdi->fd = open(filename, O_RDWR);
if (sdi->fd < 0) {
fprintf(stderr, "%s:%u: open %s: %s\n",
__FUNCTION__, __LINE__, filename,
strerror(errno));
}
}
}
if ((sdi->bs != NULL) || (sdi->fd >= 0)) {
s3c2410_io_port_f_set_bit(x49gp, 3, 1);
} else {
s3c2410_io_port_f_set_bit(x49gp, 3, 0);
}
return error;
}
int
s3c2410_sdi_is_mounted(x49gp_t *x49gp)
{
s3c2410_sdi_t *sdi = x49gp->s3c2410_sdi;
return (sdi->bs != NULL) || (sdi->fd >= 0);
}
static int
s3c2410_sdi_load(x49gp_module_t *module, GKeyFile *key)
{
x49gp_t *x49gp = module->x49gp;
s3c2410_sdi_t *sdi = module->user_data;
s3c2410_offset_t *reg;
char *filename;
char vvfat_name[1024];
struct stat st;
int error = 0;
char *filename, *filepath;
int error, error2;
int i;
#ifdef DEBUG_X49GP_MODULES
@ -542,32 +617,18 @@ s3c2410_sdi_load(x49gp_module_t *module, GKeyFile *key)
sdi->fd = -1;
sdi->bs = NULL;
sdi->filename = NULL;
filename = x49gp_module_get_filename(module, key, "filename");
if (filename && (stat(filename, &st) == 0)) {
if (S_ISDIR(st.st_mode)) {
sprintf(vvfat_name, "fat:rw:16:%s", filename);
sdi->bs = bdrv_new("");
if (sdi->bs) {
error = bdrv_open(sdi->bs, vvfat_name, 0);
fprintf(stderr, "%s:%u: bdrv_open(%s): %d\n",
__FUNCTION__, __LINE__, vvfat_name, error);
if (error != 0) {
bdrv_delete(sdi->bs);
sdi->bs = NULL;
}
}
error = x49gp_module_get_filename(module, key, "filename", "",
&filename, &filepath);
if (strcmp(filename, "")) {
error2 = s3c2410_sdi_mount(x49gp, filepath);
if (0 == error) error = error2;
} else {
sdi->fd = open(filename, O_RDWR);
}
g_free(filename);
}
if ((sdi->bs != NULL) || (sdi->fd >= 0)) {
s3c2410_io_port_f_set_bit(sdi->x49gp, 3, 1);
} else {
s3c2410_io_port_f_set_bit(sdi->x49gp, 3, 0);
s3c2410_sdi_unmount(x49gp);
}
g_free(sdi->filename);
sdi->filename = filename;
for (i = 0; i < sdi->nr_regs; i++) {
reg = &sdi->regs[i];
@ -594,6 +655,8 @@ s3c2410_sdi_save(x49gp_module_t *module, GKeyFile *key)
printf("%s: %s:%u\n", module->name, __FUNCTION__, __LINE__);
#endif
x49gp_module_set_filename(module, key, "filename", sdi->filename);
for (i = 0; i < sdi->nr_regs; i++) {
reg = &sdi->regs[i];
@ -665,6 +728,7 @@ s3c2410_sdi_init(x49gp_module_t *module)
}
module->user_data = sdi;
module->x49gp->s3c2410_sdi = sdi;
sdi->x49gp = module->x49gp;
#ifdef QEMU_OLD
@ -674,7 +738,9 @@ s3c2410_sdi_init(x49gp_module_t *module)
iotype = cpu_register_io_memory(s3c2410_sdi_readfn,
s3c2410_sdi_writefn, sdi);
#endif
#ifdef DEBUG_S3C2410_SDI
printf("%s: iotype %08x\n", __FUNCTION__, iotype);
#endif
cpu_register_physical_memory(S3C2410_SDI_BASE, S3C2410_MAP_SIZE, iotype);
bdrv_init();

View file

@ -256,7 +256,9 @@ s3c2410_spi_init(x49gp_module_t *module)
iotype = cpu_register_io_memory(s3c2410_spi_readfn,
s3c2410_spi_writefn, spi);
#endif
#ifdef DEBUG_S3C2410_SPI
printf("%s: iotype %08x\n", __FUNCTION__, iotype);
#endif
cpu_register_physical_memory(S3C2410_SPI_BASE, S3C2410_MAP_SIZE, iotype);
return 0;
}

View file

@ -15,6 +15,7 @@
typedef struct {
void *data;
char *filename;
int fd;
uint32_t offset;
size_t size;
@ -31,14 +32,11 @@ s3c2410_sram_load(x49gp_module_t *module, GKeyFile *key)
printf("%s: %s:%u\n", module->name, __FUNCTION__, __LINE__);
#endif
filename = x49gp_module_get_filename(module, key, "filename");
if (NULL == filename) {
fprintf(stderr, "%s: %s:%u: key \"filename\" not found\n",
module->name, __FUNCTION__, __LINE__);
return -ENOENT;
}
error = x49gp_module_get_filename(module, key, "filename",
"s3c2410-sram", &(filemap->filename),
&filename);
filemap->fd = open(filename, O_RDWR);
filemap->fd = open(filename, O_RDWR | O_CREAT, 0644);
if (filemap->fd < 0) {
error = -errno;
fprintf(stderr, "%s: %s:%u: open %s: %s\n",
@ -48,7 +46,19 @@ s3c2410_sram_load(x49gp_module_t *module, GKeyFile *key)
return error;
}
filemap->data = mmap(phys_ram_base + filemap->offset, S3C2410_SRAM_SIZE,
filemap->size = S3C2410_SRAM_SIZE;
if (ftruncate(filemap->fd, filemap->size) < 0) {
error = -errno;
fprintf(stderr, "%s: %s:%u: ftruncate %s: %s\n",
module->name, __FUNCTION__, __LINE__,
filename, strerror(errno));
g_free(filename);
close(filemap->fd);
filemap->fd = -1;
return error;
}
filemap->data = mmap(phys_ram_base + filemap->offset, filemap->size,
PROT_READ | PROT_WRITE, MAP_SHARED | MAP_FIXED,
filemap->fd, 0);
if (filemap->data == (void *) -1) {
@ -61,12 +71,11 @@ s3c2410_sram_load(x49gp_module_t *module, GKeyFile *key)
filemap->fd = -1;
return error;
}
filemap->size = S3C2410_SRAM_SIZE;
g_free(filename);
x49gp_schedule_lcd_update(module->x49gp);
return 0;
return error;
}
static int
@ -79,6 +88,8 @@ s3c2410_sram_save(x49gp_module_t *module, GKeyFile *key)
printf("%s: %s:%u\n", module->name, __FUNCTION__, __LINE__);
#endif
x49gp_module_set_filename(module, key, "filename", filemap->filename);
error = msync(filemap->data, filemap->size, MS_ASYNC);
if (error) {
fprintf(stderr, "%s:%u: msync: %s\n",

View file

@ -522,7 +522,9 @@ s3c2410_timer_init(x49gp_module_t *module)
iotype = cpu_register_io_memory(s3c2410_timer_readfn,
s3c2410_timer_writefn, timer);
#endif
#ifdef DEBUG_S3C2410_TIMER
printf("%s: iotype %08x\n", __FUNCTION__, iotype);
#endif
cpu_register_physical_memory(S3C2410_TIMER_BASE, S3C2410_MAP_SIZE, iotype);
return 0;
}

View file

@ -388,7 +388,9 @@ s3c2410_uart_init(x49gp_module_t *module)
iotype = cpu_register_io_memory(s3c2410_uart_readfn,
s3c2410_uart_writefn, uart_regs);
#endif
#ifdef DEBUG_S3C2410_UART
printf("%s: iotype %08x\n", __FUNCTION__, iotype);
#endif
cpu_register_physical_memory(S3C2410_UART0_BASE, S3C2410_MAP_SIZE, iotype);
return 0;

View file

@ -296,7 +296,9 @@ s3c2410_usbdev_init(x49gp_module_t *module)
iotype = cpu_register_io_memory(s3c2410_usbdev_readfn,
s3c2410_usbdev_writefn, usbdev);
#endif
#ifdef DEBUG_S3C2410_USBDEV
printf("%s: iotype %08x\n", __FUNCTION__, iotype);
#endif
cpu_register_physical_memory(S3C2410_USBDEV_BASE, S3C2410_MAP_SIZE, iotype);
return 0;
}

View file

@ -342,7 +342,9 @@ s3c2410_watchdog_init(x49gp_module_t *module)
iotype = cpu_register_io_memory(s3c2410_watchdog_readfn,
s3c2410_watchdog_writefn, watchdog);
#endif
#ifdef DEBUG_S3C2410_WATCHDOG
printf("%s: iotype %08x\n", __FUNCTION__, iotype);
#endif
cpu_register_physical_memory(S3C2410_WATCHDOG_BASE, S3C2410_MAP_SIZE, iotype);
return 0;
}

View file

@ -1 +0,0 @@
.depend

View file

@ -1,2 +0,0 @@
/.cvsignore/1.1/Thu Jun 8 05:41:42 2006//
D

View file

@ -1 +0,0 @@
x49gp/sim

View file

@ -1 +0,0 @@
:pserver:anonymous@x49gp.cvs.sourceforge.net:/cvsroot/x49gp

25
sram.c
View file

@ -18,6 +18,7 @@
typedef struct {
void *data;
void *shadow;
char *filename;
int fd;
size_t size;
uint32_t offset;
@ -611,14 +612,10 @@ sram_load(x49gp_module_t *module, GKeyFile *key)
printf("%s: %s:%u\n", module->name, __FUNCTION__, __LINE__);
#endif
filename = x49gp_module_get_filename(module, key, "filename");
if (NULL == filename) {
fprintf(stderr, "%s: %s:%u: key \"filename\" not found\n",
module->name, __FUNCTION__, __LINE__);
return -ENOENT;
}
error = x49gp_module_get_filename(module, key, "filename", "sram",
&(sram->filename), &filename);
sram->fd = open(filename, O_RDWR);
sram->fd = open(filename, O_RDWR | O_CREAT, 0644);
if (sram->fd < 0) {
error = -errno;
fprintf(stderr, "%s: %s:%u: open %s: %s\n",
@ -629,6 +626,16 @@ sram_load(x49gp_module_t *module, GKeyFile *key)
}
sram->size = 0x00080000;
if (ftruncate(sram->fd, sram->size) < 0) {
error = -errno;
fprintf(stderr, "%s: %s:%u: ftruncate %s: %s\n",
module->name, __FUNCTION__, __LINE__,
filename, strerror(errno));
g_free(filename);
close(sram->fd);
sram->fd = -1;
return error;
}
sram->data = mmap(phys_ram_base + sram->offset, sram->size,
PROT_READ | PROT_WRITE, MAP_SHARED | MAP_FIXED,
@ -662,7 +669,7 @@ sram_load(x49gp_module_t *module, GKeyFile *key)
sram->x49gp->sram = phys_ram_base + sram->offset;
g_free(filename);
return 0;
return error;
}
static int
@ -675,6 +682,8 @@ sram_save(x49gp_module_t *module, GKeyFile *key)
printf("%s: %s:%u\n", module->name, __FUNCTION__, __LINE__);
#endif
x49gp_module_set_filename(module, key, "filename", sram->filename);
error = msync(sram->data, sram->size, MS_ASYNC);
if (error) {
fprintf(stderr, "%s:%u: msync: %s\n",

View file

@ -20,6 +20,8 @@
#include <glib.h>
#include "gdbstub.h"
typedef struct {
long type;
} x49gp_clock_t;
@ -278,6 +280,7 @@ printf("PC %08x: SRAM %08x: %08x %08x %08x <%08x>\n", x49gp->env->regs[15], 0x08
if (ret == EXCP_DEBUG) {
gdb_handlesig(x49gp->env, SIGTRAP);
continue;
}
if (x49gp->arm_idle != prev_idle) {

516
ui.c
View file

@ -11,6 +11,7 @@
#include <sys/times.h>
#include <math.h>
#include <errno.h>
#include <arpa/inet.h> /* For ntohl() */
#include <gtk/gtk.h>
#include <glib.h>
@ -24,6 +25,8 @@
#include <symbol.h>
#include <glyphname.h>
#include "gdbstub.h"
#include <gdk/gdkkeysyms.h>
#if defined(__linux__)
@ -729,6 +732,47 @@ x49gp_ui_style_init(GtkStyle *style, GtkWidget *widget,
style->ythickness = 0;
}
static const uint32_t PIXBUF_MAGIC = 0x47646b50;
typedef struct {
uint32_t magic;
uint32_t length;
uint32_t pixdata_type;
uint32_t rowstride;
uint32_t width;
uint32_t height;
} pixbuf_inline_data_t;
static GdkPixbuf *
x49gp_pixbuf_new_from_inline(gint data_length, const guint8 *data)
{
const pixbuf_inline_data_t *pbd = (const pixbuf_inline_data_t *) data;
uint32_t magic, rowstride, width, height, length;
const guint8 *pixdata;
magic = ntohl(pbd->magic);
if (magic != PIXBUF_MAGIC) {
return NULL;
}
length = ntohl(pbd->length);
/* The data comes from a C string, which contains a trailing \0. */
/* This will be counted by sizeof(), but the embedded header */
/* specifies the true size. Compensate by adding 1 to it. */
if (length + 1 != data_length) {
return NULL;
}
width = ntohl(pbd->width);
height = ntohl(pbd->height);
rowstride = ntohl(pbd->rowstride);
pixdata = (void *) (pbd + 1);
return gdk_pixbuf_new_from_data(pixdata, GDK_COLORSPACE_RGB, TRUE, 8,
width, height, rowstride, NULL, NULL);
}
static int
x49gp_ui_button_pixmaps_init(x49gp_t *x49gp, x49gp_ui_button_t *button,
x49gp_ui_color_t color)
@ -750,7 +794,6 @@ x49gp_ui_button_pixmaps_init(x49gp_t *x49gp, x49gp_ui_button_t *button,
if (i == GTK_STATE_ACTIVE) {
if (color == UI_COLOR_SILVER) {
GError *gerror = NULL;
src = gdk_pixbuf_new_subpixbuf(ui->bg_pixbuf,
ui->kb_x_offset + button->key->x,
@ -760,8 +803,8 @@ x49gp_ui_button_pixmaps_init(x49gp_t *x49gp, x49gp_ui_button_t *button,
dst = gdk_pixbuf_copy(src);
g_object_unref(src);
src = gdk_pixbuf_new_from_inline(sizeof(button_round),
button_round, FALSE, &gerror);
src = x49gp_pixbuf_new_from_inline(sizeof(button_round),
button_round);
gdk_pixbuf_composite(src, dst,
0, 0,
@ -1462,6 +1505,33 @@ bitmap_font_draw_text(GdkDrawable *drawable, GdkColor *color,
}
}
static void
x49gp_ui_choose_file(x49gp_t *x49gp, const char *prompt,
GtkFileChooserAction action, char **filename)
{
GtkWidget *dialog;
x49gp_ui_t *ui = x49gp->ui;
dialog = gtk_file_chooser_dialog_new(prompt, GTK_WINDOW(ui->window),
action,
GTK_STOCK_CANCEL,
GTK_RESPONSE_CANCEL,
GTK_STOCK_OPEN,
GTK_RESPONSE_ACCEPT,
NULL);
gtk_file_chooser_set_local_only(GTK_FILE_CHOOSER(dialog), TRUE);
gtk_file_chooser_set_select_multiple(GTK_FILE_CHOOSER(dialog), FALSE);
if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
*filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog));
} else {
*filename = NULL;
}
gtk_widget_destroy(dialog);
}
static gboolean
x49gp_ui_button_press(GtkWidget *widget, GdkEventButton *event,
gpointer user_data)
@ -1469,6 +1539,7 @@ x49gp_ui_button_press(GtkWidget *widget, GdkEventButton *event,
x49gp_ui_button_t *button = user_data;
const x49gp_ui_key_t *key = button->key;
x49gp_t *x49gp = button->x49gp;
x49gp_ui_t *ui = x49gp->ui;
#ifdef DEBUG_X49GP_UI
fprintf(stderr, "%s:%u: type %u, button %u\n", __FUNCTION__, __LINE__, event->type, event->button);
@ -1479,14 +1550,15 @@ x49gp_ui_button_press(GtkWidget *widget, GdkEventButton *event,
switch (event->button) {
case 1:
ui->buttons_down++;
if (button->down) return FALSE;
button->down = TRUE;
break;
case 3:
if (!button->down) {
gtk_button_pressed(GTK_BUTTON(button->button));
}
button->down = TRUE;
button->hold = TRUE;
if (button->down) return FALSE;
gtk_button_pressed(GTK_BUTTON(button->button));
button->down = TRUE;
break;
default:
return TRUE;
@ -1499,9 +1571,7 @@ x49gp_ui_button_press(GtkWidget *widget, GdkEventButton *event,
#endif
if (key->rowbit) {
x49gp->keybycol[key->column] |= key->rowbit;
x49gp->keybyrow[key->row] |= key->columnbit;
s3c2410_io_port_g_update(x49gp);
s3c2410_io_port_g_update(x49gp, key->column, key->row, key->columnbit, key->rowbit, 1);
} else {
s3c2410_io_port_f_set_bit(x49gp, key->eint, 1);
@ -1510,32 +1580,12 @@ x49gp_ui_button_press(GtkWidget *widget, GdkEventButton *event,
return FALSE;
}
static gboolean
x49gp_ui_button_release(GtkWidget *widget, GdkEventButton *event,
gpointer user_data)
static void
x49gp_release_single_button(x49gp_ui_button_t *button, x49gp_ui_button_t *cause)
{
x49gp_ui_button_t *button = user_data;
x49gp_t *x49gp = button->x49gp;
x49gp_ui_t *ui = x49gp->ui;
const x49gp_ui_key_t *key;
GtkButton *gtkbutton;
int i;
if (event->type != GDK_BUTTON_RELEASE)
return FALSE;
switch (event->button) {
case 1:
break;
default:
return TRUE;
}
for (i = 0; i < ui->nr_buttons; i++) {
button = &ui->buttons[i];
if (! button->down)
continue;
#ifdef DEBUG_X49GP_UI
printf("%s: button %u: col %u, row %u, eint %u\n", __FUNCTION__,
@ -1548,22 +1598,85 @@ x49gp_ui_button_release(GtkWidget *widget, GdkEventButton *event,
gtkbutton = GTK_BUTTON(button->button);
if (button != user_data)
if (button != cause)
gtkbutton->in_button = FALSE;
gtk_button_released(gtkbutton);
key = button->key;
if (key->rowbit) {
x49gp->keybycol[key->column] &= ~(key->rowbit);
x49gp->keybyrow[key->row] &= ~(key->columnbit);
s3c2410_io_port_g_update(x49gp);
s3c2410_io_port_g_update(x49gp, key->column, key->row, key->columnbit, key->rowbit, 0);
} else {
s3c2410_io_port_f_set_bit(x49gp, key->eint, 0);
}
}
static void
x49gp_release_all_buttons(x49gp_t *x49gp, x49gp_ui_button_t *cause)
{
x49gp_ui_button_t *button;
x49gp_ui_t *ui = x49gp->ui;
int i;
for (i = 0; i < ui->nr_buttons; i++) {
button = &ui->buttons[i];
if (! button->down)
continue;
x49gp_release_single_button(button, cause);
}
}
static gboolean
x49gp_ui_button_release(GtkWidget *widget, GdkEventButton *event,
gpointer user_data)
{
x49gp_ui_button_t *button = user_data;
x49gp_t *x49gp = button->x49gp;
x49gp_ui_t *ui = x49gp->ui;
if (event->type != GDK_BUTTON_RELEASE)
return FALSE;
switch (event->button) {
case 1:
break;
default:
return TRUE;
}
if (ui->buttons_down > 0)
ui->buttons_down--;
if (ui->buttons_down == 0) {
x49gp_release_all_buttons(x49gp, button);
} else {
x49gp_release_single_button(button, button);
}
return FALSE;
}
static gboolean
x49gp_ui_show_menu(GtkWidget *widget, GdkEventButton *event, gpointer user_data)
{
x49gp_t *x49gp = user_data;
x49gp_ui_t *ui = x49gp->ui;
gtk_widget_set_sensitive(ui->menu_unmount,
s3c2410_sdi_is_mounted(x49gp));
if (ui->menu_debug)
gtk_widget_set_sensitive(ui->menu_debug,
! gdbserver_isactive());
if (event->type == GDK_BUTTON_PRESS && event->button == 3) {
gtk_menu_popup(GTK_MENU(ui->menu), NULL, NULL, NULL, NULL,
event->button, event->time);
return TRUE;
}
return FALSE;
}
@ -1582,6 +1695,76 @@ x49gp_ui_button_leave(GtkWidget *widget, GdkEventCrossing *event,
return TRUE;
}
static gboolean
x49gp_ui_focus_lost(GtkWidget *widget, GdkEventFocus *event,
gpointer user_data)
{
x49gp_t *x49gp = user_data;
x49gp_ui_t *ui = x49gp->ui;
if (event->type != GDK_FOCUS_CHANGE)
return FALSE;
ui->buttons_down = 0;
x49gp_release_all_buttons(x49gp, NULL);
return FALSE;
}
static void
x49gp_ui_popup_at_widget(GtkMenu *menu, gint *x, gint *y, gboolean *push_in,
gpointer user_data)
{
GtkWidget *widget = GTK_WIDGET(user_data);
gdk_window_get_origin(widget->window, x, y);
*x += widget->allocation.x;
*y += widget->allocation.y;
}
static void
x49gp_ui_mount_sd_folder(GtkMenuItem *menuitem, gpointer user_data)
{
x49gp_t *x49gp = user_data;
char *filename;
x49gp_ui_choose_file(x49gp, "Choose SD folder ...",
GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER, &filename);
if (filename != NULL) s3c2410_sdi_mount(x49gp, filename);
}
static void
x49gp_ui_mount_sd_image(GtkMenuItem *menuitem, gpointer user_data)
{
x49gp_t *x49gp = user_data;
char *filename;
x49gp_ui_choose_file(x49gp, "Choose SD image ...",
GTK_FILE_CHOOSER_ACTION_OPEN, &filename);
if (filename != NULL) s3c2410_sdi_mount(x49gp, filename);
}
static void
x49gp_ui_debug(GtkMenuItem *menuitem, gpointer user_data)
{
x49gp_t *x49gp = user_data;
if(x49gp->debug_port != 0 && ! gdbserver_isactive()) {
gdbserver_start(x49gp->debug_port);
gdb_handlesig(x49gp->env, 0);
}
}
static void
x49gp_ui_calculator_reset(GtkMenuItem *menuitem, gpointer user_data)
{
x49gp_t *x49gp = user_data;
x49gp_modules_reset(x49gp, X49GP_RESET_POWER_ON);
cpu_reset(x49gp->env);
x49gp_set_idle(x49gp, 0);
}
static gboolean
x49gp_ui_key_event(GtkWidget *widget, GdkEventKey *event, gpointer user_data)
{
@ -1591,76 +1774,95 @@ x49gp_ui_key_event(GtkWidget *widget, GdkEventKey *event, gpointer user_data)
GdkEventButton bev;
gboolean save_in;
int index;
guint keyval;
#ifdef DEBUG_X49GP_UI
fprintf(stderr, "%s:%u: type %u, keyval %04x\n", __FUNCTION__, __LINE__, event->type, event->keyval);
#endif
switch (event->keyval) {
case GDK_A: case GDK_a: case GDK_F1: index = 0; break;
case GDK_B: case GDK_b: case GDK_F2: index = 1; break;
case GDK_C: case GDK_c: case GDK_F3: index = 2; break;
case GDK_D: case GDK_d: case GDK_F4: index = 3; break;
case GDK_E: case GDK_e: case GDK_F5: index = 4; break;
case GDK_F: case GDK_f: case GDK_F6: index = 5; break;
case GDK_G: case GDK_g: index = 6; break;
case GDK_H: case GDK_h: index = 7; break;
case GDK_I: case GDK_i: index = 8; break;
case GDK_J: case GDK_j: index = 9; break;
case GDK_K: case GDK_k: index = 10; break;
case GDK_L: case GDK_l: index = 11; break;
case GDK_Up: case GDK_KP_Up: index = 12; break;
case GDK_Left: case GDK_KP_Left: index = 13; break;
case GDK_Down: case GDK_KP_Down: index = 14; break;
case GDK_Right: case GDK_KP_Right: index = 15; break;
case GDK_M: case GDK_m: index = 16; break;
case GDK_N: case GDK_n: index = 17; break;
case GDK_O: case GDK_o:
case GDK_apostrophe: index = 18; break;
case GDK_P: case GDK_p: index = 19; break;
case GDK_BackSpace: case GDK_Delete:
case GDK_KP_Delete: index = 20; break;
case GDK_Q: case GDK_q: index = 21; break;
case GDK_R: case GDK_r: index = 22; break;
case GDK_S: case GDK_s: index = 23; break;
case GDK_T: case GDK_t: index = 24; break;
case GDK_U: case GDK_u: index = 25; break;
case GDK_V: case GDK_v: index = 26; break;
case GDK_W: case GDK_w: index = 27; break;
case GDK_X: case GDK_x: index = 28; break;
case GDK_Y: case GDK_y: index = 29; break;
case GDK_Z: case GDK_z:
case GDK_slash: case GDK_KP_Divide: index = 30; break;
case GDK_Tab: index = 31; break;
#ifndef __APPLE__
case GDK_Alt_L: case GDK_Alt_R:
case GDK_Meta_L: case GDK_Meta_R:
case GDK_Mode_switch: index = 31; break;
/* We want to know the keyval as interpreted without modifiers. */
/* However, there is one modifier we do care about: NumLock, */
/* which normally is represented by MOD2. */
if (! gdk_keymap_translate_keyboard_state(gdk_keymap_get_default(),
event->hardware_keycode,
event->state & GDK_MOD2_MASK,
event->group,
&keyval, NULL, NULL, NULL))
return FALSE;
#ifdef DEBUG_X49GP_UI
fprintf(stderr, "%s:%u: state %u, base keyval %04x\n", __FUNCTION__, __LINE__, event->state, keyval);
#endif
case GDK_7: case GDK_KP_7: index = 32; break;
case GDK_8: case GDK_KP_8: index = 33; break;
case GDK_9: case GDK_KP_9: index = 34; break;
case GDK_multiply: case GDK_backslash:
case GDK_KP_Multiply: index = 35; break;
case GDK_Shift_L: index = 36; break;
case GDK_4: case GDK_KP_4: index = 37; break;
case GDK_5: case GDK_KP_5: index = 38; break;
case GDK_6: case GDK_KP_6: index = 39; break;
case GDK_minus: case GDK_KP_Subtract: index = 40; break;
case GDK_Shift_R: case GDK_Control_L: index = 41; break;
case GDK_1: case GDK_KP_1: index = 42; break;
case GDK_2: case GDK_KP_2: index = 43; break;
case GDK_3: case GDK_KP_3: index = 44; break;
case GDK_plus: case GDK_equal:
case GDK_KP_Add: index = 45; break;
case GDK_Escape: index = 46; break;
case GDK_0: case GDK_KP_0: index = 47; break;
case GDK_period: case GDK_comma:
case GDK_KP_Decimal: index = 48; break;
case GDK_space: case GDK_KP_Space: index = 49; break;
case GDK_Return: case GDK_KP_Enter: index = 50; break;
case GDK_F12:
switch (keyval) {
case GDK_KEY_a: case GDK_KEY_F1: index = 0; break;
case GDK_KEY_b: case GDK_KEY_F2: index = 1; break;
case GDK_KEY_c: case GDK_KEY_F3: index = 2; break;
case GDK_KEY_d: case GDK_KEY_F4: index = 3; break;
case GDK_KEY_e: case GDK_KEY_F5: index = 4; break;
case GDK_KEY_f: case GDK_KEY_F6: index = 5; break;
case GDK_KEY_g: index = 6; break;
case GDK_KEY_h: index = 7; break;
case GDK_KEY_i: index = 8; break;
case GDK_KEY_j: index = 9; break;
case GDK_KEY_k: index = 10; break;
case GDK_KEY_l: index = 11; break;
case GDK_KEY_Up: case GDK_KEY_KP_Up: index = 12; break;
case GDK_KEY_Left: case GDK_KEY_KP_Left: index = 13; break;
case GDK_KEY_Down: case GDK_KEY_KP_Down: index = 14; break;
case GDK_KEY_Right: case GDK_KEY_KP_Right: index = 15; break;
case GDK_KEY_m: index = 16; break;
case GDK_KEY_n: index = 17; break;
case GDK_KEY_o: case GDK_KEY_apostrophe: index = 18; break;
case GDK_KEY_p: index = 19; break;
case GDK_KEY_BackSpace: case GDK_KEY_Delete:
case GDK_KEY_KP_Delete: index = 20; break;
case GDK_KEY_dead_circumflex: case GDK_KEY_asciicircum:
case GDK_KEY_q: case GDK_KEY_caret: index = 21; break;
case GDK_KEY_r: index = 22; break;
case GDK_KEY_s: index = 23; break;
case GDK_KEY_t: index = 24; break;
case GDK_KEY_u: index = 25; break;
case GDK_KEY_v: index = 26; break;
case GDK_KEY_w: index = 27; break;
case GDK_KEY_x: index = 28; break;
case GDK_KEY_y: index = 29; break;
case GDK_KEY_z:
case GDK_KEY_slash: case GDK_KEY_KP_Divide: index = 30; break;
case GDK_KEY_Tab: index = 31; break;
#ifndef __APPLE__
//case GDK_KEY_Alt_L: case GDK_KEY_Alt_R:
//case GDK_KEY_Meta_L: case GDK_KEY_Meta_R:
case GDK_KEY_Mode_switch: index = 31; break;
#endif
case GDK_KEY_7: case GDK_KEY_KP_7: index = 32; break;
case GDK_KEY_8: case GDK_KEY_KP_8: index = 33; break;
case GDK_KEY_9: case GDK_KEY_KP_9: index = 34; break;
case GDK_KEY_multiply: case GDK_KEY_KP_Multiply: index = 35; break;
case GDK_KEY_Shift_L: case GDK_KEY_Shift_R: index = 36; break;
case GDK_KEY_4: case GDK_KEY_KP_4: index = 37; break;
case GDK_KEY_5: case GDK_KEY_KP_5: index = 38; break;
case GDK_KEY_6: case GDK_KEY_KP_6: index = 39; break;
case GDK_KEY_minus: case GDK_KEY_KP_Subtract: index = 40; break;
case GDK_KEY_Control_L: case GDK_KEY_Control_R: index = 41; break;
case GDK_KEY_1: case GDK_KEY_KP_1: index = 42; break;
case GDK_KEY_2: case GDK_KEY_KP_2: index = 43; break;
case GDK_KEY_3: case GDK_KEY_KP_3: index = 44; break;
case GDK_KEY_plus: case GDK_KEY_KP_Add: index = 45; break;
case GDK_KEY_Escape: index = 46; break;
case GDK_KEY_0: case GDK_KEY_KP_0: index = 47; break;
case GDK_KEY_period: case GDK_KEY_comma:
case GDK_KEY_KP_Decimal: case GDK_KP_Separator: index = 48; break;
case GDK_KEY_space: case GDK_KEY_KP_Space: index = 49; break;
case GDK_KEY_Return: case GDK_KEY_KP_Enter: index = 50; break;
/* QUERTY compat: US English, UK English, International English */
case GDK_KEY_backslash: index = 35; break;
case GDK_KEY_equal: index = 45; break;
/* QUERTZ compat: German */
case GDK_KEY_ssharp: index = 30; break;
case GDK_KEY_numbersign: index = 35; break;
case GDK_KEY_F12:
switch (event->type) {
case GDK_KEY_PRESS:
x49gp_modules_reset(x49gp, X49GP_RESET_POWER_ON);
@ -1674,6 +1876,19 @@ x49gp_ui_key_event(GtkWidget *widget, GdkEventKey *event, gpointer user_data)
break;
}
return FALSE;
case GDK_KEY_Menu:
gtk_widget_set_sensitive(ui->menu_unmount,
s3c2410_sdi_is_mounted(x49gp));
if (ui->menu_debug)
gtk_widget_set_sensitive(ui->menu_debug,
! gdbserver_isactive());
gtk_menu_popup(GTK_MENU(ui->menu), NULL, NULL,
x49gp_ui_popup_at_widget, ui->lcd_canvas,
0, event->time);
return FALSE;
default:
return FALSE;
}
@ -2147,7 +2362,7 @@ x49gp_window_button_press(GtkWidget *widget, GdkEventButton *event,
}
static void
x49gp_ui_quit(GtkWidget *widget, GdkEvent *event, gpointer user_data)
x49gp_ui_quit(gpointer user_data, GtkWidget *widget, GdkEvent *event)
{
x49gp_t *x49gp = user_data;
@ -2211,23 +2426,37 @@ gui_load(x49gp_module_t *module, GKeyFile *keyfile)
x49gp_ui_t *ui = module->user_data;
x49gp_ui_button_t *button;
const x49gp_ui_key_t *key;
GtkWidget *screen_box;
GtkWidget *menu_mount_folder, *menu_mount_image, *menu_unmount;
GtkWidget *menu_debug, *menu_reset, *menu_quit;
GError *gerror = NULL;
GdkBitmap *shape;
char *typestr;
char *imagefile;
char *name;
int fd;
int i;
imagefile = x49gp_module_get_filename(module, keyfile, "image");
x49gp_module_get_string(module, keyfile, "name", "hp49g+", &name);
if (!strcmp(name, "hp49g+")) {
x49gp_module_get_string(module, keyfile, "type", "hp50g", &typestr);
if (!strcmp(typestr, "hp49g+")) {
ui->calculator = UI_CALCULATOR_HP49GP;
} else if (!strcmp(name, "hp50g")) {
} else if (!strcmp(typestr, "hp50g")) {
ui->calculator = UI_CALCULATOR_HP50G;
} else {
ui->calculator = 0;
fprintf(stderr, "Invalid calculator type, reverting to default\n");
ui->calculator = UI_CALCULATOR_HP50G;
}
x49gp_module_get_string(module, keyfile, "name",
ui->calculator == UI_CALCULATOR_HP49GP ?
"HP 49g+" : "HP 50g",
&(ui->name));
fd = x49gp_module_open_rodata(module,
ui->calculator == UI_CALCULATOR_HP49GP ?
"hp49g+.png" : "hp50g.png",
&imagefile);
if (fd < 0) return fd;
gdk_pixbuf_get_file_info(imagefile, &ui->width, &ui->height);
ui->lcd_width = 131 * 2;
@ -2241,6 +2470,7 @@ gui_load(x49gp_module_t *module, GKeyFile *keyfile)
ui->kb_y_offset = 301;
ui->bg_pixbuf = gdk_pixbuf_new_from_file(imagefile, &gerror);
close(fd);
ui->window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
@ -2250,8 +2480,8 @@ gui_load(x49gp_module_t *module, GKeyFile *keyfile)
gtk_widget_set(ui->window, "resizable", FALSE, NULL);
gtk_window_set_decorated(GTK_WINDOW(ui->window), FALSE);
gtk_widget_set_name(ui->window, name);
gtk_window_set_title(GTK_WINDOW(ui->window), name);
gtk_widget_set_name(ui->window, ui->name);
gtk_window_set_title(GTK_WINDOW(ui->window), ui->name);
// gtk_window_set_icon(GTK_WINDOW(ui->window), ui->bg_pixbuf);
@ -2325,7 +2555,13 @@ gui_load(x49gp_module_t *module, GKeyFile *keyfile)
ui->lcd_canvas = gtk_drawing_area_new();
gtk_drawing_area_size(GTK_DRAWING_AREA(ui->lcd_canvas),
ui->lcd_width, ui->lcd_height);
x49gp_ui_place_at(x49gp, GTK_FIXED(ui->fixed), ui->lcd_canvas,
screen_box = gtk_event_box_new();
gtk_event_box_set_visible_window(GTK_EVENT_BOX(screen_box),
TRUE);
gtk_event_box_set_above_child(GTK_EVENT_BOX(screen_box),
FALSE);
gtk_container_add(GTK_CONTAINER(screen_box), ui->lcd_canvas);
x49gp_ui_place_at(x49gp, GTK_FIXED(ui->fixed), screen_box,
ui->lcd_x_offset, ui->lcd_y_offset,
ui->lcd_width, ui->lcd_height);
@ -2396,6 +2632,49 @@ gui_load(x49gp_module_t *module, GKeyFile *keyfile)
GDK_LEAVE_NOTIFY_MASK);
}
ui->menu = gtk_menu_new();
menu_mount_folder = gtk_menu_item_new_with_label("Mount SD folder ...");
gtk_menu_shell_append(GTK_MENU_SHELL(ui->menu), menu_mount_folder);
g_signal_connect(G_OBJECT(menu_mount_folder), "activate",
G_CALLBACK(x49gp_ui_mount_sd_folder), x49gp);
menu_mount_image = gtk_menu_item_new_with_label("Mount SD image ...");
gtk_menu_shell_append(GTK_MENU_SHELL(ui->menu), menu_mount_image);
g_signal_connect(G_OBJECT(menu_mount_image), "activate",
G_CALLBACK(x49gp_ui_mount_sd_image), x49gp);
menu_unmount = gtk_menu_item_new_with_label("Unmount SD");
gtk_menu_shell_append(GTK_MENU_SHELL(ui->menu), menu_unmount);
g_signal_connect_swapped(G_OBJECT(menu_unmount), "activate",
G_CALLBACK(s3c2410_sdi_unmount), x49gp);
ui->menu_unmount = menu_unmount;
if (x49gp->debug_port != 0) {
gtk_menu_shell_append(GTK_MENU_SHELL(ui->menu),
gtk_separator_menu_item_new());
menu_debug = gtk_menu_item_new_with_label("Start debugger");
gtk_menu_shell_append(GTK_MENU_SHELL(ui->menu), menu_debug);
g_signal_connect(G_OBJECT(menu_debug), "activate",
G_CALLBACK(x49gp_ui_debug), x49gp);
ui->menu_debug = menu_debug;
} else
ui->menu_debug = NULL;
gtk_menu_shell_append(GTK_MENU_SHELL(ui->menu),
gtk_separator_menu_item_new());
menu_reset = gtk_menu_item_new_with_label("Reset");
gtk_menu_shell_append(GTK_MENU_SHELL(ui->menu), menu_reset);
g_signal_connect(G_OBJECT(menu_reset), "activate",
G_CALLBACK(x49gp_ui_calculator_reset), x49gp);
menu_quit = gtk_menu_item_new_with_label("Quit");
gtk_menu_shell_append(GTK_MENU_SHELL(ui->menu), menu_quit);
g_signal_connect_swapped(G_OBJECT(menu_quit), "activate",
G_CALLBACK(x49gp_ui_quit), x49gp);
gtk_widget_show_all(ui->menu);
g_signal_connect(G_OBJECT(screen_box), "button-press-event",
G_CALLBACK(x49gp_ui_show_menu), x49gp);
g_signal_connect(G_OBJECT(ui->background), "configure-event",
G_CALLBACK(x49gp_window_configure_event), x49gp);
@ -2404,11 +2683,14 @@ gui_load(x49gp_module_t *module, GKeyFile *keyfile)
g_signal_connect(G_OBJECT(ui->lcd_canvas), "configure-event",
G_CALLBACK(x49gp_lcd_configure_event), x49gp);
g_signal_connect(G_OBJECT(ui->window), "delete-event",
g_signal_connect_swapped(G_OBJECT(ui->window), "delete-event",
G_CALLBACK(x49gp_ui_quit), x49gp);
g_signal_connect(G_OBJECT(ui->window), "destroy",
g_signal_connect_swapped(G_OBJECT(ui->window), "destroy",
G_CALLBACK(x49gp_ui_quit), x49gp);
g_signal_connect(G_OBJECT(ui->window), "focus-out-event",
G_CALLBACK(x49gp_ui_focus_lost), x49gp);
g_signal_connect(G_OBJECT(ui->window), "key-press-event",
G_CALLBACK(x49gp_ui_key_event), x49gp);
g_signal_connect(G_OBJECT(ui->window), "key-release-event",
@ -2418,6 +2700,7 @@ gui_load(x49gp_module_t *module, GKeyFile *keyfile)
G_CALLBACK(x49gp_window_button_press), x49gp);
gtk_widget_add_events(ui->window,
GDK_FOCUS_CHANGE_MASK |
GDK_BUTTON_PRESS_MASK |
GDK_KEY_PRESS_MASK |
GDK_KEY_RELEASE_MASK);
@ -2429,6 +2712,13 @@ gui_load(x49gp_module_t *module, GKeyFile *keyfile)
static int
gui_save(x49gp_module_t *module, GKeyFile *keyfile)
{
x49gp_ui_t *ui = module->user_data;
x49gp_module_set_string(module, keyfile, "type",
ui->calculator == UI_CALCULATOR_HP49GP ?
"hp49g+" : "hp50g");
x49gp_module_set_string(module, keyfile, "name", ui->name);
return 0;
}

View file

@ -1 +1 @@
4950_215.bin
2MB_215f.bin

View file

@ -1,3 +0,0 @@
rm flash-50g flash-noboot
make flash-50g