Merge branch 'master' into bug_479
@ -236,6 +236,8 @@
|
||||
<None Include="resource\PRAVETS8M.ROM" />
|
||||
<None Include="resource\SSC.rom" />
|
||||
<None Include="resource\ThunderClockPlus.rom" />
|
||||
<None Include="resource\TK3000e.rom" />
|
||||
<None Include="resource\TKClock.rom" />
|
||||
<None Include="source\CPU\cpu_general.inl" />
|
||||
<None Include="source\CPU\cpu_instructions.inl" />
|
||||
</ItemGroup>
|
||||
@ -283,6 +285,7 @@
|
||||
<Image Include="resource\LED_CAPS_ON_LAT.BMP" />
|
||||
<Image Include="resource\LED_CAPS_ON_P8.BMP" />
|
||||
<Image Include="resource\RUN.BMP" />
|
||||
<Image Include="resource\RUN3000E.bmp" />
|
||||
<Image Include="resource\RUNP.BMP" />
|
||||
<Image Include="resource\SETUP.BMP" />
|
||||
</ItemGroup>
|
||||
|
@ -554,6 +554,9 @@
|
||||
<Image Include="resource\SETUP.BMP">
|
||||
<Filter>Resource Files</Filter>
|
||||
</Image>
|
||||
<Image Include="resource\RUN3000E.bmp">
|
||||
<Filter>Resource Files</Filter>
|
||||
</Image>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="resource\Apple2.rom">
|
||||
@ -607,6 +610,12 @@
|
||||
<None Include="resource\ThunderClockPlus.rom">
|
||||
<Filter>Resource Files</Filter>
|
||||
</None>
|
||||
<None Include="resource\TK3000e.rom">
|
||||
<Filter>Resource Files</Filter>
|
||||
</None>
|
||||
<None Include="resource\TKClock.rom">
|
||||
<Filter>Resource Files</Filter>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Text Include="docs\CodingConventions.txt">
|
||||
|
@ -236,6 +236,8 @@
|
||||
<None Include="resource\PRAVETS8M.ROM" />
|
||||
<None Include="resource\SSC.rom" />
|
||||
<None Include="resource\ThunderClockPlus.rom" />
|
||||
<None Include="resource\TK3000e.rom" />
|
||||
<None Include="resource\TKClock.rom" />
|
||||
<None Include="source\CPU\cpu_general.inl" />
|
||||
<None Include="source\CPU\cpu_instructions.inl" />
|
||||
</ItemGroup>
|
||||
@ -283,6 +285,7 @@
|
||||
<Image Include="resource\LED_CAPS_ON_LAT.BMP" />
|
||||
<Image Include="resource\LED_CAPS_ON_P8.BMP" />
|
||||
<Image Include="resource\RUN.BMP" />
|
||||
<Image Include="resource\RUN3000E.bmp" />
|
||||
<Image Include="resource\RUNP.BMP" />
|
||||
<Image Include="resource\SETUP.BMP" />
|
||||
</ItemGroup>
|
||||
|
@ -554,6 +554,9 @@
|
||||
<Image Include="resource\SETUP.BMP">
|
||||
<Filter>Resource Files</Filter>
|
||||
</Image>
|
||||
<Image Include="resource\RUN3000E.bmp">
|
||||
<Filter>Resource Files</Filter>
|
||||
</Image>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="resource\Apple2.rom">
|
||||
@ -607,6 +610,12 @@
|
||||
<None Include="resource\ThunderClockPlus.rom">
|
||||
<Filter>Resource Files</Filter>
|
||||
</None>
|
||||
<None Include="resource\TK3000e.rom">
|
||||
<Filter>Resource Files</Filter>
|
||||
</None>
|
||||
<None Include="resource\TKClock.rom">
|
||||
<Filter>Resource Files</Filter>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Text Include="docs\CodingConventions.txt">
|
||||
|
@ -17,7 +17,7 @@ To compile from source see:
|
||||
|
||||
Next Version
|
||||
============
|
||||
Experimental build [1.26.2.4](https://github.com/AppleWin/AppleWin/releases/tag/v1.26.2.4)
|
||||
Experimental build [1.26.3.1](https://github.com/AppleWin/AppleWin/releases/tag/v1.26.3.1)
|
||||
|
||||
Please report [new issues](https://github.com/AppleWin/AppleWin/issues/new)
|
||||
|
||||
|
@ -1,4 +1,5 @@
|
||||
; Apple 2 Rom Symbol Table
|
||||
; Version 4 GH#484
|
||||
; Version 3 Cross-referenced/Sync'd with APPLE2E.SYM & A2_BASIC.SYM
|
||||
Added Text Holes
|
||||
; Version 2 by Michael Pohoreski - AppleWin Debugger Dev
|
||||
@ -15,18 +16,24 @@
|
||||
0026 GBASL
|
||||
0027 GBASH
|
||||
0028 BASL
|
||||
0029 BAS2L
|
||||
0029 BASH
|
||||
002A BAS2L
|
||||
002B BAS2H
|
||||
002C H2/LMNEM
|
||||
002D V2/RMNEM
|
||||
002E MASK/TEMPOP
|
||||
;$2E aliases 3 symbols
|
||||
;36 MASK EQU $2E
|
||||
;37 CHKSUM EQU $2E
|
||||
;38 FORMAT EQU $2E
|
||||
002E F8.MASK
|
||||
002F LENGTH/LASTIN
|
||||
; Applesoft COLOR F24F
|
||||
; ROM/Monitor COLOR 30
|
||||
; Reference: Apple ][ Reference Manual
|
||||
0030 COLOR
|
||||
0031 MODE
|
||||
0032 INVFLG/PROMPT
|
||||
0032 INVFLG
|
||||
0033 PROMPT
|
||||
0034 YSAV
|
||||
0035 SAVY1
|
||||
0036 CSWL
|
||||
@ -281,7 +288,7 @@ C4FA AMOD6
|
||||
C567 XHEADER
|
||||
C5AA WRITE2
|
||||
C5D1 XREAD
|
||||
; Disk Drive
|
||||
; IIe Technical Reference Manual (1987), Page 317, $C3XX ROM
|
||||
C603 TSTZPG
|
||||
C607 ZP1
|
||||
C610 ZP2
|
||||
|
@ -9,16 +9,37 @@ https://github.com/AppleWin/AppleWin/issues/new
|
||||
Tom Charlesworth
|
||||
|
||||
|
||||
1.26.3.0 (Experimental) - 4 Aug 2017
|
||||
1.26.3.5 (Experimental) - 4 Dec 2017
|
||||
------------------------------------
|
||||
Changes:
|
||||
. [Bug #504] Full-screen: hide mouse pointer after 2 seconds of inactivity (and show again if mouse is moved)
|
||||
. [Bug #469] New -no-printscreen-key switch to prevent the PrintScreen key from being registered.
|
||||
. [Bug #488] New -fs-height=<best|nnnn> switch.
|
||||
- best: picks the highest resolution where the height is an integer multiple of (192*2)
|
||||
- nnnn: select a specific resolution with height=nnnn pixels
|
||||
Use to select a better resolution for full-screen mode.
|
||||
NB. This changes the display resolution (and restores on exit).
|
||||
. [Bug #428] Input option to use PC Joystick 1 Thumbstick 2 for emulated Joystick 2
|
||||
. Swapping disks while a drive is on now warns and prompts if you still wish to do this instead of silently failing with no feedback.
|
||||
. [Bug #323] Skip hard disk boot by holding down the Open-Apple key during an Apple II restart
|
||||
. [Bug #224] Added Config checkbox for 'Full-Screen: Show drive/keyboard status'
|
||||
. [PR #441] Update zlib to latest version 1.2.11
|
||||
|
||||
Fixes:
|
||||
. [Bug #516] Internal video-mode was having PAGE2 permanently cleared (instead of just masked) when 80STORE was set.
|
||||
. [Bug #514] Emulator restart (or reset) wasn't clearing any pending Mousecard interrupt
|
||||
. [Bug #499] Flush current track (if dirty) before 'Send to CiderPress'
|
||||
. [Bug #496] Support polling of Mockingboard's & Phasor's 6522 IFR.Timer1
|
||||
. [Bug #492] UI fixes for full-screen & 2x windowed-mode
|
||||
. [Bug #486] Peripheral card's expansion ROM ($C800-CFFF, eg. SSC) wasn't being correctly restored from a save-state
|
||||
- Resulting in regression: Mousecard crash to monitor (#495).
|
||||
. [Bug #464] Fix for full-screen: bottom line missing when vertical resolution is 768
|
||||
. [Bug #460] Debugger: F2 whilst debugger active will immediately stop the drive spinning (allowing disk swap)
|
||||
. [Bug #456] Fix strange speaker clicks when changing configuration - DirectSound wasn't being uninitialised on a restart
|
||||
. [Bug #452] Fix for unmounted HD now gives "NO DEVICE CONNECTED" (before gave "I/O ERROR")
|
||||
. [Bug #450] Persist debugger state across an F2 (reset machine state)
|
||||
. [Bug #445] Debugger: BPM cmd: Support trigger on stack access for BRK,JSR,PLn,PHn,RTI,RTS
|
||||
. [Bug #437] AppleWin.chm blocked from opening - delete the AppleWin.chm:Zone.Identifier ADS
|
||||
. [Bug #423] Full support for INTC8ROM soft switch (fixes transient a2audit.dsk & Bejeweled failures)
|
||||
. [Bug #418] Fix for slot-3 ROM not returning floating bus when Uthernet card is enabled
|
||||
. [Bug #417] Typos in Uthernet documentation
|
||||
@ -36,9 +57,10 @@ Fixes:
|
||||
- Experimental support for 6551's control bit: DTR via -dtr switch
|
||||
- Experimental support for 6551's status bits: DCD and DSR via -dcd and -dsr switches
|
||||
. [Bug #383] "Enhanced disk speed" is very slow when debugger is active
|
||||
. [Bug #320] Mockingboard/Phasor: support 'inactive' function like real hardware
|
||||
. [Bug #269] When stepping, ESC no longer exits back to debugger (use F7, Pause keys or Debugger button instead).
|
||||
. [Bug #250] Debugger: When MODE_STEPPING, fix issue with disk LEDs staying on
|
||||
. [Bug #217] Debugger G(o) command should use normal speed
|
||||
- When stepping, ESC no longer exits back to debugger (use F7, Pause keys or Debugger button instead).
|
||||
- Persist F2 (reset machine state) across debug & stepping states
|
||||
. Debugger: Added new gg command:
|
||||
|
||||
command | run at normal speed? | run at full speed? | video quality | sound quality
|
||||
@ -46,6 +68,8 @@ Fixes:
|
||||
g | yes | only if disk active, etc | precise | precise
|
||||
gg | no | always | periodic | muted
|
||||
|
||||
. [Bug #213] Pause not setting volume to zero
|
||||
|
||||
|
||||
1.26.1.1 - 17 Feb 2017
|
||||
----------------------
|
||||
|
136
docs/VICE Knowledge Base - Article 13-005.htm
Normal file
@ -0,0 +1,136 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||
<html><head>
|
||||
|
||||
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
|
||||
<meta name="author" content="Spiro Trikaliotis">
|
||||
<meta name="copyright" content="© 2003-2007 Spiro Trikaliotis and the VICE team">
|
||||
<link rel="stylesheet" href="VICE%20Knowledge%20Base%20-%20Article%2013-005_files/vicekb.css" title="My own stylesheet">
|
||||
<meta name="keywords" content="vice knowledge base,vkb,x64,x128,xplus4,xcbm,xvic">
|
||||
<title>VICE Knowledge Base - Article 13-005</title>
|
||||
</head>
|
||||
<body>
|
||||
<!--#config timefmt="%d.%b.%Y %H:%M" -->
|
||||
<div class="top">
|
||||
<div class="title">
|
||||
<h1>
|
||||
<a href="http://web.archive.org/web/20130517193701/http://www.viceteam.org/">
|
||||
<img alt="VICE home" src="VICE%20Knowledge%20Base%20-%20Article%2013-005_files/vice-logo.png" width="120" height="45" border="0"></a>
|
||||
Knowledge Base - Article 13-005</h1>
|
||||
</div> <!-- title -->
|
||||
<hr>
|
||||
</div> <!-- top -->
|
||||
<div class="main">
|
||||
<div class="sidebar">
|
||||
<p>Article ID: 13-005</p>
|
||||
<p><b>Last Reviewed:</b><br>August 25, 2004</p>
|
||||
<p><a title="Send this article to a friend" href="http://web.archive.org/web/20130517193701/mailto:/?subject=VICE%20Knowledge%20Base%20Article%20-%2013-005&body=This%20article%20pointer%20was%20forwarded%20to%20you%20from%20the%20VICE%20Knowledge%20Base%20site.%20http://vicekb.trikaliotis.net/13-005">
|
||||
<img src="VICE%20Knowledge%20Base%20-%20Article%2013-005_files/icoEmail.gif" width="18" height="10" border="0" align="absMiddle">Send to a friend</a></p>
|
||||
<p>Provided by<br><a target="_top" href="http://web.archive.org/web/20130517193701/http://www.viceteam.org/">The VICE team</a></p>
|
||||
<p>If you want to bookmark this page or refer to it, use the following URL only, please:<br>
|
||||
<a href="http://web.archive.org/web/20130517193701/http://vicekb.trikaliotis.net/13-005">http://vicekb.trikaliotis.net/13-005</a>
|
||||
</p><hr>
|
||||
</div> <!-- sidebar -->
|
||||
<div class="content">
|
||||
<h1>[Howto] Enable networking with WinVICE</h1>
|
||||
<hr>
|
||||
The information in this article applies to the following versions of VICE: <ul><li>all Windows versions starting from 1.13</li></ul>
|
||||
<hr><h2>PROBLEMEXPOSITION</h2>
|
||||
<p>Starting with WinVICE 1.13, there is support for two ethernet cartridges allowing network access: The "<a href="http://web.archive.org/web/20130517193701/http://www.dunkels.com/adam/tfe/">The Final
|
||||
Ethernet</a>" (TFE) and the "Retroreplay-Net" (RR-Net) cartridges. If you
|
||||
want to enable support for these, you have to follow the instructions below.</p><h2>!WARNING!</h2>
|
||||
<p>Installing support for networking with VICE requires you to install
|
||||
3rd party products on your machine. The VICE team cannot be
|
||||
made responsible for any problems
|
||||
and/or damage which arises from this! The rejection of any
|
||||
warranty for VICE
|
||||
applies, too.<br>
|
||||
The product which has to be installed, <a href="http://web.archive.org/web/20130517193701/http://winpcap.polito.it/">WinPCAP</a>,
|
||||
is a capture library. That is, it captures <b>every</b> packet which is available
|
||||
on the network, regardless if it was destined for your machine or not. From this, it
|
||||
follows that it is a real security flaw using WinPCAP in a network. Using WinPCAP
|
||||
can result in disclosure of any information that is available on your network which is
|
||||
not secured by other means! Installing WinPCAP, you acknowledge that you're well aware
|
||||
of this security flaw and that the VICE team cannot be made responsible for any problems
|
||||
and/or damage which may arise from the use of WinPCAP!</p><h2>PREREQUISITES</h2>
|
||||
<p>At that moment, The ethernet emulation for WinVICE only works if you
|
||||
have a real ethernet card on your machine and you are
|
||||
connected to the net via it, that is, you must have
|
||||
direct access to any station you want to access. Ethernet
|
||||
is emulated as if the VICE emulator was
|
||||
connected to your ethernet card via a hub. Every protocol,
|
||||
in particular PPPOE or other protocols,
|
||||
are only supported if the corresponding emulated program
|
||||
supports these!</p><h2>SOLUTION</h2>
|
||||
<p></p><p>For networking support, you need administrative rights
|
||||
(administrator account or similar) on your windows machine.
|
||||
Without this, there's no chance to have networking work!</p>
|
||||
<p>If you have administrative rights, follow the following instructions to install networking
|
||||
with VICE:</p>
|
||||
<ul><li>First, read the above warning!</li><li>Get <a href="http://web.archive.org/web/20130517193701/http://winpcap.polito.it/">WinPCAP</a>
|
||||
from their site. There's only need for the WinPCAP auto-installer in order to let VICE run.</li>
|
||||
<li>Install the WinPCAP package you just downloaded. For this, you need to have the right to install
|
||||
new drivers to your system. In general, the administrator account does have this right.</li>
|
||||
<li>Now, start WinVICE as you do always. Do this with the user account you have used in the previous
|
||||
step to install WinPCAP! Choosing the VICE menu entry Settings/Ethernet, a dialog box
|
||||
shows up, allowing you to select Ethernet as NONE, TFE ("The final ethernet") or RR-Net. If this
|
||||
is possible, WinPCAP has be installed successfully to your system. If not, check the <a href="http://web.archive.org/web/20130517193701/http://winpcap.polito.it/misc/faq.htm">WinPCAP FAQ</a> to find a solution.</li>
|
||||
<li>The only program using ethernet we know to date is <a href="http://web.archive.org/web/20130517193701/http://dunkels.com/adam/contiki/index.html">Contiki</a>. To use Contiki, get a version of it
|
||||
from <a href="http://web.archive.org/web/20130517193701/http://dunkels.com/adam/contiki/index.html">the website</a>. Make sure that it is
|
||||
a version which is enabled for ethernet (TFE or RR-Net)!</li>
|
||||
<li>Run this version of Contiki inside x64. Now, enable ethernet with TFE or RR-Net settings, depending
|
||||
on which type you want to use. Since these two are almost identical, only some addresses are changed,
|
||||
it's more of a matter of taste which one to use. Select the ethernet device you want to use with
|
||||
ethernet if you have more than one.
|
||||
</li><li>You need an IP address in order to let Contiki run on your network. The virtual ethernet device
|
||||
of VICE runs as if it were connected to your host computer's device with a hub. No network address
|
||||
translation (NAT) or the like is performed! Get an IP from your network administrator as if you had
|
||||
a new machine to connect to your network. In fact, you have one, although it is only emulated.</li>
|
||||
<li> Now, run Contiki, enter your IP configuration using the IP from above, and everything should
|
||||
work.</li></ul>
|
||||
<p>Enjoy the new surfing experience.</p>
|
||||
<p>It's not necessary to log on as administrator in order to run the ethernet emulation. Anyway,
|
||||
this <b>is</b> necessary the first time you start VICE after you've booted. After you've done
|
||||
this, you can log off and log in with another account to run VICE. To circumvent this, see
|
||||
the FAQ section below.</p><h2>FAQ</h2>
|
||||
<p></p><ul><li><p><b>Why do I have to log in as administrator in order to start VICE with network support?</b></p><p>This is because the WinPCAP driver is not loaded at system startup, but rather
|
||||
on-demand when someone like VICE needs it. Not every user is allowed to start services, thus, you
|
||||
have to log in as a user with these rights in order to start it. The administrator is a person having
|
||||
this right. On many machines, an account belonging to the "main user" group is allowed,
|
||||
too. On these machines, you don't need administrator rights in order to start VICE with networking
|
||||
support.</p><p>If you don't like this solution, you have another option. See <a href="http://web.archive.org/web/20130517193701/http://winpcap.polito.it/misc/faq.htm#Q-18">Q-18</a> at the WinPCAP FAQ.</p></li>
|
||||
<li><p><b>I have problems with networking support; furthermore, there's a firewall on my machine</b></p>
|
||||
<p>This is a know problem with WinPCAP, it does not work well with all firewalls, see <a href="http://web.archive.org/web/20130517193701/http://winpcap.polito.it/misc/faq.htm#Q-10">Q-10</a> at the WinPCAP FAQ. Unfortunately, we don't
|
||||
have a solution for this. Disabling the firewall, as suggested in Q-10, might not be an option for
|
||||
you, but we cannot do anything about it.</p></li>
|
||||
<li><p><b>I have another problem not covered here.</b></p><p>Have a look at the <a href="http://web.archive.org/web/20130517193701/http://winpcap.polito.it/misc/faq.htm">WinPCAP FAQ</a>, there might be a solution for your problem.
|
||||
</p></li></ul><p></p><h2>STATUS</h2>
|
||||
<p>This document is for information purpose only. The behaviour reported
|
||||
is intentional in the VICE versions listed at the beginning
|
||||
of this article.</p><h2>LINKS</h2>
|
||||
<p></p><ul><li><a href="http://web.archive.org/web/20130517193701/http://vicekb.trikaliotis.net/11-002">11-002 [Howto] Enable networking on VICE/Unix</a>.</li> <li>The Final Ethernet Homepage: <a href="http://web.archive.org/web/20130517193701/http://www.dunkels.com/adam/tfe/">http://www.dunkels.com/adam/tfe/</a>.</li><li>
|
||||
Contiki Homepage:
|
||||
<a href="http://web.archive.org/web/20130517193701/http://dunkels.com/adam/contiki/index.html">http://dunkels.com/adam/contiki/index.html</a>.
|
||||
</li><li>WinPCAP: <a href="http://web.archive.org/web/20130517193701/http://winpcap.polito.it/">http://winpcap.polito.it/</a>.
|
||||
</li><li><a href="http://web.archive.org/web/20130517193701/http://winpcap.polito.it/misc/faq.htm">WinPCAP FAQ</a>, especially
|
||||
<a href="http://web.archive.org/web/20130517193701/http://winpcap.polito.it/misc/faq.htm#Q-10">Q-10</a> and <a href="http://web.archive.org/web/20130517193701/http://winpcap.polito.it/misc/faq.htm#Q-18">Q-18</a>.</li></ul><p></p><h2>REVISION</h2>
|
||||
<p></p><ul><li>August 25,2004: Added reference to the same information for Unix based systems</li> <li>October 14, 2003: Before, it was mistakenly said that you find ethernet on
|
||||
Options/Ethernet. This is not true, it is Settings/Ethernet.</li>
|
||||
<li>October 8, 2003: Added section PREREQUISITES.</li>
|
||||
<li>September 15, 2003: Original release of this document</li></ul><p></p> </div> <!-- content -->
|
||||
<div class="review">
|
||||
<p>Last Reviewed: August 25, 2004</p>
|
||||
</div> <!-- review -->
|
||||
</div> <!-- main -->
|
||||
<div class="footer">
|
||||
<hr>
|
||||
<div class="copyright"> © 2003-2007 <a href="http://web.archive.org/web/20130517193701/mailto:www@@trikaliotis.net">Spiro Trikaliotis</a> and <a href="http://web.archive.org/web/20130517193701/http://www.viceteam.org/">The VICE team</a><br>
|
||||
<a href="http://web.archive.org/web/20130517193701/http://vicekb.trikaliotis.net/13-005">http://vicekb.trikaliotis.net/13-005</a>
|
||||
Last modified: August 25, 2004
|
||||
</div> <!-- copyright -->
|
||||
<div class="fileinfo">
|
||||
<a href="http://web.archive.org/web/20130517193701/http://www.anybrowser.org/campaign/"><img src="VICE%20Knowledge%20Base%20-%20Article%2013-005_files/ab-ms-star-en.gif" alt="Viewable With Any Browser" width="88" height="31"></a><a href="http://web.archive.org/web/20130517193701/http://jigsaw.w3.org/css-validator/validator?uri=http://www.trikaliotis.net/vicekb/common/vicekb.css">
|
||||
<img style="border:0;width:88px;height:31px" src="VICE%20Knowledge%20Base%20-%20Article%2013-005_files/vcss.gif" alt="Valid CSS!"></a>
|
||||
</div> <!-- fileinfo -->
|
||||
</div> <!-- footer -->
|
||||
|
||||
</body></html>
|
After Width: | Height: | Size: 1.3 KiB |
BIN
docs/VICE Knowledge Base - Article 13-005_files/icoEmail.gif
Normal file
After Width: | Height: | Size: 106 B |
BIN
docs/VICE Knowledge Base - Article 13-005_files/vcss.gif
Normal file
After Width: | Height: | Size: 1.5 KiB |
BIN
docs/VICE Knowledge Base - Article 13-005_files/vice-logo.png
Normal file
After Width: | Height: | Size: 3.4 KiB |
78
docs/VICE Knowledge Base - Article 13-005_files/vicekb.css
Normal file
@ -0,0 +1,78 @@
|
||||
BODY {
|
||||
FONT-FAMILY: Helvetica, Arial, Tahoma, sans-serif
|
||||
}
|
||||
DIV.top {
|
||||
MARGIN-TOP: 0pt; MARGIN-BOTTOM: 6pt
|
||||
}
|
||||
DIV.top.title {
|
||||
center; FLOAT: right; MARGIN-LEFT: 20%
|
||||
}
|
||||
DIV.top.title P {
|
||||
text-align: center; color: red
|
||||
}
|
||||
DIV.top.logo {
|
||||
FLOAT: left; WIDTH: 20%; MARGIN-RIGHT: 80%
|
||||
}
|
||||
|
||||
DIV.main {
|
||||
}
|
||||
|
||||
DIV.sidebar {
|
||||
MARGIN-TOP: 0pt; FLOAT: right; MARGIN-BOTTOM: 6pt; WIDTH: 30%
|
||||
}
|
||||
|
||||
DIV.sidebar P {
|
||||
FONT-SIZE: 8pt; MARGIN: 0pt 2pt 6pt 36pt
|
||||
}
|
||||
|
||||
DIV.main.content {
|
||||
MARGIN-RIGHT: 30%
|
||||
PADDING-RIGHT: 2pt; PADDING-LEFT: 2pt; PADDING-BOTTOM: 2pt; PADDING-TOP: 2pt
|
||||
}
|
||||
DIV.main.content P {
|
||||
FONT-SIZE: 12pt; MARGIN: 0pt 2pt 6pt 36pt
|
||||
}
|
||||
DIV.main.content P.centered {
|
||||
FONT-SIZE: 12pt; MARGIN: 0pt 2pt 6pt; TEXT-ALIGN: center
|
||||
}
|
||||
DIV.main.content ui {
|
||||
MARGIN: 0pt 0pt 6pt
|
||||
}
|
||||
DIV.main.content li {
|
||||
FONT-SIZE: 12pt
|
||||
}
|
||||
DIV.main.content h1 {
|
||||
FONT-SIZE: 20pt
|
||||
}
|
||||
DIV.content h2 {
|
||||
FONT-SIZE: 15pt
|
||||
}
|
||||
DIV.content hr {
|
||||
MARGIN-RIGHT: 30%; HEIGHT: 3pt
|
||||
}
|
||||
|
||||
DIV.main.content P {
|
||||
}
|
||||
|
||||
DIV.footer {
|
||||
PADDING-RIGHT: 2pt; MARGIN-TOP: 6pt; PADDING-LEFT: 2pt; FLOAT: left; MARGIN-BOTTOM: 0pt; PADDING-BOTTOM: 2pt; VERTICAL-ALIGN: baseline; WIDTH: 100%; PADDING-TOP: 2pt
|
||||
}
|
||||
|
||||
DIV.copyright {
|
||||
FONT-SIZE: 60%; FLOAT: left
|
||||
}
|
||||
DIV.review {
|
||||
text-align: center; FONT-SIZE: 8pt
|
||||
}
|
||||
DIV.fileinfo {
|
||||
FONT-SIZE: 60%; FLOAT: right
|
||||
}
|
||||
|
||||
/*
|
||||
FILE ARCHIVED ON 03:57:53 Jul 19, 2013 AND RETRIEVED FROM THE
|
||||
INTERNET ARCHIVE ON 21:23:25 Dec 18, 2017.
|
||||
JAVASCRIPT APPENDED BY WAYBACK MACHINE, COPYRIGHT INTERNET ARCHIVE.
|
||||
|
||||
ALL OTHER CONTENT MAY ALSO BE PROTECTED BY COPYRIGHT (17 U.S.C.
|
||||
SECTION 108(a)(3)).
|
||||
*/
|
@ -1,6 +1,45 @@
|
||||
How To Compile/Build AppleWin
|
||||
=============================
|
||||
|
||||
MSVC 2017 Community
|
||||
===================
|
||||
|
||||
1. Install [.NET Framework 4.6](https://www.microsoft.com/en-us/download/details.aspx?id=48137)
|
||||
|
||||
NOTE: The installer _will still_ complain about 4.6 even if [4.6.2](http://www.microsoft.com/en-us/download/details.aspx?id=53344) is installed.
|
||||
)
|
||||
|
||||
2. MSVC 2017 Community Edition
|
||||
|
||||
a. Install [MSVC 2017 Community](https://www.visualstudio.com/thank-you-downloading-visual-studio/?sku=Community&rel=15)
|
||||
b. Run `vs_Community.exe`
|
||||
c. `Individual Components`
|
||||
|
||||
NOTE: Not all of these may be required but they are recommended:
|
||||
|
||||
|
||||
* [x] .NET Framework 4.6.1 SDK
|
||||
* [x] .NET Framework 4.6.1 targeting pack
|
||||
* [x] C++ profiling tools
|
||||
* [x] C++/CLI support
|
||||
* [x] Git for Windows
|
||||
* [x] Graphics Tools Windows 8.1 SDK
|
||||
* [x] Graphics debugger and GPU profiler for DirectX
|
||||
* [x] Static analysis tools
|
||||
* [x] VC++ 2017 v141 toolset (x86,x64)
|
||||
* [x] Visual Studio C++ core features
|
||||
* [x] Windows 8.1 SDK
|
||||
* [x] Windows 10 SDK (10.0.15063.0) for Desktop C++ x86 and x64
|
||||
* [x] Windows 10 SDK (10.0.15063.0) for UWP: C#, VB, JS
|
||||
* [x] Windows 10 SDK (10.0.15063.0) for UWP: C++
|
||||
|
||||
3. Clone the repository
|
||||
|
||||
git clone https://github.com/AppleWin/AppleWin.git
|
||||
|
||||
Older MSVC instructions
|
||||
=======================
|
||||
|
||||
0. Install git
|
||||
|
||||
1. Clone the repository
|
||||
|
@ -1,7 +1,7 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
<html>
|
||||
<head>
|
||||
<title>Save-State Files</title>
|
||||
<title>Command line</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
|
||||
</head>
|
||||
<body style="FONT-FAMILY: verdana; BACKGROUND-COLOR: rgb(255,255,255)" alink="#008000"
|
||||
@ -17,12 +17,21 @@
|
||||
Start with a disk in drive-2<br><br>
|
||||
-f<br>
|
||||
Start in full-screen mode<br><br>
|
||||
-fs-height=<best|nnnn><br>
|
||||
Use to select a better resolution for full-screen mode.<br>
|
||||
<ul>
|
||||
<li>best: picks the highest resolution where the height is an integer multiple of (192*2)</li>
|
||||
<li>nnnn: select a specific resolution with height=nnnn pixels</li>
|
||||
</ul>
|
||||
NB. This changes the display resolution (and restores on exit).<br><br>
|
||||
-r <number of pages><br>
|
||||
Emulate a RAMworks III card with 1 to 127 pages (each page is 64K, giving a max of 8MB)<br><br>
|
||||
-f8rom <rom-file><br>
|
||||
Use custom 2K ROM at [$F800..$FFFF]. <rom-file> must be 2048 bytes long<br><br>
|
||||
-printscreen<br>
|
||||
Enable the dialog box to display the last file saved to<br><br>
|
||||
-no-printscreen-key<br>
|
||||
Prevent the PrintScreen key from being registered<br><br>
|
||||
-use-real-printer<br>
|
||||
Enables Advanced configuration control to allow dumping to a real printer<br><br>
|
||||
-noreg<br>
|
||||
@ -46,7 +55,9 @@
|
||||
-load-state <savestate><br>
|
||||
Load a save-state file<br><br>
|
||||
-modem<br>
|
||||
Shorthand for passing -dtr -dcd -dsr<br><br>
|
||||
Shorthand for passing -dtr -dcd -dsr<br>
|
||||
Use with GBBS Pro (or any other BBS package). See the <a href="http://www.callapple.org/documentation/books/gbbs-pro-2-2/">GBBS Pro 2.2</a> book from Call-A.P.P.L.E.
|
||||
<br><br>
|
||||
-dtr<br>
|
||||
Support SSC's DTR (Data Terminal Ready) control bit<br><br>
|
||||
-dcd<br>
|
||||
@ -58,7 +69,7 @@
|
||||
<br>
|
||||
<P style="FONT-WEIGHT: bold">Debug arguments:
|
||||
</P>
|
||||
-l<br>
|
||||
-l or -log<br>
|
||||
Enable logging. Creates an AppleWin.log file<br><br>
|
||||
-m<br>
|
||||
Disable DirectSound support<br><br>
|
||||
|
@ -89,7 +89,14 @@
|
||||
<LI> <OBJECT type="text/sitemap">
|
||||
<param name="Name" value="Uthernet network card">
|
||||
<param name="Local" value="uthernet.html">
|
||||
<param name="ImageNumber" value="2">
|
||||
</OBJECT>
|
||||
<UL>
|
||||
<LI> <OBJECT type="text/sitemap">
|
||||
<param name="Name" value="WiFi workaround">
|
||||
<param name="Local" value="uthernet-wifi-workaround.html">
|
||||
</OBJECT>
|
||||
</UL>
|
||||
<LI> <OBJECT type="text/sitemap">
|
||||
<param name="Name" value="Command line">
|
||||
<param name="Local" value="CommandLine.html">
|
||||
@ -141,7 +148,7 @@
|
||||
</OBJECT>
|
||||
<UL>
|
||||
<LI> <OBJECT type="text/sitemap">
|
||||
<param name="Name" value="Entering the debugger">
|
||||
<param name="Name" value="Entering & exiting the debugger">
|
||||
<param name="Local" value="dbg-entering-debugger.html">
|
||||
</OBJECT>
|
||||
<LI> <OBJECT type="text/sitemap">
|
||||
@ -185,10 +192,6 @@
|
||||
<param name="Local" value="dbg-configuration.html">
|
||||
</OBJECT>
|
||||
</UL>
|
||||
<LI> <OBJECT type="text/sitemap">
|
||||
<param name="Name" value="Troubleshooting">
|
||||
<param name="Local" value="Troubleshooting.html">
|
||||
</OBJECT>
|
||||
<LI> <OBJECT type="text/sitemap">
|
||||
<param name="Name" value="Resources">
|
||||
<param name="Local" value="resources.html">
|
||||
@ -208,6 +211,21 @@
|
||||
<param name="Local" value="contact.html">
|
||||
</OBJECT>
|
||||
</UL>
|
||||
<LI> <OBJECT type="text/sitemap">
|
||||
<param name="Name" value="Appendix">
|
||||
<param name="Local" value="appendix.html">
|
||||
<param name="ImageNumber" value="2">
|
||||
</OBJECT>
|
||||
<UL>
|
||||
<LI> <OBJECT type="text/sitemap">
|
||||
<param name="Name" value="Full-speed mode">
|
||||
<param name="Local" value="fullspeed.html">
|
||||
</OBJECT>
|
||||
<LI> <OBJECT type="text/sitemap">
|
||||
<param name="Name" value="Troubleshooting">
|
||||
<param name="Local" value="Troubleshooting.html">
|
||||
</OBJECT>
|
||||
</UL>
|
||||
</UL>
|
||||
</UL>
|
||||
</BODY></HTML>
|
||||
|
@ -13,13 +13,13 @@
|
||||
<p style="MARGIN-LEFT: 40px">Thomas Stahl: TV emulation mode (up to v1.25.0.4)</p>
|
||||
<p style="MARGIN-LEFT: 40px">Chris Foxwell: SSI263 phoneme samples</p>
|
||||
<p style="MARGIN-LEFT: 40px">Robert Hoem: Hard disk card (source module & f/w)</p>
|
||||
<p style="MARGIN-LEFT: 40px">VICE team: TFE, Z80, MC6821 PIA emulation modules (<a href="http://www.viceteam.org">http://www.viceteam.org</a>)<br>
|
||||
<p style="MARGIN-LEFT: 40px">VICE team: TFE, Z80, MC6821 PIA emulation modules (<a href="http://vice-emu.sourceforge.net/index.html#developers">http://vice-emu.sourceforge.net/index.html#developers</a>)<br>
|
||||
- In particular, Spiro Trikaliotis for TFE, whose code Glenn Jones adapted for Uthernet support</p>
|
||||
<p style="MARGIN-LEFT: 40px">FUSE team: AY-3-8910 module (<a href="http://fuse-emulator.sourceforge.net">http://fuse-emulator.sourceforge.net</a>)</p>
|
||||
<p style="MARGIN-LEFT: 40px">Kyle Kim: Mouse card support based on code from Apple in PC</p>
|
||||
<p style="MARGIN-LEFT: 40px">Fábio Belavenuto: TK3000 Brazilian //e clone (originally responsible for integrating Z80Em)</p>
|
||||
<p style="MARGIN-LEFT: 40px">Bob Sander-Cederlof: Applesoft Symbols (<a href="http://www.txbobsc.com/scsc/scdocumentor/index.html">http://www.txbobsc.com/scsc/scdocumentor/</a> S-C DocuMentor: Applesoft)</p>
|
||||
<p style="MARGIN-LEFT: 40px">David Schmidt: Updates to this help file</p>
|
||||
<p style="MARGIN-LEFT: 40px">Mike Harvey, Founder & Editor of Nibble Magazine: For providing us Apple fans the pleasure of eagerly awaiting each next month's issue to learn about the Apple! (<a href="http://www.nibblemagazine.net/">http://www.nibblemagazine.net/</a>)</p>
|
||||
<p style="MARGIN-LEFT: 40px">Mike Harvey, Founder & Editor of Nibble Magazine: For providing us Apple fans the pleasure of eagerly awaiting each next month's issue to learn about the Apple! (<a href="http://www.nibblemagazine.com/">http://www.nibblemagazine.com/</a>)</p>
|
||||
</body>
|
||||
</html>
|
||||
|
24
help/appendix.html
Normal file
@ -0,0 +1,24 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
<html>
|
||||
<head>
|
||||
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
|
||||
<title>Appendix</title>
|
||||
|
||||
|
||||
</head>
|
||||
|
||||
|
||||
<body style="background-color: rgb(255, 255, 255); font-family: verdana;" alink="#008000" link="#008000" vlink="#008000">
|
||||
|
||||
<h2 style="color: rgb(0, 128, 0);">Appendix</h2>
|
||||
|
||||
<hr size="4">
|
||||
|
||||
<ul>
|
||||
<li><a href="fullspeed.html">Full-speed mode</a></li>
|
||||
<li><a href="Troubleshooting.html">Troubleshooting</a></li>
|
||||
</ul>
|
||||
|
||||
</body>
|
||||
</html>
|
@ -9,85 +9,83 @@
|
||||
<h2 style="COLOR: rgb(0,128,0)">Configuration Settings</h2>
|
||||
<hr size="4">
|
||||
<img style="FLOAT: right; WIDTH: 344px; HEIGHT: 460px" src="img/config.png" alt="Configuration settings"
|
||||
hspace="5" vspace="5"><strong>Model:</strong><br>
|
||||
hspace="5" vspace="5">
|
||||
|
||||
<strong>Model:</strong><br>
|
||||
This describes the mode of emulation. You have the option of emulating
|
||||
the predecessors of the Apple //e: the Apple ][ and Apple ][+. Besides running
|
||||
with a different Apple system ROM, some differences are discussed below.<br>
|
||||
<ul>
|
||||
<li>
|
||||
Apple ][ : Non-autobooting, 64K machine, no lower-case, no 80-column, 6502 CPU
|
||||
<li>
|
||||
Apple ][+ : Autobooting version of the Apple ][
|
||||
<li>
|
||||
Apple //e : 128K machine, lower-case, 80-column, 6502 CPU</li>
|
||||
<li>
|
||||
Enhanced Apple //e : 128K machine, lower-case, 80-column, 65C02 CPU</li>
|
||||
<li>
|
||||
Clone (specific model selectable from Advanced page)</li>
|
||||
<li>Apple ][ : Non-autobooting, 64K machine, no lower-case, no 80-column, 6502 CPU
|
||||
<li>Apple ][+ : Autobooting version of the Apple ][
|
||||
<li>Apple //e : 128K machine, lower-case, 80-column, 6502 CPU</li>
|
||||
<li>Enhanced Apple //e : 128K machine, lower-case, 80-column, 65C02 CPU</li>
|
||||
<li>Clone (specific model selectable from Advanced page)</li>
|
||||
</ul>
|
||||
|
||||
<strong>Confirm reboot:</strong><br>
|
||||
Show "Confirm reboot" message box when F2 is pressed.<br>
|
||||
<br>
|
||||
|
||||
<strong>Video:</strong><br>
|
||||
AppleWin can display Apple video in a variety of modes. The display can also be
|
||||
run in a standard window or full-screen. This option describes the type of
|
||||
video emulation to be used for the emulator. The differences are
|
||||
discussed below.<br>
|
||||
<ul>
|
||||
<li>
|
||||
<strong>Monochrome (custom) :</strong> This mode emulates a monochrome
|
||||
<li><strong>Monochrome (custom) :</strong> This mode emulates a monochrome
|
||||
monitor. You can choose your monochrome color from the <em>Monochrome Color</em>
|
||||
button described below.
|
||||
<li>
|
||||
<strong>Color Monitor :</strong> This mode emulates a standard color monitor.
|
||||
<li>
|
||||
<strong>B&W TV :</strong> This mode emulates an NTSC black and white TV.
|
||||
<li>
|
||||
<strong>Color TV :</strong> This mode emulates an NTSC color TV.
|
||||
<li>
|
||||
<strong>Monochrome (Amber/Green/White) :</strong> Monochrome with specified color.
|
||||
</li>
|
||||
<li><strong>50% Scan line :</strong> Only draw alternate scanline (for better monitor
|
||||
authenticity).</li>
|
||||
<li><strong>Color Monitor :</strong> This mode emulates a standard color monitor.
|
||||
<li><strong>B&W TV :</strong> This mode emulates an NTSC black and white TV.
|
||||
<li><strong>Color TV :</strong> This mode emulates an NTSC color TV.
|
||||
<li><strong>Monochrome (Amber/Green/White) :</strong> Monochrome with specified color.
|
||||
</ul>
|
||||
<P>
|
||||
<strong>Serial Port:<br>
|
||||
</strong>This option will remap the emulated Apple's serial port to your PC's
|
||||
serial port (or TCP port 1977). The Apple Super Serial Card (SSC) is emulated in slot-2.<br>
|
||||
The TCP interface to the Apple SSC can be used by the <a href="http://sourceforge.net/projects/a2gameserver">Apple // Game Server</a>.
|
||||
For details see the notes that comes with AGS:<br>
|
||||
<li>Boot the Apple II to AppleSoft (ie. power on and hit Ctrl-Reset) and type IN#2.
|
||||
</li>
|
||||
<li>From a Windows DOS box, start AGS with "localhost 1977 apple2e". This will boot the emulated Apple II from AGS.</li>
|
||||
<li>Nb. Only Enhanced Apple //e is working at the moment.
|
||||
<br>
|
||||
<STRONG>
|
||||
<BR>
|
||||
Ethernet Settings...:</STRONG>
|
||||
<br>
|
||||
This allows to choose which network interface card (NIC) you want to
|
||||
use with the Uthernet card.<P><STRONG>Monochrome Color:</STRONG><br>
|
||||
This is the color to use when you choose a monochrome video mode.<br>
|
||||
<br>
|
||||
<strong>Emulation Speed Control:</strong><br>
|
||||
This option let's you control the processor speed of the emulated system. You
|
||||
may choose to use an authentic speed (matching the speed of the original
|
||||
processor from the system) or you can underclock or overclock the emulated
|
||||
processor speed from half-speed to as fast as your PC can emulate.<br>
|
||||
<br>
|
||||
<strong>Confirm reboot:</strong><br>
|
||||
Show "Confirm reboot" message box when F2 is pressed.<br>
|
||||
<br>
|
||||
<strong>Benchmark Emulator:</strong><br>
|
||||
This will run a benchmark test that will show how fast your PC can emulate an
|
||||
Apple //e system with this emulator. In order to run the benchmark, the
|
||||
emulated machine must be reset and you will lose any unsaved work. You will be
|
||||
prompted before you continue this action. The results given are:<br>
|
||||
</P>
|
||||
|
||||
<strong>Monochrome Color:</strong><br>
|
||||
This is the color to use when you choose a monochrome video mode.<br>
|
||||
<br>
|
||||
|
||||
<strong>50% Scan line:</strong><br>
|
||||
Only draw alternate scanline (for better monitor authenticity).<br>
|
||||
<br>
|
||||
|
||||
<strong>Full-Screen: Show drive/keyboard status:</strong><br>
|
||||
When in full-screen mode, show floppy (activity and track) and harddisk status (activity); keyboard caps-lock status and if emulation is paused.<br>
|
||||
<br>
|
||||
|
||||
<strong>Serial Port:</strong><br>
|
||||
This option will remap the emulated Apple's serial port to your PC's
|
||||
serial port (or TCP port 1977). The Apple Super Serial Card (SSC) is emulated in slot-2.<br>
|
||||
The TCP interface to the Apple SSC can be used by the <a href="http://sourceforge.net/projects/a2gameserver">Apple // Game Server</a>.
|
||||
For details see the notes that comes with AGS:<br>
|
||||
<li>Boot the Apple II to AppleSoft (ie. power on and hit Ctrl-Reset) and type IN#2.
|
||||
<li>From a Windows DOS box, start AGS with "localhost 1977 apple2e". This will boot the emulated Apple II from AGS.
|
||||
<li>Nb. Only Enhanced Apple //e is working at the moment.
|
||||
<br>
|
||||
<br>
|
||||
|
||||
<strong>Ethernet Settings...:</strong><br>
|
||||
This allows to choose which network interface card (NIC) you want to
|
||||
use with the Uthernet card.<br>
|
||||
<br>
|
||||
|
||||
<strong>Emulation Speed Control:</strong><br>
|
||||
This option let's you control the processor speed of the emulated system. You
|
||||
may choose to use an authentic speed (matching the speed of the original
|
||||
processor from the system) or you can underclock or overclock the emulated
|
||||
processor speed from half-speed to as fast as your PC can emulate.<br>
|
||||
<br>
|
||||
|
||||
<strong>Benchmark Emulator:</strong><br>
|
||||
This will run a benchmark test that will show how fast your PC can emulate an
|
||||
Apple //e system with this emulator. In order to run the benchmark, the
|
||||
emulated machine must be reset and you will lose any unsaved work. You will be
|
||||
prompted before you continue this action. The results given are:<br>
|
||||
<ul>
|
||||
<li>
|
||||
Pure Video FPS
|
||||
<li>
|
||||
Pure CPU MHz
|
||||
<li>
|
||||
Expected average video game performance (in FPS)</li>
|
||||
<li> Pure Video FPS
|
||||
<li> Pure CPU MHz
|
||||
<li> Expected average video game performance (in FPS)
|
||||
</ul>
|
||||
</li>
|
||||
</body>
|
||||
|
51
help/fullspeed.html
Normal file
@ -0,0 +1,51 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
<html>
|
||||
<head>
|
||||
<title>Full-speed mode</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
|
||||
</head>
|
||||
<body style="FONT-FAMILY: verdana; BACKGROUND-COLOR: rgb(255,255,255)" alink="#008000"
|
||||
link="#008000" vlink="#008000">
|
||||
<h2 style="COLOR: rgb(0,128,0)">Full-speed mode</h2>
|
||||
<hr size="4">
|
||||
|
||||
<p style="FONT-WEIGHT: bold">Overview:</p>
|
||||
<p>Emulation can be run in full-speed (aka unthrottled) mode.</p>
|
||||
|
||||
<p style="FONT-WEIGHT: bold">Details:</p>
|
||||
<p>This can be enabled manually or automatically in a variety of ways:</p>
|
||||
|
||||
<ul>
|
||||
<li>Permanently enable by the AppleWin <a href="cfg-config.html">Configuration</a> tab's 'Emulation Speed Control', and setting 'Custom Speed (in MHz)' to 'Fastest'.
|
||||
<li>Scroll Lock key: can be configured to toggle normal/full-speed mode, or only enable full-speed when pressed.
|
||||
<ul>
|
||||
<li>See <a href="cfg-input.html">Input</a> for configuring how Scroll Lock behaves.
|
||||
</ul>
|
||||
<li>When 'Disk access speed' is set to 'Enhanced Speed' (the default), then whenever the Disk][ drive motor is on, the emulator will automatically switch to full-speed (and when the motor is switched off, then the emulator will automatically revert to what the 'Emulation Speed Control' has been set to).
|
||||
<ul>
|
||||
<li>See <a href="cfg-disk.html">Disk</a> for configuring 'Disk access speed'.
|
||||
</ul>
|
||||
<li>From the built-in debugger, single-stepping via the 'gg' command.
|
||||
</ul>
|
||||
|
||||
<p style="FONT-WEIGHT: bold">Limitations and things to bear in mind:</p>
|
||||
<ul>
|
||||
<li>Full speed mode favours speed over video accuracy:
|
||||
<ul>
|
||||
<li>The Apple II's video is only updated periodically (once a wall-clock 60Hz frame) instead of each opcode.
|
||||
</ul>
|
||||
<li>All sound (speaker, Mockingboard, etc) is muted.
|
||||
<li>Video-based timing/synchronisation loops won't work correctly.
|
||||
<ul>
|
||||
<li>The video-scanner won't advance its h/v position, so the floating bus will always return the same value.
|
||||
<li>Specifically code that does Apple II+ VBlank detection (using the floating bus) will hang, until full-speed mode is disabled. (But Apple //e soft-switch VBlank detection does work.)
|
||||
</ul>
|
||||
<li>Card detection routines (that rely on floating bus) won't work correctly.
|
||||
<li>One of your PC's CPU cores will run at 100%.
|
||||
<ul>
|
||||
<li>EG. Simply boot the Apple II (or //e) without a disk in drive-1.
|
||||
</ul>
|
||||
</ul>
|
||||
|
||||
</body>
|
||||
</html>
|
Before Width: | Height: | Size: 36 KiB After Width: | Height: | Size: 36 KiB |
Before Width: | Height: | Size: 12 KiB |
@ -43,15 +43,12 @@
|
||||
key will pause emulation. Press
|
||||
<span style="font-style: italic;">Pause</span>
|
||||
again to resume emulation.</p>
|
||||
<p><span style="font-weight: bold;">Scroll Lock:</span><br>
|
||||
Holding down the PC's
|
||||
<span style="font-style: italic;">Scroll Lock</span>
|
||||
key temporarily sets the emulation to full speed (i.e. unthrottled).<br>
|
||||
<p><span style="font-weight: bold;">Scroll Lock:</span><br>
|
||||
<span style="font-style: italic;">Scroll Lock</span>
|
||||
key can be configured to toggle normal/full-speed mode, or only enable full-speed when pressed. See <a href="cfg-input.html">Input</a> for configuring how <span style="font-style: italic;">Scroll Lock</span> behaves.
|
||||
NOTE: The status of the PC's
|
||||
<span style="font-style: italic;">Scroll Lock</span>
|
||||
LED is meaningless. The emulator will only run full speed while the
|
||||
<span style="font-style: italic;">Scroll Lock</span>
|
||||
key is pressed down.</p>
|
||||
LED is meaningless.</p>
|
||||
<p><span style="font-weight: bold;">Shift+Insert:</span><br>
|
||||
Paste text from Windows' clipboard. Text gets fed a character at a time to the
|
||||
Apple's keyboard hardware. The 'CR+LF' combination gets converted to CR.</p>
|
||||
|
@ -12,28 +12,30 @@
|
||||
Copyright © 1994-1996, Michael O'Brien<br>
|
||||
Copyright © 2001, Oliver Schmidt<br>
|
||||
Copyright © 2002-2005, Tom Charlesworth<BR>
|
||||
Copyright © 2006-2016, Tom Charlesworth, Michael Pohoreski, Nick Westgate, Linards Ticmanis
|
||||
Copyright © 2006-2017, Tom Charlesworth, Michael Pohoreski, Nick Westgate, Linards Ticmanis
|
||||
<br>
|
||||
<br>
|
||||
<a href="applewin-team.html">AppleWin team</a>
|
||||
<br>
|
||||
<a href="acknowledgements.html">Acknowledgements</a>
|
||||
<br>
|
||||
<br>
|
||||
Select one of the following categories:
|
||||
<ul>
|
||||
<li>
|
||||
<a href="quickstart.html">Quick Start</a>
|
||||
<li>
|
||||
<a href="history.html">Historical Information</a>
|
||||
<li>
|
||||
<a href="diskimages.html">Disks and Disk Images</a>
|
||||
<li>
|
||||
<a href="toolbar.html">Using the Toolbar</a>
|
||||
<li>
|
||||
<a href="keyboard.html">Using the Keyboard</a>
|
||||
<li>
|
||||
<a href="dbg-toc-intro.html">Using the Debugger</a>
|
||||
<li>
|
||||
<a href="resources.html">Resources</a></li>
|
||||
<li><a href="quickstart.html">Quick Start</a>
|
||||
<li><a href="history.html">Historical Information</a>
|
||||
<li><a href="diskimages.html">Disks and Disk Images</a>
|
||||
<li><a href="toolbar.html">Using the Toolbar</a>
|
||||
<li><a href="keyboard.html">Using the Keyboard</a>
|
||||
<li><a href="savestate.html">Save-state Files</a>
|
||||
<li><a href="sound.html">Sound</a>
|
||||
<li><a href="clock.html">Clock</a>
|
||||
<li><a href="uthernet.html">Uthernet network card</a>
|
||||
<li><a href="CommandLine.html">Command line</a>
|
||||
<li><a href="configuration.html">AppleWin Configuration</a>
|
||||
<li><a href="dbg-toc-intro.html">Using the Debugger</a>
|
||||
<li><a href="resources.html">Resources</a></li>
|
||||
<li><a href="appendix.html">Appendix</a></li>
|
||||
</ul>
|
||||
</body>
|
||||
</html>
|
||||
|
48
help/uthernet-wifi-workaround.html
Normal file
@ -0,0 +1,48 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
<html>
|
||||
<head>
|
||||
<title>WiFi workaround</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
|
||||
</head>
|
||||
<body style="FONT-FAMILY: verdana; BACKGROUND-COLOR: rgb(255,255,255)" alink="#008000"
|
||||
link="#008000" vlink="#008000">
|
||||
<h2 style="COLOR: rgb(0,128,0)">WiFi workaround</h2>
|
||||
<hr size="4">
|
||||
<p style="FONT-WEIGHT: bold">Overview:
|
||||
</p>
|
||||
<p>A (heavyweight) workaround for the WiFi issue.</p>
|
||||
|
||||
<p style="FONT-WEIGHT: bold">Details:
|
||||
</p>
|
||||
<p>Installing a virtualization solution like the (free) VMware
|
||||
Workstation Player provides a virtual ethernet card. Then installing
|
||||
WinPcap inside the virtual machine allows access to the internet via
|
||||
WiFi from AppleWin.</p>
|
||||
|
||||
<p>VMware allows you to configure the virtual ethernet card in two ways:</p>
|
||||
<ul>
|
||||
<li>Bridged, this means that the virtual Uthernet card becomes visible
|
||||
with its MAC address in the WiFi net and that an Apple II DHCP client
|
||||
gets its address from the usual DHCP server (typically a WAN router).
|
||||
<li>NAT, this means that the virtual Uthernet card is part of a virtual
|
||||
network with three participants:
|
||||
<ul>
|
||||
<li>A virtual Ethernet card added by VMware to the "outside" (aka host) Windows.
|
||||
<li>The virtual Ethernet card used by the "inside" (aka guest) Windows.
|
||||
<li>The virtual Uthernet card.
|
||||
</ul>
|
||||
<br>
|
||||
That virtual network has its own IP address range and has its own DHCP
|
||||
server (being part of VMware). An Apple II DHCP client gets its
|
||||
address from that DHCP server.
|
||||
</ul>
|
||||
|
||||
<p>Another positive aspect of that "emulation inside vitualization"
|
||||
approach is that the "inside" (aka guest) Windows always has just one
|
||||
single network interface: that virtual ethernet card mentioned above.
|
||||
And that interface has always the same name (even when switching
|
||||
between Bridged and NAT) so one never has to fiddle with network
|
||||
setting of the emulators using WinPcap.</p>
|
||||
|
||||
</body>
|
||||
</html>
|
@ -1,7 +1,7 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
<html>
|
||||
<head>
|
||||
<title>Save-State Files</title>
|
||||
<title>Uthernet network card</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
|
||||
</head>
|
||||
<body style="FONT-FAMILY: verdana; BACKGROUND-COLOR: rgb(255,255,255)" alink="#008000"
|
||||
@ -15,25 +15,23 @@
|
||||
<P style="FONT-WEIGHT: bold">Acknowledgment:
|
||||
</P>
|
||||
<P>Uthernet (TFE) support in Applewin was made possible by implementing the GPL
|
||||
source written by Spiro Trikaliotis for the Vice emulator - <A href="http://www.viceteam.org/">
|
||||
http://www.viceteam.org/</A></P>
|
||||
source written by Spiro Trikaliotis for the Vice emulator - <A href="http://vice-emu.sourceforge.net/index.html#developers">
|
||||
http://vice-emu.sourceforge.net/index.html#developers</A></P>
|
||||
<P style="FONT-WEIGHT: bold">Details:
|
||||
</P>
|
||||
<P>To enable Ethernet support in AppleWin you must first download and install
|
||||
<P>To enable ethernet support in AppleWin you must first download and install
|
||||
WinPcap.
|
||||
</P>
|
||||
<P>An Alternative to downloading WinPcap is to get the Ethereal package which
|
||||
includes WinPcap along with Ethereal network analyzer code. To use Ethereal to
|
||||
<P>An alternative to downloading WinPcap is to get the Wireshark package which
|
||||
includes WinPcap along with Wireshark network analyzer code. To use Wireshark to
|
||||
capture traffic (other than your own) you must be plugged into a shared hub vs
|
||||
a switch. If you plan on doing any network programming ethereal is a definite
|
||||
a switch. If you plan on doing any network programming Wireshark is a definite
|
||||
must have.
|
||||
</P>
|
||||
<P>WinPcap: <A href="http://www.WinPcap.org/install/default.htm">http://www.WinPcap.org/install/default.htm</A>
|
||||
or Ethereal:
|
||||
<P>WinPcap: <A href="http://www.WinPcap.org/install/default.htm">http://www.WinPcap.org/install/default.htm</A>
|
||||
or Wireshark: <A href="https://www.wireshark.org">https://www.wireshark.org</A>
|
||||
</P>
|
||||
<P><A href="http://www.ethereal.com/download.html">http://www.ethereal.com/download.html</A>
|
||||
</P>
|
||||
<P>After AppleWin starts, select the settings ICON and then select the Ethernet
|
||||
<P>After AppleWin starts, select the settings icon and then select the ethernet
|
||||
settings button.
|
||||
</P>
|
||||
<P>Uthernet will be disabled. Select Uthernet from the list of available ethernet
|
||||
@ -44,13 +42,15 @@
|
||||
</P>
|
||||
<P>If you have more than one interface you may need to select them in turn in order
|
||||
to get the text description for each interface vs what WinPcap likes to use for
|
||||
a reference. Select Ok. and then close AppleWin. *Note:* Wireless does not work
|
||||
with WinPcap.
|
||||
a reference. Select Ok. and then close AppleWin.
|
||||
</P>
|
||||
<P>NOTE: Due to a current limitation you must exit AppleWin and re-run AppleWin for
|
||||
'a' ethernet interface change to take effect.
|
||||
<P><span style="font-weight: bold;">Note:</span> Wireless does not work
|
||||
with WinPcap (but see <A href="uthernet-wifi-workaround.html">WiFi Workaround</A>).
|
||||
</P>
|
||||
<P>In order to test the Ethernet emulation out you should grab a copy of Contiki
|
||||
<P><span style="font-weight: bold;">Note:</span> Due to a current limitation you must exit AppleWin and
|
||||
re-run AppleWin for an ethernet interface change to take effect.
|
||||
</P>
|
||||
<P>In order to test the ethernet emulation out you should grab a copy of Contiki
|
||||
for the Apple II here - <A href="http://www.a2retrosystems.com/downloads.htm">http://www.a2retrosystems.com/downloads.htm</A>
|
||||
</P>
|
||||
<P>Grab the 80 Col. Primary Disk and Supplementary Disk images if using Apple //e
|
||||
@ -88,6 +88,6 @@
|
||||
<P>If you have ZoneAlarm running then try disabling it inorder to access the web.
|
||||
if you are still having difficulty then you should refer to the VICE network
|
||||
support page for additional information - <A href="http://vicekb.trikaliotis.net/13-005.shtml">
|
||||
http://vicekb.trikaliotis.net/13-005.shtml</A></P>
|
||||
http://vicekb.trikaliotis.net/13-005.shtml</A></P>
|
||||
</body>
|
||||
</html>
|
||||
|
@ -89,25 +89,26 @@ FONT 8, "MS Shell Dlg", 0, 0, 0x0
|
||||
BEGIN
|
||||
LTEXT "&Model:",IDC_STATIC,5,7,40,8
|
||||
COMBOBOX IDC_COMPUTER,45,5,95,100,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
|
||||
CONTROL "&Confirm reboot",IDC_CHECK_CONFIRM_REBOOT,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,148,8,62,10
|
||||
GROUPBOX "Video",IDC_STATIC,5,22,200,43
|
||||
CONTROL "Confirm reboot",IDC_CHECK_CONFIRM_REBOOT,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,148,8,62,10
|
||||
GROUPBOX "Video",IDC_STATIC,5,22,200,56
|
||||
LTEXT "Mo&de:",IDC_STATIC,12,33,33,8
|
||||
COMBOBOX IDC_VIDEOTYPE,45,30,95,100,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
|
||||
PUSHBUTTON "Monochrome &Color...",IDC_MONOCOLOR,12,46,80,14
|
||||
CONTROL "&50% Scan lines",IDC_CHECK_HALF_SCAN_LINES,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,103,48,62,10
|
||||
LTEXT "&Serial Port:",IDC_STATIC,5,74,40,8
|
||||
COMBOBOX IDC_SERIALPORT,45,72,95,100,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
|
||||
PUSHBUTTON "&Ethernet Settings...",IDC_ETHERNET,4,90,80,14
|
||||
GROUPBOX "Emulation Speed Control",IDC_STATIC,5,115,200,85
|
||||
CONTROL "50% Scan lines",IDC_CHECK_HALF_SCAN_LINES,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,103,48,62,10
|
||||
CONTROL "Full-Screen: Show drive/keyboard status",IDC_CHECK_FS_SHOW_SUBUNIT_STATUS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,64,140,10
|
||||
LTEXT "&Serial Port:",IDC_STATIC,5,89,40,8
|
||||
COMBOBOX IDC_SERIALPORT,45,87,95,100,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
|
||||
PUSHBUTTON "&Ethernet Settings...",IDC_ETHERNET,4,105,80,14
|
||||
GROUPBOX "Emulation Speed Control",IDC_STATIC,5,130,200,85
|
||||
CONTROL "Use &Authentic Machine Speed",IDC_AUTHENTIC_SPEED,
|
||||
"Button",BS_AUTORADIOBUTTON,15,126,115,10
|
||||
CONTROL "Select C&ustom Speed (in MHz)",IDC_CUSTOM_SPEED,"Button",BS_AUTORADIOBUTTON,15,138,115,10
|
||||
CONTROL "Generic2",IDC_SLIDER_CPU_SPEED,"msctls_trackbar32",TBS_AUTOTICKS | WS_TABSTOP,25,149,160,15
|
||||
CTEXT "0.5",IDC_0_5_MHz,23,165,20,10
|
||||
CTEXT "1.0",IDC_1_0_MHz,59,165,20,10
|
||||
CTEXT "2.0",IDC_2_0_MHz,96,165,20,10
|
||||
RTEXT "Fastest",IDC_MAX_MHz,150,165,29,10
|
||||
PUSHBUTTON "&Benchmark Emulator",IDC_BENCHMARK,15,179,85,15
|
||||
"Button",BS_AUTORADIOBUTTON,15,141,115,10
|
||||
CONTROL "Select C&ustom Speed (in MHz)",IDC_CUSTOM_SPEED,"Button",BS_AUTORADIOBUTTON,15,153,115,10
|
||||
CONTROL "Generic2",IDC_SLIDER_CPU_SPEED,"msctls_trackbar32",TBS_AUTOTICKS | WS_TABSTOP,25,164,160,15
|
||||
CTEXT "0.5",IDC_0_5_MHz,23,180,20,10
|
||||
CTEXT "1.0",IDC_1_0_MHz,59,180,20,10
|
||||
CTEXT "2.0",IDC_2_0_MHz,96,180,20,10
|
||||
RTEXT "Fastest",IDC_MAX_MHz,150,180,29,10
|
||||
PUSHBUTTON "&Benchmark Emulator",IDC_BENCHMARK,15,194,85,15
|
||||
END
|
||||
|
||||
IDD_PROPPAGE_INPUT DIALOGEX 0, 0, 210, 215
|
||||
@ -251,8 +252,8 @@ DISK_ICON ICON "DISK.ICO"
|
||||
//
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION 1,26,3,0
|
||||
PRODUCTVERSION 1,26,3,0
|
||||
FILEVERSION 1,26,3,5
|
||||
PRODUCTVERSION 1,26,3,5
|
||||
FILEFLAGSMASK 0x3fL
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS 0x1L
|
||||
@ -270,12 +271,12 @@ BEGIN
|
||||
VALUE "Comments", "https://github.com/AppleWin"
|
||||
VALUE "CompanyName", "AppleWin"
|
||||
VALUE "FileDescription", "Apple //e Emulator for Windows"
|
||||
VALUE "FileVersion", "1, 26, 3, 0"
|
||||
VALUE "FileVersion", "1, 26, 3, 5"
|
||||
VALUE "InternalName", "APPLEWIN"
|
||||
VALUE "LegalCopyright", " 1994-2017 Michael O'Brien, Oliver Schmidt, Tom Charlesworth, Michael Pohoreski, Nick Westgate, Linards Ticmanis"
|
||||
VALUE "OriginalFilename", "APPLEWIN.EXE"
|
||||
VALUE "ProductName", "Apple //e Emulator"
|
||||
VALUE "ProductVersion", "1, 26, 3, 0"
|
||||
VALUE "ProductVersion", "1, 26, 3, 5"
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
|
@ -113,6 +113,7 @@
|
||||
#define IDC_COMBO_HDD2 1079
|
||||
#define IDC_COMBO_DISK1 1080
|
||||
#define IDC_COMBO_DISK2 1081
|
||||
#define IDC_CHECK_FS_SHOW_SUBUNIT_STATUS 1082
|
||||
#define IDM_EXIT 40001
|
||||
#define IDM_HELP 40002
|
||||
#define IDM_ABOUT 40003
|
||||
|
@ -32,7 +32,6 @@
|
||||
#include "AY8910.h"
|
||||
|
||||
#include "Applewin.h" // For g_fh
|
||||
#include "Mockingboard.h" // For g_uTimer1IrqCount
|
||||
#include "YamlHelper.h"
|
||||
|
||||
/* The AY white noise RNG algorithm is based on info from MAME's ay8910.c -
|
||||
|
@ -60,7 +60,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
static UINT16 g_AppleWinVersion[4] = {0};
|
||||
char VERSIONSTRING[16] = "xx.yy.zz.ww";
|
||||
|
||||
TCHAR *g_pAppTitle = TITLE_APPLE_2E_ENHANCED;
|
||||
TCHAR *g_pAppTitle = NULL;
|
||||
|
||||
eApple2Type g_Apple2Type = A2TYPE_APPLE2EENHANCED;
|
||||
|
||||
@ -77,6 +77,7 @@ static bool g_bLoadedSaveState = false;
|
||||
TCHAR g_sProgramDir[MAX_PATH] = TEXT(""); // Directory of where AppleWin executable resides
|
||||
TCHAR g_sDebugDir [MAX_PATH] = TEXT(""); // TODO: Not currently used
|
||||
TCHAR g_sScreenShotDir[MAX_PATH] = TEXT(""); // TODO: Not currently used
|
||||
bool g_bCapturePrintScreenKey = true;
|
||||
TCHAR g_sCurrentDir[MAX_PATH] = TEXT(""); // Also Starting Dir. Debugger uses this when load/save
|
||||
bool g_bRestart = false;
|
||||
bool g_bRestartFullScreen = false;
|
||||
@ -595,7 +596,7 @@ void LoadConfiguration(void)
|
||||
}
|
||||
|
||||
char aySerialPortName[ CSuperSerialCard::SIZEOF_SERIALCHOICE_ITEM ];
|
||||
if (RegLoadString( TEXT("Configuration"),
|
||||
if (RegLoadString( TEXT(REG_CONFIG),
|
||||
TEXT(REGVALUE_SERIAL_PORT_NAME),
|
||||
TRUE,
|
||||
aySerialPortName,
|
||||
@ -617,6 +618,9 @@ void LoadConfiguration(void)
|
||||
|
||||
DWORD dwTmp;
|
||||
|
||||
if(REGLOAD(TEXT(REGVALUE_FS_SHOW_SUBUNIT_STATUS), &dwTmp))
|
||||
SetFullScreenShowSubunitStatus(dwTmp ? true : false);
|
||||
|
||||
if(REGLOAD(TEXT(REGVALUE_THE_FREEZES_F8_ROM), &dwTmp))
|
||||
sg_PropertySheet.SetTheFreezesF8Rom(dwTmp);
|
||||
|
||||
@ -918,6 +922,8 @@ int APIENTRY WinMain(HINSTANCE passinstance, HINSTANCE, LPSTR lpCmdLine, int)
|
||||
bool bShutdown = false;
|
||||
bool bSetFullScreen = false;
|
||||
bool bBoot = false;
|
||||
bool bChangedDisplayResolution = false;
|
||||
UINT bestWidth = 0, bestHeight = 0;
|
||||
LPSTR szImageName_drive1 = NULL;
|
||||
LPSTR szImageName_drive2 = NULL;
|
||||
LPSTR szSnapshotName = NULL;
|
||||
@ -962,9 +968,29 @@ int APIENTRY WinMain(HINSTANCE passinstance, HINSTANCE, LPSTR lpCmdLine, int)
|
||||
{
|
||||
bSetFullScreen = true;
|
||||
}
|
||||
else if (strcmp(lpCmdLine, "-fs8bit") == 0)
|
||||
#define CMD_FS_HEIGHT "-fs-height="
|
||||
else if (strncmp(lpCmdLine, CMD_FS_HEIGHT, sizeof(CMD_FS_HEIGHT)-1) == 0)
|
||||
{
|
||||
SetFullScreen32Bit(false); // Support old v1.24 fullscreen 8-bit palette mode
|
||||
bSetFullScreen = true; // Implied
|
||||
|
||||
LPSTR lpTmp = lpCmdLine + sizeof(CMD_FS_HEIGHT)-1;
|
||||
bool bRes = false;
|
||||
if (strcmp(lpTmp, "best") == 0)
|
||||
{
|
||||
bRes = GetBestDisplayResolutionForFullScreen(bestWidth, bestHeight);
|
||||
}
|
||||
else
|
||||
{
|
||||
UINT userSpecifiedHeight = atoi(lpTmp);
|
||||
if (userSpecifiedHeight)
|
||||
bRes = GetBestDisplayResolutionForFullScreen(bestWidth, bestHeight, userSpecifiedHeight);
|
||||
else
|
||||
LogFileOutput("Invalid cmd-line parameter for -fs-height=x switch\n");
|
||||
}
|
||||
if (bRes)
|
||||
LogFileOutput("Best resolution for -fs-height=x switch: Width=%d, Height=%d\n", bestWidth, bestHeight);
|
||||
else
|
||||
LogFileOutput("Failed to set parameter for -fs-height=x switch\n");
|
||||
}
|
||||
else if (strcmp(lpCmdLine, "-no-di") == 0)
|
||||
{
|
||||
@ -1035,6 +1061,10 @@ int APIENTRY WinMain(HINSTANCE passinstance, HINSTANCE, LPSTR lpCmdLine, int)
|
||||
{
|
||||
g_bDisplayPrintScreenFileName = true;
|
||||
}
|
||||
else if (strcmp(lpCmdLine, "-no-printscreen-key") == 0) // Don't try to capture PrintScreen key GH#469
|
||||
{
|
||||
g_bCapturePrintScreenKey = false;
|
||||
}
|
||||
else if (strcmp(lpCmdLine, "-no-printscreen-dlg") == 0) // Turn off the PrintScreen warning message dialog (if PrintScreen key can't be grabbed)
|
||||
{
|
||||
g_bShowPrintScreenWarningDialog = false;
|
||||
@ -1233,12 +1263,15 @@ int APIENTRY WinMain(HINSTANCE passinstance, HINSTANCE, LPSTR lpCmdLine, int)
|
||||
}
|
||||
|
||||
// PrintScrn support
|
||||
AppleWin_RegisterHotKeys(); // needs valid g_hFrameWindow
|
||||
if (g_bCapturePrintScreenKey)
|
||||
AppleWin_RegisterHotKeys(); // needs valid g_hFrameWindow
|
||||
LogFileOutput("Main: AppleWin_RegisterHotKeys()\n");
|
||||
|
||||
// Need to test if it's safe to call ResetMachineState(). In the meantime, just call DiskReset():
|
||||
DiskReset(); // Switch from a booting A][+ to a non-autostart A][, so need to turn off floppy motor
|
||||
LogFileOutput("Main: DiskReset()\n");
|
||||
HD_Reset(); // GH#515
|
||||
LogFileOutput("Main: HDDReset()\n");
|
||||
|
||||
if (!bSysClkOK)
|
||||
{
|
||||
@ -1293,6 +1326,21 @@ int APIENTRY WinMain(HINSTANCE passinstance, HINSTANCE, LPSTR lpCmdLine, int)
|
||||
{
|
||||
if (bSetFullScreen)
|
||||
{
|
||||
if (bestWidth && bestHeight)
|
||||
{
|
||||
DEVMODE devMode;
|
||||
memset(&devMode, 0, sizeof(devMode));
|
||||
devMode.dmSize = sizeof(devMode);
|
||||
devMode.dmPelsWidth = bestWidth;
|
||||
devMode.dmPelsHeight = bestHeight;
|
||||
devMode.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT;
|
||||
|
||||
DWORD dwFlags = 0;
|
||||
LONG res = ChangeDisplaySettings(&devMode, dwFlags);
|
||||
if (res == 0)
|
||||
bChangedDisplayResolution = true;
|
||||
}
|
||||
|
||||
PostMessage(g_hFrameWindow, WM_USER_FULLSCREEN, 0, 0);
|
||||
bSetFullScreen = false;
|
||||
}
|
||||
@ -1319,6 +1367,7 @@ int APIENTRY WinMain(HINSTANCE passinstance, HINSTANCE, LPSTR lpCmdLine, int)
|
||||
LogFileOutput("Main: MB_Reset()\n");
|
||||
|
||||
sg_Mouse.Uninitialize(); // Maybe restarting due to switching slot-4 card from MouseCard to Mockingboard
|
||||
sg_Mouse.Reset(); // Deassert any pending IRQs - GH#514
|
||||
LogFileOutput("Main: sg_Mouse.Uninitialize()\n");
|
||||
|
||||
DSUninit();
|
||||
@ -1326,6 +1375,9 @@ int APIENTRY WinMain(HINSTANCE passinstance, HINSTANCE, LPSTR lpCmdLine, int)
|
||||
}
|
||||
while (g_bRestart);
|
||||
|
||||
if (bChangedDisplayResolution)
|
||||
ChangeDisplaySettings(NULL, 0); // restore default
|
||||
|
||||
// Release COM
|
||||
SysClk_UninitTimer();
|
||||
LogFileOutput("Exit: SysClk_UninitTimer()\n");
|
||||
|
@ -539,6 +539,7 @@ DWORD CpuExecute(const DWORD uCycles, const bool bVideoUpdate)
|
||||
const DWORD uExecutedCycles = InternalCpuExecute(uCycles, bVideoUpdate);
|
||||
|
||||
MB_UpdateCycles(uExecutedCycles); // Update 6522s (NB. Do this before updating g_nCumulativeCycles below)
|
||||
// NB. Ensures that 6522 regs are up-to-date for any potential save-state
|
||||
UpdateEmulationTime(uExecutedCycles);
|
||||
|
||||
//
|
||||
|
@ -75,6 +75,7 @@ enum AppMode_e
|
||||
#define REGVALUE_CPU_TYPE "CPU Type"
|
||||
#define REGVALUE_OLD_APPLE2_TYPE "Computer Emulation" // Deprecated
|
||||
#define REGVALUE_CONFIRM_REBOOT "Confirm Reboot" // Added at 1.24.1 PageConfig
|
||||
#define REGVALUE_FS_SHOW_SUBUNIT_STATUS "Full-screen show subunit status"
|
||||
#define REGVALUE_SPKR_VOLUME "Speaker Volume"
|
||||
#define REGVALUE_MB_VOLUME "Mockingboard Volume"
|
||||
#define REGVALUE_SAVESTATE_FILENAME "Save State Filename"
|
||||
@ -211,3 +212,5 @@ inline bool IsOriginal2E(void)
|
||||
enum eBUTTON {BUTTON0=0, BUTTON1};
|
||||
|
||||
enum eBUTTONSTATE {BUTTON_UP=0, BUTTON_DOWN};
|
||||
|
||||
enum {IDEVENT_TIMER_MOUSE=1, IDEVENT_TIMER_100MSEC};
|
||||
|
@ -118,10 +118,8 @@ BOOL CPageConfig::DlgProcInternal(HWND hWnd, UINT message, WPARAM wparam, LPARAM
|
||||
break;
|
||||
|
||||
case IDC_CHECK_CONFIRM_REBOOT:
|
||||
g_bConfirmReboot = IsDlgButtonChecked(hWnd, IDC_CHECK_CONFIRM_REBOOT) ? 1 : 0;
|
||||
break;
|
||||
|
||||
case IDC_CHECK_HALF_SCAN_LINES:
|
||||
case IDC_CHECK_FS_SHOW_SUBUNIT_STATUS:
|
||||
// Checked in DlgOK()
|
||||
break;
|
||||
|
||||
@ -189,6 +187,7 @@ BOOL CPageConfig::DlgProcInternal(HWND hWnd, UINT message, WPARAM wparam, LPARAM
|
||||
|
||||
m_PropertySheetHelper.FillComboBox(hWnd,IDC_VIDEOTYPE,g_aVideoChoices,g_eVideoType);
|
||||
CheckDlgButton(hWnd, IDC_CHECK_HALF_SCAN_LINES, g_uHalfScanLines ? BST_CHECKED : BST_UNCHECKED);
|
||||
CheckDlgButton(hWnd, IDC_CHECK_FS_SHOW_SUBUNIT_STATUS, GetFullScreenShowSubunitStatus() ? BST_CHECKED : BST_UNCHECKED);
|
||||
|
||||
m_PropertySheetHelper.FillComboBox(hWnd,IDC_SERIALPORT, sg_SSC.GetSerialPortChoices(), sg_SSC.GetSerialPort());
|
||||
EnableWindow(GetDlgItem(hWnd, IDC_SERIALPORT), !sg_SSC.IsActive() ? TRUE : FALSE);
|
||||
@ -245,22 +244,24 @@ void CPageConfig::DlgOK(HWND hWnd)
|
||||
{
|
||||
bool bVideoReinit = false;
|
||||
|
||||
const DWORD newvidtype = (DWORD) SendDlgItemMessage(hWnd, IDC_VIDEOTYPE, CB_GETCURSEL, 0, 0);
|
||||
if (g_eVideoType != newvidtype)
|
||||
const DWORD uNewVideoType = (DWORD) SendDlgItemMessage(hWnd, IDC_VIDEOTYPE, CB_GETCURSEL, 0, 0);
|
||||
if (g_eVideoType != uNewVideoType)
|
||||
{
|
||||
g_eVideoType = newvidtype;
|
||||
g_eVideoType = uNewVideoType;
|
||||
bVideoReinit = true;
|
||||
}
|
||||
|
||||
const DWORD newHalfScanLines = IsDlgButtonChecked(hWnd, IDC_CHECK_HALF_SCAN_LINES) ? 1 : 0;
|
||||
if (g_uHalfScanLines != newHalfScanLines)
|
||||
const DWORD uNewHalfScanLines = IsDlgButtonChecked(hWnd, IDC_CHECK_HALF_SCAN_LINES) ? 1 : 0;
|
||||
if (g_uHalfScanLines != uNewHalfScanLines)
|
||||
{
|
||||
g_uHalfScanLines = newHalfScanLines;
|
||||
g_uHalfScanLines = uNewHalfScanLines;
|
||||
bVideoReinit = true;
|
||||
}
|
||||
|
||||
if (bVideoReinit)
|
||||
{
|
||||
Config_Save_Video();
|
||||
|
||||
FrameRefreshStatus(DRAW_TITLE, false);
|
||||
|
||||
VideoReinitialize();
|
||||
@ -270,15 +271,38 @@ void CPageConfig::DlgOK(HWND hWnd)
|
||||
}
|
||||
}
|
||||
|
||||
REGSAVE(TEXT(REGVALUE_CONFIRM_REBOOT), g_bConfirmReboot);
|
||||
//
|
||||
|
||||
const DWORD newserialport = (DWORD) SendDlgItemMessage(hWnd, IDC_SERIALPORT, CB_GETCURSEL, 0, 0);
|
||||
sg_SSC.CommSetSerialPort(hWnd, newserialport);
|
||||
const bool bNewFSSubunitStatus = IsDlgButtonChecked(hWnd, IDC_CHECK_FS_SHOW_SUBUNIT_STATUS) ? true : false;
|
||||
if (GetFullScreenShowSubunitStatus() != bNewFSSubunitStatus)
|
||||
{
|
||||
REGSAVE(TEXT(REGVALUE_FS_SHOW_SUBUNIT_STATUS), bNewFSSubunitStatus ? 1 : 0);
|
||||
SetFullScreenShowSubunitStatus(bNewFSSubunitStatus);
|
||||
|
||||
if (IsFullScreen())
|
||||
FrameRefreshStatus(DRAW_BACKGROUND | DRAW_LEDS | DRAW_DISK_STATUS);
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
const BOOL bNewConfirmReboot = IsDlgButtonChecked(hWnd, IDC_CHECK_CONFIRM_REBOOT) ? 1 : 0;
|
||||
if (g_bConfirmReboot != bNewConfirmReboot)
|
||||
{
|
||||
REGSAVE(TEXT(REGVALUE_CONFIRM_REBOOT), bNewConfirmReboot);
|
||||
g_bConfirmReboot = bNewConfirmReboot;
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
const DWORD uNewSerialPort = (DWORD) SendDlgItemMessage(hWnd, IDC_SERIALPORT, CB_GETCURSEL, 0, 0);
|
||||
sg_SSC.CommSetSerialPort(hWnd, uNewSerialPort);
|
||||
RegSaveString( TEXT(REG_CONFIG),
|
||||
TEXT(REGVALUE_SERIAL_PORT_NAME),
|
||||
TRUE,
|
||||
sg_SSC.GetSerialPortName() );
|
||||
|
||||
|
||||
//
|
||||
|
||||
if (IsDlgButtonChecked(hWnd, IDC_AUTHENTIC_SPEED))
|
||||
g_dwSpeed = SPEED_NORMAL;
|
||||
else
|
||||
@ -289,8 +313,6 @@ void CPageConfig::DlgOK(HWND hWnd)
|
||||
REGSAVE(TEXT(REGVALUE_CUSTOM_SPEED), IsDlgButtonChecked(hWnd, IDC_CUSTOM_SPEED));
|
||||
REGSAVE(TEXT(REGVALUE_EMULATION_SPEED), g_dwSpeed);
|
||||
|
||||
Config_Save_Video();
|
||||
|
||||
m_PropertySheetHelper.PostMsgAfterClose(hWnd, m_Page);
|
||||
}
|
||||
|
||||
|
@ -255,6 +255,8 @@ void CPageConfigTfe::init_tfe_dialog(HWND hwnd)
|
||||
if (gray_ungray_items(hwnd))
|
||||
{
|
||||
/* we have a problem: TFE is disabled. Give a message to the user */
|
||||
// TC (18 Dec 2017) this vicekb URL is a broken link now, so I copied it to the AppleWin repo, here:
|
||||
// . https://github.com/AppleWin/AppleWin/blob/master/docs/VICE%20Knowledge%20Base%20-%20Article%2013-005.htm
|
||||
MessageBox( hwnd,
|
||||
"TFE support is not available on your system,\n"
|
||||
"there is some important part missing. Please have a\n"
|
||||
|
@ -188,6 +188,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
// Config - Disassembly
|
||||
bool g_bConfigDisasmAddressView = true;
|
||||
int g_bConfigDisasmClick = 0; // GH#462 alt=1, ctrl=2, shift=4 bitmask
|
||||
bool g_bConfigDisasmAddressColon = true;
|
||||
bool g_bConfigDisasmOpcodesView = true;
|
||||
bool g_bConfigDisasmOpcodeSpaces = true;
|
||||
@ -2489,7 +2490,7 @@ Update_t CmdConfigDisasm( int nArgs )
|
||||
{
|
||||
case PARAM_CONFIG_BRANCH:
|
||||
if ((nArgs > 1) && (! bDisplayCurrentSettings)) // set
|
||||
{
|
||||
{
|
||||
iArg++;
|
||||
g_iConfigDisasmBranchType = g_aArgs[ iArg ].nValue;
|
||||
if (g_iConfigDisasmBranchType < 0)
|
||||
@ -2505,6 +2506,30 @@ Update_t CmdConfigDisasm( int nArgs )
|
||||
}
|
||||
break;
|
||||
|
||||
case PARAM_CONFIG_CLICK: // GH#462
|
||||
if ((nArgs > 1) && (! bDisplayCurrentSettings)) // set
|
||||
{
|
||||
iArg++;
|
||||
g_bConfigDisasmClick = (g_aArgs[ iArg ].nValue) & 7; // MAGIC NUMBER
|
||||
}
|
||||
// else // Always show current setting -- TODO: Fix remaining disasm to show current setting when set
|
||||
{
|
||||
const char *aClickKey[8] =
|
||||
{
|
||||
"" // 0
|
||||
,"Alt " // 1
|
||||
,"Ctrl " // 2
|
||||
,"Alt+Ctrl " // 3
|
||||
,"Shift " // 4
|
||||
,"Shift+Alt " // 5
|
||||
,"Shift+Ctrl " // 6
|
||||
,"Shift+Ctarl+Alt " // 7
|
||||
};
|
||||
ConsoleBufferPushFormat( sText, TEXT( "Click: %d = %sLeft click" ), g_bConfigDisasmClick, aClickKey[ g_bConfigDisasmClick & 7 ] );
|
||||
ConsoleBufferToDisplay();
|
||||
}
|
||||
break;
|
||||
|
||||
case PARAM_CONFIG_COLON:
|
||||
if ((nArgs > 1) && (! bDisplayCurrentSettings)) // set
|
||||
{
|
||||
@ -9647,14 +9672,33 @@ void DebuggerMouseClick( int x, int y )
|
||||
if (g_nAppMode != MODE_DEBUG)
|
||||
return;
|
||||
|
||||
// NOTE: KeybUpdateCtrlShiftStatus() should be called before
|
||||
int iAltCtrlShift = 0;
|
||||
iAltCtrlShift |= (g_bAltKey & 1) << 0;
|
||||
iAltCtrlShift |= (g_bCtrlKey & 1) << 1;
|
||||
iAltCtrlShift |= (g_bShiftKey & 1) << 2;
|
||||
|
||||
// GH#462 disasm click #
|
||||
if (iAltCtrlShift != g_bConfigDisasmClick)
|
||||
return;
|
||||
|
||||
int nFontWidth = g_aFontConfig[ FONT_DISASM_DEFAULT ]._nFontWidthAvg * GetViewportScale();
|
||||
int nFontHeight = g_aFontConfig[ FONT_DISASM_DEFAULT ]._nLineHeight * GetViewportScale();
|
||||
|
||||
// do picking
|
||||
|
||||
int cx = (x - VIEWPORTX) / nFontWidth;
|
||||
int cy = (y - VIEWPORTY) / nFontHeight;
|
||||
|
||||
const int nOffsetX = IsFullScreen() ? GetFullScreenOffsetX() : Get3DBorderWidth();
|
||||
const int nOffsetY = IsFullScreen() ? GetFullScreenOffsetY() : Get3DBorderHeight();
|
||||
|
||||
const int nOffsetInScreenX = x - nOffsetX;
|
||||
const int nOffsetInScreenY = y - nOffsetY;
|
||||
|
||||
if (nOffsetInScreenX < 0 || nOffsetInScreenY < 0)
|
||||
return;
|
||||
|
||||
int cx = nOffsetInScreenX / nFontWidth;
|
||||
int cy = nOffsetInScreenY / nFontHeight;
|
||||
|
||||
#if _DEBUG
|
||||
char sText[ CONSOLE_WIDTH ];
|
||||
sprintf( sText, "x:%d y:%d cx:%d cy:%d", x, y, cx, cy );
|
||||
@ -9717,6 +9761,31 @@ void DebuggerMouseClick( int x, int y )
|
||||
CmdCursorJumpPC( CURSOR_ALIGN_CENTER );
|
||||
DebugDisplay();
|
||||
}
|
||||
else
|
||||
if (cy == 4 || cy == 5)
|
||||
{
|
||||
int iFlag = -1;
|
||||
int nFlag = _6502_NUM_FLAGS;
|
||||
|
||||
while( nFlag --> 0 )
|
||||
{
|
||||
// TODO: magic number instead of DrawFlags() DISPLAY_FLAG_COLUMN, rect.left += ((2 + _6502_NUM_FLAGS) * nSpacerWidth);
|
||||
// BP_SRC_FLAG_C is 6, cx 60 --> 0
|
||||
// ...
|
||||
// BP_SRC_FLAG_N is 13, cx 53 --> 7
|
||||
if (cx == (53 + nFlag))
|
||||
{
|
||||
iFlag = 7 - nFlag;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (iFlag >= 0)
|
||||
{
|
||||
regs.ps ^= (1 << iFlag);
|
||||
DebugDisplay();
|
||||
}
|
||||
}
|
||||
else // Click on stack
|
||||
if( cy > 3)
|
||||
{
|
||||
|
@ -83,6 +83,7 @@
|
||||
|
||||
// Config - Disassembly
|
||||
extern bool g_bConfigDisasmAddressView ;
|
||||
extern int g_bConfigDisasmClick ; // GH#462
|
||||
extern bool g_bConfigDisasmAddressColon ;
|
||||
extern bool g_bConfigDisasmOpcodesView ;
|
||||
extern bool g_bConfigDisasmOpcodeSpaces ;
|
||||
|
@ -420,6 +420,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
{TEXT("N") , NULL, PARAM_FLAG_N }, // 1--- ---- Sign
|
||||
// Disasm
|
||||
{TEXT("BRANCH") , NULL, PARAM_CONFIG_BRANCH },
|
||||
{TEXT("CLICK") , NULL, PARAM_CONFIG_CLICK }, // GH#462
|
||||
{TEXT("COLON") , NULL, PARAM_CONFIG_COLON },
|
||||
{TEXT("OPCODE") , NULL, PARAM_CONFIG_OPCODE },
|
||||
{TEXT("POINTER") , NULL, PARAM_CONFIG_POINTER },
|
||||
|
@ -147,7 +147,6 @@ bool ConsolePrint ( const char * pText )
|
||||
{
|
||||
g_nConsoleBuffer++;
|
||||
}
|
||||
pSrc++;
|
||||
pDst = & g_aConsoleBuffer[ g_nConsoleBuffer ][ 0 ];
|
||||
}
|
||||
else
|
||||
|
@ -539,10 +539,11 @@ HDC GetDebuggerMemDC(void)
|
||||
{
|
||||
HDC hFrameDC = FrameGetDC();
|
||||
g_hDebuggerMemDC = CreateCompatibleDC(hFrameDC);
|
||||
g_hDebuggerMemBM = CreateCompatibleBitmap(hFrameDC, FRAMEBUFFER_W, FRAMEBUFFER_H);
|
||||
g_hDebuggerMemBM = CreateCompatibleBitmap(hFrameDC, GetFrameBufferWidth(), GetFrameBufferHeight());
|
||||
SelectObject(g_hDebuggerMemDC, g_hDebuggerMemBM);
|
||||
}
|
||||
|
||||
_ASSERT(g_hDebuggerMemDC); // TC: Could this be NULL?
|
||||
return g_hDebuggerMemDC;
|
||||
}
|
||||
|
||||
@ -563,8 +564,8 @@ void StretchBltMemToFrameDC(void)
|
||||
int nViewportCX, nViewportCY;
|
||||
GetViewportCXCY(nViewportCX, nViewportCY);
|
||||
|
||||
int xdest = GetFullScreenOffsetX();
|
||||
int ydest = GetFullScreenOffsetY();
|
||||
int xdest = IsFullScreen() ? GetFullScreenOffsetX() : 0;
|
||||
int ydest = IsFullScreen() ? GetFullScreenOffsetY() : 0;
|
||||
int wdest = nViewportCX;
|
||||
int hdest = nViewportCY;
|
||||
|
||||
@ -574,7 +575,7 @@ void StretchBltMemToFrameDC(void)
|
||||
wdest, hdest, // int nWidthDest, int nHeightDest,
|
||||
GetDebuggerMemDC(), // HDC hdcSrc,
|
||||
0, 0, // int nXOriginSrc, int nYOriginSrc,
|
||||
FRAMEBUFFER_BORDERLESS_W, FRAMEBUFFER_BORDERLESS_H, // int nWidthSrc, int nHeightSrc,
|
||||
GetFrameBufferBorderlessWidth(), GetFrameBufferBorderlessHeight(), // int nWidthSrc, int nHeightSrc,
|
||||
SRCCOPY // DWORD dwRop
|
||||
);
|
||||
}
|
||||
@ -1902,433 +1903,412 @@ WORD DrawDisassemblyLine ( int iLine, const WORD nBaseAddress )
|
||||
const int DISASM_SYMBOL_LEN = 9;
|
||||
#endif
|
||||
|
||||
HDC dc = GetDebuggerMemDC();
|
||||
if (dc) // TC: Why would this be NULL?
|
||||
int nFontHeight = g_aFontConfig[ FONT_DISASM_DEFAULT ]._nLineHeight; // _nFontHeight; // g_nFontHeight
|
||||
|
||||
RECT linerect;
|
||||
linerect.left = 0;
|
||||
linerect.top = iLine * nFontHeight;
|
||||
linerect.right = DISPLAY_DISASM_RIGHT;
|
||||
linerect.bottom = linerect.top + nFontHeight;
|
||||
|
||||
bool bBreakpointActive;
|
||||
bool bBreakpointEnable;
|
||||
GetBreakpointInfo( nBaseAddress, bBreakpointActive, bBreakpointEnable );
|
||||
bool bAddressAtPC = (nBaseAddress == regs.pc);
|
||||
bool bAddressIsBookmark = Bookmark_Find( nBaseAddress );
|
||||
|
||||
DebugColors_e iBackground = BG_DISASM_1;
|
||||
DebugColors_e iForeground = FG_DISASM_MNEMONIC; // FG_DISASM_TEXT;
|
||||
bool bCursorLine = false;
|
||||
|
||||
if (((! g_bDisasmCurBad) && (iLine == g_nDisasmCurLine))
|
||||
|| (g_bDisasmCurBad && (iLine == 0)))
|
||||
{
|
||||
int nFontHeight = g_aFontConfig[ FONT_DISASM_DEFAULT ]._nLineHeight; // _nFontHeight; // g_nFontHeight
|
||||
bCursorLine = true;
|
||||
|
||||
RECT linerect;
|
||||
linerect.left = 0;
|
||||
linerect.top = iLine * nFontHeight;
|
||||
linerect.right = DISPLAY_DISASM_RIGHT;
|
||||
linerect.bottom = linerect.top + nFontHeight;
|
||||
|
||||
// BOOL bp = g_nBreakpoints && CheckBreakpoint(nBaseAddress,nBaseAddress == regs.pc);
|
||||
|
||||
bool bBreakpointActive;
|
||||
bool bBreakpointEnable;
|
||||
GetBreakpointInfo( nBaseAddress, bBreakpointActive, bBreakpointEnable );
|
||||
bool bAddressAtPC = (nBaseAddress == regs.pc);
|
||||
bool bAddressIsBookmark = Bookmark_Find( nBaseAddress );
|
||||
|
||||
DebugColors_e iBackground = BG_DISASM_1;
|
||||
DebugColors_e iForeground = FG_DISASM_MNEMONIC; // FG_DISASM_TEXT;
|
||||
bool bCursorLine = false;
|
||||
|
||||
if (((! g_bDisasmCurBad) && (iLine == g_nDisasmCurLine))
|
||||
|| (g_bDisasmCurBad && (iLine == 0)))
|
||||
// Breakpoint
|
||||
if (bBreakpointActive)
|
||||
{
|
||||
bCursorLine = true;
|
||||
|
||||
// Breakpoint,
|
||||
if (bBreakpointActive)
|
||||
if (bBreakpointEnable)
|
||||
{
|
||||
if (bBreakpointEnable)
|
||||
{
|
||||
iBackground = BG_DISASM_BP_S_C; iForeground = FG_DISASM_BP_S_C;
|
||||
}
|
||||
else
|
||||
{
|
||||
iBackground = BG_DISASM_BP_0_C; iForeground = FG_DISASM_BP_0_C;
|
||||
}
|
||||
}
|
||||
else
|
||||
if (bAddressAtPC)
|
||||
{
|
||||
iBackground = BG_DISASM_PC_C; iForeground = FG_DISASM_PC_C;
|
||||
iBackground = BG_DISASM_BP_S_C; iForeground = FG_DISASM_BP_S_C;
|
||||
}
|
||||
else
|
||||
{
|
||||
iBackground = BG_DISASM_C; iForeground = FG_DISASM_C;
|
||||
// HACK? Sync Cursor back up to Address
|
||||
// The cursor line may of had to be been moved, due to Disasm Singularity.
|
||||
g_nDisasmCurAddress = nBaseAddress;
|
||||
iBackground = BG_DISASM_BP_0_C; iForeground = FG_DISASM_BP_0_C;
|
||||
}
|
||||
}
|
||||
else
|
||||
if (bAddressAtPC)
|
||||
{
|
||||
if (iLine & 1)
|
||||
{
|
||||
iBackground = BG_DISASM_1;
|
||||
}
|
||||
else
|
||||
{
|
||||
iBackground = BG_DISASM_2;
|
||||
}
|
||||
|
||||
// This address has a breakpoint, but the cursor is not on it (atm)
|
||||
if (bBreakpointActive)
|
||||
{
|
||||
if (bBreakpointEnable)
|
||||
{
|
||||
iForeground = FG_DISASM_BP_S_X; // Red (old Yellow)
|
||||
}
|
||||
else
|
||||
{
|
||||
iForeground = FG_DISASM_BP_0_X; // Yellow
|
||||
}
|
||||
}
|
||||
else
|
||||
if (bAddressAtPC)
|
||||
{
|
||||
iBackground = BG_DISASM_PC_X; iForeground = FG_DISASM_PC_X;
|
||||
}
|
||||
else
|
||||
{
|
||||
iForeground = FG_DISASM_MNEMONIC;
|
||||
}
|
||||
}
|
||||
|
||||
if (bAddressIsBookmark)
|
||||
{
|
||||
DebuggerSetColorBG( DebuggerGetColor( BG_DISASM_BOOKMARK ) );
|
||||
DebuggerSetColorFG( DebuggerGetColor( FG_DISASM_BOOKMARK ) );
|
||||
iBackground = BG_DISASM_PC_C; iForeground = FG_DISASM_PC_C;
|
||||
}
|
||||
else
|
||||
{
|
||||
DebuggerSetColorBG( DebuggerGetColor( iBackground ) );
|
||||
DebuggerSetColorFG( DebuggerGetColor( iForeground ) );
|
||||
iBackground = BG_DISASM_C; iForeground = FG_DISASM_C;
|
||||
// HACK? Sync Cursor back up to Address
|
||||
// The cursor line may of had to be been moved, due to Disasm Singularity.
|
||||
g_nDisasmCurAddress = nBaseAddress;
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
if (iLine & 1)
|
||||
{
|
||||
iBackground = BG_DISASM_1;
|
||||
}
|
||||
else
|
||||
{
|
||||
iBackground = BG_DISASM_2;
|
||||
}
|
||||
|
||||
// This address has a breakpoint, but the cursor is not on it (atm)
|
||||
if (bBreakpointActive)
|
||||
{
|
||||
if (bBreakpointEnable)
|
||||
{
|
||||
iForeground = FG_DISASM_BP_S_X; // Red (old Yellow)
|
||||
}
|
||||
else
|
||||
{
|
||||
iForeground = FG_DISASM_BP_0_X; // Yellow
|
||||
}
|
||||
}
|
||||
else
|
||||
if (bAddressAtPC)
|
||||
{
|
||||
iBackground = BG_DISASM_PC_X; iForeground = FG_DISASM_PC_X;
|
||||
}
|
||||
else
|
||||
{
|
||||
iForeground = FG_DISASM_MNEMONIC;
|
||||
}
|
||||
}
|
||||
|
||||
if (bAddressIsBookmark)
|
||||
{
|
||||
DebuggerSetColorBG( DebuggerGetColor( BG_DISASM_BOOKMARK ) );
|
||||
DebuggerSetColorFG( DebuggerGetColor( FG_DISASM_BOOKMARK ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
DebuggerSetColorBG( DebuggerGetColor( iBackground ) );
|
||||
DebuggerSetColorFG( DebuggerGetColor( iForeground ) );
|
||||
}
|
||||
|
||||
// Address
|
||||
if (! bCursorLine)
|
||||
DebuggerSetColorFG( DebuggerGetColor( FG_DISASM_ADDRESS ) );
|
||||
// else
|
||||
// {
|
||||
// DebuggerSetColorBG( dc, DebuggerGetColor( FG_DISASM_BOOKMARK ) ); // swapped
|
||||
// DebuggerSetColorFG( dc, DebuggerGetColor( BG_DISASM_BOOKMARK ) ); // swapped
|
||||
// }
|
||||
if (! bCursorLine)
|
||||
DebuggerSetColorFG( DebuggerGetColor( FG_DISASM_ADDRESS ) );
|
||||
// else
|
||||
// {
|
||||
// DebuggerSetColorBG( GetDebuggerMemDC(), DebuggerGetColor( FG_DISASM_BOOKMARK ) ); // swapped
|
||||
// DebuggerSetColorFG( GetDebuggerMemDC(), DebuggerGetColor( BG_DISASM_BOOKMARK ) ); // swapped
|
||||
// }
|
||||
|
||||
if( g_bConfigDisasmAddressView )
|
||||
{
|
||||
PrintTextCursorX( (LPCTSTR) line.sAddress, linerect );
|
||||
}
|
||||
if( g_bConfigDisasmAddressView )
|
||||
{
|
||||
PrintTextCursorX( (LPCTSTR) line.sAddress, linerect );
|
||||
}
|
||||
|
||||
if (bAddressIsBookmark)
|
||||
{
|
||||
DebuggerSetColorBG( DebuggerGetColor( iBackground ) );
|
||||
DebuggerSetColorFG( DebuggerGetColor( iForeground ) );
|
||||
}
|
||||
|
||||
if (bAddressIsBookmark)
|
||||
{
|
||||
DebuggerSetColorBG( DebuggerGetColor( iBackground ) );
|
||||
DebuggerSetColorFG( DebuggerGetColor( iForeground ) );
|
||||
}
|
||||
|
||||
// Address Seperator
|
||||
if (! bCursorLine)
|
||||
DebuggerSetColorFG( DebuggerGetColor( FG_DISASM_OPERATOR ) );
|
||||
if (! bCursorLine)
|
||||
DebuggerSetColorFG( DebuggerGetColor( FG_DISASM_OPERATOR ) );
|
||||
|
||||
if (g_bConfigDisasmAddressColon)
|
||||
PrintTextCursorX( ":", linerect );
|
||||
else
|
||||
PrintTextCursorX( " ", linerect ); // bugfix, not showing "addr:" doesn't alternate color lines
|
||||
if (g_bConfigDisasmAddressColon)
|
||||
PrintTextCursorX( ":", linerect );
|
||||
else
|
||||
PrintTextCursorX( " ", linerect ); // bugfix, not showing "addr:" doesn't alternate color lines
|
||||
|
||||
// Opcodes
|
||||
linerect.left = (int) aTabs[ TS_OPCODE ];
|
||||
linerect.left = (int) aTabs[ TS_OPCODE ];
|
||||
|
||||
if (! bCursorLine)
|
||||
DebuggerSetColorFG( DebuggerGetColor( FG_DISASM_OPCODE ) );
|
||||
// PrintTextCursorX( " ", linerect );
|
||||
if (! bCursorLine)
|
||||
DebuggerSetColorFG( DebuggerGetColor( FG_DISASM_OPCODE ) );
|
||||
|
||||
if (g_bConfigDisasmOpcodesView)
|
||||
PrintTextCursorX( (LPCTSTR) line.sOpCodes, linerect );
|
||||
// PrintTextCursorX( " ", linerect );
|
||||
if (g_bConfigDisasmOpcodesView)
|
||||
PrintTextCursorX( (LPCTSTR) line.sOpCodes, linerect );
|
||||
|
||||
// Label
|
||||
linerect.left = (int) aTabs[ TS_LABEL ];
|
||||
linerect.left = (int) aTabs[ TS_LABEL ];
|
||||
|
||||
if (pSymbol)
|
||||
{
|
||||
if (! bCursorLine)
|
||||
DebuggerSetColorFG( DebuggerGetColor( FG_DISASM_SYMBOL ) );
|
||||
PrintTextCursorX( pSymbol, linerect );
|
||||
}
|
||||
// linerect.left += (g_nFontWidthAvg * DISASM_SYMBOL_LEN);
|
||||
// PrintTextCursorX( " ", linerect );
|
||||
if (pSymbol)
|
||||
{
|
||||
if (! bCursorLine)
|
||||
DebuggerSetColorFG( DebuggerGetColor( FG_DISASM_SYMBOL ) );
|
||||
PrintTextCursorX( pSymbol, linerect );
|
||||
}
|
||||
|
||||
// Instruction / Mnemonic
|
||||
linerect.left = (int) aTabs[ TS_INSTRUCTION ];
|
||||
linerect.left = (int) aTabs[ TS_INSTRUCTION ];
|
||||
|
||||
if (! bCursorLine)
|
||||
{
|
||||
if( pData ) // Assembler Data Directive / Data Disassembler
|
||||
DebuggerSetColorFG( DebuggerGetColor( FG_DISASM_DIRECTIVE ) ); // TODO: FIXME: HACK? Is the color fine?
|
||||
else
|
||||
DebuggerSetColorFG( DebuggerGetColor( iForeground ) );
|
||||
}
|
||||
if (! bCursorLine)
|
||||
{
|
||||
if( pData ) // Assembler Data Directive / Data Disassembler
|
||||
DebuggerSetColorFG( DebuggerGetColor( FG_DISASM_DIRECTIVE ) ); // TODO: FIXME: HACK? Is the color fine?
|
||||
else
|
||||
DebuggerSetColorFG( DebuggerGetColor( iForeground ) );
|
||||
}
|
||||
|
||||
pMnemonic = line.sMnemonic;
|
||||
PrintTextCursorX( pMnemonic, linerect );
|
||||
PrintTextCursorX( " ", linerect );
|
||||
pMnemonic = line.sMnemonic;
|
||||
PrintTextCursorX( pMnemonic, linerect );
|
||||
PrintTextCursorX( " ", linerect );
|
||||
|
||||
// Target
|
||||
if (line.bTargetImmediate)
|
||||
if (line.bTargetImmediate)
|
||||
{
|
||||
if (! bCursorLine)
|
||||
DebuggerSetColorFG( DebuggerGetColor( FG_DISASM_OPERATOR ));
|
||||
PrintTextCursorX( "#$", linerect );
|
||||
}
|
||||
|
||||
if (line.bTargetIndexed || line.bTargetIndirect)
|
||||
{
|
||||
if (! bCursorLine)
|
||||
DebuggerSetColorFG( DebuggerGetColor( FG_DISASM_OPERATOR ));
|
||||
PrintTextCursorX( "(", linerect );
|
||||
}
|
||||
|
||||
char *pTarget = line.sTarget;
|
||||
int nLen = strlen( pTarget );
|
||||
|
||||
if (*pTarget == '$') // BUG? if ASC #:# starts with '$' ? // && (iOpcode != OPCODE_NOP)
|
||||
{
|
||||
pTarget++;
|
||||
if (! bCursorLine)
|
||||
DebuggerSetColorFG( DebuggerGetColor( FG_DISASM_OPERATOR ));
|
||||
PrintTextCursorX( "$", linerect );
|
||||
}
|
||||
|
||||
if (! bCursorLine)
|
||||
{
|
||||
if (bDisasmFormatFlags & DISASM_FORMAT_SYMBOL)
|
||||
{
|
||||
if (! bCursorLine)
|
||||
DebuggerSetColorFG( DebuggerGetColor( FG_DISASM_OPERATOR ));
|
||||
PrintTextCursorX( "#$", linerect );
|
||||
DebuggerSetColorFG( DebuggerGetColor( FG_DISASM_SYMBOL ) );
|
||||
}
|
||||
|
||||
if (line.bTargetIndexed || line.bTargetIndirect)
|
||||
else
|
||||
{
|
||||
if (! bCursorLine)
|
||||
DebuggerSetColorFG( DebuggerGetColor( FG_DISASM_OPERATOR ));
|
||||
PrintTextCursorX( "(", linerect );
|
||||
if (iOpmode == AM_M)
|
||||
// if (bDisasmFormatFlags & DISASM_FORMAT_CHAR)
|
||||
{
|
||||
DebuggerSetColorFG( DebuggerGetColor( FG_DISASM_OPCODE ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
DebuggerSetColorFG( DebuggerGetColor( FG_DISASM_TARGET ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
char *pTarget = line.sTarget;
|
||||
int nLen = strlen( pTarget );
|
||||
// https://github.com/AppleWin/AppleWin/issues/227
|
||||
// (Debugger)[1.25] AppleSoft symbol: COPY.FAC.TO.ARG.ROUNDED overflows into registers
|
||||
// Repro:
|
||||
// UEA39
|
||||
// 2.8.0.1 Clamp excessive symbol target to not overflow
|
||||
// SYM COPY.FAC.TO.ARG.ROUNDED = EB63
|
||||
// If opcodes aren't showing then length can be longer!
|
||||
// FormatOpcodeBytes() uses 3 chars/MAX_OPCODES. i.e. "## "
|
||||
int nMaxLen = MAX_TARGET_LEN;
|
||||
|
||||
if (*pTarget == '$') // BUG? if ASC #:# starts with '$' ? // && (iOpcode != OPCODE_NOP)
|
||||
// 2.8.0.8: Bug #227: AppleSoft symbol: COPY.FAC.TO.ARG.ROUNDED overflows into registers
|
||||
if ( !g_bConfigDisasmAddressView )
|
||||
nMaxLen += 4;
|
||||
if ( !g_bConfigDisasmOpcodesView )
|
||||
nMaxLen += (MAX_OPCODES*3);
|
||||
|
||||
// 2.9.0.9 Continuation of 2.8.0.8: Fix overflowing disassembly pane for long symbols
|
||||
int nOverflow = 0;
|
||||
if (bDisasmFormatFlags & DISASM_FORMAT_OFFSET)
|
||||
{
|
||||
if (line.nTargetOffset != 0)
|
||||
nOverflow++;
|
||||
|
||||
nOverflow += strlen( line.sTargetOffset );
|
||||
}
|
||||
|
||||
if (line.bTargetIndirect || line.bTargetX || line.bTargetY)
|
||||
{
|
||||
if (line.bTargetX)
|
||||
nOverflow += 2;
|
||||
else
|
||||
if ((line.bTargetY) && (! line.bTargetIndirect))
|
||||
nOverflow += 2;
|
||||
}
|
||||
|
||||
if (line.bTargetIndexed || line.bTargetIndirect)
|
||||
nOverflow++;
|
||||
|
||||
if (line.bTargetIndexed)
|
||||
{
|
||||
if (line.bTargetY)
|
||||
nOverflow += 2;
|
||||
}
|
||||
|
||||
if (bDisasmFormatFlags & DISASM_FORMAT_TARGET_POINTER)
|
||||
{
|
||||
nOverflow += strlen( line.sTargetPointer ); // '####'
|
||||
nOverflow ++ ; // ':'
|
||||
nOverflow += 2; // '##'
|
||||
nOverflow ++ ; // ' '
|
||||
}
|
||||
|
||||
if (bDisasmFormatFlags & DISASM_FORMAT_CHAR)
|
||||
{
|
||||
nOverflow += strlen( line.sImmediate );
|
||||
}
|
||||
|
||||
if (nLen >= (nMaxLen - nOverflow))
|
||||
{
|
||||
#if _DEBUG
|
||||
// TODO: Warn on import about long symbol/target names
|
||||
#endif
|
||||
pTarget[ nMaxLen - nOverflow ] = 0;
|
||||
}
|
||||
|
||||
// TODO: FIXME: 2.8.0.7: Allow ctrl characters to show as inverse; i.e. ASC 400:40F
|
||||
PrintTextCursorX( pTarget, linerect );
|
||||
|
||||
// Target Offset +/-
|
||||
if (bDisasmFormatFlags & DISASM_FORMAT_OFFSET)
|
||||
{
|
||||
if (! bCursorLine)
|
||||
DebuggerSetColorFG( DebuggerGetColor( FG_DISASM_OPERATOR ));
|
||||
|
||||
if (line.nTargetOffset > 0)
|
||||
PrintTextCursorX( "+", linerect );
|
||||
else
|
||||
if (line.nTargetOffset < 0)
|
||||
PrintTextCursorX( "-", linerect );
|
||||
|
||||
if (! bCursorLine)
|
||||
{
|
||||
pTarget++;
|
||||
DebuggerSetColorFG( DebuggerGetColor( FG_DISASM_OPCODE )); // Technically, not a hex number, but decimal
|
||||
}
|
||||
PrintTextCursorX( line.sTargetOffset, linerect );
|
||||
}
|
||||
// Inside parenthesis = Indirect Target Regs
|
||||
if (line.bTargetIndirect || line.bTargetX || line.bTargetY)
|
||||
{
|
||||
if (! bCursorLine)
|
||||
DebuggerSetColorFG( DebuggerGetColor( FG_DISASM_OPERATOR ));
|
||||
|
||||
if (line.bTargetX)
|
||||
{
|
||||
PrintTextCursorX( ",", linerect );
|
||||
if (! bCursorLine)
|
||||
DebuggerSetColorFG( DebuggerGetColor( FG_DISASM_OPERATOR ));
|
||||
PrintTextCursorX( "$", linerect );
|
||||
DebuggerSetColorFG( DebuggerGetColor( FG_INFO_REG ) );
|
||||
PrintTextCursorX( "X", linerect );
|
||||
}
|
||||
else
|
||||
if ((line.bTargetY) && (! line.bTargetIndirect))
|
||||
{
|
||||
PrintTextCursorX( ",", linerect );
|
||||
if (! bCursorLine)
|
||||
DebuggerSetColorFG( DebuggerGetColor( FG_INFO_REG ) );
|
||||
PrintTextCursorX( "Y", linerect );
|
||||
}
|
||||
}
|
||||
|
||||
if (line.bTargetIndexed || line.bTargetIndirect)
|
||||
{
|
||||
if (! bCursorLine)
|
||||
DebuggerSetColorFG( DebuggerGetColor( FG_DISASM_OPERATOR ));
|
||||
|
||||
PrintTextCursorX( ")", linerect );
|
||||
}
|
||||
|
||||
if (line.bTargetIndexed)
|
||||
{
|
||||
if (line.bTargetY)
|
||||
{
|
||||
PrintTextCursorX( ",", linerect );
|
||||
if (! bCursorLine)
|
||||
DebuggerSetColorFG( DebuggerGetColor( FG_INFO_REG ) );
|
||||
PrintTextCursorX( "Y", linerect );
|
||||
}
|
||||
}
|
||||
|
||||
// BUGFIX: 2.6.2.30: DA $target --> show right paren
|
||||
if( pData )
|
||||
{
|
||||
return nOpbyte;
|
||||
}
|
||||
|
||||
// Memory Pointer and Value
|
||||
if (bDisasmFormatFlags & DISASM_FORMAT_TARGET_POINTER) // (bTargetValue)
|
||||
{
|
||||
linerect.left = (int) aTabs[ TS_IMMEDIATE ]; // TS_IMMEDIATE ];
|
||||
|
||||
if (! bCursorLine)
|
||||
DebuggerSetColorFG( DebuggerGetColor( FG_DISASM_ADDRESS ));
|
||||
|
||||
PrintTextCursorX( line.sTargetPointer, linerect );
|
||||
|
||||
if (bDisasmFormatFlags & DISASM_FORMAT_TARGET_VALUE)
|
||||
{
|
||||
if (! bCursorLine)
|
||||
DebuggerSetColorFG( DebuggerGetColor( FG_DISASM_OPERATOR ));
|
||||
|
||||
if (g_iConfigDisasmTargets & DISASM_TARGET_BOTH)
|
||||
PrintTextCursorX( ":", linerect );
|
||||
|
||||
if (! bCursorLine)
|
||||
DebuggerSetColorFG( DebuggerGetColor( FG_DISASM_OPCODE ));
|
||||
|
||||
PrintTextCursorX( line.sTargetValue, linerect );
|
||||
PrintTextCursorX( " ", linerect );
|
||||
}
|
||||
}
|
||||
|
||||
// Immediate Char
|
||||
if (bDisasmFormatFlags & DISASM_FORMAT_CHAR)
|
||||
{
|
||||
linerect.left = (int) aTabs[ TS_CHAR ]; // TS_IMMEDIATE ];
|
||||
|
||||
if (! bCursorLine)
|
||||
{
|
||||
DebuggerSetColorFG( DebuggerGetColor( FG_DISASM_OPERATOR ) );
|
||||
}
|
||||
|
||||
if (! bCursorLine)
|
||||
{
|
||||
if (bDisasmFormatFlags & DISASM_FORMAT_SYMBOL)
|
||||
{
|
||||
DebuggerSetColorFG( DebuggerGetColor( FG_DISASM_SYMBOL ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
if (iOpmode == AM_M)
|
||||
// if (bDisasmFormatFlags & DISASM_FORMAT_CHAR)
|
||||
{
|
||||
DebuggerSetColorFG( DebuggerGetColor( FG_DISASM_OPCODE ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
DebuggerSetColorFG( DebuggerGetColor( FG_DISASM_TARGET ) );
|
||||
}
|
||||
}
|
||||
ColorizeSpecialChar( NULL, line.nImmediate, MEM_VIEW_ASCII, iBackground );
|
||||
}
|
||||
PrintTextCursorX( line.sImmediate, linerect );
|
||||
|
||||
// https://github.com/AppleWin/AppleWin/issues/227
|
||||
// (Debugger)[1.25] AppleSoft symbol: COPY.FAC.TO.ARG.ROUNDED overflows into registers
|
||||
// Repro:
|
||||
// UEA39
|
||||
// 2.8.0.1 Clamp excessive symbol target to not overflow
|
||||
// SYM COPY.FAC.TO.ARG.ROUNDED = EB63
|
||||
// If opcodes aren't showing then length can be longer!
|
||||
// FormatOpcodeBytes() uses 3 chars/MAX_OPCODES. i.e. "## "
|
||||
int nMaxLen = MAX_TARGET_LEN;
|
||||
|
||||
// 2.8.0.8: Bug #227: AppleSoft symbol: COPY.FAC.TO.ARG.ROUNDED overflows into registers
|
||||
if ( !g_bConfigDisasmAddressView )
|
||||
nMaxLen += 4;
|
||||
if ( !g_bConfigDisasmOpcodesView )
|
||||
nMaxLen += (MAX_OPCODES*3);
|
||||
|
||||
// 2.9.0.9 Continuation of 2.8.0.8: Fix overflowing disassembly pane for long symbols
|
||||
int nOverflow = 0;
|
||||
if (bDisasmFormatFlags & DISASM_FORMAT_OFFSET)
|
||||
DebuggerSetColorBG( DebuggerGetColor( iBackground ) ); // Hack: Colorize can "color bleed to EOL"
|
||||
if (! bCursorLine)
|
||||
{
|
||||
if (line.nTargetOffset != 0)
|
||||
nOverflow++;
|
||||
|
||||
nOverflow += strlen( line.sTargetOffset );
|
||||
DebuggerSetColorFG( DebuggerGetColor( FG_DISASM_OPERATOR ) );
|
||||
}
|
||||
}
|
||||
|
||||
if (line.bTargetIndirect || line.bTargetX || line.bTargetY)
|
||||
{
|
||||
if (line.bTargetX)
|
||||
nOverflow += 2;
|
||||
else
|
||||
if ((line.bTargetY) && (! line.bTargetIndirect))
|
||||
nOverflow += 2;
|
||||
}
|
||||
|
||||
if (line.bTargetIndexed || line.bTargetIndirect)
|
||||
nOverflow++;
|
||||
|
||||
if (line.bTargetIndexed)
|
||||
{
|
||||
if (line.bTargetY)
|
||||
nOverflow += 2;
|
||||
}
|
||||
|
||||
if (bDisasmFormatFlags & DISASM_FORMAT_TARGET_POINTER)
|
||||
{
|
||||
nOverflow += strlen( line.sTargetPointer ); // '####'
|
||||
nOverflow ++ ; // ':'
|
||||
nOverflow += 2; // '##'
|
||||
nOverflow ++ ; // ' '
|
||||
}
|
||||
|
||||
if (bDisasmFormatFlags & DISASM_FORMAT_CHAR)
|
||||
{
|
||||
nOverflow += strlen( line.sImmediate );
|
||||
}
|
||||
|
||||
if (nLen >= (nMaxLen - nOverflow))
|
||||
{
|
||||
#if _DEBUG
|
||||
// TODO: Warn on import about long symbol/target names
|
||||
#endif
|
||||
pTarget[ nMaxLen - nOverflow ] = 0;
|
||||
}
|
||||
|
||||
// TODO: FIXME: 2.8.0.7: Allow ctrl characters to show as inverse; i.e. ASC 400:40F
|
||||
PrintTextCursorX( pTarget, linerect );
|
||||
// PrintTextCursorX( " ", linerect );
|
||||
|
||||
// Target Offset +/-
|
||||
if (bDisasmFormatFlags & DISASM_FORMAT_OFFSET)
|
||||
{
|
||||
if (! bCursorLine)
|
||||
DebuggerSetColorFG( DebuggerGetColor( FG_DISASM_OPERATOR ));
|
||||
|
||||
if (line.nTargetOffset > 0)
|
||||
PrintTextCursorX( "+", linerect );
|
||||
else
|
||||
if (line.nTargetOffset < 0)
|
||||
PrintTextCursorX( "-", linerect );
|
||||
|
||||
if (! bCursorLine)
|
||||
{
|
||||
DebuggerSetColorFG( DebuggerGetColor( FG_DISASM_OPCODE )); // Technically, not a hex number, but decimal
|
||||
}
|
||||
PrintTextCursorX( line.sTargetOffset, linerect );
|
||||
}
|
||||
// Inside Parenthesis = Indirect Target Regs
|
||||
if (line.bTargetIndirect || line.bTargetX || line.bTargetY)
|
||||
{
|
||||
if (! bCursorLine)
|
||||
DebuggerSetColorFG( DebuggerGetColor( FG_DISASM_OPERATOR ));
|
||||
|
||||
if (line.bTargetX)
|
||||
{
|
||||
PrintTextCursorX( ",", linerect );
|
||||
if (! bCursorLine)
|
||||
DebuggerSetColorFG( DebuggerGetColor( FG_INFO_REG ) );
|
||||
PrintTextCursorX( "X", linerect );
|
||||
}
|
||||
else
|
||||
if ((line.bTargetY) && (! line.bTargetIndirect))
|
||||
{
|
||||
PrintTextCursorX( ",", linerect );
|
||||
if (! bCursorLine)
|
||||
DebuggerSetColorFG( DebuggerGetColor( FG_INFO_REG ) );
|
||||
PrintTextCursorX( "Y", linerect );
|
||||
}
|
||||
}
|
||||
|
||||
if (line.bTargetIndexed || line.bTargetIndirect)
|
||||
{
|
||||
if (! bCursorLine)
|
||||
DebuggerSetColorFG( DebuggerGetColor( FG_DISASM_OPERATOR ));
|
||||
|
||||
PrintTextCursorX( ")", linerect );
|
||||
}
|
||||
|
||||
if (line.bTargetIndexed)
|
||||
{
|
||||
if (line.bTargetY)
|
||||
{
|
||||
PrintTextCursorX( ",", linerect );
|
||||
if (! bCursorLine)
|
||||
DebuggerSetColorFG( DebuggerGetColor( FG_INFO_REG ) );
|
||||
PrintTextCursorX( "Y", linerect );
|
||||
}
|
||||
}
|
||||
|
||||
// BUGFIX: 2.6.2.30: DA $target --> show right paren
|
||||
if( pData )
|
||||
{
|
||||
return nOpbyte;
|
||||
}
|
||||
|
||||
// Memory Pointer and Value
|
||||
if (bDisasmFormatFlags & DISASM_FORMAT_TARGET_POINTER) // (bTargetValue)
|
||||
{
|
||||
linerect.left = (int) aTabs[ TS_IMMEDIATE ]; // TS_IMMEDIATE ];
|
||||
|
||||
// PrintTextCursorX( " ", linerect );
|
||||
|
||||
if (! bCursorLine)
|
||||
DebuggerSetColorFG( DebuggerGetColor( FG_DISASM_ADDRESS ));
|
||||
|
||||
PrintTextCursorX( line.sTargetPointer, linerect );
|
||||
|
||||
if (bDisasmFormatFlags & DISASM_FORMAT_TARGET_VALUE)
|
||||
{
|
||||
if (! bCursorLine)
|
||||
DebuggerSetColorFG( DebuggerGetColor( FG_DISASM_OPERATOR ));
|
||||
|
||||
if (g_iConfigDisasmTargets & DISASM_TARGET_BOTH)
|
||||
PrintTextCursorX( ":", linerect );
|
||||
|
||||
if (! bCursorLine)
|
||||
DebuggerSetColorFG( DebuggerGetColor( FG_DISASM_OPCODE ));
|
||||
|
||||
PrintTextCursorX( line.sTargetValue, linerect );
|
||||
PrintTextCursorX( " ", linerect );
|
||||
}
|
||||
}
|
||||
|
||||
// Immediate Char
|
||||
if (bDisasmFormatFlags & DISASM_FORMAT_CHAR)
|
||||
{
|
||||
linerect.left = (int) aTabs[ TS_CHAR ]; // TS_IMMEDIATE ];
|
||||
|
||||
if (! bCursorLine)
|
||||
{
|
||||
DebuggerSetColorFG( DebuggerGetColor( FG_DISASM_OPERATOR ) );
|
||||
}
|
||||
|
||||
// if (! (bDisasmFormatFlags & DISASM_FORMAT_TARGET_POINTER))
|
||||
// PrintTextCursorX( "'", linerect );
|
||||
|
||||
if (! bCursorLine)
|
||||
{
|
||||
ColorizeSpecialChar( NULL, line.nImmediate, MEM_VIEW_ASCII, iBackground );
|
||||
// iBackground, FG_INFO_CHAR_HI, FG_DISASM_CHAR, FG_INFO_CHAR_LO );
|
||||
}
|
||||
PrintTextCursorX( line.sImmediate, linerect );
|
||||
|
||||
DebuggerSetColorBG( DebuggerGetColor( iBackground ) ); // Hack: Colorize can "color bleed to EOL"
|
||||
if (! bCursorLine)
|
||||
{
|
||||
DebuggerSetColorFG( DebuggerGetColor( FG_DISASM_OPERATOR ) );
|
||||
}
|
||||
|
||||
// if (! (bDisasmFormatFlags & DISASM_FORMAT_TARGET_POINTER))
|
||||
// PrintTextCursorX( "'", linerect );
|
||||
}
|
||||
|
||||
// Branch Indicator
|
||||
if (bDisasmFormatFlags & DISASM_FORMAT_BRANCH)
|
||||
if (bDisasmFormatFlags & DISASM_FORMAT_BRANCH)
|
||||
{
|
||||
linerect.left = (int) aTabs[ TS_BRANCH ];
|
||||
|
||||
if (! bCursorLine)
|
||||
{
|
||||
linerect.left = (int) aTabs[ TS_BRANCH ];
|
||||
|
||||
if (! bCursorLine)
|
||||
{
|
||||
DebuggerSetColorFG( DebuggerGetColor( FG_DISASM_BRANCH ) );
|
||||
}
|
||||
|
||||
#if !USE_APPLE_FONT
|
||||
if (g_iConfigDisasmBranchType == DISASM_BRANCH_FANCY)
|
||||
SelectObject( GetDebuggerMemDC(), g_aFontConfig[ FONT_DISASM_BRANCH ]._hFont ); // g_hFontWebDings
|
||||
#endif
|
||||
|
||||
// PrintTextColor( sBranch, linerect );
|
||||
PrintText( line.sBranch, linerect );
|
||||
|
||||
#if !USE_APPLE_FONT
|
||||
if (g_iConfigDisasmBranchType)
|
||||
SelectObject( dc, g_aFontConfig[ FONT_DISASM_DEFAULT ]._hFont ); // g_hFontDisasm
|
||||
#endif
|
||||
DebuggerSetColorFG( DebuggerGetColor( FG_DISASM_BRANCH ) );
|
||||
}
|
||||
|
||||
#if !USE_APPLE_FONT
|
||||
if (g_iConfigDisasmBranchType == DISASM_BRANCH_FANCY)
|
||||
SelectObject( GetDebuggerMemDC(), g_aFontConfig[ FONT_DISASM_BRANCH ]._hFont ); // g_hFontWebDings
|
||||
#endif
|
||||
|
||||
PrintText( line.sBranch, linerect );
|
||||
|
||||
#if !USE_APPLE_FONT
|
||||
if (g_iConfigDisasmBranchType)
|
||||
SelectObject( GetDebuggerMemDC(), g_aFontConfig[ FONT_DISASM_DEFAULT ]._hFont ); // g_hFontDisasm
|
||||
#endif
|
||||
}
|
||||
|
||||
return nOpbyte;
|
||||
@ -2344,7 +2324,7 @@ void DrawFlags ( int line, WORD nRegFlags, LPTSTR pFlagNames_)
|
||||
|
||||
char sFlagNames[ _6502_NUM_FLAGS+1 ] = ""; // = "NVRBDIZC"; // copy from g_aFlagNames
|
||||
char sText[4] = "?";
|
||||
RECT rect;
|
||||
RECT rect;
|
||||
|
||||
int nFontWidth = g_aFontConfig[ FONT_INFO ]._nFontWidthAvg;
|
||||
|
||||
@ -2359,33 +2339,36 @@ void DrawFlags ( int line, WORD nRegFlags, LPTSTR pFlagNames_)
|
||||
nSpacerWidth++;
|
||||
#endif
|
||||
|
||||
if (GetDebuggerMemDC()) // TC: Why would this be NULL?
|
||||
{
|
||||
rect.top = line * g_nFontHeight;
|
||||
rect.bottom = rect.top + g_nFontHeight;
|
||||
rect.left = DISPLAY_FLAG_COLUMN;
|
||||
rect.right = rect.left + (10 * nFontWidth);
|
||||
//
|
||||
|
||||
DebuggerSetColorBG( DebuggerGetColor( BG_DATA_1 )); // BG_INFO
|
||||
DebuggerSetColorFG( DebuggerGetColor( FG_INFO_REG ));
|
||||
PrintText( "P ", rect );
|
||||
GetDebuggerMemDC();
|
||||
|
||||
rect.top += g_nFontHeight;
|
||||
rect.bottom += g_nFontHeight;
|
||||
rect.top = line * g_nFontHeight;
|
||||
rect.bottom = rect.top + g_nFontHeight;
|
||||
rect.left = DISPLAY_FLAG_COLUMN;
|
||||
rect.right = rect.left + (10 * nFontWidth);
|
||||
|
||||
sprintf( sText, "%02X", nRegFlags );
|
||||
DebuggerSetColorBG( DebuggerGetColor( BG_DATA_1 )); // BG_INFO
|
||||
DebuggerSetColorFG( DebuggerGetColor( FG_INFO_REG ));
|
||||
PrintText( "P ", rect );
|
||||
|
||||
DebuggerSetColorBG( DebuggerGetColor( BG_INFO ));
|
||||
DebuggerSetColorFG( DebuggerGetColor( FG_INFO_OPCODE ));
|
||||
PrintText( sText, rect );
|
||||
rect.top += g_nFontHeight;
|
||||
rect.bottom += g_nFontHeight;
|
||||
|
||||
rect.top -= g_nFontHeight;
|
||||
rect.bottom -= g_nFontHeight;
|
||||
sText[1] = 0;
|
||||
sprintf( sText, "%02X", nRegFlags );
|
||||
|
||||
rect.left += ((2 + _6502_NUM_FLAGS) * nSpacerWidth);
|
||||
rect.right = rect.left + nFontWidth;
|
||||
}
|
||||
DebuggerSetColorBG( DebuggerGetColor( BG_INFO ));
|
||||
DebuggerSetColorFG( DebuggerGetColor( FG_INFO_OPCODE ));
|
||||
PrintText( sText, rect );
|
||||
|
||||
rect.top -= g_nFontHeight;
|
||||
rect.bottom -= g_nFontHeight;
|
||||
sText[1] = 0;
|
||||
|
||||
rect.left += ((2 + _6502_NUM_FLAGS) * nSpacerWidth);
|
||||
rect.right = rect.left + nFontWidth;
|
||||
|
||||
//
|
||||
|
||||
int iFlag = 0;
|
||||
int nFlag = _6502_NUM_FLAGS;
|
||||
@ -2394,45 +2377,41 @@ void DrawFlags ( int line, WORD nRegFlags, LPTSTR pFlagNames_)
|
||||
iFlag = (_6502_NUM_FLAGS - nFlag - 1);
|
||||
|
||||
bool bSet = (nRegFlags & 1);
|
||||
if (GetDebuggerMemDC()) // TC: Why would this be NULL?
|
||||
|
||||
sText[0] = g_aBreakpointSource[ BP_SRC_FLAG_C + iFlag ][0];
|
||||
|
||||
if (bSet)
|
||||
{
|
||||
sText[0] = g_aBreakpointSource[ BP_SRC_FLAG_C + iFlag ][0];
|
||||
if (bSet)
|
||||
{
|
||||
DebuggerSetColorBG( DebuggerGetColor( BG_INFO_INVERSE ));
|
||||
DebuggerSetColorFG( DebuggerGetColor( FG_INFO_INVERSE ));
|
||||
}
|
||||
else
|
||||
{
|
||||
DebuggerSetColorBG( DebuggerGetColor( BG_INFO ));
|
||||
DebuggerSetColorFG( DebuggerGetColor( FG_INFO_TITLE ));
|
||||
}
|
||||
rect.left -= nSpacerWidth;
|
||||
rect.right -= nSpacerWidth;
|
||||
PrintText( sText, rect );
|
||||
|
||||
// Print Binary value
|
||||
rect.top += g_nFontHeight;
|
||||
rect.bottom += g_nFontHeight;
|
||||
DebuggerSetColorBG( DebuggerGetColor( BG_INFO )); //
|
||||
DebuggerSetColorFG( DebuggerGetColor( FG_INFO_TITLE ));
|
||||
|
||||
sText[0] = '0' + static_cast<int>(bSet);
|
||||
PrintText( sText, rect );
|
||||
rect.top -= g_nFontHeight;
|
||||
rect.bottom -= g_nFontHeight;
|
||||
DebuggerSetColorBG( DebuggerGetColor( BG_INFO_INVERSE ));
|
||||
DebuggerSetColorFG( DebuggerGetColor( FG_INFO_INVERSE ));
|
||||
}
|
||||
else
|
||||
{
|
||||
DebuggerSetColorBG( DebuggerGetColor( BG_INFO ));
|
||||
DebuggerSetColorFG( DebuggerGetColor( FG_INFO_TITLE ));
|
||||
}
|
||||
|
||||
rect.left -= nSpacerWidth;
|
||||
rect.right -= nSpacerWidth;
|
||||
PrintText( sText, rect );
|
||||
|
||||
// Print Binary value
|
||||
rect.top += g_nFontHeight;
|
||||
rect.bottom += g_nFontHeight;
|
||||
DebuggerSetColorBG( DebuggerGetColor( BG_INFO ));
|
||||
DebuggerSetColorFG( DebuggerGetColor( FG_INFO_TITLE ));
|
||||
|
||||
sText[0] = '0' + static_cast<int>(bSet);
|
||||
PrintText( sText, rect );
|
||||
rect.top -= g_nFontHeight;
|
||||
rect.bottom -= g_nFontHeight;
|
||||
|
||||
if (pFlagNames_)
|
||||
{
|
||||
if (! bSet) //(nFlags & 1))
|
||||
{
|
||||
if (!bSet)
|
||||
sFlagNames[nFlag] = '.';
|
||||
}
|
||||
else
|
||||
{
|
||||
sFlagNames[nFlag] = g_aBreakpointSource[ BP_SRC_FLAG_C + iFlag ][0];
|
||||
}
|
||||
}
|
||||
|
||||
nRegFlags >>= 1;
|
||||
@ -2440,27 +2419,6 @@ void DrawFlags ( int line, WORD nRegFlags, LPTSTR pFlagNames_)
|
||||
|
||||
if (pFlagNames_)
|
||||
strcpy(pFlagNames_,sFlagNames);
|
||||
/*
|
||||
if (GetDebuggerMemDC()) // TC: Why would this be NULL?
|
||||
{
|
||||
rect.top += g_nFontHeight;
|
||||
rect.bottom += g_nFontHeight;
|
||||
rect.left = DISPLAY_FLAG_COLUMN;
|
||||
rect.right = rect.left + (10 * nFontWidth);
|
||||
|
||||
DebuggerSetColorFG( DebuggerGetColor( FG_INFO_REG ));
|
||||
PrintTextCursorX( "P ", rect );
|
||||
|
||||
|
||||
DebuggerSetColorBG( DebuggerGetColor( BG_INFO )); // COLOR_BG_DATA
|
||||
|
||||
DebuggerSetColorFG( DebuggerGetColor( FG_INFO_REG ));
|
||||
PrintTextCursorX( "P ", rect );
|
||||
|
||||
rect.left += (_6502_NUM_FLAGS * nSpacerWidth);
|
||||
rect.right = rect.left + nFontWidth;
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
@ -4032,9 +3990,11 @@ void UpdateDisplay (Update_t bUpdate)
|
||||
|
||||
case WINDOW_IO:
|
||||
DrawWindow_IO( bUpdate );
|
||||
break;
|
||||
|
||||
case WINDOW_SOURCE:
|
||||
DrawWindow_Source( bUpdate );
|
||||
break;
|
||||
|
||||
case WINDOW_SYMBOLS:
|
||||
DrawWindow_Symbols( bUpdate );
|
||||
@ -4042,6 +4002,7 @@ void UpdateDisplay (Update_t bUpdate)
|
||||
|
||||
case WINDOW_ZEROPAGE:
|
||||
DrawWindow_ZeroPage( bUpdate );
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
|
@ -210,8 +210,9 @@ void Help_Categories()
|
||||
void Help_Examples()
|
||||
{
|
||||
char sText[ CONSOLE_WIDTH ];
|
||||
ConsolePrintFormat( sText, " %sExamples%s:"
|
||||
ConsolePrintFormat( sText, " %sExamples%s:%s"
|
||||
, CHC_USAGE
|
||||
, CHC_ARG_SEP
|
||||
, CHC_DEFAULT
|
||||
);
|
||||
}
|
||||
@ -322,6 +323,17 @@ void _ColorizeHeader(
|
||||
pDst += nLen;
|
||||
}
|
||||
|
||||
|
||||
void _ColorizeString(
|
||||
char * & pDst,
|
||||
const char *pSrc, const size_t nLen )
|
||||
{
|
||||
strcpy( pDst, pSrc );
|
||||
pDst += nLen;
|
||||
}
|
||||
|
||||
|
||||
// pOperator is one of CHC_*
|
||||
void _ColorizeOperator(
|
||||
char * & pDst, const char * & pSrc,
|
||||
char * pOperator )
|
||||
@ -343,6 +355,18 @@ void _ColorizeOperator(
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
bool isHexDigit( char c )
|
||||
{
|
||||
if ((c >= '0') && (c <= '9')) return true;
|
||||
if ((c >= 'A') && (c <= 'F')) return true;
|
||||
if ((c >= 'a') && (c <= 'f')) return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool Colorize( char * pDst, const char * pSrc )
|
||||
{
|
||||
if (! pSrc)
|
||||
@ -363,6 +387,9 @@ bool Colorize( char * pDst, const char * pSrc )
|
||||
const char sTotal[] = "Total:";
|
||||
const int nTotal = sizeof( sTotal ) - 1;
|
||||
|
||||
const char sExamples[] = "Examples:";
|
||||
const int nExamples = sizeof( sExamples ) - 1;
|
||||
|
||||
int nLen = 0;
|
||||
while (*pSrc)
|
||||
{
|
||||
@ -386,6 +413,11 @@ bool Colorize( char * pDst, const char * pSrc )
|
||||
_ColorizeHeader( pDst, pSrc, sTotal, nTotal );
|
||||
}
|
||||
else
|
||||
if (strncmp( sExamples, pSrc, nExamples) == 0)
|
||||
{
|
||||
_ColorizeHeader( pDst, pSrc, sExamples, nExamples );
|
||||
}
|
||||
else
|
||||
if (*pSrc == '[')
|
||||
{
|
||||
_ColorizeOperator( pDst, pSrc, CHC_ARG_OPT );
|
||||
@ -416,6 +448,25 @@ bool Colorize( char * pDst, const char * pSrc )
|
||||
_ColorizeOperator( pDst, pSrc, CHC_ARG_SEP );
|
||||
}
|
||||
else
|
||||
if ((*pSrc == '$') && isHexDigit(pSrc[1])) // Hex Number
|
||||
{
|
||||
_ColorizeOperator( pDst, pSrc, CHC_ARG_SEP );
|
||||
|
||||
const char *start = pSrc;
|
||||
const char *end = pSrc;
|
||||
|
||||
while( isHexDigit( *end ) )
|
||||
end++;
|
||||
|
||||
size_t nDigits = end - start;
|
||||
|
||||
_ColorizeString( pDst, CHC_NUM_HEX, strlen( CHC_NUM_HEX ) );
|
||||
_ColorizeString( pDst, start , nDigits );
|
||||
_ColorizeString( pDst, CHC_DEFAULT, strlen( CHC_DEFAULT ) );
|
||||
|
||||
pSrc += nDigits;
|
||||
}
|
||||
else
|
||||
{
|
||||
*pDst = *pSrc;
|
||||
pDst++;
|
||||
@ -426,6 +477,7 @@ bool Colorize( char * pDst, const char * pSrc )
|
||||
return true;
|
||||
}
|
||||
|
||||
// NOTE: This appends a new line
|
||||
inline bool ConsoleColorizePrint( char* colorizeBuf, size_t /*colorizeBufSz*/,
|
||||
const char* pText )
|
||||
{
|
||||
@ -1033,10 +1085,12 @@ Update_t CmdHelpSpecific (int nArgs)
|
||||
{
|
||||
ConsoleColorizePrint( sText, " Note: All arguments effect the disassembly view" );
|
||||
|
||||
ConsoleColorizePrintFormat( sTemp, sText, " Usage: [%s%s | %s%s | %s%s | %s%s | %s%s]"
|
||||
ConsoleColorizePrintFormat( sTemp, sText, " Usage: [%s%s | %s | %s%s | %s%s | %s%s | %s%s]"
|
||||
, CHC_COMMAND
|
||||
, g_aParameters[ PARAM_CONFIG_BRANCH ].m_sName
|
||||
, CHC_COMMAND
|
||||
, g_aParameters[ PARAM_CONFIG_CLICK ].m_sName
|
||||
, CHC_COMMAND
|
||||
, g_aParameters[ PARAM_CONFIG_COLON ].m_sName
|
||||
, CHC_COMMAND
|
||||
, g_aParameters[ PARAM_CONFIG_OPCODE ].m_sName
|
||||
@ -1053,6 +1107,23 @@ Update_t CmdHelpSpecific (int nArgs)
|
||||
DISASM_BRANCH_OFF, DISASM_BRANCH_PLAIN, DISASM_BRANCH_FANCY );
|
||||
ConsolePrintFormat( sText, " i.e. %s%s %s 1", CHC_EXAMPLE, pCommand->m_sName, g_aParameters[ iParam ].m_sName );
|
||||
|
||||
iParam = PARAM_CONFIG_CLICK;
|
||||
ConsoleColorizePrintFormat( sTemp, sText, " Usage: %s [#]", g_aParameters[ iParam ].m_sName );
|
||||
ConsoleBufferPush( " Set required key combo. (Alt, Control, or Shift) when left clicking" );
|
||||
ConsoleBufferPushFormat( sText, " 0 Left-Click (no Alt, Ctrl, Shift)" );
|
||||
ConsoleBufferPushFormat( sText, " 1 Alt Left-click" );
|
||||
ConsoleBufferPushFormat( sText, " 2 Ctrl Left-click" );
|
||||
ConsoleBufferPushFormat( sText, " 3 Alt+Ctrl Left-click" );
|
||||
ConsoleBufferPushFormat( sText, " 4 Shift Left-click" );
|
||||
ConsoleBufferPushFormat( sText, " 5 Shift+Alt Left-click" );
|
||||
ConsoleBufferPushFormat( sText, " 6 Shift+Ctrl Left-click" );
|
||||
ConsoleBufferPushFormat( sText, " 7 Shift+Ctrl+Alt Left-click" );
|
||||
Help_Examples();
|
||||
ConsolePrintFormat( sText, " %s%s %s 0 // Plain Left-click" , CHC_EXAMPLE, pCommand->m_sName, g_aParameters[ iParam ].m_sName );
|
||||
ConsolePrintFormat( sText, " %s%s %s 1 // Require Alt Left-click" , CHC_EXAMPLE, pCommand->m_sName, g_aParameters[ iParam ].m_sName );
|
||||
ConsolePrintFormat( sText, " %s%s %s 2 // Require Ctrl Left-click" , CHC_EXAMPLE, pCommand->m_sName, g_aParameters[ iParam ].m_sName );
|
||||
ConsolePrintFormat( sText, " %s%s %s 3 // Require Alt+Ctrl Left-click", CHC_EXAMPLE, pCommand->m_sName, g_aParameters[ iParam ].m_sName );
|
||||
|
||||
iParam = PARAM_CONFIG_COLON;
|
||||
ConsoleColorizePrintFormat( sTemp, sText, " Usage: %s [0|1]", g_aParameters[ iParam ].m_sName );
|
||||
ConsoleBufferPush( " Display a colon after the address" );
|
||||
@ -1281,10 +1352,23 @@ Update_t CmdHelpSpecific (int nArgs)
|
||||
// Symbols
|
||||
case CMD_SYMBOLS_LOOKUP:
|
||||
ConsoleColorizePrint( sText, " Usage: symbol [= <address>]" );
|
||||
ConsolePrintFormat( sText, " %s\"%ssymbol%s\" = %saddress"
|
||||
, CHC_ARG_MAND
|
||||
, CHC_SYMBOL
|
||||
, CHC_ARG_MAND
|
||||
, CHC_ADDRESS
|
||||
);
|
||||
ConsoleColorizePrint( sText, " Note: Valid characters are any characters above ASCII space ($20)." );
|
||||
ConsolePrintFormat( sText, " You %sMUST%s double-quote names containing special characters to be recognized."
|
||||
, CHC_WARNING
|
||||
, CHC_DEFAULT
|
||||
);
|
||||
Help_Examples();
|
||||
ConsolePrintFormat( sText, "%s %s HOME" , CHC_EXAMPLE, pCommand->m_sName );
|
||||
ConsolePrintFormat( sText, "%s %s LIFE = 2000", CHC_EXAMPLE, pCommand->m_sName );
|
||||
ConsolePrintFormat( sText, "%s %s LIFE" , CHC_EXAMPLE, pCommand->m_sName );
|
||||
ConsolePrintFormat( sText, "%s %s HOME" , CHC_EXAMPLE, pCommand->m_sName );
|
||||
ConsolePrintFormat( sText, "%s %s LIFE = 2000" , CHC_EXAMPLE, pCommand->m_sName );
|
||||
ConsolePrintFormat( sText, "%s %s LIFE" , CHC_EXAMPLE, pCommand->m_sName );
|
||||
ConsolePrintFormat( sText, "%s %s \"PR#\" = FE95", CHC_EXAMPLE, pCommand->m_sName );
|
||||
ConsolePrintFormat( sText, "%s %s \"PR#\"" , CHC_EXAMPLE, pCommand->m_sName );
|
||||
break;
|
||||
case CMD_SYMBOLS_ROM:
|
||||
case CMD_SYMBOLS_APPLESOFT:
|
||||
|
@ -111,7 +111,7 @@ int _Arg_1( LPTSTR pName )
|
||||
}
|
||||
else
|
||||
{
|
||||
_tcsncpy( g_aArgs[1].sArg, pName, MAX_ARG_LEN - 1 );
|
||||
_tcsncpy( g_aArgs[1].sArg, pName, MAX_ARG_LEN );
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
@ -201,18 +201,22 @@ void ArgsClear ()
|
||||
//===========================================================================
|
||||
bool ArgsGetValue ( Arg_t *pArg, WORD * pAddressValue_, const int nBase )
|
||||
{
|
||||
_ASSERT(pArg);
|
||||
if (pArg == NULL)
|
||||
return false;
|
||||
|
||||
TCHAR *pSrc = & (pArg->sArg[ 0 ]);
|
||||
TCHAR *pEnd = NULL;
|
||||
|
||||
if (pArg && pAddressValue_)
|
||||
if (pAddressValue_)
|
||||
{
|
||||
*pAddressValue_ = (WORD)(_tcstoul( pSrc, &pEnd, nBase) & _6502_MEM_END);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
//===========================================================================
|
||||
bool ArgsGetImmediateValue ( Arg_t *pArg, WORD * pAddressValue_ )
|
||||
{
|
||||
@ -304,7 +308,11 @@ int ArgsGet ( TCHAR * pInput )
|
||||
|
||||
if (nBuf > 0)
|
||||
{
|
||||
nLen = MIN( nBuf, MAX_ARG_LEN-1 );
|
||||
// Does anyone actually "need" > 132 character output???
|
||||
// Technically, we are capped via ParseInput(), g_aArgs[ iArg ] = g_aArgRaw[ iArg ];
|
||||
//if (iTokenSrc == TOKEN_QUOTE_DOUBLE)
|
||||
// nLen = nBuf;
|
||||
nLen = MIN( nBuf, MAX_ARG_LEN ); // NOTE: see Arg_t.sArg[] // GH#481
|
||||
_tcsncpy( pArg->sArg, pSrc, nLen );
|
||||
pArg->sArg[ nLen ] = 0;
|
||||
pArg->nArgLen = nLen;
|
||||
|
@ -256,7 +256,7 @@
|
||||
|
||||
MAX_ARGS = 32, // was 40
|
||||
ARG_SYNTAX_ERROR= -1,
|
||||
MAX_ARG_LEN = 56, // was 12, extended to allow font names
|
||||
MAX_ARG_LEN = 127, // extended to allow font names, GH#481, any value is good > CONSOLE_WIDTH=80
|
||||
};
|
||||
|
||||
// NOTE: All Commands return flags of what needs to be redrawn
|
||||
@ -1259,7 +1259,7 @@ const DisasmData_t* pDisasmData; // If != NULL then bytes are marked up as data
|
||||
|
||||
struct Arg_t
|
||||
{
|
||||
char sArg[ MAX_ARG_LEN ]; // Array chars comes first, for alignment
|
||||
char sArg[ MAX_ARG_LEN+1 ]; // Array chars comes first, for alignment, GH#481 echo 55 char limit
|
||||
int nArgLen; // Needed for TextSearch "ABC\x00"
|
||||
WORD nValue ; // 2
|
||||
// WORD nVal1 ; // 2
|
||||
@ -1319,6 +1319,7 @@ const DisasmData_t* pDisasmData; // If != NULL then bytes are marked up as data
|
||||
// Disasm
|
||||
, _PARAM_CONFIG_BEGIN = _PARAM_REGS_END // Daisy Chain
|
||||
, PARAM_CONFIG_BRANCH = _PARAM_CONFIG_BEGIN // g_iConfigDisasmBranchType [0|1|2]
|
||||
, PARAM_CONFIG_CLICK // g_bConfigDisasmClick [0..7] // GH#462
|
||||
, PARAM_CONFIG_COLON // g_bConfigDisasmAddressColon [0|1]
|
||||
, PARAM_CONFIG_OPCODE // g_bConfigDisasmOpcodesView [0|1]
|
||||
, PARAM_CONFIG_POINTER // g_bConfigInfoTargetPointer [0|1]
|
||||
|
@ -34,7 +34,7 @@ const int EOL_NULL = 0;
|
||||
bool MemoryTextFile_t::Read( char *pFileName )
|
||||
{
|
||||
bool bStatus = false;
|
||||
FILE *hFile = fopen( pFileName, "rt" );
|
||||
FILE *hFile = fopen( pFileName, "rb" );
|
||||
|
||||
if (hFile)
|
||||
{
|
||||
@ -43,13 +43,10 @@ bool MemoryTextFile_t::Read( char *pFileName )
|
||||
fseek( hFile, 0, SEEK_SET );
|
||||
|
||||
m_vBuffer.reserve( nSize + 1 );
|
||||
m_vBuffer.insert( m_vBuffer.begin(), nSize+1, 0 );
|
||||
m_vBuffer.insert( m_vBuffer.begin(), nSize+1, 0 ); // NOTE: Can NOT m_vBuffer.clear(); MUST insert() _before_ using at()
|
||||
|
||||
char *pBuffer = & m_vBuffer.at(0);
|
||||
fread( (void*)pBuffer, nSize, 1, hFile );
|
||||
|
||||
m_vBuffer.push_back( EOL_NULL );
|
||||
|
||||
fclose(hFile);
|
||||
|
||||
m_bDirty = true;
|
||||
|
@ -320,14 +320,23 @@ static void ReadTrack(const int iDrive)
|
||||
|
||||
//===========================================================================
|
||||
|
||||
void DiskFlushCurrentTrack(const int iDrive)
|
||||
{
|
||||
Disk_t *pFloppy = &g_aFloppyDisk[iDrive];
|
||||
|
||||
if (pFloppy->trackimage && pFloppy->trackimagedirty)
|
||||
WriteTrack(iDrive);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
|
||||
static void RemoveDisk(const int iDrive)
|
||||
{
|
||||
Disk_t *pFloppy = &g_aFloppyDisk[iDrive];
|
||||
|
||||
if (pFloppy->imagehandle)
|
||||
{
|
||||
if (pFloppy->trackimage && pFloppy->trackimagedirty)
|
||||
WriteTrack( iDrive);
|
||||
DiskFlushCurrentTrack(iDrive);
|
||||
|
||||
ImageClose(pFloppy->imagehandle);
|
||||
pFloppy->imagehandle = NULL;
|
||||
@ -442,10 +451,7 @@ static void __stdcall DiskControlStepper(WORD, WORD address, BYTE, BYTE, ULONG u
|
||||
: MIN(nNumTracksInImage-1, fptr->phase >> 1); // (round half tracks down)
|
||||
if (newtrack != fptr->track)
|
||||
{
|
||||
if (fptr->trackimage && fptr->trackimagedirty)
|
||||
{
|
||||
WriteTrack(currdrive);
|
||||
}
|
||||
DiskFlushCurrentTrack(currdrive);
|
||||
fptr->track = newtrack;
|
||||
fptr->trackimagedata = 0;
|
||||
}
|
||||
@ -552,9 +558,6 @@ void DiskInitialize(void)
|
||||
int loop = NUM_DRIVES;
|
||||
while (loop--)
|
||||
ZeroMemory(&g_aFloppyDisk[loop], sizeof(Disk_t));
|
||||
|
||||
TCHAR imagefilename[MAX_PATH];
|
||||
_tcscpy(imagefilename,g_sProgramDir);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
@ -1333,11 +1336,12 @@ static void DiskLoadSnapshotDriveUnit(YamlLoadHelper& yamlLoadHelper, UINT unit)
|
||||
g_aFloppyDisk[unit].trackimagedata = yamlLoadHelper.LoadUint(SS_YAML_KEY_TRACK_IMAGE_DATA);
|
||||
g_aFloppyDisk[unit].trackimagedirty = yamlLoadHelper.LoadUint(SS_YAML_KEY_TRACK_IMAGE_DIRTY);
|
||||
|
||||
std::auto_ptr<BYTE> pTrack( new BYTE [NIBBLES_PER_TRACK] );
|
||||
memset(pTrack.get(), 0, NIBBLES_PER_TRACK);
|
||||
std::vector<BYTE> track;
|
||||
track.resize(NIBBLES_PER_TRACK);
|
||||
memset(&track[0], 0, track.size());
|
||||
if (yamlLoadHelper.GetSubMap(SS_YAML_KEY_TRACK_IMAGE))
|
||||
{
|
||||
yamlLoadHelper.LoadMemory(pTrack.get(), NIBBLES_PER_TRACK);
|
||||
yamlLoadHelper.LoadMemory(&track[0], NIBBLES_PER_TRACK);
|
||||
yamlLoadHelper.PopMap();
|
||||
}
|
||||
|
||||
@ -1353,7 +1357,7 @@ static void DiskLoadSnapshotDriveUnit(YamlLoadHelper& yamlLoadHelper, UINT unit)
|
||||
if (g_aFloppyDisk[unit].trackimage == NULL)
|
||||
bImageError = true;
|
||||
else
|
||||
memcpy(g_aFloppyDisk[unit].trackimage, pTrack.get(), NIBBLES_PER_TRACK);
|
||||
memcpy(g_aFloppyDisk[unit].trackimage, &track[0], NIBBLES_PER_TRACK);
|
||||
}
|
||||
|
||||
if (bImageError)
|
||||
|
@ -47,6 +47,7 @@ void DiskDestroy(void); // no, doesn't "destroy" the disk image. DiskIIManag
|
||||
|
||||
void DiskBoot(void);
|
||||
void DiskEject(const int iDrive);
|
||||
void DiskFlushCurrentTrack(const int iDrive);
|
||||
|
||||
LPCTSTR DiskGetFullName(const int iDrive);
|
||||
LPCTSTR DiskGetFullDiskFilename(const int iDrive);
|
||||
|
@ -192,9 +192,6 @@ bool CImageBase::WriteBlock(ImageInfo* pImageInfo, const int nBlock, LPBYTE pBlo
|
||||
// Horribly inefficient! (Unzip to a normal file if you want better performance!)
|
||||
const UINT uNewImageSize = Offset+HD_BLOCK_SIZE;
|
||||
BYTE* pNewImageBuffer = new BYTE [uNewImageSize];
|
||||
_ASSERT(pNewImageBuffer);
|
||||
if (!pNewImageBuffer)
|
||||
return false;
|
||||
|
||||
memcpy(pNewImageBuffer, pImageInfo->pImageBuffer, pImageInfo->uImageSize);
|
||||
memset(&pNewImageBuffer[pImageInfo->uImageSize], 0, uNewImageSize-pImageInfo->uImageSize); // Should always be HD_BLOCK_SIZE (so this is redundant)
|
||||
@ -1153,8 +1150,6 @@ ImageError_e CImageHelperBase::CheckGZipFile(LPCTSTR pszImageFilename, ImageInfo
|
||||
|
||||
const UINT MAX_UNCOMPRESSED_SIZE = GetMaxImageSize() + 1; // +1 to detect images that are too big
|
||||
pImageInfo->pImageBuffer = new BYTE[MAX_UNCOMPRESSED_SIZE];
|
||||
if (!pImageInfo->pImageBuffer)
|
||||
return eIMAGE_ERROR_BAD_POINTER;
|
||||
|
||||
int nLen = gzread(hGZFile, pImageInfo->pImageBuffer, MAX_UNCOMPRESSED_SIZE);
|
||||
if (nLen < 0 || nLen == MAX_UNCOMPRESSED_SIZE)
|
||||
@ -1222,8 +1217,6 @@ ImageError_e CImageHelperBase::CheckZipFile(LPCTSTR pszImageFilename, ImageInfo*
|
||||
return eIMAGE_ERROR_BAD_SIZE;
|
||||
|
||||
pImageInfo->pImageBuffer = new BYTE[uFileSize];
|
||||
if (!pImageInfo->pImageBuffer)
|
||||
return eIMAGE_ERROR_BAD_POINTER;
|
||||
|
||||
nRes = unzOpenCurrentFile(hZipFile);
|
||||
if (nRes != UNZ_OK)
|
||||
@ -1352,8 +1345,6 @@ ImageError_e CImageHelperBase::CheckNormalFile(LPCTSTR pszImageFilename, ImageIn
|
||||
const UINT uDetectSize = GetMinDetectSize(dwSize, &bTempDetectBuffer);
|
||||
|
||||
pImageInfo->pImageBuffer = new BYTE [dwSize];
|
||||
if (!pImageInfo->pImageBuffer)
|
||||
return eIMAGE_ERROR_BAD_POINTER;
|
||||
|
||||
DWORD dwBytesRead;
|
||||
BOOL bRes = ReadFile(hFile, pImageInfo->pImageBuffer, dwSize, &dwBytesRead, NULL);
|
||||
@ -1377,9 +1368,6 @@ ImageError_e CImageHelperBase::CheckNormalFile(LPCTSTR pszImageFilename, ImageIn
|
||||
if (pImageType && dwSize)
|
||||
{
|
||||
pImageInfo->pImageBuffer = new BYTE [dwSize];
|
||||
if (!pImageInfo->pImageBuffer)
|
||||
return eIMAGE_ERROR_BAD_POINTER;
|
||||
|
||||
ZeroMemory(pImageInfo->pImageBuffer, dwSize);
|
||||
}
|
||||
}
|
||||
|
671
source/Frame.cpp
@ -6,39 +6,9 @@
|
||||
// Keyboard -- keystroke type
|
||||
enum {NOT_ASCII=0, ASCII};
|
||||
|
||||
// 3D Border
|
||||
#define VIEWPORTX 5
|
||||
#define VIEWPORTY 5
|
||||
|
||||
// 560 = Double Hi-Res
|
||||
// 384 = Double Scan Line
|
||||
#define FRAMEBUFFER_BORDERLESS_W 560
|
||||
#define FRAMEBUFFER_BORDERLESS_H 384
|
||||
// NTSC_BEGIN
|
||||
#if 0
|
||||
// TC: No good as NTSC render code writes to border area:
|
||||
// . NTSC.cpp: updateVideoScannerHorzEOL(): "NOTE: This writes out-of-bounds for a 560x384 framebuffer"
|
||||
#define BORDER_W 0
|
||||
#define BORDER_H 0
|
||||
#define FRAMEBUFFER_W FRAMEBUFFER_BORDERLESS_W
|
||||
#define FRAMEBUFFER_H FRAMEBUFFER_BORDERLESS_H
|
||||
#else
|
||||
#define BORDER_W 20
|
||||
#define BORDER_H 18
|
||||
#define FRAMEBUFFER_W (FRAMEBUFFER_BORDERLESS_W + BORDER_W*2)
|
||||
#define FRAMEBUFFER_H (FRAMEBUFFER_BORDERLESS_H + BORDER_H*2)
|
||||
#endif
|
||||
// NTSC_END
|
||||
|
||||
// Direct Draw -- For Full Screen
|
||||
extern LPDIRECTDRAW g_pDD;
|
||||
extern LPDIRECTDRAWSURFACE g_pDDPrimarySurface;
|
||||
extern int g_nDDFullScreenW;
|
||||
extern int g_nDDFullScreenH;
|
||||
|
||||
// Win32
|
||||
extern HWND g_hFrameWindow;
|
||||
extern BOOL g_bIsFullScreen;
|
||||
extern int g_nViewportCX;
|
||||
extern int g_nViewportCY;
|
||||
extern BOOL g_bConfirmReboot; // saved PageConfig REGSAVE
|
||||
@ -57,18 +27,19 @@
|
||||
|
||||
void FrameCreateWindow(void);
|
||||
HDC FrameGetDC ();
|
||||
HDC FrameGetVideoDC (LPBYTE *,LONG *);
|
||||
void FrameReleaseDC ();
|
||||
void FrameRefreshStatus (int, bool bUpdateDiskStatus = true );
|
||||
void FrameRegisterClass ();
|
||||
void FrameReleaseDC ();
|
||||
void FrameReleaseVideoDC ();
|
||||
void FrameSetCursorPosByMousePos();
|
||||
int GetViewportScale(void);
|
||||
int SetViewportScale(int nNewScale, bool bForce = false);
|
||||
void GetViewportCXCY(int& nViewportCX, int& nViewportCY);
|
||||
bool GetFullScreen32Bit(void);
|
||||
void SetFullScreen32Bit(bool b32Bit);
|
||||
void FrameUpdateApple2Type(void);
|
||||
bool GetBestDisplayResolutionForFullScreen(UINT& bestWidth, UINT& bestHeight, UINT userSpecifiedHeight=0);
|
||||
|
||||
bool IsFullScreen(void);
|
||||
bool GetFullScreenShowSubunitStatus(void);
|
||||
void SetFullScreenShowSubunitStatus(bool bShow);
|
||||
|
||||
void FrameDrawDiskLEDS( HDC hdc );
|
||||
void FrameDrawDiskStatus( HDC hdc );
|
||||
@ -81,3 +52,12 @@
|
||||
|
||||
int GetFullScreenOffsetX(void);
|
||||
int GetFullScreenOffsetY(void);
|
||||
|
||||
UINT GetFrameBufferBorderlessWidth(void);
|
||||
UINT GetFrameBufferBorderlessHeight(void);
|
||||
UINT GetFrameBufferBorderWidth(void);
|
||||
UINT GetFrameBufferBorderHeight(void);
|
||||
UINT GetFrameBufferWidth(void);
|
||||
UINT GetFrameBufferHeight(void);
|
||||
UINT Get3DBorderWidth(void);
|
||||
UINT Get3DBorderHeight(void);
|
||||
|
@ -289,6 +289,15 @@ static LPCTSTR HD_DiskGetBaseName(const int iDrive) // Not used
|
||||
return g_HardDisk[iDrive].imagename;
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------
|
||||
|
||||
void HD_Reset(void)
|
||||
{
|
||||
g_HardDisk[HARDDISK_1].hd_error = 0;
|
||||
g_HardDisk[HARDDISK_2].hd_error = 0;
|
||||
}
|
||||
|
||||
//-------------------------------------
|
||||
|
||||
void HD_Load_Rom(const LPBYTE pCxRomPeripheral, const UINT uSlot)
|
||||
|
@ -35,6 +35,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
void HD_SetEnabled(const bool bEnabled);
|
||||
LPCTSTR HD_GetFullName(const int iDrive);
|
||||
LPCTSTR HD_GetFullPathName(const int iDrive);
|
||||
void HD_Reset(void);
|
||||
void HD_Load_Rom(const LPBYTE pCxRomPeripheral, const UINT uSlot);
|
||||
bool HD_Select(const int iDrive);
|
||||
void HD_Unplug(const int iDrive);
|
||||
|
@ -36,10 +36,6 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
#include "YamlHelper.h"
|
||||
#include "Video.h" // Needed by TK3000 //e, to refresh the frame at each |Mode| change
|
||||
|
||||
static bool g_bKeybBufferEnable = false;
|
||||
|
||||
#define KEY_OLD
|
||||
|
||||
static BYTE asciicode[2][10] = {
|
||||
{0x08,0x0D,0x15,0x2F,0x00,0x00,0x00,0x00,0x00,0x00},
|
||||
{0x08,0x0B,0x15,0x0A,0x00,0x00,0x00,0x00,0x00,0x7F}
|
||||
@ -56,26 +52,7 @@ static bool g_bP8CapsLock = true; //Caps lock key of Pravets 8A/C
|
||||
static int lastvirtkey = 0; // Current PC keycode
|
||||
static BYTE keycode = 0; // Current Apple keycode
|
||||
|
||||
#ifdef KEY_OLD
|
||||
// Original
|
||||
static BOOL keywaiting = 0;
|
||||
#else
|
||||
// Buffered key input:
|
||||
// - Needed on faster PCs where aliasing occurs during short/fast bursts of 6502 code.
|
||||
// - Keyboard only sampled during 6502 execution, so if it's run too fast then key presses will be missed.
|
||||
const int KEY_BUFFER_MIN_SIZE = 1;
|
||||
const int KEY_BUFFER_MAX_SIZE = 2;
|
||||
static int g_nKeyBufferSize = KEY_BUFFER_MAX_SIZE; // Circ key buffer size
|
||||
static int g_nNextInIdx = 0;
|
||||
static int g_nNextOutIdx = 0;
|
||||
static int g_nKeyBufferCnt = 0;
|
||||
|
||||
static struct
|
||||
{
|
||||
int nVirtKey;
|
||||
BYTE nAppleKey;
|
||||
} g_nKeyBuffer[KEY_BUFFER_MAX_SIZE];
|
||||
#endif
|
||||
|
||||
static BYTE g_nLastKey = 0x00;
|
||||
|
||||
@ -87,34 +64,9 @@ static BYTE g_nLastKey = 0x00;
|
||||
|
||||
void KeybReset()
|
||||
{
|
||||
#ifdef KEY_OLD
|
||||
keywaiting = 0;
|
||||
#else
|
||||
g_nNextInIdx = 0;
|
||||
g_nNextOutIdx = 0;
|
||||
g_nKeyBufferCnt = 0;
|
||||
g_nLastKey = 0x00;
|
||||
|
||||
g_nKeyBufferSize = g_bKeybBufferEnable ? KEY_BUFFER_MAX_SIZE : KEY_BUFFER_MIN_SIZE;
|
||||
#endif
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
|
||||
//void KeybSetBufferMode(bool bNewKeybBufferEnable)
|
||||
//{
|
||||
// if(g_bKeybBufferEnable == bNewKeybBufferEnable)
|
||||
// return;
|
||||
//
|
||||
// g_bKeybBufferEnable = bNewKeybBufferEnable;
|
||||
// KeybReset();
|
||||
//}
|
||||
//
|
||||
//bool KeybGetBufferMode()
|
||||
//{
|
||||
// return g_bKeybBufferEnable;
|
||||
//}
|
||||
|
||||
//===========================================================================
|
||||
bool KeybGetAltStatus ()
|
||||
{
|
||||
@ -329,9 +281,6 @@ void KeybQueueKeypress (int key, BOOL bASCII)
|
||||
// Note: VK_CANCEL is Control-Break
|
||||
if ((key == VK_CANCEL) && (GetKeyState(VK_CONTROL) < 0))
|
||||
{
|
||||
#ifndef KEY_OLD
|
||||
g_nNextInIdx = g_nNextOutIdx = g_nKeyBufferCnt = 0;
|
||||
#endif
|
||||
g_bFreshReset = true;
|
||||
CtrlReset();
|
||||
return;
|
||||
@ -360,23 +309,8 @@ void KeybQueueKeypress (int key, BOOL bASCII)
|
||||
keycode = asciicode[IS_APPLE2 ? 0 : 1][key - VK_LEFT]; // Convert to Apple arrow keycode
|
||||
lastvirtkey = key;
|
||||
}
|
||||
#ifdef KEY_OLD
|
||||
|
||||
keywaiting = 1;
|
||||
#else
|
||||
bool bOverflow = false;
|
||||
|
||||
if(g_nKeyBufferCnt < g_nKeyBufferSize)
|
||||
g_nKeyBufferCnt++;
|
||||
else
|
||||
bOverflow = true;
|
||||
|
||||
g_nKeyBuffer[g_nNextInIdx].nVirtKey = lastvirtkey;
|
||||
g_nKeyBuffer[g_nNextInIdx].nAppleKey = keycode;
|
||||
g_nNextInIdx = (g_nNextInIdx + 1) % g_nKeyBufferSize;
|
||||
|
||||
if(bOverflow)
|
||||
g_nNextOutIdx = (g_nNextOutIdx + 1) % g_nKeyBufferSize;
|
||||
#endif
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
@ -472,21 +406,7 @@ BYTE __stdcall KeybReadData (WORD, WORD, BYTE, BYTE, ULONG)
|
||||
|
||||
//
|
||||
|
||||
#ifdef KEY_OLD
|
||||
return keycode | (keywaiting ? 0x80 : 0);
|
||||
#else
|
||||
BYTE nKey = g_nKeyBufferCnt ? 0x80 : 0;
|
||||
if(g_nKeyBufferCnt)
|
||||
{
|
||||
nKey |= g_nKeyBuffer[g_nNextOutIdx].nAppleKey;
|
||||
g_nLastKey = g_nKeyBuffer[g_nNextOutIdx].nAppleKey;
|
||||
}
|
||||
else
|
||||
{
|
||||
nKey |= g_nLastKey;
|
||||
}
|
||||
return nKey;
|
||||
#endif
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
@ -506,19 +426,9 @@ BYTE __stdcall KeybReadFlag (WORD, WORD, BYTE, BYTE, ULONG)
|
||||
|
||||
//
|
||||
|
||||
#ifdef KEY_OLD
|
||||
keywaiting = 0;
|
||||
|
||||
return keycode | ((GetKeyState(lastvirtkey) < 0) ? 0x80 : 0);
|
||||
#else
|
||||
BYTE nKey = (GetKeyState(g_nKeyBuffer[g_nNextOutIdx].nVirtKey) < 0) ? 0x80 : 0;
|
||||
nKey |= g_nKeyBuffer[g_nNextOutIdx].nAppleKey;
|
||||
if(g_nKeyBufferCnt)
|
||||
{
|
||||
g_nKeyBufferCnt--;
|
||||
g_nNextOutIdx = (g_nNextOutIdx + 1) % g_nKeyBufferSize;
|
||||
}
|
||||
return nKey;
|
||||
#endif
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
|
@ -534,12 +534,16 @@ static bool IsCardInSlot(const UINT uSlot);
|
||||
// 1 0 internal internal
|
||||
// 1 1 internal internal
|
||||
//
|
||||
// NB. if (INTCXROM || INTC8ROM) == true then internal ROM
|
||||
//
|
||||
// (*) SLOTCXROM'
|
||||
// -----------
|
||||
//
|
||||
// INTC8ROM: Unreadable soft switch (UTAIIe:5-28)
|
||||
// . Set: Access to $C3XX with SLOTC3ROM reset
|
||||
// . Reset: Access to $CFFF or an MMU reset
|
||||
// . Set: On access to $C3XX with SLOTC3ROM reset
|
||||
// - "From this point, $C800-$CFFF will stay assigned to motherboard ROM until
|
||||
// an access is made to $CFFF or until the MMU detects a system reset."
|
||||
// . Reset: On access to $CFFF or an MMU reset
|
||||
//
|
||||
|
||||
static BYTE __stdcall IO_Cxxx(WORD programcounter, WORD address, BYTE write, BYTE value, ULONG nCyclesLeft)
|
||||
@ -909,6 +913,7 @@ static void UpdatePaging(BOOL initialize)
|
||||
|
||||
for (loop = 0xC0; loop < 0xC8; loop++)
|
||||
{
|
||||
memdirty[loop] = 0; // ROM can't be dirty
|
||||
const UINT uSlotOffset = (loop & 0x0f) * 0x100;
|
||||
if (loop == 0xC3)
|
||||
memshadow[loop] = (SW_SLOTC3ROM && SW_SLOTCXROM) ? pCxRomPeripheral+uSlotOffset // C300..C3FF - Slot 3 ROM (all 0x00's)
|
||||
@ -920,8 +925,10 @@ static void UpdatePaging(BOOL initialize)
|
||||
|
||||
for (loop = 0xC8; loop < 0xD0; loop++)
|
||||
{
|
||||
memdirty[loop] = 0; // ROM can't be dirty (but STA $CFFF will set the dirty flag)
|
||||
const UINT uRomOffset = (loop & 0x0f) * 0x100;
|
||||
memshadow[loop] = pCxRomInternal+uRomOffset; // C800..CFFF - Internal ROM
|
||||
memshadow[loop] = (SW_SLOTCXROM && !INTC8ROM) ? pCxRomPeripheral+uRomOffset // C800..CFFF - Peripheral ROM (GH#486)
|
||||
: pCxRomInternal+uRomOffset; // C800..CFFF - Internal ROM
|
||||
}
|
||||
|
||||
for (loop = 0xD0; loop < 0xE0; loop++)
|
||||
@ -1430,6 +1437,21 @@ void MemInitializeIO(void)
|
||||
IoHandlerCardsOut();
|
||||
}
|
||||
|
||||
// Called by:
|
||||
// . Snapshot_LoadState_v2()
|
||||
void MemInitializeCardExpansionRomFromSnapshot(void)
|
||||
{
|
||||
const UINT uSlot = g_uPeripheralRomSlot;
|
||||
|
||||
if (ExpansionRom[uSlot] == NULL)
|
||||
return;
|
||||
|
||||
_ASSERT(g_eExpansionRomType == eExpRomPeripheral);
|
||||
|
||||
memcpy(pCxRomPeripheral+0x800, ExpansionRom[uSlot], FIRMWARE_EXPANSION_SIZE);
|
||||
// NB. Copied to /mem/ by UpdatePaging(TRUE)
|
||||
}
|
||||
|
||||
inline DWORD getRandomTime()
|
||||
{
|
||||
return rand() ^ timeGetTime(); // We can't use g_nCumulativeCycles as it will be zero on a fresh execution.
|
||||
@ -1950,6 +1972,7 @@ bool MemLoadSnapshot(YamlLoadHelper& yamlLoadHelper)
|
||||
modechanging = 0;
|
||||
// NB. MemUpdatePaging(TRUE) called at end of Snapshot_LoadState_v2()
|
||||
UpdatePaging(1); // Initialize=1 (Still needed, even with call to MemUpdatePaging() - why?)
|
||||
// TC-TODO: At this point, the cards haven't been loaded, so the card's expansion ROM is unknown - so pointless(?) calling this now
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -84,6 +84,7 @@ void MemInitialize ();
|
||||
void MemInitializeROM(void);
|
||||
void MemInitializeCustomF8ROM(void);
|
||||
void MemInitializeIO(void);
|
||||
void MemInitializeCardExpansionRomFromSnapshot(void);
|
||||
BYTE MemReadFloatingBus(const ULONG uExecutedCycles);
|
||||
BYTE MemReadFloatingBus(const BYTE highbit, const ULONG uExecutedCycles);
|
||||
void MemReset ();
|
||||
|
@ -117,13 +117,17 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
#define Phasor_SY6522A_Offset (1<<Phasor_SY6522A_CS)
|
||||
#define Phasor_SY6522B_Offset (1<<Phasor_SY6522B_CS)
|
||||
|
||||
enum MockingboardUnitState_e {AY_NOP0, AY_NOP1, AY_INACTIVE, AY_READ, AY_NOP4, AY_NOP5, AY_WRITE, AY_LATCH};
|
||||
|
||||
struct SY6522_AY8910
|
||||
{
|
||||
SY6522 sy6522;
|
||||
BYTE nAY8910Number;
|
||||
BYTE nAYCurrentRegister;
|
||||
BYTE nTimerStatus;
|
||||
bool bTimer1Active;
|
||||
bool bTimer2Active;
|
||||
SSI263A SpeechChip;
|
||||
MockingboardUnitState_e state; // Where a unit is a 6522+AY8910 pair (or for Phasor: 6522+2xAY8910)
|
||||
};
|
||||
|
||||
|
||||
@ -152,8 +156,8 @@ static SY6522_AY8910 g_MB[NUM_AY8910];
|
||||
|
||||
// Timer vars
|
||||
static ULONG g_n6522TimerPeriod = 0;
|
||||
static const UINT TIMERDEVICE_INVALID = -1;
|
||||
static UINT g_nMBTimerDevice = TIMERDEVICE_INVALID; // SY6522 device# which is generating timer IRQ
|
||||
static const UINT kTIMERDEVICE_INVALID = -1;
|
||||
static UINT g_nMBTimerDevice = kTIMERDEVICE_INVALID; // SY6522 device# which is generating timer IRQ
|
||||
static UINT64 g_uLastCumulativeCycles = 0;
|
||||
|
||||
// SSI263 vars:
|
||||
@ -203,51 +207,65 @@ static DWORD g_dwMaxPhonemeLen = 0;
|
||||
// When 6522 IRQ is *not* active use 60Hz update freq for MB voices
|
||||
static const double g_f6522TimerPeriod_NoIRQ = CLK_6502 / 60.0; // Constant whatever the CLK is set to
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
// External global vars:
|
||||
bool g_bMBTimerIrqActive = false;
|
||||
#ifdef _DEBUG
|
||||
UINT32 g_uTimer1IrqCount = 0; // DEBUG
|
||||
#endif
|
||||
static bool g_bCritSectionValid = false; // Deleting CritialSection when not valid causes crash on Win98
|
||||
static CRITICAL_SECTION g_CriticalSection; // To guard 6522's IFR
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
// Forward refs:
|
||||
static DWORD WINAPI SSI263Thread(LPVOID);
|
||||
static void Votrax_Write(BYTE nDevice, BYTE nValue);
|
||||
static double MB_GetFramePeriod(void);
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
static void StartTimer(SY6522_AY8910* pMB)
|
||||
static void StartTimer1(SY6522_AY8910* pMB)
|
||||
{
|
||||
// if((pMB->nAY8910Number & 1) != SY6522_DEVICE_A)
|
||||
// return;
|
||||
|
||||
if((pMB->sy6522.IER & IxR_TIMER1) == 0x00)
|
||||
return;
|
||||
|
||||
USHORT nPeriod = pMB->sy6522.TIMER1_LATCH.w;
|
||||
|
||||
// if(nPeriod <= 0xff) // Timer1L value has been written (but TIMER1H hasn't)
|
||||
// return;
|
||||
|
||||
pMB->nTimerStatus = 1;
|
||||
pMB->bTimer1Active = true;
|
||||
|
||||
// 6522 CLK runs at same speed as 6502 CLK
|
||||
g_n6522TimerPeriod = nPeriod;
|
||||
g_n6522TimerPeriod = pMB->sy6522.TIMER1_LATCH.w;
|
||||
|
||||
if (pMB->sy6522.IER & IxR_TIMER1) // Using 6522 interrupt
|
||||
g_nMBTimerDevice = pMB->nAY8910Number;
|
||||
else if (pMB->sy6522.ACR & RM_FREERUNNING) // Polling 6522 IFR
|
||||
g_nMBTimerDevice = pMB->nAY8910Number;
|
||||
}
|
||||
|
||||
// The assumption was that timer1 was only active if IER.TIMER1=1
|
||||
// . Not true, since IFR can be polled (with IER.TIMER1=0)
|
||||
static void StartTimer1_LoadStateV1(SY6522_AY8910* pMB)
|
||||
{
|
||||
if ((pMB->sy6522.IER & IxR_TIMER1) == 0x00)
|
||||
return;
|
||||
|
||||
pMB->bTimer1Active = true;
|
||||
|
||||
// 6522 CLK runs at same speed as 6502 CLK
|
||||
g_n6522TimerPeriod = pMB->sy6522.TIMER1_LATCH.w;
|
||||
|
||||
g_bMBTimerIrqActive = true;
|
||||
g_nMBTimerDevice = pMB->nAY8910Number;
|
||||
}
|
||||
|
||||
static void StopTimer1(SY6522_AY8910* pMB)
|
||||
{
|
||||
pMB->bTimer1Active = false;
|
||||
g_nMBTimerDevice = kTIMERDEVICE_INVALID;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
static void StopTimer(SY6522_AY8910* pMB)
|
||||
static void StartTimer2(SY6522_AY8910* pMB)
|
||||
{
|
||||
pMB->nTimerStatus = 0;
|
||||
g_bMBTimerIrqActive = false;
|
||||
g_nMBTimerDevice = TIMERDEVICE_INVALID;
|
||||
pMB->bTimer2Active = true;
|
||||
|
||||
// NB. Can't mimic StartTimer1() as that would stomp on global state
|
||||
// TODO: Switch to per-device state
|
||||
}
|
||||
|
||||
static void StopTimer2(SY6522_AY8910* pMB)
|
||||
{
|
||||
pMB->bTimer2Active = false;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -256,10 +274,11 @@ static void ResetSY6522(SY6522_AY8910* pMB)
|
||||
{
|
||||
memset(&pMB->sy6522,0,sizeof(SY6522));
|
||||
|
||||
if(pMB->nTimerStatus)
|
||||
StopTimer(pMB);
|
||||
StopTimer1(pMB);
|
||||
StopTimer2(pMB);
|
||||
|
||||
pMB->nAYCurrentRegister = 0;
|
||||
pMB->state = AY_INACTIVE;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -269,7 +288,7 @@ static void AY8910_Write(BYTE nDevice, BYTE nReg, BYTE nValue, BYTE nAYDevice)
|
||||
g_bMB_RegAccessedFlag = true;
|
||||
SY6522_AY8910* pMB = &g_MB[nDevice];
|
||||
|
||||
if((nValue & 4) == 0)
|
||||
if ((nValue & 4) == 0)
|
||||
{
|
||||
// RESET: Reset AY8910 only
|
||||
AY8910_reset(nDevice+2*nAYDevice);
|
||||
@ -281,45 +300,59 @@ static void AY8910_Write(BYTE nDevice, BYTE nReg, BYTE nValue, BYTE nAYDevice)
|
||||
const int nBC2 = 1; // Hardwired to +5V
|
||||
int nBC1 = nValue & 1;
|
||||
|
||||
int nAYFunc = (nBDIR<<2) | (nBC2<<1) | nBC1;
|
||||
enum {AY_NOP0, AY_NOP1, AY_INACTIVE, AY_READ, AY_NOP4, AY_NOP5, AY_WRITE, AY_LATCH};
|
||||
MockingboardUnitState_e nAYFunc = (MockingboardUnitState_e) ((nBDIR<<2) | (nBC2<<1) | nBC1);
|
||||
|
||||
switch(nAYFunc)
|
||||
if (pMB->state == AY_INACTIVE) // GH#320: functions only work from inactive state
|
||||
{
|
||||
case AY_INACTIVE: // 4: INACTIVE
|
||||
break;
|
||||
switch (nAYFunc)
|
||||
{
|
||||
case AY_INACTIVE: // 4: INACTIVE
|
||||
break;
|
||||
|
||||
case AY_READ: // 5: READ FROM PSG (need to set DDRA to input)
|
||||
break;
|
||||
case AY_READ: // 5: READ FROM PSG (need to set DDRA to input)
|
||||
break;
|
||||
|
||||
case AY_WRITE: // 6: WRITE TO PSG
|
||||
_AYWriteReg(nDevice+2*nAYDevice, pMB->nAYCurrentRegister, pMB->sy6522.ORA);
|
||||
break;
|
||||
case AY_WRITE: // 6: WRITE TO PSG
|
||||
_AYWriteReg(nDevice+2*nAYDevice, pMB->nAYCurrentRegister, pMB->sy6522.ORA);
|
||||
break;
|
||||
|
||||
case AY_LATCH: // 7: LATCH ADDRESS
|
||||
// http://www.worldofspectrum.org/forums/showthread.php?t=23327
|
||||
// Selecting an unused register number above 0x0f puts the AY into a state where
|
||||
// any values written to the data/address bus are ignored, but can be read back
|
||||
// within a few tens of thousands of cycles before they decay to zero.
|
||||
if(pMB->sy6522.ORA <= 0x0F)
|
||||
pMB->nAYCurrentRegister = pMB->sy6522.ORA & 0x0F;
|
||||
// else Pro-Mockingboard (clone from HK)
|
||||
break;
|
||||
case AY_LATCH: // 7: LATCH ADDRESS
|
||||
// http://www.worldofspectrum.org/forums/showthread.php?t=23327
|
||||
// Selecting an unused register number above 0x0f puts the AY into a state where
|
||||
// any values written to the data/address bus are ignored, but can be read back
|
||||
// within a few tens of thousands of cycles before they decay to zero.
|
||||
if(pMB->sy6522.ORA <= 0x0F)
|
||||
pMB->nAYCurrentRegister = pMB->sy6522.ORA & 0x0F;
|
||||
// else Pro-Mockingboard (clone from HK)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
pMB->state = nAYFunc;
|
||||
}
|
||||
}
|
||||
|
||||
static void UpdateIFR(SY6522_AY8910* pMB)
|
||||
static void UpdateIFR(SY6522_AY8910* pMB, BYTE clr_ifr, BYTE set_ifr=0)
|
||||
{
|
||||
pMB->sy6522.IFR &= 0x7F;
|
||||
// Need critical section to avoid data-race: main thread & SSI263Thread can both access IFR
|
||||
// . NB. Loading a save-state just directly writes into 6522.IFR (which is fine)
|
||||
_ASSERT(g_bCritSectionValid);
|
||||
if (g_bCritSectionValid) EnterCriticalSection(&g_CriticalSection);
|
||||
{
|
||||
pMB->sy6522.IFR &= ~clr_ifr;
|
||||
pMB->sy6522.IFR |= set_ifr;
|
||||
|
||||
if(pMB->sy6522.IFR & pMB->sy6522.IER & 0x7F)
|
||||
pMB->sy6522.IFR |= 0x80;
|
||||
if (pMB->sy6522.IFR & pMB->sy6522.IER & 0x7F)
|
||||
pMB->sy6522.IFR |= 0x80;
|
||||
else
|
||||
pMB->sy6522.IFR &= 0x7F;
|
||||
}
|
||||
if (g_bCritSectionValid) LeaveCriticalSection(&g_CriticalSection);
|
||||
|
||||
// Now update the IRQ signal from all 6522s
|
||||
// . OR-sum of all active TIMER1, TIMER2 & SPEECH sources (from all 6522s)
|
||||
UINT bIRQ = 0;
|
||||
for(UINT i=0; i<NUM_SY6522; i++)
|
||||
for (UINT i=0; i<NUM_SY6522; i++)
|
||||
bIRQ |= g_MB[i].sy6522.IFR & 0x80;
|
||||
|
||||
// NB. Mockingboard generates IRQ on both 6522s:
|
||||
@ -329,13 +362,9 @@ static void UpdateIFR(SY6522_AY8910* pMB)
|
||||
// . I assume Phasor's 6522s just generate 6502 IRQs (not NMIs)
|
||||
|
||||
if (bIRQ)
|
||||
{
|
||||
CpuIrqAssert(IS_6522);
|
||||
}
|
||||
else
|
||||
{
|
||||
CpuIrqDeassert(IS_6522);
|
||||
}
|
||||
}
|
||||
|
||||
static void SY6522_Write(BYTE nDevice, BYTE nReg, BYTE nValue)
|
||||
@ -392,30 +421,29 @@ static void SY6522_Write(BYTE nDevice, BYTE nReg, BYTE nValue)
|
||||
/* Initiates timer1 & clears time-out of timer1 */
|
||||
|
||||
// Clear Timer Interrupt Flag.
|
||||
pMB->sy6522.IFR &= ~IxR_TIMER1;
|
||||
UpdateIFR(pMB);
|
||||
UpdateIFR(pMB, IxR_TIMER1);
|
||||
|
||||
pMB->sy6522.TIMER1_LATCH.h = nValue;
|
||||
pMB->sy6522.TIMER1_COUNTER.w = pMB->sy6522.TIMER1_LATCH.w;
|
||||
|
||||
StartTimer(pMB);
|
||||
StartTimer1(pMB);
|
||||
break;
|
||||
case 0x07: // TIMER1H_LATCH
|
||||
// Clear Timer1 Interrupt Flag.
|
||||
UpdateIFR(pMB, IxR_TIMER1);
|
||||
pMB->sy6522.TIMER1_LATCH.h = nValue;
|
||||
pMB->sy6522.IFR &= ~IxR_TIMER1;
|
||||
UpdateIFR(pMB);
|
||||
break;
|
||||
case 0x08: // TIMER2L
|
||||
pMB->sy6522.TIMER2_LATCH.l = nValue;
|
||||
break;
|
||||
case 0x09: // TIMER2H
|
||||
// Clear Timer2 Interrupt Flag.
|
||||
pMB->sy6522.IFR &= ~IxR_TIMER2;
|
||||
UpdateIFR(pMB);
|
||||
UpdateIFR(pMB, IxR_TIMER2);
|
||||
|
||||
pMB->sy6522.TIMER2_LATCH.h = nValue;
|
||||
pMB->sy6522.TIMER2_COUNTER.w = pMB->sy6522.TIMER2_LATCH.w;
|
||||
|
||||
StartTimer2(pMB);
|
||||
break;
|
||||
case 0x0a: // SERIAL_SHIFT
|
||||
break;
|
||||
@ -428,10 +456,7 @@ static void SY6522_Write(BYTE nDevice, BYTE nReg, BYTE nValue)
|
||||
case 0x0d: // IFR
|
||||
// - Clear those bits which are set in the lower 7 bits.
|
||||
// - Can't clear bit 7 directly.
|
||||
nValue |= 0x80; // Set high bit
|
||||
nValue ^= 0x7F; // Make mask
|
||||
pMB->sy6522.IFR &= nValue;
|
||||
UpdateIFR(pMB);
|
||||
UpdateIFR(pMB, nValue);
|
||||
break;
|
||||
case 0x0e: // IER
|
||||
if(!(nValue & 0x80))
|
||||
@ -439,25 +464,28 @@ static void SY6522_Write(BYTE nDevice, BYTE nReg, BYTE nValue)
|
||||
// Clear those bits which are set in the lower 7 bits.
|
||||
nValue ^= 0x7F;
|
||||
pMB->sy6522.IER &= nValue;
|
||||
UpdateIFR(pMB);
|
||||
UpdateIFR(pMB, 0);
|
||||
|
||||
// Check if timer has been disabled.
|
||||
if(pMB->sy6522.IER & IxR_TIMER1)
|
||||
break;
|
||||
// Check if active timer has been disabled:
|
||||
if (((pMB->sy6522.IER & IxR_TIMER1) == 0) && pMB->bTimer1Active)
|
||||
StopTimer1(pMB);
|
||||
|
||||
if(pMB->nTimerStatus == 0)
|
||||
break;
|
||||
|
||||
// Stop timer
|
||||
StopTimer(pMB);
|
||||
if (((pMB->sy6522.IER & IxR_TIMER2) == 0) && pMB->bTimer2Active)
|
||||
StopTimer2(pMB);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Set those bits which are set in the lower 7 bits.
|
||||
nValue &= 0x7F;
|
||||
pMB->sy6522.IER |= nValue;
|
||||
UpdateIFR(pMB);
|
||||
StartTimer(pMB);
|
||||
UpdateIFR(pMB, 0);
|
||||
|
||||
// Check if active timer changed from non-interrupt (polling IFR) to interrupt:
|
||||
if ((pMB->sy6522.IER & IxR_TIMER1) && pMB->bTimer1Active)
|
||||
StartTimer1(pMB);
|
||||
|
||||
if ((pMB->sy6522.IER & IxR_TIMER2) && pMB->bTimer2Active)
|
||||
StartTimer2(pMB);
|
||||
}
|
||||
break;
|
||||
case 0x0f: // ORA_NO_HS
|
||||
@ -491,8 +519,7 @@ static BYTE SY6522_Read(BYTE nDevice, BYTE nReg)
|
||||
break;
|
||||
case 0x04: // TIMER1L_COUNTER
|
||||
nValue = pMB->sy6522.TIMER1_COUNTER.l;
|
||||
pMB->sy6522.IFR &= ~IxR_TIMER1; // Also clears Timer1 Interrupt Flag
|
||||
UpdateIFR(pMB);
|
||||
UpdateIFR(pMB, IxR_TIMER1);
|
||||
break;
|
||||
case 0x05: // TIMER1H_COUNTER
|
||||
nValue = pMB->sy6522.TIMER1_COUNTER.h;
|
||||
@ -505,8 +532,7 @@ static BYTE SY6522_Read(BYTE nDevice, BYTE nReg)
|
||||
break;
|
||||
case 0x08: // TIMER2L
|
||||
nValue = pMB->sy6522.TIMER2_COUNTER.l;
|
||||
pMB->sy6522.IFR &= ~IxR_TIMER2; // Also clears Timer2 Interrupt Flag
|
||||
UpdateIFR(pMB);
|
||||
UpdateIFR(pMB, IxR_TIMER2);
|
||||
break;
|
||||
case 0x09: // TIMER2H
|
||||
nValue = pMB->sy6522.TIMER2_COUNTER.h;
|
||||
@ -599,8 +625,7 @@ static void SSI263_Write(BYTE nDevice, BYTE nReg, BYTE nValue)
|
||||
}
|
||||
else
|
||||
{
|
||||
pMB->sy6522.IFR &= ~IxR_PERIPHERAL;
|
||||
UpdateIFR(pMB);
|
||||
UpdateIFR(pMB, IxR_PERIPHERAL);
|
||||
}
|
||||
pMB->SpeechChip.CurrentMode &= ~1; // Clear SSI263's D7 pin
|
||||
|
||||
@ -729,8 +754,7 @@ static void Votrax_Write(BYTE nDevice, BYTE nValue)
|
||||
|
||||
// !A/R: Acknowledge receipt of phoneme data (signal goes from high to low)
|
||||
SY6522_AY8910* pMB = &g_MB[nDevice];
|
||||
pMB->sy6522.IFR &= ~IxR_VOTRAX;
|
||||
UpdateIFR(pMB);
|
||||
UpdateIFR(pMB, IxR_VOTRAX);
|
||||
|
||||
g_nSSI263Device = nDevice;
|
||||
|
||||
@ -739,6 +763,9 @@ static void Votrax_Write(BYTE nDevice, BYTE nValue)
|
||||
|
||||
//===========================================================================
|
||||
|
||||
// Called by:
|
||||
// . MB_UpdateCycles() - when g_nMBTimerDevice == {0,1,2,3}
|
||||
// . MB_EndOfVideoFrame() - when g_nMBTimerDevice == kTIMERDEVICE_INVALID
|
||||
static void MB_Update()
|
||||
{
|
||||
//char szDbg[200];
|
||||
@ -977,8 +1004,7 @@ static DWORD WINAPI SSI263Thread(LPVOID lpParameter)
|
||||
{
|
||||
if((pMB->SpeechChip.CurrentMode != MODE_IRQ_DISABLED) && (pMB->sy6522.PCR == 0x0C))
|
||||
{
|
||||
pMB->sy6522.IFR |= IxR_PERIPHERAL;
|
||||
UpdateIFR(pMB);
|
||||
UpdateIFR(pMB, 0, IxR_PERIPHERAL);
|
||||
pMB->SpeechChip.CurrentMode |= 1; // Set SSI263's D7 pin
|
||||
}
|
||||
}
|
||||
@ -989,8 +1015,7 @@ static DWORD WINAPI SSI263Thread(LPVOID lpParameter)
|
||||
{
|
||||
// !A/R: Time-out of old phoneme (signal goes from low to high)
|
||||
|
||||
pMB->sy6522.IFR |= IxR_VOTRAX;
|
||||
UpdateIFR(pMB);
|
||||
UpdateIFR(pMB, 0, IxR_VOTRAX);
|
||||
|
||||
g_bVotraxPhoneme = false;
|
||||
}
|
||||
@ -1379,6 +1404,9 @@ void MB_Initialize()
|
||||
MB_Reset();
|
||||
LogFileOutput("MB_Initialize: MB_Reset()\n");
|
||||
}
|
||||
|
||||
InitializeCriticalSection(&g_CriticalSection);
|
||||
g_bCritSectionValid = true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -1396,8 +1424,14 @@ void MB_Destroy()
|
||||
{
|
||||
MB_DSUninit();
|
||||
|
||||
for(int i=0; i<NUM_VOICES; i++)
|
||||
for (int i=0; i<NUM_VOICES; i++)
|
||||
delete [] ppAYVoiceBuffer[i];
|
||||
|
||||
if (g_bCritSectionValid)
|
||||
{
|
||||
DeleteCriticalSection(&g_CriticalSection);
|
||||
g_bCritSectionValid = false;
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -1405,7 +1439,7 @@ void MB_Destroy()
|
||||
static void ResetState()
|
||||
{
|
||||
g_n6522TimerPeriod = 0;
|
||||
g_nMBTimerDevice = TIMERDEVICE_INVALID;
|
||||
g_nMBTimerDevice = kTIMERDEVICE_INVALID;
|
||||
g_uLastCumulativeCycles = 0;
|
||||
|
||||
g_nSSI263Device = 0;
|
||||
@ -1647,16 +1681,19 @@ void MB_StartOfCpuExecute()
|
||||
// Called by ContinueExecution() at the end of every video frame
|
||||
void MB_EndOfVideoFrame()
|
||||
{
|
||||
if(g_SoundcardType == CT_Empty)
|
||||
if (g_SoundcardType == CT_Empty)
|
||||
return;
|
||||
|
||||
if(!g_bMBTimerIrqActive)
|
||||
if (g_nMBTimerDevice == kTIMERDEVICE_INVALID)
|
||||
MB_Update();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
// Called by CpuExecute() after every N opcodes (N = ~1000 @ 1MHz)
|
||||
// Called by:
|
||||
// . CpuExecute() every ~1000 @ 1MHz
|
||||
// . CheckInterruptSources() every 128 cycles
|
||||
// . MB_Read() / MB_Write()
|
||||
void MB_UpdateCycles(ULONG uExecutedCycles)
|
||||
{
|
||||
if(g_SoundcardType == CT_Empty)
|
||||
@ -1682,41 +1719,54 @@ void MB_UpdateCycles(ULONG uExecutedCycles)
|
||||
bool bTimer1Underflow = (!(OldTimer1 & 0x8000) && (pMB->sy6522.TIMER1_COUNTER.w & 0x8000));
|
||||
bool bTimer2Underflow = (!(OldTimer2 & 0x8000) && (pMB->sy6522.TIMER2_COUNTER.w & 0x8000));
|
||||
|
||||
if( bTimer1Underflow && (g_nMBTimerDevice == i) && g_bMBTimerIrqActive )
|
||||
if (!pMB->bTimer1Active && bTimer1Underflow)
|
||||
{
|
||||
#ifdef _DEBUG
|
||||
g_uTimer1IrqCount++; // DEBUG
|
||||
#endif
|
||||
if ( (g_nMBTimerDevice == kTIMERDEVICE_INVALID) // StopTimer1() has been called
|
||||
&& (pMB->sy6522.IFR & IxR_TIMER1) // Counter underflowed
|
||||
&& ((pMB->sy6522.ACR & RUNMODE) == RM_ONESHOT) ) // One-shot mode
|
||||
{
|
||||
// Fix for Willy Byte - need to confirm that 6522 really does this!
|
||||
// . It never accesses IER/IFR/TIMER1 regs to clear IRQ
|
||||
UpdateIFR(pMB, IxR_TIMER1); // Deassert the TIMER IRQ
|
||||
}
|
||||
}
|
||||
|
||||
pMB->sy6522.IFR |= IxR_TIMER1;
|
||||
UpdateIFR(pMB);
|
||||
if (pMB->bTimer1Active && bTimer1Underflow)
|
||||
{
|
||||
UpdateIFR(pMB, 0, IxR_TIMER1);
|
||||
|
||||
// Do MB_Update() before StopTimer1()
|
||||
if (g_nMBTimerDevice == i)
|
||||
MB_Update();
|
||||
|
||||
if((pMB->sy6522.ACR & RUNMODE) == RM_ONESHOT)
|
||||
{
|
||||
// One-shot mode
|
||||
// - Phasor's playback code uses one-shot mode
|
||||
// - Willy Byte sets to one-shot to stop the timer IRQ
|
||||
StopTimer(pMB);
|
||||
StopTimer1(pMB);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Free-running mode
|
||||
// - Ultima4/5 change ACCESS_TIMER1 after a couple of IRQs into tune
|
||||
pMB->sy6522.TIMER1_COUNTER.w = pMB->sy6522.TIMER1_LATCH.w;
|
||||
StartTimer(pMB);
|
||||
StartTimer1(pMB);
|
||||
}
|
||||
|
||||
MB_Update();
|
||||
}
|
||||
else if ( bTimer1Underflow
|
||||
&& !g_bMBTimerIrqActive // StopTimer() has been called
|
||||
&& (pMB->sy6522.IFR & IxR_TIMER1) // IRQ
|
||||
&& ((pMB->sy6522.ACR & RUNMODE) == RM_ONESHOT) ) // One-shot mode
|
||||
else if (pMB->bTimer2Active && bTimer2Underflow)
|
||||
{
|
||||
// Fix for Willy Byte - need to confirm that 6522 really does this!
|
||||
// . It never accesses IER/IFR/TIMER1 regs to clear IRQ
|
||||
pMB->sy6522.IFR &= ~IxR_TIMER1; // Deassert the TIMER IRQ
|
||||
UpdateIFR(pMB);
|
||||
UpdateIFR(pMB, 0, IxR_TIMER2);
|
||||
|
||||
if((pMB->sy6522.ACR & RUNMODE) == RM_ONESHOT)
|
||||
{
|
||||
StopTimer2(pMB);
|
||||
}
|
||||
else
|
||||
{
|
||||
pMB->sy6522.TIMER2_COUNTER.w = pMB->sy6522.TIMER2_LATCH.w;
|
||||
StartTimer2(pMB);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1730,7 +1780,6 @@ SS_CARDTYPE MB_GetSoundcardType()
|
||||
|
||||
void MB_SetSoundcardType(SS_CARDTYPE NewSoundcardType)
|
||||
{
|
||||
// if ((NewSoundcardType == SC_UNINIT) || (g_SoundcardType == NewSoundcardType))
|
||||
if (g_SoundcardType == NewSoundcardType)
|
||||
return;
|
||||
|
||||
@ -1744,18 +1793,33 @@ void MB_SetSoundcardType(SS_CARDTYPE NewSoundcardType)
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
double MB_GetFramePeriod()
|
||||
static double MB_GetFramePeriod(void)
|
||||
{
|
||||
return (g_bMBTimerIrqActive||(g_MB[0].sy6522.IFR & IxR_TIMER1)) ? (double)g_n6522TimerPeriod : g_f6522TimerPeriod_NoIRQ;
|
||||
// TODO: Ideally remove this (slot-4) Phasor-IFR check: [*1]
|
||||
// . It's for Phasor music player, which runs in one-shot mode:
|
||||
// . MB_UpdateCycles()
|
||||
// -> Timer1 underflows & StopTimer1() is called, which sets g_nMBTimerDevice == kTIMERDEVICE_INVALID
|
||||
// . MB_EndOfVideoFrame(), and g_nMBTimerDevice == kTIMERDEVICE_INVALID
|
||||
// -> MB_Update()
|
||||
// -> MB_GetFramePeriod()
|
||||
// NB. Removing this Phasor-IFR check means the occasional 'g_f6522TimerPeriod_NoIRQ' gets returned.
|
||||
|
||||
if ((g_nMBTimerDevice != kTIMERDEVICE_INVALID) ||
|
||||
(g_bPhasorEnable && (g_MB[0].sy6522.IFR & IxR_TIMER1))) // [*1]
|
||||
{
|
||||
return (double)g_n6522TimerPeriod;
|
||||
}
|
||||
else
|
||||
{
|
||||
return g_f6522TimerPeriod_NoIRQ;
|
||||
}
|
||||
}
|
||||
|
||||
bool MB_IsActive()
|
||||
{
|
||||
if(!MockingboardVoice.bActive)
|
||||
if (!MockingboardVoice.bActive)
|
||||
return false;
|
||||
|
||||
// Ignore /g_bMBTimerIrqActive/ as timer's irq handler will access 6522 regs affecting /g_bMB_Active/
|
||||
|
||||
return g_bMB_Active;
|
||||
}
|
||||
|
||||
@ -1825,8 +1889,9 @@ int MB_SetSnapshot_v1(const SS_CARD_MOCKINGBOARD_v1* const pSS, const DWORD /*dw
|
||||
memcpy(AY8910_GetRegsPtr(nDeviceNum), &pSS->Unit[i].RegsAY8910, 16);
|
||||
memcpy(&pMB->SpeechChip, &pSS->Unit[i].RegsSSI263, sizeof(SSI263A));
|
||||
pMB->nAYCurrentRegister = pSS->Unit[i].nAYCurrentRegister;
|
||||
pMB->state = AY_INACTIVE;
|
||||
|
||||
StartTimer(pMB); // Attempt to start timer
|
||||
StartTimer1_LoadStateV1(pMB); // Attempt to start timer
|
||||
|
||||
//
|
||||
|
||||
@ -1840,8 +1905,7 @@ int MB_SetSnapshot_v1(const SS_CARD_MOCKINGBOARD_v1* const pSS, const DWORD /*dw
|
||||
|
||||
if((pMB->SpeechChip.CurrentMode != MODE_IRQ_DISABLED) && (pMB->sy6522.PCR == 0x0C) && (pMB->sy6522.IER & IxR_PERIPHERAL))
|
||||
{
|
||||
pMB->sy6522.IFR |= IxR_PERIPHERAL;
|
||||
UpdateIFR(pMB);
|
||||
UpdateIFR(pMB, 0, IxR_PERIPHERAL);
|
||||
pMB->SpeechChip.CurrentMode |= 1; // Set SSI263's D7 pin
|
||||
}
|
||||
}
|
||||
@ -1855,40 +1919,10 @@ int MB_SetSnapshot_v1(const SS_CARD_MOCKINGBOARD_v1* const pSS, const DWORD /*dw
|
||||
|
||||
//===========================================================================
|
||||
|
||||
static UINT DoWriteFile(const HANDLE hFile, const void* const pData, const UINT Length)
|
||||
{
|
||||
DWORD dwBytesWritten;
|
||||
BOOL bRes = WriteFile( hFile,
|
||||
pData,
|
||||
Length,
|
||||
&dwBytesWritten,
|
||||
NULL);
|
||||
|
||||
if(!bRes || (dwBytesWritten != Length))
|
||||
{
|
||||
//dwError = GetLastError();
|
||||
throw std::string("Card: save error");
|
||||
}
|
||||
|
||||
return dwBytesWritten;
|
||||
}
|
||||
|
||||
static UINT DoReadFile(const HANDLE hFile, void* const pData, const UINT Length)
|
||||
{
|
||||
DWORD dwBytesRead;
|
||||
BOOL bRes = ReadFile( hFile,
|
||||
pData,
|
||||
Length,
|
||||
&dwBytesRead,
|
||||
NULL);
|
||||
|
||||
if (dwBytesRead != Length)
|
||||
throw std::string("Card: file corrupt");
|
||||
|
||||
return dwBytesRead;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
// Unit version history:
|
||||
// 2: Added: Timer1 & Timer2 active
|
||||
// 3: Added: Unit state
|
||||
const UINT kUNIT_VERSION = 3;
|
||||
|
||||
const UINT NUM_MB_UNITS = 2;
|
||||
const UINT NUM_PHASOR_UNITS = 2;
|
||||
@ -1916,9 +1950,12 @@ const UINT NUM_PHASOR_UNITS = 2;
|
||||
#define SS_YAML_KEY_SSI263_REG_FILTER_FREQ "Filter Frequency"
|
||||
#define SS_YAML_KEY_SSI263_REG_CURRENT_MODE "Current Mode"
|
||||
#define SS_YAML_KEY_AY_CURR_REG "AY Current Register"
|
||||
#define SS_YAML_KEY_MB_UNIT_STATE "Unit State"
|
||||
#define SS_YAML_KEY_TIMER1_IRQ "Timer1 IRQ Pending"
|
||||
#define SS_YAML_KEY_TIMER2_IRQ "Timer2 IRQ Pending"
|
||||
#define SS_YAML_KEY_SPEECH_IRQ "Speech IRQ Pending"
|
||||
#define SS_YAML_KEY_TIMER1_ACTIVE "Timer1 Active"
|
||||
#define SS_YAML_KEY_TIMER2_ACTIVE "Timer2 Active"
|
||||
|
||||
#define SS_YAML_KEY_PHASOR_UNIT "Unit"
|
||||
#define SS_YAML_KEY_PHASOR_CLOCK_SCALE_FACTOR "Clock Scale Factor"
|
||||
@ -1974,7 +2011,7 @@ void MB_SaveSnapshot(YamlSaveHelper& yamlSaveHelper, const UINT uSlot)
|
||||
UINT nDeviceNum = nMbCardNum*2;
|
||||
SY6522_AY8910* pMB = &g_MB[nDeviceNum];
|
||||
|
||||
YamlSaveHelper::Slot slot(yamlSaveHelper, MB_GetSnapshotCardName(), uSlot, 1); // fixme: object should be just 1 Mockingboard card & it will know its slot
|
||||
YamlSaveHelper::Slot slot(yamlSaveHelper, MB_GetSnapshotCardName(), uSlot, kUNIT_VERSION); // fixme: object should be just 1 Mockingboard card & it will know its slot
|
||||
|
||||
YamlSaveHelper::Label state(yamlSaveHelper, "%s:\n", SS_YAML_KEY_STATE);
|
||||
|
||||
@ -1986,10 +2023,13 @@ void MB_SaveSnapshot(YamlSaveHelper& yamlSaveHelper, const UINT uSlot)
|
||||
AY8910_SaveSnapshot(yamlSaveHelper, nDeviceNum, std::string(""));
|
||||
SaveSnapshotSSI263(yamlSaveHelper, pMB->SpeechChip);
|
||||
|
||||
yamlSaveHelper.SaveHexUint4(SS_YAML_KEY_MB_UNIT_STATE, pMB->state);
|
||||
yamlSaveHelper.SaveHexUint4(SS_YAML_KEY_AY_CURR_REG, pMB->nAYCurrentRegister);
|
||||
yamlSaveHelper.Save("%s: %s # Not supported\n", SS_YAML_KEY_TIMER1_IRQ, "false");
|
||||
yamlSaveHelper.Save("%s: %s # Not supported\n", SS_YAML_KEY_TIMER2_IRQ, "false");
|
||||
yamlSaveHelper.Save("%s: %s # Not supported\n", SS_YAML_KEY_SPEECH_IRQ, "false");
|
||||
yamlSaveHelper.SaveBool(SS_YAML_KEY_TIMER1_ACTIVE, pMB->bTimer1Active);
|
||||
yamlSaveHelper.SaveBool(SS_YAML_KEY_TIMER2_ACTIVE, pMB->bTimer2Active);
|
||||
|
||||
nDeviceNum++;
|
||||
pMB++;
|
||||
@ -2039,7 +2079,7 @@ bool MB_LoadSnapshot(YamlLoadHelper& yamlLoadHelper, UINT slot, UINT version)
|
||||
if (slot != 4 && slot != 5) // fixme
|
||||
throw std::string("Card: wrong slot");
|
||||
|
||||
if (version != 1)
|
||||
if (version < 1 || version > kUNIT_VERSION)
|
||||
throw std::string("Card: wrong version");
|
||||
|
||||
AY8910UpdateSetCycles();
|
||||
@ -2067,11 +2107,29 @@ bool MB_LoadSnapshot(YamlLoadHelper& yamlLoadHelper, UINT slot, UINT version)
|
||||
yamlLoadHelper.LoadBool(SS_YAML_KEY_TIMER2_IRQ); // Consume
|
||||
yamlLoadHelper.LoadBool(SS_YAML_KEY_SPEECH_IRQ); // Consume
|
||||
|
||||
if (version >= 2)
|
||||
{
|
||||
pMB->bTimer1Active = yamlLoadHelper.LoadBool(SS_YAML_KEY_TIMER1_ACTIVE);
|
||||
pMB->bTimer2Active = yamlLoadHelper.LoadBool(SS_YAML_KEY_TIMER2_ACTIVE);
|
||||
}
|
||||
|
||||
pMB->state = AY_INACTIVE;
|
||||
if (version >= 3)
|
||||
pMB->state = (MockingboardUnitState_e) (yamlLoadHelper.LoadUint(SS_YAML_KEY_MB_UNIT_STATE) & 7);
|
||||
|
||||
yamlLoadHelper.PopMap();
|
||||
|
||||
//
|
||||
|
||||
StartTimer(pMB); // Attempt to start timer
|
||||
if (version == 1)
|
||||
{
|
||||
StartTimer1_LoadStateV1(pMB); // Attempt to start timer
|
||||
}
|
||||
else // version >= 2
|
||||
{
|
||||
if (pMB->bTimer1Active)
|
||||
StartTimer1(pMB); // Attempt to start timer
|
||||
}
|
||||
|
||||
// Crude - currently only support a single speech chip
|
||||
// FIX THIS:
|
||||
@ -2083,8 +2141,7 @@ bool MB_LoadSnapshot(YamlLoadHelper& yamlLoadHelper, UINT slot, UINT version)
|
||||
|
||||
if((pMB->SpeechChip.CurrentMode != MODE_IRQ_DISABLED) && (pMB->sy6522.PCR == 0x0C) && (pMB->sy6522.IER & IxR_PERIPHERAL))
|
||||
{
|
||||
pMB->sy6522.IFR |= IxR_PERIPHERAL;
|
||||
UpdateIFR(pMB);
|
||||
UpdateIFR(pMB, 0, IxR_PERIPHERAL);
|
||||
pMB->SpeechChip.CurrentMode |= 1; // Set SSI263's D7 pin
|
||||
}
|
||||
}
|
||||
@ -2110,7 +2167,7 @@ void Phasor_SaveSnapshot(YamlSaveHelper& yamlSaveHelper, const UINT uSlot)
|
||||
UINT nDeviceNum = 0;
|
||||
SY6522_AY8910* pMB = &g_MB[0]; // fixme: Phasor uses MB's slot4(2x6522), slot4(2xSSI263), but slot4+5(4xAY8910)
|
||||
|
||||
YamlSaveHelper::Slot slot(yamlSaveHelper, Phasor_GetSnapshotCardName(), uSlot, 1); // fixme: object should be just 1 Mockingboard card & it will know its slot
|
||||
YamlSaveHelper::Slot slot(yamlSaveHelper, Phasor_GetSnapshotCardName(), uSlot, kUNIT_VERSION); // fixme: object should be just 1 Mockingboard card & it will know its slot
|
||||
|
||||
YamlSaveHelper::Label state(yamlSaveHelper, "%s:\n", SS_YAML_KEY_STATE);
|
||||
|
||||
@ -2126,10 +2183,13 @@ void Phasor_SaveSnapshot(YamlSaveHelper& yamlSaveHelper, const UINT uSlot)
|
||||
AY8910_SaveSnapshot(yamlSaveHelper, nDeviceNum+1, std::string("-B"));
|
||||
SaveSnapshotSSI263(yamlSaveHelper, pMB->SpeechChip);
|
||||
|
||||
yamlSaveHelper.SaveHexUint4(SS_YAML_KEY_MB_UNIT_STATE, pMB->state);
|
||||
yamlSaveHelper.SaveHexUint4(SS_YAML_KEY_AY_CURR_REG, pMB->nAYCurrentRegister);
|
||||
yamlSaveHelper.Save("%s: %s # Not supported\n", SS_YAML_KEY_TIMER1_IRQ, "false");
|
||||
yamlSaveHelper.Save("%s: %s # Not supported\n", SS_YAML_KEY_TIMER2_IRQ, "false");
|
||||
yamlSaveHelper.Save("%s: %s # Not supported\n", SS_YAML_KEY_SPEECH_IRQ, "false");
|
||||
yamlSaveHelper.SaveBool(SS_YAML_KEY_TIMER1_ACTIVE, pMB->bTimer1Active);
|
||||
yamlSaveHelper.SaveBool(SS_YAML_KEY_TIMER2_ACTIVE, pMB->bTimer2Active);
|
||||
|
||||
nDeviceNum += 2;
|
||||
pMB++;
|
||||
@ -2141,7 +2201,7 @@ bool Phasor_LoadSnapshot(YamlLoadHelper& yamlLoadHelper, UINT slot, UINT version
|
||||
if (slot != 4) // fixme
|
||||
throw std::string("Card: wrong slot");
|
||||
|
||||
if (version != 1)
|
||||
if (version < 1 || version > kUNIT_VERSION)
|
||||
throw std::string("Card: wrong version");
|
||||
|
||||
g_PhasorClockScaleFactor = yamlLoadHelper.LoadUint(SS_YAML_KEY_PHASOR_CLOCK_SCALE_FACTOR);
|
||||
@ -2172,11 +2232,29 @@ bool Phasor_LoadSnapshot(YamlLoadHelper& yamlLoadHelper, UINT slot, UINT version
|
||||
yamlLoadHelper.LoadBool(SS_YAML_KEY_TIMER2_IRQ); // Consume
|
||||
yamlLoadHelper.LoadBool(SS_YAML_KEY_SPEECH_IRQ); // Consume
|
||||
|
||||
if (version >= 2)
|
||||
{
|
||||
pMB->bTimer1Active = yamlLoadHelper.LoadBool(SS_YAML_KEY_TIMER1_ACTIVE);
|
||||
pMB->bTimer2Active = yamlLoadHelper.LoadBool(SS_YAML_KEY_TIMER2_ACTIVE);
|
||||
}
|
||||
|
||||
pMB->state = AY_INACTIVE;
|
||||
if (version >= 3)
|
||||
pMB->state = (MockingboardUnitState_e) (yamlLoadHelper.LoadUint(SS_YAML_KEY_MB_UNIT_STATE) & 7);
|
||||
|
||||
yamlLoadHelper.PopMap();
|
||||
|
||||
//
|
||||
|
||||
StartTimer(pMB); // Attempt to start timer
|
||||
if (version == 1)
|
||||
{
|
||||
StartTimer1_LoadStateV1(pMB); // Attempt to start timer
|
||||
}
|
||||
else // version >= 2
|
||||
{
|
||||
if (pMB->bTimer1Active)
|
||||
StartTimer1(pMB); // Attempt to start timer
|
||||
}
|
||||
|
||||
// Crude - currently only support a single speech chip
|
||||
// FIX THIS:
|
||||
@ -2188,8 +2266,7 @@ bool Phasor_LoadSnapshot(YamlLoadHelper& yamlLoadHelper, UINT slot, UINT version
|
||||
|
||||
if((pMB->SpeechChip.CurrentMode != MODE_IRQ_DISABLED) && (pMB->sy6522.PCR == 0x0C) && (pMB->sy6522.IER & IxR_PERIPHERAL))
|
||||
{
|
||||
pMB->sy6522.IFR |= IxR_PERIPHERAL;
|
||||
UpdateIFR(pMB);
|
||||
UpdateIFR(pMB, 0, IxR_PERIPHERAL);
|
||||
pMB->SpeechChip.CurrentMode |= 1; // Set SSI263's D7 pin
|
||||
}
|
||||
}
|
||||
|
@ -1,10 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
extern bool g_bMBTimerIrqActive;
|
||||
#ifdef _DEBUG
|
||||
extern UINT32 g_uTimer1IrqCount; // DEBUG
|
||||
#endif
|
||||
|
||||
void MB_Initialize();
|
||||
void MB_Reinitialize();
|
||||
void MB_Destroy();
|
||||
@ -18,7 +13,6 @@ void MB_CheckIRQ();
|
||||
void MB_UpdateCycles(ULONG uExecutedCycles);
|
||||
SS_CARDTYPE MB_GetSoundcardType();
|
||||
void MB_SetSoundcardType(SS_CARDTYPE NewSoundcardType);
|
||||
double MB_GetFramePeriod();
|
||||
bool MB_IsActive();
|
||||
DWORD MB_GetVolume();
|
||||
void MB_SetVolume(DWORD dwVolume, DWORD dwVolumeMax);
|
||||
|
@ -889,6 +889,7 @@ namespace DIMouse
|
||||
return hr;
|
||||
|
||||
// Setup timer to read mouse position
|
||||
_ASSERT(g_TimerIDEvent == 0);
|
||||
g_TimerIDEvent = SetTimer(hDlg, IDEVENT_TIMER_MOUSE, 8, NULL); // 120Hz timer
|
||||
LogFileOutput("DirectInputInit: SetTimer(), id=0x%08X\n", g_TimerIDEvent);
|
||||
if (g_TimerIDEvent == 0)
|
||||
|
@ -101,8 +101,6 @@ protected:
|
||||
UINT m_uSlot;
|
||||
};
|
||||
|
||||
#define IDEVENT_TIMER_MOUSE 1
|
||||
|
||||
namespace DIMouse
|
||||
{
|
||||
HRESULT DirectInputInit( HWND hDlg );
|
||||
|
@ -134,6 +134,8 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
static bgra_t *g_pVideoAddress = 0;
|
||||
static bgra_t *g_pScanLines[VIDEO_SCANNER_Y_DISPLAY*2]; // To maintain the 280x192 aspect ratio for 560px width, we double every scan line -> 560x384
|
||||
|
||||
static const UINT g_kFrameBufferWidth = GetFrameBufferWidth();
|
||||
|
||||
static unsigned (*g_pHorzClockOffset)[VIDEO_SCANNER_MAX_HORZ] = 0;
|
||||
|
||||
typedef void (*UpdateScreenFunc_t)(long);
|
||||
@ -486,19 +488,19 @@ inline uint32_t getScanlineColor( const uint16_t signal, const bgra_t *pTable )
|
||||
//===========================================================================
|
||||
inline uint32_t* getScanlineNext1Address()
|
||||
{
|
||||
return (uint32_t*) (g_pVideoAddress - 1*FRAMEBUFFER_W);
|
||||
return (uint32_t*) (g_pVideoAddress - 1*g_kFrameBufferWidth);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
inline uint32_t* getScanlinePrev1Address()
|
||||
{
|
||||
return (uint32_t*) (g_pVideoAddress + 1*FRAMEBUFFER_W);
|
||||
return (uint32_t*) (g_pVideoAddress + 1*g_kFrameBufferWidth);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
inline uint32_t* getScanlinePrev2Address()
|
||||
{
|
||||
return (uint32_t*) (g_pVideoAddress + 2*FRAMEBUFFER_W);
|
||||
return (uint32_t*) (g_pVideoAddress + 2*g_kFrameBufferWidth);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
@ -1616,7 +1618,7 @@ void NTSC_VideoInit( uint8_t* pFramebuffer ) // wsVideoInit
|
||||
updateMonochromeTables( 0xFF, 0xFF, 0xFF );
|
||||
|
||||
for (int y = 0; y < (VIDEO_SCANNER_Y_DISPLAY*2); y++)
|
||||
g_pScanLines[y] = (bgra_t*)(g_pFramebufferbits + sizeof(bgra_t) * FRAMEBUFFER_W * ((FRAMEBUFFER_H - 1) - y - BORDER_H) + (sizeof(bgra_t) * BORDER_W));
|
||||
g_pScanLines[y] = (bgra_t*)(g_pFramebufferbits + sizeof(bgra_t) * GetFrameBufferWidth() * ((GetFrameBufferHeight() - 1) - y - GetFrameBufferBorderHeight()) + (sizeof(bgra_t) * GetFrameBufferBorderWidth()));
|
||||
|
||||
g_pVideoAddress = g_pScanLines[0];
|
||||
|
||||
|
@ -171,6 +171,7 @@ static void Snapshot_LoadState_v1() // .aws v1.0.0.1, up to (and including) Appl
|
||||
// Reset all sub-systems
|
||||
MemReset();
|
||||
DiskReset();
|
||||
HD_Reset();
|
||||
KeybReset();
|
||||
VideoResetState();
|
||||
MB_Reset();
|
||||
@ -492,6 +493,7 @@ static void Snapshot_LoadState_v2(void)
|
||||
MemReset();
|
||||
PravetsReset();
|
||||
DiskReset();
|
||||
HD_Reset();
|
||||
KeybReset();
|
||||
VideoResetState();
|
||||
MB_Reset();
|
||||
@ -523,6 +525,7 @@ static void Snapshot_LoadState_v2(void)
|
||||
MemInitializeROM();
|
||||
MemInitializeCustomF8ROM();
|
||||
MemInitializeIO();
|
||||
MemInitializeCardExpansionRomFromSnapshot();
|
||||
|
||||
MemUpdatePaging(TRUE);
|
||||
}
|
||||
|
@ -401,6 +401,7 @@ void CSuperSerialCard::CommTcpSerialReceive()
|
||||
if (m_bRxIrqEnabled && !m_qTcpSerialBuffer.empty())
|
||||
{
|
||||
CpuIrqAssert(IS_SSC);
|
||||
m_vbRxIrqPending = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1333,7 +1334,7 @@ void CSuperSerialCard::SetSnapshot_v1( const DWORD baudrate,
|
||||
// m_vRecvBytes = recvbytes;
|
||||
m_uStopBits = stopbits;
|
||||
|
||||
//m_uDTR = (m_uCommandByte & 0x01) ? DTR_CONTROL_ENABLE : DTR_CONTROL_DISABLE; // TODO: Once GH#386 is resolved
|
||||
m_uDTR = (m_uCommandByte & 0x01) ? DTR_CONTROL_ENABLE : DTR_CONTROL_DISABLE;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
@ -1440,7 +1441,7 @@ bool CSuperSerialCard::LoadSnapshot(YamlLoadHelper& yamlLoadHelper, UINT slot, U
|
||||
m_vbRxIrqPending = yamlLoadHelper.LoadBool(SS_YAML_KEY_RXIRQPENDING);
|
||||
m_bWrittenTx = yamlLoadHelper.LoadBool(SS_YAML_KEY_WRITTENTX);
|
||||
|
||||
//m_uDTR = (m_uCommandByte & 0x01) ? DTR_CONTROL_ENABLE : DTR_CONTROL_DISABLE; // TODO: Once GH#386 is resolved
|
||||
m_uDTR = (m_uCommandByte & 0x01) ? DTR_CONTROL_ENABLE : DTR_CONTROL_DISABLE;
|
||||
|
||||
std::string serialPortName = yamlLoadHelper.LoadString(SS_YAML_KEY_SERIALPORTNAME);
|
||||
SetSerialPortName(serialPortName.c_str());
|
||||
|
@ -130,7 +130,7 @@ static void InitRemainderBuffer()
|
||||
SetClksPerSpkrSample();
|
||||
|
||||
g_nRemainderBufferSize = (UINT) g_fClksPerSpkrSample;
|
||||
if ((double)g_nRemainderBufferSize != g_fClksPerSpkrSample)
|
||||
if ((double)g_nRemainderBufferSize < g_fClksPerSpkrSample)
|
||||
g_nRemainderBufferSize++;
|
||||
|
||||
g_pRemainderBuffer = new short [g_nRemainderBufferSize];
|
||||
@ -339,10 +339,10 @@ BYTE __stdcall SpkrToggle (WORD, WORD, BYTE, BYTE, ULONG nCyclesLeft)
|
||||
if (g_bQuieterSpeaker)
|
||||
{
|
||||
// quieten the speaker if 8 bit DAC in use
|
||||
if (g_nSpeakerData == (SPKR_DATA_INIT >> 2))
|
||||
if (g_nSpeakerData == (SPKR_DATA_INIT/4)) // NB. Don't shift -ve number right: undefined behaviour (MSDN says: implementation-dependent)
|
||||
g_nSpeakerData = ~g_nSpeakerData;
|
||||
else
|
||||
g_nSpeakerData = SPKR_DATA_INIT>>2;
|
||||
g_nSpeakerData = SPKR_DATA_INIT/4; // NB. Don't shift -ve number right: undefined behaviour (MSDN says: implementation-dependent)
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -58,6 +58,12 @@ void uilib_get_general_window_extents(HWND hwnd, int *xsize, int *ysize)
|
||||
strlen = SendMessage(hwnd, WM_GETTEXTLENGTH, 0, 0);
|
||||
/* RGJ added cast for AppleWin */
|
||||
buffer = (char *) malloc(strlen + 1);
|
||||
if (buffer == NULL) // TC: add null check for AppleWin
|
||||
{
|
||||
*xsize = 0;
|
||||
*ysize = 0;
|
||||
return;
|
||||
}
|
||||
GetWindowText(hwnd, buffer, strlen + 1);
|
||||
|
||||
hdc = GetDC(hwnd);
|
||||
|
@ -32,8 +32,6 @@
|
||||
#include <windows.h>
|
||||
#include <tchar.h>
|
||||
|
||||
extern void uilib_get_general_window_extents(HWND hwnd, int *xsize, int *ysize);
|
||||
|
||||
typedef struct {
|
||||
unsigned int idc;
|
||||
int element_type;
|
||||
|
116
source/Video.cpp
@ -148,8 +148,8 @@ void VideoInitialize ()
|
||||
|
||||
ZeroMemory(g_pFramebufferinfo,sizeof(BITMAPINFOHEADER)+256*sizeof(RGBQUAD));
|
||||
g_pFramebufferinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
|
||||
g_pFramebufferinfo->bmiHeader.biWidth = FRAMEBUFFER_W;
|
||||
g_pFramebufferinfo->bmiHeader.biHeight = FRAMEBUFFER_H;
|
||||
g_pFramebufferinfo->bmiHeader.biWidth = GetFrameBufferWidth();
|
||||
g_pFramebufferinfo->bmiHeader.biHeight = GetFrameBufferHeight();
|
||||
g_pFramebufferinfo->bmiHeader.biPlanes = 1;
|
||||
g_pFramebufferinfo->bmiHeader.biBitCount = 32;
|
||||
g_pFramebufferinfo->bmiHeader.biCompression = BI_RGB;
|
||||
@ -444,17 +444,12 @@ void VideoDisplayLogo ()
|
||||
nLogoX = (g_nViewportCX - scale*bm.bmWidth )/2;
|
||||
nLogoY = (g_nViewportCY - scale*bm.bmHeight)/2;
|
||||
|
||||
if( g_bIsFullScreen )
|
||||
if( IsFullScreen() )
|
||||
{
|
||||
#if 0
|
||||
// Draw Logo at top of screen so when the Apple display is refreshed it will automagically clear it
|
||||
nLogoX = 0;
|
||||
nLogoY = 0;
|
||||
#else
|
||||
nLogoX += GetFullScreenOffsetX();
|
||||
nLogoY += GetFullScreenOffsetY();
|
||||
#endif
|
||||
}
|
||||
|
||||
VideoDrawLogoBitmap( hFrameDC, nLogoX, nLogoY, bm.bmWidth, bm.bmHeight, scale );
|
||||
}
|
||||
}
|
||||
@ -499,8 +494,6 @@ void VideoDisplayLogo ()
|
||||
|
||||
#undef DRAWVERSION
|
||||
|
||||
FrameReleaseVideoDC();
|
||||
|
||||
DeleteObject(font);
|
||||
}
|
||||
|
||||
@ -655,59 +648,31 @@ void VideoRefreshScreen ( uint32_t uRedrawWholeScreenVideoMode /* =0*/, bool bRe
|
||||
NTSC_VideoRedrawWholeScreen();
|
||||
}
|
||||
|
||||
// NTSC_BEGIN
|
||||
LPBYTE pDstFrameBufferBits = 0;
|
||||
LONG pitch = 0;
|
||||
HDC hFrameDC = FrameGetVideoDC(&pDstFrameBufferBits,&pitch);
|
||||
|
||||
#if 1 // Keep Aspect Ratio
|
||||
// Need to clear full screen logo to black
|
||||
#define W g_nViewportCX
|
||||
#define H g_nViewportCY
|
||||
#else // Stretch
|
||||
// Stretch - doesn't preserve 1:1 aspect ratio
|
||||
#define W g_bIsFullScreen ? g_nDDFullScreenW : g_nViewportCX
|
||||
#define H g_bIsFullScreen ? g_nDDFullScreenH : g_nViewportCY
|
||||
#endif
|
||||
HDC hFrameDC = FrameGetDC();
|
||||
|
||||
if (hFrameDC)
|
||||
{
|
||||
{
|
||||
int xDst = 0;
|
||||
int yDst = 0;
|
||||
int xSrc = GetFrameBufferBorderWidth();
|
||||
int ySrc = GetFrameBufferBorderHeight();
|
||||
VideoFrameBufferAdjust(xSrc, ySrc); // TC: Hacky-fix for GH#341
|
||||
|
||||
if (g_bIsFullScreen)
|
||||
{
|
||||
// Why the need to set the mid-position here, but not for (full-screen) LOGO or DEBUG modes?
|
||||
xDst = (g_nDDFullScreenW-W)/2 - VIEWPORTX*2;
|
||||
yDst = (g_nDDFullScreenH-H)/2;
|
||||
}
|
||||
int xdest = IsFullScreen() ? GetFullScreenOffsetX() : 0;
|
||||
int ydest = IsFullScreen() ? GetFullScreenOffsetY() : 0;
|
||||
int wdest = g_nViewportCX;
|
||||
int hdest = g_nViewportCY;
|
||||
|
||||
int xSrc = BORDER_W;
|
||||
int ySrc = BORDER_H;
|
||||
VideoFrameBufferAdjust(xSrc, ySrc); // TC: Hacky-fix for GH#341
|
||||
|
||||
int xdest = GetFullScreenOffsetX();
|
||||
int ydest = GetFullScreenOffsetY();
|
||||
int wdest = g_nViewportCX;
|
||||
int hdest = g_nViewportCY;
|
||||
|
||||
SetStretchBltMode(hFrameDC, COLORONCOLOR);
|
||||
StretchBlt(
|
||||
hFrameDC,
|
||||
xdest, ydest,
|
||||
wdest, hdest,
|
||||
g_hDeviceDC,
|
||||
xSrc, ySrc,
|
||||
FRAMEBUFFER_BORDERLESS_W, FRAMEBUFFER_BORDERLESS_H,
|
||||
SRCCOPY);
|
||||
}
|
||||
SetStretchBltMode(hFrameDC, COLORONCOLOR);
|
||||
StretchBlt(
|
||||
hFrameDC,
|
||||
xdest, ydest,
|
||||
wdest, hdest,
|
||||
g_hDeviceDC,
|
||||
xSrc, ySrc,
|
||||
GetFrameBufferBorderlessWidth(), GetFrameBufferBorderlessHeight(),
|
||||
SRCCOPY);
|
||||
}
|
||||
|
||||
GdiFlush();
|
||||
|
||||
FrameReleaseVideoDC();
|
||||
// NTSC_END
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
@ -757,14 +722,7 @@ BYTE VideoSetMode (WORD, WORD address, BYTE write, BYTE, ULONG uExecutedCycles)
|
||||
case 0x5F: if (!IS_APPLE2) g_uVideoMode &= ~VF_DHIRES; break;
|
||||
}
|
||||
|
||||
// Apple IIe, Technical Notes, #3: Double High-Resolution Graphics
|
||||
// 80STORE must be OFF to display page 2
|
||||
if (SW_80STORE)
|
||||
g_uVideoMode &= ~VF_PAGE2;
|
||||
|
||||
// NTSC_BEGIN
|
||||
NTSC_SetVideoMode( g_uVideoMode );
|
||||
// NTSC_END
|
||||
|
||||
return MemReadFloatingBus(uExecutedCycles);
|
||||
}
|
||||
@ -1131,8 +1089,8 @@ static void Video_MakeScreenShot(FILE *pFile, const VideoScreenShot_e ScreenShot
|
||||
|
||||
Video_SetBitmapHeader(
|
||||
pBmp,
|
||||
ScreenShotType == SCREENSHOT_280x192 ? FRAMEBUFFER_BORDERLESS_W/2 : FRAMEBUFFER_BORDERLESS_W,
|
||||
ScreenShotType == SCREENSHOT_280x192 ? FRAMEBUFFER_BORDERLESS_H/2 : FRAMEBUFFER_BORDERLESS_H,
|
||||
ScreenShotType == SCREENSHOT_280x192 ? GetFrameBufferBorderlessWidth()/2 : GetFrameBufferBorderlessWidth(),
|
||||
ScreenShotType == SCREENSHOT_280x192 ? GetFrameBufferBorderlessHeight()/2 : GetFrameBufferBorderlessHeight(),
|
||||
32
|
||||
);
|
||||
|
||||
@ -1162,17 +1120,17 @@ static void Video_MakeScreenShot(FILE *pFile, const VideoScreenShot_e ScreenShot
|
||||
// @reference: "Storing an Image" http://msdn.microsoft.com/en-us/library/ms532340(VS.85).aspx
|
||||
pSrc = (uint32_t*) g_pFramebufferbits;
|
||||
|
||||
int xSrc = BORDER_W;
|
||||
int ySrc = BORDER_H;
|
||||
int xSrc = GetFrameBufferBorderWidth();
|
||||
int ySrc = GetFrameBufferBorderHeight();
|
||||
VideoFrameBufferAdjust(xSrc, ySrc, true); // TC: Hacky-fix for GH#341 & GH#356
|
||||
// Lines stored in reverse, so invert the y-adjust value
|
||||
|
||||
pSrc += xSrc; // Skip left border
|
||||
pSrc += ySrc * FRAMEBUFFER_W; // Skip top border
|
||||
pSrc += xSrc; // Skip left border
|
||||
pSrc += ySrc * GetFrameBufferWidth(); // Skip top border
|
||||
|
||||
if( ScreenShotType == SCREENSHOT_280x192 )
|
||||
{
|
||||
pSrc += FRAMEBUFFER_W; // Start on odd scanline (otherwise for 50% scanline mode get an all black image!)
|
||||
pSrc += GetFrameBufferWidth(); // Start on odd scanline (otherwise for 50% scanline mode get an all black image!)
|
||||
|
||||
uint32_t aScanLine[ 280 ];
|
||||
uint32_t *pDst;
|
||||
@ -1180,25 +1138,25 @@ static void Video_MakeScreenShot(FILE *pFile, const VideoScreenShot_e ScreenShot
|
||||
// 50% Half Scan Line clears every odd scanline.
|
||||
// SHIFT+PrintScreen saves only the even rows.
|
||||
// NOTE: Keep in sync with _Video_RedrawScreen() & Video_MakeScreenShot()
|
||||
for( int y = 0; y < FRAMEBUFFER_BORDERLESS_H/2; y++ )
|
||||
for( UINT y = 0; y < GetFrameBufferBorderlessHeight()/2; y++ )
|
||||
{
|
||||
pDst = aScanLine;
|
||||
for( int x = 0; x < FRAMEBUFFER_BORDERLESS_W/2; x++ )
|
||||
for( UINT x = 0; x < GetFrameBufferBorderlessWidth()/2; x++ )
|
||||
{
|
||||
*pDst++ = pSrc[1]; // correction for left edge loss of scaled scanline [Bill Buckel, B#18928]
|
||||
pSrc += 2; // skip odd pixels
|
||||
}
|
||||
fwrite( aScanLine, sizeof(uint32_t), FRAMEBUFFER_BORDERLESS_W/2, pFile );
|
||||
pSrc += FRAMEBUFFER_W; // scan lines doubled - skip odd ones
|
||||
pSrc += BORDER_W*2; // Skip right border & next line's left border
|
||||
fwrite( aScanLine, sizeof(uint32_t), GetFrameBufferBorderlessWidth()/2, pFile );
|
||||
pSrc += GetFrameBufferWidth(); // scan lines doubled - skip odd ones
|
||||
pSrc += GetFrameBufferBorderWidth()*2; // Skip right border & next line's left border
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for( int y = 0; y < FRAMEBUFFER_BORDERLESS_H; y++ )
|
||||
for( UINT y = 0; y < GetFrameBufferBorderlessHeight(); y++ )
|
||||
{
|
||||
fwrite( pSrc, sizeof(uint32_t), FRAMEBUFFER_BORDERLESS_W, pFile );
|
||||
pSrc += FRAMEBUFFER_W;
|
||||
fwrite( pSrc, sizeof(uint32_t), GetFrameBufferBorderlessWidth(), pFile );
|
||||
pSrc += GetFrameBufferWidth();
|
||||
}
|
||||
}
|
||||
#endif // SCREENSHOT_BMP
|
||||
@ -1277,7 +1235,7 @@ static void videoCreateDIBSection()
|
||||
|
||||
// CREATE THE OFFSET TABLE FOR EACH SCAN LINE IN THE FRAME BUFFER
|
||||
// DRAW THE SOURCE IMAGE INTO THE SOURCE BIT BUFFER
|
||||
ZeroMemory( g_pFramebufferbits, FRAMEBUFFER_W*FRAMEBUFFER_H*4 );
|
||||
ZeroMemory( g_pFramebufferbits, GetFrameBufferWidth()*GetFrameBufferHeight()*sizeof(bgra_t) );
|
||||
|
||||
NTSC_VideoInit( g_pFramebufferbits );
|
||||
}
|
||||
|
113
zlib/adler32.c
@ -1,14 +1,15 @@
|
||||
/* adler32.c -- compute the Adler-32 checksum of a data stream
|
||||
* Copyright (C) 1995-2004 Mark Adler
|
||||
* Copyright (C) 1995-2011, 2016 Mark Adler
|
||||
* For conditions of distribution and use, see copyright notice in zlib.h
|
||||
*/
|
||||
|
||||
/* @(#) $Id$ */
|
||||
|
||||
#define ZLIB_INTERNAL
|
||||
#include "zlib.h"
|
||||
#include "zutil.h"
|
||||
|
||||
#define BASE 65521UL /* largest prime smaller than 65536 */
|
||||
local uLong adler32_combine_ OF((uLong adler1, uLong adler2, z_off64_t len2));
|
||||
|
||||
#define BASE 65521U /* largest prime smaller than 65536 */
|
||||
#define NMAX 5552
|
||||
/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */
|
||||
|
||||
@ -18,46 +19,51 @@
|
||||
#define DO8(buf,i) DO4(buf,i); DO4(buf,i+4);
|
||||
#define DO16(buf) DO8(buf,0); DO8(buf,8);
|
||||
|
||||
/* use NO_DIVIDE if your processor does not do division in hardware */
|
||||
/* use NO_DIVIDE if your processor does not do division in hardware --
|
||||
try it both ways to see which is faster */
|
||||
#ifdef NO_DIVIDE
|
||||
# define MOD(a) \
|
||||
/* note that this assumes BASE is 65521, where 65536 % 65521 == 15
|
||||
(thank you to John Reiser for pointing this out) */
|
||||
# define CHOP(a) \
|
||||
do { \
|
||||
if (a >= (BASE << 16)) a -= (BASE << 16); \
|
||||
if (a >= (BASE << 15)) a -= (BASE << 15); \
|
||||
if (a >= (BASE << 14)) a -= (BASE << 14); \
|
||||
if (a >= (BASE << 13)) a -= (BASE << 13); \
|
||||
if (a >= (BASE << 12)) a -= (BASE << 12); \
|
||||
if (a >= (BASE << 11)) a -= (BASE << 11); \
|
||||
if (a >= (BASE << 10)) a -= (BASE << 10); \
|
||||
if (a >= (BASE << 9)) a -= (BASE << 9); \
|
||||
if (a >= (BASE << 8)) a -= (BASE << 8); \
|
||||
if (a >= (BASE << 7)) a -= (BASE << 7); \
|
||||
if (a >= (BASE << 6)) a -= (BASE << 6); \
|
||||
if (a >= (BASE << 5)) a -= (BASE << 5); \
|
||||
if (a >= (BASE << 4)) a -= (BASE << 4); \
|
||||
if (a >= (BASE << 3)) a -= (BASE << 3); \
|
||||
if (a >= (BASE << 2)) a -= (BASE << 2); \
|
||||
if (a >= (BASE << 1)) a -= (BASE << 1); \
|
||||
unsigned long tmp = a >> 16; \
|
||||
a &= 0xffffUL; \
|
||||
a += (tmp << 4) - tmp; \
|
||||
} while (0)
|
||||
# define MOD28(a) \
|
||||
do { \
|
||||
CHOP(a); \
|
||||
if (a >= BASE) a -= BASE; \
|
||||
} while (0)
|
||||
# define MOD4(a) \
|
||||
# define MOD(a) \
|
||||
do { \
|
||||
if (a >= (BASE << 4)) a -= (BASE << 4); \
|
||||
if (a >= (BASE << 3)) a -= (BASE << 3); \
|
||||
if (a >= (BASE << 2)) a -= (BASE << 2); \
|
||||
if (a >= (BASE << 1)) a -= (BASE << 1); \
|
||||
CHOP(a); \
|
||||
MOD28(a); \
|
||||
} while (0)
|
||||
# define MOD63(a) \
|
||||
do { /* this assumes a is not negative */ \
|
||||
z_off64_t tmp = a >> 32; \
|
||||
a &= 0xffffffffL; \
|
||||
a += (tmp << 8) - (tmp << 5) + tmp; \
|
||||
tmp = a >> 16; \
|
||||
a &= 0xffffL; \
|
||||
a += (tmp << 4) - tmp; \
|
||||
tmp = a >> 16; \
|
||||
a &= 0xffffL; \
|
||||
a += (tmp << 4) - tmp; \
|
||||
if (a >= BASE) a -= BASE; \
|
||||
} while (0)
|
||||
#else
|
||||
# define MOD(a) a %= BASE
|
||||
# define MOD4(a) a %= BASE
|
||||
# define MOD28(a) a %= BASE
|
||||
# define MOD63(a) a %= BASE
|
||||
#endif
|
||||
|
||||
/* ========================================================================= */
|
||||
uLong ZEXPORT adler32(adler, buf, len)
|
||||
uLong ZEXPORT adler32_z(adler, buf, len)
|
||||
uLong adler;
|
||||
const Bytef *buf;
|
||||
uInt len;
|
||||
z_size_t len;
|
||||
{
|
||||
unsigned long sum2;
|
||||
unsigned n;
|
||||
@ -89,7 +95,7 @@ uLong ZEXPORT adler32(adler, buf, len)
|
||||
}
|
||||
if (adler >= BASE)
|
||||
adler -= BASE;
|
||||
MOD4(sum2); /* only added so many BASE's */
|
||||
MOD28(sum2); /* only added so many BASE's */
|
||||
return adler | (sum2 << 16);
|
||||
}
|
||||
|
||||
@ -125,25 +131,56 @@ uLong ZEXPORT adler32(adler, buf, len)
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
uLong ZEXPORT adler32_combine(adler1, adler2, len2)
|
||||
uLong ZEXPORT adler32(adler, buf, len)
|
||||
uLong adler;
|
||||
const Bytef *buf;
|
||||
uInt len;
|
||||
{
|
||||
return adler32_z(adler, buf, len);
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
local uLong adler32_combine_(adler1, adler2, len2)
|
||||
uLong adler1;
|
||||
uLong adler2;
|
||||
z_off_t len2;
|
||||
z_off64_t len2;
|
||||
{
|
||||
unsigned long sum1;
|
||||
unsigned long sum2;
|
||||
unsigned rem;
|
||||
|
||||
/* for negative len, return invalid adler32 as a clue for debugging */
|
||||
if (len2 < 0)
|
||||
return 0xffffffffUL;
|
||||
|
||||
/* the derivation of this formula is left as an exercise for the reader */
|
||||
rem = (unsigned)(len2 % BASE);
|
||||
MOD63(len2); /* assumes len2 >= 0 */
|
||||
rem = (unsigned)len2;
|
||||
sum1 = adler1 & 0xffff;
|
||||
sum2 = rem * sum1;
|
||||
MOD(sum2);
|
||||
sum1 += (adler2 & 0xffff) + BASE - 1;
|
||||
sum2 += ((adler1 >> 16) & 0xffff) + ((adler2 >> 16) & 0xffff) + BASE - rem;
|
||||
if (sum1 > BASE) sum1 -= BASE;
|
||||
if (sum1 > BASE) sum1 -= BASE;
|
||||
if (sum2 > (BASE << 1)) sum2 -= (BASE << 1);
|
||||
if (sum2 > BASE) sum2 -= BASE;
|
||||
if (sum1 >= BASE) sum1 -= BASE;
|
||||
if (sum1 >= BASE) sum1 -= BASE;
|
||||
if (sum2 >= ((unsigned long)BASE << 1)) sum2 -= ((unsigned long)BASE << 1);
|
||||
if (sum2 >= BASE) sum2 -= BASE;
|
||||
return sum1 | (sum2 << 16);
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
uLong ZEXPORT adler32_combine(adler1, adler2, len2)
|
||||
uLong adler1;
|
||||
uLong adler2;
|
||||
z_off_t len2;
|
||||
{
|
||||
return adler32_combine_(adler1, adler2, len2);
|
||||
}
|
||||
|
||||
uLong ZEXPORT adler32_combine64(adler1, adler2, len2)
|
||||
uLong adler1;
|
||||
uLong adler2;
|
||||
z_off64_t len2;
|
||||
{
|
||||
return adler32_combine_(adler1, adler2, len2);
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* compress.c -- compress a memory buffer
|
||||
* Copyright (C) 1995-2003 Jean-loup Gailly.
|
||||
* Copyright (C) 1995-2005, 2014, 2016 Jean-loup Gailly, Mark Adler
|
||||
* For conditions of distribution and use, see copyright notice in zlib.h
|
||||
*/
|
||||
|
||||
@ -28,16 +28,11 @@ int ZEXPORT compress2 (dest, destLen, source, sourceLen, level)
|
||||
{
|
||||
z_stream stream;
|
||||
int err;
|
||||
const uInt max = (uInt)-1;
|
||||
uLong left;
|
||||
|
||||
stream.next_in = (Bytef*)source;
|
||||
stream.avail_in = (uInt)sourceLen;
|
||||
#ifdef MAXSEG_64K
|
||||
/* Check for source > 64K on 16-bit machine: */
|
||||
if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR;
|
||||
#endif
|
||||
stream.next_out = dest;
|
||||
stream.avail_out = (uInt)*destLen;
|
||||
if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR;
|
||||
left = *destLen;
|
||||
*destLen = 0;
|
||||
|
||||
stream.zalloc = (alloc_func)0;
|
||||
stream.zfree = (free_func)0;
|
||||
@ -46,15 +41,26 @@ int ZEXPORT compress2 (dest, destLen, source, sourceLen, level)
|
||||
err = deflateInit(&stream, level);
|
||||
if (err != Z_OK) return err;
|
||||
|
||||
err = deflate(&stream, Z_FINISH);
|
||||
if (err != Z_STREAM_END) {
|
||||
deflateEnd(&stream);
|
||||
return err == Z_OK ? Z_BUF_ERROR : err;
|
||||
}
|
||||
*destLen = stream.total_out;
|
||||
stream.next_out = dest;
|
||||
stream.avail_out = 0;
|
||||
stream.next_in = (z_const Bytef *)source;
|
||||
stream.avail_in = 0;
|
||||
|
||||
err = deflateEnd(&stream);
|
||||
return err;
|
||||
do {
|
||||
if (stream.avail_out == 0) {
|
||||
stream.avail_out = left > (uLong)max ? max : (uInt)left;
|
||||
left -= stream.avail_out;
|
||||
}
|
||||
if (stream.avail_in == 0) {
|
||||
stream.avail_in = sourceLen > (uLong)max ? max : (uInt)sourceLen;
|
||||
sourceLen -= stream.avail_in;
|
||||
}
|
||||
err = deflate(&stream, sourceLen ? Z_NO_FLUSH : Z_FINISH);
|
||||
} while (err == Z_OK);
|
||||
|
||||
*destLen = stream.total_out;
|
||||
deflateEnd(&stream);
|
||||
return err == Z_STREAM_END ? Z_OK : err;
|
||||
}
|
||||
|
||||
/* ===========================================================================
|
||||
@ -75,5 +81,6 @@ int ZEXPORT compress (dest, destLen, source, sourceLen)
|
||||
uLong ZEXPORT compressBound (sourceLen)
|
||||
uLong sourceLen;
|
||||
{
|
||||
return sourceLen + (sourceLen >> 12) + (sourceLen >> 14) + 11;
|
||||
return sourceLen + (sourceLen >> 12) + (sourceLen >> 14) +
|
||||
(sourceLen >> 25) + 13;
|
||||
}
|
||||
|
149
zlib/crc32.c
@ -1,5 +1,5 @@
|
||||
/* crc32.c -- compute the CRC-32 of a data stream
|
||||
* Copyright (C) 1995-2005 Mark Adler
|
||||
* Copyright (C) 1995-2006, 2010, 2011, 2012, 2016 Mark Adler
|
||||
* For conditions of distribution and use, see copyright notice in zlib.h
|
||||
*
|
||||
* Thanks to Rodney Brown <rbrown64@csc.com.au> for his contribution of faster
|
||||
@ -17,6 +17,8 @@
|
||||
of the crc tables. Therefore, if you #define DYNAMIC_CRC_TABLE, you should
|
||||
first call get_crc_table() to initialize the tables before allowing more than
|
||||
one thread to use crc32().
|
||||
|
||||
DYNAMIC_CRC_TABLE and MAKECRCH can be #defined to write out crc32.h.
|
||||
*/
|
||||
|
||||
#ifdef MAKECRCH
|
||||
@ -28,37 +30,15 @@
|
||||
|
||||
#include "zutil.h" /* for STDC and FAR definitions */
|
||||
|
||||
#define local static
|
||||
|
||||
/* Find a four-byte integer type for crc32_little() and crc32_big(). */
|
||||
#ifndef NOBYFOUR
|
||||
# ifdef STDC /* need ANSI C limits.h to determine sizes */
|
||||
# include <limits.h>
|
||||
# define BYFOUR
|
||||
# if (UINT_MAX == 0xffffffffUL)
|
||||
typedef unsigned int u4;
|
||||
# else
|
||||
# if (ULONG_MAX == 0xffffffffUL)
|
||||
typedef unsigned long u4;
|
||||
# else
|
||||
# if (USHRT_MAX == 0xffffffffUL)
|
||||
typedef unsigned short u4;
|
||||
# else
|
||||
# undef BYFOUR /* can't find a four-byte integer type! */
|
||||
# endif
|
||||
# endif
|
||||
# endif
|
||||
# endif /* STDC */
|
||||
#endif /* !NOBYFOUR */
|
||||
|
||||
/* Definitions for doing the crc four data bytes at a time. */
|
||||
#if !defined(NOBYFOUR) && defined(Z_U4)
|
||||
# define BYFOUR
|
||||
#endif
|
||||
#ifdef BYFOUR
|
||||
# define REV(w) (((w)>>24)+(((w)>>8)&0xff00)+ \
|
||||
(((w)&0xff00)<<8)+(((w)&0xff)<<24))
|
||||
local unsigned long crc32_little OF((unsigned long,
|
||||
const unsigned char FAR *, unsigned));
|
||||
const unsigned char FAR *, z_size_t));
|
||||
local unsigned long crc32_big OF((unsigned long,
|
||||
const unsigned char FAR *, unsigned));
|
||||
const unsigned char FAR *, z_size_t));
|
||||
# define TBLS 8
|
||||
#else
|
||||
# define TBLS 1
|
||||
@ -68,14 +48,16 @@
|
||||
local unsigned long gf2_matrix_times OF((unsigned long *mat,
|
||||
unsigned long vec));
|
||||
local void gf2_matrix_square OF((unsigned long *square, unsigned long *mat));
|
||||
local uLong crc32_combine_ OF((uLong crc1, uLong crc2, z_off64_t len2));
|
||||
|
||||
|
||||
#ifdef DYNAMIC_CRC_TABLE
|
||||
|
||||
local volatile int crc_table_empty = 1;
|
||||
local unsigned long FAR crc_table[TBLS][256];
|
||||
local z_crc_t FAR crc_table[TBLS][256];
|
||||
local void make_crc_table OF((void));
|
||||
#ifdef MAKECRCH
|
||||
local void write_table OF((FILE *, const unsigned long FAR *));
|
||||
local void write_table OF((FILE *, const z_crc_t FAR *));
|
||||
#endif /* MAKECRCH */
|
||||
/*
|
||||
Generate tables for a byte-wise 32-bit CRC calculation on the polynomial:
|
||||
@ -105,9 +87,9 @@ local void make_crc_table OF((void));
|
||||
*/
|
||||
local void make_crc_table()
|
||||
{
|
||||
unsigned long c;
|
||||
z_crc_t c;
|
||||
int n, k;
|
||||
unsigned long poly; /* polynomial exclusive-or pattern */
|
||||
z_crc_t poly; /* polynomial exclusive-or pattern */
|
||||
/* terms of polynomial defining this crc (except x^32): */
|
||||
static volatile int first = 1; /* flag to limit concurrent making */
|
||||
static const unsigned char p[] = {0,1,2,4,5,7,8,10,11,12,16,22,23,26};
|
||||
@ -119,13 +101,13 @@ local void make_crc_table()
|
||||
first = 0;
|
||||
|
||||
/* make exclusive-or pattern from polynomial (0xedb88320UL) */
|
||||
poly = 0UL;
|
||||
for (n = 0; n < sizeof(p)/sizeof(unsigned char); n++)
|
||||
poly |= 1UL << (31 - p[n]);
|
||||
poly = 0;
|
||||
for (n = 0; n < (int)(sizeof(p)/sizeof(unsigned char)); n++)
|
||||
poly |= (z_crc_t)1 << (31 - p[n]);
|
||||
|
||||
/* generate a crc for every 8-bit value */
|
||||
for (n = 0; n < 256; n++) {
|
||||
c = (unsigned long)n;
|
||||
c = (z_crc_t)n;
|
||||
for (k = 0; k < 8; k++)
|
||||
c = c & 1 ? poly ^ (c >> 1) : c >> 1;
|
||||
crc_table[0][n] = c;
|
||||
@ -136,11 +118,11 @@ local void make_crc_table()
|
||||
and then the byte reversal of those as well as the first table */
|
||||
for (n = 0; n < 256; n++) {
|
||||
c = crc_table[0][n];
|
||||
crc_table[4][n] = REV(c);
|
||||
crc_table[4][n] = ZSWAP32(c);
|
||||
for (k = 1; k < 4; k++) {
|
||||
c = crc_table[0][c & 0xff] ^ (c >> 8);
|
||||
crc_table[k][n] = c;
|
||||
crc_table[k + 4][n] = REV(c);
|
||||
crc_table[k + 4][n] = ZSWAP32(c);
|
||||
}
|
||||
}
|
||||
#endif /* BYFOUR */
|
||||
@ -162,7 +144,7 @@ local void make_crc_table()
|
||||
if (out == NULL) return;
|
||||
fprintf(out, "/* crc32.h -- tables for rapid CRC calculation\n");
|
||||
fprintf(out, " * Generated automatically by crc32.c\n */\n\n");
|
||||
fprintf(out, "local const unsigned long FAR ");
|
||||
fprintf(out, "local const z_crc_t FAR ");
|
||||
fprintf(out, "crc_table[TBLS][256] =\n{\n {\n");
|
||||
write_table(out, crc_table[0]);
|
||||
# ifdef BYFOUR
|
||||
@ -182,12 +164,13 @@ local void make_crc_table()
|
||||
#ifdef MAKECRCH
|
||||
local void write_table(out, table)
|
||||
FILE *out;
|
||||
const unsigned long FAR *table;
|
||||
const z_crc_t FAR *table;
|
||||
{
|
||||
int n;
|
||||
|
||||
for (n = 0; n < 256; n++)
|
||||
fprintf(out, "%s0x%08lxUL%s", n % 5 ? "" : " ", table[n],
|
||||
fprintf(out, "%s0x%08lxUL%s", n % 5 ? "" : " ",
|
||||
(unsigned long)(table[n]),
|
||||
n == 255 ? "\n" : (n % 5 == 4 ? ",\n" : ", "));
|
||||
}
|
||||
#endif /* MAKECRCH */
|
||||
@ -202,13 +185,13 @@ local void write_table(out, table)
|
||||
/* =========================================================================
|
||||
* This function can be used by asm versions of crc32()
|
||||
*/
|
||||
const unsigned long FAR * ZEXPORT get_crc_table()
|
||||
const z_crc_t FAR * ZEXPORT get_crc_table()
|
||||
{
|
||||
#ifdef DYNAMIC_CRC_TABLE
|
||||
if (crc_table_empty)
|
||||
make_crc_table();
|
||||
#endif /* DYNAMIC_CRC_TABLE */
|
||||
return (const unsigned long FAR *)crc_table;
|
||||
return (const z_crc_t FAR *)crc_table;
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
@ -216,10 +199,10 @@ const unsigned long FAR * ZEXPORT get_crc_table()
|
||||
#define DO8 DO1; DO1; DO1; DO1; DO1; DO1; DO1; DO1
|
||||
|
||||
/* ========================================================================= */
|
||||
unsigned long ZEXPORT crc32(crc, buf, len)
|
||||
unsigned long ZEXPORT crc32_z(crc, buf, len)
|
||||
unsigned long crc;
|
||||
const unsigned char FAR *buf;
|
||||
unsigned len;
|
||||
z_size_t len;
|
||||
{
|
||||
if (buf == Z_NULL) return 0UL;
|
||||
|
||||
@ -230,7 +213,7 @@ unsigned long ZEXPORT crc32(crc, buf, len)
|
||||
|
||||
#ifdef BYFOUR
|
||||
if (sizeof(void *) == sizeof(ptrdiff_t)) {
|
||||
u4 endian;
|
||||
z_crc_t endian;
|
||||
|
||||
endian = 1;
|
||||
if (*((unsigned char *)(&endian)))
|
||||
@ -250,8 +233,29 @@ unsigned long ZEXPORT crc32(crc, buf, len)
|
||||
return crc ^ 0xffffffffUL;
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
unsigned long ZEXPORT crc32(crc, buf, len)
|
||||
unsigned long crc;
|
||||
const unsigned char FAR *buf;
|
||||
uInt len;
|
||||
{
|
||||
return crc32_z(crc, buf, len);
|
||||
}
|
||||
|
||||
#ifdef BYFOUR
|
||||
|
||||
/*
|
||||
This BYFOUR code accesses the passed unsigned char * buffer with a 32-bit
|
||||
integer pointer type. This violates the strict aliasing rule, where a
|
||||
compiler can assume, for optimization purposes, that two pointers to
|
||||
fundamentally different types won't ever point to the same memory. This can
|
||||
manifest as a problem only if one of the pointers is written to. This code
|
||||
only reads from those pointers. So long as this code remains isolated in
|
||||
this compilation unit, there won't be a problem. For this reason, this code
|
||||
should not be copied and pasted into a compilation unit in which other code
|
||||
writes to the buffer that is passed to these routines.
|
||||
*/
|
||||
|
||||
/* ========================================================================= */
|
||||
#define DOLIT4 c ^= *buf4++; \
|
||||
c = crc_table[3][c & 0xff] ^ crc_table[2][(c >> 8) & 0xff] ^ \
|
||||
@ -262,19 +266,19 @@ unsigned long ZEXPORT crc32(crc, buf, len)
|
||||
local unsigned long crc32_little(crc, buf, len)
|
||||
unsigned long crc;
|
||||
const unsigned char FAR *buf;
|
||||
unsigned len;
|
||||
z_size_t len;
|
||||
{
|
||||
register u4 c;
|
||||
register const u4 FAR *buf4;
|
||||
register z_crc_t c;
|
||||
register const z_crc_t FAR *buf4;
|
||||
|
||||
c = (u4)crc;
|
||||
c = (z_crc_t)crc;
|
||||
c = ~c;
|
||||
while (len && ((ptrdiff_t)buf & 3)) {
|
||||
c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8);
|
||||
len--;
|
||||
}
|
||||
|
||||
buf4 = (const u4 FAR *)(const void FAR *)buf;
|
||||
buf4 = (const z_crc_t FAR *)(const void FAR *)buf;
|
||||
while (len >= 32) {
|
||||
DOLIT32;
|
||||
len -= 32;
|
||||
@ -293,7 +297,7 @@ local unsigned long crc32_little(crc, buf, len)
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
#define DOBIG4 c ^= *++buf4; \
|
||||
#define DOBIG4 c ^= *buf4++; \
|
||||
c = crc_table[4][c & 0xff] ^ crc_table[5][(c >> 8) & 0xff] ^ \
|
||||
crc_table[6][(c >> 16) & 0xff] ^ crc_table[7][c >> 24]
|
||||
#define DOBIG32 DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4
|
||||
@ -302,20 +306,19 @@ local unsigned long crc32_little(crc, buf, len)
|
||||
local unsigned long crc32_big(crc, buf, len)
|
||||
unsigned long crc;
|
||||
const unsigned char FAR *buf;
|
||||
unsigned len;
|
||||
z_size_t len;
|
||||
{
|
||||
register u4 c;
|
||||
register const u4 FAR *buf4;
|
||||
register z_crc_t c;
|
||||
register const z_crc_t FAR *buf4;
|
||||
|
||||
c = REV((u4)crc);
|
||||
c = ZSWAP32((z_crc_t)crc);
|
||||
c = ~c;
|
||||
while (len && ((ptrdiff_t)buf & 3)) {
|
||||
c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8);
|
||||
len--;
|
||||
}
|
||||
|
||||
buf4 = (const u4 FAR *)(const void FAR *)buf;
|
||||
buf4--;
|
||||
buf4 = (const z_crc_t FAR *)(const void FAR *)buf;
|
||||
while (len >= 32) {
|
||||
DOBIG32;
|
||||
len -= 32;
|
||||
@ -324,14 +327,13 @@ local unsigned long crc32_big(crc, buf, len)
|
||||
DOBIG4;
|
||||
len -= 4;
|
||||
}
|
||||
buf4++;
|
||||
buf = (const unsigned char FAR *)buf4;
|
||||
|
||||
if (len) do {
|
||||
c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8);
|
||||
} while (--len);
|
||||
c = ~c;
|
||||
return (unsigned long)(REV(c));
|
||||
return (unsigned long)(ZSWAP32(c));
|
||||
}
|
||||
|
||||
#endif /* BYFOUR */
|
||||
@ -367,22 +369,22 @@ local void gf2_matrix_square(square, mat)
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
uLong ZEXPORT crc32_combine(crc1, crc2, len2)
|
||||
local uLong crc32_combine_(crc1, crc2, len2)
|
||||
uLong crc1;
|
||||
uLong crc2;
|
||||
z_off_t len2;
|
||||
z_off64_t len2;
|
||||
{
|
||||
int n;
|
||||
unsigned long row;
|
||||
unsigned long even[GF2_DIM]; /* even-power-of-two zeros operator */
|
||||
unsigned long odd[GF2_DIM]; /* odd-power-of-two zeros operator */
|
||||
|
||||
/* degenerate case */
|
||||
if (len2 == 0)
|
||||
/* degenerate case (also disallow negative lengths) */
|
||||
if (len2 <= 0)
|
||||
return crc1;
|
||||
|
||||
/* put operator for one zero bit in odd */
|
||||
odd[0] = 0xedb88320L; /* CRC-32 polynomial */
|
||||
odd[0] = 0xedb88320UL; /* CRC-32 polynomial */
|
||||
row = 1;
|
||||
for (n = 1; n < GF2_DIM; n++) {
|
||||
odd[n] = row;
|
||||
@ -421,3 +423,20 @@ uLong ZEXPORT crc32_combine(crc1, crc2, len2)
|
||||
crc1 ^= crc2;
|
||||
return crc1;
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
uLong ZEXPORT crc32_combine(crc1, crc2, len2)
|
||||
uLong crc1;
|
||||
uLong crc2;
|
||||
z_off_t len2;
|
||||
{
|
||||
return crc32_combine_(crc1, crc2, len2);
|
||||
}
|
||||
|
||||
uLong ZEXPORT crc32_combine64(crc1, crc2, len2)
|
||||
uLong crc1;
|
||||
uLong crc2;
|
||||
z_off64_t len2;
|
||||
{
|
||||
return crc32_combine_(crc1, crc2, len2);
|
||||
}
|
||||
|
@ -2,7 +2,7 @@
|
||||
* Generated automatically by crc32.c
|
||||
*/
|
||||
|
||||
local const unsigned long FAR crc_table[TBLS][256] =
|
||||
local const z_crc_t FAR crc_table[TBLS][256] =
|
||||
{
|
||||
{
|
||||
0x00000000UL, 0x77073096UL, 0xee0e612cUL, 0x990951baUL, 0x076dc419UL,
|
||||
|
1321
zlib/deflate.c
@ -1,5 +1,5 @@
|
||||
/* deflate.h -- internal compression state
|
||||
* Copyright (C) 1995-2004 Jean-loup Gailly
|
||||
* Copyright (C) 1995-2016 Jean-loup Gailly
|
||||
* For conditions of distribution and use, see copyright notice in zlib.h
|
||||
*/
|
||||
|
||||
@ -48,13 +48,19 @@
|
||||
#define MAX_BITS 15
|
||||
/* All codes must not exceed MAX_BITS bits */
|
||||
|
||||
#define INIT_STATE 42
|
||||
#define EXTRA_STATE 69
|
||||
#define NAME_STATE 73
|
||||
#define COMMENT_STATE 91
|
||||
#define HCRC_STATE 103
|
||||
#define BUSY_STATE 113
|
||||
#define FINISH_STATE 666
|
||||
#define Buf_size 16
|
||||
/* size of bit buffer in bi_buf */
|
||||
|
||||
#define INIT_STATE 42 /* zlib header -> BUSY_STATE */
|
||||
#ifdef GZIP
|
||||
# define GZIP_STATE 57 /* gzip header -> BUSY_STATE | EXTRA_STATE */
|
||||
#endif
|
||||
#define EXTRA_STATE 69 /* gzip extra block -> NAME_STATE */
|
||||
#define NAME_STATE 73 /* gzip file name -> COMMENT_STATE */
|
||||
#define COMMENT_STATE 91 /* gzip comment -> HCRC_STATE */
|
||||
#define HCRC_STATE 103 /* gzip header CRC -> BUSY_STATE */
|
||||
#define BUSY_STATE 113 /* deflate -> FINISH_STATE */
|
||||
#define FINISH_STATE 666 /* stream complete */
|
||||
/* Stream status */
|
||||
|
||||
|
||||
@ -80,7 +86,7 @@ typedef struct static_tree_desc_s static_tree_desc;
|
||||
typedef struct tree_desc_s {
|
||||
ct_data *dyn_tree; /* the dynamic tree */
|
||||
int max_code; /* largest code with non zero frequency */
|
||||
static_tree_desc *stat_desc; /* the corresponding static tree */
|
||||
const static_tree_desc *stat_desc; /* the corresponding static tree */
|
||||
} FAR tree_desc;
|
||||
|
||||
typedef ush Pos;
|
||||
@ -97,11 +103,11 @@ typedef struct internal_state {
|
||||
Bytef *pending_buf; /* output still pending */
|
||||
ulg pending_buf_size; /* size of pending_buf */
|
||||
Bytef *pending_out; /* next pending byte to output to the stream */
|
||||
uInt pending; /* nb of bytes in the pending buffer */
|
||||
ulg pending; /* nb of bytes in the pending buffer */
|
||||
int wrap; /* bit 0 true for zlib, bit 1 true for gzip */
|
||||
gz_headerp gzhead; /* gzip header information to write */
|
||||
uInt gzindex; /* where in extra, name, or comment */
|
||||
Byte method; /* STORED (for zip only) or DEFLATED */
|
||||
ulg gzindex; /* where in extra, name, or comment */
|
||||
Byte method; /* can only be DEFLATED */
|
||||
int last_flush; /* value of flush param for previous deflate call */
|
||||
|
||||
/* used by deflate.c: */
|
||||
@ -188,7 +194,7 @@ typedef struct internal_state {
|
||||
int nice_match; /* Stop searching when current match exceeds this */
|
||||
|
||||
/* used by trees.c: */
|
||||
/* Didn't use ct_data typedef below to supress compiler warning */
|
||||
/* Didn't use ct_data typedef below to suppress compiler warning */
|
||||
struct ct_data_s dyn_ltree[HEAP_SIZE]; /* literal and length tree */
|
||||
struct ct_data_s dyn_dtree[2*D_CODES+1]; /* distance tree */
|
||||
struct ct_data_s bl_tree[2*BL_CODES+1]; /* Huffman tree for bit lengths */
|
||||
@ -244,9 +250,9 @@ typedef struct internal_state {
|
||||
ulg opt_len; /* bit length of current block with optimal trees */
|
||||
ulg static_len; /* bit length of current block with static trees */
|
||||
uInt matches; /* number of string matches in current block */
|
||||
int last_eob_len; /* bit length of EOB code for last block */
|
||||
uInt insert; /* bytes at end of window left to insert */
|
||||
|
||||
#ifdef DEBUG
|
||||
#ifdef ZLIB_DEBUG
|
||||
ulg compressed_len; /* total bit length of compressed file mod 2^32 */
|
||||
ulg bits_sent; /* bit length of compressed data sent mod 2^32 */
|
||||
#endif
|
||||
@ -260,12 +266,19 @@ typedef struct internal_state {
|
||||
* are always zero.
|
||||
*/
|
||||
|
||||
ulg high_water;
|
||||
/* High water mark offset in window for initialized bytes -- bytes above
|
||||
* this are set to zero in order to avoid memory check warnings when
|
||||
* longest match routines access bytes past the input. This is then
|
||||
* updated to the new high water mark.
|
||||
*/
|
||||
|
||||
} FAR deflate_state;
|
||||
|
||||
/* Output a byte on the stream.
|
||||
* IN assertion: there is enough room in pending_buf.
|
||||
*/
|
||||
#define put_byte(s, c) {s->pending_buf[s->pending++] = (c);}
|
||||
#define put_byte(s, c) {s->pending_buf[s->pending++] = (Bytef)(c);}
|
||||
|
||||
|
||||
#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1)
|
||||
@ -278,14 +291,19 @@ typedef struct internal_state {
|
||||
* distances are limited to MAX_DIST instead of WSIZE.
|
||||
*/
|
||||
|
||||
#define WIN_INIT MAX_MATCH
|
||||
/* Number of bytes after end of data in window to initialize in order to avoid
|
||||
memory checker errors from longest match routines */
|
||||
|
||||
/* in trees.c */
|
||||
void _tr_init OF((deflate_state *s));
|
||||
int _tr_tally OF((deflate_state *s, unsigned dist, unsigned lc));
|
||||
void _tr_flush_block OF((deflate_state *s, charf *buf, ulg stored_len,
|
||||
int eof));
|
||||
void _tr_align OF((deflate_state *s));
|
||||
void _tr_stored_block OF((deflate_state *s, charf *buf, ulg stored_len,
|
||||
int eof));
|
||||
void ZLIB_INTERNAL _tr_init OF((deflate_state *s));
|
||||
int ZLIB_INTERNAL _tr_tally OF((deflate_state *s, unsigned dist, unsigned lc));
|
||||
void ZLIB_INTERNAL _tr_flush_block OF((deflate_state *s, charf *buf,
|
||||
ulg stored_len, int last));
|
||||
void ZLIB_INTERNAL _tr_flush_bits OF((deflate_state *s));
|
||||
void ZLIB_INTERNAL _tr_align OF((deflate_state *s));
|
||||
void ZLIB_INTERNAL _tr_stored_block OF((deflate_state *s, charf *buf,
|
||||
ulg stored_len, int last));
|
||||
|
||||
#define d_code(dist) \
|
||||
((dist) < 256 ? _dist_code[dist] : _dist_code[256+((dist)>>7)])
|
||||
@ -294,15 +312,15 @@ void _tr_stored_block OF((deflate_state *s, charf *buf, ulg stored_len,
|
||||
* used.
|
||||
*/
|
||||
|
||||
#ifndef DEBUG
|
||||
#ifndef ZLIB_DEBUG
|
||||
/* Inline versions of _tr_tally for speed: */
|
||||
|
||||
#if defined(GEN_TREES_H) || !defined(STDC)
|
||||
extern uch _length_code[];
|
||||
extern uch _dist_code[];
|
||||
extern uch ZLIB_INTERNAL _length_code[];
|
||||
extern uch ZLIB_INTERNAL _dist_code[];
|
||||
#else
|
||||
extern const uch _length_code[];
|
||||
extern const uch _dist_code[];
|
||||
extern const uch ZLIB_INTERNAL _length_code[];
|
||||
extern const uch ZLIB_INTERNAL _dist_code[];
|
||||
#endif
|
||||
|
||||
# define _tr_tally_lit(s, c, flush) \
|
||||
@ -313,8 +331,8 @@ void _tr_stored_block OF((deflate_state *s, charf *buf, ulg stored_len,
|
||||
flush = (s->last_lit == s->lit_bufsize-1); \
|
||||
}
|
||||
# define _tr_tally_dist(s, distance, length, flush) \
|
||||
{ uch len = (length); \
|
||||
ush dist = (distance); \
|
||||
{ uch len = (uch)(length); \
|
||||
ush dist = (ush)(distance); \
|
||||
s->d_buf[s->last_lit] = dist; \
|
||||
s->l_buf[s->last_lit++] = len; \
|
||||
dist--; \
|
||||
|
25
zlib/gzclose.c
Normal file
@ -0,0 +1,25 @@
|
||||
/* gzclose.c -- zlib gzclose() function
|
||||
* Copyright (C) 2004, 2010 Mark Adler
|
||||
* For conditions of distribution and use, see copyright notice in zlib.h
|
||||
*/
|
||||
|
||||
#include "gzguts.h"
|
||||
|
||||
/* gzclose() is in a separate file so that it is linked in only if it is used.
|
||||
That way the other gzclose functions can be used instead to avoid linking in
|
||||
unneeded compression or decompression routines. */
|
||||
int ZEXPORT gzclose(file)
|
||||
gzFile file;
|
||||
{
|
||||
#ifndef NO_GZCOMPRESS
|
||||
gz_statep state;
|
||||
|
||||
if (file == NULL)
|
||||
return Z_STREAM_ERROR;
|
||||
state = (gz_statep)file;
|
||||
|
||||
return state->mode == GZ_READ ? gzclose_r(file) : gzclose_w(file);
|
||||
#else
|
||||
return gzclose_r(file);
|
||||
#endif
|
||||
}
|
218
zlib/gzguts.h
Normal file
@ -0,0 +1,218 @@
|
||||
/* gzguts.h -- zlib internal header definitions for gz* operations
|
||||
* Copyright (C) 2004, 2005, 2010, 2011, 2012, 2013, 2016 Mark Adler
|
||||
* For conditions of distribution and use, see copyright notice in zlib.h
|
||||
*/
|
||||
|
||||
#ifdef _LARGEFILE64_SOURCE
|
||||
# ifndef _LARGEFILE_SOURCE
|
||||
# define _LARGEFILE_SOURCE 1
|
||||
# endif
|
||||
# ifdef _FILE_OFFSET_BITS
|
||||
# undef _FILE_OFFSET_BITS
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_HIDDEN
|
||||
# define ZLIB_INTERNAL __attribute__((visibility ("hidden")))
|
||||
#else
|
||||
# define ZLIB_INTERNAL
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include "zlib.h"
|
||||
#ifdef STDC
|
||||
# include <string.h>
|
||||
# include <stdlib.h>
|
||||
# include <limits.h>
|
||||
#endif
|
||||
|
||||
#ifndef _POSIX_SOURCE
|
||||
# define _POSIX_SOURCE
|
||||
#endif
|
||||
#include <fcntl.h>
|
||||
|
||||
#ifdef _WIN32
|
||||
# include <stddef.h>
|
||||
#endif
|
||||
|
||||
#if defined(__TURBOC__) || defined(_MSC_VER) || defined(_WIN32)
|
||||
# include <io.h>
|
||||
#endif
|
||||
|
||||
#if defined(_WIN32) || defined(__CYGWIN__)
|
||||
# define WIDECHAR
|
||||
#endif
|
||||
|
||||
#ifdef WINAPI_FAMILY
|
||||
# define open _open
|
||||
# define read _read
|
||||
# define write _write
|
||||
# define close _close
|
||||
#endif
|
||||
|
||||
#ifdef NO_DEFLATE /* for compatibility with old definition */
|
||||
# define NO_GZCOMPRESS
|
||||
#endif
|
||||
|
||||
#if defined(STDC99) || (defined(__TURBOC__) && __TURBOC__ >= 0x550)
|
||||
# ifndef HAVE_VSNPRINTF
|
||||
# define HAVE_VSNPRINTF
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if defined(__CYGWIN__)
|
||||
# ifndef HAVE_VSNPRINTF
|
||||
# define HAVE_VSNPRINTF
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if defined(MSDOS) && defined(__BORLANDC__) && (BORLANDC > 0x410)
|
||||
# ifndef HAVE_VSNPRINTF
|
||||
# define HAVE_VSNPRINTF
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_VSNPRINTF
|
||||
# ifdef MSDOS
|
||||
/* vsnprintf may exist on some MS-DOS compilers (DJGPP?),
|
||||
but for now we just assume it doesn't. */
|
||||
# define NO_vsnprintf
|
||||
# endif
|
||||
# ifdef __TURBOC__
|
||||
# define NO_vsnprintf
|
||||
# endif
|
||||
# ifdef WIN32
|
||||
/* In Win32, vsnprintf is available as the "non-ANSI" _vsnprintf. */
|
||||
# if !defined(vsnprintf) && !defined(NO_vsnprintf)
|
||||
# if !defined(_MSC_VER) || ( defined(_MSC_VER) && _MSC_VER < 1500 )
|
||||
# define vsnprintf _vsnprintf
|
||||
# endif
|
||||
# endif
|
||||
# endif
|
||||
# ifdef __SASC
|
||||
# define NO_vsnprintf
|
||||
# endif
|
||||
# ifdef VMS
|
||||
# define NO_vsnprintf
|
||||
# endif
|
||||
# ifdef __OS400__
|
||||
# define NO_vsnprintf
|
||||
# endif
|
||||
# ifdef __MVS__
|
||||
# define NO_vsnprintf
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* unlike snprintf (which is required in C99), _snprintf does not guarantee
|
||||
null termination of the result -- however this is only used in gzlib.c where
|
||||
the result is assured to fit in the space provided */
|
||||
#if defined(_MSC_VER) && _MSC_VER < 1900
|
||||
# define snprintf _snprintf
|
||||
#endif
|
||||
|
||||
#ifndef local
|
||||
# define local static
|
||||
#endif
|
||||
/* since "static" is used to mean two completely different things in C, we
|
||||
define "local" for the non-static meaning of "static", for readability
|
||||
(compile with -Dlocal if your debugger can't find static symbols) */
|
||||
|
||||
/* gz* functions always use library allocation functions */
|
||||
#ifndef STDC
|
||||
extern voidp malloc OF((uInt size));
|
||||
extern void free OF((voidpf ptr));
|
||||
#endif
|
||||
|
||||
/* get errno and strerror definition */
|
||||
#if defined UNDER_CE
|
||||
# include <windows.h>
|
||||
# define zstrerror() gz_strwinerror((DWORD)GetLastError())
|
||||
#else
|
||||
# ifndef NO_STRERROR
|
||||
# include <errno.h>
|
||||
# define zstrerror() strerror(errno)
|
||||
# else
|
||||
# define zstrerror() "stdio error (consult errno)"
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* provide prototypes for these when building zlib without LFS */
|
||||
#if !defined(_LARGEFILE64_SOURCE) || _LFS64_LARGEFILE-0 == 0
|
||||
ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *));
|
||||
ZEXTERN z_off64_t ZEXPORT gzseek64 OF((gzFile, z_off64_t, int));
|
||||
ZEXTERN z_off64_t ZEXPORT gztell64 OF((gzFile));
|
||||
ZEXTERN z_off64_t ZEXPORT gzoffset64 OF((gzFile));
|
||||
#endif
|
||||
|
||||
/* default memLevel */
|
||||
#if MAX_MEM_LEVEL >= 8
|
||||
# define DEF_MEM_LEVEL 8
|
||||
#else
|
||||
# define DEF_MEM_LEVEL MAX_MEM_LEVEL
|
||||
#endif
|
||||
|
||||
/* default i/o buffer size -- double this for output when reading (this and
|
||||
twice this must be able to fit in an unsigned type) */
|
||||
#define GZBUFSIZE 8192
|
||||
|
||||
/* gzip modes, also provide a little integrity check on the passed structure */
|
||||
#define GZ_NONE 0
|
||||
#define GZ_READ 7247
|
||||
#define GZ_WRITE 31153
|
||||
#define GZ_APPEND 1 /* mode set to GZ_WRITE after the file is opened */
|
||||
|
||||
/* values for gz_state how */
|
||||
#define LOOK 0 /* look for a gzip header */
|
||||
#define COPY 1 /* copy input directly */
|
||||
#define GZIP 2 /* decompress a gzip stream */
|
||||
|
||||
/* internal gzip file state data structure */
|
||||
typedef struct {
|
||||
/* exposed contents for gzgetc() macro */
|
||||
struct gzFile_s x; /* "x" for exposed */
|
||||
/* x.have: number of bytes available at x.next */
|
||||
/* x.next: next output data to deliver or write */
|
||||
/* x.pos: current position in uncompressed data */
|
||||
/* used for both reading and writing */
|
||||
int mode; /* see gzip modes above */
|
||||
int fd; /* file descriptor */
|
||||
char *path; /* path or fd for error messages */
|
||||
unsigned size; /* buffer size, zero if not allocated yet */
|
||||
unsigned want; /* requested buffer size, default is GZBUFSIZE */
|
||||
unsigned char *in; /* input buffer (double-sized when writing) */
|
||||
unsigned char *out; /* output buffer (double-sized when reading) */
|
||||
int direct; /* 0 if processing gzip, 1 if transparent */
|
||||
/* just for reading */
|
||||
int how; /* 0: get header, 1: copy, 2: decompress */
|
||||
z_off64_t start; /* where the gzip data started, for rewinding */
|
||||
int eof; /* true if end of input file reached */
|
||||
int past; /* true if read requested past end */
|
||||
/* just for writing */
|
||||
int level; /* compression level */
|
||||
int strategy; /* compression strategy */
|
||||
/* seek request */
|
||||
z_off64_t skip; /* amount to skip (already rewound if backwards) */
|
||||
int seek; /* true if seek request pending */
|
||||
/* error information */
|
||||
int err; /* error code */
|
||||
char *msg; /* error message */
|
||||
/* zlib inflate or deflate stream */
|
||||
z_stream strm; /* stream structure in-place (not a pointer) */
|
||||
} gz_state;
|
||||
typedef gz_state FAR *gz_statep;
|
||||
|
||||
/* shared functions */
|
||||
void ZLIB_INTERNAL gz_error OF((gz_statep, int, const char *));
|
||||
#if defined UNDER_CE
|
||||
char ZLIB_INTERNAL *gz_strwinerror OF((DWORD error));
|
||||
#endif
|
||||
|
||||
/* GT_OFF(x), where x is an unsigned value, is true if x > maximum z_off64_t
|
||||
value -- needed when comparing unsigned to z_off64_t, which is signed
|
||||
(possible z_off64_t types off_t, off64_t, and long are all signed) */
|
||||
#ifdef INT_MAX
|
||||
# define GT_OFF(x) (sizeof(int) == sizeof(z_off64_t) && (x) > INT_MAX)
|
||||
#else
|
||||
unsigned ZLIB_INTERNAL gz_intmax OF((void));
|
||||
# define GT_OFF(x) (sizeof(int) == sizeof(z_off64_t) && (x) > gz_intmax())
|
||||
#endif
|
1026
zlib/gzio.c
641
zlib/gzlib.c
Normal file
@ -0,0 +1,641 @@
|
||||
/* gzlib.c -- zlib functions common to reading and writing gzip files
|
||||
* Copyright (C) 2004-2017 Mark Adler
|
||||
* For conditions of distribution and use, see copyright notice in zlib.h
|
||||
*/
|
||||
|
||||
#include "gzguts.h"
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#define open _open
|
||||
#endif
|
||||
|
||||
#if defined(_WIN32) && !defined(__BORLANDC__) && !defined(__MINGW32__)
|
||||
# define LSEEK _lseeki64
|
||||
#else
|
||||
#if defined(_LARGEFILE64_SOURCE) && _LFS64_LARGEFILE-0
|
||||
# define LSEEK lseek64
|
||||
#else
|
||||
# define LSEEK lseek
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Local functions */
|
||||
local void gz_reset OF((gz_statep));
|
||||
local gzFile gz_open OF((const void *, int, const char *));
|
||||
|
||||
#if defined UNDER_CE
|
||||
|
||||
/* Map the Windows error number in ERROR to a locale-dependent error message
|
||||
string and return a pointer to it. Typically, the values for ERROR come
|
||||
from GetLastError.
|
||||
|
||||
The string pointed to shall not be modified by the application, but may be
|
||||
overwritten by a subsequent call to gz_strwinerror
|
||||
|
||||
The gz_strwinerror function does not change the current setting of
|
||||
GetLastError. */
|
||||
char ZLIB_INTERNAL *gz_strwinerror (error)
|
||||
DWORD error;
|
||||
{
|
||||
static char buf[1024];
|
||||
|
||||
wchar_t *msgbuf;
|
||||
DWORD lasterr = GetLastError();
|
||||
DWORD chars = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM
|
||||
| FORMAT_MESSAGE_ALLOCATE_BUFFER,
|
||||
NULL,
|
||||
error,
|
||||
0, /* Default language */
|
||||
(LPVOID)&msgbuf,
|
||||
0,
|
||||
NULL);
|
||||
if (chars != 0) {
|
||||
/* If there is an \r\n appended, zap it. */
|
||||
if (chars >= 2
|
||||
&& msgbuf[chars - 2] == '\r' && msgbuf[chars - 1] == '\n') {
|
||||
chars -= 2;
|
||||
msgbuf[chars] = 0;
|
||||
}
|
||||
|
||||
if (chars > sizeof (buf) - 1) {
|
||||
chars = sizeof (buf) - 1;
|
||||
msgbuf[chars] = 0;
|
||||
}
|
||||
|
||||
wcstombs(buf, msgbuf, chars + 1);
|
||||
LocalFree(msgbuf);
|
||||
}
|
||||
else {
|
||||
sprintf(buf, "unknown win32 error (%ld)", error);
|
||||
}
|
||||
|
||||
SetLastError(lasterr);
|
||||
return buf;
|
||||
}
|
||||
|
||||
#endif /* UNDER_CE */
|
||||
|
||||
/* Reset gzip file state */
|
||||
local void gz_reset(state)
|
||||
gz_statep state;
|
||||
{
|
||||
state->x.have = 0; /* no output data available */
|
||||
if (state->mode == GZ_READ) { /* for reading ... */
|
||||
state->eof = 0; /* not at end of file */
|
||||
state->past = 0; /* have not read past end yet */
|
||||
state->how = LOOK; /* look for gzip header */
|
||||
}
|
||||
state->seek = 0; /* no seek request pending */
|
||||
gz_error(state, Z_OK, NULL); /* clear error */
|
||||
state->x.pos = 0; /* no uncompressed data yet */
|
||||
state->strm.avail_in = 0; /* no input data yet */
|
||||
}
|
||||
|
||||
/* Open a gzip file either by name or file descriptor. */
|
||||
local gzFile gz_open(path, fd, mode)
|
||||
const void *path;
|
||||
int fd;
|
||||
const char *mode;
|
||||
{
|
||||
gz_statep state;
|
||||
z_size_t len;
|
||||
int oflag;
|
||||
#ifdef O_CLOEXEC
|
||||
int cloexec = 0;
|
||||
#endif
|
||||
#ifdef O_EXCL
|
||||
int exclusive = 0;
|
||||
#endif
|
||||
|
||||
/* check input */
|
||||
if (path == NULL)
|
||||
return NULL;
|
||||
|
||||
/* allocate gzFile structure to return */
|
||||
state = (gz_statep)malloc(sizeof(gz_state));
|
||||
if (state == NULL)
|
||||
return NULL;
|
||||
state->size = 0; /* no buffers allocated yet */
|
||||
state->want = GZBUFSIZE; /* requested buffer size */
|
||||
state->msg = NULL; /* no error message yet */
|
||||
|
||||
/* interpret mode */
|
||||
state->mode = GZ_NONE;
|
||||
state->level = Z_DEFAULT_COMPRESSION;
|
||||
state->strategy = Z_DEFAULT_STRATEGY;
|
||||
state->direct = 0;
|
||||
while (*mode) {
|
||||
if (*mode >= '0' && *mode <= '9')
|
||||
state->level = *mode - '0';
|
||||
else
|
||||
switch (*mode) {
|
||||
case 'r':
|
||||
state->mode = GZ_READ;
|
||||
break;
|
||||
#ifndef NO_GZCOMPRESS
|
||||
case 'w':
|
||||
state->mode = GZ_WRITE;
|
||||
break;
|
||||
case 'a':
|
||||
state->mode = GZ_APPEND;
|
||||
break;
|
||||
#endif
|
||||
case '+': /* can't read and write at the same time */
|
||||
free(state);
|
||||
return NULL;
|
||||
case 'b': /* ignore -- will request binary anyway */
|
||||
break;
|
||||
#ifdef O_CLOEXEC
|
||||
case 'e':
|
||||
cloexec = 1;
|
||||
break;
|
||||
#endif
|
||||
#ifdef O_EXCL
|
||||
case 'x':
|
||||
exclusive = 1;
|
||||
break;
|
||||
#endif
|
||||
case 'f':
|
||||
state->strategy = Z_FILTERED;
|
||||
break;
|
||||
case 'h':
|
||||
state->strategy = Z_HUFFMAN_ONLY;
|
||||
break;
|
||||
case 'R':
|
||||
state->strategy = Z_RLE;
|
||||
break;
|
||||
case 'F':
|
||||
state->strategy = Z_FIXED;
|
||||
break;
|
||||
case 'T':
|
||||
state->direct = 1;
|
||||
break;
|
||||
default: /* could consider as an error, but just ignore */
|
||||
;
|
||||
}
|
||||
mode++;
|
||||
}
|
||||
|
||||
/* must provide an "r", "w", or "a" */
|
||||
if (state->mode == GZ_NONE) {
|
||||
free(state);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* can't force transparent read */
|
||||
if (state->mode == GZ_READ) {
|
||||
if (state->direct) {
|
||||
free(state);
|
||||
return NULL;
|
||||
}
|
||||
state->direct = 1; /* for empty file */
|
||||
}
|
||||
|
||||
/* save the path name for error messages */
|
||||
#ifdef WIDECHAR
|
||||
if (fd == -2) {
|
||||
len = wcstombs(NULL, path, 0);
|
||||
if (len == (z_size_t)-1)
|
||||
len = 0;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
len = strlen((const char *)path);
|
||||
state->path = (char *)malloc(len + 1);
|
||||
if (state->path == NULL) {
|
||||
free(state);
|
||||
return NULL;
|
||||
}
|
||||
#ifdef WIDECHAR
|
||||
if (fd == -2)
|
||||
if (len)
|
||||
wcstombs(state->path, path, len + 1);
|
||||
else
|
||||
*(state->path) = 0;
|
||||
else
|
||||
#endif
|
||||
#if !defined(NO_snprintf) && !defined(NO_vsnprintf)
|
||||
(void)snprintf(state->path, len + 1, "%s", (const char *)path);
|
||||
#else
|
||||
strcpy(state->path, path);
|
||||
#endif
|
||||
|
||||
/* compute the flags for open() */
|
||||
oflag =
|
||||
#ifdef O_LARGEFILE
|
||||
O_LARGEFILE |
|
||||
#endif
|
||||
#ifdef O_BINARY
|
||||
O_BINARY |
|
||||
#endif
|
||||
#ifdef O_CLOEXEC
|
||||
(cloexec ? O_CLOEXEC : 0) |
|
||||
#endif
|
||||
(state->mode == GZ_READ ?
|
||||
O_RDONLY :
|
||||
(O_WRONLY | O_CREAT |
|
||||
#ifdef O_EXCL
|
||||
(exclusive ? O_EXCL : 0) |
|
||||
#endif
|
||||
(state->mode == GZ_WRITE ?
|
||||
O_TRUNC :
|
||||
O_APPEND)));
|
||||
|
||||
/* open the file with the appropriate flags (or just use fd) */
|
||||
state->fd = fd > -1 ? fd : (
|
||||
#ifdef WIDECHAR
|
||||
fd == -2 ? _wopen(path, oflag, 0666) :
|
||||
#endif
|
||||
open((const char *)path, oflag, 0666));
|
||||
if (state->fd == -1) {
|
||||
free(state->path);
|
||||
free(state);
|
||||
return NULL;
|
||||
}
|
||||
if (state->mode == GZ_APPEND) {
|
||||
LSEEK(state->fd, 0, SEEK_END); /* so gzoffset() is correct */
|
||||
state->mode = GZ_WRITE; /* simplify later checks */
|
||||
}
|
||||
|
||||
/* save the current position for rewinding (only if reading) */
|
||||
if (state->mode == GZ_READ) {
|
||||
state->start = LSEEK(state->fd, 0, SEEK_CUR);
|
||||
if (state->start == -1) state->start = 0;
|
||||
}
|
||||
|
||||
/* initialize stream */
|
||||
gz_reset(state);
|
||||
|
||||
/* return stream */
|
||||
return (gzFile)state;
|
||||
}
|
||||
|
||||
/* -- see zlib.h -- */
|
||||
gzFile ZEXPORT gzopen(path, mode)
|
||||
const char *path;
|
||||
const char *mode;
|
||||
{
|
||||
return gz_open(path, -1, mode);
|
||||
}
|
||||
|
||||
/* -- see zlib.h -- */
|
||||
gzFile ZEXPORT gzopen64(path, mode)
|
||||
const char *path;
|
||||
const char *mode;
|
||||
{
|
||||
return gz_open(path, -1, mode);
|
||||
}
|
||||
|
||||
/* -- see zlib.h -- */
|
||||
gzFile ZEXPORT gzdopen(fd, mode)
|
||||
int fd;
|
||||
const char *mode;
|
||||
{
|
||||
char *path; /* identifier for error messages */
|
||||
gzFile gz;
|
||||
|
||||
if (fd == -1 || (path = (char *)malloc(7 + 3 * sizeof(int))) == NULL)
|
||||
return NULL;
|
||||
#if !defined(NO_snprintf) && !defined(NO_vsnprintf)
|
||||
(void)snprintf(path, 7 + 3 * sizeof(int), "<fd:%d>", fd);
|
||||
#else
|
||||
sprintf(path, "<fd:%d>", fd); /* for debugging */
|
||||
#endif
|
||||
gz = gz_open(path, fd, mode);
|
||||
free(path);
|
||||
return gz;
|
||||
}
|
||||
|
||||
/* -- see zlib.h -- */
|
||||
#ifdef WIDECHAR
|
||||
gzFile ZEXPORT gzopen_w(path, mode)
|
||||
const wchar_t *path;
|
||||
const char *mode;
|
||||
{
|
||||
return gz_open(path, -2, mode);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* -- see zlib.h -- */
|
||||
int ZEXPORT gzbuffer(file, size)
|
||||
gzFile file;
|
||||
unsigned size;
|
||||
{
|
||||
gz_statep state;
|
||||
|
||||
/* get internal structure and check integrity */
|
||||
if (file == NULL)
|
||||
return -1;
|
||||
state = (gz_statep)file;
|
||||
if (state->mode != GZ_READ && state->mode != GZ_WRITE)
|
||||
return -1;
|
||||
|
||||
/* make sure we haven't already allocated memory */
|
||||
if (state->size != 0)
|
||||
return -1;
|
||||
|
||||
/* check and set requested size */
|
||||
if ((size << 1) < size)
|
||||
return -1; /* need to be able to double it */
|
||||
if (size < 2)
|
||||
size = 2; /* need two bytes to check magic header */
|
||||
state->want = size;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* -- see zlib.h -- */
|
||||
int ZEXPORT gzrewind(file)
|
||||
gzFile file;
|
||||
{
|
||||
gz_statep state;
|
||||
|
||||
/* get internal structure */
|
||||
if (file == NULL)
|
||||
return -1;
|
||||
state = (gz_statep)file;
|
||||
|
||||
/* check that we're reading and that there's no error */
|
||||
if (state->mode != GZ_READ ||
|
||||
(state->err != Z_OK && state->err != Z_BUF_ERROR))
|
||||
return -1;
|
||||
|
||||
/* back up and start over */
|
||||
if (LSEEK(state->fd, state->start, SEEK_SET) == -1)
|
||||
return -1;
|
||||
gz_reset(state);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* -- see zlib.h -- */
|
||||
z_off64_t ZEXPORT gzseek64(file, offset, whence)
|
||||
gzFile file;
|
||||
z_off64_t offset;
|
||||
int whence;
|
||||
{
|
||||
unsigned n;
|
||||
z_off64_t ret;
|
||||
gz_statep state;
|
||||
|
||||
/* get internal structure and check integrity */
|
||||
if (file == NULL)
|
||||
return -1;
|
||||
state = (gz_statep)file;
|
||||
if (state->mode != GZ_READ && state->mode != GZ_WRITE)
|
||||
return -1;
|
||||
|
||||
/* check that there's no error */
|
||||
if (state->err != Z_OK && state->err != Z_BUF_ERROR)
|
||||
return -1;
|
||||
|
||||
/* can only seek from start or relative to current position */
|
||||
if (whence != SEEK_SET && whence != SEEK_CUR)
|
||||
return -1;
|
||||
|
||||
/* normalize offset to a SEEK_CUR specification */
|
||||
if (whence == SEEK_SET)
|
||||
offset -= state->x.pos;
|
||||
else if (state->seek)
|
||||
offset += state->skip;
|
||||
state->seek = 0;
|
||||
|
||||
/* if within raw area while reading, just go there */
|
||||
if (state->mode == GZ_READ && state->how == COPY &&
|
||||
state->x.pos + offset >= 0) {
|
||||
ret = LSEEK(state->fd, offset - state->x.have, SEEK_CUR);
|
||||
if (ret == -1)
|
||||
return -1;
|
||||
state->x.have = 0;
|
||||
state->eof = 0;
|
||||
state->past = 0;
|
||||
state->seek = 0;
|
||||
gz_error(state, Z_OK, NULL);
|
||||
state->strm.avail_in = 0;
|
||||
state->x.pos += offset;
|
||||
return state->x.pos;
|
||||
}
|
||||
|
||||
/* calculate skip amount, rewinding if needed for back seek when reading */
|
||||
if (offset < 0) {
|
||||
if (state->mode != GZ_READ) /* writing -- can't go backwards */
|
||||
return -1;
|
||||
offset += state->x.pos;
|
||||
if (offset < 0) /* before start of file! */
|
||||
return -1;
|
||||
if (gzrewind(file) == -1) /* rewind, then skip to offset */
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* if reading, skip what's in output buffer (one less gzgetc() check) */
|
||||
if (state->mode == GZ_READ) {
|
||||
n = GT_OFF(state->x.have) || (z_off64_t)state->x.have > offset ?
|
||||
(unsigned)offset : state->x.have;
|
||||
state->x.have -= n;
|
||||
state->x.next += n;
|
||||
state->x.pos += n;
|
||||
offset -= n;
|
||||
}
|
||||
|
||||
/* request skip (if not zero) */
|
||||
if (offset) {
|
||||
state->seek = 1;
|
||||
state->skip = offset;
|
||||
}
|
||||
return state->x.pos + offset;
|
||||
}
|
||||
|
||||
/* -- see zlib.h -- */
|
||||
z_off_t ZEXPORT gzseek(file, offset, whence)
|
||||
gzFile file;
|
||||
z_off_t offset;
|
||||
int whence;
|
||||
{
|
||||
z_off64_t ret;
|
||||
|
||||
ret = gzseek64(file, (z_off64_t)offset, whence);
|
||||
return ret == (z_off_t)ret ? (z_off_t)ret : -1;
|
||||
}
|
||||
|
||||
/* -- see zlib.h -- */
|
||||
z_off64_t ZEXPORT gztell64(file)
|
||||
gzFile file;
|
||||
{
|
||||
gz_statep state;
|
||||
|
||||
/* get internal structure and check integrity */
|
||||
if (file == NULL)
|
||||
return -1;
|
||||
state = (gz_statep)file;
|
||||
if (state->mode != GZ_READ && state->mode != GZ_WRITE)
|
||||
return -1;
|
||||
|
||||
/* return position */
|
||||
return state->x.pos + (state->seek ? state->skip : 0);
|
||||
}
|
||||
|
||||
/* -- see zlib.h -- */
|
||||
z_off_t ZEXPORT gztell(file)
|
||||
gzFile file;
|
||||
{
|
||||
z_off64_t ret;
|
||||
|
||||
ret = gztell64(file);
|
||||
return ret == (z_off_t)ret ? (z_off_t)ret : -1;
|
||||
}
|
||||
|
||||
/* -- see zlib.h -- */
|
||||
z_off64_t ZEXPORT gzoffset64(file)
|
||||
gzFile file;
|
||||
{
|
||||
z_off64_t offset;
|
||||
gz_statep state;
|
||||
|
||||
/* get internal structure and check integrity */
|
||||
if (file == NULL)
|
||||
return -1;
|
||||
state = (gz_statep)file;
|
||||
if (state->mode != GZ_READ && state->mode != GZ_WRITE)
|
||||
return -1;
|
||||
|
||||
/* compute and return effective offset in file */
|
||||
offset = LSEEK(state->fd, 0, SEEK_CUR);
|
||||
if (offset == -1)
|
||||
return -1;
|
||||
if (state->mode == GZ_READ) /* reading */
|
||||
offset -= state->strm.avail_in; /* don't count buffered input */
|
||||
return offset;
|
||||
}
|
||||
|
||||
/* -- see zlib.h -- */
|
||||
z_off_t ZEXPORT gzoffset(file)
|
||||
gzFile file;
|
||||
{
|
||||
z_off64_t ret;
|
||||
|
||||
ret = gzoffset64(file);
|
||||
return ret == (z_off_t)ret ? (z_off_t)ret : -1;
|
||||
}
|
||||
|
||||
/* -- see zlib.h -- */
|
||||
int ZEXPORT gzeof(file)
|
||||
gzFile file;
|
||||
{
|
||||
gz_statep state;
|
||||
|
||||
/* get internal structure and check integrity */
|
||||
if (file == NULL)
|
||||
return 0;
|
||||
state = (gz_statep)file;
|
||||
if (state->mode != GZ_READ && state->mode != GZ_WRITE)
|
||||
return 0;
|
||||
|
||||
/* return end-of-file state */
|
||||
return state->mode == GZ_READ ? state->past : 0;
|
||||
}
|
||||
|
||||
/* -- see zlib.h -- */
|
||||
const char * ZEXPORT gzerror(file, errnum)
|
||||
gzFile file;
|
||||
int *errnum;
|
||||
{
|
||||
gz_statep state;
|
||||
|
||||
/* get internal structure and check integrity */
|
||||
if (file == NULL)
|
||||
return NULL;
|
||||
state = (gz_statep)file;
|
||||
if (state->mode != GZ_READ && state->mode != GZ_WRITE)
|
||||
return NULL;
|
||||
|
||||
/* return error information */
|
||||
if (errnum != NULL)
|
||||
*errnum = state->err;
|
||||
return state->err == Z_MEM_ERROR ? "out of memory" :
|
||||
(state->msg == NULL ? "" : state->msg);
|
||||
}
|
||||
|
||||
/* -- see zlib.h -- */
|
||||
void ZEXPORT gzclearerr(file)
|
||||
gzFile file;
|
||||
{
|
||||
gz_statep state;
|
||||
|
||||
/* get internal structure and check integrity */
|
||||
if (file == NULL)
|
||||
return;
|
||||
state = (gz_statep)file;
|
||||
if (state->mode != GZ_READ && state->mode != GZ_WRITE)
|
||||
return;
|
||||
|
||||
/* clear error and end-of-file */
|
||||
if (state->mode == GZ_READ) {
|
||||
state->eof = 0;
|
||||
state->past = 0;
|
||||
}
|
||||
gz_error(state, Z_OK, NULL);
|
||||
}
|
||||
|
||||
/* Create an error message in allocated memory and set state->err and
|
||||
state->msg accordingly. Free any previous error message already there. Do
|
||||
not try to free or allocate space if the error is Z_MEM_ERROR (out of
|
||||
memory). Simply save the error message as a static string. If there is an
|
||||
allocation failure constructing the error message, then convert the error to
|
||||
out of memory. */
|
||||
void ZLIB_INTERNAL gz_error(state, err, msg)
|
||||
gz_statep state;
|
||||
int err;
|
||||
const char *msg;
|
||||
{
|
||||
/* free previously allocated message and clear */
|
||||
if (state->msg != NULL) {
|
||||
if (state->err != Z_MEM_ERROR)
|
||||
free(state->msg);
|
||||
state->msg = NULL;
|
||||
}
|
||||
|
||||
/* if fatal, set state->x.have to 0 so that the gzgetc() macro fails */
|
||||
if (err != Z_OK && err != Z_BUF_ERROR)
|
||||
state->x.have = 0;
|
||||
|
||||
/* set error code, and if no message, then done */
|
||||
state->err = err;
|
||||
if (msg == NULL)
|
||||
return;
|
||||
|
||||
/* for an out of memory error, return literal string when requested */
|
||||
if (err == Z_MEM_ERROR)
|
||||
return;
|
||||
|
||||
/* construct error message with path */
|
||||
if ((state->msg = (char *)malloc(strlen(state->path) + strlen(msg) + 3)) ==
|
||||
NULL) {
|
||||
state->err = Z_MEM_ERROR;
|
||||
return;
|
||||
}
|
||||
#if !defined(NO_snprintf) && !defined(NO_vsnprintf)
|
||||
(void)snprintf(state->msg, strlen(state->path) + strlen(msg) + 3,
|
||||
"%s%s%s", state->path, ": ", msg);
|
||||
#else
|
||||
strcpy(state->msg, state->path);
|
||||
strcat(state->msg, ": ");
|
||||
strcat(state->msg, msg);
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifndef INT_MAX
|
||||
/* portably return maximum value for an int (when limits.h presumed not
|
||||
available) -- we need to do this to cover cases where 2's complement not
|
||||
used, since C standard permits 1's complement and sign-bit representations,
|
||||
otherwise we could just use ((unsigned)-1) >> 1 */
|
||||
unsigned ZLIB_INTERNAL gz_intmax()
|
||||
{
|
||||
unsigned p, q;
|
||||
|
||||
p = 1;
|
||||
do {
|
||||
q = p;
|
||||
p <<= 1;
|
||||
p++;
|
||||
} while (p > q);
|
||||
return q >> 1;
|
||||
}
|
||||
#endif
|
659
zlib/gzread.c
Normal file
@ -0,0 +1,659 @@
|
||||
/* gzread.c -- zlib functions for reading gzip files
|
||||
* Copyright (C) 2004, 2005, 2010, 2011, 2012, 2013, 2016 Mark Adler
|
||||
* For conditions of distribution and use, see copyright notice in zlib.h
|
||||
*/
|
||||
|
||||
#include "gzguts.h"
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#define close _close
|
||||
#define read _read
|
||||
#endif
|
||||
|
||||
/* Local functions */
|
||||
local int gz_load OF((gz_statep, unsigned char *, unsigned, unsigned *));
|
||||
local int gz_avail OF((gz_statep));
|
||||
local int gz_look OF((gz_statep));
|
||||
local int gz_decomp OF((gz_statep));
|
||||
local int gz_fetch OF((gz_statep));
|
||||
local int gz_skip OF((gz_statep, z_off64_t));
|
||||
local z_size_t gz_read OF((gz_statep, voidp, z_size_t));
|
||||
|
||||
/* Use read() to load a buffer -- return -1 on error, otherwise 0. Read from
|
||||
state->fd, and update state->eof, state->err, and state->msg as appropriate.
|
||||
This function needs to loop on read(), since read() is not guaranteed to
|
||||
read the number of bytes requested, depending on the type of descriptor. */
|
||||
local int gz_load(state, buf, len, have)
|
||||
gz_statep state;
|
||||
unsigned char *buf;
|
||||
unsigned len;
|
||||
unsigned *have;
|
||||
{
|
||||
int ret;
|
||||
unsigned get, max = ((unsigned)-1 >> 2) + 1;
|
||||
|
||||
*have = 0;
|
||||
do {
|
||||
get = len - *have;
|
||||
if (get > max)
|
||||
get = max;
|
||||
ret = read(state->fd, buf + *have, get);
|
||||
if (ret <= 0)
|
||||
break;
|
||||
*have += (unsigned)ret;
|
||||
} while (*have < len);
|
||||
if (ret < 0) {
|
||||
gz_error(state, Z_ERRNO, zstrerror());
|
||||
return -1;
|
||||
}
|
||||
if (ret == 0)
|
||||
state->eof = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Load up input buffer and set eof flag if last data loaded -- return -1 on
|
||||
error, 0 otherwise. Note that the eof flag is set when the end of the input
|
||||
file is reached, even though there may be unused data in the buffer. Once
|
||||
that data has been used, no more attempts will be made to read the file.
|
||||
If strm->avail_in != 0, then the current data is moved to the beginning of
|
||||
the input buffer, and then the remainder of the buffer is loaded with the
|
||||
available data from the input file. */
|
||||
local int gz_avail(state)
|
||||
gz_statep state;
|
||||
{
|
||||
unsigned got;
|
||||
z_streamp strm = &(state->strm);
|
||||
|
||||
if (state->err != Z_OK && state->err != Z_BUF_ERROR)
|
||||
return -1;
|
||||
if (state->eof == 0) {
|
||||
if (strm->avail_in) { /* copy what's there to the start */
|
||||
unsigned char *p = state->in;
|
||||
unsigned const char *q = strm->next_in;
|
||||
unsigned n = strm->avail_in;
|
||||
do {
|
||||
*p++ = *q++;
|
||||
} while (--n);
|
||||
}
|
||||
if (gz_load(state, state->in + strm->avail_in,
|
||||
state->size - strm->avail_in, &got) == -1)
|
||||
return -1;
|
||||
strm->avail_in += got;
|
||||
strm->next_in = state->in;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Look for gzip header, set up for inflate or copy. state->x.have must be 0.
|
||||
If this is the first time in, allocate required memory. state->how will be
|
||||
left unchanged if there is no more input data available, will be set to COPY
|
||||
if there is no gzip header and direct copying will be performed, or it will
|
||||
be set to GZIP for decompression. If direct copying, then leftover input
|
||||
data from the input buffer will be copied to the output buffer. In that
|
||||
case, all further file reads will be directly to either the output buffer or
|
||||
a user buffer. If decompressing, the inflate state will be initialized.
|
||||
gz_look() will return 0 on success or -1 on failure. */
|
||||
local int gz_look(state)
|
||||
gz_statep state;
|
||||
{
|
||||
z_streamp strm = &(state->strm);
|
||||
|
||||
/* allocate read buffers and inflate memory */
|
||||
if (state->size == 0) {
|
||||
/* allocate buffers */
|
||||
state->in = (unsigned char *)malloc(state->want);
|
||||
state->out = (unsigned char *)malloc(state->want << 1);
|
||||
if (state->in == NULL || state->out == NULL) {
|
||||
free(state->out);
|
||||
free(state->in);
|
||||
gz_error(state, Z_MEM_ERROR, "out of memory");
|
||||
return -1;
|
||||
}
|
||||
state->size = state->want;
|
||||
|
||||
/* allocate inflate memory */
|
||||
state->strm.zalloc = Z_NULL;
|
||||
state->strm.zfree = Z_NULL;
|
||||
state->strm.opaque = Z_NULL;
|
||||
state->strm.avail_in = 0;
|
||||
state->strm.next_in = Z_NULL;
|
||||
if (inflateInit2(&(state->strm), 15 + 16) != Z_OK) { /* gunzip */
|
||||
free(state->out);
|
||||
free(state->in);
|
||||
state->size = 0;
|
||||
gz_error(state, Z_MEM_ERROR, "out of memory");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/* get at least the magic bytes in the input buffer */
|
||||
if (strm->avail_in < 2) {
|
||||
if (gz_avail(state) == -1)
|
||||
return -1;
|
||||
if (strm->avail_in == 0)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* look for gzip magic bytes -- if there, do gzip decoding (note: there is
|
||||
a logical dilemma here when considering the case of a partially written
|
||||
gzip file, to wit, if a single 31 byte is written, then we cannot tell
|
||||
whether this is a single-byte file, or just a partially written gzip
|
||||
file -- for here we assume that if a gzip file is being written, then
|
||||
the header will be written in a single operation, so that reading a
|
||||
single byte is sufficient indication that it is not a gzip file) */
|
||||
if (strm->avail_in > 1 &&
|
||||
strm->next_in[0] == 31 && strm->next_in[1] == 139) {
|
||||
inflateReset(strm);
|
||||
state->how = GZIP;
|
||||
state->direct = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* no gzip header -- if we were decoding gzip before, then this is trailing
|
||||
garbage. Ignore the trailing garbage and finish. */
|
||||
if (state->direct == 0) {
|
||||
strm->avail_in = 0;
|
||||
state->eof = 1;
|
||||
state->x.have = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* doing raw i/o, copy any leftover input to output -- this assumes that
|
||||
the output buffer is larger than the input buffer, which also assures
|
||||
space for gzungetc() */
|
||||
state->x.next = state->out;
|
||||
if (strm->avail_in) {
|
||||
memcpy(state->x.next, strm->next_in, strm->avail_in);
|
||||
state->x.have = strm->avail_in;
|
||||
strm->avail_in = 0;
|
||||
}
|
||||
state->how = COPY;
|
||||
state->direct = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Decompress from input to the provided next_out and avail_out in the state.
|
||||
On return, state->x.have and state->x.next point to the just decompressed
|
||||
data. If the gzip stream completes, state->how is reset to LOOK to look for
|
||||
the next gzip stream or raw data, once state->x.have is depleted. Returns 0
|
||||
on success, -1 on failure. */
|
||||
local int gz_decomp(state)
|
||||
gz_statep state;
|
||||
{
|
||||
int ret = Z_OK;
|
||||
unsigned had;
|
||||
z_streamp strm = &(state->strm);
|
||||
|
||||
/* fill output buffer up to end of deflate stream */
|
||||
had = strm->avail_out;
|
||||
do {
|
||||
/* get more input for inflate() */
|
||||
if (strm->avail_in == 0 && gz_avail(state) == -1)
|
||||
return -1;
|
||||
if (strm->avail_in == 0) {
|
||||
gz_error(state, Z_BUF_ERROR, "unexpected end of file");
|
||||
break;
|
||||
}
|
||||
|
||||
/* decompress and handle errors */
|
||||
ret = inflate(strm, Z_NO_FLUSH);
|
||||
if (ret == Z_STREAM_ERROR || ret == Z_NEED_DICT) {
|
||||
gz_error(state, Z_STREAM_ERROR,
|
||||
"internal error: inflate stream corrupt");
|
||||
return -1;
|
||||
}
|
||||
if (ret == Z_MEM_ERROR) {
|
||||
gz_error(state, Z_MEM_ERROR, "out of memory");
|
||||
return -1;
|
||||
}
|
||||
if (ret == Z_DATA_ERROR) { /* deflate stream invalid */
|
||||
gz_error(state, Z_DATA_ERROR,
|
||||
strm->msg == NULL ? "compressed data error" : strm->msg);
|
||||
return -1;
|
||||
}
|
||||
} while (strm->avail_out && ret != Z_STREAM_END);
|
||||
|
||||
/* update available output */
|
||||
state->x.have = had - strm->avail_out;
|
||||
state->x.next = strm->next_out - state->x.have;
|
||||
|
||||
/* if the gzip stream completed successfully, look for another */
|
||||
if (ret == Z_STREAM_END)
|
||||
state->how = LOOK;
|
||||
|
||||
/* good decompression */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Fetch data and put it in the output buffer. Assumes state->x.have is 0.
|
||||
Data is either copied from the input file or decompressed from the input
|
||||
file depending on state->how. If state->how is LOOK, then a gzip header is
|
||||
looked for to determine whether to copy or decompress. Returns -1 on error,
|
||||
otherwise 0. gz_fetch() will leave state->how as COPY or GZIP unless the
|
||||
end of the input file has been reached and all data has been processed. */
|
||||
local int gz_fetch(state)
|
||||
gz_statep state;
|
||||
{
|
||||
z_streamp strm = &(state->strm);
|
||||
|
||||
do {
|
||||
switch(state->how) {
|
||||
case LOOK: /* -> LOOK, COPY (only if never GZIP), or GZIP */
|
||||
if (gz_look(state) == -1)
|
||||
return -1;
|
||||
if (state->how == LOOK)
|
||||
return 0;
|
||||
break;
|
||||
case COPY: /* -> COPY */
|
||||
if (gz_load(state, state->out, state->size << 1, &(state->x.have))
|
||||
== -1)
|
||||
return -1;
|
||||
state->x.next = state->out;
|
||||
return 0;
|
||||
case GZIP: /* -> GZIP or LOOK (if end of gzip stream) */
|
||||
strm->avail_out = state->size << 1;
|
||||
strm->next_out = state->out;
|
||||
if (gz_decomp(state) == -1)
|
||||
return -1;
|
||||
}
|
||||
} while (state->x.have == 0 && (!state->eof || strm->avail_in));
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Skip len uncompressed bytes of output. Return -1 on error, 0 on success. */
|
||||
local int gz_skip(state, len)
|
||||
gz_statep state;
|
||||
z_off64_t len;
|
||||
{
|
||||
unsigned n;
|
||||
|
||||
/* skip over len bytes or reach end-of-file, whichever comes first */
|
||||
while (len)
|
||||
/* skip over whatever is in output buffer */
|
||||
if (state->x.have) {
|
||||
n = GT_OFF(state->x.have) || (z_off64_t)state->x.have > len ?
|
||||
(unsigned)len : state->x.have;
|
||||
state->x.have -= n;
|
||||
state->x.next += n;
|
||||
state->x.pos += n;
|
||||
len -= n;
|
||||
}
|
||||
|
||||
/* output buffer empty -- return if we're at the end of the input */
|
||||
else if (state->eof && state->strm.avail_in == 0)
|
||||
break;
|
||||
|
||||
/* need more data to skip -- load up output buffer */
|
||||
else {
|
||||
/* get more output, looking for header if required */
|
||||
if (gz_fetch(state) == -1)
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Read len bytes into buf from file, or less than len up to the end of the
|
||||
input. Return the number of bytes read. If zero is returned, either the
|
||||
end of file was reached, or there was an error. state->err must be
|
||||
consulted in that case to determine which. */
|
||||
local z_size_t gz_read(state, buf, len)
|
||||
gz_statep state;
|
||||
voidp buf;
|
||||
z_size_t len;
|
||||
{
|
||||
z_size_t got;
|
||||
unsigned n;
|
||||
|
||||
/* if len is zero, avoid unnecessary operations */
|
||||
if (len == 0)
|
||||
return 0;
|
||||
|
||||
/* process a skip request */
|
||||
if (state->seek) {
|
||||
state->seek = 0;
|
||||
if (gz_skip(state, state->skip) == -1)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* get len bytes to buf, or less than len if at the end */
|
||||
got = 0;
|
||||
do {
|
||||
/* set n to the maximum amount of len that fits in an unsigned int */
|
||||
n = -1;
|
||||
if (n > len)
|
||||
n = len;
|
||||
|
||||
/* first just try copying data from the output buffer */
|
||||
if (state->x.have) {
|
||||
if (state->x.have < n)
|
||||
n = state->x.have;
|
||||
memcpy(buf, state->x.next, n);
|
||||
state->x.next += n;
|
||||
state->x.have -= n;
|
||||
}
|
||||
|
||||
/* output buffer empty -- return if we're at the end of the input */
|
||||
else if (state->eof && state->strm.avail_in == 0) {
|
||||
state->past = 1; /* tried to read past end */
|
||||
break;
|
||||
}
|
||||
|
||||
/* need output data -- for small len or new stream load up our output
|
||||
buffer */
|
||||
else if (state->how == LOOK || n < (state->size << 1)) {
|
||||
/* get more output, looking for header if required */
|
||||
if (gz_fetch(state) == -1)
|
||||
return 0;
|
||||
continue; /* no progress yet -- go back to copy above */
|
||||
/* the copy above assures that we will leave with space in the
|
||||
output buffer, allowing at least one gzungetc() to succeed */
|
||||
}
|
||||
|
||||
/* large len -- read directly into user buffer */
|
||||
else if (state->how == COPY) { /* read directly */
|
||||
if (gz_load(state, (unsigned char *)buf, n, &n) == -1)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* large len -- decompress directly into user buffer */
|
||||
else { /* state->how == GZIP */
|
||||
state->strm.avail_out = n;
|
||||
state->strm.next_out = (unsigned char *)buf;
|
||||
if (gz_decomp(state) == -1)
|
||||
return 0;
|
||||
n = state->x.have;
|
||||
state->x.have = 0;
|
||||
}
|
||||
|
||||
/* update progress */
|
||||
len -= n;
|
||||
buf = (char *)buf + n;
|
||||
got += n;
|
||||
state->x.pos += n;
|
||||
} while (len);
|
||||
|
||||
/* return number of bytes read into user buffer */
|
||||
return got;
|
||||
}
|
||||
|
||||
/* -- see zlib.h -- */
|
||||
int ZEXPORT gzread(file, buf, len)
|
||||
gzFile file;
|
||||
voidp buf;
|
||||
unsigned len;
|
||||
{
|
||||
gz_statep state;
|
||||
|
||||
/* get internal structure */
|
||||
if (file == NULL)
|
||||
return -1;
|
||||
state = (gz_statep)file;
|
||||
|
||||
/* check that we're reading and that there's no (serious) error */
|
||||
if (state->mode != GZ_READ ||
|
||||
(state->err != Z_OK && state->err != Z_BUF_ERROR))
|
||||
return -1;
|
||||
|
||||
/* since an int is returned, make sure len fits in one, otherwise return
|
||||
with an error (this avoids a flaw in the interface) */
|
||||
if ((int)len < 0) {
|
||||
gz_error(state, Z_STREAM_ERROR, "request does not fit in an int");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* read len or fewer bytes to buf */
|
||||
len = gz_read(state, buf, len);
|
||||
|
||||
/* check for an error */
|
||||
if (len == 0 && state->err != Z_OK && state->err != Z_BUF_ERROR)
|
||||
return -1;
|
||||
|
||||
/* return the number of bytes read (this is assured to fit in an int) */
|
||||
return (int)len;
|
||||
}
|
||||
|
||||
/* -- see zlib.h -- */
|
||||
z_size_t ZEXPORT gzfread(buf, size, nitems, file)
|
||||
voidp buf;
|
||||
z_size_t size;
|
||||
z_size_t nitems;
|
||||
gzFile file;
|
||||
{
|
||||
z_size_t len;
|
||||
gz_statep state;
|
||||
|
||||
/* get internal structure */
|
||||
if (file == NULL)
|
||||
return 0;
|
||||
state = (gz_statep)file;
|
||||
|
||||
/* check that we're reading and that there's no (serious) error */
|
||||
if (state->mode != GZ_READ ||
|
||||
(state->err != Z_OK && state->err != Z_BUF_ERROR))
|
||||
return 0;
|
||||
|
||||
/* compute bytes to read -- error on overflow */
|
||||
len = nitems * size;
|
||||
if (size && len / size != nitems) {
|
||||
gz_error(state, Z_STREAM_ERROR, "request does not fit in a size_t");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* read len or fewer bytes to buf, return the number of full items read */
|
||||
return len ? gz_read(state, buf, len) / size : 0;
|
||||
}
|
||||
|
||||
/* -- see zlib.h -- */
|
||||
#ifdef Z_PREFIX_SET
|
||||
# undef z_gzgetc
|
||||
#else
|
||||
# undef gzgetc
|
||||
#endif
|
||||
int ZEXPORT gzgetc(file)
|
||||
gzFile file;
|
||||
{
|
||||
int ret;
|
||||
unsigned char buf[1];
|
||||
gz_statep state;
|
||||
|
||||
/* get internal structure */
|
||||
if (file == NULL)
|
||||
return -1;
|
||||
state = (gz_statep)file;
|
||||
|
||||
/* check that we're reading and that there's no (serious) error */
|
||||
if (state->mode != GZ_READ ||
|
||||
(state->err != Z_OK && state->err != Z_BUF_ERROR))
|
||||
return -1;
|
||||
|
||||
/* try output buffer (no need to check for skip request) */
|
||||
if (state->x.have) {
|
||||
state->x.have--;
|
||||
state->x.pos++;
|
||||
return *(state->x.next)++;
|
||||
}
|
||||
|
||||
/* nothing there -- try gz_read() */
|
||||
ret = gz_read(state, buf, 1);
|
||||
return ret < 1 ? -1 : buf[0];
|
||||
}
|
||||
|
||||
int ZEXPORT gzgetc_(file)
|
||||
gzFile file;
|
||||
{
|
||||
return gzgetc(file);
|
||||
}
|
||||
|
||||
/* -- see zlib.h -- */
|
||||
int ZEXPORT gzungetc(c, file)
|
||||
int c;
|
||||
gzFile file;
|
||||
{
|
||||
gz_statep state;
|
||||
|
||||
/* get internal structure */
|
||||
if (file == NULL)
|
||||
return -1;
|
||||
state = (gz_statep)file;
|
||||
|
||||
/* check that we're reading and that there's no (serious) error */
|
||||
if (state->mode != GZ_READ ||
|
||||
(state->err != Z_OK && state->err != Z_BUF_ERROR))
|
||||
return -1;
|
||||
|
||||
/* process a skip request */
|
||||
if (state->seek) {
|
||||
state->seek = 0;
|
||||
if (gz_skip(state, state->skip) == -1)
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* can't push EOF */
|
||||
if (c < 0)
|
||||
return -1;
|
||||
|
||||
/* if output buffer empty, put byte at end (allows more pushing) */
|
||||
if (state->x.have == 0) {
|
||||
state->x.have = 1;
|
||||
state->x.next = state->out + (state->size << 1) - 1;
|
||||
state->x.next[0] = (unsigned char)c;
|
||||
state->x.pos--;
|
||||
state->past = 0;
|
||||
return c;
|
||||
}
|
||||
|
||||
/* if no room, give up (must have already done a gzungetc()) */
|
||||
if (state->x.have == (state->size << 1)) {
|
||||
gz_error(state, Z_DATA_ERROR, "out of room to push characters");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* slide output data if needed and insert byte before existing data */
|
||||
if (state->x.next == state->out) {
|
||||
unsigned char *src = state->out + state->x.have;
|
||||
unsigned char *dest = state->out + (state->size << 1);
|
||||
while (src > state->out)
|
||||
*--dest = *--src;
|
||||
state->x.next = dest;
|
||||
}
|
||||
state->x.have++;
|
||||
state->x.next--;
|
||||
state->x.next[0] = (unsigned char)c;
|
||||
state->x.pos--;
|
||||
state->past = 0;
|
||||
return c;
|
||||
}
|
||||
|
||||
/* -- see zlib.h -- */
|
||||
char * ZEXPORT gzgets(file, buf, len)
|
||||
gzFile file;
|
||||
char *buf;
|
||||
int len;
|
||||
{
|
||||
unsigned left, n;
|
||||
char *str;
|
||||
unsigned char *eol;
|
||||
gz_statep state;
|
||||
|
||||
/* check parameters and get internal structure */
|
||||
if (file == NULL || buf == NULL || len < 1)
|
||||
return NULL;
|
||||
state = (gz_statep)file;
|
||||
|
||||
/* check that we're reading and that there's no (serious) error */
|
||||
if (state->mode != GZ_READ ||
|
||||
(state->err != Z_OK && state->err != Z_BUF_ERROR))
|
||||
return NULL;
|
||||
|
||||
/* process a skip request */
|
||||
if (state->seek) {
|
||||
state->seek = 0;
|
||||
if (gz_skip(state, state->skip) == -1)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* copy output bytes up to new line or len - 1, whichever comes first --
|
||||
append a terminating zero to the string (we don't check for a zero in
|
||||
the contents, let the user worry about that) */
|
||||
str = buf;
|
||||
left = (unsigned)len - 1;
|
||||
if (left) do {
|
||||
/* assure that something is in the output buffer */
|
||||
if (state->x.have == 0 && gz_fetch(state) == -1)
|
||||
return NULL; /* error */
|
||||
if (state->x.have == 0) { /* end of file */
|
||||
state->past = 1; /* read past end */
|
||||
break; /* return what we have */
|
||||
}
|
||||
|
||||
/* look for end-of-line in current output buffer */
|
||||
n = state->x.have > left ? left : state->x.have;
|
||||
eol = (unsigned char *)memchr(state->x.next, '\n', n);
|
||||
if (eol != NULL)
|
||||
n = (unsigned)(eol - state->x.next) + 1;
|
||||
|
||||
/* copy through end-of-line, or remainder if not found */
|
||||
memcpy(buf, state->x.next, n);
|
||||
state->x.have -= n;
|
||||
state->x.next += n;
|
||||
state->x.pos += n;
|
||||
left -= n;
|
||||
buf += n;
|
||||
} while (left && eol == NULL);
|
||||
|
||||
/* return terminated string, or if nothing, end of file */
|
||||
if (buf == str)
|
||||
return NULL;
|
||||
buf[0] = 0;
|
||||
return str;
|
||||
}
|
||||
|
||||
/* -- see zlib.h -- */
|
||||
int ZEXPORT gzdirect(file)
|
||||
gzFile file;
|
||||
{
|
||||
gz_statep state;
|
||||
|
||||
/* get internal structure */
|
||||
if (file == NULL)
|
||||
return 0;
|
||||
state = (gz_statep)file;
|
||||
|
||||
/* if the state is not known, but we can find out, then do so (this is
|
||||
mainly for right after a gzopen() or gzdopen()) */
|
||||
if (state->mode == GZ_READ && state->how == LOOK && state->x.have == 0)
|
||||
(void)gz_look(state);
|
||||
|
||||
/* return 1 if transparent, 0 if processing a gzip stream */
|
||||
return state->direct;
|
||||
}
|
||||
|
||||
/* -- see zlib.h -- */
|
||||
int ZEXPORT gzclose_r(file)
|
||||
gzFile file;
|
||||
{
|
||||
int ret, err;
|
||||
gz_statep state;
|
||||
|
||||
/* get internal structure */
|
||||
if (file == NULL)
|
||||
return Z_STREAM_ERROR;
|
||||
state = (gz_statep)file;
|
||||
|
||||
/* check that we're reading */
|
||||
if (state->mode != GZ_READ)
|
||||
return Z_STREAM_ERROR;
|
||||
|
||||
/* free memory and close file */
|
||||
if (state->size) {
|
||||
inflateEnd(&(state->strm));
|
||||
free(state->out);
|
||||
free(state->in);
|
||||
}
|
||||
err = state->err == Z_BUF_ERROR ? Z_BUF_ERROR : Z_OK;
|
||||
gz_error(state, Z_OK, NULL);
|
||||
free(state->path);
|
||||
ret = close(state->fd);
|
||||
free(state);
|
||||
return ret ? Z_ERRNO : err;
|
||||
}
|
670
zlib/gzwrite.c
Normal file
@ -0,0 +1,670 @@
|
||||
/* gzwrite.c -- zlib functions for writing gzip files
|
||||
* Copyright (C) 2004-2017 Mark Adler
|
||||
* For conditions of distribution and use, see copyright notice in zlib.h
|
||||
*/
|
||||
|
||||
#include "gzguts.h"
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#define close _close
|
||||
#define write _write
|
||||
#endif
|
||||
|
||||
/* Local functions */
|
||||
local int gz_init OF((gz_statep));
|
||||
local int gz_comp OF((gz_statep, int));
|
||||
local int gz_zero OF((gz_statep, z_off64_t));
|
||||
local z_size_t gz_write OF((gz_statep, voidpc, z_size_t));
|
||||
|
||||
/* Initialize state for writing a gzip file. Mark initialization by setting
|
||||
state->size to non-zero. Return -1 on a memory allocation failure, or 0 on
|
||||
success. */
|
||||
local int gz_init(state)
|
||||
gz_statep state;
|
||||
{
|
||||
int ret;
|
||||
z_streamp strm = &(state->strm);
|
||||
|
||||
/* allocate input buffer (double size for gzprintf) */
|
||||
state->in = (unsigned char *)malloc(state->want << 1);
|
||||
if (state->in == NULL) {
|
||||
gz_error(state, Z_MEM_ERROR, "out of memory");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* only need output buffer and deflate state if compressing */
|
||||
if (!state->direct) {
|
||||
/* allocate output buffer */
|
||||
state->out = (unsigned char *)malloc(state->want);
|
||||
if (state->out == NULL) {
|
||||
free(state->in);
|
||||
gz_error(state, Z_MEM_ERROR, "out of memory");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* allocate deflate memory, set up for gzip compression */
|
||||
strm->zalloc = Z_NULL;
|
||||
strm->zfree = Z_NULL;
|
||||
strm->opaque = Z_NULL;
|
||||
ret = deflateInit2(strm, state->level, Z_DEFLATED,
|
||||
MAX_WBITS + 16, DEF_MEM_LEVEL, state->strategy);
|
||||
if (ret != Z_OK) {
|
||||
free(state->out);
|
||||
free(state->in);
|
||||
gz_error(state, Z_MEM_ERROR, "out of memory");
|
||||
return -1;
|
||||
}
|
||||
strm->next_in = NULL;
|
||||
}
|
||||
|
||||
/* mark state as initialized */
|
||||
state->size = state->want;
|
||||
|
||||
/* initialize write buffer if compressing */
|
||||
if (!state->direct) {
|
||||
strm->avail_out = state->size;
|
||||
strm->next_out = state->out;
|
||||
state->x.next = strm->next_out;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Compress whatever is at avail_in and next_in and write to the output file.
|
||||
Return -1 if there is an error writing to the output file or if gz_init()
|
||||
fails to allocate memory, otherwise 0. flush is assumed to be a valid
|
||||
deflate() flush value. If flush is Z_FINISH, then the deflate() state is
|
||||
reset to start a new gzip stream. If gz->direct is true, then simply write
|
||||
to the output file without compressing, and ignore flush. */
|
||||
local int gz_comp(state, flush)
|
||||
gz_statep state;
|
||||
int flush;
|
||||
{
|
||||
int ret, writ;
|
||||
unsigned have, put, max = ((unsigned)-1 >> 2) + 1;
|
||||
z_streamp strm = &(state->strm);
|
||||
|
||||
/* allocate memory if this is the first time through */
|
||||
if (state->size == 0 && gz_init(state) == -1)
|
||||
return -1;
|
||||
|
||||
/* write directly if requested */
|
||||
if (state->direct) {
|
||||
while (strm->avail_in) {
|
||||
put = strm->avail_in > max ? max : strm->avail_in;
|
||||
writ = write(state->fd, strm->next_in, put);
|
||||
if (writ < 0) {
|
||||
gz_error(state, Z_ERRNO, zstrerror());
|
||||
return -1;
|
||||
}
|
||||
strm->avail_in -= (unsigned)writ;
|
||||
strm->next_in += writ;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* run deflate() on provided input until it produces no more output */
|
||||
ret = Z_OK;
|
||||
do {
|
||||
/* write out current buffer contents if full, or if flushing, but if
|
||||
doing Z_FINISH then don't write until we get to Z_STREAM_END */
|
||||
if (strm->avail_out == 0 || (flush != Z_NO_FLUSH &&
|
||||
(flush != Z_FINISH || ret == Z_STREAM_END))) {
|
||||
while (strm->next_out > state->x.next) {
|
||||
put = strm->next_out - state->x.next > (int)max ? max :
|
||||
(unsigned)(strm->next_out - state->x.next);
|
||||
writ = write(state->fd, state->x.next, put);
|
||||
if (writ < 0) {
|
||||
gz_error(state, Z_ERRNO, zstrerror());
|
||||
return -1;
|
||||
}
|
||||
state->x.next += writ;
|
||||
}
|
||||
if (strm->avail_out == 0) {
|
||||
strm->avail_out = state->size;
|
||||
strm->next_out = state->out;
|
||||
state->x.next = state->out;
|
||||
}
|
||||
}
|
||||
|
||||
/* compress */
|
||||
have = strm->avail_out;
|
||||
ret = deflate(strm, flush);
|
||||
if (ret == Z_STREAM_ERROR) {
|
||||
gz_error(state, Z_STREAM_ERROR,
|
||||
"internal error: deflate stream corrupt");
|
||||
return -1;
|
||||
}
|
||||
have -= strm->avail_out;
|
||||
} while (have);
|
||||
|
||||
/* if that completed a deflate stream, allow another to start */
|
||||
if (flush == Z_FINISH)
|
||||
deflateReset(strm);
|
||||
|
||||
/* all done, no errors */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Compress len zeros to output. Return -1 on a write error or memory
|
||||
allocation failure by gz_comp(), or 0 on success. */
|
||||
local int gz_zero(state, len)
|
||||
gz_statep state;
|
||||
z_off64_t len;
|
||||
{
|
||||
int first;
|
||||
unsigned n;
|
||||
z_streamp strm = &(state->strm);
|
||||
|
||||
/* consume whatever's left in the input buffer */
|
||||
if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1)
|
||||
return -1;
|
||||
|
||||
/* compress len zeros (len guaranteed > 0) */
|
||||
first = 1;
|
||||
while (len) {
|
||||
n = GT_OFF(state->size) || (z_off64_t)state->size > len ?
|
||||
(unsigned)len : state->size;
|
||||
if (first) {
|
||||
memset(state->in, 0, n);
|
||||
first = 0;
|
||||
}
|
||||
strm->avail_in = n;
|
||||
strm->next_in = state->in;
|
||||
state->x.pos += n;
|
||||
if (gz_comp(state, Z_NO_FLUSH) == -1)
|
||||
return -1;
|
||||
len -= n;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Write len bytes from buf to file. Return the number of bytes written. If
|
||||
the returned value is less than len, then there was an error. */
|
||||
local z_size_t gz_write(state, buf, len)
|
||||
gz_statep state;
|
||||
voidpc buf;
|
||||
z_size_t len;
|
||||
{
|
||||
z_size_t put = len;
|
||||
|
||||
/* if len is zero, avoid unnecessary operations */
|
||||
if (len == 0)
|
||||
return 0;
|
||||
|
||||
/* allocate memory if this is the first time through */
|
||||
if (state->size == 0 && gz_init(state) == -1)
|
||||
return 0;
|
||||
|
||||
/* check for seek request */
|
||||
if (state->seek) {
|
||||
state->seek = 0;
|
||||
if (gz_zero(state, state->skip) == -1)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* for small len, copy to input buffer, otherwise compress directly */
|
||||
if (len < state->size) {
|
||||
/* copy to input buffer, compress when full */
|
||||
do {
|
||||
unsigned have, copy;
|
||||
|
||||
if (state->strm.avail_in == 0)
|
||||
state->strm.next_in = state->in;
|
||||
have = (unsigned)((state->strm.next_in + state->strm.avail_in) -
|
||||
state->in);
|
||||
copy = state->size - have;
|
||||
if (copy > len)
|
||||
copy = len;
|
||||
memcpy(state->in + have, buf, copy);
|
||||
state->strm.avail_in += copy;
|
||||
state->x.pos += copy;
|
||||
buf = (const char *)buf + copy;
|
||||
len -= copy;
|
||||
if (len && gz_comp(state, Z_NO_FLUSH) == -1)
|
||||
return 0;
|
||||
} while (len);
|
||||
}
|
||||
else {
|
||||
/* consume whatever's left in the input buffer */
|
||||
if (state->strm.avail_in && gz_comp(state, Z_NO_FLUSH) == -1)
|
||||
return 0;
|
||||
|
||||
/* directly compress user buffer to file */
|
||||
state->strm.next_in = (z_const Bytef *)buf;
|
||||
do {
|
||||
unsigned n = (unsigned)-1;
|
||||
if (n > len)
|
||||
n = len;
|
||||
state->strm.avail_in = n;
|
||||
state->x.pos += n;
|
||||
if (gz_comp(state, Z_NO_FLUSH) == -1)
|
||||
return 0;
|
||||
len -= n;
|
||||
} while (len);
|
||||
}
|
||||
|
||||
/* input was all buffered or compressed */
|
||||
return put;
|
||||
}
|
||||
|
||||
/* -- see zlib.h -- */
|
||||
int ZEXPORT gzwrite(file, buf, len)
|
||||
gzFile file;
|
||||
voidpc buf;
|
||||
unsigned len;
|
||||
{
|
||||
gz_statep state;
|
||||
|
||||
/* get internal structure */
|
||||
if (file == NULL)
|
||||
return 0;
|
||||
state = (gz_statep)file;
|
||||
|
||||
/* check that we're writing and that there's no error */
|
||||
if (state->mode != GZ_WRITE || state->err != Z_OK)
|
||||
return 0;
|
||||
|
||||
/* since an int is returned, make sure len fits in one, otherwise return
|
||||
with an error (this avoids a flaw in the interface) */
|
||||
if ((int)len < 0) {
|
||||
gz_error(state, Z_DATA_ERROR, "requested length does not fit in int");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* write len bytes from buf (the return value will fit in an int) */
|
||||
return (int)gz_write(state, buf, len);
|
||||
}
|
||||
|
||||
/* -- see zlib.h -- */
|
||||
z_size_t ZEXPORT gzfwrite(buf, size, nitems, file)
|
||||
voidpc buf;
|
||||
z_size_t size;
|
||||
z_size_t nitems;
|
||||
gzFile file;
|
||||
{
|
||||
z_size_t len;
|
||||
gz_statep state;
|
||||
|
||||
/* get internal structure */
|
||||
if (file == NULL)
|
||||
return 0;
|
||||
state = (gz_statep)file;
|
||||
|
||||
/* check that we're writing and that there's no error */
|
||||
if (state->mode != GZ_WRITE || state->err != Z_OK)
|
||||
return 0;
|
||||
|
||||
/* compute bytes to read -- error on overflow */
|
||||
len = nitems * size;
|
||||
if (size && len / size != nitems) {
|
||||
gz_error(state, Z_STREAM_ERROR, "request does not fit in a size_t");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* write len bytes to buf, return the number of full items written */
|
||||
return len ? gz_write(state, buf, len) / size : 0;
|
||||
}
|
||||
|
||||
/* -- see zlib.h -- */
|
||||
int ZEXPORT gzputc(file, c)
|
||||
gzFile file;
|
||||
int c;
|
||||
{
|
||||
unsigned have;
|
||||
unsigned char buf[1];
|
||||
gz_statep state;
|
||||
z_streamp strm;
|
||||
|
||||
/* get internal structure */
|
||||
if (file == NULL)
|
||||
return -1;
|
||||
state = (gz_statep)file;
|
||||
strm = &(state->strm);
|
||||
|
||||
/* check that we're writing and that there's no error */
|
||||
if (state->mode != GZ_WRITE || state->err != Z_OK)
|
||||
return -1;
|
||||
|
||||
/* check for seek request */
|
||||
if (state->seek) {
|
||||
state->seek = 0;
|
||||
if (gz_zero(state, state->skip) == -1)
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* try writing to input buffer for speed (state->size == 0 if buffer not
|
||||
initialized) */
|
||||
if (state->size) {
|
||||
if (strm->avail_in == 0)
|
||||
strm->next_in = state->in;
|
||||
have = (unsigned)((strm->next_in + strm->avail_in) - state->in);
|
||||
if (have < state->size) {
|
||||
state->in[have] = (unsigned char)c;
|
||||
strm->avail_in++;
|
||||
state->x.pos++;
|
||||
return c & 0xff;
|
||||
}
|
||||
}
|
||||
|
||||
/* no room in buffer or not initialized, use gz_write() */
|
||||
buf[0] = (unsigned char)c;
|
||||
if (gz_write(state, buf, 1) != 1)
|
||||
return -1;
|
||||
return c & 0xff;
|
||||
}
|
||||
|
||||
/* -- see zlib.h -- */
|
||||
int ZEXPORT gzputs(file, str)
|
||||
gzFile file;
|
||||
const char *str;
|
||||
{
|
||||
int ret;
|
||||
z_size_t len;
|
||||
gz_statep state;
|
||||
|
||||
/* get internal structure */
|
||||
if (file == NULL)
|
||||
return -1;
|
||||
state = (gz_statep)file;
|
||||
|
||||
/* check that we're writing and that there's no error */
|
||||
if (state->mode != GZ_WRITE || state->err != Z_OK)
|
||||
return -1;
|
||||
|
||||
/* write string */
|
||||
len = strlen(str);
|
||||
ret = gz_write(state, str, len);
|
||||
return ret == 0 && len != 0 ? -1 : ret;
|
||||
}
|
||||
|
||||
#if defined(STDC) || defined(Z_HAVE_STDARG_H)
|
||||
#include <stdarg.h>
|
||||
|
||||
/* -- see zlib.h -- */
|
||||
int ZEXPORTVA gzvprintf(gzFile file, const char *format, va_list va)
|
||||
{
|
||||
int len;
|
||||
unsigned left;
|
||||
char *next;
|
||||
gz_statep state;
|
||||
z_streamp strm;
|
||||
|
||||
/* get internal structure */
|
||||
if (file == NULL)
|
||||
return Z_STREAM_ERROR;
|
||||
state = (gz_statep)file;
|
||||
strm = &(state->strm);
|
||||
|
||||
/* check that we're writing and that there's no error */
|
||||
if (state->mode != GZ_WRITE || state->err != Z_OK)
|
||||
return Z_STREAM_ERROR;
|
||||
|
||||
/* make sure we have some buffer space */
|
||||
if (state->size == 0 && gz_init(state) == -1)
|
||||
return state->err;
|
||||
|
||||
/* check for seek request */
|
||||
if (state->seek) {
|
||||
state->seek = 0;
|
||||
if (gz_zero(state, state->skip) == -1)
|
||||
return state->err;
|
||||
}
|
||||
|
||||
/* do the printf() into the input buffer, put length in len -- the input
|
||||
buffer is double-sized just for this function, so there is guaranteed to
|
||||
be state->size bytes available after the current contents */
|
||||
if (strm->avail_in == 0)
|
||||
strm->next_in = state->in;
|
||||
next = (char *)(state->in + (strm->next_in - state->in) + strm->avail_in);
|
||||
next[state->size - 1] = 0;
|
||||
#ifdef NO_vsnprintf
|
||||
# ifdef HAS_vsprintf_void
|
||||
(void)vsprintf(next, format, va);
|
||||
for (len = 0; len < state->size; len++)
|
||||
if (next[len] == 0) break;
|
||||
# else
|
||||
len = vsprintf(next, format, va);
|
||||
# endif
|
||||
#else
|
||||
# ifdef HAS_vsnprintf_void
|
||||
(void)vsnprintf(next, state->size, format, va);
|
||||
len = strlen(next);
|
||||
# else
|
||||
len = vsnprintf(next, state->size, format, va);
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* check that printf() results fit in buffer */
|
||||
if (len == 0 || (unsigned)len >= state->size || next[state->size - 1] != 0)
|
||||
return 0;
|
||||
|
||||
/* update buffer and position, compress first half if past that */
|
||||
strm->avail_in += (unsigned)len;
|
||||
state->x.pos += len;
|
||||
if (strm->avail_in >= state->size) {
|
||||
left = strm->avail_in - state->size;
|
||||
strm->avail_in = state->size;
|
||||
if (gz_comp(state, Z_NO_FLUSH) == -1)
|
||||
return state->err;
|
||||
memcpy(state->in, state->in + state->size, left);
|
||||
strm->next_in = state->in;
|
||||
strm->avail_in = left;
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
int ZEXPORTVA gzprintf(gzFile file, const char *format, ...)
|
||||
{
|
||||
va_list va;
|
||||
int ret;
|
||||
|
||||
va_start(va, format);
|
||||
ret = gzvprintf(file, format, va);
|
||||
va_end(va);
|
||||
return ret;
|
||||
}
|
||||
|
||||
#else /* !STDC && !Z_HAVE_STDARG_H */
|
||||
|
||||
/* -- see zlib.h -- */
|
||||
int ZEXPORTVA gzprintf (file, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10,
|
||||
a11, a12, a13, a14, a15, a16, a17, a18, a19, a20)
|
||||
gzFile file;
|
||||
const char *format;
|
||||
int a1, a2, a3, a4, a5, a6, a7, a8, a9, a10,
|
||||
a11, a12, a13, a14, a15, a16, a17, a18, a19, a20;
|
||||
{
|
||||
unsigned len, left;
|
||||
char *next;
|
||||
gz_statep state;
|
||||
z_streamp strm;
|
||||
|
||||
/* get internal structure */
|
||||
if (file == NULL)
|
||||
return Z_STREAM_ERROR;
|
||||
state = (gz_statep)file;
|
||||
strm = &(state->strm);
|
||||
|
||||
/* check that can really pass pointer in ints */
|
||||
if (sizeof(int) != sizeof(void *))
|
||||
return Z_STREAM_ERROR;
|
||||
|
||||
/* check that we're writing and that there's no error */
|
||||
if (state->mode != GZ_WRITE || state->err != Z_OK)
|
||||
return Z_STREAM_ERROR;
|
||||
|
||||
/* make sure we have some buffer space */
|
||||
if (state->size == 0 && gz_init(state) == -1)
|
||||
return state->error;
|
||||
|
||||
/* check for seek request */
|
||||
if (state->seek) {
|
||||
state->seek = 0;
|
||||
if (gz_zero(state, state->skip) == -1)
|
||||
return state->error;
|
||||
}
|
||||
|
||||
/* do the printf() into the input buffer, put length in len -- the input
|
||||
buffer is double-sized just for this function, so there is guaranteed to
|
||||
be state->size bytes available after the current contents */
|
||||
if (strm->avail_in == 0)
|
||||
strm->next_in = state->in;
|
||||
next = (char *)(strm->next_in + strm->avail_in);
|
||||
next[state->size - 1] = 0;
|
||||
#ifdef NO_snprintf
|
||||
# ifdef HAS_sprintf_void
|
||||
sprintf(next, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12,
|
||||
a13, a14, a15, a16, a17, a18, a19, a20);
|
||||
for (len = 0; len < size; len++)
|
||||
if (next[len] == 0)
|
||||
break;
|
||||
# else
|
||||
len = sprintf(next, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11,
|
||||
a12, a13, a14, a15, a16, a17, a18, a19, a20);
|
||||
# endif
|
||||
#else
|
||||
# ifdef HAS_snprintf_void
|
||||
snprintf(next, state->size, format, a1, a2, a3, a4, a5, a6, a7, a8, a9,
|
||||
a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
|
||||
len = strlen(next);
|
||||
# else
|
||||
len = snprintf(next, state->size, format, a1, a2, a3, a4, a5, a6, a7, a8,
|
||||
a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* check that printf() results fit in buffer */
|
||||
if (len == 0 || len >= state->size || next[state->size - 1] != 0)
|
||||
return 0;
|
||||
|
||||
/* update buffer and position, compress first half if past that */
|
||||
strm->avail_in += len;
|
||||
state->x.pos += len;
|
||||
if (strm->avail_in >= state->size) {
|
||||
left = strm->avail_in - state->size;
|
||||
strm->avail_in = state->size;
|
||||
if (gz_comp(state, Z_NO_FLUSH) == -1)
|
||||
return state->err;
|
||||
memcpy(state->in, state->in + state->size, left);
|
||||
strm->next_in = state->in;
|
||||
strm->avail_in = left;
|
||||
}
|
||||
return (int)len;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/* -- see zlib.h -- */
|
||||
int ZEXPORT gzflush(file, flush)
|
||||
gzFile file;
|
||||
int flush;
|
||||
{
|
||||
gz_statep state;
|
||||
|
||||
/* get internal structure */
|
||||
if (file == NULL)
|
||||
return Z_STREAM_ERROR;
|
||||
state = (gz_statep)file;
|
||||
|
||||
/* check that we're writing and that there's no error */
|
||||
if (state->mode != GZ_WRITE || state->err != Z_OK)
|
||||
return Z_STREAM_ERROR;
|
||||
|
||||
/* check flush parameter */
|
||||
if (flush < 0 || flush > Z_FINISH)
|
||||
return Z_STREAM_ERROR;
|
||||
|
||||
/* check for seek request */
|
||||
if (state->seek) {
|
||||
state->seek = 0;
|
||||
if (gz_zero(state, state->skip) == -1)
|
||||
return state->err;
|
||||
}
|
||||
|
||||
/* compress remaining data with requested flush */
|
||||
(void)gz_comp(state, flush);
|
||||
return state->err;
|
||||
}
|
||||
|
||||
/* -- see zlib.h -- */
|
||||
int ZEXPORT gzsetparams(file, level, strategy)
|
||||
gzFile file;
|
||||
int level;
|
||||
int strategy;
|
||||
{
|
||||
gz_statep state;
|
||||
z_streamp strm;
|
||||
|
||||
/* get internal structure */
|
||||
if (file == NULL)
|
||||
return Z_STREAM_ERROR;
|
||||
state = (gz_statep)file;
|
||||
strm = &(state->strm);
|
||||
|
||||
/* check that we're writing and that there's no error */
|
||||
if (state->mode != GZ_WRITE || state->err != Z_OK)
|
||||
return Z_STREAM_ERROR;
|
||||
|
||||
/* if no change is requested, then do nothing */
|
||||
if (level == state->level && strategy == state->strategy)
|
||||
return Z_OK;
|
||||
|
||||
/* check for seek request */
|
||||
if (state->seek) {
|
||||
state->seek = 0;
|
||||
if (gz_zero(state, state->skip) == -1)
|
||||
return state->err;
|
||||
}
|
||||
|
||||
/* change compression parameters for subsequent input */
|
||||
if (state->size) {
|
||||
/* flush previous input with previous parameters before changing */
|
||||
if (strm->avail_in && gz_comp(state, Z_BLOCK) == -1)
|
||||
return state->err;
|
||||
deflateParams(strm, level, strategy);
|
||||
}
|
||||
state->level = level;
|
||||
state->strategy = strategy;
|
||||
return Z_OK;
|
||||
}
|
||||
|
||||
/* -- see zlib.h -- */
|
||||
int ZEXPORT gzclose_w(file)
|
||||
gzFile file;
|
||||
{
|
||||
int ret = Z_OK;
|
||||
gz_statep state;
|
||||
|
||||
/* get internal structure */
|
||||
if (file == NULL)
|
||||
return Z_STREAM_ERROR;
|
||||
state = (gz_statep)file;
|
||||
|
||||
/* check that we're writing */
|
||||
if (state->mode != GZ_WRITE)
|
||||
return Z_STREAM_ERROR;
|
||||
|
||||
/* check for seek request */
|
||||
if (state->seek) {
|
||||
state->seek = 0;
|
||||
if (gz_zero(state, state->skip) == -1)
|
||||
ret = state->err;
|
||||
}
|
||||
|
||||
/* flush, free memory, and close file */
|
||||
if (gz_comp(state, Z_FINISH) == -1)
|
||||
ret = state->err;
|
||||
if (state->size) {
|
||||
if (!state->direct) {
|
||||
(void)deflateEnd(&(state->strm));
|
||||
free(state->out);
|
||||
}
|
||||
free(state->in);
|
||||
}
|
||||
gz_error(state, Z_OK, NULL);
|
||||
free(state->path);
|
||||
if (close(state->fd) == -1)
|
||||
ret = Z_ERRNO;
|
||||
free(state);
|
||||
return ret;
|
||||
}
|
107
zlib/infback.c
@ -1,5 +1,5 @@
|
||||
/* infback.c -- inflate using a call-back interface
|
||||
* Copyright (C) 1995-2005 Mark Adler
|
||||
* Copyright (C) 1995-2016 Mark Adler
|
||||
* For conditions of distribution and use, see copyright notice in zlib.h
|
||||
*/
|
||||
|
||||
@ -42,20 +42,29 @@ int stream_size;
|
||||
return Z_STREAM_ERROR;
|
||||
strm->msg = Z_NULL; /* in case we return an error */
|
||||
if (strm->zalloc == (alloc_func)0) {
|
||||
#ifdef Z_SOLO
|
||||
return Z_STREAM_ERROR;
|
||||
#else
|
||||
strm->zalloc = zcalloc;
|
||||
strm->opaque = (voidpf)0;
|
||||
#endif
|
||||
}
|
||||
if (strm->zfree == (free_func)0) strm->zfree = zcfree;
|
||||
if (strm->zfree == (free_func)0)
|
||||
#ifdef Z_SOLO
|
||||
return Z_STREAM_ERROR;
|
||||
#else
|
||||
strm->zfree = zcfree;
|
||||
#endif
|
||||
state = (struct inflate_state FAR *)ZALLOC(strm, 1,
|
||||
sizeof(struct inflate_state));
|
||||
if (state == Z_NULL) return Z_MEM_ERROR;
|
||||
Tracev((stderr, "inflate: allocated\n"));
|
||||
strm->state = (struct internal_state FAR *)state;
|
||||
state->dmax = 32768U;
|
||||
state->wbits = windowBits;
|
||||
state->wbits = (uInt)windowBits;
|
||||
state->wsize = 1U << windowBits;
|
||||
state->window = window;
|
||||
state->write = 0;
|
||||
state->wnext = 0;
|
||||
state->whave = 0;
|
||||
return Z_OK;
|
||||
}
|
||||
@ -246,14 +255,14 @@ out_func out;
|
||||
void FAR *out_desc;
|
||||
{
|
||||
struct inflate_state FAR *state;
|
||||
unsigned char FAR *next; /* next input */
|
||||
z_const unsigned char FAR *next; /* next input */
|
||||
unsigned char FAR *put; /* next output */
|
||||
unsigned have, left; /* available input and output */
|
||||
unsigned long hold; /* bit buffer */
|
||||
unsigned bits; /* bits in bit buffer */
|
||||
unsigned copy; /* number of stored or match bytes to copy */
|
||||
unsigned char FAR *from; /* where to copy match bytes from */
|
||||
code this; /* current decoding table entry */
|
||||
code here; /* current decoding table entry */
|
||||
code last; /* parent table entry */
|
||||
unsigned len; /* length to copy for repeats, bits to drop */
|
||||
int ret; /* return code */
|
||||
@ -389,19 +398,18 @@ void FAR *out_desc;
|
||||
state->have = 0;
|
||||
while (state->have < state->nlen + state->ndist) {
|
||||
for (;;) {
|
||||
this = state->lencode[BITS(state->lenbits)];
|
||||
if ((unsigned)(this.bits) <= bits) break;
|
||||
here = state->lencode[BITS(state->lenbits)];
|
||||
if ((unsigned)(here.bits) <= bits) break;
|
||||
PULLBYTE();
|
||||
}
|
||||
if (this.val < 16) {
|
||||
NEEDBITS(this.bits);
|
||||
DROPBITS(this.bits);
|
||||
state->lens[state->have++] = this.val;
|
||||
if (here.val < 16) {
|
||||
DROPBITS(here.bits);
|
||||
state->lens[state->have++] = here.val;
|
||||
}
|
||||
else {
|
||||
if (this.val == 16) {
|
||||
NEEDBITS(this.bits + 2);
|
||||
DROPBITS(this.bits);
|
||||
if (here.val == 16) {
|
||||
NEEDBITS(here.bits + 2);
|
||||
DROPBITS(here.bits);
|
||||
if (state->have == 0) {
|
||||
strm->msg = (char *)"invalid bit length repeat";
|
||||
state->mode = BAD;
|
||||
@ -411,16 +419,16 @@ void FAR *out_desc;
|
||||
copy = 3 + BITS(2);
|
||||
DROPBITS(2);
|
||||
}
|
||||
else if (this.val == 17) {
|
||||
NEEDBITS(this.bits + 3);
|
||||
DROPBITS(this.bits);
|
||||
else if (here.val == 17) {
|
||||
NEEDBITS(here.bits + 3);
|
||||
DROPBITS(here.bits);
|
||||
len = 0;
|
||||
copy = 3 + BITS(3);
|
||||
DROPBITS(3);
|
||||
}
|
||||
else {
|
||||
NEEDBITS(this.bits + 7);
|
||||
DROPBITS(this.bits);
|
||||
NEEDBITS(here.bits + 7);
|
||||
DROPBITS(here.bits);
|
||||
len = 0;
|
||||
copy = 11 + BITS(7);
|
||||
DROPBITS(7);
|
||||
@ -438,7 +446,16 @@ void FAR *out_desc;
|
||||
/* handle error breaks in while */
|
||||
if (state->mode == BAD) break;
|
||||
|
||||
/* build code tables */
|
||||
/* check for end-of-block code (better have one) */
|
||||
if (state->lens[256] == 0) {
|
||||
strm->msg = (char *)"invalid code -- missing end-of-block";
|
||||
state->mode = BAD;
|
||||
break;
|
||||
}
|
||||
|
||||
/* build code tables -- note: do not change the lenbits or distbits
|
||||
values here (9 and 6) without reading the comments in inftrees.h
|
||||
concerning the ENOUGH constants, which depend on those values */
|
||||
state->next = state->codes;
|
||||
state->lencode = (code const FAR *)(state->next);
|
||||
state->lenbits = 9;
|
||||
@ -474,28 +491,28 @@ void FAR *out_desc;
|
||||
|
||||
/* get a literal, length, or end-of-block code */
|
||||
for (;;) {
|
||||
this = state->lencode[BITS(state->lenbits)];
|
||||
if ((unsigned)(this.bits) <= bits) break;
|
||||
here = state->lencode[BITS(state->lenbits)];
|
||||
if ((unsigned)(here.bits) <= bits) break;
|
||||
PULLBYTE();
|
||||
}
|
||||
if (this.op && (this.op & 0xf0) == 0) {
|
||||
last = this;
|
||||
if (here.op && (here.op & 0xf0) == 0) {
|
||||
last = here;
|
||||
for (;;) {
|
||||
this = state->lencode[last.val +
|
||||
here = state->lencode[last.val +
|
||||
(BITS(last.bits + last.op) >> last.bits)];
|
||||
if ((unsigned)(last.bits + this.bits) <= bits) break;
|
||||
if ((unsigned)(last.bits + here.bits) <= bits) break;
|
||||
PULLBYTE();
|
||||
}
|
||||
DROPBITS(last.bits);
|
||||
}
|
||||
DROPBITS(this.bits);
|
||||
state->length = (unsigned)this.val;
|
||||
DROPBITS(here.bits);
|
||||
state->length = (unsigned)here.val;
|
||||
|
||||
/* process literal */
|
||||
if (this.op == 0) {
|
||||
Tracevv((stderr, this.val >= 0x20 && this.val < 0x7f ?
|
||||
if (here.op == 0) {
|
||||
Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ?
|
||||
"inflate: literal '%c'\n" :
|
||||
"inflate: literal 0x%02x\n", this.val));
|
||||
"inflate: literal 0x%02x\n", here.val));
|
||||
ROOM();
|
||||
*put++ = (unsigned char)(state->length);
|
||||
left--;
|
||||
@ -504,21 +521,21 @@ void FAR *out_desc;
|
||||
}
|
||||
|
||||
/* process end of block */
|
||||
if (this.op & 32) {
|
||||
if (here.op & 32) {
|
||||
Tracevv((stderr, "inflate: end of block\n"));
|
||||
state->mode = TYPE;
|
||||
break;
|
||||
}
|
||||
|
||||
/* invalid code */
|
||||
if (this.op & 64) {
|
||||
if (here.op & 64) {
|
||||
strm->msg = (char *)"invalid literal/length code";
|
||||
state->mode = BAD;
|
||||
break;
|
||||
}
|
||||
|
||||
/* length code -- get extra bits, if any */
|
||||
state->extra = (unsigned)(this.op) & 15;
|
||||
state->extra = (unsigned)(here.op) & 15;
|
||||
if (state->extra != 0) {
|
||||
NEEDBITS(state->extra);
|
||||
state->length += BITS(state->extra);
|
||||
@ -528,30 +545,30 @@ void FAR *out_desc;
|
||||
|
||||
/* get distance code */
|
||||
for (;;) {
|
||||
this = state->distcode[BITS(state->distbits)];
|
||||
if ((unsigned)(this.bits) <= bits) break;
|
||||
here = state->distcode[BITS(state->distbits)];
|
||||
if ((unsigned)(here.bits) <= bits) break;
|
||||
PULLBYTE();
|
||||
}
|
||||
if ((this.op & 0xf0) == 0) {
|
||||
last = this;
|
||||
if ((here.op & 0xf0) == 0) {
|
||||
last = here;
|
||||
for (;;) {
|
||||
this = state->distcode[last.val +
|
||||
here = state->distcode[last.val +
|
||||
(BITS(last.bits + last.op) >> last.bits)];
|
||||
if ((unsigned)(last.bits + this.bits) <= bits) break;
|
||||
if ((unsigned)(last.bits + here.bits) <= bits) break;
|
||||
PULLBYTE();
|
||||
}
|
||||
DROPBITS(last.bits);
|
||||
}
|
||||
DROPBITS(this.bits);
|
||||
if (this.op & 64) {
|
||||
DROPBITS(here.bits);
|
||||
if (here.op & 64) {
|
||||
strm->msg = (char *)"invalid distance code";
|
||||
state->mode = BAD;
|
||||
break;
|
||||
}
|
||||
state->offset = (unsigned)this.val;
|
||||
state->offset = (unsigned)here.val;
|
||||
|
||||
/* get distance extra bits, if any */
|
||||
state->extra = (unsigned)(this.op) & 15;
|
||||
state->extra = (unsigned)(here.op) & 15;
|
||||
if (state->extra != 0) {
|
||||
NEEDBITS(state->extra);
|
||||
state->offset += BITS(state->extra);
|
||||
|
159
zlib/inffast.c
@ -1,5 +1,5 @@
|
||||
/* inffast.c -- fast decoding
|
||||
* Copyright (C) 1995-2004 Mark Adler
|
||||
* Copyright (C) 1995-2017 Mark Adler
|
||||
* For conditions of distribution and use, see copyright notice in zlib.h
|
||||
*/
|
||||
|
||||
@ -8,26 +8,9 @@
|
||||
#include "inflate.h"
|
||||
#include "inffast.h"
|
||||
|
||||
#ifndef ASMINF
|
||||
|
||||
/* Allow machine dependent optimization for post-increment or pre-increment.
|
||||
Based on testing to date,
|
||||
Pre-increment preferred for:
|
||||
- PowerPC G3 (Adler)
|
||||
- MIPS R5000 (Randers-Pehrson)
|
||||
Post-increment preferred for:
|
||||
- none
|
||||
No measurable difference:
|
||||
- Pentium III (Anderson)
|
||||
- M68060 (Nikl)
|
||||
*/
|
||||
#ifdef POSTINC
|
||||
# define OFF 0
|
||||
# define PUP(a) *(a)++
|
||||
#ifdef ASMINF
|
||||
# pragma message("Assembler code may have bugs -- use at your own risk")
|
||||
#else
|
||||
# define OFF 1
|
||||
# define PUP(a) *++(a)
|
||||
#endif
|
||||
|
||||
/*
|
||||
Decode literal, length, and distance codes and write out the resulting
|
||||
@ -64,13 +47,13 @@
|
||||
requires strm->avail_out >= 258 for each loop to avoid checking for
|
||||
output space.
|
||||
*/
|
||||
void inflate_fast(strm, start)
|
||||
void ZLIB_INTERNAL inflate_fast(strm, start)
|
||||
z_streamp strm;
|
||||
unsigned start; /* inflate()'s starting value for strm->avail_out */
|
||||
{
|
||||
struct inflate_state FAR *state;
|
||||
unsigned char FAR *in; /* local strm->next_in */
|
||||
unsigned char FAR *last; /* while in < last, enough input available */
|
||||
z_const unsigned char FAR *in; /* local strm->next_in */
|
||||
z_const unsigned char FAR *last; /* have enough input while in < last */
|
||||
unsigned char FAR *out; /* local strm->next_out */
|
||||
unsigned char FAR *beg; /* inflate()'s initial strm->next_out */
|
||||
unsigned char FAR *end; /* while out < end, enough space available */
|
||||
@ -79,7 +62,7 @@ unsigned start; /* inflate()'s starting value for strm->avail_out */
|
||||
#endif
|
||||
unsigned wsize; /* window size or zero if not using window */
|
||||
unsigned whave; /* valid bytes in the window */
|
||||
unsigned write; /* window write index */
|
||||
unsigned wnext; /* window write index */
|
||||
unsigned char FAR *window; /* allocated sliding window, if wsize != 0 */
|
||||
unsigned long hold; /* local strm->hold */
|
||||
unsigned bits; /* local strm->bits */
|
||||
@ -87,7 +70,7 @@ unsigned start; /* inflate()'s starting value for strm->avail_out */
|
||||
code const FAR *dcode; /* local strm->distcode */
|
||||
unsigned lmask; /* mask for first level of length codes */
|
||||
unsigned dmask; /* mask for first level of distance codes */
|
||||
code this; /* retrieved table entry */
|
||||
code here; /* retrieved table entry */
|
||||
unsigned op; /* code bits, operation, extra bits, or */
|
||||
/* window position, window bytes to copy */
|
||||
unsigned len; /* match length, unused bytes */
|
||||
@ -96,9 +79,9 @@ unsigned start; /* inflate()'s starting value for strm->avail_out */
|
||||
|
||||
/* copy state to local variables */
|
||||
state = (struct inflate_state FAR *)strm->state;
|
||||
in = strm->next_in - OFF;
|
||||
in = strm->next_in;
|
||||
last = in + (strm->avail_in - 5);
|
||||
out = strm->next_out - OFF;
|
||||
out = strm->next_out;
|
||||
beg = out - (start - strm->avail_out);
|
||||
end = out + (strm->avail_out - 257);
|
||||
#ifdef INFLATE_STRICT
|
||||
@ -106,7 +89,7 @@ unsigned start; /* inflate()'s starting value for strm->avail_out */
|
||||
#endif
|
||||
wsize = state->wsize;
|
||||
whave = state->whave;
|
||||
write = state->write;
|
||||
wnext = state->wnext;
|
||||
window = state->window;
|
||||
hold = state->hold;
|
||||
bits = state->bits;
|
||||
@ -119,29 +102,29 @@ unsigned start; /* inflate()'s starting value for strm->avail_out */
|
||||
input data or output space */
|
||||
do {
|
||||
if (bits < 15) {
|
||||
hold += (unsigned long)(PUP(in)) << bits;
|
||||
hold += (unsigned long)(*in++) << bits;
|
||||
bits += 8;
|
||||
hold += (unsigned long)(PUP(in)) << bits;
|
||||
hold += (unsigned long)(*in++) << bits;
|
||||
bits += 8;
|
||||
}
|
||||
this = lcode[hold & lmask];
|
||||
here = lcode[hold & lmask];
|
||||
dolen:
|
||||
op = (unsigned)(this.bits);
|
||||
op = (unsigned)(here.bits);
|
||||
hold >>= op;
|
||||
bits -= op;
|
||||
op = (unsigned)(this.op);
|
||||
op = (unsigned)(here.op);
|
||||
if (op == 0) { /* literal */
|
||||
Tracevv((stderr, this.val >= 0x20 && this.val < 0x7f ?
|
||||
Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ?
|
||||
"inflate: literal '%c'\n" :
|
||||
"inflate: literal 0x%02x\n", this.val));
|
||||
PUP(out) = (unsigned char)(this.val);
|
||||
"inflate: literal 0x%02x\n", here.val));
|
||||
*out++ = (unsigned char)(here.val);
|
||||
}
|
||||
else if (op & 16) { /* length base */
|
||||
len = (unsigned)(this.val);
|
||||
len = (unsigned)(here.val);
|
||||
op &= 15; /* number of extra bits */
|
||||
if (op) {
|
||||
if (bits < op) {
|
||||
hold += (unsigned long)(PUP(in)) << bits;
|
||||
hold += (unsigned long)(*in++) << bits;
|
||||
bits += 8;
|
||||
}
|
||||
len += (unsigned)hold & ((1U << op) - 1);
|
||||
@ -150,25 +133,25 @@ unsigned start; /* inflate()'s starting value for strm->avail_out */
|
||||
}
|
||||
Tracevv((stderr, "inflate: length %u\n", len));
|
||||
if (bits < 15) {
|
||||
hold += (unsigned long)(PUP(in)) << bits;
|
||||
hold += (unsigned long)(*in++) << bits;
|
||||
bits += 8;
|
||||
hold += (unsigned long)(PUP(in)) << bits;
|
||||
hold += (unsigned long)(*in++) << bits;
|
||||
bits += 8;
|
||||
}
|
||||
this = dcode[hold & dmask];
|
||||
here = dcode[hold & dmask];
|
||||
dodist:
|
||||
op = (unsigned)(this.bits);
|
||||
op = (unsigned)(here.bits);
|
||||
hold >>= op;
|
||||
bits -= op;
|
||||
op = (unsigned)(this.op);
|
||||
op = (unsigned)(here.op);
|
||||
if (op & 16) { /* distance base */
|
||||
dist = (unsigned)(this.val);
|
||||
dist = (unsigned)(here.val);
|
||||
op &= 15; /* number of extra bits */
|
||||
if (bits < op) {
|
||||
hold += (unsigned long)(PUP(in)) << bits;
|
||||
hold += (unsigned long)(*in++) << bits;
|
||||
bits += 8;
|
||||
if (bits < op) {
|
||||
hold += (unsigned long)(PUP(in)) << bits;
|
||||
hold += (unsigned long)(*in++) << bits;
|
||||
bits += 8;
|
||||
}
|
||||
}
|
||||
@ -187,79 +170,101 @@ unsigned start; /* inflate()'s starting value for strm->avail_out */
|
||||
if (dist > op) { /* see if copy from window */
|
||||
op = dist - op; /* distance back in window */
|
||||
if (op > whave) {
|
||||
strm->msg = (char *)"invalid distance too far back";
|
||||
state->mode = BAD;
|
||||
break;
|
||||
if (state->sane) {
|
||||
strm->msg =
|
||||
(char *)"invalid distance too far back";
|
||||
state->mode = BAD;
|
||||
break;
|
||||
}
|
||||
#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR
|
||||
if (len <= op - whave) {
|
||||
do {
|
||||
*out++ = 0;
|
||||
} while (--len);
|
||||
continue;
|
||||
}
|
||||
len -= op - whave;
|
||||
do {
|
||||
*out++ = 0;
|
||||
} while (--op > whave);
|
||||
if (op == 0) {
|
||||
from = out - dist;
|
||||
do {
|
||||
*out++ = *from++;
|
||||
} while (--len);
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
from = window - OFF;
|
||||
if (write == 0) { /* very common case */
|
||||
from = window;
|
||||
if (wnext == 0) { /* very common case */
|
||||
from += wsize - op;
|
||||
if (op < len) { /* some from window */
|
||||
len -= op;
|
||||
do {
|
||||
PUP(out) = PUP(from);
|
||||
*out++ = *from++;
|
||||
} while (--op);
|
||||
from = out - dist; /* rest from output */
|
||||
}
|
||||
}
|
||||
else if (write < op) { /* wrap around window */
|
||||
from += wsize + write - op;
|
||||
op -= write;
|
||||
else if (wnext < op) { /* wrap around window */
|
||||
from += wsize + wnext - op;
|
||||
op -= wnext;
|
||||
if (op < len) { /* some from end of window */
|
||||
len -= op;
|
||||
do {
|
||||
PUP(out) = PUP(from);
|
||||
*out++ = *from++;
|
||||
} while (--op);
|
||||
from = window - OFF;
|
||||
if (write < len) { /* some from start of window */
|
||||
op = write;
|
||||
from = window;
|
||||
if (wnext < len) { /* some from start of window */
|
||||
op = wnext;
|
||||
len -= op;
|
||||
do {
|
||||
PUP(out) = PUP(from);
|
||||
*out++ = *from++;
|
||||
} while (--op);
|
||||
from = out - dist; /* rest from output */
|
||||
}
|
||||
}
|
||||
}
|
||||
else { /* contiguous in window */
|
||||
from += write - op;
|
||||
from += wnext - op;
|
||||
if (op < len) { /* some from window */
|
||||
len -= op;
|
||||
do {
|
||||
PUP(out) = PUP(from);
|
||||
*out++ = *from++;
|
||||
} while (--op);
|
||||
from = out - dist; /* rest from output */
|
||||
}
|
||||
}
|
||||
while (len > 2) {
|
||||
PUP(out) = PUP(from);
|
||||
PUP(out) = PUP(from);
|
||||
PUP(out) = PUP(from);
|
||||
*out++ = *from++;
|
||||
*out++ = *from++;
|
||||
*out++ = *from++;
|
||||
len -= 3;
|
||||
}
|
||||
if (len) {
|
||||
PUP(out) = PUP(from);
|
||||
*out++ = *from++;
|
||||
if (len > 1)
|
||||
PUP(out) = PUP(from);
|
||||
*out++ = *from++;
|
||||
}
|
||||
}
|
||||
else {
|
||||
from = out - dist; /* copy direct from output */
|
||||
do { /* minimum length is three */
|
||||
PUP(out) = PUP(from);
|
||||
PUP(out) = PUP(from);
|
||||
PUP(out) = PUP(from);
|
||||
*out++ = *from++;
|
||||
*out++ = *from++;
|
||||
*out++ = *from++;
|
||||
len -= 3;
|
||||
} while (len > 2);
|
||||
if (len) {
|
||||
PUP(out) = PUP(from);
|
||||
*out++ = *from++;
|
||||
if (len > 1)
|
||||
PUP(out) = PUP(from);
|
||||
*out++ = *from++;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ((op & 64) == 0) { /* 2nd level distance code */
|
||||
this = dcode[this.val + (hold & ((1U << op) - 1))];
|
||||
here = dcode[here.val + (hold & ((1U << op) - 1))];
|
||||
goto dodist;
|
||||
}
|
||||
else {
|
||||
@ -269,7 +274,7 @@ unsigned start; /* inflate()'s starting value for strm->avail_out */
|
||||
}
|
||||
}
|
||||
else if ((op & 64) == 0) { /* 2nd level length code */
|
||||
this = lcode[this.val + (hold & ((1U << op) - 1))];
|
||||
here = lcode[here.val + (hold & ((1U << op) - 1))];
|
||||
goto dolen;
|
||||
}
|
||||
else if (op & 32) { /* end-of-block */
|
||||
@ -291,8 +296,8 @@ unsigned start; /* inflate()'s starting value for strm->avail_out */
|
||||
hold &= (1U << bits) - 1;
|
||||
|
||||
/* update state and return */
|
||||
strm->next_in = in + OFF;
|
||||
strm->next_out = out + OFF;
|
||||
strm->next_in = in;
|
||||
strm->next_out = out;
|
||||
strm->avail_in = (unsigned)(in < last ? 5 + (last - in) : 5 - (in - last));
|
||||
strm->avail_out = (unsigned)(out < end ?
|
||||
257 + (end - out) : 257 - (out - end));
|
||||
@ -305,7 +310,7 @@ unsigned start; /* inflate()'s starting value for strm->avail_out */
|
||||
inflate_fast() speedups that turned out slower (on a PowerPC G3 750CXe):
|
||||
- Using bit fields for code structure
|
||||
- Different op definition to avoid & for extra bits (do & for table bits)
|
||||
- Three separate decoding do-loops for direct, window, and write == 0
|
||||
- Three separate decoding do-loops for direct, window, and wnext == 0
|
||||
- Special case for distance > 1 copies to do overlapped load and store copy
|
||||
- Explicit branch predictions (based on measured branch probabilities)
|
||||
- Deferring match copy and interspersed it with decoding subsequent codes
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* inffast.h -- header to use inffast.c
|
||||
* Copyright (C) 1995-2003 Mark Adler
|
||||
* Copyright (C) 1995-2003, 2010 Mark Adler
|
||||
* For conditions of distribution and use, see copyright notice in zlib.h
|
||||
*/
|
||||
|
||||
@ -8,4 +8,4 @@
|
||||
subject to change. Applications should only use zlib.h.
|
||||
*/
|
||||
|
||||
void inflate_fast OF((z_streamp strm, unsigned start));
|
||||
void ZLIB_INTERNAL inflate_fast OF((z_streamp strm, unsigned start));
|
||||
|
@ -2,9 +2,9 @@
|
||||
* Generated automatically by makefixed().
|
||||
*/
|
||||
|
||||
/* WARNING: this file should *not* be used by applications. It
|
||||
is part of the implementation of the compression library and
|
||||
is subject to change. Applications should only use zlib.h.
|
||||
/* WARNING: this file should *not* be used by applications.
|
||||
It is part of the implementation of this library and is
|
||||
subject to change. Applications should only use zlib.h.
|
||||
*/
|
||||
|
||||
static const code lenfix[512] = {
|
||||
|
585
zlib/inflate.c
@ -1,5 +1,5 @@
|
||||
/* inflate.c -- zlib decompression
|
||||
* Copyright (C) 1995-2005 Mark Adler
|
||||
* Copyright (C) 1995-2016 Mark Adler
|
||||
* For conditions of distribution and use, see copyright notice in zlib.h
|
||||
*/
|
||||
|
||||
@ -45,7 +45,7 @@
|
||||
* - Rearrange window copies in inflate_fast() for speed and simplification
|
||||
* - Unroll last copy for window match in inflate_fast()
|
||||
* - Use local copies of window variables in inflate_fast() for speed
|
||||
* - Pull out common write == 0 case for speed in inflate_fast()
|
||||
* - Pull out common wnext == 0 case for speed in inflate_fast()
|
||||
* - Make op and len in inflate_fast() unsigned for consistency
|
||||
* - Add FAR to lcode and dcode declarations in inflate_fast()
|
||||
* - Simplified bad distance check in inflate_fast()
|
||||
@ -92,37 +92,156 @@
|
||||
#endif
|
||||
|
||||
/* function prototypes */
|
||||
local int inflateStateCheck OF((z_streamp strm));
|
||||
local void fixedtables OF((struct inflate_state FAR *state));
|
||||
local int updatewindow OF((z_streamp strm, unsigned out));
|
||||
local int updatewindow OF((z_streamp strm, const unsigned char FAR *end,
|
||||
unsigned copy));
|
||||
#ifdef BUILDFIXED
|
||||
void makefixed OF((void));
|
||||
#endif
|
||||
local unsigned syncsearch OF((unsigned FAR *have, unsigned char FAR *buf,
|
||||
local unsigned syncsearch OF((unsigned FAR *have, const unsigned char FAR *buf,
|
||||
unsigned len));
|
||||
|
||||
local int inflateStateCheck(strm)
|
||||
z_streamp strm;
|
||||
{
|
||||
struct inflate_state FAR *state;
|
||||
if (strm == Z_NULL ||
|
||||
strm->zalloc == (alloc_func)0 || strm->zfree == (free_func)0)
|
||||
return 1;
|
||||
state = (struct inflate_state FAR *)strm->state;
|
||||
if (state == Z_NULL || state->strm != strm ||
|
||||
state->mode < HEAD || state->mode > SYNC)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ZEXPORT inflateResetKeep(strm)
|
||||
z_streamp strm;
|
||||
{
|
||||
struct inflate_state FAR *state;
|
||||
|
||||
if (inflateStateCheck(strm)) return Z_STREAM_ERROR;
|
||||
state = (struct inflate_state FAR *)strm->state;
|
||||
strm->total_in = strm->total_out = state->total = 0;
|
||||
strm->msg = Z_NULL;
|
||||
if (state->wrap) /* to support ill-conceived Java test suite */
|
||||
strm->adler = state->wrap & 1;
|
||||
state->mode = HEAD;
|
||||
state->last = 0;
|
||||
state->havedict = 0;
|
||||
state->dmax = 32768U;
|
||||
state->head = Z_NULL;
|
||||
state->hold = 0;
|
||||
state->bits = 0;
|
||||
state->lencode = state->distcode = state->next = state->codes;
|
||||
state->sane = 1;
|
||||
state->back = -1;
|
||||
Tracev((stderr, "inflate: reset\n"));
|
||||
return Z_OK;
|
||||
}
|
||||
|
||||
int ZEXPORT inflateReset(strm)
|
||||
z_streamp strm;
|
||||
{
|
||||
struct inflate_state FAR *state;
|
||||
|
||||
if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
|
||||
if (inflateStateCheck(strm)) return Z_STREAM_ERROR;
|
||||
state = (struct inflate_state FAR *)strm->state;
|
||||
strm->total_in = strm->total_out = state->total = 0;
|
||||
strm->msg = Z_NULL;
|
||||
strm->adler = 1; /* to support ill-conceived Java test suite */
|
||||
state->mode = HEAD;
|
||||
state->last = 0;
|
||||
state->havedict = 0;
|
||||
state->dmax = 32768U;
|
||||
state->head = Z_NULL;
|
||||
state->wsize = 0;
|
||||
state->whave = 0;
|
||||
state->write = 0;
|
||||
state->hold = 0;
|
||||
state->bits = 0;
|
||||
state->lencode = state->distcode = state->next = state->codes;
|
||||
Tracev((stderr, "inflate: reset\n"));
|
||||
return Z_OK;
|
||||
state->wnext = 0;
|
||||
return inflateResetKeep(strm);
|
||||
}
|
||||
|
||||
int ZEXPORT inflateReset2(strm, windowBits)
|
||||
z_streamp strm;
|
||||
int windowBits;
|
||||
{
|
||||
int wrap;
|
||||
struct inflate_state FAR *state;
|
||||
|
||||
/* get the state */
|
||||
if (inflateStateCheck(strm)) return Z_STREAM_ERROR;
|
||||
state = (struct inflate_state FAR *)strm->state;
|
||||
|
||||
/* extract wrap request from windowBits parameter */
|
||||
if (windowBits < 0) {
|
||||
wrap = 0;
|
||||
windowBits = -windowBits;
|
||||
}
|
||||
else {
|
||||
wrap = (windowBits >> 4) + 5;
|
||||
#ifdef GUNZIP
|
||||
if (windowBits < 48)
|
||||
windowBits &= 15;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* set number of window bits, free window if different */
|
||||
if (windowBits && (windowBits < 8 || windowBits > 15))
|
||||
return Z_STREAM_ERROR;
|
||||
if (state->window != Z_NULL && state->wbits != (unsigned)windowBits) {
|
||||
ZFREE(strm, state->window);
|
||||
state->window = Z_NULL;
|
||||
}
|
||||
|
||||
/* update state and reset the rest of it */
|
||||
state->wrap = wrap;
|
||||
state->wbits = (unsigned)windowBits;
|
||||
return inflateReset(strm);
|
||||
}
|
||||
|
||||
int ZEXPORT inflateInit2_(strm, windowBits, version, stream_size)
|
||||
z_streamp strm;
|
||||
int windowBits;
|
||||
const char *version;
|
||||
int stream_size;
|
||||
{
|
||||
int ret;
|
||||
struct inflate_state FAR *state;
|
||||
|
||||
if (version == Z_NULL || version[0] != ZLIB_VERSION[0] ||
|
||||
stream_size != (int)(sizeof(z_stream)))
|
||||
return Z_VERSION_ERROR;
|
||||
if (strm == Z_NULL) return Z_STREAM_ERROR;
|
||||
strm->msg = Z_NULL; /* in case we return an error */
|
||||
if (strm->zalloc == (alloc_func)0) {
|
||||
#ifdef Z_SOLO
|
||||
return Z_STREAM_ERROR;
|
||||
#else
|
||||
strm->zalloc = zcalloc;
|
||||
strm->opaque = (voidpf)0;
|
||||
#endif
|
||||
}
|
||||
if (strm->zfree == (free_func)0)
|
||||
#ifdef Z_SOLO
|
||||
return Z_STREAM_ERROR;
|
||||
#else
|
||||
strm->zfree = zcfree;
|
||||
#endif
|
||||
state = (struct inflate_state FAR *)
|
||||
ZALLOC(strm, 1, sizeof(struct inflate_state));
|
||||
if (state == Z_NULL) return Z_MEM_ERROR;
|
||||
Tracev((stderr, "inflate: allocated\n"));
|
||||
strm->state = (struct internal_state FAR *)state;
|
||||
state->strm = strm;
|
||||
state->window = Z_NULL;
|
||||
state->mode = HEAD; /* to pass state test in inflateReset2() */
|
||||
ret = inflateReset2(strm, windowBits);
|
||||
if (ret != Z_OK) {
|
||||
ZFREE(strm, state);
|
||||
strm->state = Z_NULL;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ZEXPORT inflateInit_(strm, version, stream_size)
|
||||
z_streamp strm;
|
||||
const char *version;
|
||||
int stream_size;
|
||||
{
|
||||
return inflateInit2_(strm, DEF_WBITS, version, stream_size);
|
||||
}
|
||||
|
||||
int ZEXPORT inflatePrime(strm, bits, value)
|
||||
@ -132,66 +251,20 @@ int value;
|
||||
{
|
||||
struct inflate_state FAR *state;
|
||||
|
||||
if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
|
||||
if (inflateStateCheck(strm)) return Z_STREAM_ERROR;
|
||||
state = (struct inflate_state FAR *)strm->state;
|
||||
if (bits > 16 || state->bits + bits > 32) return Z_STREAM_ERROR;
|
||||
if (bits < 0) {
|
||||
state->hold = 0;
|
||||
state->bits = 0;
|
||||
return Z_OK;
|
||||
}
|
||||
if (bits > 16 || state->bits + (uInt)bits > 32) return Z_STREAM_ERROR;
|
||||
value &= (1L << bits) - 1;
|
||||
state->hold += value << state->bits;
|
||||
state->bits += bits;
|
||||
state->hold += (unsigned)value << state->bits;
|
||||
state->bits += (uInt)bits;
|
||||
return Z_OK;
|
||||
}
|
||||
|
||||
int ZEXPORT inflateInit2_(strm, windowBits, version, stream_size)
|
||||
z_streamp strm;
|
||||
int windowBits;
|
||||
const char *version;
|
||||
int stream_size;
|
||||
{
|
||||
struct inflate_state FAR *state;
|
||||
|
||||
if (version == Z_NULL || version[0] != ZLIB_VERSION[0] ||
|
||||
stream_size != (int)(sizeof(z_stream)))
|
||||
return Z_VERSION_ERROR;
|
||||
if (strm == Z_NULL) return Z_STREAM_ERROR;
|
||||
strm->msg = Z_NULL; /* in case we return an error */
|
||||
if (strm->zalloc == (alloc_func)0) {
|
||||
strm->zalloc = zcalloc;
|
||||
strm->opaque = (voidpf)0;
|
||||
}
|
||||
if (strm->zfree == (free_func)0) strm->zfree = zcfree;
|
||||
state = (struct inflate_state FAR *)
|
||||
ZALLOC(strm, 1, sizeof(struct inflate_state));
|
||||
if (state == Z_NULL) return Z_MEM_ERROR;
|
||||
Tracev((stderr, "inflate: allocated\n"));
|
||||
strm->state = (struct internal_state FAR *)state;
|
||||
if (windowBits < 0) {
|
||||
state->wrap = 0;
|
||||
windowBits = -windowBits;
|
||||
}
|
||||
else {
|
||||
state->wrap = (windowBits >> 4) + 1;
|
||||
#ifdef GUNZIP
|
||||
if (windowBits < 48) windowBits &= 15;
|
||||
#endif
|
||||
}
|
||||
if (windowBits < 8 || windowBits > 15) {
|
||||
ZFREE(strm, state);
|
||||
strm->state = Z_NULL;
|
||||
return Z_STREAM_ERROR;
|
||||
}
|
||||
state->wbits = (unsigned)windowBits;
|
||||
state->window = Z_NULL;
|
||||
return inflateReset(strm);
|
||||
}
|
||||
|
||||
int ZEXPORT inflateInit_(strm, version, stream_size)
|
||||
z_streamp strm;
|
||||
const char *version;
|
||||
int stream_size;
|
||||
{
|
||||
return inflateInit2_(strm, DEF_WBITS, version, stream_size);
|
||||
}
|
||||
|
||||
/*
|
||||
Return state with length and distance decoding tables and index sizes set to
|
||||
fixed code decoding. Normally this returns fixed tables from inffixed.h.
|
||||
@ -286,8 +359,8 @@ void makefixed()
|
||||
low = 0;
|
||||
for (;;) {
|
||||
if ((low % 7) == 0) printf("\n ");
|
||||
printf("{%u,%u,%d}", state.lencode[low].op, state.lencode[low].bits,
|
||||
state.lencode[low].val);
|
||||
printf("{%u,%u,%d}", (low & 127) == 99 ? 64 : state.lencode[low].op,
|
||||
state.lencode[low].bits, state.lencode[low].val);
|
||||
if (++low == size) break;
|
||||
putchar(',');
|
||||
}
|
||||
@ -320,12 +393,13 @@ void makefixed()
|
||||
output will fall in the output data, making match copies simpler and faster.
|
||||
The advantage may be dependent on the size of the processor's data caches.
|
||||
*/
|
||||
local int updatewindow(strm, out)
|
||||
local int updatewindow(strm, end, copy)
|
||||
z_streamp strm;
|
||||
unsigned out;
|
||||
const Bytef *end;
|
||||
unsigned copy;
|
||||
{
|
||||
struct inflate_state FAR *state;
|
||||
unsigned copy, dist;
|
||||
unsigned dist;
|
||||
|
||||
state = (struct inflate_state FAR *)strm->state;
|
||||
|
||||
@ -340,30 +414,29 @@ unsigned out;
|
||||
/* if window not in use yet, initialize */
|
||||
if (state->wsize == 0) {
|
||||
state->wsize = 1U << state->wbits;
|
||||
state->write = 0;
|
||||
state->wnext = 0;
|
||||
state->whave = 0;
|
||||
}
|
||||
|
||||
/* copy state->wsize or less output bytes into the circular window */
|
||||
copy = out - strm->avail_out;
|
||||
if (copy >= state->wsize) {
|
||||
zmemcpy(state->window, strm->next_out - state->wsize, state->wsize);
|
||||
state->write = 0;
|
||||
zmemcpy(state->window, end - state->wsize, state->wsize);
|
||||
state->wnext = 0;
|
||||
state->whave = state->wsize;
|
||||
}
|
||||
else {
|
||||
dist = state->wsize - state->write;
|
||||
dist = state->wsize - state->wnext;
|
||||
if (dist > copy) dist = copy;
|
||||
zmemcpy(state->window + state->write, strm->next_out - copy, dist);
|
||||
zmemcpy(state->window + state->wnext, end - copy, dist);
|
||||
copy -= dist;
|
||||
if (copy) {
|
||||
zmemcpy(state->window, strm->next_out - copy, copy);
|
||||
state->write = copy;
|
||||
zmemcpy(state->window, end - copy, copy);
|
||||
state->wnext = copy;
|
||||
state->whave = state->wsize;
|
||||
}
|
||||
else {
|
||||
state->write += dist;
|
||||
if (state->write == state->wsize) state->write = 0;
|
||||
state->wnext += dist;
|
||||
if (state->wnext == state->wsize) state->wnext = 0;
|
||||
if (state->whave < state->wsize) state->whave += dist;
|
||||
}
|
||||
}
|
||||
@ -464,11 +537,6 @@ unsigned out;
|
||||
bits -= bits & 7; \
|
||||
} while (0)
|
||||
|
||||
/* Reverse the bytes in a 32-bit value */
|
||||
#define REVERSE(q) \
|
||||
((((q) >> 24) & 0xff) + (((q) >> 8) & 0xff00) + \
|
||||
(((q) & 0xff00) << 8) + (((q) & 0xff) << 24))
|
||||
|
||||
/*
|
||||
inflate() uses a state machine to process as much input data and generate as
|
||||
much output data as possible before returning. The state machine is
|
||||
@ -556,7 +624,7 @@ z_streamp strm;
|
||||
int flush;
|
||||
{
|
||||
struct inflate_state FAR *state;
|
||||
unsigned char FAR *next; /* next input */
|
||||
z_const unsigned char FAR *next; /* next input */
|
||||
unsigned char FAR *put; /* next output */
|
||||
unsigned have, left; /* available input and output */
|
||||
unsigned long hold; /* bit buffer */
|
||||
@ -564,7 +632,7 @@ int flush;
|
||||
unsigned in, out; /* save starting available input and output */
|
||||
unsigned copy; /* number of stored or match bytes to copy */
|
||||
unsigned char FAR *from; /* where to copy match bytes from */
|
||||
code this; /* current decoding table entry */
|
||||
code here; /* current decoding table entry */
|
||||
code last; /* parent table entry */
|
||||
unsigned len; /* length to copy for repeats, bits to drop */
|
||||
int ret; /* return code */
|
||||
@ -574,7 +642,7 @@ int flush;
|
||||
static const unsigned short order[19] = /* permutation of code lengths */
|
||||
{16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
|
||||
|
||||
if (strm == Z_NULL || strm->state == Z_NULL || strm->next_out == Z_NULL ||
|
||||
if (inflateStateCheck(strm) || strm->next_out == Z_NULL ||
|
||||
(strm->next_in == Z_NULL && strm->avail_in != 0))
|
||||
return Z_STREAM_ERROR;
|
||||
|
||||
@ -594,6 +662,8 @@ int flush;
|
||||
NEEDBITS(16);
|
||||
#ifdef GUNZIP
|
||||
if ((state->wrap & 2) && hold == 0x8b1f) { /* gzip header */
|
||||
if (state->wbits == 0)
|
||||
state->wbits = 15;
|
||||
state->check = crc32(0L, Z_NULL, 0);
|
||||
CRC2(state->check, hold);
|
||||
INITBITS();
|
||||
@ -619,7 +689,9 @@ int flush;
|
||||
}
|
||||
DROPBITS(4);
|
||||
len = BITS(4) + 8;
|
||||
if (len > state->wbits) {
|
||||
if (state->wbits == 0)
|
||||
state->wbits = len;
|
||||
if (len > 15 || len > state->wbits) {
|
||||
strm->msg = (char *)"invalid window size";
|
||||
state->mode = BAD;
|
||||
break;
|
||||
@ -646,14 +718,16 @@ int flush;
|
||||
}
|
||||
if (state->head != Z_NULL)
|
||||
state->head->text = (int)((hold >> 8) & 1);
|
||||
if (state->flags & 0x0200) CRC2(state->check, hold);
|
||||
if ((state->flags & 0x0200) && (state->wrap & 4))
|
||||
CRC2(state->check, hold);
|
||||
INITBITS();
|
||||
state->mode = TIME;
|
||||
case TIME:
|
||||
NEEDBITS(32);
|
||||
if (state->head != Z_NULL)
|
||||
state->head->time = hold;
|
||||
if (state->flags & 0x0200) CRC4(state->check, hold);
|
||||
if ((state->flags & 0x0200) && (state->wrap & 4))
|
||||
CRC4(state->check, hold);
|
||||
INITBITS();
|
||||
state->mode = OS;
|
||||
case OS:
|
||||
@ -662,7 +736,8 @@ int flush;
|
||||
state->head->xflags = (int)(hold & 0xff);
|
||||
state->head->os = (int)(hold >> 8);
|
||||
}
|
||||
if (state->flags & 0x0200) CRC2(state->check, hold);
|
||||
if ((state->flags & 0x0200) && (state->wrap & 4))
|
||||
CRC2(state->check, hold);
|
||||
INITBITS();
|
||||
state->mode = EXLEN;
|
||||
case EXLEN:
|
||||
@ -671,7 +746,8 @@ int flush;
|
||||
state->length = (unsigned)(hold);
|
||||
if (state->head != Z_NULL)
|
||||
state->head->extra_len = (unsigned)hold;
|
||||
if (state->flags & 0x0200) CRC2(state->check, hold);
|
||||
if ((state->flags & 0x0200) && (state->wrap & 4))
|
||||
CRC2(state->check, hold);
|
||||
INITBITS();
|
||||
}
|
||||
else if (state->head != Z_NULL)
|
||||
@ -689,7 +765,7 @@ int flush;
|
||||
len + copy > state->head->extra_max ?
|
||||
state->head->extra_max - len : copy);
|
||||
}
|
||||
if (state->flags & 0x0200)
|
||||
if ((state->flags & 0x0200) && (state->wrap & 4))
|
||||
state->check = crc32(state->check, next, copy);
|
||||
have -= copy;
|
||||
next += copy;
|
||||
@ -708,9 +784,9 @@ int flush;
|
||||
if (state->head != Z_NULL &&
|
||||
state->head->name != Z_NULL &&
|
||||
state->length < state->head->name_max)
|
||||
state->head->name[state->length++] = len;
|
||||
state->head->name[state->length++] = (Bytef)len;
|
||||
} while (len && copy < have);
|
||||
if (state->flags & 0x0200)
|
||||
if ((state->flags & 0x0200) && (state->wrap & 4))
|
||||
state->check = crc32(state->check, next, copy);
|
||||
have -= copy;
|
||||
next += copy;
|
||||
@ -729,9 +805,9 @@ int flush;
|
||||
if (state->head != Z_NULL &&
|
||||
state->head->comment != Z_NULL &&
|
||||
state->length < state->head->comm_max)
|
||||
state->head->comment[state->length++] = len;
|
||||
state->head->comment[state->length++] = (Bytef)len;
|
||||
} while (len && copy < have);
|
||||
if (state->flags & 0x0200)
|
||||
if ((state->flags & 0x0200) && (state->wrap & 4))
|
||||
state->check = crc32(state->check, next, copy);
|
||||
have -= copy;
|
||||
next += copy;
|
||||
@ -743,7 +819,7 @@ int flush;
|
||||
case HCRC:
|
||||
if (state->flags & 0x0200) {
|
||||
NEEDBITS(16);
|
||||
if (hold != (state->check & 0xffff)) {
|
||||
if ((state->wrap & 4) && hold != (state->check & 0xffff)) {
|
||||
strm->msg = (char *)"header crc mismatch";
|
||||
state->mode = BAD;
|
||||
break;
|
||||
@ -760,7 +836,7 @@ int flush;
|
||||
#endif
|
||||
case DICTID:
|
||||
NEEDBITS(32);
|
||||
strm->adler = state->check = REVERSE(hold);
|
||||
strm->adler = state->check = ZSWAP32(hold);
|
||||
INITBITS();
|
||||
state->mode = DICT;
|
||||
case DICT:
|
||||
@ -771,7 +847,7 @@ int flush;
|
||||
strm->adler = state->check = adler32(0L, Z_NULL, 0);
|
||||
state->mode = TYPE;
|
||||
case TYPE:
|
||||
if (flush == Z_BLOCK) goto inf_leave;
|
||||
if (flush == Z_BLOCK || flush == Z_TREES) goto inf_leave;
|
||||
case TYPEDO:
|
||||
if (state->last) {
|
||||
BYTEBITS();
|
||||
@ -791,7 +867,11 @@ int flush;
|
||||
fixedtables(state);
|
||||
Tracev((stderr, "inflate: fixed codes block%s\n",
|
||||
state->last ? " (last)" : ""));
|
||||
state->mode = LEN; /* decode codes */
|
||||
state->mode = LEN_; /* decode codes */
|
||||
if (flush == Z_TREES) {
|
||||
DROPBITS(2);
|
||||
goto inf_leave;
|
||||
}
|
||||
break;
|
||||
case 2: /* dynamic block */
|
||||
Tracev((stderr, "inflate: dynamic codes block%s\n",
|
||||
@ -816,6 +896,9 @@ int flush;
|
||||
Tracev((stderr, "inflate: stored length %u\n",
|
||||
state->length));
|
||||
INITBITS();
|
||||
state->mode = COPY_;
|
||||
if (flush == Z_TREES) goto inf_leave;
|
||||
case COPY_:
|
||||
state->mode = COPY;
|
||||
case COPY:
|
||||
copy = state->length;
|
||||
@ -861,7 +944,7 @@ int flush;
|
||||
while (state->have < 19)
|
||||
state->lens[order[state->have++]] = 0;
|
||||
state->next = state->codes;
|
||||
state->lencode = (code const FAR *)(state->next);
|
||||
state->lencode = (const code FAR *)(state->next);
|
||||
state->lenbits = 7;
|
||||
ret = inflate_table(CODES, state->lens, 19, &(state->next),
|
||||
&(state->lenbits), state->work);
|
||||
@ -876,19 +959,18 @@ int flush;
|
||||
case CODELENS:
|
||||
while (state->have < state->nlen + state->ndist) {
|
||||
for (;;) {
|
||||
this = state->lencode[BITS(state->lenbits)];
|
||||
if ((unsigned)(this.bits) <= bits) break;
|
||||
here = state->lencode[BITS(state->lenbits)];
|
||||
if ((unsigned)(here.bits) <= bits) break;
|
||||
PULLBYTE();
|
||||
}
|
||||
if (this.val < 16) {
|
||||
NEEDBITS(this.bits);
|
||||
DROPBITS(this.bits);
|
||||
state->lens[state->have++] = this.val;
|
||||
if (here.val < 16) {
|
||||
DROPBITS(here.bits);
|
||||
state->lens[state->have++] = here.val;
|
||||
}
|
||||
else {
|
||||
if (this.val == 16) {
|
||||
NEEDBITS(this.bits + 2);
|
||||
DROPBITS(this.bits);
|
||||
if (here.val == 16) {
|
||||
NEEDBITS(here.bits + 2);
|
||||
DROPBITS(here.bits);
|
||||
if (state->have == 0) {
|
||||
strm->msg = (char *)"invalid bit length repeat";
|
||||
state->mode = BAD;
|
||||
@ -898,16 +980,16 @@ int flush;
|
||||
copy = 3 + BITS(2);
|
||||
DROPBITS(2);
|
||||
}
|
||||
else if (this.val == 17) {
|
||||
NEEDBITS(this.bits + 3);
|
||||
DROPBITS(this.bits);
|
||||
else if (here.val == 17) {
|
||||
NEEDBITS(here.bits + 3);
|
||||
DROPBITS(here.bits);
|
||||
len = 0;
|
||||
copy = 3 + BITS(3);
|
||||
DROPBITS(3);
|
||||
}
|
||||
else {
|
||||
NEEDBITS(this.bits + 7);
|
||||
DROPBITS(this.bits);
|
||||
NEEDBITS(here.bits + 7);
|
||||
DROPBITS(here.bits);
|
||||
len = 0;
|
||||
copy = 11 + BITS(7);
|
||||
DROPBITS(7);
|
||||
@ -925,9 +1007,18 @@ int flush;
|
||||
/* handle error breaks in while */
|
||||
if (state->mode == BAD) break;
|
||||
|
||||
/* build code tables */
|
||||
/* check for end-of-block code (better have one) */
|
||||
if (state->lens[256] == 0) {
|
||||
strm->msg = (char *)"invalid code -- missing end-of-block";
|
||||
state->mode = BAD;
|
||||
break;
|
||||
}
|
||||
|
||||
/* build code tables -- note: do not change the lenbits or distbits
|
||||
values here (9 and 6) without reading the comments in inftrees.h
|
||||
concerning the ENOUGH constants, which depend on those values */
|
||||
state->next = state->codes;
|
||||
state->lencode = (code const FAR *)(state->next);
|
||||
state->lencode = (const code FAR *)(state->next);
|
||||
state->lenbits = 9;
|
||||
ret = inflate_table(LENS, state->lens, state->nlen, &(state->next),
|
||||
&(state->lenbits), state->work);
|
||||
@ -936,7 +1027,7 @@ int flush;
|
||||
state->mode = BAD;
|
||||
break;
|
||||
}
|
||||
state->distcode = (code const FAR *)(state->next);
|
||||
state->distcode = (const code FAR *)(state->next);
|
||||
state->distbits = 6;
|
||||
ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist,
|
||||
&(state->next), &(state->distbits), state->work);
|
||||
@ -946,88 +1037,102 @@ int flush;
|
||||
break;
|
||||
}
|
||||
Tracev((stderr, "inflate: codes ok\n"));
|
||||
state->mode = LEN_;
|
||||
if (flush == Z_TREES) goto inf_leave;
|
||||
case LEN_:
|
||||
state->mode = LEN;
|
||||
case LEN:
|
||||
if (have >= 6 && left >= 258) {
|
||||
RESTORE();
|
||||
inflate_fast(strm, out);
|
||||
LOAD();
|
||||
if (state->mode == TYPE)
|
||||
state->back = -1;
|
||||
break;
|
||||
}
|
||||
state->back = 0;
|
||||
for (;;) {
|
||||
this = state->lencode[BITS(state->lenbits)];
|
||||
if ((unsigned)(this.bits) <= bits) break;
|
||||
here = state->lencode[BITS(state->lenbits)];
|
||||
if ((unsigned)(here.bits) <= bits) break;
|
||||
PULLBYTE();
|
||||
}
|
||||
if (this.op && (this.op & 0xf0) == 0) {
|
||||
last = this;
|
||||
if (here.op && (here.op & 0xf0) == 0) {
|
||||
last = here;
|
||||
for (;;) {
|
||||
this = state->lencode[last.val +
|
||||
here = state->lencode[last.val +
|
||||
(BITS(last.bits + last.op) >> last.bits)];
|
||||
if ((unsigned)(last.bits + this.bits) <= bits) break;
|
||||
if ((unsigned)(last.bits + here.bits) <= bits) break;
|
||||
PULLBYTE();
|
||||
}
|
||||
DROPBITS(last.bits);
|
||||
state->back += last.bits;
|
||||
}
|
||||
DROPBITS(this.bits);
|
||||
state->length = (unsigned)this.val;
|
||||
if ((int)(this.op) == 0) {
|
||||
Tracevv((stderr, this.val >= 0x20 && this.val < 0x7f ?
|
||||
DROPBITS(here.bits);
|
||||
state->back += here.bits;
|
||||
state->length = (unsigned)here.val;
|
||||
if ((int)(here.op) == 0) {
|
||||
Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ?
|
||||
"inflate: literal '%c'\n" :
|
||||
"inflate: literal 0x%02x\n", this.val));
|
||||
"inflate: literal 0x%02x\n", here.val));
|
||||
state->mode = LIT;
|
||||
break;
|
||||
}
|
||||
if (this.op & 32) {
|
||||
if (here.op & 32) {
|
||||
Tracevv((stderr, "inflate: end of block\n"));
|
||||
state->back = -1;
|
||||
state->mode = TYPE;
|
||||
break;
|
||||
}
|
||||
if (this.op & 64) {
|
||||
if (here.op & 64) {
|
||||
strm->msg = (char *)"invalid literal/length code";
|
||||
state->mode = BAD;
|
||||
break;
|
||||
}
|
||||
state->extra = (unsigned)(this.op) & 15;
|
||||
state->extra = (unsigned)(here.op) & 15;
|
||||
state->mode = LENEXT;
|
||||
case LENEXT:
|
||||
if (state->extra) {
|
||||
NEEDBITS(state->extra);
|
||||
state->length += BITS(state->extra);
|
||||
DROPBITS(state->extra);
|
||||
state->back += state->extra;
|
||||
}
|
||||
Tracevv((stderr, "inflate: length %u\n", state->length));
|
||||
state->was = state->length;
|
||||
state->mode = DIST;
|
||||
case DIST:
|
||||
for (;;) {
|
||||
this = state->distcode[BITS(state->distbits)];
|
||||
if ((unsigned)(this.bits) <= bits) break;
|
||||
here = state->distcode[BITS(state->distbits)];
|
||||
if ((unsigned)(here.bits) <= bits) break;
|
||||
PULLBYTE();
|
||||
}
|
||||
if ((this.op & 0xf0) == 0) {
|
||||
last = this;
|
||||
if ((here.op & 0xf0) == 0) {
|
||||
last = here;
|
||||
for (;;) {
|
||||
this = state->distcode[last.val +
|
||||
here = state->distcode[last.val +
|
||||
(BITS(last.bits + last.op) >> last.bits)];
|
||||
if ((unsigned)(last.bits + this.bits) <= bits) break;
|
||||
if ((unsigned)(last.bits + here.bits) <= bits) break;
|
||||
PULLBYTE();
|
||||
}
|
||||
DROPBITS(last.bits);
|
||||
state->back += last.bits;
|
||||
}
|
||||
DROPBITS(this.bits);
|
||||
if (this.op & 64) {
|
||||
DROPBITS(here.bits);
|
||||
state->back += here.bits;
|
||||
if (here.op & 64) {
|
||||
strm->msg = (char *)"invalid distance code";
|
||||
state->mode = BAD;
|
||||
break;
|
||||
}
|
||||
state->offset = (unsigned)this.val;
|
||||
state->extra = (unsigned)(this.op) & 15;
|
||||
state->offset = (unsigned)here.val;
|
||||
state->extra = (unsigned)(here.op) & 15;
|
||||
state->mode = DISTEXT;
|
||||
case DISTEXT:
|
||||
if (state->extra) {
|
||||
NEEDBITS(state->extra);
|
||||
state->offset += BITS(state->extra);
|
||||
DROPBITS(state->extra);
|
||||
state->back += state->extra;
|
||||
}
|
||||
#ifdef INFLATE_STRICT
|
||||
if (state->offset > state->dmax) {
|
||||
@ -1036,11 +1141,6 @@ int flush;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
if (state->offset > state->whave + out - left) {
|
||||
strm->msg = (char *)"invalid distance too far back";
|
||||
state->mode = BAD;
|
||||
break;
|
||||
}
|
||||
Tracevv((stderr, "inflate: distance %u\n", state->offset));
|
||||
state->mode = MATCH;
|
||||
case MATCH:
|
||||
@ -1048,12 +1148,32 @@ int flush;
|
||||
copy = out - left;
|
||||
if (state->offset > copy) { /* copy from window */
|
||||
copy = state->offset - copy;
|
||||
if (copy > state->write) {
|
||||
copy -= state->write;
|
||||
if (copy > state->whave) {
|
||||
if (state->sane) {
|
||||
strm->msg = (char *)"invalid distance too far back";
|
||||
state->mode = BAD;
|
||||
break;
|
||||
}
|
||||
#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR
|
||||
Trace((stderr, "inflate.c too far\n"));
|
||||
copy -= state->whave;
|
||||
if (copy > state->length) copy = state->length;
|
||||
if (copy > left) copy = left;
|
||||
left -= copy;
|
||||
state->length -= copy;
|
||||
do {
|
||||
*put++ = 0;
|
||||
} while (--copy);
|
||||
if (state->length == 0) state->mode = LEN;
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
if (copy > state->wnext) {
|
||||
copy -= state->wnext;
|
||||
from = state->window + (state->wsize - copy);
|
||||
}
|
||||
else
|
||||
from = state->window + (state->write - copy);
|
||||
from = state->window + (state->wnext - copy);
|
||||
if (copy > state->length) copy = state->length;
|
||||
}
|
||||
else { /* copy from output */
|
||||
@ -1080,15 +1200,15 @@ int flush;
|
||||
out -= left;
|
||||
strm->total_out += out;
|
||||
state->total += out;
|
||||
if (out)
|
||||
if ((state->wrap & 4) && out)
|
||||
strm->adler = state->check =
|
||||
UPDATE(state->check, put - out, out);
|
||||
out = left;
|
||||
if ((
|
||||
if ((state->wrap & 4) && (
|
||||
#ifdef GUNZIP
|
||||
state->flags ? hold :
|
||||
#endif
|
||||
REVERSE(hold)) != state->check) {
|
||||
ZSWAP32(hold)) != state->check) {
|
||||
strm->msg = (char *)"incorrect data check";
|
||||
state->mode = BAD;
|
||||
break;
|
||||
@ -1132,8 +1252,9 @@ int flush;
|
||||
*/
|
||||
inf_leave:
|
||||
RESTORE();
|
||||
if (state->wsize || (state->mode < CHECK && out != strm->avail_out))
|
||||
if (updatewindow(strm, out)) {
|
||||
if (state->wsize || (out != strm->avail_out && state->mode < BAD &&
|
||||
(state->mode < CHECK || flush != Z_FINISH)))
|
||||
if (updatewindow(strm, strm->next_out, out - strm->avail_out)) {
|
||||
state->mode = MEM;
|
||||
return Z_MEM_ERROR;
|
||||
}
|
||||
@ -1142,11 +1263,12 @@ int flush;
|
||||
strm->total_in += in;
|
||||
strm->total_out += out;
|
||||
state->total += out;
|
||||
if (state->wrap && out)
|
||||
if ((state->wrap & 4) && out)
|
||||
strm->adler = state->check =
|
||||
UPDATE(state->check, strm->next_out - out, out);
|
||||
strm->data_type = state->bits + (state->last ? 64 : 0) +
|
||||
(state->mode == TYPE ? 128 : 0);
|
||||
strm->data_type = (int)state->bits + (state->last ? 64 : 0) +
|
||||
(state->mode == TYPE ? 128 : 0) +
|
||||
(state->mode == LEN_ || state->mode == COPY_ ? 256 : 0);
|
||||
if (((in == 0 && out == 0) || flush == Z_FINISH) && ret == Z_OK)
|
||||
ret = Z_BUF_ERROR;
|
||||
return ret;
|
||||
@ -1156,7 +1278,7 @@ int ZEXPORT inflateEnd(strm)
|
||||
z_streamp strm;
|
||||
{
|
||||
struct inflate_state FAR *state;
|
||||
if (strm == Z_NULL || strm->state == Z_NULL || strm->zfree == (free_func)0)
|
||||
if (inflateStateCheck(strm))
|
||||
return Z_STREAM_ERROR;
|
||||
state = (struct inflate_state FAR *)strm->state;
|
||||
if (state->window != Z_NULL) ZFREE(strm, state->window);
|
||||
@ -1166,43 +1288,59 @@ z_streamp strm;
|
||||
return Z_OK;
|
||||
}
|
||||
|
||||
int ZEXPORT inflateGetDictionary(strm, dictionary, dictLength)
|
||||
z_streamp strm;
|
||||
Bytef *dictionary;
|
||||
uInt *dictLength;
|
||||
{
|
||||
struct inflate_state FAR *state;
|
||||
|
||||
/* check state */
|
||||
if (inflateStateCheck(strm)) return Z_STREAM_ERROR;
|
||||
state = (struct inflate_state FAR *)strm->state;
|
||||
|
||||
/* copy dictionary */
|
||||
if (state->whave && dictionary != Z_NULL) {
|
||||
zmemcpy(dictionary, state->window + state->wnext,
|
||||
state->whave - state->wnext);
|
||||
zmemcpy(dictionary + state->whave - state->wnext,
|
||||
state->window, state->wnext);
|
||||
}
|
||||
if (dictLength != Z_NULL)
|
||||
*dictLength = state->whave;
|
||||
return Z_OK;
|
||||
}
|
||||
|
||||
int ZEXPORT inflateSetDictionary(strm, dictionary, dictLength)
|
||||
z_streamp strm;
|
||||
const Bytef *dictionary;
|
||||
uInt dictLength;
|
||||
{
|
||||
struct inflate_state FAR *state;
|
||||
unsigned long id;
|
||||
unsigned long dictid;
|
||||
int ret;
|
||||
|
||||
/* check state */
|
||||
if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
|
||||
if (inflateStateCheck(strm)) return Z_STREAM_ERROR;
|
||||
state = (struct inflate_state FAR *)strm->state;
|
||||
if (state->wrap != 0 && state->mode != DICT)
|
||||
return Z_STREAM_ERROR;
|
||||
|
||||
/* check for correct dictionary id */
|
||||
/* check for correct dictionary identifier */
|
||||
if (state->mode == DICT) {
|
||||
id = adler32(0L, Z_NULL, 0);
|
||||
id = adler32(id, dictionary, dictLength);
|
||||
if (id != state->check)
|
||||
dictid = adler32(0L, Z_NULL, 0);
|
||||
dictid = adler32(dictid, dictionary, dictLength);
|
||||
if (dictid != state->check)
|
||||
return Z_DATA_ERROR;
|
||||
}
|
||||
|
||||
/* copy dictionary to window */
|
||||
if (updatewindow(strm, strm->avail_out)) {
|
||||
/* copy dictionary to window using updatewindow(), which will amend the
|
||||
existing dictionary if appropriate */
|
||||
ret = updatewindow(strm, dictionary + dictLength, dictLength);
|
||||
if (ret) {
|
||||
state->mode = MEM;
|
||||
return Z_MEM_ERROR;
|
||||
}
|
||||
if (dictLength > state->wsize) {
|
||||
zmemcpy(state->window, dictionary + dictLength - state->wsize,
|
||||
state->wsize);
|
||||
state->whave = state->wsize;
|
||||
}
|
||||
else {
|
||||
zmemcpy(state->window + state->wsize - dictLength, dictionary,
|
||||
dictLength);
|
||||
state->whave = dictLength;
|
||||
}
|
||||
state->havedict = 1;
|
||||
Tracev((stderr, "inflate: dictionary set\n"));
|
||||
return Z_OK;
|
||||
@ -1215,7 +1353,7 @@ gz_headerp head;
|
||||
struct inflate_state FAR *state;
|
||||
|
||||
/* check state */
|
||||
if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
|
||||
if (inflateStateCheck(strm)) return Z_STREAM_ERROR;
|
||||
state = (struct inflate_state FAR *)strm->state;
|
||||
if ((state->wrap & 2) == 0) return Z_STREAM_ERROR;
|
||||
|
||||
@ -1238,7 +1376,7 @@ gz_headerp head;
|
||||
*/
|
||||
local unsigned syncsearch(have, buf, len)
|
||||
unsigned FAR *have;
|
||||
unsigned char FAR *buf;
|
||||
const unsigned char FAR *buf;
|
||||
unsigned len;
|
||||
{
|
||||
unsigned got;
|
||||
@ -1268,7 +1406,7 @@ z_streamp strm;
|
||||
struct inflate_state FAR *state;
|
||||
|
||||
/* check parameters */
|
||||
if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
|
||||
if (inflateStateCheck(strm)) return Z_STREAM_ERROR;
|
||||
state = (struct inflate_state FAR *)strm->state;
|
||||
if (strm->avail_in == 0 && state->bits < 8) return Z_BUF_ERROR;
|
||||
|
||||
@ -1315,7 +1453,7 @@ z_streamp strm;
|
||||
{
|
||||
struct inflate_state FAR *state;
|
||||
|
||||
if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
|
||||
if (inflateStateCheck(strm)) return Z_STREAM_ERROR;
|
||||
state = (struct inflate_state FAR *)strm->state;
|
||||
return state->mode == STORED && state->bits == 0;
|
||||
}
|
||||
@ -1330,8 +1468,7 @@ z_streamp source;
|
||||
unsigned wsize;
|
||||
|
||||
/* check input */
|
||||
if (dest == Z_NULL || source == Z_NULL || source->state == Z_NULL ||
|
||||
source->zalloc == (alloc_func)0 || source->zfree == (free_func)0)
|
||||
if (inflateStateCheck(source) || dest == Z_NULL)
|
||||
return Z_STREAM_ERROR;
|
||||
state = (struct inflate_state FAR *)source->state;
|
||||
|
||||
@ -1350,8 +1487,9 @@ z_streamp source;
|
||||
}
|
||||
|
||||
/* copy state */
|
||||
zmemcpy(dest, source, sizeof(z_stream));
|
||||
zmemcpy(copy, state, sizeof(struct inflate_state));
|
||||
zmemcpy((voidpf)dest, (voidpf)source, sizeof(z_stream));
|
||||
zmemcpy((voidpf)copy, (voidpf)state, sizeof(struct inflate_state));
|
||||
copy->strm = dest;
|
||||
if (state->lencode >= state->codes &&
|
||||
state->lencode <= state->codes + ENOUGH - 1) {
|
||||
copy->lencode = copy->codes + (state->lencode - state->codes);
|
||||
@ -1366,3 +1504,58 @@ z_streamp source;
|
||||
dest->state = (struct internal_state FAR *)copy;
|
||||
return Z_OK;
|
||||
}
|
||||
|
||||
int ZEXPORT inflateUndermine(strm, subvert)
|
||||
z_streamp strm;
|
||||
int subvert;
|
||||
{
|
||||
struct inflate_state FAR *state;
|
||||
|
||||
if (inflateStateCheck(strm)) return Z_STREAM_ERROR;
|
||||
state = (struct inflate_state FAR *)strm->state;
|
||||
#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR
|
||||
state->sane = !subvert;
|
||||
return Z_OK;
|
||||
#else
|
||||
(void)subvert;
|
||||
state->sane = 1;
|
||||
return Z_DATA_ERROR;
|
||||
#endif
|
||||
}
|
||||
|
||||
int ZEXPORT inflateValidate(strm, check)
|
||||
z_streamp strm;
|
||||
int check;
|
||||
{
|
||||
struct inflate_state FAR *state;
|
||||
|
||||
if (inflateStateCheck(strm)) return Z_STREAM_ERROR;
|
||||
state = (struct inflate_state FAR *)strm->state;
|
||||
if (check)
|
||||
state->wrap |= 4;
|
||||
else
|
||||
state->wrap &= ~4;
|
||||
return Z_OK;
|
||||
}
|
||||
|
||||
long ZEXPORT inflateMark(strm)
|
||||
z_streamp strm;
|
||||
{
|
||||
struct inflate_state FAR *state;
|
||||
|
||||
if (inflateStateCheck(strm))
|
||||
return -(1L << 16);
|
||||
state = (struct inflate_state FAR *)strm->state;
|
||||
return (long)(((unsigned long)((long)state->back)) << 16) +
|
||||
(state->mode == COPY ? state->length :
|
||||
(state->mode == MATCH ? state->was - state->length : 0));
|
||||
}
|
||||
|
||||
unsigned long ZEXPORT inflateCodesUsed(strm)
|
||||
z_streamp strm;
|
||||
{
|
||||
struct inflate_state FAR *state;
|
||||
if (inflateStateCheck(strm)) return (unsigned long)-1;
|
||||
state = (struct inflate_state FAR *)strm->state;
|
||||
return (unsigned long)(state->next - state->codes);
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* inflate.h -- internal inflate state definition
|
||||
* Copyright (C) 1995-2004 Mark Adler
|
||||
* Copyright (C) 1995-2016 Mark Adler
|
||||
* For conditions of distribution and use, see copyright notice in zlib.h
|
||||
*/
|
||||
|
||||
@ -18,7 +18,7 @@
|
||||
|
||||
/* Possible inflate modes between inflate() calls */
|
||||
typedef enum {
|
||||
HEAD, /* i: waiting for magic header */
|
||||
HEAD = 16180, /* i: waiting for magic header */
|
||||
FLAGS, /* i: waiting for method and flags (gzip) */
|
||||
TIME, /* i: waiting for modification time (gzip) */
|
||||
OS, /* i: waiting for extra flags and operating system (gzip) */
|
||||
@ -32,11 +32,13 @@ typedef enum {
|
||||
TYPE, /* i: waiting for type bits, including last-flag bit */
|
||||
TYPEDO, /* i: same, but skip check to exit inflate on new block */
|
||||
STORED, /* i: waiting for stored size (length and complement) */
|
||||
COPY_, /* i/o: same as COPY below, but only first time in */
|
||||
COPY, /* i/o: waiting for input or output to copy stored block */
|
||||
TABLE, /* i: waiting for dynamic block table lengths */
|
||||
LENLENS, /* i: waiting for code length code lengths */
|
||||
CODELENS, /* i: waiting for length/lit and distance code lengths */
|
||||
LEN, /* i: waiting for length/lit code */
|
||||
LEN_, /* i: same as LEN below, but only first time in */
|
||||
LEN, /* i: waiting for length/lit/eob code */
|
||||
LENEXT, /* i: waiting for length extra bits */
|
||||
DIST, /* i: waiting for distance code */
|
||||
DISTEXT, /* i: waiting for distance extra bits */
|
||||
@ -53,19 +55,21 @@ typedef enum {
|
||||
/*
|
||||
State transitions between above modes -
|
||||
|
||||
(most modes can go to the BAD or MEM mode -- not shown for clarity)
|
||||
(most modes can go to BAD or MEM on error -- not shown for clarity)
|
||||
|
||||
Process header:
|
||||
HEAD -> (gzip) or (zlib)
|
||||
(gzip) -> FLAGS -> TIME -> OS -> EXLEN -> EXTRA -> NAME
|
||||
NAME -> COMMENT -> HCRC -> TYPE
|
||||
HEAD -> (gzip) or (zlib) or (raw)
|
||||
(gzip) -> FLAGS -> TIME -> OS -> EXLEN -> EXTRA -> NAME -> COMMENT ->
|
||||
HCRC -> TYPE
|
||||
(zlib) -> DICTID or TYPE
|
||||
DICTID -> DICT -> TYPE
|
||||
(raw) -> TYPEDO
|
||||
Read deflate blocks:
|
||||
TYPE -> STORED or TABLE or LEN or CHECK
|
||||
STORED -> COPY -> TYPE
|
||||
TABLE -> LENLENS -> CODELENS -> LEN
|
||||
Read deflate codes:
|
||||
TYPE -> TYPEDO -> STORED or TABLE or LEN_ or CHECK
|
||||
STORED -> COPY_ -> COPY -> TYPE
|
||||
TABLE -> LENLENS -> CODELENS -> LEN_
|
||||
LEN_ -> LEN
|
||||
Read deflate codes in fixed or dynamic block:
|
||||
LEN -> LENEXT or LIT or TYPE
|
||||
LENEXT -> DIST -> DISTEXT -> MATCH -> LEN
|
||||
LIT -> LEN
|
||||
@ -73,11 +77,14 @@ typedef enum {
|
||||
CHECK -> LENGTH -> DONE
|
||||
*/
|
||||
|
||||
/* state maintained between inflate() calls. Approximately 7K bytes. */
|
||||
/* State maintained between inflate() calls -- approximately 7K bytes, not
|
||||
including the allocated sliding window, which is up to 32K bytes. */
|
||||
struct inflate_state {
|
||||
z_streamp strm; /* pointer back to this zlib stream */
|
||||
inflate_mode mode; /* current inflate mode */
|
||||
int last; /* true if processing last block */
|
||||
int wrap; /* bit 0 true for zlib, bit 1 true for gzip */
|
||||
int wrap; /* bit 0 true for zlib, bit 1 true for gzip,
|
||||
bit 2 true to validate check value */
|
||||
int havedict; /* true if dictionary provided */
|
||||
int flags; /* gzip header method and flags (0 if zlib) */
|
||||
unsigned dmax; /* zlib header max distance (INFLATE_STRICT) */
|
||||
@ -88,7 +95,7 @@ struct inflate_state {
|
||||
unsigned wbits; /* log base 2 of requested window size */
|
||||
unsigned wsize; /* window size or zero if not using window */
|
||||
unsigned whave; /* valid bytes in the window */
|
||||
unsigned write; /* window write index */
|
||||
unsigned wnext; /* window write index */
|
||||
unsigned char FAR *window; /* allocated sliding window, if needed */
|
||||
/* bit accumulator */
|
||||
unsigned long hold; /* input bit accumulator */
|
||||
@ -112,4 +119,7 @@ struct inflate_state {
|
||||
unsigned short lens[320]; /* temporary storage for code lengths */
|
||||
unsigned short work[288]; /* work area for code table building */
|
||||
code codes[ENOUGH]; /* space for code tables */
|
||||
int sane; /* if false, allow invalid distance too far */
|
||||
int back; /* bits back of last unprocessed length/lit */
|
||||
unsigned was; /* initial length of match */
|
||||
};
|
||||
|
109
zlib/inftrees.c
@ -1,5 +1,5 @@
|
||||
/* inftrees.c -- generate Huffman trees for efficient decoding
|
||||
* Copyright (C) 1995-2005 Mark Adler
|
||||
* Copyright (C) 1995-2017 Mark Adler
|
||||
* For conditions of distribution and use, see copyright notice in zlib.h
|
||||
*/
|
||||
|
||||
@ -9,7 +9,7 @@
|
||||
#define MAXBITS 15
|
||||
|
||||
const char inflate_copyright[] =
|
||||
" inflate 1.2.3 Copyright 1995-2005 Mark Adler ";
|
||||
" inflate 1.2.11 Copyright 1995-2017 Mark Adler ";
|
||||
/*
|
||||
If you use the zlib library in a product, an acknowledgment is welcome
|
||||
in the documentation of your product. If for some reason you cannot
|
||||
@ -29,7 +29,7 @@ const char inflate_copyright[] =
|
||||
table index bits. It will differ if the request is greater than the
|
||||
longest code or if it is less than the shortest code.
|
||||
*/
|
||||
int inflate_table(type, lens, codes, table, bits, work)
|
||||
int ZLIB_INTERNAL inflate_table(type, lens, codes, table, bits, work)
|
||||
codetype type;
|
||||
unsigned short FAR *lens;
|
||||
unsigned codes;
|
||||
@ -50,11 +50,11 @@ unsigned short FAR *work;
|
||||
unsigned fill; /* index for replicating entries */
|
||||
unsigned low; /* low bits for current root entry */
|
||||
unsigned mask; /* mask for low root bits */
|
||||
code this; /* table entry for duplication */
|
||||
code here; /* table entry for duplication */
|
||||
code FAR *next; /* next available space in table */
|
||||
const unsigned short FAR *base; /* base value table to use */
|
||||
const unsigned short FAR *extra; /* extra bits table to use */
|
||||
int end; /* use base and extra for symbol > end */
|
||||
unsigned match; /* use base and extra for symbol >= match */
|
||||
unsigned short count[MAXBITS+1]; /* number of codes of each length */
|
||||
unsigned short offs[MAXBITS+1]; /* offsets in table for each length */
|
||||
static const unsigned short lbase[31] = { /* Length codes 257..285 base */
|
||||
@ -62,7 +62,7 @@ unsigned short FAR *work;
|
||||
35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0};
|
||||
static const unsigned short lext[31] = { /* Length codes 257..285 extra */
|
||||
16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18,
|
||||
19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 201, 196};
|
||||
19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 77, 202};
|
||||
static const unsigned short dbase[32] = { /* Distance codes 0..29 base */
|
||||
1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193,
|
||||
257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145,
|
||||
@ -115,15 +115,15 @@ unsigned short FAR *work;
|
||||
if (count[max] != 0) break;
|
||||
if (root > max) root = max;
|
||||
if (max == 0) { /* no symbols to code at all */
|
||||
this.op = (unsigned char)64; /* invalid code marker */
|
||||
this.bits = (unsigned char)1;
|
||||
this.val = (unsigned short)0;
|
||||
*(*table)++ = this; /* make a table to force an error */
|
||||
*(*table)++ = this;
|
||||
here.op = (unsigned char)64; /* invalid code marker */
|
||||
here.bits = (unsigned char)1;
|
||||
here.val = (unsigned short)0;
|
||||
*(*table)++ = here; /* make a table to force an error */
|
||||
*(*table)++ = here;
|
||||
*bits = 1;
|
||||
return 0; /* no symbols, but wait for decoding to report error */
|
||||
}
|
||||
for (min = 1; min <= MAXBITS; min++)
|
||||
for (min = 1; min < max; min++)
|
||||
if (count[min] != 0) break;
|
||||
if (root < min) root = min;
|
||||
|
||||
@ -166,11 +166,10 @@ unsigned short FAR *work;
|
||||
entered in the tables.
|
||||
|
||||
used keeps track of how many table entries have been allocated from the
|
||||
provided *table space. It is checked when a LENS table is being made
|
||||
against the space in *table, ENOUGH, minus the maximum space needed by
|
||||
the worst case distance code, MAXD. This should never happen, but the
|
||||
sufficiency of ENOUGH has not been proven exhaustively, hence the check.
|
||||
This assumes that when type == LENS, bits == 9.
|
||||
provided *table space. It is checked for LENS and DIST tables against
|
||||
the constants ENOUGH_LENS and ENOUGH_DISTS to guard against changes in
|
||||
the initial root table size constants. See the comments in inftrees.h
|
||||
for more information.
|
||||
|
||||
sym increments through all symbols, and the loop terminates when
|
||||
all codes of length max, i.e. all codes, have been processed. This
|
||||
@ -182,19 +181,17 @@ unsigned short FAR *work;
|
||||
switch (type) {
|
||||
case CODES:
|
||||
base = extra = work; /* dummy value--not used */
|
||||
end = 19;
|
||||
match = 20;
|
||||
break;
|
||||
case LENS:
|
||||
base = lbase;
|
||||
base -= 257;
|
||||
extra = lext;
|
||||
extra -= 257;
|
||||
end = 256;
|
||||
match = 257;
|
||||
break;
|
||||
default: /* DISTS */
|
||||
default: /* DISTS */
|
||||
base = dbase;
|
||||
extra = dext;
|
||||
end = -1;
|
||||
match = 0;
|
||||
}
|
||||
|
||||
/* initialize state for loop */
|
||||
@ -209,24 +206,25 @@ unsigned short FAR *work;
|
||||
mask = used - 1; /* mask for comparing low */
|
||||
|
||||
/* check available table space */
|
||||
if (type == LENS && used >= ENOUGH - MAXD)
|
||||
if ((type == LENS && used > ENOUGH_LENS) ||
|
||||
(type == DISTS && used > ENOUGH_DISTS))
|
||||
return 1;
|
||||
|
||||
/* process all codes and make table entries */
|
||||
for (;;) {
|
||||
/* create table entry */
|
||||
this.bits = (unsigned char)(len - drop);
|
||||
if ((int)(work[sym]) < end) {
|
||||
this.op = (unsigned char)0;
|
||||
this.val = work[sym];
|
||||
here.bits = (unsigned char)(len - drop);
|
||||
if (work[sym] + 1U < match) {
|
||||
here.op = (unsigned char)0;
|
||||
here.val = work[sym];
|
||||
}
|
||||
else if ((int)(work[sym]) > end) {
|
||||
this.op = (unsigned char)(extra[work[sym]]);
|
||||
this.val = base[work[sym]];
|
||||
else if (work[sym] >= match) {
|
||||
here.op = (unsigned char)(extra[work[sym] - match]);
|
||||
here.val = base[work[sym] - match];
|
||||
}
|
||||
else {
|
||||
this.op = (unsigned char)(32 + 64); /* end of block */
|
||||
this.val = 0;
|
||||
here.op = (unsigned char)(32 + 64); /* end of block */
|
||||
here.val = 0;
|
||||
}
|
||||
|
||||
/* replicate for those indices with low len bits equal to huff */
|
||||
@ -235,7 +233,7 @@ unsigned short FAR *work;
|
||||
min = fill; /* save offset to next table */
|
||||
do {
|
||||
fill -= incr;
|
||||
next[(huff >> drop) + fill] = this;
|
||||
next[(huff >> drop) + fill] = here;
|
||||
} while (fill != 0);
|
||||
|
||||
/* backwards increment the len-bit code huff */
|
||||
@ -277,7 +275,8 @@ unsigned short FAR *work;
|
||||
|
||||
/* check for enough space */
|
||||
used += 1U << curr;
|
||||
if (type == LENS && used >= ENOUGH - MAXD)
|
||||
if ((type == LENS && used > ENOUGH_LENS) ||
|
||||
(type == DISTS && used > ENOUGH_DISTS))
|
||||
return 1;
|
||||
|
||||
/* point entry in root table to sub-table */
|
||||
@ -288,38 +287,14 @@ unsigned short FAR *work;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Fill in rest of table for incomplete codes. This loop is similar to the
|
||||
loop above in incrementing huff for table indices. It is assumed that
|
||||
len is equal to curr + drop, so there is no loop needed to increment
|
||||
through high index bits. When the current sub-table is filled, the loop
|
||||
drops back to the root table to fill in any remaining entries there.
|
||||
*/
|
||||
this.op = (unsigned char)64; /* invalid code marker */
|
||||
this.bits = (unsigned char)(len - drop);
|
||||
this.val = (unsigned short)0;
|
||||
while (huff != 0) {
|
||||
/* when done with sub-table, drop back to root table */
|
||||
if (drop != 0 && (huff & mask) != low) {
|
||||
drop = 0;
|
||||
len = root;
|
||||
next = *table;
|
||||
this.bits = (unsigned char)len;
|
||||
}
|
||||
|
||||
/* put invalid code marker in table */
|
||||
next[huff >> drop] = this;
|
||||
|
||||
/* backwards increment the len-bit code huff */
|
||||
incr = 1U << (len - 1);
|
||||
while (huff & incr)
|
||||
incr >>= 1;
|
||||
if (incr != 0) {
|
||||
huff &= incr - 1;
|
||||
huff += incr;
|
||||
}
|
||||
else
|
||||
huff = 0;
|
||||
/* fill in remaining table entry if code is incomplete (guaranteed to have
|
||||
at most one remaining entry, since if the code is incomplete, the
|
||||
maximum code length that was allowed to get this far is one bit) */
|
||||
if (huff != 0) {
|
||||
here.op = (unsigned char)64; /* invalid code marker */
|
||||
here.bits = (unsigned char)(len - drop);
|
||||
here.val = (unsigned short)0;
|
||||
next[huff] = here;
|
||||
}
|
||||
|
||||
/* set return parameters */
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* inftrees.h -- header to use inftrees.c
|
||||
* Copyright (C) 1995-2005 Mark Adler
|
||||
* Copyright (C) 1995-2005, 2010 Mark Adler
|
||||
* For conditions of distribution and use, see copyright notice in zlib.h
|
||||
*/
|
||||
|
||||
@ -35,21 +35,28 @@ typedef struct {
|
||||
01000000 - invalid code
|
||||
*/
|
||||
|
||||
/* Maximum size of dynamic tree. The maximum found in a long but non-
|
||||
exhaustive search was 1444 code structures (852 for length/literals
|
||||
and 592 for distances, the latter actually the result of an
|
||||
exhaustive search). The true maximum is not known, but the value
|
||||
below is more than safe. */
|
||||
#define ENOUGH 2048
|
||||
#define MAXD 592
|
||||
/* Maximum size of the dynamic table. The maximum number of code structures is
|
||||
1444, which is the sum of 852 for literal/length codes and 592 for distance
|
||||
codes. These values were found by exhaustive searches using the program
|
||||
examples/enough.c found in the zlib distribtution. The arguments to that
|
||||
program are the number of symbols, the initial root table size, and the
|
||||
maximum bit length of a code. "enough 286 9 15" for literal/length codes
|
||||
returns returns 852, and "enough 30 6 15" for distance codes returns 592.
|
||||
The initial root table size (9 or 6) is found in the fifth argument of the
|
||||
inflate_table() calls in inflate.c and infback.c. If the root table size is
|
||||
changed, then these maximum sizes would be need to be recalculated and
|
||||
updated. */
|
||||
#define ENOUGH_LENS 852
|
||||
#define ENOUGH_DISTS 592
|
||||
#define ENOUGH (ENOUGH_LENS+ENOUGH_DISTS)
|
||||
|
||||
/* Type of code to build for inftable() */
|
||||
/* Type of code to build for inflate_table() */
|
||||
typedef enum {
|
||||
CODES,
|
||||
LENS,
|
||||
DISTS
|
||||
} codetype;
|
||||
|
||||
extern int inflate_table OF((codetype type, unsigned short FAR *lens,
|
||||
int ZLIB_INTERNAL inflate_table OF((codetype type, unsigned short FAR *lens,
|
||||
unsigned codes, code FAR * FAR *table,
|
||||
unsigned FAR *bits, unsigned short FAR *work));
|
||||
|
242
zlib/trees.c
@ -1,5 +1,6 @@
|
||||
/* trees.c -- output deflated data using Huffman coding
|
||||
* Copyright (C) 1995-2005 Jean-loup Gailly
|
||||
* Copyright (C) 1995-2017 Jean-loup Gailly
|
||||
* detect_data_type() function provided freely by Cosmin Truta, 2006
|
||||
* For conditions of distribution and use, see copyright notice in zlib.h
|
||||
*/
|
||||
|
||||
@ -35,7 +36,7 @@
|
||||
|
||||
#include "deflate.h"
|
||||
|
||||
#ifdef DEBUG
|
||||
#ifdef ZLIB_DEBUG
|
||||
# include <ctype.h>
|
||||
#endif
|
||||
|
||||
@ -73,11 +74,6 @@ local const uch bl_order[BL_CODES]
|
||||
* probability, to avoid transmitting the lengths for unused bit length codes.
|
||||
*/
|
||||
|
||||
#define Buf_size (8 * 2*sizeof(char))
|
||||
/* Number of bits used within bi_buf. (bi_buf might be implemented on
|
||||
* more than 16 bits on some systems.)
|
||||
*/
|
||||
|
||||
/* ===========================================================================
|
||||
* Local data. These are initialized only once.
|
||||
*/
|
||||
@ -126,13 +122,13 @@ struct static_tree_desc_s {
|
||||
int max_length; /* max bit length for the codes */
|
||||
};
|
||||
|
||||
local static_tree_desc static_l_desc =
|
||||
local const static_tree_desc static_l_desc =
|
||||
{static_ltree, extra_lbits, LITERALS+1, L_CODES, MAX_BITS};
|
||||
|
||||
local static_tree_desc static_d_desc =
|
||||
local const static_tree_desc static_d_desc =
|
||||
{static_dtree, extra_dbits, 0, D_CODES, MAX_BITS};
|
||||
|
||||
local static_tree_desc static_bl_desc =
|
||||
local const static_tree_desc static_bl_desc =
|
||||
{(const ct_data *)0, extra_blbits, 0, BL_CODES, MAX_BL_BITS};
|
||||
|
||||
/* ===========================================================================
|
||||
@ -150,24 +146,22 @@ local void send_tree OF((deflate_state *s, ct_data *tree, int max_code));
|
||||
local int build_bl_tree OF((deflate_state *s));
|
||||
local void send_all_trees OF((deflate_state *s, int lcodes, int dcodes,
|
||||
int blcodes));
|
||||
local void compress_block OF((deflate_state *s, ct_data *ltree,
|
||||
ct_data *dtree));
|
||||
local void set_data_type OF((deflate_state *s));
|
||||
local void compress_block OF((deflate_state *s, const ct_data *ltree,
|
||||
const ct_data *dtree));
|
||||
local int detect_data_type OF((deflate_state *s));
|
||||
local unsigned bi_reverse OF((unsigned value, int length));
|
||||
local void bi_windup OF((deflate_state *s));
|
||||
local void bi_flush OF((deflate_state *s));
|
||||
local void copy_block OF((deflate_state *s, charf *buf, unsigned len,
|
||||
int header));
|
||||
|
||||
#ifdef GEN_TREES_H
|
||||
local void gen_trees_header OF((void));
|
||||
#endif
|
||||
|
||||
#ifndef DEBUG
|
||||
#ifndef ZLIB_DEBUG
|
||||
# define send_code(s, c, tree) send_bits(s, tree[c].Code, tree[c].Len)
|
||||
/* Send a code of the given tree. c and tree must not have side effects */
|
||||
|
||||
#else /* DEBUG */
|
||||
#else /* !ZLIB_DEBUG */
|
||||
# define send_code(s, c, tree) \
|
||||
{ if (z_verbose>2) fprintf(stderr,"\ncd %3d ",(c)); \
|
||||
send_bits(s, tree[c].Code, tree[c].Len); }
|
||||
@ -186,7 +180,7 @@ local void gen_trees_header OF((void));
|
||||
* Send a value on a given number of bits.
|
||||
* IN assertion: length <= 16 and value fits in length bits.
|
||||
*/
|
||||
#ifdef DEBUG
|
||||
#ifdef ZLIB_DEBUG
|
||||
local void send_bits OF((deflate_state *s, int value, int length));
|
||||
|
||||
local void send_bits(s, value, length)
|
||||
@ -203,31 +197,31 @@ local void send_bits(s, value, length)
|
||||
* unused bits in value.
|
||||
*/
|
||||
if (s->bi_valid > (int)Buf_size - length) {
|
||||
s->bi_buf |= (value << s->bi_valid);
|
||||
s->bi_buf |= (ush)value << s->bi_valid;
|
||||
put_short(s, s->bi_buf);
|
||||
s->bi_buf = (ush)value >> (Buf_size - s->bi_valid);
|
||||
s->bi_valid += length - Buf_size;
|
||||
} else {
|
||||
s->bi_buf |= value << s->bi_valid;
|
||||
s->bi_buf |= (ush)value << s->bi_valid;
|
||||
s->bi_valid += length;
|
||||
}
|
||||
}
|
||||
#else /* !DEBUG */
|
||||
#else /* !ZLIB_DEBUG */
|
||||
|
||||
#define send_bits(s, value, length) \
|
||||
{ int len = length;\
|
||||
if (s->bi_valid > (int)Buf_size - len) {\
|
||||
int val = value;\
|
||||
s->bi_buf |= (val << s->bi_valid);\
|
||||
int val = (int)value;\
|
||||
s->bi_buf |= (ush)val << s->bi_valid;\
|
||||
put_short(s, s->bi_buf);\
|
||||
s->bi_buf = (ush)val >> (Buf_size - s->bi_valid);\
|
||||
s->bi_valid += len - Buf_size;\
|
||||
} else {\
|
||||
s->bi_buf |= (value) << s->bi_valid;\
|
||||
s->bi_buf |= (ush)(value) << s->bi_valid;\
|
||||
s->bi_valid += len;\
|
||||
}\
|
||||
}
|
||||
#endif /* DEBUG */
|
||||
#endif /* ZLIB_DEBUG */
|
||||
|
||||
|
||||
/* the arguments must not have side effects */
|
||||
@ -250,11 +244,13 @@ local void tr_static_init()
|
||||
if (static_init_done) return;
|
||||
|
||||
/* For some embedded targets, global variables are not initialized: */
|
||||
#ifdef NO_INIT_GLOBAL_POINTERS
|
||||
static_l_desc.static_tree = static_ltree;
|
||||
static_l_desc.extra_bits = extra_lbits;
|
||||
static_d_desc.static_tree = static_dtree;
|
||||
static_d_desc.extra_bits = extra_dbits;
|
||||
static_bl_desc.extra_bits = extra_blbits;
|
||||
#endif
|
||||
|
||||
/* Initialize the mapping length (0..255) -> length code (0..28) */
|
||||
length = 0;
|
||||
@ -319,7 +315,7 @@ local void tr_static_init()
|
||||
* Genererate the file trees.h describing the static trees.
|
||||
*/
|
||||
#ifdef GEN_TREES_H
|
||||
# ifndef DEBUG
|
||||
# ifndef ZLIB_DEBUG
|
||||
# include <stdio.h>
|
||||
# endif
|
||||
|
||||
@ -348,13 +344,14 @@ void gen_trees_header()
|
||||
static_dtree[i].Len, SEPARATOR(i, D_CODES-1, 5));
|
||||
}
|
||||
|
||||
fprintf(header, "const uch _dist_code[DIST_CODE_LEN] = {\n");
|
||||
fprintf(header, "const uch ZLIB_INTERNAL _dist_code[DIST_CODE_LEN] = {\n");
|
||||
for (i = 0; i < DIST_CODE_LEN; i++) {
|
||||
fprintf(header, "%2u%s", _dist_code[i],
|
||||
SEPARATOR(i, DIST_CODE_LEN-1, 20));
|
||||
}
|
||||
|
||||
fprintf(header, "const uch _length_code[MAX_MATCH-MIN_MATCH+1]= {\n");
|
||||
fprintf(header,
|
||||
"const uch ZLIB_INTERNAL _length_code[MAX_MATCH-MIN_MATCH+1]= {\n");
|
||||
for (i = 0; i < MAX_MATCH-MIN_MATCH+1; i++) {
|
||||
fprintf(header, "%2u%s", _length_code[i],
|
||||
SEPARATOR(i, MAX_MATCH-MIN_MATCH, 20));
|
||||
@ -379,7 +376,7 @@ void gen_trees_header()
|
||||
/* ===========================================================================
|
||||
* Initialize the tree data structures for a new zlib stream.
|
||||
*/
|
||||
void _tr_init(s)
|
||||
void ZLIB_INTERNAL _tr_init(s)
|
||||
deflate_state *s;
|
||||
{
|
||||
tr_static_init();
|
||||
@ -395,8 +392,7 @@ void _tr_init(s)
|
||||
|
||||
s->bi_buf = 0;
|
||||
s->bi_valid = 0;
|
||||
s->last_eob_len = 8; /* enough lookahead for inflate */
|
||||
#ifdef DEBUG
|
||||
#ifdef ZLIB_DEBUG
|
||||
s->compressed_len = 0L;
|
||||
s->bits_sent = 0L;
|
||||
#endif
|
||||
@ -524,12 +520,12 @@ local void gen_bitlen(s, desc)
|
||||
xbits = 0;
|
||||
if (n >= base) xbits = extra[n-base];
|
||||
f = tree[n].Freq;
|
||||
s->opt_len += (ulg)f * (bits + xbits);
|
||||
if (stree) s->static_len += (ulg)f * (stree[n].Len + xbits);
|
||||
s->opt_len += (ulg)f * (unsigned)(bits + xbits);
|
||||
if (stree) s->static_len += (ulg)f * (unsigned)(stree[n].Len + xbits);
|
||||
}
|
||||
if (overflow == 0) return;
|
||||
|
||||
Trace((stderr,"\nbit length overflow\n"));
|
||||
Tracev((stderr,"\nbit length overflow\n"));
|
||||
/* This happens for example on obj2 and pic of the Calgary corpus */
|
||||
|
||||
/* Find the first bit length which could increase: */
|
||||
@ -556,9 +552,8 @@ local void gen_bitlen(s, desc)
|
||||
m = s->heap[--h];
|
||||
if (m > max_code) continue;
|
||||
if ((unsigned) tree[m].Len != (unsigned) bits) {
|
||||
Trace((stderr,"code %d bits %d->%d\n", m, tree[m].Len, bits));
|
||||
s->opt_len += ((long)bits - (long)tree[m].Len)
|
||||
*(long)tree[m].Freq;
|
||||
Tracev((stderr,"code %d bits %d->%d\n", m, tree[m].Len, bits));
|
||||
s->opt_len += ((ulg)bits - tree[m].Len) * tree[m].Freq;
|
||||
tree[m].Len = (ush)bits;
|
||||
}
|
||||
n--;
|
||||
@ -580,7 +575,7 @@ local void gen_codes (tree, max_code, bl_count)
|
||||
ushf *bl_count; /* number of codes at each bit length */
|
||||
{
|
||||
ush next_code[MAX_BITS+1]; /* next code value for each bit length */
|
||||
ush code = 0; /* running code value */
|
||||
unsigned code = 0; /* running code value */
|
||||
int bits; /* bit index */
|
||||
int n; /* code index */
|
||||
|
||||
@ -588,7 +583,8 @@ local void gen_codes (tree, max_code, bl_count)
|
||||
* without bit reversal.
|
||||
*/
|
||||
for (bits = 1; bits <= MAX_BITS; bits++) {
|
||||
next_code[bits] = code = (code + bl_count[bits-1]) << 1;
|
||||
code = (code + bl_count[bits-1]) << 1;
|
||||
next_code[bits] = (ush)code;
|
||||
}
|
||||
/* Check that the bit counts in bl_count are consistent. The last code
|
||||
* must be all ones.
|
||||
@ -601,7 +597,7 @@ local void gen_codes (tree, max_code, bl_count)
|
||||
int len = tree[n].Len;
|
||||
if (len == 0) continue;
|
||||
/* Now reverse the bits */
|
||||
tree[n].Code = bi_reverse(next_code[len]++, len);
|
||||
tree[n].Code = (ush)bi_reverse(next_code[len]++, len);
|
||||
|
||||
Tracecv(tree != static_ltree, (stderr,"\nn %3d %c l %2d c %4x (%x) ",
|
||||
n, (isgraph(n) ? n : ' '), len, tree[n].Code, next_code[len]-1));
|
||||
@ -823,7 +819,7 @@ local int build_bl_tree(s)
|
||||
if (s->bl_tree[bl_order[max_blindex]].Len != 0) break;
|
||||
}
|
||||
/* Update opt_len to include the bit length tree and counts */
|
||||
s->opt_len += 3*(max_blindex+1) + 5+5+4;
|
||||
s->opt_len += 3*((ulg)max_blindex+1) + 5+5+4;
|
||||
Tracev((stderr, "\ndyn trees: dyn %ld, stat %ld",
|
||||
s->opt_len, s->static_len));
|
||||
|
||||
@ -864,65 +860,59 @@ local void send_all_trees(s, lcodes, dcodes, blcodes)
|
||||
/* ===========================================================================
|
||||
* Send a stored block
|
||||
*/
|
||||
void _tr_stored_block(s, buf, stored_len, eof)
|
||||
void ZLIB_INTERNAL _tr_stored_block(s, buf, stored_len, last)
|
||||
deflate_state *s;
|
||||
charf *buf; /* input block */
|
||||
ulg stored_len; /* length of input block */
|
||||
int eof; /* true if this is the last block for a file */
|
||||
int last; /* one if this is the last block for a file */
|
||||
{
|
||||
send_bits(s, (STORED_BLOCK<<1)+eof, 3); /* send block type */
|
||||
#ifdef DEBUG
|
||||
send_bits(s, (STORED_BLOCK<<1)+last, 3); /* send block type */
|
||||
bi_windup(s); /* align on byte boundary */
|
||||
put_short(s, (ush)stored_len);
|
||||
put_short(s, (ush)~stored_len);
|
||||
zmemcpy(s->pending_buf + s->pending, (Bytef *)buf, stored_len);
|
||||
s->pending += stored_len;
|
||||
#ifdef ZLIB_DEBUG
|
||||
s->compressed_len = (s->compressed_len + 3 + 7) & (ulg)~7L;
|
||||
s->compressed_len += (stored_len + 4) << 3;
|
||||
s->bits_sent += 2*16;
|
||||
s->bits_sent += stored_len<<3;
|
||||
#endif
|
||||
copy_block(s, buf, (unsigned)stored_len, 1); /* with header */
|
||||
}
|
||||
|
||||
/* ===========================================================================
|
||||
* Flush the bits in the bit buffer to pending output (leaves at most 7 bits)
|
||||
*/
|
||||
void ZLIB_INTERNAL _tr_flush_bits(s)
|
||||
deflate_state *s;
|
||||
{
|
||||
bi_flush(s);
|
||||
}
|
||||
|
||||
/* ===========================================================================
|
||||
* Send one empty static block to give enough lookahead for inflate.
|
||||
* This takes 10 bits, of which 7 may remain in the bit buffer.
|
||||
* The current inflate code requires 9 bits of lookahead. If the
|
||||
* last two codes for the previous block (real code plus EOB) were coded
|
||||
* on 5 bits or less, inflate may have only 5+3 bits of lookahead to decode
|
||||
* the last real code. In this case we send two empty static blocks instead
|
||||
* of one. (There are no problems if the previous block is stored or fixed.)
|
||||
* To simplify the code, we assume the worst case of last real code encoded
|
||||
* on one bit only.
|
||||
*/
|
||||
void _tr_align(s)
|
||||
void ZLIB_INTERNAL _tr_align(s)
|
||||
deflate_state *s;
|
||||
{
|
||||
send_bits(s, STATIC_TREES<<1, 3);
|
||||
send_code(s, END_BLOCK, static_ltree);
|
||||
#ifdef DEBUG
|
||||
#ifdef ZLIB_DEBUG
|
||||
s->compressed_len += 10L; /* 3 for block type, 7 for EOB */
|
||||
#endif
|
||||
bi_flush(s);
|
||||
/* Of the 10 bits for the empty block, we have already sent
|
||||
* (10 - bi_valid) bits. The lookahead for the last real code (before
|
||||
* the EOB of the previous block) was thus at least one plus the length
|
||||
* of the EOB plus what we have just sent of the empty static block.
|
||||
*/
|
||||
if (1 + s->last_eob_len + 10 - s->bi_valid < 9) {
|
||||
send_bits(s, STATIC_TREES<<1, 3);
|
||||
send_code(s, END_BLOCK, static_ltree);
|
||||
#ifdef DEBUG
|
||||
s->compressed_len += 10L;
|
||||
#endif
|
||||
bi_flush(s);
|
||||
}
|
||||
s->last_eob_len = 7;
|
||||
}
|
||||
|
||||
/* ===========================================================================
|
||||
* Determine the best encoding for the current block: dynamic trees, static
|
||||
* trees or store, and output the encoded block to the zip file.
|
||||
* trees or store, and write out the encoded block.
|
||||
*/
|
||||
void _tr_flush_block(s, buf, stored_len, eof)
|
||||
void ZLIB_INTERNAL _tr_flush_block(s, buf, stored_len, last)
|
||||
deflate_state *s;
|
||||
charf *buf; /* input block, or NULL if too old */
|
||||
ulg stored_len; /* length of input block */
|
||||
int eof; /* true if this is the last block for a file */
|
||||
int last; /* one if this is the last block for a file */
|
||||
{
|
||||
ulg opt_lenb, static_lenb; /* opt_len and static_len in bytes */
|
||||
int max_blindex = 0; /* index of last bit length code of non zero freq */
|
||||
@ -931,8 +921,8 @@ void _tr_flush_block(s, buf, stored_len, eof)
|
||||
if (s->level > 0) {
|
||||
|
||||
/* Check if the file is binary or text */
|
||||
if (stored_len > 0 && s->strm->data_type == Z_UNKNOWN)
|
||||
set_data_type(s);
|
||||
if (s->strm->data_type == Z_UNKNOWN)
|
||||
s->strm->data_type = detect_data_type(s);
|
||||
|
||||
/* Construct the literal and distance trees */
|
||||
build_tree(s, (tree_desc *)(&(s->l_desc)));
|
||||
@ -978,24 +968,26 @@ void _tr_flush_block(s, buf, stored_len, eof)
|
||||
* successful. If LIT_BUFSIZE <= WSIZE, it is never too late to
|
||||
* transform a block into a stored block.
|
||||
*/
|
||||
_tr_stored_block(s, buf, stored_len, eof);
|
||||
_tr_stored_block(s, buf, stored_len, last);
|
||||
|
||||
#ifdef FORCE_STATIC
|
||||
} else if (static_lenb >= 0) { /* force static trees */
|
||||
#else
|
||||
} else if (s->strategy == Z_FIXED || static_lenb == opt_lenb) {
|
||||
#endif
|
||||
send_bits(s, (STATIC_TREES<<1)+eof, 3);
|
||||
compress_block(s, (ct_data *)static_ltree, (ct_data *)static_dtree);
|
||||
#ifdef DEBUG
|
||||
send_bits(s, (STATIC_TREES<<1)+last, 3);
|
||||
compress_block(s, (const ct_data *)static_ltree,
|
||||
(const ct_data *)static_dtree);
|
||||
#ifdef ZLIB_DEBUG
|
||||
s->compressed_len += 3 + s->static_len;
|
||||
#endif
|
||||
} else {
|
||||
send_bits(s, (DYN_TREES<<1)+eof, 3);
|
||||
send_bits(s, (DYN_TREES<<1)+last, 3);
|
||||
send_all_trees(s, s->l_desc.max_code+1, s->d_desc.max_code+1,
|
||||
max_blindex+1);
|
||||
compress_block(s, (ct_data *)s->dyn_ltree, (ct_data *)s->dyn_dtree);
|
||||
#ifdef DEBUG
|
||||
compress_block(s, (const ct_data *)s->dyn_ltree,
|
||||
(const ct_data *)s->dyn_dtree);
|
||||
#ifdef ZLIB_DEBUG
|
||||
s->compressed_len += 3 + s->opt_len;
|
||||
#endif
|
||||
}
|
||||
@ -1005,21 +997,21 @@ void _tr_flush_block(s, buf, stored_len, eof)
|
||||
*/
|
||||
init_block(s);
|
||||
|
||||
if (eof) {
|
||||
if (last) {
|
||||
bi_windup(s);
|
||||
#ifdef DEBUG
|
||||
#ifdef ZLIB_DEBUG
|
||||
s->compressed_len += 7; /* align on byte boundary */
|
||||
#endif
|
||||
}
|
||||
Tracev((stderr,"\ncomprlen %lu(%lu) ", s->compressed_len>>3,
|
||||
s->compressed_len-7*eof));
|
||||
s->compressed_len-7*last));
|
||||
}
|
||||
|
||||
/* ===========================================================================
|
||||
* Save the match info and tally the frequency counts. Return true if
|
||||
* the current block must be flushed.
|
||||
*/
|
||||
int _tr_tally (s, dist, lc)
|
||||
int ZLIB_INTERNAL _tr_tally (s, dist, lc)
|
||||
deflate_state *s;
|
||||
unsigned dist; /* distance of matched string */
|
||||
unsigned lc; /* match length-MIN_MATCH or unmatched char (if dist==0) */
|
||||
@ -1071,8 +1063,8 @@ int _tr_tally (s, dist, lc)
|
||||
*/
|
||||
local void compress_block(s, ltree, dtree)
|
||||
deflate_state *s;
|
||||
ct_data *ltree; /* literal tree */
|
||||
ct_data *dtree; /* distance tree */
|
||||
const ct_data *ltree; /* literal tree */
|
||||
const ct_data *dtree; /* distance tree */
|
||||
{
|
||||
unsigned dist; /* distance of matched string */
|
||||
int lc; /* match length or unmatched char (if dist == 0) */
|
||||
@ -1102,7 +1094,7 @@ local void compress_block(s, ltree, dtree)
|
||||
send_code(s, code, dtree); /* send the distance code */
|
||||
extra = extra_dbits[code];
|
||||
if (extra != 0) {
|
||||
dist -= base_dist[code];
|
||||
dist -= (unsigned)base_dist[code];
|
||||
send_bits(s, dist, extra); /* send the extra distance bits */
|
||||
}
|
||||
} /* literal or match pair ? */
|
||||
@ -1114,28 +1106,48 @@ local void compress_block(s, ltree, dtree)
|
||||
} while (lx < s->last_lit);
|
||||
|
||||
send_code(s, END_BLOCK, ltree);
|
||||
s->last_eob_len = ltree[END_BLOCK].Len;
|
||||
}
|
||||
|
||||
/* ===========================================================================
|
||||
* Set the data type to BINARY or TEXT, using a crude approximation:
|
||||
* set it to Z_TEXT if all symbols are either printable characters (33 to 255)
|
||||
* or white spaces (9 to 13, or 32); or set it to Z_BINARY otherwise.
|
||||
* Check if the data type is TEXT or BINARY, using the following algorithm:
|
||||
* - TEXT if the two conditions below are satisfied:
|
||||
* a) There are no non-portable control characters belonging to the
|
||||
* "black list" (0..6, 14..25, 28..31).
|
||||
* b) There is at least one printable character belonging to the
|
||||
* "white list" (9 {TAB}, 10 {LF}, 13 {CR}, 32..255).
|
||||
* - BINARY otherwise.
|
||||
* - The following partially-portable control characters form a
|
||||
* "gray list" that is ignored in this detection algorithm:
|
||||
* (7 {BEL}, 8 {BS}, 11 {VT}, 12 {FF}, 26 {SUB}, 27 {ESC}).
|
||||
* IN assertion: the fields Freq of dyn_ltree are set.
|
||||
*/
|
||||
local void set_data_type(s)
|
||||
local int detect_data_type(s)
|
||||
deflate_state *s;
|
||||
{
|
||||
/* black_mask is the bit mask of black-listed bytes
|
||||
* set bits 0..6, 14..25, and 28..31
|
||||
* 0xf3ffc07f = binary 11110011111111111100000001111111
|
||||
*/
|
||||
unsigned long black_mask = 0xf3ffc07fUL;
|
||||
int n;
|
||||
|
||||
for (n = 0; n < 9; n++)
|
||||
/* Check for non-textual ("black-listed") bytes. */
|
||||
for (n = 0; n <= 31; n++, black_mask >>= 1)
|
||||
if ((black_mask & 1) && (s->dyn_ltree[n].Freq != 0))
|
||||
return Z_BINARY;
|
||||
|
||||
/* Check for textual ("white-listed") bytes. */
|
||||
if (s->dyn_ltree[9].Freq != 0 || s->dyn_ltree[10].Freq != 0
|
||||
|| s->dyn_ltree[13].Freq != 0)
|
||||
return Z_TEXT;
|
||||
for (n = 32; n < LITERALS; n++)
|
||||
if (s->dyn_ltree[n].Freq != 0)
|
||||
break;
|
||||
if (n == 9)
|
||||
for (n = 14; n < 32; n++)
|
||||
if (s->dyn_ltree[n].Freq != 0)
|
||||
break;
|
||||
s->strm->data_type = (n == 32) ? Z_TEXT : Z_BINARY;
|
||||
return Z_TEXT;
|
||||
|
||||
/* There are no "black-listed" or "white-listed" bytes:
|
||||
* this stream either is empty or has tolerated ("gray-listed") bytes only.
|
||||
*/
|
||||
return Z_BINARY;
|
||||
}
|
||||
|
||||
/* ===========================================================================
|
||||
@ -1185,35 +1197,7 @@ local void bi_windup(s)
|
||||
}
|
||||
s->bi_buf = 0;
|
||||
s->bi_valid = 0;
|
||||
#ifdef DEBUG
|
||||
#ifdef ZLIB_DEBUG
|
||||
s->bits_sent = (s->bits_sent+7) & ~7;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* ===========================================================================
|
||||
* Copy a stored block, storing first the length and its
|
||||
* one's complement if requested.
|
||||
*/
|
||||
local void copy_block(s, buf, len, header)
|
||||
deflate_state *s;
|
||||
charf *buf; /* the input data */
|
||||
unsigned len; /* its length */
|
||||
int header; /* true if block header must be written */
|
||||
{
|
||||
bi_windup(s); /* align on byte boundary */
|
||||
s->last_eob_len = 8; /* enough lookahead for inflate */
|
||||
|
||||
if (header) {
|
||||
put_short(s, (ush)len);
|
||||
put_short(s, (ush)~len);
|
||||
#ifdef DEBUG
|
||||
s->bits_sent += 2*16;
|
||||
#endif
|
||||
}
|
||||
#ifdef DEBUG
|
||||
s->bits_sent += (ulg)len<<3;
|
||||
#endif
|
||||
while (len--) {
|
||||
put_byte(s, *buf++);
|
||||
}
|
||||
}
|
||||
|
@ -70,7 +70,7 @@ local const ct_data static_dtree[D_CODES] = {
|
||||
{{19},{ 5}}, {{11},{ 5}}, {{27},{ 5}}, {{ 7},{ 5}}, {{23},{ 5}}
|
||||
};
|
||||
|
||||
const uch _dist_code[DIST_CODE_LEN] = {
|
||||
const uch ZLIB_INTERNAL _dist_code[DIST_CODE_LEN] = {
|
||||
0, 1, 2, 3, 4, 4, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8,
|
||||
8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10,
|
||||
10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
|
||||
@ -99,7 +99,7 @@ const uch _dist_code[DIST_CODE_LEN] = {
|
||||
29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29
|
||||
};
|
||||
|
||||
const uch _length_code[MAX_MATCH-MIN_MATCH+1]= {
|
||||
const uch ZLIB_INTERNAL _length_code[MAX_MATCH-MIN_MATCH+1]= {
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 12, 12,
|
||||
13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16,
|
||||
17, 17, 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 19,
|
||||
|
116
zlib/uncompr.c
@ -1,5 +1,5 @@
|
||||
/* uncompr.c -- decompress a memory buffer
|
||||
* Copyright (C) 1995-2003 Jean-loup Gailly.
|
||||
* Copyright (C) 1995-2003, 2010, 2014, 2016 Jean-loup Gailly, Mark Adler
|
||||
* For conditions of distribution and use, see copyright notice in zlib.h
|
||||
*/
|
||||
|
||||
@ -9,53 +9,85 @@
|
||||
#include "zlib.h"
|
||||
|
||||
/* ===========================================================================
|
||||
Decompresses the source buffer into the destination buffer. sourceLen is
|
||||
the byte length of the source buffer. Upon entry, destLen is the total
|
||||
size of the destination buffer, which must be large enough to hold the
|
||||
entire uncompressed data. (The size of the uncompressed data must have
|
||||
been saved previously by the compressor and transmitted to the decompressor
|
||||
by some mechanism outside the scope of this compression library.)
|
||||
Upon exit, destLen is the actual size of the compressed buffer.
|
||||
This function can be used to decompress a whole file at once if the
|
||||
input file is mmap'ed.
|
||||
Decompresses the source buffer into the destination buffer. *sourceLen is
|
||||
the byte length of the source buffer. Upon entry, *destLen is the total size
|
||||
of the destination buffer, which must be large enough to hold the entire
|
||||
uncompressed data. (The size of the uncompressed data must have been saved
|
||||
previously by the compressor and transmitted to the decompressor by some
|
||||
mechanism outside the scope of this compression library.) Upon exit,
|
||||
*destLen is the size of the decompressed data and *sourceLen is the number
|
||||
of source bytes consumed. Upon return, source + *sourceLen points to the
|
||||
first unused input byte.
|
||||
|
||||
uncompress returns Z_OK if success, Z_MEM_ERROR if there was not
|
||||
enough memory, Z_BUF_ERROR if there was not enough room in the output
|
||||
buffer, or Z_DATA_ERROR if the input data was corrupted.
|
||||
uncompress returns Z_OK if success, Z_MEM_ERROR if there was not enough
|
||||
memory, Z_BUF_ERROR if there was not enough room in the output buffer, or
|
||||
Z_DATA_ERROR if the input data was corrupted, including if the input data is
|
||||
an incomplete zlib stream.
|
||||
*/
|
||||
int ZEXPORT uncompress2 (dest, destLen, source, sourceLen)
|
||||
Bytef *dest;
|
||||
uLongf *destLen;
|
||||
const Bytef *source;
|
||||
uLong *sourceLen;
|
||||
{
|
||||
z_stream stream;
|
||||
int err;
|
||||
const uInt max = (uInt)-1;
|
||||
uLong len, left;
|
||||
Byte buf[1]; /* for detection of incomplete stream when *destLen == 0 */
|
||||
|
||||
len = *sourceLen;
|
||||
if (*destLen) {
|
||||
left = *destLen;
|
||||
*destLen = 0;
|
||||
}
|
||||
else {
|
||||
left = 1;
|
||||
dest = buf;
|
||||
}
|
||||
|
||||
stream.next_in = (z_const Bytef *)source;
|
||||
stream.avail_in = 0;
|
||||
stream.zalloc = (alloc_func)0;
|
||||
stream.zfree = (free_func)0;
|
||||
stream.opaque = (voidpf)0;
|
||||
|
||||
err = inflateInit(&stream);
|
||||
if (err != Z_OK) return err;
|
||||
|
||||
stream.next_out = dest;
|
||||
stream.avail_out = 0;
|
||||
|
||||
do {
|
||||
if (stream.avail_out == 0) {
|
||||
stream.avail_out = left > (uLong)max ? max : (uInt)left;
|
||||
left -= stream.avail_out;
|
||||
}
|
||||
if (stream.avail_in == 0) {
|
||||
stream.avail_in = len > (uLong)max ? max : (uInt)len;
|
||||
len -= stream.avail_in;
|
||||
}
|
||||
err = inflate(&stream, Z_NO_FLUSH);
|
||||
} while (err == Z_OK);
|
||||
|
||||
*sourceLen -= len + stream.avail_in;
|
||||
if (dest != buf)
|
||||
*destLen = stream.total_out;
|
||||
else if (stream.total_out && err == Z_BUF_ERROR)
|
||||
left = 1;
|
||||
|
||||
inflateEnd(&stream);
|
||||
return err == Z_STREAM_END ? Z_OK :
|
||||
err == Z_NEED_DICT ? Z_DATA_ERROR :
|
||||
err == Z_BUF_ERROR && left + stream.avail_out ? Z_DATA_ERROR :
|
||||
err;
|
||||
}
|
||||
|
||||
int ZEXPORT uncompress (dest, destLen, source, sourceLen)
|
||||
Bytef *dest;
|
||||
uLongf *destLen;
|
||||
const Bytef *source;
|
||||
uLong sourceLen;
|
||||
{
|
||||
z_stream stream;
|
||||
int err;
|
||||
|
||||
stream.next_in = (Bytef*)source;
|
||||
stream.avail_in = (uInt)sourceLen;
|
||||
/* Check for source > 64K on 16-bit machine: */
|
||||
if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR;
|
||||
|
||||
stream.next_out = dest;
|
||||
stream.avail_out = (uInt)*destLen;
|
||||
if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR;
|
||||
|
||||
stream.zalloc = (alloc_func)0;
|
||||
stream.zfree = (free_func)0;
|
||||
|
||||
err = inflateInit(&stream);
|
||||
if (err != Z_OK) return err;
|
||||
|
||||
err = inflate(&stream, Z_FINISH);
|
||||
if (err != Z_STREAM_END) {
|
||||
inflateEnd(&stream);
|
||||
if (err == Z_NEED_DICT || (err == Z_BUF_ERROR && stream.avail_in == 0))
|
||||
return Z_DATA_ERROR;
|
||||
return err;
|
||||
}
|
||||
*destLen = stream.total_out;
|
||||
|
||||
err = inflateEnd(&stream);
|
||||
return err;
|
||||
return uncompress2(dest, destLen, source, &sourceLen);
|
||||
}
|
||||
|
326
zlib/zconf.h
@ -1,5 +1,5 @@
|
||||
/* zconf.h -- configuration of the zlib compression library
|
||||
* Copyright (C) 1995-2005 Jean-loup Gailly.
|
||||
* Copyright (C) 1995-2016 Jean-loup Gailly, Mark Adler
|
||||
* For conditions of distribution and use, see copyright notice in zlib.h
|
||||
*/
|
||||
|
||||
@ -11,52 +11,158 @@
|
||||
/*
|
||||
* If you *really* need a unique prefix for all types and library functions,
|
||||
* compile with -DZ_PREFIX. The "standard" zlib should be compiled without it.
|
||||
* Even better than compiling with -DZ_PREFIX would be to use configure to set
|
||||
* this permanently in zconf.h using "./configure --zprefix".
|
||||
*/
|
||||
#ifdef Z_PREFIX
|
||||
# define deflateInit_ z_deflateInit_
|
||||
#ifdef Z_PREFIX /* may be set to #if 1 by ./configure */
|
||||
# define Z_PREFIX_SET
|
||||
|
||||
/* all linked symbols and init macros */
|
||||
# define _dist_code z__dist_code
|
||||
# define _length_code z__length_code
|
||||
# define _tr_align z__tr_align
|
||||
# define _tr_flush_bits z__tr_flush_bits
|
||||
# define _tr_flush_block z__tr_flush_block
|
||||
# define _tr_init z__tr_init
|
||||
# define _tr_stored_block z__tr_stored_block
|
||||
# define _tr_tally z__tr_tally
|
||||
# define adler32 z_adler32
|
||||
# define adler32_combine z_adler32_combine
|
||||
# define adler32_combine64 z_adler32_combine64
|
||||
# define adler32_z z_adler32_z
|
||||
# ifndef Z_SOLO
|
||||
# define compress z_compress
|
||||
# define compress2 z_compress2
|
||||
# define compressBound z_compressBound
|
||||
# endif
|
||||
# define crc32 z_crc32
|
||||
# define crc32_combine z_crc32_combine
|
||||
# define crc32_combine64 z_crc32_combine64
|
||||
# define crc32_z z_crc32_z
|
||||
# define deflate z_deflate
|
||||
# define deflateEnd z_deflateEnd
|
||||
# define inflateInit_ z_inflateInit_
|
||||
# define inflate z_inflate
|
||||
# define inflateEnd z_inflateEnd
|
||||
# define deflateInit2_ z_deflateInit2_
|
||||
# define deflateSetDictionary z_deflateSetDictionary
|
||||
# define deflateCopy z_deflateCopy
|
||||
# define deflateReset z_deflateReset
|
||||
# define deflateParams z_deflateParams
|
||||
# define deflateBound z_deflateBound
|
||||
# define deflateCopy z_deflateCopy
|
||||
# define deflateEnd z_deflateEnd
|
||||
# define deflateGetDictionary z_deflateGetDictionary
|
||||
# define deflateInit z_deflateInit
|
||||
# define deflateInit2 z_deflateInit2
|
||||
# define deflateInit2_ z_deflateInit2_
|
||||
# define deflateInit_ z_deflateInit_
|
||||
# define deflateParams z_deflateParams
|
||||
# define deflatePending z_deflatePending
|
||||
# define deflatePrime z_deflatePrime
|
||||
# define deflateReset z_deflateReset
|
||||
# define deflateResetKeep z_deflateResetKeep
|
||||
# define deflateSetDictionary z_deflateSetDictionary
|
||||
# define deflateSetHeader z_deflateSetHeader
|
||||
# define deflateTune z_deflateTune
|
||||
# define deflate_copyright z_deflate_copyright
|
||||
# define get_crc_table z_get_crc_table
|
||||
# ifndef Z_SOLO
|
||||
# define gz_error z_gz_error
|
||||
# define gz_intmax z_gz_intmax
|
||||
# define gz_strwinerror z_gz_strwinerror
|
||||
# define gzbuffer z_gzbuffer
|
||||
# define gzclearerr z_gzclearerr
|
||||
# define gzclose z_gzclose
|
||||
# define gzclose_r z_gzclose_r
|
||||
# define gzclose_w z_gzclose_w
|
||||
# define gzdirect z_gzdirect
|
||||
# define gzdopen z_gzdopen
|
||||
# define gzeof z_gzeof
|
||||
# define gzerror z_gzerror
|
||||
# define gzflush z_gzflush
|
||||
# define gzfread z_gzfread
|
||||
# define gzfwrite z_gzfwrite
|
||||
# define gzgetc z_gzgetc
|
||||
# define gzgetc_ z_gzgetc_
|
||||
# define gzgets z_gzgets
|
||||
# define gzoffset z_gzoffset
|
||||
# define gzoffset64 z_gzoffset64
|
||||
# define gzopen z_gzopen
|
||||
# define gzopen64 z_gzopen64
|
||||
# ifdef _WIN32
|
||||
# define gzopen_w z_gzopen_w
|
||||
# endif
|
||||
# define gzprintf z_gzprintf
|
||||
# define gzputc z_gzputc
|
||||
# define gzputs z_gzputs
|
||||
# define gzread z_gzread
|
||||
# define gzrewind z_gzrewind
|
||||
# define gzseek z_gzseek
|
||||
# define gzseek64 z_gzseek64
|
||||
# define gzsetparams z_gzsetparams
|
||||
# define gztell z_gztell
|
||||
# define gztell64 z_gztell64
|
||||
# define gzungetc z_gzungetc
|
||||
# define gzvprintf z_gzvprintf
|
||||
# define gzwrite z_gzwrite
|
||||
# endif
|
||||
# define inflate z_inflate
|
||||
# define inflateBack z_inflateBack
|
||||
# define inflateBackEnd z_inflateBackEnd
|
||||
# define inflateBackInit z_inflateBackInit
|
||||
# define inflateBackInit_ z_inflateBackInit_
|
||||
# define inflateCodesUsed z_inflateCodesUsed
|
||||
# define inflateCopy z_inflateCopy
|
||||
# define inflateEnd z_inflateEnd
|
||||
# define inflateGetDictionary z_inflateGetDictionary
|
||||
# define inflateGetHeader z_inflateGetHeader
|
||||
# define inflateInit z_inflateInit
|
||||
# define inflateInit2 z_inflateInit2
|
||||
# define inflateInit2_ z_inflateInit2_
|
||||
# define inflateInit_ z_inflateInit_
|
||||
# define inflateMark z_inflateMark
|
||||
# define inflatePrime z_inflatePrime
|
||||
# define inflateReset z_inflateReset
|
||||
# define inflateReset2 z_inflateReset2
|
||||
# define inflateResetKeep z_inflateResetKeep
|
||||
# define inflateSetDictionary z_inflateSetDictionary
|
||||
# define inflateSync z_inflateSync
|
||||
# define inflateSyncPoint z_inflateSyncPoint
|
||||
# define inflateCopy z_inflateCopy
|
||||
# define inflateReset z_inflateReset
|
||||
# define inflateBack z_inflateBack
|
||||
# define inflateBackEnd z_inflateBackEnd
|
||||
# define compress z_compress
|
||||
# define compress2 z_compress2
|
||||
# define compressBound z_compressBound
|
||||
# define uncompress z_uncompress
|
||||
# define adler32 z_adler32
|
||||
# define crc32 z_crc32
|
||||
# define get_crc_table z_get_crc_table
|
||||
# define inflateUndermine z_inflateUndermine
|
||||
# define inflateValidate z_inflateValidate
|
||||
# define inflate_copyright z_inflate_copyright
|
||||
# define inflate_fast z_inflate_fast
|
||||
# define inflate_table z_inflate_table
|
||||
# ifndef Z_SOLO
|
||||
# define uncompress z_uncompress
|
||||
# define uncompress2 z_uncompress2
|
||||
# endif
|
||||
# define zError z_zError
|
||||
# ifndef Z_SOLO
|
||||
# define zcalloc z_zcalloc
|
||||
# define zcfree z_zcfree
|
||||
# endif
|
||||
# define zlibCompileFlags z_zlibCompileFlags
|
||||
# define zlibVersion z_zlibVersion
|
||||
|
||||
# define alloc_func z_alloc_func
|
||||
# define free_func z_free_func
|
||||
# define in_func z_in_func
|
||||
# define out_func z_out_func
|
||||
/* all zlib typedefs in zlib.h and zconf.h */
|
||||
# define Byte z_Byte
|
||||
# define uInt z_uInt
|
||||
# define uLong z_uLong
|
||||
# define Bytef z_Bytef
|
||||
# define alloc_func z_alloc_func
|
||||
# define charf z_charf
|
||||
# define free_func z_free_func
|
||||
# ifndef Z_SOLO
|
||||
# define gzFile z_gzFile
|
||||
# endif
|
||||
# define gz_header z_gz_header
|
||||
# define gz_headerp z_gz_headerp
|
||||
# define in_func z_in_func
|
||||
# define intf z_intf
|
||||
# define out_func z_out_func
|
||||
# define uInt z_uInt
|
||||
# define uIntf z_uIntf
|
||||
# define uLong z_uLong
|
||||
# define uLongf z_uLongf
|
||||
# define voidpf z_voidpf
|
||||
# define voidp z_voidp
|
||||
# define voidpc z_voidpc
|
||||
# define voidpf z_voidpf
|
||||
|
||||
/* all zlib structs in zlib.h and zconf.h */
|
||||
# define gz_header_s z_gz_header_s
|
||||
# define internal_state z_internal_state
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(__MSDOS__) && !defined(MSDOS)
|
||||
@ -125,9 +231,25 @@
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* Some Mac compilers merge all .h files incorrectly: */
|
||||
#if defined(__MWERKS__)||defined(applec)||defined(THINK_C)||defined(__SC__)
|
||||
# define NO_DUMMY_DECL
|
||||
#if defined(ZLIB_CONST) && !defined(z_const)
|
||||
# define z_const const
|
||||
#else
|
||||
# define z_const
|
||||
#endif
|
||||
|
||||
#ifdef Z_SOLO
|
||||
typedef unsigned long z_size_t;
|
||||
#else
|
||||
# define z_longlong long long
|
||||
# if defined(NO_SIZE_T)
|
||||
typedef unsigned NO_SIZE_T z_size_t;
|
||||
# elif defined(STDC)
|
||||
# include <stddef.h>
|
||||
typedef size_t z_size_t;
|
||||
# else
|
||||
typedef unsigned long z_size_t;
|
||||
# endif
|
||||
# undef z_longlong
|
||||
#endif
|
||||
|
||||
/* Maximum value for memLevel in deflateInit2 */
|
||||
@ -157,7 +279,7 @@
|
||||
Of course this will generally degrade compression (there's no free lunch).
|
||||
|
||||
The memory requirements for inflate are (in bytes) 1 << windowBits
|
||||
that is, 32K for windowBits=15 (default value) plus a few kilobytes
|
||||
that is, 32K for windowBits=15 (default value) plus about 7 kilobytes
|
||||
for small objects.
|
||||
*/
|
||||
|
||||
@ -171,6 +293,14 @@
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef Z_ARG /* function prototypes for stdarg */
|
||||
# if defined(STDC) || defined(Z_HAVE_STDARG_H)
|
||||
# define Z_ARG(args) args
|
||||
# else
|
||||
# define Z_ARG(args) ()
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* The following definitions for FAR are needed only for MSDOS mixed
|
||||
* model programming (small or medium model with some far allocations).
|
||||
* This was tested only with MSC; for other MSDOS compilers you may have
|
||||
@ -284,49 +414,121 @@ typedef uLong FAR uLongf;
|
||||
typedef Byte *voidp;
|
||||
#endif
|
||||
|
||||
#if 0 /* HAVE_UNISTD_H -- this line is updated by ./configure */
|
||||
# include <sys/types.h> /* for off_t */
|
||||
# include <unistd.h> /* for SEEK_* and off_t */
|
||||
# ifdef VMS
|
||||
# include <unixio.h> /* for off_t */
|
||||
#if !defined(Z_U4) && !defined(Z_SOLO) && defined(STDC)
|
||||
# include <limits.h>
|
||||
# if (UINT_MAX == 0xffffffffUL)
|
||||
# define Z_U4 unsigned
|
||||
# elif (ULONG_MAX == 0xffffffffUL)
|
||||
# define Z_U4 unsigned long
|
||||
# elif (USHRT_MAX == 0xffffffffUL)
|
||||
# define Z_U4 unsigned short
|
||||
# endif
|
||||
# define z_off_t off_t
|
||||
#endif
|
||||
#ifndef SEEK_SET
|
||||
|
||||
#ifdef Z_U4
|
||||
typedef Z_U4 z_crc_t;
|
||||
#else
|
||||
typedef unsigned long z_crc_t;
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_UNISTD_H /* may be set to #if 1 by ./configure */
|
||||
# define Z_HAVE_UNISTD_H
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_STDARG_H /* may be set to #if 1 by ./configure */
|
||||
# define Z_HAVE_STDARG_H
|
||||
#endif
|
||||
|
||||
#ifdef STDC
|
||||
# ifndef Z_SOLO
|
||||
# include <sys/types.h> /* for off_t */
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if defined(STDC) || defined(Z_HAVE_STDARG_H)
|
||||
# ifndef Z_SOLO
|
||||
# include <stdarg.h> /* for va_list */
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
# ifndef Z_SOLO
|
||||
# include <stddef.h> /* for wchar_t */
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* a little trick to accommodate both "#define _LARGEFILE64_SOURCE" and
|
||||
* "#define _LARGEFILE64_SOURCE 1" as requesting 64-bit operations, (even
|
||||
* though the former does not conform to the LFS document), but considering
|
||||
* both "#undef _LARGEFILE64_SOURCE" and "#define _LARGEFILE64_SOURCE 0" as
|
||||
* equivalently requesting no 64-bit operations
|
||||
*/
|
||||
#if defined(_LARGEFILE64_SOURCE) && -_LARGEFILE64_SOURCE - -1 == 1
|
||||
# undef _LARGEFILE64_SOURCE
|
||||
#endif
|
||||
|
||||
#if defined(__WATCOMC__) && !defined(Z_HAVE_UNISTD_H)
|
||||
# define Z_HAVE_UNISTD_H
|
||||
#endif
|
||||
#ifndef Z_SOLO
|
||||
# if defined(Z_HAVE_UNISTD_H) || defined(_LARGEFILE64_SOURCE)
|
||||
# include <unistd.h> /* for SEEK_*, off_t, and _LFS64_LARGEFILE */
|
||||
# ifdef VMS
|
||||
# include <unixio.h> /* for off_t */
|
||||
# endif
|
||||
# ifndef z_off_t
|
||||
# define z_off_t off_t
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if defined(_LFS64_LARGEFILE) && _LFS64_LARGEFILE-0
|
||||
# define Z_LFS64
|
||||
#endif
|
||||
|
||||
#if defined(_LARGEFILE64_SOURCE) && defined(Z_LFS64)
|
||||
# define Z_LARGE64
|
||||
#endif
|
||||
|
||||
#if defined(_FILE_OFFSET_BITS) && _FILE_OFFSET_BITS-0 == 64 && defined(Z_LFS64)
|
||||
# define Z_WANT64
|
||||
#endif
|
||||
|
||||
#if !defined(SEEK_SET) && !defined(Z_SOLO)
|
||||
# define SEEK_SET 0 /* Seek from beginning of file. */
|
||||
# define SEEK_CUR 1 /* Seek from current position. */
|
||||
# define SEEK_END 2 /* Set file pointer to EOF plus "offset" */
|
||||
#endif
|
||||
|
||||
#ifndef z_off_t
|
||||
# define z_off_t long
|
||||
#endif
|
||||
|
||||
#if defined(__OS400__)
|
||||
# define NO_vsnprintf
|
||||
#endif
|
||||
|
||||
#if defined(__MVS__)
|
||||
# define NO_vsnprintf
|
||||
# ifdef FAR
|
||||
# undef FAR
|
||||
#if !defined(_WIN32) && defined(Z_LARGE64)
|
||||
# define z_off64_t off64_t
|
||||
#else
|
||||
# if defined(_WIN32) && !defined(__GNUC__) && !defined(Z_SOLO)
|
||||
# define z_off64_t __int64
|
||||
# else
|
||||
# define z_off64_t z_off_t
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* MVS linker does not support external names larger than 8 bytes */
|
||||
#if defined(__MVS__)
|
||||
# pragma map(deflateInit_,"DEIN")
|
||||
# pragma map(deflateInit2_,"DEIN2")
|
||||
# pragma map(deflateEnd,"DEEND")
|
||||
# pragma map(deflateBound,"DEBND")
|
||||
# pragma map(inflateInit_,"ININ")
|
||||
# pragma map(inflateInit2_,"ININ2")
|
||||
# pragma map(inflateEnd,"INEND")
|
||||
# pragma map(inflateSync,"INSY")
|
||||
# pragma map(inflateSetDictionary,"INSEDI")
|
||||
# pragma map(compressBound,"CMBND")
|
||||
# pragma map(inflate_table,"INTABL")
|
||||
# pragma map(inflate_fast,"INFA")
|
||||
# pragma map(inflate_copyright,"INCOPY")
|
||||
#pragma map(deflateInit_,"DEIN")
|
||||
#pragma map(deflateInit2_,"DEIN2")
|
||||
#pragma map(deflateEnd,"DEEND")
|
||||
#pragma map(deflateBound,"DEBND")
|
||||
#pragma map(inflateInit_,"ININ")
|
||||
#pragma map(inflateInit2_,"ININ2")
|
||||
#pragma map(inflateEnd,"INEND")
|
||||
#pragma map(inflateSync,"INSY")
|
||||
#pragma map(inflateSetDictionary,"INSEDI")
|
||||
#pragma map(compressBound,"CMBND")
|
||||
#pragma map(inflate_table,"INTABL")
|
||||
#pragma map(inflate_fast,"INFA")
|
||||
#pragma map(inflate_copyright,"INCOPY")
|
||||
#endif
|
||||
|
||||
#endif /* ZCONF_H */
|
||||
|
332
zlib/zconf.in.h
@ -1,332 +0,0 @@
|
||||
/* zconf.h -- configuration of the zlib compression library
|
||||
* Copyright (C) 1995-2005 Jean-loup Gailly.
|
||||
* For conditions of distribution and use, see copyright notice in zlib.h
|
||||
*/
|
||||
|
||||
/* @(#) $Id$ */
|
||||
|
||||
#ifndef ZCONF_H
|
||||
#define ZCONF_H
|
||||
|
||||
/*
|
||||
* If you *really* need a unique prefix for all types and library functions,
|
||||
* compile with -DZ_PREFIX. The "standard" zlib should be compiled without it.
|
||||
*/
|
||||
#ifdef Z_PREFIX
|
||||
# define deflateInit_ z_deflateInit_
|
||||
# define deflate z_deflate
|
||||
# define deflateEnd z_deflateEnd
|
||||
# define inflateInit_ z_inflateInit_
|
||||
# define inflate z_inflate
|
||||
# define inflateEnd z_inflateEnd
|
||||
# define deflateInit2_ z_deflateInit2_
|
||||
# define deflateSetDictionary z_deflateSetDictionary
|
||||
# define deflateCopy z_deflateCopy
|
||||
# define deflateReset z_deflateReset
|
||||
# define deflateParams z_deflateParams
|
||||
# define deflateBound z_deflateBound
|
||||
# define deflatePrime z_deflatePrime
|
||||
# define inflateInit2_ z_inflateInit2_
|
||||
# define inflateSetDictionary z_inflateSetDictionary
|
||||
# define inflateSync z_inflateSync
|
||||
# define inflateSyncPoint z_inflateSyncPoint
|
||||
# define inflateCopy z_inflateCopy
|
||||
# define inflateReset z_inflateReset
|
||||
# define inflateBack z_inflateBack
|
||||
# define inflateBackEnd z_inflateBackEnd
|
||||
# define compress z_compress
|
||||
# define compress2 z_compress2
|
||||
# define compressBound z_compressBound
|
||||
# define uncompress z_uncompress
|
||||
# define adler32 z_adler32
|
||||
# define crc32 z_crc32
|
||||
# define get_crc_table z_get_crc_table
|
||||
# define zError z_zError
|
||||
|
||||
# define alloc_func z_alloc_func
|
||||
# define free_func z_free_func
|
||||
# define in_func z_in_func
|
||||
# define out_func z_out_func
|
||||
# define Byte z_Byte
|
||||
# define uInt z_uInt
|
||||
# define uLong z_uLong
|
||||
# define Bytef z_Bytef
|
||||
# define charf z_charf
|
||||
# define intf z_intf
|
||||
# define uIntf z_uIntf
|
||||
# define uLongf z_uLongf
|
||||
# define voidpf z_voidpf
|
||||
# define voidp z_voidp
|
||||
#endif
|
||||
|
||||
#if defined(__MSDOS__) && !defined(MSDOS)
|
||||
# define MSDOS
|
||||
#endif
|
||||
#if (defined(OS_2) || defined(__OS2__)) && !defined(OS2)
|
||||
# define OS2
|
||||
#endif
|
||||
#if defined(_WINDOWS) && !defined(WINDOWS)
|
||||
# define WINDOWS
|
||||
#endif
|
||||
#if defined(_WIN32) || defined(_WIN32_WCE) || defined(__WIN32__)
|
||||
# ifndef WIN32
|
||||
# define WIN32
|
||||
# endif
|
||||
#endif
|
||||
#if (defined(MSDOS) || defined(OS2) || defined(WINDOWS)) && !defined(WIN32)
|
||||
# if !defined(__GNUC__) && !defined(__FLAT__) && !defined(__386__)
|
||||
# ifndef SYS16BIT
|
||||
# define SYS16BIT
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Compile with -DMAXSEG_64K if the alloc function cannot allocate more
|
||||
* than 64k bytes at a time (needed on systems with 16-bit int).
|
||||
*/
|
||||
#ifdef SYS16BIT
|
||||
# define MAXSEG_64K
|
||||
#endif
|
||||
#ifdef MSDOS
|
||||
# define UNALIGNED_OK
|
||||
#endif
|
||||
|
||||
#ifdef __STDC_VERSION__
|
||||
# ifndef STDC
|
||||
# define STDC
|
||||
# endif
|
||||
# if __STDC_VERSION__ >= 199901L
|
||||
# ifndef STDC99
|
||||
# define STDC99
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
#if !defined(STDC) && (defined(__STDC__) || defined(__cplusplus))
|
||||
# define STDC
|
||||
#endif
|
||||
#if !defined(STDC) && (defined(__GNUC__) || defined(__BORLANDC__))
|
||||
# define STDC
|
||||
#endif
|
||||
#if !defined(STDC) && (defined(MSDOS) || defined(WINDOWS) || defined(WIN32))
|
||||
# define STDC
|
||||
#endif
|
||||
#if !defined(STDC) && (defined(OS2) || defined(__HOS_AIX__))
|
||||
# define STDC
|
||||
#endif
|
||||
|
||||
#if defined(__OS400__) && !defined(STDC) /* iSeries (formerly AS/400). */
|
||||
# define STDC
|
||||
#endif
|
||||
|
||||
#ifndef STDC
|
||||
# ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */
|
||||
# define const /* note: need a more gentle solution here */
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* Some Mac compilers merge all .h files incorrectly: */
|
||||
#if defined(__MWERKS__)||defined(applec)||defined(THINK_C)||defined(__SC__)
|
||||
# define NO_DUMMY_DECL
|
||||
#endif
|
||||
|
||||
/* Maximum value for memLevel in deflateInit2 */
|
||||
#ifndef MAX_MEM_LEVEL
|
||||
# ifdef MAXSEG_64K
|
||||
# define MAX_MEM_LEVEL 8
|
||||
# else
|
||||
# define MAX_MEM_LEVEL 9
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* Maximum value for windowBits in deflateInit2 and inflateInit2.
|
||||
* WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files
|
||||
* created by gzip. (Files created by minigzip can still be extracted by
|
||||
* gzip.)
|
||||
*/
|
||||
#ifndef MAX_WBITS
|
||||
# define MAX_WBITS 15 /* 32K LZ77 window */
|
||||
#endif
|
||||
|
||||
/* The memory requirements for deflate are (in bytes):
|
||||
(1 << (windowBits+2)) + (1 << (memLevel+9))
|
||||
that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values)
|
||||
plus a few kilobytes for small objects. For example, if you want to reduce
|
||||
the default memory requirements from 256K to 128K, compile with
|
||||
make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7"
|
||||
Of course this will generally degrade compression (there's no free lunch).
|
||||
|
||||
The memory requirements for inflate are (in bytes) 1 << windowBits
|
||||
that is, 32K for windowBits=15 (default value) plus a few kilobytes
|
||||
for small objects.
|
||||
*/
|
||||
|
||||
/* Type declarations */
|
||||
|
||||
#ifndef OF /* function prototypes */
|
||||
# ifdef STDC
|
||||
# define OF(args) args
|
||||
# else
|
||||
# define OF(args) ()
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* The following definitions for FAR are needed only for MSDOS mixed
|
||||
* model programming (small or medium model with some far allocations).
|
||||
* This was tested only with MSC; for other MSDOS compilers you may have
|
||||
* to define NO_MEMCPY in zutil.h. If you don't need the mixed model,
|
||||
* just define FAR to be empty.
|
||||
*/
|
||||
#ifdef SYS16BIT
|
||||
# if defined(M_I86SM) || defined(M_I86MM)
|
||||
/* MSC small or medium model */
|
||||
# define SMALL_MEDIUM
|
||||
# ifdef _MSC_VER
|
||||
# define FAR _far
|
||||
# else
|
||||
# define FAR far
|
||||
# endif
|
||||
# endif
|
||||
# if (defined(__SMALL__) || defined(__MEDIUM__))
|
||||
/* Turbo C small or medium model */
|
||||
# define SMALL_MEDIUM
|
||||
# ifdef __BORLANDC__
|
||||
# define FAR _far
|
||||
# else
|
||||
# define FAR far
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if defined(WINDOWS) || defined(WIN32)
|
||||
/* If building or using zlib as a DLL, define ZLIB_DLL.
|
||||
* This is not mandatory, but it offers a little performance increase.
|
||||
*/
|
||||
# ifdef ZLIB_DLL
|
||||
# if defined(WIN32) && (!defined(__BORLANDC__) || (__BORLANDC__ >= 0x500))
|
||||
# ifdef ZLIB_INTERNAL
|
||||
# define ZEXTERN extern __declspec(dllexport)
|
||||
# else
|
||||
# define ZEXTERN extern __declspec(dllimport)
|
||||
# endif
|
||||
# endif
|
||||
# endif /* ZLIB_DLL */
|
||||
/* If building or using zlib with the WINAPI/WINAPIV calling convention,
|
||||
* define ZLIB_WINAPI.
|
||||
* Caution: the standard ZLIB1.DLL is NOT compiled using ZLIB_WINAPI.
|
||||
*/
|
||||
# ifdef ZLIB_WINAPI
|
||||
# ifdef FAR
|
||||
# undef FAR
|
||||
# endif
|
||||
# include <windows.h>
|
||||
/* No need for _export, use ZLIB.DEF instead. */
|
||||
/* For complete Windows compatibility, use WINAPI, not __stdcall. */
|
||||
# define ZEXPORT WINAPI
|
||||
# ifdef WIN32
|
||||
# define ZEXPORTVA WINAPIV
|
||||
# else
|
||||
# define ZEXPORTVA FAR CDECL
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if defined (__BEOS__)
|
||||
# ifdef ZLIB_DLL
|
||||
# ifdef ZLIB_INTERNAL
|
||||
# define ZEXPORT __declspec(dllexport)
|
||||
# define ZEXPORTVA __declspec(dllexport)
|
||||
# else
|
||||
# define ZEXPORT __declspec(dllimport)
|
||||
# define ZEXPORTVA __declspec(dllimport)
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef ZEXTERN
|
||||
# define ZEXTERN extern
|
||||
#endif
|
||||
#ifndef ZEXPORT
|
||||
# define ZEXPORT
|
||||
#endif
|
||||
#ifndef ZEXPORTVA
|
||||
# define ZEXPORTVA
|
||||
#endif
|
||||
|
||||
#ifndef FAR
|
||||
# define FAR
|
||||
#endif
|
||||
|
||||
#if !defined(__MACTYPES__)
|
||||
typedef unsigned char Byte; /* 8 bits */
|
||||
#endif
|
||||
typedef unsigned int uInt; /* 16 bits or more */
|
||||
typedef unsigned long uLong; /* 32 bits or more */
|
||||
|
||||
#ifdef SMALL_MEDIUM
|
||||
/* Borland C/C++ and some old MSC versions ignore FAR inside typedef */
|
||||
# define Bytef Byte FAR
|
||||
#else
|
||||
typedef Byte FAR Bytef;
|
||||
#endif
|
||||
typedef char FAR charf;
|
||||
typedef int FAR intf;
|
||||
typedef uInt FAR uIntf;
|
||||
typedef uLong FAR uLongf;
|
||||
|
||||
#ifdef STDC
|
||||
typedef void const *voidpc;
|
||||
typedef void FAR *voidpf;
|
||||
typedef void *voidp;
|
||||
#else
|
||||
typedef Byte const *voidpc;
|
||||
typedef Byte FAR *voidpf;
|
||||
typedef Byte *voidp;
|
||||
#endif
|
||||
|
||||
#if 0 /* HAVE_UNISTD_H -- this line is updated by ./configure */
|
||||
# include <sys/types.h> /* for off_t */
|
||||
# include <unistd.h> /* for SEEK_* and off_t */
|
||||
# ifdef VMS
|
||||
# include <unixio.h> /* for off_t */
|
||||
# endif
|
||||
# define z_off_t off_t
|
||||
#endif
|
||||
#ifndef SEEK_SET
|
||||
# define SEEK_SET 0 /* Seek from beginning of file. */
|
||||
# define SEEK_CUR 1 /* Seek from current position. */
|
||||
# define SEEK_END 2 /* Set file pointer to EOF plus "offset" */
|
||||
#endif
|
||||
#ifndef z_off_t
|
||||
# define z_off_t long
|
||||
#endif
|
||||
|
||||
#if defined(__OS400__)
|
||||
# define NO_vsnprintf
|
||||
#endif
|
||||
|
||||
#if defined(__MVS__)
|
||||
# define NO_vsnprintf
|
||||
# ifdef FAR
|
||||
# undef FAR
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* MVS linker does not support external names larger than 8 bytes */
|
||||
#if defined(__MVS__)
|
||||
# pragma map(deflateInit_,"DEIN")
|
||||
# pragma map(deflateInit2_,"DEIN2")
|
||||
# pragma map(deflateEnd,"DEEND")
|
||||
# pragma map(deflateBound,"DEBND")
|
||||
# pragma map(inflateInit_,"ININ")
|
||||
# pragma map(inflateInit2_,"ININ2")
|
||||
# pragma map(inflateEnd,"INEND")
|
||||
# pragma map(inflateSync,"INSY")
|
||||
# pragma map(inflateSetDictionary,"INSEDI")
|
||||
# pragma map(compressBound,"CMBND")
|
||||
# pragma map(inflate_table,"INTABL")
|
||||
# pragma map(inflate_fast,"INFA")
|
||||
# pragma map(inflate_copyright,"INCOPY")
|
||||
#endif
|
||||
|
||||
#endif /* ZCONF_H */
|
@ -173,7 +173,23 @@
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\gzio.c"
|
||||
RelativePath=".\gzclose.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\gzguts.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\gzlib.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\gzread.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\gzwrite.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
@ -224,10 +240,6 @@
|
||||
RelativePath=".\zconf.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\zconf.in.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\zlib.h"
|
||||
>
|
||||
|
@ -127,7 +127,10 @@
|
||||
<ClCompile Include="compress.c" />
|
||||
<ClCompile Include="crc32.c" />
|
||||
<ClCompile Include="deflate.c" />
|
||||
<ClCompile Include="gzio.c" />
|
||||
<ClCompile Include="gzclose.c" />
|
||||
<ClCompile Include="gzlib.c" />
|
||||
<ClCompile Include="gzread.c" />
|
||||
<ClCompile Include="gzwrite.c" />
|
||||
<ClCompile Include="infback.c" />
|
||||
<ClCompile Include="inffast.c" />
|
||||
<ClCompile Include="inflate.c" />
|
||||
@ -139,13 +142,13 @@
|
||||
<ItemGroup>
|
||||
<ClInclude Include="crc32.h" />
|
||||
<ClInclude Include="deflate.h" />
|
||||
<ClInclude Include="gzguts.h" />
|
||||
<ClInclude Include="inffast.h" />
|
||||
<ClInclude Include="inffixed.h" />
|
||||
<ClInclude Include="inflate.h" />
|
||||
<ClInclude Include="inftrees.h" />
|
||||
<ClInclude Include="trees.h" />
|
||||
<ClInclude Include="zconf.h" />
|
||||
<ClInclude Include="zconf.in.h" />
|
||||
<ClInclude Include="zlib.h" />
|
||||
<ClInclude Include="zutil.h" />
|
||||
</ItemGroup>
|
||||
|
@ -19,9 +19,6 @@
|
||||
<ClCompile Include="deflate.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="gzio.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="infback.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
@ -43,6 +40,18 @@
|
||||
<ClCompile Include="zutil.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="gzclose.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="gzlib.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="gzread.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="gzwrite.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="crc32.h">
|
||||
@ -69,15 +78,15 @@
|
||||
<ClInclude Include="zconf.h">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="zconf.in.h">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="zlib.h">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="zutil.h">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="gzguts.h">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="README" />
|
||||
|
@ -1,4 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
@ -15,7 +15,10 @@
|
||||
<ClCompile Include="compress.c" />
|
||||
<ClCompile Include="crc32.c" />
|
||||
<ClCompile Include="deflate.c" />
|
||||
<ClCompile Include="gzio.c" />
|
||||
<ClCompile Include="gzclose.c" />
|
||||
<ClCompile Include="gzlib.c" />
|
||||
<ClCompile Include="gzread.c" />
|
||||
<ClCompile Include="gzwrite.c" />
|
||||
<ClCompile Include="infback.c" />
|
||||
<ClCompile Include="inffast.c" />
|
||||
<ClCompile Include="inflate.c" />
|
||||
@ -27,13 +30,13 @@
|
||||
<ItemGroup>
|
||||
<ClInclude Include="crc32.h" />
|
||||
<ClInclude Include="deflate.h" />
|
||||
<ClInclude Include="gzguts.h" />
|
||||
<ClInclude Include="inffast.h" />
|
||||
<ClInclude Include="inffixed.h" />
|
||||
<ClInclude Include="inflate.h" />
|
||||
<ClInclude Include="inftrees.h" />
|
||||
<ClInclude Include="trees.h" />
|
||||
<ClInclude Include="zconf.h" />
|
||||
<ClInclude Include="zconf.in.h" />
|
||||
<ClInclude Include="zlib.h" />
|
||||
<ClInclude Include="zutil.h" />
|
||||
</ItemGroup>
|
||||
|
@ -1,4 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<ClCompile Include="adler32.c">
|
||||
@ -13,9 +13,6 @@
|
||||
<ClCompile Include="deflate.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="gzio.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="infback.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
@ -37,6 +34,18 @@
|
||||
<ClCompile Include="zutil.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="gzclose.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="gzlib.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="gzread.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="gzwrite.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="crc32.h">
|
||||
@ -63,15 +72,15 @@
|
||||
<ClInclude Include="zconf.h">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="zconf.in.h">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="zlib.h">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="zutil.h">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="gzguts.h">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Filter Include="Source Files">
|
||||
|
@ -1,4 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
@ -15,7 +15,10 @@
|
||||
<ClCompile Include="compress.c" />
|
||||
<ClCompile Include="crc32.c" />
|
||||
<ClCompile Include="deflate.c" />
|
||||
<ClCompile Include="gzio.c" />
|
||||
<ClCompile Include="gzclose.c" />
|
||||
<ClCompile Include="gzlib.c" />
|
||||
<ClCompile Include="gzread.c" />
|
||||
<ClCompile Include="gzwrite.c" />
|
||||
<ClCompile Include="infback.c" />
|
||||
<ClCompile Include="inffast.c" />
|
||||
<ClCompile Include="inflate.c" />
|
||||
@ -27,13 +30,13 @@
|
||||
<ItemGroup>
|
||||
<ClInclude Include="crc32.h" />
|
||||
<ClInclude Include="deflate.h" />
|
||||
<ClInclude Include="gzguts.h" />
|
||||
<ClInclude Include="inffast.h" />
|
||||
<ClInclude Include="inffixed.h" />
|
||||
<ClInclude Include="inflate.h" />
|
||||
<ClInclude Include="inftrees.h" />
|
||||
<ClInclude Include="trees.h" />
|
||||
<ClInclude Include="zconf.h" />
|
||||
<ClInclude Include="zconf.in.h" />
|
||||
<ClInclude Include="zlib.h" />
|
||||
<ClInclude Include="zutil.h" />
|
||||
</ItemGroup>
|
||||
|
@ -1,4 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<ClCompile Include="adler32.c">
|
||||
@ -13,9 +13,6 @@
|
||||
<ClCompile Include="deflate.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="gzio.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="infback.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
@ -37,6 +34,18 @@
|
||||
<ClCompile Include="zutil.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="gzclose.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="gzlib.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="gzread.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="gzwrite.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="crc32.h">
|
||||
@ -63,15 +72,15 @@
|
||||
<ClInclude Include="zconf.h">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="zconf.in.h">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="zlib.h">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="zutil.h">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="gzguts.h">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Filter Include="Source Files">
|
||||
|
@ -15,7 +15,10 @@
|
||||
<ClCompile Include="compress.c" />
|
||||
<ClCompile Include="crc32.c" />
|
||||
<ClCompile Include="deflate.c" />
|
||||
<ClCompile Include="gzio.c" />
|
||||
<ClCompile Include="gzclose.c" />
|
||||
<ClCompile Include="gzlib.c" />
|
||||
<ClCompile Include="gzread.c" />
|
||||
<ClCompile Include="gzwrite.c" />
|
||||
<ClCompile Include="infback.c" />
|
||||
<ClCompile Include="inffast.c" />
|
||||
<ClCompile Include="inflate.c" />
|
||||
@ -27,13 +30,13 @@
|
||||
<ItemGroup>
|
||||
<ClInclude Include="crc32.h" />
|
||||
<ClInclude Include="deflate.h" />
|
||||
<ClInclude Include="gzguts.h" />
|
||||
<ClInclude Include="inffast.h" />
|
||||
<ClInclude Include="inffixed.h" />
|
||||
<ClInclude Include="inflate.h" />
|
||||
<ClInclude Include="inftrees.h" />
|
||||
<ClInclude Include="trees.h" />
|
||||
<ClInclude Include="zconf.h" />
|
||||
<ClInclude Include="zconf.in.h" />
|
||||
<ClInclude Include="zlib.h" />
|
||||
<ClInclude Include="zutil.h" />
|
||||
</ItemGroup>
|
||||
|
@ -13,9 +13,6 @@
|
||||
<ClCompile Include="deflate.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="gzio.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="infback.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
@ -37,6 +34,18 @@
|
||||
<ClCompile Include="zutil.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="gzclose.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="gzlib.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="gzread.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="gzwrite.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="crc32.h">
|
||||
@ -63,15 +72,15 @@
|
||||
<ClInclude Include="zconf.h">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="zconf.in.h">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="zlib.h">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="zutil.h">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="gzguts.h">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Filter Include="Source Files">
|
||||
|