2001-05-18: Updated to version 1.25

This commit is contained in:
Gwenhael Le Moine 2024-03-19 22:37:03 +01:00
parent 0f41d8fed0
commit 5f619b11ab
No known key found for this signature in database
GPG key ID: FDFE3669426707A7
61 changed files with 5547 additions and 2438 deletions

Binary file not shown.

View file

@ -1,5 +1,5 @@
CARDCOPY - A HP48 Port1 Import/Export Tool for Emu48
05/23/00 (c) by Christoph Gießelink, cgiess@swol.de
12/27/00 (c) by Christoph Gießelink, cgiess@swol.de
************
@ -8,13 +8,13 @@ CARDCOPY - A HP48 Port1 Import/Export Tool for Emu48
Emu48, when emulating a HP48, save the user, the port1 memory and other
information in one file (*.E48). But sometimes it's useful to import or to
export port1 data. CARDCOPY now allows you to import/export a 128KB card file
into/from the port1 memory of an Emu48 state file. The program can handle
HP48SX/GX state and 128KB card files (file size 256KB) as source or destination.
On all other file types you'll get an error. It's recommended to switch off the
emulated HP48 before importing port1 data into a state file. So you're sure that
the HP48 wasn't busy and, when you switch on the emulated calculator, the
changed card will be detected.
export port1 data. CARDCOPY now allows you to import/export 32KB or 128KB card
files into/from the port1 memory of an Emu48 state file. The program can handle
HP48SX/GX state and 32/128KB card files (file size 64/256KB) as source or
destination. On all other file types you'll get an error. It's recommended to
switch off the emulated HP48 before importing port1 data into a state file. So
you're sure that the HP48 wasn't busy and, when you switch on the emulated
calculator, the changed card will be detected.
Remember: Don't import data when port1 is merged! This will corrupt memory.
Second, when you import data, all files that are saved in port1 are purged.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 212 KiB

After

Width:  |  Height:  |  Size: 212 KiB

View file

@ -12,7 +12,7 @@ Global
Print ""
Print "A few improvements by Sebastien Carlier, the author of Emu48."
Print "Please visit the Emu48 Official Homepage :"
Print "http://www.geocities.com/CapeCanaveral/5948/index.html"
Print "http://www.epita.fr/~sebc/Emu48/index.html"
Print ""
Print "Thanks for using Emu48 !"
Print ""
@ -23,7 +23,7 @@ Global
Rom "ROM.48G"
Patch "BEEP.EXT"
Bitmap "cp_48g3.bmp"
Debug 1
Debug 0
End
Background
@ -536,7 +536,7 @@ End
Button 110
Type 1
Size 23 22
Offset 23 5
Offset 12 5
NoHold
OnUp
MenuItem 1
@ -545,7 +545,7 @@ End
Button 111
Type 1
Size 23 22
Offset 46 5
Offset 35 5
NoHold
OnUp
MenuItem 2
@ -554,7 +554,7 @@ End
Button 112
Type 1
Size 23 22
Offset 69 5
Offset 59 5
NoHold
OnUp
MenuItem 3
@ -563,7 +563,7 @@ End
Button 113
Type 1
Size 23 22
Offset 97 5
Offset 86 5
NoHold
OnUp
MenuItem 6
@ -572,7 +572,7 @@ End
Button 114
Type 1
Size 23 22
Offset 125 5
Offset 114 5
NoHold
OnUp
MenuItem 8
@ -581,7 +581,7 @@ End
Button 115
Type 1
Size 23 22
Offset 148 5
Offset 137 5
NoHold
OnUp
MenuItem 7
@ -590,7 +590,7 @@ End
Button 116
Type 1
Size 23 22
Offset 171 5
Offset 160 5
NoHold
OnUp
MenuItem 17
@ -599,25 +599,34 @@ End
Button 117
Type 1
Size 23 22
Offset 199 5
Offset 188 5
NoHold
OnUp
MenuItem 9
MenuItem 22
End
End
Button 118
Type 1
Size 23 22
Offset 222 5
Offset 216 5
NoHold
OnUp
MenuItem 10
MenuItem 9
End
End
Button 119
Type 1
Size 23 22
Offset 250 5
Offset 239 5
NoHold
OnUp
MenuItem 10
End
End
Button 120
Type 1
Size 23 22
Offset 267 5
NoHold
OnUp
MenuItem 11

Binary file not shown.

Before

Width:  |  Height:  |  Size: 212 KiB

After

Width:  |  Height:  |  Size: 212 KiB

View file

@ -14,8 +14,8 @@ Global
Model "S"
Rom "ROM.48S"
Patch "BEEP.EXT"
Debug 0
Bitmap "cp_48s3.bmp"
Debug 0
End
Background
@ -528,7 +528,7 @@ End
Button 110
Type 1
Size 23 22
Offset 23 5
Offset 12 5
NoHold
OnUp
MenuItem 1
@ -537,7 +537,7 @@ End
Button 111
Type 1
Size 23 22
Offset 46 5
Offset 35 5
NoHold
OnUp
MenuItem 2
@ -546,7 +546,7 @@ End
Button 112
Type 1
Size 23 22
Offset 69 5
Offset 59 5
NoHold
OnUp
MenuItem 3
@ -555,7 +555,7 @@ End
Button 113
Type 1
Size 23 22
Offset 97 5
Offset 86 5
NoHold
OnUp
MenuItem 6
@ -564,7 +564,7 @@ End
Button 114
Type 1
Size 23 22
Offset 125 5
Offset 114 5
NoHold
OnUp
MenuItem 8
@ -573,7 +573,7 @@ End
Button 115
Type 1
Size 23 22
Offset 148 5
Offset 137 5
NoHold
OnUp
MenuItem 7
@ -582,7 +582,7 @@ End
Button 116
Type 1
Size 23 22
Offset 171 5
Offset 160 5
NoHold
OnUp
MenuItem 17
@ -591,25 +591,34 @@ End
Button 117
Type 1
Size 23 22
Offset 199 5
Offset 188 5
NoHold
OnUp
MenuItem 9
MenuItem 22
End
End
Button 118
Type 1
Size 23 22
Offset 222 5
Offset 216 5
NoHold
OnUp
MenuItem 10
MenuItem 9
End
End
Button 119
Type 1
Size 23 22
Offset 250 5
Offset 239 5
NoHold
OnUp
MenuItem 10
End
End
Button 120
Type 1
Size 23 22
Offset 267 5
NoHold
OnUp
MenuItem 11

View file

@ -3,7 +3,7 @@ Debugger in Emu48/Tools/Debugger...
This is a short description of the internal assembly debugger of Emu48. The debugger is not perfect and/or complete. I provide it as it is. Please don't send me any suggestions or changes at the moment. If you have a better idea make it for yourself. Of course you're free to publish them or send me your changes.
The debugger was designed to help costumers inspecting assembler code objects, a part that cannot be handled satisfactorily by the JAZZ package. Thanks to Mika Heiskanen and all the others supporting this great program.
The debugger was designed to help customers inspecting assembler code objects, a part that cannot be handled satisfactorily by the JAZZ package. Thanks to Mika Heiskanen and all the others supporting this great program.
After starting the debugger the emulation will stop at the current PC position. The emulation will continue after closing the debugger window. Please remember that the clock now shows the wrong time.
@ -14,6 +14,10 @@ After starting the debugger the emulation will stop at the current PC position.
Continue calculator emulation under debugger control. The emulation will stop at a breakpoint. Please remember that the emulation speed is slower than without debugger control.
- Run to Cursor F6
Execute program until address at cursor position is reached. Code and memory breakpoints are still active and may stop execution before.
- Step Into F7
Execute one code instruction.
@ -62,29 +66,32 @@ So be careful using the F9 key.
- Break F11
Stop the emulation started with F5.
Stop the emulation at the current program counter position.
2.) Menu Breakpoints
- Set breakpoint F2
- Set Breakpoint F2
Toggle a code breakpoint at the cursor position in the code window.
- Edit breakpoints...
- Edit Breakpoints...
You get a sorted list of the current code and memory breakpoints. With "Add" you can add a new, with "Delete" you can delete an existing breakpoint. Addresses greater than #FFFFF are cutted after the fifths nibble. When adding a new breakpoint, you must select if this is a "Code", "Memory Access", "Memory Read" or "Memory Write" breakpoint.
You get a sorted list of the current code and memory breakpoints. When the breakpoint is checked it's enabled otherwise it's disabled. With "Add" you can add a new or enable an existing breakpoint, with "Delete" you can delete the selected ones. Addresses greater than #FFFFF are cut after the fifths nibble. When adding a new breakpoint, you must select if this is a "Code", "RPL", "Memory Access", "Memory Read" or "Memory Write" breakpoint.
- "Code" stop before opcode execution on this address
- "RPL" stop on the first opcode of the selected RPL address
- "Memory Access" stop before reading or writing to the selected address
- "Memory Read" stop before reading the selected address
- "Memory Write" stop before writing to the selected address
- Clear all breakpoints
With a left mouse button double click on a breakpoint you can toggle the check box inside.
- Clear All Breakpoints
Clear all breakpoints except the NOP3 ones.
- NOP3 code breakpoints
- NOP3 Code Breakpoints
What are NOP3 code breakpoints? As you know user programs are loaded somewhere in memory and can be moved after a garbage collection. So it's very difficult to break a user program at a hard set breakpoint with F2. To solve this problem the debugger will stop emulation at a NOP3 opcode. So you can easily add a NOP3 command into your sources to force a break condition. To enable this you have to check this item.
@ -120,25 +127,29 @@ CODE
GOVLNG =GETPTRLOOP
ENDCODE
- RPL breakpoints
- CODE Object Breakpoints
If this item is checked, the debugger stops program execution on every A=DAT0 A, D0=D0+ 5, PC=(A) sequence. This is the typical RPL exit sequence, so you're able to jump easily to the end of any RPL command.
If this item is checked, the debugger stops program execution at the first instruction of every DOCODE object which isn't located in ROM. For inspecting DOCODE objects in ROM use the static CODE breakpoints instead please.
- RPL Breakpoints
If this item is checked, the debugger stops program execution on every instruction called after a PC=(A) or PC=(C) opcode. This is normally the begin of a new RPL command. RPL breakpoints use a "-R" marker instead of the assembler "->" PC position marker.
3.) Menu Interrupts
- Step Over Interrupts
If this item is checked, interrupt handler code will be skipped. This option is useful when you don't want to debug the interrupt handler. But be careful, when you disable the interrupts all code until interrupt enable belong to the interrupt handler code and could't executed in single step any more. Code and memory breakpoints are still active.
If this item is checked, interrupt handler code will be skipped. This option is useful when you don't want to debug the interrupt handler. But be careful, when you disable the interrupts all code until interrupt enable belong to the interrupt handler code and couldn't executed in single step any more. Code and memory breakpoints are still active.
You can also use this option if you want to quit the interrupt handler. Just check this option, press F7 for "Step Into", and uncheck the option again. The debugger stopped behind the RTI instruction.
You can also use this option if you want to quit the interrupt handler. Just check this option, press F7 for "Step Into" for stopping the debugger behind the RTI instruction, and uncheck this option again.
4.) Menu Info
- Last Instructions...
This is a short viewer for the last 255 executed CPU addresses. The disassembled opcode maybe wrong, because only the CPU address of each command was saved and memory mapping may have changed meanwhile.
This is a short viewer for the last 255 executed CPU addresses. The disassembled opcode maybe wrong, because only the CPU address of each command was saved and memory mapping may have changed meanwhile. In the "Last Instructions" dialog you can copy selected lines to the clipboard or clear this list.
5.) Code window
@ -168,9 +179,9 @@ Set the PC to the cursor position. Be careful with this command, you change the
6.) Register window
Here you can see the actual contents of the CPU registers. The values are only updated after a single step execution.
Here you can see the actual contents of the CPU registers. The values are only updated at a program execution stop. All changed CPU registers are highlighted.
With the left mouse button you change the content of the register. On bit registers like CY and Mode the state changes immediately without any request.
With the left mouse button you change the content of the register. On bit registers, like CY and Mode, the state change immediately without any request.
7.) Memory window
@ -195,16 +206,20 @@ Sets the cursor to the actual position of the D0 register.
- Go to D1
Sets the cursor to the actual position of the D0 register.
Sets the cursor to the actual position of the D1 register.
- Go to Stack
Sets the cursor to the return address placed in the top level of the stack.
- Find... F
Calls the "Find" dialog box, allowing you to search for a data sequence in hexadecimal or ASCII mode. The search area is restricted to the mapped CPU address area, so it isn't possible to access hidden memory. When you close the "Find" dialog box, you will loose all saved strings in the data combo box.
8.) Stack window
The content of the hardware stack is viewed here.
The content of the hardware stack is viewed here. In "1:" is the current return address. A double click on an item shows the address content in the code window.
9.) MMU window
@ -215,17 +230,17 @@ This example
LC(5) #C0000 128KB size
CONFIG
LC(5) #98765 start address of modul
LC(5) #98765 start address of module
CONFIG
will config a 128KB modul at address #80000 and not at the given address. So the MMU viewer will show you address #80000.
will config a 128KB module at address #80000 and not at the given address. So the MMU viewer will show you address #80000.
10.) Miscellaneous window
The Miscellaneous window show you the internal state of the interrupt flag, the 1ms keyboard handler and the contents of the Bank Switcher latch. The Bank Switcher item is only enabled on a HP48GX and a HP49G calculator. Only these versions have a latch inside. You see the loaded value of the address lines A6-A0. You have to ignore the last bit (A0), because it isn't wired to the six bit latch.
The Miscellaneous window show you the internal state of the interrupt flag, the 1ms keyboard handler and the contents of the Bank Switcher latch. The Bank Switcher item is only enabled on calculators with a latch inside. You see the loaded value of the address lines A6-A0. You have to ignore the last bit (A0), because it isn't wired to the six bit latch.
You can change the values by pressing the left mouse button over the old content.
06/13/00 (c) by Christoph Gießelink, cgiess@swol.de
05/15/01 (c) by Christoph Gießelink, cgiess@swol.de

BIN
EMU48.EXE

Binary file not shown.

View file

@ -1,7 +1,8 @@
Emu48 - A freeware HP38/48/49 Emulator for Windows 9x, NT and 2000
Emu48 - A freeware HP38/39/40/48/49 Emulator
for Windows 9x, ME, NT and 2000
@ -10,12 +11,14 @@
****************
Emu48 is distributed in 1 archive:
- Emu48-1_20.zip All files and sources
- Emu48-1_25.zip All files and sources
To install Emu48, just unzip Emu48-1_20.zip into an empty directory. When you
To install Emu48, just unzip Emu48-1_25.zip into an empty directory. When you
first run Emu48, it will detect the directory in which you installed it, and
will write its configuration to a file named Emu48.ini in your Windows
directory.
directory. If you move the Emu48 directory to another place you have to change
the directory path inside the Emu48.ini file manually or have to delete the
Emu48.ini file.
You can also update your current version with the Unofficial Service Packs:
- E48BP2x.ZIP New EXE-File
@ -36,10 +39,12 @@ recompile the sources to run Emu48 with Windows NT on a DEC Alpha.
* YOU NEED A ROM IMAGE *
************************
Emu48 needs an image of the ROM of YOUR calculator to be able to run. Since the
ROM is copyrighted by HP, I won't give you mine, and you should not give yours
or make it freely available. To use the ROM software of a calculator, you must
be the owner of this calculator.
Emu48 needs an image of a calculator ROM to be able to run. Since fall 2000 the
emulator ROM's for the HP38, 39, 40, 48 and 49 are freely available on different
internet sites. Because there's no license for the distribution of the ROM
images, they aren't included in the Emu48 package. You can still use the classic
way extracting them from your own calculator. But in mostly all cases you have
to convert the ROM files into the Emu48 ROM format.
- HP38:
To upload the ROM of your HP38G, you will need a special aplet called "ROM
@ -52,6 +57,17 @@ To do that, start a Command Prompt while running Windows, and type:
Where <rom-file> is the path to your ROM image. This will create a file named
ROM.38G. This tool will also check its validity.
- HP39/40:
To upload the ROM of your HP39G/HP40G, you will need a special aplet called "ROM
UPLOAD", available at http://privat.swol.de/ChristophGiesselink/emu48.htm. Once
you've uploaded the ROM, you have to convert it using the Rom2emu utility.
To do that, start a Command Prompt while running Windows, and type:
Rom2emu <rom-file> ROM.39G
There's also a HP39G/HP40G beta ROM for emulators at
http://www.epita.fr/~avenar_j/hp/39.htm for download.
- HP48:
If you have already used another HP48 emulator, you can convert the ROM using
the Convert utility.
@ -68,17 +84,13 @@ still check the validity of the ROM.
If you have never used an HP48 emulator, and don't have a ROM dump, you can
either use Jean-Yves Avenard's ROMUPL.BIN or the ROMDump Wizard V1.x, which will
almost automatically get the ROM from your HP48. Don't use the ROMDump Wizard
versions V0.x any more please! After the download you may have to convert your
dump with the CONVERT utility into the Emu48 format.
almost automatically get the ROM from your HP48. After the download you may have
to convert your dump with the CONVERT utility into the Emu48 format.
You can find the latest version of the ROM dump programs on:
ROMUPL.BIN http://www.epita.fr/~avenar_j/hp/calcen.html
ROMDump Wizard http://privat.swol.de/ChristophGiesselink/index.htm
Once you have your ROM dump(s), SAVE THEM TO A FLOPPY DISK! It will save you a
lot of trouble if you were lose them.
- HP49:
There's no ROM download program available so far. But you can find a HP49G ROM
for emulators in the YorkeM emulator package or in the HP49G SDK on
@ -89,8 +101,9 @@ http://www.hpcalc.org in the HP49 section.
* HOW TO START *
****************
When Emu48 is installed and you have put the ROM image(s) in the Emu48
directory, you can start Emu48. You'll see a "Choose Your KML Script" box.
When Emu48 is installed and you have put the ROM image(s), which must be in the
Emu48 ROM format, into the Emu48 directory, you can start Emu48. You'll see a
"Choose Your KML Script" box.
KML Scripts in fact define the visual aspect of Emu48, the behavior of the
buttons, of the keyboard, ... It's a GREAT way to customize your copy of Emu48.
@ -99,11 +112,10 @@ Check that the path in the "Emu48 Directory" text area is correct. Modify it if
the directory in which you installed Emu48 is not the directory displayed. Click
the refresh button ("V") after modifying it to update the list box.
Choose a KML script in the list box. If you have put a G/GX ROM dump in Emu48's
directory, choose a script for G/GX. If you have put a S/SX ROM dump in Emu48's
directory, choose a script for S/SX.
Choose a KML script in the list box for your calculator ROM you put into Emu48's
directory.
Several scripts are included in the common archive:
Several HP48 scripts are included in the Emu48 archive:
* Emu48's Default Faceplate for HP48G/GX
* Emu48's Default Faceplate for HP48S/SX
These two are simple scripts, good for 800x600 display resolution.
@ -117,28 +129,33 @@ Several scripts are included in the common archive:
This one has been designed for small resolutions such as 640x480.
Note: some things in this script have to be fixed.
If you want other great scripts, visit Casey's Emu48 homepage:
If you want other great scripts, visit Casey's Emu48 homepage
http://www.gulftel.com/~pattersc/emu48/
or visit Eric Rechlin's great HP archive
http://www.hpcalc.org/
And if you are interested in writing new scripts, get the KML 2.0 documentation
from Christoph's page at http://privat.swol.de/ChristophGiesselink/emu48.htm
Once you have selected a script, press OK to start the emulator. While it's
running, you can use the View/Change KML Script... command to change the visual
aspect of Emu48.
Once you have selected a script, press OK to start the emulator. In most cases,
when Emu48 crash after pressing the OK button, you forgot to convert the ROM
image into the emulator format. While it's running, you can use the View/Change
KML Script... command to change the visual aspect of Emu48.
***************
* KML SCRIPTS *
***************
In some cases you have to fix Color 0 in your KML script file, because the
colors red and blue has been swapped in the "Lcd" section (bugfix in a previous
version). Don't use TRUELCD.KMI for emulating display contrast in your scripts.
It's not fully correct. The hardware contrast values are in the area from 0 to
31. But the ROMs bounds them to useful values. The HP48 S(X) ROM use only
display contrast values between 3 and 19 and the HP48 G(X) ROM values between 9
and 24.
Don't use TRUELCD.KMI for emulating display contrast in your scripts. It's not
fully correct. The hardware contrast values are in the area from 0 to 31. But
the ROMs bounds them to useful values. The HP48 S(X) ROM use only display
contrast values between 3 and 19 and the HP48 G(X) ROM values between 9 and 24.
Maybe you have to adjust the "Rom" filename in the "Global" section. This mostly
happen with the HP49G ROM name. Some KML files use the name ROM.E49, that's the
name of the emulator ROM file published by HP. But Emu48 state files for the
HP49G have the same file extension, so the use of ROM.49G is preferred now.
****************
@ -188,13 +205,16 @@ utility will allow you to create it.
The syntax is:
MkShared <filename> <size_in_kilobytes>
For example, you can create a 4MB RAM card name SHARED.BIN (in Emu48's
For example, you can create a 2MB RAM card name SHARED.BIN (in Emu48's
directory) with the following command:
MkShared SHARED.BIN 4096
MkShared SHARED.BIN 2048
Valid sizes are 32, 128, 256, 512, 1024, 2048 and 4096 KB. If you use RAM cards
greater than 128 KB in a HP48SX, you can only see the first 128 KB of the card.
Please remember, the firmware of all HP48GX versions has a bug when using a 4MB
RAM card. You always get the message "Warning: Invalid Card Data" at startup and
Port 33 is unaccessible. This is not a bug of the emulator!
When you have created this file, run Emu48, and use the Close menu item to close
the calculator state. Now select File/Settings. In the "Port 2" text area, type
@ -216,7 +236,7 @@ two calculators. This RAM card is used by both S/SX and G/GX types.
The HP49G save the operation system a reprogramable memory, a so called flash
memory. The flash memory is divided into two parts, into the Operating System
and into a User Data area. The User Data area is viewed as Port 2 in the HP49G.
Emu48 saves the Port 2 data in the ROM file (normally ROM.E49). As default
Emu48 saves the Port 2 data in the ROM file (normally ROM.49G). As default
setting the ROM file is writeable in the first instance of Emu48. When you open
another instance of a HP49G emulation the Port 2 area is READ ONLY, that mean
all changes in Port 2 are lost when you exit this instance. If you don't want to
@ -404,8 +424,8 @@ Other graphics and scripts are available at Casey's Emu48 Graphics Page:
* LEGAL STUFF *
***************
Emu48 - An HP38/48/49 Emulator
Copyright (C) 2000 Sebastien Carlier & Christoph Gießelink
Emu48 - An HP38/39/40/48/49 Emulator
Copyright (C) 2001 Sebastien Carlier & Christoph Gießelink
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

BIN
Emu48asc/EMU48ASC.BIN Normal file

Binary file not shown.

48
Emu48asc/EMU48ASC.SRC Normal file
View file

@ -0,0 +1,48 @@
%%HP: T(3)A(D)F(.);
C$ $
::
CK1NoBlame ( one argument, attribute errors correctly )
CK&DISPATCH1 ( one argument... )
THREE ( ...check if it's a string )
::
DUP ( duplicate string )
ELEVEN ( last character + 1 to pull out )
1_#1-SUB$ ( pull out string of first characters )
$ "%%HP:" ( test string )
ONE ( search from first position )
POS$ ( find position of test string )
DUP ( duplicate position )
#0=?SKIP ( if header doesn't exist, skip secondary )
::
#5+ ( skip "%%HP:" header )
LAST$ ( pull out the rest of the string on level three )
DUP ( duplicate string )
$ ";" ( substring to find )
ONE ( search from first position )
POS$ ( find position of substring )
2DUP ( duplicate string and position )
#1+ ( add one to bint...this is first char to take )
LAST$ ( pull out the rest of the string on level three )
UNROT ( 3 2 1 -> 1 3 2 )
1_#1-SUB$ ( take out the Kermit header at given position )
PTR 30477 ( set settings based on header [unsupported] )
;
DROP ( garbage...we don't need this )
KINVISLF ( translate, remove all CR's; we just need LF's )
DROP ( drop empty string )
palparse ( get object from string, returns true or false )
?SEMI ( if true skip to end of secondary... )
2DROP ( else drop two )
;
ZERO ( ...check if it's not a string [actually, anything] )
::
EDITDECOMP$ ( make into string )
KVISLF ( translations, add a CR to each LF for Windows/DOS )
$ "%%HP:" ( Kermit pre-header )
PTR 303AC ( retrieve current settings [unsupported] )
!append$ ( combine strings, use little memory )
$ ";\\r\\n" ( semicolon, CR, LF )
!append$SWAP ( combine strings, use little memory, swap )
!append$ ( combine strings, use little memory )
;
;

42
Emu48asc/EMU48ASC.TXT Normal file
View file

@ -0,0 +1,42 @@
ASCII to Binary and Binary to ASCII Translator
Emu48 can't import programs transferred via ASCII mode. This System
RPL program will take the string that Emu48 puts on the stack when the
program was originally transferred in ASCII mode and will convert it
to a binary. If the header exists the settings will set accordingly,
and if any comments exist it will remove them. If you are loading a
text file rather than a program, this will simply remove the carriage
returns so there is nothing but line feeds. If you give it a binary
program rather than a text file, it will convert it to a text file,
making it suitable for exporting from Emu48. Remember that Emu48 adds
a 13-byte HPHP48-W header to the beginning that must be removed when
exporting ASCII files.
Simple directions:
1. Load emu48asc.bin into Emu48 with the Edit-Load Object... command
2. STO it in a variable
3. Load the file you want to translate
4. Run this program with the VAR menu softkey
5. STO the translated program in a variable (if wanted) or export it
with the Edit-Save Object... command
This can also be used on a real HP48 if you prefer to transfer ASCII
files via Xmodem, which doesn't do translation. However, it will be
very slow.
Unfortunately, this program sometimes fails on directories. I'm not
entirely sure why it doesn't work (since it properly imports some
directories) and don't have a solution at present. For these pesky
directories, you'll have to use your real HP48.
The commented System RPL source code is in emu48asc.src. This uses
two unsupported entry points, PTR 30477 and PTR 303AC, but they appear
stable and have been tested to work in revisions D, E, M, P, and R.
Program created by Eric Rechlin <eric@hpcalc.org> based on posts to
comp.sys.hp48 by John H Meyers <jhmeyers@mum.edu>. I would also like
to thank Christoph Giesselink for optimizing my program, saving about
20 bytes, as well as for correcting a major bug. The attached HP49G
version of this program is unsupported, use it on your own risk.
Revision 1.4, see http://www.hpcalc.org for updates.

BIN
Emu48asc/EMU49ASC.BIN Normal file

Binary file not shown.

60
Emu48asc/EMU49ASC.SRC Normal file
View file

@ -0,0 +1,60 @@
Here are the MASD sources for the HP49G v1.19-4/5 version of
EMU48ASC
!NO CODE
!RPL
::
CK1NoBlame
CK&DISPATCH1
BINT3
::
DUP
BINT11
1_#1-SUB$
"%%HP:"
BINT1
POS$
DUP
#0=?SKIP
::
#5+
LAST$
DUP
";"
BINT1
POS$
2DUP
#1+
LAST$
UNROT
1_#1-SUB$
PTR 4649A
;
DROP
KINVISLF
DROP
palparse
?SEMI
2DROP
;
BINT0
::
EDITDECOMP$
KVISLF
"%%HP:"
PTR 463CF
!append$
";\0D\0A"
!append$SWAP
!append$
;
;
@
Please don't blame me if this program destroy your memory content. The
unsupported entry points are picked up from the beta ROM v1.19-4. These
entry points may change in future and very important, they have changed
in past! Use it on your own risk.
Christoph

BIN
MKE48.EXE Normal file

Binary file not shown.

57
MKE48.TXT Normal file
View file

@ -0,0 +1,57 @@
MKE48 - HP48 State File Template for Emu48
12/08/00 (c) by Christoph Gießelink, cgiess@swol.de
*********
* MKE48 *
*********
Emu48 can only generate a HP48SX with 32KB system or a HP48GX with 128KB system
RAM both with 128KB port1 RAM. It isn't for example possible to generate a HP48G
with 32KB system and no port1 RAM. Emulating a HP48G is only interesting for
test purpose, so this type isn't selectable in Emu48. MKE48 now create a Emu48
state file with the given memory capabilities with one restriction. The state
file has no control on the port2 file, this is part of Emu48. So if you want to
emulate a HP48 with no port2 memory you have to disable port2 in Emu48. Refer to
Emu48.txt, especially to the COMMAND LINE section please.
The syntax is: MKE48 <E48-File> <Model[S|G]> <Port0-Size> <Port1-Size>
where
- <E48-File> is the state file name to create
- <Model[S|G]> is the calculator model (S for S(X), G for G(X))
- <Port0-Size> is the size of system memory in KB
- <Port1-Size> is the size of port1 memory in KB
There's no parameter check, so you have to know what you do.
If you want to
- create a HP48G state file with the name HP48G.E48 then type
MKE48 HP48G.E48 G 32 0
- start the emulator with the state file HP48G.E48 and no port2 RAM then type
EMU48 HP48G.E48 ""
Of course I never start Emu48 from the command line, I usually add the command
line arguments to a Windows link. After starting the emulator you're asked for a
KML script that should be used with the state file.
***************
* LEGAL STUFF *
***************
MKE48 - HP48 State File Template for Emu48
Copyright (C) 2000 Christoph Gießelink
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 license with this program in the file
"COPYING". If not, write to the Free Software Foundation, Inc.,
59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.

Binary file not shown.

View file

@ -1,10 +1,12 @@
Known bugs and restrictions of Emu48 V1.20
Known bugs and restrictions of Emu48 V1.25
------------------------------------------
- the following I/O bits aren't emulated (incomplete)
DTEST (0x102) [VDIG LID TRIM]
DSPCTL (0x103) [LRT LRTD LRTC BIN]
LPD (0x108) [LB2 LB1 LB0 VLBI]
LPE (0x109) [ELBI EVLBI GRST RST]
CMODE (0x10A) Mode register
IOC (0x110) [ERBZ]
RCS (0x111) [RX RER RBZ]
TCS (0x112) [BRK TBZ TBF]
@ -30,16 +32,19 @@ Known bugs and restrictions of Emu48 V1.20
-> all programs that run on a real calculator will run as well,
programs with incorrect DA19 / BEN handling may run on the
emulator but will crash on a real calculator
- incomplete reset logic of the bank switcher FF, on real
calculators a reset happen after about 4s in deep sleep, in the
emulator this happens immediately
- no MP interrupt on card control circuit or timer restart
- no beeper support with OUT command -> all programs that aren't
use the "=makebeep" subroutine, like alarm wake up, have no sound
- beeper emulation, ATTN key doesn't work,
Windows 9x: plays only default sound event or standard system beep
- no infrared printer support
- problem with timer2 (8192Hz) emulation in Windows 2000, timer2
values may skip, so an emulated delay loop may take very very long
- memory window of debugger view some addresses in I/O register area
with invalid data
- the 'Offset' command in the 'Background' section of KML scripts
don't work, the offset is always zero
- Shell OS: clock isn't synchronized with real time
- HP49G: the flash memory is emulated now with some restrictions
- first implementation, at the moment the flash memory is more a
@ -52,4 +57,4 @@ Known bugs and restrictions of Emu48 V1.20
- quitting the emulator while programming the flash isn't allowed,
because the content of flash state machine isn't saved so far
07/10/00 (c) by Christoph Gießelink, cgiess@swol.de
05/15/01 (c) by Christoph Gießelink, cgiess@swol.de

View file

@ -1,31 +1,31 @@
Color 0 130 173 161
Color 1 128 166 159
Color 2 124 160 154
Color 3 119 155 148
Color 4 115 149 143
Color 5 110 143 137
Color 6 106 137 132
Color 8 102 132 126
Color 9 98 126 121
Color 10 93 120 115
Color 11 89 114 110
Color 12 83 109 104
Color 13 79 103 99
Color 14 74 97 93
Color 15 70 91 88
Color 16 65 86 82
Color 17 61 80 77
Color 18 57 74 71
Color 19 53 68 66
Color 20 48 63 60
Color 21 44 57 55
Color 22 39 51 49
Color 23 35 46 44
Color 24 31 41 38
Color 25 27 35 33
Color 26 22 29 27
Color 27 18 23 22
Color 28 13 18 16
Color 29 9 12 11
Color 30 4 6 5
Color 0 161 173 130
Color 1 159 166 128
Color 2 154 160 124
Color 3 148 155 119
Color 4 143 149 115
Color 5 137 143 110
Color 6 132 137 106
Color 8 126 132 102
Color 9 121 126 98
Color 10 115 120 93
Color 11 110 114 89
Color 12 104 109 83
Color 13 99 103 79
Color 14 93 97 74
Color 15 88 91 70
Color 16 82 86 65
Color 17 77 80 61
Color 18 71 74 57
Color 19 66 68 53
Color 20 60 63 48
Color 21 55 57 44
Color 22 49 51 39
Color 23 44 46 35
Color 24 38 41 31
Color 25 33 35 27
Color 26 27 29 22
Color 27 22 23 18
Color 28 13 16 18
Color 29 9 11 12
Color 30 4 5 6
Color 31 0 0 0

View file

@ -22,17 +22,18 @@
#include <windows.h>
#include <stdio.h>
#include <assert.h>
#include "types.h"
#define VERSION "1.0"
#define VERSION "2.0"
#define FT_ERR 0 // illegal format
#define FT_NEW 1 // empty file
#define FT_SXGX 2 // Emu48 HP48SX/GX state file
#define FT_PORT 3 // 128KB port file
#define PORT1SIZE (128*1024*2) // file size of 128KB file
#define _KB(n) (n*1024*2) // KB in state file
#define HP48SIG "Emu48 Document\xFE" // HP48 state file signature
UINT CheckType(char *lpszFileName)
{
BYTE pbyFileSignature[16];
@ -47,8 +48,8 @@ UINT CheckType(char *lpszFileName)
// check filesize
FileSizeLow = GetFileSize(hFile,&FileSizeHigh);
if (FileSizeHigh == 0 && FileSizeLow == PORT1SIZE)
nType = FT_PORT;
if (FileSizeHigh == 0 && (FileSizeLow == _KB(32) || FileSizeLow == _KB(128)))
nType = FileSizeLow; // return card size
// Read and Compare signature
ReadFile(hFile,pbyFileSignature,sizeof(pbyFileSignature),&FileSizeLow,NULL);
@ -59,14 +60,50 @@ UINT CheckType(char *lpszFileName)
return nType;
}
BOOL CopyData(HANDLE hFileSource,HANDLE hFileDest)
BOOL SeekData(HANDLE hFile,UINT *nPortSize)
{
BYTE byBuffer[16];
CHIPSET Chipset;
UINT i;
DWORD lBytes;
SetFilePointer(hFile,0,NULL,FILE_BEGIN);
// read and check signature
ReadFile(hFile,byBuffer,sizeof(byBuffer),&lBytes,NULL);
if (lBytes != sizeof(HP48SIG) || strcmp(byBuffer,HP48SIG) != 0) return TRUE;
// read KML file length
ReadFile(hFile,&i,sizeof(i),&lBytes,NULL);
if (lBytes != sizeof(i)) return TRUE;
// skip KML file name
SetFilePointer(hFile,i,NULL,FILE_CURRENT);
// read CHIPSET structure length
ReadFile(hFile,&i,sizeof(i),&lBytes,NULL);
if (lBytes != sizeof(i)) return TRUE;
// read CHIPSET structure
ReadFile(hFile,&Chipset,sizeof(Chipset),&lBytes,NULL);
if (lBytes != sizeof(Chipset)) return TRUE;
// skip port0
SetFilePointer(hFile,_KB(Chipset.Port0Size),NULL,FILE_CURRENT);
*nPortSize = _KB(Chipset.Port1Size); // expected filesize
return FALSE;
}
BOOL CopyData(HANDLE hFileSource,HANDLE hFileDest,UINT nSize)
{
BYTE byBuffer[16];
INT i;
DWORD lBytes;
assert(PORT1SIZE % sizeof(byBuffer) == 0);
for (i = PORT1SIZE / sizeof(byBuffer); i > 0; --i)
assert(nSize % sizeof(byBuffer) == 0);
for (i = nSize / sizeof(byBuffer); i > 0; --i)
{
ReadFile(hFileSource,byBuffer,sizeof(byBuffer),&lBytes,NULL);
if (lBytes != sizeof(byBuffer)) return TRUE;
@ -74,7 +111,6 @@ BOOL CopyData(HANDLE hFileSource,HANDLE hFileDest)
WriteFile(hFileDest,byBuffer,sizeof(byBuffer),&lBytes,NULL);
if (lBytes != sizeof(byBuffer)) return TRUE;
}
return FALSE;
}
@ -82,6 +118,7 @@ UINT main(int argc, char *argv[])
{
HANDLE hFileSource,hFileDest;
UINT nSourceType,nDestType;
UINT nError = 0;
printf("HP48 Port1 Import/Export Tool for Emu48 V" VERSION "\n");
if (argc != 3)
@ -92,7 +129,7 @@ UINT main(int argc, char *argv[])
// check source file type
nSourceType = CheckType(argv[1]);
if (nSourceType == FT_ERR)
if (nSourceType == FT_ERR || nSourceType == FT_NEW)
{
printf("Error: Illegal source file type\n");
return 2;
@ -113,18 +150,29 @@ UINT main(int argc, char *argv[])
hFileDest = CreateFile(argv[2],GENERIC_READ|GENERIC_WRITE,0,NULL,OPEN_ALWAYS,0,NULL);
if (hFileDest != INVALID_HANDLE_VALUE)
{
if (nSourceType == FT_SXGX) SetFilePointer(hFileSource,-PORT1SIZE,NULL,FILE_END);
if (nDestType == FT_SXGX) SetFilePointer(hFileDest ,-PORT1SIZE,NULL,FILE_END);
BOOL bFormatErr = FALSE;
CopyData(hFileSource,hFileDest);
puts("Copy successful.");
if (nSourceType == FT_SXGX) bFormatErr |= SeekData(hFileSource,&nSourceType);
if (nDestType == FT_SXGX) bFormatErr |= SeekData(hFileDest,&nDestType);
if (!bFormatErr && (nSourceType == nDestType || nDestType == FT_NEW))
{
assert(nSourceType > FT_SXGX);
CopyData(hFileSource,hFileDest,nSourceType);
puts("Copy successful.");
}
else
{
printf("Error: Non matching file size or format\n");
nError = 4;
}
CloseHandle(hFileDest);
}
else
{
printf("Error: Can't open destination file %s\n",argv[2]);
return 4;
nError = 5;
}
CloseHandle(hFileSource);
@ -132,8 +180,8 @@ UINT main(int argc, char *argv[])
else
{
printf("Error: Can't open source file %s\n",argv[1]);
return 5;
nError = 6;
}
return 0;
return nError;
}

103
sources/Cardcopy/TYPES.H Normal file
View file

@ -0,0 +1,103 @@
/*
* types.h
*
* This file is part of Emu48
*
* Copyright (C) 1995 Sebastien Carlier
*
*/
// HST bits
#define XM 1
#define SB 2
#define SR 4
#define MP 8
#define SWORD SHORT // signed 16 Bit variable
#define QWORD ULONGLONG // unsigned 64 Bit variable
#define CHIPSET Chipset_t
typedef struct
{
SWORD nPosX; // position of window
SWORD nPosY;
BYTE type; // calculator type
DWORD Port0Size; // real size of module in KB
DWORD Port1Size; // real size of module in KB
DWORD Port2Size; // real size of module in KB (HP49G only)
LPBYTE Port0;
LPBYTE Port1;
LPBYTE Port2;
DWORD pc;
DWORD d0;
DWORD d1;
DWORD rstkp;
DWORD rstk[8];
BYTE A[16];
BYTE B[16];
BYTE C[16];
BYTE D[16];
BYTE R0[16];
BYTE R1[16];
BYTE R2[16];
BYTE R3[16];
BYTE R4[16];
BYTE ST[4];
BYTE HST;
BYTE P;
WORD out;
WORD in;
BOOL SoftInt;
BOOL Shutdn;
BOOL mode_dec;
BOOL inte; // interrupt status flag (FALSE = int in service)
BOOL intk; // 1 ms keyboard scan flag (TRUE = enable)
BOOL intd; // keyboard interrupt pending (TRUE = int pending)
BOOL carry;
WORD crc;
WORD wPort2Crc; // fingerprint of port2
WORD wRomCrc; // fingerprint of ROM
#if defined _USRDLL // DLL version
QWORD cycles; // oscillator cycles
#else // EXE version
DWORD cycles; // oscillator cycles
DWORD cycles_reserved; // reserved for MSB of oscillator cycles
#endif
DWORD dwKdnCycles; // cpu cycles at start of 1ms key handler
UINT Bank_FF; // save state of HP48GX port2 or state of HP49G ROM FF
UINT FlashRomState; // WSM state of flash memory (unused)
BYTE cards_status;
BYTE IORam[64]; // I/O hardware register
UINT IOBase; // address of I/O modules page
BOOL IOCfig; // I/O module configuration flag
BYTE P0Base, BSBase, P1Base, P2Base; // address of modules first 2KB page
BYTE P0Size, BSSize, P1Size, P2Size; // mapped size of module in 2KB
BYTE P0End, BSEnd, P1End, P2End; // address of modules last 2KB page
BOOL P0Cfig, BSCfig, P1Cfig, P2Cfig; // module address configuration flag
BOOL P0Cfg2, BSCfg2, P1Cfg2, P2Cfg2; // module size configuration flag
BYTE t1;
DWORD t2;
BOOL bShutdnWake; // flag for wake up from SHUTDN mode
BYTE Keyboard_Row[9];
WORD IR15X;
UINT Keyboard_State; // not used
signed short loffset;
signed int width;
UINT boffset;
UINT lcounter;
UINT sync; // not used
BYTE contrast;
BOOL dispon;
DWORD start1;
DWORD start12;
DWORD end1;
DWORD start2, end2;
} Chipset_t;

View file

@ -1,3 +1,483 @@
Service Pack 25 for Emu48 Version 1.0
DDESERV.C
- replaced variable type _TCHAR with TCHAR
- added some UNREFERENCED_PARAMETER statements
DEBUGGER.C
- replaced variable type _TCHAR with TCHAR
- added UNREFERENCED_PARAMETER statement
- bugfix in function UpdateCodeWnd(), used uninitialized variables
at first call and optimized actual address searching
- changed function UpdateStackWnd(), save stack content also as
value for easier access
- changed function OnKeyF6(), optimized getting address of selected
item
- changed function OnKeyF8(), optimized GOSUB, GOSUBL, GOSBVL
decoding
- replaced functions OnNOP3Break(), OnRplBreak() and
OnInterruptsStepOverInt() with OnToggleMenuItem()
- changed function OnDblClick(), double click on stack window item
now shows the address content in the code window
- bugfix in function InfoIntr(), variable lIndex may be used without
having been initialized
DISASM.C
- replaced variable type _TCHAR with TCHAR
- bugfix in function disassemble(), the r=-r fs opcodes showed
always as r=r-1 fs opcodes
DISPLAY.C
- added UNICODE support in debug output parts
- used wrong black and white RGB definition, so default display
color was white on black background and not vice versa
- changed function UpdateContrast(), optimization
EMU48.C
- replaced variable type _TCHAR with TCHAR
- changed function CopyItemsToClipboard(), SetCommList(),
OnStackCopy() and OnStackPaste(), added some brackets
EMU48.H
- replaced variable type _TCHAR with TCHAR
- added MapData defines
- extern declaration of global variable and function
- removed declaration of Npack() and Nunpack()
EMU48.RC
- changed properties of IDC_DEBUG_STACK
- added Menuitem Debug "CODE Objects Breakpoints" in debugger menu
- changed version and copyright
ENGINE.C
- replaced variable type _TCHAR with TCHAR
- changed function Debugger(), added DOCODE breakpoint handling
EXTERNAL.C
- added ops.h in header definition
FILES.C
- replaced variable type _TCHAR with TCHAR
- added ops.h in header definition
- changed function PatchRom(), added typecast for GCC compiler
- bugfix in function PatchRom(), lines beginning with a remark were
sometimes decoded as a valid line
- bugfix in function MapPort2(), 32KB cards were rejected
I28F160.C
- changed table definitions fnWrState[] and fnRdState[], removed a
CONST statement
KML.C
- replaced variable type _TCHAR with TCHAR
- changed function ParseLines(), added some brackets
- changed prototypes of function GetStringParam(), GetIntegerParam()
and SkipLines(), fixed argument mismatch
- changed function RunLine(), added default case for GCC compiler
- changed function SkipWhite(), If() and InitKML(), removed unused
variables
- changed function KillKML(), optimizations
- changed function DrawAnnunciator(), optimizations
KML.H
- replaced variable type _TCHAR with TCHAR
MOPS.C
- added UNICODE support in debug output parts
- added ops.h in header definition
- moved MapData defines to EMU48.H
- made function MapData() public
- changed function Npeek(), Nread() and Nwrite(), added brackets for
better code understanding
OPCODES.C
- changed function o8Cd4() and o8Ed4(), added some spaces for better
code understanding
OPS.H
- changed function Npack() and Nunpack(), made them static
- changed function Nneg(), added some brackets
RESOURCE.H
- added definition
RPL.C
- added ops.h in header definition
- added missing HP39/40G entries in RAM entry table
SERIAL.C
- replaced variable type _TCHAR with TCHAR
- changed function UpdateUSRQ(), added return type
- changed function CommTransmit() and CommReceive(), derivate
interrupt generation from the state of the USRQ bit now
SETTINGS.C
- replaced variable type _TCHAR with TCHAR
- bugfix in registry macro WriteString(), used wrong data size in
UNICODE mode
- bugfix in function GetRegistryString(), returned wrong string
length and used wrong read buffer size in UNICODE mode
TIMER.C
- added ops.h in header definition
- changed function MAX(), had no definition of return value
- changed function RescheduleT2(), added some brackets
Service Pack 24 for Emu48 Version 1.0
DBGTOOL.BMP
- bitmap with debugger toolbar buttons
DEBUGGER.C
- added toolbar to debugger window
- changed function EnterBreakpoint(), DrawBreakpoint() and
EditBreakpoint(), added RPL breakpoint handling
- changed function OnToggleCheck(), changed method of item redraw
- changed function EditBreakpoint(), added multiple selection for
deleting breakpoints
DEBUGGER.H
- added new breakpoint define
DISASM.C
- bugfix in function rn_map(), handle NULL pointer pages now
- bugfix in function disasm_8(), fixed broken opcode 80810
mnemonic
EMU48.C
- changed function SetWindowTitle(), optimization
EMU48.DSP
- added library comctl32.lib
EMU48.RC
- added debugger toolbar
- added RPL breakpoint in "Enter breakpoint" dialog
- changed version and copyright
ENGINE.C
- changed function Debugger(), added RPL breakpoint handling
PCH.H
- added include commctrl.h
RESOURCE.H
- added definitions
Service Pack 23 for Emu48 Version 1.0
DDESERV.C
- replaced numbers with state machines defines
DEBUGGER.C
- new function DisableMenuKeys(), replace menu item disable in
function OnKeyF5() and OnKeyF9()
- bugfix in function StrToReg() and OnLButtonUp(), used ASCII
instead of a member function of TCHAR.H
- changed function OnLButtonUp(), skip automatically disabled
windows
- bugfix in function OnKeyF9(), "Run to Cursor" menu item wasn't
disabled
DISASM.C
- bugfix in function disasm_8(), illegal opcodes beginning with 8081
crashed emulator, illegal opcodes beginning with 818f were shown
as r=r+CON fs,n and r=r-CON fs,n opcodes, illegal opcodes
beginning with 819f were shown as rSRB.F opcodes
EMU48.C
- replaced numbers with state machines defines
- moved the ShowWindow() call in main program behind the state file
load to avoid viewing the window at the standard startup position
EMU48.RC
- changed version and copyright
ENGINE.C
- replaced numbers with state machines defines
- bugfix in function Debugger(), checked wrong data breakpoint
addresses in connection with the P,WP,XS,S,M fields
FILES.C
- bugfix in function SaveDocument(), when the emulator window is
minimized the wrong window position was saved in the Chipset
structure
IO.H
- changed LINECOUNT MSB definitions
KEYBOARD.C
- replaced numbers with state machines defines
KML.C
- replaced numbers with state machines defines
MOPS.C
- bugfix in function CpuReset(), BS-FF must be cleared as well
OPCODES.C
- bugfix in function o807(), added BS-FF reset handling
- removed function o_invalid()
OPCODES.H
- removed prototype of function o_invalid()
Service Pack 22 for Emu48 Version 1.0
DEBUGGER.C
- moved global variables to EMU48.C and ENGINE.C
- changed function ViewCodeWnd() and NotifyDebugger(), changed "->"
PC position marker to "-R" on RPL breakpoints
- bugfix in function DisableDebugger(), don't destroy handle before
windows closed
- changed function Debugger(), set signal for window and last
instruction buffer closed at end of WM_DESTROY message handler,
init additional variables
- added implementation of "Find" dialog box
- bugfix in function NewValue(), EnterAddr() and EnterBreakpoint(),
used ASCII instead of a member function of TCHAR.H
- changed function OnToggleCheck(), OnDrawBreakWnd(),
DrawBreakpoint() and EditBreakpoint(), now the list box element
use a link to the corresponding breakpoint element
- bugfix in function OnDrawBreakWnd(), sometimes the old focus
rectangle wasn't purged
- changed function EditBreakpoint(), checkbox can also be toggled
with the space key now
- bugfix in function OnEditBreakpoint(), redrawed code window always
at PC position and not at actual address
DEBUGGER.H
- moved extern declaration of global variables to EMU48.H
DISPLAY.C
- bugfix in function UpdateDisplayPointers(), UpdateMainDisplay(),
UpdateMenuDisplay(), WriteToMainDisplay(), WriteToMenuDisplay(),
calculated wrong display areas when LINECOUNT (0x128,0x129)
register was zero
EMU48.C
- replaced numbers with state machines defines
- added global variable from DEBUGGER.C
- changed function UpdateWindowStatus(), use groups for
enable/disable menu items now
- changed function SettingsProc(), use global variable if COM port
is open instead of calling CommConnect()
- bugfix in function OnPaint(), calculated wrong rectangle for
display area when LINECOUNT (0x128,0x129) register was zero
- bugfix in function OnDropFiles(), OnStackPaste(), OnObjectLoad(),
can't switch on if in debugger mode
- changed function WinMain(), added non modal "Find" dialog box in
main message handler
- bugfix in function WinMain(), fixed a resource leak
EMU48.DSP
- added library advapi32.lib
EMU48.H
- removed extern declaration of global variable and function
- removed COM port state defines
- added state machine defines
- extern declaration of global variables
- changed function prototype
EMU48.RC
- changed properties of IDC_BREAKEDIT_WND
- added "Find" dialog
- changed version
ENGINE.C
- replaced numbers with state machines defines
- made COM port open flag public
- added global variables from DEBUGGER.C
- changed function Debugger(), a RPL breakpoint is now set on the
destination address of a PC=(A) or a PC=(C) instruction and the
RPL breakpoint detection with a prior A=DAT0 A D0=D0+ 5 sequence
has been removed
- changed function CheckSerial(), use return value of CommOpen()
instead of calling CommConnect()
- changed function WaitForSleepState(), close debugger before going
into sleep state
- changed function SwitchToState(), changed detection of emulation
thread termination and debugger now can be active when changing
from Run to Sleep state
FILES.C
- changed function OpenDocument(), because of changed function
CpuReset() additional work for automatic restart on changed ROM
needed
IO.H
- added BITOFFSET definition
MOPS.C
- removed variable ir_ctrl_acc, was never used
- bugfix in function CpuReset(), changed some initial settings
- bugfix in function WriteIO(), force new COM port initialization
when the EIRU bit in the IRC (0x11A) register has changed
- bugfix in function WriteIO(), reading from the LINECOUNT
(0x128,0x129) register destroyed the settings for the
Chipset.lcounter variable
RESOURCE.H
- added some definitions
RPL.C
- changed function RPL_CreateTemp(), changed remarks
SERIAL.C
- removed function CommConnect(), not used any more
- changed function CommOpen(), changed function return type
- bugfix in function CommOpen(), receiver state variables weren't
resetted
- bugfix in function CommClose(), changed detection of thread
termination and fixed a resource leak
- bugfix in function CommTransmit(), receive buffer may be
overflowed when LPB (Loop Back) bit was set
SETTINGS.C
- prepared for registry support
Service Pack 21 for Emu48 Version 1.0
CHECKBOX.BMP
- bitmap with checked and unchecked box
DDESERV.C
- prepared for UNICODE support
DEBUGGER.C
- prepared for UNICODE support
- added implementation of "Run to Cursor"
- added HP39/40G stuff to function InitBsArea() and UpdateMiscWnd()
- added Enable/Disable of breakpoints in the Edit breakpoints dialog
- added breakpoint load/save file functions
- bugfix in function NewValue(), EnterAddr(), EnterBreakpoint(),
EditBreakpoint() and InfoIntr(), try to get a window handle at
begin of a dialog message handler cause illegal handles in some
cases
DEBUGGER.H
- extern declaration of global variable and functions
DISASM.C
- prepared for UNICODE support
- changed function rn_port2(), select internal or external port2
memory by the Chipset.Port2Size variable now
DISPLAY.C
- prepared for UNICODE support
EMU48.C
- prepared for UNICODE support
- added HP39/40G stuff to function UpdateWindowStatus(),
SettingsProc(), OnDropFiles() and Disasm()
- bugfix in function OnPaint(), redraw display and button area even
if emulation is suspended, redraw only requested bitmap area and
redraw display without updating bitmap with display data
- bugfix in function OnFileNew(), overwrite title only on new
document
EMU48.H
- prepared for UNICODE support
EMU48.ICO
- deleted unused device images
EMU48.RC
- changed properties of IDC_BREAKEDIT_WND
- added Menuitem Debug "Run to Cursor" in debugger menu
- changed version and copyright
ENGINE.C
- prepared for UNICODE support
- added part for debugger function "Run to Cursor"
EXTERNAL.C
- added HP39/40G stuff to the SFLAG53_56 definition
FILES.C
- prepared for UNICODE support
- added new document type for HP39/40G in several functions
- bugfix in function MapPort2(), in the first program instance in
not shared mode a read only port2 file couldn't be loaded
- bugfix in function ResetDocument(), delete MMU mappings as well
- bugfix in function OpenDocument(), ask for new KML script when
emulator state file and KML script file use different 'Model'
settings
- changed function OpenDocument() and SaveDocument(), added debugger
breakpoint data handling
IO.H
- added LINECOUNT definition
KML.C
- prepared for UNICODE support
- added "Class" keyword in Global section
- deleted function IsDigit(), replaced by function _istdigit()
- bugfix in function AddToLog(), fixed a memory leak
- new function MapKMLFile(), map KML file into memory
- new functions iSqrt(), AdjustPixel() and TransparentCircle(),
subroutines for new button type
- changed function DrawButton(), changed button type 5 (was same
implementation as type 0) to draw transparent circles
- changed function RefreshButtons(), redraw only buttons in
requested area
KML.H
- prepared for UNICODE support
- added TOK_CLASS definition
MOPS.C
- new function UpdateDisplay(), handle display update
- changed function MapP2(), select internal or external port2 memory
by the Chipset.Port2Size variable now
- added HP39/40G stuff to function MapROM(), RomSwitch(), Nread(),
Nwrite() and ReadIO()
- bugfix in function Nwrite(), update display with address content
- changed function ReadIO(), set RX bit in the RCS (0x111) register
for no character receive
- bugfix in function ReadIO(), wrong implementation of TBR register
(0x116,0x117), read return last written byte
- bugfix in function WriteIO(), clearing the SON bit in the IOC
(0x110) register clears also the IOC (0x110), RCS (0x111), TCS
(0x112), RBR (0x114,0x115) and TBR (0x116,0x117) register
- bugfix in function WriteIO(), writing to the RCS (0x111), TCS
(0x111) and TBR (0x116,0x117) register only works when the SON bit
in the IOC (0x110) register is set
OPCODES.C
- prepared for UNICODE support
- removed InfoMessage in SREQ? opcode
PCH.H
- added include tchar.h
RESOURCE.H
- added some definitions
- removed IDC_DISASM_MNEMONICS
RPL.C
- bugfix in function Metakernel(), check for port1 memory before
reading
SERIAL.C
- prepared for UNICODE support
- bugfix in function UpdateUSRQ(), USRQ bit in SRQ1 (0x118) register
only set on serial interrupt condition when UART enabled
SETTINGS.C
- prepared for UNICODE support
- changed function ReadSettings(), use variable content as default
TIMER.C
- bugfix in function StartTimers(), check for timer interrupts at
timer start
Service Pack 20 for Emu48 Version 1.0
DEBUGGER.C
@ -145,18 +625,18 @@ IO.H
MOPS.C
- removed conditional compiling with WSMSET
- bugfix in function RomSwitch(), mirror smaller ROMs than 2MB
- bugfix in function Npeek(), wrong content of SRQ2 register (0x119)
- bugfix in function Npeek(), wrong content of SRQ2 (0x119) register
- bugfix in function ReadIO(), wrong implementation of the SMP and
SWINT bit in the CARDCTL register (0x10E)
SWINT bit in the CARDCTL (0x10E) register
- bugfix in function ReadIO(), wrong implementation of the NINT2 and
NINT bit in the SRQ2 register (0x119)
NINT bit in the SRQ2 (0x119) register
- bugfix in function WriteIO(), wrong implementation of the SMP and
ECDT bit and removed some wrong stuff in the CARDCTL register
(0x10E)
ECDT bit and removed some wrong stuff in the CARDCTL (0x10E)
register
- bugfix in function WriteIO(), the DA19 bit in the LINECOUNT
register (0x129) is also available in the Clarke hardware
(0x129) register is also available in the Clarke hardware
- bugfix in function WriteIO(), the RUN bit in the TIMER2CTRL
register (0x12F) has an affection to the display annunciators
(0x12F) register has an affection to the display annunciators
OPCODES.C
- added io.h in header definition
@ -335,10 +815,10 @@ MOPS.C
when writing on slot2 enabled (GX only)
- changed function Nread() and Nwrite(), added Flash memory access
detection part
- bugfix in function ReadIO(), the CARDSTATUS register (0x10F)
- bugfix in function ReadIO(), the CARDSTATUS (0x10F) register
return zero when card detection is disabled
- bugfix in function WriteIO(), on a HP49 force new memory mapping
on changing the LED bit in the LCR register (0x11C)
on changing the LED bit in the LCR (0x11C) register
RESOURCE.H
- added several definitions
@ -446,15 +926,15 @@ MOPS.C
- added function CpuReset() to set cpu registers after reset
- changed function Npeek(), return data from I/O register area as
well now (for debugger support)
- bugfix in function Nread(), reading from the timer2 MSB register
(0x13F) updates the CRC register (0x104-0x107)
- bugfix in function Nread(), reading from the timer2 MSB (0x13F)
register updates the CRC (0x104-0x107) register
- bugfix in function ReadIO(), update the USRQ bit in the SRQ1
register (0x118) after reading the RBR register (0x114,0x115)
(0x118) register after reading the RBR (0x114,0x115) register
- bugfix in function ReadIO(), update the NINT2 and NINT bits in the
SRQ2 register (0x119)
SRQ2 (0x119) register
- bugfix in function WriteIO(), update the USRQ bit in the SRQ1
register (0x118) after writing the IOC register (0x110) or the
TBR register (0x116,0x117)
(0x118) register after writing the IOC (0x110) register or the
TBR (0x116,0x117) register
OPCODES.C
- added DWORD casting from w.cycles variable
@ -473,11 +953,11 @@ SERIAL.C
function CommOpen() and CommClose() to main program
- added function UpdateUSRQ(), implements USRQ bit handling
- bugfix in function CommTransmit(), added LPB bit emulation in the
TCS register (0x112) and USRQ bit emulation in the SRQ1 register
(0x118)
TCS (0x112) register and USRQ bit emulation in the SRQ1 (0x118)
register
- bugfix in function CommReceive(), only reject reading if com port
is closed and not whole operation and added USRQ bit emulation in
the SRQ1 register (0x118)
the SRQ1 (0x118) register
SERIAL.H
- renamed to IO.H
@ -490,7 +970,7 @@ TIMER.C
- replaced INT define with INTR (conflict with C variable type INT)
- renamed wShutdnWake variable to bShutdnWake
- bugfix in function CheckT1() and CheckT2(), added TSRQ bit
emulation in the SRQ1 register (0x118)
emulation in the SRQ1 (0x118) register
TYPES.H
- changed variable type of wPosX and wPosY, position data is signed
@ -575,8 +1055,8 @@ KML.C
MOPS.C
- added HP49 MMU parts
- bugfix in function ReadIO(), update the UCK bit in the BAU
register (0x10D)
- bugfix in function ReadIO(), update the UCK bit in the BAU (0x10D)
register
OPS.H
- moved inline function FASTPTR() from ENGINE.C to header file
@ -797,7 +1277,7 @@ KML.C
MOPS.C
- added new function IOBit()
- bugfix in function ReadIO(), update the KDN bit in the SRQ2
register (0x119) before reading
(0x119) register before reading
OPCODES.H
- bugfix in A=IN and C=IN command, update KDN bit in the SRQ
@ -879,13 +1359,13 @@ MOPS.C
display area and IO area couldn't be unconfigured
- removed functions Nread2(), Nwrite2(), Nread5() and Nwrite5()
- bugfix in function ReadIO(), several minor fixes in the LINECOUNT
register (0x128,0x129) emulation
(0x128,0x129) register emulation
- bugfix in function ReadIO(), the TIMER1CTRL and TIMER2CTRL
register (0x12E,0x12F) must be updated before reading
(0x12E,0x12F) register must be updated before reading
- bugfix in function WriteIO(), don't clear the XTRA bit in the
TIMER1CTRL register (0x12E) while setting
TIMER1CTRL (0x12E) register while setting
- bugfix in function WriteIO(), after setting new TIMER1CTRL and
TIMER2CTRL register (0x12E,0x12F) values the control bit
TIMER2CTRL (0x12E,0x12F) register values the control bit
condition must be checked
- bugfix in function WriteIO(), handle start/stop of the LINECOUNT
register when the DON bit in the DISPIO (0x100) register has
@ -1078,18 +1558,18 @@ KML.C
MOPS.C
- bugfix in function WriteIO(), the Chipset.start1 variable only
was updated when five nibbles at the DISPADDR register (0x120)
was updated when five nibbles at the DISPADDR (0x120) register
has been written
- bugfix in function WriteIO(), the Chipset.loffset variable only
was updated when three nibbles at the LINEOFFS register (0x125)
was updated when three nibbles at the LINEOFFS (0x125) register
has been written
- bugfix in function WriteIO(), the Chipset.lcounter variable only
was updated when the MSB of the LINECOUNT register (0x129) has
was updated when the MSB of the LINECOUNT (0x129) register has
been written
- bugfix in function WriteIO(), the Chipset.start2 variable only
was updated when five nibbles at the MENUADDR register (0x130)
was updated when five nibbles at the MENUADDR (0x130) register
has been written
- bugfix in function ReadIO(), the LINECOUNT register (0x128-0x129)
- bugfix in function ReadIO(), the LINECOUNT (0x128-0x129) register
is a down counter
OPCODES.H

BIN
sources/Emu48/CHECKBOX.BMP Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 250 B

BIN
sources/Emu48/DBGTOOL.BMP Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

View file

@ -13,7 +13,7 @@ HDDEDATA CALLBACK DdeCallback(UINT iType,UINT iFmt,HCONV hConv,
HSZ hsz1,HSZ hsz2,HDDEDATA hData,
DWORD dwData1,DWORD dwData2)
{
BYTE szBuffer[32];
TCHAR szBuffer[32];
HDDEDATA hReturn;
LPBYTE lpData,lpHeader;
DWORD dwAddress,dwSize,dwLoop,dwIndex;
@ -22,15 +22,15 @@ HDDEDATA CALLBACK DdeCallback(UINT iType,UINT iFmt,HCONV hConv,
switch (iType)
{
case XTYP_CONNECT:
DdeQueryString(idDdeInst,hsz2,szBuffer,sizeof(szBuffer),0);
if (0 != strcmp(szBuffer,szAppName))
DdeQueryString(idDdeInst,hsz2,szBuffer,ARRAYSIZEOF(szBuffer),0);
if (0 != lstrcmp(szBuffer,szAppName))
return (HDDEDATA) FALSE;
DdeQueryString(idDdeInst,hsz1,szBuffer,sizeof(szBuffer),0);
return (HDDEDATA) (0==strcmp(szBuffer,szTopic));
DdeQueryString(idDdeInst,hsz1,szBuffer,ARRAYSIZEOF(szBuffer),0);
return (HDDEDATA) (0==lstrcmp(szBuffer,szTopic));
case XTYP_POKE:
// illegal data format or not in running state
if (iFmt != uCF_HpObj || nState != 0)
if (iFmt != uCF_HpObj || nState != SM_RUN)
return (HDDEDATA) DDE_FNOTPROCESSED;
DdeAccessData(hData,&dwSize); // fetch data size
@ -55,7 +55,7 @@ HDDEDATA CALLBACK DdeCallback(UINT iType,UINT iFmt,HCONV hConv,
}
while (nState!=nNextState) Sleep(0);
_ASSERT(nState==3);
_ASSERT(nState==SM_SLEEP);
// fetch data and write to stack
DdeGetData(hData,(LPBYTE) &dwIndex,sizeof(DWORD),0L);
@ -65,9 +65,9 @@ HDDEDATA CALLBACK DdeCallback(UINT iType,UINT iFmt,HCONV hConv,
bSuccess = (WriteStack(lpData,dwSize) == S_ERR_NO);
LocalFree(lpData); // free memory
SwitchToState(0); // run state
SwitchToState(SM_RUN); // run state
while (nState!=nNextState) Sleep(0);
_ASSERT(nState==0);
_ASSERT(nState==SM_RUN);
if (bSuccess == FALSE)
return (HDDEDATA) DDE_FNOTPROCESSED;
@ -82,19 +82,19 @@ HDDEDATA CALLBACK DdeCallback(UINT iType,UINT iFmt,HCONV hConv,
case XTYP_REQUEST:
// illegal data format or not in running state
if (iFmt != uCF_HpObj || nState != 0)
if (iFmt != uCF_HpObj || nState != SM_RUN)
return NULL;
if (WaitForSleepState()) // wait for cpu SHUTDN then sleep state
return NULL;
while (nState!=nNextState) Sleep(0);
_ASSERT(nState==3);
_ASSERT(nState==SM_SLEEP);
dwAddress = RPL_Pick(1); // pick address of level1 object
if (dwAddress == 0)
{
SwitchToState(0); // run state
SwitchToState(SM_RUN); // run state
return NULL;
}
dwLoop = dwSize = (RPL_SkipOb(dwAddress) - dwAddress + 1) / 2;
@ -110,7 +110,7 @@ HDDEDATA CALLBACK DdeCallback(UINT iType,UINT iFmt,HCONV hConv,
// reserve memory
if ((lpData = (LPBYTE) LocalAlloc(LMEM_FIXED,dwSize)) == NULL)
{
SwitchToState(0); // run state
SwitchToState(SM_RUN); // run state
return NULL;
}
@ -128,11 +128,14 @@ HDDEDATA CALLBACK DdeCallback(UINT iType,UINT iFmt,HCONV hConv,
hReturn = DdeCreateDataHandle(idDdeInst,lpData,dwSize,0,hsz2,iFmt,0);
LocalFree(lpData);
SwitchToState(0); // run state
SwitchToState(SM_RUN); // run state
while (nState!=nNextState) Sleep(0);
_ASSERT(nState==0);
_ASSERT(nState==SM_RUN);
return hReturn;
}
return NULL;
UNREFERENCED_PARAMETER(hConv);
UNREFERENCED_PARAMETER(dwData1);
UNREFERENCED_PARAMETER(dwData2);
}

File diff suppressed because it is too large Load diff

View file

@ -8,10 +8,11 @@
*/
// breakpoint type definitions
#define BP_EXEC 1 // code breakpoint
#define BP_READ 2 // read memory breakpoint
#define BP_WRITE 4 // write memory breakpoint
#define BP_ACCESS (BP_READ|BP_WRITE) // read/write memory breakpoint
#define BP_EXEC 0x01 // code breakpoint
#define BP_READ 0x02 // read memory breakpoint
#define BP_WRITE 0x04 // write memory breakpoint
#define BP_RPL 0x08 // RPL breakpoint
#define BP_ACCESS (BP_READ|BP_WRITE) // read/write memory breakpoint
// debugger state definitions
#define DBG_RUN 0
@ -20,19 +21,9 @@
#define DBG_STEPOUT 3
// debugger.c
extern HWND hDlgDebug;
extern HANDLE hEventDebug;
extern BOOL bDbgEnable;
extern INT nDbgState;
extern BOOL bDbgNOP3;
extern BOOL bDbgRPL;
extern BOOL bDbgSkipInt;
extern DWORD dwDbgRstkp;
extern DWORD dwDbgRstk;
extern DWORD *pdwInstrArray;
extern WORD wInstrSize;
extern WORD wInstrWp;
extern WORD wInstrRp;
extern BOOL CheckBreakpoint(DWORD dwAddr, DWORD wRange, UINT nType);
extern VOID NotifyDebugger(BOOL bType);
extern VOID DisableDebugger(VOID);
extern LRESULT OnToolDebug(VOID);
extern VOID LoadBreakpointList(HANDLE hFile);
extern VOID SaveBreakpointList(HANDLE hFile);

File diff suppressed because it is too large Load diff

View file

@ -12,10 +12,15 @@
#include "io.h"
#include "kml.h"
// #define DEBUG_DISPLAY // switch for DISPLAY debug purpose
#define LCD1_ROW 144
#define LCD2_ROW 288
#define LCD3_ROW 576
// main display lines, handle zero lines exception
#define LINES(n) ((n == 0) ? 64 : (n+1))
UINT nBackgroundX = 0;
UINT nBackgroundY = 0;
UINT nBackgroundW = 0;
@ -31,8 +36,8 @@ static HBITMAP hMainBitmap;
static HBITMAP hOldLcdBitmap;
static HBITMAP hOldMainBitmap;
#define B 0x00FFFFFF
#define W 0x00000000
#define B 0x00000000
#define W 0x00FFFFFF
#define I 0xFFFFFFFF
static struct
{
@ -73,6 +78,7 @@ VOID UpdateContrast(BYTE byContrast)
Pattern[i] = (Pattern[i] << 8) | ((i&j) ? c : b);
}
}
return;
}
c = (c<<8) | c;
@ -84,6 +90,7 @@ VOID UpdateContrast(BYTE byContrast)
Pattern[1] = (b<<16)|c;
Pattern[2] = (c<<16)|b;
Pattern[3] = (c<<16)|c;
return;
}
c = (c<<16) | c;
@ -103,7 +110,7 @@ VOID SetLcdColor(UINT nId, UINT nRed, UINT nGreen, UINT nBlue)
return;
}
VOID CreateLcdBitmap()
VOID CreateLcdBitmap(VOID)
{
// create LCD bitmap
_ASSERT(nLcdDoubled == 1 || nLcdDoubled == 2 || nLcdDoubled == 4);
@ -120,7 +127,7 @@ VOID CreateLcdBitmap()
UpdateContrast(Chipset.contrast);
}
VOID DestroyLcdBitmap()
VOID DestroyLcdBitmap(VOID)
{
WORD i;
// clear background colors
@ -139,7 +146,7 @@ VOID DestroyLcdBitmap()
return;
}
BOOL CreateMainBitmap(LPSTR szFilename)
BOOL CreateMainBitmap(LPCTSTR szFilename)
{
HPALETTE hAssertPalette;
@ -161,7 +168,7 @@ BOOL CreateMainBitmap(LPSTR szFilename)
return TRUE;
}
VOID DestroyMainBitmap()
VOID DestroyMainBitmap(VOID)
{
if (hMainDC != NULL)
{
@ -182,11 +189,21 @@ VOID DestroyMainBitmap()
//*
//****************
VOID UpdateDisplayPointers()
VOID UpdateDisplayPointers(VOID)
{
UINT nLines = LINES(Chipset.lcounter);
#if defined DEBUG_DISPLAY
{
TCHAR buffer[256];
wsprintf(buffer,_T("%.5lx: Update Display Pointer\n"),Chipset.pc);
OutputDebugString(buffer);
}
#endif
// calculate display width
Chipset.width = (34 + Chipset.loffset + (Chipset.boffset / 4) * 2) & 0xFFFFFFFE;
Chipset.end1 = Chipset.start1 + (Chipset.lcounter + 1) * Chipset.width;
Chipset.end1 = Chipset.start1 + nLines * Chipset.width;
if (Chipset.end1 < Chipset.start1)
{
// calculate first address of main display
@ -198,36 +215,37 @@ VOID UpdateDisplayPointers()
{
Chipset.start12 = Chipset.start1;
}
Chipset.end2 = Chipset.start2 + (63 - Chipset.lcounter) * 34;
Chipset.end2 = Chipset.start2 + (64 - nLines) * 34;
}
static BYTE Buf[36];
static BOOL bScreenIsClean = FALSE;
VOID UpdateMainDisplay()
VOID UpdateMainDisplay(VOID)
{
UINT x, y;
INT nLines;
UINT x, y, nLines;
DWORD d = Chipset.start1;
BYTE *p = pbyLcd;
#if defined DEBUG_DISPLAY
{
TCHAR buffer[256];
wsprintf(buffer,_T("%.5lx: Update Main Display\n"),Chipset.pc);
OutputDebugString(buffer);
}
#endif
_ASSERT(nLcdDoubled == 1 || nLcdDoubled == 2 || nLcdDoubled == 4);
if (!Chipset.dispon)
{
nLines = 64;
if (!bScreenIsClean)
{
bScreenIsClean = TRUE;
ZeroMemory(pbyLcd, LCD1_ROW * nLcdDoubled * nLines * nLcdDoubled);
}
ZeroMemory(pbyLcd, LCD1_ROW * nLcdDoubled * nLines * nLcdDoubled);
}
else
{
nLines = Chipset.lcounter + 1;
bScreenIsClean = FALSE;
_ASSERT(nLcdDoubled == 1 || nLcdDoubled == 2 || nLcdDoubled == 4);
nLines = LINES(Chipset.lcounter); // main display lines
if (nLcdDoubled == 4)
{
for (y=0; y<=Chipset.lcounter; y++)
for (y = 0; y < nLines; ++y)
{
Npeek(Buf,d,36);
for (x=0; x<36; x++)
@ -246,7 +264,7 @@ VOID UpdateMainDisplay()
}
if (nLcdDoubled == 2)
{
for (y=0; y<=Chipset.lcounter; y++)
for (y = 0; y < nLines; ++y)
{
Npeek(Buf,d,36);
for (x=0; x<36; x++)
@ -261,7 +279,7 @@ VOID UpdateMainDisplay()
}
if (nLcdDoubled == 1)
{
for (y=0; y<=Chipset.lcounter; y++)
for (y = 0; y < nLines; ++y)
{
Npeek(Buf,d,36);
for (x=0; x<36; x++) *(((DWORD*)p)++)=Pattern[Buf[x]];
@ -271,30 +289,42 @@ VOID UpdateMainDisplay()
}
EnterCriticalSection(&csGDILock); // solving NT GDI problems
{
BitBlt(hWindowDC, nLcdX, nLcdY, 131*nLcdDoubled, nLines*nLcdDoubled, hLcdDC, Chipset.boffset*nLcdDoubled, 0, SRCCOPY);
BitBlt(hWindowDC, nLcdX, nLcdY, 131*nLcdDoubled, nLines*nLcdDoubled,
hLcdDC, Chipset.boffset*nLcdDoubled, 0, SRCCOPY);
GdiFlush();
}
LeaveCriticalSection(&csGDILock);
return;
}
VOID UpdateMenuDisplay()
VOID UpdateMenuDisplay(VOID)
{
UINT x, y;
UINT x, y, nLines;
BYTE *p;
DWORD d = Chipset.start2;
#if defined DEBUG_DISPLAY
{
TCHAR buffer[256];
wsprintf(buffer,_T("%.5lx: Update Menu Display\n"),Chipset.pc);
OutputDebugString(buffer);
}
#endif
nLines = LINES(Chipset.lcounter);
if (!Chipset.dispon) return;
if (Chipset.lcounter==0x3F) return; // menu disabled
if (nLines == 64) return; // menu disabled
_ASSERT(nLcdDoubled == 1 || nLcdDoubled == 2 || nLcdDoubled == 4);
// calculate offset once
p = pbyLcd + ((Chipset.lcounter+1)*nLcdDoubled*LCD1_ROW*nLcdDoubled);
// calculate bitmap offset
p = pbyLcd + (nLines*nLcdDoubled*LCD1_ROW*nLcdDoubled);
if (nLcdDoubled == 4)
{
for (y=Chipset.lcounter+1; y<64; y++)
for (y = nLines; y < 64; ++y)
{
Npeek(Buf,d,34); // 34 nibbles are viewed
for (x=0; x<36; x++)
for (x = 0; x < 36; ++x)
{
*(((DWORD*)p)++)=Pattern[Buf[x]&1];
*(((DWORD*)p)++)=Pattern[(Buf[x]>>1) & 1];
@ -310,10 +340,10 @@ VOID UpdateMenuDisplay()
}
if (nLcdDoubled == 2)
{
for (y=Chipset.lcounter+1; y<64; y++)
for (y = nLines; y < 64; ++y)
{
Npeek(Buf,d,34); // 34 nibbles are viewed
for (x=0; x<36; x++)
for (x = 0; x < 36; ++x)
{
*(((DWORD*)p)++)=Pattern[Buf[x]&3];
*(((DWORD*)p)++)=Pattern[Buf[x]>>2];
@ -325,18 +355,18 @@ VOID UpdateMenuDisplay()
}
if (nLcdDoubled == 1)
{
for (y=Chipset.lcounter+1; y<64; y++)
for (y = nLines; y < 64; ++y)
{
Npeek(Buf,d,34); // 34 nibbles are viewed
for (x=0; x<36; x++) *(((DWORD*)p)++)=Pattern[Buf[x]];
for (x = 0; x < 36; ++x) *(((DWORD*)p)++)=Pattern[Buf[x]];
d+=34;
}
}
EnterCriticalSection(&csGDILock); // solving NT GDI problems
{
BitBlt(hWindowDC, nLcdX, nLcdY+(Chipset.lcounter+1)*nLcdDoubled,
131*nLcdDoubled, (63-Chipset.lcounter)*nLcdDoubled,
hLcdDC, 0, (Chipset.lcounter+1)*nLcdDoubled, SRCCOPY);
BitBlt(hWindowDC, nLcdX, nLcdY+nLines*nLcdDoubled,
131*nLcdDoubled, (64-nLines)*nLcdDoubled,
hLcdDC, 0, nLines*nLcdDoubled, SRCCOPY);
GdiFlush();
}
LeaveCriticalSection(&csGDILock);
@ -345,11 +375,20 @@ VOID UpdateMenuDisplay()
VOID WriteToMainDisplay(LPBYTE a, DWORD d, UINT s)
{
INT x0, x;
INT y0, y;
DWORD *p;
INT x0, x;
INT y0, y;
DWORD *p;
INT lWidth = abs(Chipset.width); // display width
INT lWidth = abs(Chipset.width); // display width
UINT nLines = LINES(Chipset.lcounter); // main display lines
#if defined DEBUG_DISPLAY
{
TCHAR buffer[256];
wsprintf(buffer,_T("%.5lx: Write Main Display %x,%u\n"),Chipset.pc,d,s);
OutputDebugString(buffer);
}
#endif
d -= Chipset.start1; // nibble offset to DISPADDR (start of display)
d += 64 * lWidth; // make positive offset
@ -358,7 +397,7 @@ VOID WriteToMainDisplay(LPBYTE a, DWORD d, UINT s)
y = y0; x = x0; // load loop variables
// outside main display area
_ASSERT(y0 >= 0 && y0 <= (INT) Chipset.lcounter);
_ASSERT(y0 >= 0 && y0 < (INT) nLines);
// illegal zoom factor
_ASSERT(nLcdDoubled == 1 || nLcdDoubled == 2 || nLcdDoubled == 4);
@ -393,7 +432,7 @@ VOID WriteToMainDisplay(LPBYTE a, DWORD d, UINT s)
if ((x==lWidth)&&s) // end of display line
{
// end of main display area
if (y == (INT) Chipset.lcounter) break;
if (y == (INT) nLines - 1) break;
x = 0; // first coloumn
++y; // next row
@ -447,9 +486,19 @@ VOID WriteToMenuDisplay(LPBYTE a, DWORD d, UINT s)
UINT y0, y;
DWORD *p;
if (Chipset.lcounter==0x3F) return; // menu disabled
UINT nLines = LINES(Chipset.lcounter); // main display lines
#if defined DEBUG_DISPLAY
{
TCHAR buffer[256];
wsprintf(buffer,_T("%.5lx: Write Menu Display %x,%u\n"),Chipset.pc,d,s);
OutputDebugString(buffer);
}
#endif
if (nLines == 64) return; // menu disabled
d -= Chipset.start2;
y0 = y = (d / 34) + (Chipset.lcounter+1);
y0 = y = (d / 34) + nLines;
x0 = x = d % 34;
if (x0 > 32) return; // position out of viewed area
_ASSERT(nLcdDoubled == 1 || nLcdDoubled == 2 || nLcdDoubled == 4);
@ -566,14 +615,14 @@ VOID WriteToMenuDisplay(LPBYTE a, DWORD d, UINT s)
return;
}
VOID UpdateAnnunciators()
VOID UpdateAnnunciators(VOID)
{
BYTE c;
c = (BYTE)(Chipset.IORam[ANNCTRL] | (Chipset.IORam[ANNCTRL+1]<<4));
// switch annunciators off if timer stopped
if ((c & AON) == 0 || (Chipset.IORam[TIMER2_CTRL] & RUN) == 0)
c=0;
c = 0;
DrawAnnunciator(1,c&LA1);
DrawAnnunciator(2,c&LA2);
@ -584,7 +633,7 @@ VOID UpdateAnnunciators()
return;
}
VOID ResizeWindow()
VOID ResizeWindow(VOID)
{
RECT rectWindow;
RECT rectClient;

File diff suppressed because it is too large Load diff

View file

@ -52,7 +52,7 @@ BSC32=bscmake.exe
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386
# ADD LINK32 kernel32.lib user32.lib gdi32.lib comdlg32.lib shell32.lib winmm.lib /nologo /subsystem:windows /machine:I386
# ADD LINK32 kernel32.lib user32.lib gdi32.lib comdlg32.lib shell32.lib winmm.lib comctl32.lib advapi32.lib /nologo /subsystem:windows /machine:I386
!ELSEIF "$(CFG)" == "Emu48 - Win32 Debug"
@ -78,7 +78,7 @@ BSC32=bscmake.exe
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386
# ADD LINK32 kernel32.lib user32.lib gdi32.lib comdlg32.lib shell32.lib winmm.lib /nologo /subsystem:windows /debug /machine:I386
# ADD LINK32 kernel32.lib user32.lib gdi32.lib comdlg32.lib shell32.lib winmm.lib comctl32.lib advapi32.lib /nologo /subsystem:windows /debug /machine:I386
!ENDIF
@ -112,6 +112,13 @@ SOURCE=.\Emu48.c
# Begin Source File
SOURCE=.\Emu48.rc
!IF "$(CFG)" == "Emu48 - Win32 Release"
!ELSEIF "$(CFG)" == "Emu48 - Win32 Debug"
!ENDIF
# End Source File
# Begin Source File
@ -220,6 +227,10 @@ SOURCE=.\types.h
# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;cnt;rtf;gif;jpg;jpeg;jpe"
# Begin Source File
SOURCE=.\DBGTOOL.BMP
# End Source File
# Begin Source File
SOURCE=.\Emu48.ico
# End Source File
# End Group

View file

@ -8,6 +8,8 @@
*/
#include "types.h"
#define ARRAYSIZEOF(a) (sizeof(a) / sizeof(a[0]))
// cards status
#define PORT1_PRESENT ((cCurrentRomType=='S')?P1C:P2C)
#define PORT1_WRITE ((cCurrentRomType=='S')?P1W:P2W)
@ -17,16 +19,17 @@
#define BINARYHEADER48 "HPHP48-W"
#define BINARYHEADER49 "HPHP49-W"
#define SM_RUN 0 // states of cpu emulation thread
#define SM_INVALID 1
#define SM_RETURN 2
#define SM_SLEEP 3
#define S_ERR_NO 0 // stack errorcodes
#define S_ERR_BINARY 1
#define S_ERR_ASCII 2
#define NO_SERIAL "disabled" // port not open
#define PORT_CLOSE 0 // COM port status
#define PORT_WIRE 1
#define PORT_IR 2
#define HP_MNEMONICS FALSE // disassembler mnenomics mode
#define CLASS_MNEMONICS TRUE
@ -44,27 +47,32 @@
#define DISP_MENUE 0x04
#define DISP_ANNUN 0x08
// values for mapping area
enum MMUMAP { M_IO, M_ROM, M_RAM, M_P1, M_P2, M_BS };
// Emu48.c
extern HPALETTE hPalette;
extern HPALETTE hOldPalette;
extern HANDLE hEventShutdn;
extern LPSTR szAppName;
extern LPSTR szTopic;
extern LPSTR szTitle;
extern CRITICAL_SECTION csGDILock;
extern CRITICAL_SECTION csKeyLock;
extern CRITICAL_SECTION csIOLock;
extern CRITICAL_SECTION csT1Lock;
extern CRITICAL_SECTION csT2Lock;
extern CRITICAL_SECTION csRecvLock;
extern INT nArgc;
extern LPCTSTR *ppArgv;
extern LARGE_INTEGER lFreq;
extern LARGE_INTEGER lAppStart;
extern DWORD idDdeInst;
extern UINT uCF_HpObj;
extern HPALETTE hOldPalette;
extern HANDLE hEventShutdn;
extern LPTSTR szAppName;
extern LPTSTR szTopic;
extern LPTSTR szTitle;
extern CRITICAL_SECTION csGDILock;
extern CRITICAL_SECTION csKeyLock;
extern CRITICAL_SECTION csIOLock;
extern CRITICAL_SECTION csT1Lock;
extern CRITICAL_SECTION csT2Lock;
extern CRITICAL_SECTION csRecvLock;
extern INT nArgc;
extern LPCTSTR *ppArgv;
extern LARGE_INTEGER lFreq;
extern LARGE_INTEGER lAppStart;
extern DWORD idDdeInst;
extern UINT uCF_HpObj;
extern HINSTANCE hApp;
extern HWND hWnd;
extern HWND hDlgDebug;
extern HWND hDlgFind;
extern HDC hWindowDC;
extern BOOL bPort2IsShared;
extern BOOL bAutoSave;
@ -72,7 +80,7 @@ extern BOOL bAutoSaveOnExit;
extern BOOL bAlwaysDisplayLog;
extern HANDLE hThread;
extern DWORD lThreadId;
extern VOID SetWindowTitle(LPSTR szString);
extern VOID SetWindowTitle(LPTSTR szString);
extern VOID CopyItemsToClipboard(HWND hWnd);
extern VOID UpdateWindowStatus(VOID);
@ -93,55 +101,70 @@ extern UINT nLcdDoubled;
extern LPBYTE pbyLcd;
extern HDC hLcdDC;
extern HDC hMainDC;
extern VOID UpdateContrast(BYTE byContrast);
extern VOID SetLcdColor(UINT nId, UINT nRed, UINT nGreen, UINT nBlue);
extern VOID CreateLcdBitmap(VOID);
extern VOID DestroyLcdBitmap(VOID);
extern BOOL CreateMainBitmap(LPSTR szFilename);
extern VOID DestroyMainBitmap(VOID);
extern VOID UpdateDisplayPointers(VOID);
extern VOID UpdateMainDisplay(VOID);
extern VOID UpdateMenuDisplay(VOID);
extern VOID WriteToMainDisplay(LPBYTE a, DWORD d, UINT s);
extern VOID WriteToMenuDisplay(LPBYTE a, DWORD d, UINT s);
extern VOID UpdateAnnunciators(VOID);
extern VOID ResizeWindow(VOID);
extern VOID UpdateContrast(BYTE byContrast);
extern VOID SetLcdColor(UINT nId, UINT nRed, UINT nGreen, UINT nBlue);
extern VOID CreateLcdBitmap(VOID);
extern VOID DestroyLcdBitmap(VOID);
extern BOOL CreateMainBitmap(LPCTSTR szFilename);
extern VOID DestroyMainBitmap(VOID);
extern VOID UpdateDisplayPointers(VOID);
extern VOID UpdateMainDisplay(VOID);
extern VOID UpdateMenuDisplay(VOID);
extern VOID WriteToMainDisplay(LPBYTE a, DWORD d, UINT s);
extern VOID WriteToMenuDisplay(LPBYTE a, DWORD d, UINT s);
extern VOID UpdateAnnunciators(VOID);
extern VOID ResizeWindow(VOID);
// Engine.c
extern BOOL bInterrupt;
extern UINT nState;
extern UINT nNextState;
extern BOOL bRealSpeed;
extern BOOL bKeySlow;
extern CHIPSET Chipset;
extern char szSerialWire[16];
extern char szSerialIr[16];
extern DWORD dwSXCycles;
extern DWORD dwGXCycles;
extern VOID AdjKeySpeed(VOID);
extern VOID SetSpeed(BOOL bAdjust);
extern VOID UpdateKdnBit(VOID);
extern BOOL WaitForSleepState(VOID);
extern UINT SwitchToState(UINT nNewState);
extern UINT WorkerThread(LPVOID pParam);
extern DWORD Npack(BYTE *a, UINT s);
extern VOID Nunpack(BYTE *a, DWORD b, UINT s);
extern BOOL bInterrupt;
extern UINT nState;
extern UINT nNextState;
extern BOOL bRealSpeed;
extern BOOL bKeySlow;
extern BOOL bCommInit;
extern CHIPSET Chipset;
extern TCHAR szSerialWire[16];
extern TCHAR szSerialIr[16];
extern DWORD dwSXCycles;
extern DWORD dwGXCycles;
extern HANDLE hEventDebug;
extern BOOL bDbgEnable;
extern INT nDbgState;
extern BOOL bDbgNOP3;
extern BOOL bDbgCode;
extern BOOL bDbgRPL;
extern BOOL bDbgSkipInt;
extern DWORD dwDbgStopPC;
extern DWORD dwDbgRplPC;
extern DWORD dwDbgRstkp;
extern DWORD dwDbgRstk;
extern DWORD *pdwInstrArray;
extern WORD wInstrSize;
extern WORD wInstrWp;
extern WORD wInstrRp;
extern VOID AdjKeySpeed(VOID);
extern VOID SetSpeed(BOOL bAdjust);
extern VOID UpdateKdnBit(VOID);
extern BOOL WaitForSleepState(VOID);
extern UINT SwitchToState(UINT nNewState);
extern UINT WorkerThread(LPVOID pParam);
// Fetch.c
extern VOID EvalOpcode(LPBYTE I);
// Files.c
extern char szEmu48Directory[260];
extern char szCurrentDirectory[260];
extern char szCurrentKml[260];
extern char szBackupKml[260];
extern char szCurrentFilename[260];
extern char szBackupFilename[260];
extern char szBufferFilename[260];
extern char szPort2Filename[260];
extern TCHAR szEmu48Directory[260];
extern TCHAR szCurrentDirectory[260];
extern TCHAR szCurrentKml[260];
extern TCHAR szBackupKml[260];
extern TCHAR szCurrentFilename[260];
extern TCHAR szBackupFilename[260];
extern TCHAR szBufferFilename[260];
extern TCHAR szPort2Filename[260];
extern LPBYTE pbyRom;
extern DWORD dwRomSize;
extern char cCurrentRomType;
extern BYTE cCurrentRomType;
extern UINT nCurrentClass;
extern BOOL bRomWriteable;
extern LPBYTE pbyPort2;
extern BOOL bPort2Writeable;
@ -150,15 +173,15 @@ extern DWORD dwPort2Size;
extern DWORD dwPort2Mask;
extern BOOL bBackup;
extern WORD WriteStack(LPBYTE,DWORD);
extern BOOL MapRom(LPCSTR szFilename);
extern BOOL MapRom(LPCTSTR szFilename);
extern VOID UnmapRom(VOID);
extern BOOL MapPort2(LPCSTR szFilename);
extern BOOL MapPort2(LPCTSTR szFilename);
extern VOID UnmapPort2(VOID);
extern VOID UpdatePatches(BOOL bPatch);
extern BOOL PatchRom(LPCSTR szFilename);
extern BOOL PatchRom(LPCTSTR szFilename);
extern VOID ResetDocument(VOID);
extern BOOL NewDocument(VOID);
extern BOOL OpenDocument(LPCSTR szFilename);
extern BOOL OpenDocument(LPCTSTR szFilename);
extern BOOL SaveDocument(VOID);
extern BOOL SaveDocumentAs(LPCTSTR szFilename);
extern BOOL SaveBackup(VOID);
@ -168,9 +191,9 @@ extern BOOL GetOpenFilename(VOID);
extern BOOL GetSaveAsFilename(VOID);
extern BOOL GetLoadObjectFilename(VOID);
extern BOOL GetSaveObjectFilename(VOID);
extern BOOL LoadObject(LPCSTR szFilename);
extern BOOL SaveObject(LPCSTR szFilename);
extern HBITMAP LoadBitmapFile(LPCSTR szFilename);
extern BOOL LoadObject(LPCTSTR szFilename);
extern BOOL SaveObject(LPCTSTR szFilename);
extern HBITMAP LoadBitmapFile(LPCTSTR szFilename);
// Timer.c
extern VOID SetHP48Time(VOID);
@ -182,30 +205,30 @@ extern BYTE ReadT1(VOID);
extern VOID SetT1(BYTE byValue);
// MOps.c
extern BOOL ioc_acc;
extern BOOL ir_ctrl_acc;
extern BOOL bFlashRomArray;
extern BYTE disp;
extern LPBYTE RMap[256];
extern LPBYTE WMap[256];
extern VOID Map(BYTE a, BYTE b);
extern VOID RomSwitch(DWORD adr);
extern VOID Config(VOID);
extern VOID Uncnfg(VOID);
extern VOID Reset(VOID);
extern VOID C_Eq_Id(VOID);
extern VOID CpuReset(VOID);
extern BYTE GetLineCounter(VOID);
extern VOID Npeek(BYTE *a, DWORD d, UINT s);
extern VOID Nread(BYTE *a, DWORD d, UINT s);
extern VOID Nwrite(BYTE *a, DWORD d, UINT s);
extern BYTE Read2(DWORD d);
extern DWORD Read5(DWORD d);
extern VOID Write5(DWORD d, DWORD n);
extern VOID Write2(DWORD d, BYTE n);
extern VOID IOBit(DWORD d, BYTE b, BOOL s);
extern VOID ReadIO(BYTE *a, DWORD b, DWORD s);
extern VOID WriteIO(BYTE *a, DWORD b, DWORD s);
extern BOOL ioc_acc;
extern BOOL bFlashRomArray;
extern BYTE disp;
extern LPBYTE RMap[256];
extern LPBYTE WMap[256];
extern VOID Map(BYTE a, BYTE b);
extern VOID RomSwitch(DWORD adr);
extern VOID Config(VOID);
extern VOID Uncnfg(VOID);
extern VOID Reset(VOID);
extern VOID C_Eq_Id(VOID);
extern enum MMUMAP MapData(DWORD d);
extern VOID CpuReset(VOID);
extern BYTE GetLineCounter(VOID);
extern VOID Npeek(BYTE *a, DWORD d, UINT s);
extern VOID Nread(BYTE *a, DWORD d, UINT s);
extern VOID Nwrite(BYTE *a, DWORD d, UINT s);
extern BYTE Read2(DWORD d);
extern DWORD Read5(DWORD d);
extern VOID Write5(DWORD d, DWORD n);
extern VOID Write2(DWORD d, BYTE n);
extern VOID IOBit(DWORD d, BYTE b, BOOL s);
extern VOID ReadIO(BYTE *a, DWORD b, DWORD s);
extern VOID WriteIO(BYTE *a, DWORD b, DWORD s);
// Keyboard.c
extern VOID ScanKeyboard(BOOL bReset);
@ -228,28 +251,33 @@ extern HDDEDATA CALLBACK DdeCallback(UINT, UINT, HCONV, HSZ, HSZ, HDDEDATA, DWOR
// Disasm.c
extern BOOL disassembler_mode;
extern WORD disassembler_map;
extern DWORD disassemble (DWORD addr, LPSTR out, BOOL view);
extern DWORD disassemble (DWORD addr, LPTSTR out, BOOL view);
// Serial.c
extern WORD CommConnect(VOID);
extern VOID CommOpen(LPSTR strWirePort,LPSTR strIrPort);
extern BOOL CommOpen(LPTSTR strWirePort,LPTSTR strIrPort);
extern VOID CommClose(VOID);
extern VOID CommSetBaud(VOID);
extern VOID UpdateUSRQ(VOID);
extern BOOL UpdateUSRQ(VOID);
extern VOID CommTransmit(VOID);
extern VOID CommReceive(VOID);
#if defined _USRDLL // DLL version
// Emu48dll.c
extern BOOL DLLCreateWnd(LPCTSTR lpszFilename);
extern BOOL DLLDestroyWnd(VOID);
#endif
// Message Boxes
static __inline int InfoMessage(LPCSTR szMessage) {return MessageBox(hWnd, szMessage, szTitle, MB_APPLMODAL|MB_OK|MB_ICONINFORMATION|MB_SETFOREGROUND);}
static __inline int AbortMessage(LPCSTR szMessage) {return MessageBox(hWnd, szMessage, szTitle, MB_APPLMODAL|MB_OK|MB_ICONSTOP|MB_SETFOREGROUND);}
static __inline int YesNoMessage(LPCSTR szMessage) {return MessageBox(hWnd, szMessage, szTitle, MB_APPLMODAL|MB_YESNO|MB_ICONEXCLAMATION|MB_SETFOREGROUND);}
static __inline int YesNoCancelMessage(LPCSTR szMessage) {return MessageBox(hWnd, szMessage, szTitle, MB_APPLMODAL|MB_YESNOCANCEL|MB_ICONEXCLAMATION|MB_SETFOREGROUND);}
static __inline int InfoMessage(LPCTSTR szMessage) {return MessageBox(hWnd, szMessage, szTitle, MB_APPLMODAL|MB_OK|MB_ICONINFORMATION|MB_SETFOREGROUND);}
static __inline int AbortMessage(LPCTSTR szMessage) {return MessageBox(hWnd, szMessage, szTitle, MB_APPLMODAL|MB_OK|MB_ICONSTOP|MB_SETFOREGROUND);}
static __inline int YesNoMessage(LPCTSTR szMessage) {return MessageBox(hWnd, szMessage, szTitle, MB_APPLMODAL|MB_YESNO|MB_ICONEXCLAMATION|MB_SETFOREGROUND);}
static __inline int YesNoCancelMessage(LPCTSTR szMessage) {return MessageBox(hWnd, szMessage, szTitle, MB_APPLMODAL|MB_YESNOCANCEL|MB_ICONEXCLAMATION|MB_SETFOREGROUND);}
// Missing Win32 API calls
static __inline LPSTR DuplicateString(LPCSTR szString)
static __inline LPTSTR DuplicateString(LPCTSTR szString)
{
UINT uLength = strlen(szString) + 1;
LPSTR szDup = LocalAlloc(LMEM_FIXED,uLength);
CopyMemory(szDup,szString,uLength);
UINT uLength = lstrlen(szString) + 1;
LPTSTR szDup = LocalAlloc(LMEM_FIXED,uLength*sizeof(*(LPTSTR)0));
lstrcpy(szDup,szString);
return szDup;
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.9 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

View file

@ -29,10 +29,18 @@ LANGUAGE LANG_FRENCH, SUBLANG_FRENCH
#ifdef APSTUDIO_INVOKED
GUIDELINES DESIGNINFO DISCARDABLE
BEGIN
IDD_FIND, DIALOG
BEGIN
LEFTMARGIN, 6
RIGHTMARGIN, 190
TOPMARGIN, 7
BOTTOMMARGIN, 40
END
IDD_BREAKEDIT, DIALOG
BEGIN
LEFTMARGIN, 5
RIGHTMARGIN, 106
RIGHTMARGIN, 113
TOPMARGIN, 5
BOTTOMMARGIN, 95
END
@ -81,8 +89,8 @@ BEGIN
BEGIN
LEFTMARGIN, 5
RIGHTMARGIN, 274
TOPMARGIN, 2
BOTTOMMARGIN, 252
TOPMARGIN, 17
BOTTOMMARGIN, 264
END
IDD_NEWVALUE, DIALOG
@ -106,7 +114,7 @@ BEGIN
LEFTMARGIN, 8
RIGHTMARGIN, 149
TOPMARGIN, 7
BOTTOMMARGIN, 69
BOTTOMMARGIN, 79
END
IDD_INSTRUCTIONS, DIALOG
@ -125,28 +133,45 @@ END
// Dialog
//
IDD_BREAKEDIT DIALOG DISCARDABLE 0, 0, 111, 100
IDD_FIND DIALOGEX 0, 0, 197, 47
STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
EXSTYLE WS_EX_TOOLWINDOW
CAPTION "Find"
FONT 8, "MS Sans Serif"
BEGIN
LTEXT "Find &what:",IDC_STATIC,7,9,34,8
COMBOBOX IDC_FIND_DATA,46,7,88,41,CBS_DROPDOWN | CBS_AUTOHSCROLL |
WS_VSCROLL | WS_TABSTOP
CONTROL "Find &ASCII",IDC_FIND_ASCII,"Button",BS_AUTOCHECKBOX |
WS_TABSTOP,46,30,49,10
DEFPUSHBUTTON "Find Next",IDOK,140,7,50,14
PUSHBUTTON "Cancel",IDCANCEL,140,26,50,14
END
IDD_BREAKEDIT DIALOG DISCARDABLE 0, 0, 118, 100
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Edit breakpoints"
CAPTION "Edit Breakpoints"
FONT 8, "Courier New"
BEGIN
DEFPUSHBUTTON "OK",IDOK,78,81,28,14
DEFPUSHBUTTON "OK",IDCANCEL,83,81,30,14
LTEXT "Current breakpoints:",IDC_STATIC_BREAKPOINT,5,5,82,8
LISTBOX IDC_BREAKEDIT_WND,5,17,101,58,NOT LBS_NOTIFY | LBS_SORT |
LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_TABSTOP
PUSHBUTTON "&Add",IDC_BREAKEDIT_ADD,5,81,28,14
PUSHBUTTON "&Delete",IDC_BREAKEDIT_DELETE,41,81,28,14
LISTBOX IDC_BREAKEDIT_WND,5,17,108,58,LBS_SORT |
LBS_OWNERDRAWFIXED | LBS_HASSTRINGS |
LBS_NOINTEGRALHEIGHT | LBS_WANTKEYBOARDINPUT |
LBS_EXTENDEDSEL | WS_VSCROLL | WS_TABSTOP
PUSHBUTTON "&Add...",IDC_BREAKEDIT_ADD,5,81,30,14
PUSHBUTTON "&Delete",IDC_BREAKEDIT_DELETE,44,81,30,14
END
IDD_ABOUT DIALOGEX 0, 0, 261, 160
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "About Emu48"
FONT 8, "MS Sans Serif", 0, 0, 0x1
FONT 8, "MS Sans Serif"
BEGIN
ICON IDI_EMU48,IDC_STATIC,7,6,20,20,SS_REALSIZEIMAGE,
WS_EX_TRANSPARENT
LTEXT "",IDC_VERSION,29,6,151,8,NOT WS_GROUP
LTEXT "Copyright © 2000 Sébastien Carlier && Christoph Gießelink",
LTEXT "Copyright © 2001 Sébastien Carlier && Christoph Gießelink",
IDC_STATIC,29,18,181,8
DEFPUSHBUTTON "OK",IDOK,215,12,39,14
EDITTEXT IDC_LICENSE,7,33,247,112,ES_MULTILINE | ES_AUTOHSCROLL |
@ -156,7 +181,7 @@ END
IDD_SETTINGS DIALOGEX 0, 0, 167, 209
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Settings"
FONT 8, "MS Sans Serif", 0, 0, 0x1
FONT 8, "MS Sans Serif"
BEGIN
CONTROL "Authentic Calculator Speed",IDC_REALSPEED,"Button",
BS_AUTOCHECKBOX | WS_TABSTOP,13,13,104,10
@ -172,7 +197,7 @@ BEGIN
WS_GROUP | WS_TABSTOP,13,81,65,11
CONTROL "Class Mnemonics",IDC_DISASM_CLASS,"Button",
BS_AUTORADIOBUTTON,84,81,70,11
GROUPBOX "Disassembler",IDC_DISASM_MNEMONICS,7,70,153,28
GROUPBOX "Disassembler",IDC_STATIC,7,70,153,28
CONTROL "Port 1 is Plugged",IDC_PORT1EN,"Button",BS_AUTOCHECKBOX |
WS_TABSTOP,13,110,67,10
CONTROL "Port 1 is Writeable",IDC_PORT1WR,"Button",
@ -211,7 +236,7 @@ END
IDD_KMLLOG DIALOGEX 0, 0, 301, 167
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "KML Script Compilation Result"
FONT 8, "MS Sans Serif", 0, 0, 0x1
FONT 8, "MS Sans Serif"
BEGIN
DEFPUSHBUTTON "OK",IDOK,86,146,50,14
PUSHBUTTON "Cancel",IDCANCEL,164,146,50,14
@ -229,7 +254,7 @@ END
IDD_DISASM DIALOGEX 0, 0, 255, 165
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Disassembler"
FONT 8, "Courier New", 0, 0, 0x1
FONT 8, "Courier New"
BEGIN
LTEXT "Address (HEX):",IDC_ADDRESS,7,147,46,8
EDITTEXT IDC_DISASM_ADR,56,145,36,12,ES_AUTOHSCROLL
@ -252,95 +277,94 @@ BEGIN
WS_TABSTOP,WS_EX_NOPARENTNOTIFY
END
IDD_DEBUG DIALOGEX 0, 0, 279, 254
IDD_DEBUG DIALOGEX 0, 0, 279, 269
STYLE WS_MINIMIZEBOX | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
CAPTION "Debugger"
MENU IDR_DEBUG
FONT 8, "Courier New", 0, 0, 0x1
FONT 8, "Courier New"
BEGIN
LISTBOX IDC_DEBUG_CODE,11,12,165,122,NOT LBS_NOTIFY |
LISTBOX IDC_DEBUG_CODE,11,27,165,122,NOT LBS_NOTIFY |
LBS_OWNERDRAWFIXED | LBS_HASSTRINGS |
LBS_NOINTEGRALHEIGHT | LBS_WANTKEYBOARDINPUT |
WS_TABSTOP
GROUPBOX "Code",IDC_STATIC_CODE,5,2,177,138
LTEXT "A= 0000000000000000",IDC_REG_A,192,12,77,8
LTEXT "B= 0000000000000000",IDC_REG_B,192,19,77,8
LTEXT "C= 0000000000000000",IDC_REG_C,192,26,77,8
LTEXT "D= 0000000000000000",IDC_REG_D,192,33,77,8
LTEXT "R0=0000000000000000",IDC_REG_R0,192,43,77,8
LTEXT "R1=0000000000000000",IDC_REG_R1,192,50,77,8
LTEXT "R2=0000000000000000",IDC_REG_R2,192,57,77,8
LTEXT "R3=0000000000000000",IDC_REG_R3,192,64,77,8
LTEXT "R4=0000000000000000",IDC_REG_R4,192,71,77,8
LTEXT "D0=00000",IDC_REG_D0,192,82,33,8
LTEXT "D1=00000",IDC_REG_D1,236,82,33,8
LTEXT "P=0",IDC_REG_P,192,93,13,8
LTEXT "PC=00000",IDC_REG_PC,236,93,33,8
LTEXT "OUT=000",IDC_REG_OUT,192,104,29,8
LTEXT "IN=0000",IDC_REG_IN,240,104,29,8
LTEXT "ST=0000",IDC_REG_ST,192,115,29,8
LTEXT "CY=0",IDC_REG_CY,224,115,17,8
LTEXT "Mode=H",IDC_REG_MODE,244,115,25,8
LTEXT "MP=0",IDC_REG_MP,192,125,17,8
LTEXT "SR=0",IDC_REG_SR,212,125,17,8
LTEXT "SB=0",IDC_REG_SB,232,125,17,8
LTEXT "XM=0",IDC_REG_XM,252,125,17,8
GROUPBOX "Registers",IDC_STATIC_REGISTERS,187,2,87,138
CONTROL "",IDC_DEBUG_MEM,"Static",SS_WHITERECT | WS_GROUP,11,151,
GROUPBOX "Code",IDC_STATIC_CODE,5,17,177,138
LTEXT "A= 0000000000000000",IDC_REG_A,192,27,77,8
LTEXT "B= 0000000000000000",IDC_REG_B,192,34,77,8
LTEXT "C= 0000000000000000",IDC_REG_C,192,41,77,8
LTEXT "D= 0000000000000000",IDC_REG_D,192,48,77,8
LTEXT "R0=0000000000000000",IDC_REG_R0,192,58,77,8
LTEXT "R1=0000000000000000",IDC_REG_R1,192,65,77,8
LTEXT "R2=0000000000000000",IDC_REG_R2,192,72,77,8
LTEXT "R3=0000000000000000",IDC_REG_R3,192,79,77,8
LTEXT "R4=0000000000000000",IDC_REG_R4,192,86,77,8
LTEXT "D0=00000",IDC_REG_D0,192,97,33,8
LTEXT "D1=00000",IDC_REG_D1,236,97,33,8
LTEXT "P=0",IDC_REG_P,192,108,13,8
LTEXT "PC=00000",IDC_REG_PC,236,108,33,8
LTEXT "OUT=000",IDC_REG_OUT,192,119,29,8
LTEXT "IN=0000",IDC_REG_IN,240,119,29,8
LTEXT "ST=0000",IDC_REG_ST,192,130,29,8
LTEXT "CY=0",IDC_REG_CY,224,130,17,8
LTEXT "Mode=H",IDC_REG_MODE,244,130,25,8
LTEXT "MP=0",IDC_REG_MP,192,140,17,8
LTEXT "SR=0",IDC_REG_SR,212,140,17,8
LTEXT "SB=0",IDC_REG_SB,232,140,17,8
LTEXT "XM=0",IDC_REG_XM,252,140,17,8
GROUPBOX "Registers",IDC_STATIC_REGISTERS,187,17,87,138
CONTROL "",IDC_DEBUG_MEM,"Static",SS_WHITERECT | WS_GROUP,11,166,
165,52,WS_EX_CLIENTEDGE
LISTBOX IDC_DEBUG_MEM_ADDR,12,153,25,48,NOT LBS_NOTIFY |
LISTBOX IDC_DEBUG_MEM_ADDR,12,168,25,48,NOT LBS_NOTIFY |
LBS_NOINTEGRALHEIGHT | LBS_NOSEL | WS_DISABLED | NOT
WS_BORDER
LISTBOX IDC_DEBUG_MEM_COL0,40,153,11,48,LBS_NOINTEGRALHEIGHT |
LISTBOX IDC_DEBUG_MEM_COL0,40,168,11,48,LBS_NOINTEGRALHEIGHT |
LBS_WANTKEYBOARDINPUT | NOT WS_BORDER | WS_TABSTOP
LISTBOX IDC_DEBUG_MEM_COL1,52,153,11,48,LBS_NOINTEGRALHEIGHT |
LISTBOX IDC_DEBUG_MEM_COL1,52,168,11,48,LBS_NOINTEGRALHEIGHT |
LBS_WANTKEYBOARDINPUT | NOT WS_BORDER
LISTBOX IDC_DEBUG_MEM_COL2,64,153,11,48,LBS_NOINTEGRALHEIGHT |
LISTBOX IDC_DEBUG_MEM_COL2,64,168,11,48,LBS_NOINTEGRALHEIGHT |
LBS_WANTKEYBOARDINPUT | NOT WS_BORDER
LISTBOX IDC_DEBUG_MEM_COL3,76,153,11,48,LBS_NOINTEGRALHEIGHT |
LISTBOX IDC_DEBUG_MEM_COL3,76,168,11,48,LBS_NOINTEGRALHEIGHT |
LBS_WANTKEYBOARDINPUT | NOT WS_BORDER
LISTBOX IDC_DEBUG_MEM_COL4,88,153,11,48,LBS_NOINTEGRALHEIGHT |
LISTBOX IDC_DEBUG_MEM_COL4,88,168,11,48,LBS_NOINTEGRALHEIGHT |
LBS_WANTKEYBOARDINPUT | NOT WS_BORDER
LISTBOX IDC_DEBUG_MEM_COL5,100,153,11,48,LBS_NOINTEGRALHEIGHT |
LISTBOX IDC_DEBUG_MEM_COL5,100,168,11,48,LBS_NOINTEGRALHEIGHT |
LBS_WANTKEYBOARDINPUT | NOT WS_BORDER
LISTBOX IDC_DEBUG_MEM_COL6,112,153,11,48,LBS_NOINTEGRALHEIGHT |
LISTBOX IDC_DEBUG_MEM_COL6,112,168,11,48,LBS_NOINTEGRALHEIGHT |
LBS_WANTKEYBOARDINPUT | NOT WS_BORDER
LISTBOX IDC_DEBUG_MEM_COL7,124,153,11,48,LBS_NOINTEGRALHEIGHT |
LISTBOX IDC_DEBUG_MEM_COL7,124,168,11,48,LBS_NOINTEGRALHEIGHT |
LBS_WANTKEYBOARDINPUT | NOT WS_BORDER
LISTBOX IDC_DEBUG_MEM_TEXT,139,153,35,48,NOT LBS_NOTIFY |
LISTBOX IDC_DEBUG_MEM_TEXT,139,168,35,48,NOT LBS_NOTIFY |
LBS_NOINTEGRALHEIGHT | LBS_NOSEL | WS_DISABLED | NOT
WS_BORDER
GROUPBOX "Memory",IDC_STATIC_MEMORY,5,141,177,68
LISTBOX IDC_DEBUG_STACK,192,151,76,52,NOT LBS_NOTIFY |
LBS_NOINTEGRALHEIGHT | LBS_WANTKEYBOARDINPUT |
WS_VSCROLL | WS_TABSTOP
GROUPBOX "Stack",IDC_STATIC_STACK,187,141,87,68
LTEXT "Size Mask",IDC_STATIC,11,228,37,8
LTEXT "Address",IDC_STATIC,11,236,29,8
CTEXT "I/O",IDC_STATIC,55,220,21,8
CTEXT "NCE2",IDC_STATIC,80,220,21,8
CTEXT "CE1",IDC_STATIC,105,220,21,8
CTEXT "CE2",IDC_STATIC,130,220,21,8
CTEXT "NCE3",IDC_STATIC,155,220,21,8
CTEXT "-----",IDC_MMU_IO_S,55,228,21,8
CTEXT "-----",IDC_MMU_NCE2_S,80,228,21,8
CTEXT "-----",IDC_MMU_CE1_S,105,228,21,8
CTEXT "-----",IDC_MMU_CE2_S,130,228,21,8
CTEXT "-----",IDC_MMU_NCE3_S,155,228,21,8
CTEXT "-----",IDC_MMU_IO_A,55,236,21,8
CTEXT "-----",IDC_MMU_CE1_A,105,236,21,8
CTEXT "-----",IDC_MMU_CE2_A,130,236,21,8
CTEXT "-----",IDC_MMU_NCE2_A,80,236,21,8
CTEXT "-----",IDC_MMU_NCE3_A,155,236,21,8
GROUPBOX "MMU",IDC_STATIC_MMU,5,210,177,39
LTEXT "Interrupts =",IDC_STATIC,193,220,61,8
LTEXT "Keyboard Scan =",IDC_STATIC,193,228,61,8
LTEXT "Bank Switcher =",IDC_MISC_BS_TXT,193,236,61,8,
GROUPBOX "Memory",IDC_STATIC_MEMORY,5,156,177,68
LISTBOX IDC_DEBUG_STACK,192,166,76,52,LBS_NOINTEGRALHEIGHT |
LBS_WANTKEYBOARDINPUT | WS_VSCROLL | WS_TABSTOP
GROUPBOX "Stack",IDC_STATIC_STACK,187,156,87,68
LTEXT "Size Mask",IDC_STATIC,11,243,37,8
LTEXT "Address",IDC_STATIC,11,251,29,8
CTEXT "I/O",IDC_STATIC,55,235,21,8
CTEXT "NCE2",IDC_STATIC,80,235,21,8
CTEXT "CE1",IDC_STATIC,105,235,21,8
CTEXT "CE2",IDC_STATIC,130,235,21,8
CTEXT "NCE3",IDC_STATIC,155,235,21,8
CTEXT "-----",IDC_MMU_IO_S,55,243,21,8
CTEXT "-----",IDC_MMU_NCE2_S,80,243,21,8
CTEXT "-----",IDC_MMU_CE1_S,105,243,21,8
CTEXT "-----",IDC_MMU_CE2_S,130,243,21,8
CTEXT "-----",IDC_MMU_NCE3_S,155,243,21,8
CTEXT "-----",IDC_MMU_IO_A,55,251,21,8
CTEXT "-----",IDC_MMU_CE1_A,105,251,21,8
CTEXT "-----",IDC_MMU_CE2_A,130,251,21,8
CTEXT "-----",IDC_MMU_NCE2_A,80,251,21,8
CTEXT "-----",IDC_MMU_NCE3_A,155,251,21,8
GROUPBOX "MMU",IDC_STATIC_MMU,5,225,177,39
LTEXT "Interrupts =",IDC_STATIC,193,235,61,8
LTEXT "Keyboard Scan =",IDC_STATIC,193,243,61,8
LTEXT "Bank Switcher =",IDC_MISC_BS_TXT,193,251,61,8,
WS_DISABLED
LTEXT "",IDC_MISC_INT,256,220,13,8
LTEXT "",IDC_MISC_KEY,256,228,13,8
LTEXT "00",IDC_MISC_BS,256,236,13,8,WS_DISABLED
GROUPBOX "Miscellaneous",IDC_STATIC_MISC,187,210,87,39
LTEXT "",IDC_MISC_INT,256,235,13,8
LTEXT "",IDC_MISC_KEY,256,243,13,8
LTEXT "00",IDC_MISC_BS,256,251,13,8,WS_DISABLED
GROUPBOX "Miscellaneous",IDC_STATIC_MISC,187,225,87,39
END
IDD_NEWVALUE DIALOG DISCARDABLE 0, 0, 175, 50
@ -356,7 +380,7 @@ END
IDD_ENTERADR DIALOG DISCARDABLE 0, 0, 156, 50
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Enter address"
CAPTION "Enter Address"
FONT 8, "MS Sans Serif"
BEGIN
LTEXT "Enter address (hexdezimal):",IDC_STATIC,8,9,90,8
@ -365,29 +389,30 @@ BEGIN
PUSHBUTTON "Cancel",IDCANCEL,92,29,50,14
END
IDD_ENTERBREAK DIALOG DISCARDABLE 0, 0, 156, 76
IDD_ENTERBREAK DIALOG DISCARDABLE 0, 0, 156, 86
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Enter breakpoint"
CAPTION "Enter Breakpoint"
FONT 8, "MS Sans Serif"
BEGIN
LTEXT "Enter breakpoint (hexdezimal):",IDC_STATIC,8,9,96,8
EDITTEXT IDC_ENTERADR,110,7,39,12,ES_AUTOHSCROLL
CONTROL "&Code",IDC_BPCODE,"Button",BS_AUTORADIOBUTTON |
WS_GROUP | WS_TABSTOP,17,24,33,10
CONTROL "R&PL",IDC_BPRPL,"Button",BS_AUTORADIOBUTTON,17,50,30,10
CONTROL "Memory &Access",IDC_BPACCESS,"Button",
BS_AUTORADIOBUTTON,79,24,63,10
CONTROL "Memory &Read",IDC_BPREAD,"Button",BS_AUTORADIOBUTTON,17,
38,60,10
CONTROL "Memory &Read",IDC_BPREAD,"Button",BS_AUTORADIOBUTTON,79,
37,60,10
CONTROL "Memory &Write",IDC_BPWRITE,"Button",BS_AUTORADIOBUTTON,
79,38,59,10
DEFPUSHBUTTON "OK",IDOK,14,55,50,14
PUSHBUTTON "Cancel",IDCANCEL,92,55,50,14
79,50,59,10
DEFPUSHBUTTON "OK",IDOK,14,65,50,14
PUSHBUTTON "Cancel",IDCANCEL,92,65,50,14
END
IDD_INSTRUCTIONS DIALOGEX 0, 0, 186, 169
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Last Instructions"
FONT 8, "Courier New", 0, 0, 0x1
FONT 8, "Courier New"
BEGIN
LTEXT "Instructions (disassembly maybe incorrect):",
IDC_INSTR_TEXT,7,7,173,8
@ -400,6 +425,35 @@ BEGIN
END
/////////////////////////////////////////////////////////////////////////////
//
// Bitmap
//
IDB_CHECKBOX BITMAP DISCARDABLE "checkbox.bmp"
IDR_DEBUG_TOOLBAR BITMAP MOVEABLE PURE "dbgtool.bmp"
/////////////////////////////////////////////////////////////////////////////
//
// Toolbar
//
IDR_DEBUG_TOOLBAR TOOLBAR DISCARDABLE 16, 15
BEGIN
BUTTON ID_DEBUG_RUN
BUTTON ID_DEBUG_CANCEL
BUTTON ID_DEBUG_BREAK
SEPARATOR
BUTTON ID_BREAKPOINTS_SETBREAK
BUTTON ID_BREAKPOINTS_CODEEDIT
SEPARATOR
BUTTON ID_DEBUG_STEP
BUTTON ID_DEBUG_STEPOVER
BUTTON ID_DEBUG_STEPOUT
BUTTON ID_DEBUG_RUNCURSOR
END
#ifndef _MAC
/////////////////////////////////////////////////////////////////////////////
//
@ -407,13 +461,13 @@ END
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION 1,2,0,0
PRODUCTVERSION 1,2,0,0
FILEVERSION 1,2,5,0
PRODUCTVERSION 1,2,5,0
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x21L
FILEFLAGS 0x1L
#else
FILEFLAGS 0x20L
FILEFLAGS 0x0L
#endif
FILEOS 0x40004L
FILETYPE 0x1L
@ -425,13 +479,12 @@ BEGIN
BEGIN
VALUE "CompanyName", "Sebastien Carlier & Christoph Gießelink\0"
VALUE "FileDescription", "HP38/39/40/48/49 Emulator\0"
VALUE "FileVersion", "1, 2, 0, 0\0"
VALUE "FileVersion", "1, 2, 5, 0\0"
VALUE "InternalName", "Emu48\0"
VALUE "LegalCopyright", "Copyright © 2000\0"
VALUE "LegalCopyright", "Copyright © 2001\0"
VALUE "OriginalFilename", "Emu48.exe\0"
VALUE "ProductName", "Emu48\0"
VALUE "ProductVersion", "1, 2, 0, 0\0"
VALUE "SpecialBuild", "Service Pack 20, Christoph Gießelink\0"
VALUE "ProductVersion", "1, 2, 5, 0\0"
END
END
BLOCK "VarFileInfo"
@ -509,6 +562,7 @@ BEGIN
POPUP "&Debug"
BEGIN
MENUITEM "&Run\tF5", ID_DEBUG_RUN
MENUITEM "Run to &Cursor\tF6", ID_DEBUG_RUNCURSOR
MENUITEM "&Step Into\tF7", ID_DEBUG_STEP
MENUITEM "Step &Over\tF8", ID_DEBUG_STEPOVER
MENUITEM "Step O&ut\tF9", ID_DEBUG_STEPOUT
@ -516,13 +570,14 @@ BEGIN
END
POPUP "&Breakpoints"
BEGIN
MENUITEM "Set &breakpoint\tF2", ID_BREAKPOINTS_SETBREAK
MENUITEM "&Edit breakpoints...", ID_BREAKPOINTS_CODEEDIT
MENUITEM "&Clear all breakpoints", ID_BREAKPOINTS_CLEARALL
MENUITEM "Set &Breakpoint\tF2", ID_BREAKPOINTS_SETBREAK
MENUITEM "&Edit Breakpoints...", ID_BREAKPOINTS_CODEEDIT
MENUITEM "&Clear All Breakpoints", ID_BREAKPOINTS_CLEARALL
MENUITEM SEPARATOR
MENUITEM "&NOP3 code breakpoints", ID_BREAKPOINTS_NOP3
MENUITEM "&NOP3 Code Breakpoints", ID_BREAKPOINTS_NOP3
MENUITEM "CODE &Object Breakpoints", ID_BREAKPOINTS_DOCODE
MENUITEM SEPARATOR
MENUITEM "&RPL breakpoints", ID_BREAKPOINTS_RPL
MENUITEM "&RPL Breakpoints", ID_BREAKPOINTS_RPL
END
POPUP "I&nterrupts"
BEGIN
@ -554,6 +609,8 @@ BEGIN
MENUITEM "Go to D&0", ID_DEBUG_MEM_GOD0
MENUITEM "Go to D&1", ID_DEBUG_MEM_GOD1
MENUITEM "Go to &Stack", ID_DEBUG_MEM_GOSTACK
MENUITEM SEPARATOR
MENUITEM "Find...\tF", ID_DEBUG_MEM_FIND
END
END
@ -583,6 +640,25 @@ END
#endif // APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// String Table
//
STRINGTABLE DISCARDABLE
BEGIN
ID_DEBUG_RUN "Run"
ID_DEBUG_RUNCURSOR "Run to Cursor"
ID_DEBUG_STEP "Step Into"
ID_DEBUG_STEPOVER "Step Over"
ID_DEBUG_BREAK "Break Execution"
ID_DEBUG_STEPOUT "Step Out"
ID_DEBUG_CANCEL "Stop Debugging"
ID_BREAKPOINTS_SETBREAK "Insert/Remove Breakpoint"
ID_BREAKPOINTS_CODEEDIT "Breakpoint List"
END
#endif // French (France) resources
/////////////////////////////////////////////////////////////////////////////

View file

@ -14,20 +14,44 @@
#define SAMPLE 16384 // speed adjust sample frequency
BOOL bInterrupt = FALSE;
UINT nState = 1;
UINT nNextState = 0;
BOOL bRealSpeed = FALSE;
BOOL bKeySlow = FALSE; // slow down for key emulation
CHIPSET Chipset;
BOOL bInterrupt = FALSE;
UINT nState = SM_INVALID;
UINT nNextState = SM_RUN;
BOOL bRealSpeed = FALSE;
BOOL bKeySlow = FALSE; // slow down for key emulation
BOOL bCommInit = FALSE; // COM port not open
char szSerialWire[16]; // evicename for wire port
char szSerialIr[16]; // devicename for IR port
CHIPSET Chipset;
DWORD dwSXCycles = 82; // SX cpu cycles in interval
DWORD dwGXCycles = 123; // GX cpu cycles in interval
TCHAR szSerialWire[16]; // devicename for wire port
TCHAR szSerialIr[16]; // devicename for IR port
DWORD dwSXCycles = 82; // SX cpu cycles in interval
DWORD dwGXCycles = 123; // GX cpu cycles in interval
// variables for debugger engine
HANDLE hEventDebug; // event handle to stop cpu thread
BOOL bDbgEnable = FALSE; // debugger mode enable flag
INT nDbgState = DBG_RUN; // state of debugger
BOOL bDbgNOP3 = FALSE; // halt on NOP3 (#420 opcode)
BOOL bDbgRPL = FALSE; // halt on RPL entry
BOOL bDbgCode = FALSE; // halt on DOCODE entry
BOOL bDbgSkipInt = FALSE; // execute interrupt handler
DWORD dwDbgStopPC = -1; // stop address for goto cursor
DWORD dwDbgRplPC = -1; // stop address for RPL breakpoint
DWORD dwDbgRstkp; // stack recursion level of step over end
DWORD dwDbgRstk; // possible return address
DWORD *pdwInstrArray = NULL; // last instruction array
WORD wInstrSize; // size of last instruction array
WORD wInstrWp; // write pointer of instruction array
WORD wInstrRp; // read pointer of instruction array
static BOOL bCommInit = FALSE; // COM port not open
static BOOL bCpuSlow = FALSE; // enable/disable real speed
static DWORD dwEDbgT2 = 0; // debugger timer2 emulation
@ -55,8 +79,8 @@ static __inline VOID SaveInstrAddr(DWORD dwAddr)
static __inline VOID Debugger(VOID) // debugger part
{
LARGE_INTEGER lDummyInt; // sample timer ticks
BOOL bStopEmulation;
BOOL bRplBreak = FALSE; // flag for RPL breakpoint
BOOL bStopEmulation;
BOOL bRplBreak = FALSE; // flag for RPL breakpoint
LPBYTE I = FASTPTR(Chipset.pc); // get opcode stream
@ -76,44 +100,59 @@ static __inline VOID Debugger(VOID) // debugger part
{
dwRange = (I[2] & 0x8) ? 2 : 5;
}
else // P,WP,XS,X,S,M,W or number of nibbles
else // number of nibbles, (P,WP,XS,X,S,M,W)
{
if (I[2] & 0x8) // number of nibbles
{
dwRange = I[3]+1;
}
else // P,WP,XS,X,S,M,W
{
dwData += F_s[I[3]];
dwRange = F_l[I[3]];
}
dwRange = (I[2] & 0x8) ? (I[3]+1) : (F_l[I[3]]);
}
#if defined DEBUG_DEBUGGER
{
char buffer[256];
wsprintf(buffer,"Memory breakpoint %.5lx, %u\n",dwData,dwRange);
TCHAR buffer[256];
wsprintf(buffer,_T("Memory breakpoint %.5lx, %u\n",dwData,dwRange));
OutputDebugString(buffer);
}
#endif
bStopEmulation |= CheckBreakpoint(dwData, dwRange, nType);
}
// check for step cursor
bStopEmulation |= (dwDbgStopPC == Chipset.pc);
// check for RPL breakpoint
if (dwDbgRplPC == Chipset.pc)
{
dwDbgRplPC = -1;
bRplBreak = TRUE;
bStopEmulation = TRUE;
}
// NOP3, opcode #420 (GOC)
if (bDbgNOP3 && I[0] == 0x4 && I[1] == 0x2 && I[2] == 0x0)
bStopEmulation = TRUE;
// RPL breakpoints, PC=(A), opcode #808C or PC=(C), opcode #808E
if (bDbgRPL && I[0] == 0x8 && I[1] == 0x0 && I[2] == 0x8 && (I[3] == 0xC || I[3] == 0xE ))
// stop on first instruction of DOCODE object
if (bDbgCode && (Chipset.pc == 0x02DDE || Chipset.pc == 0x02E3C))
{
BYTE byRplPtr[5];
// return address
DWORD dwAddr = Chipset.rstk[(Chipset.rstkp-1)&7];
// A=DAT0 A, D0=D0+ 5, PC=(A)
// C=DAT0 A, D0=D0+ 5, PC=(C)
Npeek(byRplPtr,Chipset.d0-5,5);
if (memcmp(byRplPtr,(I[3] == 0xC) ? Chipset.A : Chipset.C,5) == 0)
_ASSERT(I[0] == 0 && I[1] == 1); // stopped at RTN opcode
if (MapData(dwAddr) != M_ROM) // address not in ROM
dwDbgStopPC = dwAddr; // then stop
}
// RPL breakpoints, PC=(A), opcode #808C or PC=(C), opcode #808E
if (I[0] == 0x8 && I[1] == 0x0 && I[2] == 0x8 && (I[3] == 0xC || I[3] == 0xE ))
{
// get next RPL entry
DWORD dwAddr = Npack((I[3] == 0xC) ? Chipset.A : Chipset.C,5);
if (bDbgRPL || CheckBreakpoint(dwAddr, 1, BP_RPL))
{
bRplBreak = TRUE;
bStopEmulation = TRUE;
BYTE byRplPtr[5];
Npeek(byRplPtr,dwAddr,5); // get PC address of next opcode
dwDbgRplPC = Npack(byRplPtr,5); // set RPL breakpoint
}
}
@ -167,10 +206,10 @@ static __inline VOID Debugger(VOID) // debugger part
}
dwEDbgT2 = Chipset.t2; // timer2 check reference value
// OutputDebugString("Emulator stopped...\n");
// OutputDebugString(_T("Emulator stopped...\n"));
NotifyDebugger(bRplBreak);
WaitForSingleObject(hEventDebug,INFINITE);
// OutputDebugString("Emulator running...\n");
// OutputDebugString(_T("Emulator running...\n"));
StartTimers(); // continue timers
@ -209,11 +248,10 @@ static __inline VOID CheckSerial(VOID)
// COM port closed and serial on
if (bCommInit == FALSE && (Chipset.IORam[IOC] & SON) != 0)
{
CommOpen(szSerialWire,szSerialIr); // open COM ports
bCommInit = CommConnect() != PORT_CLOSE;
bCommInit = CommOpen(szSerialWire,szSerialIr); // open COM ports
}
// COM port opend and serial off
// COM port opened and serial off
if (bCommInit == TRUE && (Chipset.IORam[IOC] & SON) == 0)
{
CommClose(); // close COM port
@ -227,6 +265,7 @@ static __inline VOID CheckSerial(VOID)
INTERRUPT;
}
}
return;
}
static __inline VOID AdjustSpeed(VOID) // adjust emulation speed
@ -273,7 +312,7 @@ VOID AdjKeySpeed(VOID) // slow down key repeat
if (bCpuSlow) return; // no need to slow down
bKey = FALSE; // search for a pressed key
for (i = 0;i < sizeof(Chipset.Keyboard_Row) / sizeof(Chipset.Keyboard_Row[0]) && !bKey;++i)
for (i = 0;i < ARRAYSIZEOF(Chipset.Keyboard_Row) && !bKey;++i)
bKey = (Chipset.Keyboard_Row[i] != 0);
if (!bKeySlow && bKey) // key pressed, init variables
@ -309,16 +348,19 @@ VOID UpdateKdnBit(VOID) // update KDN bit
BOOL WaitForSleepState(VOID) // wait for cpu SHUTDN then sleep state
{
DWORD dwRefTime = timeGetTime();
DWORD dwRefTime;
DisableDebugger(); // disable debugger
dwRefTime = timeGetTime();
// wait for the SHUTDN command with 1.5 sec timeout
while (timeGetTime() - dwRefTime < 1500L && !Chipset.Shutdn)
Sleep(0);
if (Chipset.Shutdn) // not timeout, cpu is down
SwitchToState(3); // go to sleep state
SwitchToState(SM_SLEEP); // go to sleep state
return 3 != nNextState; // state not changed, emulator was busy
return SM_SLEEP != nNextState; // state not changed, emulator was busy
}
UINT SwitchToState(UINT nNewState)
@ -328,16 +370,12 @@ UINT SwitchToState(UINT nNewState)
if (nState == nNewState) return nOldState;
switch (nState)
{
case 0: // Run
if (hDlgDebug) // debugger running
{
DestroyWindow(hDlgDebug); // then close debugger to renter emulation
hDlgDebug = NULL;
}
case SM_RUN: // Run
switch (nNewState)
{
case 1: // -> Invalid
nNextState = 1;
case SM_INVALID: // -> Invalid
DisableDebugger(); // disable debugger
nNextState = SM_INVALID;
if (Chipset.Shutdn)
SetEvent(hEventShutdn);
else
@ -345,73 +383,77 @@ UINT SwitchToState(UINT nNewState)
while (nState!=nNextState) Sleep(0);
UpdateWindowStatus();
break;
case 2: // -> Return
nNextState = 1;
case SM_RETURN: // -> Return
DisableDebugger(); // disable debugger
nNextState = SM_INVALID;
if (Chipset.Shutdn)
SetEvent(hEventShutdn);
else
bInterrupt = TRUE;
while (nState!=nNextState) Sleep(0);
nNextState = 2;
nNextState = SM_RETURN;
SetEvent(hEventShutdn);
while (nState!=nNextState) Sleep(0);
WaitForSingleObject(hThread,INFINITE);
UpdateWindowStatus();
break;
case 3: // -> Sleep
nNextState = 3;
if (Chipset.Shutdn)
SetEvent(hEventShutdn);
else
bInterrupt = TRUE;
case SM_SLEEP: // -> Sleep
nNextState = SM_SLEEP;
bInterrupt = TRUE; // exit main loop
SetEvent(hEventDebug); // exit debugger
SetEvent(hEventShutdn); // exit shutdown
while (nState!=nNextState) Sleep(0);
bInterrupt = FALSE;
ResetEvent(hEventDebug);
ResetEvent(hEventShutdn);
break;
}
break;
case 1: // Invalid
case SM_INVALID: // Invalid
switch (nNewState)
{
case 0: // -> Run
nNextState = 0;
case SM_RUN: // -> Run
nNextState = SM_RUN;
// don't enter opcode loop on interrupt request
bInterrupt = Chipset.Shutdn || Chipset.SoftInt;
SetEvent(hEventShutdn);
while (nState!=nNextState) Sleep(0);
UpdateWindowStatus();
break;
case 2: // -> Return
nNextState = 2;
case SM_RETURN: // -> Return
nNextState = SM_RETURN;
SetEvent(hEventShutdn);
while (nState!=nNextState) Sleep(0);
WaitForSingleObject(hThread,INFINITE);
break;
case 3: // -> Sleep
nNextState = 3;
case SM_SLEEP: // -> Sleep
nNextState = SM_SLEEP;
SetEvent(hEventShutdn);
while (nState!=nNextState) Sleep(0);
UpdateWindowStatus();
break;
}
break;
case 3: // Sleep
case SM_SLEEP: // Sleep
switch (nNewState)
{
case 0: // -> Run
nNextState = 0;
if (Chipset.Shutdn) bInterrupt=TRUE;
SetEvent(hEventShutdn);
case SM_RUN: // -> Run
nNextState = SM_RUN;
// don't enter opcode loop on interrupt request
bInterrupt = !bDbgEnable && (Chipset.Shutdn || Chipset.SoftInt);
SetEvent(hEventShutdn); // leave sleep state
break;
case 1: // -> Invalid
nNextState = 1;
case SM_INVALID: // -> Invalid
nNextState = SM_INVALID;
SetEvent(hEventShutdn);
while (nState!=nNextState) Sleep(0);
UpdateWindowStatus();
break;
case 2: // -> Return
nNextState = 1;
case SM_RETURN: // -> Return
nNextState = SM_INVALID;
SetEvent(hEventShutdn);
while (nState!=nNextState) Sleep(0);
nNextState = 2;
nNextState = SM_RETURN;
SetEvent(hEventShutdn);
while (nState!=nNextState) Sleep(0);
WaitForSingleObject(hThread,INFINITE);
UpdateWindowStatus();
break;
}
@ -429,24 +471,24 @@ UINT WorkerThread(LPVOID pParam)
_ASSERT(dwTickRef); // tick resolution error
loop:
while (nNextState == 1) // go into invalid state
while (nNextState == SM_INVALID) // go into invalid state
{
CommClose(); // close COM port
bCommInit = FALSE; // COM port not open
nState = 1; // in invalid state
nState = SM_INVALID; // in invalid state
WaitForSingleObject(hEventShutdn,INFINITE);
if (nNextState == 2) // go into return state
if (nNextState == SM_RETURN) // go into return state
{
nState = 2; // in return state
nState = SM_RETURN; // in return state
return 0; // kill thread
}
ioc_acc = TRUE; // test if UART on
}
while (nNextState == 0)
while (nNextState == SM_RUN)
{
if (nState!=0)
if (nState != SM_RUN)
{
nState = 0;
nState = SM_RUN;
// clear port2 status bits
Chipset.cards_status &= ~(PORT2_PRESENT | PORT2_WRITE);
if (pbyPort2 || Chipset.Port2) // card plugged in port2
@ -524,13 +566,13 @@ loop:
}
}
}
_ASSERT(nNextState != 0);
_ASSERT(nNextState != SM_RUN);
StopTimers();
while (nNextState == 3) // go into sleep state
while (nNextState == SM_SLEEP) // go into sleep state
{
nState = 3; // in sleep state
nState = SM_SLEEP; // in sleep state
WaitForSingleObject(hEventShutdn,INFINITE);
}
goto loop;

View file

@ -8,23 +8,24 @@
*/
#include "pch.h"
#include "Emu48.h"
#include "ops.h"
//| 38G | 48SX | 48GX | 49G | Name
//#F0E4F #706D2 #80850 #80F0F =SFLAG53_56
//| 38G | 39G | 40G | 48SX | 48GX | 49G | Name
//#F0E4F #80F0F #80F0F #706D2 #80850 #80F0F =SFLAG53_56
// memory address for flags -53 to -56
#define SFLAG53_56 ( (cCurrentRomType=='6') \
? 0xE0E4F \
: ( (cCurrentRomType=='A') \
? 0xF0E4F \
: ( (cCurrentRomType!='X') \
? ( (cCurrentRomType=='S') \
? 0x706D2 \
: 0x80850 \
) \
: 0x80F0F \
) \
) \
#define SFLAG53_56 ( (cCurrentRomType=='6') \
? 0xE0E4F \
: ( (cCurrentRomType=='A') \
? 0xF0E4F \
: ( (cCurrentRomType!='E' && cCurrentRomType!='X') \
? ( (cCurrentRomType=='S') \
? 0x706D2 \
: 0x80850 \
) \
: 0x80F0F \
) \
) \
)
static __inline VOID Return(CHIPSET* w)

View file

@ -321,7 +321,7 @@ static const JMPTAB o8A_[] =
static const JMPTAB o81B_[] =
{
o_invalid4, F,
o81B1, F,
o81B1, F, // normally o_invalid4, beep patch
o81B2, F,
o81B3, F,
o81B4, F,

View file

@ -8,36 +8,40 @@
*/
#include "pch.h"
#include "Emu48.h"
#include "ops.h"
#include "io.h" // I/O register definitions
#include "kml.h"
#include "i28f160.h" // flash support
#include "debugger.h"
char szEmu48Directory[260];
char szCurrentDirectory[260];
char szCurrentKml[260];
char szBackupKml[260];
char szCurrentFilename[260];
char szBackupFilename[260];
char szBufferFilename[260];
char szPort2Filename[260];
TCHAR szEmu48Directory[260];
TCHAR szCurrentDirectory[260];
TCHAR szCurrentKml[260];
TCHAR szBackupKml[260];
TCHAR szCurrentFilename[260];
TCHAR szBackupFilename[260];
TCHAR szBufferFilename[260];
TCHAR szPort2Filename[260];
LPBYTE pbyRom = NULL;
LPBYTE pbyRom = NULL;
static HANDLE hRomFile = NULL;
static HANDLE hRomMap = NULL;
DWORD dwRomSize = 0;
char cCurrentRomType = 0;
BOOL bRomWriteable = FALSE; // flag if ROM writeable
DWORD dwRomSize = 0;
BYTE cCurrentRomType = 0; // Model -> hardware
UINT nCurrentClass = 0; // Class -> derivate
BOOL bRomWriteable = TRUE; // flag if ROM writeable
static HANDLE hPort2File = NULL;
static HANDLE hPort2Map = NULL;
LPBYTE pbyPort2 = NULL;
BOOL bPort2Writeable = FALSE;
BOOL bPort2IsShared = FALSE;
DWORD dwPort2Size = 0; // size of mapped port2
DWORD dwPort2Mask = 0;
LPBYTE pbyPort2 = NULL;
BOOL bPort2Writeable = FALSE;
BOOL bPort2IsShared = FALSE;
DWORD dwPort2Size = 0; // size of mapped port2
DWORD dwPort2Mask = 0;
// document signatures
static BYTE pbySignatureA[16] = "Emu38 Document\xFE";
static BYTE pbySignatureB[16] = "Emu39 Document\xFE";
static BYTE pbySignatureE[16] = "Emu48 Document\xFE";
static BYTE pbySignatureW[16] = "Win48 Document\xFE";
static BYTE pbySignatureV[16] = "Emu49 Document\xFE";
@ -105,7 +109,7 @@ WORD WriteStack(LPBYTE lpBuf,DWORD dwSize) // separated from LoadObject()
//#
//################
static __inline BYTE Asc2Nib(char c)
static __inline BYTE Asc2Nib(BYTE c)
{
if (c<'0') return 0;
if (c<='9') return c-'0';
@ -186,7 +190,7 @@ VOID UpdatePatches(BOOL bPatch)
return;
}
BOOL PatchRom(LPCSTR szFilename)
BOOL PatchRom(LPCTSTR szFilename)
{
HANDLE hFile = NULL;
DWORD dwFileSizeLow = 0;
@ -243,9 +247,9 @@ BOOL PatchRom(LPCSTR szFilename)
break;
}
} while (lpBuf[nPos]);
continue;
}
if (lpBuf[nPos] == 0) break;
dwAddress = strtoul(&lpBuf[nPos],&lpStop,16);
dwAddress = strtoul(&lpBuf[nPos],(CHAR **)&lpStop,16);
nPos += lpStop-&lpBuf[nPos]+1;
if (*lpStop != ':' || *lpStop == 0)
continue;
@ -287,7 +291,7 @@ static WORD CrcRom(VOID) // calculate fingerprint of ROM
return (WORD) dwCrc;
}
BOOL MapRom(LPCSTR szFilename)
BOOL MapRom(LPCTSTR szFilename)
{
DWORD dwFileSizeHigh;
@ -354,7 +358,7 @@ BOOL MapRom(LPCSTR szFilename)
}
if (GetLastError() == ERROR_ALREADY_EXISTS)
{
AbortMessage("Sharing file mapping handle.");
AbortMessage(_T("Sharing file mapping handle."));
}
pbyRom = MapViewOfFile(hRomMap, bWrite ? FILE_MAP_WRITE : FILE_MAP_COPY, 0, 0, dwRomSize);
if (pbyRom == NULL)
@ -398,7 +402,7 @@ static WORD CrcPort2(VOID) // calculate fingerprint of port2
WORD wCrc = 0;
// port2 CRC isn't available
if (cCurrentRomType=='X' || pbyPort2==NULL) return wCrc;
if (pbyPort2 == NULL) return wCrc;
dwFileSize = GetFileSize(hPort2File, &dwCount); // get real filesize
_ASSERT(dwCount == 0); // isn't created by MapPort2()
@ -408,7 +412,7 @@ static WORD CrcPort2(VOID) // calculate fingerprint of port2
return wCrc;
}
BOOL MapPort2(LPCSTR szFilename)
BOOL MapPort2(LPCTSTR szFilename)
{
DWORD dwFileSizeLo;
DWORD dwFileSizeHi;
@ -418,51 +422,31 @@ BOOL MapPort2(LPCSTR szFilename)
dwPort2Size = 0; // reset size of port2
SetCurrentDirectory(szEmu48Directory);
if (bPort2IsShared)
hPort2File = CreateFile(szFilename,
GENERIC_READ|GENERIC_WRITE,
bPort2IsShared ? FILE_SHARE_READ : 0,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);
if (hPort2File == INVALID_HANDLE_VALUE)
{
bPort2Writeable = FALSE;
hPort2File = CreateFile(szFilename,
GENERIC_READ|GENERIC_WRITE,
FILE_SHARE_READ,
GENERIC_READ,
bPort2IsShared ? (FILE_SHARE_READ|FILE_SHARE_WRITE) : 0,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);
SetCurrentDirectory(szCurrentDirectory);
if (hPort2File == INVALID_HANDLE_VALUE)
{
bPort2Writeable = FALSE;
SetCurrentDirectory(szEmu48Directory);
hPort2File = CreateFile(szFilename,
GENERIC_READ,
FILE_SHARE_READ|FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);
SetCurrentDirectory(szCurrentDirectory);
if (hPort2File == INVALID_HANDLE_VALUE)
{
hPort2File = NULL;
return FALSE;
}
}
}
else
{
hPort2File = CreateFile(szFilename,
GENERIC_READ|GENERIC_WRITE,
0,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);
SetCurrentDirectory(szCurrentDirectory);
if (hPort2File == INVALID_HANDLE_VALUE)
{
hPort2File = NULL;
return FALSE;
}
}
SetCurrentDirectory(szCurrentDirectory);
dwFileSizeLo = GetFileSize(hPort2File, &dwFileSizeHi);
if (dwFileSizeHi != 0)
{ // file is too large.
@ -472,7 +456,7 @@ BOOL MapPort2(LPCSTR szFilename)
bPort2Writeable = FALSE;
return FALSE;
}
if (dwFileSizeLo & 0x3FFFF)
if (dwFileSizeLo & 0x2FFFF)
{ // file size is wrong
CloseHandle(hPort2File);
hPort2File = NULL;
@ -480,7 +464,7 @@ BOOL MapPort2(LPCSTR szFilename)
bPort2Writeable = FALSE;
return FALSE;
}
dwPort2Mask = (dwFileSizeLo >> 18) - 1; // mask for valid address lines of the BS-FF
dwPort2Mask = (dwFileSizeLo - 1) >> 18; // mask for valid address lines of the BS-FF
hPort2Map = CreateFileMapping(hPort2File, NULL, bPort2Writeable ? PAGE_READWRITE : PAGE_READONLY,
0, dwFileSizeLo, NULL);
if (hPort2Map == NULL)
@ -545,15 +529,10 @@ VOID ResetDocument(VOID)
szCurrentFilename[0]=0;
if (Chipset.Port0) LocalFree(Chipset.Port0);
if (Chipset.Port1) LocalFree(Chipset.Port1);
if (cCurrentRomType == 'X')
{
if (Chipset.Port2) LocalFree(Chipset.Port2);
}
else
{
UnmapPort2();
}
if (Chipset.Port2) LocalFree(Chipset.Port2); else UnmapPort2();
FillMemory(&Chipset,sizeof(Chipset),0);
FillMemory(&RMap,sizeof(RMap),0); // delete MMU mappings
FillMemory(&WMap,sizeof(WMap),0);
UpdateWindowStatus();
return;
}
@ -571,23 +550,25 @@ BOOL NewDocument(VOID)
Chipset.Port0Size = (Chipset.type == 'A') ? 32 : 64;
Chipset.Port1Size = 0;
Chipset.Port2Size = 0;
Chipset.Port0 = (LPBYTE)LocalAlloc(0,Chipset.Port0Size*2048);
_ASSERT(Chipset.Port0 != NULL);
FillMemory(Chipset.Port0, Chipset.Port0Size*2048, 0);
Chipset.Port1 = NULL;
Chipset.Port2 = NULL;
Chipset.cards_status = 0x0;
}
if (Chipset.type == 'E') // HP39/40G
{
Chipset.Port0Size = 128;
Chipset.Port1Size = 0;
Chipset.Port2Size = 128;
Chipset.cards_status = 0xF;
bPort2Writeable = TRUE; // port2 is writeable
}
if (Chipset.type == 'S') // HP48SX
{
Chipset.Port0Size = 32;
Chipset.Port1Size = 128;
Chipset.Port0 = (LPBYTE)LocalAlloc(0,Chipset.Port0Size*2048);
_ASSERT(Chipset.Port0 != NULL);
FillMemory(Chipset.Port0, Chipset.Port0Size*2048, 0);
Chipset.Port1 = (LPBYTE)LocalAlloc(0,Chipset.Port1Size*2048);
_ASSERT(Chipset.Port1 != NULL);
FillMemory(Chipset.Port1, Chipset.Port1Size*2048, 0);
Chipset.Port2Size = 0;
Chipset.cards_status = 0x5;
// use 2nd command line argument if defined
@ -597,12 +578,8 @@ BOOL NewDocument(VOID)
{
Chipset.Port0Size = 128;
Chipset.Port1Size = 128;
Chipset.Port0 = (LPBYTE)LocalAlloc(0,Chipset.Port0Size*2048);
_ASSERT(Chipset.Port0 != NULL);
FillMemory(Chipset.Port0, Chipset.Port0Size*2048, 0);
Chipset.Port1 = (LPBYTE)LocalAlloc(0,Chipset.Port1Size*2048);
_ASSERT(Chipset.Port1 != NULL);
FillMemory(Chipset.Port1, Chipset.Port1Size*2048, 0);
Chipset.Port2Size = 0;
Chipset.cards_status = 0xA;
// use 2nd command line argument if defined
@ -613,21 +590,30 @@ BOOL NewDocument(VOID)
Chipset.Port0Size = 256;
Chipset.Port1Size = 128;
Chipset.Port2Size = 128;
Chipset.Port0 = (LPBYTE)LocalAlloc(0,Chipset.Port0Size*2048);
_ASSERT(Chipset.Port0 != NULL);
FillMemory(Chipset.Port0, Chipset.Port0Size*2048, 0);
Chipset.Port1 = (LPBYTE)LocalAlloc(0,Chipset.Port1Size*2048);
_ASSERT(Chipset.Port1 != NULL);
FillMemory(Chipset.Port1, Chipset.Port1Size*2048, 0);
Chipset.Port2 = (LPBYTE)LocalAlloc(0,Chipset.Port2Size*2048);
_ASSERT(Chipset.Port2 != NULL);
FillMemory(Chipset.Port2, Chipset.Port2Size*2048, 0);
bPort2Writeable = TRUE;
Chipset.cards_status = 0xF;
bPort2Writeable = TRUE; // port2 is writeable
FlashInit(); // init flash structure
}
// allocate port memory
if (Chipset.Port0Size)
{
Chipset.Port0 = (LPBYTE)LocalAlloc(LPTR,Chipset.Port0Size*2048);
_ASSERT(Chipset.Port0 != NULL);
}
if (Chipset.Port1Size)
{
Chipset.Port1 = (LPBYTE)LocalAlloc(LPTR,Chipset.Port1Size*2048);
_ASSERT(Chipset.Port1 != NULL);
}
if (Chipset.Port2Size)
{
Chipset.Port2 = (LPBYTE)LocalAlloc(LPTR,Chipset.Port2Size*2048);
_ASSERT(Chipset.Port2 != NULL);
}
LoadBreakpointList(NULL); // clear debugger breakpoint list
RomSwitch(0); // boot ROM view of HP49G and map memory
SaveBackup();
return TRUE;
@ -636,7 +622,7 @@ restore:
ResetBackup();
// HP48SX/GX
if(Chipset.type != '6' && Chipset.type != 'A' && Chipset.type != 'X')
if(Chipset.type == 'S' || Chipset.type == 'G')
{
// use 2nd command line argument if defined
MapPort2((nArgc < 3) ? szPort2Filename : ppArgv[2]);
@ -649,7 +635,7 @@ restore:
return FALSE;
}
BOOL OpenDocument(LPCSTR szFilename)
BOOL OpenDocument(LPCTSTR szFilename)
{
HANDLE hFile = INVALID_HANDLE_VALUE;
DWORD lBytesRead;
@ -665,13 +651,13 @@ BOOL OpenDocument(LPCSTR szFilename)
// Open file
if (lstrcmpi(szBackupFilename, szFilename)==0)
{
if (YesNoMessage("Do you want to reload this document ?") == IDNO)
if (YesNoMessage(_T("Do you want to reload this document ?")) == IDNO)
goto restore;
}
hFile = CreateFile(szFilename, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
if (hFile == INVALID_HANDLE_VALUE)
{
AbortMessage("This file is missing or already loaded in another instance of Emu48.\n");
AbortMessage(_T("This file is missing or already loaded in another instance of Emu48."));
goto restore;
}
@ -681,13 +667,13 @@ BOOL OpenDocument(LPCSTR szFilename)
{
case 'E':
pbySig = (pbyFileSignature[3] == '3')
? pbySignatureA
? ((pbyFileSignature[4] == '8') ? pbySignatureA : pbySignatureB)
: ((pbyFileSignature[4] == '8') ? pbySignatureE : pbySignatureV);
for (ctBytesCompared=0; ctBytesCompared<14; ctBytesCompared++)
{
if (pbyFileSignature[ctBytesCompared]!=pbySig[ctBytesCompared])
{
AbortMessage("This file is not a valid Emu48 document.");
AbortMessage(_T("This file is not a valid Emu48 document."));
goto restore;
}
}
@ -697,29 +683,45 @@ BOOL OpenDocument(LPCSTR szFilename)
{
if (pbyFileSignature[ctBytesCompared]!=pbySignatureW[ctBytesCompared])
{
AbortMessage("This file is not a valid Win48 document.");
AbortMessage(_T("This file is not a valid Win48 document."));
goto restore;
}
}
break;
default:
AbortMessage("This file is not a valid document.");
AbortMessage(_T("This file is not a valid document."));
goto restore;
}
switch (pbyFileSignature[14])
{
case 0xFE: // Win48 2.1 / Emu4x 0.99.x format
ReadFile(hFile, &nLength, sizeof(nLength), &lBytesRead, NULL);
ReadFile(hFile, szCurrentKml, nLength, &lBytesRead, NULL);
ReadFile(hFile,&nLength,sizeof(nLength),&lBytesRead,NULL);
#if defined _UNICODE
{
LPSTR szTmp = LocalAlloc(LMEM_FIXED,nLength);
if (szTmp == NULL)
{
AbortMessage(_T("Memory Allocation Failure."));
goto restore;
}
ReadFile(hFile, szTmp, nLength, &lBytesRead, NULL);
MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, szTmp, lBytesRead,
szCurrentKml, ARRAYSIZEOF(szCurrentKml));
LocalFree(szTmp);
}
#else
{
ReadFile(hFile, szCurrentKml, nLength, &lBytesRead, NULL);
}
#endif
if (nLength != lBytesRead) goto read_err;
szCurrentKml[nLength] = 0;
break;
case 0xFF: // Win48 2.05 format
break;
default:
AbortMessage("This file is for an unknown version of Emu48.\n"
"Please contact the author (see Emu48.txt).");
AbortMessage(_T("This file is for an unknown version of Emu48."));
goto restore;
}
@ -727,7 +729,7 @@ BOOL OpenDocument(LPCSTR szFilename)
if (lBytesRead != sizeof(lSizeofChipset)) goto read_err;
if (lSizeofChipset!=sizeof(CHIPSET))
{
AbortMessage("This file is probably corrupted, and cannot be loaded.");
AbortMessage(_T("This file is probably corrupted, and cannot be loaded."));
goto restore;
}
@ -744,8 +746,15 @@ BOOL OpenDocument(LPCSTR szFilename)
if (!DisplayChooseKml(Chipset.type))
goto restore;
}
while (!InitKML(szCurrentKml,FALSE))
while (TRUE)
{
BOOL bOK;
bOK = InitKML(szCurrentKml,FALSE);
bOK = bOK && (cCurrentRomType == Chipset.type);
if (bOK) break;
KillKML();
if (!DisplayChooseKml(Chipset.type))
goto restore;
}
@ -757,7 +766,7 @@ BOOL OpenDocument(LPCSTR szFilename)
Chipset.Port0 = (LPBYTE)LocalAlloc(0,Chipset.Port0Size*2048);
if (Chipset.Port0 == NULL)
{
AbortMessage("Memory Allocation Failure.");
AbortMessage(_T("Memory Allocation Failure."));
goto restore;
}
@ -770,7 +779,7 @@ BOOL OpenDocument(LPCSTR szFilename)
Chipset.Port1 = (LPBYTE)LocalAlloc(0,Chipset.Port1Size*2048);
if (Chipset.Port1 == NULL)
{
AbortMessage("Memory Allocation Failure.");
AbortMessage(_T("Memory Allocation Failure."));
goto restore;
}
@ -778,32 +787,29 @@ BOOL OpenDocument(LPCSTR szFilename)
if (lBytesRead != Chipset.Port1Size*2048) goto read_err;
}
if (cCurrentRomType!='X') // HP38G, HP48SX/GX
// HP48SX/GX
if(cCurrentRomType=='S' || cCurrentRomType=='G')
{
// HP48SX/GX
if(cCurrentRomType!='6' && cCurrentRomType!='A')
MapPort2((nArgc < 3) ? szPort2Filename : ppArgv[2]);
// port2 changed and card detection enabled
if ( Chipset.wPort2Crc != CrcPort2()
&& (Chipset.IORam[CARDCTL] & ECDT) != 0 && (Chipset.IORam[TIMER2_CTRL] & RUN) != 0
)
{
MapPort2((nArgc < 3) ? szPort2Filename : ppArgv[2]);
// port2 changed and card detection enabled
if ( Chipset.wPort2Crc != CrcPort2()
&& (Chipset.IORam[CARDCTL] & ECDT) != 0 && (Chipset.IORam[TIMER2_CTRL] & RUN) != 0
)
{
Chipset.HST |= MP; // set Module Pulled
IOBit(SRQ2,NINT,FALSE); // set NINT to low
Chipset.SoftInt = TRUE; // set interrupt
bInterrupt = TRUE;
}
Chipset.HST |= MP; // set Module Pulled
IOBit(SRQ2,NINT,FALSE); // set NINT to low
Chipset.SoftInt = TRUE; // set interrupt
bInterrupt = TRUE;
}
}
else // HP49G
else // HP38G, HP39/40G, HP49G
{
if (Chipset.Port2Size)
{
Chipset.Port2 = (LPBYTE)LocalAlloc(0,Chipset.Port2Size*2048);
if (Chipset.Port2 == NULL)
{
AbortMessage("Memory Allocation Failure.");
AbortMessage(_T("Memory Allocation Failure."));
goto restore;
}
@ -815,10 +821,14 @@ BOOL OpenDocument(LPCSTR szFilename)
}
}
LoadBreakpointList(hFile); // load debugger breakpoint list
RomSwitch(Chipset.Bank_FF); // reload ROM view of HP49G and map memory
if (Chipset.wRomCrc != CrcRom()) // ROM changed
{
CpuReset();
Chipset.Shutdn = FALSE; // automatic restart
}
lstrcpy(szCurrentFilename, szFilename);
_ASSERT(hCurrentFile == NULL);
@ -828,7 +838,7 @@ BOOL OpenDocument(LPCSTR szFilename)
return TRUE;
read_err:
AbortMessage("This file must be truncated, and cannot be loaded.");
AbortMessage(_T("This file must be truncated, and cannot be loaded."));
restore:
if (INVALID_HANDLE_VALUE != hFile) // close if valid handle
CloseHandle(hFile);
@ -836,7 +846,7 @@ restore:
ResetBackup();
// HP48SX/GX
if(cCurrentRomType!='6' && cCurrentRomType!='A' && cCurrentRomType!='X')
if(cCurrentRomType=='S' || cCurrentRomType=='G')
{
// use 2nd command line argument if defined
MapPort2((nArgc < 3) ? szPort2Filename : ppArgv[2]);
@ -846,42 +856,62 @@ restore:
BOOL SaveDocument(VOID)
{
DWORD lBytesWritten;
DWORD lSizeofChipset;
LPBYTE pbySig;
UINT nLength;
RECT Rect;
DWORD lBytesWritten;
DWORD lSizeofChipset;
LPBYTE pbySig;
UINT nLength;
WINDOWPLACEMENT wndpl;
if (hCurrentFile == NULL) return FALSE;
GetWindowRect(hWnd, &Rect); // update saved window position
Chipset.nPosX = (SWORD)Rect.left;
Chipset.nPosY = (SWORD)Rect.top;
_ASSERT(hWnd); // window open
wndpl.length = sizeof(wndpl); // update saved window position
GetWindowPlacement(hWnd, &wndpl);
Chipset.nPosX = (SWORD) wndpl.rcNormalPosition.left;
Chipset.nPosY = (SWORD) wndpl.rcNormalPosition.top;
SetFilePointer(hCurrentFile,0,0,FILE_BEGIN);
SetFilePointer(hCurrentFile,0,NULL,FILE_BEGIN);
// get document signature
pbySig = (Chipset.type=='6' || Chipset.type=='A')
? pbySignatureA : ((Chipset.type!='X') ? pbySignatureE : pbySignatureV);
? pbySignatureA : (Chipset.type=='E' ? pbySignatureB : ((Chipset.type!='X') ? pbySignatureE : pbySignatureV));
if (!WriteFile(hCurrentFile, pbySig, 16, &lBytesWritten, NULL))
{
AbortMessage("Could not write into file !");
AbortMessage(_T("Could not write into file !"));
return FALSE;
}
Chipset.wRomCrc = CrcRom(); // save fingerprint of ROM
Chipset.wPort2Crc = CrcPort2(); // save fingerprint of port2
nLength = strlen(szCurrentKml);
nLength = lstrlen(szCurrentKml);
WriteFile(hCurrentFile, &nLength, sizeof(nLength), &lBytesWritten, NULL);
WriteFile(hCurrentFile, szCurrentKml, nLength, &lBytesWritten, NULL);
#if defined _UNICODE
{
LPSTR szTmp = LocalAlloc(LMEM_FIXED,nLength);
if (szTmp != NULL)
{
WideCharToMultiByte(CP_ACP, WC_COMPOSITECHECK,
szCurrentKml, nLength,
szTmp, nLength, NULL, NULL);
WriteFile(hCurrentFile, szTmp, nLength, &lBytesWritten, NULL);
LocalFree(szTmp);
}
}
#else
{
WriteFile(hCurrentFile, szCurrentKml, nLength, &lBytesWritten, NULL);
}
#endif
lSizeofChipset = sizeof(CHIPSET);
WriteFile(hCurrentFile, &lSizeofChipset, sizeof(lSizeofChipset), &lBytesWritten, NULL);
WriteFile(hCurrentFile, &Chipset, lSizeofChipset, &lBytesWritten, NULL);
if (Chipset.Port0Size) WriteFile(hCurrentFile, Chipset.Port0, Chipset.Port0Size*2048, &lBytesWritten, NULL);
if (Chipset.Port1Size) WriteFile(hCurrentFile, Chipset.Port1, Chipset.Port1Size*2048, &lBytesWritten, NULL);
if (cCurrentRomType=='X' && Chipset.Port2Size) WriteFile(hCurrentFile, Chipset.Port2, Chipset.Port2Size*2048, &lBytesWritten, NULL);
if (Chipset.Port2Size) WriteFile(hCurrentFile, Chipset.Port2, Chipset.Port2Size*2048, &lBytesWritten, NULL);
SaveBreakpointList(hCurrentFile); // save debugger breakpoint list
SetEndOfFile(hCurrentFile); // cut the rest
return TRUE;
}
@ -897,7 +927,7 @@ BOOL SaveDocumentAs(LPCTSTR szFilename)
hFile = CreateFile(szFilename, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, 0, NULL);
if (hFile == INVALID_HANDLE_VALUE) // error, couldn't create a new file
{
AbortMessage("This file must be currently used by another instance of Emu48.");
AbortMessage(_T("This file must be currently used by another instance of Emu48."));
return FALSE;
}
lstrcpy(szCurrentFilename, szFilename); // save new file name
@ -937,7 +967,7 @@ BOOL SaveBackup(VOID)
BackupChipset.Port1 = (LPBYTE)LocalAlloc(0,Chipset.Port1Size*2048);
CopyMemory(BackupChipset.Port1, Chipset.Port1, Chipset.Port1Size*2048);
BackupChipset.Port2 = NULL;
if (cCurrentRomType=='X') // HP49G
if (Chipset.Port2Size) // internal port2
{
BackupChipset.Port2 = (LPBYTE)LocalAlloc(0,Chipset.Port2Size*2048);
CopyMemory(BackupChipset.Port2, Chipset.Port2, Chipset.Port2Size*2048);
@ -973,7 +1003,7 @@ BOOL RestoreBackup(VOID)
CopyMemory(Chipset.Port0, BackupChipset.Port0, Chipset.Port0Size*2048);
Chipset.Port1 = (LPBYTE)LocalAlloc(0,Chipset.Port1Size*2048);
CopyMemory(Chipset.Port1, BackupChipset.Port1, Chipset.Port1Size*2048);
if (cCurrentRomType=='X') // HP49G
if (Chipset.Port2Size) // internal port2
{
Chipset.Port2 = (LPBYTE)LocalAlloc(0,Chipset.Port2Size*2048);
CopyMemory(Chipset.Port2, BackupChipset.Port2, Chipset.Port2Size*2048);
@ -981,7 +1011,7 @@ BOOL RestoreBackup(VOID)
// map port2
else
{
if(cCurrentRomType!='6' && cCurrentRomType!='A') // HP48SX/GX
if(cCurrentRomType=='S' || cCurrentRomType=='G') // HP48SX/GX
{
// use 2nd command line argument if defined
MapPort2((nArgc < 3) ? szPort2Filename : ppArgv[2]);
@ -1030,28 +1060,28 @@ BOOL GetOpenFilename(VOID)
InitializeOFN(&ofn);
ofn.lpstrFilter =
"Emu38 Document (*.E38)\0*.E38\0"
"Emu48 Document (*.E48)\0*.E48\0"
"Emu49 Document (*.E49)\0*.E49\0"
"Win48 Document (*.W48)\0*.W48\0"
"\0\0";
if (cCurrentRomType!='X') // HP38G / HP48SX/GX
_T("Emu38 Document (*.E38)\0*.E38\0")
_T("Emu39 Document (*.E39)\0*.E39\0")
_T("Emu48 Document (*.E48)\0*.E48\0")
_T("Emu49 Document (*.E49)\0*.E49\0")
_T("Win48 Document (*.W48)\0*.W48\0")
_T("\0\0");
ofn.lpstrDefExt = _T("E48"); // HP48SX/GX
ofn.nFilterIndex = 3;
if (cCurrentRomType=='6' || cCurrentRomType=='A') // HP38G
{
if (cCurrentRomType=='6' || cCurrentRomType=='A') // HP38G
{
ofn.lpstrDefExt = "E38";
ofn.nFilterIndex = 1;
}
else
{
ofn.lpstrDefExt = "E48";
ofn.nFilterIndex = 2;
}
ofn.lpstrDefExt = _T("E38");
ofn.nFilterIndex = 1;
}
else // HP49G
if (cCurrentRomType=='E') // HP39/40G
{
ofn.lpstrDefExt = "E49";
ofn.nFilterIndex = 3;
ofn.lpstrDefExt = _T("E39");
ofn.nFilterIndex = 2;
}
if (cCurrentRomType=='X') // HP49G
{
ofn.lpstrDefExt = _T("E49");
ofn.nFilterIndex = 4;
}
ofn.lpstrFile = LocalAlloc(0,512);
ofn.lpstrFile[0] = 0;
@ -1073,28 +1103,28 @@ BOOL GetSaveAsFilename(VOID)
InitializeOFN(&ofn);
ofn.lpstrFilter =
"Emu38 Document (*.E38)\0*.E38\0"
"Emu48 Document (*.E48)\0*.E48\0"
"Emu49 Document (*.E49)\0*.E49\0"
"Win48 Document (*.W48)\0*.W48\0"
"\0\0";
if (cCurrentRomType!='X') // HP38G / HP48SX/GX
_T("Emu38 Document (*.E38)\0*.E38\0")
_T("Emu39 Document (*.E39)\0*.E39\0")
_T("Emu48 Document (*.E48)\0*.E48\0")
_T("Emu49 Document (*.E49)\0*.E49\0")
_T("Win48 Document (*.W48)\0*.W48\0")
_T("\0\0");
ofn.lpstrDefExt = _T("E48"); // HP48SX/GX
ofn.nFilterIndex = 3;
if (cCurrentRomType=='6' || cCurrentRomType=='A') // HP38G
{
if (cCurrentRomType=='6' || cCurrentRomType=='A') // HP38G
{
ofn.lpstrDefExt = "E38";
ofn.nFilterIndex = 1;
}
else
{
ofn.lpstrDefExt = "E48";
ofn.nFilterIndex = 2;
}
ofn.lpstrDefExt = _T("E38");
ofn.nFilterIndex = 1;
}
else // HP49G
if (cCurrentRomType=='E') // HP39/40G
{
ofn.lpstrDefExt = "E49";
ofn.nFilterIndex = 3;
ofn.lpstrDefExt = _T("E39");
ofn.nFilterIndex = 2;
}
if (cCurrentRomType=='X') // HP49G
{
ofn.lpstrDefExt = _T("E49");
ofn.nFilterIndex = 4;
}
ofn.lpstrFile = LocalAlloc(0,512);
ofn.lpstrFile[0] = 0;
@ -1115,7 +1145,7 @@ BOOL GetLoadObjectFilename(VOID)
OPENFILENAME ofn;
InitializeOFN(&ofn);
ofn.lpstrFilter = "All Files (*.*)\0*.*\0" "\0\0";
ofn.lpstrFilter = _T("All Files (*.*)\0*.*\0") _T("\0\0");
ofn.nFilterIndex = 1;
ofn.lpstrFile = LocalAlloc(0,512);
ofn.lpstrFile[0] = 0;
@ -1136,7 +1166,7 @@ BOOL GetSaveObjectFilename(VOID)
OPENFILENAME ofn;
InitializeOFN(&ofn);
ofn.lpstrFilter = "All Files (*.*)\0*.*\0" "\0\0";
ofn.lpstrFilter = _T("All Files (*.*)\0*.*\0") _T("\0\0");
ofn.nFilterIndex = 1;
ofn.lpstrFile = LocalAlloc(0,512);
ofn.lpstrFile[0] = 0;
@ -1160,7 +1190,7 @@ BOOL GetSaveObjectFilename(VOID)
//#
//################
BOOL LoadObject(LPCSTR szFilename) // separated stack writing part
BOOL LoadObject(LPCTSTR szFilename) // separated stack writing part
{
HANDLE hFile;
DWORD dwFileSizeLow;
@ -1188,16 +1218,16 @@ BOOL LoadObject(LPCSTR szFilename) // separated stack writing part
wError = WriteStack(lpBuf,dwFileSizeLow);
if (wError == S_ERR_BINARY)
AbortMessage("The HP48 has not enough free memory left to load this binary file.");
AbortMessage(_T("The HP48 has not enough free memory left to load this binary file."));
if (wError == S_ERR_ASCII)
AbortMessage("The HP48 has not enough free memory left to load this text file.");
AbortMessage(_T("The HP48 has not enough free memory left to load this text file."));
LocalFree(lpBuf);
return (wError == S_ERR_NO);
}
BOOL SaveObject(LPCSTR szFilename) // separated stack reading part
BOOL SaveObject(LPCTSTR szFilename) // separated stack reading part
{
HANDLE hFile;
LPBYTE pbyHeader;
@ -1208,7 +1238,7 @@ BOOL SaveObject(LPCSTR szFilename) // separated stack reading part
dwAddress = RPL_Pick(1);
if (dwAddress == 0)
{
AbortMessage("Too Few Arguments.");
AbortMessage(_T("Too Few Arguments."));
return FALSE;
}
dwLength = (RPL_SkipOb(dwAddress) - dwAddress + 1) / 2;
@ -1216,7 +1246,7 @@ BOOL SaveObject(LPCSTR szFilename) // separated stack reading part
hFile = CreateFile(szFilename, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_FLAG_SEQUENTIAL_SCAN, NULL);
if (hFile == INVALID_HANDLE_VALUE)
{
AbortMessage("Cannot open file.");
AbortMessage(_T("Cannot open file."));
return FALSE;
}
@ -1267,7 +1297,7 @@ static HPALETTE CreateBIPalette(LPBITMAPINFOHEADER lpbi)
return NULL;
// Get a pointer to the color table and the number of colors in it
pRgb = (RGBQUAD FAR *)((LPSTR)lpbi + (WORD)lpbi->biSize);
pRgb = (RGBQUAD FAR *)((LPBYTE)lpbi + (WORD)lpbi->biSize);
nNumColors = DibNumColors(lpbi);
if (nNumColors)
@ -1328,7 +1358,7 @@ static HPALETTE CreateBIPalette(LPBITMAPINFOHEADER lpbi)
return hpal;
}
HBITMAP LoadBitmapFile(LPCSTR szFilename)
HBITMAP LoadBitmapFile(LPCTSTR szFilename)
{
HANDLE hFile;
HANDLE hMap;

View file

@ -84,7 +84,7 @@ static VOID WrStateB8D(BYTE a, DWORD d);
static VOID WrState60(DWORD d);
static VOID WrState60D(BYTE a, DWORD d);
static CONST VOID (*CONST fnWrState[])(BYTE a, DWORD d) =
static VOID (*CONST fnWrState[])(BYTE a, DWORD d) =
{
WrStateIdle,
WrStateE8N, WrStateE8D, WrStateE8C,
@ -102,7 +102,7 @@ static BYTE RdStateQuery(DWORD d);
static BYTE RdStateSR(DWORD d);
static BYTE RdStateXSR(DWORD d);
static CONST BYTE (*CONST fnRdState[])(DWORD d) =
static BYTE (*CONST fnRdState[])(DWORD d) =
{
RdStateData, RdStateId, RdStateQuery, RdStateSR, RdStateXSR
};

View file

@ -8,6 +8,7 @@
*/
// I/O addresses without mapping offset
#define BITOFFSET 0x00 // Display bit offset and DON
#define CRC 0x04 // Crc (16 bit, LSB first)
#define ANNCTRL 0x0b // Annunciator Control (2 nibble)
#define BAUD 0x0d // Baudrate (Bit 2-0)
@ -25,11 +26,18 @@
#define SRQ2 0x19 // SRQ2
#define IR_CTRL 0x1a // IR CONTROL
#define LCR 0x1c // Led Control Register
#define LINECOUNT 0x28 // Display Line Counter
#define TIMER1_CTRL 0x2e // Timer1 Control
#define TIMER2_CTRL 0x2f // Timer2 Control
#define TIMER1 0x37 // Timer1 (4 bit)
#define TIMER2 0x38 // Timer2 (32 bit, LSB first)
// 0x00 Display bit offset and DON [DON OFF2 OFF1 OFF0]
#define DON 0x08 // Display On
#define OFF2 0x04 // Display OFFset Bit2
#define OFF1 0x02 // Display OFFset Bit1
#define OFF0 0x01 // Display OFFset Bit0
// 0x0b Annunciator Control [AON XTRA LA6 LA5] [LA4 LA3 LA2 LA1]
#define AON 0x80 // Annunciators on
#define LXTRA 0x40 // does nothing
@ -94,6 +102,18 @@
#define LBZ 0x02 // Led Port Busy
#define LBF 0x01 // Led Buffer Full
// 0x28 Display Line Counter LSB [LC3 LC2 LC1 LC0]
#define LC3 0x08 // LC3 - Line Counter Bit3
#define LC2 0x04 // LC2 - Line Counter Bit2
#define LC1 0x02 // LC1 - Line Counter Bit1
#define LC0 0x01 // LC0 - Line Counter Bit0
// 0x29 Display Line Counter MSB [DA19 M32 LC5 LC4]
#define DA19 0x08 // Drive A[19]
#define M32 0x04 // Multiplex 32 way
#define LC5 0x02 // LC5 - Line Counter Bit5
#define LC4 0x01 // LC4 - Line Counter Bit4
// 0x2e Timer1 Control [SRQ WKE INT XTRA]
#define SRQ 0x08 // Service request
#define WKE 0x04 // Wake up

View file

@ -83,7 +83,7 @@ VOID ScanKeyboard(BOOL bReset)
VOID KeyboardEvent(BOOL bPress, UINT out, UINT in)
{
if (nState != 0) // not in running state
if (nState != SM_RUN) // not in running state
return; // ignore key
if (in == 0x8000) // ON key ?
{

File diff suppressed because it is too large Load diff

View file

@ -41,19 +41,20 @@ typedef enum eTokenId
TOK_DEBUG, //25
TOK_COLOR, //26
TOK_MODEL, //27
TOK_PRESS, //28
TOK_TYPE, //29
TOK_SIZE, //30
TOK_DOWN, //31
TOK_ZOOM, //32
TOK_ELSE, //33
TOK_ONUP, //34
TOK_EOL, //35
TOK_MAP, //36
TOK_ROM, //37
TOK_LCD, //38
TOK_NOTFLAG, //39
TOK_END //40
TOK_CLASS, //28
TOK_PRESS, //29
TOK_TYPE, //30
TOK_SIZE, //31
TOK_DOWN, //32
TOK_ZOOM, //33
TOK_ELSE, //34
TOK_ONUP, //35
TOK_EOL, //36
TOK_MAP, //37
TOK_ROM, //38
TOK_LCD, //39
TOK_NOTFLAG, //40
TOK_END //41
} TokenId;
#define TYPE_NONE 00
@ -65,7 +66,7 @@ typedef struct Token
TokenId eId;
DWORD nParams;
DWORD nLen;
CHAR szName[20];
TCHAR szName[20];
} Token;
typedef struct Line
@ -110,10 +111,10 @@ extern Block* pKml;
extern BOOL DisplayChooseKml(CHAR cType);
extern VOID FreeBlocks(Block* pBlock);
extern VOID DrawAnnunciator(UINT nId, BOOL bOn);
extern VOID RefreshButtons();
extern VOID RefreshButtons(RECT *rc);
extern VOID MouseButtonDownAt(UINT nFlags, DWORD x, DWORD y);
extern VOID MouseButtonUpAt(UINT nFlags, DWORD x, DWORD y);
extern VOID MouseMovesTo(UINT nFlags, DWORD x, DWORD y);
extern VOID RunKey(BYTE nId, BOOL bPressed);
extern BOOL InitKML(LPCSTR szFilename, BOOL bNoLog);
extern VOID KillKML();
extern BOOL InitKML(LPCTSTR szFilename, BOOL bNoLog);
extern VOID KillKML(VOID);

View file

@ -8,6 +8,7 @@
*/
#include "pch.h"
#include "Emu48.h"
#include "ops.h"
#include "opcodes.h"
#include "io.h"
#include "i28f160.h" // flash support
@ -26,11 +27,7 @@
#define P2MAPBASE ((BYTE)(Chipset.P2Base & ~Chipset.P2Size))
#define BSMAPBASE ((BYTE)(Chipset.BSBase & ~Chipset.BSSize))
// values for mapping area
enum MMUMAP { M_IO, M_ROM, M_RAM, M_P1, M_P2, M_BS };
BOOL ioc_acc = FALSE; // flag ioc changed
BOOL ir_ctrl_acc = FALSE; // flag ir_ctl changed
BOOL bFlashRomArray = TRUE; // flag ROM mode
@ -51,6 +48,16 @@ static __inline VOID UpCRC(BYTE nib)
Chipset.crc = (WORD)((Chipset.crc>>4)^crc_table[(Chipset.crc^nib)&0xf]);
}
static __inline UINT MIN(UINT a, UINT b)
{
return (a<b)?a:b;
}
static __inline UINT MAX(UINT a, UINT b)
{
return (a>b)?a:b;
}
// generate UCK signal
static __inline BYTE UckBit(BYTE byBaudIndex)
{
@ -59,7 +66,7 @@ static __inline BYTE UckBit(BYTE byBaudIndex)
LARGE_INTEGER lLC;
_ASSERT(byBaudIndex < sizeof(dwBaudrates) / sizeof(dwBaudrates[0]));
_ASSERT(byBaudIndex < ARRAYSIZEOF(dwBaudrates));
QueryPerformanceCounter(&lLC); // get counter value
@ -82,6 +89,50 @@ static __inline DWORD FlashROMAddr(DWORD d)
return dwLinAddr;
}
// update display
static __inline VOID UpdateDisplay(DWORD d, UINT s)
{
BYTE p[16];
DWORD u;
UINT c;
// address in display main area?
if ((d<Chipset.end1)&&(d+s>Chipset.start12))
{
// write to display main area
u = d; // copy destination ptr
c = MIN(s,Chipset.end1-d); // number of nibbles to copy
if (d < Chipset.start12) // first address is out of display area
{
u = Chipset.start12; // set destination ptr to start of display area
c -= Chipset.start12 - d; // - number of bytes that aren't in display area
}
_ASSERT(c <= ARRAYSIZEOF(p));
Npeek(p,u,c); // get source data
WriteToMainDisplay(p,u,c);
}
// address in display menu area?
if ((d<Chipset.end2)&&(d+s>Chipset.start2))
{
// write to display menu area
u = d; // copy destination ptr
c = MIN(s,Chipset.end2-d); // number of nibbles to copy
if (d < Chipset.start2) // first address is out of display area
{
u = Chipset.start2; // set destination ptr to start of display area
c -= Chipset.start2 - d; // - number of bytes that are not in display area
}
_ASSERT(c <= ARRAYSIZEOF(p));
Npeek(p,u,c); // get source data
WriteToMenuDisplay(p,u,c);
}
return;
}
// LCD line counter calculation
static BYTE F4096Hz(VOID) // get a 6 bit 4096Hz down counter value
{
@ -93,43 +144,11 @@ static BYTE F4096Hz(VOID) // get a 6 bit 4096Hz down counter value
return -(BYTE)(((lLC.QuadPart - lAppStart.QuadPart) << 12) / lFreq.QuadPart) & 0x3F;
}
// port configuration
static enum MMUMAP MapData(DWORD d) // check MMU area
{
BYTE u = (BYTE) (d>>12);
if (Chipset.IOCfig && ((d&0xFFFC0)==Chipset.IOBase)) return M_IO;
if (Chipset.P0Cfig && (((u^Chipset.P0Base) & ~Chipset.P0Size) == 0)) return M_RAM;
if (cCurrentRomType=='S')
{
if (Chipset.P2Cfig && (((u^Chipset.P2Base) & ~Chipset.P2Size) == 0)) return M_P2;
if (Chipset.P1Cfig && (((u^Chipset.P1Base) & ~Chipset.P1Size) == 0)) return M_P1;
if (Chipset.BSCfig && (((u^Chipset.BSBase) & ~Chipset.BSSize) == 0)) return M_BS;
}
else
{
if (Chipset.P1Cfig && (((u^Chipset.P1Base) & ~Chipset.P1Size) == 0)) return M_P1;
if (Chipset.BSCfig && (((u^Chipset.BSBase) & ~Chipset.BSSize) == 0)) return M_BS;
if (Chipset.P2Cfig && (((u^Chipset.P2Base) & ~Chipset.P2Size) == 0)) return M_P2;
}
return M_ROM;
}
// port mapping
LPBYTE RMap[256] = {NULL,};
LPBYTE WMap[256] = {NULL,};
static __inline UINT MIN(UINT a, UINT b)
{
return (a<b)?a:b;
}
static __inline UINT MAX(UINT a, UINT b)
{
return (a>b)?a:b;
}
static VOID MapP0(BYTE a, BYTE b)
{
UINT i;
@ -163,7 +182,7 @@ static VOID MapBS(BYTE a, BYTE b)
// mapping area may have holes
if (((i ^ Chipset.BSBase) & ~Chipset.BSSize) == 0)
{
RMap[i]=NULL; // bugfix, no read cycle, open data bus
RMap[i]=NULL; // no read cycle, open data bus
WMap[i]=NULL;
}
}
@ -235,7 +254,7 @@ static VOID MapP2(BYTE a, BYTE b)
a = (BYTE)MAX(a,P2MAPBASE); // adjust base to mapping boundary
b = (BYTE)MIN(b,Chipset.P2End);
if (cCurrentRomType == 'X') // HP49G
if (Chipset.Port2Size) // internal port2
{
m = (Chipset.Port2Size*2048)-1;
p = (a<<12)&m; // offset to begin of P0 in nibbles
@ -280,7 +299,7 @@ static VOID MapP2(BYTE a, BYTE b)
// SX: CE2.2 = CE2
// GX: CE2.2 = BEN & /DA19 & /NCE3
if (cCurrentRomType == 'S' || ((Chipset.IORam[0x29]&0x8) == 0 && (Chipset.Bank_FF&0x40)))
if (cCurrentRomType == 'S' || ((Chipset.IORam[0x29]&DA19) == 0 && (Chipset.Bank_FF&0x40)))
{
if (bPort2Writeable)
{
@ -316,7 +335,8 @@ static VOID MapROM(BYTE a, BYTE b)
UINT i;
DWORD p, m;
if (cCurrentRomType == 'X') // HP49G
// HP39/49G, HP49G
if (cCurrentRomType == 'E' || cCurrentRomType == 'X')
{
if (bFlashRomArray) // view flash ROM data
{
@ -346,7 +366,7 @@ static VOID MapROM(BYTE a, BYTE b)
// HP38G / HP48SX / HP48GX
m = dwRomSize - 1; // ROM address mask for mirroring
// when 512KB ROM and DA19=0 (ROM disabled)
if ((m & 0x80000) != 0 && (Chipset.IORam[0x29]&0x8) == 0)
if ((m & 0x80000) != 0 && (Chipset.IORam[0x29]&DA19) == 0)
m >>= 1; // mirror ROM at #80000 (AR18=0)
p = (a*0x1000)&m; // data offset in nibbles
for (i=a;i<=b;i++) // scan each 2KB page
@ -360,12 +380,12 @@ static VOID MapROM(BYTE a, BYTE b)
VOID Map(BYTE a, BYTE b) // maps 2KB pages with priority
{
// On HP49G Chipset.cards_status must be 0xF
_ASSERT(cCurrentRomType!='X' || !Chipset.P1Cfig || Chipset.cards_status == 0xF);
// On HP39/40G and HP49G Chipset.cards_status must be 0xF
_ASSERT((cCurrentRomType!='E' && cCurrentRomType!='X') || !Chipset.P1Cfig || Chipset.cards_status == 0xF);
// priority order is HDW, RAM, CE2, CE1, NCE3, ROM
MapROM(a,b); // ROM, lowest priority, always mapped
if (cCurrentRomType=='S') // HP48SX
if (cCurrentRomType == 'S') // HP48SX
{
if (Chipset.BSCfig) MapBS(a,b); // NCE3, not used in S(X)
if (Chipset.P1Cfig) MapP1(a,b); // CE1, port1 (lower priority than CE2)
@ -390,7 +410,8 @@ VOID Map(BYTE a, BYTE b) // maps 2KB pages with priority
VOID RomSwitch(DWORD adr)
{
if (cCurrentRomType=='X') // only HP49G
// only HP39/40G, HP49G
if (cCurrentRomType=='E' || cCurrentRomType=='X')
{
Chipset.Bank_FF = adr; // save address line
adr = (adr >> 1) & 0x3f; // 6 bit of latch (was A6-A1 of address bus)
@ -607,18 +628,59 @@ VOID C_Eq_Id()
return;
}
enum MMUMAP MapData(DWORD d) // check MMU area
{
BYTE u = (BYTE) (d>>12);
if (Chipset.IOCfig && ((d&0xFFFC0)==Chipset.IOBase)) return M_IO;
if (Chipset.P0Cfig && (((u^Chipset.P0Base) & ~Chipset.P0Size) == 0)) return M_RAM;
if (cCurrentRomType == 'S')
{
if (Chipset.P2Cfig && (((u^Chipset.P2Base) & ~Chipset.P2Size) == 0)) return M_P2;
if (Chipset.P1Cfig && (((u^Chipset.P1Base) & ~Chipset.P1Size) == 0)) return M_P1;
if (Chipset.BSCfig && (((u^Chipset.BSBase) & ~Chipset.BSSize) == 0)) return M_BS;
}
else
{
if (Chipset.P1Cfig && (((u^Chipset.P1Base) & ~Chipset.P1Size) == 0)) return M_P1;
if (Chipset.BSCfig && (((u^Chipset.BSBase) & ~Chipset.BSSize) == 0)) return M_BS;
if (Chipset.P2Cfig && (((u^Chipset.P2Base) & ~Chipset.P2Size) == 0)) return M_P2;
}
return M_ROM;
}
VOID CpuReset(VOID) // register setting after Cpu Reset
{
StopTimers(); // stop timer, do here because function change Chipset.t2
Chipset.pc = 0;
Chipset.rstkp = 0;
FillMemory(Chipset.rstk,sizeof(Chipset.rstk),0);
ZeroMemory(Chipset.rstk,sizeof(Chipset.rstk));
Chipset.HST = 0;
Chipset.inte = TRUE;
Chipset.Shutdn = FALSE;
Chipset.SoftInt = TRUE;
Chipset.SoftInt = FALSE;
Chipset.Shutdn = TRUE;
Chipset.inte = TRUE; // enable interrupts
Chipset.intk = TRUE; // INTON
Chipset.intd = FALSE; // no keyboard interrupts pending
Chipset.crc = 0;
Chipset.Bank_FF = 0; // state of bank switcher FF
Chipset.FlashRomState = 0; // WSM state of flash memory
ZeroMemory(Chipset.IORam,sizeof(Chipset.IORam));
Reset(); // reset MMU
bInterrupt = TRUE;
Chipset.t1 = 0; // reset timer values
Chipset.t2 = 0;
Chipset.loffset = 0; // right margin
Chipset.boffset = 0; // left margin
Chipset.lcounter = 0; // number of main display lines
Chipset.contrast = 0; // contrast dark
Chipset.dispon = 0; // display off
UpdateContrast(Chipset.contrast); // update contrast
// display update when changing to run state
CommSetBaud(); // new baudrate
ioc_acc = TRUE; // new IOC value, close serial port
RomSwitch(Chipset.Bank_FF); // force new memory mapping
return;
}
@ -661,7 +723,7 @@ VOID Npeek(BYTE *a, DWORD d, UINT s)
v = d&0xFFF;
c = MIN(s,0x1000-v);
// Flash memory Read access
if (cCurrentRomType == 'X' && (Chipset.IORam[LCR] & LED) && M_P2 == eMap)
if (cCurrentRomType=='X' && (Chipset.IORam[LCR] & LED) && M_P2 == eMap)
{
FlashRead(a, FlashROMAddr(d), s);
}
@ -671,18 +733,16 @@ VOID Npeek(BYTE *a, DWORD d, UINT s)
{
memcpy(a, p+v, c);
}
// simulate open data bus
else // open data bus
{
for (u=0; u<c; ++u) // fill all nibbles
{
if (v+u & 1) // odd address
if ((v+u) & 1) // odd address
a[u] = READODD;
else // even address
a[u] = READEVEN;
}
}
// end of bugfix
}
}
if (s-=c) {a+=c; d+=c;}
@ -715,20 +775,20 @@ VOID Nread(BYTE *a, DWORD d, UINT s)
v = d&0xFFF;
c = MIN(s,0x1000-v);
// bank switcher access
if (cCurrentRomType != 'S' && M_BS == eMap)
if (cCurrentRomType!='S' && M_BS == eMap)
{
if (cCurrentRomType == 'G') // HP48GX
if (cCurrentRomType=='G') // HP48GX
{
Chipset.Bank_FF = v+c; // save FF value
Map(Chipset.P2Base,Chipset.P2End);
}
if (cCurrentRomType == 'X') // HP49G
if (cCurrentRomType=='E' || cCurrentRomType=='X') // HP39/40G, HP49G
{
RomSwitch(v+c);
}
}
// Flash memory Read access
if (cCurrentRomType == 'X' && (Chipset.IORam[LCR] & LED) && M_P2 == eMap)
if (cCurrentRomType=='X' && (Chipset.IORam[LCR] & LED) && M_P2 == eMap)
{
DWORD dwLinAddr = FlashROMAddr(d);
@ -736,8 +796,19 @@ VOID Nread(BYTE *a, DWORD d, UINT s)
#if defined DEBUG_FLASH
{
char buffer[256];
wsprintf(buffer,"%.5lx: Flash Read : %.5x (%.6x),%u\n",Chipset.pc,d,dwLinAddr,s);
TCHAR buffer[256];
DWORD j;
int i;
i = wsprintf(buffer,_T("%.5lx: Flash Read : %.5x (%.6x),%u = "),Chipset.pc,d,dwLinAddr,s);
for (j = 0;j < s;++j,++i)
{
buffer[i] = a[j];
if (buffer[i] > 9) buffer[i] += _T('a') - _T('9') - 1;
buffer[i] += _T('0');
}
buffer[i++] = _T('\n');
buffer[i] = 0;
OutputDebugString(buffer);
}
#endif
@ -753,7 +824,7 @@ VOID Nread(BYTE *a, DWORD d, UINT s)
{
for (u=0; u<c; ++u) // fill all nibbles
{
if (v+u & 1) // odd address
if ((v+u) & 1) // odd address
a[u] = READODD;
else // even address
a[u] = READEVEN;
@ -776,34 +847,6 @@ VOID Nwrite(BYTE *a, DWORD d, UINT s)
UINT c;
BYTE *p;
if ((d<Chipset.end1)&&(d+s>Chipset.start12))
{
p = a; // copy source ptr
u = d; // copy destination ptr
c = MIN(s,Chipset.end1-d); // number of nibbles to copy
if (d < Chipset.start12) // first address is out of display area
{
u = Chipset.start12; // set destination ptr to start of display area
c -= Chipset.start12 - d; // - number of bytes that aren't in display area
p += Chipset.start12 - d; // adjust source ptr
}
WriteToMainDisplay(p,u,c);
}
if ((d<Chipset.end2)&&(d+s>Chipset.start2))
{
p = a; // copy source ptr
u = d; // copy destination ptr
c = MIN(s,Chipset.end2-d); // number of nibbles to copy
if (d < Chipset.start2) // first address is out of display area
{
u = Chipset.start2; // set destination ptr to start of display area
c -= Chipset.start2 - d; // - number of bytes that are not in display area
p += Chipset.start2 - d; // adjust source ptr
}
WriteToMenuDisplay(p,u,c);
}
do
{
eMap = MapData(d); // get active memory controller
@ -819,7 +862,7 @@ VOID Nwrite(BYTE *a, DWORD d, UINT s)
v = d&0xFFF;
c = MIN(s,0x1000-v);
// bank switcher access
if (cCurrentRomType != 'S' && M_BS == eMap)
if (cCurrentRomType!='S' && M_BS == eMap)
{
BOOL bWrite = FALSE;
@ -837,7 +880,7 @@ VOID Nwrite(BYTE *a, DWORD d, UINT s)
bWrite = TRUE; // bank switched
}
if ((v+c & 1) != 0) // high address odd
if (((v+c) & 1) != 0) // high address odd
{
Chipset.Bank_FF = v+c-1;// save FF value
bWrite = TRUE; // bank switched
@ -847,13 +890,13 @@ VOID Nwrite(BYTE *a, DWORD d, UINT s)
if (bWrite) // write cycle?
{
// HP48GX
if (cCurrentRomType == 'G') Map(Chipset.P2Base,Chipset.P2End);
// HP49G
if (cCurrentRomType == 'X') RomSwitch(Chipset.Bank_FF);
if (cCurrentRomType=='G') Map(Chipset.P2Base,Chipset.P2End);
// HP39/40G, HP49G
if (cCurrentRomType=='E' || cCurrentRomType=='X') RomSwitch(Chipset.Bank_FF);
}
}
// Flash memory Write access
if (cCurrentRomType == 'X' && (Chipset.IORam[LCR] & LED) && M_P2 == eMap)
if (cCurrentRomType=='X' && (Chipset.IORam[LCR] & LED) && M_P2 == eMap)
{
DWORD dwLinAddr = FlashROMAddr(d);
@ -861,18 +904,18 @@ VOID Nwrite(BYTE *a, DWORD d, UINT s)
#if defined DEBUG_FLASH
{
char buffer[256];
TCHAR buffer[256];
DWORD j;
int i;
i = wsprintf(buffer,"%.5lx: Flash Write: %.5x (%.6x),%u = ",Chipset.pc,d,dwLinAddr,s);
i = wsprintf(buffer,_T("%.5lx: Flash Write: %.5x (%.6x),%u = "),Chipset.pc,d,dwLinAddr,s);
for (j = 0;j < s;++j,++i)
{
buffer[i] = a[j];
if (buffer[i] > 9) buffer[i] += 0x27;
buffer[i] += '0';
if (buffer[i] > 9) buffer[i] += _T('a') - _T('9') - 1;
buffer[i] += _T('0');
}
buffer[i++] = '\n';
buffer[i++] = _T('\n');
buffer[i] = 0;
OutputDebugString(buffer);
}
@ -883,6 +926,7 @@ VOID Nwrite(BYTE *a, DWORD d, UINT s)
if ((p=WMap[u]) != NULL) memcpy(p+v, a, c);
}
}
UpdateDisplay(d, c); // update display
a+=c;
d+=c;
} while (s-=c);
@ -891,7 +935,7 @@ VOID Nwrite(BYTE *a, DWORD d, UINT s)
DWORD Read5(DWORD d)
{
BYTE p[8];
BYTE p[5];
Npeek(p,d,5);
return Npack(p,5);
@ -907,7 +951,7 @@ BYTE Read2(DWORD d)
VOID Write5(DWORD d, DWORD n)
{
BYTE p[8];
BYTE p[5];
Nunpack(p,n,5);
Nwrite(p,d,5);
@ -945,8 +989,8 @@ VOID ReadIO(BYTE *a, DWORD d, DWORD s)
#if defined DEBUG_IO
{
char buffer[256];
wsprintf(buffer,"%.5lx: IO read : %02x,%u\n",Chipset.pc,d,s);
TCHAR buffer[256];
wsprintf(buffer,_T("%.5lx: IO read : %02x,%u\n"),Chipset.pc,d,s);
OutputDebugString(buffer);
}
#endif
@ -972,8 +1016,8 @@ VOID ReadIO(BYTE *a, DWORD d, DWORD s)
*a = Chipset.IORam[d] & 0x7;
#if defined DEBUG_SERIAL // return BAUD value
{
char buffer[256];
wsprintf(buffer,"%.5lx: BAUD Read: %x\n",Chipset.pc,*a);
TCHAR buffer[256];
wsprintf(buffer,_T("%.5lx: BAUD Read: %x\n"),Chipset.pc,*a);
OutputDebugString(buffer);
}
#endif
@ -996,8 +1040,8 @@ VOID ReadIO(BYTE *a, DWORD d, DWORD s)
}
else
{
// on a HP49G Chipset.cards_status bust always be 0xF
_ASSERT(cCurrentRomType!='X' || Chipset.cards_status == 0xF);
// on a HP30/40G and HP49G Chipset.cards_status bust always be 0xF
_ASSERT((cCurrentRomType!='E' && cCurrentRomType!='X') || Chipset.cards_status == 0xF);
*a = Chipset.cards_status;
}
break;
@ -1005,18 +1049,18 @@ VOID ReadIO(BYTE *a, DWORD d, DWORD s)
*a = Chipset.IORam[d]; // return IO CONTROL value
#if defined DEBUG_SERIAL
{
char buffer[256];
wsprintf(buffer,"%.5lx: IOC Read: %x\n",Chipset.pc,*a);
TCHAR buffer[256];
wsprintf(buffer,_T("%.5lx: IOC Read: %x\n"),Chipset.pc,*a);
OutputDebugString(buffer);
}
#endif
break;
case 0x11: // RCS
*a = Chipset.IORam[d]; // return RCS value
*a = Chipset.IORam[d] | RX; // return RCS value
#if defined DEBUG_SERIAL
{
char buffer[256];
wsprintf(buffer,"%.5lx: RCS Read: %x\n",Chipset.pc,*a);
TCHAR buffer[256];
wsprintf(buffer,_T("%.5lx: RCS Read: %x\n"),Chipset.pc,*a);
OutputDebugString(buffer);
}
#endif
@ -1025,8 +1069,8 @@ VOID ReadIO(BYTE *a, DWORD d, DWORD s)
*a = Chipset.IORam[d]; // return TCS value
#if defined DEBUG_SERIAL
{
char buffer[256];
wsprintf(buffer,"%.5lx: TCS Read: %x\n",Chipset.pc,*a);
TCHAR buffer[256];
wsprintf(buffer,_T("%.5lx: TCS Read: %x\n"),Chipset.pc,*a);
OutputDebugString(buffer);
}
#endif
@ -1042,16 +1086,14 @@ VOID ReadIO(BYTE *a, DWORD d, DWORD s)
rbr_acc = TRUE; // search for new RBR value
#if defined DEBUG_SERIAL
{
char buffer[256];
wsprintf(buffer,"%.5lx: RBR %s Read: %x\n",Chipset.pc,(d==0x14) ? "LSB" : "MSB",*a);
TCHAR buffer[256];
wsprintf(buffer,_T("%.5lx: RBR %s Read: %x\n"),Chipset.pc,(d==0x14) ? "LSB" : "MSB",*a);
OutputDebugString(buffer);
}
#endif
break;
case 0x16: // TBR LSB
case 0x17: // TBR MSB
*a = 0;
break;
// case 0x16: *a = Chipset.IORam[d]; break; // TBR LSB
// case 0x17: *a = Chipset.IORam[d]; break; // TBR MSB
case 0x19: // SREQ? MSB
UpdateKdnBit(); // update KDN bit
bNINT2 = Chipset.IORam[SRQ1] == 0 && (Chipset.IORam[SRQ2] & LSRQ) == 0;
@ -1071,18 +1113,24 @@ VOID ReadIO(BYTE *a, DWORD d, DWORD s)
*a = Chipset.IORam[d]; // return SREQ value
#if defined DEBUG_SERIAL
{
char buffer[256];
wsprintf(buffer,"%.5lx: SEQ %s Read: %x\n",Chipset.pc,(d==0x18) ? "LSB" : "MSB",*a);
TCHAR buffer[256];
wsprintf(buffer,_T("%.5lx: SEQ %s Read: %x\n"),Chipset.pc,(d==0x18) ? "LSB" : "MSB",*a);
OutputDebugString(buffer);
}
#endif
break;
case 0x1A: // IR CONTROL
if (cCurrentRomType=='E') // HP39/40G
{
Chipset.IORam[d] = (nCurrentClass != 40)
? (Chipset.IORam[d] & ~IRI) // HP39G
: (Chipset.IORam[d] | IRI); // HP40G
}
*a = Chipset.IORam[d]; // return IR CONTROL value
#if defined DEBUG_SERIAL
{
char buffer[256];
wsprintf(buffer,"%.5lx: IRC Read: %x\n",Chipset.pc,*a);
TCHAR buffer[256];
wsprintf(buffer,_T("%.5lx: IRC Read: %x\n"),Chipset.pc,*a);
OutputDebugString(buffer);
}
#endif
@ -1090,8 +1138,8 @@ VOID ReadIO(BYTE *a, DWORD d, DWORD s)
case 0x1B: *a = 0; break;
case 0x1C: *a = 0; break; // LED CONTROL
case 0x1D: *a = 0; break; // LED BUFFER
// case 0x1E: *a = Chipset.IORam[0x1E]; break;
// case 0x1F: *a = Chipset.IORam[0x1F]; break;
// case 0x1E: *a = Chipset.IORam[d]; break;
// case 0x1F: *a = Chipset.IORam[d]; break;
case 0x20: *a = 3; break;
case 0x21: *a = 3; break;
case 0x22: *a = 3; break;
@ -1102,14 +1150,14 @@ VOID ReadIO(BYTE *a, DWORD d, DWORD s)
case 0x27: *a = 3; break;
case 0x28: // LINECOUNT LSB
case 0x29: // LINECOUNT MSB + DA19 M32
if (Chipset.IORam[0x00]&8) // display on
if (Chipset.IORam[0x00]&DON) // display on
{
if (c == 0xFF) // no actual line information
{
c = GetLineCounter(); // get LCD update line
// save line information in IO registers
Chipset.IORam[0x28] = c & 0xF;
Chipset.IORam[0x29] = (Chipset.IORam[0x29] & 0xC) | (c >> 4);
Chipset.IORam[0x29] = (Chipset.IORam[0x29] & (DA19|M32)) | (c >> 4);
}
}
*a = Chipset.IORam[d];
@ -1162,28 +1210,26 @@ VOID WriteIO(BYTE *a, DWORD d, DWORD s)
{
DWORD b;
BYTE c;
BOOL tbr_acc = FALSE; // flag to transmit data
BOOL bDISPADDR = FALSE; // flag addr 0x120-0x124 changed
BOOL bLINEOFFS = FALSE; // flag addr 0x125-0x127 changed
BOOL bLINECOUNT = FALSE; // flag addr 0x128-0x129 changed
BOOL bMENUADDR = FALSE; // flag addr 0x130-0x134 changed
BOOL tbr_acc = FALSE; // flag to transmit data
BOOL bDISPADDR = FALSE; // flag addr 0x120-0x124 changed
BOOL bLINEOFFS = FALSE; // flag addr 0x125-0x127 changed
BOOL bMENUADDR = FALSE; // flag addr 0x130-0x134 changed
#if defined DEBUG_IO
{
char buffer[256];
TCHAR buffer[256];
DWORD j;
int i;
i = wsprintf(buffer,"%.5lx: IO write: %02x,%u = ",Chipset.pc,d,s);
i = wsprintf(buffer,_T("%.5lx: IO write: %02x,%u = "),Chipset.pc,d,s);
for (j = 0;j < s;++j,++i)
{
buffer[i] = a[j];
if (buffer[i] > 9) buffer[i] += 0x27;
buffer[i] += '0';
if (buffer[i] > 9) buffer[i] += _T('a') - _T('9') - 1;
buffer[i] += _T('0');
}
buffer[i++] = '\n';
buffer[i++] = _T('\n');
buffer[i] = 0;
OutputDebugString(buffer);
}
#endif
@ -1204,7 +1250,7 @@ VOID WriteIO(BYTE *a, DWORD d, DWORD s)
// 00100 @ Display bit offset and DON [DON OFF2 OFF1 OFF0]
// 00100 @ 3 nibs for display offset (scrolling), DON=Display ON
case 0x00:
if ((c^Chipset.IORam[d])&8) // DON bit changed
if ((c^Chipset.IORam[d])&DON) // DON bit changed
{
Chipset.dispon = c>>3;
disp |= (DISP_POINTER | DISP_MAIN | DISP_MENUE);
@ -1224,9 +1270,10 @@ VOID WriteIO(BYTE *a, DWORD d, DWORD s)
ReadIO(a,0x28,2); // update VBL at display off time
}
}
if ((c^Chipset.IORam[d])&7) // OFF bits changed
// OFF bits changed
if ((c^Chipset.IORam[d]) & (OFF2 | OFF1 | OFF0))
{
Chipset.boffset = c&7;
Chipset.boffset = c & (OFF2 | OFF1 | OFF0);
disp |= (DISP_POINTER | DISP_MAIN);
}
Chipset.IORam[d] = c;
@ -1301,8 +1348,8 @@ VOID WriteIO(BYTE *a, DWORD d, DWORD s)
CommSetBaud(); // set baudrate
#if defined DEBUG_SERIAL
{
char buffer[256];
wsprintf(buffer,"%.5lx: BAUD write: %x\n",Chipset.pc,Chipset.IORam[d]);
TCHAR buffer[256];
wsprintf(buffer,_T("%.5lx: BAUD write: %x\n"),Chipset.pc,Chipset.IORam[d]);
OutputDebugString(buffer);
}
#endif
@ -1362,13 +1409,23 @@ VOID WriteIO(BYTE *a, DWORD d, DWORD s)
// 00110 @ Serial I/O Control [SON ETBE ERBF ERBZ]
// 00110 @ Serial On, Interrupt On Recv.Buf.Empty, Full, Buzy
case 0x10:
if ((c & SON) == 0) // SON bit cleared
{
c = 0; // clear IOC
Chipset.IORam[RCS] = 0; // clear RCS
Chipset.IORam[TCS] = 0; // clear TCS
Chipset.IORam[RBR_LSB] = 0; // clear RBR
Chipset.IORam[RBR_MSB] = 0;
Chipset.IORam[TBR_LSB] = 0; // clear TBR
Chipset.IORam[TBR_MSB] = 0;
}
Chipset.IORam[d]=c;
UpdateUSRQ(); // update USRQ
ioc_acc = TRUE; // new IOC value
#if defined DEBUG_SERIAL
{
char buffer[256];
wsprintf(buffer,"%.5lx: IOC write: %x\n",Chipset.pc,Chipset.IORam[d]);
TCHAR buffer[256];
wsprintf(buffer,_T("%.5lx: IOC write: %x\n"),Chipset.pc,Chipset.IORam[d]);
OutputDebugString(buffer);
}
#endif
@ -1377,27 +1434,33 @@ VOID WriteIO(BYTE *a, DWORD d, DWORD s)
// 00111 = HP:RCS
// 00111 Serial Receive Control/Status [RX RER RBZ RBF] (bit 3 is read-only)
case 0x11:
Chipset.IORam[d]=(Chipset.IORam[d]&8)|(c&7);
#if defined DEBUG_SERIAL
if (Chipset.IORam[IOC] & SON)
{
char buffer[256];
wsprintf(buffer,"%.5lx: RCS write: %x\n",Chipset.pc,Chipset.IORam[d]);
OutputDebugString(buffer);
Chipset.IORam[d]=(Chipset.IORam[d]&8)|(c&7);
#if defined DEBUG_SERIAL
{
TCHAR buffer[256];
wsprintf(buffer,_T("%.5lx: RCS write: %x\n"),Chipset.pc,Chipset.IORam[d]);
OutputDebugString(buffer);
}
#endif
}
#endif
break;
// 00112 = HP:TCS
// 00112 @ Serial Transmit Control/Status [BRK LPB TBZ TBF]
case 0x12:
Chipset.IORam[d]=c;
#if defined DEBUG_SERIAL
if (Chipset.IORam[IOC] & SON)
{
char buffer[256];
wsprintf(buffer,"%.5lx: TCS write: %x\n",Chipset.pc,Chipset.IORam[d]);
OutputDebugString(buffer);
Chipset.IORam[d]=c;
#if defined DEBUG_SERIAL
{
TCHAR buffer[256];
wsprintf(buffer,_T("%.5lx: TCS write: %x\n"),Chipset.pc,Chipset.IORam[d]);
OutputDebugString(buffer);
}
#endif
}
#endif
break;
// 00113 = HP:CRER
@ -1406,8 +1469,8 @@ VOID WriteIO(BYTE *a, DWORD d, DWORD s)
Chipset.IORam[RCS]&=~RER;
#if defined DEBUG_SERIAL
{
char buffer[256];
wsprintf(buffer,"%.5lx: CRER write: %x\n",Chipset.pc,Chipset.IORam[d]);
TCHAR buffer[256];
wsprintf(buffer,_T("%.5lx: CRER write: %x\n"),Chipset.pc,Chipset.IORam[d]);
OutputDebugString(buffer);
}
#endif
@ -1423,17 +1486,20 @@ VOID WriteIO(BYTE *a, DWORD d, DWORD s)
// 00116 @ Serial Transmit Buffer Register (Writing sets TBF bit)
case 0x16:
case 0x17:
Chipset.IORam[d]=c;
Chipset.IORam[TCS]|=TBF;
UpdateUSRQ(); // update USRQ
tbr_acc = TRUE; // new TBR value
#if defined DEBUG_SERIAL
if (Chipset.IORam[IOC] & SON)
{
char buffer[256];
wsprintf(buffer,"%.5lx: TBR %s write: %x\n",Chipset.pc,(d==0x16) ? "LSB" : "MSB",*a);
OutputDebugString(buffer);
Chipset.IORam[d]=c;
Chipset.IORam[TCS]|=TBF;
UpdateUSRQ(); // update USRQ
tbr_acc = TRUE; // new TBR value
#if defined DEBUG_SERIAL
{
TCHAR buffer[256];
wsprintf(buffer,_T("%.5lx: TBR %s write: %x\n"),Chipset.pc,(d==0x16) ? "LSB" : "MSB",*a);
OutputDebugString(buffer);
}
#endif
}
#endif
break;
// 00118 = NS:SRR
@ -1446,12 +1512,19 @@ VOID WriteIO(BYTE *a, DWORD d, DWORD s)
// 0011A @ IR Control Register [IRI EIRU EIRI IRE] (bit 3 is read-only)
// 0011A @ IR Input, Enable IR UART mode, Enable IR Interrupt, IR Event
case 0x1A:
// COM port open and EIRU bit changed
if (bCommInit && ((c^Chipset.IORam[d]) & EIRU) != 0)
{
// save new value for COM open
Chipset.IORam[d]=(Chipset.IORam[d]&8)|(c&7);
// reopen COM port with new setting
bCommInit = CommOpen(szSerialWire,szSerialIr);
}
Chipset.IORam[d]=(Chipset.IORam[d]&8)|(c&7);
ir_ctrl_acc = TRUE; // new IR_CTRL value
#if defined DEBUG_SERIAL
{
char buffer[256];
wsprintf(buffer,"%.5lx: IRC write: %x\n",Chipset.pc,Chipset.IORam[d]);
TCHAR buffer[256];
wsprintf(buffer,_T("%.5lx: IRC write: %x\n"),Chipset.pc,Chipset.IORam[d]);
OutputDebugString(buffer);
}
#endif
@ -1471,8 +1544,8 @@ VOID WriteIO(BYTE *a, DWORD d, DWORD s)
Map(Chipset.P2Base,Chipset.P2End); // new ROM mapping
#if defined DEBUG_FLASH
{
char buffer[256];
wsprintf(buffer,"%.5lx: NCE3: R%cM\n",Chipset.pc,(c&LED) ? 'O' : 'A');
TCHAR buffer[256];
wsprintf(buffer,_T("%.5lx: NCE3: R%cM\n"),Chipset.pc,(c&LED) ? 'O' : 'A');
OutputDebugString(buffer);
}
#endif
@ -1501,7 +1574,7 @@ VOID WriteIO(BYTE *a, DWORD d, DWORD s)
case 0x23:
case 0x24:
Chipset.IORam[d]=c;
bDISPADDR = TRUE; // addr 0x120-0x124 changed
bDISPADDR = TRUE; // addr 0x120-0x124 changed
break;
// 00125 = NS:LINEOFFS
@ -1511,7 +1584,7 @@ VOID WriteIO(BYTE *a, DWORD d, DWORD s)
case 0x26:
case 0x27:
Chipset.IORam[d]=c;
bLINEOFFS = TRUE; // addr 0x125-0x127 changed
bLINEOFFS = TRUE; // addr 0x125-0x127 changed
break;
// 00128 = NS:LINECOUNT
@ -1520,17 +1593,28 @@ VOID WriteIO(BYTE *a, DWORD d, DWORD s)
// 00128 @ Line counter 6 bits -> max = 2^6-1 = 63 = disp height
// 00128 @ Normally has 55 -> Menu starts at display row 56
case 0x28:
case 0x29:
if (d == 0x29)
// LSB of LINECOUNT changed
if (c != (BYTE) (Chipset.lcounter & 0xf))
{
if ((c^Chipset.IORam[d])&8) // DA19 changed
{
Chipset.IORam[d]=c; // save new DA19
Map(0x00,0xFF); // new ROM mapping
}
Chipset.lcounter = (Chipset.lcounter & ~0xF) | c;
disp |= (DISP_POINTER | DISP_MAIN | DISP_MENUE);
}
break;
case 0x29:
// MSB of LINECOUNT changed
b = (c & 0x3) << 4; // upper two bits
if (b != (Chipset.lcounter & 0x30))
{
Chipset.lcounter = (Chipset.lcounter & ~0x30) | b;
disp |= (DISP_POINTER | DISP_MAIN | DISP_MENUE);
}
if ((c^Chipset.IORam[d])&DA19) // DA19 changed
{
Chipset.IORam[d]^=DA19; // save new DA19
Map(0x00,0xFF); // new ROM mapping
}
Chipset.IORam[d]=c;
bLINECOUNT = TRUE; // addr 0x128-0x129 changed
break;
case 0x2A: break;
@ -1606,15 +1690,6 @@ VOID WriteIO(BYTE *a, DWORD d, DWORD s)
disp |= (DISP_POINTER | DISP_MAIN);
}
}
if (bLINECOUNT) // addr 0x128-0x129 changed
{
b = Npack(Chipset.IORam+0x28,2)&0x3F;
if (Chipset.lcounter != b)
{
Chipset.lcounter = b;
disp |= (DISP_POINTER | DISP_MAIN | DISP_MENUE);
}
}
if (bMENUADDR) // addr 0x130-0x134 changed
{
b = Npack(Chipset.IORam+0x30,5)&0xFFFFE;

View file

@ -1001,30 +1001,48 @@ VOID o807(LPBYTE I) // SHUTDN
{
BOOL bShutdn = TRUE; // shut down
w.cycles+=5;
w.pc+=3;
// only shut down when no timer wake up
if (w.IORam[0x2E]&0x04) // WKE bit of timer1 is set
if (w.IORam[TIMER1_CTRL]&WKE) // WKE bit of timer1 is set
{
if (ReadT1()&0x08) // and MSB of timer1 is set
{
w.IORam[0x2E] &= ~0x04; // clear WKE
w.IORam[TIMER1_CTRL] &= ~WKE; // clear WKE
bShutdn = FALSE; // don't shut down
}
}
if (w.IORam[0x2F]&0x04) // WKE bit of timer2 is set
if (w.IORam[TIMER2_CTRL]&WKE) // WKE bit of timer2 is set
{
if (ReadT2()&0x80000000) // and MSB of timer2 is set
{
w.IORam[0x2F] &= ~0x04; // clear WKE
w.IORam[TIMER2_CTRL] &= ~WKE; // clear WKE
bShutdn = FALSE; // don't shut down
}
}
if (w.in==0 && bShutdn) // changed, shut down only when enabled
if (w.in==0 && bShutdn) // shut down only when enabled
{
w.Shutdn = TRUE; // set mode before exit emulation loop
bInterrupt = TRUE;
// emulation of BS reset circuit in deep sleep
// HP39/40G, HP48GX, HP49G, display off, card control off or in slow mode
if ( (cCurrentRomType=='E' || cCurrentRomType=='G' || cCurrentRomType=='X')
&& (w.IORam[BITOFFSET]&DON) == 0
&& ((w.IORam[CARDCTL]&(ECDT|RCDT)) != (ECDT|RCDT)))
{
// on HP48GX ROM must be selected (DA19=1) and
// the NOT MA18 address line must be low (test for high)
// else we get power on VCO from the ROM chip
// (MA18 input pin security diode to VCC pin)
if ( cCurrentRomType!='G'
|| ((w.IORam[LINECOUNT+1]&DA19) && (w.pc & 0x80000)))
{
w.Bank_FF = 0; // reset bank switcher FF
RomSwitch(w.Bank_FF); // force new mapping
}
}
}
w.cycles+=5;
w.pc+=3;
return;
}
@ -1082,7 +1100,7 @@ VOID o8083(LPBYTE I) // BUSCB
w.cycles+=7;
w.pc+=4;
// emulated as NOP
// InfoMessage("BUSCB instruction executed.");
// InfoMessage(_T("BUSCB instruction executed."));
return;
}
@ -1164,7 +1182,7 @@ VOID o808D(LPBYTE I) // BUSCD
w.cycles+=7;
w.pc+=4;
// emulated as NOP
// InfoMessage("BUSCD instruction executed.");
// InfoMessage(_T("BUSCD instruction executed."));
return;
}
@ -1207,7 +1225,7 @@ VOID o80B(LPBYTE I) // BUSCC
w.cycles+=6;
w.pc+=3;
// emulated as NOP
// InfoMessage("BUSCC instruction executed.");
// InfoMessage(_T("BUSCC instruction executed."));
return;
}
@ -1233,7 +1251,7 @@ VOID o80E(LPBYTE I) // SREQ?
w.cycles+=7;
w.pc+=3;
w.C[0]=0;
InfoMessage("SREQ? instruction executed.");
// InfoMessage(_T("SREQ? instruction executed."));
return;
}
@ -2092,7 +2110,7 @@ VOID o8BF(LPBYTE I) // ?D<=C A
VOID o8Cd4(LPBYTE I) // GOLONG #dddd
{
DWORD d=Npack(I+2, 4);
if (d&0x8000) w.pc-=0xfffe-d; else w.pc+=d+2;
if (d&0x8000) w.pc -= 0xfffe - d; else w.pc+= d + 2;
w.cycles+=14;
w.pc&=0xFFFFF;
return;
@ -2109,7 +2127,7 @@ VOID o8Ed4(LPBYTE I) // GOSUBL #dddd
{
DWORD d=Npack(I+2,4);
rstkpush(w.pc+6);
if (d&0x8000) w.pc-=0xfffa-d; else w.pc+=d+6;
if (d&0x8000) w.pc -= 0xfffa - d; else w.pc += d + 6;
w.cycles+=14;
w.pc&=0xFFFFF;
return;
@ -2363,14 +2381,6 @@ VOID oFD(LPBYTE I) { w.cycles+=7; w.pc+=2; Nnot(w.B, 5); return; }
VOID oFE(LPBYTE I) { w.cycles+=7; w.pc+=2; Nnot(w.C, 5); return; }
VOID oFF(LPBYTE I) { w.cycles+=7; w.pc+=2; Nnot(w.D, 5); return; }
// invalid, unknown length (LPBYTE I) reset
VOID o_invalid(LPBYTE I)
{
_ASSERT(FALSE); // invalid, unknow length
w.pc=0;
return;
}
// length is guessed, just skip
VOID o_invalid3(LPBYTE I)
{
@ -2423,15 +2433,7 @@ VOID o_goyes5(LPBYTE I)
}
//////// EXTENSIONS ////////
#if 0 // unused extension
VOID o81B0(LPBYTE I)
// ?Win48
w.HST |= SB;
w.pc+=4;
return;
#endif
VOID o81B1(LPBYTE I)
VOID o81B1(LPBYTE I) // beep patch
{
External(&w);
PCHANGED; // update field select table

View file

@ -436,7 +436,6 @@ extern VOID oFD(LPBYTE I); // B=-B-1 A
extern VOID oFE(LPBYTE I); // C=-C-1 A
extern VOID oFF(LPBYTE I); // D=-D-1 A
extern VOID o_invalid(LPBYTE I);
extern VOID o_invalid3(LPBYTE I);
extern VOID o_invalid4(LPBYTE I);
extern VOID o_invalid5(LPBYTE I);
@ -445,4 +444,4 @@ extern VOID o_invalid6(LPBYTE I);
extern VOID o_goyes3(LPBYTE I);
extern VOID o_goyes5(LPBYTE I);
extern VOID o81B1(LPBYTE I);
extern VOID o81B1(LPBYTE I); // beep patch

View file

@ -6,7 +6,6 @@
* Copyright (C) 1995 Sebastien Carlier
*
*/
// #pragma warning(disable:4244)
#define NFunpack(a, b, f) Nunpack((a)+F_s[f], b, F_l[f])
#define NFread(a, b, f) Nread((a)+F_s[f], b, F_l[f])
@ -74,7 +73,7 @@ static __inline DWORD rstkpop()
return r;
}
__inline DWORD Npack(BYTE *a, UINT s)
static __inline DWORD Npack(BYTE *a, UINT s)
{
DWORD r = 0;
@ -82,7 +81,7 @@ __inline DWORD Npack(BYTE *a, UINT s)
return r;
}
__inline VOID Nunpack(BYTE *a, DWORD b, UINT s)
static __inline VOID Nunpack(BYTE *a, DWORD b, UINT s)
{
UINT i;
for (i=0; i<s; i++) { a[i] = (BYTE)(b&0xf); b>>=4; }
@ -288,7 +287,7 @@ static __inline void Nneg(BYTE *a, UINT s)
BYTE cBase = Chipset.mode_dec ? 10 : 16;
for (i=0; i<s && a[i]==0; ++i) { } // search for non-zero digit
if (Chipset.carry = (i!=s)) // value was non-zero
if ((Chipset.carry = (i!=s))) // value was non-zero
{
a[i] = cBase - a[i]; // first non-zero digit
if ((a[i] & 0xF0) != 0) // check overflow (dec mode only)

View file

@ -3,7 +3,9 @@
//
#include <windows.h>
#include <tchar.h>
#include <shellapi.h>
#include <commctrl.h>
#include <stdlib.h>
#include <stdio.h>
#include <direct.h>

View file

@ -5,19 +5,22 @@
#define IDI_EMU48 100
#define IDR_MENU 101
#define IDR_DEBUG 102
#define IDR_DEBUG_CODE 103
#define IDR_DEBUG_MEM 104
#define IDD_ABOUT 105
#define IDD_SETTINGS 106
#define IDD_CHOOSEKML 107
#define IDD_KMLLOG 108
#define IDD_DISASM 109
#define IDD_DEBUG 110
#define IDD_NEWVALUE 111
#define IDD_ENTERADR 112
#define IDD_BREAKEDIT 113
#define IDD_ENTERBREAK 114
#define IDD_INSTRUCTIONS 115
#define IDR_DEBUG_TOOLBAR 103
#define IDR_DEBUG_CODE 104
#define IDR_DEBUG_MEM 105
#define IDD_ABOUT 106
#define IDD_SETTINGS 107
#define IDD_CHOOSEKML 108
#define IDD_KMLLOG 109
#define IDD_DISASM 110
#define IDD_DEBUG 111
#define IDD_NEWVALUE 112
#define IDD_ENTERADR 113
#define IDD_BREAKEDIT 114
#define IDD_ENTERBREAK 115
#define IDD_INSTRUCTIONS 116
#define IDD_FIND 117
#define IDB_CHECKBOX 120
#define IDC_PORT1WR 1000
#define IDC_AUTOSAVE 1001
#define IDC_AUTOSAVEONEXIT 1002
@ -45,80 +48,83 @@
#define IDC_DISASM_MODULE 1024
#define IDC_DISASM_HP 1025
#define IDC_DISASM_CLASS 1026
#define IDC_DISASM_MNEMONICS 1027
#define IDC_ADDRESS 1028
#define IDC_DISASM_ADR 1029
#define IDC_DISASM_NEXT 1030
#define IDC_DISASM_COPY 1031
#define IDC_DEBUG_CODE 1032
#define IDC_STATIC_CODE 1033
#define IDC_STATIC_REGISTERS 1034
#define IDC_STATIC_MEMORY 1035
#define IDC_STATIC_STACK 1036
#define IDC_REG_A 1037
#define IDC_REG_B 1038
#define IDC_REG_C 1039
#define IDC_REG_D 1040
#define IDC_REG_R0 1041
#define IDC_REG_R1 1042
#define IDC_REG_R2 1043
#define IDC_REG_R3 1044
#define IDC_REG_R4 1045
#define IDC_REG_D0 1046
#define IDC_REG_D1 1047
#define IDC_REG_P 1048
#define IDC_REG_PC 1049
#define IDC_REG_OUT 1050
#define IDC_REG_IN 1051
#define IDC_REG_ST 1052
#define IDC_REG_CY 1053
#define IDC_REG_MODE 1054
#define IDC_REG_MP 1055
#define IDC_REG_SR 1056
#define IDC_REG_SB 1057
#define IDC_REG_XM 1058
#define IDC_MISC_INT 1059
#define IDC_MISC_KEY 1060
#define IDC_MISC_BS 1061
#define IDC_NEWVALUE 1062
#define IDC_ENTERADR 1063
#define IDC_DEBUG_MEM 1064
#define IDC_DEBUG_MEM_ADDR 1065
#define IDC_DEBUG_MEM_COL0 1066
#define IDC_DEBUG_MEM_COL1 1067
#define IDC_DEBUG_MEM_COL2 1068
#define IDC_DEBUG_MEM_COL3 1069
#define IDC_DEBUG_MEM_COL4 1070
#define IDC_DEBUG_MEM_COL5 1071
#define IDC_DEBUG_MEM_COL6 1072
#define IDC_DEBUG_MEM_COL7 1073
#define IDC_DEBUG_MEM_TEXT 1074
#define IDC_DEBUG_STACK 1075
#define IDC_STATIC_BREAKPOINT 1076
#define IDC_BREAKEDIT_ADD 1077
#define IDC_BREAKEDIT_DELETE 1078
#define IDC_BREAKEDIT_WND 1079
#define IDC_STATIC_MMU 1080
#define IDC_MMU_IO_A 1081
#define IDC_MMU_NCE2_A 1082
#define IDC_MMU_CE1_A 1083
#define IDC_MMU_CE2_A 1084
#define IDC_MMU_NCE3_A 1085
#define IDC_MMU_IO_S 1086
#define IDC_MMU_CE1_S 1087
#define IDC_MMU_CE2_S 1088
#define IDC_MMU_NCE2_S 1089
#define IDC_MMU_NCE3_S 1090
#define IDC_STATIC_MISC 1091
#define IDC_MISC_BS_TXT 1092
#define IDC_INSTR_TEXT 1093
#define IDC_INSTR_CODE 1094
#define IDC_INSTR_COPY 1095
#define IDC_INSTR_CLEAR 1096
#define IDC_BPCODE 1097
#define IDC_ADDRESS 1027
#define IDC_DISASM_ADR 1028
#define IDC_DISASM_NEXT 1029
#define IDC_DISASM_COPY 1030
#define IDC_DEBUG_CODE 1031
#define IDC_STATIC_CODE 1032
#define IDC_STATIC_REGISTERS 1033
#define IDC_STATIC_MEMORY 1034
#define IDC_STATIC_STACK 1035
#define IDC_REG_A 1036
#define IDC_REG_B 1037
#define IDC_REG_C 1038
#define IDC_REG_D 1039
#define IDC_REG_R0 1040
#define IDC_REG_R1 1041
#define IDC_REG_R2 1042
#define IDC_REG_R3 1043
#define IDC_REG_R4 1044
#define IDC_REG_D0 1045
#define IDC_REG_D1 1046
#define IDC_REG_P 1047
#define IDC_REG_PC 1048
#define IDC_REG_OUT 1049
#define IDC_REG_IN 1050
#define IDC_REG_ST 1051
#define IDC_REG_CY 1052
#define IDC_REG_MODE 1053
#define IDC_REG_MP 1054
#define IDC_REG_SR 1055
#define IDC_REG_SB 1056
#define IDC_REG_XM 1057
#define IDC_MISC_INT 1058
#define IDC_MISC_KEY 1059
#define IDC_MISC_BS 1060
#define IDC_NEWVALUE 1061
#define IDC_ENTERADR 1062
#define IDC_DEBUG_MEM 1063
#define IDC_DEBUG_MEM_ADDR 1064
#define IDC_DEBUG_MEM_COL0 1065
#define IDC_DEBUG_MEM_COL1 1066
#define IDC_DEBUG_MEM_COL2 1067
#define IDC_DEBUG_MEM_COL3 1068
#define IDC_DEBUG_MEM_COL4 1069
#define IDC_DEBUG_MEM_COL5 1070
#define IDC_DEBUG_MEM_COL6 1071
#define IDC_DEBUG_MEM_COL7 1072
#define IDC_DEBUG_MEM_TEXT 1073
#define IDC_DEBUG_STACK 1074
#define IDC_STATIC_BREAKPOINT 1075
#define IDC_BREAKEDIT_ADD 1076
#define IDC_BREAKEDIT_DELETE 1077
#define IDC_BREAKEDIT_WND 1078
#define IDC_STATIC_MMU 1079
#define IDC_MMU_IO_A 1080
#define IDC_MMU_NCE2_A 1081
#define IDC_MMU_CE1_A 1082
#define IDC_MMU_CE2_A 1083
#define IDC_MMU_NCE3_A 1084
#define IDC_MMU_IO_S 1085
#define IDC_MMU_CE1_S 1086
#define IDC_MMU_CE2_S 1087
#define IDC_MMU_NCE2_S 1088
#define IDC_MMU_NCE3_S 1089
#define IDC_STATIC_MISC 1090
#define IDC_MISC_BS_TXT 1091
#define IDC_INSTR_TEXT 1092
#define IDC_INSTR_CODE 1093
#define IDC_INSTR_COPY 1094
#define IDC_INSTR_CLEAR 1095
#define IDC_BPCODE 1096
#define IDC_BPRPL 1097
#define IDC_BPACCESS 1098
#define IDC_BPREAD 1099
#define IDC_BPWRITE 1100
#define IDC_FIND_DATA 1101
#define IDC_FIND_ASCII 1102
#define IDC_FIND_CASE 1103
#define ID_FILE_NEW 40001
#define ID_FILE_OPEN 40002
#define ID_FILE_SAVE 40003
@ -140,33 +146,37 @@
#define ID_TOOL_DISASM 40021
#define ID_TOOL_DEBUG 40022
#define ID_DEBUG_RUN 40023
#define ID_DEBUG_STEP 40024
#define ID_DEBUG_STEPOVER 40025
#define ID_DEBUG_BREAK 40026
#define ID_DEBUG_STEPOUT 40027
#define ID_BREAKPOINTS_SETBREAK 40028
#define ID_BREAKPOINTS_CODEEDIT 40029
#define ID_BREAKPOINTS_CLEARALL 40030
#define ID_BREAKPOINTS_NOP3 40031
#define ID_BREAKPOINTS_RPL 40032
#define ID_DEBUG_CODE_GOADR 40033
#define ID_DEBUG_CODE_GOPC 40034
#define ID_DEBUG_CODE_SETPCTOSELECT 40035
#define ID_DEBUG_MEM_GOADR 40036
#define ID_DEBUG_MEM_GOPC 40037
#define ID_DEBUG_MEM_GOD0 40038
#define ID_DEBUG_MEM_GOD1 40039
#define ID_DEBUG_MEM_GOSTACK 40040
#define ID_INFO_LASTINSTRUCTIONS 40041
#define ID_INTR_STEPOVERINT 40042
#define ID_DEBUG_RUNCURSOR 40024
#define ID_DEBUG_STEP 40025
#define ID_DEBUG_STEPOVER 40026
#define ID_DEBUG_BREAK 40027
#define ID_DEBUG_STEPOUT 40028
#define ID_DEBUG_CANCEL 40029
#define ID_BREAKPOINTS_SETBREAK 40030
#define ID_BREAKPOINTS_CODEEDIT 40031
#define ID_BREAKPOINTS_CLEARALL 40032
#define ID_BREAKPOINTS_NOP3 40033
#define ID_BREAKPOINTS_DOCODE 40034
#define ID_BREAKPOINTS_RPL 40035
#define ID_DEBUG_CODE_GOADR 40036
#define ID_DEBUG_CODE_GOPC 40037
#define ID_DEBUG_CODE_SETPCTOSELECT 40038
#define ID_DEBUG_MEM_GOADR 40039
#define ID_DEBUG_MEM_GOPC 40040
#define ID_DEBUG_MEM_GOD0 40041
#define ID_DEBUG_MEM_GOD1 40042
#define ID_DEBUG_MEM_GOSTACK 40043
#define ID_DEBUG_MEM_FIND 40044
#define ID_INFO_LASTINSTRUCTIONS 40045
#define ID_INTR_STEPOVERINT 40046
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 116
#define _APS_NEXT_COMMAND_VALUE 40043
#define _APS_NEXT_CONTROL_VALUE 1101
#define _APS_NEXT_RESOURCE_VALUE 121
#define _APS_NEXT_COMMAND_VALUE 40047
#define _APS_NEXT_CONTROL_VALUE 1104
#define _APS_NEXT_SYMED_VALUE 108
#endif
#endif

View file

@ -8,15 +8,16 @@
*/
#include "pch.h"
#include "Emu48.h"
#include "ops.h"
#include "io.h"
//| 38G | 48SX | 48GX | 49G | Name
// #7056A #806E9 #806E9 =TEMPOB
// #7056F #806EE #806EE =TEMPTOP
//#F0692 #70574 #806F3 #806F3 =RSKTOP (B)
//#F0697 #70579 #806F8 #806F8 =DSKTOP (D1)
//#F0DEA #7066E #807ED #80E9B =AVMEM (D)
//#F0705 #705B0 #8072F #8076B =INTRPPTR (D0)
//| 38G | 39G | 40G | 48SX | 48GX | 49G | Name
//#F0688 #806E9 #806E9 #7056A #806E9 #806E9 =TEMPOB
//#F068D #806EE #806EE #7056F #806EE #806EE =TEMPTOP
//#F0692 #806F3 #806F3 #70574 #806F3 #806F3 =RSKTOP (B)
//#F0697 #806F8 #806F8 #70579 #806F8 #806F8 =DSKTOP (D1)
//#F0DEA #80E9B #80E9B #7066E #807ED #80E9B =AVMEM (D)
//#F0705 #8076B #8076B #705B0 #8072F #8076B =INTRPPTR (D0)
#define TEMPOB ((cCurrentRomType=='S')?0x7056A:0x806E9)
#define TEMPTOP ((cCurrentRomType=='S')?0x7056F:0x806EE)
@ -34,7 +35,7 @@ static BOOL Metakernel(VOID)
BOOL bMkDetect = FALSE;
// card in slot1 of a HP48GX enabled
if (cCurrentRomType=='G' && Chipset.cards_status & PORT1_PRESENT)
if (cCurrentRomType=='G' && Chipset.Port1 && Chipset.cards_status & PORT1_PRESENT)
{
// check for Metakernel string "MDGKER:"
if (!strncmp(&Chipset.Port1[12],"\xD\x4\x4\x4\x7\x4\xB\x4\x5\x4\x2\x5\xA\x3",14))
@ -255,20 +256,20 @@ DWORD RPL_CreateTemp(DWORD l)
DWORD a, b, c;
BYTE *p;
l += 6;
a = Read5(TEMPTOP);
b = Read5(RSKTOP); // start of available mem
c = Read5(DSKTOP); // end of available mem
if ((b+l)>c) return 0; // check if there is enough memory
Write5(TEMPTOP, a+l); // adjust end of temporary objects
Write5(RSKTOP, b+l); // adjust start of available mem
Write5(AVMEM, (c-(b+l))/5); // free memory (*5 nibbles)
p = (BYTE*)LocalAlloc(0,b-a);
l += 6; // memory for link field (5) + marker (1) and end
a = Read5(TEMPTOP); // tail address of top object
b = Read5(RSKTOP); // tail address of rtn stack
c = Read5(DSKTOP); // top of data stack
if ((b+l)>c) return 0; // check if there's enough memory to move DSKTOP
Write5(TEMPTOP, a+l); // adjust new end of top object
Write5(RSKTOP, b+l); // adjust new end of rtn stack
Write5(AVMEM, (c-b-l)/5); // calculate free memory (*5 nibbles)
p = (BYTE*)LocalAlloc(LMEM_FIXED,b-a); // move down rtn stack
Npeek(p,a,b-a);
Nwrite(p,a+l,b-a);
LocalFree(p);
Write5(a+l-5,l); // set temporary object length field
return (a+1); // return temporary object address
Write5(a+l-5,l); // set object length field
return (a+1); // return base address of new object
}
DWORD RPL_Pick(UINT l)

View file

@ -13,25 +13,24 @@
#define INTERRUPT ((void)(Chipset.SoftInt=TRUE,bInterrupt=TRUE))
// state of USRQ
#define NINT2ERBZ ((Chipset.IORam[IOC] & ERBZ) != 0 && (Chipset.IORam[RCS] & RBZ) != 0)
#define NINT2ERBF ((Chipset.IORam[IOC] & ERBF) != 0 && (Chipset.IORam[RCS] & RBF) != 0)
#define NINT2ETBE ((Chipset.IORam[IOC] & ETBE) != 0 && (Chipset.IORam[TCS] & TBF) == 0)
#define NINT2ERBZ ((Chipset.IORam[IOC] & (SON | ERBZ)) == (SON | ERBZ) && (Chipset.IORam[RCS] & RBZ) != 0)
#define NINT2ERBF ((Chipset.IORam[IOC] & (SON | ERBF)) == (SON | ERBF) && (Chipset.IORam[RCS] & RBF) != 0)
#define NINT2ETBE ((Chipset.IORam[IOC] & (SON | ETBE)) == (SON | ETBE) && (Chipset.IORam[TCS] & TBF) == 0)
#define NINT2USRQ (NINT2ERBZ || NINT2ERBF || NINT2ETBE)
static HANDLE hComm = NULL;
static HANDLE hCThread = NULL;
static DWORD lSerialThreadId = 0;
static WORD wPort = PORT_CLOSE;
static DWORD lSerialThreadId;
static BOOL bReading;
static BYTE cBuffer[128];
static WORD nRp;
static DWORD dwBytesRead = 0L;
static DWORD dwBytesRead;
static DWORD WINAPI SerialThread(LPVOID pParam)
{
DWORD dwEvent;
DWORD dwEvent;
bReading = TRUE; // flag for SerialThread started
while (bReading)
@ -49,27 +48,21 @@ static DWORD WINAPI SerialThread(LPVOID pParam)
}
}
}
lSerialThreadId = 0; // signal serial thread is down
return 0;
UNREFERENCED_PARAMETER(pParam);
}
WORD CommConnect(VOID)
{
return wPort;
}
VOID CommOpen(LPSTR strWirePort,LPSTR strIrPort)
BOOL CommOpen(LPTSTR strWirePort,LPTSTR strIrPort)
{
COMMTIMEOUTS CommTimeouts = { MAXDWORD, 0L, 0L, 0L, 0L };
LPSTR strPort = (Chipset.IORam[IR_CTRL] & EIRU) ? strIrPort : strWirePort;
LPTSTR strPort = (Chipset.IORam[IR_CTRL] & EIRU) ? strIrPort : strWirePort;
_ASSERT(Chipset.IORam[IOC] & SON); // UART on
if (hComm != NULL) // port already open
CloseHandle(hComm);
if (strcmp(strPort, NO_SERIAL)) // port defined
if (lstrcmp(strPort, _T(NO_SERIAL))) // port defined
{
hComm = CreateFile(strPort,
GENERIC_READ | GENERIC_WRITE,
@ -81,7 +74,9 @@ VOID CommOpen(LPSTR strWirePort,LPSTR strIrPort)
if(hComm != INVALID_HANDLE_VALUE)
{
wPort = (Chipset.IORam[IR_CTRL] & EIRU) ? PORT_IR : PORT_WIRE;
nRp = 0; // reset receiver state
dwBytesRead = 0L;
SetCommTimeouts(hComm,&CommTimeouts);
CommSetBaud();
@ -98,12 +93,12 @@ VOID CommOpen(LPSTR strWirePort,LPSTR strIrPort)
#if defined DEBUG_SERIAL
{
char buffer[256];
wsprintf(buffer,"COM port %s.\n",hComm ? "opened": "open error");
TCHAR buffer[256];
wsprintf(buffer,_T("COM port %s.\n"),hComm ? _T("opened"): _T("open error"));
OutputDebugString(buffer);
}
#endif
return;
return hComm != NULL;
}
VOID CommClose(VOID)
@ -113,13 +108,13 @@ VOID CommClose(VOID)
Sleep(25); // workaround to fix problems with some Kermit server
bReading = FALSE; // kill read thread
SetCommMask(hComm,0L); // clear all events and force WaitCommEvent to return
while (lSerialThreadId != 0) Sleep(0); // wait for termination
WaitForSingleObject(hCThread,INFINITE); // wait for thread termination
CloseHandle(hCThread); // close thread handle
CloseHandle(hComm); // close port
hComm = NULL;
#if defined DEBUG_SERIAL
OutputDebugString("COM port closed.\n");
OutputDebugString(_T("COM port closed.\n"));
#endif
wPort = PORT_CLOSE;
}
return;
}
@ -152,8 +147,8 @@ VOID CommSetBaud(VOID)
#if defined DEBUG_SERIAL
{
char buffer[256];
wsprintf(buffer,"CommsetBaud: %ld\n",dcb.BaudRate);
TCHAR buffer[256];
wsprintf(buffer,_T("CommsetBaud: %ld\n"),dcb.BaudRate);
OutputDebugString(buffer);
}
#endif
@ -163,10 +158,11 @@ VOID CommSetBaud(VOID)
return;
}
VOID UpdateUSRQ(VOID) // USRQ handling
BOOL UpdateUSRQ(VOID) // USRQ handling
{
IOBit(SRQ1,USRQ,NINT2USRQ); // update USRQ bit
return;
BOOL bUSRQ = NINT2USRQ;
IOBit(SRQ1,USRQ,bUSRQ); // update USRQ bit
return bUSRQ;
}
VOID CommTransmit(VOID)
@ -178,17 +174,18 @@ VOID CommTransmit(VOID)
#if defined DEBUG_SERIAL
{
char buffer[256];
TCHAR buffer[256];
if (isprint(tbr))
wsprintf(buffer,"-> '%c'\n",tbr);
wsprintf(buffer,_T("-> '%c'\n"),tbr);
else
wsprintf(buffer,"-> %02X\n",tbr);
wsprintf(buffer,_T("-> %02X\n"),tbr);
OutputDebugString(buffer);
}
#endif
if (Chipset.IORam[TCS] & LPB) // is loopback bit set
{
if (dwBytesRead == 0) nRp = 0; // no character received, reset read pointer
cBuffer[nRp+dwBytesRead] = tbr; // save character in receive buffer
++dwBytesRead;
@ -204,8 +201,7 @@ VOID CommTransmit(VOID)
}
Chipset.IORam[TCS] &= (~TBF); // clear transmit buffer
UpdateUSRQ(); // update USRQ bit
if (Chipset.IORam[IOC] & ETBE) // interrupt on transmit buffer empty
if (UpdateUSRQ()) // update USRQ bit
INTERRUPT;
return;
}
@ -240,11 +236,11 @@ VOID CommReceive(VOID)
#if defined DEBUG_SERIAL
{
char buffer[256];
TCHAR buffer[256];
if (isprint(cBuffer[nRp]))
wsprintf(buffer,"<- '%c'\n",cBuffer[nRp]);
wsprintf(buffer,_T("<- '%c'\n"),cBuffer[nRp]);
else
wsprintf(buffer,"<- %02X\n",cBuffer[nRp]);
wsprintf(buffer,_T("<- %02X\n"),cBuffer[nRp]);
OutputDebugString(buffer);
}
#endif
@ -255,8 +251,7 @@ VOID CommReceive(VOID)
--dwBytesRead;
Chipset.IORam[RCS] |= RBF; // receive buffer full
UpdateUSRQ(); // update USRQ bit
if (Chipset.IORam[IOC] & ERBF) // interrupt on recv buffer full
if (UpdateUSRQ()) // update USRQ bit
INTERRUPT;
}
while(0);

View file

@ -3,84 +3,190 @@
*
* This file is part of Emu48
*
* Copyright (C) 1995 Sebastien Carlier
* Copyright (C) 1999 Christoph Gießelink
* Copyright (C) 2000 Christoph Gießelink
*
*/
#include "pch.h"
#include "Emu48.h"
#include "i28f160.h"
// #define REGISTRY // use registry instead of *.ini file
//################
//#
//# Low level subroutines
//#
//################
#ifndef REGISTRY
#define EMU48_INI "Emu48.ini"
#define ReadString(sec,key,dv,v,sv) GetPrivateProfileString(sec,key,dv,v,sv,_T(EMU48_INI))
#define ReadInt(sec,key,dv) GetPrivateProfileInt(sec,key,dv,_T(EMU48_INI));
#define WriteString(sec,key,v) WritePrivateProfileString(sec,key,v,_T(EMU48_INI))
#define WriteInt(sec,key,v) WritePrivateProfileInt(sec,key,v,_T(EMU48_INI))
static BOOL WritePrivateProfileInt(LPCTSTR lpszSection, LPCTSTR lpszEntry, int nValue, LPCTSTR lpszFilename)
{
char s[16];
wsprintf(s,"%i",nValue);
TCHAR s[16];
wsprintf(s,_T("%i"),nValue);
return WritePrivateProfileString(lpszSection, lpszEntry, s, lpszFilename);
}
#else
#define SUBKEY "Software\\Emu48\\"
#define ReadString(sec,key,dv,v,sv) GetRegistryString(sec,key,dv,v,sv)
#define ReadInt(sec,key,dv) GetRegistryInt(sec,key,dv)
#define WriteString(sec,key,v) WriteReg(sec,key,REG_SZ,(BYTE *) v,(lstrlen(v)+1) * sizeof(*v))
#define WriteInt(sec,key,v) WriteReg(sec,key,REG_DWORD,(BYTE *) &v,sizeof(int))
static VOID ReadReg(LPCTSTR lpSubKey, LPCTSTR lpValueName, LPBYTE lpData, DWORD *pdwSize)
{
TCHAR lpKey[256] = _T(SUBKEY);
DWORD retCode,dwType;
HKEY hKey;
lstrcat(lpKey, lpSubKey); // full registry key
retCode = RegOpenKeyEx(HKEY_CURRENT_USER,
lpKey,
0,
KEY_QUERY_VALUE,
&hKey);
if (retCode == ERROR_SUCCESS)
{
retCode = RegQueryValueEx(hKey,lpValueName,NULL,&dwType,lpData,pdwSize);
RegCloseKey(hKey);
}
if (retCode != ERROR_SUCCESS) // registry entry not found
*pdwSize = 0; // return zero size
return;
}
static VOID WriteReg(LPCTSTR lpSubKey, LPCTSTR lpValueName, DWORD dwType, CONST BYTE *lpData, DWORD cbData)
{
TCHAR lpKey[256] = _T(SUBKEY);
DWORD retCode;
HKEY hKey;
DWORD dwDisposition;
lstrcat(lpKey, lpSubKey); // full registry key
retCode = RegCreateKeyEx(HKEY_CURRENT_USER,
lpKey,
0,_T(""),
REG_OPTION_NON_VOLATILE,
KEY_WRITE,
NULL,
&hKey,
&dwDisposition);
_ASSERT(retCode == ERROR_SUCCESS);
RegSetValueEx(hKey,lpValueName,0,dwType,lpData,cbData);
RegCloseKey(hKey);
return;
}
static DWORD GetRegistryString(LPCTSTR lpszSection, LPCTSTR lpszEntry, LPCTSTR lpDefault, LPTSTR lpData, DWORD dwSize)
{
dwSize *= sizeof(*lpData); // buffer size in bytes
ReadReg(lpszSection,lpszEntry,(LPBYTE) lpData,&dwSize);
if (dwSize == 0)
{
lstrcpy(lpData,lpDefault);
dwSize = lstrlen(lpData);
}
else
{
dwSize = (dwSize / sizeof(*lpData)) - 1;
}
return dwSize;
}
static INT GetRegistryInt(LPCTSTR lpszSection, LPCTSTR lpszEntry, INT nDefault)
{
UINT nValue;
DWORD dwSize = sizeof(nValue);
ReadReg(lpszSection,lpszEntry,(LPBYTE) &nValue,&dwSize);
return dwSize ? nValue : nDefault;
}
#endif
//################
//#
//# Public functions
//#
//################
VOID ReadSettings(VOID)
{
// Files
GetPrivateProfileString("Files","Emu48Directory",szCurrentDirectory,szEmu48Directory,
sizeof(szEmu48Directory),EMU48_INI);
bAutoSave = GetPrivateProfileInt("Files","AutoSave",bAutoSave,EMU48_INI);
bAutoSaveOnExit = GetPrivateProfileInt("Files","AutoSaveOnExit",bAutoSaveOnExit,EMU48_INI);
ReadString(_T("Files"),_T("Emu48Directory"),szCurrentDirectory,szEmu48Directory,ARRAYSIZEOF(szEmu48Directory));
bAutoSave = ReadInt(_T("Files"),_T("AutoSave"),bAutoSave);
bAutoSaveOnExit = ReadInt(_T("Files"),_T("AutoSaveOnExit"),bAutoSaveOnExit);
// Port2
bPort2IsShared = GetPrivateProfileInt("Port2","IsShared",0,EMU48_INI);
GetPrivateProfileString("Port2","Filename","SHARED.BIN",szPort2Filename,sizeof(szPort2Filename),EMU48_INI);
bPort2IsShared = ReadInt(_T("Port2"),_T("IsShared"),bPort2IsShared);
ReadString(_T("Port2"),_T("Filename"),_T("SHARED.BIN"),szPort2Filename,ARRAYSIZEOF(szPort2Filename));
// KML
bAlwaysDisplayLog = GetPrivateProfileInt("KML","AlwaysDisplayLog",bAlwaysDisplayLog,EMU48_INI);
bAlwaysDisplayLog = ReadInt(_T("KML"),_T("AlwaysDisplayLog"),bAlwaysDisplayLog);
// Disassebler
disassembler_mode = GetPrivateProfileInt("Disassembler","Mnemonics",disassembler_mode,EMU48_INI);
disassembler_mode = ReadInt(_T("Disassembler"),_T("Mnemonics"),disassembler_mode);
// Emulator
bRealSpeed = GetPrivateProfileInt("Emulator","RealSpeed",0,EMU48_INI);
dwSXCycles = GetPrivateProfileInt("Emulator","SXCycles",dwSXCycles,EMU48_INI);
dwGXCycles = GetPrivateProfileInt("Emulator","GXCycles",dwGXCycles,EMU48_INI);
bRealSpeed = ReadInt(_T("Emulator"),_T("RealSpeed"),bRealSpeed);
dwSXCycles = ReadInt(_T("Emulator"),_T("SXCycles"),dwSXCycles);
dwGXCycles = ReadInt(_T("Emulator"),_T("GXCycles"),dwGXCycles);
SetSpeed(bRealSpeed); // set speed
// Serial
GetPrivateProfileString("Serial","Wire",NO_SERIAL,szSerialWire,sizeof(szSerialWire),EMU48_INI);
GetPrivateProfileString("Serial","Ir",NO_SERIAL,szSerialIr,sizeof(szSerialIr),EMU48_INI);
ReadString(_T("Serial"),_T("Wire"),_T(NO_SERIAL),szSerialWire,ARRAYSIZEOF(szSerialWire));
ReadString(_T("Serial"),_T("Ir"),_T(NO_SERIAL),szSerialIr,ARRAYSIZEOF(szSerialIr));
// ROM
bRomWriteable = GetPrivateProfileInt("ROM","Writeable",TRUE,EMU48_INI);
bWP = GetPrivateProfileInt("ROM","WP#",FALSE,EMU48_INI);
bRomWriteable = ReadInt(_T("ROM"),_T("Writeable"),bRomWriteable);
bWP = ReadInt(_T("ROM"),_T("WP#"),bWP);
return;
}
VOID WriteSettings(VOID)
{
// Files
WritePrivateProfileString("Files","Emu48Directory",szEmu48Directory,EMU48_INI);
WritePrivateProfileInt("Files","AutoSave",bAutoSave,EMU48_INI);
WritePrivateProfileInt("Files","AutoSaveOnExit",bAutoSaveOnExit,EMU48_INI);
WriteString(_T("Files"),_T("Emu48Directory"),szEmu48Directory);
WriteInt(_T("Files"),_T("AutoSave"),bAutoSave);
WriteInt(_T("Files"),_T("AutoSaveOnExit"),bAutoSaveOnExit);
// Port2
WritePrivateProfileInt("Port2","IsShared",bPort2IsShared,EMU48_INI);
WritePrivateProfileString("Port2","Filename",szPort2Filename,EMU48_INI);
WriteInt(_T("Port2"),_T("IsShared"),bPort2IsShared);
WriteString(_T("Port2"),_T("Filename"),szPort2Filename);
// KML
WritePrivateProfileInt("KML","AlwaysDisplayLog",bAlwaysDisplayLog,EMU48_INI);
WriteInt(_T("KML"),_T("AlwaysDisplayLog"),bAlwaysDisplayLog);
// Disassebler
WritePrivateProfileInt("Disassembler","Mnemonics",disassembler_mode,EMU48_INI);
WriteInt(_T("Disassembler"),_T("Mnemonics"),disassembler_mode);
// Emulator
WritePrivateProfileInt("Emulator","RealSpeed",bRealSpeed,EMU48_INI);
WritePrivateProfileInt("Emulator","SXCycles",dwSXCycles,EMU48_INI);
WritePrivateProfileInt("Emulator","GXCycles",dwGXCycles,EMU48_INI);
WriteInt(_T("Emulator"),_T("RealSpeed"),bRealSpeed);
WriteInt(_T("Emulator"),_T("SXCycles"),dwSXCycles);
WriteInt(_T("Emulator"),_T("GXCycles"),dwGXCycles);
// Serial
WritePrivateProfileString("Serial","Wire",szSerialWire,EMU48_INI);
WritePrivateProfileString("Serial","Ir",szSerialIr,EMU48_INI);
WriteString(_T("Serial"),_T("Wire"),szSerialWire);
WriteString(_T("Serial"),_T("Ir"),szSerialIr);
// ROM
WritePrivateProfileInt("ROM","Writeable",bRomWriteable,EMU48_INI);
WriteInt(_T("ROM"),_T("Writeable"),bRomWriteable);
return;
}
VOID ReadLastDocument(LPTSTR szFilename, DWORD nSize)
{
GetPrivateProfileString("Files","LastDocument","",szFilename,nSize,EMU48_INI);
ReadString(_T("Files"),_T("LastDocument"),_T(""),szFilename,nSize);
return;
}
VOID WriteLastDocument(LPCTSTR szFilename)
{
WritePrivateProfileString("Files","LastDocument",szFilename,EMU48_INI);
WriteString(_T("Files"),_T("LastDocument"),szFilename);
return;
}

View file

@ -8,6 +8,7 @@
*/
#include "pch.h"
#include "Emu48.h"
#include "ops.h"
#include "io.h" // I/O definitions
#define AUTO_OFF 10 // Time in minutes for 'auto off'
@ -39,7 +40,7 @@ static TIMECAPS tc; // timer information
static BOOL bT2Val; // last access values valid
static __inline MAX(int a, int b) {return (a>b)?a:b;}
static __inline int MAX(int a, int b) {return (a>b)?a:b;}
static void CALLBACK TimeProc(UINT uEventId, UINT uMsg, DWORD dwUser, DWORD dw1, DWORD dw2);
@ -175,7 +176,7 @@ static VOID RescheduleT2(BOOL bRefPoint)
uDelay &= 0x7FFFFFFF; // execute timer2 event when MSB change
uDelay >>= 3; // timer delay in ms
uDelay = MAX(tc.wPeriodMin,uDelay); // wait minimum delay of timer
if (bOutRange = uDelay > tc.wPeriodMax) // delay greater maximum delay
if ((bOutRange = uDelay > tc.wPeriodMax)) // delay greater maximum delay
uDelay = tc.wPeriodMax; // wait maximum delay time
// start timer2; schedule event, when Chipset.t2 will be zero (Chipset.t2 / 8 = time in ms)
uT2TimerId = timeSetEvent(uDelay,0,(LPTIMECALLBACK)&TimeProc,2,TIME_ONESHOT);
@ -310,6 +311,8 @@ VOID StartTimers(VOID)
// set timer resolution to 1 ms, if failed don't use "Accurate timer"
bAccurateTimer = (timeBeginPeriod(1) == TIMERR_NOERROR);
timeGetDevCaps(&tc,sizeof(tc)); // get timer resolution
CheckT1(Chipset.t1); // check for timer1 interrupts
CheckT2(Chipset.t2); // check for timer2 interrupts
// set timer1 with given period
uT1TimerId = timeSetEvent(T1_FREQ,0,(LPTIMECALLBACK)&TimeProc,1,TIME_PERIODIC);
_ASSERT(uT1TimerId); // test if timer1 started

View file

@ -0,0 +1,705 @@
//Microsoft Developer Studio generated resource script.
//
#include "resource.h"
#define APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 2 resource.
//
#include "winresrc.h"
/////////////////////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
// French (France) resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_FRA)
#ifdef _WIN32
LANGUAGE LANG_FRENCH, SUBLANG_FRENCH
#pragma code_page(1252)
#endif //_WIN32
/////////////////////////////////////////////////////////////////////////////
//
// DESIGNINFO
//
#ifdef APSTUDIO_INVOKED
GUIDELINES DESIGNINFO DISCARDABLE
BEGIN
IDD_FIND, DIALOG
BEGIN
LEFTMARGIN, 6
RIGHTMARGIN, 190
TOPMARGIN, 7
BOTTOMMARGIN, 40
END
IDD_BREAKEDIT, DIALOG
BEGIN
LEFTMARGIN, 5
RIGHTMARGIN, 113
TOPMARGIN, 5
BOTTOMMARGIN, 95
END
IDD_ABOUT, DIALOG
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 254
TOPMARGIN, 6
BOTTOMMARGIN, 145
END
IDD_SETTINGS, DIALOG
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 160
TOPMARGIN, 4
BOTTOMMARGIN, 202
END
IDD_CHOOSEKML, DIALOG
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 179
TOPMARGIN, 7
BOTTOMMARGIN, 59
END
IDD_KMLLOG, DIALOG
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 294
TOPMARGIN, 7
BOTTOMMARGIN, 160
END
IDD_DISASM, DIALOG
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 248
TOPMARGIN, 5
BOTTOMMARGIN, 158
END
IDD_DEBUG, DIALOG
BEGIN
LEFTMARGIN, 5
RIGHTMARGIN, 274
TOPMARGIN, 17
BOTTOMMARGIN, 264
END
IDD_NEWVALUE, DIALOG
BEGIN
LEFTMARGIN, 8
RIGHTMARGIN, 168
TOPMARGIN, 7
BOTTOMMARGIN, 43
END
IDD_ENTERADR, DIALOG
BEGIN
LEFTMARGIN, 8
RIGHTMARGIN, 149
TOPMARGIN, 7
BOTTOMMARGIN, 43
END
IDD_ENTERBREAK, DIALOG
BEGIN
LEFTMARGIN, 8
RIGHTMARGIN, 149
TOPMARGIN, 7
BOTTOMMARGIN, 79
END
IDD_INSTRUCTIONS, DIALOG
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 179
TOPMARGIN, 7
BOTTOMMARGIN, 162
END
END
#endif // APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Dialog
//
IDD_FIND DIALOGEX 0, 0, 197, 47
STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
EXSTYLE WS_EX_TOOLWINDOW
CAPTION "Find"
FONT 8, "MS Sans Serif"
BEGIN
LTEXT "Find &what:",IDC_STATIC,7,9,34,8
COMBOBOX IDC_FIND_DATA,46,7,88,41,CBS_DROPDOWN | CBS_AUTOHSCROLL |
WS_VSCROLL | WS_TABSTOP
CONTROL "Find &ASCII",IDC_FIND_ASCII,"Button",BS_AUTOCHECKBOX |
WS_TABSTOP,46,30,49,10
DEFPUSHBUTTON "Find Next",IDOK,140,7,50,14
PUSHBUTTON "Cancel",IDCANCEL,140,26,50,14
END
IDD_BREAKEDIT DIALOG DISCARDABLE 0, 0, 118, 100
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Edit Breakpoints"
FONT 8, "Courier New"
BEGIN
DEFPUSHBUTTON "OK",IDCANCEL,83,81,30,14
LTEXT "Current breakpoints:",IDC_STATIC_BREAKPOINT,5,5,82,8
LISTBOX IDC_BREAKEDIT_WND,5,17,108,58,LBS_SORT |
LBS_OWNERDRAWFIXED | LBS_HASSTRINGS |
LBS_NOINTEGRALHEIGHT | LBS_WANTKEYBOARDINPUT |
LBS_EXTENDEDSEL | WS_VSCROLL | WS_TABSTOP
PUSHBUTTON "&Add...",IDC_BREAKEDIT_ADD,5,81,30,14
PUSHBUTTON "&Delete",IDC_BREAKEDIT_DELETE,44,81,30,14
END
IDD_ABOUT DIALOGEX 0, 0, 261, 160
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "About Emu48"
FONT 8, "MS Sans Serif"
BEGIN
ICON IDI_EMU48,IDC_STATIC,7,6,20,20,SS_REALSIZEIMAGE,
WS_EX_TRANSPARENT
LTEXT "",IDC_VERSION,29,6,151,8,NOT WS_GROUP
LTEXT "Copyright © 2001 Sébastien Carlier && Christoph Gießelink",
IDC_STATIC,29,18,181,8
DEFPUSHBUTTON "OK",IDOK,215,12,39,14
EDITTEXT IDC_LICENSE,7,33,247,112,ES_MULTILINE | ES_AUTOHSCROLL |
ES_READONLY
END
IDD_SETTINGS DIALOGEX 0, 0, 167, 209
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Settings"
FONT 8, "MS Sans Serif"
BEGIN
CONTROL "Authentic Calculator Speed",IDC_REALSPEED,"Button",
BS_AUTOCHECKBOX | WS_TABSTOP,13,13,104,10
CONTROL "Automatically Save Files",IDC_AUTOSAVE,"Button",
BS_AUTOCHECKBOX | WS_TABSTOP,13,26,89,10
CONTROL "Automatically Save Files On Exit",IDC_AUTOSAVEONEXIT,
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,13,39,114,10
CONTROL "Always display KML Compilation Result",
IDC_ALWAYSDISPLOG,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,
13,52,136,10
GROUPBOX "General",IDC_STATIC,7,4,153,63
CONTROL "HP Mnemonics",IDC_DISASM_HP,"Button",BS_AUTORADIOBUTTON |
WS_GROUP | WS_TABSTOP,13,81,65,11
CONTROL "Class Mnemonics",IDC_DISASM_CLASS,"Button",
BS_AUTORADIOBUTTON,84,81,70,11
GROUPBOX "Disassembler",IDC_STATIC,7,70,153,28
CONTROL "Port 1 is Plugged",IDC_PORT1EN,"Button",BS_AUTOCHECKBOX |
WS_TABSTOP,13,110,67,10
CONTROL "Port 1 is Writeable",IDC_PORT1WR,"Button",
BS_AUTOCHECKBOX | WS_TABSTOP,84,110,69,10
CONTROL "Port 2 is Shared",IDC_PORT2ISSHARED,"Button",
BS_AUTOCHECKBOX | WS_TABSTOP,13,123,65,10
LTEXT "Port 2 File :",IDC_STATIC,13,136,37,8
EDITTEXT IDC_PORT2,51,134,104,12,ES_AUTOHSCROLL
GROUPBOX "Memory Cards",IDC_STATIC,7,101,153,50
LTEXT "Wire:",IDC_STATIC,13,166,17,8
COMBOBOX IDC_WIRE,31,164,48,42,CBS_DROPDOWNLIST | WS_VSCROLL |
WS_TABSTOP,WS_EX_LEFTSCROLLBAR
LTEXT "IR:",IDC_STATIC,89,166,9,8
COMBOBOX IDC_IR,107,164,48,43,CBS_DROPDOWNLIST | WS_VSCROLL |
WS_TABSTOP
GROUPBOX "Serial Ports",IDC_STATIC,7,154,153,27
DEFPUSHBUTTON "&Ok",IDOK,9,188,50,14
PUSHBUTTON "&Cancel",IDCANCEL,107,188,50,14
END
IDD_CHOOSEKML DIALOG DISCARDABLE 0, 0, 186, 66
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Choose Your KML Script"
FONT 8, "MS Sans Serif"
BEGIN
DEFPUSHBUTTON "OK",IDOK,129,7,50,14
PUSHBUTTON "Cancel",IDCANCEL,129,27,50,14
COMBOBOX IDC_KMLSCRIPT,7,47,172,120,CBS_DROPDOWNLIST |
CBS_OEMCONVERT | CBS_SORT | WS_VSCROLL | WS_TABSTOP
EDITTEXT IDC_EMU48DIR,7,17,107,14,ES_AUTOHSCROLL
LTEXT "Emu48 Directory :",IDC_STATIC,7,7,115,8
LTEXT "Current KML Script :",IDC_STATIC,7,37,115,8
PUSHBUTTON "V",IDC_UPDATE,115,17,10,14
END
IDD_KMLLOG DIALOGEX 0, 0, 301, 167
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "KML Script Compilation Result"
FONT 8, "MS Sans Serif"
BEGIN
DEFPUSHBUTTON "OK",IDOK,86,146,50,14
PUSHBUTTON "Cancel",IDCANCEL,164,146,50,14
CONTROL "Always",IDC_ALWAYSDISPLOG,"Button",BS_AUTOCHECKBOX |
BS_PUSHLIKE | WS_TABSTOP,263,147,31,13,WS_EX_STATICEDGE
GROUPBOX "",IDC_STATIC,7,7,287,36
CTEXT "Title of the Script",IDC_TITLE,71,14,158,8
CTEXT "by",IDC_STATIC,71,22,158,8
CTEXT "The Author",IDC_AUTHOR,71,30,158,8,NOT WS_GROUP
EDITTEXT IDC_KMLLOG,7,48,287,92,ES_MULTILINE | ES_AUTOHSCROLL |
ES_OEMCONVERT | ES_READONLY | ES_WANTRETURN | NOT
WS_BORDER | WS_VSCROLL | NOT WS_TABSTOP,WS_EX_CLIENTEDGE
END
IDD_DISASM DIALOGEX 0, 0, 255, 165
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Disassembler"
FONT 8, "Courier New"
BEGIN
LTEXT "Address (HEX):",IDC_ADDRESS,7,147,46,8
EDITTEXT IDC_DISASM_ADR,56,145,36,12,ES_AUTOHSCROLL
PUSHBUTTON "&Next Address",IDC_DISASM_NEXT,99,144,47,14
PUSHBUTTON "&Copy Data",IDC_DISASM_COPY,150,144,47,14
PUSHBUTTON "Cancel",IDCANCEL,201,144,47,14
GROUPBOX "Module",IDC_DISASM_MODULE,7,5,241,26
CONTROL "Map",IDC_DISASM_MAP,"Button",BS_AUTORADIOBUTTON |
WS_GROUP | WS_TABSTOP,14,16,37,10
CONTROL "ROM",IDC_DISASM_ROM,"Button",BS_AUTORADIOBUTTON,61,16,
37,10
CONTROL "RAM",IDC_DISASM_RAM,"Button",BS_AUTORADIOBUTTON,108,16,
37,10
CONTROL "Port 1",IDC_DISASM_PORT1,"Button",BS_AUTORADIOBUTTON,
155,16,37,10
CONTROL "Port 2",IDC_DISASM_PORT2,"Button",BS_AUTORADIOBUTTON,
202,16,37,10
LISTBOX IDC_DISASM_WIN,7,37,241,100,NOT LBS_NOTIFY |
LBS_NOINTEGRALHEIGHT | LBS_EXTENDEDSEL | WS_VSCROLL |
WS_TABSTOP,WS_EX_NOPARENTNOTIFY
END
IDD_DEBUG DIALOGEX 0, 0, 279, 269
STYLE WS_MINIMIZEBOX | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
CAPTION "Debugger"
MENU IDR_DEBUG
FONT 8, "Courier New"
BEGIN
LISTBOX IDC_DEBUG_CODE,11,27,165,122,NOT LBS_NOTIFY |
LBS_OWNERDRAWFIXED | LBS_HASSTRINGS |
LBS_NOINTEGRALHEIGHT | LBS_WANTKEYBOARDINPUT |
WS_TABSTOP
GROUPBOX "Code",IDC_STATIC_CODE,5,17,177,138
LTEXT "A= 0000000000000000",IDC_REG_A,192,27,77,8
LTEXT "B= 0000000000000000",IDC_REG_B,192,34,77,8
LTEXT "C= 0000000000000000",IDC_REG_C,192,41,77,8
LTEXT "D= 0000000000000000",IDC_REG_D,192,48,77,8
LTEXT "R0=0000000000000000",IDC_REG_R0,192,58,77,8
LTEXT "R1=0000000000000000",IDC_REG_R1,192,65,77,8
LTEXT "R2=0000000000000000",IDC_REG_R2,192,72,77,8
LTEXT "R3=0000000000000000",IDC_REG_R3,192,79,77,8
LTEXT "R4=0000000000000000",IDC_REG_R4,192,86,77,8
LTEXT "D0=00000",IDC_REG_D0,192,97,33,8
LTEXT "D1=00000",IDC_REG_D1,236,97,33,8
LTEXT "P=0",IDC_REG_P,192,108,13,8
LTEXT "PC=00000",IDC_REG_PC,236,108,33,8
LTEXT "OUT=000",IDC_REG_OUT,192,119,29,8
LTEXT "IN=0000",IDC_REG_IN,240,119,29,8
LTEXT "ST=0000",IDC_REG_ST,192,130,29,8
LTEXT "CY=0",IDC_REG_CY,224,130,17,8
LTEXT "Mode=H",IDC_REG_MODE,244,130,25,8
LTEXT "MP=0",IDC_REG_MP,192,140,17,8
LTEXT "SR=0",IDC_REG_SR,212,140,17,8
LTEXT "SB=0",IDC_REG_SB,232,140,17,8
LTEXT "XM=0",IDC_REG_XM,252,140,17,8
GROUPBOX "Registers",IDC_STATIC_REGISTERS,187,17,87,138
CONTROL "",IDC_DEBUG_MEM,"Static",SS_WHITERECT | WS_GROUP,11,166,
165,52,WS_EX_CLIENTEDGE
LISTBOX IDC_DEBUG_MEM_ADDR,12,168,25,48,NOT LBS_NOTIFY |
LBS_NOINTEGRALHEIGHT | LBS_NOSEL | WS_DISABLED | NOT
WS_BORDER
LISTBOX IDC_DEBUG_MEM_COL0,40,168,11,48,LBS_NOINTEGRALHEIGHT |
LBS_WANTKEYBOARDINPUT | NOT WS_BORDER | WS_TABSTOP
LISTBOX IDC_DEBUG_MEM_COL1,52,168,11,48,LBS_NOINTEGRALHEIGHT |
LBS_WANTKEYBOARDINPUT | NOT WS_BORDER
LISTBOX IDC_DEBUG_MEM_COL2,64,168,11,48,LBS_NOINTEGRALHEIGHT |
LBS_WANTKEYBOARDINPUT | NOT WS_BORDER
LISTBOX IDC_DEBUG_MEM_COL3,76,168,11,48,LBS_NOINTEGRALHEIGHT |
LBS_WANTKEYBOARDINPUT | NOT WS_BORDER
LISTBOX IDC_DEBUG_MEM_COL4,88,168,11,48,LBS_NOINTEGRALHEIGHT |
LBS_WANTKEYBOARDINPUT | NOT WS_BORDER
LISTBOX IDC_DEBUG_MEM_COL5,100,168,11,48,LBS_NOINTEGRALHEIGHT |
LBS_WANTKEYBOARDINPUT | NOT WS_BORDER
LISTBOX IDC_DEBUG_MEM_COL6,112,168,11,48,LBS_NOINTEGRALHEIGHT |
LBS_WANTKEYBOARDINPUT | NOT WS_BORDER
LISTBOX IDC_DEBUG_MEM_COL7,124,168,11,48,LBS_NOINTEGRALHEIGHT |
LBS_WANTKEYBOARDINPUT | NOT WS_BORDER
LISTBOX IDC_DEBUG_MEM_TEXT,139,168,35,48,NOT LBS_NOTIFY |
LBS_NOINTEGRALHEIGHT | LBS_NOSEL | WS_DISABLED | NOT
WS_BORDER
GROUPBOX "Memory",IDC_STATIC_MEMORY,5,156,177,68
LISTBOX IDC_DEBUG_STACK,192,166,76,52,LBS_NOINTEGRALHEIGHT |
LBS_WANTKEYBOARDINPUT | WS_VSCROLL | WS_TABSTOP
GROUPBOX "Stack",IDC_STATIC_STACK,187,156,87,68
LTEXT "Size Mask",IDC_STATIC,11,243,37,8
LTEXT "Address",IDC_STATIC,11,251,29,8
CTEXT "I/O",IDC_STATIC,55,235,21,8
CTEXT "NCE2",IDC_STATIC,80,235,21,8
CTEXT "CE1",IDC_STATIC,105,235,21,8
CTEXT "CE2",IDC_STATIC,130,235,21,8
CTEXT "NCE3",IDC_STATIC,155,235,21,8
CTEXT "-----",IDC_MMU_IO_S,55,243,21,8
CTEXT "-----",IDC_MMU_NCE2_S,80,243,21,8
CTEXT "-----",IDC_MMU_CE1_S,105,243,21,8
CTEXT "-----",IDC_MMU_CE2_S,130,243,21,8
CTEXT "-----",IDC_MMU_NCE3_S,155,243,21,8
CTEXT "-----",IDC_MMU_IO_A,55,251,21,8
CTEXT "-----",IDC_MMU_CE1_A,105,251,21,8
CTEXT "-----",IDC_MMU_CE2_A,130,251,21,8
CTEXT "-----",IDC_MMU_NCE2_A,80,251,21,8
CTEXT "-----",IDC_MMU_NCE3_A,155,251,21,8
GROUPBOX "MMU",IDC_STATIC_MMU,5,225,177,39
LTEXT "Interrupts =",IDC_STATIC,193,235,61,8
LTEXT "Keyboard Scan =",IDC_STATIC,193,243,61,8
LTEXT "Bank Switcher =",IDC_MISC_BS_TXT,193,251,61,8,
WS_DISABLED
LTEXT "",IDC_MISC_INT,256,235,13,8
LTEXT "",IDC_MISC_KEY,256,243,13,8
LTEXT "00",IDC_MISC_BS,256,251,13,8,WS_DISABLED
GROUPBOX "Miscellaneous",IDC_STATIC_MISC,187,225,87,39
END
IDD_NEWVALUE DIALOG DISCARDABLE 0, 0, 175, 50
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "New Value"
FONT 8, "MS Sans Serif"
BEGIN
LTEXT "New value (hexdezimal):",IDC_STATIC,8,9,81,8
EDITTEXT IDC_NEWVALUE,91,7,77,12,ES_AUTOHSCROLL
DEFPUSHBUTTON "OK",IDOK,21,29,50,14
PUSHBUTTON "Cancel",IDCANCEL,103,29,50,14
END
IDD_ENTERADR DIALOG DISCARDABLE 0, 0, 156, 50
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Enter Address"
FONT 8, "MS Sans Serif"
BEGIN
LTEXT "Enter address (hexdezimal):",IDC_STATIC,8,9,90,8
EDITTEXT IDC_ENTERADR,106,7,43,12,ES_AUTOHSCROLL
DEFPUSHBUTTON "OK",IDOK,14,29,50,14
PUSHBUTTON "Cancel",IDCANCEL,92,29,50,14
END
IDD_ENTERBREAK DIALOG DISCARDABLE 0, 0, 156, 86
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Enter Breakpoint"
FONT 8, "MS Sans Serif"
BEGIN
LTEXT "Enter breakpoint (hexdezimal):",IDC_STATIC,8,9,96,8
EDITTEXT IDC_ENTERADR,110,7,39,12,ES_AUTOHSCROLL
CONTROL "&Code",IDC_BPCODE,"Button",BS_AUTORADIOBUTTON |
WS_GROUP | WS_TABSTOP,17,24,33,10
CONTROL "R&PL",IDC_BPRPL,"Button",BS_AUTORADIOBUTTON,17,50,30,10
CONTROL "Memory &Access",IDC_BPACCESS,"Button",
BS_AUTORADIOBUTTON,79,24,63,10
CONTROL "Memory &Read",IDC_BPREAD,"Button",BS_AUTORADIOBUTTON,79,
37,60,10
CONTROL "Memory &Write",IDC_BPWRITE,"Button",BS_AUTORADIOBUTTON,
79,50,59,10
DEFPUSHBUTTON "OK",IDOK,14,65,50,14
PUSHBUTTON "Cancel",IDCANCEL,92,65,50,14
END
IDD_INSTRUCTIONS DIALOGEX 0, 0, 186, 169
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Last Instructions"
FONT 8, "Courier New"
BEGIN
LTEXT "Instructions (disassembly maybe incorrect):",
IDC_INSTR_TEXT,7,7,173,8
LISTBOX IDC_INSTR_CODE,7,18,172,122,NOT LBS_NOTIFY |
LBS_NOINTEGRALHEIGHT | LBS_EXTENDEDSEL | WS_VSCROLL |
WS_TABSTOP,WS_EX_NOPARENTNOTIFY
PUSHBUTTON "&Copy Data",IDC_INSTR_COPY,7,148,50,14
PUSHBUTTON "C&lear Data",IDC_INSTR_CLEAR,68,148,50,14
DEFPUSHBUTTON "Cancel",IDCANCEL,129,148,50,14
END
/////////////////////////////////////////////////////////////////////////////
//
// Bitmap
//
IDB_CHECKBOX BITMAP DISCARDABLE "checkbox.bmp"
IDR_DEBUG_TOOLBAR BITMAP MOVEABLE PURE "dbgtool.bmp"
/////////////////////////////////////////////////////////////////////////////
//
// Toolbar
//
#if 0
// with VC++, this definition would be possible:
IDR_DEBUG_TOOLBAR TOOLBAR DISCARDABLE 16, 15
BEGIN
BUTTON ID_DEBUG_RUN
BUTTON ID_DEBUG_CANCEL
BUTTON ID_DEBUG_BREAK
SEPARATOR
BUTTON ID_BREAKPOINTS_SETBREAK
BUTTON ID_BREAKPOINTS_CODEEDIT
SEPARATOR
BUTTON ID_DEBUG_STEP
BUTTON ID_DEBUG_STEPOVER
BUTTON ID_DEBUG_STEPOUT
BUTTON ID_DEBUG_RUNCURSOR
END
#else
// winres does not recognize TOOLBAR, so this workaround is used:
IDR_DEBUG_TOOLBAR 241 DISCARDABLE
BEGIN
1, // wVersion
16, // wWidth
15, // wHeight
11, // wItemCount
ID_DEBUG_RUN,
ID_DEBUG_CANCEL,
ID_DEBUG_BREAK,
0,
ID_BREAKPOINTS_SETBREAK,
ID_BREAKPOINTS_CODEEDIT,
0,
ID_DEBUG_STEP,
ID_DEBUG_STEPOVER,
ID_DEBUG_STEPOUT,
ID_DEBUG_RUNCURSOR
END
#endif
#ifndef _MAC
/////////////////////////////////////////////////////////////////////////////
//
// Version
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION 1,2,5,0
PRODUCTVERSION 1,2,5,0
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
#else
FILEFLAGS 0x0L
#endif
FILEOS 0x40004L
FILETYPE 0x1L
FILESUBTYPE 0x0L
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "00000000"
BEGIN
VALUE "CompanyName", "Sebastien Carlier & Christoph Gießelink\0"
VALUE "FileDescription", "HP38/39/40/48/49 Emulator\0"
VALUE "FileVersion", "1, 2, 5, 0\0"
VALUE "InternalName", "Emu48\0"
VALUE "LegalCopyright", "Copyright © 2001\0"
VALUE "OriginalFilename", "Emu48.exe\0"
VALUE "ProductName", "Emu48\0"
VALUE "ProductVersion", "1, 2, 5, 0\0"
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x0, 0
END
END
#endif // !_MAC
/////////////////////////////////////////////////////////////////////////////
//
// Icon
//
// Icon with lowest ID value placed first to ensure application icon
// remains consistent on all systems.
IDI_EMU48 ICON DISCARDABLE "Emu48.ico"
/////////////////////////////////////////////////////////////////////////////
//
// Menu
//
IDR_MENU MENU DISCARDABLE
BEGIN
POPUP "&File"
BEGIN
MENUITEM "&New...", ID_FILE_NEW
MENUITEM "&Open...", ID_FILE_OPEN
MENUITEM "&Save", ID_FILE_SAVE, GRAYED
MENUITEM "Save &As...", ID_FILE_SAVEAS, GRAYED
MENUITEM "&Close", ID_FILE_CLOSE, GRAYED
MENUITEM SEPARATOR
MENUITEM "S&ettings...", ID_VIEW_SETTINGS
MENUITEM SEPARATOR
MENUITEM "E&xit", ID_FILE_EXIT
END
POPUP "&Edit"
BEGIN
MENUITEM "&Load Object...", ID_OBJECT_LOAD
MENUITEM "&Save Object...", ID_OBJECT_SAVE
MENUITEM SEPARATOR
MENUITEM "&Copy String", ID_STACK_COPY
MENUITEM "C&opy Screen", ID_VIEW_COPY
MENUITEM "&Paste String", ID_STACK_PASTE
MENUITEM SEPARATOR
MENUITEM "&Reset Calculator", ID_VIEW_RESET, GRAYED
POPUP "&Backup"
BEGIN
MENUITEM "&Save", ID_BACKUP_SAVE, GRAYED
MENUITEM "&Restore", ID_BACKUP_RESTORE
, GRAYED
MENUITEM "&Delete", ID_BACKUP_DELETE, GRAYED
END
END
POPUP "&View"
BEGIN
MENUITEM "Change &KML Script...", ID_VIEW_SCRIPT
END
POPUP "&Tools"
BEGIN
MENUITEM "D&isassembler...", ID_TOOL_DISASM
MENUITEM "&Debugger...", ID_TOOL_DEBUG
END
POPUP "&Help"
BEGIN
MENUITEM "&About Emu48...", ID_ABOUT
END
END
IDR_DEBUG MENU DISCARDABLE
BEGIN
POPUP "&Debug"
BEGIN
MENUITEM "&Run\tF5", ID_DEBUG_RUN
MENUITEM "Run to &Cursor\tF6", ID_DEBUG_RUNCURSOR
MENUITEM "&Step Into\tF7", ID_DEBUG_STEP
MENUITEM "Step &Over\tF8", ID_DEBUG_STEPOVER
MENUITEM "Step O&ut\tF9", ID_DEBUG_STEPOUT
MENUITEM "&Break\tF11", ID_DEBUG_BREAK
END
POPUP "&Breakpoints"
BEGIN
MENUITEM "Set &Breakpoint\tF2", ID_BREAKPOINTS_SETBREAK
MENUITEM "&Edit Breakpoints...", ID_BREAKPOINTS_CODEEDIT
MENUITEM "&Clear All Breakpoints", ID_BREAKPOINTS_CLEARALL
MENUITEM SEPARATOR
MENUITEM "&NOP3 Code Breakpoints", ID_BREAKPOINTS_NOP3
MENUITEM "CODE &Object Breakpoints", ID_BREAKPOINTS_DOCODE
MENUITEM SEPARATOR
MENUITEM "&RPL Breakpoints", ID_BREAKPOINTS_RPL
END
POPUP "I&nterrupts"
BEGIN
MENUITEM "&Step Over Interrupts", ID_INTR_STEPOVERINT
END
POPUP "&Info"
BEGIN
MENUITEM "&Last Instructions...", ID_INFO_LASTINSTRUCTIONS
END
END
IDR_DEBUG_CODE MENU DISCARDABLE
BEGIN
POPUP ""
BEGIN
MENUITEM "&Go to address...\tG", ID_DEBUG_CODE_GOADR
MENUITEM "Go to &PC", ID_DEBUG_CODE_GOPC
MENUITEM "Set &breakpoint\tF2", ID_BREAKPOINTS_SETBREAK
MENUITEM "&Set PC to selection", ID_DEBUG_CODE_SETPCTOSELECT
END
END
IDR_DEBUG_MEM MENU DISCARDABLE
BEGIN
POPUP ""
BEGIN
MENUITEM "&Go to address...\tG", ID_DEBUG_MEM_GOADR
MENUITEM "Go to &PC", ID_DEBUG_MEM_GOPC
MENUITEM "Go to D&0", ID_DEBUG_MEM_GOD0
MENUITEM "Go to D&1", ID_DEBUG_MEM_GOD1
MENUITEM "Go to &Stack", ID_DEBUG_MEM_GOSTACK
MENUITEM SEPARATOR
MENUITEM "Find...\tF", ID_DEBUG_MEM_FIND
END
END
#ifdef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// TEXTINCLUDE
//
1 TEXTINCLUDE DISCARDABLE
BEGIN
"resource.h\0"
END
2 TEXTINCLUDE DISCARDABLE
BEGIN
"#include ""winres.h""\r\n"
"\0"
END
3 TEXTINCLUDE DISCARDABLE
BEGIN
"\r\n"
"\0"
END
#endif // APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// String Table
//
STRINGTABLE DISCARDABLE
BEGIN
ID_DEBUG_RUN "Run"
ID_DEBUG_RUNCURSOR "Run to Cursor"
ID_DEBUG_STEP "Step Into"
ID_DEBUG_STEPOVER "Step Over"
ID_DEBUG_BREAK "Break Execution"
ID_DEBUG_STEPOUT "Step Out"
ID_DEBUG_CANCEL "Stop Debugging"
ID_BREAKPOINTS_SETBREAK "Insert/Remove Breakpoint"
ID_BREAKPOINTS_CODEEDIT "Breakpoint List"
END
#endif // French (France) resources
/////////////////////////////////////////////////////////////////////////////
#ifndef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 3 resource.
//
/////////////////////////////////////////////////////////////////////////////
#endif // not APSTUDIO_INVOKED

117
sources/GCCPatch/Makefile Normal file
View file

@ -0,0 +1,117 @@
PRJ=Emu48gcc
CC=gcc
LD=gcc
# This is to make GCC not bitch at things M$ allows
CFLAGS= -Wall -Wno-missing-braces -Wno-format -Wno-uninitialized -O3
# Things we need around to compile successfully
# I wonder why we need this _WIN32_IE definition, should take the
# default from the headers, but take a look and win32api 0.5's commctrl.h
DEFINES= -D_TCHAR=TCHAR -DIDC_STATIC=-1 -D_WIN32_IE=0x0300
LDFLAGS= -s -mwindows
TARGET=$(PRJ).exe
#
# Warning.. my own resources because WINDRES doesn't understand
# the FONT definition for dialogs produced by the M$ tools
#
RSRC=$(PRJ).rc
RSRCOBJ=$(PRJ).o
OBJS=disasm.o display.o debugger.o ddeserv.o \
emu48.o engine.o external.o fetch.o files.o i28f160.o keyboard.o \
kml.o mops.o opcodes.o rpl.o serial.o settings.o timer.o \
$(RSRCOBJ)
LIBS=-lwinmm -lcomctl32
all: $(TARGET)
rebuild: tidy $(TARGET)
tidy: cleanemacs cleanobj cleanexe
cleanemacs:
-rm -f *~
cleanobj:
-rm -f $(OBJS)
cleanexe:
-rm -f $(TARGET)
ddeserv.o: ddeserv.c pch.h emu48.h types.h
$(CC) $(CFLAGS) $(DEFINES) -c -o ddeserv.o ddeserv.c
debugger.o: debugger.c pch.h resource.h emu48.h \
types.h opcodes.h ops.h color.h debugger.h
$(CC) $(CFLAGS) $(DEFINES) -c -o debugger.o debugger.c
disasm.o: disasm.c pch.h emu48.h types.h
$(CC) $(CFLAGS) $(DEFINES) -c -o disasm.o disasm.c
display.o: display.c pch.h resource.h emu48.h \
types.h io.h kml.h
$(CC) $(CFLAGS) $(DEFINES) -c -o display.o display.c
emu48.o: emu48.c pch.h resource.h emu48.h types.h \
io.h kml.h debugger.h
$(CC) $(CFLAGS) $(DEFINES) -c -o emu48.o emu48.c
engine.o: engine.c pch.h emu48.h types.h opcodes.h \
io.h debugger.h ops.h
$(CC) $(CFLAGS) $(DEFINES) -c -o engine.o engine.c
external.o: external.c pch.h emu48.h types.h
$(CC) $(CFLAGS) $(DEFINES) -c -o external.o external.c
fetch.o: fetch.c pch.h opcodes.h
$(CC) $(CFLAGS) $(DEFINES) -c -o fetch.o fetch.c
files.o: files.c pch.h emu48.h types.h io.h \
kml.h i28f160.h debugger.h
$(CC) $(CFLAGS) $(DEFINES) -c -o files.o files.c
i28f160.o: i28f160.c pch.h emu48.h types.h i28f160.h
$(CC) $(CFLAGS) $(DEFINES) -c -o i28f160.o i28f160.c
keyboard.o: keyboard.c pch.h emu48.h types.h io.h
$(CC) $(CFLAGS) $(DEFINES) -c -o keyboard.o keyboard.c
kml.o: kml.c pch.h resource.h emu48.h types.h kml.h
$(CC) $(CFLAGS) $(DEFINES) -c -o kml.o kml.c
mops.o: mops.c pch.h emu48.h types.h opcodes.h io.h \
i28f160.h
$(CC) $(CFLAGS) $(DEFINES) -c -o mops.o mops.c
opcodes.o: opcodes.c pch.h emu48.h types.h opcodes.h \
io.h ops.h
$(CC) $(CFLAGS) $(DEFINES) -c -o opcodes.o opcodes.c
# pch.o: pch.c pch.h
# $(CC) $(CFLAGS) $(DEFINES) -c -o pch.o pch.c
rpl.o: rpl.c pch.h emu48.h types.h io.h
$(CC) $(CFLAGS) $(DEFINES) -c -o rpl.o rpl.c
serial.o: serial.c pch.h emu48.h types.h io.h
$(CC) $(CFLAGS) $(DEFINES) -c -o serial.o serial.c
settings.o: settings.c pch.h emu48.h types.h i28f160.h
$(CC) $(CFLAGS) $(DEFINES) -c -o settings.o settings.c
timer.o: timer.c pch.h emu48.h types.h io.h
$(CC) $(CFLAGS) $(DEFINES) -c -o timer.o timer.c
$(RSRCOBJ): $(RSRC) resource.h dbgtool.bmp emu48.ico checkbox.bmp
windres $(DEFINES) -i $(RSRC) -o $(RSRCOBJ)
$(TARGET): $(OBJS)
$(LD) $(LDFLAGS) -o $(TARGET) $(OBJS) $(LIBS)

37
sources/GCCPatch/PCH.H Normal file
View file

@ -0,0 +1,37 @@
//
// PCH.H (MinGW version)
//
#include <windows.h>
#include <tchar.h>
#include <shellapi.h>
#include <commctrl.h>
#include <stdlib.h>
#include <ctype.h> // for functions missing in stdlib.h
#include <stdio.h>
#include <direct.h>
// #include <crtdbg.h> // missing file
#define _ASSERT(a) // normally defined in missing crtdbg.h
#if defined POINTSTOPOINT // wrong implemented, so new correct definition
#undef POINTSTOPOINT
#define POINTSTOPOINT(pt, pts) \
{ (pt).x = (LONG)(SHORT)LOWORD(*(LONG*)&pts); \
(pt).y = (LONG)(SHORT)HIWORD(*(LONG*)&pts); }
#endif
#if !defined TTN_GETDISPINFOA // missing
#define TTN_GETDISPINFOA (TTN_FIRST - 0)
#endif
#if !defined TTN_GETDISPINFOW // missing
#define TTN_GETDISPINFOW (TTN_FIRST - 10)
#endif
#if !defined TTN_GETDISPINFO // missing
#ifdef UNICODE
#define TTN_GETDISPINFO TTN_GETDISPINFOW
#else
#define TTN_GETDISPINFO TTN_GETDISPINFOA
#endif
#endif

View file

@ -0,0 +1,25 @@
*********************
* Emu48 GCC Version *
*********************
Emu48 is normally compiled with the Microsoft Visual C++ V6.0 compiler. An
alternative is the GCC compiler from the GNU project. A great distribution
of the compiler and the necessary file is MinGW at www.mingw.org.
Emu48 was tested with the following MinGW file versions:
libbfd-2.10.91-20010121.zip
binutils-2.10.91-20010114.zip
ld-2.10.91-20010126.zip
gcc-2.95.2-3.zip
w32api-0.5.1.tar.gz
mingw-runtime-0.5-20010221.tar.gz
Because of some inconsistences in the current MinGW distribution you have to
add the files of this archive to the actual Emu48 source files.
Many thanks to Pedro A. Arranda Gutiérrez for his work on making Emu48 GCC
compatible.
04/21/01 (c) by Christoph Gießelink, cgiess@swol.de

View file

@ -3,7 +3,6 @@
#include <windows.h>
#include <stdlib.h>
#include <stdio.h>
#include <malloc.h>
HANDLE hFile;
DWORD dwWritten;
@ -21,6 +20,9 @@ UINT main(int argc, char *argv[])
nSize = atoi(argv[2]);
switch (nSize)
{
case 32:
nBlocks = 16;
break;
case 128:
nBlocks = 64;
break;
@ -40,7 +42,7 @@ UINT main(int argc, char *argv[])
nBlocks = 2048;
break;
default:
puts("Error: Valid sizes are 128, 256, 512, 1024, 2048 and 4096.\n");
puts("Error: Valid sizes are 32, 128, 256, 512, 1024, 2048 and 4096.\n");
return 0;
}
@ -55,6 +57,7 @@ UINT main(int argc, char *argv[])
while (nBlocks--) WriteFile(hFile, pbyBuffer, 4096, &dwWritten, NULL);
LocalFree(pbyBuffer);
CloseHandle(hFile);
printf("Done.");

120
sources/Mke48/MKE48.C Normal file
View file

@ -0,0 +1,120 @@
/*
* T48G, (c) 2000 Christoph Giesselink (cgiess@swol.de)
*
* 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 this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston,
* MA 02111-1307, USA.
*/
#define WIN32_LEAN_AND_MEAN
#define WIN32_EXTRA_LEAN
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
#include <assert.h>
#include "types.h"
#define VERSION "1.0"
#define _KB(n) (n*1024*2) // KB emulator block
#define HP48SIG "Emu48 Document\xFE" // HP49 state file signature
VOID MakeTemplate(FILE *hFile,BYTE type,DWORD Port0Size,DWORD Port1Size)
{
CHIPSET Chipset;
DWORD dwBytesWritten;
UINT nVar;
BYTE byZ;
// file signature
WriteFile(hFile,HP48SIG,sizeof(HP48SIG),&dwBytesWritten,NULL);
assert(dwBytesWritten == sizeof(HP48SIG));
// KML filename length
nVar = 0; // no name
WriteFile(hFile,&nVar,sizeof(nVar),&dwBytesWritten,NULL);
assert(dwBytesWritten == sizeof(nVar));
// KML filename
// Chipset Size
nVar = sizeof(Chipset); // length, no name
WriteFile(hFile,&nVar,sizeof(nVar),&dwBytesWritten,NULL);
assert(dwBytesWritten == sizeof(nVar));
// Chipset
ZeroMemory(&Chipset,sizeof(Chipset));
Chipset.type = type;
Chipset.Port0Size = Port0Size;
Chipset.Port1Size = Port1Size;
Chipset.Port2Size = 0;
Chipset.cards_status = 0x0;
WriteFile(hFile,&Chipset,sizeof(Chipset),&dwBytesWritten,NULL);
assert(dwBytesWritten == sizeof(Chipset));
byZ = 0; // fill with zero nibble
// write port0 memory content
for (nVar = 0; nVar < _KB(Chipset.Port0Size); ++nVar)
{
WriteFile(hFile,&byZ,1,&dwBytesWritten,NULL);
assert(dwBytesWritten == 1);
}
// write port1 memory content
for (nVar = 0; nVar < _KB(Chipset.Port1Size); ++nVar)
{
WriteFile(hFile,&byZ,1,&dwBytesWritten,NULL);
assert(dwBytesWritten == 1);
}
return;
}
UINT main(int argc, char *argv[])
{
HANDLE hFile;
BYTE type;
DWORD Port0Size;
DWORD Port1Size;
printf("HP48 State File Template for Emu48 V" VERSION "\n");
if (argc != 5 || (*argv[2] != 'S' && *argv[2] != 'G'))
{
printf("\nUsage:\n\t%s <E48-File> <Model[S|G]> <Port0-Size> <Port1-Size>\n\n", argv[0]);
return 1;
}
type = *argv[2];
Port0Size = atoi(argv[3]);
Port1Size = atoi(argv[4]);
hFile = CreateFile(argv[1],GENERIC_WRITE,0,NULL,CREATE_ALWAYS,0,NULL);
if (hFile != INVALID_HANDLE_VALUE)
{
// write template
MakeTemplate(hFile,type,Port0Size,Port1Size);
puts("Generation successful.");
CloseHandle(hFile);
}
else
{
printf("Cannot open file %s.\n", argv[1]);
return TRUE;
}
return FALSE;
}

103
sources/Mke48/MKE48.DSP Normal file
View file

@ -0,0 +1,103 @@
# Microsoft Developer Studio Project File - Name="MKE48" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 5.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Console Application" 0x0103
CFG=MKE48 - Win32 Release
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
!MESSAGE
!MESSAGE NMAKE /f "MKE48.MAK".
!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE NMAKE /f "MKE48.MAK" CFG="MKE48 - Win32 Release"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "MKE48 - Win32 Release" (based on "Win32 (x86) Console Application")
!MESSAGE "MKE48 - Win32 Debug" (based on "Win32 (x86) Console Application")
!MESSAGE
# Begin Project
# PROP Scc_ProjName ""
# PROP Scc_LocalPath ""
CPP=cl.exe
RSC=rc.exe
!IF "$(CFG)" == "MKE48 - Win32 Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "Release"
# PROP BASE Intermediate_Dir "Release"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "Release"
# PROP Intermediate_Dir "Release"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
# ADD BASE RSC /l 0x407 /d "NDEBUG"
# ADD RSC /l 0x407 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
!ELSEIF "$(CFG)" == "MKE48 - Win32 Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "Debug"
# PROP BASE Intermediate_Dir "Debug"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "Debug"
# PROP Intermediate_Dir "Debug"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
# ADD CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
# ADD BASE RSC /l 0x407 /d "_DEBUG"
# ADD RSC /l 0x407 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
!ENDIF
# Begin Target
# Name "MKE48 - Win32 Release"
# Name "MKE48 - Win32 Debug"
# Begin Group "Source Files"
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
# Begin Source File
SOURCE=.\MKE48.C
# End Source File
# End Group
# Begin Group "Header Files"
# PROP Default_Filter "h;hpp;hxx;hm;inl"
# Begin Source File
SOURCE=.\TYPES.H
# End Source File
# End Group
# Begin Group "Resource Files"
# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
# End Group
# End Target
# End Project

103
sources/Mke48/TYPES.H Normal file
View file

@ -0,0 +1,103 @@
/*
* types.h
*
* This file is part of Emu48
*
* Copyright (C) 1995 Sebastien Carlier
*
*/
// HST bits
#define XM 1
#define SB 2
#define SR 4
#define MP 8
#define SWORD SHORT // signed 16 Bit variable
#define QWORD ULONGLONG // unsigned 64 Bit variable
#define CHIPSET Chipset_t
typedef struct
{
SWORD nPosX; // position of window
SWORD nPosY;
BYTE type; // calculator type
DWORD Port0Size; // real size of module in KB
DWORD Port1Size; // real size of module in KB
DWORD Port2Size; // real size of module in KB (HP49G only)
LPBYTE Port0;
LPBYTE Port1;
LPBYTE Port2;
DWORD pc;
DWORD d0;
DWORD d1;
DWORD rstkp;
DWORD rstk[8];
BYTE A[16];
BYTE B[16];
BYTE C[16];
BYTE D[16];
BYTE R0[16];
BYTE R1[16];
BYTE R2[16];
BYTE R3[16];
BYTE R4[16];
BYTE ST[4];
BYTE HST;
BYTE P;
WORD out;
WORD in;
BOOL SoftInt;
BOOL Shutdn;
BOOL mode_dec;
BOOL inte; // interrupt status flag (FALSE = int in service)
BOOL intk; // 1 ms keyboard scan flag (TRUE = enable)
BOOL intd; // keyboard interrupt pending (TRUE = int pending)
BOOL carry;
WORD crc;
WORD wPort2Crc; // fingerprint of port2
WORD wRomCrc; // fingerprint of ROM
#if defined _USRDLL // DLL version
QWORD cycles; // oscillator cycles
#else // EXE version
DWORD cycles; // oscillator cycles
DWORD cycles_reserved; // reserved for MSB of oscillator cycles
#endif
DWORD dwKdnCycles; // cpu cycles at start of 1ms key handler
UINT Bank_FF; // save state of HP48GX port2 or state of HP49G ROM FF
UINT FlashRomState; // WSM state of flash memory (unused)
BYTE cards_status;
BYTE IORam[64]; // I/O hardware register
UINT IOBase; // address of I/O modules page
BOOL IOCfig; // I/O module configuration flag
BYTE P0Base, BSBase, P1Base, P2Base; // address of modules first 2KB page
BYTE P0Size, BSSize, P1Size, P2Size; // mapped size of module in 2KB
BYTE P0End, BSEnd, P1End, P2End; // address of modules last 2KB page
BOOL P0Cfig, BSCfig, P1Cfig, P2Cfig; // module address configuration flag
BOOL P0Cfg2, BSCfg2, P1Cfg2, P2Cfg2; // module size configuration flag
BYTE t1;
DWORD t2;
BOOL bShutdnWake; // flag for wake up from SHUTDN mode
BYTE Keyboard_Row[9];
WORD IR15X;
UINT Keyboard_State; // not used
signed short loffset;
signed int width;
UINT boffset;
UINT lcounter;
UINT sync; // not used
BYTE contrast;
BOOL dispon;
DWORD start1;
DWORD start12;
DWORD end1;
DWORD start2, end2;
} Chipset_t;